From b56a0c1b16f10ba6290b4decedbc424433972f46 Mon Sep 17 00:00:00 2001
From: Wires77
Date: Thu, 27 Feb 2025 15:40:35 -0600
Subject: feat(core): Add option for Windows SO_EXCLUSIVEADDRUSE
---
src/options.c | 20 ++++++++++++++++++++
src/options.h | 5 +++++
src/tcp.c | 6 ++++++
src/udp.c | 6 ++++++
4 files changed, 37 insertions(+)
diff --git a/src/options.c b/src/options.c
index 9dea6bd..1c3eb1c 100644
--- a/src/options.c
+++ b/src/options.c
@@ -93,6 +93,26 @@ int opt_get_reuseaddr(lua_State *L, p_socket ps)
return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);
}
+/*------------------------------------------------------*/
+/* enables reuse of local address */
+int opt_set_exclusiveaddruse(lua_State* L, p_socket ps)
+{
+#ifndef SO_EXCLUSIVEADDRUSE
+ return luaL_error(L, "SO_EXCLUSIVEADDRUSE is not supported on this operating system");
+#else
+ return opt_setboolean(L, ps, SOL_SOCKET, SO_EXCLUSIVEADDRUSE);
+#endif
+}
+
+int opt_get_exclusiveaddruse(lua_State* L, p_socket ps)
+{
+#ifndef SO_EXCLUSIVEADDRUSE
+ return luaL_error(L, "SO_EXCLUSIVEADDRUSE is not supported on this operating system");
+#else
+ return opt_getboolean(L, ps, SOL_SOCKET, SO_EXCLUSIVEADDRUSE);
+#endif
+}
+
/*------------------------------------------------------*/
/* enables reuse of local port */
int opt_set_reuseport(lua_State *L, p_socket ps)
diff --git a/src/options.h b/src/options.h
index 26d6f02..6d6d7e0 100644
--- a/src/options.h
+++ b/src/options.h
@@ -28,6 +28,11 @@ int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps);
int opt_set_reuseaddr(lua_State *L, p_socket ps);
int opt_get_reuseaddr(lua_State *L, p_socket ps);
+#ifdef SO_EXCLUSIVEADDRUSE
+int opt_set_exclusiveaddruse(lua_State* L, p_socket ps);
+int opt_get_exclusiveaddruse(lua_State* L, p_socket ps);
+#endif
+
int opt_set_reuseport(lua_State *L, p_socket ps);
int opt_get_reuseport(lua_State *L, p_socket ps);
diff --git a/src/tcp.c b/src/tcp.c
index f001206..0a36cde 100644
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -74,6 +74,9 @@ static t_opt optget[] = {
{"bindtodevice", opt_get_bindtodevice},
{"keepalive", opt_get_keepalive},
{"reuseaddr", opt_get_reuseaddr},
+#ifdef SO_EXCLUSIVEADDRUSE
+ {"exclusiveaddruse", opt_get_exclusiveaddruse},
+#endif
{"reuseport", opt_get_reuseport},
{"tcp-nodelay", opt_get_tcp_nodelay},
#ifdef TCP_KEEPIDLE
@@ -96,6 +99,9 @@ static t_opt optset[] = {
{"bindtodevice", opt_set_bindtodevice},
{"keepalive", opt_set_keepalive},
{"reuseaddr", opt_set_reuseaddr},
+#ifdef SO_EXCLUSIVEADDRUSE
+ {"exclusiveaddruse", opt_set_exclusiveaddruse},
+#endif
{"reuseport", opt_set_reuseport},
{"tcp-nodelay", opt_set_tcp_nodelay},
#ifdef TCP_KEEPIDLE
diff --git a/src/udp.c b/src/udp.c
index 712ad50..6c0d39e 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -74,6 +74,9 @@ static t_opt optset[] = {
{"dontroute", opt_set_dontroute},
{"broadcast", opt_set_broadcast},
{"reuseaddr", opt_set_reuseaddr},
+#ifdef SO_EXCLUSIVEADDRUSE
+ {"exclusiveaddruse", opt_set_exclusiveaddruse},
+#endif
{"reuseport", opt_set_reuseport},
{"ip-multicast-if", opt_set_ip_multicast_if},
{"ip-multicast-ttl", opt_set_ip_multicast_ttl},
@@ -96,6 +99,9 @@ static t_opt optget[] = {
{"dontroute", opt_get_dontroute},
{"broadcast", opt_get_broadcast},
{"reuseaddr", opt_get_reuseaddr},
+#ifdef SO_EXCLUSIVEADDRUSE
+ {"exclusiveaddruse", opt_get_exclusiveaddruse},
+#endif
{"reuseport", opt_get_reuseport},
{"ip-multicast-if", opt_get_ip_multicast_if},
{"ip-multicast-loop", opt_get_ip_multicast_loop},
--
cgit v1.2.3-55-g6feb
From a9a1e25fdec1faba0237a554027a0f717f132c51 Mon Sep 17 00:00:00 2001
From: Thijs Schreijer
Date: Sun, 30 Aug 2026 15:58:20 +0200
Subject: chore(docs): add docs for SO_EXCLUSIVEADDRUSE and others
Adds docs for the option, but also adds the docs for other
options present in the code but missing from the docs.
---
docs/tcp.html | 31 ++++++++++++++++++++++++++++++-
docs/udp.html | 45 +++++++++++++++++++++++++++++++++++++++++----
2 files changed, 71 insertions(+), 5 deletions(-)
diff --git a/docs/tcp.html b/docs/tcp.html
index a26228d..d223abf 100644
--- a/docs/tcp.html
+++ b/docs/tcp.html
@@ -236,10 +236,20 @@ option names and values.
Option is a string with the option name.
+- 'bindtodevice'
- 'keepalive'
-- 'linger'
- 'reuseaddr'
+- 'exclusiveaddruse'
+- 'reuseport'
- 'tcp-nodelay'
+- 'tcp-keepidle'
+- 'tcp-keepcnt'
+- 'tcp-keepintvl'
+- 'linger'
+- 'error': Returns the socket's pending error status, if
+any, and clears it. Get-only.
+- 'recv-buffer-size'
+- 'send-buffer-size'
@@ -456,6 +466,11 @@ depends on the option being set:
+- 'bindtodevice': Binds the socket to a specific network
+interface, given its name (e.g. "eth0"), so that only packets
+received on that interface are processed. Receives a string. Linux
+only!!
+
- 'keepalive': Setting this option to true enables
the periodic transmission of messages on a connected socket. Should the
connected party fail to respond to these messages, the connection is
@@ -476,6 +491,14 @@ zero;
used in validating addresses supplied in a call to
bind should allow reuse of local addresses;
+- 'exclusiveaddruse': Setting this option to true
+prevents other sockets from binding to the same address and port, even if
+those sockets set 'reuseaddr'. Windows only!!
+
+- 'reuseport': Allows completely duplicate bindings by
+multiple processes if they all set 'reuseport' before binding
+the port.
+
- 'tcp-nodelay': Setting this option to true
disables the Nagle's algorithm for the connection;
@@ -494,6 +517,12 @@ disables the Nagle's algorithm for the connection;
- 'ipv6-v6only':
Setting this option to true restricts an inet6 socket to
sending and receiving only IPv6 packets.
+
+- 'recv-buffer-size': Sets the size, in bytes, of the
+socket's receive buffer (SO_RCVBUF). Receives a number.
+
+- 'send-buffer-size': Sets the size, in bytes, of the
+socket's send buffer (SO_SNDBUF). Receives a number.
diff --git a/docs/udp.html b/docs/udp.html
index 99613b8..8d807a4 100644
--- a/docs/udp.html
+++ b/docs/udp.html
@@ -80,13 +80,18 @@ description of the option names and values.
'dontroute'
'broadcast'
'reuseaddr'
+ 'exclusiveaddruse'
'reuseport'
'ip-multicast-loop'
'ipv6-v6only'
+ 'ipv6-unicast-hops'
+ 'ipv6-multicast-hops'
+ 'ipv6-multicast-loop'
'ip-multicast-if'
- 'ip-multicast-ttl'
- 'ip-add-membership'
- 'ip-drop-membership'
+ 'error': Returns the socket's pending error status, if
+any, and clears it. Get-only.
+ 'recv-buffer-size'
+ 'send-buffer-size'
@@ -294,6 +299,10 @@ Receives a boolean value;
validating addresses supplied in a bind() call
should allow reuse of local addresses.
Receives a boolean value;
+ 'exclusiveaddruse': Setting this option to true
+prevents other sockets from binding to the same address and port, even
+if those sockets set 'reuseaddr'.
+Receives a boolean value. Windows only!!
'reuseport': Allows completely duplicate
bindings by multiple processes if they all set
'reuseport' before binding the port.
@@ -307,6 +316,28 @@ Receives a boolean value;
Specifies whether to restrict inet6 sockets to
sending and receiving only IPv6 packets.
Receive a boolean value;
+ 'ipv6-unicast-hops':
+Sets the unicast hop limit (the IPv6 equivalent of the IPv4 TTL)
+for outgoing packets.
+Receives a number;
+ 'ipv6-multicast-hops':
+Sets the hop limit for outgoing IPv6 multicast datagrams.
+Receives a number;
+ 'ipv6-multicast-loop':
+Specifies whether or not a copy of an outgoing IPv6 multicast
+datagram is delivered to the sending host as long as it is a
+member of the multicast group.
+Receives a boolean value;
+ 'ipv6-add-membership':
+Joins the IPv6 multicast group specified.
+Receives a table with field
+multiaddr, an IPv6 address, and optionally
+interface, a network interface index number;
+ 'ipv6-drop-membership': Leaves the IPv6 multicast
+group specified.
+Receives a table with field
+multiaddr, an IPv6 address, and optionally
+interface, a network interface index number;
'ip-multicast-if':
Sets the interface over which outgoing multicast datagrams
are sent.
@@ -324,7 +355,13 @@ IP address;
group specified.
Receives a table with fields
multiaddr and interface, each containing an
-IP address.
+IP address;
+ 'recv-buffer-size': Sets the size, in bytes, of the
+socket's receive buffer (SO_RCVBUF).
+Receives a number;
+ 'send-buffer-size': Sets the size, in bytes, of the
+socket's send buffer (SO_SNDBUF).
+Receives a number.
--
cgit v1.2.3-55-g6feb