]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Distinguish empty and non-empty prefilters
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 18 Aug 2019 08:32:21 +0000 (09:32 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 18 Aug 2019 08:32:21 +0000 (09:32 +0100)
src/libserver/rspamd_symcache.c
src/libserver/task.c
src/libserver/task.h

index f91aa9a22834282bcda2a6b59195ad4bfb2a4233..71d3ab5e8e3f5cb9e1087a37cf39e026b0fab07a 100644 (file)
@@ -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);
                }
 
index acec922a759aad77aba50f34c2f3d85d95df4541..e9a63cbad019c17103757eb3f9347116f817dc69 100644 (file)
@@ -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);
index 28e0dc0703529fb08303a3f549aea5aa2139fb75..573f6d9b708fbfc3445d52d4df2d79da9692c4d7 100644 (file)
@@ -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 | \