diff options
| author | Florian Zeitz <florob@babelmonkeys.de> | 2012-07-18 21:05:30 +0200 |
|---|---|---|
| committer | Florian Zeitz <florob@babelmonkeys.de> | 2012-07-18 21:05:30 +0200 |
| commit | 7503bb0ca3f4f6216d48185d7a92e6ba5ef6d124 (patch) | |
| tree | 6cc3bfa29d5af665ed805c80620be4db7a41cf7f /src | |
| parent | a6cf48596d421c5dcc61b745dde73e3265876f69 (diff) | |
| download | luasocket-7503bb0ca3f4f6216d48185d7a92e6ba5ef6d124.tar.gz luasocket-7503bb0ca3f4f6216d48185d7a92e6ba5ef6d124.tar.bz2 luasocket-7503bb0ca3f4f6216d48185d7a92e6ba5ef6d124.zip | |
Add IPv6 support to udp:receivefrom()
Diffstat (limited to 'src')
| -rw-r--r-- | src/udp.c | 70 |
1 files changed, 54 insertions, 16 deletions
| @@ -222,29 +222,67 @@ static int meth_receive(lua_State *L) { | |||
| 222 | \*-------------------------------------------------------------------------*/ | 222 | \*-------------------------------------------------------------------------*/ |
| 223 | static int meth_receivefrom(lua_State *L) { | 223 | static int meth_receivefrom(lua_State *L) { |
| 224 | p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); | 224 | p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); |
| 225 | struct sockaddr_in addr; | ||
| 226 | socklen_t addr_len = sizeof(addr); | ||
| 227 | char buffer[UDP_DATAGRAMSIZE]; | 225 | char buffer[UDP_DATAGRAMSIZE]; |
| 228 | size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); | 226 | size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); |
| 229 | int err; | 227 | int err; |
| 230 | p_timeout tm = &udp->tm; | 228 | p_timeout tm = &udp->tm; |
| 231 | timeout_markstart(tm); | 229 | timeout_markstart(tm); |
| 232 | count = MIN(count, sizeof(buffer)); | 230 | count = MIN(count, sizeof(buffer)); |
| 233 | err = socket_recvfrom(&udp->sock, buffer, count, &got, | 231 | switch (udp->family) { |
| 234 | (SA *) &addr, &addr_len, tm); | 232 | case PF_INET: { |
| 235 | /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ | 233 | struct sockaddr_in addr; |
| 236 | if (err == IO_CLOSED) | 234 | socklen_t addr_len = sizeof(addr); |
| 237 | err = IO_DONE; | 235 | err = socket_recvfrom(&udp->sock, buffer, count, &got, |
| 238 | if (err == IO_DONE) { | 236 | (SA *) &addr, &addr_len, tm); |
| 239 | lua_pushlstring(L, buffer, got); | 237 | /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ |
| 240 | lua_pushstring(L, inet_ntoa(addr.sin_addr)); | 238 | if (err == IO_CLOSED) |
| 241 | lua_pushnumber(L, ntohs(addr.sin_port)); | 239 | err = IO_DONE; |
| 242 | return 3; | 240 | if (err == IO_DONE) { |
| 243 | } else { | 241 | char addrstr[INET_ADDRSTRLEN]; |
| 244 | lua_pushnil(L); | 242 | lua_pushlstring(L, buffer, got); |
| 245 | lua_pushstring(L, udp_strerror(err)); | 243 | if (!inet_ntop(AF_INET, &addr.sin_addr, |
| 246 | return 2; | 244 | addrstr, sizeof(addrstr))) { |
| 245 | lua_pushnil(L); | ||
| 246 | lua_pushstring(L, "invalid source address"); | ||
| 247 | return 2; | ||
| 248 | } | ||
| 249 | lua_pushstring(L, addrstr); | ||
| 250 | lua_pushnumber(L, ntohs(addr.sin_port)); | ||
| 251 | return 3; | ||
| 252 | } | ||
| 253 | break; | ||
| 254 | } | ||
| 255 | case PF_INET6: { | ||
| 256 | struct sockaddr_in6 addr; | ||
| 257 | socklen_t addr_len = sizeof(addr); | ||
| 258 | err = socket_recvfrom(&udp->sock, buffer, count, &got, | ||
| 259 | (SA *) &addr, &addr_len, tm); | ||
| 260 | /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ | ||
| 261 | if (err == IO_CLOSED) | ||
| 262 | err = IO_DONE; | ||
| 263 | if (err == IO_DONE) { | ||
| 264 | char addrstr[INET6_ADDRSTRLEN]; | ||
| 265 | lua_pushlstring(L, buffer, got); | ||
| 266 | if (!inet_ntop(AF_INET6, &addr.sin6_addr, | ||
| 267 | addrstr, sizeof(addrstr))) { | ||
| 268 | lua_pushnil(L); | ||
| 269 | lua_pushstring(L, "invalid source address"); | ||
| 270 | return 2; | ||
| 271 | } | ||
| 272 | lua_pushstring(L, addrstr); | ||
| 273 | lua_pushnumber(L, ntohs(addr.sin6_port)); | ||
| 274 | return 3; | ||
| 275 | } | ||
| 276 | break; | ||
| 277 | } | ||
| 278 | default: | ||
| 279 | lua_pushnil(L); | ||
| 280 | lua_pushfstring(L, "unknown family %d", udp->family); | ||
| 281 | return 2; | ||
| 247 | } | 282 | } |
| 283 | lua_pushnil(L); | ||
| 284 | lua_pushstring(L, udp_strerror(err)); | ||
| 285 | return 2; | ||
| 248 | } | 286 | } |
| 249 | 287 | ||
| 250 | /*-------------------------------------------------------------------------*\ | 288 | /*-------------------------------------------------------------------------*\ |
