krb5 commit: Use k5_hashtab in KDC lookaside cache

Greg Hudson ghudson at mit.edu
Wed Aug 22 13:49:25 EDT 2018


https://github.com/krb5/krb5/commit/570dd10792fbba725a866320baece826ac981b4e
commit 570dd10792fbba725a866320baece826ac981b4e
Author: Greg Hudson <ghudson at mit.edu>
Date:   Sat Aug 4 20:23:11 2018 -0400

    Use k5_hashtab in KDC lookaside cache

 src/kdc/replay.c   |  125 +++++-----------
 src/kdc/t_replay.c |  415 +++-------------------------------------------------
 2 files changed, 60 insertions(+), 480 deletions(-)

diff --git a/src/kdc/replay.c b/src/kdc/replay.c
index caca783..5125bc6 100644
--- a/src/kdc/replay.c
+++ b/src/kdc/replay.c
@@ -26,23 +26,20 @@
 
 #include "k5-int.h"
 #include "k5-queue.h"
+#include "k5-hashtab.h"
 #include "kdc_util.h"
 #include "extern.h"
 
 #ifndef NOCACHE
 
 struct entry {
-    K5_LIST_ENTRY(entry) bucket_links;
-    K5_TAILQ_ENTRY(entry) expire_links;
+    K5_TAILQ_ENTRY(entry) links;
     int num_hits;
     krb5_timestamp timein;
     krb5_data req_packet;
     krb5_data reply_packet;
 };
 
-#ifndef LOOKASIDE_HASH_SIZE
-#define LOOKASIDE_HASH_SIZE 16384
-#endif
 #ifndef LOOKASIDE_MAX_SIZE
 #define LOOKASIDE_MAX_SIZE (10 * 1024 * 1024)
 #endif
