From 5f7c522cdd27610bc816d20235f2a9088de2de08 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 3 Feb 2015 22:19:25 +0000 Subject: [PATCH] Fix LRU hash in keypairs cache. --- src/libutil/keypairs_cache.c | 58 ++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/src/libutil/keypairs_cache.c b/src/libutil/keypairs_cache.c index 1e747028f..c88333bd6 100644 --- a/src/libutil/keypairs_cache.c +++ b/src/libutil/keypairs_cache.c @@ -28,15 +28,43 @@ #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 -- 2.39.5