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 | ||
