]> source.dussan.org Git - rspamd.git/commitdiff
Fix serializing of hyperscan regexps
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 7 Dec 2015 18:26:21 +0000 (18:26 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 7 Dec 2015 18:26:21 +0000 (18:26 +0000)
src/hs_helper.c
src/libserver/re_cache.c
src/libserver/re_cache.h

index 0e912daa174869399529f2ec001be7b34472d970..220224572fe2494aa63774906046555306c1d034 100644 (file)
@@ -127,6 +127,7 @@ start_hs_helper (struct rspamd_worker *worker)
        struct hs_helper_ctx *ctx = worker->ctx;
        GError *err = NULL;
        struct rspamd_srv_command srv_cmd;
+       gint ncompiled;
 
        ctx->ev_base = rspamd_prepare_worker (worker,
                        "hs_helper",
@@ -136,9 +137,9 @@ start_hs_helper (struct rspamd_worker *worker)
                msg_warn ("cannot cleanup cache dir '%s'", ctx->hs_dir);
        }
 
-       if (!rspamd_re_cache_compile_hyperscan (ctx->cfg->re_cache,
+       if ((ncompiled = rspamd_re_cache_compile_hyperscan (ctx->cfg->re_cache,
                        ctx->hs_dir,
-                       &err)) {
+                       &err)) == -1) {
                msg_err ("failed to compile re cache: %e", err);
                g_error_free (err);
 
@@ -146,6 +147,9 @@ start_hs_helper (struct rspamd_worker *worker)
                exit (EXIT_SUCCESS);
        }
 
+       msg_info ("compiled %d regular expressions to the hyperscan tree",
+                       ncompiled);
+
        event_base_loop (ctx->ev_base, 0);
        rspamd_worker_block_signals ();
 
index b6ee1a2c41c3317dfba16ef4abcdefbb73a26ac6..e3d7ec075fee3f3f643ce449bd0a352ad88431f6 100644 (file)
@@ -631,7 +631,7 @@ rspamd_re_cache_type_from_string (const char *str)
        return ret;
 }
 
-gboolean
+gint
 rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
                const char *cache_dir,
                GError **err)
@@ -641,7 +641,7 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
 
 #ifndef WITH_HYPERSCAN
        g_set_error (err, rspamd_re_cache_quark (), EINVAL, "hyperscan is disabled");
-       return FALSE;
+       return -1;
 #else
        GHashTableIter it, cit;
        gpointer k, v;
@@ -654,7 +654,8 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
        guint *hs_flags = NULL;
        const gchar **hs_pats = NULL;
        gchar *hs_serialized;
-       gsize serialized_len;
+       gsize serialized_len, total = 0;
+       struct iovec iov[3];
 
        g_hash_table_iter_init (&it, cache->re_classes);
 
@@ -667,7 +668,7 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
                if (fd == -1) {
                        g_set_error (err, rspamd_re_cache_quark (), errno, "cannot open file "
                                        "%s: %s", path, strerror (errno));
-                       return FALSE;
+                       return -1;
                }
 
                g_hash_table_iter_init (&cit, re_class->re);
@@ -740,11 +741,10 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
                                close (fd);
                                hs_free_compile_error (hs_errors);
 
-                               return FALSE;
+                               return -1;
                        }
 
                        g_free (hs_flags);
-                       g_free (hs_ids);
                        g_free (hs_pats);
 
                        if (hs_serialize_database (test_db, &hs_serialized,
@@ -756,31 +756,45 @@ rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
                                                re_class->hash);
 
                                close (fd);
+                               g_free (hs_ids);
                                hs_free_database (test_db);
 
-                               return FALSE;
+                               return -1;
                        }
 
                        hs_free_database (test_db);
 
-                       if (write (fd, hs_serialized, serialized_len) != (gssize)serialized_len) {
+                       /* Write N, then all ID's and then the compiled structure */
+                       iov[0].iov_base = &n;
+                       iov[0].iov_len = sizeof (n);
+                       iov[1].iov_base = hs_ids;
+                       iov[1].iov_len = sizeof (*hs_ids) * n;
+                       iov[2].iov_base = hs_serialized;
+                       iov[2].iov_len = serialized_len;
+
+                       if (writev (fd, iov, 3) !=
+                                       (gssize)serialized_len + sizeof (n) + sizeof (*hs_ids) * n) {
                                g_set_error (err,
                                                rspamd_re_cache_quark (),
                                                errno,
                                                "cannot serialize tree of regexp to %s: %s",
                                                path, strerror (errno));
                                close (fd);
+                               g_free (hs_ids);
                                g_free (hs_serialized);
 
-                               return FALSE;
+                               return -1;
                        }
 
+                       total += n;
+
                        g_free (hs_serialized);
+                       g_free (hs_ids);
                }
 
                close (fd);
        }
 
-       return TRUE;
+       return total;
 #endif
 }
index 5093689a608dbdd7348ededcbdc65aaa695aaaaf..0e1e6ecc820508b64e5596a388a3a6288914cf78 100644 (file)
@@ -129,7 +129,7 @@ enum rspamd_re_type rspamd_re_cache_type_from_string (const char *str);
 /**
  * Compile expressions to the hyperscan tree and store in the `cache_dir`
  */
-gboolean rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
+gint rspamd_re_cache_compile_hyperscan (struct rspamd_re_cache *cache,
                const char *cache_dir,
                GError **err);