1 /* ==========================================================================
2 * socket.c - Lua Continuation Queues
3 * --------------------------------------------------------------------------
4 * Copyright (c) 2012, 2013, 2014 William Ahern
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to permit
11 * persons to whom the Software is furnished to do so, subject to the
12 * following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
20 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * ==========================================================================
25 */
26 #include "config.h"
27
28 #include <stddef.h> /* NULL offsetof size_t */
29 #include <stdarg.h> /* va_list va_start va_arg va_end */
30 #include <stdlib.h> /* strtol(3) */
31 #include <string.h> /* memset(3) memchr(3) memcpy(3) memmem(3) */
32 #include <math.h> /* NAN */
33 #include <errno.h> /* EBADF ENOTSOCK EOPNOTSUPP EOVERFLOW EPIPE */
34
35 #include <sys/types.h>
36 #include <sys/socket.h> /* AF_UNIX MSG_CMSG_CLOEXEC SOCK_CLOEXEC SOCK_STREAM SOCK_SEQPACKET SOCK_DGRAM PF_UNSPEC socketpair(2) */
37 #include <sys/un.h> /* struct sockaddr_un */
38 #include <unistd.h> /* dup(2) */
39 #include <fcntl.h> /* F_DUPFD_CLOEXEC fcntl(2) */
40 #include <arpa/inet.h> /* ntohs(3) */
41
42 #include <openssl/ssl.h> /* SSL_CTX, SSL_CTX_free(), SSL_CTX_up_ref(), SSL, SSL_up_ref() */
43 #include <openssl/crypto.h> /* CRYPTO_LOCK_SSL CRYPTO_add() */
44
45 #include <lua.h>
46 #include <lauxlib.h>
47
48 #include "lib/socket.h"
49 #include "lib/fifo.h"
50 #include "lib/dns.h"
51
52 #include "cqueues.h"
53
54
55 /*
56 * F E A T U R E R O U T I N E S
57 *
58 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
59
60 #ifdef LIBRESSL_VERSION_NUMBER
61 #define OPENSSL_PREREQ(M, m, p) (0)
62 #define LIBRESSL_PREREQ(M, m, p) \
63 (LIBRESSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12)))
64 #else
65 #define OPENSSL_PREREQ(M, m, p) \
66 (OPENSSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12)))
67 #define LIBRESSL_PREREQ(M, m, p) (0)
68 #endif
69
70 #ifndef HAVE_SSL_CTX_UP_REF
71 #define HAVE_SSL_CTX_UP_REF (OPENSSL_PREREQ(1,1,0) || LIBRESSL_PREREQ(2,7,0))
72 #endif
73
74 #ifndef HAVE_SSL_UP_REF
75 #define HAVE_SSL_UP_REF (OPENSSL_PREREQ(1,1,0) || LIBRESSL_PREREQ(2,7,0))
76 #endif
77
78
79 /*
80 * C O M P A T R O U T I N E S
81 *
82 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
83
84 #if !HAVE_SSL_CTX_UP_REF
85 #define SSL_CTX_up_ref(ctx) CRYPTO_add(&(ctx)->references, 1, CRYPTO_LOCK_SSL_CTX)
86 #endif
87
88 #if !HAVE_SSL_UP_REF
89 #define SSL_up_ref(ssl) CRYPTO_add(&(ssl)->references, 1, CRYPTO_LOCK_SSL)
90 #endif
91
92
93 /*
94 * T E X T M U N G I N G R O U T I N E S
95 *
96 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
97
mime_isblank(unsigned char ch)98 static inline _Bool mime_isblank(unsigned char ch) {
99 return ch == 32 || ch == 9;
100 } /* mime_isblank() */
101
102
mime_isfname(unsigned char ch)103 static inline _Bool mime_isfname(unsigned char ch) {
104 return ch >= 33 && ch <= 126 && ch != 58 /* : */;
105 } /* mime_isfname() */
106
107
iov_chr(const struct iovec * iov,size_t p)108 static int iov_chr(const struct iovec *iov, size_t p) {
109 return (p < iov->iov_len)? ((unsigned char *)iov->iov_base)[p] : -1;
110 } /* iov_chr() */
111
112
iov_lc(const struct iovec * iov)113 static int iov_lc(const struct iovec *iov) {
114 return (iov->iov_len)? iov_chr(iov, iov->iov_len - 1) : -1;
115 } /* iov_lc() */
116
117
iov_addzu(size_t * r,size_t a,size_t b)118 static int iov_addzu(size_t *r, size_t a, size_t b) {
119 int error;
120
121 if ((error = cqs_addzu(r, a, b)))
122 return error;
123
124 return (*r == (size_t)-1)? EOVERFLOW : 0;
125 } /* iov_addzu() */
126
127
128 /*
129 * Find end of MIME header. Returns 0 < length <= .iov_len to end of header,
130 * 0 if not found. If length is >.iov_len then needs more data. Returns -1
131 * on error.
132 */
133 #define IOV_F_EMPTYFNAME 1
134
iov_eoh(const struct iovec * iov,_Bool eof,int flags,int * _error)135 static size_t iov_eoh(const struct iovec *iov, _Bool eof, int flags, int *_error) {
136 const char *tp, *p, *pe;
137 size_t n;
138 int error;
139
140 tp = iov->iov_base;
141 p = tp;
142 pe = tp + iov->iov_len;
143
144 while (p < pe && mime_isfname(*p))
145 p++;
146
147 if (p == tp && p < pe && !(flags & IOV_F_EMPTYFNAME))
148 return 0; /* not allowing empty field names */
149
150 while (p < pe && mime_isblank(*p))
151 p++;
152
153 if (p < pe && *p != ':')
154 return 0; /* not a valid field name */
155
156 while (p < pe && (p = memchr(p, '\n', pe - p))) {
157 if (++p < pe && !mime_isblank(*p))
158 return p - tp; /* found */
159 }
160
161 if (eof)
162 return 0; /* do not allow truncated headers */
163
164 if ((error = iov_addzu(&n, iov->iov_len, 1)))
165 goto error;
166
167 return n; /* need more */
168 error:
169 *_error = error;
170
171 return -1;
172 } /* iov_eoh() */
173
174
175 /*
176 * Find end of MIME boundary marker. Returns length to end of marker, or 0
177 * if not found.
178 */
iov_eob(const struct iovec * iov,const char * eob,size_t eoblen)179 static size_t iov_eob(const struct iovec *iov, const char *eob, size_t eoblen) {
180 const char *p;
181
182 if (iov->iov_len < eoblen)
183 return 0;
184
185 if ((p = memmem(iov->iov_base, iov->iov_len, eob, eoblen)))
186 return (p + eoblen) - (char *)iov->iov_base;
187
188 return 0;
189 } /* iov_eob() */
190
191
192 /*
193 * Find end of text region which would fill >= minbuf and <= maxbuf after
194 * calling iov_trimcr, and without leaving a trailing \r unless EOF. If
195 * return value > iov.iov_len, then need more data. Returns -1 on error.
196 */
iov_eot(const struct iovec * iov,size_t minbuf,size_t maxbuf,_Bool eof,int * _error)197 static size_t iov_eot(const struct iovec *iov, size_t minbuf, size_t maxbuf, _Bool eof, int *_error) {
198 const char *p, *pe;
199 size_t n = 0, eot;
200 int lc = -1, error;
201
202 p = iov->iov_base;
203 pe = p + iov->iov_len;
204
205 for (; p < pe && n < maxbuf; ++n) {
206 lc = *p++;
207
208 if (lc == '\r' && p < pe && *p == '\n') {
209 lc = *p++; /* skip \n so we don't ++n */
210 }
211 }
212
213 if ((size_t)-1 == (eot = p - (char *)iov->iov_base)) {
214 error = EOVERFLOW;
215 goto error;
216 }
217
218 if (n < maxbuf) {
219 if (!eof) {
220 if (n >= minbuf && lc != '\r') {
221 /*
222 * just continue as we're not splitting a
223 * \r\n pair
224 */
225 (void)0;
226 } else if (n > minbuf && lc == '\r') {
227 /*
228 * just exclude it. we might end up
229 * returning a trailing \r, but we know for
230 * a fact it's not part of a \r\n pair.
231 */
232 --eot;
233 } else if ((error = iov_addzu(&eot, eot, maxbuf - n))) {
234 goto error;
235 }
236 }
237 } else if (lc == '\r') {
238 if (n > minbuf) {
239 --eot; /* see comment ~10 lines above */
240 } else if ((error = iov_addzu(&eot, eot, 1))) {
241 goto error;
242 }
243 }
244
245 return eot;
246 error:
247 *_error = error;
248
249 return -1;
250 } /* iov_eot() */
251
252
iov_eol(const struct iovec * iov)253 static size_t iov_eol(const struct iovec *iov) {
254 const char *p, *pe;
255 size_t eol = 0;
256
257 p = iov->iov_base;
258 pe = p + iov->iov_len;
259
260 while (p < pe && (p = memchr(p, '\n', pe - p))) {
261 eol = ++p - (char *)iov->iov_base;
262 }
263
264 return (eol)? eol : iov->iov_len;
265 } /* iov_eol() */
266
267
268 /* strip \r from \r\n sequences */
iov_trimcr(struct iovec * iov,_Bool chomp)269 static size_t iov_trimcr(struct iovec *iov, _Bool chomp) {
270 char *p, *pe;
271
272 p = iov->iov_base;
273 pe = p + iov->iov_len;
274
275 if (chomp) {
276 if (pe - p >= 2 && pe[-1] == '\n' && pe[-2] == '\r')
277 *(--pe - 1) = '\n';
278 } else {
279 while (p < pe && (p = memchr(p, '\r', pe - p))) {
280 if (++p >= pe) {
281 break;
282 } else if (*p == '\n') {
283 memmove(p - 1, p, pe - p);
284 --pe;
285 }
286 }
287 }
288
289 return iov->iov_len = pe - (char *)iov->iov_base;
290 } /* iov_trimcr() */
291
292
293 /* strip \r?\n from \r?\n sequences */
iov_trimcrlf(struct iovec * iov,_Bool chomp)294 static size_t iov_trimcrlf(struct iovec *iov, _Bool chomp) {
295 char *sp, *p, *pe;
296
297 sp = iov->iov_base;
298 p = iov->iov_base;
299 pe = p + iov->iov_len;
300
301 if (chomp) {
302 if (p < pe && pe[-1] == '\n') {
303 --pe;
304
305 if (p < pe && pe[-1] == '\r')
306 --pe;
307 }
308 } else {
309 while (p < pe && (p = memchr(p, '\n', pe - p))) {
310 if (p > sp && p[-1] == '\r') {
311 ++p;
312 memmove(p - 2, p, pe - p);
313 pe -= 2;
314 } else {
315 memmove(p, p + 1, pe - p - 1);
316 --pe;
317 }
318 }
319 }
320
321 return iov->iov_len = pe - (char *)iov->iov_base;
322 } /* iov_trimcrlf() */
323
324
325 /*
326 * L U A S O C K E T R O U T I N E S
327 *
328 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
329
330 #define lso_error_t int
331 #define lso_nargs_t int
332
333 #define LSO_CLASS "CQS Socket"
334 #define LSO_INDEX 1
335 #define LSO_UPVALUES 1
336
337 #define LSO_MAXERRS 100
338
339 #define LSO_BUFSIZ 4096
340 #define LSO_MAXLINE 4096
341 #define LSO_INFSIZ ((size_t)-1)
342
343 #define LSO_LINEBUF 0x01
344 #define LSO_FULLBUF 0x02
345 #define LSO_NOBUF 0x04
346 #define LSO_ALLBUF (LSO_LINEBUF|LSO_FULLBUF|LSO_NOBUF)
347 #define LSO_TEXT 0x08
348 #define LSO_BINARY 0x10
349 #define LSO_AUTOFLUSH 0x20
350 #define LSO_PUSHBACK 0x40
351
352 #define LSO_INITMODE (LSO_LINEBUF|LSO_TEXT|LSO_AUTOFLUSH|LSO_PUSHBACK)
353 #define LSO_RDMASK (~(LSO_ALLBUF|LSO_AUTOFLUSH))
354 #define LSO_WRMASK (~LSO_PUSHBACK)
355
356 /*
357 * A placeholder until we make it optional. Some Microsoft services have
358 * buggy line buffering and will choke if, e.g., an SMTP command is
359 * fragmented across TCP packets.
360 */
361 #define LSO_DEFRAG 1
362
363 #if !defined __NetBSD__ || NETBSD_PREREQ(6,0)
364 #define LSO_NAN (NAN)
365 #else
366 #define LSO_NAN (__builtin_nan(""))
367 #endif
368
369 #define LSO_DO_FLUSH 0x01 /* flush output buffer */
370 #define LSO_DO_STARTTLS 0x02 /* initiate starttls */
371
372 struct luasocket {
373 int todo, done;
374
375 struct {
376 _Bool once;
377 struct so_starttls config;
378 } tls;
379
380 struct {
381 int mode;
382 size_t maxline;
383 size_t bufsiz;
384
385 struct fifo fifo;
386
387 _Bool eof;
388 _Bool eom;
389
390 int error;
391 size_t numerrs;
392 size_t maxerrs;
393 } ibuf;
394
395 struct {
396 int mode;
397 size_t maxline;
398 size_t bufsiz;
399
400 struct fifo fifo;
401
402 _Bool eof;
403 size_t eol;
404
405 int error;
406 size_t numerrs;
407 size_t maxerrs;
408 } obuf;
409
410 int type;
411 struct socket *socket;
412
413 cqs_ref_t onerror;
414
415 lua_State *mainthread;
416
417 double timeout;
418 }; /* struct luasocket */
419
420
421 static struct luasocket lso_initializer = {
422 .ibuf = { .mode = (LSO_RDMASK & LSO_INITMODE), .maxline = LSO_MAXLINE, .bufsiz = LSO_BUFSIZ, .maxerrs = LSO_MAXERRS },
423 .obuf = { .mode = (LSO_WRMASK & LSO_INITMODE), .maxline = LSO_MAXLINE, .bufsiz = LSO_BUFSIZ, .maxerrs = LSO_MAXERRS },
424 .type = SOCK_STREAM,
425 .onerror = LUA_NOREF,
426 .timeout = LSO_NAN,
427 };
428
429
lso_optsize(struct lua_State * L,int index,size_t def)430 static size_t lso_optsize(struct lua_State *L, int index, size_t def) {
431 lua_Number size;
432
433 if (lua_isnoneornil(L, index))
434 return def;
435
436 size = luaL_checknumber(L, index);
437
438 if (size < 0 || isinf(size))
439 return LSO_INFSIZ;
440
441 return (size > 0)? (size_t)size : def;
442 } /* lso_optsize() */
443
444
lso_checksize(struct lua_State * L,int index)445 static size_t lso_checksize(struct lua_State *L, int index) {
446 lua_Number size = luaL_checknumber(L, index);
447
448 if (size < 0 || isinf(size))
449 return LSO_INFSIZ;
450
451 return (size_t)size;
452 } /* lso_checksize() */
453
454
lso_pushsize(struct lua_State * L,size_t size)455 static void lso_pushsize(struct lua_State *L, size_t size) {
456 if (size == LSO_INFSIZ) {
457 lua_pushnumber(L, INFINITY);
458 } else {
459 lua_pushinteger(L, size);
460 }
461 } /* lso_pushsize() */
462
463
lso_tofileno(lua_State * L,int index)464 static int lso_tofileno(lua_State *L, int index) {
465 struct luasocket *so;
466 luaL_Stream *fh;
467
468 if (lua_isnumber(L, index)) {
469 return lua_tointeger(L, index);
470 } else if ((so = luaL_testudata(L, index, LSO_CLASS))) {
471 return so_peerfd(so->socket);
472 } else if ((fh = luaL_testudata(L, index, LUA_FILEHANDLE))) {
473 return (fh->f)? fileno(fh->f) : -1;
474 } else {
475 return -1;
476 }
477 } /* lso_tofileno() */
478
479
lso_getfield(lua_State * L,int index,const char * k)480 static _Bool lso_getfield(lua_State *L, int index, const char *k) {
481 lua_getfield(L, index, k);
482
483 if (lua_isnil(L, -1)) {
484 lua_pop(L, 1);
485
486 return 0;
487 } else {
488 return 1;
489 }
490 } /* lso_getfield() */
491
492
lso_rawgeti(lua_State * L,int index,int k)493 static _Bool lso_rawgeti(lua_State *L, int index, int k) {
494 lua_rawgeti(L, index, k);
495
496 if (lua_isnil(L, -1)) {
497 lua_pop(L, 1);
498
499 return 0;
500 } else {
501 return 1;
502 }
503 } /* lso_rawgeti() */
504
505
lso_altfield(lua_State * L,int index,...)506 static _Bool lso_altfield(lua_State *L, int index, ...) {
507 const char *k;
508 va_list ap;
509
510 va_start(ap, index);
511
512 while ((k = va_arg(ap, const char *))) {
513 if (lso_getfield(L, index, k))
514 break;
515 }
516
517 va_end(ap);
518
519 return !!k;
520 } /* lso_altfield() */
521
522 #define lso_altfield(...) lso_altfield(__VA_ARGS__, (const char *)0)
523
524
lso_popbool(lua_State * L)525 static _Bool lso_popbool(lua_State *L) {
526 _Bool val;
527 luaL_checktype(L, -1, LUA_TBOOLEAN);
528 val = lua_toboolean(L, -1);
529 lua_pop(L, 1);
530 return val;
531 } /* lso_popbool() */
532
533
lso_singleton(lua_State * L,const void * key,const void * init,size_t len)534 static void *lso_singleton(lua_State *L, const void *key, const void *init, size_t len) {
535 void *p;
536
537 lua_rawgetp(L, LUA_REGISTRYINDEX, key);
538 p = lua_touserdata(L, -1);
539 lua_pop(L, 1);
540
541 if (p)
542 return p;
543
544 p = lua_newuserdata(L, len);
545 if (init)
546 memcpy(p, init, len);
547 else
548 memset(p, 0, len);
549 lua_rawsetp(L, LUA_REGISTRYINDEX, key);
550
551 return p;
552 } /* lso_singleton() */
553
554
lso_checkperm(lua_State * L,int index)555 static mode_t lso_checkperm(lua_State *L, int index) {
556 const char *mode = luaL_checkstring(L, index);
557 mode_t perm = 0;
558
559 if (*mode >= '0' && *mode <= '9') {
560 perm = strtol(mode, NULL, 0);
561 } else {
562 int i = 9, flag, ch;
563
564 while ((ch = *mode++) && i > 0) {
565 if (ch == 'r' || ch == 'R')
566 flag = 04;
567 else if (ch == 'w' || ch == 'W')
568 flag = 02;
569 else if (ch == 'x' || ch == 'X')
570 flag = 01;
571 else if (ch == '-')
572 flag = 00;
573 else
574 continue;
575
576 perm |= (flag << (3 * (--i / 3)));
577 }
578 }
579
580 return perm;
581 } /* lso_checkperm() */
582
583
lso_checkopts(lua_State * L,int index)584 static struct so_options lso_checkopts(lua_State *L, int index) {
585 struct so_options opts = *so_opts();
586
587 /* TODO: Support explicit interface name via .if_name/.name */
588 if (lso_altfield(L, index, "bind", "sa_bind")) {
589 static const int regindex;
590 struct sockaddr *sa;
591 const char *addr = NULL;
592 size_t plen;
593 const char *path = NULL;
594 int port = -1, error;
595
596 if (lua_istable(L, -1)) {
597 if (lso_altfield(L, -1, "path", "sun_path") || lso_rawgeti(L, -1, 1)) {
598 path = luaL_checklstring(L, -1, &plen);
599 lua_pop(L, 1);
600 } else {
601 if (lso_altfield(L, -1, "addr", "address", "sin_addr", "sin6_addr") || lso_rawgeti(L, -1, 1)) {
602 addr = luaL_checkstring(L, -1);
603 lua_pop(L, 1);
604 }
605
606 if (lso_altfield(L, -1, "port", "sin_port", "sin6_port") || lso_rawgeti(L, -1, 2)) {
607 port = luaL_checkint(L, -1);
608 lua_pop(L, 1);
609 }
610 }
611 } else {
612 addr = luaL_checkstring(L, -1);
613 }
614
615 luaL_argcheck(L, path != NULL || addr != NULL, index, "no bind address specified");
616
617 if (path) {
618 sa = lso_singleton(L, CQS_UNIQUE_LIGHTUSERDATA_MASK(®index), NULL, sizeof(struct sockaddr_un));
619 sa->sa_family = AF_UNIX;
620 memcpy(((struct sockaddr_un*)sa)->sun_path, path, MIN(plen, sizeof(((struct sockaddr_un*)sa)->sun_path)));
621 } else {
622 sa = lso_singleton(L, CQS_UNIQUE_LIGHTUSERDATA_MASK(®index), NULL, sizeof(struct sockaddr_storage));
623 if (!sa_pton(sa, sizeof(struct sockaddr_storage), addr, NULL, &error))
624 luaL_argerror(L, index, lua_pushfstring(L, "%s: unable to parse bind address (%s)", addr, cqs_strerror(error)));
625
626 if (port >= 0)
627 *sa_port(sa, &(unsigned short){ 0 }, NULL) = htons((unsigned short)port);
628 }
629
630 opts.sa_bind = sa;
631
632 lua_pop(L, 1);
633 }
634
635 if (lso_altfield(L, index, "mode", "sun_mode")) {
636 opts.sun_mode = S_IFSOCK | lso_checkperm(L, -1);
637 lua_pop(L, 1);
638 }
639
640 if (lso_altfield(L, index, "mask", "sun_mask")) {
641 opts.sun_mask = S_IFSOCK | lso_checkperm(L, -1);
642 lua_pop(L, 1);
643 }
644
645 if (lso_altfield(L, index, "unlink", "sun_unlink"))
646 opts.sun_unlink = lso_popbool(L);
647
648 if (lso_altfield(L, index, "reuseaddr", "sin_reuseaddr"))
649 opts.sin_reuseaddr = lso_popbool(L);
650
651 if (lso_altfield(L, index, "reuseport", "sin_reuseport"))
652 opts.sin_reuseport = lso_popbool(L);
653
654 if (lso_altfield(L, index, "broadcast", "sin_broadcast"))
655 opts.sin_broadcast = lso_popbool(L);
656
657 if (lso_altfield(L, index, "nodelay", "sin_nodelay"))
658 opts.sin_nodelay = lso_popbool(L);
659
660 if (lso_altfield(L, index, "nopush", "sin_nopush"))
661 opts.sin_nopush = lso_popbool(L);
662
663 if (lso_altfield(L, index, "v6only", "sin_v6only"))
664 opts.sin_v6only = (lso_popbool(L))? SO_V6ONLY_ENABLE : SO_V6ONLY_DISABLE;
665
666 if (lso_altfield(L, index, "oobinline", "sin_oobinline"))
667 opts.sin_oobinline = lso_popbool(L);
668
669 if (lso_altfield(L, index, "nonblock", "fd_nonblock"))
670 opts.fd_nonblock = lso_popbool(L);
671
672 if (lso_altfield(L, index, "cloexec", "fd_cloexec"))
673 opts.fd_cloexec = lso_popbool(L);
674
675 if (lso_altfield(L, index, "nosigpipe", "fd_nosigpipe"))
676 opts.fd_nosigpipe = lso_popbool(L);
677
678 if (lso_altfield(L, index, "verify", "tls_verify"))
679 opts.tls_verify = lso_popbool(L);
680
681 if (lso_altfield(L, index, "sendname", "tls_sendname")) {
682 if (lua_isboolean(L, -1)) {
683 opts.tls_sendname = (lua_toboolean(L, -1))? SO_OPTS_TLS_HOSTNAME : NULL;
684 } else {
685 opts.tls_sendname = luaL_checkstring(L, -1);
686 }
687
688 lua_pop(L, 1);
689 }
690
691 if (lso_altfield(L, index, "time", "st_time"))
692 opts.st_time = lso_popbool(L);
693
694 return opts;
695 } /* lso_checkopts() */
696
697
lso_closefd(int * fd,void * arg)698 static int lso_closefd(int *fd, void *arg) {
699 struct luasocket *S = arg;
700
701 if (S->mainthread) {
702 cqs_cancelfd(S->mainthread, *fd);
703 cqs_closefd(fd);
704 }
705
706 return 0;
707 } /* lso_closefd() */
708
709
lso_testself(lua_State * L,int index)710 static struct luasocket *lso_testself(lua_State *L, int index) {
711 return cqs_testudata(L, index, LSO_INDEX);
712 } /* lso_testself() */
713
714
lso_checkvalid(lua_State * L,int index,struct luasocket * S)715 static struct luasocket *lso_checkvalid(lua_State *L, int index, struct luasocket *S) {
716 luaL_argcheck(L, !!S->socket, index, "socket closed");
717 return S;
718 } /* lso_checkvalid() */
719
720
lso_checkself(lua_State * L,int index)721 static struct luasocket *lso_checkself(lua_State *L, int index) {
722 return lso_checkvalid(L, index, cqs_checkudata(L, index, LSO_INDEX, LSO_CLASS));
723 } /* lso_checkself() */
724
725
lso_imode(const char * str,int init)726 static int lso_imode(const char *str, int init) {
727 int mode = init, ch;
728
729 while ((ch = *str++)) {
730 switch (ch) {
731 case 'n':
732 mode = LSO_NOBUF | (mode & ~LSO_ALLBUF);
733 break;
734 case 'l':
735 mode = LSO_LINEBUF | (mode & ~LSO_ALLBUF);
736 break;
737 case 'f':
738 mode = LSO_FULLBUF | (mode & ~LSO_ALLBUF);
739 break;
740 case 't':
741 mode = LSO_TEXT | (mode & ~LSO_BINARY);
742 break;
743 case 'b':
744 mode = LSO_BINARY | (mode & ~LSO_TEXT);
745 break;
746 case 'a':
747 mode |= LSO_AUTOFLUSH;
748 break;
749 case 'A':
750 mode &= ~LSO_AUTOFLUSH;
751 break;
752 case 'p':
753 mode |= LSO_PUSHBACK;
754 break;
755 case 'P':
756 mode &= ~LSO_PUSHBACK;
757 break;
758 } /* switch() */
759 } /* while() */
760
761 return mode;
762 } /* lso_imode() */
763
764
lso_pushmode(lua_State * L,int mode,int mask,_Bool libc)765 static void lso_pushmode(lua_State *L, int mode, int mask, _Bool libc) {
766 if (libc) {
767 if (mode & LSO_NOBUF)
768 lua_pushstring(L, "no");
769 else if (mode & LSO_LINEBUF)
770 lua_pushstring(L, "line");
771 else if (mode & LSO_FULLBUF)
772 lua_pushstring(L, "full");
773 else
774 lua_pushnil(L); /* XXX: shouldn't happen */
775 } else {
776 char flag[8], *p = flag;
777
778 if (mode & LSO_TEXT)
779 *p++ = 't';
780 else if (mode & LSO_BINARY)
781 *p++ = 'b';
782 else
783 *p++ = '-';
784
785 if (mode & LSO_NOBUF)
786 *p++ = 'n';
787 else if (mode & LSO_LINEBUF)
788 *p++ = 'l';
789 else if (mode & LSO_FULLBUF)
790 *p++ = 'f';
791 else
792 *p++ = '-';
793
794 if (mask & LSO_AUTOFLUSH)
795 *p++ = (mode & LSO_AUTOFLUSH)? 'a' : 'A';
796
797 if (mask & LSO_PUSHBACK)
798 *p++ = (mode & LSO_PUSHBACK)? 'p' : 'P';
799
800 lua_pushlstring(L, flag, p - flag);
801 }
802 } /* lso_pushmode() */
803
804
805 //static lso_nargs_t lso_throw(lua_State *L, struct luasocket *S, int error) {
806 // return luaL_error(L, "socket: %s", cqs_strerror(error));
807 //} /* lso_throw() */
808
809
lso_prototype(lua_State * L)810 static struct luasocket *lso_prototype(lua_State *L) {
811 static const int regindex;
812
813 return lso_singleton(L, CQS_UNIQUE_LIGHTUSERDATA_MASK(®index), &lso_initializer, sizeof lso_initializer);
814 } /* lso_prototype() */
815
816
lso_newsocket(lua_State * L,int type)817 static struct luasocket *lso_newsocket(lua_State *L, int type) {
818 struct luasocket *S;
819
820 S = lua_newuserdata(L, sizeof *S);
821 *S = *lso_prototype(L);
822
823 S->type = type;
824
825 fifo_init(&S->ibuf.fifo);
826 fifo_init(&S->obuf.fifo);
827
828 if (S->onerror != LUA_NOREF && S->onerror != LUA_REFNIL) {
829 cqs_getref(L, S->onerror);
830 S->onerror = LUA_NOREF;
831 cqs_ref(L, &S->onerror);
832 }
833
834 #if defined LUA_RIDX_MAINTHREAD
835 lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD);
836 S->mainthread = lua_tothread(L, -1);
837 lua_pop(L, 1);
838 #endif
839
840 luaL_getmetatable(L, LSO_CLASS);
841 lua_setmetatable(L, -2);
842
843 return S;
844 } /* lso_newsocket() */
845
846
lso_adjbuf(struct fifo * buf,size_t size)847 static lso_error_t lso_adjbuf(struct fifo *buf, size_t size) {
848 if (size == LSO_INFSIZ)
849 return 0;
850
851 return fifo_realloc(buf, size);
852 } /* lso_adjbuf() */
853
lso_adjbufs(struct luasocket * S)854 static lso_error_t lso_adjbufs(struct luasocket *S) {
855 int error;
856
857 if ((error = lso_adjbuf(&S->ibuf.fifo, S->ibuf.bufsiz)))
858 return error;
859
860 if ((error = lso_adjbuf(&S->obuf.fifo, S->obuf.bufsiz)))
861 return error;
862
863 return 0;
864 } /* lso_adjbufs() */
865
866
lso_prepsocket(struct luasocket * S)867 static lso_error_t lso_prepsocket(struct luasocket *S) {
868 return lso_adjbufs(S);
869 } /* lso_prepsocket() */
870
871
872 static lso_error_t lso_doflush(struct luasocket *, int);
873
lso_checktodo(struct luasocket * S)874 static lso_error_t lso_checktodo(struct luasocket *S) {
875 int todo, error;
876
877 while ((todo = (S->todo & ~S->done))) {
878 if (todo & LSO_DO_FLUSH) {
879 so_clear(S->socket);
880
881 if ((error = lso_doflush(S, LSO_NOBUF)))
882 return error;
883
884 S->done |= LSO_DO_FLUSH;
885 } else if (todo & LSO_DO_STARTTLS) {
886 so_clear(S->socket);
887
888 if (!S->tls.once) {
889 S->tls.once = 1;
890
891 if (S->ibuf.mode & LSO_PUSHBACK)
892 fifo_rvec(&S->ibuf.fifo, &S->tls.config.pushback, 1);
893
894 error = so_starttls(S->socket, &S->tls.config);
895
896 if (S->ibuf.mode & LSO_PUSHBACK) {
897 fifo_purge(&S->ibuf.fifo);
898 S->ibuf.eom = 0;
899 }
900 } else {
901 error = so_starttls(S->socket, NULL);
902 }
903
904 if (S->tls.config.instance) {
905 SSL_free(S->tls.config.instance);
906 S->tls.config.instance = NULL;
907 }
908
909 if (S->tls.config.context) {
910 SSL_CTX_free(S->tls.config.context);
911 S->tls.config.context = NULL;
912 }
913
914 if (error)
915 return error;
916
917 S->done |= LSO_DO_STARTTLS;
918 }
919 }
920
921 return 0;
922 } /* lso_checktodo() */
923
924
lso_connect2(lua_State * L)925 static lso_nargs_t lso_connect2(lua_State *L) {
926 const char *host NOTUSED = NULL, *port NOTUSED = NULL;
927 const char *path = NULL;
928 struct so_options opts;
929 struct luasocket *S;
930 size_t plen;
931 int family, type, error;
932
933 if (lua_istable(L, 1)) {
934 opts = lso_checkopts(L, 1);
935
936 lua_getfield(L, 1, "family");
937 family = luaL_optinteger(L, -1, AF_UNSPEC);
938 lua_pop(L, 1);
939
940 lua_getfield(L, 1, "type");
941 type = luaL_optinteger(L, -1, SOCK_STREAM);
942 lua_pop(L, 1);
943
944 if (lso_getfield(L, 1, "path")) {
945 path = luaL_checklstring(L, -1, &plen);
946 family = AF_UNIX;
947 } else {
948 lua_getfield(L, 1, "host");
949 host = luaL_checkstring(L, -1);
950 lua_getfield(L, 1, "port");
951 port = luaL_checkstring(L, -1);
952 }
953 } else {
954 opts = *so_opts();
955 host = luaL_checkstring(L, 1);
956 port = luaL_checkstring(L, 2);
957 family = luaL_optinteger(L, 3, AF_UNSPEC);
958 type = luaL_optinteger(L, 4, SOCK_STREAM);
959 }
960
961 S = lso_newsocket(L, type);
962
963 opts.fd_close.arg = S;
964 opts.fd_close.cb = &lso_closefd;
965
966 if (path) {
967 struct sockaddr_un sun;
968
969 memset(&sun, 0, sizeof sun);
970 sun.sun_family = AF_UNIX;
971 memcpy(sun.sun_path, path, MIN(plen, sizeof sun.sun_path));
972
973 if (!(S->socket = so_dial((struct sockaddr *)&sun, type, &opts, &error)))
974 goto error;
975 } else {
976 if (!(S->socket = so_open(host, port, 0, family, type, &opts, &error)))
977 goto error;
978 }
979
980 if ((error = lso_prepsocket(S)))
981 goto error;
982
983 (void)so_connect(S->socket);
984
985 return 1;
986 error:
987 lua_pushnil(L);
988 lua_pushinteger(L, error);
989
990 return 2;
991 } /* lso_connect2() */
992
993
lso_connect1(lua_State * L)994 static lso_nargs_t lso_connect1(lua_State *L) {
995 struct luasocket *S = lso_checkself(L, 1);
996 int error;
997
998 so_clear(S->socket);
999
1000 if (!(error = so_connect(S->socket))) {
1001 lua_pushvalue(L, 1);
1002
1003 return 1;
1004 } else {
1005 lua_pushnil(L);
1006 lua_pushinteger(L, error);
1007
1008 return 2;
1009 }
1010 } /* lso_connect1() */
1011
1012
lso_listen2(lua_State * L)1013 static lso_nargs_t lso_listen2(lua_State *L) {
1014 const char *host NOTUSED = NULL, *port NOTUSED = NULL;
1015 const char *path = NULL;
1016 struct so_options opts;
1017 struct luasocket *S;
1018 size_t plen;
1019 int family, type, error;
1020
1021 if (lua_istable(L, 1)) {
1022 opts = lso_checkopts(L, 1);
1023
1024 lua_getfield(L, 1, "family");
1025 family = luaL_optinteger(L, -1, AF_UNSPEC);
1026 lua_pop(L, 1);
1027
1028 lua_getfield(L, 1, "type");
1029 type = luaL_optinteger(L, -1, SOCK_STREAM);
1030 lua_pop(L, 1);
1031
1032 if (lso_getfield(L, 1, "path")) {
1033 path = luaL_checklstring(L, -1, &plen);
1034 family = AF_UNIX;
1035 } else {
1036 lua_getfield(L, 1, "host");
1037 host = luaL_checkstring(L, -1);
1038 lua_getfield(L, 1, "port");
1039 port = luaL_checkstring(L, -1);
1040 }
1041 } else {
1042 opts = *so_opts();
1043 host = luaL_checkstring(L, 1);
1044 port = luaL_checkstring(L, 2);
1045 family = luaL_optinteger(L, 3, AF_UNSPEC);
1046 type = luaL_optinteger(L, 4, SOCK_STREAM);
1047 }
1048
1049 S = lso_newsocket(L, type);
1050
1051 opts.fd_close.arg = S;
1052 opts.fd_close.cb = &lso_closefd;
1053
1054 if (path) {
1055 struct sockaddr_un sun;
1056
1057 memset(&sun, 0, sizeof sun);
1058 sun.sun_family = AF_UNIX;
1059 memcpy(sun.sun_path, path, MIN(plen, sizeof sun.sun_path));
1060
1061 if (!(S->socket = so_dial((struct sockaddr *)&sun, type, &opts, &error)))
1062 goto error;
1063 } else {
1064 if (!(S->socket = so_open(host, port, 0, family, type, &opts, &error)))
1065 goto error;
1066 }
1067
1068 if ((error = lso_prepsocket(S)))
1069 goto error;
1070
1071 (void)so_listen(S->socket);
1072
1073 return 1;
1074 error:
1075 lua_pushnil(L);
1076 lua_pushinteger(L, error);
1077
1078 return 2;
1079 } /* lso_listen2() */
1080
1081
lso_listen1(lua_State * L)1082 static lso_nargs_t lso_listen1(lua_State *L) {
1083 struct luasocket *S = lso_checkself(L, 1);
1084 int error;
1085
1086 so_clear(S->socket);
1087
1088 if (!(error = so_listen(S->socket))) {
1089 lua_pushvalue(L, 1);
1090
1091 return 1;
1092 } else {
1093 lua_pushnil(L);
1094 lua_pushinteger(L, error);
1095
1096 return 2;
1097 }
1098 } /* lso_listen1() */
1099
1100
1101 /* luasec compat */
1102 #define LSEC_MODE_INVALID 0
1103 #define LSEC_MODE_SERVER 1
1104 #define LSEC_MODE_CLIENT 2
1105
1106 typedef struct {
1107 SSL_CTX *context;
1108 lua_State *L;
1109 DH *dh_param;
1110 int mode;
1111 } lsec_context;
1112
1113
lso_starttls(lua_State * L)1114 static lso_nargs_t lso_starttls(lua_State *L) {
1115 struct luasocket *S = lso_checkself(L, 1);
1116 SSL_CTX **ctx = NULL;
1117 SSL **ssl = NULL;
1118 int error;
1119
1120 /*
1121 * NB: short-circuit if we've already started so we don't
1122 * unnecessarily check for or take a reference to the SSL_CTX
1123 * object.
1124 */
1125 if ((S->todo & LSO_DO_STARTTLS))
1126 goto check;
1127
1128 if ((ssl = luaL_testudata(L, 2, "SSL*"))) {
1129 /* accept-mode check handled by so_starttls() */
1130 } else if ((ctx = luaL_testudata(L, 2, "SSL_CTX*"))) {
1131 /* accept-mode check handled by so_starttls() */
1132 } else if ((ctx = luaL_testudata(L, 2, "SSL:Context"))) { /* luasec compatability */
1133 luaL_argcheck(L, ((lsec_context*)ctx)->mode != LSEC_MODE_INVALID, 2, "invalid mode");
1134 so_setbool(&S->tls.config.accept, ((((lsec_context*)ctx)->mode) == LSEC_MODE_SERVER));
1135 }
1136
1137 if (ssl && *ssl && *ssl != S->tls.config.instance) {
1138 if (S->tls.config.instance)
1139 SSL_free(S->tls.config.instance);
1140
1141 SSL_up_ref(*ssl);
1142 S->tls.config.instance = *ssl;
1143 }
1144
1145 if (ctx && *ctx && *ctx != S->tls.config.context) {
1146 if (S->tls.config.context)
1147 SSL_CTX_free(S->tls.config.context);
1148
1149 SSL_CTX_up_ref(*ctx);
1150 S->tls.config.context = *ctx;
1151 }
1152
1153 S->todo |= LSO_DO_STARTTLS;
1154
1155 if (S->obuf.mode & LSO_AUTOFLUSH)
1156 S->todo |= LSO_DO_FLUSH;
1157 check:
1158 if ((error = lso_checktodo(S)))
1159 goto error;
1160
1161 lua_pushvalue(L, 1);
1162
1163 return 1;
1164 error:
1165 lua_pushnil(L);
1166 lua_pushinteger(L, error);
1167
1168 return 2;
1169 } /* lso_starttls() */
1170
1171
lso_checktls(lua_State * L)1172 static lso_nargs_t lso_checktls(lua_State *L) {
1173 struct luasocket *S = lso_checkself(L, 1);
1174 SSL **ssl;
1175
1176 ssl = lua_newuserdata(L, sizeof *ssl);
1177
1178 if (!(*ssl = so_checktls(S->socket)))
1179 return 0;
1180
1181 luaL_getmetatable(L, "SSL*");
1182
1183 if (lua_isnil(L, -1))
1184 return 0;
1185
1186 lua_setmetatable(L, -2);
1187
1188 SSL_up_ref(*ssl);
1189
1190 return 1;
1191 } /* lso_checktls() */
1192
1193
cqs_socket_fdopen(lua_State * L,int fd,const struct so_options * _opts)1194 lso_error_t cqs_socket_fdopen(lua_State *L, int fd, const struct so_options *_opts) {
1195 struct so_options opts = *((_opts)? _opts : so_opts());
1196 struct luasocket *S;
1197 int type = SOCK_STREAM, error;
1198
1199 if (0 != getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &(socklen_t){ sizeof type })) {
1200 switch (errno) {
1201 case ENOTSOCK:
1202 case EOPNOTSUPP:
1203 break;
1204 default:
1205 goto syerr;
1206 }
1207 }
1208
1209 S = lso_newsocket(L, type);
1210
1211 if ((error = lso_prepsocket(S)))
1212 goto error;
1213
1214 opts.fd_close.arg = S;
1215 opts.fd_close.cb = &lso_closefd;
1216
1217 if (!(S->socket = so_fdopen(fd, &opts, &error)))
1218 goto error;
1219
1220 return 0;
1221 syerr:
1222 error = errno;
1223 error:
1224 lua_pop(L, 1);
1225
1226 return error;
1227 } /* cqs_socket_fdopen() */
1228
1229
lso_dup(lua_State * L)1230 static lso_nargs_t lso_dup(lua_State *L) {
1231 struct so_options opts;
1232 int ofd, fd = -1, error;
1233
1234 if (lua_istable(L, 1)) {
1235 opts = lso_checkopts(L, 1);
1236
1237 if (!lso_altfield(L, 1, "fd", "file", "socket"))
1238 lua_rawgeti(L, 1, 1);
1239
1240 ofd = lso_tofileno(L, -1);
1241
1242 lua_pop(L, 1);
1243 } else {
1244 opts = *so_opts();
1245 ofd = lso_tofileno(L, 1);
1246 }
1247
1248 if (ofd < 0)
1249 goto badfd;
1250
1251 #if defined F_DUPFD_CLOEXEC
1252 if (-1 == (fd = fcntl(ofd, F_DUPFD_CLOEXEC, 0)))
1253 goto syerr;
1254 #else
1255 if (-1 == (fd = dup(ofd)))
1256 goto syerr;
1257 #endif
1258
1259 if ((error = cqs_socket_fdopen(L, fd, &opts)))
1260 goto error;
1261
1262 return 1;
1263 badfd:
1264 error = EBADF;
1265 goto error;
1266 syerr:
1267 error = errno;
1268 error:
1269 cqs_closefd(&fd);
1270
1271 lua_pushnil(L);
1272 lua_pushinteger(L, error);
1273
1274 return 2;
1275 } /* lso_dup() */
1276
1277
1278 /*
1279 * NOTE: Only permit integer descriptors to mitigate the risk that we wrap a
1280 * descriptor still owned by a GC-able object. Cf. socket.dup.
1281 */
lso_fdopen(lua_State * L)1282 static lso_nargs_t lso_fdopen(lua_State *L) {
1283 struct so_options opts;
1284 int fd, error;
1285
1286 if (lua_istable(L, 1)) {
1287 opts = lso_checkopts(L, 1);
1288
1289 if (lso_altfield(L, 1, "fd")) {
1290 fd = luaL_checkint(L, -1);
1291 } else {
1292 lua_rawgeti(L, 1, 1);
1293 fd = luaL_checkint(L, -1);
1294 }
1295
1296 lua_pop(L, 1);
1297 } else {
1298 opts = *so_opts();
1299 fd = luaL_checkint(L, 1);
1300 }
1301
1302 if (fd < 0)
1303 goto badfd;
1304
1305 if ((error = cqs_socket_fdopen(L, fd, &opts)))
1306 goto error;
1307
1308 return 1;
1309 badfd:
1310 error = EBADF;
1311 goto error;
1312 error:
1313 lua_pushnil(L);
1314 lua_pushinteger(L, error);
1315
1316 return 2;
1317 } /* lso_fdopen() */
1318
1319
lso_pair(lua_State * L)1320 static lso_nargs_t lso_pair(lua_State *L) {
1321 struct luasocket *a = NULL, *b = NULL;
1322 struct so_options opts;
1323 int fd[2] = { -1, -1 };
1324 int type, error;
1325
1326 if (lua_istable(L, 1)) {
1327 opts = lso_checkopts(L, 1);
1328
1329 lua_getfield(L, 1, "type");
1330 type = luaL_optinteger(L, -1, SOCK_STREAM);
1331 lua_pop(L, 1);
1332 } else {
1333 opts = *so_opts();
1334 type = luaL_optinteger(L, 1, SOCK_STREAM);
1335 }
1336
1337 a = lso_newsocket(L, type);
1338 b = lso_newsocket(L, type);
1339
1340 #if defined SOCK_CLOEXEC
1341 if (0 != socketpair(AF_UNIX, type|SOCK_CLOEXEC, PF_UNSPEC, fd))
1342 goto syerr;
1343 #else
1344 if (0 != socketpair(AF_UNIX, type, PF_UNSPEC, fd))
1345 goto syerr;
1346 #endif
1347
1348 opts.fd_close.arg = a;
1349 opts.fd_close.cb = &lso_closefd;
1350
1351 if (!(a->socket = so_fdopen(fd[0], &opts, &error)))
1352 goto error;
1353
1354 fd[0] = -1;
1355
1356 if ((error = lso_prepsocket(a)))
1357 goto error;
1358
1359 opts.fd_close.arg = b;
1360 opts.fd_close.cb = &lso_closefd;
1361
1362 if (!(b->socket = so_fdopen(fd[1], &opts, &error)))
1363 goto error;
1364
1365 fd[1] = -1;
1366
1367 if ((error = lso_prepsocket(b)))
1368 goto error;
1369
1370 return 2;
1371 syerr:
1372 error = errno;
1373 error:
1374 cqs_closefd(&fd[0]);
1375 cqs_closefd(&fd[1]);
1376
1377 lua_pushnil(L);
1378 lua_pushnil(L);
1379 lua_pushinteger(L, error);
1380
1381 return 3;
1382 } /* lso_pair() */
1383
1384
lso_checkvbuf(struct lua_State * L,int index)1385 static int lso_checkvbuf(struct lua_State *L, int index) {
1386 switch (luaL_checkoption(L, index, "line", (const char *[]){ "line", "full", "nobuf", "no", NULL })) {
1387 case 0: /* "line" */
1388 return LSO_LINEBUF;
1389 case 1: /* "full" */
1390 return LSO_FULLBUF;
1391 case 2: /* "nobuf" */
1392 /* FALL THROUGH */
1393 case 3: /* "no" */
1394 /* FALL THROUGH */
1395 default:
1396 return LSO_NOBUF;
1397 }
1398 } /* lso_checkvbuf() */
1399
1400
lso_setvbuf_(struct lua_State * L,struct luasocket * S,int modeidx,int bufidx)1401 static lso_nargs_t lso_setvbuf_(struct lua_State *L, struct luasocket *S, int modeidx, int bufidx) {
1402 lso_pushmode(L, S->obuf.mode, LSO_WRMASK, 1);
1403 lua_pushinteger(L, S->obuf.bufsiz);
1404
1405 S->obuf.mode = lso_checkvbuf(L, modeidx) | (S->obuf.mode & ~LSO_ALLBUF);
1406
1407 if (S->obuf.mode & (LSO_LINEBUF|LSO_FULLBUF))
1408 S->obuf.bufsiz = lso_optsize(L, bufidx, LSO_BUFSIZ);
1409
1410 return 2;
1411 } /* lso_setvbuf_() */
1412
1413
lso_setvbuf2(struct lua_State * L)1414 static lso_nargs_t lso_setvbuf2(struct lua_State *L) {
1415 lua_settop(L, 2);
1416
1417 return lso_setvbuf_(L, lso_prototype(L), 1, 2);
1418 } /* lso_setvbuf2() */
1419
1420
lso_setvbuf3(struct lua_State * L)1421 static lso_nargs_t lso_setvbuf3(struct lua_State *L) {
1422 lua_settop(L, 3);
1423
1424 return lso_setvbuf_(L, lso_checkself(L, 1), 2, 3);
1425 } /* lso_setvbuf3() */
1426
1427
lso_setmode_(struct lua_State * L,struct luasocket * S,int ridx,int widx)1428 static lso_nargs_t lso_setmode_(struct lua_State *L, struct luasocket *S, int ridx, int widx) {
1429 lso_pushmode(L, S->ibuf.mode, LSO_RDMASK, 0);
1430 lso_pushmode(L, S->obuf.mode, LSO_WRMASK, 0);
1431
1432 if (!lua_isnil(L, ridx))
1433 S->ibuf.mode = LSO_RDMASK & lso_imode(luaL_checkstring(L, ridx), LSO_INITMODE);
1434
1435 if (!lua_isnil(L, widx))
1436 S->obuf.mode = LSO_WRMASK & lso_imode(luaL_checkstring(L, widx), LSO_INITMODE);
1437
1438 return 2;
1439 } /* lso_setmode_() */
1440
1441
lso_setmode2(struct lua_State * L)1442 static lso_nargs_t lso_setmode2(struct lua_State *L) {
1443 lua_settop(L, 2);
1444
1445 return lso_setmode_(L, lso_prototype(L), 1, 2);
1446 } /* lso_setmode2() */
1447
1448
lso_setmode3(struct lua_State * L)1449 static lso_nargs_t lso_setmode3(struct lua_State *L) {
1450 lua_settop(L, 3);
1451
1452 return lso_setmode_(L, lso_checkself(L, 1), 2, 3);
1453 } /* lso_setmode3() */
1454
1455
lso_setbufsiz_(struct lua_State * L,struct luasocket * S,int ridx,int widx)1456 static lso_nargs_t lso_setbufsiz_(struct lua_State *L, struct luasocket *S, int ridx, int widx) {
1457 lso_pushsize(L, S->ibuf.bufsiz);
1458 lso_pushsize(L, S->obuf.bufsiz);
1459
1460 S->ibuf.bufsiz = lso_optsize(L, ridx, S->ibuf.bufsiz);
1461 S->obuf.bufsiz = lso_optsize(L, widx, S->obuf.bufsiz);
1462
1463 return 2;
1464 } /* lso_setbufsiz_() */
1465
1466
lso_setbufsiz2(struct lua_State * L)1467 static lso_nargs_t lso_setbufsiz2(struct lua_State *L) {
1468 lua_settop(L, 2);
1469
1470 return lso_setbufsiz_(L, lso_prototype(L), 1, 2);
1471 } /* lso_setbufsiz2() */
1472
1473
lso_setbufsiz3(struct lua_State * L)1474 static lso_nargs_t lso_setbufsiz3(struct lua_State *L) {
1475 struct luasocket *S = lso_checkself(L, 1);
1476 int n, error;
1477
1478 lua_settop(L, 3);
1479
1480 n = lso_setbufsiz_(L, S, 2, 3);
1481
1482 if ((error = lso_adjbufs(S)))
1483 goto error;
1484
1485 return n;
1486 error:
1487 lua_pushnil(L);
1488 lua_pushnil(L);
1489 lua_pushinteger(L, error);
1490
1491 return 3;
1492 } /* lso_setbufsiz3() */
1493
1494
lso_setmaxline_(struct lua_State * L,struct luasocket * S,int ridx,int widx)1495 static lso_nargs_t lso_setmaxline_(struct lua_State *L, struct luasocket *S, int ridx, int widx) {
1496 lso_pushsize(L, S->ibuf.maxline);
1497 lso_pushsize(L, S->obuf.maxline);
1498
1499 S->ibuf.maxline = lso_optsize(L, ridx, S->ibuf.maxline);
1500 S->obuf.maxline = lso_optsize(L, widx, S->obuf.maxline);
1501
1502 return 2;
1503 } /* lso_setmaxline_() */
1504
1505
lso_setmaxline2(struct lua_State * L)1506 static lso_nargs_t lso_setmaxline2(struct lua_State *L) {
1507 lua_settop(L, 2);
1508
1509 return lso_setmaxline_(L, lso_prototype(L), 1, 2);
1510 } /* lso_setmaxline2() */
1511
1512
lso_setmaxline3(struct lua_State * L)1513 static lso_nargs_t lso_setmaxline3(struct lua_State *L) {
1514 lua_settop(L, 3);
1515
1516 return lso_setmaxline_(L, lso_checkself(L, 1), 2, 3);
1517 } /* lso_setmaxline3() */
1518
1519
lso_settimeout_(struct lua_State * L,struct luasocket * S,int index)1520 static lso_nargs_t lso_settimeout_(struct lua_State *L, struct luasocket *S, int index) {
1521 double timeout;
1522
1523 if (isnormal(S->timeout) || S->timeout == 0) {
1524 lua_pushnumber(L, S->timeout);
1525 } else {
1526 lua_pushnil(L);
1527 }
1528
1529 timeout = luaL_optnumber(L, index, NAN);
1530
1531 S->timeout = (isnormal(timeout) || timeout == 0)? timeout : NAN;
1532
1533 return 1;
1534 } /* lso_settimeout_() */
1535
1536
lso_settimeout1(struct lua_State * L)1537 static lso_nargs_t lso_settimeout1(struct lua_State *L) {
1538 lua_settop(L, 1);
1539
1540 return lso_settimeout_(L, lso_prototype(L), 1);
1541 } /* lso_settimeout1() */
1542
1543
lso_settimeout2(struct lua_State * L)1544 static lso_nargs_t lso_settimeout2(struct lua_State *L) {
1545 lua_settop(L, 2);
1546
1547 return lso_settimeout_(L, lso_checkself(L, 1), 2);
1548 } /* lso_settimeout2() */
1549
1550
lso_setmaxerrs_(struct lua_State * L,struct luasocket * S,int index)1551 static lso_nargs_t lso_setmaxerrs_(struct lua_State *L, struct luasocket *S, int index) {
1552 const char *what = "rw";
1553 int nret = 0;
1554
1555 if (lua_type(L, index) == LUA_TSTRING) {
1556 what = luaL_checkstring(L, index);
1557 index++;
1558 }
1559
1560 for (; *what; what++) {
1561 switch (*what) {
1562 case 'r':
1563 lua_pushinteger(L, S->ibuf.maxerrs);
1564 nret++;
1565
1566 S->ibuf.maxerrs = luaL_optunsigned(L, index, S->ibuf.maxerrs);
1567
1568 break;
1569 case 'w':
1570 lua_pushinteger(L, S->obuf.maxerrs);
1571 nret++;
1572
1573 S->obuf.maxerrs = luaL_optunsigned(L, index, S->obuf.maxerrs);
1574
1575 break;
1576 default:
1577 return luaL_argerror(L, 1, lua_pushfstring(L, "%s: %c: only `r' or `w' accepted", what, *what));
1578 }
1579 }
1580
1581 return nret;
1582 } /* lso_setmaxerrs_() */
1583
1584
lso_setmaxerrs1(struct lua_State * L)1585 static lso_nargs_t lso_setmaxerrs1(struct lua_State *L) {
1586 return lso_setmaxerrs_(L, lso_prototype(L), 1);
1587 } /* lso_setmaxerrs1() */
1588
1589
lso_setmaxerrs2(struct lua_State * L)1590 static lso_nargs_t lso_setmaxerrs2(struct lua_State *L) {
1591 return lso_setmaxerrs_(L, lso_checkself(L, 1), 2);
1592 } /* lso_setmaxerrs2() */
1593
1594
lso_onerror_(struct lua_State * L,struct luasocket * S,int fidx)1595 static lso_nargs_t lso_onerror_(struct lua_State *L, struct luasocket *S, int fidx) {
1596 cqs_getref(L, S->onerror);
1597
1598 if (lua_gettop(L) > fidx) {
1599 if (!lua_isnil(L, fidx))
1600 luaL_checktype(L, fidx, LUA_TFUNCTION);
1601 lua_pushvalue(L, fidx);
1602 cqs_ref(L, &S->onerror);
1603 }
1604
1605 return 1;
1606 } /* lso_onerror_() */
1607
1608
lso_onerror1(struct lua_State * L)1609 static lso_nargs_t lso_onerror1(struct lua_State *L) {
1610 return lso_onerror_(L, lso_prototype(L), 1);
1611 } /* lso_onerror1() */
1612
1613
lso_onerror2(struct lua_State * L)1614 static lso_nargs_t lso_onerror2(struct lua_State *L) {
1615 return lso_onerror_(L, lso_checkself(L, 1), 2);
1616 } /* lso_onerror2() */
1617
1618
lso_pusherror(struct lua_State * L,int error)1619 static void lso_pusherror(struct lua_State *L, int error) {
1620 if (error)
1621 lua_pushinteger(L, error);
1622 else
1623 lua_pushnil(L);
1624 } /* lso_pusherror() */
1625
1626
lso_seterror_(struct lua_State * L,struct luasocket * S,const char * what,int error)1627 static lso_nargs_t lso_seterror_(struct lua_State *L, struct luasocket *S, const char *what, int error) {
1628 int nret = 0;
1629
1630 for (; *what; what++) {
1631 switch (*what) {
1632 case 'r':
1633 lso_pusherror(L, S->ibuf.error);
1634 nret++;
1635
1636 if (!(S->ibuf.error = error))
1637 S->ibuf.numerrs = 0;
1638
1639 break;
1640 case 'w':
1641 lso_pusherror(L, S->obuf.error);
1642 nret++;
1643
1644 if (!(S->obuf.error = error))
1645 S->obuf.numerrs = 0;
1646
1647 break;
1648 default:
1649 return luaL_argerror(L, 2, lua_pushfstring(L, "%s: %c: only `r' or `w' accepted", what, *what));
1650 } /* switch() */
1651 } /* for() */
1652
1653 return nret;
1654 } /* lso_seterror_() */
1655
1656
lso_seterror(struct lua_State * L)1657 static lso_nargs_t lso_seterror(struct lua_State *L) {
1658 struct luasocket *S = lso_checkself(L, 1);
1659 const char *what = luaL_checkstring(L, 2);
1660 int error = luaL_optint(L, 3, 0);
1661
1662 return lso_seterror_(L, S, what, error);
1663 } /* lso_seterror() */
1664
1665
lso_error(struct lua_State * L)1666 static lso_nargs_t lso_error(struct lua_State *L) {
1667 struct luasocket *S = lso_checkself(L, 1);
1668 const char *what = luaL_optstring(L, 2, "rw");
1669 int nret = 0;
1670
1671 for (; *what; what++) {
1672 switch (*what) {
1673 case 'r':
1674 lso_pusherror(L, S->ibuf.error);
1675 nret++;
1676
1677 break;
1678 case 'w':
1679 lso_pusherror(L, S->obuf.error);
1680 nret++;
1681
1682 break;
1683 default:
1684 return luaL_argerror(L, 2, lua_pushfstring(L, "%s: %c: only `r' or `w' accepted", what, *what));
1685 } /* switch() */
1686 } /* for() */
1687
1688 return nret;
1689 } /* lso_error() */
1690
1691
lso_clearerr(struct lua_State * L)1692 static lso_nargs_t lso_clearerr(struct lua_State *L) {
1693 struct luasocket *S = lso_checkself(L, 1);
1694 const char *what = luaL_optstring(L, 2, "rw");
1695
1696 return lso_seterror_(L, S, what, 0);
1697 } /* lso_clearerr() */
1698
1699
lso_fill(struct luasocket * S,size_t limit)1700 static lso_error_t lso_fill(struct luasocket *S, size_t limit) {
1701 struct iovec iov;
1702 size_t prepbuf, count;
1703 int error;
1704
1705 if (S->ibuf.eom && fifo_rlen(&S->ibuf.fifo) > 0)
1706 return 0;
1707
1708 prepbuf = (S->type == SOCK_DGRAM)? (SO_MIN(limit, 65536)) : 1;
1709
1710 while (fifo_rlen(&S->ibuf.fifo) < limit) {
1711 if ((error = fifo_wbuf(&S->ibuf.fifo, &iov, prepbuf)))
1712 return error;
1713
1714 if ((count = so_read(S->socket, iov.iov_base, iov.iov_len, &error))) {
1715 fifo_update(&S->ibuf.fifo, count);
1716
1717 if (S->type == SOCK_DGRAM || S->type == SOCK_SEQPACKET) {
1718 S->ibuf.eom = 1;
1719
1720 return 0;
1721 }
1722 } else {
1723 if (error == EPIPE)
1724 S->ibuf.eof = 1;
1725
1726 return error;
1727 }
1728 }
1729
1730 return 0;
1731 } /* lso_fill() */
1732
1733
lso_nomore(struct luasocket * S,size_t limit)1734 static _Bool lso_nomore(struct luasocket *S, size_t limit) {
1735 return S->ibuf.eof || S->ibuf.eom || fifo_rlen(&S->ibuf.fifo) >= limit;
1736 } /* lso_nomore() */
1737
1738
lso_asserterror(int error)1739 static lso_error_t lso_asserterror(int error) {
1740 return (error)? error : EFAULT;
1741 } /* lso_asserterror() */
1742
1743
lso_getline(struct luasocket * S,struct iovec * iov)1744 static lso_error_t lso_getline(struct luasocket *S, struct iovec *iov) {
1745 int error;
1746
1747 while (!fifo_lvec(&S->ibuf.fifo, iov)) {
1748 error = lso_fill(S, S->ibuf.maxline);
1749
1750 if (fifo_lvec(&S->ibuf.fifo, iov))
1751 break;
1752
1753 if (fifo_rlen(&S->ibuf.fifo) > 0 && lso_nomore(S, S->ibuf.maxline)) {
1754 fifo_slice(&S->ibuf.fifo, iov, 0, S->ibuf.maxline);
1755
1756 break;
1757 }
1758
1759 return lso_asserterror(error);
1760 }
1761
1762 iov->iov_len = MIN(iov->iov_len, S->ibuf.maxline);
1763
1764 return 0;
1765 } /* lso_getline() */
1766
1767
lso_getheader(struct luasocket * S,struct iovec * iov)1768 static lso_error_t lso_getheader(struct luasocket *S, struct iovec *iov) {
1769 size_t eoh;
1770 int error;
1771
1772 fifo_slice(&S->ibuf.fifo, iov, 0, S->ibuf.maxline);
1773
1774 if ((size_t)-1 == (eoh = iov_eoh(iov, lso_nomore(S, S->ibuf.maxline), 0, &error)))
1775 goto error;
1776
1777 if (!eoh || eoh > iov->iov_len) {
1778 error = lso_fill(S, S->ibuf.maxline);
1779
1780 fifo_slice(&S->ibuf.fifo, iov, 0, S->ibuf.maxline);
1781
1782 if ((size_t)-1 == (eoh = iov_eoh(iov, lso_nomore(S, S->ibuf.maxline), 0, &error)))
1783 goto error;
1784 else if (!eoh)
1785 goto nomore;
1786 else if (eoh > iov->iov_len)
1787 goto error; /* lso_fill should have returned error */
1788 }
1789
1790 iov->iov_len = eoh;
1791
1792 return 0;
1793 nomore:
1794 iov->iov_len = 0;
1795
1796 return 0;
1797 error:
1798 return lso_asserterror(error);
1799 } /* lso_getheader() */
1800
1801
lso_getbody(struct luasocket * S,struct iovec * iov,int * eom,const char * eob,size_t eoblen,int mode)1802 static lso_error_t lso_getbody(struct luasocket *S, struct iovec *iov, int *eom, const char *eob, size_t eoblen, int mode) {
1803 size_t bufsiz, maxbuf, n;
1804 int error;
1805
1806 bufsiz = (mode & LSO_TEXT)? MAX(S->ibuf.bufsiz, S->ibuf.maxline) : S->ibuf.bufsiz;
1807 bufsiz = MAX(bufsiz, 2); /* see comment in text-mode handling below wrt >=2 */
1808
1809 /*
1810 * Adjust window. We need at least 1 + "\r\n" + eoblen to make
1811 * forward progress. But we actually want to return bufsiz-sized
1812 * intermediate chunks. So we want a temporary buffer of bufsiz +
1813 * "\r\n" + eoblen.
1814 */
1815 if ((error = cqs_addzu(&maxbuf, bufsiz, 2)))
1816 return error;
1817 if ((error = cqs_addzu(&maxbuf, maxbuf, eoblen)))
1818 return error;
1819
1820 error = lso_fill(S, maxbuf);
1821
1822 fifo_slice(&S->ibuf.fifo, iov, 0, maxbuf);
1823
1824 if ((n = iov_eob(iov, eob, eoblen))) {
1825 iov->iov_len = n - eoblen; /* n >= eoblen */
1826
1827 *eom = 1;
1828 } else if (iov->iov_len >= maxbuf) {
1829 /*
1830 * Because maxbuf is >= bufsiz + 2 + eoblen we can be sure
1831 * that returning bufsiz bytes won't cause problems trimming
1832 * the \r\n preceding the boundary marker. It's inelegant
1833 * but very simple. In the case of a stall or broken
1834 * connection we may be leaving more bytes in the buffer
1835 * than strictly necessary, but in those cases something is
1836 * broken, anyhow.
1837 */
1838 iov->iov_len = bufsiz;
1839
1840 if (mode & LSO_TEXT) {
1841 iov->iov_len = iov_eol(iov);
1842
1843 /* trim if might be part of \r\n sequence */
1844 if (iov_lc(iov) == '\r')
1845 --iov->iov_len;
1846 /*
1847 * NOTE: we guaranteed above that bufsiz >= 2 so we
1848 * don't accidentally return an empty string if we
1849 * trimmed a \r here.
1850 */
1851 }
1852 }
1853
1854 return 0;
1855 } /* lso_getbody() */
1856
1857
lso_getblock(struct luasocket * S,struct iovec * iov,size_t minbuf,size_t maxbuf,int mode)1858 static lso_error_t lso_getblock(struct luasocket *S, struct iovec *iov, size_t minbuf, size_t maxbuf, int mode) {
1859 int error;
1860
1861 if (mode & LSO_TEXT) {
1862 size_t fillsz = maxbuf, n;
1863
1864 do {
1865 error = lso_fill(S, fillsz);
1866
1867 fifo_slice(&S->ibuf.fifo, iov, 0, -1);
1868
1869 if ((size_t)-1 == (n = iov_eot(iov, minbuf, maxbuf, (S->ibuf.eof || S->ibuf.eom), &error))) {
1870 goto error;
1871 } else if (n > iov->iov_len) {
1872 if (fillsz < n)
1873 error = 0;
1874
1875 fillsz = n;
1876 } else {
1877 iov->iov_len = n;
1878
1879 return 0;
1880 }
1881 } while (!error);
1882 } else {
1883 error = lso_fill(S, maxbuf);
1884
1885 if (fifo_slice(&S->ibuf.fifo, iov, 0, maxbuf) >= minbuf)
1886 return 0;
1887
1888 if ((S->ibuf.eof || S->ibuf.eom) && iov->iov_len > 0)
1889 return 0;
1890 }
1891
1892 error:
1893 return lso_asserterror(error);
1894 } /* lso_getblock() */
1895
1896
1897 struct lso_rcvop {
1898 int index;
1899
1900 enum {
1901 LSO_NONE,
1902 LSO_NUMBER,
1903 LSO_SLURP,
1904 LSO_CHOMP,
1905 LSO_LINE,
1906 LSO_FIELD,
1907 LSO_HEADER,
1908 LSO_BODY,
1909 LSO_BLOCK,
1910 LSO_LIMIT,
1911 } type;
1912
1913 int mode;
1914
1915 EXTENSION union {
1916 size_t size;
1917
1918 struct {
1919 const char *eob;
1920 size_t eoblen;
1921 } body;
1922 };
1923 }; /* struct lso_rcvop */
1924
1925
lso_checkrcvop(lua_State * L,int index,int mode)1926 static struct lso_rcvop lso_checkrcvop(lua_State *L, int index, int mode) {
1927 struct lso_rcvop op = { index, LSO_NONE, mode };
1928 lua_Number size;
1929
1930 if (!lua_isnumber(L, index)) {
1931 size_t len;
1932 const char *fmt = luaL_optlstring(L, index, "*l", &len);
1933
1934 if (fmt[0] == '*' && len == 2) {
1935 switch (fmt[1]) {
1936 case 'n':
1937 op.type = LSO_NUMBER;
1938 break;
1939 case 'a':
1940 op.type = LSO_SLURP;
1941 break;
1942 case 'l':
1943 op.type = LSO_CHOMP;
1944 break;
1945 case 'L':
1946 op.type = LSO_LINE;
1947 break;
1948 case 'h':
1949 op.type = LSO_FIELD;
1950 break;
1951 case 'H':
1952 op.type = LSO_HEADER;
1953 break;
1954 }
1955 } else if (fmt[0] == '-' && fmt[1] == '-') {
1956 op.type = LSO_BODY;
1957 op.body.eob = fmt;
1958 op.body.eoblen = len;
1959 }
1960 } else {
1961 if ((size = luaL_checknumber(L, index)) < 0) {
1962 op.type = LSO_LIMIT;
1963 op.size = -size;
1964 } else {
1965 op.type = LSO_BLOCK;
1966 op.size = size;
1967 }
1968 }
1969
1970 if (op.type == LSO_NONE)
1971 luaL_argerror(L, index, lua_pushfstring(L, "invalid format %s", luaL_checkstring(L, index)));
1972
1973 return op;
1974 } /* lso_checkrcvop() */
1975
1976
1977 #define LSO_CHECKERRS(L, iobuf) do { \
1978 if (!(iobuf).error) \
1979 return 0; \
1980 if (++(iobuf).numerrs > (iobuf).maxerrs) \
1981 luaL_error((L), "exceeded unchecked error limit (%s)", cqs_strerror((iobuf).error)); \
1982 return (iobuf).error; \
1983 } while (0)
1984
lso_checkrcverrs(lua_State * L,struct luasocket * S)1985 static lso_error_t lso_checkrcverrs(lua_State *L, struct luasocket *S) {
1986 LSO_CHECKERRS(L, S->ibuf);
1987 } /* lso_checkrcverrs() */
1988
lso_checksnderrs(lua_State * L,struct luasocket * S)1989 static lso_error_t lso_checksnderrs(lua_State *L, struct luasocket *S) {
1990 LSO_CHECKERRS(L, S->obuf);
1991 } /* lso_checksnderrs() */
1992
1993
lso_preprcv(lua_State * L,struct luasocket * S)1994 static lso_error_t lso_preprcv(lua_State *L, struct luasocket *S) {
1995 int error;
1996
1997 if ((error = lso_checkrcverrs(L, S)))
1998 return error;
1999
2000 if ((error = lso_checktodo(S)))
2001 return error;
2002
2003 so_clear(S->socket);
2004
2005 if (S->obuf.mode & LSO_AUTOFLUSH) {
2006 switch ((error = lso_doflush(S, LSO_NOBUF))) {
2007 case EAGAIN:
2008 break;
2009 case EPIPE:
2010 break;
2011 default:
2012 return error;
2013 }
2014 }
2015
2016 return 0;
2017 } /* lso_preprcv() */
2018
lso_prepsnd(lua_State * L,struct luasocket * S)2019 static lso_error_t lso_prepsnd(lua_State *L, struct luasocket *S) {
2020 int error;
2021
2022 if ((error = lso_checksnderrs(L, S)))
2023 return error;
2024
2025 return lso_checktodo(S);
2026 } /* lso_prepsnd() */
2027
2028
lso_recv3(lua_State * L)2029 static lso_nargs_t lso_recv3(lua_State *L) {
2030 struct luasocket *S = lso_checkself(L, 1);
2031 struct lso_rcvop op;
2032 struct iovec iov;
2033 size_t count;
2034 int error;
2035
2036 if ((error = lso_preprcv(L, S)))
2037 goto error;
2038
2039 lua_settop(L, 3);
2040
2041 op = lso_checkrcvop(L, 2, lso_imode(luaL_optstring(L, 3, ""), S->ibuf.mode));
2042
2043 switch (op.type) {
2044 case LSO_NUMBER:
2045 return luaL_argerror(L, op.index, "*n not implemented yet");
2046 case LSO_SLURP:
2047 error = lso_fill(S, (size_t)-1);
2048
2049 if (!(S->ibuf.eom || S->ibuf.eof))
2050 goto error;
2051
2052 fifo_rvec(&S->ibuf.fifo, &iov, 1);
2053
2054 if ((count = iov.iov_len)) {
2055 if (op.mode & LSO_TEXT)
2056 iov_trimcr(&iov, 0);
2057
2058 lua_pushlstring(L, iov.iov_base, iov.iov_len);
2059 fifo_discard(&S->ibuf.fifo, count);
2060 } else {
2061 lua_pushnil(L);
2062 }
2063
2064 break;
2065 case LSO_CHOMP:
2066 if ((error = lso_getline(S, &iov)))
2067 goto error;
2068
2069 count = iov.iov_len;
2070
2071 if (op.mode & LSO_TEXT)
2072 iov_trimcr(&iov, 1);
2073
2074 if (iov_lc(&iov) == '\n')
2075 --iov.iov_len;
2076
2077 lua_pushlstring(L, iov.iov_base, iov.iov_len);
2078 fifo_discard(&S->ibuf.fifo, count);
2079
2080 break;
2081 case LSO_LINE:
2082 if ((error = lso_getline(S, &iov)))
2083 goto error;
2084
2085 count = iov.iov_len;
2086
2087 if (op.mode & LSO_TEXT)
2088 iov_trimcr(&iov, 1);
2089
2090 lua_pushlstring(L, iov.iov_base, iov.iov_len);
2091 fifo_discard(&S->ibuf.fifo, count);
2092
2093 break;
2094 case LSO_FIELD:
2095 if ((error = lso_getheader(S, &iov)))
2096 goto error;
2097
2098 if ((count = iov.iov_len)) {
2099 iov_trimcrlf(&iov, 0);
2100
2101 lua_pushlstring(L, iov.iov_base, iov.iov_len);
2102 fifo_discard(&S->ibuf.fifo, count);
2103 } else {
2104 lua_pushnil(L);
2105 }
2106
2107 break;
2108 case LSO_HEADER:
2109 if ((error = lso_getheader(S, &iov)))
2110 goto error;
2111
2112 if ((count = iov.iov_len)) {
2113 if (op.mode & LSO_TEXT)
2114 iov_trimcr(&iov, 0);
2115
2116 lua_pushlstring(L, iov.iov_base, iov.iov_len);
2117 fifo_discard(&S->ibuf.fifo, count);
2118 } else {
2119 lua_pushnil(L);
2120 }
2121
2122 break;
2123 case LSO_BODY: {
2124 int eom = 0; /* it would be confusing to overload ibuf.eom */
2125
2126 if ((error = lso_getbody(S, &iov, &eom, op.body.eob, op.body.eoblen, op.mode)))
2127 goto error;
2128
2129 if ((count = iov.iov_len)) {
2130 if (eom) {
2131 /* trim any \r\n preceding the boundary */
2132 iov_trimcrlf(&iov, 1);
2133
2134 if (op.mode & LSO_TEXT)
2135 iov_trimcr(&iov, 0);
2136
2137 if (iov.iov_len)
2138 lua_pushlstring(L, iov.iov_base, iov.iov_len);
2139 else
2140 lua_pushnil(L);
2141 } else {
2142 if (op.mode & LSO_TEXT)
2143 iov_trimcr(&iov, 0);
2144
2145 lua_pushlstring(L, iov.iov_base, iov.iov_len);
2146 }
2147
2148 fifo_discard(&S->ibuf.fifo, count);
2149 } else {
2150 lua_pushnil(L);
2151 }
2152
2153 break;
2154 }
2155 case LSO_BLOCK:
2156 if (op.size == 0) {
2157 lua_pushlstring(L, "", 0);
2158
2159 break;
2160 }
2161
2162 if ((error = lso_getblock(S, &iov, op.size, op.size, op.mode)))
2163 goto error;
2164
2165 if ((count = iov.iov_len)) {
2166 if (op.mode & LSO_TEXT)
2167 iov_trimcr(&iov, 0);
2168
2169 lua_pushlstring(L, iov.iov_base, iov.iov_len);
2170 fifo_discard(&S->ibuf.fifo, count);
2171 } else {
2172 lua_pushnil(L);
2173 }
2174
2175 break;
2176 case LSO_LIMIT:
2177 if (op.size == 0) {
2178 lua_pushlstring(L, "", 0);
2179
2180 break;
2181 }
2182
2183 if ((error = lso_getblock(S, &iov, 1, op.size, op.mode)))
2184 goto error;
2185
2186 if ((count = iov.iov_len)) {
2187 if (op.mode & LSO_TEXT)
2188 iov_trimcr(&iov, 0);
2189
2190 lua_pushlstring(L, iov.iov_base, iov.iov_len);
2191 fifo_discard(&S->ibuf.fifo, count);
2192 } else {
2193 lua_pushnil(L);
2194 }
2195
2196 break;
2197 default:
2198 error = EFAULT;
2199
2200 goto error;
2201 } /* switch(op) */
2202
2203 if (!fifo_rlen(&S->ibuf.fifo))
2204 S->ibuf.eom = 0;
2205
2206 return 1;
2207 error:
2208 lua_pushnil(L);
2209 lua_pushinteger(L, lso_asserterror(error));
2210
2211 return 2;
2212 } /* lso_recv3() */
2213
2214
lso_unget2(lua_State * L)2215 static lso_nargs_t lso_unget2(lua_State *L) {
2216 struct luasocket *S = lso_checkself(L, 1);
2217 const void *src;
2218 size_t len;
2219 struct iovec iov;
2220 int error;
2221
2222 src = luaL_checklstring(L, 2, &len);
2223
2224 if ((error = fifo_grow(&S->ibuf.fifo, len)))
2225 goto error;
2226
2227 fifo_rewind(&S->ibuf.fifo, len);
2228 fifo_slice(&S->ibuf.fifo, &iov, 0, len);
2229 memcpy(iov.iov_base, src, len);
2230
2231 S->ibuf.eof = 0;
2232
2233 lua_pushboolean(L, 1);
2234
2235 return 1;
2236 error:
2237 lua_pushboolean(L, 0);
2238 lua_pushinteger(L, error);
2239
2240 return 2;
2241 } /* lso_unget2() */
2242
2243
lso_doflush(struct luasocket * S,int mode)2244 static lso_error_t lso_doflush(struct luasocket *S, int mode) {
2245 size_t amount = 0, n;
2246 struct iovec iov;
2247 int error;
2248
2249 if (mode & LSO_LINEBUF) {
2250 if (S->obuf.eol > 0) {
2251 amount = S->obuf.eol;
2252 } else if (fifo_rlen(&S->obuf.fifo) >= S->obuf.maxline) {
2253 amount = S->obuf.maxline;
2254 }
2255 } else if (mode & LSO_FULLBUF) {
2256 amount = fifo_rlen(&S->obuf.fifo);
2257 amount -= amount % S->obuf.bufsiz;
2258 } else if (mode & LSO_NOBUF) {
2259 amount = fifo_rlen(&S->obuf.fifo);
2260 }
2261
2262 while (amount) {
2263 if (!fifo_slice(&S->obuf.fifo, &iov, 0, amount))
2264 break; /* should never happen */
2265
2266 if (!(n = so_write(S->socket, iov.iov_base, iov.iov_len, &error)))
2267 goto error;
2268
2269 fifo_discard(&S->obuf.fifo, n);
2270 amount -= n;
2271 S->obuf.eol -= MIN(S->obuf.eol, n);
2272 }
2273
2274 return 0;
2275 error:
2276 switch (error) {
2277 case EPIPE:
2278 S->obuf.eof = 1;
2279
2280 break;
2281 } /* switch() */
2282
2283 return error;
2284 } /* lso_doflush() */
2285
2286
lso_send5(lua_State * L)2287 static lso_nargs_t lso_send5(lua_State *L) {
2288 struct luasocket *S = lso_checkself(L, 1);
2289 const unsigned char *src, *lf;
2290 size_t tp, p, pe, end, n;
2291 int mode, byline, error;
2292
2293 if ((error = lso_prepsnd(L, S))) {
2294 lua_pushinteger(L, 0);
2295 lua_pushinteger(L, error);
2296
2297 return 2;
2298 }
2299
2300 lua_settop(L, 5);
2301
2302 src = (const void *)luaL_checklstring(L, 2, &end);
2303 tp = lso_checksize(L, 3) - 1;
2304 pe = lso_checksize(L, 4);
2305 mode = lso_imode(luaL_optstring(L, 5, ""), S->obuf.mode);
2306 byline = (mode & (LSO_TEXT|LSO_LINEBUF)) || (S->obuf.mode & LSO_LINEBUF);
2307
2308 luaL_argcheck(L, tp <= end, 3, "start index beyond object boundary");
2309 luaL_argcheck(L, pe <= end, 4, "end index beyond object boundary");
2310
2311 p = tp;
2312
2313 so_clear(S->socket);
2314
2315 while (p < pe) {
2316 if (byline) {
2317 n = MIN(pe - p, S->obuf.maxline);
2318
2319 if ((lf = memchr(&src[p], '\n', n))) {
2320 n = lf - &src[p];
2321
2322 if ((error = fifo_write(&S->obuf.fifo, &src[p], n)))
2323 goto error;
2324
2325 if ((mode & LSO_TEXT) && (error = fifo_putc(&S->obuf.fifo, '\r')))
2326 goto error;
2327
2328 if ((error = fifo_putc(&S->obuf.fifo, '\n')))
2329 goto error;
2330
2331 p += n + 1;
2332
2333 S->obuf.eol = fifo_rlen(&S->obuf.fifo);
2334 } else {
2335 if ((error = fifo_write(&S->obuf.fifo, &src[p], n)))
2336 goto error;
2337
2338 p += n;
2339 }
2340 } else {
2341 n = MIN(pe - p, LSO_BUFSIZ);
2342
2343 if ((error = fifo_write(&S->obuf.fifo, &src[p], n)))
2344 goto error;
2345
2346 p += n;
2347 }
2348
2349 if (fifo_rlen(&S->obuf.fifo) > S->obuf.bufsiz) {
2350 if ((error = lso_doflush(S, mode)))
2351 goto error;
2352 }
2353 }
2354
2355 if ((error = lso_doflush(S, mode)))
2356 goto error;
2357
2358 lua_pushinteger(L, p - tp);
2359
2360 return 1;
2361 error:
2362 lua_pushinteger(L, p - tp);
2363 lua_pushinteger(L, error);
2364
2365 return 2;
2366 } /* lso_send5() */
2367
2368
lso_flush(lua_State * L)2369 static lso_nargs_t lso_flush(lua_State *L) {
2370 struct luasocket *S = lso_checkself(L, 1);
2371 int mode = lso_imode(luaL_optstring(L, 2, "n"), S->obuf.mode);
2372 int error;
2373
2374 if ((error = lso_prepsnd(L, S)) || (error = lso_doflush(S, mode))) {
2375 lua_pushboolean(L, 0);
2376 lua_pushinteger(L, error);
2377
2378 return 2;
2379 } else {
2380 lua_pushboolean(L, 1);
2381
2382 return 1;
2383 }
2384 } /* lso_flush() */
2385
2386
lso_uncork(lua_State * L)2387 static lso_nargs_t lso_uncork(lua_State *L) {
2388 struct luasocket *S = lso_checkself(L, 1);
2389 int error;
2390
2391 if ((error = so_uncork(S->socket))) {
2392 lua_pushboolean(L, 0);
2393 lua_pushinteger(L, error);
2394
2395 return 2;
2396 } else {
2397 lua_pushboolean(L, 1);
2398
2399 return 1;
2400 }
2401 } /* lso_uncork() */
2402
2403
lso_pending(lua_State * L)2404 static lso_nargs_t lso_pending(lua_State *L) {
2405 struct luasocket *S = lso_checkself(L, 1);
2406
2407 lua_pushunsigned(L, fifo_rlen(&S->ibuf.fifo));
2408 lua_pushunsigned(L, fifo_rlen(&S->obuf.fifo));
2409
2410 return 2;
2411 } /* lso_pending() */
2412
2413
lso_sendfd3(lua_State * L)2414 static lso_nargs_t lso_sendfd3(lua_State *L) {
2415 struct luasocket *S = lso_checkself(L, 1);
2416 const void *src;
2417 size_t len;
2418 int fd, error;
2419
2420 if ((error = lso_prepsnd(L, S)))
2421 goto error;
2422
2423 lua_settop(L, 3);
2424
2425 src = luaL_checklstring(L, 2, &len);
2426
2427 if ((fd = lso_tofileno(L, 3)) < 0)
2428 goto badfd;
2429
2430 so_clear(S->socket);
2431
2432 if ((error = so_sendmsg(S->socket, so_fdmsg(src, len, fd), 0)))
2433 goto error;
2434
2435 lua_pushboolean(L, 1);
2436
2437 return 1;
2438 badfd:
2439 error = EBADF;
2440 error:
2441 lua_pushboolean(L, 0);
2442 lua_pushinteger(L, error);
2443
2444 return 2;
2445 } /* lso_sendfd3() */
2446
2447
lso_recvfd2(lua_State * L)2448 static lso_nargs_t lso_recvfd2(lua_State *L) {
2449 struct luasocket *S = lso_checkself(L, 1);
2450 size_t bufsiz = luaL_optunsigned(L, 2, S->ibuf.maxline);
2451 struct msghdr *msg;
2452 struct cmsghdr *cmsg;
2453 struct iovec iov;
2454 int fd = -1, error;
2455
2456 if ((error = lso_preprcv(L, S)))
2457 goto error;
2458
2459 if ((error = fifo_grow(&S->ibuf.fifo, bufsiz)))
2460 goto error;
2461
2462 fifo_wvec(&S->ibuf.fifo, &iov, 1);
2463
2464 msg = so_fdmsg(iov.iov_base, iov.iov_len, -1);
2465
2466 #if defined MSG_CMSG_CLOEXEC
2467 if ((error = so_recvmsg(S->socket, msg, MSG_CMSG_CLOEXEC)))
2468 goto error;
2469 #else
2470 if ((error = so_recvmsg(S->socket, msg, 0)))
2471 goto error;
2472 #endif
2473
2474 for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
2475 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS)
2476 continue;
2477
2478 cqs_closefd(&fd);
2479 memcpy(&fd, CMSG_DATA(cmsg), sizeof fd);
2480 }
2481
2482 if (msg->msg_flags & (MSG_TRUNC|MSG_CTRUNC))
2483 goto trunc;
2484
2485 if (msg->msg_iovlen > 0 && msg->msg_iov[0].iov_len > 0)
2486 lua_pushlstring(L, msg->msg_iov[0].iov_base, msg->msg_iov[0].iov_len);
2487 else
2488 lua_pushliteral(L, "");
2489
2490 if (fd == -1)
2491 lua_pushnil(L);
2492 else if ((error = cqs_socket_fdopen(L, fd, so_opts())))
2493 goto error;
2494
2495 return 2;
2496 trunc:
2497 error = ENOBUFS;
2498 error:
2499 cqs_closefd(&fd);
2500
2501 lua_pushnil(L);
2502 lua_pushnil(L);
2503 lua_pushinteger(L, error);
2504
2505 return 3;
2506 } /* lso_recvfd2() */
2507
2508
lso_pack4(lua_State * L)2509 static lso_nargs_t lso_pack4(lua_State *L) {
2510 struct luasocket *S = lso_checkself(L, 1);
2511 lua_Number value;
2512 unsigned count;
2513 int mode, error;
2514
2515 if ((error = lso_prepsnd(L, S)))
2516 goto error;
2517
2518 lua_settop(L, 4);
2519
2520 value = luaL_checknumber(L, 2);
2521 count = luaL_optunsigned(L, 3, 32);
2522 mode = lso_imode(luaL_optstring(L, 4, ""), S->obuf.mode);
2523
2524 if ((error = fifo_pack(&S->obuf.fifo, (unsigned long long)(long long)value, count)))
2525 goto error;
2526
2527 so_clear(S->socket);
2528
2529 if ((error = lso_doflush(S, mode)))
2530 goto error;
2531
2532 lua_pushboolean(L, 1);
2533
2534 return 1;
2535 error:
2536 lua_pushboolean(L, 0);
2537 lua_pushinteger(L, error);
2538
2539 return 2;
2540 } /* lso_pack4() */
2541
2542
lso_unpack2(lua_State * L)2543 static lso_nargs_t lso_unpack2(lua_State *L) {
2544 struct luasocket *S = lso_checkself(L, 1);
2545 unsigned long long value;
2546 unsigned count;
2547 int error;
2548
2549 if ((error = lso_preprcv(L, S)))
2550 goto error;
2551
2552 lua_settop(L, 2);
2553
2554 count = luaL_optunsigned(L, 2, 32);
2555
2556 if (fifo_rbits(&S->ibuf.fifo) < count) {
2557 size_t rem = ((count - fifo_rbits(&S->ibuf.fifo)) + 7U) / 8U;
2558
2559 if ((error = lso_fill(S, rem))) {
2560 if (fifo_rbits(&S->ibuf.fifo) < count)
2561 goto error;
2562 }
2563 }
2564
2565 value = fifo_unpack(&S->ibuf.fifo, count);
2566
2567 if (value == (unsigned long long)(lua_Integer)value)
2568 lua_pushinteger(L, (lua_Integer)value);
2569 else if (value == (unsigned long long)(lua_Number)value)
2570 lua_pushnumber(L, (lua_Number)value);
2571 else
2572 goto range;
2573
2574 return 1;
2575 range:
2576 error = ERANGE;
2577 error:
2578 lua_pushnil(L);
2579 lua_pushinteger(L, error);
2580
2581 return 2;
2582 } /* lso_unpack2() */
2583
2584
lso_fill2(lua_State * L)2585 static lso_nargs_t lso_fill2(lua_State *L) {
2586 struct luasocket *S = lso_checkself(L, 1);
2587 size_t size = lso_checksize(L, 2);
2588 int error;
2589
2590 if ((error = lso_preprcv(L, S)) || (error = lso_fill(S, size))) {
2591 lua_pushboolean(L, 0);
2592 lua_pushinteger(L, error);
2593
2594 return 2;
2595 }
2596
2597 lua_pushboolean(L, 1);
2598
2599 return 1;
2600 } /* lso_fill2() */
2601
2602
lso_clear(lua_State * L)2603 static lso_nargs_t lso_clear(lua_State *L) {
2604 struct luasocket *S = lso_checkself(L, 1);
2605
2606 so_clear(S->socket);
2607
2608 lua_pushboolean(L, 1);
2609
2610 return 1;
2611 } /* lso_clear() */
2612
2613
cqs_socket_pollfd(lua_State * L,int index)2614 int cqs_socket_pollfd(lua_State *L, int index) {
2615 struct luasocket *S = lso_checkvalid(L, index, lua_touserdata(L, index));
2616
2617 return so_pollfd(S->socket);
2618 } /* cqs_socket_pollfd() */
2619
lso_pollfd(lua_State * L)2620 static lso_nargs_t lso_pollfd(lua_State *L) {
2621 struct luasocket *S = lso_checkself(L, 1);
2622
2623 lua_pushinteger(L, so_pollfd(S->socket));
2624
2625 return 1;
2626 } /* lso_pollfd() */
2627
2628
cqs_socket_events(lua_State * L,int index)2629 int cqs_socket_events(lua_State *L, int index) {
2630 struct luasocket *S = lso_checkvalid(L, index, lua_touserdata(L, index));
2631
2632 return so_events(S->socket);
2633 } /* cqs_socket_events() */
2634
lso_events(lua_State * L)2635 static lso_nargs_t lso_events(lua_State *L) {
2636 struct luasocket *S = lso_checkself(L, 1);
2637 short events = so_events(S->socket);
2638 char mode[3], *p = mode;
2639
2640 if ((events & POLLIN))
2641 *p++ = 'r';
2642
2643 if ((events & POLLOUT))
2644 *p++ = 'w';
2645
2646 lua_pushlstring(L, mode, p - mode);
2647
2648 return 1;
2649 } /* lso_events() */
2650
2651
cqs_socket_timeout(lua_State * L NOTUSED,int index NOTUSED)2652 double cqs_socket_timeout(lua_State *L NOTUSED, int index NOTUSED) {
2653 struct luasocket *S = lso_checkvalid(L, index, lua_touserdata(L, index));
2654
2655 return S->timeout;
2656 } /* cqs_socket_timeout() */
2657
2658
lso_timeout(lua_State * L)2659 static lso_nargs_t lso_timeout(lua_State *L) {
2660 struct luasocket *S = lso_checkself(L, 1);
2661
2662 if (isnormal(S->timeout) || S->timeout == 0) {
2663 lua_pushnumber(L, S->timeout);
2664
2665 return 1;
2666 }
2667
2668 return 0;
2669 } /* lso_timeout() */
2670
2671
lso_shutdown(lua_State * L)2672 static lso_nargs_t lso_shutdown(lua_State *L) {
2673 struct luasocket *S = lso_checkself(L, 1);
2674 int how, error;
2675
2676 switch (luaL_checkoption(L, 2, "rw", (const char *[]){ "r", "w", "rw", "wr", 0 })) {
2677 case 0:
2678 how = SHUT_RD;
2679
2680 break;
2681 case 1:
2682 how = SHUT_WR;
2683
2684 break;
2685 default:
2686 how = SHUT_RDWR;
2687
2688 break;
2689 } /* switch() */
2690
2691 if ((error = so_shutdown(S->socket, how))) {
2692 lua_pushboolean(L, 0);
2693 lua_pushinteger(L, error);
2694
2695 return 2;
2696 } else {
2697 lua_pushboolean(L, 1);
2698
2699 return 1;
2700 }
2701 } /* lso_shutdown() */
2702
2703
lso_eof(lua_State * L)2704 static lso_nargs_t lso_eof(lua_State *L) {
2705 struct luasocket *S = lso_checkself(L, 1);
2706 const char *which = luaL_optstring(L, 2, "rw");
2707 int nret = 0;
2708
2709 for (; *which; which++) {
2710 switch (*which) {
2711 case 'r':
2712 lua_pushboolean(L, S->ibuf.eof);
2713 nret++;
2714
2715 break;
2716 case 'w':
2717 lua_pushboolean(L, S->obuf.eof);
2718 nret++;
2719
2720 break;
2721 }
2722 } /* for() */
2723
2724 return nret;
2725 } /* lso_eof() */
2726
2727
lso_accept(lua_State * L)2728 static lso_nargs_t lso_accept(lua_State *L) {
2729 struct luasocket *A = lso_checkself(L, 1), *S;
2730 struct so_options opts;
2731 int fd = -1, error;
2732
2733 if (lua_istable(L, 2)) {
2734 opts = lso_checkopts(L, 2);
2735 } else {
2736 opts = *so_opts();
2737 }
2738
2739 S = lso_newsocket(L, A->type);
2740
2741 opts.fd_close.arg = S;
2742 opts.fd_close.cb = &lso_closefd;
2743
2744 so_clear(A->socket);
2745
2746 if (-1 == (fd = so_accept(A->socket, 0, 0, &error)))
2747 goto error;
2748
2749 if ((error = lso_prepsocket(S)))
2750 goto error;
2751
2752 if (!(S->socket = so_fdopen(fd, &opts, &error)))
2753 goto error;
2754
2755 return 1;
2756 error:
2757 cqs_closefd(&fd);
2758 lua_pushnil(L);
2759 lua_pushinteger(L, error);
2760
2761 return 2;
2762 } /* lso_accept() */
2763
2764
lso_pushname(lua_State * L,struct sockaddr_storage * ss,socklen_t salen)2765 static lso_nargs_t lso_pushname(lua_State *L, struct sockaddr_storage *ss, socklen_t salen) {
2766 switch (ss->ss_family) {
2767 case AF_INET:
2768 /* FALL THROUGH */
2769 case AF_INET6:
2770 lua_pushinteger(L, ss->ss_family);
2771 lua_pushstring(L, sa_ntoa(ss));
2772 lua_pushinteger(L, ntohs(*sa_port(ss, SA_PORT_NONE, NULL)));
2773
2774 return 3;
2775 case AF_UNIX:
2776 lua_pushinteger(L, ss->ss_family);
2777
2778 /* support nameless sockets and Linux's abstract namespace */
2779 if (salen > offsetof(struct sockaddr_un, sun_path)) {
2780 struct sockaddr_un *sun = (struct sockaddr_un *)ss;
2781 char *pe = (char *)sun + SO_MIN(sizeof *sun, salen);
2782 size_t plen;
2783
2784 while (pe > sun->sun_path && pe[-1] == '\0')
2785 --pe;
2786
2787 if ((plen = (pe - sun->sun_path)) > 0) {
2788 lua_pushlstring(L, sun->sun_path, plen);
2789 } else {
2790 lua_pushnil(L);
2791 }
2792 } else {
2793 lua_pushnil(L);
2794 }
2795
2796 return 2;
2797 default:
2798 lua_pushinteger(L, ss->ss_family);
2799
2800 return 1;
2801 }
2802 } /* lso_pushname() */
2803
2804
lso_peername(lua_State * L)2805 static lso_nargs_t lso_peername(lua_State *L) {
2806 struct luasocket *S = lso_checkself(L, 1);
2807 struct sockaddr_storage ss;
2808 socklen_t salen = sizeof ss;
2809 int error;
2810
2811 memset(&ss, 0, sizeof ss);
2812
2813 if ((error = so_remoteaddr(S->socket, &ss, &salen))) {
2814 lua_pushnil(L);
2815 lua_pushinteger(L, error);
2816
2817 return 2;
2818 }
2819
2820 return lso_pushname(L, &ss, salen);
2821 } /* lso_peername() */
2822
2823
lso_peereid(lua_State * L)2824 static lso_nargs_t lso_peereid(lua_State *L) {
2825 struct luasocket *S = lso_checkself(L, 1);
2826 uid_t uid;
2827 gid_t gid;
2828 int error;
2829
2830 if ((error = so_peereid(S->socket, &uid, &gid))) {
2831 lua_pushnil(L);
2832 lua_pushinteger(L, error);
2833
2834 return 2;
2835 }
2836
2837 lua_pushinteger(L, uid);
2838 lua_pushinteger(L, gid);
2839
2840 return 2;
2841 } /* lso_peereid() */
2842
2843
lso_peerpid(lua_State * L)2844 static lso_nargs_t lso_peerpid(lua_State *L) {
2845 struct luasocket *S = lso_checkself(L, 1);
2846 pid_t pid;
2847 int error;
2848
2849 if ((error = so_peerpid(S->socket, &pid))) {
2850 lua_pushnil(L);
2851 lua_pushinteger(L, error);
2852
2853 return 2;
2854 }
2855
2856 lua_pushinteger(L, pid);
2857
2858 return 1;
2859 } /* lso_peerpid() */
2860
2861
lso_localname(lua_State * L)2862 static lso_nargs_t lso_localname(lua_State *L) {
2863 struct luasocket *S = lso_checkself(L, 1);
2864 struct sockaddr_storage ss;
2865 socklen_t salen = sizeof ss;
2866 int error;
2867
2868 memset(&ss, 0, sizeof ss);
2869
2870 if ((error = so_localaddr(S->socket, &ss, &salen))) {
2871 lua_pushnil(L);
2872 lua_pushinteger(L, error);
2873
2874 return 2;
2875 }
2876
2877 return lso_pushname(L, &ss, salen);
2878 } /* lso_localname() */
2879
2880
lso_stat(lua_State * L)2881 static lso_nargs_t lso_stat(lua_State *L) {
2882 struct luasocket *S = lso_checkself(L, 1);
2883 const struct so_stat *st = so_stat(S->socket);
2884
2885 lua_newtable(L);
2886
2887 lua_newtable(L);
2888 lua_pushinteger(L, st->sent.count);
2889 lua_setfield(L, -2, "count");
2890 lua_pushboolean(L, st->sent.eof);
2891 lua_setfield(L, -2, "eof");
2892 lua_pushinteger(L, st->sent.time);
2893 lua_setfield(L, -2, "time");
2894 lua_setfield(L, -2, "sent");
2895
2896 lua_newtable(L);
2897 lua_pushinteger(L, st->rcvd.count);
2898 lua_setfield(L, -2, "count");
2899 lua_pushboolean(L, st->rcvd.eof);
2900 lua_setfield(L, -2, "eof");
2901 lua_pushinteger(L, st->rcvd.time);
2902 lua_setfield(L, -2, "time");
2903 lua_setfield(L, -2, "rcvd");
2904
2905 return 1;
2906 } /* lso_stat() */
2907
2908
lso_destroy(lua_State * L,struct luasocket * S)2909 static void lso_destroy(lua_State *L, struct luasocket *S) {
2910 cqs_unref(L, &S->onerror);
2911
2912 if (S->tls.config.instance) {
2913 SSL_free(S->tls.config.instance);
2914 S->tls.config.instance = NULL;
2915 }
2916
2917 if (S->tls.config.context) {
2918 SSL_CTX_free(S->tls.config.context);
2919 S->tls.config.context = NULL;
2920 }
2921
2922 fifo_reset(&S->ibuf.fifo);
2923 fifo_reset(&S->obuf.fifo);
2924
2925 /* Hack for Lua 5.1 and LuaJIT */
2926 if (!S->mainthread) {
2927 S->mainthread = L;
2928 so_close(S->socket);
2929 S->mainthread = 0;
2930 } else {
2931 so_close(S->socket);
2932 }
2933
2934 S->socket = 0;
2935 } /* lso_destroy() */
2936
2937
lso_close(lua_State * L)2938 static lso_nargs_t lso_close(lua_State *L) {
2939 struct luasocket *S = luaL_checkudata(L, 1, LSO_CLASS);
2940
2941 lso_destroy(L, S);
2942
2943 return 0;
2944 } /* lso_close() */
2945
2946
lso__gc(lua_State * L)2947 static lso_nargs_t lso__gc(lua_State *L) {
2948 struct luasocket *S = luaL_checkudata(L, 1, LSO_CLASS);
2949
2950 S->mainthread = NULL; // disable poll cancellation
2951 lso_destroy(L, S);
2952
2953 return 0;
2954 } /* lso__gc() */
2955
2956
lso_type(lua_State * L)2957 static int lso_type(lua_State *L) {
2958 struct luasocket *S;
2959
2960 if ((S = lso_testself(L, 1))) {
2961 lua_pushstring(L, (S->socket)? "socket" : "closed socket");
2962 } else {
2963 lua_pushnil(L);
2964 }
2965
2966 return 1;
2967 } /* lso_type() */
2968
2969
lso_interpose(lua_State * L)2970 static int lso_interpose(lua_State *L) {
2971 return cqs_interpose(L, LSO_CLASS);
2972 } /* lso_interpose() */
2973
2974
2975 static luaL_Reg lso_methods[] = {
2976 { "connect", &lso_connect1 },
2977 { "listen", &lso_listen1 },
2978 { "starttls", &lso_starttls },
2979 { "checktls", &lso_checktls },
2980 { "setvbuf", &lso_setvbuf3 },
2981 { "setmode", &lso_setmode3 },
2982 { "setbufsiz", &lso_setbufsiz3 },
2983 { "setmaxline", &lso_setmaxline3 },
2984 { "settimeout", &lso_settimeout2 },
2985 { "seterror", &lso_seterror },
2986 { "setmaxerrs", &lso_setmaxerrs2 },
2987 { "error", &lso_error },
2988 { "clearerr", &lso_clearerr },
2989 { "onerror", &lso_onerror2 },
2990 { "recv", &lso_recv3 },
2991 { "unget", &lso_unget2 },
2992 { "send", &lso_send5 },
2993 { "flush", &lso_flush },
2994 { "uncork", &lso_uncork },
2995 { "pending", &lso_pending },
2996 { "sendfd", &lso_sendfd3 },
2997 { "recvfd", &lso_recvfd2 },
2998 { "pack", &lso_pack4 },
2999 { "unpack", &lso_unpack2 },
3000 { "fill", &lso_fill2 },
3001 { "clear", &lso_clear },
3002 { "pollfd", &lso_pollfd },
3003 { "events", &lso_events },
3004 { "timeout", &lso_timeout },
3005 { "shutdown", &lso_shutdown },
3006 { "eof", &lso_eof },
3007 { "accept", &lso_accept },
3008 { "peername", &lso_peername },
3009 { "peereid", &lso_peereid },
3010 { "peerpid", &lso_peerpid },
3011 { "localname", &lso_localname },
3012 { "stat", &lso_stat },
3013 { "close", &lso_close },
3014 { 0, 0 }
3015 }; /* lso_methods[] */
3016
3017
3018 static luaL_Reg lso_metamethods[] = {
3019 { "__gc", &lso__gc },
3020 { 0, 0 }
3021 }; /* lso_metamethods[] */
3022
3023
3024 static luaL_Reg lso_globals[] = {
3025 { "connect", &lso_connect2 },
3026 { "listen", &lso_listen2 },
3027 { "dup", &lso_dup },
3028 { "fdopen", &lso_fdopen },
3029 { "pair", &lso_pair },
3030 { "type", &lso_type },
3031 { "interpose", &lso_interpose },
3032 { "setvbuf", &lso_setvbuf2 },
3033 { "setmode", &lso_setmode2 },
3034 { "setbufsiz", &lso_setbufsiz2 },
3035 { "setmaxline", &lso_setmaxline2 },
3036 { "settimeout", &lso_settimeout1 },
3037 { "setmaxerrs", &lso_setmaxerrs1 },
3038 { "onerror", &lso_onerror1 },
3039 { 0, 0 }
3040 }; /* lso_globals[] */
3041
3042
luaopen__cqueues_socket(lua_State * L)3043 lso_nargs_t luaopen__cqueues_socket(lua_State *L) {
3044 static const struct cqs_macro macros[] = {
3045 { "AF_UNSPEC", AF_UNSPEC },
3046 { "AF_INET", AF_INET },
3047 { "AF_INET6", AF_INET6 },
3048 { "AF_UNIX", AF_UNIX },
3049 { "SOCK_STREAM", SOCK_STREAM },
3050 { "SOCK_SEQPACKET", SOCK_SEQPACKET },
3051 { "SOCK_DGRAM", SOCK_DGRAM },
3052 };
3053
3054 cqs_pushnils(L, LSO_UPVALUES); /* initial upvalues */
3055 cqs_newmetatable(L, LSO_CLASS, lso_methods, lso_metamethods, LSO_UPVALUES);
3056 lua_pushvalue(L, -1); /* push self as replacement upvalue */
3057 cqs_setmetaupvalue(L, -2, LSO_INDEX); /* insert self as upvalue */
3058
3059 luaL_newlibtable(L, lso_globals);
3060 cqs_pushnils(L, LSO_UPVALUES); /* initial upvalues */
3061 luaL_setfuncs(L, lso_globals, LSO_UPVALUES);
3062 lua_pushvalue(L, -2); /* push metatable */
3063 cqs_setfuncsupvalue(L, -2, LSO_INDEX);
3064
3065 cqs_setmacros(L, -1, macros, countof(macros), 0);
3066
3067 return 1;
3068 } /* luaopen__cqueues_socket() */
3069
3070
3071 /*
3072 * D E B U G & U N I T T E S T I N G R O U T I N E S
3073 *
3074 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
3075
dbg_checksize(lua_State * L,int index)3076 static size_t dbg_checksize(lua_State *L, int index) {
3077 lua_Number n = luaL_checknumber(L, index);
3078
3079 return (n < 0)? (size_t)0 - (size_t)-n : (size_t)n;
3080 } /* dbg_checksize() */
3081
3082
dbg_checkbool(lua_State * L,int index)3083 static size_t dbg_checkbool(lua_State *L, int index) {
3084 luaL_checktype(L, index, LUA_TBOOLEAN);
3085
3086 return lua_toboolean(L, index);
3087 } /* dbg_checkbool() */
3088
3089
dbg_checkstring(lua_State * L,int index)3090 static struct iovec dbg_checkstring(lua_State *L, int index) {
3091 struct iovec iov;
3092
3093 iov.iov_base = (void *)luaL_checklstring(L, index, &iov.iov_len);
3094
3095 return iov;
3096 } /* dbg_checkstring() */
3097
3098
dbg_iov_eoh(lua_State * L)3099 static int dbg_iov_eoh(lua_State *L) {
3100 struct iovec iov = dbg_checkstring(L, 1);
3101 _Bool eof = dbg_checkbool(L, 2);
3102 size_t eoh;
3103 int error;
3104
3105 if ((size_t)-1 == (eoh = iov_eoh(&iov, eof, 0, &error))) {
3106 lua_pushnil(L);
3107 lua_pushstring(L, cqs_strerror(error));
3108 lua_pushinteger(L, error);
3109
3110 return 3;
3111 } else {
3112 lua_pushinteger(L, eoh);
3113
3114 return 1;
3115 }
3116 } /* dbg_iov_eoh() */
3117
3118
dbg_iov_eob(lua_State * L)3119 static int dbg_iov_eob(lua_State *L) {
3120 struct iovec haystack = dbg_checkstring(L, 1);
3121 struct iovec needle = dbg_checkstring(L, 2);
3122
3123 lua_pushinteger(L, iov_eob(&haystack, needle.iov_base, needle.iov_len));
3124
3125 return 1;
3126 } /* dbg_iov_eob() */
3127
3128
dbg_iov_eot(lua_State * L)3129 static int dbg_iov_eot(lua_State *L) {
3130 struct iovec iov = dbg_checkstring(L, 1);
3131 size_t minbuf = dbg_checksize(L, 2);
3132 size_t maxbuf = dbg_checksize(L, 3);
3133 _Bool eof = dbg_checkbool(L, 4);
3134 size_t n;
3135 int error;
3136
3137 if ((size_t)-1 == (n = iov_eot(&iov, minbuf, maxbuf, eof, &error))) {
3138 lua_pushnil(L);
3139 lua_pushstring(L, cqs_strerror(error));
3140 lua_pushinteger(L, error);
3141
3142 return 3;
3143 } else {
3144 lua_pushinteger(L, n);
3145
3146 return 1;
3147 }
3148 } /* dbg_iov_eot() */
3149
3150
dbg_iov_trimcr(lua_State * L)3151 static int dbg_iov_trimcr(lua_State *L) {
3152 struct iovec src = dbg_checkstring(L, 1);
3153 _Bool chomp = dbg_checkbool(L, 2);
3154 struct iovec dst = { memcpy(lua_newuserdata(L, src.iov_len), src.iov_base, src.iov_len), src.iov_len };
3155
3156 iov_trimcr(&dst, chomp);
3157
3158 lua_pushlstring(L, dst.iov_base, dst.iov_len);
3159
3160 return 1;
3161 } /* dbg_iov_trimcr() */
3162
3163
dbg_iov_trimcrlf(lua_State * L)3164 static int dbg_iov_trimcrlf(lua_State *L) {
3165 struct iovec src = dbg_checkstring(L, 1);
3166 _Bool chomp = dbg_checkbool(L, 2);
3167 struct iovec dst = { memcpy(lua_newuserdata(L, src.iov_len), src.iov_base, src.iov_len), src.iov_len };
3168
3169 iov_trimcrlf(&dst, chomp);
3170
3171 lua_pushlstring(L, dst.iov_base, dst.iov_len);
3172
3173 return 1;
3174 } /* dbg_iov_trimcrlf() */
3175
3176
3177 static luaL_Reg dbg_globals[] = {
3178 { "iov_eoh", &dbg_iov_eoh },
3179 { "iov_eob", &dbg_iov_eob },
3180 { "iov_eot", &dbg_iov_eot },
3181 { "iov_trimcr", &dbg_iov_trimcr },
3182 { "iov_trimcrlf", &dbg_iov_trimcrlf },
3183 { NULL, NULL }
3184 }; /* dbg_globals[] */
3185
3186
luaopen__cqueues_socket_debug(lua_State * L)3187 lso_nargs_t luaopen__cqueues_socket_debug(lua_State *L) {
3188 luaL_newlib(L, dbg_globals);
3189
3190 return 1;
3191 } /* luaopen__cqueues_socket_debug() */
3192
3193
3194