aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/reference.html2
-rw-r--r--doc/socket.html25
-rw-r--r--doc/udp.html33
-rw-r--r--src/select.c5
-rw-r--r--src/udp.c58
-rw-r--r--src/udp.h2
-rw-r--r--test/testclnt.lua1
7 files changed, 64 insertions, 62 deletions
diff --git a/doc/reference.html b/doc/reference.html
index 6067ba6..878e7d2 100644
--- a/doc/reference.html
+++ b/doc/reference.html
@@ -147,6 +147,7 @@ Support, Manual">
147<a href="socket.html#connect">connect</a>, 147<a href="socket.html#connect">connect</a>,
148<a href="socket.html#connect">connect4</a>, 148<a href="socket.html#connect">connect4</a>,
149<a href="socket.html#connect">connect6</a>, 149<a href="socket.html#connect">connect6</a>,
150<a href="socket.html#datagramsize">_DATAGRAMSIZE</a>,
150<a href="socket.html#debug">_DEBUG</a>, 151<a href="socket.html#debug">_DEBUG</a>,
151<a href="dns.html#dns">dns</a>, 152<a href="dns.html#dns">dns</a>,
152<a href="socket.html#gettime">gettime</a>, 153<a href="socket.html#gettime">gettime</a>,
@@ -158,6 +159,7 @@ Support, Manual">
158<a href="socket.html#skip">skip</a>, 159<a href="socket.html#skip">skip</a>,
159<a href="socket.html#sleep">sleep</a>, 160<a href="socket.html#sleep">sleep</a>,
160<a href="socket.html#setsize">_SETSIZE</a>, 161<a href="socket.html#setsize">_SETSIZE</a>,
162<a href="socket.html#socketinvalid">_SOCKETINVALID</a>,
161<a href="socket.html#source">source</a>, 163<a href="socket.html#source">source</a>,
162<a href="tcp.html#socket.tcp">tcp</a>, 164<a href="tcp.html#socket.tcp">tcp</a>,
163<a href="tcp.html#socket.tcp4">tcp4</a>, 165<a href="tcp.html#socket.tcp4">tcp4</a>,
diff --git a/doc/socket.html b/doc/socket.html
index e6a9bf8..8a81414 100644
--- a/doc/socket.html
+++ b/doc/socket.html
@@ -90,7 +90,7 @@ of connect are defined as simple helper functions that restrict the
90 90
91<!-- debug ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 91<!-- debug ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
92 92
93<p class=name id=debug> 93<p class=name id=debug>
94socket.<b>_DEBUG</b> 94socket.<b>_DEBUG</b>
95</p> 95</p>
96 96
@@ -99,6 +99,19 @@ This constant is set to <tt><b>true</b></tt> if the library was compiled
99with debug support. 99with debug support.
100</p> 100</p>
101 101
102<!-- datagramsize +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
103
104<p class=name id=debug>
105socket.<b>_DATAGRAMSIZE</b>
106</p>
107
108<p class=description>
109Default datagram size used by calls to
110<a href="udp.html#receive"<tt>receive</tt></a> and
111<a href="udp.html#receivefrom"><tt>receivefrom</tt></a>.
112(Unless changed in compile time, the value is 8192.)
113</p>
114
102<!-- get time +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 115<!-- get time +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
103 116
104<p class=name id=gettime> 117<p class=name id=gettime>
@@ -393,6 +406,16 @@ The maximum number of sockets that the <a
393href=#select><tt>select</tt></a> function can handle. 406href=#select><tt>select</tt></a> function can handle.
394</p> 407</p>
395 408
409<!-- socketinvalid ++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
410
411<p class=name id=socketinvalid>
412socket.<b>_SOCKETINVALID</b>
413</p>
414
415<p class=description>
416The OS value for an invalid socket.
417</p>
418
396<!-- try ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 419<!-- try ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
397 420
398<p class=name id=try> 421<p class=name id=try>
diff --git a/doc/udp.html b/doc/udp.html
index 22d7c72..9437c51 100644
--- a/doc/udp.html
+++ b/doc/udp.html
@@ -42,7 +42,7 @@
42<!-- socket.udp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 42<!-- socket.udp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
43 43
44<p class="name" id="socket.udp"> 44<p class="name" id="socket.udp">
45socket.<b>udp(</b>[buffersize]<b>)</b> 45socket.<b>udp()</b>
46</p> 46</p>
47 47
48<p class="description"> 48<p class="description">
@@ -62,13 +62,6 @@ The <a href="#setpeername"><tt>setpeername</tt></a>
62is used to connect the object. 62is used to connect the object.
63</p> 63</p>
64 64
65<p class="parameters">
66The optional <tt>buffersize</tt> parameter
67specifies the size of the largest datagram that will
68ever be received by the UDP object. The default value is
698192.
70</p>
71
72<p class="return"> 65<p class="return">
73In case of success, a new unconnected UDP object 66In case of success, a new unconnected UDP object
74returned. In case of error, <b><tt>nil</tt></b> is returned, followed by 67returned. In case of error, <b><tt>nil</tt></b> is returned, followed by
@@ -92,7 +85,7 @@ href=#setoption><tt>setoption</tt></a> will fail.
92<!-- socket.udp4 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 85<!-- socket.udp4 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
93 86
94<p class="name" id="socket.udp"> 87<p class="name" id="socket.udp">
95socket.<b>udp4(</b>[buffersize]<b>)</b> 88socket.<b>udp4()</b>
96</p> 89</p>
97 90
98<p class="description"> 91<p class="description">
@@ -112,13 +105,6 @@ The <a href="#setpeername"><tt>setpeername</tt></a>
112is used to connect the object. 105is used to connect the object.
113</p> 106</p>
114 107
115<p class="parameters">
116The optional <tt>buffersize</tt> parameter
117specifies the size of the largest datagram that will
118ever be received by the UDP object. The default value is
1198192.
120</p>
121
122<p class="return"> 108<p class="return">
123In case of success, a new unconnected UDP object 109In case of success, a new unconnected UDP object
124returned. In case of error, <b><tt>nil</tt></b> is returned, followed by 110returned. In case of error, <b><tt>nil</tt></b> is returned, followed by
@@ -128,7 +114,7 @@ an error message.
128<!-- socket.udp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 114<!-- socket.udp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
129 115
130<p class="name" id="socket.udp6"> 116<p class="name" id="socket.udp6">
131socket.<b>udp6(</b>[buffersize]<b>)</b> 117socket.<b>udp6()</b>
132</p> 118</p>
133 119
134<p class="description"> 120<p class="description">
@@ -148,13 +134,6 @@ The <a href="#setpeername"><tt>setpeername</tt></a>
148is used to connect the object. 134is used to connect the object.
149</p> 135</p>
150 136
151<p class="parameters">
152The optional <tt>buffersize</tt> parameter
153specifies the size of the largest datagram that will
154ever be received by the UDP object. The default value is
1558192.
156</p>
157
158<p class="return"> 137<p class="return">
159In case of success, a new unconnected UDP object 138In case of success, a new unconnected UDP object
160returned. In case of error, <b><tt>nil</tt></b> is returned, followed by 139returned. In case of error, <b><tt>nil</tt></b> is returned, followed by
@@ -261,8 +240,10 @@ the excess bytes are discarded. If there are less then
261<tt>size</tt> bytes available in the current datagram, the 240<tt>size</tt> bytes available in the current datagram, the
262available bytes are returned. 241available bytes are returned.
263If <tt>size</tt> is omitted, the 242If <tt>size</tt> is omitted, the
264<tt>buffersize</tt> argument at creation time is used 243compile-time constant <a
265(which defaults to 8192 bytes). 244href=socket.html#datagramsize><tt>socket._DATAGRAMSIZE</tt></a> is used
245(it defaults to 8192 bytes). Larger sizes will cause a
246temporary buffer to be allocated for the operation.
266</p> 247</p>
267 248
268<p class="return"> 249<p class="return">
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
diff --git a/test/testclnt.lua b/test/testclnt.lua
index ee1201f..170e187 100644
--- a/test/testclnt.lua
+++ b/test/testclnt.lua
@@ -669,7 +669,6 @@ local udp_methods = {
669 "settimeout" 669 "settimeout"
670} 670}
671 671
672
673------------------------------------------------------------------------ 672------------------------------------------------------------------------
674test_methods(socket.udp(), udp_methods) 673test_methods(socket.udp(), udp_methods)
675do local sock = socket.tcp6() 674do local sock = socket.tcp6()