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/udp.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/udp.c')
| -rw-r--r-- | src/udp.c | 35 |
1 files changed, 19 insertions, 16 deletions
| @@ -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) { | |||
| 366 | static int meth_setpeername(lua_State *L) { | 366 | static 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 | } |
