]> source.dussan.org Git - rspamd.git/commitdiff
Refactor metric actions handling.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 13 Sep 2013 00:09:09 +0000 (01:09 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 13 Sep 2013 00:09:09 +0000 (01:09 +0100)
Use array of actions instead of a linked list to speed up processing.
* Removed required_score, reject_score and action in metric config,
now REJECT is the only default action for a metric.

12 files changed:
src/cfg_rcl.c
src/cfg_utils.c
src/cfg_xml.c
src/cfg_xml.h
src/dynamic_cfg.c
src/filter.c
src/filter.h
src/lua/lua_task.c
src/protocol.c
src/roll_history.c
src/smtp_utils.c
src/webui.c

index b6a08657aa4f5beece2021c70d485c43b258b38c..243d1437ed0681ba0fb3a3b89f0555399664d621 100644 (file)
@@ -328,10 +328,9 @@ rspamd_rcl_metric_handler (struct config_file *cfg, rspamd_cl_object_t *obj,
                                g_set_error (err, CFG_RCL_ERROR, EINVAL, "invalid action definition: %s", cur->key);
                                return FALSE;
                        }
-                       action = memory_pool_alloc (cfg->cfg_pool, sizeof (struct metric_action));
+                       action = &metric->actions[action_value];
                        action->action = action_value;
                        action->score = action_score;
-                       metric->actions = g_list_prepend (metric->actions, action);
                }
        }
        else if (new) {
index af438a4c6c5663c2801c32729b600bdc37619916..6bdb3c8f7136a1c6a18919f22342a55f8d0593c7 100644 (file)
@@ -729,8 +729,7 @@ post_load_config (struct config_file *cfg)
        if ((def_metric = g_hash_table_lookup (cfg->metrics, DEFAULT_METRIC)) == NULL) {
                def_metric = check_metric_conf (cfg, NULL);
                def_metric->name = DEFAULT_METRIC;
-               def_metric->required_score = DEFAULT_SCORE;
-               def_metric->reject_score = DEFAULT_REJECT_SCORE;
+               def_metric->actions[METRIC_ACTION_REJECT].score = DEFAULT_SCORE;
                cfg->metrics_list = g_list_prepend (cfg->metrics_list, def_metric);
                g_hash_table_insert (cfg->metrics, DEFAULT_METRIC, def_metric);
        }
@@ -858,12 +857,15 @@ check_statfile_conf (struct config_file *cfg, struct statfile *c)
 struct metric *
 check_metric_conf (struct config_file *cfg, struct metric *c)
 {
+       int i;
        if (c == NULL) {
                c = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric));
-               c->action = METRIC_ACTION_REJECT;
                c->grow_factor = 1.0;
                c->symbols = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
                c->descriptions = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
+               for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
+                       c->actions[i].score = -1.0;
+               }
                memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func) g_hash_table_destroy, c->symbols);
                memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func) g_hash_table_destroy, c->descriptions);
        }
