commit cb22849: [Fix] Distinguish empty and non-empty prefilters

Vsevolod Stakhov vsevolod at highsecure.ru
Sun Aug 18 09:00:03 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-08-18 09:32:21 +0100
URL: https://github.com/rspamd/rspamd/commit/cb2284917bc94c5033ed12f3789bdf8611cec6de

[Fix] Distinguish empty and non-empty prefilters

---
 src/libserver/rspamd_symcache.c | 42 ++++++++++++++++++++++++++++++++---------
 src/libserver/task.c            |  9 +++++++--
 src/libserver/task.h            | 29 ++++++++++++++--------------
 3 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/src/libserver/rspamd_symcache.c b/src/libserver/rspamd_symcache.c
index f91aa9a22..71d3ab5e8 100644
--- a/src/libserver/rspamd_symcache.c
+++ b/src/libserver/rspamd_symcache.c
@@ -161,6 +161,7 @@ struct rspamd_symcache {
 	GPtrArray *items_by_id;
 	struct symcache_order *items_by_order;
 	GPtrArray *filters;
+	GPtrArray *prefilters_empty;
 	GPtrArray *prefilters;
 	GPtrArray *postfilters;
 	GPtrArray *composites;
@@ -210,6 +211,7 @@ struct delayed_cache_condition {
 
 enum rspamd_cache_savepoint_stage {
 	RSPAMD_CACHE_PASS_INIT = 0,
+	RSPAMD_CACHE_PASS_PREFILTERS_EMPTY,
 	RSPAMD_CACHE_PASS_PREFILTERS,
 	RSPAMD_CACHE_PASS_FILTERS,
 	RSPAMD_CACHE_PASS_POSTFILTERS,
@@ -644,6 +646,7 @@ rspamd_symcache_post_init (struct rspamd_symcache *cache)
 		}
 	}
 
+	g_ptr_array_sort_with_data (cache->prefilters_empty, prefilters_cmp, cache);
 	g_ptr_array_sort_with_data (cache->prefilters, prefilters_cmp, cache);
 	g_ptr_array_sort_with_data (cache->postfilters, postfilters_cmp, cache);
 	g_ptr_array_sort_with_data (cache->idempotent, postfilters_cmp, cache);
@@ -998,8 +1001,15 @@ rspamd_symcache_add_symbol (struct rspamd_symcache *cache,
 		g_assert (parent == -1);
 
 		if (item->type & SYMBOL_TYPE_PREFILTER) {
-			g_ptr_array_add (cache->prefilters, item);
-			item->container = cache->prefilters;
+			if (item->type & SYMBOL_TYPE_EMPTY) {
+				/* Executed before mime parsing stage */
+				g_ptr_array_add (cache->prefilters_empty, item);
+				item->container = cache->prefilters_empty;
+			}
+			else {
+				g_ptr_array_add (cache->prefilters, item);
+				item->container = cache->prefilters;
+			}
 		}
 		else if (item->type & SYMBOL_TYPE_IDEMPOTENT) {
 			g_ptr_array_add (cache->idempotent, item);
@@ -1195,6 +1205,7 @@ rspamd_symcache_destroy (struct rspamd_symcache *cache)
 		rspamd_mempool_delete (cache->static_pool);
 		g_ptr_array_free (cache->filters, TRUE);
 		g_ptr_array_free (cache->prefilters, TRUE);
+		g_ptr_array_free (cache->prefilters_empty, TRUE);
 		g_ptr_array_free (cache->postfilters, TRUE);
 		g_ptr_array_free (cache->idempotent, TRUE);
 		g_ptr_array_free (cache->composites, TRUE);
@@ -1222,6 +1233,7 @@ rspamd_symcache_new (struct rspamd_config *cfg)
 	cache->items_by_id = g_ptr_array_new ();
 	cache->filters = g_ptr_array_new ();
 	cache->prefilters = g_ptr_array_new ();
+	cache->prefilters_empty = g_ptr_array_new ();
 	cache->postfilters = g_ptr_array_new ();
 	cache->idempotent = g_ptr_array_new ();
 	cache->composites = g_ptr_array_new ();
@@ -1923,9 +1935,11 @@ rspamd_symcache_process_symbols (struct rspamd_task *task,
 	struct rspamd_symcache_item *item = NULL;
 	struct rspamd_symcache_dynamic_item *dyn_item;
 	struct cache_savepoint *checkpoint;
+	GPtrArray *sel;
 	gint i;
 	gboolean all_done;
 	gint saved_priority;
+	enum rspamd_cache_savepoint_stage next;
 	guint start_events_pending;
 
 	g_assert (cache != NULL);
@@ -1954,12 +1968,24 @@ rspamd_symcache_process_symbols (struct rspamd_task *task,
 	switch (checkpoint->pass) {
 	case RSPAMD_CACHE_PASS_INIT:
 	case RSPAMD_CACHE_PASS_PREFILTERS:
+	case RSPAMD_CACHE_PASS_PREFILTERS_EMPTY:
 		/* Check for prefilters */
 		saved_priority = G_MININT;
 		all_done = TRUE;
 
-		for (i = 0; i < (gint)cache->prefilters->len; i ++) {
-			item = g_ptr_array_index (cache->prefilters, i);
+		if (checkpoint->pass != RSPAMD_CACHE_PASS_PREFILTERS) {
+			sel = cache->prefilters_empty;
+			next = RSPAMD_CACHE_PASS_PREFILTERS;
+			checkpoint->pass = RSPAMD_CACHE_PASS_PREFILTERS_EMPTY;
+		}
+		else {
+			sel = cache->prefilters;
+			next = RSPAMD_CACHE_PASS_FILTERS;
+		}
+
+
+		for (i = 0; i < (gint)sel->len; i ++) {
+			item = g_ptr_array_index (sel, i);
 			dyn_item = rspamd_symcache_get_dynamic (checkpoint, item);
 
 			if (RSPAMD_TASK_IS_SKIPPED (task)) {
@@ -1979,8 +2005,6 @@ rspamd_symcache_process_symbols (struct rspamd_task *task,
 						 * Delay further checks as we have higher
 						 * priority filters to be processed
 						 */
-						checkpoint->pass = RSPAMD_CACHE_PASS_PREFILTERS;
-
 						return TRUE;
 					}
 				}
@@ -1991,11 +2015,11 @@ rspamd_symcache_process_symbols (struct rspamd_task *task,
 			}
 		}
 
-		if (all_done || stage == RSPAMD_TASK_STAGE_FILTERS) {
-			checkpoint->pass = RSPAMD_CACHE_PASS_FILTERS;
+		if (all_done || stage == next) {
+			checkpoint->pass = next;
 		}
 
-		if (stage == RSPAMD_TASK_STAGE_FILTERS) {
+		if (stage == next) {
 			return rspamd_symcache_process_symbols (task, cache, stage);
 		}
 
diff --git a/src/libserver/task.c b/src/libserver/task.c
index acec922a7..e9a63cbad 100644
--- a/src/libserver/task.c
+++ b/src/libserver/task.c
@@ -716,9 +716,9 @@ rspamd_task_process (struct rspamd_task *task, guint stages)
 		}
 		break;
 
-	case RSPAMD_TASK_STAGE_PRE_FILTERS:
+	case RSPAMD_TASK_STAGE_PRE_FILTERS_EMPTY:
 		rspamd_symcache_process_symbols (task, task->cfg->cache,
-				RSPAMD_TASK_STAGE_PRE_FILTERS);
+				RSPAMD_TASK_STAGE_PRE_FILTERS_EMPTY);
 		break;
 
 	case RSPAMD_TASK_STAGE_PROCESS_MESSAGE:
@@ -727,6 +727,11 @@ rspamd_task_process (struct rspamd_task *task, guint stages)
 		}
 		break;
 
+	case RSPAMD_TASK_STAGE_PRE_FILTERS:
+		rspamd_symcache_process_symbols (task, task->cfg->cache,
+				RSPAMD_TASK_STAGE_PRE_FILTERS);
+		break;
+
 	case RSPAMD_TASK_STAGE_FILTERS:
 		rspamd_symcache_process_symbols (task, task->cfg->cache,
 				RSPAMD_TASK_STAGE_FILTERS);
diff --git a/src/libserver/task.h b/src/libserver/task.h
index 28e0dc070..573f6d9b7 100644
--- a/src/libserver/task.h
+++ b/src/libserver/task.h
@@ -42,21 +42,22 @@ enum rspamd_task_stage {
 	RSPAMD_TASK_STAGE_CONNECT = (1u << 0u),
 	RSPAMD_TASK_STAGE_ENVELOPE = (1u << 1u),
 	RSPAMD_TASK_STAGE_READ_MESSAGE = (1u << 2u),
-	RSPAMD_TASK_STAGE_PRE_FILTERS = (1u << 3u),
+	RSPAMD_TASK_STAGE_PRE_FILTERS_EMPTY = (1u << 3u),
 	RSPAMD_TASK_STAGE_PROCESS_MESSAGE = (1u << 4u),
-	RSPAMD_TASK_STAGE_FILTERS = (1u << 5u),
-	RSPAMD_TASK_STAGE_CLASSIFIERS_PRE = (1u << 6u),
-	RSPAMD_TASK_STAGE_CLASSIFIERS = (1u << 7u),
-	RSPAMD_TASK_STAGE_CLASSIFIERS_POST = (1u << 8u),
-	RSPAMD_TASK_STAGE_COMPOSITES = (1u << 9u),
-	RSPAMD_TASK_STAGE_POST_FILTERS = (1u << 10u),
-	RSPAMD_TASK_STAGE_LEARN_PRE = (1u << 11u),
-	RSPAMD_TASK_STAGE_LEARN = (1u << 12u),
-	RSPAMD_TASK_STAGE_LEARN_POST = (1u << 13u),
-	RSPAMD_TASK_STAGE_COMPOSITES_POST = (1u << 14u),
-	RSPAMD_TASK_STAGE_IDEMPOTENT = (1u << 15u),
-	RSPAMD_TASK_STAGE_DONE = (1u << 16u),
-	RSPAMD_TASK_STAGE_REPLIED = (1u << 17u)
+	RSPAMD_TASK_STAGE_PRE_FILTERS = (1u << 5u),
+	RSPAMD_TASK_STAGE_FILTERS = (1u << 6u),
+	RSPAMD_TASK_STAGE_CLASSIFIERS_PRE = (1u << 7u),
+	RSPAMD_TASK_STAGE_CLASSIFIERS = (1u << 8u),
+	RSPAMD_TASK_STAGE_CLASSIFIERS_POST = (1u << 9u),
+	RSPAMD_TASK_STAGE_COMPOSITES = (1u << 10u),
+	RSPAMD_TASK_STAGE_POST_FILTERS = (1u << 11u),
+	RSPAMD_TASK_STAGE_LEARN_PRE = (1u << 12u),
+	RSPAMD_TASK_STAGE_LEARN = (1u << 13u),
+	RSPAMD_TASK_STAGE_LEARN_POST = (1u << 14u),
+	RSPAMD_TASK_STAGE_COMPOSITES_POST = (1u << 15u),
+	RSPAMD_TASK_STAGE_IDEMPOTENT = (1u << 16u),
+	RSPAMD_TASK_STAGE_DONE = (1u << 17u),
+	RSPAMD_TASK_STAGE_REPLIED = (1u << 18u)
 };
 
 #define RSPAMD_TASK_PROCESS_ALL (RSPAMD_TASK_STAGE_CONNECT | \


More information about the Commits mailing list