diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-10-11 15:35:07 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-10-11 15:35:07 +0100 |
commit | 98f0a701b71191a7b0373b8dd511bcf5f409e440 (patch) | |
tree | e94d06ebaed1bdccaeb4e5613a5d2603a3e6c238 /src | |
parent | f5051a01e8d0c622682f8a282b818ff3a31be01a (diff) | |
download | rspamd-98f0a701b71191a7b0373b8dd511bcf5f409e440.tar.gz rspamd-98f0a701b71191a7b0373b8dd511bcf5f409e440.zip |
[Project] Finish rework of passthrough actions
Diffstat (limited to 'src')
-rw-r--r-- | src/libmime/filter.c | 76 | ||||
-rw-r--r-- | src/libmime/filter.h | 33 | ||||
-rw-r--r-- | src/libmime/message.c | 24 | ||||
-rw-r--r-- | src/lua/lua_task.c | 52 |
4 files changed, 140 insertions, 45 deletions
diff --git a/src/libmime/filter.c b/src/libmime/filter.c index cdbfdcfbf..c06df1b77 100644 --- a/src/libmime/filter.c +++ b/src/libmime/filter.c @@ -60,6 +60,7 @@ rspamd_create_metric_result (struct rspamd_task *task) metric_res->sym_groups = kh_init (rspamd_symbols_group_hash); metric_res->grow_factor = 0; metric_res->score = 0; + metric_res->passthrough_result = NULL; /* Optimize allocation */ kh_resize (rspamd_symbols_group_hash, metric_res->sym_groups, 4); @@ -82,6 +83,49 @@ rspamd_create_metric_result (struct rspamd_task *task) return metric_res; } +static inline int +rspamd_pr_sort (const struct rspamd_passthrough_result *pra, + const struct rspamd_passthrough_result *prb) +{ + return prb->priority - pra->priority; +} + +void +rspamd_add_passthrough_result (struct rspamd_task *task, + enum rspamd_action_type action, + guint priority, + double target_score, + const gchar *message, + const gchar *module) +{ + struct rspamd_metric_result *metric_res; + struct rspamd_passthrough_result *pr; + + metric_res = task->result; + + pr = rspamd_mempool_alloc (task->task_pool, sizeof (*pr)); + pr->action = action; + pr->priority = priority; + pr->message = message; + pr->module = module; + pr->target_score = target_score; + + DL_APPEND (metric_res->passthrough_result, pr); + DL_SORT (metric_res->passthrough_result, rspamd_pr_sort); + + if (!isnan (target_score)) { + msg_info_task ("<%s>: set pre-result to %s (%.2f): '%s' from %s(%d)", + task->message_id, rspamd_action_to_str (action), target_score, + message, module, priority); + } + + else { + msg_info_task ("<%s>: set pre-result to %s (no score): '%s' from %s(%d)", + task->message_id, rspamd_action_to_str (action), + message, module, priority); + } +} + static inline gdouble rspamd_check_group_score (struct rspamd_task *task, const gchar *symbol, @@ -417,12 +461,13 @@ enum rspamd_action_type rspamd_check_action_metric (struct rspamd_task *task, struct rspamd_metric_result *mres) { struct rspamd_action *action, *selected_action = NULL; + struct rspamd_passthrough_result *pr; double max_score = -(G_MAXDOUBLE), sc; int i; gboolean set_action = FALSE; /* We are not certain about the results during processing */ - if (task->pre_result.action == METRIC_ACTION_MAX) { + if (task->result->passthrough_result == NULL) { for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) { action = &task->cfg->actions[i]; sc = mres->actions_limits[i]; @@ -442,26 +487,33 @@ rspamd_check_action_metric (struct rspamd_task *task, struct rspamd_metric_resul } } else { + /* Peek the highest priority result */ + pr = task->result->passthrough_result; sc = NAN; - for (i = task->pre_result.action; i < METRIC_ACTION_MAX; i ++) { - selected_action = &task->cfg->actions[i]; - sc = mres->actions_limits[i]; + if (isnan (pr->target_score)) { + for (i = pr->action; i < METRIC_ACTION_MAX; i++) { + selected_action = &task->cfg->actions[i]; + sc = mres->actions_limits[i]; - if (isnan (sc)) { - if (i == task->pre_result.action) { - /* No scores defined, just avoid NaN */ - sc = 0; + if (isnan (sc)) { + if (i == pr->action) { + /* No scores defined, just avoid NaN */ + sc = 0; + break; + } + } + else { break; } } - else { - break; - } + } + else { + sc = pr->target_score; } if (!isnan (sc)) { - if (task->pre_result.action == METRIC_ACTION_NOACTION) { + if (pr->action == METRIC_ACTION_NOACTION) { mres->score = MIN (sc, mres->score); } else { diff --git a/src/libmime/filter.h b/src/libmime/filter.h index 9137258f5..fdd0f8dc9 100644 --- a/src/libmime/filter.h +++ b/src/libmime/filter.h @@ -58,10 +58,25 @@ KHASH_INIT (rspamd_symbols_group_hash, 1, rspamd_ptr_hash_func, rspamd_ptr_equal_func); + +#define RSPAMD_PASSTHROUGH_NORMAL 1 +#define RSPAMD_PASSTHROUGH_LOW 0 +#define RSPAMD_PASSTHROUGH_HIGH 2 +#define RSPAMD_PASSTHROUGH_CRITICAL 3 + +struct rspamd_passthrough_result { + enum rspamd_action_type action; + guint priority; + double target_score; + const gchar *message; + const gchar *module; + struct rspamd_passthrough_result *prev, *next; +}; + struct rspamd_metric_result { double score; /**< total score */ double grow_factor; /**< current grow factor */ - + struct rspamd_passthrough_result *passthrough_result; khash_t(rspamd_symbols_hash) *symbols; /**< symbols of metric */ khash_t(rspamd_symbols_group_hash) *sym_groups; /**< groups of symbols */ gdouble actions_limits[METRIC_ACTION_MAX]; /**< set of actions for this metric */ @@ -74,6 +89,22 @@ struct rspamd_metric_result { */ struct rspamd_metric_result * rspamd_create_metric_result (struct rspamd_task *task); +/** + * Adds a new passthrough result to a task + * @param task + * @param action + * @param priority + * @param target_score + * @param message + * @param module + */ +void rspamd_add_passthrough_result (struct rspamd_task *task, + enum rspamd_action_type action, + guint priority, + double target_score, + const gchar *message, + const gchar *module); + enum rspamd_symbol_insert_flags { RSPAMD_SYMBOL_INSERT_DEFAULT = 0, RSPAMD_SYMBOL_INSERT_SINGLE = (1 << 0), diff --git a/src/libmime/message.c b/src/libmime/message.c index 4206211c1..43158d083 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -32,6 +32,8 @@ #include "libstemmer.h" #endif +#include <math.h> + #define GTUBE_SYMBOL "GTUBE" #define SET_PART_RAW(part) ((part)->flags &= ~RSPAMD_MIME_TEXT_PART_FLAG_UTF) @@ -854,22 +856,18 @@ rspamd_message_process_text_part_maybe (struct rspamd_task *task, act = rspamd_check_gtube (task, text_part); if (act != METRIC_ACTION_NOACTION) { - struct rspamd_metric_result *mres; - - mres = task->result; + struct rspamd_metric_result *mres = task->result; + gdouble score = NAN; - if (mres != NULL) { - if (act == METRIC_ACTION_REJECT) { - mres->score = rspamd_task_get_required_score (task, mres); - } - else { - mres->score = mres->actions_limits[act]; - } + if (act == METRIC_ACTION_REJECT) { + score = rspamd_task_get_required_score (task, mres); + } + else { + score = mres->actions_limits[act]; } - task->result = mres; - task->pre_result.action = act; - task->pre_result.str = "Gtube pattern"; + rspamd_add_passthrough_result (task, act, RSPAMD_PASSTHROUGH_CRITICAL, + score, "Gtube pattern", "GTUBE"); if (ucl_object_lookup (task->messages, "smtp_message") == NULL) { ucl_object_replace_key (task->messages, diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 7f2711e19..a6b32b089 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -1567,8 +1567,10 @@ lua_task_set_pre_result (lua_State * L) { LUA_TRACE_POINT; struct rspamd_task *task = lua_check_task (L, 1); - gchar *action_str; + const gchar *message = NULL, *module = NULL; + gdouble score = NAN; gint action = METRIC_ACTION_MAX; + guint priority = RSPAMD_PASSTHROUGH_NORMAL; if (task != NULL) { @@ -1584,26 +1586,38 @@ lua_task_set_pre_result (lua_State * L) rspamd_action_from_str (lua_tostring (L, 2), &action); } - if (action < METRIC_ACTION_MAX && action >= METRIC_ACTION_REJECT) { - /* We also need to set the default metric to that result */ + if (lua_type (L, 3) == LUA_TSTRING) { + message = lua_tostring (L, 3); - task->pre_result.action = action; + /* Keep compatibility here :( */ + ucl_object_replace_key (task->messages, + ucl_object_fromstring (message), "smtp_message", 0, + false); + } + else { + message = "unknown reason"; + } - if (lua_gettop (L) >= 3) { - action_str = rspamd_mempool_strdup (task->task_pool, - luaL_checkstring (L, 3)); - task->pre_result.str = action_str; - ucl_object_replace_key (task->messages, - ucl_object_fromstring (action_str), "smtp_message", 0, - false); - } - else { - task->pre_result.str = "unknown"; - } + if (lua_type (L, 4) == LUA_TSTRING) { + module = lua_tostring (L, 4); + } + else { + module = "Unknown lua"; + } + + if (lua_type (L, 5) == LUA_TNUMBER) { + score = lua_tonumber (L, 5); + } + + if (lua_type (L, 6) == LUA_TNUMBER) { + priority = lua_tonumber (L, 5); + } + + if (action < METRIC_ACTION_MAX && action >= METRIC_ACTION_REJECT) { - msg_info_task ("<%s>: set pre-result to %s: '%s'", - task->message_id, rspamd_action_to_str (action), - task->pre_result.str); + rspamd_add_passthrough_result (task, action, priority, + score, rspamd_mempool_strdup (task->task_pool, message), + rspamd_mempool_strdup (task->task_pool, module)); /* Don't classify or filter message if pre-filter sets results */ task->processed_stages |= (RSPAMD_TASK_STAGE_FILTERS | @@ -1629,7 +1643,7 @@ lua_task_has_pre_result (lua_State * L) struct rspamd_task *task = lua_check_task (L, 1); if (task) { - lua_pushboolean (L, task->pre_result.action != METRIC_ACTION_MAX); + lua_pushboolean (L, task->result->passthrough_result != NULL); } else { return luaL_error (L, "invalid arguments"); |