@@ -50,7 +47,7 @@ struct entry {
 K5_LIST_HEAD(entry_list, entry);
 K5_TAILQ_HEAD(entry_queue, entry);
 
-static struct entry_list hash_table[LOOKASIDE_HASH_SIZE];
+static struct k5_hashtab *hash_table;
 static struct entry_queue expiration_queue;
 
 static int hits = 0;
@@ -58,50 +55,10 @@ static int calls = 0;
 static int max_hits_per_entry = 0;
 static int num_entries = 0;
 static size_t total_size = 0;
-static krb5_ui_4 seed;
 
 #define STALE_TIME      (2*60)            /* two minutes */
 #define STALE(ptr, now) (ts_after(now, ts_incr((ptr)->timein, STALE_TIME)))
 
-/* Return x rotated to the left by r bits. */
-static inline krb5_ui_4
-rotl32(krb5_ui_4 x, int r)
-{
-    return (x << r) | (x >> (32 - r));
-}
-
-/*
- * Return a non-cryptographic hash of data, seeded by seed (the global
- * variable), using the MurmurHash3 algorithm by Austin Appleby.  Return the
- * result modulo LOOKASIDE_HASH_SIZE.
- */
-static int
-murmurhash3(const krb5_data *data)
-{
-    const krb5_ui_4 c1 = 0xcc9e2d51, c2 = 0x1b873593;
-    const unsigned char *start = (unsigned char *)data->data, *endblocks, *p;
-    int tail_len = (data->length % 4);
-    krb5_ui_4 h = seed, final;
-
-    endblocks = start + data->length - tail_len;
-    for (p = start; p < endblocks; p += 4) {
-        h ^= rotl32(load_32_le(p) * c1, 15) * c2;
-        h = rotl32(h, 13) * 5 + 0xe6546b64;
-    }
-
-    final = 0;
-    final |= (tail_len >= 3) ? p[2] << 16 : 0;
-    final |= (tail_len >= 2) ? p[1] << 8 : 0;
-    final |= (tail_len >= 1) ? p[0] : 0;
-    h ^= rotl32(final * c1, 15) * c2;
-
-    h ^= data->length;
-    h = (h ^ (h >> 16)) * 0x85ebca6b;
-    h = (h ^ (h >> 13)) * 0xc2b2ae35;
-    h ^= h >> 16;
-    return h % LOOKASIDE_HASH_SIZE;
-}
-
 /* Return the rough memory footprint of an entry containing req and rep. */
 static size_t
 entry_size(const krb5_data *req, const krb5_data *rep)
@@ -117,35 +74,40 @@ insert_entry(krb5_context context, krb5_data *req, krb5_data *rep,
 {
     krb5_error_code ret;
     struct entry *entry;
-    krb5_ui_4 req_hash = murmurhash3(req);
     size_t esize = entry_size(req, rep);
 
     entry = calloc(1, sizeof(*entry));
     if (entry == NULL)
-        return NULL;
+        goto error;
     entry->timein = time;
 
     ret = krb5int_copy_data_contents(context, req, &entry->req_packet);
-    if (ret) {
-        free(entry);
-        return NULL;
-    }
+    if (ret)
+        goto error;
 
     if (rep != NULL) {
         ret = krb5int_copy_data_contents(context, rep, &entry->reply_packet);
-        if (ret) {
-            krb5_free_data_contents(context, &entry->req_packet);
-            free(entry);
-            return NULL;
-        }
+        if (ret)
+            goto error;
     }
 
-    K5_TAILQ_INSERT_TAIL(&expiration_queue, entry, expire_links);
-    K5_LIST_INSERT_HEAD(&hash_table[req_hash], entry, bucket_links);
+    ret = k5_hashtab_add(hash_table, entry->req_packet.data,
+                         entry->req_packet.length, entry);
+    if (ret)
+        goto error;
+    K5_TAILQ_INSERT_TAIL(&expiration_queue, entry, links);
     num_entries++;
     total_size += esize;
 
     return entry;
+
+error:
+    if (entry != NULL) {
+        krb5_free_data_contents(context, &entry->req_packet);
+        krb5_free_data_contents(context, &entry->reply_packet);
+        free(entry);
+    }
+    return NULL;
 }
 
 
@@ -155,38 +117,30 @@ discard_entry(krb5_context context, struct entry *entry)
 {
     total_size -= entry_size(&entry->req_packet, &entry->reply_packet);
     num_entries--;
-    K5_LIST_REMOVE(entry, bucket_links);
-    K5_TAILQ_REMOVE(&expiration_queue, entry, expire_links);
+    k5_hashtab_remove(hash_table, entry->req_packet.data,
+                      entry->req_packet.length);
+    K5_TAILQ_REMOVE(&expiration_queue, entry, links);
     krb5_free_data_contents(context, &entry->req_packet);
     krb5_free_data_contents(context, &entry->reply_packet);
     free(entry);
 }
 
-/* Return the entry for req_packet, or NULL if we don't have one. */
-static struct entry *
-find_entry(krb5_data *req_packet)
-{
-    krb5_ui_4 hash = murmurhash3(req_packet);
-    struct entry *e;
-
-    K5_LIST_FOREACH(e, &hash_table[hash], bucket_links) {
-        if (data_eq(e->req_packet, *req_packet))
-            return e;
-    }
-    return NULL;
-}
-
 /* Initialize the lookaside cache structures and randomize the hash seed. */
 krb5_error_code
 kdc_init_lookaside(krb5_context context)
 {
-    krb5_data d = make_data(&seed, sizeof(seed));
-    int i;
-
-    for (i = 0; i < LOOKASIDE_HASH_SIZE; i++)
-        K5_LIST_INIT(&hash_table[i]);
+    krb5_error_code ret;
+    uint8_t seed[K5_HASH_SEED_LEN];
+    krb5_data d = make_data(seed, sizeof(seed));
+
+    ret = krb5_c_random_make_octets(context, &d);
+    if (ret)
+        return ret;
+    ret = k5_hashtab_create(seed, 8192, &hash_table);
+    if (ret)
+        return ret;
     K5_TAILQ_INIT(&expiration_queue);
-    return krb5_c_random_make_octets(context, &d);
+    return 0;
 }
 
 /* Remove the lookaside cache entry for a packet. */
@@ -195,7 +149,7 @@ kdc_remove_lookaside(krb5_context kcontext, krb5_data *req_packet)
 {
     struct entry *e;
 
-    e = find_entry(req_packet);
+    e = k5_hashtab_get(hash_table, req_packet->data, req_packet->length);
     if (e != NULL)
         discard_entry(kcontext, e);
 }
@@ -217,7 +171,7 @@ kdc_check_lookaside(krb5_context kcontext, krb5_data *req_packet,
     *reply_packet_out = NULL;
     calls++;
 
-    e = find_entry(req_packet);
+    e = k5_hashtab_get(hash_table, req_packet->data, req_packet->length);
     if (e == NULL)
         return FALSE;
 
@@ -251,7 +205,7 @@ kdc_insert_lookaside(krb5_context kcontext, krb5_data *req_packet,
         return;
 
     /* Purge stale entries and limit the total size of the entries. */
-    K5_TAILQ_FOREACH_SAFE(e, &expiration_queue, expire_links, next) {
+    K5_TAILQ_FOREACH_SAFE(e, &expiration_queue, links, next) {
         if (!STALE(e, timenow) && total_size + esize <= LOOKASIDE_MAX_SIZE)
             break;
         max_hits_per_entry = max(max_hits_per_entry, e->num_hits);
@@ -268,9 +222,10 @@ kdc_free_lookaside(krb5_context kcontext)
 {
     struct entry *e, *next;
 
-    K5_TAILQ_FOREACH_SAFE(e, &expiration_queue, expire_links, next) {
+    K5_TAILQ_FOREACH_SAFE(e, &expiration_queue, links, next) {
         discard_entry(kcontext, e);
     }
+    k5_hashtab_free(hash_table);
 }
 
 #endif /* NOCACHE */
diff --git a/src/kdc/t_replay.c b/src/kdc/t_replay.c
index 00bb390..57aad88 100644
--- a/src/kdc/t_replay.c
+++ b/src/kdc/t_replay.c
@@ -64,14 +64,9 @@ __wrap_krb5_timeofday(krb5_context context, krb5_timestamp *timeret)
     cmocka_unit_test_setup_teardown(fn, setup_lookaside, destroy_lookaside)
 
 /*
- * Helper functions and values
+ * Helper functions
  */
 
-/* Two packet datas that give the same murmur hash using the test seed */
-static char hc_data1[8] = { 0X33, 0X6F, 0X65, 0X58, 0X48, 0XF7, 0X3A, 0XD3 };
-static char hc_data2[8] = { 0X91, 0XB5, 0X4C, 0XD8, 0XAD, 0X92, 0XBF, 0X6B };
-static uint32_t hc_hash = 0x00000F94;
-
 static void
 time_return(krb5_timestamp time, krb5_error_code err)
 {
@@ -115,7 +110,6 @@ setup_lookaside(void **state)
         return ret;
 
     /* Ensure some vars are all set to initial values */
-    seed = SEED;
     hits = 0;
     calls = 0;
     max_hits_per_entry = 0;
@@ -133,124 +127,6 @@ destroy_lookaside(void **state)
 }
 
 /*
- * rotl32 tests
- */
-
-static void
-test_rotl32_rand_1bit(void **state)
-{
-    uint32_t result;
-
-    result = rotl32(0x1B8578BA, 1);
-    assert_true(result == 0x370AF174);
-}
-
-static void
-test_rotl32_rand_2bit(void **state)
-{
-    uint32_t result;
-
-    result = rotl32(0x1B8578BA, 2);
-    assert_true(result == 0x6E15E2E8);
-}
-
-static void
-test_rotl32_rand_3bit(void **state)
-{
-    uint32_t result;
-
-    result = rotl32(0x1B8578BA, 3);
-    assert_true(result == 0xDC2BC5D0);
-}
-
-static void
-test_rotl32_one(void **state)
-{
-    uint32_t result;
-
-    result = rotl32(0x00000001, 1);
-    assert_true(result == 0x00000002);
-}
-
-static void
-test_rotl32_zero(void **state)
-{
-    uint32_t result;
-
-    result = rotl32(0x00000000, 1);
-    assert_true(result == 0x00000000);
-}
-
-static void
-test_rotl32_full(void **state)
-{
-    uint32_t result;
-
-    result = rotl32(0xFFFFFFFF, 1);
-    assert_true(result == 0xFFFFFFFF);
-}
-
-/*
- * murmurhash3 tests
- */
-
-static void
-test_murmurhash3_string(void **state)
-{
-    int result;
-    const krb5_data data = string2data("Don't mind me I'm just some random "
-                                       "data waiting to be hashed!");
-
-    result = murmurhash3(&data);
-    assert_int_equal(result, 0x000038FB);
-}
-
-static void
-test_murmurhash3_single_byte_changed(void **state)
-{
-    int result;
-    const krb5_data data = string2data("Don't mind me I'm just some random "
-                                       "data waiting to be hashed");
-
-    result = murmurhash3(&data);
-    assert_int_equal(result, 0x000007DC);
-}
-
-static void
-test_murmurhash3_string2(void **state)
-{
-    int result;
-    const krb5_data data = string2data("I'm completely different data "
-                                       "waiting for a hash :)");
-
-    result = murmurhash3(&data);
-    assert_int_equal(result, 0x000021AD);
-
-}
-
-static void
-test_murmurhash3_byte(void **state)
-{
-    int result;
-    char s = 's';
-    const krb5_data data = make_data(&s, sizeof(s));
-
-    result = murmurhash3(&data);
-    assert_int_equal(result, 0x000010EE);
-}
-
-static void
-test_murmurhash3_zero(void **state)
-{
-    int result;
-    char zero = 0;
-    const krb5_data data = make_data(&zero, sizeof(zero));
-
-    result = murmurhash3(&data);
-    assert_int_equal(result, 0x00003DFA);
-}
-
-/*
  * entry_size tests
  */
 
@@ -286,11 +162,10 @@ test_insert_entry(void **state)
     krb5_context context = *state;
     krb5_data req = string2data("I'm a test request");
     krb5_data rep = string2data("I'm a test response");
-    uint32_t req_hash = 0x000011BE;
 
     e = insert_entry(context, &req, &rep, 15);
 
-    assert_ptr_equal(K5_LIST_FIRST(&hash_table[req_hash]), e);
+    assert_ptr_equal(k5_hashtab_get(hash_table, req.data, req.length), e);
     assert_ptr_equal(K5_TAILQ_FIRST(&expiration_queue), e);
     assert_true(data_eq(e->req_packet, req));
     assert_true(data_eq(e->reply_packet, rep));
@@ -303,11 +178,10 @@ test_insert_entry_no_response(void **state)
     struct entry *e;
     krb5_context context = *state;
     krb5_data req = string2data("I'm a test request");
-    uint32_t req_hash = 0x000011BE;
 
     e = insert_entry(context, &req, NULL, 10);
 
-    assert_ptr_equal(K5_LIST_FIRST(&hash_table[req_hash]), e);
+    assert_ptr_equal(k5_hashtab_get(hash_table, req.data, req.length), e);
     assert_ptr_equal(K5_TAILQ_FIRST(&expiration_queue), e);
     assert_true(data_eq(e->req_packet, req));
     assert_int_equal(e->reply_packet.length, 0);
@@ -321,13 +195,11 @@ test_insert_entry_multiple(void **state)
     krb5_context context = *state;
     krb5_data req1 = string2data("I'm a test request");
     krb5_data rep1 = string2data("I'm a test response");
-    uint32_t req_hash1 = 0x000011BE;
     krb5_data req2 = string2data("I'm a different test request");
-    uint32_t req_hash2 = 0x00003597;
 
     e1 = insert_entry(context, &req1, &rep1, 20);
 
-    assert_ptr_equal(K5_LIST_FIRST(&hash_table[req_hash1]), e1);
+    assert_ptr_equal(k5_hashtab_get(hash_table, req1.data, req1.length), e1);
     assert_ptr_equal(K5_TAILQ_FIRST(&expiration_queue), e1);
     assert_true(data_eq(e1->req_packet, req1));
     assert_true(data_eq(e1->reply_packet, rep1));
@@ -335,39 +207,13 @@ test_insert_entry_multiple(void **state)
 
     e2 = insert_entry(context, &req2, NULL, 30);
 
-    assert_ptr_equal(K5_LIST_FIRST(&hash_table[req_hash2]), e2);
+    assert_ptr_equal(k5_hashtab_get(hash_table, req2.data, req2.length), e2);
     assert_ptr_equal(K5_TAILQ_LAST(&expiration_queue,entry_queue), e2);
     assert_true(data_eq(e2->req_packet, req2));
     assert_int_equal(e2->reply_packet.length, 0);
     assert_int_equal(e2->timein, 30);
 }
 
-static void
-test_insert_entry_hash_collision(void **state)
-{
-    struct entry *e1, *e2;
-    krb5_context context = *state;
-    krb5_data req1 = make_data(hc_data1, sizeof(hc_data1));
-    krb5_data rep1 = string2data("I'm a test response");
-    krb5_data req2 = make_data(hc_data2, sizeof(hc_data2));
-
-    e1 = insert_entry(context, &req1, &rep1, 40);
-
-    assert_ptr_equal(K5_LIST_FIRST(&hash_table[hc_hash]), e1);
-    assert_ptr_equal(K5_TAILQ_FIRST(&expiration_queue), e1);
-    assert_true(data_eq(e1->req_packet, req1));
-    assert_true(data_eq(e1->reply_packet, rep1));
-    assert_int_equal(e1->timein, 40);
-
-    e2 = insert_entry(context, &req2, NULL, 50);
-
-    assert_ptr_equal(K5_LIST_FIRST(&hash_table[hc_hash]), e2);
-    assert_ptr_equal(K5_TAILQ_LAST(&expiration_queue,entry_queue), e2);
-    assert_true(data_eq(e2->req_packet, req2));
-    assert_int_equal(e2->reply_packet.length, 0);
-    assert_int_equal(e2->timein, 50);
-}
-
 /*
  * discard_entry tests
  */
@@ -379,12 +225,11 @@ test_discard_entry(void **state)
     krb5_context context = *state;
     krb5_data req = string2data("I'm a test request");
     krb5_data rep = string2data("I'm a test response");
-    uint32_t req_hash = 0x000011BE;
 
     e = insert_entry(context, &req, &rep, 0);
     discard_entry(context, e);
 
-    assert_null(K5_LIST_FIRST(&hash_table[req_hash]));
+    assert_null(k5_hashtab_get(hash_table, req.data, req.length));
     assert_int_equal(num_entries, 0);
     assert_int_equal(total_size, 0);
 }
@@ -395,102 +240,15 @@ test_discard_entry_no_response(void **state)
     struct entry *e;
     krb5_context context = *state;
     krb5_data req = string2data("I'm a test request");
-    uint32_t req_hash = 0x000011BE;
 
     e = insert_entry(context, &req, NULL, 0);
     discard_entry(context, e);
 
-    assert_null(K5_LIST_FIRST(&hash_table[req_hash]));
+    assert_null(k5_hashtab_get(hash_table, req.data, req.length));
     assert_int_equal(num_entries, 0);
     assert_int_equal(total_size, 0);
 }
 
-static void
-test_discard_entry_hash_collision(void **state)
-{
-    struct entry *e1, *e2, *e_tmp;
-    krb5_context context = *state;
-    krb5_data req1 = make_data(hc_data1, sizeof(hc_data1));
-    krb5_data rep1 = string2data("I'm a test response");
-    krb5_data req2 = make_data(hc_data2, sizeof(hc_data2));
-    krb5_data rep2 = string2data("I'm a test response");
-
-    e1 = insert_entry(context, &req1, &rep1, 0);
-    e2 = insert_entry(context, &req2, &rep2, 0);
-
-    discard_entry(context, e1);
-
-    K5_LIST_FOREACH(e_tmp, &hash_table[hc_hash], bucket_links)
-        assert_ptr_not_equal(e_tmp, e1);
-
-    assert_ptr_equal(K5_LIST_FIRST(&hash_table[hc_hash]), e2);
-    assert_int_equal(num_entries, 1);
-    assert_int_equal(total_size, entry_size(&req2, &rep2));
-
-    discard_entry(context, e2);
-
-    assert_null(K5_LIST_FIRST(&hash_table[hc_hash]));
-    assert_int_equal(num_entries, 0);
-    assert_int_equal(total_size, 0);
-}
-
-/*
- * find_entry tests
- */
-
-static void
-test_find_entry(void **state)
-{
-    struct entry *e, *result;
-    krb5_context context = *state;
-    krb5_data req = string2data("I'm a test request");
-    krb5_data rep = string2data("I'm a test response");
-
-    e = insert_entry(context, &req, &rep, 0);
-
-    result = find_entry(&req);
-    assert_ptr_equal(result, e);
-}
-
-static void
-test_find_entry_multiple(void **state)
-{
-    struct entry *e1, *e2, *result;
-    krb5_context context = *state;
-    krb5_data req1 = string2data("I'm a test request");
-    krb5_data rep1 = string2data("I'm a test response");
-    krb5_data req2 = string2data("I'm a different test request");
-
-    e1 = insert_entry(context, &req1, &rep1, 0);
-    e2 = insert_entry(context, &req2, NULL, 0);
-
-    result = find_entry(&req1);
-    assert_ptr_equal(result, e1);
-
-    result = find_entry(&req2);
-    assert_ptr_equal(result, e2);
-}
-
-static void
-test_find_entry_hash_collision(void **state)
-{
-    struct entry *e1, *e2, *result;
-    krb5_context context = *state;
-    krb5_data req1 = make_data(hc_data1, sizeof(hc_data1));
-    krb5_data rep1 = string2data("I'm a test response");
-    krb5_data req2 = make_data(hc_data2, sizeof(hc_data2));
-    krb5_data rep2 = string2data("I'm a test response");
-
-    e1 = insert_entry(context, &req1, &rep1, 0);
-    e2 = insert_entry(context, &req2, &rep2, 0);
-
-    result = find_entry(&req1);
-    assert_ptr_equal(result, e1);
-
-    result = find_entry(&req2);
-    assert_ptr_equal(result, e2);
-}
-
 /*
  * kdc_remove_lookaside tests
  */
@@ -501,12 +259,11 @@ test_kdc_remove_lookaside(void **state)
     krb5_context context = *state;
     krb5_data req = string2data("I'm a test request");
     krb5_data rep = string2data("I'm a test response");
-    uint32_t req_hash = 0x000011BE;
 
     insert_entry(context, &req, &rep, 0);
     kdc_remove_lookaside(context, &req);
 
-    assert_null(K5_LIST_FIRST(&hash_table[req_hash]));
+    assert_null(k5_hashtab_get(hash_table, req.data, req.length));
     assert_int_equal(num_entries, 0);
     assert_int_equal(total_size, 0);
 }
@@ -531,13 +288,12 @@ test_kdc_remove_lookaside_unknown(void **state)
     krb5_context context = *state;
     krb5_data req1 = string2data("I'm a test request");
     krb5_data rep1 = string2data("I'm a test response");
-    uint32_t req_hash1 = 0x000011BE;
     krb5_data req2 = string2data("I'm a different test request");
 
     e = insert_entry(context, &req1, &rep1, 0);
     kdc_remove_lookaside(context, &req2);
 
-    assert_ptr_equal(K5_LIST_FIRST(&hash_table[req_hash1]), e);
+    assert_ptr_equal(k5_hashtab_get(hash_table, req1.data, req1.length), e);
     assert_int_equal(num_entries, 1);
     assert_int_equal(total_size, entry_size(&req1, &rep1));
 }
@@ -549,51 +305,21 @@ test_kdc_remove_lookaside_multiple(void **state)
     krb5_context context = *state;
     krb5_data req1 = string2data("I'm a test request");
     krb5_data rep1 = string2data("I'm a test response");
-    uint32_t req_hash1 = 0x000011BE;
     krb5_data req2 = string2data("I'm a different test request");
-    uint32_t req_hash2 = 0x00003597;
 
     e1 = insert_entry(context, &req1, &rep1, 0);
     insert_entry(context, &req2, NULL, 0);
 
     kdc_remove_lookaside(context, &req2);
 
-    assert_null(K5_LIST_FIRST(&hash_table[req_hash2]));
-    assert_ptr_equal(K5_LIST_FIRST(&hash_table[req_hash1]), e1);
+    assert_null(k5_hashtab_get(hash_table, req2.data, req2.length));
+    assert_ptr_equal(k5_hashtab_get(hash_table, req1.data, req1.length), e1);
     assert_int_equal(num_entries, 1);
     assert_int_equal(total_size, entry_size(&req1, &rep1));
 
     kdc_remove_lookaside(context, &req1);
 
-    assert_null(K5_LIST_FIRST(&hash_table[req_hash1]));
-    assert_int_equal(num_entries, 0);
-    assert_int_equal(total_size, 0);
-}
-
-static void
-test_kdc_remove_lookaside_hash_collision(void **state)
-{
-    struct entry *e1, *e2, *e_tmp;
-    krb5_context context = *state;
-    krb5_data req1 = make_data(hc_data1, sizeof(hc_data1));
-    krb5_data rep1 = string2data("I'm a test response");
-    krb5_data req2 = make_data(hc_data2, sizeof(hc_data2));
-
-    e1 = insert_entry(context, &req1, &rep1, 0);
-    e2 = insert_entry(context, &req2, NULL, 0);
-
-    kdc_remove_lookaside(context, &req1);
-
-    K5_LIST_FOREACH(e_tmp, &hash_table[hc_hash], bucket_links)
-        assert_ptr_not_equal(e_tmp, e1);
-
-    assert_ptr_equal(K5_LIST_FIRST(&hash_table[hc_hash]), e2);
-    assert_int_equal(num_entries, 1);
-    assert_int_equal(total_size, entry_size(&req2, NULL));
-
-    kdc_remove_lookaside(context, &req2);
-
-    assert_null(K5_LIST_FIRST(&hash_table[hc_hash]));
+    assert_null(k5_hashtab_get(hash_table, req1.data, req1.length));
     assert_int_equal(num_entries, 0);
     assert_int_equal(total_size, 0);
 }
@@ -712,41 +438,6 @@ test_kdc_check_lookaside_hit_multiple(void **state)
     assert_int_equal(e2->num_hits, 1);
 }
 
