summaryrefslogtreecommitdiffstats
path: root/src/libmime
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2019-01-14 16:48:52 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2019-01-14 16:48:52 +0000
commitaa07f4bc9eff2a252743e20faa334f2aa7d589d5 (patch)
tree177051f9fe263c7b1523aff6f83e8c1675d7d8b0 /src/libmime
parent137f4b1e53572d5f43a5a6368482f82149652091 (diff)
downloadrspamd-aa07f4bc9eff2a252743e20faa334f2aa7d589d5.tar.gz
rspamd-aa07f4bc9eff2a252743e20faa334f2aa7d589d5.zip
[Project] More work towards flexible actions
Diffstat (limited to 'src/libmime')
-rw-r--r--src/libmime/filter.c65
-rw-r--r--src/libmime/filter.h54
-rw-r--r--src/libmime/filter_private.h31
-rw-r--r--src/libmime/message.c27
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);