diff options
-rw-r--r-- | src/libserver/cfg_file.h | 6 | ||||
-rw-r--r-- | src/libserver/cfg_rcl.c | 101 | ||||
-rw-r--r-- | src/libserver/cfg_utils.c | 113 | ||||
-rw-r--r-- | src/lua/lua_config.c | 26 | ||||
-rw-r--r-- | src/plugins/regexp.c | 15 |
5 files changed, 140 insertions, 121 deletions
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index 373daf744..88b5b4538 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -101,6 +101,7 @@ struct rspamd_symbol_def { gchar *description; gdouble *weight_ptr; gdouble score; + guint priority; struct rspamd_symbols_group *gr; GList *groups; guint flags; @@ -494,6 +495,7 @@ gboolean rspamd_init_filters (struct rspamd_config *cfg, bool reconfig); /** * Add new symbol to the metric + * @param cfg * @param metric metric's name (or NULL for the default metric) * @param symbol symbol's name * @param score symbol's score @@ -501,12 +503,14 @@ gboolean rspamd_init_filters (struct rspamd_config *cfg, bool reconfig); * @param group optional group name * @param one_shot TRUE if symbol can add its score once * @param rewrite_existing TRUE if we need to rewrite the existing symbol + * @param priority use the following priority for a symbol * @return TRUE if symbol has been inserted or FALSE if `rewrite_existing` is not enabled and symbol already exists */ gboolean rspamd_config_add_metric_symbol (struct rspamd_config *cfg, const gchar *metric, const gchar *symbol, gdouble score, const gchar *description, - const gchar *group, gboolean one_shot, gboolean rewrite_existing); + const gchar *group, guint flags, + guint priority); /** * Checks if a specified C or lua module is enabled or disabled in the config. diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index 7b6d1180a..c21c8321d 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -316,67 +316,52 @@ rspamd_rcl_symbol_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, struct rspamd_rcl_section *section, GError **err) { struct rspamd_rcl_symbol_data *sd = ud; - struct rspamd_symbol_def *sym_def; struct metric *metric; struct rspamd_config *cfg; const ucl_object_t *elt; - GList *metric_list; + const gchar *description = NULL; + gdouble score = 0.0; + guint priority = 1, flags = 0; g_assert (key != NULL); metric = sd->metric; g_assert (metric != NULL); cfg = sd->cfg; - sym_def = g_hash_table_lookup (metric->symbols, key); - - if (sym_def == NULL) { - sym_def = rspamd_mempool_alloc0 (pool, sizeof (*sym_def)); - sym_def->name = rspamd_mempool_strdup (pool, key); - sym_def->gr = sd->gr; - sym_def->weight_ptr = rspamd_mempool_alloc (pool, sizeof (gdouble)); - - g_hash_table_insert (metric->symbols, sym_def->name, sym_def); - - if (sd->gr) { - g_hash_table_insert (sd->gr->symbols, sym_def->name, sym_def); - } - if ((metric_list = - g_hash_table_lookup (cfg->metrics_symbols, sym_def->name)) == NULL) { - metric_list = g_list_prepend (NULL, metric); - rspamd_mempool_add_destructor (cfg->cfg_pool, - (rspamd_mempool_destruct_t)g_list_free, - metric_list); - g_hash_table_insert (cfg->metrics_symbols, sym_def->name, metric_list); - } - else { - if (!g_list_find (metric_list, metric)) { - metric_list = g_list_append (metric_list, metric); - } - } - } - else { - msg_warn_config ("redefining symbol '%s' in metric '%s'", key, metric->name); - } - if ((elt = ucl_object_lookup (obj, "one_shot")) != NULL) { if (ucl_object_toboolean (elt)) { - sym_def->flags |= RSPAMD_SYMBOL_FLAG_ONESHOT; + flags |= RSPAMD_SYMBOL_FLAG_ONESHOT; } } if ((elt = ucl_object_lookup (obj, "ignore")) != NULL) { if (ucl_object_toboolean (elt)) { - sym_def->flags |= RSPAMD_SYMBOL_FLAG_IGNORE; + flags |= RSPAMD_SYMBOL_FLAG_IGNORE; } } - if (!rspamd_rcl_section_parse_defaults (section, pool, obj, - sym_def, err)) { - return FALSE; + elt = ucl_object_lookup_any (obj, "score", "weight", NULL); + if (elt) { + score = ucl_object_todouble (elt); + } + + elt = ucl_object_lookup (obj, "priority"); + if (elt) { + priority = ucl_object_toint (elt); + } + + elt = ucl_object_lookup (obj, "description"); + if (elt) { + description = ucl_object_tostring (elt); } - if (ucl_object_lookup_any (obj, "score", "weight", NULL) != NULL) { - *sym_def->weight_ptr = sym_def->score; + if (sd->gr) { + rspamd_config_add_metric_symbol (cfg, metric->name, key, score, + description, sd->gr->name, flags, priority); + } + else { + rspamd_config_add_metric_symbol (cfg, metric->name, key, score, + description, NULL, flags, priority); } return TRUE; @@ -1790,24 +1775,6 @@ rspamd_rcl_config_init (struct rspamd_config *cfg) TRUE, sub->doc_ref, "Symbols settings"); - rspamd_rcl_add_default_handler (ssub, - "description", - rspamd_rcl_parse_struct_string, - G_STRUCT_OFFSET (struct rspamd_symbol_def, description), - 0, - "Symbol's description"); - rspamd_rcl_add_default_handler (ssub, - "score", - rspamd_rcl_parse_struct_double, - G_STRUCT_OFFSET (struct rspamd_symbol_def, score), - 0, - "Symbol's score"); - rspamd_rcl_add_default_handler (ssub, - "weight", - rspamd_rcl_parse_struct_double, - G_STRUCT_OFFSET (struct rspamd_symbol_def, score), - 0, - "Symbol's score"); /* Actions part */ ssub = rspamd_rcl_add_section_doc (&sub->subsections, @@ -1856,24 +1823,6 @@ rspamd_rcl_config_init (struct rspamd_config *cfg) TRUE, ssub->doc_ref, "Symbols settings"); - rspamd_rcl_add_default_handler (sssub, - "description", - rspamd_rcl_parse_struct_string, - G_STRUCT_OFFSET (struct rspamd_symbol_def, description), - 0, - "Description of a symbol"); - rspamd_rcl_add_default_handler (sssub, - "score", - rspamd_rcl_parse_struct_double, - G_STRUCT_OFFSET (struct rspamd_symbol_def, score), - 0, - "Symbol's score"); - rspamd_rcl_add_default_handler (sssub, - "weight", - rspamd_rcl_parse_struct_double, - G_STRUCT_OFFSET (struct rspamd_symbol_def, score), - 0, - "Symbol's score"); /** * Worker section diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index a857571c4..a9ccb4231 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -1298,39 +1298,17 @@ rspamd_init_filters (struct rspamd_config *cfg, bool reconfig) return rspamd_init_lua_filters (cfg); } -gboolean -rspamd_config_add_metric_symbol (struct rspamd_config *cfg, - const gchar *metric_name, const gchar *symbol, +static void +rspamd_config_new_metric_symbol (struct rspamd_config *cfg, + struct metric *metric, const gchar *symbol, gdouble score, const gchar *description, const gchar *group, - gboolean one_shot, gboolean rewrite_existing) + guint flags, guint priority) { struct rspamd_symbols_group *sym_group; struct rspamd_symbol_def *sym_def; GList *metric_list; - struct metric *metric; gdouble *score_ptr; - g_assert (cfg != NULL); - g_assert (symbol != NULL); - - if (metric_name == NULL) { - metric_name = DEFAULT_METRIC; - } - - metric = g_hash_table_lookup (cfg->metrics, metric_name); - - if (metric == NULL) { - msg_err_config ("metric %s has not been found", metric_name); - return FALSE; - } - - if (g_hash_table_lookup (cfg->metrics_symbols, symbol) != NULL && - !rewrite_existing) { - msg_debug_config ("symbol %s has been already registered, do not override", - symbol); - return FALSE; - } - sym_def = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_symbol_def)); score_ptr = rspamd_mempool_alloc (cfg->cfg_pool, sizeof (gdouble)); @@ -1339,10 +1317,8 @@ 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); - - if (one_shot) { - sym_def->flags |= RSPAMD_SYMBOL_FLAG_ONESHOT; - } + sym_def->priority = priority; + sym_def->flags = flags; if (description) { sym_def->description = rspamd_mempool_strdup (cfg->cfg_pool, description); @@ -1354,11 +1330,11 @@ rspamd_config_add_metric_symbol (struct rspamd_config *cfg, g_hash_table_insert (metric->symbols, sym_def->name, sym_def); if ((metric_list = - g_hash_table_lookup (cfg->metrics_symbols, sym_def->name)) == NULL) { + g_hash_table_lookup (cfg->metrics_symbols, sym_def->name)) == NULL) { metric_list = g_list_prepend (NULL, metric); rspamd_mempool_add_destructor (cfg->cfg_pool, - (rspamd_mempool_destruct_t)g_list_free, - metric_list); + (rspamd_mempool_destruct_t)g_list_free, + metric_list); g_hash_table_insert (cfg->metrics_symbols, sym_def->name, metric_list); } else { @@ -1381,6 +1357,77 @@ rspamd_config_add_metric_symbol (struct rspamd_config *cfg, sym_def->gr = sym_group; g_hash_table_insert (sym_group->symbols, sym_def->name, sym_def); +} + + +gboolean +rspamd_config_add_metric_symbol (struct rspamd_config *cfg, + const gchar *metric_name, const gchar *symbol, + gdouble score, const gchar *description, const gchar *group, + guint flags, guint priority) +{ + struct rspamd_symbol_def *sym_def; + struct metric *metric; + + g_assert (cfg != NULL); + g_assert (symbol != NULL); + + if (metric_name == NULL) { + metric_name = DEFAULT_METRIC; + } + + metric = g_hash_table_lookup (cfg->metrics, metric_name); + + if (metric == NULL) { + msg_err_config ("metric %s has not been found", metric_name); + return FALSE; + } + + sym_def = g_hash_table_lookup (cfg->metrics_symbols, symbol); + + if (sym_def != NULL) { + if (sym_def->priority >= priority) { + msg_info_config ("symbol %s has been already registered with" + "priority %ud, do not override (new priority: %ud)", + symbol, + sym_def->priority, + priority); + /* But we can still add description */ + if (!sym_def->description && description) { + sym_def->description = rspamd_mempool_strdup (cfg->cfg_pool, + description); + } + + return FALSE; + } + else { + msg_info_config ("symbol %s has been already registered with" + "priority %ud, override it with new priority: %ud, " + "old score: %.2f, new score: %.2f", + symbol, + sym_def->priority, + priority, + sym_def->score, + score); + + *sym_def->weight_ptr = score; + sym_def->score = score; + + sym_def->flags = flags; + + if (description) { + sym_def->description = rspamd_mempool_strdup (cfg->cfg_pool, + description); + } + + sym_def->priority = priority; + + return TRUE; + } + } + + rspamd_config_new_metric_symbol (cfg, metric, symbol, score, description, + group, flags, priority); return TRUE; } diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c index 4421bf179..59ca08864 100644 --- a/src/lua/lua_config.c +++ b/src/lua/lua_config.c @@ -1282,15 +1282,17 @@ lua_config_set_metric_symbol (lua_State * L) struct metric *metric; gboolean one_shot = FALSE; GError *err = NULL; + gdouble priority = 0.0; + guint flags = 0; if (cfg) { if (lua_type (L, 2) == LUA_TTABLE) { if (!rspamd_lua_parse_table_arguments (L, 2, &err, "*name=S;score=N;description=S;" - "group=S;one_shot=B;metric=S", + "group=S;one_shot=B;metric=S;priority=N", &name, &weight, &description, - &group, &one_shot, &metric_name)) { + &group, &one_shot, &metric_name, &priority)) { msg_err_config ("bad arguments: %e", err); g_error_free (err); @@ -1320,13 +1322,16 @@ lua_config_set_metric_symbol (lua_State * L) } metric = g_hash_table_lookup (cfg->metrics, metric_name); + if (one_shot) { + flags |= RSPAMD_SYMBOL_FLAG_ONESHOT; + } if (metric == NULL) { msg_err_config ("metric named %s is not defined", metric_name); } else if (name != NULL && weight != 0) { rspamd_config_add_metric_symbol (cfg, metric_name, name, - weight, description, group, one_shot, FALSE); + weight, description, group, flags, (guint)priority); } } @@ -1410,7 +1415,7 @@ lua_config_newindex (lua_State *L) gint type = SYMBOL_TYPE_NORMAL, priority = 0, idx; gdouble weight = 1.0, score; const char *type_str, *group = NULL, *description = NULL; - gboolean one_shot = FALSE; + guint flags = 0; /* * Table can have the following attributes: @@ -1533,16 +1538,18 @@ lua_config_newindex (lua_State *L) lua_gettable (L, -2); if (lua_type (L, -1) == LUA_TBOOLEAN) { - one_shot = lua_toboolean (L, -1); + if (lua_toboolean (L, -1)) { + flags |= RSPAMD_SYMBOL_FLAG_ONESHOT; + } } lua_pop (L, 1); /* - * Do not override the existing symbols, since we are - * having default values here + * Do not override the existing symbols (using zero priority), + * since we are defining default values here */ rspamd_config_add_metric_symbol (cfg, NULL, name, score, - description, group, one_shot, FALSE); + description, group, flags, 0); } else { lua_pop (L, 1); @@ -1553,6 +1560,9 @@ lua_config_newindex (lua_State *L) lua_pop (L, 1); } } + else { + return luaL_error (L, "invalid arguments"); + } return 0; } diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c index 6458e1577..d80b11f1f 100644 --- a/src/plugins/regexp.c +++ b/src/plugins/regexp.c @@ -184,7 +184,8 @@ regexp_module_config (struct rspamd_config *cfg) const gchar *description = NULL, *group = NULL, *metric = DEFAULT_METRIC; gdouble score = 0.0; - gboolean one_shot = FALSE, is_lua = FALSE, valid_expression = TRUE; + guint flags = 0, priority = 0; + gboolean is_lua = FALSE, valid_expression = TRUE; /* We have some lua table, extract its arguments */ elt = ucl_object_lookup (value, "callback"); @@ -269,11 +270,19 @@ regexp_module_config (struct rspamd_config *cfg) elt = ucl_object_lookup (value, "one_shot"); if (elt) { - one_shot = ucl_object_toboolean (elt); + if (ucl_object_toboolean (elt)) { + flags |= RSPAMD_SYMBOL_FLAG_ONESHOT; + } + } + + elt = ucl_object_lookup (value, "priority"); + + if (elt) { + priority = ucl_object_toint (elt); } rspamd_config_add_metric_symbol (cfg, metric, cur_item->symbol, - score, description, group, one_shot, FALSE); + score, description, group, flags, priority); } } else { |