diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-01-14 16:48:52 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-01-14 16:48:52 +0000 |
commit | aa07f4bc9eff2a252743e20faa334f2aa7d589d5 (patch) | |
tree | 177051f9fe263c7b1523aff6f83e8c1675d7d8b0 /src/libmime | |
parent | 137f4b1e53572d5f43a5a6368482f82149652091 (diff) | |
download | rspamd-aa07f4bc9eff2a252743e20faa334f2aa7d589d5.tar.gz rspamd-aa07f4bc9eff2a252743e20faa334f2aa7d589d5.zip |
[Project] More work towards flexible actions
Diffstat (limited to 'src/libmime')
-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 |
4 files changed, 109 insertions, 68 deletions
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); |