diff options
author | Diego Nehab <diego@impa.br> | 2012-08-23 19:31:15 -0300 |
---|---|---|
committer | Diego Nehab <diego@impa.br> | 2012-08-23 19:31:15 -0300 |
commit | 6368caeb5ab5f628b8021c8ebf4d6df436162aaf (patch) | |
tree | 2a2005f2e27ee81e8ced7e4fc84098728e106af0 /src/inet.c | |
parent | 03ba06f70c9ad5cdc9b49d816490fc28d6dbbdc5 (diff) | |
download | luasocket-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.c | 45 |
1 files changed, 33 insertions, 12 deletions
@@ -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 | \*-------------------------------------------------------------------------*/ | ||
373 | const 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; | ||
389 | fprintf(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 | \*-------------------------------------------------------------------------*/ |
373 | const char *inet_tryconnect(p_socket ps, const char *address, | 401 | const 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; |