From: Vsevolod Stakhov Date: Thu, 6 May 2010 16:01:20 +0000 (+0400) Subject: * Support versions of hashes file X-Git-Tag: 0.3.0~17 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=222d164e6ef4727798babb4918f8d489f91d5857;p=rspamd.git * Support versions of hashes file --- diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c index 0f1d47ac7..3be999720 100644 --- a/src/fuzzy_storage.c +++ b/src/fuzzy_storage.c @@ -57,6 +57,10 @@ #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) { diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c index 279d97394..a1637c0cf 100644 --- a/src/plugins/fuzzy_check.c +++ b/src/plugins/fuzzy_check.c @@ -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;