diff options
-rw-r--r-- | src/controller.c | 17 | ||||
-rw-r--r-- | src/libmime/filter.c | 65 | ||||
-rw-r--r-- | src/libmime/filter.h | 54 | ||||
-rw-r--r-- | src/libmime/filter_private.h | 31 | ||||
-rw-r--r-- | src/libmime/message.c | 27 | ||||
-rw-r--r-- | src/libserver/cfg_file.h | 3 | ||||
-rw-r--r-- | src/libserver/cfg_file_private.h | 2 | ||||
-rw-r--r-- | src/libserver/cfg_utils.c | 21 | ||||
-rw-r--r-- | src/libserver/events.c | 1 | ||||
-rw-r--r-- | src/libserver/html.c | 2 | ||||
-rw-r--r-- | src/libserver/protocol.c | 34 | ||||
-rw-r--r-- | src/libserver/roll_history.c | 5 | ||||
-rw-r--r-- | src/libserver/task.c | 30 | ||||
-rw-r--r-- | src/lua/lua_task.c | 106 | ||||
-rw-r--r-- | src/worker.c | 11 |
15 files changed, 255 insertions, 154 deletions
diff --git a/src/controller.c b/src/controller.c index ee7e80e20..6a839b4df 100644 --- a/src/controller.c +++ b/src/controller.c @@ -15,6 +15,7 @@ */ #include "config.h" #include "libserver/dynamic_cfg.h" +#include "libserver/cfg_file_private.h" #include "libutil/rrd.h" #include "libutil/map.h" #include "libutil/map_helpers.h" @@ -864,8 +865,7 @@ rspamd_controller_handle_actions (struct rspamd_http_connection_entry *conn_ent, struct rspamd_http_message *msg) { struct rspamd_controller_session *session = conn_ent->ud; - struct rspamd_action *act; - gint i; + struct rspamd_action *act, *tmp; ucl_object_t *obj, *top; if (!rspamd_controller_check_password (conn_ent, session, msg, FALSE)) { @@ -874,15 +874,14 @@ rspamd_controller_handle_actions (struct rspamd_http_connection_entry *conn_ent, top = ucl_object_typed_new (UCL_ARRAY); - /* Get actions for default metric */ - for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) { - act = &session->cfg->actions[i]; + HASH_ITER (hh, session->cfg->actions, act, tmp) { obj = ucl_object_typed_new (UCL_OBJECT); ucl_object_insert_key (obj, - ucl_object_fromstring (rspamd_action_to_str ( - act->action)), "action", 0, false); - ucl_object_insert_key (obj, ucl_object_fromdouble ( - act->threshold), "value", 0, false); + ucl_object_fromstring (act->name), + "action", 0, false); + ucl_object_insert_key (obj, + ucl_object_fromdouble (act->threshold), + "value", 0, false); ucl_array_append (top, obj); } diff --git a/src/libmime/filter.c b/src/libmime/filter.c index 2bda47fe7..46a0e5b92 100644 --- a/src/libmime/filter.c +++ b/src/libmime/filter.c @@ -19,6 +19,8 @@ #include "rspamd.h" #include "message.h" #include "lua/lua_common.h" +#include "libserver/cfg_file_private.h" +#include "libmime/filter_private.h" #include <math.h> #include "contrib/uthash/utlist.h" @@ -70,14 +72,22 @@ rspamd_create_metric_result (struct rspamd_task *task) } if (task->cfg) { - for (i = 0; i < METRIC_ACTION_MAX; i++) { - metric_res->actions_limits[i] = task->cfg->actions[i].threshold; - } - } - else { - for (i = 0; i < METRIC_ACTION_MAX; i++) { - metric_res->actions_limits[i] = NAN; + struct rspamd_action *act, *tmp; + + metric_res->actions_limits = rspamd_mempool_alloc0 (task->task_pool, + sizeof (struct rspamd_action_result) * HASH_COUNT (task->cfg->actions)); + i = 0; + + HASH_ITER (hh, task->cfg->actions, act, tmp) { + if (!(act->flags & RSPAMD_ACTION_NO_THRESHOLD)) { + metric_res->actions_limits[i].cur_limit = act->threshold; + } + metric_res->actions_limits[i].action = act; + + i ++; } + + metric_res->nactions = i; } rspamd_mempool_add_destructor (task->task_pool, @@ -96,7 +106,7 @@ rspamd_pr_sort (const struct rspamd_passthrough_result *pra, void rspamd_add_passthrough_result (struct rspamd_task *task, - enum rspamd_action_type action, + struct rspamd_action *action, guint priority, double target_score, const gchar *message, @@ -119,13 +129,13 @@ rspamd_add_passthrough_result (struct rspamd_task *task, if (!isnan (target_score)) { msg_info_task ("<%s>: set pre-result to %s (%.2f): '%s' from %s(%d)", - task->message_id, rspamd_action_to_str (action), target_score, + task->message_id, action->name, target_score, message, module, priority); } else { msg_info_task ("<%s>: set pre-result to %s (no score): '%s' from %s(%d)", - task->message_id, rspamd_action_to_str (action), + task->message_id, action->name, message, module, priority); } } @@ -475,43 +485,50 @@ rspamd_task_add_result_option (struct rspamd_task *task, return ret; } -enum rspamd_action_type -rspamd_check_action_metric (struct rspamd_task *task, struct rspamd_metric_result *mres) +struct rspamd_action* +rspamd_check_action_metric (struct rspamd_task *task) { - struct rspamd_action *action, *selected_action = NULL; + struct rspamd_action_result *action_lim, + *noaction = NULL; + struct rspamd_action *selected_action = NULL; struct rspamd_passthrough_result *pr; double max_score = -(G_MAXDOUBLE), sc; int i; gboolean set_action = FALSE; + struct rspamd_metric_result *mres = task->result; /* We are not certain about the results during processing */ - if (task->result->passthrough_result == NULL) { - for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) { - action = &task->cfg->actions[i]; - sc = mres->actions_limits[i]; + if (mres->passthrough_result == NULL) { + for (i = 0; i < mres->nactions; i++) { + action_lim = &mres->actions_limits[i]; + sc = action_lim->cur_limit; + + if (action_lim->action->action_type == METRIC_ACTION_NOACTION) { + noaction = action_lim; + } if (isnan (sc)) { continue; } if (mres->score >= sc && sc > max_score) { - selected_action = action; + selected_action = action_lim->action; max_score = sc; } } if (set_action && selected_action == NULL) { - selected_action = &task->cfg->actions[METRIC_ACTION_NOACTION]; + selected_action = noaction->action; } } else { /* Peek the highest priority result */ - pr = task->result->passthrough_result; + pr = mres->passthrough_result; sc = pr->target_score; - selected_action = &task->cfg->actions[pr->action]; + selected_action = pr->action; if (!isnan (sc)) { - if (pr->action == METRIC_ACTION_NOACTION) { + if (pr->action->action_type == METRIC_ACTION_NOACTION) { mres->score = MIN (sc, mres->score); } else { @@ -521,10 +538,10 @@ rspamd_check_action_metric (struct rspamd_task *task, struct rspamd_metric_resul } if (selected_action) { - return selected_action->action; + return selected_action; } - return METRIC_ACTION_NOACTION; + return noaction ? noaction->action : NULL; } struct rspamd_symbol_result* diff --git a/src/libmime/filter.h b/src/libmime/filter.h index 73f8269fa..7ee0f1163 100644 --- a/src/libmime/filter.h +++ b/src/libmime/filter.h @@ -9,7 +9,6 @@ #include "config.h" #include "rspamd_symcache.h" #include "task.h" -#include "khash.h" struct rspamd_task; struct rspamd_settings; @@ -25,14 +24,14 @@ enum rspamd_symbol_result_flags { RSPAMD_SYMBOL_RESULT_IGNORED = (1 << 0) }; +struct kh_rspamd_options_hash_s; + /** * Rspamd symbol */ - -KHASH_MAP_INIT_STR (rspamd_options_hash, struct rspamd_symbol_option *); struct rspamd_symbol_result { double score; /**< symbol's score */ - khash_t(rspamd_options_hash) *options; /**< list of symbol's options */ + struct kh_rspamd_options_hash_s *options; /**< list of symbol's options */ struct rspamd_symbol_option *opts_head; /**< head of linked list of options */ const gchar *name; struct rspamd_symbol *sym; /**< symbol configuration */ @@ -40,24 +39,6 @@ struct rspamd_symbol_result { enum rspamd_symbol_result_flags flags; }; -/** - * Result of metric processing - */ -KHASH_MAP_INIT_STR (rspamd_symbols_hash, struct rspamd_symbol_result); -#if UINTPTR_MAX <= UINT_MAX -/* 32 bit */ -#define rspamd_ptr_hash_func(key) (khint32_t)(((uintptr_t)(key))>>1) -#else -/* likely 64 bit */ -#define rspamd_ptr_hash_func(key) (khint32_t)(((uintptr_t)(key))>>3) -#endif -#define rspamd_ptr_equal_func(a, b) ((a) == (b)) -KHASH_INIT (rspamd_symbols_group_hash, - void *, - double, - 1, - rspamd_ptr_hash_func, - rspamd_ptr_equal_func); #define RSPAMD_PASSTHROUGH_NORMAL 1 #define RSPAMD_PASSTHROUGH_LOW 0 @@ -65,7 +46,7 @@ KHASH_INIT (rspamd_symbols_group_hash, #define RSPAMD_PASSTHROUGH_CRITICAL 3 struct rspamd_passthrough_result { - enum rspamd_action_type action; + struct rspamd_action *action; guint priority; double target_score; const gchar *message; @@ -73,6 +54,15 @@ struct rspamd_passthrough_result { struct rspamd_passthrough_result *prev, *next; }; +struct rspamd_action_result { + gdouble cur_limit; + struct rspamd_action *action; +}; + +struct kh_rspamd_symbols_hash_s; +struct kh_rspamd_symbols_group_hash_s; + + struct rspamd_metric_result { double score; /**< total score */ double grow_factor; /**< current grow factor */ @@ -81,9 +71,10 @@ struct rspamd_metric_result { guint nnegative; double positive_score; double negative_score; - khash_t(rspamd_symbols_hash) *symbols; /**< symbols of metric */ - khash_t(rspamd_symbols_group_hash) *sym_groups; /**< groups of symbols */ - gdouble actions_limits[METRIC_ACTION_MAX]; /**< set of actions for this metric */ + struct kh_rspamd_symbols_hash_s *symbols; /**< symbols of metric */ + struct kh_rspamd_symbols_group_hash_s *sym_groups; /**< groups of symbols */ + struct rspamd_action_result *actions_limits; + guint nactions; }; /** @@ -103,7 +94,7 @@ struct rspamd_metric_result * rspamd_create_metric_result (struct rspamd_task *t * @param module */ void rspamd_add_passthrough_result (struct rspamd_task *task, - enum rspamd_action_type action, + struct rspamd_action *action, guint priority, double target_score, const gchar *message, @@ -175,10 +166,11 @@ double rspamd_factor_consolidation_func (struct rspamd_task *task, const gchar *unused); -/* - * Get action for specific metric +/** + * Check thresholds and return action for a task + * @param task + * @return */ -enum rspamd_action_type rspamd_check_action_metric (struct rspamd_task *task, - struct rspamd_metric_result *mres); +struct rspamd_action* rspamd_check_action_metric (struct rspamd_task *task); #endif diff --git a/src/libmime/filter_private.h b/src/libmime/filter_private.h new file mode 100644 index 000000000..82322a6bb --- /dev/null +++ b/src/libmime/filter_private.h @@ -0,0 +1,31 @@ +// +// Created by Vsevolod Stakhov on 2019-01-14. +// + +#ifndef RSPAMD_FILTER_PRIVATE_H +#define RSPAMD_FILTER_PRIVATE_H + +#include "filter.h" +#include "contrib/libucl/khash.h" + +KHASH_MAP_INIT_STR (rspamd_options_hash, struct rspamd_symbol_option *); +/** + * Result of metric processing + */ +KHASH_MAP_INIT_STR (rspamd_symbols_hash, struct rspamd_symbol_result); +#if UINTPTR_MAX <= UINT_MAX +/* 32 bit */ +#define rspamd_ptr_hash_func(key) (khint32_t)(((uintptr_t)(key))>>1) +#else +/* likely 64 bit */ +#define rspamd_ptr_hash_func(key) (khint32_t)(((uintptr_t)(key))>>3) +#endif +#define rspamd_ptr_equal_func(a, b) ((a) == (b)) +KHASH_INIT (rspamd_symbols_group_hash, + void *, + double, + 1, + rspamd_ptr_hash_func, + rspamd_ptr_equal_func); + +#endif //RSPAMD_FILTER_PRIVATE_H diff --git a/src/libmime/message.c b/src/libmime/message.c index a07cb6c8d..cb85a512b 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -34,6 +34,7 @@ #include <math.h> #include <unicode/uchar.h> +#include <src/libserver/cfg_file_private.h> #define GTUBE_SYMBOL "GTUBE" @@ -883,23 +884,23 @@ rspamd_message_process_text_part_maybe (struct rspamd_task *task, act = rspamd_check_gtube (task, text_part); if (act != METRIC_ACTION_NOACTION) { - struct rspamd_metric_result *mres = task->result; + struct rspamd_action *action; gdouble score = NAN; - if (act == METRIC_ACTION_REJECT) { - score = rspamd_task_get_required_score (task, mres); - } - else { - score = mres->actions_limits[act]; - } + action = rspamd_config_get_action_by_type (task->cfg, act); - rspamd_add_passthrough_result (task, act, RSPAMD_PASSTHROUGH_CRITICAL, - score, "Gtube pattern", "GTUBE"); + if (action) { + score = action->threshold; - if (ucl_object_lookup (task->messages, "smtp_message") == NULL) { - ucl_object_replace_key (task->messages, - ucl_object_fromstring ("Gtube pattern"), "smtp_message", 0, - false); + rspamd_add_passthrough_result (task, action, + RSPAMD_PASSTHROUGH_CRITICAL, + score, "Gtube pattern", "GTUBE"); + + if (ucl_object_lookup (task->messages, "smtp_message") == NULL) { + ucl_object_replace_key (task->messages, + ucl_object_fromstring ("Gtube pattern"), + "smtp_message", 0, false); + } } rspamd_task_insert_result (task, GTUBE_SYMBOL, 0, NULL); diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index 0557f4487..5c245a31b 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -708,6 +708,9 @@ gboolean rspamd_config_radix_from_ucl (struct rspamd_config *cfg, struct rspamd_action * rspamd_config_get_action (struct rspamd_config *cfg, const gchar *name); +struct rspamd_action * rspamd_config_get_action_by_type (struct rspamd_config *cfg, + enum rspamd_action_type type); + #define msg_err_config(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \ cfg->cfg_pool->tag.tagname, cfg->checksum, \ G_STRFUNC, \ diff --git a/src/libserver/cfg_file_private.h b/src/libserver/cfg_file_private.h index 03f735efe..94cb9aa08 100644 --- a/src/libserver/cfg_file_private.h +++ b/src/libserver/cfg_file_private.h @@ -26,7 +26,7 @@ * Action config definition */ struct rspamd_action { - enum rspamd_action_type action; + enum rspamd_action_type action_type; enum rspamd_action_flags flags; guint priority; gint lua_handler_ref; /* If special handling is needed */ diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index 1ab2ff054..26bf4e4b0 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -141,7 +141,7 @@ rspamd_config_new (enum rspamd_config_init_flags flags) action->threshold = NAN; action->name = rspamd_mempool_strdup (cfg->cfg_pool, rspamd_action_to_str (i)); - action->action = i; + action->action_type = i; if (i == METRIC_ACTION_SOFT_REJECT) { action->flags |= RSPAMD_ACTION_NO_THRESHOLD; @@ -1946,10 +1946,10 @@ rspamd_config_action_from_ucl (struct rspamd_config *cfg, act->flags = flags; if (rspamd_action_from_str (act->name, &std_act)) { - act->action = std_act; + act->action_type = std_act; } else { - act->action = METRIC_ACTION_CUSTOM; + act->action_type = METRIC_ACTION_CUSTOM; } rspamd_actions_sort (cfg); @@ -2060,6 +2060,21 @@ rspamd_config_get_action (struct rspamd_config *cfg, const gchar *name) return res; } +struct rspamd_action * +rspamd_config_get_action_by_type (struct rspamd_config *cfg, + enum rspamd_action_type type) +{ + struct rspamd_action *cur, *tmp; + + HASH_ITER (hh, cfg->actions, cur, tmp) { + if (cur->action_type == type) { + return cur; + } + } + + return NULL; +} + gboolean rspamd_config_radix_from_ucl (struct rspamd_config *cfg, const ucl_object_t *obj, diff --git a/src/libserver/events.c b/src/libserver/events.c index 2fd0c55ff..3f6d47112 100644 --- a/src/libserver/events.c +++ b/src/libserver/events.c @@ -16,6 +16,7 @@ #include "config.h" #include "rspamd.h" #include "contrib/uthash/utlist.h" +#include "contrib/libucl/khash.h" #include "events.h" #include "cryptobox.h" diff --git a/src/libserver/html.c b/src/libserver/html.c index 2568d4c2a..8ebb3862e 100644 --- a/src/libserver/html.c +++ b/src/libserver/html.c @@ -22,6 +22,8 @@ #include "html_colors.h" #include "html_entities.h" #include "url.h" +#include "contrib/libucl/khash.h" + #include <unicode/uversion.h> #include <unicode/ucnv.h> #if U_ICU_VERSION_MAJOR_NUM >= 46 diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index 35463be52..713c54499 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -19,6 +19,8 @@ #include "utlist.h" #include "http_private.h" #include "worker_private.h" +#include "libserver/cfg_file_private.h" +#include "libmime/filter_private.h" #include "contrib/zstd/zstd.h" #include "lua/lua_common.h" #include "unix-std.h" @@ -922,12 +924,12 @@ rspamd_metric_result_ucl (struct rspamd_task *task, { struct rspamd_symbol_result *sym; gboolean is_spam; - enum rspamd_action_type action = METRIC_ACTION_NOACTION; + struct rspamd_action *action; ucl_object_t *obj = NULL, *sobj; const gchar *subject; - action = rspamd_check_action_metric (task, mres); - is_spam = (action < METRIC_ACTION_GREYLIST); + action = rspamd_check_action_metric (task); + is_spam = !(action->flags & RSPAMD_ACTION_HAM); if (task->cmd != CMD_CHECK_V2) { obj = ucl_object_typed_new (UCL_OBJECT); @@ -955,10 +957,10 @@ rspamd_metric_result_ucl (struct rspamd_task *task, ucl_object_fromdouble (rspamd_task_get_required_score (task, mres)), "required_score", 0, false); ucl_object_insert_key (obj, - ucl_object_fromstring (rspamd_action_to_str (action)), + ucl_object_fromstring (action->name), "action", 0, false); - if (action == METRIC_ACTION_REWRITE_SUBJECT) { + if (action->action_type == METRIC_ACTION_REWRITE_SUBJECT) { subject = rspamd_protocol_rewrite_subject (task); if (subject) { @@ -1253,7 +1255,8 @@ rspamd_protocol_http_reply (struct rspamd_http_message *msg, gpointer h, v; ucl_object_t *top = NULL; rspamd_fstring_t *reply; - gint action, flags = RSPAMD_PROTOCOL_DEFAULT; + gint flags = RSPAMD_PROTOCOL_DEFAULT; + struct rspamd_action *action; /* Write custom headers */ g_hash_table_iter_init (&hiter, task->reply_headers); @@ -1376,19 +1379,24 @@ end: if (metric_res != NULL) { - action = rspamd_check_action_metric (task, metric_res); + action = rspamd_check_action_metric (task); - if (action == METRIC_ACTION_SOFT_REJECT && + /* TODO: handle custom actions in stats */ + if (action->action_type == METRIC_ACTION_SOFT_REJECT && (task->flags & RSPAMD_TASK_FLAG_GREYLISTED)) { /* Set stat action to greylist to display greylisted messages */ - action = METRIC_ACTION_GREYLIST; +#ifndef HAVE_ATOMIC_BUILTINS + task->worker->srv->stat->actions_stat[METRIC_ACTION_GREYLIST]++; +#else + __atomic_add_fetch (&task->worker->srv->stat->actions_stat[METRIC_ACTION_GREYLIST], + 1, __ATOMIC_RELEASE); +#endif } - - if (action < METRIC_ACTION_MAX) { + else if (action->action_type < METRIC_ACTION_MAX) { #ifndef HAVE_ATOMIC_BUILTINS - task->worker->srv->stat->actions_stat[action]++; + task->worker->srv->stat->actions_stat[action->action_type]++; #else - __atomic_add_fetch (&task->worker->srv->stat->actions_stat[action], + __atomic_add_fetch (&task->worker->srv->stat->actions_stat[action->action_type], 1, __ATOMIC_RELEASE); #endif } diff --git a/src/libserver/roll_history.c b/src/libserver/roll_history.c index 3df597816..c9367409d 100644 --- a/src/libserver/roll_history.c +++ b/src/libserver/roll_history.c @@ -17,6 +17,7 @@ #include "rspamd.h" #include "lua/lua_common.h" #include "unix-std.h" +#include "cfg_file_private.h" static const gchar rspamd_history_magic_old[] = {'r', 's', 'h', '1'}; @@ -101,6 +102,7 @@ rspamd_roll_history_update (struct roll_history *history, struct roll_history_row *row; struct rspamd_metric_result *metric_res; struct history_metric_callback_data cbdata; + struct rspamd_action *action; if (history->disabled) { return; @@ -155,7 +157,8 @@ rspamd_roll_history_update (struct roll_history *history, } else { row->score = metric_res->score; - row->action = rspamd_check_action_metric (task, metric_res); + action = rspamd_check_action_metric (task); + row->action = action->action_type; row->required_score = rspamd_task_get_required_score (task, metric_res); cbdata.pos = row->symbols; cbdata.remain = sizeof (row->symbols); diff --git a/src/libserver/task.c b/src/libserver/task.c index eaa379361..df1a561cb 100644 --- a/src/libserver/task.c +++ b/src/libserver/task.c @@ -26,7 +26,10 @@ #include "utlist.h" #include "contrib/zstd/zstd.h" #include "libserver/mempool_vars_internal.h" +#include "libserver/cfg_file_private.h" #include "libmime/lang_detection.h" +#include "libmime/filter_private.h" + #include <math.h> /* @@ -1072,11 +1075,11 @@ rspamd_task_log_metric_res (struct rspamd_task *task, rspamd_fstring_t *symbuf; struct rspamd_symbol_result *sym; GPtrArray *sorted_symbols; - enum rspamd_action_type act; + struct rspamd_action *act; guint i, j; mres = task->result; - act = rspamd_check_action_metric (task, mres); + act = rspamd_check_action_metric (task); if (mres != NULL) { switch (lf->type) { @@ -1084,7 +1087,7 @@ rspamd_task_log_metric_res (struct rspamd_task *task, if (RSPAMD_TASK_IS_SKIPPED (task)) { res.begin = "S"; } - else if (act == METRIC_ACTION_REJECT) { + else if (!(act->flags & RSPAMD_ACTION_HAM)) { res.begin = "T"; } else { @@ -1094,7 +1097,7 @@ rspamd_task_log_metric_res (struct rspamd_task *task, res.len = 1; break; case RSPAMD_LOG_ACTION: - res.begin = rspamd_action_to_str (act); + res.begin = act->name; res.len = strlen (res.begin); break; case RSPAMD_LOG_SCORES: @@ -1441,14 +1444,17 @@ rspamd_task_log_variable (struct rspamd_task *task, if (!isnan (pr->target_score)) { var.len = rspamd_snprintf (numbuf, sizeof (numbuf), "%s \"%s\"; score=%.2f (set by %s)", - rspamd_action_to_str (pr->action), - pr->message, pr->target_score, pr->module); + pr->action->name, + pr->message, + pr->target_score, + pr->module); } else { var.len = rspamd_snprintf (numbuf, sizeof (numbuf), "%s \"%s\"; score=nan (set by %s)", - rspamd_action_to_str (pr->action), - pr->message, pr->module); + pr->action->name, + pr->message, + pr->module); } var.begin = numbuf; } @@ -1536,7 +1542,7 @@ rspamd_task_write_log (struct rspamd_task *task) gdouble rspamd_task_get_required_score (struct rspamd_task *task, struct rspamd_metric_result *m) { - guint i; + gint i; if (m == NULL) { m = task->result; @@ -1546,9 +1552,9 @@ rspamd_task_get_required_score (struct rspamd_task *task, struct rspamd_metric_r } } - for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_NOACTION; i ++) { - if (!isnan (m->actions_limits[i])) { - return m->actions_limits[i]; + for (i = m->nactions - 1; i >= 0; i --) { + if (!isnan (m->actions_limits[i].cur_limit)) { + return m->actions_limits[i].cur_limit; } } diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 00e819f32..5728b3342 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -23,6 +23,8 @@ #include "libserver/mempool_vars_internal.h" #include "libserver/dkim.h" #include "libserver/task.h" +#include "libserver/cfg_file_private.h" +#include "libmime/filter_private.h" #include "libstat/stat_api.h" #include "libutil/map_helpers.h" @@ -1653,7 +1655,7 @@ lua_task_set_pre_result (lua_State * L) struct rspamd_task *task = lua_check_task (L, 1); const gchar *message = NULL, *module = NULL; gdouble score = NAN; - gint action = METRIC_ACTION_MAX; + struct rspamd_action *action; guint priority = RSPAMD_PASSTHROUGH_NORMAL; if (task != NULL) { @@ -1663,11 +1665,15 @@ lua_task_set_pre_result (lua_State * L) return 0; } - if (lua_type (L, 2) == LUA_TNUMBER) { - action = lua_tointeger (L, 2); + if (lua_type (L, 2) == LUA_TSTRING) { + action = rspamd_config_get_action (task->cfg, lua_tostring (L, 2)); } - else if (lua_type (L, 2) == LUA_TSTRING) { - rspamd_action_from_str (lua_tostring (L, 2), &action); + else { + return luaL_error (L, "invalid arguments"); + } + + if (action == NULL) { + return luaL_error (L, "unknown action %s", lua_tostring (L, 2)); } if (lua_type (L, 3) == LUA_TSTRING) { @@ -1698,21 +1704,16 @@ lua_task_set_pre_result (lua_State * L) priority = lua_tonumber (L, 6); } - if (action < METRIC_ACTION_MAX && action >= METRIC_ACTION_REJECT) { - rspamd_add_passthrough_result (task, action, priority, - score, rspamd_mempool_strdup (task->task_pool, message), - rspamd_mempool_strdup (task->task_pool, module)); + rspamd_add_passthrough_result (task, action, priority, + score, rspamd_mempool_strdup (task->task_pool, message), + rspamd_mempool_strdup (task->task_pool, module)); - /* Don't classify or filter message if pre-filter sets results */ - task->processed_stages |= (RSPAMD_TASK_STAGE_FILTERS | - RSPAMD_TASK_STAGE_CLASSIFIERS | - RSPAMD_TASK_STAGE_CLASSIFIERS_PRE | - RSPAMD_TASK_STAGE_CLASSIFIERS_POST); - } - else { - return luaL_error (L, "invalid arguments"); - } + /* Don't classify or filter message if pre-filter sets results */ + task->processed_stages |= (RSPAMD_TASK_STAGE_FILTERS | + RSPAMD_TASK_STAGE_CLASSIFIERS | + RSPAMD_TASK_STAGE_CLASSIFIERS_PRE | + RSPAMD_TASK_STAGE_CLASSIFIERS_POST); } else { return luaL_error (L, "invalid arguments"); @@ -4360,20 +4361,23 @@ lua_task_set_settings (lua_State *L) /* Adjust desired actions */ mres = task->result; - for (i = 0; i < METRIC_ACTION_MAX; i++) { - elt = ucl_object_lookup_any (act, rspamd_action_to_str (i), - rspamd_action_to_str_alt (i), NULL); + for (i = 0; i < mres->nactions; i++) { + struct rspamd_action_result *act_res = &mres->actions_limits[i]; + elt = ucl_object_lookup (act, act_res->action->name); if (elt) { - if (ucl_object_type (elt) == UCL_FLOAT || ucl_object_type (elt) == UCL_INT) { - mres->actions_limits[i] = ucl_object_todouble (elt); - msg_debug_task ("adjusted action %s to %.2f", - ucl_object_key (elt), mres->actions_limits[i]); + gdouble nscore = ucl_object_todouble (elt); + + msg_debug_task ("adjusted action %s: %.2f -> %.2f", + ucl_object_key (elt), + act_res->cur_limit, + nscore); + act_res->cur_limit = nscore; } else if (ucl_object_type (elt) == UCL_NULL) { - mres->actions_limits[i] = NAN; + act_res->cur_limit = NAN; msg_info_task ("disabled action %s due to settings", ucl_object_key (elt)); } @@ -4384,6 +4388,8 @@ lua_task_set_settings (lua_State *L) vars = ucl_object_lookup (task->settings, "variables"); if (vars && ucl_object_type (vars) == UCL_OBJECT) { /* Set memory pool variables */ + it = NULL; + while ((cur = ucl_object_iterate (vars, &it, true)) != NULL) { if (ucl_object_type (cur) == UCL_STRING) { rspamd_mempool_set_variable (task->task_pool, @@ -4741,6 +4747,7 @@ lua_task_get_metric_result (lua_State *L) LUA_TRACE_POINT; struct rspamd_task *task = lua_check_task (L, 1); struct rspamd_metric_result *metric_res; + struct rspamd_action *action; if (task) { metric_res = task->result; @@ -4760,10 +4767,13 @@ lua_task_get_metric_result (lua_State *L) lua_pushnumber (L, metric_res->score); lua_settable (L, -3); - lua_pushstring (L, "action"); - lua_pushstring (L, rspamd_action_to_str ( - rspamd_check_action_metric (task, metric_res))); - lua_settable (L, -3); + action = rspamd_check_action_metric (task); + + if (action) { + lua_pushstring (L, "action"); + lua_pushstring (L, action->name); + lua_settable (L, -3); + } lua_pushstring (L, "nnegative"); lua_pushnumber (L, metric_res->nnegative); @@ -4826,13 +4836,13 @@ lua_task_get_metric_action (lua_State *L) LUA_TRACE_POINT; struct rspamd_task *task = lua_check_task (L, 1); struct rspamd_metric_result *metric_res; - enum rspamd_action_type action; + struct rspamd_action *action; if (task) { metric_res = task->result; - action = rspamd_check_action_metric (task, metric_res); - lua_pushstring (L, rspamd_action_to_str (action)); + action = rspamd_check_action_metric (task); + lua_pushstring (L, action->name); } else { return luaL_error (L, "invalid arguments"); @@ -4880,21 +4890,29 @@ lua_task_disable_action (lua_State *L) LUA_TRACE_POINT; struct rspamd_task *task = lua_check_task (L, 1); const gchar *action_name; - gint action; + struct rspamd_action_result *action_res; action_name = luaL_checkstring (L, 2); - if (task && action_name && rspamd_action_from_str (action_name, &action)) { - if (!task->result) { - task->result = rspamd_create_metric_result (task); - } - if (isnan (task->result->actions_limits[action])) { - lua_pushboolean (L, false); - } - else { - task->result->actions_limits[action] = NAN; - lua_pushboolean (L, true); + if (task && action_name) { + + for (guint i = 0; i < task->result->nactions; i ++) { + action_res = &task->result->actions_limits[i]; + + if (strcmp (action_name, action_res->action->name) == 0) { + if (isnan (action_res->cur_limit)) { + lua_pushboolean (L, false); + } + else { + action_res->cur_limit = NAN; + lua_pushboolean (L, true); + } + + break; + } } + + } else { return luaL_error (L, "invalid arguments"); diff --git a/src/worker.c b/src/worker.c index 5147e0a2d..2f7176a8d 100644 --- a/src/worker.c +++ b/src/worker.c @@ -36,6 +36,7 @@ #include "libutil/http_private.h" #include "libmime/lang_detection.h" #include <math.h> +#include <src/libserver/cfg_file_private.h> #include "unix-std.h" #include "lua/lua_common.h" @@ -144,11 +145,15 @@ rspamd_task_timeout (gint fd, short what, gpointer ud) msg_info_task ("processing of task timed out, forced processing"); if (task->cfg->soft_reject_on_timeout) { - struct rspamd_metric_result *res = task->result; + struct rspamd_action *action, *soft_reject; - if (rspamd_check_action_metric (task, res) != METRIC_ACTION_REJECT) { + action = rspamd_check_action_metric (task); + + if (action->action_type != METRIC_ACTION_REJECT) { + soft_reject = rspamd_config_get_action_by_type (task->cfg, + METRIC_ACTION_SOFT_REJECT); rspamd_add_passthrough_result (task, - METRIC_ACTION_SOFT_REJECT, + soft_reject, 0, NAN, "timeout processing message", |