-static void
-test_kdc_check_lookaside_hit_hash_collision(void **state)
-{
-    struct entry *e1, *e2;
-    krb5_boolean result;
-    krb5_data *result_data;
-    krb5_context context = *state;
-    krb5_data req1 = make_data(hc_data1, sizeof(hc_data1));
-    krb5_data rep1 = string2data("I'm a test response");
-    krb5_data req2 = make_data(hc_data2, sizeof(hc_data2));
-
-    e1 = insert_entry(context, &req1, &rep1, 0);
-    e2 = insert_entry(context, &req2, NULL, 0);
-
-    result = kdc_check_lookaside(context, &req1, &result_data);
-
-    assert_true(result);
-    assert_true(data_eq(rep1, *result_data));
-    assert_int_equal(hits, 1);
-    assert_int_equal(e1->num_hits, 1);
-    assert_int_equal(e2->num_hits, 0);
-
-    krb5_free_data(context, result_data);
-
-    /* Set result_data so we can verify that it is reset to NULL. */
-    result_data = &req1;
-    result = kdc_check_lookaside(context, &req2, &result_data);
-
-    assert_true(result);
-    assert_null(result_data);
-    assert_int_equal(hits, 2);
-    assert_int_equal(e1->num_hits, 1);
-    assert_int_equal(e2->num_hits, 1);
-}
-
 /*
  * kdc_insert_lookaside tests
  */
