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