diff options
| author | Caleb Maclennan <caleb@alerque.com> | 2026-08-31 10:57:42 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-31 10:57:42 +0300 |
| commit | 535178a3f0e2cff59f4d59ee3a655bee263a5c90 (patch) | |
| tree | 22d97c928a8043fd7e4a89897b163ab3deba9591 | |
| parent | 84c2bb905bda5f1fc58195171c75723b5fec6e87 (diff) | |
| parent | a9a1e25fdec1faba0237a554027a0f717f132c51 (diff) | |
| download | luasocket-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.html | 31 | ||||
| -rw-r--r-- | docs/udp.html | 45 | ||||
| -rw-r--r-- | src/options.c | 20 | ||||
| -rw-r--r-- | src/options.h | 5 | ||||
| -rw-r--r-- | src/tcp.c | 6 | ||||
| -rw-r--r-- | src/udp.c | 6 |
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 | ||
| 250 | any, 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 | ||
| 470 | interface, given its name (e.g. <tt>"eth0"</tt>), so that only packets | ||
| 471 | received on that interface are processed. Receives a string. Linux | ||
| 472 | only!!</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 |
| 460 | the periodic transmission of messages on a connected socket. Should the | 475 | the periodic transmission of messages on a connected socket. Should the |
| 461 | connected party fail to respond to these messages, the connection is | 476 | connected party fail to respond to these messages, the connection is |
| @@ -476,6 +491,14 @@ zero;</li> | |||
| 476 | used in validating addresses supplied in a call to | 491 | used 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> | ||
| 495 | prevents other sockets from binding to the same address and port, even if | ||
| 496 | those sockets set '<tt>reuseaddr</tt>'. Windows only!!</li> | ||
| 497 | |||
| 498 | <li> '<tt>reuseport</tt>': Allows completely duplicate bindings by | ||
| 499 | multiple processes if they all set '<tt>reuseport</tt>' before binding | ||
| 500 | the 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> |
| 480 | disables the Nagle's algorithm for the connection;</li> | 503 | disables 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>': |
| 495 | Setting this option to <tt>true</tt> restricts an <tt>inet6</tt> socket to | 518 | Setting this option to <tt>true</tt> restricts an <tt>inet6</tt> socket to |
| 496 | sending and receiving only IPv6 packets.</li> | 519 | sending and receiving only IPv6 packets.</li> |
| 520 | |||
| 521 | <li> '<tt>recv-buffer-size</tt>': Sets the size, in bytes, of the | ||
| 522 | socket'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 | ||
| 525 | socket'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> | 92 | any, 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> | |||
| 294 | validating addresses supplied in a <tt>bind()</tt> call | 299 | validating addresses supplied in a <tt>bind()</tt> call |
| 295 | should allow reuse of local addresses. | 300 | should allow reuse of local addresses. |
| 296 | Receives a boolean value;</li> | 301 | Receives a boolean value;</li> |
| 302 | <li> '<tt>exclusiveaddruse</tt>': Setting this option to <tt>true</tt> | ||
| 303 | prevents other sockets from binding to the same address and port, even | ||
| 304 | if those sockets set '<tt>reuseaddr</tt>'. | ||
| 305 | Receives a boolean value. Windows only!!</li> | ||
| 297 | <li> '<tt>reuseport</tt>': Allows completely duplicate | 306 | <li> '<tt>reuseport</tt>': Allows completely duplicate |
| 298 | bindings by multiple processes if they all set | 307 | bindings 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> | |||
| 307 | Specifies whether to restrict <tt>inet6</tt> sockets to | 316 | Specifies whether to restrict <tt>inet6</tt> sockets to |
| 308 | sending and receiving only IPv6 packets. | 317 | sending and receiving only IPv6 packets. |
| 309 | Receive a boolean value;</li> | 318 | Receive a boolean value;</li> |
| 319 | <li> '<tt>ipv6-unicast-hops</tt>': | ||
| 320 | Sets the unicast hop limit (the IPv6 equivalent of the IPv4 TTL) | ||
| 321 | for outgoing packets. | ||
| 322 | Receives a number;</li> | ||
| 323 | <li> '<tt>ipv6-multicast-hops</tt>': | ||
| 324 | Sets the hop limit for outgoing IPv6 multicast datagrams. | ||
| 325 | Receives a number;</li> | ||
| 326 | <li> '<tt>ipv6-multicast-loop</tt>': | ||
| 327 | Specifies whether or not a copy of an outgoing IPv6 multicast | ||
| 328 | datagram is delivered to the sending host as long as it is a | ||
| 329 | member of the multicast group. | ||
| 330 | Receives a boolean value;</li> | ||
| 331 | <li> '<tt>ipv6-add-membership</tt>': | ||
| 332 | Joins the IPv6 multicast group specified. | ||
| 333 | Receives 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 | ||
| 337 | group specified. | ||
| 338 | Receives 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>': |
| 311 | Sets the interface over which outgoing multicast datagrams | 342 | Sets the interface over which outgoing multicast datagrams |
| 312 | are sent. | 343 | are sent. |
| @@ -324,7 +355,13 @@ IP address;</li> | |||
| 324 | group specified. | 355 | group specified. |
| 325 | Receives a table with fields | 356 | Receives 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 |
| 327 | IP address.</li> | 358 | IP address;</li> |
| 359 | <li> '<tt>recv-buffer-size</tt>': Sets the size, in bytes, of the | ||
| 360 | socket's receive buffer (<tt>SO_RCVBUF</tt>). | ||
| 361 | Receives a number;</li> | ||
| 362 | <li> '<tt>send-buffer-size</tt>': Sets the size, in bytes, of the | ||
| 363 | socket's send buffer (<tt>SO_SNDBUF</tt>). | ||
| 364 | Receives 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 */ | ||
| 98 | int 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 | |||
| 107 | int 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 */ |
| 98 | int opt_set_reuseport(lua_State *L, p_socket ps) | 118 | int 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); | |||
| 28 | int opt_set_reuseaddr(lua_State *L, p_socket ps); | 28 | int opt_set_reuseaddr(lua_State *L, p_socket ps); |
| 29 | int opt_get_reuseaddr(lua_State *L, p_socket ps); | 29 | int opt_get_reuseaddr(lua_State *L, p_socket ps); |
| 30 | 30 | ||
| 31 | #ifdef SO_EXCLUSIVEADDRUSE | ||
| 32 | int opt_set_exclusiveaddruse(lua_State* L, p_socket ps); | ||
| 33 | int opt_get_exclusiveaddruse(lua_State* L, p_socket ps); | ||
| 34 | #endif | ||
| 35 | |||
| 31 | int opt_set_reuseport(lua_State *L, p_socket ps); | 36 | int opt_set_reuseport(lua_State *L, p_socket ps); |
| 32 | int opt_get_reuseport(lua_State *L, p_socket ps); | 37 | int opt_get_reuseport(lua_State *L, p_socket ps); |
| 33 | 38 | ||
| @@ -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 |
| @@ -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}, |
