aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2002-07-03 19:06:52 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2002-07-03 19:06:52 +0000
commitb04b81ddd959948143f817ee7230783660e24222 (patch)
tree524d50637a604f5b10e236dd783586fe8d6495fa /src
parent5a92c17d8534e7ac762de1bd6b825039f71099f3 (diff)
downloadluasocket-b04b81ddd959948143f817ee7230783660e24222.tar.gz
luasocket-b04b81ddd959948143f817ee7230783660e24222.tar.bz2
luasocket-b04b81ddd959948143f817ee7230783660e24222.zip
main module. just initializes other modules.
Diffstat (limited to 'src')
-rw-r--r--src/luasocket.c2188
1 files changed, 37 insertions, 2151 deletions
diff --git a/src/luasocket.c b/src/luasocket.c
index 636bec2..d329d4e 100644
--- a/src/luasocket.c
+++ b/src/luasocket.c
@@ -1,2174 +1,60 @@
1/*=========================================================================*\ 1/*=========================================================================*\
2* IPv4 Sockets for the Lua language 2* Networking support for the Lua language
3* Diego Nehab 3* Diego Nehab
4* 26/11/1999 4* 26/11/1999
5* 5*
6* Module: luasocket.c 6* This library is part of an effort to progressively increase the network
7* 7* connectivity of the Lua language. The Lua interface to networking
8* This module is part of an effort to make the most important features 8* functions follows the Sockets API closely, trying to simplify all tasks
9* of the IPv4 Socket layer available to Lua scripts. 9* involved in setting up both client and server connections. The provided
10* The Lua interface to TCP/IP follows the BSD TCP/IP API closely, 10* IO routines, however, follow the Lua style, being very similar to the
11* trying to simplify all tasks involved in setting up both client 11* standard Lua read and write functions.
12* and server connections.
13* The provided IO routines, send and receive, follow the Lua style, being
14* very similar to the standard Lua read and write functions.
15* The module implements both a BSD bind and a Winsock2 bind, and has
16* been tested on several Unix flavors, as well as Windows 98 and NT.
17* 12*
18* RCS ID: $Id$ 13* RCS ID: $Id$
19\*=========================================================================*/ 14\*=========================================================================*/
20 15
21/*=========================================================================*\ 16/*=========================================================================*\
22* Common include files 17* Standard include files
23\*=========================================================================*/ 18\*=========================================================================*/
24#include <errno.h>
25#include <signal.h>
26#include <stdlib.h>
27#include <string.h>
28#include <ctype.h>
29
30#include <lauxlib.h>
31#include <lua.h> 19#include <lua.h>
32 20#include <lauxlib.h>
33#include "luasocket.h"
34
35/*=========================================================================*\
36* WinSock2 include files
37\*=========================================================================*/
38#ifdef WIN32
39#include <winsock2.h>
40#include <winbase.h>
41#else
42
43/*=========================================================================*\
44* BSD include files
45\*=========================================================================*/
46/* close function */
47#include <unistd.h>
48/* fnctnl function and associated constants */
49#include <fcntl.h>
50/* struct timeval and CLK_TCK */
51#include <sys/time.h>
52/* times function and struct tms */
53#include <sys/times.h>
54/* internet protocol definitions */
55#include <netinet/in.h>
56#include <arpa/inet.h>
57/* struct sockaddr */
58#include <sys/types.h>
59/* socket function */
60#include <sys/socket.h>
61/* gethostbyname and gethostbyaddr functions */
62#include <netdb.h>
63#endif
64
65/*=========================================================================*\
66* Datatype compatibilization and some simple changes
67\*=========================================================================*/
68#ifndef WIN32
69/* WinSock2 has a closesock function instead of the regular close */
70#define closesocket close
71/* it defines a SOCKET type instead of using an integer file descriptor */
72#define SOCKET int
73/* and uses the this macro to represent and invalid socket */
74#define INVALID_SOCKET (-1)
75/* SunOS, does not define CLK_TCK */
76#ifndef CLK_TCK
77#define CLK_TCK 60
78#endif
79#endif
80
81/*=========================================================================*\
82* Module definitions
83\*=========================================================================*/
84/*-------------------------------------------------------------------------*\
85* The send and receive function can return one of the following return
86* codes. The values are mapped into Lua values by the function
87* push_error.
88\*-------------------------------------------------------------------------*/
89#define NET_DONE -1 /* operation completed successfully */
90#define NET_TIMEOUT 0 /* operation timed out */
91#define NET_CLOSED 1 /* the connection has been closed */
92#define NET_REFUSED 2 /* the data transfer has been refused */
93
94/*-------------------------------------------------------------------------*\
95* Time out mode to be checked
96\*-------------------------------------------------------------------------*/
97#define TM_RECEIVE 1
98#define TM_SEND 2
99
100/*-------------------------------------------------------------------------*\
101* Each socket is represented by a table with the supported methods and
102* the p_sock structure as fields.
103\*-------------------------------------------------------------------------*/
104#define P_SOCK "(p_sock)sock"
105
106/*-------------------------------------------------------------------------*\
107* Both socket types are stored in the same structure to simplify
108* implementation. The tag value used is different, though.
109* The buffer parameters are not used by server and UDP sockets.
110\*-------------------------------------------------------------------------*/
111typedef struct t_sock {
112 /* operating system socket object */
113 SOCKET sock;
114 /* start time of the current operation */
115 int tm_start;
116 /* return and blocking timeout values (-1 if no limit) */
117 int tm_return, tm_block;
118 /* buffered I/O storage */
119 unsigned char bf_buffer[LUASOCKET_TCPBUFFERSIZE];
120 /* first and last red bytes not yet passed to application */
121 int bf_first, bf_last;
122 /* is this udp socket in "connected" state? */
123 int is_connected;
124#ifdef _DEBUG
125 /* end time of current operation, for debug purposes */
126 int tm_end;
127#endif
128} t_sock;
129typedef t_sock *p_sock;
130
131/*-------------------------------------------------------------------------*\
132* Tags passed as closure values to global LuaSocket API functions
133\*-------------------------------------------------------------------------*/
134typedef struct t_tags {
135 int client, server, table, udp;
136} t_tags;
137typedef t_tags *p_tags;
138
139/*-------------------------------------------------------------------------*\
140* Macros and internal declarations
141\*-------------------------------------------------------------------------*/
142/* min and max macros */
143#ifndef MIN
144#define MIN(x, y) ((x) < (y) ? x : y)
145#endif
146#ifndef MAX
147#define MAX(x, y) ((x) > (y) ? x : y)
148#endif
149
150/* we are lazy.. */
151typedef struct sockaddr SA;
152
153/*=========================================================================*\
154* Internal function prototypes
155\*=========================================================================*/
156/* luasocket global API functions */
157static int global_tcpconnect(lua_State *L);
158static int global_tcpbind(lua_State *L);
159static int global_select(lua_State *L);
160static int global_toip(lua_State *L);
161static int global_tohostname(lua_State *L);
162static int global_udpsocket(lua_State *L);
163
164#ifndef LUASOCKET_NOGLOBALS
165static int global_callfromtable(lua_State *L);
166#endif
167
168/* luasocket table method API functions */
169static int table_tcpaccept(lua_State *L);
170static int table_tcpsend(lua_State *L);
171static int table_tcpreceive(lua_State *L);
172static int table_udpsendto(lua_State *L);
173static int table_udpreceivefrom(lua_State *L);
174static int table_udpsetpeername(lua_State *L);
175static int table_timeout(lua_State *L);
176static int table_close(lua_State *L);
177static int table_getpeername(lua_State *L);
178static int table_getsockname(lua_State *L);
179
180/* buffered I/O management */
181static const unsigned char *bf_receive(p_sock sock, int *length);
182static void bf_skip(p_sock sock, int length);
183static int bf_isempty(p_sock sock);
184
185/* timeout management */
186static int tm_timedout(p_sock sock, int mode);
187static int tm_gettimeleft(p_sock sock);
188static int tm_gettime(void);
189static void tm_markstart(p_sock sock);
190
191/* I/O */
192static int send_raw(p_sock sock, const char *data, int wanted, int *err);
193static int receive_raw(lua_State *L, p_sock sock, int wanted);
194static int receive_word(lua_State *L, p_sock sock);
195static int receive_dosline(lua_State *L, p_sock sock);
196static int receive_unixline(lua_State *L, p_sock sock);
197static int receive_all(lua_State *L, p_sock sock);
198
199/* parameter manipulation functions */
200static p_tags pop_tags(lua_State *L);
201static p_sock pop_sock(lua_State *L);
202static p_sock get_sock(lua_State *L, int s, p_tags tags, int *tag);
203static p_sock get_selfsock(lua_State *L, p_tags tags, int *tag);
204static p_sock push_servertable(lua_State *L, p_tags tags);
205static p_sock push_clienttable(lua_State *L, p_tags tags);
206static p_sock push_udptable(lua_State *L, p_tags tags);
207static void push_error(lua_State *L, int err);
208static void push_resolved(lua_State *L, struct hostent *hp);
209
210/* error code translations functions */
211static char *host_strerror(void);
212static char *bind_strerror(void);
213static char *socket_strerror(void);
214static char *connect_strerror(void);
215
216/* socket auxiliary functions */
217static const char *tcp_trybind(p_sock sock, const char *address,
218 unsigned short port, int backlog);
219static const char *tcp_tryconnect(p_sock sock, const char *address,
220 unsigned short port);
221static const char *udp_setpeername(p_sock sock, const char *address,
222 unsigned short port);
223static const char *udp_setsockname(p_sock sock, const char *address,
224 unsigned short port);
225static int set_option(lua_State *L, p_sock sock);
226static void set_reuseaddr(p_sock sock);
227static void set_blocking(p_sock sock);
228static void set_nonblocking(p_sock sock);
229
230#ifdef WIN32
231static int winsock_open(void);
232#define LUASOCKET_ATON
233#endif
234
235#ifdef LUASOCKET_ATON
236static int inet_aton(const char *cp, struct in_addr *inp);
237#endif
238
239/* tag methods */
240static int gc_table(lua_State *L);
241
242/*=========================================================================*\
243* Test support functions
244\*=========================================================================*/
245#ifdef _DEBUG
246/*-------------------------------------------------------------------------*\
247* Returns the time the system has been up, in secconds.
248\*-------------------------------------------------------------------------*/
249static int global_time(lua_State *L);
250static int global_time(lua_State *L)
251{
252 lua_pushnumber(L, tm_gettime()/1000.0);
253 return 1;
254}
255
256/*-------------------------------------------------------------------------*\
257* Causes a Lua script to sleep for the specified number of secconds
258\*-------------------------------------------------------------------------*/
259static int global_sleep(lua_State *L);
260static int global_sleep(lua_State *L)
261{
262 int sec = (int) luaL_check_number(L, 1);
263#ifdef WIN32
264 Sleep(1000*sec);
265#else
266 sleep(sec);
267#endif
268 return 0;
269}
270
271#endif
272
273/*=========================================================================*\
274* Lua exported functions
275* These functions can be accessed from a Lua script.
276\*=========================================================================*/
277/*-------------------------------------------------------------------------*\
278* Creates a client socket and returns it to the Lua script. The timeout
279* values are initialized as -1 so that the socket will block at any
280* IO operation.
281* Lua Input: address, port
282* address: host name or ip address to connect to
283* port: port number on host
284* Lua Returns
285* On success: client socket object
286* On error: nil, followed by an error message
287\*-------------------------------------------------------------------------*/
288static int global_tcpconnect(lua_State *L)
289{
290 p_tags tags = pop_tags(L);
291 const char *address = luaL_check_string(L, 1);
292 unsigned short port = (unsigned short) luaL_check_number(L, 2);
293 p_sock sock = push_clienttable(L, tags);
294 const char *err = tcp_tryconnect(sock, address, port);
295 if (err) {
296 lua_pushnil(L);
297 lua_pushstring(L, err);
298 return 2;
299 }
300 set_nonblocking(sock);
301 return 1;
302}
303
304/*-------------------------------------------------------------------------*\
305* Creates a udp socket object and returns it to the Lua script.
306* Lua Returns
307* On success: udp socket
308* On error: nil, followed by an error message
309\*-------------------------------------------------------------------------*/
310static int global_udpsocket(lua_State *L)
311{
312 p_tags tags = pop_tags(L);
313 int top = lua_gettop(L);
314 p_sock sock = push_udptable(L, tags);
315 if (!sock) return 2;
316 if (top >= 1 ) {
317 if (lua_istable(L, 1)) {
318 lua_pushnil(L);
319 while (lua_next(L, 1)) {
320 if (!set_option(L, sock)) lua_error(L, "error setting option");
321 lua_pop(L, 1);
322 }
323 } else luaL_argerror(L, 1, "invalid options");
324 }
325 return 1;
326}
327
328/*-------------------------------------------------------------------------*\
329* Waits for and returns a client socket object attempting connection
330* with a server socket. The function blocks until a client shows up or
331* until a timeout condition is met.
332* Lua Input: sock
333* sock: server socket created by the bind function
334* Lua Returns
335* On success: client socket attempting connection
336* On error: nil followed by an error message
337\*-------------------------------------------------------------------------*/
338static int table_tcpaccept(lua_State *L)
339{
340 struct sockaddr_in client_addr;
341 size_t client_len = sizeof(client_addr);
342 p_sock server = pop_sock(L);
343 p_tags tags = pop_tags(L);
344 p_sock client = push_clienttable(L, tags);
345 tm_markstart(server);
346 if (tm_gettimeleft(server) >= 0) {
347 set_nonblocking(server);
348 do {
349 if (tm_timedout(server, TM_RECEIVE)) {
350 lua_pushnil(L);
351 push_error(L, NET_TIMEOUT);
352 return 2;
353 }
354 client->sock = accept(server->sock, (SA *) &client_addr,
355 &client_len);
356 } while (client->sock == INVALID_SOCKET);
357
358 } else {
359 set_blocking(server);
360 client->sock = accept(server->sock, (SA *) &client_addr, &client_len);
361 }
362 set_nonblocking(client);
363 return 1;
364}
365
366/*-------------------------------------------------------------------------*\
367* Associates an address to a server socket.
368* Lua Input: address, port [, backlog]
369* address: host name or ip address to bind to
370* port: port to bind to
371* backlog: connection queue length (default: 1)
372* Lua Returns
373* On success: server socket bound to address
374* On error: nil, followed by an error message
375\*-------------------------------------------------------------------------*/
376static int global_tcpbind(lua_State *L)
377{
378 p_tags tags = pop_tags(L);
379 const char *address = luaL_check_string(L, 1);
380 unsigned short port = (unsigned short) luaL_check_number(L, 2);
381 int backlog = (int) luaL_opt_number(L, 3, 1);
382 p_sock sock = push_servertable(L, tags);
383 const char *err;
384 if (!sock) {
385 lua_pushnil(L);
386 lua_pushstring(L, "out of memory");
387 return 2;
388 }
389 err = tcp_trybind(sock, address, port, backlog);
390 if (err) {
391 lua_pushnil(L);
392 lua_pushstring(L, err);
393 return 2;
394 }
395 return 1;
396}
397
398/*-------------------------------------------------------------------------*\
399* Associates a local address to UDP socket
400* Lua Input: address, port
401* address: host name or ip address to bind to
402* port: port to bind to
403* Lua Returns
404* On success: nil
405* On error: error message
406\*-------------------------------------------------------------------------*/
407static int table_udpsetsockname(lua_State *L)
408{
409 p_sock sock = pop_sock(L);
410 const char *address = luaL_check_string(L, 2);
411 unsigned short port = (unsigned short) luaL_check_number(L, 3);
412 const char *err = udp_setsockname(sock, address, port);
413 if (err) {
414 lua_pushstring(L, err);
415 return 1;
416 }
417 lua_pushnil(L);
418 return 1;
419}
420
421/*-------------------------------------------------------------------------*\
422* Sets a peer for a UDP socket
423* Lua Input: address, port
424* address: remote host name
425* port: remote host port
426* Lua Returns
427* On success: nil
428* On error: error message
429\*-------------------------------------------------------------------------*/
430static int table_udpsetpeername(lua_State *L)
431{
432 p_sock sock = pop_sock(L);
433 const char *address = luaL_check_string(L, 2);
434 unsigned short port = (unsigned short) luaL_check_number(L, 3);
435 const char *err = udp_setpeername(sock, address, port);
436 if (err) {
437 lua_pushstring(L, err);
438 return 1;
439 }
440 sock->is_connected = 1;
441 lua_pushnil(L);
442 return 1;
443}
444
445/*-------------------------------------------------------------------------*\
446* Sets timeout values for IO operations on a socket
447* Lua Input: sock, time [, mode]
448* sock: client socket created by the connect function
449* time: time out value in seconds
450* mode: "b" for block timeout, "r" for return timeout. (default: b)
451\*-------------------------------------------------------------------------*/
452static int table_timeout(lua_State *L)
453{
454 p_sock sock = pop_sock(L);
455 int ms = lua_isnil(L, 2) ? -1 : (int) (luaL_check_number(L, 2)*1000.0);
456 const char *mode = luaL_opt_string(L, 3, "b");
457 switch (*mode) {
458 case 'b':
459 sock->tm_block = ms;
460 break;
461 case 'r':
462 sock->tm_return = ms;
463 break;
464 default:
465 luaL_arg_check(L, 0, 3, "invalid timeout mode");
466 break;
467 }
468 return 0;
469}
470
471/*-------------------------------------------------------------------------*\
472* Send data through a TCP socket
473* Lua Input: sock, a_1 [, a_2, a_3 ... a_n]
474* sock: client socket created by the connect function
475* a_i: strings to be sent. The strings will be sent on the order they
476* appear as parameters
477* Lua Returns
478* On success: nil, followed by the total number of bytes sent
479* On error: error message
480\*-------------------------------------------------------------------------*/
481static int table_tcpsend(lua_State *L)
482{
483 int arg;
484 p_sock sock = pop_sock(L);
485 int top = lua_gettop(L);
486 int total = 0;
487 int err = NET_DONE;
488 tm_markstart(sock);
489 for (arg = 2; arg <= top; arg++) { /* skip self table */
490 int sent;
491 size_t wanted;
492 const char *data = luaL_opt_lstr(L, arg, NULL, &wanted);
493 if (!data || err != NET_DONE) break;
494 err = send_raw(sock, data, wanted, &sent);
495 total += sent;
496 }
497 push_error(L, err);
498 lua_pushnumber(L, total);
499#ifdef _DEBUG
500 /* push time elapsed during operation as the last return value */
501 lua_pushnumber(L, (sock->tm_end - sock->tm_start)/1000.0);
502#endif
503 return lua_gettop(L) - top;
504}
505
506/*-------------------------------------------------------------------------*\
507* Send data through a unconnected UDP socket
508* Lua Input: sock, data, ip, port
509* sock: udp socket
510* data: data to be sent
511* ip: ip address of target
512* port: port in target
513* Lua Returns
514* On success: nil, followed by the total number of bytes sent
515* On error: error message
516\*-------------------------------------------------------------------------*/
517static int table_udpsendto(lua_State *L)
518{
519 p_sock sock = pop_sock(L);
520 size_t wanted;
521 const char *data = luaL_check_lstr(L, 2, &wanted);
522 const char *ip = luaL_check_string(L, 3);
523 unsigned short port = (unsigned short) luaL_check_number(L, 4);
524 struct sockaddr_in peer;
525 int sent;
526 if (sock->is_connected) lua_error(L, "sendto on connected socket");
527 tm_markstart(sock);
528 if (tm_timedout(sock, TM_SEND)) {
529 push_error(L, NET_TIMEOUT);
530 return 1;
531 }
532 memset(&peer, 0, sizeof(peer));
533 peer.sin_family = AF_INET;
534 peer.sin_port = htons(port);
535 if (!inet_aton(ip, &peer.sin_addr)) lua_error(L, "invalid ip address");
536 sent = sendto(sock->sock, data, wanted, 0, (SA *) &peer, sizeof(peer));
537 if (sent >= 0) {
538 lua_pushnil(L);
539 lua_pushnumber(L, sent);
540 return 2;
541 } else {
542 push_error(L, NET_REFUSED);
543 return 1;
544 }
545}
546
547/*-------------------------------------------------------------------------*\
548* Global function that calls corresponding table method.
549\*-------------------------------------------------------------------------*/
550#ifndef LUASOCKET_NOGLOBALS
551int global_callfromtable(lua_State *L)
552{
553 p_tags tags = pop_tags(L);
554 if (lua_tag(L, 1) != tags->table) lua_error(L, "invalid socket object");
555 lua_gettable(L, 1);
556 lua_insert(L, 1);
557 lua_call(L, lua_gettop(L)-1, LUA_MULTRET);
558 return lua_gettop(L);
559}
560#endif
561
562/*-------------------------------------------------------------------------*\
563* Waits for a set of sockets until a condition is met or timeout.
564* Lua Input: {input}, {output} [, timeout]
565* {input}: table of sockets to be tested for input
566* {output}: table of sockets to be tested for output
567* timeout: maximum amount of time to wait for condition, in seconds
568* Lua Returns: {input}, {output}, err
569* {input}: table with sockets ready for input
570* {output}: table with sockets ready for output
571* err: "timeout" or nil
572\*-------------------------------------------------------------------------*/
573int global_select(lua_State *L)
574{
575 p_tags tags = pop_tags(L);
576 int ms = lua_isnil(L, 3) ? -1 : (int) (luaL_opt_number(L, 3, -1) * 1000);
577 fd_set readfds, *prfds = NULL, writefds, *pwfds = NULL;
578 struct timeval tm, *ptm = NULL;
579 int ret, dirty = 0;
580 unsigned max = 0;
581 SOCKET s;
582 int byfds, canread, canwrite;
583 /* reset the file descriptor sets */
584 FD_ZERO(&readfds); FD_ZERO(&writefds);
585 /* all sockets, indexed by socket number, for internal use */
586 lua_newtable(L); byfds = lua_gettop(L);
587 /* readable sockets table to be returned */
588 lua_newtable(L); canread = lua_gettop(L);
589 /* writable sockets table to be returned */
590 lua_newtable(L); canwrite = lua_gettop(L);
591 /* get sockets we will test for readability into fd_set */
592 if (lua_istable(L, 1)) {
593 lua_pushnil(L);
594 while (lua_next(L, 1)) {
595 if (lua_tag(L, -1) == tags->table) { /* skip strange fields */
596 p_sock sock = get_sock(L, -1, tags, NULL);
597 if (sock->sock != INVALID_SOCKET) { /* skip closed sockets */
598 lua_pushnumber(L, sock->sock);
599 lua_pushvalue(L, -2);
600 lua_settable(L, byfds);
601 if (sock->sock > max) max = sock->sock;
602 /* a socket can have unread data in our internal
603 buffer. in that case, we only call select to find
604 out which of the other sockets can be written to
605 or read from immediately. */
606 if (!bf_isempty(sock)) {
607 ms = 0; dirty = 1;
608 lua_pushnumber(L, lua_getn(L, canread) + 1);
609 lua_pushvalue(L, -2);
610 lua_settable(L, canread);
611 } else {
612 FD_SET(sock->sock, &readfds);
613 prfds = &readfds;
614 }
615 }
616 }
617 /* get rid of lua_next value and expose index */
618 lua_pop(L, 1);
619 }
620 } else if (!lua_isnil(L, 1)) luaL_argerror(L, 1, "expected table or nil");
621 /* get sockets we will test for writability into fd_set */
622 if (lua_istable(L, 2)) {
623 lua_pushnil(L);
624 while (lua_next(L, 2)) {
625 if (lua_tag(L, -1) == tags->table) { /* skip strange fields */
626 p_sock sock = get_sock(L, -1, tags, NULL);
627 if (sock->sock != INVALID_SOCKET) { /* skip closed sockets */
628 lua_pushnumber(L, sock->sock);
629 lua_pushvalue(L, -2);
630 lua_settable(L, byfds);
631 if (sock->sock > max) max = sock->sock;
632 FD_SET(sock->sock, &writefds);
633 pwfds = &writefds;
634 }
635 }
636 /* get rid of lua_next value and expose index */
637 lua_pop(L, 1);
638 }
639 } else if (!lua_isnil(L, 2)) luaL_argerror(L, 2, "expected table or nil");
640 max++;
641 /* configure timeout value */
642 if (ms >= 0) {
643 ptm = &tm; /* ptm == NULL when we don't have timeout */
644 /* fill timeval structure */
645 tm.tv_sec = ms / 1000;
646 tm.tv_usec = (ms % 1000) * 1000;
647 }
648 /* see if we can read, write or if we timedout */
649 ret = select(max, prfds, pwfds, NULL, ptm);
650 /* did we timeout? */
651 if (ret <= 0 && ms >= 0 && !dirty) {
652 push_error(L, NET_TIMEOUT);
653 return 3;
654 }
655 /* collect readable sockets */
656 if (prfds) {
657 for (s = 0; s < max; s++) {
658 if (FD_ISSET(s, prfds)) {
659 lua_pushnumber(L, lua_getn(L, canread) + 1);
660 lua_pushnumber(L, s);
661 lua_gettable(L, byfds);
662 lua_settable(L, canread);
663 }
664 }
665 }
666 /* collect writable sockets */
667 if (pwfds) {
668 for (s = 0; s < max; s++) {
669 if (FD_ISSET(s, pwfds)) {
670 lua_pushnumber(L, lua_getn(L, canwrite) + 1);
671 lua_pushnumber(L, s);
672 lua_gettable(L, byfds);
673 lua_settable(L, canwrite);
674 }
675 }
676 }
677 lua_pushnil(L);
678 return 3;
679}
680
681/*-------------------------------------------------------------------------*\
682* Returns the list of ip addresses associated with a host name
683* Lua Input: address
684* address: ip address or hostname to dns lookup
685* Lua Returns
686* On success: first IP address followed by a resolved table
687* On error: nil, followed by an error message
688\*-------------------------------------------------------------------------*/
689static int global_toip(lua_State *L)
690{
691 const char *address = luaL_check_string(L, 1);
692 struct in_addr addr;
693 struct hostent *hp;
694 if (inet_aton(address, &addr))
695 hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
696 else hp = gethostbyname(address);
697 if (!hp) {
698 lua_pushnil(L);
699 lua_pushstring(L, host_strerror());
700 return 2;
701 }
702 addr = *((struct in_addr *) hp->h_addr);
703 lua_pushstring(L, inet_ntoa(addr));
704 push_resolved(L, hp);
705 return 2;
706}
707
708/*-------------------------------------------------------------------------*\
709* Returns the list of host names associated with an ip address
710* Lua Input: address
711* address: ip address or host name to reverse dns lookup
712* Lua Returns
713* On success: canonic name followed by a resolved table
714* On error: nil, followed by an error message
715\*-------------------------------------------------------------------------*/
716static int global_tohostname(lua_State *L)
717{
718 const char *address = luaL_check_string(L, 1);
719 struct in_addr addr;
720 struct hostent *hp;
721 if (inet_aton(address, &addr))
722 hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
723 else hp = gethostbyname(address);
724 if (!hp) {
725 lua_pushnil(L);
726 lua_pushstring(L, host_strerror());
727 return 2;
728 }
729 lua_pushstring(L, hp->h_name);
730 push_resolved(L, hp);
731 return 2;
732}
733
734/*-------------------------------------------------------------------------*\
735* Send data through a connected UDP socket
736* Lua Input: sock, data
737* sock: udp socket
738* data: data to be sent
739* Lua Returns
740* On success: nil, followed by the total number of bytes sent
741* On error: error message
742\*-------------------------------------------------------------------------*/
743static int table_udpsend(lua_State *L)
744{
745 p_sock sock = pop_sock(L);
746 size_t wanted;
747 int sent;
748 const char *data = luaL_check_lstr(L, 2, &wanted);
749 if (!sock->is_connected) lua_error(L, "send on unconnected socket");
750 tm_markstart(sock);
751 if (tm_timedout(sock, TM_SEND)) {
752 push_error(L, NET_TIMEOUT);
753 return 1;
754 }
755 sent = send(sock->sock, data, wanted, 0);
756 if (sent >= 0) {
757 lua_pushnil(L);
758 lua_pushnumber(L, sent);
759 return 2;
760 } else {
761 push_error(L, NET_REFUSED);
762 return 1;
763 }
764}
765
766/*-------------------------------------------------------------------------*\
767* Receives a datagram from a UDP socket
768* Lua Input: sock [, wanted]
769* sock: client socket created by the connect function
770* wanted: the number of bytes expected (default: LUASOCKET_UDPBUFFERSIZE)
771* Lua Returns
772* On success: datagram received, ip and port of sender
773* On error: nil, followed by an error message
774\*-------------------------------------------------------------------------*/
775static int table_udpreceivefrom(lua_State *L)
776{
777 p_sock sock = pop_sock(L);
778 size_t wanted = (int) luaL_opt_number(L, 2, LUASOCKET_UDPBUFFERSIZE);
779 struct sockaddr_in peer;
780 size_t peer_len = sizeof(peer);
781 unsigned char buffer[LUASOCKET_UDPBUFFERSIZE];
782 int got;
783 if (sock->is_connected) lua_error(L, "receivefrom on connected socket");
784 tm_markstart(sock);
785 if (tm_timedout(sock, TM_RECEIVE)) {
786 lua_pushnil(L);
787 push_error(L, NET_TIMEOUT);
788 return 2;
789 }
790 wanted = MIN(wanted, sizeof(buffer));
791 got = recvfrom(sock->sock, buffer, wanted, 0, (SA *) &peer, &peer_len);
792 if (got >= 0) {
793 lua_pushlstring(L, buffer, got);
794 lua_pushstring(L, inet_ntoa(peer.sin_addr));
795 lua_pushnumber(L, ntohs(peer.sin_port));
796 return 3;
797 } else {
798 lua_pushnil(L);
799 push_error(L, NET_REFUSED);
800 return 2;
801 }
802}
803
804/*-------------------------------------------------------------------------*\
805* Receives data from a UDP socket
806* Lua Input: sock [, wanted]
807* sock: client socket created by the connect function
808* wanted: the number of bytes expected (default: LUASOCKET_UDPBUFFERSIZE)
809* Lua Returns
810* On success: datagram received
811* On error: nil, followed by an error message
812\*-------------------------------------------------------------------------*/
813static int table_udpreceive(lua_State *L)
814{
815 p_sock sock = pop_sock(L);
816 size_t wanted = (size_t) luaL_opt_number(L, 2, LUASOCKET_UDPBUFFERSIZE);
817 unsigned char buffer[LUASOCKET_UDPBUFFERSIZE];
818 int got;
819 tm_markstart(sock);
820 if (tm_timedout(sock, TM_RECEIVE)) {
821 lua_pushnil(L);
822 push_error(L, NET_TIMEOUT);
823 return 2;
824 }
825 got = recv(sock->sock, buffer, MIN(wanted, sizeof(buffer)), 0);
826 if (got >= 0) {
827 lua_pushlstring(L, buffer, got);
828 return 1;
829 } else {
830 lua_pushnil(L);
831 push_error(L, NET_REFUSED);
832 return 2;
833 }
834}
835
836/*-------------------------------------------------------------------------*\
837* Receive data from a TCP socket
838* Lua Input: sock [pat_1, pat_2 ... pat_n]
839* sock: client socket created by the connect function
840* pat_i: may be one of the following
841* "*l": reads a text line, defined as a string of caracters terminates
842* by a LF character, preceded or not by a CR character. This is
843* the default pattern
844* "*lu": reads a text line, terminanted by a CR character only. (Unix mode)
845* "*a": reads until connection closed
846* number: reads 'number' characters from the socket
847* Lua Returns
848* On success: one string for each pattern
849* On error: all strings for which there was no error, followed by one
850* nil value for the remaining strings, followed by an error code
851\*-------------------------------------------------------------------------*/
852static int table_tcpreceive(lua_State *L)
853{
854 static const char *const modenames[] = {"*l", "*lu", "*a", "*w", NULL};
855 const char *mode;
856 int err = NET_DONE;
857 int arg;
858 p_sock sock = pop_sock(L);
859 int top = lua_gettop(L);
860 tm_markstart(sock);
861 /* push default pattern if need be */
862 if (top < 2) {
863 lua_pushstring(L, "*l");
864 top++;
865 }
866 /* make sure we have enough stack space */
867 luaL_checkstack(L, top+LUA_MINSTACK, "too many arguments");
868 /* receive all patterns */
869 for (arg = 2; arg <= top; arg++) {
870 /* if one pattern fails, we just skip all other patterns */
871 if (err != NET_DONE) {
872 lua_pushnil(L);
873 continue;
874 }
875 if (lua_isnumber(L, arg)) {
876 int size = (int) lua_tonumber(L, arg);
877 err = receive_raw(L, sock, size);
878 } else {
879 mode = luaL_opt_string(L, arg, NULL);
880 /* get next pattern */
881 switch (luaL_findstring(mode, modenames)) {
882 /* DOS line mode */
883 case 0: err = receive_dosline(L, sock); break;
884 /* Unix line mode */
885 case 1: err = receive_unixline(L, sock); break;
886 /* until closed mode */
887 case 2: err = receive_all(L, sock); break;
888 /* word */
889 case 3: err = receive_word(L, sock); break;
890 /* else it is an error */
891 default:
892 luaL_arg_check(L, 0, arg, "invalid receive pattern");
893 break;
894 }
895 }
896 }
897 /* last return is an error code */
898 push_error(L, err);
899#ifdef _DEBUG
900 /* push time elapsed during operation as the last return value */
901 lua_pushnumber(L, (sock->tm_end - sock->tm_start)/1000.0);
902#endif
903 return lua_gettop(L) - top;
904}
905
906/*-------------------------------------------------------------------------*\
907* Retrieves socket peer name
908* Lua Input: sock
909* sock: socket
910* Lua Returns
911* On success: ip address and port of peer
912* On error: nil
913\*-------------------------------------------------------------------------*/
914static int table_getpeername(lua_State *L)
915{
916 p_sock sock = pop_sock(L);
917 struct sockaddr_in peer;
918 size_t peer_len = sizeof(peer);
919 if (getpeername(sock->sock, (SA *) &peer, &peer_len) < 0) {
920 lua_pushnil(L);
921 return 1;
922 }
923 lua_pushstring(L, inet_ntoa(peer.sin_addr));
924 lua_pushnumber(L, ntohs(peer.sin_port));
925 return 2;
926}
927
928/*-------------------------------------------------------------------------*\
929* Retrieves socket local name
930* Lua Input: sock
931* sock: socket
932* Lua Returns
933* On success: local ip address and port
934* On error: nil
935\*-------------------------------------------------------------------------*/
936static int table_getsockname(lua_State *L)
937{
938 p_sock sock = pop_sock(L);
939 struct sockaddr_in local;
940 size_t local_len = sizeof(local);
941 if (getsockname(sock->sock, (SA *) &local, &local_len) < 0) {
942 lua_pushnil(L);
943 return 1;
944 }
945 lua_pushstring(L, inet_ntoa(local.sin_addr));
946 lua_pushnumber(L, ntohs(local.sin_port));
947 return 2;
948}
949
950/*-------------------------------------------------------------------------*\
951* Closes a socket.
952* Lua Input
953* sock: socket to be closed
954\*-------------------------------------------------------------------------*/
955static int table_close(lua_State *L)
956{
957 /* close socket and set value to INVALID_SOCKET so that
958 ** pop_sock can later detect the use of a closed socket */
959 p_sock sock = (p_sock) lua_touserdata(L, -1);
960 if (!sock) lua_error(L, "invalid socket object");
961 if (sock->sock != INVALID_SOCKET) closesocket(sock->sock);
962 sock->sock = INVALID_SOCKET;
963 return 0;
964}
965
966/*-------------------------------------------------------------------------*\
967* Garbage collection fallback for the socket objects. This function
968* makes sure that all collected sockets are closed.
969\*-------------------------------------------------------------------------*/
970static int gc_table(lua_State *L)
971{
972 p_tags tags = pop_tags(L);
973 p_sock sock = get_selfsock(L, tags, NULL);
974 /* sock might have been closed before */
975 if (sock->sock != INVALID_SOCKET) {
976 closesocket(sock->sock);
977 sock->sock = INVALID_SOCKET;
978 }
979 return 0;
980}
981
982/*=========================================================================*\
983* Internal functions
984\*=========================================================================*/
985/*-------------------------------------------------------------------------*\
986* Instals a handler to ignore sigpipe. That is, unless the signal had
987* already been redefined. This function is not needed on the WinSock2,
988* since it's sockets don't raise this signal.
989\*-------------------------------------------------------------------------*/
990#ifndef WIN32
991static void handle_sigpipe(void);
992static void handle_sigpipe(void)
993{
994 struct sigaction new;
995 memset(&new, 0, sizeof(new));
996 new.sa_handler = SIG_IGN;
997 sigaction(SIGPIPE, &new, NULL);
998}
999#endif
1000
1001/*-------------------------------------------------------------------------*\
1002* Tries to create a TCP socket and connect to remote address (address, port)
1003* Input
1004* address: host name or ip address
1005* port: port number to bind to
1006* Returns
1007* NULL in case of success, error message otherwise
1008\*-------------------------------------------------------------------------*/
1009static const char *tcp_tryconnect(p_sock sock, const char *address,
1010 unsigned short port)
1011{
1012 struct sockaddr_in remote;
1013 memset(&remote, 0, sizeof(remote));
1014 if (inet_aton(address, &remote.sin_addr)) {
1015 remote.sin_family = AF_INET;
1016 remote.sin_port = htons(port);
1017 sock->sock = socket(AF_INET, SOCK_STREAM, 0);
1018 if (sock->sock == INVALID_SOCKET) return socket_strerror();
1019 if (connect(sock->sock, (SA *) &remote, sizeof(remote)) < 0) {
1020 closesocket(sock->sock);
1021 sock->sock = INVALID_SOCKET;
1022 return connect_strerror();
1023 }
1024 /* go ahead and try by hostname resolution */
1025 } else {
1026 struct hostent *hp = gethostbyname(address);
1027 struct in_addr **addr;
1028 if (!hp) return host_strerror();
1029 addr = (struct in_addr **) hp->h_addr_list;
1030 for (; *addr != NULL; addr++) {
1031 memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr));
1032 remote.sin_family = AF_INET;
1033 remote.sin_port = htons(port);
1034 sock->sock = socket(AF_INET, SOCK_STREAM, 0);
1035 if (sock->sock == INVALID_SOCKET) return socket_strerror();
1036 if (connect(sock->sock, (SA *) &remote, sizeof(remote)) == 0)
1037 break;
1038 closesocket(sock->sock);
1039 sock->sock = INVALID_SOCKET;
1040 memset(&remote, 0, sizeof(remote));
1041 }
1042 }
1043 if (sock->sock == INVALID_SOCKET) return connect_strerror();
1044 return NULL;
1045}
1046
1047/*-------------------------------------------------------------------------*\
1048* Sets the SO_REUSEADDR socket option
1049* Input
1050* sock: socket to set option
1051\*-------------------------------------------------------------------------*/
1052void set_reuseaddr(p_sock sock)
1053{
1054 int val = 1;
1055 setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
1056}
1057
1058/*-------------------------------------------------------------------------*\
1059* Set socket options from a table on top of Lua stack.
1060* Supports SO_KEEPALIVE, SO_DONTROUTE, SO_BROADCAST, and SO_LINGER options.
1061* Input
1062* L: Lua state to use
1063* sock: socket to set option
1064* Returns
1065* 1 if successful, 0 otherwise
1066\*-------------------------------------------------------------------------*/
1067static int set_option(lua_State *L, p_sock sock)
1068{
1069 static const char *const optionnames[] = {
1070 "SO_KEEPALIVE", "SO_DONTROUTE", "SO_BROADCAST", "SO_LINGER", NULL
1071 };
1072 const char *option;
1073 int err;
1074 if (!lua_isstring(L, -2)) return 0;
1075 option = lua_tostring(L, -2);
1076 switch (luaL_findstring(option, optionnames)) {
1077 case 0: {
1078 int bool;
1079 if (!lua_isnumber(L, -1))
1080 lua_error(L, "invalid SO_KEEPALIVE value");
1081 bool = (int) lua_tonumber(L, -1);
1082 err = setsockopt(sock->sock, SOL_SOCKET, SO_KEEPALIVE,
1083 (char *) &bool, sizeof(bool));
1084 return err >= 0;
1085 }
1086 case 1: {
1087 int bool;
1088 if (!lua_isnumber(L, -1))
1089 lua_error(L, "invalid SO_DONTROUTE value");
1090 bool = (int) lua_tonumber(L, -1);
1091 err = setsockopt(sock->sock, SOL_SOCKET, SO_DONTROUTE,
1092 (char *) &bool, sizeof(bool));
1093 return err >= 0;
1094 }
1095 case 2: {
1096 int bool;
1097 if (!lua_isnumber(L, -1))
1098 lua_error(L, "invalid SO_BROADCAST value");
1099 bool = (int) lua_tonumber(L, -1);
1100 err = setsockopt(sock->sock, SOL_SOCKET, SO_BROADCAST,
1101 (char *) &bool, sizeof(bool));
1102 return err >= 0;
1103 }
1104 case 3: {
1105 struct linger linger;
1106 if (!lua_istable(L, -1))
1107 lua_error(L, "invalid SO_LINGER value");
1108 lua_pushstring(L, "l_onoff");
1109 lua_gettable(L, -2);
1110 if (!lua_isnumber(L, -1))
1111 lua_error(L, "invalid SO_LINGER (l_onoff) value");
1112 linger.l_onoff = (int) lua_tonumber(L, -1);
1113 lua_pop(L, 1);
1114 lua_pushstring(L, "l_linger");
1115 lua_gettable(L, -2);
1116 if (!lua_isnumber(L, -1))
1117 lua_error(L, "invalid SO_LINGER (l_linger) value");
1118 linger.l_linger = (int) lua_tonumber(L, -1);
1119 lua_pop(L, 1);
1120 err = setsockopt(sock->sock, SOL_SOCKET, SO_LINGER,
1121 (char *) &linger, sizeof(linger));
1122 return err >= 0;
1123 }
1124 default: return 0;
1125 }
1126}
1127
1128
1129/*-------------------------------------------------------------------------*\
1130* Tries to create a TCP socket and bind it to (address, port)
1131* Input
1132* address: host name or ip address
1133* port: port number to bind to
1134* backlog: backlog to set
1135* Returns
1136* NULL in case of success, error message otherwise
1137\*-------------------------------------------------------------------------*/
1138static const char *tcp_trybind(p_sock sock, const char *address,
1139 unsigned short port, int backlog)
1140{
1141 struct sockaddr_in local;
1142 memset(&local, 0, sizeof(local));
1143 local.sin_port = htons(port);
1144 local.sin_family = AF_INET;
1145 local.sin_addr.s_addr = htonl(INADDR_ANY);
1146 sock->sock = socket(AF_INET, SOCK_STREAM, 0);
1147 if (sock->sock == INVALID_SOCKET) return socket_strerror();
1148 set_reuseaddr(sock);
1149 /* address is either wildcard or a valid ip address */
1150 if (!strcmp(address, "*") || inet_aton(address, &local.sin_addr)) {
1151 if (bind(sock->sock, (SA *) &local, sizeof(local)) < 0) {
1152 closesocket(sock->sock);
1153 sock->sock = INVALID_SOCKET;
1154 return bind_strerror();
1155 }
1156 /* otherwise, proceed with domain name resolution */
1157 } else {
1158 struct hostent *hp = gethostbyname(address);
1159 struct in_addr **addr;
1160 if (!hp) return host_strerror();
1161 addr = (struct in_addr **) hp->h_addr_list;
1162 for (; *addr != NULL; addr++) {
1163 memcpy(&local.sin_addr, *addr, sizeof(struct in_addr));
1164 if (bind(sock->sock, (SA *) &local, sizeof(local)) < 0) {
1165 closesocket(sock->sock);
1166 sock->sock = socket(AF_INET, SOCK_DGRAM, 0);
1167 if (sock->sock == INVALID_SOCKET) return socket_strerror();
1168 set_reuseaddr(sock);
1169 } else break;
1170 }
1171 if (*addr == NULL) return bind_strerror();
1172 }
1173 /* set connection queue length */
1174 if (listen(sock->sock, backlog) < 0) {
1175 closesocket(sock->sock);
1176 sock->sock = INVALID_SOCKET;
1177 return "listen error";
1178 }
1179 /* no errors found */
1180 return NULL;
1181}
1182
1183/*-------------------------------------------------------------------------*\
1184* Tries to bind the UDP socket to (address, port)
1185* Input
1186* address: host name or ip address
1187* port: port number to bind to
1188* Returns
1189* NULL in case of success, error message otherwise
1190\*-------------------------------------------------------------------------*/
1191static const char *udp_setsockname(p_sock sock, const char *address,
1192 unsigned short port)
1193{
1194 struct sockaddr_in local;
1195 memset(&local, 0, sizeof(local));
1196 local.sin_port = htons(port);
1197 local.sin_family = AF_INET;
1198 local.sin_addr.s_addr = htonl(INADDR_ANY);
1199 set_reuseaddr(sock);
1200 /* address is either wildcard or a valid ip address */
1201 if (!strcmp(address, "*") || inet_aton(address, &local.sin_addr)) {
1202 if (bind(sock->sock, (SA *) &local, sizeof(local)) < 0) {
1203 closesocket(sock->sock);
1204 sock->sock = INVALID_SOCKET;
1205 return bind_strerror();
1206 }
1207 /* otherwise, proceed with domain name resolution */
1208 } else {
1209 struct hostent *hp = gethostbyname(address);
1210 struct in_addr **addr;
1211 if (!hp) return host_strerror();
1212 addr = (struct in_addr **) hp->h_addr_list;
1213 for (; *addr != NULL; addr++) {
1214 memcpy(&local.sin_addr, *addr, sizeof(struct in_addr));
1215 if (bind(sock->sock, (SA *) &local, sizeof(local)) < 0) {
1216 closesocket(sock->sock);
1217 sock->sock = socket(AF_INET, SOCK_DGRAM, 0);
1218 if (sock->sock == INVALID_SOCKET) return socket_strerror();
1219 set_reuseaddr(sock);
1220 } else break;
1221 }
1222 if (*addr == NULL) return bind_strerror();
1223 }
1224 /* no errors found */
1225 return NULL;
1226}
1227
1228/*-------------------------------------------------------------------------*\
1229* Tries to connect a UDP to remote address (address, port)
1230* Input
1231* address: host name or ip address
1232* port: port number to bind to
1233* Returns
1234* NULL in case of success, error message otherwise
1235\*-------------------------------------------------------------------------*/
1236static const char *udp_setpeername(p_sock sock, const char *address,
1237 unsigned short port)
1238{
1239 struct sockaddr_in local;
1240 memset(&local, 0, sizeof(local));
1241 local.sin_port = htons(port);
1242 local.sin_family = AF_INET;
1243 local.sin_addr.s_addr = htonl(INADDR_ANY);
1244 /* address is a valid ip address */
1245 if (inet_aton(address, &local.sin_addr)) {
1246 if (connect(sock->sock, (SA *) &local, sizeof(local)) < 0) {
1247 closesocket(sock->sock);
1248 sock->sock = INVALID_SOCKET;
1249 return connect_strerror();
1250 }
1251 /* otherwise, proceed with domain name resolution */
1252 } else {
1253 struct hostent *hp = gethostbyname(address);
1254 struct in_addr **addr;
1255 if (!hp) return host_strerror();
1256 addr = (struct in_addr **) hp->h_addr_list;
1257 for (; *addr != NULL; addr++) {
1258 memcpy(&local.sin_addr, *addr, sizeof(struct in_addr));
1259 if (connect(sock->sock, (SA *) &local, sizeof(local)) < 0) {
1260 closesocket(sock->sock);
1261 sock->sock = socket(AF_INET, SOCK_DGRAM, 0);
1262 if (sock->sock == INVALID_SOCKET) return socket_strerror();
1263 } else break;
1264 }
1265 if (*addr == NULL) return connect_strerror();
1266 }
1267 /* no errors found */
1268 return NULL;
1269}
1270
1271/*=========================================================================*\
1272* Timeout management functions
1273\*=========================================================================*/
1274/*-------------------------------------------------------------------------*\
1275* Determines how much time we have left for the current io operation
1276* an IO write operation.
1277* Input
1278* sock: socket structure being used in operation
1279* Returns
1280* the number of ms left or -1 if there is no time limit
1281\*-------------------------------------------------------------------------*/
1282static int tm_gettimeleft(p_sock sock)
1283{
1284 /* no timeout */
1285 if (sock->tm_block < 0 && sock->tm_return < 0)
1286 return -1;
1287 /* there is no block timeout, we use the return timeout */
1288 else if (sock->tm_block < 0)
1289 return MAX(sock->tm_return - tm_gettime() + sock->tm_start, 0);
1290 /* there is no return timeout, we use the block timeout */
1291 else if (sock->tm_return < 0)
1292 return sock->tm_block;
1293 /* both timeouts are specified */
1294 else return MIN(sock->tm_block,
1295 MAX(sock->tm_return - tm_gettime() + sock->tm_start, 0));
1296}
1297
1298/*-------------------------------------------------------------------------*\
1299* Determines if we have a timeout condition or if we can proceed with
1300* an IO operation.
1301* Input
1302* sock: socket structure being used in operation
1303* mode: TM_RECEIVE or TM_SEND
1304* Returns
1305* 1 if we can proceed, 0 if a timeout has occured
1306\*-------------------------------------------------------------------------*/
1307static int tm_timedout(p_sock sock, int mode)
1308{
1309 fd_set fds;
1310 int ret;
1311 fd_set *preadfds = NULL, *pwritefds = NULL;
1312 struct timeval tm;
1313 struct timeval *ptm = NULL;
1314 /* find out how much time we have left, in ms */
1315 int ms = tm_gettimeleft(sock);
1316 /* fill file descriptor set */
1317 FD_ZERO(&fds); FD_SET(sock->sock, &fds);
1318 /* fill timeval structure */
1319 tm.tv_sec = ms / 1000;
1320 tm.tv_usec = (ms % 1000) * 1000;
1321 /* define function parameters */
1322 if (ms >= 0) ptm = &tm; /* ptm == NULL when we don't have timeout */
1323 if (mode == TM_RECEIVE) preadfds = &fds;
1324 else pwritefds = &fds;
1325 /* see if we can read, write or if we timedout */
1326 ret = select(sock->sock+1, preadfds, pwritefds, NULL, ptm);
1327#ifdef _DEBUG
1328 /* store end time for this operation next call to OS */
1329 sock->tm_end = tm_gettime();
1330#endif
1331 return ret <= 0;
1332}
1333
1334/*-------------------------------------------------------------------------*\
1335* Marks the operation start time in sock structure
1336* Input
1337* sock: socket structure being used in operation
1338\*-------------------------------------------------------------------------*/
1339static void tm_markstart(p_sock sock)
1340{
1341 sock->tm_start = tm_gettime();
1342#ifdef _DEBUG
1343 sock->tm_end = sock->tm_start;
1344#endif
1345}
1346
1347/*-------------------------------------------------------------------------*\
1348* Gets time in ms, relative to system startup.
1349* Returns
1350* time in ms.
1351\*-------------------------------------------------------------------------*/
1352static int tm_gettime(void)
1353{
1354#ifdef WIN32
1355 return GetTickCount();
1356#else
1357 struct tms t;
1358 return (times(&t)*1000)/CLK_TCK;
1359#endif
1360}
1361
1362/*=========================================================================*\
1363* Buffered I/O management functions
1364\*=========================================================================*/
1365/*-------------------------------------------------------------------------*\
1366* Determines of there is any data in the read buffer
1367* Input
1368* sock: socket structure being used in operation
1369* Returns
1370* 1 if empty, 0 if there is data
1371\*-------------------------------------------------------------------------*/
1372static int bf_isempty(p_sock sock)
1373{
1374 return sock->bf_first >= sock->bf_last;
1375}
1376
1377/*-------------------------------------------------------------------------*\
1378* Skip a given number of bytes in read buffer
1379* Input
1380* sock: socket structure being used in operation
1381* length: number of bytes to skip
1382\*-------------------------------------------------------------------------*/
1383static void bf_skip(p_sock sock, int length)
1384{
1385 sock->bf_first += length;
1386 if (bf_isempty(sock)) sock->bf_first = sock->bf_last = 0;
1387}
1388
1389/*-------------------------------------------------------------------------*\
1390* Return any data avilable in buffer, or get more data from transport layer
1391* if buffer is empty.
1392* Input
1393* sock: socket structure being used in operation
1394* Output
1395* length: number of bytes available in buffer
1396* Returns
1397* pointer to start of data
1398\*-------------------------------------------------------------------------*/
1399static const unsigned char *bf_receive(p_sock sock, int *length)
1400{
1401 if (bf_isempty(sock)) {
1402 int got = recv(sock->sock, sock->bf_buffer, LUASOCKET_TCPBUFFERSIZE, 0);
1403 sock->bf_first = 0;
1404 if (got >= 0) sock->bf_last = got;
1405 else sock->bf_last = 0;
1406 }
1407 *length = sock->bf_last - sock->bf_first;
1408 return sock->bf_buffer + sock->bf_first;
1409}
1410 21
1411/*=========================================================================*\ 22/*=========================================================================*\
1412* These are the function that are called for each I/O pattern 23* LuaSocket includes
1413* The read patterns leave their result on the Lua stack
1414\*=========================================================================*/ 24\*=========================================================================*/
1415/*-------------------------------------------------------------------------*\ 25#include "luasocket.h"
1416* Sends a raw block of data through a socket. The operations are all 26#include "lspriv.h"
1417* non-blocking and the function respects the timeout values in sock. 27#include "lsselect.h"
1418* Input 28#include "lscompat.h"
1419* sock: socket structure being used in operation 29#include "lsbase.h"
1420* data: buffer to be sent 30#include "lstm.h"
1421* wanted: number of bytes in buffer 31#include "lsbuf.h"
1422* Output 32#include "lssock.h"
1423* total: Number of bytes written 33#include "lsinet.h"
1424* Returns 34#include "lstcpc.h"
1425* operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED 35#include "lstcps.h"
1426\*-------------------------------------------------------------------------*/ 36#include "lstcps.h"
1427static int send_raw(p_sock sock, const char *data, int wanted, int *total) 37#include "lsudp.h"
1428{
1429 int put = 0;
1430 *total = 0;
1431 while (wanted > 0) {
1432 if (tm_timedout(sock, TM_SEND)) return NET_TIMEOUT;
1433 put = send(sock->sock, data, wanted, 0);
1434 if (put <= 0) {
1435#ifdef WIN32
1436 /* a bug in WinSock forces us to do a busy wait until we manage
1437 ** to write, because select returns immediately even though it
1438 ** should have blocked us until we could write... */
1439 if (put < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
1440 continue;
1441#endif
1442#ifdef __CYGWIN__
1443 /* this is for CYGWIN, which is like Unix but with Win32 Bugs */
1444 if (put < 0 && errno == EWOULDBLOCK)
1445 continue;
1446#endif
1447
1448 return NET_CLOSED;
1449 }
1450 wanted -= put;
1451 data += put;
1452 *total += put;
1453 }
1454 return NET_DONE;
1455}
1456
1457/*-------------------------------------------------------------------------*\
1458* Reads a raw block of data from a socket. The operations are all
1459* non-blocking and the function respects the timeout values in sock.
1460* Input
1461* sock: socket structure being used in operation
1462* wanted: number of bytes to be read
1463* Returns
1464* operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
1465\*-------------------------------------------------------------------------*/
1466static int receive_raw(lua_State *L, p_sock sock, int wanted)
1467{
1468 int got = 0;
1469 const unsigned char *buffer = NULL;
1470 luaL_Buffer b;
1471 luaL_buffinit(L, &b);
1472 while (wanted > 0) {
1473 if (bf_isempty(sock) && tm_timedout(sock, TM_RECEIVE)) {
1474 luaL_pushresult(&b);
1475 return NET_TIMEOUT;
1476 }
1477 buffer = bf_receive(sock, &got);
1478 if (got <= 0) {
1479 luaL_pushresult(&b);
1480 return NET_CLOSED;
1481 }
1482 got = MIN(got, wanted);
1483 luaL_addlstring(&b, buffer, got);
1484 bf_skip(sock, got);
1485 wanted -= got;
1486 }
1487 luaL_pushresult(&b);
1488 return NET_DONE;
1489}
1490
1491/*-------------------------------------------------------------------------*\
1492* Reads everything until the connection is closed
1493* Input
1494* sock: socket structure being used in operation
1495* Result
1496* operation error code. NET_DONE, NET_TIMEOUT
1497\*-------------------------------------------------------------------------*/
1498static int receive_all(lua_State *L, p_sock sock)
1499{
1500 int got = 0;
1501 const unsigned char *buffer = NULL;
1502 luaL_Buffer b;
1503 luaL_buffinit(L, &b);
1504 for ( ;; ) {
1505 if (bf_isempty(sock) && tm_timedout(sock, TM_RECEIVE)) {
1506 luaL_pushresult(&b);
1507 return NET_TIMEOUT;
1508 }
1509 buffer = bf_receive(sock, &got);
1510 if (got <= 0) {
1511 luaL_pushresult(&b);
1512 return NET_DONE;
1513 }
1514 luaL_addlstring(&b, buffer, got);
1515 bf_skip(sock, got);
1516 }
1517}
1518
1519/*-------------------------------------------------------------------------*\
1520* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF
1521* are not returned by the function and are discarded from the stream. All
1522* operations are non-blocking and the function respects the timeout
1523* values in sock.
1524* Input
1525* sock: socket structure being used in operation
1526* Result
1527* operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
1528\*-------------------------------------------------------------------------*/
1529static int receive_dosline(lua_State *L, p_sock sock)
1530{
1531 int got, pos;
1532 const unsigned char *buffer = NULL;
1533 luaL_Buffer b;
1534 luaL_buffinit(L, &b);
1535 for ( ;; ) {
1536 if (bf_isempty(sock) && tm_timedout(sock, TM_RECEIVE)) {
1537 luaL_pushresult(&b);
1538 return NET_TIMEOUT;
1539 }
1540 buffer = bf_receive(sock, &got);
1541 if (got <= 0) {
1542 luaL_pushresult(&b);
1543 return NET_CLOSED;
1544 }
1545 pos = 0;
1546 while (pos < got && buffer[pos] != '\n') {
1547 /* we ignore all \r's */
1548 if (buffer[pos] != '\r') luaL_putchar(&b, buffer[pos]);
1549 pos++;
1550 }
1551 if (pos < got) {
1552 luaL_pushresult(&b);
1553 bf_skip(sock, pos+1); /* skip '\n' too */
1554 return NET_DONE;
1555 } else bf_skip(sock, pos);
1556 }
1557}
1558
1559/*-------------------------------------------------------------------------*\
1560* Reads a line terminated by a LF character, which is not returned by
1561* the function, and is skipped in the stream. All operations are
1562* non-blocking and the function respects the timeout values in sock.
1563* Input
1564* sock: socket structure being used in operation
1565* Returns
1566* operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
1567\*-------------------------------------------------------------------------*/
1568static int receive_unixline(lua_State *L, p_sock sock)
1569{
1570 int got, pos;
1571 const unsigned char *buffer = NULL;
1572 luaL_Buffer b;
1573 luaL_buffinit(L, &b);
1574 for ( ;; ) {
1575 if (bf_isempty(sock) && tm_timedout(sock, TM_RECEIVE)) {
1576 luaL_pushresult(&b);
1577 return NET_TIMEOUT;
1578 }
1579 buffer = bf_receive(sock, &got);
1580 if (got <= 0) {
1581 luaL_pushresult(&b);
1582 return NET_CLOSED;
1583 }
1584 pos = 0;
1585 while (pos < got && buffer[pos] != '\n') pos++;
1586 luaL_addlstring(&b, buffer, pos);
1587 if (pos < got) {
1588 luaL_pushresult(&b);
1589 bf_skip(sock, pos+1); /* skip '\n' too */
1590 return NET_DONE;
1591 } else bf_skip(sock, pos);
1592 }
1593}
1594
1595/*-------------------------------------------------------------------------*\
1596* Reads a word (maximal sequence of non--white-space characters), skipping
1597* white-spaces if needed.
1598* Input
1599* sock: socket structure being used in operation
1600* Result
1601* operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
1602\*-------------------------------------------------------------------------*/
1603static int receive_word(lua_State *L, p_sock sock)
1604{
1605 int pos, got;
1606 const unsigned char *buffer = NULL;
1607 luaL_Buffer b;
1608 luaL_buffinit(L, &b);
1609 /* skip leading white-spaces */
1610 for ( ;; ) {
1611 if (bf_isempty(sock) && tm_timedout(sock, TM_RECEIVE)) {
1612 lua_pushstring(L, "");
1613 return NET_TIMEOUT;
1614 }
1615 buffer = bf_receive(sock, &got);
1616 if (got <= 0) {
1617 lua_pushstring(L, "");
1618 return NET_CLOSED;
1619 }
1620 pos = 0;
1621 while (pos < got && isspace(buffer[pos])) pos++;
1622 bf_skip(sock, pos);
1623 if (pos < got) {
1624 buffer += pos;
1625 got -= pos;
1626 pos = 0;
1627 break;
1628 }
1629 }
1630 /* capture word */
1631 for ( ;; ) {
1632 while (pos < got && !isspace(buffer[pos])) pos++;
1633 luaL_addlstring(&b, buffer, pos);
1634 bf_skip(sock, pos);
1635 if (pos < got) {
1636 luaL_pushresult(&b);
1637 return NET_DONE;
1638 }
1639 if (bf_isempty(sock) && tm_timedout(sock, TM_RECEIVE)) {
1640 luaL_pushresult(&b);
1641 return NET_TIMEOUT;
1642 }
1643 buffer = bf_receive(sock, &got);
1644 if (got <= 0) {
1645 luaL_pushresult(&b);
1646 return NET_CLOSED;
1647 }
1648 pos = 0;
1649 }
1650}
1651 38
1652/*=========================================================================*\ 39/*=========================================================================*\
1653* Module exported functions 40* Exported functions
1654\*=========================================================================*/ 41\*=========================================================================*/
1655/*-------------------------------------------------------------------------*\ 42/*-------------------------------------------------------------------------*\
1656* Initializes the library interface with Lua and the socket library. 43* Initializes all library modules.
1657* Defines the symbols exported to Lua.
1658\*-------------------------------------------------------------------------*/ 44\*-------------------------------------------------------------------------*/
1659LUASOCKET_API int lua_socketlibopen(lua_State *L) 45LUASOCKET_API int lua_socketlibopen(lua_State *L)
1660{ 46{
1661 struct luaL_reg funcs[] = { 47 priv_open(L);
1662 {"bind", global_tcpbind}, 48 select_open(L);
1663 {"connect", global_tcpconnect}, 49 base_open(L);
1664 {"select", global_select}, 50 tm_open(L);
1665 {"toip", global_toip}, 51 compat_open(L);
1666 {"tohostname", global_tohostname}, 52 fd_open(L);
1667 {"udpsocket", global_udpsocket}, 53 sock_open(L);
1668 }; 54 inet_open(L);
1669 unsigned int i; 55 tcpc_open(L);
1670 /* declare new Lua tags for used userdata values */ 56 buf_open(L);
1671 p_tags tags = (p_tags) lua_newuserdata(L, sizeof(t_tags)); 57 tcps_open(L);
1672 tags->client = lua_newtag(L); 58 udp_open(L);
1673 tags->server = lua_newtag(L);
1674 tags->table = lua_newtag(L);
1675 tags->udp = lua_newtag(L);
1676 /* global functions exported */
1677 for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) {
1678 lua_pushvalue(L, -1);
1679 lua_pushcclosure(L, funcs[i].func, 1);
1680 lua_setglobal(L, funcs[i].name);
1681 }
1682 /* socket garbage collection */
1683 lua_pushvalue(L, -1);
1684 lua_pushcclosure(L, gc_table, 1);
1685 lua_settagmethod(L, tags->table, "gc");
1686#ifdef WIN32
1687 /* WinSock needs special initialization */
1688 if (!winsock_open()) return 0;
1689#else
1690 /* avoid getting killed by a SIGPIPE signal thrown by send */
1691 handle_sigpipe();
1692#endif
1693#ifdef _DEBUG
1694 /* test support functions */
1695 lua_pushcfunction(L, global_sleep); lua_setglobal(L, "_sleep");
1696 lua_pushcfunction(L, global_time); lua_setglobal(L, "_time");
1697#endif
1698#ifndef LUASOCKET_NOGLOBALS
1699 {
1700 char *global[] = {
1701 "accept", "close", "getpeername",
1702 "getsockname", "receive", "send",
1703 "receivefrom", "sendto"
1704 };
1705 unsigned int i;
1706 for (i = 0; i < sizeof(global)/sizeof(char *); i++) {
1707 lua_pushstring(L, global[i]);
1708 lua_pushvalue(L, -2);
1709 lua_pushcclosure(L, global_callfromtable, 2);
1710 lua_setglobal(L, global[i]);
1711 }
1712 }
1713#endif
1714 /* remove tags userdatum from stack */
1715 lua_pop(L, 1);
1716 return 1; 59 return 1;
1717} 60}
1718
1719/*=========================================================================*\
1720* Lua Stack manipulation functions
1721\*=========================================================================*/
1722/*-------------------------------------------------------------------------*\
1723* Creates a t_sock structure with default values for a client sock.
1724* Pushes the Lua table with sock fields and appropriate methods
1725* Input
1726* tags: tags structure
1727* Returns
1728* pointer to allocated t_sock structure, NULL in case of error
1729\*-------------------------------------------------------------------------*/
1730static p_sock push_clienttable(lua_State *L, p_tags tags)
1731{
1732 static struct luaL_reg funcs[] = {
1733 {"close", table_close},
1734 {"getsockname", table_getsockname},
1735 {"getpeername", table_getpeername},
1736 {"receive", table_tcpreceive},
1737 {"send", table_tcpsend},
1738 {"timeout", table_timeout},
1739 };
1740 unsigned int i;
1741 p_sock sock = (p_sock) lua_newuserdata(L, sizeof(t_sock));
1742 lua_settag(L, tags->client);
1743 lua_newtable(L); lua_settag(L, tags->table);
1744 lua_pushstring(L, P_SOCK);
1745 lua_pushvalue(L, -3);
1746 lua_settable(L, -3);
1747 sock->sock = INVALID_SOCKET;
1748 sock->is_connected = 0;
1749 sock->tm_block = -1;
1750 sock->tm_return = -1;
1751 sock->bf_first = sock->bf_last = 0;
1752 for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) {
1753 lua_pushstring(L, funcs[i].name);
1754 lua_pushvalue(L, -3);
1755 lua_pushcclosure(L, funcs[i].func, 1);
1756 lua_settable(L, -3);
1757 }
1758 return sock;
1759}
1760
1761/*-------------------------------------------------------------------------*\
1762* Creates a t_sock structure with default values for a server sock.
1763* Pushes the Lua table with sock fields and appropriate methods
1764* Input
1765* tags: tags structure
1766* Returns
1767* pointer to allocated t_sock structure, NULL in case of error
1768\*-------------------------------------------------------------------------*/
1769static p_sock push_servertable(lua_State *L, p_tags tags)
1770{
1771 static struct luaL_reg funcs[] = {
1772 {"close", table_close},
1773 {"getsockname", table_getsockname},
1774 {"timeout", table_timeout},
1775 };
1776 unsigned int i;
1777 p_sock sock = (p_sock) lua_newuserdata(L, sizeof(t_sock));
1778 lua_settag(L, tags->server);
1779 lua_newtable(L); lua_settag(L, tags->table);
1780 lua_pushstring(L, P_SOCK);
1781 lua_pushvalue(L, -3);
1782 lua_settable(L, -3);
1783 sock->sock = INVALID_SOCKET;
1784 sock->tm_block = -1;
1785 sock->tm_return = -1;
1786 sock->bf_first = sock->bf_last = 0;
1787 for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) {
1788 lua_pushstring(L, funcs[i].name);
1789 lua_pushvalue(L, -3);
1790 lua_pushcclosure(L, funcs[i].func, 1);
1791 lua_settable(L, -3);
1792 }
1793 /* the accept method is different, it needs the tags closure too */
1794 lua_pushstring(L, "accept");
1795#ifdef LUASOCKET_41FRIENDLY
1796 lua_newuserdatabox(L, tags);
1797#else
1798 lua_pushuserdata(L, tags);
1799#endif
1800 lua_pushvalue(L, -4);
1801 lua_pushcclosure(L, table_tcpaccept, 2);
1802 lua_settable(L, -3);
1803 return sock;
1804}
1805
1806/*-------------------------------------------------------------------------*\
1807* Creates a t_sock structure with default values for a udp sock.
1808* Pushes the Lua table with sock fields and appropriate methods
1809* Input
1810* tags: tags structure
1811* Returns
1812* pointer to allocated t_sock structure, NULL in case of error
1813\*-------------------------------------------------------------------------*/
1814static p_sock push_udptable(lua_State *L, p_tags tags)
1815{
1816 static struct luaL_reg funcs[] = {
1817 {"sendto", table_udpsendto},
1818 {"setpeername", table_udpsetpeername},
1819 {"setsockname", table_udpsetsockname},
1820 {"getpeername", table_getpeername},
1821 {"getsockname", table_getsockname},
1822 {"receivefrom", table_udpreceivefrom},
1823 {"receive", table_udpreceive},
1824 {"send", table_udpsend},
1825 {"close", table_close},
1826 {"timeout", table_timeout},
1827 };
1828 unsigned int i;
1829 p_sock sock = (p_sock) lua_newuserdata(L, sizeof(t_sock));
1830 lua_settag(L, tags->udp);
1831 lua_newtable(L); lua_settag(L, tags->table);
1832 lua_pushstring(L, P_SOCK);
1833 lua_pushvalue(L, -3);
1834 lua_settable(L, -3);
1835 sock->sock = socket(AF_INET, SOCK_DGRAM, 0);
1836 if (sock->sock == INVALID_SOCKET) {
1837 lua_pushnil(L);
1838 lua_pushstring(L, socket_strerror());
1839 return NULL;
1840 }
1841 sock->is_connected = 0;
1842 sock->tm_block = -1;
1843 sock->tm_return = -1;
1844 sock->bf_first = sock->bf_last = 0;
1845 for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) {
1846 lua_pushstring(L, funcs[i].name);
1847 lua_pushvalue(L, -3);
1848 lua_pushcclosure(L, funcs[i].func, 1);
1849 lua_settable(L, -3);
1850 }
1851 return sock;
1852}
1853
1854/*-------------------------------------------------------------------------*\
1855* Passes all resolver information to Lua as a table
1856* Input
1857* hp: hostent structure returned by resolver
1858\*-------------------------------------------------------------------------*/
1859static void push_resolved(lua_State *L, struct hostent *hp)
1860{
1861 char **alias;
1862 struct in_addr **addr;
1863 int i, resolved;
1864
1865 lua_newtable(L); resolved = lua_gettop(L);
1866
1867 lua_pushstring(L, "name");
1868 lua_pushstring(L, hp->h_name);
1869 lua_settable(L, resolved);
1870
1871 lua_pushstring(L, "ip");
1872 lua_pushstring(L, "alias");
1873
1874 i = 1;
1875 alias = hp->h_aliases;
1876 lua_newtable(L);
1877 while (*alias) {
1878 lua_pushnumber(L, i);
1879 lua_pushstring(L, *alias);
1880 lua_settable(L, -3);
1881 i++; alias++;
1882 }
1883 lua_settable(L, resolved);
1884
1885 i = 1;
1886 lua_newtable(L);
1887 addr = (struct in_addr **) hp->h_addr_list;
1888 while (*addr) {
1889 lua_pushnumber(L, i);
1890 lua_pushstring(L, inet_ntoa(**addr));
1891 lua_settable(L, -3);
1892 i++; addr++;
1893 }
1894 lua_settable(L, resolved);
1895}
1896
1897/*-------------------------------------------------------------------------*\
1898* Passes an error code to Lua. The NET_DONE error is translated to nil.
1899* Input
1900* err: error code to be passed to Lua
1901\*-------------------------------------------------------------------------*/
1902static void push_error(lua_State *L, int err)
1903{
1904 switch (err) {
1905 case NET_DONE:
1906 lua_pushnil(L);
1907 break;
1908 case NET_TIMEOUT:
1909 lua_pushstring(L, "timeout");
1910 break;
1911 case NET_CLOSED:
1912 lua_pushstring(L, "closed");
1913 break;
1914 case NET_REFUSED:
1915 lua_pushstring(L, "refused");
1916 break;
1917 }
1918}
1919
1920static p_tags pop_tags(lua_State *L)
1921{
1922 p_tags tags = (p_tags) lua_touserdata(L, -1);
1923 if (!tags) lua_error(L, "invalid closure! (probably misuse of library)");
1924 lua_pop(L, 1);
1925 return tags;
1926}
1927
1928static p_sock pop_sock(lua_State *L)
1929{
1930 p_sock sock = (p_sock) lua_touserdata(L, -1);
1931 if (!sock) lua_error(L, "invalid socket object");
1932 if (sock->sock == INVALID_SOCKET)
1933 lua_error(L, "operation on closed socket");
1934 lua_pop(L, 1);
1935 return sock;
1936}
1937
1938static p_sock get_sock(lua_State *L, int s, p_tags tags, int *tag)
1939{
1940 p_sock sock;
1941 if (lua_tag(L, s) != tags->table) lua_error(L, "invalid socket object");
1942 lua_pushstring(L, P_SOCK);
1943 lua_gettable(L, s > 0 ? s : s-1);
1944 sock = lua_touserdata(L, -1);
1945 if (!sock) lua_error(L, "invalid socket object");
1946 if (tag) *tag = lua_tag(L, -1);
1947 lua_pop(L, 1);
1948 return sock;
1949}
1950
1951static p_sock get_selfsock(lua_State *L, p_tags tags, int *tag)
1952{
1953 return get_sock(L, 1, tags, tag);
1954}
1955
1956/*=========================================================================*\
1957* WinSock2 specific functions.
1958\*=========================================================================*/
1959#ifdef WIN32
1960/*-------------------------------------------------------------------------*\
1961* Initializes WinSock2 library.
1962* Returns
1963* 1 in case of success. 0 in case of error.
1964\*-------------------------------------------------------------------------*/
1965static int winsock_open(void)
1966{
1967 WORD wVersionRequested;
1968 WSADATA wsaData;
1969 int err;
1970 wVersionRequested = MAKEWORD(2, 0);
1971 err = WSAStartup(wVersionRequested, &wsaData );
1972 if (err != 0) {
1973 return 0;
1974 }
1975 if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) {
1976 WSACleanup();
1977 return 0;
1978 }
1979 return 1;
1980}
1981
1982/*-------------------------------------------------------------------------*\
1983* Put socket into blocking mode.
1984\*-------------------------------------------------------------------------*/
1985static void set_blocking(p_sock sock)
1986{
1987 u_long argp = 0;
1988 ioctlsocket(sock->sock, FIONBIO, &argp);
1989}
1990
1991/*-------------------------------------------------------------------------*\
1992* Put socket into non-blocking mode.
1993\*-------------------------------------------------------------------------*/
1994static void set_nonblocking(p_sock sock)
1995{
1996 u_long argp = 1;
1997 ioctlsocket(sock->sock, FIONBIO, &argp);
1998}
1999
2000/*-------------------------------------------------------------------------*\
2001* Returns a string describing the last host manipulation error.
2002\*-------------------------------------------------------------------------*/
2003static char *host_strerror(void)
2004{
2005 switch (WSAGetLastError()) {
2006 case HOST_NOT_FOUND: return "host not found";
2007 case NO_ADDRESS: return "unable to resolve host name";
2008 case NO_RECOVERY: return "name server error";
2009 case TRY_AGAIN: return "name server unavailable, try again later.";
2010 default: return "unknown error";
2011 }
2012}
2013
2014/*-------------------------------------------------------------------------*\
2015* Returns a string describing the last socket manipulation error.
2016\*-------------------------------------------------------------------------*/
2017static char *socket_strerror(void)
2018{
2019 switch (WSAGetLastError()) {
2020 case WSANOTINITIALISED: return "not initialized";
2021 case WSAENETDOWN: return "network is down";
2022 case WSAEMFILE: return "descriptor table is full";
2023 case WSAENOBUFS: return "insufficient buffer space";
2024 default: return "unknown error";
2025 }
2026}
2027
2028/*-------------------------------------------------------------------------*\
2029* Returns a string describing the last bind operation error.
2030\*-------------------------------------------------------------------------*/
2031static char *bind_strerror(void)
2032{
2033 switch (WSAGetLastError()) {
2034 case WSANOTINITIALISED: return "not initialized";
2035 case WSAENETDOWN: return "network is down";
2036 case WSAEADDRINUSE: return "address already in use";
2037 case WSAEINVAL: return "socket already bound";
2038 case WSAENOBUFS: return "too many connections";
2039 case WSAEFAULT: return "invalid address";
2040 case WSAENOTSOCK: return "not a socket descriptor";
2041 default: return "unknown error";
2042 }
2043}
2044
2045/*-------------------------------------------------------------------------*\
2046* Returns a string describing the last connect operationerror.
2047\*-------------------------------------------------------------------------*/
2048static char *connect_strerror(void)
2049{
2050 switch (WSAGetLastError()) {
2051 case WSANOTINITIALISED: return "not initialized";
2052 case WSAENETDOWN: return "network is down";
2053 case WSAEADDRINUSE: return "address already in use";
2054 case WSAEADDRNOTAVAIL: return "address unavailable";
2055 case WSAECONNREFUSED: return "connection refused";
2056 case WSAENETUNREACH: return "network is unreachable";
2057 default: return "unknown error";
2058 }
2059}
2060#else
2061
2062/*=========================================================================*\
2063* BSD specific functions.
2064\*=========================================================================*/
2065/*-------------------------------------------------------------------------*\
2066* Put socket into blocking mode.
2067\*-------------------------------------------------------------------------*/
2068static void set_blocking(p_sock sock)
2069{
2070 int flags = fcntl(sock->sock, F_GETFL, 0);
2071 flags &= (~(O_NONBLOCK));
2072 fcntl(sock->sock, F_SETFL, flags);
2073}
2074
2075/*-------------------------------------------------------------------------*\
2076* Put socket into non-blocking mode.
2077\*-------------------------------------------------------------------------*/
2078static void set_nonblocking(p_sock sock)
2079{
2080 int flags = fcntl(sock->sock, F_GETFL, 0);
2081 flags |= O_NONBLOCK;
2082 fcntl(sock->sock, F_SETFL, flags);
2083}
2084
2085/*-------------------------------------------------------------------------*\
2086* Returns a string describing the last host manipulation error.
2087\*-------------------------------------------------------------------------*/
2088static char *host_strerror(void)
2089{
2090 switch (h_errno) {
2091 case HOST_NOT_FOUND: return "host not found";
2092 case NO_ADDRESS: return "unable to resolve host name";
2093 case NO_RECOVERY: return "name server error";
2094 case TRY_AGAIN: return "name server unavailable, try again later";
2095 default: return "unknown error";
2096 }
2097}
2098
2099/*-------------------------------------------------------------------------*\
2100* Returns a string describing the last socket manipulation error.
2101\*-------------------------------------------------------------------------*/
2102static char *socket_strerror(void)
2103{
2104 switch (errno) {
2105 case EACCES: return "access denied";
2106 case EMFILE: return "descriptor table is full";
2107 case ENFILE: return "too many open files";
2108 case ENOBUFS: return "insuffucient buffer space";
2109 default: return "unknown error";
2110 }
2111}
2112
2113/*-------------------------------------------------------------------------*\
2114* Returns a string describing the last bind command error.
2115\*-------------------------------------------------------------------------*/
2116static char *bind_strerror(void)
2117{
2118 switch (errno) {
2119 case EBADF: return "invalid descriptor";
2120 case EINVAL: return "socket already bound";
2121 case EACCES: return "access denied";
2122 case ENOTSOCK: return "not a socket descriptor";
2123 case EADDRINUSE: return "address already in use";
2124 case EADDRNOTAVAIL: return "address unavailable";
2125 case ENOMEM: return "out of memory";
2126 default: return "unknown error";
2127 }
2128}
2129
2130/*-------------------------------------------------------------------------*\
2131* Returns a string describing the last connect error.
2132\*-------------------------------------------------------------------------*/
2133static char *connect_strerror(void)
2134{
2135 switch (errno) {
2136 case EBADF: return "invalid descriptor";
2137 case ENOTSOCK: return "not a socket descriptor";
2138 case EADDRNOTAVAIL: return "address not availabe";
2139 case ETIMEDOUT: return "connection timed out";
2140 case ECONNREFUSED: return "connection refused";
2141 case EACCES: return "access denied";
2142 case ENETUNREACH: return "network is unreachable";
2143 case EADDRINUSE: return "address already in use";
2144 default: return "unknown error";
2145 }
2146}
2147#endif
2148
2149/*-------------------------------------------------------------------------*\
2150* Some systems do not provide this so that we provide our own. It's not
2151* marvelously fast, but it works just fine.
2152\*-------------------------------------------------------------------------*/
2153#ifdef LUASOCKET_ATON
2154static int inet_aton(const char *cp, struct in_addr *inp)
2155{
2156 unsigned int a = 0, b = 0, c = 0, d = 0;
2157 int n = 0, r;
2158 unsigned long int addr = 0;
2159 r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n);
2160 if (r == 0 || n == 0) return 0;
2161 cp += n;
2162 if (*cp) return 0;
2163 if (a > 255 || b > 255 || c > 255 || d > 255) return 0;
2164 if (inp) {
2165 addr += a; addr <<= 8;
2166 addr += b; addr <<= 8;
2167 addr += c; addr <<= 8;
2168 addr += d;
2169 inp->s_addr = htonl(addr);
2170 }
2171 return 1;
2172}
2173#endif
2174