aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2010-05-06 20:01:20 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2010-05-06 20:01:20 +0400
commit222d164e6ef4727798babb4918f8d489f91d5857 (patch)
tree0e553991f53a6d4dc66833d2d44ab5ba89640504 /src
parent91e513035a1ac2ada85b42cc4fa4f4d08d2397fc (diff)
downloadrspamd-222d164e6ef4727798babb4918f8d489f91d5857.tar.gz
rspamd-222d164e6ef4727798babb4918f8d489f91d5857.zip
* Support versions of hashes file
Diffstat (limited to 'src')
-rw-r--r--src/fuzzy_storage.c65
-rw-r--r--src/plugins/fuzzy_check.c2
2 files changed, 60 insertions, 7 deletions
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;