aboutsummaryrefslogtreecommitdiff
path: root/src/inet.c
diff options
context:
space:
mode:
authorDiego Nehab <diego@impa.br>2012-08-23 19:31:15 -0300
committerDiego Nehab <diego@impa.br>2012-08-23 19:31:15 -0300
commit6368caeb5ab5f628b8021c8ebf4d6df436162aaf (patch)
tree2a2005f2e27ee81e8ced7e4fc84098728e106af0 /src/inet.c
parent03ba06f70c9ad5cdc9b49d816490fc28d6dbbdc5 (diff)
downloadluasocket-6368caeb5ab5f628b8021c8ebf4d6df436162aaf.tar.gz
luasocket-6368caeb5ab5f628b8021c8ebf4d6df436162aaf.tar.bz2
luasocket-6368caeb5ab5f628b8021c8ebf4d6df436162aaf.zip
Fix udp:setpeername("*")
There seems to be a curious difference between MacOS and Linux and I am not sure if this is documented. When you break a "connection" on Mac OS, you only eliminate the peer association, but the local address remains bound. On Linux, breaking a "connection" eliminates the binding to the local address. Have you guys ever come accross this? Another irritating difference is that connect() returns the error EAFNOSUPPORT on Mac OS. I am going to ignore all errors when the reason for calling connect() is simply to break the "connection".
Diffstat (limited to 'src/inet.c')
-rw-r--r--src/inet.c45
1 files changed, 33 insertions, 12 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;