]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Increase default size of internal hash maps to 4 * --max-clients
authorArne Schwabe <arne@rfc2549.org>
Wed, 25 Mar 2026 12:45:26 +0000 (13:45 +0100)
committerGert Doering <gert@greenie.muc.de>
Thu, 26 Mar 2026 14:48:10 +0000 (15:48 +0100)
The default of 256 seems quite low as with (at least) 1024 possible
entries (the --max-clients default setting) we have a guaranteed
collisions. Using 4 times the number of possible entries for real
addresses should reduce collisions quite a bit while also leaving
some headroom for the virtual addresses hash where a client might
have more than one address.

A reason to keep the limit so low are the memory requirements. Each
bucket has the size of one linked-list pointer (4 byte or 32 bit and
8 byte for 64 bit). So 256 buckets use 1 or 2 kB while 4096 will use
16 kB or 32 kB.

When the current limit was set 20 years ago this might have been a
meaningful memory saving but today the collision probability is
more important.

Change-Id: Ia699b0dfa407ac377970bb130434298eaaec592b
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Antonio Quartulli <antonio@mandelbit.com>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1563
Message-Id: <20260325124526.124049-1-frank@lichtenheld.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg36268.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit 7b5ebf7c447db16953c9541fdd00c7aa56124fc5)

doc/man-sections/advanced-options.rst
doc/man-sections/server-options.rst
src/openvpn/options.c

index e1115e49f5bd622587d7f6530c6ed622f5493403..73ca44a3e4ca383b6b26724dd212ac213d508cd3 100644 (file)
@@ -36,7 +36,8 @@ used when debugging or testing out special usage scenarios.
 
      hash-size r v
 
-  By default, both tables are sized at 256 buckets.
+  By default, both tables are sized at 4 times ``--max-clients`` buckets.
+  With the default of 1024 of ``--max-clients`` this gives 4096 buckets.
 
 --bcast-buffers n
   Allocate ``n`` buffers for broadcast datagrams (default :code:`256`).
index 03ce651805fc00b145fb31fae4f8bb066901a606..eb8e27366957131bdb11851979f9f2bf82fe6752 100644 (file)
@@ -414,7 +414,7 @@ fast hardware. SSL/TLS authentication must be used in this mode.
      iroute-ipv6 ipv6addr/bits
 
 --max-clients n
-  Limit server to a maximum of ``n`` concurrent clients.
+  Limit server to a maximum of ``n`` concurrent clients. Defaults to 1024.
 
 --max-routes-per-client n
   Allow a maximum of ``n`` internal routes per client (default
index 8a47cd0758e3ac92a789b3364c7307fa9d1c8898..f2d5efe438848a75f94610125da16c5567ecf058 100644 (file)
@@ -854,8 +854,6 @@ init_options(struct options *o)
 #endif
     o->vlan_accept = VLAN_ALL;
     o->vlan_pvid = 1;
-    o->real_hash_size = 256;
-    o->virtual_hash_size = 256;
     o->n_bcast_buf = 256;
     o->tcp_queue_limit = 64;
     o->max_clients = 1024;
@@ -3737,6 +3735,22 @@ dhcp_options_postprocess_dns(struct options *o, struct env_set *es)
     gc_free(&gc);
 }
 #endif /* if defined(_WIN32) || defined(TARGET_ANDROID) */
+/**
+ * Sets the internal hash maps sizes according to the max_clients
+ *
+ */
+static void
+helper_hashmap_sizes(struct options *o)
+{
+    if (!o->real_hash_size)
+    {
+        o->real_hash_size = 4 * o->max_clients;
+    }
+    if (!o->virtual_hash_size)
+    {
+        o->virtual_hash_size = 4 * o->max_clients;
+    }
+}
 
 static void
 options_postprocess_mutate(struct options *o, struct env_set *es)
@@ -3752,6 +3766,11 @@ options_postprocess_mutate(struct options *o, struct env_set *es)
     helper_keepalive(o);
     helper_tcp_nodelay(o);
 
+    if (o->mode == MODE_SERVER)
+    {
+        helper_hashmap_sizes(o);
+    }
+
     options_postprocess_setdefault_ncpciphers(o);
     options_set_backwards_compatible_options(o);
     options_process_mutate_prf(o);