]> source.dussan.org Git - rspamd.git/commitdiff
Add ability to ignore certain symbols in metric when validating cache
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 3 Dec 2015 12:13:10 +0000 (12:13 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 3 Dec 2015 12:13:10 +0000 (12:13 +0000)
src/libmime/filter.c
src/libserver/cfg_file.h
src/libserver/cfg_rcl.c
src/libserver/cfg_utils.c
src/libserver/symbols_cache.c

index ab8833a8ae80104689d22bce3e4f4d2162561dcc..48115375f6207f1a6f6c93141ff6f54cf04293ca 100644 (file)
@@ -140,7 +140,7 @@ insert_metric_result (struct rspamd_task *task,
 
        /* Add metric score */
        if ((s = g_hash_table_lookup (metric_res->symbols, symbol)) != NULL) {
-               if (sdef && sdef->one_shot) {
+               if (sdef && (sdef->flags & RSPAMD_SYMBOL_FLAG_ONESHOT)) {
                        /*
                         * For one shot symbols we do not need to add them again, so
                         * we just force single behaviour here
index 6263705ac94cc74499455d73bad858cf854c07f8..05946a79e02c287c6c9f9daaa78ea430af087eba 100644 (file)
@@ -89,6 +89,9 @@ struct rspamd_symbols_group {
        gboolean one_shot;
 };
 
+#define RSPAMD_SYMBOL_FLAG_ONESHOT (1 << 0)
+#define RSPAMD_SYMBOL_FLAG_IGNORE (1 << 1)
+
 /**
  * Symbol definition
  */
@@ -99,7 +102,7 @@ struct rspamd_symbol_def {
        gdouble score;
        struct rspamd_symbols_group *gr;
        GList *groups;
-       gboolean one_shot;
+       guint flags;
 };
 
 
index e8e0818ca4501fabf5eff225e5cfc0a3a3ec5a2a..bbe241cb120d35884d77fb753169d552af9eb146 100644 (file)
@@ -321,6 +321,7 @@ rspamd_rcl_symbol_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
        struct rspamd_symbol_def *sym_def;
        struct metric *metric;
        struct rspamd_config *cfg;
+       const ucl_object_t *elt;
        GList *metric_list;
 
        g_assert (key != NULL);
@@ -359,6 +360,18 @@ rspamd_rcl_symbol_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
                msg_warn_config ("redefining symbol '%s' in metric '%s'", key, metric->name);
        }
 
+       if ((elt = ucl_object_find_key (obj, "one_shot")) != NULL) {
+               if (ucl_object_toboolean (elt)) {
+                       sym_def->flags |= RSPAMD_SYMBOL_FLAG_ONESHOT;
+               }
+       }
+
+       if ((elt = ucl_object_find_key (obj, "ignore")) != NULL) {
+               if (ucl_object_toboolean (elt)) {
+                       sym_def->flags |= RSPAMD_SYMBOL_FLAG_IGNORE;
+               }
+       }
+
        if (!rspamd_rcl_section_parse_defaults (section, pool, obj,
                        sym_def, err)) {
                return FALSE;
@@ -408,11 +421,13 @@ rspamd_rcl_metric_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
                const gchar *key, gpointer ud,
                struct rspamd_rcl_section *section, GError **err)
 {
-       const ucl_object_t *val, *cur;
+       const ucl_object_t *val, *cur, *elt;
+       ucl_object_iter_t it;
        struct rspamd_config *cfg = ud;
        struct metric *metric;
        struct rspamd_rcl_section *subsection;
        struct rspamd_rcl_symbol_data sd;
+       struct rspamd_symbol_def *sym_def;
 
        g_assert (key != NULL);
 
@@ -483,6 +498,29 @@ rspamd_rcl_metric_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
                }
        }
 
+       /* Handle ignored symbols */
+       val = ucl_object_find_key (obj, "ignore");
+       if (val != NULL && ucl_object_type (val) == UCL_ARRAY) {
+               LL_FOREACH (val, cur) {
+                       it = NULL;
+
+                       while ((elt = ucl_iterate_object (cur, &it, true)) != NULL) {
+                               if (ucl_object_type (elt) == UCL_STRING) {
+                                       sym_def = g_hash_table_lookup (metric->symbols,
+                                                       ucl_object_tostring (elt));
+
+                                       if (sym_def != NULL) {
+                                               sym_def->flags |= RSPAMD_SYMBOL_FLAG_IGNORE;
+                                       }
+                                       else {
+                                               msg_warn ("cannot find symbol %s to set ignore flag",
+                                                               ucl_object_tostring (elt));
+                                       }
+                               }
+                       }
+               }
+       }
+
        return TRUE;
 }
 
@@ -1515,11 +1553,6 @@ rspamd_rcl_config_init (void)
                        rspamd_rcl_parse_struct_string,
                        G_STRUCT_OFFSET (struct rspamd_symbol_def, description),
                        0);
-       rspamd_rcl_add_default_handler (ssub,
-                       "one_shot",
-                       rspamd_rcl_parse_struct_boolean,
-                       G_STRUCT_OFFSET (struct rspamd_symbol_def, one_shot),
-                       0);
        rspamd_rcl_add_default_handler (ssub,
                        "score",
                        rspamd_rcl_parse_struct_double,
@@ -1574,11 +1607,6 @@ rspamd_rcl_config_init (void)
                        rspamd_rcl_parse_struct_string,
                        G_STRUCT_OFFSET (struct rspamd_symbol_def, description),
                        0);
-       rspamd_rcl_add_default_handler (sssub,
-                       "one_shot",
-                       rspamd_rcl_parse_struct_boolean,
-                       G_STRUCT_OFFSET (struct rspamd_symbol_def, one_shot),
-                       0);
        rspamd_rcl_add_default_handler (sssub,
                        "score",
                        rspamd_rcl_parse_struct_double,
index 9447eaf32fbe672017eb8d2b01fb6af0795e5b31..042658f8a3b8b7b13d1856810e98fcef26c72bb1 100644 (file)
@@ -1246,7 +1246,10 @@ rspamd_config_add_metric_symbol (struct rspamd_config *cfg,
        sym_def->score = score;
        sym_def->weight_ptr = score_ptr;
        sym_def->name = rspamd_mempool_strdup (cfg->cfg_pool, symbol);
-       sym_def->one_shot = one_shot;
+
+       if (one_shot) {
+               sym_def->flags |= RSPAMD_SYMBOL_FLAG_ONESHOT;
+       }
 
        if (description) {
                sym_def->description = rspamd_mempool_strdup (cfg->cfg_pool, description);
index 94a3302e8cd0826f0f31efc8f3ed06a03285496a..e64c35e2a3e26410686ed66b96220a21a46b0baf 100644 (file)
@@ -848,7 +848,12 @@ rspamd_symbols_cache_validate (struct symbols_cache *cache,
        gboolean strict)
 {
        struct cache_item *item;
-       GList *cur, *metric_symbols;
+       GHashTableIter it;
+       GList *cur;
+       gpointer k, v;
+       struct rspamd_symbol_def *sym_def;
+       struct metric *metric;
+       gboolean ignore_symbol = FALSE, ret = TRUE;
 
        if (cache == NULL) {
                msg_err_cache ("empty cache is invalid");
@@ -866,28 +871,42 @@ rspamd_symbols_cache_validate (struct symbols_cache *cache,
                        rspamd_symbols_cache_validate_cb,
                        cache);
        /* Now check each metric item and find corresponding symbol in a cache */
-       metric_symbols = g_hash_table_get_keys (cfg->metrics_symbols);
-       cur = metric_symbols;
-       while (cur) {
-               item = g_hash_table_lookup (cache->items_by_symbol, cur->data);
-
-               if (item == NULL) {
-                       msg_warn_cache (
-                               "symbol '%s' has its score defined but there is no "
-                               "corresponding rule registered",
-                               cur->data);
-                       if (strict) {
-                               g_list_free (metric_symbols);
-                               return FALSE;
+       g_hash_table_iter_init (&it, cfg->metrics_symbols);
+
+       while (g_hash_table_iter_next (&it, &k, &v)) {
+               ignore_symbol = FALSE;
+               cur = v;
+
+               while (cur) {
+                       metric = cur->data;
+                       sym_def = g_hash_table_lookup (metric->symbols, k);
+
+                       if (sym_def && (sym_def->flags & RSPAMD_SYMBOL_FLAG_IGNORE)) {
+                               ignore_symbol = TRUE;
+                               break;
+                       }
+
+                       cur = g_list_next (cur);
+               }
+
+               if (!ignore_symbol) {
+                       item = g_hash_table_lookup (cache->items_by_symbol, k);
+
+                       if (item == NULL) {
+                               msg_warn_cache (
+                                               "symbol '%s' has its score defined but there is no "
+                                                               "corresponding rule registered",
+                                               k);
+                               if (strict) {
+                                       ret = FALSE;
+                               }
                        }
                }
-               cur = g_list_next (cur);
        }
-       g_list_free (metric_symbols);
 
        post_cache_init (cache);
 
-       return TRUE;
+       return ret;
 }
 
 static gboolean