From: Greg Hudson Date: Sun, 5 Aug 2018 00:23:11 +0000 (-0400) Subject: Use k5_hashtab in KDC lookaside cache X-Git-Tag: krb5-1.17-beta1~58 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=570dd10792fbba725a866320baece826ac981b4e;p=thirdparty%2Fkrb5.git Use k5_hashtab in KDC lookaside cache --- diff --git a/src/kdc/replay.c b/src/kdc/replay.c index caca783bf1..5125bc63c1 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 00bb390126..57aad886cd 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; @@ -132,124 +126,6 @@ destroy_lookaside(void **state) return 0; } -/* - * 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); @@ -836,44 +523,6 @@ test_kdc_insert_lookaside_multiple(void **state) assert_int_equal(total_size, e1_size + e2_size); } -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) { @@ -881,17 +530,15 @@ test_kdc_insert_lookaside_cache_expire(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_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) };