]> source.dussan.org Git - rspamd.git/commitdiff
Fix LRU hash in keypairs cache.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 3 Feb 2015 22:19:25 +0000 (22:19 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 3 Feb 2015 22:19:25 +0000 (22:19 +0000)
src/libutil/keypairs_cache.c

index 1e747028f04ef25ad8a895946b85464c979d4e37..c88333bd6df63f8a33bbbbe4a77a69619c2c35e6 100644 (file)
 #include "keypairs_cache.h"
 #include "keypair_private.h"
 #include "hash.h"
+#include "xxhash.h"
 
 struct rspamd_keypair_elt {
        guchar nm[crypto_box_BEFORENMBYTES];
+       guchar pair[crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES];
 };
 
 struct rspamd_keypair_cache {
        rspamd_lru_hash_t *hash;
 };
 
+static void
+rspamd_keypair_destroy (gpointer ptr)
+{
+       struct rspamd_keypair_elt *elt = (struct rspamd_keypair_elt *)ptr;
+
+       rspamd_explicit_memzero (elt, sizeof (*elt));
+       g_slice_free1 (sizeof (*elt), elt);
+}
+
+static guint
+rspamd_keypair_hash (gconstpointer ptr)
+{
+       struct rspamd_keypair_elt *elt = (struct rspamd_keypair_elt *)ptr;
+
+       return XXH32 (elt->pair, sizeof (elt->pair), 0xdeadbabe);
+}
+
+static gboolean
+rspamd_keypair_equal (gconstpointer p1, gconstpointer p2)
+{
+       struct rspamd_keypair_elt *e1 = (struct rspamd_keypair_elt *)p1,
+                       *e2 = (struct rspamd_keypair_elt *)p2;
+
+       return memcmp (e1->pair, e2->pair, sizeof (e1->pair)) == 0;
+}
+
 struct rspamd_keypair_cache *
 rspamd_keypair_cache_new (guint max_items)
 {
@@ -45,7 +73,8 @@ rspamd_keypair_cache_new (guint max_items)
        g_assert (max_items > 0);
 
        c = g_slice_alloc (sizeof (*c));
-       c->hash = rspamd_lru_hash_new (max_items, -1, g_free, g_free);
+       c->hash = rspamd_lru_hash_new_full (max_items, -1, NULL,
+                       rspamd_keypair_destroy, rspamd_keypair_hash, rspamd_keypair_equal);
 
        return c;
 }
@@ -56,18 +85,29 @@ rspamd_keypair_cache_process (struct rspamd_keypair_cache *c,
 {
        struct rspamd_http_keypair *kp_local = (struct rspamd_http_keypair *)lk,
                        *kp_remote = (struct rspamd_http_keypair *)rk;
-       guchar nm[crypto_box_BEFORENMBYTES];
+       struct rspamd_keypair_elt search, *new;
 
        g_assert (kp_local != NULL);
        g_assert (kp_remote != NULL);
 
-       /*
-        * XXX: at this point we do nothing, since LRU hash is completely broken
-        * and useless for our purposes
-        */
-       crypto_box_beforenm (nm, kp_remote->pk, kp_local->sk);
-       memcpy (kp_remote->nm, nm, sizeof (nm));
-       memcpy (kp_local->nm, nm, sizeof (nm));
+       memcpy (search.pair, kp_remote->pk, crypto_box_PUBLICKEYBYTES);
+       memcpy (&search.pair[crypto_box_PUBLICKEYBYTES], kp_local->sk,
+                       crypto_box_SECRETKEYBYTES);
+       new = rspamd_lru_hash_lookup (c->hash, &search, time (NULL));
+
+       if (new == NULL) {
+               new = g_slice_alloc (sizeof (*new));
+               memcpy (new->pair, kp_remote->pk, crypto_box_PUBLICKEYBYTES);
+               memcpy (&new->pair[crypto_box_PUBLICKEYBYTES], kp_local->sk,
+                               crypto_box_SECRETKEYBYTES);
+               crypto_box_beforenm (new->nm, kp_remote->pk, kp_local->sk);
+               rspamd_lru_hash_insert (c->hash, new, new, time (NULL), -1);
+       }
+
+       g_assert (new != NULL);
+
+       memcpy (kp_remote->nm, new->nm, crypto_box_BEFORENMBYTES);
+       memcpy (kp_local->nm, new->nm, crypto_box_BEFORENMBYTES);
 }
 
 void