aboutsummaryrefslogtreecommitdiff
path: root/src/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/udp.c')
-rw-r--r--src/udp.c57
1 files changed, 29 insertions, 28 deletions
diff --git a/src/udp.c b/src/udp.c
index 7ff00f5..17d932a 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -27,6 +27,7 @@
27* Internal function prototypes 27* Internal function prototypes
28\*=========================================================================*/ 28\*=========================================================================*/
29static int global_create(lua_State *L); 29static int global_create(lua_State *L);
30static int global_create4(lua_State *L);
30static int global_create6(lua_State *L); 31static int global_create6(lua_State *L);
31static int meth_send(lua_State *L); 32static int meth_send(lua_State *L);
32static int meth_sendto(lua_State *L); 33static int meth_sendto(lua_State *L);
@@ -107,6 +108,7 @@ static t_opt optget[] = {
107/* functions in library namespace */ 108/* functions in library namespace */
108static luaL_Reg func[] = { 109static luaL_Reg func[] = {
109 {"udp", global_create}, 110 {"udp", global_create},
111 {"udp4", global_create4},
110 {"udp6", global_create6}, 112 {"udp6", global_create6},
111 {NULL, NULL} 113 {NULL, NULL}
112}; 114};
@@ -183,7 +185,7 @@ static int meth_sendto(lua_State *L) {
183 return 2; 185 return 2;
184 } 186 }
185 timeout_markstart(tm); 187 timeout_markstart(tm);
186 err = socket_sendto(&udp->sock, data, count, &sent, ai->ai_addr, 188 err = socket_sendto(&udp->sock, data, count, &sent, ai->ai_addr,
187 (socklen_t) ai->ai_addrlen, tm); 189 (socklen_t) ai->ai_addrlen, tm);
188 freeaddrinfo(ai); 190 freeaddrinfo(ai);
189 if (err != IO_DONE) { 191 if (err != IO_DONE) {
@@ -235,7 +237,7 @@ static int meth_receivefrom(lua_State *L)
235 char portstr[6]; 237 char portstr[6];
236 timeout_markstart(tm); 238 timeout_markstart(tm);
237 count = MIN(count, sizeof(buffer)); 239 count = MIN(count, sizeof(buffer));
238 err = socket_recvfrom(&udp->sock, buffer, count, &got, (SA *) &addr, 240 err = socket_recvfrom(&udp->sock, buffer, count, &got, (SA *) &addr,
239 &addr_len, tm); 241 &addr_len, tm);
240 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ 242 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */
241 if (err == IO_CLOSED) 243 if (err == IO_CLOSED)
@@ -245,7 +247,7 @@ static int meth_receivefrom(lua_State *L)
245 lua_pushstring(L, udp_strerror(err)); 247 lua_pushstring(L, udp_strerror(err));
246 return 2; 248 return 2;
247 } 249 }
248 err = getnameinfo((struct sockaddr *)&addr, addr_len, addrstr, 250 err = getnameinfo((struct sockaddr *)&addr, addr_len, addrstr,
249 INET6_ADDRSTRLEN, portstr, 6, NI_NUMERICHOST | NI_NUMERICSERV); 251 INET6_ADDRSTRLEN, portstr, 6, NI_NUMERICHOST | NI_NUMERICSERV);
250 if (err) { 252 if (err) {
251 lua_pushnil(L); 253 lua_pushnil(L);
@@ -264,7 +266,7 @@ static int meth_receivefrom(lua_State *L)
264static int meth_getfamily(lua_State *L) 266static int meth_getfamily(lua_State *L)
265{ 267{
266 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); 268 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
267 if (udp->family == PF_INET6) { 269 if (udp->family == AF_INET6) {
268 lua_pushliteral(L, "inet6"); 270 lua_pushliteral(L, "inet6");
269 return 1; 271 return 1;
270 } else { 272 } else {
@@ -349,7 +351,7 @@ static int meth_setpeername(lua_State *L) {
349 /* make sure we try to connect only to the same family */ 351 /* make sure we try to connect only to the same family */
350 connecthints.ai_family = udp->family; 352 connecthints.ai_family = udp->family;
351 if (connecting) { 353 if (connecting) {
352 err = inet_tryconnect(&udp->sock, &udp->family, address, 354 err = inet_tryconnect(&udp->sock, &udp->family, address,
353 port, tm, &connecthints); 355 port, tm, &connecthints);
354 if (err) { 356 if (err) {
355 lua_pushnil(L); 357 lua_pushnil(L);
@@ -363,7 +365,6 @@ static int meth_setpeername(lua_State *L) {
363 inet_trydisconnect(&udp->sock, udp->family, tm); 365 inet_trydisconnect(&udp->sock, udp->family, tm);
364 auxiliar_setclass(L, "udp{unconnected}", 1); 366 auxiliar_setclass(L, "udp{unconnected}", 1);
365 } 367 }
366 /* change class to connected or unconnected depending on address */
367 lua_pushnumber(L, 1); 368 lua_pushnumber(L, 1);
368 return 1; 369 return 1;
369} 370}
@@ -391,7 +392,7 @@ static int meth_setsockname(lua_State *L) {
391 bindhints.ai_socktype = SOCK_DGRAM; 392 bindhints.ai_socktype = SOCK_DGRAM;
392 bindhints.ai_family = udp->family; 393 bindhints.ai_family = udp->family;
393 bindhints.ai_flags = AI_PASSIVE; 394 bindhints.ai_flags = AI_PASSIVE;
394 err = inet_trybind(&udp->sock, address, port, &bindhints); 395 err = inet_trybind(&udp->sock, &udp->family, address, port, &bindhints);
395 if (err) { 396 if (err) {
396 lua_pushnil(L); 397 lua_pushnil(L);
397 lua_pushstring(L, err); 398 lua_pushstring(L, err);
@@ -408,32 +409,32 @@ static int meth_setsockname(lua_State *L) {
408* Creates a master udp object 409* Creates a master udp object
409\*-------------------------------------------------------------------------*/ 410\*-------------------------------------------------------------------------*/
410static int udp_create(lua_State *L, int family) { 411static int udp_create(lua_State *L, int family) {
411 t_socket sock; 412 /* allocate udp object */
412 const char *err = inet_trycreate(&sock, family, SOCK_DGRAM); 413 p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp));
413 /* try to allocate a system socket */ 414 auxiliar_setclass(L, "udp{unconnected}", -1);
414 if (!err) { 415 /* if family is AF_UNSPEC, we leave the socket invalid and
415 /* allocate udp object */ 416 * store AF_UNSPEC into family. This will allow it to later be
416 p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); 417 * replaced with an AF_INET6 or AF_INET socket upon first use. */
417 auxiliar_setclass(L, "udp{unconnected}", -1); 418 udp->sock = SOCKET_INVALID;
418 /* initialize remaining structure fields */ 419 timeout_init(&udp->tm, -1, -1);
419 socket_setnonblocking(&sock); 420 udp->family = family;
420 if (family == PF_INET6) { 421 if (family != AF_UNSPEC) {
421 int yes = 1; 422 const char *err = inet_trycreate(&udp->sock, family, SOCK_DGRAM, 0);
422 setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, 423 if (err != NULL) {
423 (void *)&yes, sizeof(yes)); 424 lua_pushnil(L);
425 lua_pushstring(L, err);
426 return 2;
424 } 427 }
425 udp->sock = sock; 428 socket_setnonblocking(&udp->sock);
426 timeout_init(&udp->tm, -1, -1);
427 udp->family = family;
428 return 1;
429 } else {
430 lua_pushnil(L);
431 lua_pushstring(L, err);
432 return 2;
433 } 429 }
430 return 1;
434} 431}
435 432
436static int global_create(lua_State *L) { 433static int global_create(lua_State *L) {
434 return udp_create(L, AF_UNSPEC);
435}
436
437static int global_create4(lua_State *L) {
437 return udp_create(L, AF_INET); 438 return udp_create(L, AF_INET);
438} 439}
439 440