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