]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Use mumhash by default for incremental hashing
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 20 Jun 2016 14:48:21 +0000 (15:48 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 20 Jun 2016 14:48:21 +0000 (15:48 +0100)
src/libcryptobox/cryptobox.c
src/libcryptobox/cryptobox.h
src/rspamd.c

index 71180da12b07a7f8bcf13270f1794cbbf4ea2b84..08ae1fd8fce0a0d69d5815bbc09034f6883cfb9e 100644 (file)
@@ -1412,44 +1412,77 @@ void rspamd_cryptobox_hash (guchar *out,
        rspamd_cryptobox_hash_final (&st, out);
 }
 
+/* MUST be 64 bytes at maximum */
+struct rspamd_cryptobox_fast_hash_state_real {
+       guint64 h;  /* current hash value */
+       guint64 pos; /* pos in bytes in the buf */
+       guint64 buf;
+};
 
 void
 rspamd_cryptobox_fast_hash_init (rspamd_cryptobox_fast_hash_state_t *st,
                guint64 seed)
 {
-#if defined(__LP64__) || defined(_LP64)
-       XXH64_state_t *rst = (XXH64_state_t *)st;
-       XXH64_reset (rst, seed);
-#else
-       XXH32_state_t *rst = (XXH32_state_t *)st;
-       XXH32_reset (rst, seed);
-#endif
+       struct rspamd_cryptobox_fast_hash_state_real *rst =
+                       (struct rspamd_cryptobox_fast_hash_state_real *)st;
+
+       memset (rst, 0, sizeof (*rst));
+       rst->h = seed;
 }
 
 void
 rspamd_cryptobox_fast_hash_update (rspamd_cryptobox_fast_hash_state_t *st,
                const void *data, gsize len)
 {
-#if defined(__LP64__) || defined(_LP64)
-       XXH64_state_t *rst = (XXH64_state_t *)st;
-       XXH64_update (rst, data, len);
+       struct rspamd_cryptobox_fast_hash_state_real *rst =
+                       (struct rspamd_cryptobox_fast_hash_state_real *)st;
+       const guchar *d = data;
+       guint leftover;
+       guint64 n;
+
+       leftover = rst->pos;
+
+       if (leftover > 0 && len + leftover >= 8) {
+               n = sizeof (rst->buf) - leftover;
+               memcpy (((guchar *)&rst->buf) + leftover, d, n);
+               d += n;
+               len -= n;
+               rst->h = mum_hash_step (rst->h, rst->buf);
+               rst->buf = 0;
+       }
+
+       while (len > 8) {
+#ifdef _MUM_UNALIGNED_ACCESS
+               rst->h = mum_hash_step (rst->h, *(guint64 *)d);
 #else
-       XXH32_state_t *rst = (XXH32_state_t *)st;
-       XXH32_update (rst, data, len);
+               memcpy (&n, d, sizeof (n));
+               rst->h = mum_hash_step (rst->h, n);
 #endif
+               len -= 8;
+               d += 8;
+       }
+
+       if (len > 0 && rst->pos + len <= 8) {
+               memcpy (((guchar *)&rst->buf) + rst->pos, d, len);
+               rst->pos += len;
+       }
 }
 
 guint64
 rspamd_cryptobox_fast_hash_final (rspamd_cryptobox_fast_hash_state_t *st)
 {
-#if defined(__LP64__) || defined(_LP64)
-       XXH64_state_t *rst = (XXH64_state_t *)st;
-       return XXH64_digest (rst);
-#else
-       XXH32_state_t *rst = (XXH32_state_t *)st;
-       XXH32_digest (rst);
-#endif
+       struct rspamd_cryptobox_fast_hash_state_real *rst =
+                       (struct rspamd_cryptobox_fast_hash_state_real *)st;
+       guint leftover;
+
+       leftover = rst->pos;
+
+       if (leftover > 0) {
+               memset (((guchar *)&rst->buf) + leftover, 0, sizeof (rst->buf) - leftover);
+               rst->h = mum_hash_step (rst->h, rst->buf);
+       }
 
+       return rst->h;
 }
 
 /**
index 6facf0a0e99e38b281ff311ac4afeec4c5e66cf0..13a3b91216aba25fdeeceeab1555e6a6024b5d39 100644 (file)
@@ -326,7 +326,7 @@ void rspamd_cryptobox_hash (guchar *out,
 
 /* Non crypto hash IUF interface */
 typedef struct RSPAMD_ALIGNED(32) rspamd_cryptobox_fast_hash_state_s  {
-       unsigned char opaque[88];
+       unsigned char opaque[64];
 } rspamd_cryptobox_fast_hash_state_t;
 
 /**
index 922327f3840916e17a4e86866ef70fabf10e32bd..eaf6c6d30952c55d4e20f32b4ad02d16eec1d260 100644 (file)
@@ -508,6 +508,7 @@ spawn_workers (struct rspamd_main *rspamd_main, struct event_base *ev_base)
                        if (cf->worker->flags & RSPAMD_WORKER_HAS_SOCKET) {
                                LL_FOREACH (cf->bind_conf, bcf) {
                                        key = make_listen_key (bcf);
+
                                        if ((p =
                                                g_hash_table_lookup (listen_sockets,
                                                                GINT_TO_POINTER (key))) == NULL) {