diff options
author | Caleb Maclennan <caleb@alerque.com> | 2023-11-10 09:12:04 +0300 |
---|---|---|
committer | Caleb Maclennan <caleb@alerque.com> | 2023-11-10 09:12:04 +0300 |
commit | 5c4fc93d5f4137bf4c22ddf1a048c907a4a26727 (patch) | |
tree | a9a68e1f6a9c3bfe2b64fa1c3a4098865b7d3b5d /src/options.c | |
parent | ccef3bc4e2aa6ee5b997a80aabb58f4ff0b0e98f (diff) | |
parent | 43a97b7f0053313b43906371dbdc226271e6c8ab (diff) | |
download | luasocket-hjelmeland-patch-1.tar.gz luasocket-hjelmeland-patch-1.tar.bz2 luasocket-hjelmeland-patch-1.zip |
Merge branch 'master' into hjelmeland-patch-1hjelmeland-patch-1
Diffstat (limited to '')
-rw-r--r-- | src/options.c | 175 |
1 files changed, 154 insertions, 21 deletions
diff --git a/src/options.c b/src/options.c index 20f4c28..9dea6bd 100644 --- a/src/options.c +++ b/src/options.c | |||
@@ -2,14 +2,11 @@ | |||
2 | * Common option interface | 2 | * Common option interface |
3 | * LuaSocket toolkit | 3 | * LuaSocket toolkit |
4 | \*=========================================================================*/ | 4 | \*=========================================================================*/ |
5 | #include <string.h> | 5 | #include "luasocket.h" |
6 | |||
7 | #include "lauxlib.h" | ||
8 | |||
9 | #include "auxiliar.h" | 6 | #include "auxiliar.h" |
10 | #include "options.h" | 7 | #include "options.h" |
11 | #include "inet.h" | 8 | #include "inet.h" |
12 | 9 | #include <string.h> | |
13 | 10 | ||
14 | /*=========================================================================*\ | 11 | /*=========================================================================*\ |
15 | * Internal functions prototypes | 12 | * Internal functions prototypes |
@@ -37,7 +34,7 @@ int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps) | |||
37 | while (opt->name && strcmp(name, opt->name)) | 34 | while (opt->name && strcmp(name, opt->name)) |
38 | opt++; | 35 | opt++; |
39 | if (!opt->func) { | 36 | if (!opt->func) { |
40 | char msg[45]; | 37 | char msg[57]; |
41 | sprintf(msg, "unsupported option `%.35s'", name); | 38 | sprintf(msg, "unsupported option `%.35s'", name); |
42 | luaL_argerror(L, 2, msg); | 39 | luaL_argerror(L, 2, msg); |
43 | } | 40 | } |
@@ -50,13 +47,41 @@ int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps) | |||
50 | while (opt->name && strcmp(name, opt->name)) | 47 | while (opt->name && strcmp(name, opt->name)) |
51 | opt++; | 48 | opt++; |
52 | if (!opt->func) { | 49 | if (!opt->func) { |
53 | char msg[45]; | 50 | char msg[57]; |
54 | sprintf(msg, "unsupported option `%.35s'", name); | 51 | sprintf(msg, "unsupported option `%.35s'", name); |
55 | luaL_argerror(L, 2, msg); | 52 | luaL_argerror(L, 2, msg); |
56 | } | 53 | } |
57 | return opt->func(L, ps); | 54 | return opt->func(L, ps); |
58 | } | 55 | } |
59 | 56 | ||
57 | /*------------------------------------------------------*/ | ||
58 | /* binds socket to network interface */ | ||
59 | int opt_set_bindtodevice(lua_State *L, p_socket ps) | ||
60 | { | ||
61 | #ifndef SO_BINDTODEVICE | ||
62 | return luaL_error(L, "SO_BINDTODEVICE is not supported on this operating system"); | ||
63 | #else | ||
64 | const char *dev = luaL_checkstring(L, 3); | ||
65 | return opt_set(L, ps, SOL_SOCKET, SO_BINDTODEVICE, (char*)dev, strlen(dev)+1); | ||
66 | #endif | ||
67 | } | ||
68 | |||
69 | int opt_get_bindtodevice(lua_State *L, p_socket ps) | ||
70 | { | ||
71 | #ifndef SO_BINDTODEVICE | ||
72 | return luaL_error(L, "SO_BINDTODEVICE is not supported on this operating system"); | ||
73 | #else | ||
74 | char dev[IFNAMSIZ]; | ||
75 | int len = sizeof(dev); | ||
76 | int err = opt_get(L, ps, SOL_SOCKET, SO_BINDTODEVICE, &dev, &len); | ||
77 | if (err) | ||
78 | return err; | ||
79 | lua_pushstring(L, dev); | ||
80 | return 1; | ||
81 | #endif | ||
82 | } | ||
83 | |||
84 | /*------------------------------------------------------*/ | ||
60 | /* enables reuse of local address */ | 85 | /* enables reuse of local address */ |
61 | int opt_set_reuseaddr(lua_State *L, p_socket ps) | 86 | int opt_set_reuseaddr(lua_State *L, p_socket ps) |
62 | { | 87 | { |
@@ -68,6 +93,7 @@ int opt_get_reuseaddr(lua_State *L, p_socket ps) | |||
68 | return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); | 93 | return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); |
69 | } | 94 | } |
70 | 95 | ||
96 | /*------------------------------------------------------*/ | ||
71 | /* enables reuse of local port */ | 97 | /* enables reuse of local port */ |
72 | int opt_set_reuseport(lua_State *L, p_socket ps) | 98 | int opt_set_reuseport(lua_State *L, p_socket ps) |
73 | { | 99 | { |
@@ -79,7 +105,8 @@ int opt_get_reuseport(lua_State *L, p_socket ps) | |||
79 | return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEPORT); | 105 | return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEPORT); |
80 | } | 106 | } |
81 | 107 | ||
82 | /* disables the Naggle algorithm */ | 108 | /*------------------------------------------------------*/ |
109 | /* disables the Nagle algorithm */ | ||
83 | int opt_set_tcp_nodelay(lua_State *L, p_socket ps) | 110 | int opt_set_tcp_nodelay(lua_State *L, p_socket ps) |
84 | { | 111 | { |
85 | return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); | 112 | return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); |
@@ -90,6 +117,52 @@ int opt_get_tcp_nodelay(lua_State *L, p_socket ps) | |||
90 | return opt_getboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); | 117 | return opt_getboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); |
91 | } | 118 | } |
92 | 119 | ||
120 | /*------------------------------------------------------*/ | ||
121 | #ifdef TCP_KEEPIDLE | ||
122 | |||
123 | int opt_get_tcp_keepidle(lua_State *L, p_socket ps) | ||
124 | { | ||
125 | return opt_getint(L, ps, IPPROTO_TCP, TCP_KEEPIDLE); | ||
126 | } | ||
127 | |||
128 | int opt_set_tcp_keepidle(lua_State *L, p_socket ps) | ||
129 | { | ||
130 | return opt_setint(L, ps, IPPROTO_TCP, TCP_KEEPIDLE); | ||
131 | } | ||
132 | |||
133 | #endif | ||
134 | |||
135 | /*------------------------------------------------------*/ | ||
136 | #ifdef TCP_KEEPCNT | ||
137 | |||
138 | int opt_get_tcp_keepcnt(lua_State *L, p_socket ps) | ||
139 | { | ||
140 | return opt_getint(L, ps, IPPROTO_TCP, TCP_KEEPCNT); | ||
141 | } | ||
142 | |||
143 | int opt_set_tcp_keepcnt(lua_State *L, p_socket ps) | ||
144 | { | ||
145 | return opt_setint(L, ps, IPPROTO_TCP, TCP_KEEPCNT); | ||
146 | } | ||
147 | |||
148 | #endif | ||
149 | |||
150 | /*------------------------------------------------------*/ | ||
151 | #ifdef TCP_KEEPINTVL | ||
152 | |||
153 | int opt_get_tcp_keepintvl(lua_State *L, p_socket ps) | ||
154 | { | ||
155 | return opt_getint(L, ps, IPPROTO_TCP, TCP_KEEPINTVL); | ||
156 | } | ||
157 | |||
158 | int opt_set_tcp_keepintvl(lua_State *L, p_socket ps) | ||
159 | { | ||
160 | return opt_setint(L, ps, IPPROTO_TCP, TCP_KEEPINTVL); | ||
161 | } | ||
162 | |||
163 | #endif | ||
164 | |||
165 | /*------------------------------------------------------*/ | ||
93 | int opt_set_keepalive(lua_State *L, p_socket ps) | 166 | int opt_set_keepalive(lua_State *L, p_socket ps) |
94 | { | 167 | { |
95 | return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); | 168 | return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); |
@@ -100,6 +173,7 @@ int opt_get_keepalive(lua_State *L, p_socket ps) | |||
100 | return opt_getboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); | 173 | return opt_getboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); |
101 | } | 174 | } |
102 | 175 | ||
176 | /*------------------------------------------------------*/ | ||
103 | int opt_set_dontroute(lua_State *L, p_socket ps) | 177 | int opt_set_dontroute(lua_State *L, p_socket ps) |
104 | { | 178 | { |
105 | return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); | 179 | return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); |
@@ -110,6 +184,7 @@ int opt_get_dontroute(lua_State *L, p_socket ps) | |||
110 | return opt_getboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); | 184 | return opt_getboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); |
111 | } | 185 | } |
112 | 186 | ||
187 | /*------------------------------------------------------*/ | ||
113 | int opt_set_broadcast(lua_State *L, p_socket ps) | 188 | int opt_set_broadcast(lua_State *L, p_socket ps) |
114 | { | 189 | { |
115 | return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST); | 190 | return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST); |
@@ -120,6 +195,54 @@ int opt_get_broadcast(lua_State *L, p_socket ps) | |||
120 | return opt_getboolean(L, ps, SOL_SOCKET, SO_BROADCAST); | 195 | return opt_getboolean(L, ps, SOL_SOCKET, SO_BROADCAST); |
121 | } | 196 | } |
122 | 197 | ||
198 | /*------------------------------------------------------*/ | ||
199 | int opt_set_recv_buf_size(lua_State *L, p_socket ps) | ||
200 | { | ||
201 | return opt_setint(L, ps, SOL_SOCKET, SO_RCVBUF); | ||
202 | } | ||
203 | |||
204 | int opt_get_recv_buf_size(lua_State *L, p_socket ps) | ||
205 | { | ||
206 | return opt_getint(L, ps, SOL_SOCKET, SO_RCVBUF); | ||
207 | } | ||
208 | |||
209 | /*------------------------------------------------------*/ | ||
210 | int opt_get_send_buf_size(lua_State *L, p_socket ps) | ||
211 | { | ||
212 | return opt_getint(L, ps, SOL_SOCKET, SO_SNDBUF); | ||
213 | } | ||
214 | |||
215 | int opt_set_send_buf_size(lua_State *L, p_socket ps) | ||
216 | { | ||
217 | return opt_setint(L, ps, SOL_SOCKET, SO_SNDBUF); | ||
218 | } | ||
219 | |||
220 | /*------------------------------------------------------*/ | ||
221 | |||
222 | #ifdef TCP_FASTOPEN | ||
223 | int opt_set_tcp_fastopen(lua_State *L, p_socket ps) | ||
224 | { | ||
225 | return opt_setint(L, ps, IPPROTO_TCP, TCP_FASTOPEN); | ||
226 | } | ||
227 | #endif | ||
228 | |||
229 | #ifdef TCP_FASTOPEN_CONNECT | ||
230 | int opt_set_tcp_fastopen_connect(lua_State *L, p_socket ps) | ||
231 | { | ||
232 | return opt_setint(L, ps, IPPROTO_TCP, TCP_FASTOPEN_CONNECT); | ||
233 | } | ||
234 | #endif | ||
235 | |||
236 | /*------------------------------------------------------*/ | ||
237 | |||
238 | #ifdef TCP_DEFER_ACCEPT | ||
239 | int opt_set_tcp_defer_accept(lua_State *L, p_socket ps) | ||
240 | { | ||
241 | return opt_setint(L, ps, IPPROTO_TCP, TCP_DEFER_ACCEPT); | ||
242 | } | ||
243 | #endif | ||
244 | |||
245 | /*------------------------------------------------------*/ | ||
123 | int opt_set_ip6_unicast_hops(lua_State *L, p_socket ps) | 246 | int opt_set_ip6_unicast_hops(lua_State *L, p_socket ps) |
124 | { | 247 | { |
125 | return opt_setint(L, ps, IPPROTO_IPV6, IPV6_UNICAST_HOPS); | 248 | return opt_setint(L, ps, IPPROTO_IPV6, IPV6_UNICAST_HOPS); |
@@ -130,6 +253,7 @@ int opt_get_ip6_unicast_hops(lua_State *L, p_socket ps) | |||
130 | return opt_getint(L, ps, IPPROTO_IPV6, IPV6_UNICAST_HOPS); | 253 | return opt_getint(L, ps, IPPROTO_IPV6, IPV6_UNICAST_HOPS); |
131 | } | 254 | } |
132 | 255 | ||
256 | /*------------------------------------------------------*/ | ||
133 | int opt_set_ip6_multicast_hops(lua_State *L, p_socket ps) | 257 | int opt_set_ip6_multicast_hops(lua_State *L, p_socket ps) |
134 | { | 258 | { |
135 | return opt_setint(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_HOPS); | 259 | return opt_setint(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_HOPS); |
@@ -140,6 +264,7 @@ int opt_get_ip6_multicast_hops(lua_State *L, p_socket ps) | |||
140 | return opt_getint(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_HOPS); | 264 | return opt_getint(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_HOPS); |
141 | } | 265 | } |
142 | 266 | ||
267 | /*------------------------------------------------------*/ | ||
143 | int opt_set_ip_multicast_loop(lua_State *L, p_socket ps) | 268 | int opt_set_ip_multicast_loop(lua_State *L, p_socket ps) |
144 | { | 269 | { |
145 | return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); | 270 | return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); |
@@ -150,6 +275,7 @@ int opt_get_ip_multicast_loop(lua_State *L, p_socket ps) | |||
150 | return opt_getboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); | 275 | return opt_getboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); |
151 | } | 276 | } |
152 | 277 | ||
278 | /*------------------------------------------------------*/ | ||
153 | int opt_set_ip6_multicast_loop(lua_State *L, p_socket ps) | 279 | int opt_set_ip6_multicast_loop(lua_State *L, p_socket ps) |
154 | { | 280 | { |
155 | return opt_setboolean(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_LOOP); | 281 | return opt_setboolean(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_LOOP); |
@@ -160,6 +286,7 @@ int opt_get_ip6_multicast_loop(lua_State *L, p_socket ps) | |||
160 | return opt_getboolean(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_LOOP); | 286 | return opt_getboolean(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_LOOP); |
161 | } | 287 | } |
162 | 288 | ||
289 | /*------------------------------------------------------*/ | ||
163 | int opt_set_linger(lua_State *L, p_socket ps) | 290 | int opt_set_linger(lua_State *L, p_socket ps) |
164 | { | 291 | { |
165 | struct linger li; /* obj, name, table */ | 292 | struct linger li; /* obj, name, table */ |
@@ -192,11 +319,13 @@ int opt_get_linger(lua_State *L, p_socket ps) | |||
192 | return 1; | 319 | return 1; |
193 | } | 320 | } |
194 | 321 | ||
322 | /*------------------------------------------------------*/ | ||
195 | int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps) | 323 | int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps) |
196 | { | 324 | { |
197 | return opt_setint(L, ps, IPPROTO_IP, IP_MULTICAST_TTL); | 325 | return opt_setint(L, ps, IPPROTO_IP, IP_MULTICAST_TTL); |
198 | } | 326 | } |
199 | 327 | ||
328 | /*------------------------------------------------------*/ | ||
200 | int opt_set_ip_multicast_if(lua_State *L, p_socket ps) | 329 | int opt_set_ip_multicast_if(lua_State *L, p_socket ps) |
201 | { | 330 | { |
202 | const char *address = luaL_checkstring(L, 3); /* obj, name, ip */ | 331 | const char *address = luaL_checkstring(L, 3); /* obj, name, ip */ |
@@ -221,6 +350,7 @@ int opt_get_ip_multicast_if(lua_State *L, p_socket ps) | |||
221 | return 1; | 350 | return 1; |
222 | } | 351 | } |
223 | 352 | ||
353 | /*------------------------------------------------------*/ | ||
224 | int opt_set_ip_add_membership(lua_State *L, p_socket ps) | 354 | int opt_set_ip_add_membership(lua_State *L, p_socket ps) |
225 | { | 355 | { |
226 | return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP); | 356 | return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP); |
@@ -231,6 +361,7 @@ int opt_set_ip_drop_membersip(lua_State *L, p_socket ps) | |||
231 | return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP); | 361 | return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP); |
232 | } | 362 | } |
233 | 363 | ||
364 | /*------------------------------------------------------*/ | ||
234 | int opt_set_ip6_add_membership(lua_State *L, p_socket ps) | 365 | int opt_set_ip6_add_membership(lua_State *L, p_socket ps) |
235 | { | 366 | { |
236 | return opt_ip6_setmembership(L, ps, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP); | 367 | return opt_ip6_setmembership(L, ps, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP); |
@@ -241,6 +372,7 @@ int opt_set_ip6_drop_membersip(lua_State *L, p_socket ps) | |||
241 | return opt_ip6_setmembership(L, ps, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP); | 372 | return opt_ip6_setmembership(L, ps, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP); |
242 | } | 373 | } |
243 | 374 | ||
375 | /*------------------------------------------------------*/ | ||
244 | int opt_get_ip6_v6only(lua_State *L, p_socket ps) | 376 | int opt_get_ip6_v6only(lua_State *L, p_socket ps) |
245 | { | 377 | { |
246 | return opt_getboolean(L, ps, IPPROTO_IPV6, IPV6_V6ONLY); | 378 | return opt_getboolean(L, ps, IPPROTO_IPV6, IPV6_V6ONLY); |
@@ -251,6 +383,20 @@ int opt_set_ip6_v6only(lua_State *L, p_socket ps) | |||
251 | return opt_setboolean(L, ps, IPPROTO_IPV6, IPV6_V6ONLY); | 383 | return opt_setboolean(L, ps, IPPROTO_IPV6, IPV6_V6ONLY); |
252 | } | 384 | } |
253 | 385 | ||
386 | /*------------------------------------------------------*/ | ||
387 | int opt_get_error(lua_State *L, p_socket ps) | ||
388 | { | ||
389 | int val = 0; | ||
390 | socklen_t len = sizeof(val); | ||
391 | if (getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *) &val, &len) < 0) { | ||
392 | lua_pushnil(L); | ||
393 | lua_pushstring(L, "getsockopt failed"); | ||
394 | return 2; | ||
395 | } | ||
396 | lua_pushstring(L, socket_strerror(val)); | ||
397 | return 1; | ||
398 | } | ||
399 | |||
254 | /*=========================================================================*\ | 400 | /*=========================================================================*\ |
255 | * Auxiliar functions | 401 | * Auxiliar functions |
256 | \*=========================================================================*/ | 402 | \*=========================================================================*/ |
@@ -337,19 +483,6 @@ static int opt_getboolean(lua_State *L, p_socket ps, int level, int name) | |||
337 | return 1; | 483 | return 1; |
338 | } | 484 | } |
339 | 485 | ||
340 | int opt_get_error(lua_State *L, p_socket ps) | ||
341 | { | ||
342 | int val = 0; | ||
343 | socklen_t len = sizeof(val); | ||
344 | if (getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *) &val, &len) < 0) { | ||
345 | lua_pushnil(L); | ||
346 | lua_pushstring(L, "getsockopt failed"); | ||
347 | return 2; | ||
348 | } | ||
349 | lua_pushstring(L, socket_strerror(val)); | ||
350 | return 1; | ||
351 | } | ||
352 | |||
353 | static int opt_setboolean(lua_State *L, p_socket ps, int level, int name) | 486 | static int opt_setboolean(lua_State *L, p_socket ps, int level, int name) |
354 | { | 487 | { |
355 | int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */ | 488 | int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */ |