diff options
Diffstat (limited to 'src/udp.c')
-rw-r--r-- | src/udp.c | 122 |
1 files changed, 62 insertions, 60 deletions
@@ -155,31 +155,31 @@ static int meth_sendto(lua_State *L) { | |||
155 | p_timeout tm = &udp->tm; | 155 | p_timeout tm = &udp->tm; |
156 | int err; | 156 | int err; |
157 | switch (udp->family) { | 157 | switch (udp->family) { |
158 | case PF_INET: { | 158 | case PF_INET: { |
159 | struct sockaddr_in addr; | 159 | struct sockaddr_in addr; |
160 | memset(&addr, 0, sizeof(addr)); | 160 | memset(&addr, 0, sizeof(addr)); |
161 | if (inet_pton(AF_INET, ip, &addr.sin_addr) != 1) | 161 | if (inet_pton(AF_INET, ip, &addr.sin_addr) != 1) |
162 | luaL_argerror(L, 3, "invalid ip address"); | 162 | luaL_argerror(L, 3, "invalid ip address"); |
163 | addr.sin_family = AF_INET; | 163 | addr.sin_family = AF_INET; |
164 | addr.sin_port = htons(port); | 164 | addr.sin_port = htons(port); |
165 | timeout_markstart(tm); | 165 | timeout_markstart(tm); |
166 | err = socket_sendto(&udp->sock, data, count, &sent, | 166 | err = socket_sendto(&udp->sock, data, count, &sent, |
167 | (SA *) &addr, sizeof(addr), tm); | 167 | (SA *) &addr, sizeof(addr), tm); |
168 | break; | 168 | break; |
169 | } | 169 | } |
170 | case PF_INET6: { | 170 | case PF_INET6: { |
171 | struct sockaddr_in6 addr; | 171 | struct sockaddr_in6 addr; |
172 | memset(&addr, 0, sizeof(addr)); | 172 | memset(&addr, 0, sizeof(addr)); |
173 | if (!inet_pton(AF_INET6, ip, &addr.sin6_addr) != 1) | 173 | if (!inet_pton(AF_INET6, ip, &addr.sin6_addr) != 1) |
174 | luaL_argerror(L, 3, "invalid ip address"); | 174 | luaL_argerror(L, 3, "invalid ip address"); |
175 | addr.sin6_family = AF_INET6; | 175 | addr.sin6_family = AF_INET6; |
176 | addr.sin6_port = htons(port); | 176 | addr.sin6_port = htons(port); |
177 | timeout_markstart(tm); | 177 | timeout_markstart(tm); |
178 | err = socket_sendto(&udp->sock, data, count, &sent, | 178 | err = socket_sendto(&udp->sock, data, count, &sent, |
179 | (SA *) &addr, sizeof(addr), tm); | 179 | (SA *) &addr, sizeof(addr), tm); |
180 | break; | 180 | break; |
181 | } | 181 | } |
182 | default: | 182 | default: |
183 | lua_pushnil(L); | 183 | lua_pushnil(L); |
184 | lua_pushfstring(L, "unknown family %d", udp->family); | 184 | lua_pushfstring(L, "unknown family %d", udp->family); |
185 | return 2; | 185 | return 2; |
@@ -229,38 +229,40 @@ static int meth_receivefrom(lua_State *L) { | |||
229 | timeout_markstart(tm); | 229 | timeout_markstart(tm); |
230 | count = MIN(count, sizeof(buffer)); | 230 | count = MIN(count, sizeof(buffer)); |
231 | switch (udp->family) { | 231 | switch (udp->family) { |
232 | case PF_INET: { | 232 | case PF_INET: { |
233 | struct sockaddr_in addr; | 233 | struct sockaddr_in addr; |
234 | socklen_t addr_len = sizeof(addr); | 234 | socklen_t addr_len = sizeof(addr); |
235 | err = socket_recvfrom(&udp->sock, buffer, count, &got, | 235 | err = socket_recvfrom(&udp->sock, buffer, count, &got, |
236 | (SA *) &addr, &addr_len, tm); | 236 | (SA *) &addr, &addr_len, tm); |
237 | /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ | 237 | /* Unlike TCP, recv() of zero is not closed, |
238 | if (err == IO_CLOSED) | 238 | * but a zero-length packet. */ |
239 | err = IO_DONE; | 239 | if (err == IO_CLOSED) |
240 | if (err == IO_DONE) { | 240 | err = IO_DONE; |
241 | char addrstr[INET_ADDRSTRLEN]; | 241 | if (err == IO_DONE) { |
242 | lua_pushlstring(L, buffer, got); | 242 | char addrstr[INET_ADDRSTRLEN]; |
243 | if (!inet_ntop(AF_INET, &addr.sin_addr, | 243 | lua_pushlstring(L, buffer, got); |
244 | addrstr, sizeof(addrstr))) { | 244 | if (!inet_ntop(AF_INET, &addr.sin_addr, |
245 | lua_pushnil(L); | 245 | addrstr, sizeof(addrstr))) { |
246 | lua_pushstring(L, "invalid source address"); | 246 | lua_pushnil(L); |
247 | return 2; | 247 | lua_pushstring(L, "invalid source address"); |
248 | } | 248 | return 2; |
249 | lua_pushstring(L, addrstr); | 249 | } |
250 | lua_pushnumber(L, ntohs(addr.sin_port)); | 250 | lua_pushstring(L, addrstr); |
251 | return 3; | 251 | lua_pushnumber(L, ntohs(addr.sin_port)); |
252 | } | 252 | return 3; |
253 | break; | 253 | } |
254 | } | 254 | break; |
255 | case PF_INET6: { | 255 | } |
256 | struct sockaddr_in6 addr; | 256 | case PF_INET6: { |
257 | socklen_t addr_len = sizeof(addr); | 257 | struct sockaddr_in6 addr; |
258 | err = socket_recvfrom(&udp->sock, buffer, count, &got, | 258 | socklen_t addr_len = sizeof(addr); |
259 | (SA *) &addr, &addr_len, tm); | 259 | err = socket_recvfrom(&udp->sock, buffer, count, &got, |
260 | /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ | 260 | (SA *) &addr, &addr_len, tm); |
261 | if (err == IO_CLOSED) | 261 | /* Unlike TCP, recv() of zero is not closed, |
262 | * but a zero-length packet. */ | ||
263 | if (err == IO_CLOSED) | ||
262 | err = IO_DONE; | 264 | err = IO_DONE; |
263 | if (err == IO_DONE) { | 265 | if (err == IO_DONE) { |
264 | char addrstr[INET6_ADDRSTRLEN]; | 266 | char addrstr[INET6_ADDRSTRLEN]; |
265 | lua_pushlstring(L, buffer, got); | 267 | lua_pushlstring(L, buffer, got); |
266 | if (!inet_ntop(AF_INET6, &addr.sin6_addr, | 268 | if (!inet_ntop(AF_INET6, &addr.sin6_addr, |
@@ -272,9 +274,9 @@ static int meth_receivefrom(lua_State *L) { | |||
272 | lua_pushstring(L, addrstr); | 274 | lua_pushstring(L, addrstr); |
273 | lua_pushnumber(L, ntohs(addr.sin6_port)); | 275 | lua_pushnumber(L, ntohs(addr.sin6_port)); |
274 | return 3; | 276 | return 3; |
275 | } | 277 | } |
276 | break; | 278 | break; |
277 | } | 279 | } |
278 | default: | 280 | default: |
279 | lua_pushnil(L); | 281 | lua_pushnil(L); |
280 | lua_pushfstring(L, "unknown family %d", udp->family); | 282 | lua_pushfstring(L, "unknown family %d", udp->family); |
@@ -413,7 +415,7 @@ static int meth_setsockname(lua_State *L) { | |||
413 | const char *address = luaL_checkstring(L, 2); | 415 | const char *address = luaL_checkstring(L, 2); |
414 | const char *port = luaL_checkstring(L, 3); | 416 | const char *port = luaL_checkstring(L, 3); |
415 | const char *err; | 417 | const char *err; |
416 | struct addrinfo bindhints; | 418 | struct addrinfo bindhints; |
417 | memset(&bindhints, 0, sizeof(bindhints)); | 419 | memset(&bindhints, 0, sizeof(bindhints)); |
418 | bindhints.ai_socktype = SOCK_DGRAM; | 420 | bindhints.ai_socktype = SOCK_DGRAM; |
419 | bindhints.ai_family = udp->family; | 421 | bindhints.ai_family = udp->family; |
@@ -461,9 +463,9 @@ static int udp_create(lua_State *L, int family) { | |||
461 | } | 463 | } |
462 | 464 | ||
463 | static int global_create(lua_State *L) { | 465 | static int global_create(lua_State *L) { |
464 | return udp_create(L, AF_INET); | 466 | return udp_create(L, AF_INET); |
465 | } | 467 | } |
466 | 468 | ||
467 | static int global_create6(lua_State *L) { | 469 | static int global_create6(lua_State *L) { |
468 | return udp_create(L, AF_INET6); | 470 | return udp_create(L, AF_INET6); |
469 | } | 471 | } |