aboutsummaryrefslogtreecommitdiff
path: root/src/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/udp.c')
-rw-r--r--src/udp.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/udp.c b/src/udp.c
index 6c0d39e..6d017da 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -283,6 +283,7 @@ static int meth_receivefrom(lua_State *L) {
283 lua_pushliteral(L, "out of memory"); 283 lua_pushliteral(L, "out of memory");
284 return 2; 284 return 2;
285 } 285 }
286 memset(&addr, 0, sizeof(addr));
286 err = socket_recvfrom(&udp->sock, dgram, wanted, &got, (SA *) &addr, 287 err = socket_recvfrom(&udp->sock, dgram, wanted, &got, (SA *) &addr,
287 &addr_len, tm); 288 &addr_len, tm);
288 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ 289 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */
@@ -292,6 +293,17 @@ static int meth_receivefrom(lua_State *L) {
292 if (wanted > sizeof(buf)) free(dgram); 293 if (wanted > sizeof(buf)) free(dgram);
293 return 2; 294 return 2;
294 } 295 }
296 /* a zero-length request may be satisfied by some kernels (notably
297 * Darwin/BSD) without ever touching the sender's address -- only
298 * resolve it when the OS actually reported one, instead of feeding
299 * getnameinfo() a garbage/zeroed sockaddr. */
300 if (addr.ss_family != AF_INET && addr.ss_family != AF_INET6) {
301 lua_pushlstring(L, dgram, got);
302 lua_pushnil(L);
303 lua_pushnil(L);
304 if (wanted > sizeof(buf)) free(dgram);
305 return 3;
306 }
295 err = getnameinfo((struct sockaddr *)&addr, addr_len, addrstr, 307 err = getnameinfo((struct sockaddr *)&addr, addr_len, addrstr,
296 INET6_ADDRSTRLEN, portstr, 6, NI_NUMERICHOST | NI_NUMERICSERV); 308 INET6_ADDRSTRLEN, portstr, 6, NI_NUMERICHOST | NI_NUMERICSERV);
297 if (err) { 309 if (err) {