index 23564de95ac43f2e60a26c679b97ab50cee99e7a..0393f026c59dde0f1b5fc071e310390c2c5b197e 100644 (file)
@@ -442,14 +442,14 @@ static struct xml_parser_rule grammar[] = {
                        },
                        {
                                "required_score",
-                               xml_handle_double,
-                               G_STRUCT_OFFSET (struct metric, required_score),
+                               xml_handle_deprecated,
+                               0,
                                NULL
                        },
                        {
                                "reject_score",
-                               xml_handle_double,
-                               G_STRUCT_OFFSET (struct metric, reject_score),
+                               xml_handle_deprecated,
+                               0,
                                NULL
                        },
                        {
@@ -1057,7 +1057,7 @@ handle_metric_action (struct config_file *cfg, struct rspamd_xml_userdata *ctx,
        /* First of all check whether we have data with weight (reject:50 for example) */
        if ((p = strchr (data, ':')) == NULL) {
                if (check_action_str (data, &res)) {
-                       metric->action = res;
+                       /* XXX: no longer needed */
                        return TRUE;
                }
                return FALSE;
@@ -1067,7 +1067,7 @@ handle_metric_action (struct config_file *cfg, struct rspamd_xml_userdata *ctx,
                        return FALSE;
                }
                else {
-                       action = memory_pool_alloc (cfg->cfg_pool, sizeof (struct metric_action));
+                       action = &metric->actions[res];
                        action->action = res;
                        errno = 0;
                        action->score = strtod (p + 1, &errstr);
@@ -1075,7 +1075,6 @@ handle_metric_action (struct config_file *cfg, struct rspamd_xml_userdata *ctx,
                                msg_err ("invalid double value: %s", data);
                                return FALSE;
                        }
-                       metric->actions = g_list_prepend (metric->actions, action);
                }
        }
 
@@ -1797,6 +1796,14 @@ xml_handle_boolean (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GH
        return TRUE;
 }
 
+gboolean
+xml_handle_deprecated (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset)
+{
+
+       msg_err ("parameter is depreciated: %s", ctx->section_name);
+       return TRUE;
+}
+
 gboolean 
 xml_handle_double (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset)
 {
index c4d992c14fc64d0cb679ca277433ce4529be8069..c2930c3651699b2294f99bd5eead9cae1da7853f 100644 (file)
@@ -116,6 +116,9 @@ gboolean xml_handle_uint16 (struct config_file *cfg, struct rspamd_xml_userdata
 /* Flags */
 gboolean xml_handle_boolean (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
 
+/* For deprecated attributes */
+gboolean xml_handle_deprecated (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
+
 /* Specific params */
 /* Options specific */
 gboolean options_handle_nameserver (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
index eacd262a8c4e4e5997f8f3456117f2a0be9df9a9..970fcea16e214e4bf4b9d32b042dc2be4ac4a2ab 100644 (file)
@@ -40,7 +40,7 @@ struct dynamic_cfg_action {
 
 struct dynamic_cfg_metric {
        GList                                              *symbols;
-       GList                                              *actions;
+       struct dynamic_cfg_action       actions[METRIC_ACTION_MAX];
        gchar                                              *name;
 };
 
@@ -62,7 +62,6 @@ dynamic_cfg_free (GList *conf_metrics)
        GList                                                           *cur, *cur_elt;
        struct dynamic_cfg_metric                       *metric;
        struct dynamic_cfg_symbol                       *sym;
-       struct dynamic_cfg_action                       *act;
 
        if (conf_metrics) {
                cur = conf_metrics;
@@ -78,16 +77,6 @@ dynamic_cfg_free (GList *conf_metrics)
                                }
                                g_list_free (metric->symbols);
                        }
-
-                       if (metric->actions) {
-                               cur_elt = metric->actions;
-                               while (cur_elt) {
-                                       act = cur_elt->data;
-                                       g_slice_free1 (sizeof (struct dynamic_cfg_symbol), act);
-                                       cur_elt = g_list_next (cur_elt);
-                               }
-                               g_list_free (metric->actions);
-                       }
                        g_slice_free1 (sizeof (struct dynamic_cfg_metric), metric);
                        cur = g_list_next (cur);
                }
@@ -102,13 +91,14 @@ dynamic_cfg_free (GList *conf_metrics)
 static void
 apply_dynamic_conf (GList *conf_metrics, struct config_file *cfg)
 {
-       GList                                                           *cur, *cur_elt, *tmp;
+       GList                                                           *cur, *cur_elt;
        struct dynamic_cfg_metric                       *metric;
        struct dynamic_cfg_symbol                       *sym;
        struct dynamic_cfg_action                       *act;
        struct metric                                           *real_metric;
        struct metric_action                            *real_act;
        gdouble                                                         *w;
+       gint                                 i, j;
 
        cur = conf_metrics;
        while (cur) {
@@ -126,22 +116,21 @@ apply_dynamic_conf (GList *conf_metrics, struct config_file *cfg)
                                cur_elt = g_list_next (cur_elt);
                        }
 
-                       cur_elt = metric->actions;
-                       while (cur_elt) {
-                               act = cur_elt->data;
-                               tmp = real_metric->actions;
-                               while (tmp) {
-                                       real_act = tmp->data;
+                       for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
+                               act = &metric->actions[i];
+                               if (act->value < 0) {
+                                       continue;
+                               }
+                               for (j = METRIC_ACTION_REJECT; j < METRIC_ACTION_MAX; j ++) {
+                                       real_act = &real_metric->actions[j];
                                        if (real_act->action == act->action) {
                                                real_act->score = act->value;
                                        }
                                        /* Update required score accordingly to metric's action */
-                                       if (act->action == real_metric->action) {
-                                               real_metric->required_score = act->value;
+                                       if (act->action == METRIC_ACTION_REJECT) {
+                                               real_metric->actions[METRIC_ACTION_REJECT].score = act->value;
                                        }
-                                       tmp = g_list_next (tmp);
                                }
-                               cur_elt = g_list_next (cur_elt);
                        }
                }
                cur = g_list_next (cur);
@@ -257,6 +246,9 @@ json_config_fin_cb (memory_pool_t * pool, struct map_cb_data *data)
                        continue;
                }
                cur_metric = g_slice_alloc0 (sizeof (struct dynamic_cfg_metric));
+               for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
+                       cur_metric->actions[i].value = -1.0;
+               }
                cur_metric->name = g_strdup (json_string_value (cur_nm));
                cur_nm = json_object_get (cur_elt, "symbols");
                /* Parse symbols */
@@ -286,17 +278,14 @@ json_config_fin_cb (memory_pool_t * pool, struct map_cb_data *data)
                                it_val = json_array_get (cur_nm, j);
                                if (it_val && json_is_object (it_val)) {
                                        if (json_object_get (it_val, "name") && json_object_get (it_val, "value")) {
-
-                                               cur_action = g_slice_alloc0 (sizeof (struct dynamic_cfg_action));
                                                if (!check_action_str (json_string_value (json_object_get (it_val, "name")), &test_act)) {
                                                        msg_err ("unknown action: %s", json_string_value (json_object_get (it_val, "name")));
                                                        g_slice_free1 (sizeof (struct dynamic_cfg_action), cur_action);
                                                        continue;
                                                }
+                                               cur_action = &cur_metric->actions[test_act];
                                                cur_action->action = test_act;
                                                cur_action->value = json_number_value (json_object_get (it_val, "value"));
-                                               /* Insert action */
-                                               cur_metric->actions = g_list_prepend (cur_metric->actions, cur_action);
                                        }
                                        else {
                                                msg_info ("json symbol object has no mandatory 'name' and 'value' attributes");
@@ -351,6 +340,8 @@ dump_dynamic_list (gint fd, GList *rules)
        struct dynamic_cfg_symbol                       *sym;
        struct dynamic_cfg_action                       *act;
        FILE                                                            *f;
+       gint                                 i;
+       gboolean                             start = TRUE;
 
        /* Open buffered stream for the descriptor */
        if ((f = fdopen (fd, "a+")) == NULL) {
@@ -387,16 +378,16 @@ dump_dynamic_list (gint fd, GList *rules)
                        }
 
                        if (metric->actions) {
-                               cur_elt = metric->actions;
                                fprintf (f, "  \"actions\": [\n");
-                               while (cur_elt) {
-                                       act = cur_elt->data;
-                                       cur_elt = g_list_next (cur_elt);
-                                       if (cur_elt) {
-                                               fprintf (f, "    {\"name\": \"%s\",\"value\": %.2f},\n", str_action_metric (act->action), act->value);
+                               for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
+                                       act = &metric->actions[i];
+                                       if (act->value < 0) {
+                                               continue;
                                        }
-                                       else {
-                                               fprintf (f, "    {\"name\": \"%s\",\"value\": %.2f}\n", str_action_metric (act->action), act->value);
+                                       fprintf (f, "    %s{\"name\": \"%s\",\"value\": %.2f}\n",
+                                                       (start ? "" : ","), str_action_metric (act->action), act->value);
+                                       if (start) {
+                                               start = FALSE;
                                        }
                                }
                                fprintf (f, "  ]\n");
@@ -573,7 +564,6 @@ add_dynamic_action (struct config_file *cfg, const gchar *metric_name, guint act
 {
        GList                                                           *cur;
        struct dynamic_cfg_metric                       *metric = NULL;
-       struct dynamic_cfg_action                       *act = NULL;
 
        if (cfg->dynamic_conf == NULL) {
                msg_info ("dynamic conf is disabled");
@@ -592,33 +582,12 @@ add_dynamic_action (struct config_file *cfg, const gchar *metric_name, guint act
 
        if (metric != NULL) {
                /* Search for an action */
-               cur = metric->actions;
-               while (cur) {
-                       act = cur->data;
-                       if (act->action == action) {
-                               act->value = value;
-                               msg_debug ("change value of action %d to %.2f", action, value);
-                               break;
-                       }
-                       act = NULL;
-                       cur = g_list_next (cur);
-               }
-               if (act == NULL) {
-                       /* Action not found, insert it */
-                       act = g_slice_alloc (sizeof (struct dynamic_cfg_action));
-                       act->action = action;
-                       act->value = value;
-                       metric->actions = g_list_prepend (metric->actions, act);
-                       msg_debug ("create action %d in metric %s", action, metric_name);
-               }
+               metric->actions[action].value = value;
        }
        else {
                /* Metric not found, create it */
                metric = g_slice_alloc0 (sizeof (struct dynamic_cfg_metric));
-               act = g_slice_alloc (sizeof (struct dynamic_cfg_action));
-               act->action = action;
-               act->value = value;
-               metric->actions = g_list_prepend (metric->actions, act);
+               metric->actions[action].value = value;
                metric->name = g_strdup (metric_name);
                cfg->current_dynamic_conf = g_list_prepend (cfg->current_dynamic_conf, metric);
                msg_debug ("create metric %s for action %d", metric_name, action);
index 1876344e1b6283a4e2e6fbbdfe3997fd13a4d027..c62a690845600f22bf4c8501c1534b2629250102 100644 (file)
@@ -227,7 +227,7 @@ check_metric_is_spam (struct worker_task *task, struct metric *metric)
        struct metric_result           *res;
        double                          ms, rs;
 
-       /* Avoid concurrenting while checking results */
+       /* Avoid concurrency while checking results */
 #if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
        g_static_mutex_lock (&result_mtx);
 #else
@@ -241,9 +241,9 @@ check_metric_is_spam (struct worker_task *task, struct metric *metric)
                G_UNLOCK (result_mtx);
 #endif
                if (!check_metric_settings (res, &ms, &rs)) {
-                       ms = metric->required_score;
+                       ms = metric->actions[METRIC_ACTION_REJECT].score;
                }
-               return res->score >= ms;
+               return (ms > 0 && res->score >= ms);
        }
 
 #if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
@@ -280,7 +280,7 @@ process_filters (struct worker_task *task)
                while (cur) {
                        metric = cur->data;
                        if (!task->pass_all_filters &&
-                                               metric->action == METRIC_ACTION_REJECT && 
+                                               metric->actions[METRIC_ACTION_REJECT].score > 0 &&
                                                check_metric_is_spam (task, metric)) {
                                task->s->wanna_die = TRUE;
                                check_session_pending (task->s);
@@ -763,9 +763,9 @@ insert_metric_header (gpointer metric_name, gpointer metric_value, gpointer data
        rspamd_snprintf (header_name, sizeof (header_name), "X-Spam-%s", metric_res->metric->name);
 
        if (!check_metric_settings (metric_res, &ms, &rs)) {
-               ms = metric_res->metric->required_score;
+               ms = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
        }
-       if (metric_res->score >= ms) {
+       if (ms > 0 && metric_res->score >= ms) {
                r += rspamd_snprintf (outbuf + r, sizeof (outbuf) - r, "yes; %.2f/%.2f/%.2f; ", metric_res->score, ms, rs);
        }
        else {
@@ -835,7 +835,9 @@ str_action_metric (enum rspamd_metric_action action)
        case METRIC_ACTION_GREYLIST:
                return "greylist";
        case METRIC_ACTION_NOACTION:
-               return "no action";
+               return "no_action";
+       case METRIC_ACTION_MAX:
+               return "invalid max action";
        }
 
        return "unknown action";
@@ -844,25 +846,26 @@ str_action_metric (enum rspamd_metric_action action)
 gint
 check_metric_action (double score, double required_score, struct metric *metric)
 {
-       GList                          *cur;
        struct metric_action           *action, *selected_action = NULL;
        double                          max_score = 0;
+       int                             i;
 
        if (score >= required_score) {
-               return metric->action;
+               return METRIC_ACTION_REJECT;
        }
        else if (metric->actions == NULL) {
                return METRIC_ACTION_NOACTION;
        }
        else {
-               cur = metric->actions;
-               while (cur) {
-                       action = cur->data;
+               for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
+                       action = &metric->actions[i];
+                       if (action->score < 0) {
+                               continue;
+                       }
                        if (score >= action->score && action->score > max_score) {
                                selected_action = action;
                                max_score = action->score;
                        }
-                       cur = g_list_next (cur);
                }
                if (selected_action) {
                        return selected_action->action;
index 5dc141af8cac296f6f45db04afc6246b82eb5c24..7843775acc6fec5bbba4c347223b10072e7a57d6 100644 (file)
@@ -42,7 +42,8 @@ enum rspamd_metric_action {
        METRIC_ACTION_REWRITE_SUBJECT,
        METRIC_ACTION_ADD_HEADER,
        METRIC_ACTION_GREYLIST,
-       METRIC_ACTION_NOACTION
+       METRIC_ACTION_NOACTION,
+       METRIC_ACTION_MAX
 };
 
 struct metric_action {
@@ -58,12 +59,9 @@ struct metric {
        gchar *func_name;                                                               /**< name of consolidation function                                     */
        metric_cons_func func;                                                  /**< c consolidation function                                           */
        double grow_factor;                                                             /**< grow factor for metric                                                     */
-       double required_score;                                                  /**< required score for this metric                                     */
-       double reject_score;                                                    /**< reject score for this metric                                       */
        GHashTable *symbols;                                                    /**< weights of symbols in metric                                       */
        GHashTable *descriptions;                                               /**< descriptions of symbols in metric                          */
-       enum rspamd_metric_action action;                               /**< action to do by this metric by default                     */
-       GList *actions;                                                                 /**< actions that can be performed by this metric       */
+       struct metric_action actions[METRIC_ACTION_MAX]; /**< all actions of the metric                                 */
        gchar *subject;                                                                 /**< subject rewrite string                                                     */
 };
 
index d78aff036e70c55a3f4b04e7d919d04f0f972aad..86dcd459d4bf05aee615f3c7eaf511a31d988eaa 100644 (file)
@@ -1552,9 +1552,9 @@ lua_task_get_metric_score (lua_State *L)
                        lua_newtable (L);
                        lua_pushnumber (L, metric_res->score);
                        lua_rawseti (L, -2, 1);
-                       lua_pushnumber (L, metric_res->metric->required_score);
+                       lua_pushnumber (L, metric_res->metric->actions[METRIC_ACTION_REJECT].score);
                        lua_rawseti (L, -2, 2);
-                       lua_pushnumber (L, metric_res->metric->reject_score);
+                       lua_pushnumber (L, metric_res->metric->actions[METRIC_ACTION_REJECT].score);
                        lua_rawseti (L, -2, 3);
                }
                else {
@@ -1578,7 +1578,8 @@ lua_task_get_metric_action (lua_State *L)
 
        if (task && metric_name) {
                if ((metric_res = g_hash_table_lookup (task->results, metric_name)) != NULL) {
-                       action = check_metric_action (metric_res->score, metric_res->metric->required_score, metric_res->metric);
+                       action = check_metric_action (metric_res->score,
+                                       metric_res->metric->actions[METRIC_ACTION_REJECT].score, metric_res->metric);
                        lua_pushstring (L, str_action_metric (action));
                }
                else {
index bb66f29d44ce3ddffbfc918ee82ae5be002876ef..8b16dca7f5899a28423ff56e66d9e7e1994c7c27 100644 (file)
@@ -113,6 +113,8 @@ str_action_metric_spamc (enum rspamd_metric_action action)
                return "greylist";
        case METRIC_ACTION_NOACTION:
                return "no action";
+       case METRIC_ACTION_MAX:
+               return "invalid max action";
        }
 
        return "unknown action";
@@ -1210,15 +1212,15 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
        }
        if (metric_name == NULL || metric_value == NULL) {
                m = g_hash_table_lookup (task->cfg->metrics, DEFAULT_METRIC);
-               default_required_score = m->required_score;
+               default_required_score = m->actions[METRIC_ACTION_REJECT].score;
                default_score = 0;
                if (metric_res != NULL && !check_metric_settings (metric_res, &ms, &rs)) {
-                       ms = m->required_score;
-                       rs = m->reject_score;
+                       ms = m->actions[METRIC_ACTION_REJECT].score;
+                       rs = m->actions[METRIC_ACTION_REJECT].score;
                }
                else if (metric_res == NULL) {
-                       ms = m->required_score;
-                       rs = m->reject_score;
+                       ms = m->actions[METRIC_ACTION_REJECT].score;
+                       rs = m->actions[METRIC_ACTION_REJECT].score;
                }
 
                if (!task->is_json) {
@@ -1232,24 +1234,24 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
                if (!task->is_skipped) {
                        cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
                                        cd->log_size - cd->log_offset,
-                                       "(%s: F (no action): [0.00/%.2f/%.2f] [", "default", ms, rs);
+                                       "(%s: F (no action): [0.00/%.2f] [", "default", ms);
                }
                else {
                        cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
-                                       cd->log_size - cd->log_offset, "(%s: S: [0.00/%.2f/%.2f] [",
-                                       "default", ms, rs);
+                                       cd->log_size - cd->log_offset, "(%s: S: [0.00/%.2f] [",
+                                       "default", ms);
                }
        }
        else {
                /* XXX: dirty hack */
                if (strcmp (metric_res->metric->name, DEFAULT_METRIC) == 0) {
-                       default_required_score = metric_res->metric->required_score;
+                       default_required_score = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
                        default_score = metric_res->score;
                }
 
                if (!check_metric_settings (metric_res, &ms, &rs)) {
-                       ms = metric_res->metric->required_score;
-                       rs = metric_res->metric->reject_score;
+                       ms = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
+                       rs = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
                }
                if (!check_metric_action_settings (task, metric_res,
                                metric_res->score, &action)) {
@@ -1273,15 +1275,15 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
 
                        cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
                                        cd->log_size - cd->log_offset,
-                                       "(%s: %c (%s): [%.2f/%.2f/%.2f] [", (gchar *) metric_name,
+                                       "(%s: %c (%s): [%.2f/%.2f] [", (gchar *) metric_name,
                                        is_spam ? 'T' : 'F', str_action_metric (action),
-                                       metric_res->score, ms, rs);
+                                       metric_res->score, ms);
                }
                else {
                        cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
                                        cd->log_size - cd->log_offset,
-                                       "(%s: %c (default): [%.2f/%.2f/%.2f] [",
-                                       (gchar *) metric_name, 'S', metric_res->score, ms, rs);
+                                       "(%s: %c (default): [%.2f/%.2f] [",
+                                       (gchar *) metric_name, 'S', metric_res->score, ms);
 
                }
        }
index 4206a6a8b9ba3e7ed778c6d85fa16e4fd9b42f76..fb9fe2e0c830011d6b7a318e5c03ae095f8082c4 100644 (file)
@@ -127,8 +127,9 @@ rspamd_roll_history_update (struct roll_history *history, struct worker_task *ta
        }
        else {
                row->score = metric_res->score;
-               row->required_score = metric_res->metric->required_score;
-               row->action = check_metric_action (metric_res->score, metric_res->metric->required_score, metric_res->metric);
+               row->required_score = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
+               row->action = check_metric_action (metric_res->score,
+                               metric_res->metric->actions[METRIC_ACTION_REJECT].score, metric_res->metric);
                cbdata.pos = row->symbols;
                cbdata.remain = sizeof (row->symbols);
                g_hash_table_foreach (metric_res->symbols, roll_history_symbols_callback, &cbdata);
index 302d7433b1c406183a534db37d25403332f67f4e..13e1617ce5c5f97d8637caa0c4df51974fce36d8 100644 (file)
@@ -146,8 +146,8 @@ smtp_metric_callback (gpointer key, gpointer value, gpointer ud)
        task = cd->session->task;
 
        if (!check_metric_settings (metric_res, &ms, &rs)) {
-               ms = metric_res->metric->required_score;
-               rs = metric_res->metric->reject_score;
+               ms = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
+               rs = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
        }
        if (! check_metric_action_settings (task, metric_res, metric_res->score, &action)) {
                action = check_metric_action (metric_res->score, ms, metric_res->metric);
index eb9cf8ba818727971ae8f73a9de4ccdfae74bc89..0a9542ddd2bd70e524d2c8ca2a9a3e70184a022a 100644 (file)
@@ -364,9 +364,11 @@ http_scan_task_free (gpointer arg)
                                        "\"required_score\":%.2f,"
                                        "\"action\":\"%s\","
                                        "\"symbols\":[",
-                                       mres->score >= mres->metric->required_score ? "true" : "false",
-                                       cbdata->task->is_skipped ? "true" : "false", mres->score, mres->metric->required_score,
-                                       str_action_metric (check_metric_action (mres->score, mres->metric->required_score, mres->metric)));
+                                       mres->score >= mres->metric->actions[METRIC_ACTION_REJECT].score ? "true" : "false",
+                                       cbdata->task->is_skipped ? "true" : "false", mres->score,
+                                       mres->metric->actions[METRIC_ACTION_REJECT].score,
+                                       str_action_metric (
+                                                       check_metric_action (mres->score, mres->metric->actions[METRIC_ACTION_REJECT].score, mres->metric)));
                        /* Iterate all symbols */
                        g_hash_table_foreach (mres->symbols, http_scan_metric_symbols_callback, cbdata);
                        evbuffer_add (evb, "]}" CRLF, 4);
@@ -670,31 +672,15 @@ http_set_metric_action (struct config_file *cfg,
                json_t *jv, struct metric *metric, enum rspamd_metric_action act)
 {
        gdouble                                                                  actval;
-       GList                                                                   *cur;
-       struct metric_action                                    *act_found;
 
        if (!json_is_number (jv)) {
                msg_err ("json element data error");
                return FALSE;
        }
        actval = json_number_value (jv);
-       if (metric->action == act && metric->required_score != actval) {
+       if (metric->actions[act].score != actval) {
                return add_dynamic_action (cfg, DEFAULT_METRIC, act, actval);
        }
-
-       /* Try to search in all metrics */
-       /* XXX: clarify this code, currently it looks like a crap */
-       cur = metric->actions;
-       while (cur) {
-               act_found = cur->data;
-               if (act_found->action == act) {
-                       if (act_found->score != actval) {
-                               return add_dynamic_action (cfg, DEFAULT_METRIC, act, actval);
-                       }
-               }
-               cur = g_list_next (cur);
-       }
-
        return TRUE;
 }
 
@@ -838,8 +824,9 @@ http_handle_actions (struct evhttp_request *req, gpointer arg)
        struct rspamd_webui_worker_ctx                  *ctx = arg;
        struct evbuffer                                                 *evb;
        struct metric                                                   *metric;
-       GList                                                                   *cur;
        struct metric_action                                    *act;
+       gboolean                                                                 start = TRUE;
+       gint                                                                     i;
 
        if (!http_check_password (ctx, req)) {
                return;
@@ -858,15 +845,16 @@ http_handle_actions (struct evhttp_request *req, gpointer arg)
        /* Get actions for default metric */
        metric = g_hash_table_lookup (ctx->cfg->metrics, DEFAULT_METRIC);
        if (metric != NULL) {
-
-               cur = metric->actions;
-               while (cur) {
-                       act = cur->data;
-                       cur = g_list_next (cur);
-                       evbuffer_add_printf (evb, "{\"action\":\"%s\",\"value\":%.2f},", str_action_metric (act->action), act->score);
+               for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
+                       act = &metric->actions[i];
+                       if (act->score > 0) {
+                               evbuffer_add_printf (evb, "%s{\"action\":\"%s\",\"value\":%.2f}",
+                                               (start ? "" : ","), str_action_metric (act->action), act->score);
+                               if (start) {
+                                       start = FALSE;
+                               }
+                       }
                }
-               /* Print default action */
-               evbuffer_add_printf (evb, "{\"action\":\"%s\",\"value\":%.2f}", str_action_metric (metric->action), metric->required_score);
        }
 
        evbuffer_add (evb, "]" CRLF, 3);