@@ -757,13 +448,12 @@ test_kdc_insert_lookaside_single(void **state)
     krb5_context context = *state;
     krb5_data req = string2data("I'm a test request");
     krb5_data rep = string2data("I'm a test response");
-    uint32_t req_hash = 0x000011BE;
     struct entry *hash_ent, *exp_ent;
 
     time_return(0, 0);
     kdc_insert_lookaside(context, &req, &rep);
 
-    hash_ent = K5_LIST_FIRST(&hash_table[req_hash]);
+    hash_ent = k5_hashtab_get(hash_table, req.data, req.length);
     assert_non_null(hash_ent);
     assert_true(data_eq(hash_ent->req_packet, req));
     assert_true(data_eq(hash_ent->reply_packet, rep));
@@ -779,13 +469,12 @@ test_kdc_insert_lookaside_no_reply(void **state)
 {
     krb5_context context = *state;
     krb5_data req = string2data("I'm a test request");
-    uint32_t req_hash = 0x000011BE;
     struct entry *hash_ent, *exp_ent;
 
     time_return(0, 0);
     kdc_insert_lookaside(context, &req, NULL);
 
-    hash_ent = K5_LIST_FIRST(&hash_table[req_hash]);
+    hash_ent = k5_hashtab_get(hash_table, req.data, req.length);
     assert_non_null(hash_ent);
     assert_true(data_eq(hash_ent->req_packet, req));
     assert_int_equal(hash_ent->reply_packet.length, 0);
@@ -802,17 +491,15 @@ test_kdc_insert_lookaside_multiple(void **state)
     krb5_context context = *state;
     krb5_data req1 = string2data("I'm a test request");
     krb5_data rep1 = string2data("I'm a test response");
-    uint32_t req_hash1 = 0x000011BE;
     size_t e1_size = entry_size(&req1, &rep1);
     krb5_data req2 = string2data("I'm a different test request");
-    uint32_t req_hash2 = 0x00003597;
     size_t e2_size = entry_size(&req2, NULL);
     struct entry *hash1_ent, *hash2_ent, *exp_first, *exp_last;
 
     time_return(0, 0);
     kdc_insert_lookaside(context, &req1, &rep1);
 
-    hash1_ent = K5_LIST_FIRST(&hash_table[req_hash1]);
+    hash1_ent = k5_hashtab_get(hash_table, req1.data, req1.length);
     assert_non_null(hash1_ent);
     assert_true(data_eq(hash1_ent->req_packet, req1));
     assert_true(data_eq(hash1_ent->reply_packet, rep1));
@@ -825,7 +512,7 @@ test_kdc_insert_lookaside_multiple(void **state)
     time_return(0, 0);
     kdc_insert_lookaside(context, &req2, NULL);
 
-    hash2_ent = K5_LIST_FIRST(&hash_table[req_hash2]);
+    hash2_ent = k5_hashtab_get(hash_table, req2.data, req2.length);
     assert_non_null(hash2_ent);
     assert_true(data_eq(hash2_ent->req_packet, req2));
     assert_int_equal(hash2_ent->reply_packet.length, 0);
@@ -837,61 +524,21 @@ test_kdc_insert_lookaside_multiple(void **state)
 }
 
 static void
