diff options
Diffstat (limited to 'src/udp.c')
| -rw-r--r-- | src/udp.c | 12 |
1 files changed, 12 insertions, 0 deletions
| @@ -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) { |
