diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-02-28 22:58:20 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-02-28 22:58:20 +0000 |
commit | 0c9184dcbde07a7f9cf04835ce10b45891f4c628 (patch) | |
tree | 8241c348605aa072b1e8e16d7cf0efdaa8131ab1 /src | |
parent | f309a84d17bce0456f369b693ae270288e72892f (diff) | |
download | rspamd-0c9184dcbde07a7f9cf04835ce10b45891f4c628.tar.gz rspamd-0c9184dcbde07a7f9cf04835ce10b45891f4c628.zip |
[Feature] Add priorities for actions
Add dedicated API to modify action limits with priorities from different
configuration place. This follows the logic of symbols' priorities and
will be used for dynamic rules and override definitions.
Diffstat (limited to 'src')
-rw-r--r-- | src/libmime/filter.h | 20 | ||||
-rw-r--r-- | src/libserver/cfg_file.h | 48 | ||||
-rw-r--r-- | src/libserver/cfg_rcl.c | 25 | ||||
-rw-r--r-- | src/libserver/cfg_utils.c | 59 | ||||
-rw-r--r-- | src/libserver/dynamic_cfg.c | 19 | ||||
-rw-r--r-- | src/libserver/task.h | 10 |
6 files changed, 135 insertions, 46 deletions
diff --git a/src/libmime/filter.h b/src/libmime/filter.h index 51a1d4304..bacbede06 100644 --- a/src/libmime/filter.h +++ b/src/libmime/filter.h @@ -24,26 +24,6 @@ struct symbol { struct rspamd_symbol_def *def; /**< symbol configuration */ }; -struct metric_action { - enum rspamd_metric_action action; - gdouble score; -}; - -/** - * Common definition of metric - */ -struct metric { - const gchar *name; /**< name of metric */ - gchar *func_name; /**< name of consolidation function */ - gboolean accept_unknown_symbols; /**< if true unknown symbols are registered here */ - gdouble unknown_weight; /**< weight of unknown symbols */ - gdouble grow_factor; /**< grow factor for metric */ - GHashTable *symbols; /**< weights of symbols in metric */ - gchar *subject; /**< subject rewrite string */ - GHashTable * groups; /**< groups of symbols */ - struct metric_action actions[METRIC_ACTION_MAX]; /**< all actions of the metric */ -}; - /** * Result of metric processing */ diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index 2ed82930b..8a59f8c74 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -221,6 +221,37 @@ struct rspamd_log_format { struct rspamd_log_format *prev, *next; }; +enum rspamd_metric_action { + METRIC_ACTION_REJECT = 0, + METRIC_ACTION_SOFT_REJECT, + METRIC_ACTION_REWRITE_SUBJECT, + METRIC_ACTION_ADD_HEADER, + METRIC_ACTION_GREYLIST, + METRIC_ACTION_NOACTION, + METRIC_ACTION_MAX +}; + +struct metric_action { + enum rspamd_metric_action action; + gdouble score; + guint priority; +}; + +/** + * Common definition of metric + */ +struct metric { + const gchar *name; /**< name of metric */ + gchar *func_name; /**< name of consolidation function */ + gboolean accept_unknown_symbols; /**< if true unknown symbols are registered here */ + gdouble unknown_weight; /**< weight of unknown symbols */ + gdouble grow_factor; /**< grow factor for metric */ + GHashTable *symbols; /**< weights of symbols in metric */ + gchar *subject; /**< subject rewrite string */ + GHashTable * groups; /**< groups of symbols */ + struct metric_action actions[METRIC_ACTION_MAX]; /**< all actions of the metric */ +}; + /** * Structure that stores all config data */ @@ -506,7 +537,7 @@ gboolean rspamd_init_filters (struct rspamd_config *cfg, bool reconfig); * @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 + * @return TRUE if symbol has been inserted or FALSE if symbol already exists with higher priority */ gboolean rspamd_config_add_metric_symbol (struct rspamd_config *cfg, const gchar *metric, @@ -515,6 +546,21 @@ gboolean rspamd_config_add_metric_symbol (struct rspamd_config *cfg, guint priority); /** + * Sets action score for a specified metric with the specified priority + * @param cfg config file + * @param metric metric name (or NULL for default metric) + * @param action_name symbolic name of action + * @param score score limit + * @param priority priority for action + * @return TRUE if symbol has been inserted or FALSE if action already exists with higher priority + */ +gboolean rspamd_config_set_action_score (struct rspamd_config *cfg, + const gchar *metric, + const gchar *action_name, + gdouble score, + guint priority); + +/** * Checks if a specified C or lua module is enabled or disabled in the config. * The logic of check is the following: * diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index b5f5b0763..1481a3ebe 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -370,17 +370,26 @@ rspamd_rcl_symbol_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, return TRUE; } +struct metric_actions_cbdata { + struct rspamd_config *cfg; + struct metric *metric; +}; + static gboolean rspamd_rcl_actions_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, const gchar *key, gpointer ud, struct rspamd_rcl_section *section, GError **err) { gdouble action_score; - struct metric_action *action; - struct metric *metric = ud; + struct metric_actions_cbdata *cbdata = ud; gint action_value; const ucl_object_t *cur; ucl_object_iter_t it = NULL; + struct metric *metric; + struct rspamd_config *cfg; + + metric = cbdata->metric; + cfg = cbdata->cfg; while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) { if (!rspamd_action_from_str (ucl_object_key (cur), &action_value) || @@ -393,9 +402,9 @@ rspamd_rcl_actions_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, return FALSE; } else { - action = &metric->actions[action_value]; - action->action = action_value; - action->score = action_score; + rspamd_config_set_action_score (cfg, metric->name, + ucl_object_key (cur), action_score, + ucl_object_get_priority (cur)); } } @@ -414,6 +423,7 @@ rspamd_rcl_metric_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, struct rspamd_rcl_section *subsection; struct rspamd_rcl_symbol_data sd; struct rspamd_symbol_def *sym_def; + struct metric_actions_cbdata acts_cbdata; g_assert (key != NULL); @@ -442,7 +452,10 @@ rspamd_rcl_metric_handler (rspamd_mempool_t *pool, const ucl_object_t *obj, HASH_FIND_STR (section->subsections, "actions", subsection); g_assert (subsection != NULL); - if (!rspamd_rcl_process_section (subsection, metric, val, + acts_cbdata.cfg = cfg; + acts_cbdata.metric = metric; + + if (!rspamd_rcl_process_section (subsection, &acts_cbdata, val, cfg->cfg_pool, err)) { return FALSE; } diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index ea6894259..f797b3654 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -1516,3 +1516,62 @@ rspamd_config_is_module_enabled (struct rspamd_config *cfg, return TRUE; } + +gboolean +rspamd_config_set_action_score (struct rspamd_config *cfg, + const gchar *metric_name, + const gchar *action_name, + gdouble score, + guint priority) +{ + struct metric_action *act; + struct metric *metric; + gint act_num; + + g_assert (cfg != NULL); + g_assert (action_name != 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 (!rspamd_action_from_str (action_name, &act_num)) { + msg_err_config ("invalid action name", action_name); + return FALSE; + } + + g_assert (act_num > 0 && act_num < METRIC_ACTION_MAX); + + act = &metric->actions[act_num]; + + if (act->priority > priority) { + msg_info_config ("action %s has been already registered with" + "priority %ud, do not override (new priority: %ud)", + action_name, + act->priority, + priority); + return FALSE; + } + else { + msg_info_config ("action %s has been already registered with" + "priority %ud, override it with new priority: %ud, " + "old score: %.2f, new score: %.2f", + action_name, + act->priority, + priority, + act->score, + score); + + act->score = score; + act->priority = priority; + } + + return TRUE; +} diff --git a/src/libserver/dynamic_cfg.c b/src/libserver/dynamic_cfg.c index 041438698..27fec9da9 100644 --- a/src/libserver/dynamic_cfg.c +++ b/src/libserver/dynamic_cfg.c @@ -37,8 +37,9 @@ apply_dynamic_conf (const ucl_object_t *top, struct rspamd_config *cfg) const ucl_object_t *cur_elt, *cur_nm, *it_val; ucl_object_iter_t it = NULL; struct metric *real_metric; - struct metric_action *cur_action; + const gchar *name; gdouble nscore; + static const guint priority = 3; while ((cur_elt = ucl_object_iterate (top, &it, true))) { if (ucl_object_type (cur_elt) != UCL_OBJECT) { @@ -79,7 +80,7 @@ apply_dynamic_conf (const ucl_object_t *top, struct rspamd_config *cfg) */ rspamd_config_add_metric_symbol (cfg, real_metric->name, ucl_object_tostring (n), nscore, NULL, NULL, - 0, 3); + 0, priority); } else { msg_info ( @@ -102,18 +103,18 @@ apply_dynamic_conf (const ucl_object_t *top, struct rspamd_config *cfg) while ((it_val = ucl_object_iterate (cur_nm, &nit, true))) { if (ucl_object_lookup (it_val, "name") && ucl_object_lookup (it_val, "value")) { - if (!rspamd_action_from_str (ucl_object_tostring ( - ucl_object_lookup (it_val, "name")), &test_act)) { + name = ucl_object_tostring (ucl_object_lookup (it_val, "name")); + + if (!name || !rspamd_action_from_str (name, &test_act)) { msg_err ("unknown action: %s", ucl_object_tostring (ucl_object_lookup (it_val, "name"))); continue; } - cur_action = &real_metric->actions[test_act]; - cur_action->action = test_act; - cur_action->score = - ucl_object_todouble (ucl_object_lookup (it_val, - "value")); + nscore = ucl_object_todouble (ucl_object_lookup (it_val, + "value")); + rspamd_config_set_action_score (cfg, real_metric->name, + name, nscore, priority); } else { msg_info ( diff --git a/src/libserver/task.h b/src/libserver/task.h index 749f3adc2..a653b0a47 100644 --- a/src/libserver/task.h +++ b/src/libserver/task.h @@ -37,16 +37,6 @@ enum rspamd_command { CMD_OTHER }; -enum rspamd_metric_action { - METRIC_ACTION_REJECT = 0, - METRIC_ACTION_SOFT_REJECT, - METRIC_ACTION_REWRITE_SUBJECT, - METRIC_ACTION_ADD_HEADER, - METRIC_ACTION_GREYLIST, - METRIC_ACTION_NOACTION, - METRIC_ACTION_MAX -}; - enum rspamd_task_stage { RSPAMD_TASK_STAGE_CONNECT = (1 << 0), RSPAMD_TASK_STAGE_ENVELOPE = (1 << 1), |