aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/select.c5
-rw-r--r--src/udp.c58
-rw-r--r--src/udp.h2
3 files changed, 31 insertions, 34 deletions
diff --git a/src/select.c b/src/select.c
index d14c40a..9d133b7 100644
--- a/src/select.c
+++ b/src/select.c
@@ -39,7 +39,10 @@ static luaL_Reg func[] = {
39\*-------------------------------------------------------------------------*/ 39\*-------------------------------------------------------------------------*/
40int select_open(lua_State *L) { 40int select_open(lua_State *L) {
41 lua_pushstring(L, "_SETSIZE"); 41 lua_pushstring(L, "_SETSIZE");
42 lua_pushnumber(L, FD_SETSIZE); 42 lua_pushinteger(L, FD_SETSIZE);
43 lua_rawset(L, -3);
44 lua_pushstring(L, "_SOCKETINVALID");
45 lua_pushinteger(L, SOCKET_INVALID);
43 lua_rawset(L, -3); 46 lua_rawset(L, -3);
44 luaL_setfuncs(L, func, 0); 47 luaL_setfuncs(L, func, 0);
45 return 0; 48 return 0;
diff --git a/src/udp.c b/src/udp.c
index 9c27b60..968dca8 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -41,7 +41,6 @@ static int meth_setpeername(lua_State *L);
41static int meth_close(lua_State *L); 41static int meth_close(lua_State *L);
42static int meth_setoption(lua_State *L); 42static int meth_setoption(lua_State *L);
43static int meth_getoption(lua_State *L); 43static int meth_getoption(lua_State *L);
44static int meth_getbufferlength(lua_State *L);
45static int meth_settimeout(lua_State *L); 44static int meth_settimeout(lua_State *L);
46static int meth_getfd(lua_State *L); 45static int meth_getfd(lua_State *L);
47static int meth_setfd(lua_State *L); 46static int meth_setfd(lua_State *L);
@@ -64,7 +63,6 @@ static luaL_Reg udp_methods[] = {
64 {"setfd", meth_setfd}, 63 {"setfd", meth_setfd},
65 {"setoption", meth_setoption}, 64 {"setoption", meth_setoption},
66 {"getoption", meth_getoption}, 65 {"getoption", meth_getoption},
67 {"getoption", meth_getbufferlength},
68 {"setpeername", meth_setpeername}, 66 {"setpeername", meth_setpeername},
69 {"setsockname", meth_setsockname}, 67 {"setsockname", meth_setsockname},
70 {"settimeout", meth_settimeout}, 68 {"settimeout", meth_settimeout},
@@ -118,8 +116,7 @@ static luaL_Reg func[] = {
118/*-------------------------------------------------------------------------*\ 116/*-------------------------------------------------------------------------*\
119* Initializes module 117* Initializes module
120\*-------------------------------------------------------------------------*/ 118\*-------------------------------------------------------------------------*/
121int udp_open(lua_State *L) 119int udp_open(lua_State *L) {
122{
123 /* create classes */ 120 /* create classes */
124 auxiliar_newclass(L, "udp{connected}", udp_methods); 121 auxiliar_newclass(L, "udp{connected}", udp_methods);
125 auxiliar_newclass(L, "udp{unconnected}", udp_methods); 122 auxiliar_newclass(L, "udp{unconnected}", udp_methods);
@@ -130,6 +127,10 @@ int udp_open(lua_State *L)
130 auxiliar_add2group(L, "udp{unconnected}", "select{able}"); 127 auxiliar_add2group(L, "udp{unconnected}", "select{able}");
131 /* define library functions */ 128 /* define library functions */
132 luaL_setfuncs(L, func, 0); 129 luaL_setfuncs(L, func, 0);
130 /* export default UDP size */
131 lua_pushliteral(L, "_DATAGRAMSIZE");
132 lua_pushinteger(L, UDP_DATAGRAMSIZE);
133 lua_rawset(L, -3);
133 return 0; 134 return 0;
134} 135}
135 136
@@ -205,30 +206,26 @@ static int meth_sendto(lua_State *L) {
205static int meth_receive(lua_State *L) { 206static int meth_receive(lua_State *L) {
206 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); 207 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
207 char buf[UDP_DATAGRAMSIZE]; 208 char buf[UDP_DATAGRAMSIZE];
208 size_t len = MAX(udp->len, UDP_DATAGRAMSIZE); 209 size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf));
209 char *dgram = len > sizeof(buf)? udp->buf: buf; 210 char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf;
210 size_t got, wanted = (size_t) luaL_optnumber(L, 2, len);
211 int err; 211 int err;
212 p_timeout tm = &udp->tm; 212 p_timeout tm = &udp->tm;
213 timeout_markstart(tm); 213 timeout_markstart(tm);
214 wanted = MIN(wanted, len); 214 if (!dgram) {
215 lua_pushnil(L);
216 lua_pushliteral(L, "out of memory");
217 return 2;
218 }
215 err = socket_recv(&udp->sock, dgram, wanted, &got, tm); 219 err = socket_recv(&udp->sock, dgram, wanted, &got, tm);
216 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ 220 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */
217 if (err != IO_DONE && err != IO_CLOSED ) { 221 if (err != IO_DONE && err != IO_CLOSED) {
218 lua_pushnil(L); 222 lua_pushnil(L);
219 lua_pushstring(L, udp_strerror(err)); 223 lua_pushstring(L, udp_strerror(err));
224 if (wanted > sizeof(buf)) free(dgram);
220 return 2; 225 return 2;
221 } 226 }
222 lua_pushlstring(L, dgram, got); 227 lua_pushlstring(L, dgram, got);
223 return 1; 228 if (wanted > sizeof(buf)) free(dgram);
224}
225
226/*-------------------------------------------------------------------------*\
227* Receives data from a UDP socket
228\*-------------------------------------------------------------------------*/
229static int meth_getbufferlength(lua_State *L) {
230 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
231 lua_pushinteger(L, MAX(UDP_DATAGRAMSIZE, udp->len));
232 return 1; 229 return 1;
233} 230}
234 231
@@ -238,9 +235,8 @@ static int meth_getbufferlength(lua_State *L) {
238static int meth_receivefrom(lua_State *L) { 235static int meth_receivefrom(lua_State *L) {
239 p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); 236 p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1);
240 char buf[UDP_DATAGRAMSIZE]; 237 char buf[UDP_DATAGRAMSIZE];
241 size_t len = MAX(udp->len, UDP_DATAGRAMSIZE); 238 size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf));
242 char *dgram = len > sizeof(buf)? udp->buf: buf; 239 char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf;
243 size_t got, wanted = (size_t) luaL_optnumber(L, 2, len);
244 struct sockaddr_storage addr; 240 struct sockaddr_storage addr;
245 socklen_t addr_len = sizeof(addr); 241 socklen_t addr_len = sizeof(addr);
246 char addrstr[INET6_ADDRSTRLEN]; 242 char addrstr[INET6_ADDRSTRLEN];
@@ -248,13 +244,18 @@ static int meth_receivefrom(lua_State *L) {
248 int err; 244 int err;
249 p_timeout tm = &udp->tm; 245 p_timeout tm = &udp->tm;
250 timeout_markstart(tm); 246 timeout_markstart(tm);
251 wanted = MIN(wanted, len); 247 if (!dgram) {
248 lua_pushnil(L);
249 lua_pushliteral(L, "out of memory");
250 return 2;
251 }
252 err = socket_recvfrom(&udp->sock, dgram, wanted, &got, (SA *) &addr, 252 err = socket_recvfrom(&udp->sock, dgram, wanted, &got, (SA *) &addr,
253 &addr_len, tm); 253 &addr_len, tm);
254 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ 254 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */
255 if (err != IO_DONE && err != IO_CLOSED) { 255 if (err != IO_DONE && err != IO_CLOSED) {
256 lua_pushnil(L); 256 lua_pushnil(L);
257 lua_pushstring(L, udp_strerror(err)); 257 lua_pushstring(L, udp_strerror(err));
258 if (wanted > sizeof(buf)) free(dgram);
258 return 2; 259 return 2;
259 } 260 }
260 err = getnameinfo((struct sockaddr *)&addr, addr_len, addrstr, 261 err = getnameinfo((struct sockaddr *)&addr, addr_len, addrstr,
@@ -262,19 +263,20 @@ static int meth_receivefrom(lua_State *L) {
262 if (err) { 263 if (err) {
263 lua_pushnil(L); 264 lua_pushnil(L);
264 lua_pushstring(L, gai_strerror(err)); 265 lua_pushstring(L, gai_strerror(err));
266 if (wanted > sizeof(buf)) free(dgram);
265 return 2; 267 return 2;
266 } 268 }
267 lua_pushlstring(L, dgram, got); 269 lua_pushlstring(L, dgram, got);
268 lua_pushstring(L, addrstr); 270 lua_pushstring(L, addrstr);
269 lua_pushinteger(L, (int) strtol(portstr, (char **) NULL, 10)); 271 lua_pushinteger(L, (int) strtol(portstr, (char **) NULL, 10));
272 if (wanted > sizeof(buf)) free(dgram);
270 return 3; 273 return 3;
271} 274}
272 275
273/*-------------------------------------------------------------------------*\ 276/*-------------------------------------------------------------------------*\
274* Returns family as string 277* Returns family as string
275\*-------------------------------------------------------------------------*/ 278\*-------------------------------------------------------------------------*/
276static int meth_getfamily(lua_State *L) 279static int meth_getfamily(lua_State *L) {
277{
278 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); 280 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
279 if (udp->family == AF_INET6) { 281 if (udp->family == AF_INET6) {
280 lua_pushliteral(L, "inet6"); 282 lua_pushliteral(L, "inet6");
@@ -419,19 +421,13 @@ static int meth_setsockname(lua_State *L) {
419* Creates a master udp object 421* Creates a master udp object
420\*-------------------------------------------------------------------------*/ 422\*-------------------------------------------------------------------------*/
421static int udp_create(lua_State *L, int family) { 423static int udp_create(lua_State *L, int family) {
422 p_udp udp = NULL;
423 /* optional length for private datagram buffer. this is useful when
424 * you need larger datagrams than UDP_DATAGRAMSIZE */
425 size_t len = (size_t) luaL_optinteger(L, 1, 0);
426 if (len <= UDP_DATAGRAMSIZE) len = 0;
427 /* allocate udp object */ 424 /* allocate udp object */
428 udp = (p_udp) lua_newuserdata(L, sizeof(t_udp) + len - 1); 425 p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp));
429 auxiliar_setclass(L, "udp{unconnected}", -1); 426 auxiliar_setclass(L, "udp{unconnected}", -1);
430 /* if family is AF_UNSPEC, we leave the socket invalid and 427 /* if family is AF_UNSPEC, we leave the socket invalid and
431 * store AF_UNSPEC into family. This will allow it to later be 428 * store AF_UNSPEC into family. This will allow it to later be
432 * replaced with an AF_INET6 or AF_INET socket upon first use. */ 429 * replaced with an AF_INET6 or AF_INET socket upon first use. */
433 udp->sock = SOCKET_INVALID; 430 udp->sock = SOCKET_INVALID;
434 udp->len = len;
435 timeout_init(&udp->tm, -1, -1); 431 timeout_init(&udp->tm, -1, -1);
436 udp->family = family; 432 udp->family = family;
437 if (family != AF_UNSPEC) { 433 if (family != AF_UNSPEC) {
diff --git a/src/udp.h b/src/udp.h
index da27a7a..be9b6a5 100644
--- a/src/udp.h
+++ b/src/udp.h
@@ -23,8 +23,6 @@ typedef struct t_udp_ {
23 t_socket sock; 23 t_socket sock;
24 t_timeout tm; 24 t_timeout tm;
25 int family; 25 int family;
26 size_t len; /* length of datagram buffer below */
27 char buf[1]; /* allocate larger structure to hold actual buffer */
28} t_udp; 26} t_udp;
29typedef t_udp *p_udp; 27typedef t_udp *p_udp;
30 28