aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver
diff options
context:
space:
mode:
Diffstat (limited to 'src/libserver')
-rw-r--r--src/libserver/cfg_file.h48
-rw-r--r--src/libserver/cfg_rcl.c25
-rw-r--r--src/libserver/cfg_utils.c59
-rw-r--r--src/libserver/dynamic_cfg.c19
-rw-r--r--src/libserver/task.h10
5 files changed, 135 insertions, 26 deletions
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),