[Openvpn-devel,v8] Change hash values in our hash map from uint32_t to uint64_t

Message ID 20260628210033.4583-1-gert@greenie.muc.de
State New
Headers
Series [Openvpn-devel,v8] Change hash values in our hash map from uint32_t to uint64_t |

Commit Message

Gert Doering June 28, 2026, 9 p.m. UTC
  From: Arne Schwabe <arne@rfc2549.org>

32 bit architectures are playing a very small role today, so the difference
between 64 bit and 32 bit hash values is not expected to be large anymore.

This is also in preparation to replace our hash function with a more modern
replacement.

Change-Id: Ib8140107f98164d2a2e1768a6d8ac65016cd7f7c
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1570
---

This change was reviewed on Gerrit and approved by at least one
developer. I request to merge it to master.

Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1570
This mail reflects revision 8 of this Change.

Acked-by according to Gerrit (reflected above):
  

Comments

Gert Doering June 29, 2026, 6:57 a.m. UTC | #1
Good morning,

another patch in a long series of code overhauls on the way to 2.8 - I
did not consider this "urgent", but merging 1572ee902f brought in one
piece of new code that assumes 64 bit hash values, creating a (false 
positive) integer conversion warning - so merging this now, to make
-Werror compiles build again.

As this is refactoring / future work, master only.

Your patch has been applied to the master branch.

commit d8536b34d39507a878db107a2098846faf932778
Author: Arne Schwabe
Date:   Sun Jun 28 23:00:27 2026 +0200

     Change hash values in our hash map from uint32_t to uint64_t

     Signed-off-by: Arne Schwabe <arne@rfc2549.org>
     Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1570
     Message-Id: <20260628210033.4583-1-gert@greenie.muc.de>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg37349.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering
  

Patch

diff --git a/src/openvpn/list.c b/src/openvpn/list.c
index f0e9908..c07e764 100644
--- a/src/openvpn/list.c
+++ b/src/openvpn/list.c
@@ -35,7 +35,7 @@ 
 
 struct hash *
 hash_init(const uint32_t n_buckets, const uint32_t iv,
-          uint32_t (*hash_function)(const void *key, uint32_t iv),
+          uint64_t (*hash_function)(const void *key, uint32_t iv),
           bool (*compare_function)(const void *key1, const void *key2))
 {
     struct hash *h;
@@ -76,7 +76,7 @@ 
 }
 
 struct hash_element *
-hash_lookup_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint32_t hv)
+hash_lookup_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint64_t hv)
 {
     struct hash_element *he;
     struct hash_element *prev = NULL;
@@ -104,7 +104,7 @@ 
 }
 
 bool
-hash_remove_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint32_t hv)
+hash_remove_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint64_t hv)
 {
     struct hash_element *he;
     struct hash_element *prev = NULL;
@@ -136,7 +136,7 @@ 
 bool
 hash_add(struct hash *hash, const void *key, void *value, bool replace)
 {
-    uint32_t hv;
+    uint64_t hv;
     struct hash_bucket *bucket;
     struct hash_element *he;
     bool ret = false;
@@ -412,7 +412,7 @@ 
         c ^= (b >> 15); \
     }
 
-uint32_t
+uint64_t
 hash_func(const uint8_t *k, uint32_t length, uint32_t initval)
 {
     uint32_t a, b, c, len;
diff --git a/src/openvpn/list.h b/src/openvpn/list.h
index 04cc3ab..06377c6 100644
--- a/src/openvpn/list.h
+++ b/src/openvpn/list.h
@@ -40,7 +40,7 @@ 
 {
     void *value;
     const void *key;
-    uint32_t hash_value;
+    uint64_t hash_value;
     struct hash_element *next;
 };
 
@@ -55,13 +55,13 @@ 
     uint32_t n_elements;
     uint32_t mask;
     uint32_t iv;
-    uint32_t (*hash_function)(const void *key, uint32_t iv);
+    uint64_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 uint32_t n_buckets, const uint32_t iv,
-                       uint32_t (*hash_function)(const void *key, uint32_t iv),
+                       uint64_t (*hash_function)(const void *key, uint32_t iv),
                        bool (*compare_function)(const void *key1, const void *key2));
 
 void hash_free(struct hash *hash);
@@ -69,9 +69,9 @@ 
 bool hash_add(struct hash *hash, const void *key, void *value, bool replace);
 
 struct hash_element *hash_lookup_fast(struct hash *hash, struct hash_bucket *bucket,
-                                      const void *key, uint32_t hv);
+                                      const void *key, uint64_t hv);
 
-bool hash_remove_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint32_t hv);
+bool hash_remove_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint64_t hv);
 
 void hash_remove_by_value(struct hash *hash, void *value);
 
@@ -98,9 +98,9 @@ 
 
 void hash_iterator_free(struct hash_iterator *hi);
 
-uint32_t hash_func(const uint8_t *k, uint32_t length, uint32_t initval);
+uint64_t hash_func(const uint8_t *k, uint32_t length, uint32_t initval);
 
-static inline uint32_t
+static inline uint64_t
 hash_value(const struct hash *hash, const void *key)
 {
     return (*hash->hash_function)(key, hash->iv);
@@ -119,7 +119,7 @@ 
 }
 
 static inline struct hash_bucket *
-hash_bucket(struct hash *hash, uint32_t hv)
+hash_bucket(struct hash *hash, uint64_t hv)
 {
     return &hash->buckets[hv & hash->mask];
 }
