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 | |
parent | a6cf48596d421c5dcc61b745dde73e3265876f69 (diff) | |
download | luasocket-7503bb0ca3f4f6216d48185d7a92e6ba5ef6d124.tar.gz luasocket-7503bb0ca3f4f6216d48185d7a92e6ba5ef6d124.tar.bz2 luasocket-7503bb0ca3f4f6216d48185d7a92e6ba5ef6d124.zip |
Add IPv6 support to udp:receivefrom()
-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 | /*-------------------------------------------------------------------------*\ |