aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-10-11 15:35:07 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-10-11 15:35:07 +0100
commit98f0a701b71191a7b0373b8dd511bcf5f409e440 (patch)
treee94d06ebaed1bdccaeb4e5613a5d2603a3e6c238 /src
parentf5051a01e8d0c622682f8a282b818ff3a31be01a (diff)
downloadrspamd-98f0a701b71191a7b0373b8dd511bcf5f409e440.tar.gz
rspamd-98f0a701b71191a7b0373b8dd511bcf5f409e440.zip
[Project] Finish rework of passthrough actions
Diffstat (limited to 'src')
-rw-r--r--src/libmime/filter.c76
-rw-r--r--src/libmime/filter.h33
-rw-r--r--src/libmime/message.c24
-rw-r--r--src/lua/lua_task.c52
4 files changed, 140 insertions, 45 deletions
diff --git a/src/libmime/filter.c b/src/libmime/filter.c
index cdbfdcfbf..c06df1b77 100644
--- a/src/libmime/filter.c
+++ b/src/libmime/filter.c
@@ -60,6 +60,7 @@ rspamd_create_metric_result (struct rspamd_task *task)
metric_res->sym_groups = kh_init (rspamd_symbols_group_hash);
metric_res->grow_factor = 0;
metric_res->score = 0;
+ metric_res->passthrough_result = NULL;
/* Optimize allocation */
kh_resize (rspamd_symbols_group_hash, metric_res->sym_groups, 4);
@@ -82,6 +83,49 @@ rspamd_create_metric_result (struct rspamd_task *task)
return metric_res;
}
+static inline int
+rspamd_pr_sort (const struct rspamd_passthrough_result *pra,
+ const struct rspamd_passthrough_result *prb)
+{
+ return prb->priority - pra->priority;
+}
+
+void
+rspamd_add_passthrough_result (struct rspamd_task *task,
+ enum rspamd_action_type action,
+ guint priority,
+ double target_score,
+ const gchar *message,
+ const gchar *module)
+{
+ struct rspamd_metric_result *metric_res;
+ struct rspamd_passthrough_result *pr;
+
+ metric_res = task->result;
+
+ pr = rspamd_mempool_alloc (task->task_pool, sizeof (*pr));
+ pr->action = action;
+ pr->priority = priority;
+ pr->message = message;
+ pr->module = module;
+ pr->target_score = target_score;
+
+ DL_APPEND (metric_res->passthrough_result, pr);
+ DL_SORT (metric_res->passthrough_result, rspamd_pr_sort);
+
+ 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,
+ 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),
+ message, module, priority);
+ }
+}
+
static inline gdouble
rspamd_check_group_score (struct rspamd_task *task,
const gchar *symbol,
@@ -417,12 +461,13 @@ enum rspamd_action_type
rspamd_check_action_metric (struct rspamd_task *task, struct rspamd_metric_result *mres)
{
struct rspamd_action *action, *selected_action = NULL;
+ struct rspamd_passthrough_result *pr;
double max_score = -(G_MAXDOUBLE), sc;
int i;
gboolean set_action = FALSE;
/* We are not certain about the results during processing */
- if (task->pre_result.action == METRIC_ACTION_MAX) {
+ 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];
@@ -442,26 +487,33 @@ rspamd_check_action_metric (struct rspamd_task *task, struct rspamd_metric_resul
}
}
else {
+ /* Peek the highest priority result */
+ pr = task->result->passthrough_result;
sc = NAN;
- for (i = task->pre_result.action; i < METRIC_ACTION_MAX; i ++) {
- selected_action = &task->cfg->actions[i];
- sc = mres->actions_limits[i];
+ if (isnan (pr->target_score)) {
+ for (i = pr->action; i < METRIC_ACTION_MAX; i++) {
+ selected_action = &task->cfg->actions[i];
+ sc = mres->actions_limits[i];
- if (isnan (sc)) {
- if (i == task->pre_result.action) {
- /* No scores defined, just avoid NaN */
- sc = 0;
+ if (isnan (sc)) {
+ if (i == pr->action) {
+ /* No scores defined, just avoid NaN */
+ sc = 0;
+ break;
+ }
+ }
+ else {
break;
}
}
- else {
- break;
- }
+ }
+ else {
+ sc = pr->target_score;
}
if (!isnan (sc)) {
- if (task->pre_result.action == METRIC_ACTION_NOACTION) {
+ if (pr->action == METRIC_ACTION_NOACTION) {
mres->score = MIN (sc, mres->score);
}
else {
diff --git a/src/libmime/filter.h b/src/libmime/filter.h
index 9137258f5..fdd0f8dc9 100644
--- a/src/libmime/filter.h
+++ b/src/libmime/filter.h
@@ -58,10 +58,25 @@ KHASH_INIT (rspamd_symbols_group_hash,
1,
rspamd_ptr_hash_func,
rspamd_ptr_equal_func);
+
+#define RSPAMD_PASSTHROUGH_NORMAL 1
+#define RSPAMD_PASSTHROUGH_LOW 0
+#define RSPAMD_PASSTHROUGH_HIGH 2
+#define RSPAMD_PASSTHROUGH_CRITICAL 3
+
+struct rspamd_passthrough_result {
+ enum rspamd_action_type action;
+ guint priority;
+ double target_score;
+ const gchar *message;
+ const gchar *module;
+ struct rspamd_passthrough_result *prev, *next;
+};
+
struct rspamd_metric_result {
double score; /**< total score */
double grow_factor; /**< current grow factor */
-
+ struct rspamd_passthrough_result *passthrough_result;
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 */
@@ -74,6 +89,22 @@ struct rspamd_metric_result {
*/
struct rspamd_metric_result * rspamd_create_metric_result (struct rspamd_task *task);
+/**
+ * Adds a new passthrough result to a task
+ * @param task
+ * @param action
+ * @param priority
+ * @param target_score
+ * @param message
+ * @param module
+ */
+void rspamd_add_passthrough_result (struct rspamd_task *task,
+ enum rspamd_action_type action,
+ guint priority,
+ double target_score,
+ const gchar *message,
+ const gchar *module);
+
enum rspamd_symbol_insert_flags {
RSPAMD_SYMBOL_INSERT_DEFAULT = 0,
RSPAMD_SYMBOL_INSERT_SINGLE = (1 << 0),
diff --git a/src/libmime/message.c b/src/libmime/message.c
index 4206211c1..43158d083 100644
--- a/src/libmime/message.c
+++ b/src/libmime/message.c
@@ -32,6 +32,8 @@
#include "libstemmer.h"
#endif
+#include <math.h>
+
#define GTUBE_SYMBOL "GTUBE"
#define SET_PART_RAW(part) ((part)->flags &= ~RSPAMD_MIME_TEXT_PART_FLAG_UTF)
@@ -854,22 +856,18 @@ 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;
-
- mres = task->result;
+ struct rspamd_metric_result *mres = task->result;
+ gdouble score = NAN;
- if (mres != NULL) {
- if (act == METRIC_ACTION_REJECT) {
- mres->score = rspamd_task_get_required_score (task, mres);
- }
- else {
- mres->score = mres->actions_limits[act];
- }
+ if (act == METRIC_ACTION_REJECT) {
+ score = rspamd_task_get_required_score (task, mres);
+ }
+ else {
+ score = mres->actions_limits[act];
}
- task->result = mres;
- task->pre_result.action = act;
- task->pre_result.str = "Gtube pattern";
+ rspamd_add_passthrough_result (task, act, RSPAMD_PASSTHROUGH_CRITICAL,
+ score, "Gtube pattern", "GTUBE");
if (ucl_object_lookup (task->messages, "smtp_message") == NULL) {
ucl_object_replace_key (task->messages,
diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c
index 7f2711e19..a6b32b089 100644
--- a/src/lua/lua_task.c
+++ b/src/lua/lua_task.c
@@ -1567,8 +1567,10 @@ lua_task_set_pre_result (lua_State * L)
{
LUA_TRACE_POINT;
struct rspamd_task *task = lua_check_task (L, 1);
- gchar *action_str;
+ const gchar *message = NULL, *module = NULL;
+ gdouble score = NAN;
gint action = METRIC_ACTION_MAX;
+ guint priority = RSPAMD_PASSTHROUGH_NORMAL;
if (task != NULL) {
@@ -1584,26 +1586,38 @@ lua_task_set_pre_result (lua_State * L)
rspamd_action_from_str (lua_tostring (L, 2), &action);
}
- if (action < METRIC_ACTION_MAX && action >= METRIC_ACTION_REJECT) {
- /* We also need to set the default metric to that result */
+ if (lua_type (L, 3) == LUA_TSTRING) {
+ message = lua_tostring (L, 3);
- task->pre_result.action = action;
+ /* Keep compatibility here :( */
+ ucl_object_replace_key (task->messages,
+ ucl_object_fromstring (message), "smtp_message", 0,
+ false);
+ }
+ else {
+ message = "unknown reason";
+ }
- if (lua_gettop (L) >= 3) {
- action_str = rspamd_mempool_strdup (task->task_pool,
- luaL_checkstring (L, 3));
- task->pre_result.str = action_str;
- ucl_object_replace_key (task->messages,
- ucl_object_fromstring (action_str), "smtp_message", 0,
- false);
- }
- else {
- task->pre_result.str = "unknown";
- }
+ if (lua_type (L, 4) == LUA_TSTRING) {
+ module = lua_tostring (L, 4);
+ }
+ else {
+ module = "Unknown lua";
+ }
+
+ if (lua_type (L, 5) == LUA_TNUMBER) {
+ score = lua_tonumber (L, 5);
+ }
+
+ if (lua_type (L, 6) == LUA_TNUMBER) {
+ priority = lua_tonumber (L, 5);
+ }
+
+ if (action < METRIC_ACTION_MAX && action >= METRIC_ACTION_REJECT) {
- msg_info_task ("<%s>: set pre-result to %s: '%s'",
- task->message_id, rspamd_action_to_str (action),
- task->pre_result.str);
+ 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 |
@@ -1629,7 +1643,7 @@ lua_task_has_pre_result (lua_State * L)
struct rspamd_task *task = lua_check_task (L, 1);
if (task) {
- lua_pushboolean (L, task->pre_result.action != METRIC_ACTION_MAX);
+ lua_pushboolean (L, task->result->passthrough_result != NULL);
}
else {
return luaL_error (L, "invalid arguments");