aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaleb Maclennan <caleb@alerque.com>2026-08-31 10:57:42 +0300
committerGitHub <noreply@github.com>2026-08-31 10:57:42 +0300
commit535178a3f0e2cff59f4d59ee3a655bee263a5c90 (patch)
tree22d97c928a8043fd7e4a89897b163ab3deba9591
parent84c2bb905bda5f1fc58195171c75723b5fec6e87 (diff)
parenta9a1e25fdec1faba0237a554027a0f717f132c51 (diff)
downloadluasocket-535178a3f0e2cff59f4d59ee3a655bee263a5c90.tar.gz
luasocket-535178a3f0e2cff59f4d59ee3a655bee263a5c90.tar.bz2
luasocket-535178a3f0e2cff59f4d59ee3a655bee263a5c90.zip
Merge pull request #449 from Wires77/add_SO_EXCLUSIVEADDRUSE
Add option for SO_EXCLUSIVEADDRUSE in Windows
-rw-r--r--docs/tcp.html31
-rw-r--r--docs/udp.html45
-rw-r--r--src/options.c20
-rw-r--r--src/options.h5
-rw-r--r--src/tcp.c6
-rw-r--r--src/udp.c6
6 files changed, 108 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.
236<p class="parameters"> 236<p class="parameters">
237<tt>Option</tt> is a string with the option name.</p> 237<tt>Option</tt> is a string with the option name.</p>
238<ul> 238<ul>
239<li> '<tt>bindtodevice</tt>'</li>
239<li> '<tt>keepalive</tt>'</li> 240<li> '<tt>keepalive</tt>'</li>
240<li> '<tt>linger</tt>'</li>
241<li> '<tt>reuseaddr</tt>'</li> 241<li> '<tt>reuseaddr</tt>'</li>
242<li> '<tt>exclusiveaddruse</tt>'</li>
243<li> '<tt>reuseport</tt>'</li>
242<li> '<tt>tcp-nodelay</tt>'</li> 244<li> '<tt>tcp-nodelay</tt>'</li>
245<li> '<tt>tcp-keepidle</tt>'</li>
246<li> '<tt>tcp-keepcnt</tt>'</li>
247<li> '<tt>tcp-keepintvl</tt>'</li>
248<li> '<tt>linger</tt>'</li>
249<li> '<tt>error</tt>': Returns the socket's pending error status, if
250any, and clears it. Get-only.</li>
251<li> '<tt>recv-buffer-size</tt>'</li>
252<li> '<tt>send-buffer-size</tt>'</li>
243</ul> 253</ul>
244 254
245<p class="return"> 255<p class="return">
@@ -456,6 +466,11 @@ depends on the option being set:</p>
456 466
457<ul> 467<ul>
458 468
469<li> '<tt>bindtodevice</tt>': Binds the socket to a specific network
470interface, given its name (e.g. <tt>"eth0"</tt>), so that only packets
471received on that interface are processed. Receives a string. Linux
472only!!</li>
473
459<li> '<tt>keepalive</tt>': Setting this option to <tt>true</tt> enables 474<li> '<tt>keepalive</tt>': Setting this option to <tt>true</tt> enables
460the periodic transmission of messages on a connected socket. Should the 475the periodic transmission of messages on a connected socket. Should the
461connected party fail to respond to these messages, the connection is 476connected party fail to respond to these messages, the connection is
@@ -476,6 +491,14 @@ zero;</li>
476used in validating addresses supplied in a call to 491used in validating addresses supplied in a call to
477<a href="#bind"><tt>bind</tt></a> should allow reuse of local addresses;</li> 492<a href="#bind"><tt>bind</tt></a> should allow reuse of local addresses;</li>
478 493
494<li> '<tt>exclusiveaddruse</tt>': Setting this option to <tt>true</tt>
495prevents other sockets from binding to the same address and port, even if
496those sockets set '<tt>reuseaddr</tt>'. Windows only!!</li>
497
498<li> '<tt>reuseport</tt>': Allows completely duplicate bindings by
499multiple processes if they all set '<tt>reuseport</tt>' before binding
500the port.</li>
501
479<li> '<tt>tcp-nodelay</tt>': Setting this option to <tt>true</tt> 502<li> '<tt>tcp-nodelay</tt>': Setting this option to <tt>true</tt>
480disables the Nagle's algorithm for the connection;</li> 503disables the Nagle's algorithm for the connection;</li>
481 504
@@ -494,6 +517,12 @@ disables the Nagle's algorithm for the connection;</li>
494<li> '<tt>ipv6-v6only</tt>': 517<li> '<tt>ipv6-v6only</tt>':
495Setting this option to <tt>true</tt> restricts an <tt>inet6</tt> socket to 518Setting this option to <tt>true</tt> restricts an <tt>inet6</tt> socket to
496sending and receiving only IPv6 packets.</li> 519sending and receiving only IPv6 packets.</li>
520
521<li> '<tt>recv-buffer-size</tt>': Sets the size, in bytes, of the
522socket's receive buffer (<tt>SO_RCVBUF</tt>). Receives a number.</li>
523
524<li> '<tt>send-buffer-size</tt>': Sets the size, in bytes, of the
525socket's send buffer (<tt>SO_SNDBUF</tt>). Receives a number.</li>
497</ul> 526</ul>
498 527
499<p class="return"> 528<p class="return">
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.
80<li> '<tt>dontroute</tt>'</li> 80<li> '<tt>dontroute</tt>'</li>
81<li> '<tt>broadcast</tt>'</li> 81<li> '<tt>broadcast</tt>'</li>
82<li> '<tt>reuseaddr</tt>'</li> 82<li> '<tt>reuseaddr</tt>'</li>
83<li> '<tt>exclusiveaddruse</tt>'</li>
83<li> '<tt>reuseport</tt>'</li> 84<li> '<tt>reuseport</tt>'</li>
84<li> '<tt>ip-multicast-loop</tt>'</li> 85<li> '<tt>ip-multicast-loop</tt>'</li>
85<li> '<tt>ipv6-v6only</tt>'</li> 86<li> '<tt>ipv6-v6only</tt>'</li>
87<li> '<tt>ipv6-unicast-hops</tt>'</li>
88<li> '<tt>ipv6-multicast-hops</tt>'</li>
89<li> '<tt>ipv6-multicast-loop</tt>'</li>
86<li> '<tt>ip-multicast-if</tt>'</li> 90<li> '<tt>ip-multicast-if</tt>'</li>
87<li> '<tt>ip-multicast-ttl</tt>'</li> 91<li> '<tt>error</tt>': Returns the socket's pending error status, if
88<li> '<tt>ip-add-membership</tt>'</li> 92any, and clears it. Get-only.</li>
89<li> '<tt>ip-drop-membership</tt>'</li> 93<li> '<tt>recv-buffer-size</tt>'</li>
94<li> '<tt>send-buffer-size</tt>'</li>
90</ul> 95</ul>
91</p> 96</p>
92 97
@@ -294,6 +299,10 @@ Receives a boolean value;</li>
294validating addresses supplied in a <tt>bind()</tt> call 299validating addresses supplied in a <tt>bind()</tt> call
295should allow reuse of local addresses. 300should allow reuse of local addresses.
296Receives a boolean value;</li> 301Receives a boolean value;</li>
302<li> '<tt>exclusiveaddruse</tt>': Setting this option to <tt>true</tt>
303prevents other sockets from binding to the same address and port, even
304if those sockets set '<tt>reuseaddr</tt>'.
305Receives a boolean value. Windows only!!</li>
297<li> '<tt>reuseport</tt>': Allows completely duplicate 306<li> '<tt>reuseport</tt>': Allows completely duplicate
298bindings by multiple processes if they all set 307bindings by multiple processes if they all set
299'<tt>reuseport</tt>' before binding the port. 308'<tt>reuseport</tt>' before binding the port.
@@ -307,6 +316,28 @@ Receives a boolean value;</li>
307Specifies whether to restrict <tt>inet6</tt> sockets to 316Specifies whether to restrict <tt>inet6</tt> sockets to
308sending and receiving only IPv6 packets. 317sending and receiving only IPv6 packets.
309Receive a boolean value;</li> 318Receive a boolean value;</li>
319<li> '<tt>ipv6-unicast-hops</tt>':
320Sets the unicast hop limit (the IPv6 equivalent of the IPv4 TTL)
321for outgoing packets.
322Receives a number;</li>
323<li> '<tt>ipv6-multicast-hops</tt>':
324Sets the hop limit for outgoing IPv6 multicast datagrams.
325Receives a number;</li>
326<li> '<tt>ipv6-multicast-loop</tt>':
327Specifies whether or not a copy of an outgoing IPv6 multicast
328datagram is delivered to the sending host as long as it is a
329member of the multicast group.
330Receives a boolean value;</li>
331<li> '<tt>ipv6-add-membership</tt>':
332Joins the IPv6 multicast group specified.
333Receives a table with field
334<tt>multiaddr</tt>, an IPv6 address, and optionally
335<tt>interface</tt>, a network interface index number;</li>
336<li> '<tt>ipv6-drop-membership</tt>': Leaves the IPv6 multicast
337group specified.
338Receives a table with field
339<tt>multiaddr</tt>, an IPv6 address, and optionally
340<tt>interface</tt>, a network interface index number;</li>
310<li> '<tt>ip-multicast-if</tt>': 341<li> '<tt>ip-multicast-if</tt>':
311Sets the interface over which outgoing multicast datagrams 342Sets the interface over which outgoing multicast datagrams
312are sent. 343are sent.
@@ -324,7 +355,13 @@ IP address;</li>
324group specified. 355group specified.
325Receives a table with fields 356Receives a table with fields
326<tt>multiaddr</tt> and <tt>interface</tt>, each containing an 357<tt>multiaddr</tt> and <tt>interface</tt>, each containing an
327IP address.</li> 358IP address;</li>
359<li> '<tt>recv-buffer-size</tt>': Sets the size, in bytes, of the
360socket's receive buffer (<tt>SO_RCVBUF</tt>).
361Receives a number;</li>
362<li> '<tt>send-buffer-size</tt>': Sets the size, in bytes, of the
363socket's send buffer (<tt>SO_SNDBUF</tt>).
364Receives a number.</li>
328</ul> 365</ul>
329 366
330<p class="return"> 367<p class="return">
diff --git a/src/options.c b/src/options.c
index 9dea6bd..1c3eb1c 100644
--- a/src/options.c
+++ b/src/options.c
@@ -94,6 +94,26 @@ int opt_get_reuseaddr(lua_State *L, p_socket ps)
94} 94}
95 95
96/*------------------------------------------------------*/ 96/*------------------------------------------------------*/
97/* enables reuse of local address */
98int opt_set_exclusiveaddruse(lua_State* L, p_socket ps)
99{
100#ifndef SO_EXCLUSIVEADDRUSE
101 return luaL_error(L, "SO_EXCLUSIVEADDRUSE is not supported on this operating system");
102#else
103 return opt_setboolean(L, ps, SOL_SOCKET, SO_EXCLUSIVEADDRUSE);
104#endif
105}
106
107int opt_get_exclusiveaddruse(lua_State* L, p_socket ps)
108{
109#ifndef SO_EXCLUSIVEADDRUSE
110 return luaL_error(L, "SO_EXCLUSIVEADDRUSE is not supported on this operating system");
111#else
112 return opt_getboolean(L, ps, SOL_SOCKET, SO_EXCLUSIVEADDRUSE);
113#endif
114}
115
116/*------------------------------------------------------*/
97/* enables reuse of local port */ 117/* enables reuse of local port */
98int opt_set_reuseport(lua_State *L, p_socket ps) 118int opt_set_reuseport(lua_State *L, p_socket ps)
99{ 119{
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);
28int opt_set_reuseaddr(lua_State *L, p_socket ps); 28int opt_set_reuseaddr(lua_State *L, p_socket ps);
29int opt_get_reuseaddr(lua_State *L, p_socket ps); 29int opt_get_reuseaddr(lua_State *L, p_socket ps);
30 30
31#ifdef SO_EXCLUSIVEADDRUSE
32int opt_set_exclusiveaddruse(lua_State* L, p_socket ps);
33int opt_get_exclusiveaddruse(lua_State* L, p_socket ps);
34#endif
35
31int opt_set_reuseport(lua_State *L, p_socket ps); 36int opt_set_reuseport(lua_State *L, p_socket ps);
32int opt_get_reuseport(lua_State *L, p_socket ps); 37int opt_get_reuseport(lua_State *L, p_socket ps);
33 38
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[] = {
74 {"bindtodevice", opt_get_bindtodevice}, 74 {"bindtodevice", opt_get_bindtodevice},
75 {"keepalive", opt_get_keepalive}, 75 {"keepalive", opt_get_keepalive},
76 {"reuseaddr", opt_get_reuseaddr}, 76 {"reuseaddr", opt_get_reuseaddr},
77#ifdef SO_EXCLUSIVEADDRUSE
78 {"exclusiveaddruse", opt_get_exclusiveaddruse},
79#endif
77 {"reuseport", opt_get_reuseport}, 80 {"reuseport", opt_get_reuseport},
78 {"tcp-nodelay", opt_get_tcp_nodelay}, 81 {"tcp-nodelay", opt_get_tcp_nodelay},
79#ifdef TCP_KEEPIDLE 82#ifdef TCP_KEEPIDLE
@@ -96,6 +99,9 @@ static t_opt optset[] = {
96 {"bindtodevice", opt_set_bindtodevice}, 99 {"bindtodevice", opt_set_bindtodevice},
97 {"keepalive", opt_set_keepalive}, 100 {"keepalive", opt_set_keepalive},
98 {"reuseaddr", opt_set_reuseaddr}, 101 {"reuseaddr", opt_set_reuseaddr},
102#ifdef SO_EXCLUSIVEADDRUSE
103 {"exclusiveaddruse", opt_set_exclusiveaddruse},
104#endif
99 {"reuseport", opt_set_reuseport}, 105 {"reuseport", opt_set_reuseport},
100 {"tcp-nodelay", opt_set_tcp_nodelay}, 106 {"tcp-nodelay", opt_set_tcp_nodelay},
101#ifdef TCP_KEEPIDLE 107#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[] = {
74 {"dontroute", opt_set_dontroute}, 74 {"dontroute", opt_set_dontroute},
75 {"broadcast", opt_set_broadcast}, 75 {"broadcast", opt_set_broadcast},
76 {"reuseaddr", opt_set_reuseaddr}, 76 {"reuseaddr", opt_set_reuseaddr},
77#ifdef SO_EXCLUSIVEADDRUSE
78 {"exclusiveaddruse", opt_set_exclusiveaddruse},
79#endif
77 {"reuseport", opt_set_reuseport}, 80 {"reuseport", opt_set_reuseport},
78 {"ip-multicast-if", opt_set_ip_multicast_if}, 81 {"ip-multicast-if", opt_set_ip_multicast_if},
79 {"ip-multicast-ttl", opt_set_ip_multicast_ttl}, 82 {"ip-multicast-ttl", opt_set_ip_multicast_ttl},
@@ -96,6 +99,9 @@ static t_opt optget[] = {
96 {"dontroute", opt_get_dontroute}, 99 {"dontroute", opt_get_dontroute},
97 {"broadcast", opt_get_broadcast}, 100 {"broadcast", opt_get_broadcast},
98 {"reuseaddr", opt_get_reuseaddr}, 101 {"reuseaddr", opt_get_reuseaddr},
102#ifdef SO_EXCLUSIVEADDRUSE
103 {"exclusiveaddruse", opt_get_exclusiveaddruse},
104#endif
99 {"reuseport", opt_get_reuseport}, 105 {"reuseport", opt_get_reuseport},
100 {"ip-multicast-if", opt_get_ip_multicast_if}, 106 {"ip-multicast-if", opt_get_ip_multicast_if},
101 {"ip-multicast-loop", opt_get_ip_multicast_loop}, 107 {"ip-multicast-loop", opt_get_ip_multicast_loop},