aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/inet.c45
-rw-r--r--src/inet.h1
-rw-r--r--src/tcp.c4
-rw-r--r--src/udp.c35
4 files changed, 55 insertions, 30 deletions
diff --git a/src/inet.c b/src/inet.c
index e769cd8..dfee700 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -177,8 +177,8 @@ static int inet_global_getaddrinfo(lua_State *L)
177 lua_newtable(L); 177 lua_newtable(L);
178 for (iterator = resolved; iterator; iterator = iterator->ai_next) { 178 for (iterator = resolved; iterator; iterator = iterator->ai_next) {
179 char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; 179 char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
180 getnameinfo(iterator->ai_addr, iterator->ai_addrlen, hbuf, sizeof(hbuf), 180 getnameinfo(iterator->ai_addr, iterator->ai_addrlen, hbuf,
181 sbuf, 0, NI_NUMERICHOST); 181 sizeof(hbuf), sbuf, 0, NI_NUMERICHOST);
182 lua_pushnumber(L, i); 182 lua_pushnumber(L, i);
183 lua_newtable(L); 183 lua_newtable(L);
184 switch (iterator->ai_family) { 184 switch (iterator->ai_family) {
@@ -368,6 +368,34 @@ const char *inet_trycreate(p_socket ps, int family, int type) {
368} 368}
369 369
370/*-------------------------------------------------------------------------*\ 370/*-------------------------------------------------------------------------*\
371* "Disconnects" a DGRAM socket
372\*-------------------------------------------------------------------------*/
373const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm)
374{
375 switch (family) {
376 case PF_INET: {
377 struct sockaddr_in sin;
378 memset((char *) &sin, 0, sizeof(sin));
379 sin.sin_family = AF_UNSPEC;
380 sin.sin_addr.s_addr = INADDR_ANY;
381 return socket_strerror(socket_connect(ps, (SA *) &sin,
382 sizeof(sin), tm));
383 }
384 case PF_INET6: {
385 struct sockaddr_in6 sin6;
386 struct in6_addr addrany = IN6ADDR_ANY_INIT;
387 memset((char *) &sin6, 0, sizeof(sin6));
388 sin6.sin6_family = AF_UNSPEC;
389fprintf(stderr, "disconnecting\n");
390 sin6.sin6_addr = addrany;
391 return socket_strerror(socket_connect(ps, (SA *) &sin6,
392 sizeof(sin6), tm));
393 }
394 }
395 return NULL;
396}
397
398/*-------------------------------------------------------------------------*\
371* Tries to connect to remote address (address, port) 399* Tries to connect to remote address (address, port)
372\*-------------------------------------------------------------------------*/ 400\*-------------------------------------------------------------------------*/
373const char *inet_tryconnect(p_socket ps, const char *address, 401const char *inet_tryconnect(p_socket ps, const char *address,
@@ -382,17 +410,14 @@ const char *inet_tryconnect(p_socket ps, const char *address,
382 if (resolved) freeaddrinfo(resolved); 410 if (resolved) freeaddrinfo(resolved);
383 return err; 411 return err;
384 } 412 }
385 /* iterate over all returned addresses trying to connect */
386 for (iterator = resolved; iterator; iterator = iterator->ai_next) { 413 for (iterator = resolved; iterator; iterator = iterator->ai_next) {
387 timeout_markstart(tm); 414 timeout_markstart(tm);
388 /* try connecting to remote address */ 415 /* try connecting to remote address */
389 err = socket_strerror(socket_connect(ps, 416 err = socket_strerror(socket_connect(ps, (SA *) iterator->ai_addr,
390 (SA *) iterator->ai_addr,
391 iterator->ai_addrlen, tm)); 417 iterator->ai_addrlen, tm));
392 /* if success, break out of loop */ 418 /* if success, break out of loop */
393 if (err == NULL) break; 419 if (err == NULL) break;
394 } 420 }
395
396 freeaddrinfo(resolved); 421 freeaddrinfo(resolved);
397 /* here, if err is set, we failed */ 422 /* here, if err is set, we failed */
398 return err; 423 return err;
@@ -407,12 +432,8 @@ const char *inet_trybind(p_socket ps, const char *address, const char *serv,
407 struct addrinfo *iterator = NULL, *resolved = NULL; 432 struct addrinfo *iterator = NULL, *resolved = NULL;
408 const char *err = NULL; 433 const char *err = NULL;
409 t_socket sock = *ps; 434 t_socket sock = *ps;
410 /* translate luasocket special values to C */
411 if (strcmp(address, "*") == 0) address = NULL;
412 if (!serv) serv = "0";
413 /* try resolving */ 435 /* try resolving */
414 err = socket_gaistrerror(getaddrinfo(address, serv, 436 err = socket_gaistrerror(getaddrinfo(address, serv, bindhints, &resolved));
415 bindhints, &resolved));
416 if (err) { 437 if (err) {
417 if (resolved) freeaddrinfo(resolved); 438 if (resolved) freeaddrinfo(resolved);
418 return err; 439 return err;
@@ -420,7 +441,7 @@ const char *inet_trybind(p_socket ps, const char *address, const char *serv,
420 /* iterate over resolved addresses until one is good */ 441 /* iterate over resolved addresses until one is good */
421 for (iterator = resolved; iterator; iterator = iterator->ai_next) { 442 for (iterator = resolved; iterator; iterator = iterator->ai_next) {
422 if(sock == SOCKET_INVALID) { 443 if(sock == SOCKET_INVALID) {
423 err = socket_strerror( socket_create(&sock, iterator->ai_family, 444 err = socket_strerror(socket_create(&sock, iterator->ai_family,
424 iterator->ai_socktype, iterator->ai_protocol)); 445 iterator->ai_socktype, iterator->ai_protocol));
425 if(err) 446 if(err)
426 continue; 447 continue;
diff --git a/src/inet.h b/src/inet.h
index 05633bb..2346734 100644
--- a/src/inet.h
+++ b/src/inet.h
@@ -29,6 +29,7 @@ const char *inet_tryconnect(p_socket ps, const char *address,
29 const char *serv, p_timeout tm, struct addrinfo *connecthints); 29 const char *serv, p_timeout tm, struct addrinfo *connecthints);
30const char *inet_trybind(p_socket ps, const char *address, const char *serv, 30const char *inet_trybind(p_socket ps, const char *address, const char *serv,
31 struct addrinfo *bindhints); 31 struct addrinfo *bindhints);
32const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm);
32 33
33int inet_meth_getpeername(lua_State *L, p_socket ps, int family); 34int inet_meth_getpeername(lua_State *L, p_socket ps, int family);
34int inet_meth_getsockname(lua_State *L, p_socket ps, int family); 35int inet_meth_getsockname(lua_State *L, p_socket ps, int family);
diff --git a/src/tcp.c b/src/tcp.c
index 2085937..5c85ae0 100644
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -222,6 +222,7 @@ static int meth_bind(lua_State *L)
222 bindhints.ai_socktype = SOCK_STREAM; 222 bindhints.ai_socktype = SOCK_STREAM;
223 bindhints.ai_family = tcp->family; 223 bindhints.ai_family = tcp->family;
224 bindhints.ai_flags = AI_PASSIVE; 224 bindhints.ai_flags = AI_PASSIVE;
225 address = strcmp(address, "*")? address: NULL;
225 err = inet_trybind(&tcp->sock, address, port, &bindhints); 226 err = inet_trybind(&tcp->sock, address, port, &bindhints);
226 if (err) { 227 if (err) {
227 lua_pushnil(L); 228 lua_pushnil(L);
@@ -247,8 +248,7 @@ static int meth_connect(lua_State *L)
247 /* make sure we try to connect only to the same family */ 248 /* make sure we try to connect only to the same family */
248 connecthints.ai_family = tcp->family; 249 connecthints.ai_family = tcp->family;
249 timeout_markstart(&tcp->tm); 250 timeout_markstart(&tcp->tm);
250 err = inet_tryconnect(&tcp->sock, address, port, 251 err = inet_tryconnect(&tcp->sock, address, port, &tcp->tm, &connecthints);
251 &tcp->tm, &connecthints);
252 /* have to set the class even if it failed due to non-blocking connects */ 252 /* have to set the class even if it failed due to non-blocking connects */
253 auxiliar_setclass(L, "tcp{client}", 1); 253 auxiliar_setclass(L, "tcp{client}", 1);
254 if (err) { 254 if (err) {
diff --git a/src/udp.c b/src/udp.c
index bdf584b..4cd9a41 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -275,10 +275,10 @@ static int meth_receivefrom(lua_State *L) {
275 } 275 }
276 break; 276 break;
277 } 277 }
278 default: 278 default:
279 lua_pushnil(L); 279 lua_pushnil(L);
280 lua_pushfstring(L, "unknown family %d", udp->family); 280 lua_pushfstring(L, "unknown family %d", udp->family);
281 return 2; 281 return 2;
282 } 282 }
283 lua_pushnil(L); 283 lua_pushnil(L);
284 lua_pushstring(L, udp_strerror(err)); 284 lua_pushstring(L, udp_strerror(err));
@@ -366,27 +366,30 @@ static int meth_settimeout(lua_State *L) {
366static int meth_setpeername(lua_State *L) { 366static int meth_setpeername(lua_State *L) {
367 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); 367 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
368 p_timeout tm = &udp->tm; 368 p_timeout tm = &udp->tm;
369 const char *address = luaL_checkstring(L, 2); 369 const char *address = luaL_checkstring(L, 2);
370 int connecting = strcmp(address, "*"); 370 int connecting = strcmp(address, "*");
371 const char *port = connecting ? 371 const char *port = connecting? luaL_checkstring(L, 3): "0";
372 luaL_checkstring(L, 3) :
373 luaL_optstring(L, 3, "0");
374 struct addrinfo connecthints; 372 struct addrinfo connecthints;
375 const char *err; 373 const char *err;
376 memset(&connecthints, 0, sizeof(connecthints)); 374 memset(&connecthints, 0, sizeof(connecthints));
377 connecthints.ai_socktype = SOCK_DGRAM; 375 connecthints.ai_socktype = SOCK_DGRAM;
378 /* make sure we try to connect only to the same family */ 376 /* make sure we try to connect only to the same family */
379 connecthints.ai_family = udp->family; 377 connecthints.ai_family = udp->family;
380 err = inet_tryconnect(&udp->sock, address, port, 378 if (connecting) {
381 tm, &connecthints); 379 err = inet_tryconnect(&udp->sock, address, port, tm, &connecthints);
382 if (err) { 380 if (err) {
383 lua_pushnil(L); 381 lua_pushnil(L);
384 lua_pushstring(L, err); 382 lua_pushstring(L, err);
385 return 2; 383 return 2;
384 }
385 auxiliar_setclass(L, "udp{connected}", 1);
386 } else {
387 /* we ignore possible errors because Mac OS X always
388 * returns EAFNOSUPPORT */
389 inet_trydisconnect(&udp->sock, udp->family, tm);
390 auxiliar_setclass(L, "udp{unconnected}", 1);
386 } 391 }
387 /* change class to connected or unconnected depending on address */ 392 /* change class to connected or unconnected depending on address */
388 if (connecting) auxiliar_setclass(L, "udp{connected}", 1);
389 else auxiliar_setclass(L, "udp{unconnected}", 1);
390 lua_pushnumber(L, 1); 393 lua_pushnumber(L, 1);
391 return 1; 394 return 1;
392} 395}