]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Add least passthrough results
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 29 Apr 2019 08:58:31 +0000 (09:58 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 29 Apr 2019 08:58:31 +0000 (09:58 +0100)
src/libmime/filter.c
src/libmime/filter.h
src/libmime/message.c
src/lua/lua_task.c
src/worker.c

index 45563e23f11f469d22fea93655331eb3995b6d14..c3f3089f858919fa98bcdda00422aac17c6da9b8 100644 (file)
@@ -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*
index 7ee0f116372e807a737196cfa38ed2cbcb4772d8..f9218194a4a9670ca03bf033f06b4843205417ed 100644 (file)
@@ -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,
index 9ce8950b77a4f023b545b92068a5043b908afb3d..6211ea2f3332baf6a3b463eb8bfcd690930be6ff 100644 (file)
@@ -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,
index 945e06e0869221a011919e2efffeebde227f7641..6a4ae145d685aef505fe52a101c0212d2a417537 100644 (file)
@@ -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");
index c7f4f76871c1ebdbecc3c1e39258fa08ad29bd15..fc206cc3212a15c6edd590fb7d68483d6c1971f9 100644 (file)
@@ -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",