@@ -129,7 +129,7 @@ 
 {
     void *ret = NULL;
     struct hash_element *he;
-    uint32_t hv = hash_value(hash, key);
+    uint64_t hv = hash_value(hash, key);
     struct hash_bucket *bucket = &hash->buckets[hv & hash->mask];
 
     he = hash_lookup_fast(hash, bucket, key, hv);
@@ -143,7 +143,7 @@ 
 
 /* NOTE: assumes that key is not a duplicate */
 static inline void
-hash_add_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint32_t hv,
+hash_add_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint64_t hv,
               void *value)
 {
     struct hash_element *he;
@@ -160,7 +160,7 @@ 
 static inline bool
 hash_remove(struct hash *hash, const void *key)
 {
-    uint32_t hv;
+    uint64_t hv;
     struct hash_bucket *bucket;
     bool ret;
 
diff --git a/src/openvpn/mroute.c b/src/openvpn/mroute.c
index 6fa70a3..78c689e 100644
--- a/src/openvpn/mroute.c
+++ b/src/openvpn/mroute.c
@@ -354,7 +354,7 @@ 
  * address type, number of bits in the network address,
  * and the actual address.
  */
-uint32_t
+uint64_t
 mroute_addr_hash_function(const void *key, uint32_t iv)
 {
     return hash_func(mroute_addr_hash_ptr((const struct mroute_addr *)key),
diff --git a/src/openvpn/mroute.h b/src/openvpn/mroute.h
index c8daa15..2f5d019 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);
 
-uint32_t mroute_addr_hash_function(const void *key, uint32_t iv);
+uint64_t mroute_addr_hash_function(const void *key, uint32_t iv);
 
 bool mroute_addr_compare_function(const void *key1, const void *key2);
 
diff --git a/src/openvpn/mtcp.c b/src/openvpn/mtcp.c
index 7651b4d..f000283 100644
--- a/src/openvpn/mtcp.c
+++ b/src/openvpn/mtcp.c
@@ -49,7 +49,7 @@ 
     {
         mi->real.proto = sock->info.proto;
         struct hash_element *he;
-        const uint32_t hv = hash_value(hash, &mi->real);
+        const uint64_t hv = hash_value(hash, &mi->real);
         struct hash_bucket *bucket = hash_bucket(hash, hv);
 
         multi_assign_peer_id(m, mi);
diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c
index 143a330..b1de446 100644
--- a/src/openvpn/mudp.c
+++ b/src/openvpn/mudp.c
@@ -212,7 +212,7 @@ 
     if (mroute_extract_openvpn_sockaddr(&real, &m->top.c2.from.dest, true) && m->top.c2.buf.len > 0)
     {
         struct hash_element *he;
-        const uint32_t hv = hash_value(hash, &real);
+        const uint64_t hv = hash_value(hash, &real);
         struct hash_bucket *bucket = hash_bucket(hash, hv);
         uint8_t *ptr = BPTR(&m->top.c2.buf);
         uint8_t op = ptr[0] >> P_OPCODE_SHIFT;
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index e96d43c..e1c9c80 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -228,11 +228,11 @@ 
 
 #ifdef ENABLE_MANAGEMENT
 
-static uint32_t
+static uint64_t
 cid_hash_function(const void *key, uint32_t iv)
 {
     const unsigned long *k = (const unsigned long *)key;
-    return (uint32_t)*k;
+    return (uint64_t)*k;
 }
 
 static bool
@@ -246,19 +246,19 @@ 
 #endif
 
 #ifdef ENABLE_ASYNC_PUSH
-static uint32_t
+static uint64_t
 /*
  * inotify watcher descriptors are used as hash value
  */
 int_hash_function(const void *key, uint32_t iv)
 {
-    return (uint32_t)(uintptr_t)key;
+    return (uintptr_t)key;
 }
 
 static bool
 int_compare_function(const void *key1, const void *key2)
 {
-    return (unsigned long)key1 == (unsigned long)key2;
+    return (uintptr_t)key1 == (uintptr_t)key2;
 }
 #endif
 
@@ -1011,7 +1011,7 @@ 
                  const unsigned int flags)
 {
     struct hash_element *he;
-    const uint32_t hv = hash_value(m->vhash, addr);
+    const uint64_t hv = hash_value(m->vhash, addr);
     struct hash_bucket *bucket = hash_bucket(m->vhash, hv);
     struct multi_route *oldroute = NULL;
     struct multi_instance *owner = NULL;
@@ -3094,7 +3094,7 @@ 
         goto done;
     }
 
-    const uint32_t hv = hash_value(hash, &real);
+    const uint64_t hv = hash_value(hash, &real);
     struct hash_bucket *bucket = hash_bucket(hash, hv);
 
     /* make sure that we don't float to an address taken by another client */
@@ -4230,7 +4230,7 @@ 
 multi_unlearn_addr(struct multi_context *m, struct multi_instance *mi, const struct mroute_addr *addr)
 {
     struct hash_element *he;
-    const uint32_t hv = hash_value(m->vhash, addr);
+    const uint64_t hv = hash_value(m->vhash, addr);
     struct hash_bucket *bucket = hash_bucket(m->vhash, hv);
     struct multi_route *r = NULL;
 
diff --git a/tests/unit_tests/openvpn/test_misc.c b/tests/unit_tests/openvpn/test_misc.c
index a9ae33f..ccdfdee 100644
--- a/tests/unit_tests/openvpn/test_misc.c
+++ b/tests/unit_tests/openvpn/test_misc.c
@@ -124,7 +124,7 @@ 
 };
 
 
-static uint32_t
+static uint64_t
 word_hash_function(const void *key, uint32_t iv)
 {
     const char *str = (const char *)key;