aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-12-03 12:13:10 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-12-03 12:13:10 +0000
commit5936aed13e97ac84e44e38a00dcfde16ec9fd173 (patch)
tree29c319fc298117e56aeaf97ed1780dc4cadbe5e5 /src/libserver
parenta752628025143687ee60f6f1cf94ad483023d1db (diff)
downloadrspamd-5936aed13e97ac84e44e38a00dcfde16ec9fd173.tar.gz
rspamd-5936aed13e97ac84e44e38a00dcfde16ec9fd173.zip
Add ability to ignore certain symbols in metric when validating cache
Diffstat (limited to 'src/libserver')
-rw-r--r--src/libserver/cfg_file.h5
-rw-r--r--src/libserver/cfg_rcl.c50
-rw-r--r--src/libserver/cfg_utils.c5
-rw-r--r--src/libserver/symbols_cache.c53
4 files changed, 83 insertions, 30 deletions
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;
}
@@ -1516,11 +1554,6 @@ rspamd_rcl_config_init (void)
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,
G_STRUCT_OFFSET (struct rspamd_symbol_def, score),
@@ -1575,11 +1608,6 @@ rspamd_rcl_config_init (void)
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,
G_STRUCT_OFFSET (struct rspamd_symbol_def, score),
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