From 79dc60d2a151ab68707e8ef041418e94d53c8ef7 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 29 Apr 2019 09:58:31 +0100 Subject: [PATCH] [Feature] Add least passthrough results --- src/libmime/filter.c | 92 ++++++++++++++++++++++++++----------------- src/libmime/filter.h | 6 ++- src/libmime/message.c | 2 +- src/lua/lua_task.c | 35 +++++++++++----- src/worker.c | 3 +- 5 files changed, 89 insertions(+), 49 deletions(-) diff --git a/src/libmime/filter.c b/src/libmime/filter.c index 45563e23f..c3f3089f8 100644 --- a/src/libmime/filter.c +++ b/src/libmime/filter.c @@ -110,7 +110,8 @@ rspamd_add_passthrough_result (struct rspamd_task *task, guint priority, double target_score, const gchar *message, - const gchar *module) + const gchar *module, + guint flags) { struct rspamd_metric_result *metric_res; struct rspamd_passthrough_result *pr; @@ -123,19 +124,23 @@ rspamd_add_passthrough_result (struct rspamd_task *task, pr->message = message; pr->module = module; pr->target_score = target_score; + pr->flags = flags; 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, action->name, target_score, + + msg_info_task ("<%s>: set pre-result to '%s' %s(%.2f): '%s' from %s(%d)", + task->message_id, action->name, + flags & RSPAMD_PASSTHROUGH_LEAST ? "*least " : "", + target_score, message, module, priority); } - else { - msg_info_task ("<%s>: set pre-result to %s (no score): '%s' from %s(%d)", + msg_info_task ("<%s>: set pre-result to '%s' %s(no score): '%s' from %s(%d)", task->message_id, action->name, + flags & RSPAMD_PASSTHROUGH_LEAST ? "*least " : "", message, module, priority); } } @@ -495,53 +500,68 @@ rspamd_check_action_metric (struct rspamd_task *task) double max_score = -(G_MAXDOUBLE), sc; int i; struct rspamd_metric_result *mres = task->result; + gboolean seen_least = FALSE; - /* We are not certain about the results during processing */ - if (mres->passthrough_result == NULL) { - for (i = mres->nactions - 1; i >= 0; i--) { - action_lim = &mres->actions_limits[i]; - sc = action_lim->cur_limit; + if (mres->passthrough_result != NULL) { + /* Peek the highest priority result */ + pr = mres->passthrough_result; + sc = pr->target_score; + selected_action = pr->action; - if (action_lim->action->action_type == METRIC_ACTION_NOACTION) { - noaction = action_lim; + if (!(pr->flags & RSPAMD_PASSTHROUGH_LEAST)) { + if (!isnan (sc)) { + if (pr->action->action_type == METRIC_ACTION_NOACTION) { + mres->score = MIN (sc, mres->score); + } + else { + mres->score = sc; + } } - if (isnan (sc) || - (action_lim->action->flags & (RSPAMD_ACTION_NO_THRESHOLD|RSPAMD_ACTION_HAM))) { - continue; - } + return selected_action; + } + else { + seen_least = true; + } + } + /* We are not certain about the results during processing */ - if (mres->score >= sc && sc > max_score) { - selected_action = action_lim->action; - max_score = sc; - } + /* + * Select result by score + */ + for (i = mres->nactions - 1; i >= 0; i--) { + action_lim = &mres->actions_limits[i]; + sc = action_lim->cur_limit; + + if (action_lim->action->action_type == METRIC_ACTION_NOACTION) { + noaction = action_lim; } - if (selected_action == NULL) { - selected_action = noaction->action; + if (isnan (sc) || + (action_lim->action->flags & (RSPAMD_ACTION_NO_THRESHOLD|RSPAMD_ACTION_HAM))) { + continue; } - } - else { - /* Peek the highest priority result */ - pr = mres->passthrough_result; - sc = pr->target_score; - selected_action = pr->action; - if (!isnan (sc)) { - if (pr->action->action_type == METRIC_ACTION_NOACTION) { - mres->score = MIN (sc, mres->score); - } - else { - mres->score = sc; - } + if (mres->score >= sc && sc > max_score) { + selected_action = action_lim->action; + max_score = sc; } } + if (selected_action == NULL) { + selected_action = noaction->action; + } + if (selected_action) { + + if (seen_least) { + mres->score = MIN (sc, mres->score); + } + return selected_action; } - return noaction ? noaction->action : NULL; + return noaction->action; } struct rspamd_symbol_result* diff --git a/src/libmime/filter.h b/src/libmime/filter.h index 7ee0f1163..f9218194a 100644 --- a/src/libmime/filter.h +++ b/src/libmime/filter.h @@ -45,9 +45,12 @@ struct rspamd_symbol_result { #define RSPAMD_PASSTHROUGH_HIGH 2 #define RSPAMD_PASSTHROUGH_CRITICAL 3 +#define RSPAMD_PASSTHROUGH_LEAST (1u << 0u) + struct rspamd_passthrough_result { struct rspamd_action *action; guint priority; + guint flags; double target_score; const gchar *message; const gchar *module; @@ -98,7 +101,8 @@ void rspamd_add_passthrough_result (struct rspamd_task *task, guint priority, double target_score, const gchar *message, - const gchar *module); + const gchar *module, + guint flags); enum rspamd_symbol_insert_flags { RSPAMD_SYMBOL_INSERT_DEFAULT = 0, diff --git a/src/libmime/message.c b/src/libmime/message.c index 9ce8950b7..6211ea2f3 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -961,7 +961,7 @@ rspamd_message_process_text_part_maybe (struct rspamd_task *task, rspamd_add_passthrough_result (task, action, RSPAMD_PASSTHROUGH_CRITICAL, - score, "Gtube pattern", "GTUBE"); + score, "Gtube pattern", "GTUBE", 0); 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 945e06e08..6a4ae145d 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -1767,7 +1767,7 @@ lua_task_set_pre_result (lua_State * L) const gchar *message = NULL, *module = NULL; gdouble score = NAN; struct rspamd_action *action; - guint priority = RSPAMD_PASSTHROUGH_NORMAL; + guint priority = RSPAMD_PASSTHROUGH_NORMAL, flags = 0; if (task != NULL) { @@ -1834,18 +1834,33 @@ lua_task_set_pre_result (lua_State * L) priority = lua_tonumber (L, 6); } + if (lua_type (L, 7) == LUA_TSTRING) { + const gchar *fl_str = lua_tostring (L, 7); + + if (strstr (fl_str, "least") != NULL) { + flags |= RSPAMD_PASSTHROUGH_LEAST; + } + } - rspamd_add_passthrough_result (task, action, priority, - score, rspamd_mempool_strdup (task->task_pool, message), - rspamd_mempool_strdup (task->task_pool, module)); + + rspamd_add_passthrough_result (task, + action, + priority, + score, + rspamd_mempool_strdup (task->task_pool, message), + rspamd_mempool_strdup (task->task_pool, module), + flags); /* Don't classify or filter message if pre-filter sets results */ - task->processed_stages |= (RSPAMD_TASK_STAGE_CLASSIFIERS | - RSPAMD_TASK_STAGE_CLASSIFIERS_PRE | - RSPAMD_TASK_STAGE_CLASSIFIERS_POST); - rspamd_symcache_disable_all_symbols (task, task->cfg->cache, - SYMBOL_TYPE_IDEMPOTENT|SYMBOL_TYPE_IGNORE_PASSTHROUGH| - SYMBOL_TYPE_POSTFILTER); + + if (!(flags & RSPAMD_PASSTHROUGH_LEAST)) { + task->processed_stages |= (RSPAMD_TASK_STAGE_CLASSIFIERS | + RSPAMD_TASK_STAGE_CLASSIFIERS_PRE | + RSPAMD_TASK_STAGE_CLASSIFIERS_POST); + rspamd_symcache_disable_all_symbols (task, task->cfg->cache, + SYMBOL_TYPE_IDEMPOTENT | SYMBOL_TYPE_IGNORE_PASSTHROUGH | + SYMBOL_TYPE_POSTFILTER); + } } else { return luaL_error (L, "invalid arguments"); diff --git a/src/worker.c b/src/worker.c index c7f4f7687..fc206cc32 100644 --- a/src/worker.c +++ b/src/worker.c @@ -157,7 +157,8 @@ rspamd_task_timeout (gint fd, short what, gpointer ud) 0, NAN, "timeout processing message", - "task timeout"); + "task timeout", + 0); ucl_object_replace_key (task->messages, ucl_object_fromstring_common ("timeout processing message", -- 2.39.5