plaisthos has uploaded a new patch set (#6). ( http://gerrit.openvpn.net/c/openvpn/+/1571?usp=email )
Change subject: Change hash iv to a dynamically allocated ctx ...................................................................... Change hash iv to a dynamically allocated ctx While for our own hash function, always using an uint32_t works well, it does not work very well if we move to another hash function. Move the context of a hardcoded uint32_t iv to a void pointer to a real ctx. Change-Id: If47c7d920b2fa4047b7db03fcde821899839324d Signed-off-by: Arne Schwabe <[email protected]> --- M src/openvpn/list.c M src/openvpn/list.h M src/openvpn/mroute.c M src/openvpn/mroute.h M src/openvpn/multi.c M tests/unit_tests/openvpn/test_misc.c 6 files changed, 42 insertions(+), 23 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/71/1571/6 diff --git a/src/openvpn/list.c b/src/openvpn/list.c index c07e764..36d8ede 100644 --- a/src/openvpn/list.c +++ b/src/openvpn/list.c @@ -29,13 +29,16 @@ #include "integer.h" #include "list.h" + +#include "crypto.h" #include "misc.h" #include "memdbg.h" struct hash * -hash_init(const uint32_t n_buckets, const uint32_t iv, - uint64_t (*hash_function)(const void *key, uint32_t iv), +hash_init(const uint32_t n_buckets, void *ctx, + void (*free_hash_ctx)(void *ctx), + uint64_t (*hash_function)(const void *key, void *ctx), bool (*compare_function)(const void *key1, const void *key2)) { struct hash *h; @@ -46,7 +49,8 @@ h->mask = h->n_buckets - 1; h->hash_function = hash_function; h->compare_function = compare_function; - h->iv = iv; + h->free_ctx = free_hash_ctx; + h->ctx = ctx; ALLOC_ARRAY(h->buckets, struct hash_bucket, h->n_buckets); for (uint32_t i = 0; i < h->n_buckets; ++i) { @@ -71,6 +75,7 @@ he = next; } } + hash->free_ctx(hash->ctx); free(hash->buckets); free(hash); } @@ -412,6 +417,14 @@ c ^= (b >> 15); \ } +void * +hash_func_new_ctx(void) +{ + uint32_t *ctx = malloc(sizeof(uint32_t)); + *ctx = (uint32_t)get_random(); + return ctx; +} + uint64_t hash_func(const uint8_t *k, uint32_t length, uint32_t initval) { diff --git a/src/openvpn/list.h b/src/openvpn/list.h index 06377c6..ea6f47a 100644 --- a/src/openvpn/list.h +++ b/src/openvpn/list.h @@ -54,14 +54,17 @@ uint32_t n_buckets; uint32_t n_elements; uint32_t mask; - uint32_t iv; - uint64_t (*hash_function)(const void *key, uint32_t iv); + void *ctx; + uint64_t (*hash_function)(const void *key, void *ctx); bool (*compare_function)(const void *key1, const void *key2); /* return true if equal */ + void (*free_ctx)(void *ctx); + void *free_ctx_arg; struct hash_bucket *buckets; }; -struct hash *hash_init(const uint32_t n_buckets, const uint32_t iv, - uint64_t (*hash_function)(const void *key, uint32_t iv), +struct hash *hash_init(const uint32_t n_buckets, void *ctx, + void (*free_hash_ctx)(void *ctx), + uint64_t (*hash_function)(const void *key, void *ctx), bool (*compare_function)(const void *key1, const void *key2)); void hash_free(struct hash *hash); @@ -100,10 +103,12 @@ uint64_t hash_func(const uint8_t *k, uint32_t length, uint32_t initval); +void *hash_func_new_ctx(void); + static inline uint64_t hash_value(const struct hash *hash, const void *key) { - return (*hash->hash_function)(key, hash->iv); + return (*hash->hash_function)(key, hash->ctx); } static inline uint32_t diff --git a/src/openvpn/mroute.c b/src/openvpn/mroute.c index 78c689e..89b3ecc 100644 --- a/src/openvpn/mroute.c +++ b/src/openvpn/mroute.c @@ -355,10 +355,11 @@ * and the actual address. */ uint64_t -mroute_addr_hash_function(const void *key, uint32_t iv) +mroute_addr_hash_function(const void *key, void *ctx) { + uint32_t *iv = ctx; return hash_func(mroute_addr_hash_ptr((const struct mroute_addr *)key), - mroute_addr_hash_len((const struct mroute_addr *)key), iv); + mroute_addr_hash_len((const struct mroute_addr *)key), *iv); } bool diff --git a/src/openvpn/mroute.h b/src/openvpn/mroute.h index 2f5d019..51b62d2 100644 --- a/src/openvpn/mroute.h +++ b/src/openvpn/mroute.h @@ -144,7 +144,7 @@ bool mroute_learnable_address(const struct mroute_addr *addr, struct gc_arena *gc); -uint64_t mroute_addr_hash_function(const void *key, uint32_t iv); +uint64_t mroute_addr_hash_function(const void *key, void *ctx); bool mroute_addr_compare_function(const void *key1, const void *key2); diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index e1c9c80..da19183 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -229,7 +229,7 @@ #ifdef ENABLE_MANAGEMENT static uint64_t -cid_hash_function(const void *key, uint32_t iv) +cid_hash_function(const void *key, void *ctx) { const unsigned long *k = (const unsigned long *)key; return (uint64_t)*k; @@ -250,7 +250,7 @@ /* * inotify watcher descriptors are used as hash value */ -int_hash_function(const void *key, uint32_t iv) +int_hash_function(const void *key, void *ctx) { return (uintptr_t)key; } @@ -290,18 +290,18 @@ * to determine which client sent an incoming packet * which is seen on the TCP/UDP socket. */ - m->hash = hash_init(t->options.real_hash_size, (uint32_t)get_random(), + m->hash = hash_init(t->options.real_hash_size, hash_func_new_ctx(), free, mroute_addr_hash_function, mroute_addr_compare_function); /* * Virtual address hash table. Used to determine * which client to route a packet to. */ - m->vhash = hash_init(t->options.virtual_hash_size, (uint32_t)get_random(), + m->vhash = hash_init(t->options.virtual_hash_size, hash_func_new_ctx(), free, mroute_addr_hash_function, mroute_addr_compare_function); #ifdef ENABLE_MANAGEMENT - m->cid_hash = hash_init(t->options.real_hash_size, 0, cid_hash_function, cid_compare_function); + m->cid_hash = hash_init(t->options.real_hash_size, NULL, free, cid_hash_function, cid_compare_function); #endif #ifdef ENABLE_ASYNC_PUSH @@ -309,8 +309,8 @@ * Mapping between inotify watch descriptors and * multi_instances. */ - m->inotify_watchers = hash_init(t->options.real_hash_size, (uint32_t)get_random(), - int_hash_function, int_compare_function); + m->inotify_watchers = + hash_init(t->options.real_hash_size, NULL, free, int_hash_function, int_compare_function); #endif /* diff --git a/tests/unit_tests/openvpn/test_misc.c b/tests/unit_tests/openvpn/test_misc.c index ccdfdee..24bf22d 100644 --- a/tests/unit_tests/openvpn/test_misc.c +++ b/tests/unit_tests/openvpn/test_misc.c @@ -125,11 +125,12 @@ static uint64_t -word_hash_function(const void *key, uint32_t iv) +word_hash_function(const void *key, void *ctx) { + uint32_t *iv = (uint32_t *)ctx; const char *str = (const char *)key; const uint32_t len = (uint32_t)strlen(str); - return hash_func((const uint8_t *)str, len, iv); + return hash_func((const uint8_t *)str, len, *iv); } static bool @@ -171,10 +172,9 @@ * Test the hash code by implementing a simple * word frequency algorithm. */ - struct gc_arena gc = gc_new(); - struct hash *hash = hash_init(10000, get_random(), word_hash_function, word_compare_function); - struct hash *nhash = hash_init(256, get_random(), word_hash_function, word_compare_function); + struct hash *hash = hash_init(10000, hash_func_new_ctx(), free, word_hash_function, word_compare_function); + struct hash *nhash = hash_init(256, hash_func_new_ctx(), free, word_hash_function, word_compare_function); printf("hash_init n_buckets=%u mask=0x%08x\n", hash->n_buckets, hash->mask); -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1571?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email Gerrit-MessageType: newpatchset Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: If47c7d920b2fa4047b7db03fcde821899839324d Gerrit-Change-Number: 1571 Gerrit-PatchSet: 6 Gerrit-Owner: plaisthos <[email protected]> Gerrit-CC: openvpn-devel <[email protected]>
_______________________________________________ Openvpn-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openvpn-devel
