From: Vsevolod Stakhov Date: Thu, 3 Dec 2015 12:13:10 +0000 (+0000) Subject: Add ability to ignore certain symbols in metric when validating cache X-Git-Tag: 1.1.0~426 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=5936aed13e97ac84e44e38a00dcfde16ec9fd173;p=rspamd.git Add ability to ignore certain symbols in metric when validating cache --- diff --git a/src/libmime/filter.c b/src/libmime/filter.c index ab8833a8a..48115375f 100644 --- a/src/libmime/filter.c +++ b/src/libmime/filter.c @@ -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 diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index 6263705ac..05946a79e 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -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; }; diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index e8e0818ca..bbe241cb1 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -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, diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index 9447eaf32..042658f8a 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -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); diff --git a/src/libserver/symbols_cache.c b/src/libserver/symbols_cache.c index 94a3302e8..e64c35e2a 100644 --- a/src/libserver/symbols_cache.c +++ b/src/libserver/symbols_cache.c @@ -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