mirror of
https://github.com/OpenVPN/openvpn.git
synced 2026-05-28 04:03:29 -04:00
list: Make types of hash elements consistent
Really no use in having the indices and limits in int. Change-Id: I3334465738fb1fbf508dfd719b6a238b500cc0ae Signed-off-by: Frank Lichtenheld <frank@lichtenheld.com> Acked-by: Gert Doering <gert@greenie.muc.de> Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1119 Message-Id: <20250919173838.28092-1-gert@greenie.muc.de> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg33108.html Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
parent
efb58abbcc
commit
a69aac41c4
8 changed files with 61 additions and 48 deletions
|
|
@ -135,6 +135,27 @@ constrain_int(int x, int min, int max)
|
|||
}
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
constrain_uint(unsigned int x, unsigned int min, unsigned int max)
|
||||
{
|
||||
if (min > max)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
if (x < min)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
else if (x > max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else
|
||||
{
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions used for circular buffer index arithmetic.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,22 +34,21 @@
|
|||
#include "memdbg.h"
|
||||
|
||||
struct hash *
|
||||
hash_init(const int n_buckets, const uint32_t iv,
|
||||
hash_init(const uint32_t n_buckets, const uint32_t iv,
|
||||
uint32_t (*hash_function)(const void *key, uint32_t iv),
|
||||
bool (*compare_function)(const void *key1, const void *key2))
|
||||
{
|
||||
struct hash *h;
|
||||
int i;
|
||||
|
||||
ASSERT(n_buckets > 0);
|
||||
ALLOC_OBJ_CLEAR(h, struct hash);
|
||||
h->n_buckets = (int)adjust_power_of_2(n_buckets);
|
||||
h->n_buckets = (uint32_t)adjust_power_of_2(n_buckets);
|
||||
h->mask = h->n_buckets - 1;
|
||||
h->hash_function = hash_function;
|
||||
h->compare_function = compare_function;
|
||||
h->iv = iv;
|
||||
ALLOC_ARRAY(h->buckets, struct hash_bucket, h->n_buckets);
|
||||
for (i = 0; i < h->n_buckets; ++i)
|
||||
for (uint32_t i = 0; i < h->n_buckets; ++i)
|
||||
{
|
||||
struct hash_bucket *b = &h->buckets[i];
|
||||
b->list = NULL;
|
||||
|
|
@ -60,8 +59,7 @@ hash_init(const int n_buckets, const uint32_t iv,
|
|||
void
|
||||
hash_free(struct hash *hash)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < hash->n_buckets; ++i)
|
||||
for (uint32_t i = 0; i < hash->n_buckets; ++i)
|
||||
{
|
||||
struct hash_bucket *b = &hash->buckets[i];
|
||||
struct hash_element *he = b->list;
|
||||
|
|
@ -212,15 +210,15 @@ hash_remove_marked(struct hash *hash, struct hash_bucket *bucket)
|
|||
}
|
||||
|
||||
void
|
||||
hash_iterator_init_range(struct hash *hash, struct hash_iterator *hi, int start_bucket,
|
||||
int end_bucket)
|
||||
hash_iterator_init_range(struct hash *hash, struct hash_iterator *hi, uint32_t start_bucket,
|
||||
uint32_t end_bucket)
|
||||
{
|
||||
if (end_bucket > hash->n_buckets)
|
||||
{
|
||||
end_bucket = hash->n_buckets;
|
||||
}
|
||||
|
||||
ASSERT(start_bucket >= 0 && start_bucket <= end_bucket);
|
||||
ASSERT(start_bucket <= end_bucket);
|
||||
|
||||
hi->hash = hash;
|
||||
hi->elem = NULL;
|
||||
|
|
@ -325,6 +323,9 @@ hash_iterator_delete_element(struct hash_iterator *hi)
|
|||
* the return value. Every 1-bit and 2-bit delta achieves avalanche.
|
||||
* About 36+6len instructions.
|
||||
*
|
||||
* #define hashsize(n) ((uint32_t)1<<(n))
|
||||
* #define hashmask(n) (hashsize(n)-1)
|
||||
*
|
||||
* The best hash table sizes are powers of 2. There is no need to do
|
||||
* mod a prime (mod is sooo slow!). If you need less than 32 bits,
|
||||
* use a bitmask. For example, if you need only 10 bits, do
|
||||
|
|
|
|||
|
|
@ -36,14 +36,11 @@
|
|||
#include "basic.h"
|
||||
#include "buffer.h"
|
||||
|
||||
#define hashsize(n) ((uint32_t)1 << (n))
|
||||
#define hashmask(n) (hashsize(n) - 1)
|
||||
|
||||
struct hash_element
|
||||
{
|
||||
void *value;
|
||||
const void *key;
|
||||
unsigned int hash_value;
|
||||
uint32_t hash_value;
|
||||
struct hash_element *next;
|
||||
};
|
||||
|
||||
|
|
@ -54,16 +51,16 @@ struct hash_bucket
|
|||
|
||||
struct hash
|
||||
{
|
||||
int n_buckets;
|
||||
int n_elements;
|
||||
int mask;
|
||||
uint32_t n_buckets;
|
||||
uint32_t n_elements;
|
||||
uint32_t mask;
|
||||
uint32_t iv;
|
||||
uint32_t (*hash_function)(const void *key, uint32_t iv);
|
||||
bool (*compare_function)(const void *key1, const void *key2); /* return true if equal */
|
||||
struct hash_bucket *buckets;
|
||||
};
|
||||
|
||||
struct hash *hash_init(const int n_buckets, const uint32_t iv,
|
||||
struct hash *hash_init(const uint32_t n_buckets, const uint32_t iv,
|
||||
uint32_t (*hash_function)(const void *key, uint32_t iv),
|
||||
bool (*compare_function)(const void *key1, const void *key2));
|
||||
|
||||
|
|
@ -81,17 +78,17 @@ void hash_remove_by_value(struct hash *hash, void *value);
|
|||
struct hash_iterator
|
||||
{
|
||||
struct hash *hash;
|
||||
int bucket_index;
|
||||
uint32_t bucket_index;
|
||||
struct hash_bucket *bucket;
|
||||
struct hash_element *elem;
|
||||
struct hash_element *last;
|
||||
bool bucket_marked;
|
||||
int bucket_index_start;
|
||||
int bucket_index_end;
|
||||
uint32_t bucket_index_start;
|
||||
uint32_t bucket_index_end;
|
||||
};
|
||||
|
||||
void hash_iterator_init_range(struct hash *hash, struct hash_iterator *hi, int start_bucket,
|
||||
int end_bucket);
|
||||
void hash_iterator_init_range(struct hash *hash, struct hash_iterator *hi, uint32_t start_bucket,
|
||||
uint32_t end_bucket);
|
||||
|
||||
void hash_iterator_init(struct hash *hash, struct hash_iterator *iter);
|
||||
|
||||
|
|
@ -109,13 +106,13 @@ hash_value(const struct hash *hash, const void *key)
|
|||
return (*hash->hash_function)(key, hash->iv);
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline uint32_t
|
||||
hash_n_elements(const struct hash *hash)
|
||||
{
|
||||
return hash->n_elements;
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline uint32_t
|
||||
hash_n_buckets(const struct hash *hash)
|
||||
{
|
||||
return hash->n_buckets;
|
||||
|
|
|
|||
|
|
@ -169,18 +169,12 @@ multi_ifconfig_pool_persist(struct multi_context *m, bool force)
|
|||
}
|
||||
|
||||
static void
|
||||
multi_reap_range(const struct multi_context *m, int start_bucket, int end_bucket)
|
||||
multi_reap_range(const struct multi_context *m, uint32_t start_bucket, uint32_t end_bucket)
|
||||
{
|
||||
struct gc_arena gc = gc_new();
|
||||
struct hash_iterator hi;
|
||||
struct hash_element *he;
|
||||
|
||||
if (start_bucket < 0)
|
||||
{
|
||||
start_bucket = 0;
|
||||
end_bucket = hash_n_buckets(m->vhash);
|
||||
}
|
||||
|
||||
dmsg(D_MULTI_DEBUG, "MULTI: REAP range %d -> %d", start_bucket, end_bucket);
|
||||
hash_iterator_init_range(m->vhash, &hi, start_bucket, end_bucket);
|
||||
while ((he = hash_iterator_next(&hi)) != NULL)
|
||||
|
|
@ -201,11 +195,11 @@ multi_reap_range(const struct multi_context *m, int start_bucket, int end_bucket
|
|||
static void
|
||||
multi_reap_all(const struct multi_context *m)
|
||||
{
|
||||
multi_reap_range(m, -1, 0);
|
||||
multi_reap_range(m, 0, hash_n_buckets(m->vhash));
|
||||
}
|
||||
|
||||
static struct multi_reap *
|
||||
multi_reap_new(int buckets_per_pass)
|
||||
multi_reap_new(uint32_t buckets_per_pass)
|
||||
{
|
||||
struct multi_reap *mr;
|
||||
ALLOC_OBJ(mr, struct multi_reap);
|
||||
|
|
@ -237,10 +231,10 @@ multi_reap_free(struct multi_reap *mr)
|
|||
/*
|
||||
* How many buckets in vhash to reap per pass.
|
||||
*/
|
||||
static int
|
||||
reap_buckets_per_pass(int n_buckets)
|
||||
static uint32_t
|
||||
reap_buckets_per_pass(uint32_t n_buckets)
|
||||
{
|
||||
return constrain_int(n_buckets / REAP_DIVISOR, REAP_MIN, REAP_MAX);
|
||||
return constrain_uint(n_buckets / REAP_DIVISOR, REAP_MIN, REAP_MAX);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MANAGEMENT
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@
|
|||
*/
|
||||
struct multi_reap
|
||||
{
|
||||
int bucket_base;
|
||||
int buckets_per_pass;
|
||||
uint32_t bucket_base;
|
||||
uint32_t buckets_per_pass;
|
||||
time_t last_call;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7956,8 +7956,8 @@ add_option(struct options *options, char *p[], bool is_inline, const char *file,
|
|||
{
|
||||
goto err;
|
||||
}
|
||||
options->real_hash_size = real;
|
||||
options->virtual_hash_size = virtual;
|
||||
options->real_hash_size = (uint32_t)real;
|
||||
options->virtual_hash_size = (uint32_t)virtual;
|
||||
}
|
||||
else if (streq(p[0], "connect-freq") && p[1] && p[2] && !p[3])
|
||||
{
|
||||
|
|
|
|||
|
|
@ -499,8 +499,8 @@ struct options
|
|||
struct in6_addr ifconfig_ipv6_pool_base; /* IPv6 */
|
||||
int ifconfig_ipv6_pool_netbits; /* IPv6 */
|
||||
|
||||
int real_hash_size;
|
||||
int virtual_hash_size;
|
||||
uint32_t real_hash_size;
|
||||
uint32_t virtual_hash_size;
|
||||
const char *client_connect_script;
|
||||
const char *client_disconnect_script;
|
||||
const char *learn_address_script;
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ static uint32_t
|
|||
word_hash_function(const void *key, uint32_t iv)
|
||||
{
|
||||
const char *str = (const char *)key;
|
||||
const int len = strlen(str);
|
||||
const uint32_t len = (uint32_t)strlen(str);
|
||||
return hash_func((const uint8_t *)str, len, iv);
|
||||
}
|
||||
|
||||
|
|
@ -138,11 +138,11 @@ word_compare_function(const void *key1, const void *key2)
|
|||
return strcmp((const char *)key1, (const char *)key2) == 0;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
static uint32_t
|
||||
get_random(void)
|
||||
{
|
||||
/* rand() is not very random, but it's C99 and this is just for testing */
|
||||
return rand();
|
||||
return (uint32_t)rand();
|
||||
}
|
||||
|
||||
static struct hash_element *
|
||||
|
|
@ -176,7 +176,7 @@ test_list(void **state)
|
|||
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);
|
||||
|
||||
printf("hash_init n_buckets=%d mask=0x%08x\n", hash->n_buckets, hash->mask);
|
||||
printf("hash_init n_buckets=%u mask=0x%08x\n", hash->n_buckets, hash->mask);
|
||||
|
||||
char wordfile[PATH_MAX] = { 0 };
|
||||
openvpn_test_get_srcdir_dir(wordfile, PATH_MAX, "/../../../COPYRIGHT.GPL");
|
||||
|
|
@ -254,10 +254,10 @@ test_list(void **state)
|
|||
|
||||
/* output contents of hash table */
|
||||
{
|
||||
ptr_type inc = 0;
|
||||
uint32_t inc = 0;
|
||||
int count = 0;
|
||||
|
||||
for (ptr_type base = 0; base < hash_n_buckets(hash); base += inc)
|
||||
for (uint32_t base = 0; base < hash_n_buckets(hash); base += inc)
|
||||
{
|
||||
struct hash_iterator hi;
|
||||
struct hash_element *he;
|
||||
|
|
|
|||
Loading…
Reference in a new issue