aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2000-06-02 17:55:14 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2000-06-02 17:55:14 +0000
commitd455d1707fbdd03592f78a5c5476e90822221359 (patch)
treea90731352375798ad94dd2031a1dfb5e2b399ac2 /src
downloadluasocket-d455d1707fbdd03592f78a5c5476e90822221359.tar.gz
luasocket-d455d1707fbdd03592f78a5c5476e90822221359.tar.bz2
luasocket-d455d1707fbdd03592f78a5c5476e90822221359.zip
Initial revision
Diffstat (limited to 'src')
-rw-r--r--src/luasocket.c1357
1 files changed, 1357 insertions, 0 deletions
diff --git a/src/luasocket.c b/src/luasocket.c
new file mode 100644
index 0000000..027afa3
--- /dev/null
+++ b/src/luasocket.c
@@ -0,0 +1,1357 @@
1/*=========================================================================*\
2* TCP/IP bind for the Lua language
3* Diego Nehab
4* 26/11/1999
5*
6* Module: LSOCK.C
7*
8* This module is part of an effort to make the most important features
9* of the TCP/IP protocol available for Lua scripts.
10* The main intent of the project was the distribution with the CGILua
11* toolkit, in which is is used to implement the SMTP client functions.
12* The Lua interface to TCP/IP follows the BSD TCP/IP API closely,
13* trying to simplify all tasks involved in setting up a client connection
14* and simple server connections.
15* The provided IO routines, send and receive, follow the Lua style, being
16* very similar to the read and write functions found in that language.
17* The module implements both a BSD bind and a Winsock2 bind, and has
18* been tested on several Unix flavors, as well as Windows 98 and NT.
19\*=========================================================================*/
20
21/*=========================================================================*\
22* Common include files
23\*=========================================================================*/
24#include <stdio.h>
25#include <stdlib.h>
26#include <errno.h>
27#include <string.h>
28#include <signal.h>
29
30#include <assert.h>
31
32#define LUA_REENTRANT
33
34#include <lua.h>
35#include <lauxlib.h>
36#include <lualib.h>
37
38#include "lsock.h"
39
40/*=========================================================================*\
41* WinSock2 include files
42\*=========================================================================*/
43#ifdef WIN32
44#include <winsock2.h>
45#include <winbase.h>
46
47/*=========================================================================*\
48* BSD include files
49\*=========================================================================*/
50#else
51/* close function */
52#include <unistd.h>
53/* fnctnl function and associated constants */
54#include <fcntl.h>
55/* struct timeval and CLK_TCK */
56#include <sys/time.h>
57/* times function and struct tms */
58#include <sys/times.h>
59/* internet protocol definitions */
60#include <netinet/in.h>
61#include <arpa/inet.h>
62/* struct sockaddr */
63#include <sys/types.h>
64/* socket function */
65#include <sys/socket.h>
66/* gethostbyname and gethostbyaddr functions */
67#include <netdb.h>
68/* for some reason, bcopy and it's friends are not defined automatically
69** on the IRIX plataforms... */
70#ifdef __sgi
71#include <bstring.h>
72#endif
73#endif
74
75/*=========================================================================*\
76* Datatype compatibilization and some simple changes
77\*=========================================================================*/
78#ifndef WIN32
79#define closesocket close /* WinSock2 has a closesock function instead
80 ** of using the regular close function */
81#define SOCKET int /* it defines a SOCKET type instead of
82 ** using an integer file descriptor */
83#define INVALID_SOCKET (-1) /* and uses the this macro to represent and
84 ** invalid socket */
85#ifndef INADDR_NONE /* some unix flavours don't define this */
86#define INADDR_NONE (-1)
87#endif
88#ifndef CLK_TCK /* SunOS, for instance, does not define */
89#define CLK_TCK 60 /* CLK_TCK */
90#endif
91#endif
92
93/*=========================================================================*\
94* Module definitions
95\*=========================================================================*/
96/*-------------------------------------------------------------------------*\
97* The send and receive function can return one of the following return
98* codes. The values are mapped into Lua values by the function
99* push_error.
100\*-------------------------------------------------------------------------*/
101#define NET_DONE -1 /* operation completed successfully */
102#define NET_TIMEOUT 0 /* operation timed out */
103#define NET_CLOSED 1 /* the connection has been closed */
104
105/*-------------------------------------------------------------------------*\
106* As far as a Lua script is concerned, there are two kind of objects
107* representing a socket. A client socket is an object created by the
108* function connect, and implementing the methods send, receive, timeout
109* and close. A server socket is an object created by the function bind,
110* and implementing the methods listen, accept and close. Lua tag values
111* for these objects are created in the lua_socklibopen function, and
112* passed as closure values (first argumnents to every library function,
113# because we can't have any global variables.
114\*-------------------------------------------------------------------------*/
115#define CLIENT_TAG 1
116#define SERVER_TAG 2
117#define FIRST_PAR 3
118
119/*-------------------------------------------------------------------------*\
120* Both socket types are stored in the same structure to simplify
121* implementation. The tag value used is different, though. The timeout
122* fields are not used for the server socket object.
123* There are two timeout values. The block timeout specifies the maximum
124* time the any IO operation performed by luasock can be blocked waiting
125* for completion. The return timeout specifies the maximum time a Lua script
126* can be blocked waiting for an luasock IO operation to complete.
127\*-------------------------------------------------------------------------*/
128typedef struct t_sock {
129 SOCKET sock; /* operating system socket object */
130 int b; /* block timeout in ms */
131 int r; /* return timeout in ms */
132 int blocking; /* is this socket in blocking mode? */
133} t_sock;
134typedef t_sock *p_sock;
135
136/*-------------------------------------------------------------------------*\
137* Macros and internal declarations
138\*-------------------------------------------------------------------------*/
139/* internal function prototypes */
140#include "sock.h"
141
142/* return time since marked start in ms */
143#define time_since(start) (get_time()-start)
144
145/* min and max macros */
146#ifndef min
147#define min(x, y) ((x) < (y) ? x : y)
148#endif
149#ifndef max
150#define max(x, y) ((x) > (y) ? x : y)
151#endif
152
153/*=========================================================================*\
154* Test support functions
155\*=========================================================================*/
156#ifdef _DEBUG
157/*-------------------------------------------------------------------------*\
158* Returns the time the system has been up, in secconds.
159\*-------------------------------------------------------------------------*/
160static void net_time(lua_State *L);
161static void net_time(lua_State *L)
162{
163 lua_pushnumber(L, get_time()/1000.0);
164}
165
166/*-------------------------------------------------------------------------*\
167* Causes a Lua script to sleep for the specified number of secconds
168\*-------------------------------------------------------------------------*/
169static void net_sleep(lua_State *L);
170static void net_sleep(lua_State *L)
171{
172 int sec = (int) luaL_check_number(L, 1);
173#ifdef WIN32
174 Sleep(1000*sec);
175#else
176 sleep(sec);
177#endif
178}
179
180#endif
181
182/*=========================================================================*\
183* Lua exported functions
184* These functions can be accessed from a Lua script.
185\*=========================================================================*/
186/*-------------------------------------------------------------------------*\
187* Creates a client socket and returns it to the Lua script. The timeout
188* values are initialized as -1 so that the socket will block at any
189* IO operation.
190* Input
191* host: host name or ip address to connect to
192* port: port number on host
193* Returns
194* On success: client socket
195* On error: nil, followed by an error message
196\*-------------------------------------------------------------------------*/
197static void net_connect(lua_State *L)
198{
199 const char *hostname = luaL_check_string(L, FIRST_PAR);
200 unsigned short port = (unsigned short) luaL_check_number(L, FIRST_PAR+1);
201 struct sockaddr_in server;
202 p_sock sock = create_tcpsock();
203 if (!sock) {
204 lua_pushnil(L);
205 lua_pushstring(L, sock_strerror());
206 }
207 /* fills the sockaddr structure with the information needed to
208 ** connect our socket with the remote host */
209 if (!fill_sockaddr(&server, hostname, port)) {
210 free(sock);
211 lua_pushnil(L);
212 lua_pushstring(L, host_strerror());
213 return;
214 }
215 if (connect(sock->sock,(struct sockaddr *)&server,sizeof(server)) < 0) {
216 /* no connection? we close the socket to free the descriptor */
217 closesocket(sock->sock);
218 lua_pushnil(L);
219 lua_pushstring(L, connect_strerror());
220 return;
221 }
222 push_client(L, sock);
223 /* no need to push second return value, since it would be nil anyways */
224}
225
226/*-------------------------------------------------------------------------*\
227* Specifies the number of connections that can be queued on a server
228* socket.
229* Input
230* sock: server socket created by the bind function
231* Returns
232* On success: nil
233* On error: an error message
234\*-------------------------------------------------------------------------*/
235static void net_listen(lua_State *L)
236{
237 p_sock sock = check_server(L, FIRST_PAR);
238 unsigned int backlog = (unsigned int) luaL_check_number(L, FIRST_PAR+1);
239
240 if (listen(sock->sock, backlog) < 0)
241 lua_pushstring(L, "listen error");
242 /* no need to push return value, since it would be nil anyways */
243}
244
245/*-------------------------------------------------------------------------*\
246* Returns a client socket attempting to connect to a server socket.
247* The function blocks until a client shows up.
248* Input
249* sock: server socket created by the bind function
250* Returns
251* On success: client socket attempting connection
252* On error: nil followed by an error message
253\*-------------------------------------------------------------------------*/
254static void net_accept(lua_State *L)
255{
256 struct sockaddr_in client_addr;
257 p_sock server = check_server(L, FIRST_PAR);
258 int client_sock = -1;
259 unsigned int client_len = sizeof(client_addr);
260 p_sock client;
261 /* waits for a connection */
262 client_sock = accept(server->sock, (struct sockaddr *) &client_addr,
263 &client_len);
264 /* we create and return a client socket object, passing the received
265 ** socket to Lua, as a client socket */
266 client = create_sock();
267 if (!client) {
268 lua_pushnil(L);
269 lua_pushstring(L, "out of memory");
270 return;
271 }
272 client->sock = client_sock;
273 push_client(L, client);
274}
275
276/*-------------------------------------------------------------------------*\
277* Associates an address to a server socket.
278* Input
279* host: host name or ip address to bind to
280* port: port to bind to
281* backlog: optional parameter specifying the number of connections
282* to keep waiting before refuse a connection. the default value is 1.
283* Returns
284* On success: server socket bound to address
285* On error: nil, followed by an error message
286\*-------------------------------------------------------------------------*/
287static void net_bind(lua_State *L)
288{
289 const char *hostname = luaL_check_string(L, FIRST_PAR);
290 unsigned short port = (unsigned short) luaL_check_number(L, FIRST_PAR+1);
291 unsigned int backlog = (unsigned int) luaL_opt_number(L, FIRST_PAR+2, 1.0);
292 struct sockaddr_in server;
293 p_sock sock = create_tcpsock();
294 if (!sock) {
295 lua_pushnil(L);
296 lua_pushstring(L, sock_strerror());
297 }
298 /* fills the sockaddr structure with the information needed to
299 ** connect our socket with local address */
300 if (!fill_sockaddr(&server, hostname, port)) {
301 free(sock);
302 lua_pushnil(L);
303 lua_pushstring(L, host_strerror());
304 return;
305 }
306 if (bind(sock->sock,(struct sockaddr *)&server,sizeof(server)) < 0) {
307 lua_pushnil(L);
308 lua_pushstring(L, bind_strerror());
309 return;
310 }
311 /* define the connection waiting queue length */
312 if (listen(sock->sock, backlog) < 0) {
313 lua_pushnil(L);
314 lua_pushstring(L, "listen error");
315 return;
316 }
317 /* pass the created socket to Lua, as a server socket */
318 push_server(L, sock);
319 /* no need to push return value, since it would be nil anyways */
320}
321
322/*-------------------------------------------------------------------------*\
323* Sets timeout values for IO operations on a client socket
324* Input
325* sock: client socket created by the connect function
326* time: time out value in seconds
327* mode: optional timeout mode. "block" specifies the upper bound on
328* the time any IO operation on sock can cause the program to block.
329* "return" specifies the upper bound on the time elapsed before the
330* function returns control to the script. "block" is the default.
331* Returns
332* no return value
333\*-------------------------------------------------------------------------*/
334static void net_timeout(lua_State *L)
335{
336 p_sock sock = check_client(L, FIRST_PAR);
337 int ms = (int) (luaL_check_number(L, FIRST_PAR+1)*1000.0);
338 const char *mode = luaL_opt_string(L, FIRST_PAR+2, "b");
339 switch (*mode) {
340 case 'b':
341 sock->b = ms;
342 break;
343 case 'r':
344 sock->r = ms;
345 break;
346 default:
347 luaL_arg_check(L, 0, FIRST_PAR+2, "invalid timeout mode");
348 break;
349 }
350}
351
352/*-------------------------------------------------------------------------*\
353* Send data through a socket
354* Input: sock, a_1 [, a_2, a_3 ... a_n]
355* sock: client socket created by the connect function
356* a_i: strings to be sent. The strings will be sent on the order they
357* appear as parameters
358* Returns
359* On success: nil, followed by the total number of bytes sent
360* On error: NET_TIMEOUT if the connection timedout, or NET_CLOSED if
361* the connection has been closed
362\*-------------------------------------------------------------------------*/
363static void net_send(lua_State *L)
364{
365 p_sock sock = check_client(L, FIRST_PAR);
366 const char *data;
367 long size;
368 int start = get_time();
369 long total = 0;
370 int arg = FIRST_PAR+1;
371 int err = NET_DONE;
372 int end;
373#ifdef _DEBUG_BLOCK
374printf("luasock: send start\n");
375#endif
376 while ((data = luaL_opt_lstr(L, arg++, NULL, &size)) && err == NET_DONE)
377 total += send_raw(sock, data, size, start, &err, &end);
378 push_error(L, err);
379 lua_pushnumber(L, (double) total);
380#ifdef _DEBUG_BLOCK
381printf("luasock: send end\n");
382#endif
383#ifdef _DEBUG
384/* pass the time elapsed during function execution to Lua, so that
385** the test script can make sure we respected the timeouts */
386lua_pushnumber(L, (end-start)/1000.0);
387#endif
388}
389
390/*-------------------------------------------------------------------------*\
391* Receive data from a socket
392* Input: sock [pat_1, pat_2 ... pat_n]
393* sock: client socket created by the connect function
394* pat_i: may be one of the following
395* "*l": reads a text line, defined as a string of caracters terminates
396* by a LF character, preceded or not by a CR character. This is
397* the default pattern
398* "*lu": reads a text line, terminanted by a CR character only. (Unix mode)
399* number: reads 'number' characters from the socket
400* Returns
401* On success: one string for each pattern
402* On error: all strings for which there was no error, followed by on
403* nil value for each failed string, followed by an error code
404\*-------------------------------------------------------------------------*/
405static void net_receive(lua_State *L)
406{
407 static const char *const modenames[] = {"*l", "*lu", NULL};
408 p_sock sock = check_client(L, FIRST_PAR);
409 int err = NET_DONE, arg = FIRST_PAR+1, got = 0;
410 char *data = NULL;
411 int start = get_time();
412 const char *mode = luaL_opt_string(L, arg++, "*l");
413 int end;
414#ifdef _DEBUG_BLOCK
415printf("luasock: receive start\n");
416#endif
417 do {
418 /* if one pattern failed, we just skip all other patterns */
419 if (err != NET_DONE) {
420 lua_pushnil(L);
421 continue;
422 }
423 /* get next pattern */
424 switch (luaL_findstring(mode, modenames)) {
425 /* DOS line mode */
426 case 0:
427 got = receive_dosline(L, sock, &data, start, &err, &end);
428 break;
429 /* Unix line mode */
430 case 2:
431 got = receive_unixline(L, sock, &data, start, &err, &end);
432 break;
433 /* else it must be a number, raw mode */
434 default: {
435 long size = (long) luaL_check_number(L, arg-1);
436 got = receive_raw(L, sock, size, &data, start, &err, &end);
437 break;
438 }
439 }
440 /* pass result */
441 lua_pushlstring(L, data, got);
442 } while ((mode = luaL_opt_string(L, arg++, NULL)));
443 /* last return is an error code */
444 push_error(L, err);
445#ifdef _DEBUG_BLOCK
446printf("luasock: receive end\n");
447#endif
448#ifdef _DEBUG
449/* pass the time elapsed during function execution to Lua, so that
450** the test script can make sure we respected the timeouts */
451lua_pushnumber(L, (end-start)/1000.0);
452#endif
453}
454
455/*-------------------------------------------------------------------------*\
456* Closes a socket.
457* Input
458* sock: socket to be closed
459\*-------------------------------------------------------------------------*/
460static void net_close(lua_State *L)
461{
462 p_sock sock = check_sock(L, FIRST_PAR);
463 closesocket(sock->sock);
464 /* set value to -1 so that we can later detect the use of a
465 ** closed socket */
466 sock->sock = -1;
467}
468
469/*-------------------------------------------------------------------------*\
470* Gettable fallback for the client socket. This function provides the
471* alternative interface client:receive, client:send etc for the client
472* socket methods.
473\*-------------------------------------------------------------------------*/
474static void client_gettable(lua_State *L)
475{
476 static const char *const net_api[] = {"receive","send","timeout","close",
477 "connect", NULL};
478 const char *idx = luaL_check_string(L, FIRST_PAR+1);
479 switch (luaL_findstring(idx, net_api)) {
480 case 0:
481 lua_pushnumber(L, get_tag(L, CLIENT_TAG));
482 lua_pushnumber(L, get_tag(L, SERVER_TAG));
483 lua_pushcclosure(L, net_receive, 2);
484 break;
485 case 1:
486 lua_pushnumber(L, get_tag(L, CLIENT_TAG));
487 lua_pushnumber(L, get_tag(L, SERVER_TAG));
488 lua_pushcclosure(L, net_send, 2);
489 break;
490 case 2:
491 lua_pushnumber(L, get_tag(L, CLIENT_TAG));
492 lua_pushnumber(L, get_tag(L, SERVER_TAG));
493 lua_pushcclosure(L, net_timeout, 2);
494 break;
495 case 3:
496 lua_pushnumber(L, get_tag(L, CLIENT_TAG));
497 lua_pushnumber(L, get_tag(L, SERVER_TAG));
498 lua_pushcclosure(L, net_close, 2);
499 break;
500 default:
501 lua_pushnil(L);
502 break;
503 }
504}
505
506/*-------------------------------------------------------------------------*\
507* Gettable fallback for the server socket. This function provides the
508* alternative interface server:listen, server:accept etc for the server
509* socket methods.
510\*-------------------------------------------------------------------------*/
511static void server_gettable(lua_State *L)
512{
513 static const char *const net_api[] = {"listen","accept","close", NULL};
514 const char *idx = luaL_check_string(L, FIRST_PAR+1);
515 switch (luaL_findstring(idx, net_api)) {
516 case 0:
517 lua_pushnumber(L, get_tag(L, CLIENT_TAG));
518 lua_pushnumber(L, get_tag(L, SERVER_TAG));
519 lua_pushcclosure(L, net_listen, 2);
520 break;
521 case 1:
522 lua_pushnumber(L, get_tag(L, CLIENT_TAG));
523 lua_pushnumber(L, get_tag(L, SERVER_TAG));
524 lua_pushcclosure(L, net_accept, 2);
525 break;
526 case 2:
527 lua_pushnumber(L, get_tag(L, CLIENT_TAG));
528 lua_pushnumber(L, get_tag(L, SERVER_TAG));
529 lua_pushcclosure(L, net_close, 2);
530 break;
531 default:
532 lua_pushnil(L);
533 break;
534 }
535}
536
537/*-------------------------------------------------------------------------*\
538* Garbage collection fallback for the socket objects. This function
539* makes sure that all collected sockets are closed and that the memory
540* used by the C structure t_sock is properly released.
541\*-------------------------------------------------------------------------*/
542static void sock_gc(lua_State *L)
543{
544 p_sock sock = check_sock(L, FIRST_PAR);
545 if (sock->sock >= 0)
546 closesocket(sock->sock);
547 free(sock);
548}
549
550/*=========================================================================*\
551* Internal functions
552\*=========================================================================*/
553/*-------------------------------------------------------------------------*\
554* Instals a handler to ignore sigpipe. That is, unless the signal had
555* already been redefined. This function is not needed on the WinSock2,
556* since it's sockets don't raise this signal.
557\*-------------------------------------------------------------------------*/
558#ifndef WIN32
559static void handle_sigpipe(void);
560static void handle_sigpipe(void)
561{
562 struct sigaction old, new;
563 bzero(&new, sizeof new);
564 new.sa_handler = SIG_IGN;
565 sigaction(SIGPIPE, &new, &old);
566 /* test if the signal had been before, and restore it if so */
567 if (old.sa_handler != SIG_DFL) {
568#ifdef _DEBUG
569/* this is a somewhat dangerous situation. we can only hope the
570** installed signal handler understands that this signal can be
571** raised by a socket operation */
572printf("SIGPIPE ALREADY REDEFINED!!!\n");
573#endif
574 sigaction(SIGPIPE, &old, NULL);
575 }
576}
577#endif
578
579/*-------------------------------------------------------------------------*\
580* Creates a t_sock structure with default values.
581\*-------------------------------------------------------------------------*/
582static p_sock create_sock(void)
583{
584 p_sock sock = (p_sock) malloc(sizeof(t_sock));
585 if (!sock)
586 return NULL;
587 sock->sock = -1;
588 sock->r = -1;
589 sock->b = -1;
590 sock->blocking = 1;
591 return sock;
592}
593
594/*-------------------------------------------------------------------------*\
595* Creates a TCP/IP socket.
596* Returns
597* A pointer to a t_sock structure or NULL in case of error
598\*-------------------------------------------------------------------------*/
599static p_sock create_tcpsock(void)
600{
601 p_sock sock = create_sock();
602 if (!sock)
603 return NULL;
604 sock->sock = socket(AF_INET, SOCK_STREAM, 0);
605 if (sock->sock < 0) {
606 free(sock);
607 sock = NULL;
608 }
609#ifdef _DEBUG
610/* this allow us to re-bind onto an address even if there is still
611** a TIME_WAIT condition. debugging is much more confortable, because
612** we don't get "address already in use" errors all the time we
613** re-run the program before the OS is ready. in real life, though
614** there could be data pending on the socket and this could lead to
615** some weird errors. */
616{
617 int val = 1;
618 setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
619 sizeof(val));
620}
621#endif
622 return sock;
623}
624
625/*-------------------------------------------------------------------------*\
626* Fills a sockaddr structure according to a given host name of ip
627* address and a port number.
628* Input
629* address: pointer to sockaddr structure to be filled
630* hostname: host name or ip address
631* port: port number
632* Returns
633* 1 in case of success, 0 otherwise
634\*-------------------------------------------------------------------------*/
635static int fill_sockaddr(struct sockaddr_in *address, const char *hostname,
636 unsigned short port)
637{
638 struct hostent *host = NULL;
639 unsigned long addr = inet_addr(hostname);
640 /* BSD says we could have used gethostbyname even if the hostname is
641 ** in ip address form, but WinSock2 says we can't. Therefore we
642 ** choose a method that works on both plataforms */
643 if (addr == INADDR_NONE)
644 host = gethostbyname(hostname);
645 else
646 host = gethostbyaddr((char * ) &addr, sizeof(unsigned long), AF_INET);
647 if (!host)
648 return 0;
649 memset(address, 0, sizeof(struct sockaddr_in));
650 address->sin_family = AF_INET;
651 address->sin_port = htons(port);
652 memcpy(&(address->sin_addr), host->h_addr, (unsigned) host->h_length);
653 return 1;
654}
655
656/*-------------------------------------------------------------------------*\
657* Determine the time limit to be passed to the select function, given
658* the time elapsed since the beginning of the operation.
659* Input
660* sock: socket structure being used in operation
661* elapsed: time elapsed since operation started
662* Returns
663* time limit before function return in ms or -1 in case there is no
664* time limit
665\*-------------------------------------------------------------------------*/
666static int get_timeout(p_sock sock, int elapsed)
667{
668 /* no timeout */
669 if (sock->b < 0 && sock->r < 0)
670 return -1;
671 /* there is no block timeout, we use the return timeout */
672 if (sock->b < 0)
673 return max(0, sock->r - elapsed);
674 /* there is no return timeout, we use the block timeout */
675 else if (sock->r < 0)
676 return sock->b;
677 /* both timeouts are specified */
678 else
679 return min(sock->b, max(0, sock->r - elapsed));
680}
681
682/*-------------------------------------------------------------------------*\
683* Determines if we have a timeout condition or if we can proceed with
684* an IO read operation.
685* Input
686* sock: socket structure being used in operation
687* elapsed: time elapsed since operation started
688* Returns
689* 1 if we can proceed, 0 if a timeou has occured
690\*-------------------------------------------------------------------------*/
691static int read_or_timeout(p_sock sock, int elapsed)
692{
693 fd_set set; /* file descriptor set */
694 struct timeval to; /* timeout structure */
695 int ms = get_timeout(sock, elapsed);
696 int err;
697 /* got timeout */
698 if (ms == 0)
699 return 0;
700 FD_ZERO(&set);
701 FD_SET(sock->sock, &set);
702 /* we have a limit on the time we can wait */
703 if (ms > 0) {
704 to.tv_sec = ms / 1000;
705 to.tv_usec = (ms % 1000) * 1000;
706 err = select(sock->sock+1, &set, NULL, NULL, &to);
707 set_nonblocking(sock);
708 /* we can wait forever */
709 } else {
710 err = select(sock->sock+1, &set, NULL, NULL, NULL);
711 set_blocking(sock);
712 }
713 return (err > 0);
714}
715
716/*-------------------------------------------------------------------------*\
717* Determines if we have a timeout condition or if we can proceed with
718* an IO write operation.
719* Input
720* sock: socket structure being used in operation
721* elapsed: time elapsed since operation started
722* Returns
723* 1 if we can proceed, 0 if a timeou has occured
724\*-------------------------------------------------------------------------*/
725static int write_or_timeout(p_sock sock, int elapsed)
726{
727 fd_set set; /* file descriptor set */
728 struct timeval to; /* timeout structure */
729 int ms = get_timeout(sock, elapsed);
730 int err;
731 /* got timeout */
732 if (ms == 0)
733 return 0;
734 FD_ZERO(&set);
735 FD_SET(sock->sock, &set);
736 /* we have a limit on the time we can wait */
737 if (ms > 0) {
738 to.tv_sec = ms / 1000;
739 to.tv_usec = (ms % 1000) * 1000;
740 err = select(sock->sock+1, NULL, &set, NULL, &to);
741 set_nonblocking(sock);
742 /* we can wait forever */
743 } else {
744 err = select(sock->sock+1, NULL, &set, NULL, NULL);
745 set_blocking(sock);
746 }
747 return (err > 0);
748}
749
750/*-------------------------------------------------------------------------*\
751* Sends a raw block of data through a socket. The operations are all
752* non-blocking and the function respects the timeout values in sock.
753* Input
754* sock: socket structure being used in operation
755* data: buffer to be sent
756* wanted: number of bytes in buffer
757* start: time the operation started, in ms
758* Output
759* err: operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
760* Returns
761* Number of bytes written
762\*-------------------------------------------------------------------------*/
763static int send_raw(p_sock sock, const char *data, int wanted,
764 int start, int *err, int *end)
765{
766 int put = 0, total = 0;
767 *end = start;
768 while (wanted > 0) {
769 if(!write_or_timeout(sock, time_since(start))) {
770#ifdef _DEBUG
771*end = get_time();
772#endif
773 *err = NET_TIMEOUT;
774 return total;
775 }
776#ifdef _DEBUG
777/* the lua_pushlstring function can take a long time to pass a large block
778** to Lua, therefore, we mark the time before passing the result.
779** also, the call to write of read might take longer then the time we had
780** left, so that the end of the operation is marked before the last call
781** to the OS */
782*end = get_time();
783#endif
784 put = send(sock->sock, data, wanted, 0);
785 if (put <= 0) {
786#ifdef WIN32
787 /* on WinSock, a select over a socket on which there is a
788 ** non-blocking operation pending returns immediately, even
789 ** if the call would block. therefore, we have to do a busy
790 ** wait here. */
791 if (WSAGetLastError() == WSAEWOULDBLOCK)
792 continue;
793#endif
794 *err = NET_CLOSED;
795 return total;
796 }
797#ifdef _DEBUG_BLOCK
798printf("luasock: sent %d bytes, %dms elapsed\n", put, time_since(start));
799#endif
800 wanted -= put;
801 data += put;
802 total += put;
803 }
804 *err = NET_DONE;
805 return total;
806}
807
808/*-------------------------------------------------------------------------*\
809* Reads a raw block of data from a socket. The operations are all
810* non-blocking and the function respects the timeout values in sock.
811* Input
812* sock: socket structure being used in operation
813* wanted: number of bytes to be read
814* start: time the operation started, in ms
815* Output
816* data: pointer to an internal buffer containing the data read
817* err: operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
818* Returns
819* Number of bytes read
820\*-------------------------------------------------------------------------*/
821static int receive_raw(lua_State *L, p_sock sock, int wanted, char **data,
822 int start, int *err, int *end)
823{
824 int got = 0;
825 char *buffer = NULL;
826 *end = start;
827 luaL_resetbuffer(L);
828 while (wanted > 0) {
829 buffer = luaL_openspace(L, wanted);
830 if(!read_or_timeout(sock, time_since(start))) {
831#ifdef _DEBUG
832*end = get_time();
833#endif
834 *data = luaL_buffer(L);
835 *err = NET_TIMEOUT;
836 return luaL_getsize(L);
837 }
838#ifdef _DEBUG
839*end = get_time();
840#endif
841 got = recv(sock->sock, buffer, wanted, 0);
842#ifdef _DEBUG_BLOCK
843printf("luasock: wanted %d, got %d, %dms elapsed\n", wanted, got, time_since(start));
844#endif
845 if (got <= 0) {
846 *data = luaL_buffer(L);
847 *err = NET_CLOSED;
848 return luaL_getsize(L);
849 }
850 wanted -= got;
851 luaL_addsize(L,got);
852 }
853 *data = luaL_buffer(L);
854 *err = NET_DONE;
855 return luaL_getsize(L);
856}
857
858/*-------------------------------------------------------------------------*\
859* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF
860* are not returned by the function. All operations are non-blocking and the
861* function respects the timeout values in sock.
862* Input
863* sock: socket structure being used in operation
864* wanted: number of bytes in buffer
865* start: time the operation started, in ms
866* Output
867* data: pointer to an internal buffer containing the data read
868* err: operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
869* Returns
870* Number of bytes read
871\*-------------------------------------------------------------------------*/
872static long receive_dosline(lua_State *L, p_sock sock, char **data,
873 int start, int *err, int *end)
874{
875 char c = ' ';
876 long got = 0;
877 *end = start;
878 luaL_resetbuffer(L);
879 while (c != '\n') {
880 if (read_or_timeout(sock, time_since(start))) {
881#ifdef _DEBUG
882*end = get_time();
883#endif
884 got = recv(sock->sock, &c, 1, 0);
885 if (got <= 0) {
886 *err = NET_CLOSED;
887 *data = luaL_buffer(L);
888 return luaL_getsize(L);
889 }
890 luaL_addchar(L, c);
891 } else {
892 *err = NET_TIMEOUT;
893 *data = luaL_buffer(L);
894 return luaL_getsize(L);
895 }
896 }
897 *err = NET_DONE;
898 *data = luaL_buffer(L);
899 got = luaL_getsize(L);
900 if ((*data)[got-2] == '\r') return got-2;
901 else return got-1;
902}
903
904/*-------------------------------------------------------------------------*\
905* Reads a line terminated by a LF character, which is not returned by
906* the function. All operations are non-blocking and the function respects
907* the timeout values in sock.
908* Input
909* sock: socket structure being used in operation
910* wanted: number of bytes in buffer
911* start: time the operation started, in ms
912* Output
913* data: pointer to an internal buffer containing the data read
914* err: operation error code. NET_DONE, NET_TIMEOUT or NET_CLOSED
915* Returns
916* Number of bytes read
917\*-------------------------------------------------------------------------*/
918static long receive_unixline(lua_State *L, p_sock sock, char **data,
919 int start, int *err, int *end)
920{
921 char c = ' ';
922 *end = start;
923 luaL_resetbuffer(L);
924 while (c != '\n') {
925 if (read_or_timeout(sock, time_since(start))) {
926#ifdef _DEBUG
927*end = get_time();
928#endif
929 if (recv(sock->sock, &c, 1, 0) <= 0) {
930 *err = NET_CLOSED;
931 *data = luaL_buffer(L);
932 return luaL_getsize(L);
933 }
934 luaL_addchar(L, c);
935 } else {
936 *err = NET_TIMEOUT;
937 *data = luaL_buffer(L);
938 return luaL_getsize(L);
939 }
940 }
941 *err = NET_DONE;
942 *data = luaL_buffer(L);
943 return luaL_getsize(L) - 1;
944}
945
946/*-------------------------------------------------------------------------*\
947* Gets a tag from a closure parameter
948* Input
949* L: lua environment
950* par: parameter number
951\*-------------------------------------------------------------------------*/
952static int get_tag(lua_State *L, int par)
953{
954 return (int) lua_getnumber(L, lua_getparam(L, par));
955}
956
957/*-------------------------------------------------------------------------*\
958* Passes an error code to Lua. The NET_DONE error is translated to nil.
959* Input
960* err: error code to be passed to Lua
961\*-------------------------------------------------------------------------*/
962static void push_error(lua_State *L, int err)
963{
964 switch (err) {
965 case NET_DONE:
966 lua_pushnil(L);
967 break;
968 case NET_TIMEOUT:
969 lua_pushstring(L, "timeout");
970 break;
971 case NET_CLOSED:
972 lua_pushstring(L, "closed");
973 break;
974 }
975}
976
977/*-------------------------------------------------------------------------*\
978* Passes a client socket to Lua.
979* Must be called from a closure receiving the socket tags as its
980* parameters.
981* Input
982* L: lua environment
983* sock: pointer to socket structure to be used
984\*-------------------------------------------------------------------------*/
985static void push_client(lua_State *L, p_sock sock)
986{
987 lua_pushusertag(L, (void *) sock, get_tag(L, CLIENT_TAG));
988}
989
990/*-------------------------------------------------------------------------*\
991* Passes a server socket to Lua.
992* Must be called from a closure receiving the socket tags as its
993* parameters.
994* Input
995* L: lua environment
996* sock: pointer to socket structure to be used
997\*-------------------------------------------------------------------------*/
998static void push_server(lua_State *L, p_sock sock)
999{
1000 lua_pushusertag(L, (void *) sock, get_tag(L, SERVER_TAG));
1001}
1002
1003/*=========================================================================*\
1004* WinSock2 specific functions.
1005\*=========================================================================*/
1006#ifdef WIN32
1007/*-------------------------------------------------------------------------*\
1008* Initializes WinSock2 library.
1009* Returns
1010* 1 in case of success. 0 in case of error.
1011\*-------------------------------------------------------------------------*/
1012static int wsock_open(void)
1013{
1014 WORD wVersionRequested;WSADATA wsaData;int err;
1015 wVersionRequested = MAKEWORD( 2, 0 );
1016 err = WSAStartup( wVersionRequested, &wsaData );
1017 if ( err != 0 ) {
1018 return 0;
1019 }
1020 if ( LOBYTE( wsaData.wVersion ) != 2 ||
1021 HIBYTE( wsaData.wVersion ) != 0 ) {
1022 WSACleanup( );
1023 return 0;
1024 }
1025 return 1;
1026}
1027
1028/*-------------------------------------------------------------------------*\
1029* Gets time in ms, relative to system startup.
1030* Returns
1031* time in ms.
1032\*-------------------------------------------------------------------------*/
1033static int get_time(void)
1034{
1035 return GetTickCount();
1036}
1037
1038/*-------------------------------------------------------------------------*\
1039* Put socket into blocking mode.
1040\*-------------------------------------------------------------------------*/
1041static void set_blocking(p_sock sock)
1042{
1043 u_long argp = 0;
1044 if (!sock->blocking) {
1045 ioctlsocket(sock->sock, FIONBIO, &argp);
1046 sock->blocking = 1;
1047 }
1048}
1049
1050/*-------------------------------------------------------------------------*\
1051* Put socket into non-blocking mode.
1052\*-------------------------------------------------------------------------*/
1053static void set_nonblocking(p_sock sock)
1054{
1055 u_long argp = 1;
1056 if (sock->blocking) {
1057 ioctlsocket(sock->sock, FIONBIO, &argp);
1058 sock->blocking = 0;
1059 }
1060}
1061
1062/*-------------------------------------------------------------------------*\
1063* Returns a string describing the last host manipulation error.
1064\*-------------------------------------------------------------------------*/
1065static char *host_strerror(void)
1066{
1067 switch (WSAGetLastError()) {
1068 case HOST_NOT_FOUND: return "host not found";
1069 case NO_ADDRESS: return "unable to resolve host name";
1070 case NO_RECOVERY: return "name server error";
1071 case TRY_AGAIN: return "name server unavailable, try again later.";
1072 default: return "unknown error";
1073 }
1074}
1075
1076/*-------------------------------------------------------------------------*\
1077* Returns a string describing the last socket manipulation error.
1078\*-------------------------------------------------------------------------*/
1079static char *sock_strerror(void)
1080{
1081 switch (WSAGetLastError()) {
1082 case WSANOTINITIALISED: return "not initialized";
1083 case WSAENETDOWN: return "network is down";
1084 case WSAEMFILE: return "descriptor table is full";
1085 case WSAENOBUFS: return "insufficient buffer space";
1086 default: return "unknown error";
1087 }
1088}
1089
1090/*-------------------------------------------------------------------------*\
1091* Returns a string describing the last bind operation error.
1092\*-------------------------------------------------------------------------*/
1093static char *bind_strerror(void)
1094{
1095 switch (WSAGetLastError()) {
1096 case WSANOTINITIALISED: return "not initialized";
1097 case WSAENETDOWN: return "network is down";
1098 case WSAEADDRINUSE: return "address already in use";
1099 case WSAEINVAL: return "socket already bound";
1100 case WSAENOBUFS: return "too many connections";
1101 case WSAEFAULT: return "invalid address";
1102 case WSAENOTSOCK: return "not a socket descriptor";
1103 default: return "unknown error";
1104 }
1105}
1106
1107/*-------------------------------------------------------------------------*\
1108* Returns a string describing the last connect operationerror.
1109\*-------------------------------------------------------------------------*/
1110static char *connect_strerror(void)
1111{
1112 switch (WSAGetLastError()) {
1113 case WSANOTINITIALISED: return "not initialized";
1114 case WSAENETDOWN: return "network is down";
1115 case WSAEADDRINUSE: return "address already in use";
1116 case WSAEADDRNOTAVAIL: return "address unavailable";
1117 case WSAECONNREFUSED: return "connection refused";
1118 case WSAENETUNREACH: return "network is unreachable";
1119 default: return "unknown error";
1120 }
1121}
1122#else
1123
1124/*=========================================================================*\
1125* BSD specific functions.
1126\*=========================================================================*/
1127/*-------------------------------------------------------------------------*\
1128* Gets time in ms, relative to system startup.
1129* Returns
1130* time in ms.
1131\*-------------------------------------------------------------------------*/
1132static int get_time(void)
1133{
1134 struct tms t;
1135 return (times(&t)*1000)/CLK_TCK;
1136}
1137
1138/*-------------------------------------------------------------------------*\
1139* Put socket into blocking mode.
1140\*-------------------------------------------------------------------------*/
1141static void set_blocking(p_sock sock)
1142{
1143 if (!sock->blocking) {
1144 int flags = fcntl(sock->sock, F_GETFL, 0);
1145 flags &= (~(O_NONBLOCK));
1146 fcntl(sock->sock, F_SETFL, flags);
1147 sock->blocking = 1;
1148 }
1149}
1150
1151/*-------------------------------------------------------------------------*\
1152* Put socket into non-blocking mode.
1153\*-------------------------------------------------------------------------*/
1154static void set_nonblocking(p_sock sock)
1155{
1156 if (sock->blocking) {
1157 int flags = fcntl(sock->sock, F_GETFL, 0);
1158 flags |= O_NONBLOCK;
1159 fcntl(sock->sock, F_SETFL, flags);
1160 sock->blocking = 0;
1161 }
1162}
1163
1164/*-------------------------------------------------------------------------*\
1165* Returns a string describing the last host manipulation error.
1166\*-------------------------------------------------------------------------*/
1167static char *host_strerror(void)
1168{
1169 switch (h_errno) {
1170 case HOST_NOT_FOUND: return "host not found";
1171 case NO_ADDRESS: return "unable to resolve host name";
1172 case NO_RECOVERY: return "name server error";
1173 case TRY_AGAIN: return "name server unavailable, try again later";
1174 default: return "unknown error";
1175 }
1176}
1177
1178/*-------------------------------------------------------------------------*\
1179* Returns a string describing the last socket manipulation error.
1180\*-------------------------------------------------------------------------*/
1181static char *sock_strerror(void)
1182{
1183 switch (errno) {
1184 case EACCES: return "access denied";
1185 case EMFILE: return "descriptor table is full";
1186 case ENFILE: return "too many open files";
1187 case ENOBUFS: return "insuffucient buffer space";
1188 default: return "unknown error";
1189 }
1190}
1191
1192/*-------------------------------------------------------------------------*\
1193* Returns a string describing the last bind command error.
1194\*-------------------------------------------------------------------------*/
1195static char *bind_strerror(void)
1196{
1197 switch (errno) {
1198 case EBADF: return "invalid descriptor";
1199 case EINVAL: return "socket already bound";
1200 case EACCES: return "access denied";
1201 case ENOTSOCK: return "not a socket descriptor";
1202 case EADDRINUSE: return "address already in use";
1203 case EADDRNOTAVAIL: return "address unavailable";
1204 case ENOMEM: return "out of memory";
1205 default: return "unknown error";
1206 }
1207}
1208
1209/*-------------------------------------------------------------------------*\
1210* Returns a string describing the last connect error.
1211\*-------------------------------------------------------------------------*/
1212static char *connect_strerror(void)
1213{
1214 switch (errno) {
1215 case EBADF: return "invalid descriptor";
1216 case ENOTSOCK: return "not a socket descriptor";
1217 case EADDRNOTAVAIL: return "address not availabe";
1218 case ETIMEDOUT: return "connection timed out";
1219 case ECONNREFUSED: return "connection refused";
1220 case EACCES: return "access denied";
1221 case ENETUNREACH: return "network is unreachable";
1222 case EADDRINUSE: return "address already in use";
1223 default: return "unknown error";
1224 }
1225}
1226
1227#endif
1228
1229/*=========================================================================*\
1230* Module exported functions
1231\*=========================================================================*/
1232/*-------------------------------------------------------------------------*\
1233* Initializes the library interface with Lua and the socket library.
1234* Defines the symbols exported to Lua.
1235\*-------------------------------------------------------------------------*/
1236void lua_socklibopen(lua_State *L)
1237{
1238 int client_tag, server_tag;
1239 static struct luaL_reg funcs[] = {
1240 {"connect", net_connect},
1241 {"bind", net_bind},
1242 {"listen", net_listen},
1243 {"accept", net_accept},
1244 {"close", net_close},
1245 {"send", net_send},
1246 {"receive", net_receive},
1247 {"timeout", net_timeout}
1248 };
1249 int i;
1250
1251#ifdef WIN32
1252 wsock_open();
1253#endif
1254 /* declare new Lua tags for used userdata values */
1255 client_tag = lua_newtag(L);
1256 server_tag = lua_newtag(L);
1257 /* Lua exported functions */
1258 for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) {
1259 lua_pushnumber(L, client_tag);
1260 lua_pushnumber(L, server_tag);
1261 lua_pushcclosure(L, funcs[i].func, 2 );
1262 lua_setglobal(L, funcs[i].name );
1263 }
1264 /* fallbacks */
1265 lua_pushnumber(L, client_tag);
1266 lua_pushnumber(L, server_tag);
1267 lua_pushcclosure(L, client_gettable, 2);
1268 lua_settagmethod(L, client_tag, "gettable");
1269
1270 lua_pushnumber(L, client_tag);
1271 lua_pushnumber(L, server_tag);
1272 lua_pushcclosure(L, server_gettable, 2);
1273 lua_settagmethod(L, server_tag, "gettable");
1274
1275 lua_pushnumber(L, client_tag);
1276 lua_pushnumber(L, server_tag);
1277 lua_pushcclosure(L, sock_gc, 2);
1278 lua_settagmethod(L, client_tag, "gc");
1279
1280 lua_pushnumber(L, client_tag);
1281 lua_pushnumber(L, server_tag);
1282 lua_pushcclosure(L, sock_gc, 2);
1283 lua_settagmethod(L, server_tag, "gc");
1284
1285 /* avoid stupid compiler warnings */
1286 (void) set_blocking;
1287
1288#ifndef WIN32
1289 /* avoid getting killed by a SIGPIPE signal */
1290 handle_sigpipe();
1291#endif
1292
1293#ifdef _DEBUG
1294/* test support functions */
1295lua_pushcfunction(L, net_sleep); lua_setglobal(L, "sleep");
1296lua_pushcfunction(L, net_time); lua_setglobal(L, "time");
1297#endif
1298}
1299
1300/*=========================================================================*\
1301* Lua2c and c2lua stack auxiliary functions
1302\*=========================================================================*/
1303/*-------------------------------------------------------------------------*\
1304* Checks if argument is a client socket, printing an error message in
1305* case of error
1306* Input
1307* numArg: argument position in lua2c stack
1308* Returns
1309* pointer to client socket, or doesn't return in case of error
1310\*-------------------------------------------------------------------------*/
1311static p_sock check_client(lua_State *L, int numArg)
1312{
1313 p_sock sock;
1314 lua_Object o = lua_getparam(L, numArg);
1315 luaL_arg_check(L, lua_tag(L, o) == get_tag(L, CLIENT_TAG),
1316 numArg, "client socket expected");
1317 sock = (p_sock) lua_getuserdata(L, o);
1318 if (sock->sock < 0)
1319 lua_error(L, "operation on closed socket");
1320 return sock;
1321}
1322
1323/*-------------------------------------------------------------------------*\
1324* Checks if argument is a server socket, printing an error message in
1325* case of error
1326* Input
1327* numArg: argument position in lua2c stack
1328* Returns
1329* pointer to server socket, or doesn't return in case of error
1330\*-------------------------------------------------------------------------*/
1331static p_sock check_server(lua_State *L, int numArg)
1332{
1333 p_sock sock;
1334 lua_Object o = lua_getparam(L, numArg);
1335 luaL_arg_check(L, lua_tag(L, o) == get_tag(L, SERVER_TAG),
1336 numArg, "server socket expected");
1337 sock = (p_sock) lua_getuserdata(L, o);
1338 if (sock->sock < 0)
1339 lua_error(L, "operation on closed socket");
1340 return sock;
1341}
1342
1343/*-------------------------------------------------------------------------*\
1344* Checks if argument is a socket, printing an error message in
1345* case of error
1346* Input
1347* numArg: argument position in lua2c stack
1348* Returns
1349* pointer to socket, or doesn't return in case of error
1350\*-------------------------------------------------------------------------*/
1351static p_sock check_sock(lua_State *L, int numArg)
1352{
1353 lua_Object o = lua_getparam(L, numArg);
1354 luaL_arg_check(L, (lua_tag(L, o) == get_tag(L, CLIENT_TAG)) ||
1355 (lua_tag(L, o) == get_tag(L, SERVER_TAG)), numArg, "socket expected");
1356 return lua_getuserdata(L, o);
1357}