commit 79dc60d: [Feature] Add least passthrough results

Vsevolod Stakhov vsevolod at highsecure.ru
Mon Apr 29 09:00:03 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-04-29 09:58:31 +0100
URL: https://github.com/rspamd/rspamd/commit/79dc60d2a151ab68707e8ef041418e94d53c8ef7 (HEAD -> master)

[Feature] Add least passthrough results

---
 src/libmime/filter.c  | 92 +++++++++++++++++++++++++++++++--------------------
 src/libmime/filter.h  |  6 +++-
 src/libmime/message.c |  2 +-
 src/lua/lua_task.c    | 35 ++++++++++++++------
 src/worker.c          |  3 +-
 5 files changed, 89 insertions(+), 49 deletions(-)

diff --git a/src/libmime/filter.c b/src/libmime/filter.c
index 45563e23f..c3f3089f8 100644
--- a/src/libmime/filter.c
+++ b/src/libmime/filter.c
@@ -110,7 +110,8 @@ rspamd_add_passthrough_result (struct rspamd_task *task,
 									guint priority,
 									double target_score,
 									const gchar *message,
-									const gchar *module)
+									const gchar *module,
+									guint flags)
 {
 	struct rspamd_metric_result *metric_res;
 	struct rspamd_passthrough_result *pr;
@@ -123,19 +124,23 @@ rspamd_add_passthrough_result (struct rspamd_task *task,
 	pr->message = message;
 	pr->module = module;
 	pr->target_score = target_score;
+	pr->flags = flags;
 
 	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, action->name, target_score,
+
+		msg_info_task ("<%s>: set pre-result to '%s' %s(%.2f): '%s' from %s(%d)",
+				task->message_id, action->name,
+				flags & RSPAMD_PASSTHROUGH_LEAST ? "*least " : "",
+				target_score,
 				message, module, priority);
 	}
-
 	else {
-		msg_info_task ("<%s>: set pre-result to %s (no score): '%s' from %s(%d)",
+		msg_info_task ("<%s>: set pre-result to '%s' %s(no score): '%s' from %s(%d)",
 				task->message_id, action->name,
+				flags & RSPAMD_PASSTHROUGH_LEAST ? "*least " : "",
 				message, module, priority);
 	}
 }
@@ -495,53 +500,68 @@ rspamd_check_action_metric (struct rspamd_task *task)
 	double max_score = -(G_MAXDOUBLE), sc;
 	int i;
 	struct rspamd_metric_result *mres = task->result;
+	gboolean seen_least = FALSE;
 
-	/* We are not certain about the results during processing */
-	if (mres->passthrough_result == NULL) {
-		for (i = mres->nactions - 1; i >= 0; i--) {
-			action_lim = &mres->actions_limits[i];
-			sc = action_lim->cur_limit;
+	if (mres->passthrough_result != NULL)  {
+		/* Peek the highest priority result */
+		pr = mres->passthrough_result;
+		sc = pr->target_score;
+		selected_action = pr->action;
 
-			if (action_lim->action->action_type == METRIC_ACTION_NOACTION) {
-				noaction = action_lim;
+		if (!(pr->flags & RSPAMD_PASSTHROUGH_LEAST)) {
+			if (!isnan (sc)) {
+				if (pr->action->action_type == METRIC_ACTION_NOACTION) {
+					mres->score = MIN (sc, mres->score);
+				}
+				else {
+					mres->score = sc;
+				}
 			}
 
-			if (isnan (sc) ||
-			 	(action_lim->action->flags & (RSPAMD_ACTION_NO_THRESHOLD|RSPAMD_ACTION_HAM))) {
-				continue;
-			}
+			return selected_action;
+		}
+		else {
+			seen_least = true;
+		}
+	}
+	/* We are not certain about the results during processing */
 
-			if (mres->score >= sc && sc > max_score) {
-				selected_action = action_lim->action;
-				max_score = sc;
-			}
+	/*
+	 * Select result by score
+	 */
+	for (i = mres->nactions - 1; i >= 0; 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 (selected_action == NULL) {
-			selected_action = noaction->action;
+		if (isnan (sc) ||
+			(action_lim->action->flags & (RSPAMD_ACTION_NO_THRESHOLD|RSPAMD_ACTION_HAM))) {
+			continue;
 		}
-	}
-	else {
-		/* Peek the highest priority result */
-		pr = mres->passthrough_result;
-		sc = pr->target_score;
-		selected_action = pr->action;
 
-		if (!isnan (sc)) {
-			if (pr->action->action_type == METRIC_ACTION_NOACTION) {
-				mres->score = MIN (sc, mres->score);
-			}
-			else {
-				mres->score = sc;
-			}
+		if (mres->score >= sc && sc > max_score) {
+			selected_action = action_lim->action;
+			max_score = sc;
 		}
 	}
 
+	if (selected_action == NULL) {
+		selected_action = noaction->action;
+	}
+
 	if (selected_action) {
+
+		if (seen_least) {
+			mres->score = MIN (sc, mres->score);
+		}
+
 		return selected_action;
 	}
 
-	return noaction ? noaction->action : NULL;
+	return noaction->action;
 }
 
 struct rspamd_symbol_result*
diff --git a/src/libmime/filter.h b/src/libmime/filter.h
index 7ee0f1163..f9218194a 100644
--- a/src/libmime/filter.h
+++ b/src/libmime/filter.h
@@ -45,9 +45,12 @@ struct rspamd_symbol_result {
 #define RSPAMD_PASSTHROUGH_HIGH 2
 #define RSPAMD_PASSTHROUGH_CRITICAL 3
 
+#define RSPAMD_PASSTHROUGH_LEAST (1u << 0u)
+
 struct rspamd_passthrough_result {
 	struct rspamd_action *action;
 	guint priority;
+	guint flags;
 	double target_score;
 	const gchar *message;
 	const gchar *module;
@@ -98,7 +101,8 @@ void rspamd_add_passthrough_result (struct rspamd_task *task,
 									guint priority,
 									double target_score,
 									const gchar *message,
-									const gchar *module);
+									const gchar *module,
+									guint flags);
 
 enum rspamd_symbol_insert_flags {
 	RSPAMD_SYMBOL_INSERT_DEFAULT = 0,
diff --git a/src/libmime/message.c b/src/libmime/message.c
index 9ce8950b7..6211ea2f3 100644
--- a/src/libmime/message.c
+++ b/src/libmime/message.c
@@ -961,7 +961,7 @@ rspamd_message_process_text_part_maybe (struct rspamd_task *task,
 
 			rspamd_add_passthrough_result (task, action,
 					RSPAMD_PASSTHROUGH_CRITICAL,
-					score, "Gtube pattern", "GTUBE");
+					score, "Gtube pattern", "GTUBE", 0);
 
 			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 945e06e08..6a4ae145d 100644
--- a/src/lua/lua_task.c
+++ b/src/lua/lua_task.c
@@ -1767,7 +1767,7 @@ lua_task_set_pre_result (lua_State * L)
 	const gchar *message = NULL, *module = NULL;
 	gdouble score = NAN;
 	struct rspamd_action *action;
-	guint priority = RSPAMD_PASSTHROUGH_NORMAL;
+	guint priority = RSPAMD_PASSTHROUGH_NORMAL, flags = 0;
 
 	if (task != NULL) {
 
@@ -1834,18 +1834,33 @@ lua_task_set_pre_result (lua_State * L)
 			priority = lua_tonumber (L, 6);
 		}
 
+		if (lua_type (L, 7) == LUA_TSTRING) {
+			const gchar *fl_str = lua_tostring (L, 7);
+
+			if (strstr (fl_str, "least") != NULL) {
+				flags |= RSPAMD_PASSTHROUGH_LEAST;
+			}
+		}
 
-		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),
+				flags);
 
 		/* Don't classify or filter message if pre-filter sets results */
-		task->processed_stages |= (RSPAMD_TASK_STAGE_CLASSIFIERS |
-								   RSPAMD_TASK_STAGE_CLASSIFIERS_PRE |
-								   RSPAMD_TASK_STAGE_CLASSIFIERS_POST);
-		rspamd_symcache_disable_all_symbols (task, task->cfg->cache,
-				SYMBOL_TYPE_IDEMPOTENT|SYMBOL_TYPE_IGNORE_PASSTHROUGH|
-				SYMBOL_TYPE_POSTFILTER);
+
+		if (!(flags & RSPAMD_PASSTHROUGH_LEAST)) {
+			task->processed_stages |= (RSPAMD_TASK_STAGE_CLASSIFIERS |
+									   RSPAMD_TASK_STAGE_CLASSIFIERS_PRE |
+									   RSPAMD_TASK_STAGE_CLASSIFIERS_POST);
+			rspamd_symcache_disable_all_symbols (task, task->cfg->cache,
+					SYMBOL_TYPE_IDEMPOTENT | SYMBOL_TYPE_IGNORE_PASSTHROUGH |
+					SYMBOL_TYPE_POSTFILTER);
+		}
 	}
 	else {
 		return luaL_error (L, "invalid arguments");
diff --git a/src/worker.c b/src/worker.c
index c7f4f7687..fc206cc32 100644
--- a/src/worker.c
+++ b/src/worker.c
@@ -157,7 +157,8 @@ rspamd_task_timeout (gint fd, short what, gpointer ud)
 						0,
 						NAN,
 						"timeout processing message",
-						"task timeout");
+						"task timeout",
+						0);
 
 				ucl_object_replace_key (task->messages,
 						ucl_object_fromstring_common ("timeout processing message",


More information about the Commits mailing list