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(&regindex), 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(&regindex), 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(&regindex), &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