]> source.dussan.org Git - rspamd.git/commitdiff
* Support versions of hashes file
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 6 May 2010 16:01:20 +0000 (20:01 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 6 May 2010 16:01:20 +0000 (20:01 +0400)
src/fuzzy_storage.c
src/plugins/fuzzy_check.c

index 0f1d47ac7e81b6fff86e6e97451b29f0baa4c922..3be9997208a821518dc7851ab44b135a388fd5a0 100644 (file)
 #define MAX_RETRIES 40
 /* Weight of hash to consider it frequent */
 #define DEFAULT_FREQUENT_SCORE 100
+/* Magic sequence for hashes file */
+#define FUZZY_FILE_MAGIC "rsh"
+/* Current version of fuzzy hash file format */
+#define CURRENT_FUZZY_VERSION 1
 
 static GQueue                  *hashes[BUCKETS];
 static GQueue                  *frequent;
@@ -82,6 +86,7 @@ struct rspamd_fuzzy_node {
        fuzzy_hash_t                    h;
 };
 
+
 #ifndef HAVE_SA_SIGINFO
 static void
 sig_handler (int signo)
@@ -116,7 +121,7 @@ static void
 sync_cache (struct rspamd_worker *wrk)
 {
        int                             fd, i;
-       char                           *filename, *exp_str;
+       char                           *filename, *exp_str, header[4];
        GList                          *cur, *tmp;
        struct rspamd_fuzzy_node       *node;
        uint64_t                        expire, now;
@@ -151,6 +156,14 @@ sync_cache (struct rspamd_worker *wrk)
        (void)lock_file (fd, FALSE);
 
        now = (uint64_t) time (NULL);
+       
+       /* Fill header */
+       memcpy (header, FUZZY_FILE_MAGIC, 3);
+       header[3] = (char)CURRENT_FUZZY_VERSION;
+       if (write (fd, header, sizeof (header)) == -1) {
+               msg_err ("cannot write file %s while writing header: %s", filename, strerror (errno));
+               goto end;
+       }
 
 #ifdef WITH_JUDY
        if (use_judy) {
@@ -172,6 +185,7 @@ sync_cache (struct rspamd_worker *wrk)
                        }
                        if (write (fd, node, sizeof (struct rspamd_fuzzy_node)) == -1) {
                                msg_err ("cannot write file %s: %s", filename, strerror (errno));
+                               goto end;
                        }
                        pvalue = JudySLNext (jtree, indexbuf, PJE0);
                }
@@ -203,6 +217,7 @@ sync_cache (struct rspamd_worker *wrk)
                        }
                        if (write (fd, node, sizeof (struct rspamd_fuzzy_node)) == -1) {
                                msg_err ("cannot write file %s: %s", filename, strerror (errno));
+                               goto end;
                        }
                        cur = g_list_next (cur);
                }
@@ -211,6 +226,7 @@ sync_cache (struct rspamd_worker *wrk)
        }
 #endif
 
+end:
        (void)unlock_file (fd, FALSE);
        close (fd);
 }
@@ -239,6 +255,7 @@ sigusr_handler (int fd, short what, void *arg)
        struct rspamd_worker           *worker = (struct rspamd_worker *)arg;
        /* Do not accept new connections, preparing to end worker's process */
        struct timeval                  tv;
+
        tv.tv_sec = SOFT_SHUTDOWN_TIME;
        tv.tv_usec = 0;
        event_del (&worker->sig_ev);
@@ -253,10 +270,15 @@ sigusr_handler (int fd, short what, void *arg)
 static                          gboolean
 read_hashes_file (struct rspamd_worker *wrk)
 {
-       int                             r, fd, i;
+       int                             r, fd, i, version = 0;
        struct stat                     st;
-       char                           *filename;
+       char                           *filename, header[4];
        struct rspamd_fuzzy_node       *node;
+       struct {
+               int32_t                         value;
+               uint64_t                        time;
+               fuzzy_hash_t                    h;
+       }                                                               legacy_node;
 #ifdef WITH_JUDY
        PPvoid_t                         pvalue;
 
@@ -287,11 +309,42 @@ read_hashes_file (struct rspamd_worker *wrk)
 
        fstat (fd, &st);
 
+       /* First of all try to read magic and version number */
+       if ((r = read (fd, header, sizeof (header))) == sizeof (header)) {
+               if (memcmp (header, FUZZY_FILE_MAGIC, sizeof (header) - 1) == 0) {
+                       /* We have version in last byte of header */
+                       version = (int)header[3];
+                       if (version > CURRENT_FUZZY_VERSION) {
+                               msg_err ("unsupported version of fuzzy hash file: %d", version);
+                               return FALSE;
+                       }
+               }
+               else {
+                       /* Old version */
+                       version = 0;
+                       msg_info ("got old version of fuzzy hashes storage, it would be converted to new version %d automatically", CURRENT_FUZZY_VERSION);
+                       /* Rewind file */
+                       (void)lseek (fd, 0, SEEK_SET);
+               }
+       }
+
        for (;;) {
                node = g_malloc (sizeof (struct rspamd_fuzzy_node));
-               r = read (fd, node, sizeof (struct rspamd_fuzzy_node));
-               if (r != sizeof (struct rspamd_fuzzy_node)) {
-                       break;
+               if (version == 0) {
+                       r = read (fd, &legacy_node, sizeof (legacy_node));
+                       if (r != sizeof (legacy_node)) {
+                               break;
+                       }
+                       node->value = legacy_node.value;
+                       node->time = legacy_node.time;
+                       memcpy (&node->h, &legacy_node.h, sizeof (fuzzy_hash_t));
+                       node->flag = 0;
+               }
+               else {
+                       r = read (fd, node, sizeof (struct rspamd_fuzzy_node));
+                       if (r != sizeof (struct rspamd_fuzzy_node)) {
+                               break;
+                       }
                }
 #ifdef WITH_JUDY
                if (use_judy) {
index 279d97394addff5e419bd606418eb237dbb5011e..a1637c0cf1bab5a4c9981ef0a654af9e2cf05fc5 100644 (file)
@@ -225,7 +225,7 @@ fuzzy_check_module_init (struct config_file *cfg, struct module_ctx **ctx)
        fuzzy_module_ctx->fuzzy_pool = memory_pool_new (memory_pool_get_size ());
        fuzzy_module_ctx->servers = NULL;
        fuzzy_module_ctx->servers_num = 0;
-       fuzzy_module_ctx->flags = g_hash_table_new (g_int_hash, g_int_equal);
+       fuzzy_module_ctx->flags = g_hash_table_new (g_direct_hash, g_direct_equal);
 
        *ctx = (struct module_ctx *)fuzzy_module_ctx;