diff options
| author | Florian Zeitz <florob@babelmonkeys.de> | 2011-06-15 00:51:02 +0200 |
|---|---|---|
| committer | Sam Roberts <vieuxtech@gmail.com> | 2012-04-11 13:33:34 -0700 |
| commit | 594f826aa129f8b497c37fe08429eff5651dac9d (patch) | |
| tree | 85b80f9cde7bae3b32742c93f127de87b9e4dc98 /src | |
| parent | 5874d47f550a2f278ca35ccda96d49ccf0ca7e36 (diff) | |
| download | luasocket-594f826aa129f8b497c37fe08429eff5651dac9d.tar.gz luasocket-594f826aa129f8b497c37fe08429eff5651dac9d.tar.bz2 luasocket-594f826aa129f8b497c37fe08429eff5651dac9d.zip | |
Add support for connecting to IPv6 hosts
Diffstat (limited to 'src')
| -rw-r--r-- | src/inet.c | 42 | ||||
| -rw-r--r-- | src/inet.h | 4 | ||||
| -rw-r--r-- | src/socket.lua | 10 | ||||
| -rw-r--r-- | src/tcp.c | 52 | ||||
| -rw-r--r-- | src/udp.c | 37 |
5 files changed, 86 insertions, 59 deletions
| @@ -252,25 +252,31 @@ const char *inet_trycreate(p_socket ps, int domain, int type) { | |||
| 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 | const char *serv, p_timeout tm, struct addrinfo *connecthints) |
| 256 | { | 256 | { |
| 257 | struct sockaddr_in remote; | 257 | struct addrinfo *iterator = NULL, *resolved = NULL; |
| 258 | int err; | 258 | const char *err = NULL; |
| 259 | memset(&remote, 0, sizeof(remote)); | 259 | /* try resolving */ |
| 260 | remote.sin_family = AF_INET; | 260 | err = socket_gaistrerror(getaddrinfo(address, serv, |
| 261 | remote.sin_port = htons(port); | 261 | connecthints, &resolved)); |
| 262 | if (strcmp(address, "*")) { | 262 | if (err != NULL) { |
| 263 | if (!inet_aton(address, &remote.sin_addr)) { | 263 | if (resolved) freeaddrinfo(resolved); |
| 264 | struct hostent *hp = NULL; | 264 | return err; |
| 265 | struct in_addr **addr; | 265 | } |
| 266 | err = socket_gethostbyname(address, &hp); | 266 | /* iterate over all returned addresses trying to connect */ |
| 267 | if (err != IO_DONE) return socket_hoststrerror(err); | 267 | for (iterator = resolved; iterator; iterator = iterator->ai_next) { |
| 268 | addr = (struct in_addr **) hp->h_addr_list; | 268 | timeout_markstart(tm); |
| 269 | memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr)); | 269 | /* try connecting to remote address */ |
| 270 | } | 270 | err = socket_strerror(socket_connect(ps, |
| 271 | } else remote.sin_family = AF_UNSPEC; | 271 | (SA *) iterator->ai_addr, |
| 272 | err = socket_connect(ps, (SA *) &remote, sizeof(remote), tm); | 272 | iterator->ai_addrlen, tm)); |
| 273 | return socket_strerror(err); | 273 | /* if success, break out of loop */ |
| 274 | if (err == NULL) break; | ||
| 275 | } | ||
| 276 | |||
| 277 | freeaddrinfo(resolved); | ||
| 278 | /* here, if err is set, we failed */ | ||
| 279 | return err; | ||
| 274 | } | 280 | } |
| 275 | 281 | ||
| 276 | /*-------------------------------------------------------------------------*\ | 282 | /*-------------------------------------------------------------------------*\ |
| @@ -25,8 +25,8 @@ | |||
| 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 domain, 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 | const char *serv, p_timeout tm, struct addrinfo *connecthints); |
| 30 | const char *inet_trybind(p_socket ps, const char *address, const char *serv, | 30 | const char *inet_trybind(p_socket ps, const char *address, const char *serv, |
| 31 | struct addrinfo *bindhints); | 31 | struct addrinfo *bindhints); |
| 32 | 32 | ||
diff --git a/src/socket.lua b/src/socket.lua index 7a77fbc..734da3c 100644 --- a/src/socket.lua +++ b/src/socket.lua | |||
| @@ -17,7 +17,15 @@ module("socket") | |||
| 17 | -- Exported auxiliar functions | 17 | -- Exported auxiliar functions |
| 18 | ----------------------------------------------------------------------------- | 18 | ----------------------------------------------------------------------------- |
| 19 | function connect(address, port, laddress, lport) | 19 | function connect(address, port, laddress, lport) |
| 20 | local sock, err = socket.tcp() | 20 | if address == "*" then address = "0.0.0.0" end |
| 21 | local addrinfo, err = socket.dns.getaddrinfo(address); | ||
| 22 | if not addrinfo then return nil, err end | ||
| 23 | local sock, err; | ||
| 24 | if addrinfo[1].family == "inet" then | ||
| 25 | sock, err = socket.tcp() | ||
| 26 | else | ||
| 27 | sock, err = socket.tcp6() | ||
| 28 | end | ||
| 21 | if not sock then return nil, err end | 29 | if not sock then return nil, err end |
| 22 | if laddress then | 30 | if laddress then |
| 23 | local res, err = sock:bind(laddress, lport, -1) | 31 | local res, err = sock:bind(laddress, lport, -1) |
| @@ -1,10 +1,10 @@ | |||
| 1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
| 2 | * TCP object | 2 | * TCP object |
| 3 | * LuaSocket toolkit | 3 | * LuaSocket toolkit |
| 4 | * | 4 | * |
| 5 | * RCS ID: $Id: tcp.c,v 1.42 2009/05/27 09:31:35 diego Exp $ | 5 | * RCS ID: $Id: tcp.c,v 1.42 2009/05/27 09:31:35 diego Exp $ |
| 6 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
| 7 | #include <string.h> | 7 | #include <string.h> |
| 8 | 8 | ||
| 9 | #include "lua.h" | 9 | #include "lua.h" |
| 10 | #include "lauxlib.h" | 10 | #include "lauxlib.h" |
| @@ -97,7 +97,7 @@ int tcp_open(lua_State *L) | |||
| 97 | auxiliar_add2group(L, "tcp{client}", "tcp{any}"); | 97 | auxiliar_add2group(L, "tcp{client}", "tcp{any}"); |
| 98 | auxiliar_add2group(L, "tcp{server}", "tcp{any}"); | 98 | auxiliar_add2group(L, "tcp{server}", "tcp{any}"); |
| 99 | /* define library functions */ | 99 | /* define library functions */ |
| 100 | luaL_openlib(L, NULL, func, 0); | 100 | luaL_openlib(L, NULL, func, 0); |
| 101 | return 0; | 101 | return 0; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| @@ -150,7 +150,7 @@ static int meth_getfd(lua_State *L) | |||
| 150 | static int meth_setfd(lua_State *L) | 150 | static int meth_setfd(lua_State *L) |
| 151 | { | 151 | { |
| 152 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | 152 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); |
| 153 | tcp->sock = (t_socket) luaL_checknumber(L, 2); | 153 | tcp->sock = (t_socket) luaL_checknumber(L, 2); |
| 154 | return 0; | 154 | return 0; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| @@ -162,8 +162,8 @@ static int meth_dirty(lua_State *L) | |||
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | /*-------------------------------------------------------------------------*\ | 164 | /*-------------------------------------------------------------------------*\ |
| 165 | * Waits for and returns a client object attempting connection to the | 165 | * Waits for and returns a client object attempting connection to the |
| 166 | * server object | 166 | * server object |
| 167 | \*-------------------------------------------------------------------------*/ | 167 | \*-------------------------------------------------------------------------*/ |
| 168 | static int meth_accept(lua_State *L) | 168 | static int meth_accept(lua_State *L) |
| 169 | { | 169 | { |
| @@ -178,20 +178,20 @@ static int meth_accept(lua_State *L) | |||
| 178 | /* initialize structure fields */ | 178 | /* initialize structure fields */ |
| 179 | socket_setnonblocking(&sock); | 179 | socket_setnonblocking(&sock); |
| 180 | clnt->sock = sock; | 180 | clnt->sock = sock; |
| 181 | io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv, | 181 | io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv, |
| 182 | (p_error) socket_ioerror, &clnt->sock); | 182 | (p_error) socket_ioerror, &clnt->sock); |
| 183 | timeout_init(&clnt->tm, -1, -1); | 183 | timeout_init(&clnt->tm, -1, -1); |
| 184 | buffer_init(&clnt->buf, &clnt->io, &clnt->tm); | 184 | buffer_init(&clnt->buf, &clnt->io, &clnt->tm); |
| 185 | return 1; | 185 | return 1; |
| 186 | } else { | 186 | } else { |
| 187 | lua_pushnil(L); | 187 | lua_pushnil(L); |
| 188 | lua_pushstring(L, socket_strerror(err)); | 188 | lua_pushstring(L, socket_strerror(err)); |
| 189 | return 2; | 189 | return 2; |
| 190 | } | 190 | } |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | /*-------------------------------------------------------------------------*\ | 193 | /*-------------------------------------------------------------------------*\ |
| 194 | * Binds an object to an address | 194 | * Binds an object to an address |
| 195 | \*-------------------------------------------------------------------------*/ | 195 | \*-------------------------------------------------------------------------*/ |
| 196 | static int meth_bind(lua_State *L) | 196 | static int meth_bind(lua_State *L) |
| 197 | { | 197 | { |
| @@ -219,12 +219,18 @@ static int meth_bind(lua_State *L) | |||
| 219 | \*-------------------------------------------------------------------------*/ | 219 | \*-------------------------------------------------------------------------*/ |
| 220 | static int meth_connect(lua_State *L) | 220 | static int meth_connect(lua_State *L) |
| 221 | { | 221 | { |
| 222 | |||
| 223 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | 222 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); |
| 224 | const char *address = luaL_checkstring(L, 2); | 223 | const char *address = luaL_checkstring(L, 2); |
| 225 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); | 224 | const char *port = luaL_checkstring(L, 3); |
| 226 | p_timeout tm = timeout_markstart(&tcp->tm); | 225 | struct addrinfo connecthints; |
| 227 | const char *err = inet_tryconnect(&tcp->sock, address, port, tm); | 226 | const char *err; |
| 227 | memset(&connecthints, 0, sizeof(connecthints)); | ||
| 228 | connecthints.ai_socktype = SOCK_STREAM; | ||
| 229 | /* make sure we try to connect only to the same family */ | ||
| 230 | connecthints.ai_family = tcp->domain; | ||
| 231 | timeout_markstart(&tcp->tm); | ||
| 232 | err = inet_tryconnect(&tcp->sock, address, port, | ||
| 233 | &tcp->tm, &connecthints); | ||
| 228 | /* have to set the class even if it failed due to non-blocking connects */ | 234 | /* have to set the class even if it failed due to non-blocking connects */ |
| 229 | auxiliar_setclass(L, "tcp{client}", 1); | 235 | auxiliar_setclass(L, "tcp{client}", 1); |
| 230 | if (err) { | 236 | if (err) { |
| @@ -237,7 +243,7 @@ static int meth_connect(lua_State *L) | |||
| 237 | } | 243 | } |
| 238 | 244 | ||
| 239 | /*-------------------------------------------------------------------------*\ | 245 | /*-------------------------------------------------------------------------*\ |
| 240 | * Closes socket used by object | 246 | * Closes socket used by object |
| 241 | \*-------------------------------------------------------------------------*/ | 247 | \*-------------------------------------------------------------------------*/ |
| 242 | static int meth_close(lua_State *L) | 248 | static int meth_close(lua_State *L) |
| 243 | { | 249 | { |
| @@ -322,7 +328,7 @@ static int meth_settimeout(lua_State *L) | |||
| 322 | * Library functions | 328 | * Library functions |
| 323 | \*=========================================================================*/ | 329 | \*=========================================================================*/ |
| 324 | /*-------------------------------------------------------------------------*\ | 330 | /*-------------------------------------------------------------------------*\ |
| 325 | * Creates a master tcp object | 331 | * Creates a master tcp object |
| 326 | \*-------------------------------------------------------------------------*/ | 332 | \*-------------------------------------------------------------------------*/ |
| 327 | static int tcp_create(lua_State *L, int domain) { | 333 | static int tcp_create(lua_State *L, int domain) { |
| 328 | t_socket sock; | 334 | t_socket sock; |
| @@ -341,7 +347,7 @@ static int tcp_create(lua_State *L, int domain) { | |||
| 341 | (void *)&yes, sizeof(yes)); | 347 | (void *)&yes, sizeof(yes)); |
| 342 | } | 348 | } |
| 343 | tcp->sock = sock; | 349 | tcp->sock = sock; |
| 344 | io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, | 350 | io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, |
| 345 | (p_error) socket_ioerror, &tcp->sock); | 351 | (p_error) socket_ioerror, &tcp->sock); |
| 346 | timeout_init(&tcp->tm, -1, -1); | 352 | timeout_init(&tcp->tm, -1, -1); |
| 347 | buffer_init(&tcp->buf, &tcp->io, &tcp->tm); | 353 | buffer_init(&tcp->buf, &tcp->io, &tcp->tm); |
| @@ -367,19 +373,19 @@ static const char *tryconnect6(const char *remoteaddr, const char *remoteserv, | |||
| 367 | struct addrinfo *iterator = NULL, *resolved = NULL; | 373 | struct addrinfo *iterator = NULL, *resolved = NULL; |
| 368 | const char *err = NULL; | 374 | const char *err = NULL; |
| 369 | /* try resolving */ | 375 | /* try resolving */ |
| 370 | err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv, | 376 | err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv, |
| 371 | connecthints, &resolved)); | 377 | connecthints, &resolved)); |
| 372 | if (err != NULL) { | 378 | if (err != NULL) { |
| 373 | if (resolved) freeaddrinfo(resolved); | 379 | if (resolved) freeaddrinfo(resolved); |
| 374 | return err; | 380 | return err; |
| 375 | } | 381 | } |
| 376 | /* iterate over all returned addresses trying to connect */ | 382 | /* iterate over all returned addresses trying to connect */ |
| 377 | for (iterator = resolved; iterator; iterator = iterator->ai_next) { | 383 | for (iterator = resolved; iterator; iterator = iterator->ai_next) { |
| 378 | p_timeout tm = timeout_markstart(&tcp->tm); | 384 | p_timeout tm = timeout_markstart(&tcp->tm); |
| 379 | /* create new socket if one wasn't created by the bind stage */ | 385 | /* create new socket if one wasn't created by the bind stage */ |
| 380 | if (tcp->sock == SOCKET_INVALID) { | 386 | if (tcp->sock == SOCKET_INVALID) { |
| 381 | err = socket_strerror(socket_create(&tcp->sock, | 387 | err = socket_strerror(socket_create(&tcp->sock, |
| 382 | iterator->ai_family, iterator->ai_socktype, | 388 | iterator->ai_family, iterator->ai_socktype, |
| 383 | iterator->ai_protocol)); | 389 | iterator->ai_protocol)); |
| 384 | if (err != NULL) { | 390 | if (err != NULL) { |
| 385 | freeaddrinfo(resolved); | 391 | freeaddrinfo(resolved); |
| @@ -389,7 +395,7 @@ static const char *tryconnect6(const char *remoteaddr, const char *remoteserv, | |||
| 389 | socket_setnonblocking(&tcp->sock); | 395 | socket_setnonblocking(&tcp->sock); |
| 390 | } | 396 | } |
| 391 | /* finally try connecting to remote address */ | 397 | /* finally try connecting to remote address */ |
| 392 | err = socket_strerror(socket_connect(&tcp->sock, | 398 | err = socket_strerror(socket_connect(&tcp->sock, |
| 393 | (SA *) iterator->ai_addr, | 399 | (SA *) iterator->ai_addr, |
| 394 | iterator->ai_addrlen, tm)); | 400 | iterator->ai_addrlen, tm)); |
| 395 | /* if success, break out of loop */ | 401 | /* if success, break out of loop */ |
| @@ -410,7 +416,7 @@ static int global_connect6(lua_State *L) { | |||
| 410 | struct addrinfo bindhints, connecthints; | 416 | struct addrinfo bindhints, connecthints; |
| 411 | const char *err = NULL; | 417 | const char *err = NULL; |
| 412 | /* initialize tcp structure */ | 418 | /* initialize tcp structure */ |
| 413 | io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, | 419 | io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, |
| 414 | (p_error) socket_ioerror, &tcp->sock); | 420 | (p_error) socket_ioerror, &tcp->sock); |
| 415 | timeout_init(&tcp->tm, -1, -1); | 421 | timeout_init(&tcp->tm, -1, -1); |
| 416 | buffer_init(&tcp->buf, &tcp->io, &tcp->tm); | 422 | buffer_init(&tcp->buf, &tcp->io, &tcp->tm); |
| @@ -432,7 +438,7 @@ static int global_connect6(lua_State *L) { | |||
| 432 | memset(&connecthints, 0, sizeof(connecthints)); | 438 | memset(&connecthints, 0, sizeof(connecthints)); |
| 433 | connecthints.ai_socktype = SOCK_STREAM; | 439 | connecthints.ai_socktype = SOCK_STREAM; |
| 434 | /* make sure we try to connect only to the same family */ | 440 | /* make sure we try to connect only to the same family */ |
| 435 | connecthints.ai_family = bindhints.ai_family; | 441 | connecthints.ai_family = bindhints.ai_family; |
| 436 | err = tryconnect6(remoteaddr, remoteserv, &connecthints, tcp); | 442 | err = tryconnect6(remoteaddr, remoteserv, &connecthints, tcp); |
| 437 | if (err) { | 443 | if (err) { |
| 438 | socket_destroy(&tcp->sock); | 444 | socket_destroy(&tcp->sock); |
| @@ -1,10 +1,10 @@ | |||
| 1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
| 2 | * UDP object | 2 | * UDP object |
| 3 | * LuaSocket toolkit | 3 | * LuaSocket toolkit |
| 4 | * | 4 | * |
| 5 | * RCS ID: $Id: udp.c,v 1.30 2009/05/27 09:31:35 diego Exp $ | 5 | * RCS ID: $Id: udp.c,v 1.30 2009/05/27 09:31:35 diego Exp $ |
| 6 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
| 7 | #include <string.h> | 7 | #include <string.h> |
| 8 | 8 | ||
| 9 | #include "lua.h" | 9 | #include "lua.h" |
| 10 | #include "lauxlib.h" | 10 | #include "lauxlib.h" |
| @@ -18,10 +18,10 @@ | |||
| 18 | /* min and max macros */ | 18 | /* min and max macros */ |
| 19 | #ifndef MIN | 19 | #ifndef MIN |
| 20 | #define MIN(x, y) ((x) < (y) ? x : y) | 20 | #define MIN(x, y) ((x) < (y) ? x : y) |
| 21 | #endif | 21 | #endif |
| 22 | #ifndef MAX | 22 | #ifndef MAX |
| 23 | #define MAX(x, y) ((x) > (y) ? x : y) | 23 | #define MAX(x, y) ((x) > (y) ? x : y) |
| 24 | #endif | 24 | #endif |
| 25 | 25 | ||
| 26 | /*=========================================================================*\ | 26 | /*=========================================================================*\ |
| 27 | * Internal function prototypes | 27 | * Internal function prototypes |
| @@ -109,7 +109,7 @@ int udp_open(lua_State *L) | |||
| 109 | auxiliar_add2group(L, "udp{connected}", "select{able}"); | 109 | auxiliar_add2group(L, "udp{connected}", "select{able}"); |
| 110 | auxiliar_add2group(L, "udp{unconnected}", "select{able}"); | 110 | auxiliar_add2group(L, "udp{unconnected}", "select{able}"); |
| 111 | /* define library functions */ | 111 | /* define library functions */ |
| 112 | luaL_openlib(L, NULL, func, 0); | 112 | luaL_openlib(L, NULL, func, 0); |
| 113 | return 0; | 113 | return 0; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| @@ -156,12 +156,12 @@ static int meth_sendto(lua_State *L) { | |||
| 156 | struct sockaddr_in addr; | 156 | struct sockaddr_in addr; |
| 157 | int err; | 157 | int err; |
| 158 | memset(&addr, 0, sizeof(addr)); | 158 | memset(&addr, 0, sizeof(addr)); |
| 159 | if (!inet_aton(ip, &addr.sin_addr)) | 159 | if (!inet_aton(ip, &addr.sin_addr)) |
| 160 | luaL_argerror(L, 3, "invalid ip address"); | 160 | luaL_argerror(L, 3, "invalid ip address"); |
| 161 | addr.sin_family = AF_INET; | 161 | addr.sin_family = AF_INET; |
| 162 | addr.sin_port = htons(port); | 162 | addr.sin_port = htons(port); |
| 163 | timeout_markstart(tm); | 163 | timeout_markstart(tm); |
| 164 | err = socket_sendto(&udp->sock, data, count, &sent, | 164 | err = socket_sendto(&udp->sock, data, count, &sent, |
| 165 | (SA *) &addr, sizeof(addr), tm); | 165 | (SA *) &addr, sizeof(addr), tm); |
| 166 | if (err != IO_DONE) { | 166 | if (err != IO_DONE) { |
| 167 | lua_pushnil(L); | 167 | lua_pushnil(L); |
| @@ -206,7 +206,7 @@ static int meth_receivefrom(lua_State *L) { | |||
| 206 | p_timeout tm = &udp->tm; | 206 | p_timeout tm = &udp->tm; |
| 207 | timeout_markstart(tm); | 207 | timeout_markstart(tm); |
| 208 | count = MIN(count, sizeof(buffer)); | 208 | count = MIN(count, sizeof(buffer)); |
| 209 | err = socket_recvfrom(&udp->sock, buffer, count, &got, | 209 | err = socket_recvfrom(&udp->sock, buffer, count, &got, |
| 210 | (SA *) &addr, &addr_len, tm); | 210 | (SA *) &addr, &addr_len, tm); |
| 211 | if (err == IO_DONE) { | 211 | if (err == IO_DONE) { |
| 212 | lua_pushlstring(L, buffer, got); | 212 | lua_pushlstring(L, buffer, got); |
| @@ -288,10 +288,17 @@ static int meth_setpeername(lua_State *L) { | |||
| 288 | p_timeout tm = &udp->tm; | 288 | p_timeout tm = &udp->tm; |
| 289 | const char *address = luaL_checkstring(L, 2); | 289 | const char *address = luaL_checkstring(L, 2); |
| 290 | int connecting = strcmp(address, "*"); | 290 | int connecting = strcmp(address, "*"); |
| 291 | unsigned short port = connecting ? | 291 | const char *port = connecting ? |
| 292 | (unsigned short) luaL_checknumber(L, 3) : | 292 | luaL_checkstring(L, 3) : |
| 293 | (unsigned short) luaL_optnumber(L, 3, 0); | 293 | luaL_optstring(L, 3, "0"); |
| 294 | const char *err = inet_tryconnect(&udp->sock, address, port, tm); | 294 | struct addrinfo connecthints; |
| 295 | const char *err; | ||
| 296 | memset(&connecthints, 0, sizeof(connecthints)); | ||
| 297 | connecthints.ai_socktype = SOCK_DGRAM; | ||
| 298 | /* make sure we try to connect only to the same family */ | ||
| 299 | connecthints.ai_family = udp->domain; | ||
| 300 | err = inet_tryconnect(&udp->sock, address, port, | ||
| 301 | tm, &connecthints); | ||
| 295 | if (err) { | 302 | if (err) { |
| 296 | lua_pushnil(L); | 303 | lua_pushnil(L); |
| 297 | lua_pushstring(L, err); | 304 | lua_pushstring(L, err); |
| @@ -305,7 +312,7 @@ static int meth_setpeername(lua_State *L) { | |||
| 305 | } | 312 | } |
| 306 | 313 | ||
| 307 | /*-------------------------------------------------------------------------*\ | 314 | /*-------------------------------------------------------------------------*\ |
| 308 | * Closes socket used by object | 315 | * Closes socket used by object |
| 309 | \*-------------------------------------------------------------------------*/ | 316 | \*-------------------------------------------------------------------------*/ |
| 310 | static int meth_close(lua_State *L) { | 317 | static int meth_close(lua_State *L) { |
| 311 | p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | 318 | p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); |
| @@ -341,13 +348,13 @@ static int meth_setsockname(lua_State *L) { | |||
| 341 | * Library functions | 348 | * Library functions |
| 342 | \*=========================================================================*/ | 349 | \*=========================================================================*/ |
| 343 | /*-------------------------------------------------------------------------*\ | 350 | /*-------------------------------------------------------------------------*\ |
| 344 | * Creates a master udp object | 351 | * Creates a master udp object |
| 345 | \*-------------------------------------------------------------------------*/ | 352 | \*-------------------------------------------------------------------------*/ |
| 346 | static int udp_create(lua_State *L, int domain) { | 353 | static int udp_create(lua_State *L, int domain) { |
| 347 | t_socket sock; | 354 | t_socket sock; |
| 348 | const char *err = inet_trycreate(&sock, domain, SOCK_DGRAM); | 355 | const char *err = inet_trycreate(&sock, domain, SOCK_DGRAM); |
| 349 | /* try to allocate a system socket */ | 356 | /* try to allocate a system socket */ |
| 350 | if (!err) { | 357 | if (!err) { |
| 351 | /* allocate udp object */ | 358 | /* allocate udp object */ |
| 352 | p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); | 359 | p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); |
| 353 | auxiliar_setclass(L, "udp{unconnected}", -1); | 360 | auxiliar_setclass(L, "udp{unconnected}", -1); |
