diff options
author | Florian Zeitz <florob@babelmonkeys.de> | 2011-06-14 01:17:07 +0200 |
---|---|---|
committer | Sam Roberts <vieuxtech@gmail.com> | 2012-04-11 13:33:34 -0700 |
commit | 923eef192925cae29223974dbf1addd59b4b0f28 (patch) | |
tree | fa8a9daf1b6acd5a7b9d0b6528d0aba8147ac8d0 /src | |
parent | 5c33ef99977587dd9ae4e013d2d43aa8bf493ad1 (diff) | |
download | luasocket-923eef192925cae29223974dbf1addd59b4b0f28.tar.gz luasocket-923eef192925cae29223974dbf1addd59b4b0f28.tar.bz2 luasocket-923eef192925cae29223974dbf1addd59b4b0f28.zip |
Rework binding IPv6 sockets by harmonizing it with the IPv4 variant
Diffstat (limited to 'src')
-rw-r--r-- | src/inet.c | 58 | ||||
-rw-r--r-- | src/inet.h | 6 | ||||
-rw-r--r-- | src/tcp.c | 111 | ||||
-rw-r--r-- | src/tcp.h | 1 | ||||
-rw-r--r-- | src/udp.c | 27 | ||||
-rw-r--r-- | src/udp.h | 1 |
6 files changed, 80 insertions, 124 deletions
@@ -56,7 +56,7 @@ static int inet_gethost(const char *address, struct hostent **hp) { | |||
56 | struct in_addr addr; | 56 | struct in_addr addr; |
57 | if (inet_aton(address, &addr)) | 57 | if (inet_aton(address, &addr)) |
58 | return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp); | 58 | return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp); |
59 | else | 59 | else |
60 | return socket_gethostbyname(address, hp); | 60 | return socket_gethostbyname(address, hp); |
61 | } | 61 | } |
62 | 62 | ||
@@ -66,7 +66,7 @@ static int inet_gethost(const char *address, struct hostent **hp) { | |||
66 | \*-------------------------------------------------------------------------*/ | 66 | \*-------------------------------------------------------------------------*/ |
67 | static int inet_global_tohostname(lua_State *L) { | 67 | static int inet_global_tohostname(lua_State *L) { |
68 | const char *address = luaL_checkstring(L, 1); | 68 | const char *address = luaL_checkstring(L, 1); |
69 | struct hostent *hp = NULL; | 69 | struct hostent *hp = NULL; |
70 | int err = inet_gethost(address, &hp); | 70 | int err = inet_gethost(address, &hp); |
71 | if (err != IO_DONE) { | 71 | if (err != IO_DONE) { |
72 | lua_pushnil(L); | 72 | lua_pushnil(L); |
@@ -85,7 +85,7 @@ static int inet_global_tohostname(lua_State *L) { | |||
85 | static int inet_global_toip(lua_State *L) | 85 | static int inet_global_toip(lua_State *L) |
86 | { | 86 | { |
87 | const char *address = luaL_checkstring(L, 1); | 87 | const char *address = luaL_checkstring(L, 1); |
88 | struct hostent *hp = NULL; | 88 | struct hostent *hp = NULL; |
89 | int err = inet_gethost(address, &hp); | 89 | int err = inet_gethost(address, &hp); |
90 | if (err != IO_DONE) { | 90 | if (err != IO_DONE) { |
91 | lua_pushnil(L); | 91 | lua_pushnil(L); |
@@ -136,7 +136,7 @@ static int inet_global_toip6(lua_State *L) | |||
136 | lua_settable(L, -3); | 136 | lua_settable(L, -3); |
137 | lua_settable(L, -3); | 137 | lua_settable(L, -3); |
138 | i++; | 138 | i++; |
139 | } | 139 | } |
140 | freeaddrinfo(resolved); | 140 | freeaddrinfo(resolved); |
141 | return 1; | 141 | return 1; |
142 | } | 142 | } |
@@ -244,14 +244,14 @@ static void inet_pushresolved(lua_State *L, struct hostent *hp) | |||
244 | /*-------------------------------------------------------------------------*\ | 244 | /*-------------------------------------------------------------------------*\ |
245 | * Tries to create a new inet socket | 245 | * Tries to create a new inet socket |
246 | \*-------------------------------------------------------------------------*/ | 246 | \*-------------------------------------------------------------------------*/ |
247 | const char *inet_trycreate(p_socket ps, int type) { | 247 | const char *inet_trycreate(p_socket ps, int domain, int type) { |
248 | return socket_strerror(socket_create(ps, AF_INET, type, 0)); | 248 | return socket_strerror(socket_create(ps, domain, type, 0)); |
249 | } | 249 | } |
250 | 250 | ||
251 | /*-------------------------------------------------------------------------*\ | 251 | /*-------------------------------------------------------------------------*\ |
252 | * Tries to connect to remote address (address, port) | 252 | * Tries to connect to remote address (address, port) |
253 | \*-------------------------------------------------------------------------*/ | 253 | \*-------------------------------------------------------------------------*/ |
254 | const char *inet_tryconnect(p_socket ps, const char *address, | 254 | const char *inet_tryconnect(p_socket ps, const char *address, |
255 | unsigned short port, p_timeout tm) | 255 | unsigned short port, p_timeout tm) |
256 | { | 256 | { |
257 | struct sockaddr_in remote; | 257 | struct sockaddr_in remote; |
@@ -276,25 +276,35 @@ const char *inet_tryconnect(p_socket ps, const char *address, | |||
276 | /*-------------------------------------------------------------------------*\ | 276 | /*-------------------------------------------------------------------------*\ |
277 | * Tries to bind socket to (address, port) | 277 | * Tries to bind socket to (address, port) |
278 | \*-------------------------------------------------------------------------*/ | 278 | \*-------------------------------------------------------------------------*/ |
279 | const char *inet_trybind(p_socket ps, const char *address, unsigned short port) | 279 | const char *inet_trybind(p_socket ps, const char *address, const char *serv, |
280 | struct addrinfo *bindhints) | ||
280 | { | 281 | { |
281 | struct sockaddr_in local; | 282 | struct addrinfo *iterator = NULL, *resolved = NULL; |
282 | int err; | 283 | const char *err = NULL; |
283 | memset(&local, 0, sizeof(local)); | 284 | /* translate luasocket special values to C */ |
284 | /* address is either wildcard or a valid ip address */ | 285 | if (strcmp(address, "*") == 0) address = NULL; |
285 | local.sin_addr.s_addr = htonl(INADDR_ANY); | 286 | if (!serv) serv = "0"; |
286 | local.sin_port = htons(port); | 287 | /* try resolving */ |
287 | local.sin_family = AF_INET; | 288 | err = socket_gaistrerror(getaddrinfo(address, serv, |
288 | if (strcmp(address, "*") && !inet_aton(address, &local.sin_addr)) { | 289 | bindhints, &resolved)); |
289 | struct hostent *hp = NULL; | 290 | if (err) { |
290 | struct in_addr **addr; | 291 | if (resolved) freeaddrinfo(resolved); |
291 | err = socket_gethostbyname(address, &hp); | 292 | return err; |
292 | if (err != IO_DONE) return socket_hoststrerror(err); | ||
293 | addr = (struct in_addr **) hp->h_addr_list; | ||
294 | memcpy(&local.sin_addr, *addr, sizeof(struct in_addr)); | ||
295 | } | 293 | } |
296 | err = socket_bind(ps, (SA *) &local, sizeof(local)); | 294 | /* iterate over resolved addresses until one is good */ |
297 | return socket_strerror(err); | 295 | for (iterator = resolved; iterator; iterator = iterator->ai_next) { |
296 | /* try binding to local address */ | ||
297 | err = socket_strerror(socket_bind(ps, | ||
298 | (SA *) iterator->ai_addr, | ||
299 | iterator->ai_addrlen)); | ||
300 | /* if faiiled, we try the next one */ | ||
301 | if (err != NULL) socket_destroy(ps); | ||
302 | /* if success, we abort loop */ | ||
303 | else break; | ||
304 | } | ||
305 | /* cleanup and return error */ | ||
306 | freeaddrinfo(resolved); | ||
307 | return err; | ||
298 | } | 308 | } |
299 | 309 | ||
300 | /*-------------------------------------------------------------------------*\ | 310 | /*-------------------------------------------------------------------------*\ |
@@ -24,11 +24,11 @@ | |||
24 | 24 | ||
25 | int inet_open(lua_State *L); | 25 | int inet_open(lua_State *L); |
26 | 26 | ||
27 | const char *inet_trycreate(p_socket ps, int type); | 27 | const char *inet_trycreate(p_socket ps, int domain, int type); |
28 | const char *inet_tryconnect(p_socket ps, const char *address, | 28 | const char *inet_tryconnect(p_socket ps, const char *address, |
29 | unsigned short port, p_timeout tm); | 29 | unsigned short port, p_timeout tm); |
30 | const char *inet_trybind(p_socket ps, const char *address, | 30 | const char *inet_trybind(p_socket ps, const char *address, const char *serv, |
31 | unsigned short port); | 31 | struct addrinfo *bindhints); |
32 | 32 | ||
33 | int inet_meth_getpeername(lua_State *L, p_socket ps); | 33 | int inet_meth_getpeername(lua_State *L, p_socket ps); |
34 | int inet_meth_getsockname(lua_State *L, p_socket ps); | 34 | int inet_meth_getsockname(lua_State *L, p_socket ps); |
@@ -19,8 +19,8 @@ | |||
19 | * Internal function prototypes | 19 | * Internal function prototypes |
20 | \*=========================================================================*/ | 20 | \*=========================================================================*/ |
21 | static int global_create(lua_State *L); | 21 | static int global_create(lua_State *L); |
22 | static int global_create6(lua_State *L); | ||
22 | static int global_connect6(lua_State *L); | 23 | static int global_connect6(lua_State *L); |
23 | static int global_bind6(lua_State *L); | ||
24 | static int meth_connect(lua_State *L); | 24 | static int meth_connect(lua_State *L); |
25 | static int meth_listen(lua_State *L); | 25 | static int meth_listen(lua_State *L); |
26 | static int meth_bind(lua_State *L); | 26 | static int meth_bind(lua_State *L); |
@@ -77,8 +77,8 @@ static t_opt optset[] = { | |||
77 | /* functions in library namespace */ | 77 | /* functions in library namespace */ |
78 | static luaL_reg func[] = { | 78 | static luaL_reg func[] = { |
79 | {"tcp", global_create}, | 79 | {"tcp", global_create}, |
80 | {"tcp6", global_create6}, | ||
80 | {"connect6", global_connect6}, | 81 | {"connect6", global_connect6}, |
81 | {"bind6", global_bind6}, | ||
82 | {NULL, NULL} | 82 | {NULL, NULL} |
83 | }; | 83 | }; |
84 | 84 | ||
@@ -196,8 +196,14 @@ static int meth_bind(lua_State *L) | |||
196 | { | 196 | { |
197 | p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); | 197 | p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); |
198 | const char *address = luaL_checkstring(L, 2); | 198 | const char *address = luaL_checkstring(L, 2); |
199 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); | 199 | const char *port = luaL_checkstring(L, 3); |
200 | const char *err = inet_trybind(&tcp->sock, address, port); | 200 | const char *err; |
201 | struct addrinfo bindhints; | ||
202 | memset(&bindhints, 0, sizeof(bindhints)); | ||
203 | bindhints.ai_socktype = SOCK_STREAM; | ||
204 | bindhints.ai_family = tcp->domain; | ||
205 | bindhints.ai_flags = AI_PASSIVE; | ||
206 | err = inet_trybind(&tcp->sock, address, port, &bindhints); | ||
201 | if (err) { | 207 | if (err) { |
202 | lua_pushnil(L); | 208 | lua_pushnil(L); |
203 | lua_pushstring(L, err); | 209 | lua_pushstring(L, err); |
@@ -317,11 +323,11 @@ static int meth_settimeout(lua_State *L) | |||
317 | /*-------------------------------------------------------------------------*\ | 323 | /*-------------------------------------------------------------------------*\ |
318 | * Creates a master tcp object | 324 | * Creates a master tcp object |
319 | \*-------------------------------------------------------------------------*/ | 325 | \*-------------------------------------------------------------------------*/ |
320 | static int global_create(lua_State *L) { | 326 | static int tcp_create(lua_State *L, int domain) { |
321 | t_socket sock; | 327 | t_socket sock; |
322 | const char *err = inet_trycreate(&sock, SOCK_STREAM); | 328 | const char *err = inet_trycreate(&sock, domain, SOCK_STREAM); |
323 | /* try to allocate a system socket */ | 329 | /* try to allocate a system socket */ |
324 | if (!err) { | 330 | if (!err) { |
325 | /* allocate tcp object */ | 331 | /* allocate tcp object */ |
326 | p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); | 332 | p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); |
327 | /* set its type as master object */ | 333 | /* set its type as master object */ |
@@ -333,6 +339,7 @@ static int global_create(lua_State *L) { | |||
333 | (p_error) socket_ioerror, &tcp->sock); | 339 | (p_error) socket_ioerror, &tcp->sock); |
334 | timeout_init(&tcp->tm, -1, -1); | 340 | timeout_init(&tcp->tm, -1, -1); |
335 | buffer_init(&tcp->buf, &tcp->io, &tcp->tm); | 341 | buffer_init(&tcp->buf, &tcp->io, &tcp->tm); |
342 | tcp->domain = domain; | ||
336 | return 1; | 343 | return 1; |
337 | } else { | 344 | } else { |
338 | lua_pushnil(L); | 345 | lua_pushnil(L); |
@@ -341,92 +348,12 @@ static int global_create(lua_State *L) { | |||
341 | } | 348 | } |
342 | } | 349 | } |
343 | 350 | ||
344 | static const char *trybind6(const char *localaddr, const char *localserv, | 351 | static int global_create(lua_State *L) { |
345 | struct addrinfo *bindhints, p_tcp tcp) { | 352 | return tcp_create(L, AF_INET); |
346 | struct addrinfo *iterator = NULL, *resolved = NULL; | ||
347 | const char *err = NULL; | ||
348 | /* translate luasocket special values to C */ | ||
349 | if (strcmp(localaddr, "*") == 0) localaddr = NULL; | ||
350 | if (!localserv) localserv = "0"; | ||
351 | /* try resolving */ | ||
352 | err = socket_gaistrerror(getaddrinfo(localaddr, localserv, | ||
353 | bindhints, &resolved)); | ||
354 | if (err) { | ||
355 | if (resolved) freeaddrinfo(resolved); | ||
356 | return err; | ||
357 | } | ||
358 | /* iterate over resolved addresses until one is good */ | ||
359 | for (iterator = resolved; iterator; iterator = iterator->ai_next) { | ||
360 | /* create a new socket each time because parameters | ||
361 | * may have changed */ | ||
362 | err = socket_strerror(socket_create(&tcp->sock, | ||
363 | iterator->ai_family, iterator->ai_socktype, | ||
364 | iterator->ai_protocol)); | ||
365 | /* if failed to create socket, bail out */ | ||
366 | if (err != NULL) { | ||
367 | freeaddrinfo(resolved); | ||
368 | return err; | ||
369 | } | ||
370 | /* all sockets are set as non-blocking initially */ | ||
371 | socket_setnonblocking(&tcp->sock); | ||
372 | /* try binding to local address */ | ||
373 | err = socket_strerror(socket_bind(&tcp->sock, | ||
374 | (SA *) iterator->ai_addr, | ||
375 | iterator->ai_addrlen)); | ||
376 | /* if faiiled, we try the next one */ | ||
377 | if (err != NULL) socket_destroy(&tcp->sock); | ||
378 | /* if success, we abort loop */ | ||
379 | else break; | ||
380 | } | ||
381 | /* at this point, if err is not set, se succeeded */ | ||
382 | if (err == NULL) { | ||
383 | /* save family of chosen local address */ | ||
384 | bindhints->ai_family = iterator->ai_family; | ||
385 | } | ||
386 | /* cleanup and return error */ | ||
387 | freeaddrinfo(resolved); | ||
388 | return err; | ||
389 | } | 353 | } |
390 | 354 | ||
391 | static int global_bind6(lua_State *L) { | 355 | static int global_create6(lua_State *L) { |
392 | const char *localaddr = luaL_checkstring(L, 1); | 356 | return tcp_create(L, AF_INET6); |
393 | const char *localserv = luaL_checkstring(L, 2); | ||
394 | int backlog = luaL_checkint(L, 3); | ||
395 | p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); | ||
396 | struct addrinfo bindhints; | ||
397 | const char *err = NULL; | ||
398 | /* initialize tcp structure */ | ||
399 | io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, | ||
400 | (p_error) socket_ioerror, &tcp->sock); | ||
401 | timeout_init(&tcp->tm, -1, -1); | ||
402 | buffer_init(&tcp->buf, &tcp->io, &tcp->tm); | ||
403 | tcp->sock = SOCKET_INVALID; | ||
404 | /* try binding to local address */ | ||
405 | memset(&bindhints, 0, sizeof(bindhints)); | ||
406 | bindhints.ai_socktype = SOCK_STREAM; | ||
407 | bindhints.ai_family = PF_UNSPEC; | ||
408 | bindhints.ai_flags = AI_PASSIVE; | ||
409 | err = trybind6(localaddr, localserv, &bindhints, tcp); | ||
410 | if (err == NULL) { | ||
411 | /* all server sockets initially with reuseaddr set */ | ||
412 | int val = 1; | ||
413 | setsockopt(tcp->sock, SOL_SOCKET, SO_REUSEADDR, | ||
414 | (char *) &val, sizeof(val)); | ||
415 | /* set the backlog and listen */ | ||
416 | err = socket_strerror(socket_listen(&tcp->sock, backlog)); | ||
417 | if (err) { | ||
418 | socket_destroy(&tcp->sock); | ||
419 | lua_pushnil(L); | ||
420 | lua_pushstring(L, err); | ||
421 | return 2; | ||
422 | } | ||
423 | auxiliar_setclass(L, "tcp{server}", -1); | ||
424 | return 1; | ||
425 | } else { | ||
426 | lua_pushnil(L); | ||
427 | lua_pushstring(L, err); | ||
428 | return 2; | ||
429 | } | ||
430 | } | 357 | } |
431 | 358 | ||
432 | static const char *tryconnect6(const char *remoteaddr, const char *remoteserv, | 359 | static const char *tryconnect6(const char *remoteaddr, const char *remoteserv, |
@@ -488,7 +415,7 @@ static int global_connect6(lua_State *L) { | |||
488 | bindhints.ai_family = PF_UNSPEC; | 415 | bindhints.ai_family = PF_UNSPEC; |
489 | bindhints.ai_flags = AI_PASSIVE; | 416 | bindhints.ai_flags = AI_PASSIVE; |
490 | if (localaddr) { | 417 | if (localaddr) { |
491 | err = trybind6(localaddr, localserv, &bindhints, tcp); | 418 | err = inet_trybind(&tcp->sock, localaddr, localserv, &bindhints); |
492 | if (err) { | 419 | if (err) { |
493 | lua_pushnil(L); | 420 | lua_pushnil(L); |
494 | lua_pushstring(L, err); | 421 | lua_pushstring(L, err); |
@@ -25,6 +25,7 @@ typedef struct t_tcp_ { | |||
25 | t_io io; | 25 | t_io io; |
26 | t_buffer buf; | 26 | t_buffer buf; |
27 | t_timeout tm; | 27 | t_timeout tm; |
28 | int domain; | ||
28 | } t_tcp; | 29 | } t_tcp; |
29 | 30 | ||
30 | typedef t_tcp *p_tcp; | 31 | typedef t_tcp *p_tcp; |
@@ -27,6 +27,7 @@ | |||
27 | * Internal function prototypes | 27 | * Internal function prototypes |
28 | \*=========================================================================*/ | 28 | \*=========================================================================*/ |
29 | static int global_create(lua_State *L); | 29 | static int global_create(lua_State *L); |
30 | static int global_create6(lua_State *L); | ||
30 | static int meth_send(lua_State *L); | 31 | static int meth_send(lua_State *L); |
31 | static int meth_sendto(lua_State *L); | 32 | static int meth_sendto(lua_State *L); |
32 | static int meth_receive(lua_State *L); | 33 | static int meth_receive(lua_State *L); |
@@ -89,6 +90,7 @@ static t_opt optget[] = { | |||
89 | /* functions in library namespace */ | 90 | /* functions in library namespace */ |
90 | static luaL_reg func[] = { | 91 | static luaL_reg func[] = { |
91 | {"udp", global_create}, | 92 | {"udp", global_create}, |
93 | {"udp6", global_create6}, | ||
92 | {NULL, NULL} | 94 | {NULL, NULL} |
93 | }; | 95 | }; |
94 | 96 | ||
@@ -317,8 +319,14 @@ static int meth_close(lua_State *L) { | |||
317 | static int meth_setsockname(lua_State *L) { | 319 | static int meth_setsockname(lua_State *L) { |
318 | p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); | 320 | p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); |
319 | const char *address = luaL_checkstring(L, 2); | 321 | const char *address = luaL_checkstring(L, 2); |
320 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); | 322 | const char *port = luaL_checkstring(L, 3); |
321 | const char *err = inet_trybind(&udp->sock, address, port); | 323 | const char *err; |
324 | struct addrinfo bindhints; | ||
325 | memset(&bindhints, 0, sizeof(bindhints)); | ||
326 | bindhints.ai_socktype = SOCK_DGRAM; | ||
327 | bindhints.ai_family = udp->domain; | ||
328 | bindhints.ai_flags = AI_PASSIVE; | ||
329 | err = inet_trybind(&udp->sock, address, port, &bindhints); | ||
322 | if (err) { | 330 | if (err) { |
323 | lua_pushnil(L); | 331 | lua_pushnil(L); |
324 | lua_pushstring(L, err); | 332 | lua_pushstring(L, err); |
@@ -334,18 +342,19 @@ static int meth_setsockname(lua_State *L) { | |||
334 | /*-------------------------------------------------------------------------*\ | 342 | /*-------------------------------------------------------------------------*\ |
335 | * Creates a master udp object | 343 | * Creates a master udp object |
336 | \*-------------------------------------------------------------------------*/ | 344 | \*-------------------------------------------------------------------------*/ |
337 | static int global_create(lua_State *L) { | 345 | static int udp_create(lua_State *L, int domain) { |
338 | t_socket sock; | 346 | t_socket sock; |
339 | const char *err = inet_trycreate(&sock, SOCK_DGRAM); | 347 | const char *err = inet_trycreate(&sock, domain, SOCK_DGRAM); |
340 | /* try to allocate a system socket */ | 348 | /* try to allocate a system socket */ |
341 | if (!err) { | 349 | if (!err) { |
342 | /* allocate tcp object */ | 350 | /* allocate udp object */ |
343 | p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); | 351 | p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); |
344 | auxiliar_setclass(L, "udp{unconnected}", -1); | 352 | auxiliar_setclass(L, "udp{unconnected}", -1); |
345 | /* initialize remaining structure fields */ | 353 | /* initialize remaining structure fields */ |
346 | socket_setnonblocking(&sock); | 354 | socket_setnonblocking(&sock); |
347 | udp->sock = sock; | 355 | udp->sock = sock; |
348 | timeout_init(&udp->tm, -1, -1); | 356 | timeout_init(&udp->tm, -1, -1); |
357 | udp->domain = domain; | ||
349 | return 1; | 358 | return 1; |
350 | } else { | 359 | } else { |
351 | lua_pushnil(L); | 360 | lua_pushnil(L); |
@@ -353,3 +362,11 @@ static int global_create(lua_State *L) { | |||
353 | return 2; | 362 | return 2; |
354 | } | 363 | } |
355 | } | 364 | } |
365 | |||
366 | static int global_create(lua_State *L) { | ||
367 | return udp_create(L, AF_INET); | ||
368 | } | ||
369 | |||
370 | static int global_create6(lua_State *L) { | ||
371 | return udp_create(L, AF_INET6); | ||
372 | } | ||
@@ -23,6 +23,7 @@ | |||
23 | typedef struct t_udp_ { | 23 | typedef struct t_udp_ { |
24 | t_socket sock; | 24 | t_socket sock; |
25 | t_timeout tm; | 25 | t_timeout tm; |
26 | int domain; | ||
26 | } t_udp; | 27 | } t_udp; |
27 | typedef t_udp *p_udp; | 28 | typedef t_udp *p_udp; |
28 | 29 | ||