-test_kdc_insert_lookaside_hash_collision(void **state)
-{
-    krb5_context context = *state;
-    krb5_data req1 = make_data(hc_data1, sizeof(hc_data1));
-    krb5_data rep1 = string2data("I'm a test response");
-    size_t e1_size = entry_size(&req1, &rep1);
-    krb5_data req2 = make_data(hc_data2, sizeof(hc_data2));
-    size_t e2_size = entry_size(&req2, NULL);
-    struct entry *hash_ent, *exp_first, *exp_last;
-
-    time_return(0, 0);
-    kdc_insert_lookaside(context, &req1, &rep1);
-
-    hash_ent = K5_LIST_FIRST(&hash_table[hc_hash]);
-    assert_non_null(hash_ent);
-    assert_true(data_eq(hash_ent->req_packet, req1));
-    assert_true(data_eq(hash_ent->reply_packet, rep1));
-    exp_first = K5_TAILQ_FIRST(&expiration_queue);
-    assert_true(data_eq(exp_first->req_packet, req1));
-    assert_true(data_eq(exp_first->reply_packet, rep1));
-    assert_int_equal(num_entries, 1);
-    assert_int_equal(total_size, e1_size);
-
-    time_return(0, 0);
-    kdc_insert_lookaside(context, &req2, NULL);
-
-    hash_ent = K5_LIST_FIRST(&hash_table[hc_hash]);
-    assert_non_null(hash_ent);
-    assert_true(data_eq(hash_ent->req_packet, req2));
-    assert_int_equal(hash_ent->reply_packet.length, 0);
-    exp_last = K5_TAILQ_LAST(&expiration_queue, entry_queue);
-    assert_true(data_eq(exp_last->req_packet, req2));
-    assert_int_equal(exp_last->reply_packet.length, 0);
-    assert_int_equal(num_entries, 2);
-    assert_int_equal(total_size, e1_size + e2_size);
-}
-
-static void
 test_kdc_insert_lookaside_cache_expire(void **state)
 {
     struct entry *e;
     krb5_context context = *state;
     krb5_data req1 = string2data("I'm a test request");
     krb5_data rep1 = string2data("I'm a test response");
-    uint32_t req_hash1 = 0x000011BE;
     size_t e1_size = entry_size(&req1, &rep1);
     krb5_data req2 = string2data("I'm a different test request");
-    uint32_t req_hash2 = 0x00003597;
     size_t e2_size = entry_size(&req2, NULL);
     struct entry *hash1_ent, *hash2_ent, *exp_ent;
 
     time_return(0, 0);
     kdc_insert_lookaside(context, &req1, &rep1);
 
-    hash1_ent = K5_LIST_FIRST(&hash_table[req_hash1]);
+    hash1_ent = k5_hashtab_get(hash_table, req1.data, req1.length);
     assert_non_null(hash1_ent);
     assert_true(data_eq(hash1_ent->req_packet, req1));
     assert_true(data_eq(hash1_ent->reply_packet, rep1));
@@ -902,17 +549,17 @@ test_kdc_insert_lookaside_cache_expire(void **state)
     assert_int_equal(total_size, e1_size);
 
     /* Increase hits on entry */
-    e = find_entry(&req1);
+    e = k5_hashtab_get(hash_table, req1.data, req1.length);
     assert_non_null(e);
     e->num_hits = 5;
 
     time_return(STALE_TIME + 1, 0);
     kdc_insert_lookaside(context, &req2, NULL);
 
-    assert_null(K5_LIST_FIRST(&hash_table[req_hash1]));
+    assert_null(k5_hashtab_get(hash_table, req1.data, req1.length));
     assert_int_equal(max_hits_per_entry, 5);
 
-    hash2_ent = K5_LIST_FIRST(&hash_table[req_hash2]);
+    hash2_ent = k5_hashtab_get(hash_table, req2.data, req2.length);
     assert_non_null(hash2_ent);
     assert_true(data_eq(hash2_ent->req_packet, req2));
     assert_int_equal(hash2_ent-> reply_packet.length, 0);
@@ -928,19 +575,6 @@ int main()
     int ret;
 
     const struct CMUnitTest replay_tests[] = {
-        /* rotl32 tests */
-        cmocka_unit_test(test_rotl32_rand_1bit),
-        cmocka_unit_test(test_rotl32_rand_2bit),
-        cmocka_unit_test(test_rotl32_rand_3bit),
-        cmocka_unit_test(test_rotl32_one),
-        cmocka_unit_test(test_rotl32_zero),
-        cmocka_unit_test(test_rotl32_full),
-        /* murmurhash3 tests */
-        replay_unit_test(test_murmurhash3_string),
-        replay_unit_test(test_murmurhash3_single_byte_changed),
-        replay_unit_test(test_murmurhash3_string2),
-        replay_unit_test(test_murmurhash3_byte),
-        replay_unit_test(test_murmurhash3_zero),
         /* entry_size tests */
         replay_unit_test(test_entry_size_no_response),
         replay_unit_test(test_entry_size_w_response),
@@ -948,33 +582,24 @@ int main()
         replay_unit_test(test_insert_entry),
         replay_unit_test(test_insert_entry_no_response),
         replay_unit_test(test_insert_entry_multiple),
-        replay_unit_test(test_insert_entry_hash_collision),
         /* discard_entry tests */
         replay_unit_test(test_discard_entry),
         replay_unit_test(test_discard_entry_no_response),
-        replay_unit_test(test_discard_entry_hash_collision),
-        /* find_entry tests */
-        replay_unit_test(test_find_entry),
-        replay_unit_test(test_find_entry_multiple),
-        replay_unit_test(test_find_entry_hash_collision),
         /* kdc_remove_lookaside tests */
         replay_unit_test(test_kdc_remove_lookaside),
         replay_unit_test(test_kdc_remove_lookaside_empty_cache),
         replay_unit_test(test_kdc_remove_lookaside_unknown),
         replay_unit_test(test_kdc_remove_lookaside_multiple),
-        replay_unit_test(test_kdc_remove_lookaside_hash_collision),
         /* kdc_check_lookaside tests */
         replay_unit_test(test_kdc_check_lookaside_hit),
         replay_unit_test(test_kdc_check_lookaside_no_hit),
         replay_unit_test(test_kdc_check_lookaside_empty),
         replay_unit_test(test_kdc_check_lookaside_no_response),
         replay_unit_test(test_kdc_check_lookaside_hit_multiple),
-        replay_unit_test(test_kdc_check_lookaside_hit_hash_collision),
         /* kdc_insert_lookaside tests */
         replay_unit_test(test_kdc_insert_lookaside_single),
         replay_unit_test(test_kdc_insert_lookaside_no_reply),
         replay_unit_test(test_kdc_insert_lookaside_multiple),
-        replay_unit_test(test_kdc_insert_lookaside_hash_collision),
         replay_unit_test(test_kdc_insert_lookaside_cache_expire)
     };
 


More information about the cvs-krb5 mailing list