aboutsummaryrefslogtreecommitdiff
path: root/src/udp.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/udp.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/udp.c')
-rw-r--r--src/udp.c35
1 files changed, 19 insertions, 16 deletions
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}