1 /*
2  * Lua unsafe core engine
3  *
4  * Copyright 2015-2016 Thierry Fournier <tfournier@arpalert.org>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  *
11  */
12 
13 #define _GNU_SOURCE
14 
15 #include <ctype.h>
16 #include <limits.h>
17 #include <setjmp.h>
18 
19 #include <lauxlib.h>
20 #include <lua.h>
21 #include <lualib.h>
22 
23 #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 503
24 #error "Requires Lua 5.3 or later."
25 #endif
26 
27 #include <ebpttree.h>
28 
29 #include <common/cfgparse.h>
30 #include <common/compiler.h>
31 #include <common/hathreads.h>
32 #include <common/initcall.h>
33 #include <common/xref.h>
34 #include <common/h1.h>
35 
36 #include <types/cli.h>
37 #include <types/hlua.h>
38 #include <types/proxy.h>
39 #include <types/stats.h>
40 
41 #include <proto/arg.h>
42 #include <proto/applet.h>
43 #include <proto/channel.h>
44 #include <proto/cli.h>
45 #include <proto/connection.h>
46 #include <proto/stats.h>
47 #include <proto/hlua.h>
48 #include <proto/hlua_fcn.h>
49 #include <proto/http_fetch.h>
50 #include <proto/http_htx.h>
51 #include <proto/http_rules.h>
52 #include <proto/map.h>
53 #include <proto/obj_type.h>
54 #include <proto/queue.h>
55 #include <proto/pattern.h>
56 #include <proto/payload.h>
57 #include <proto/http_ana.h>
58 #include <proto/sample.h>
59 #include <proto/server.h>
60 #include <proto/session.h>
61 #include <proto/stream.h>
62 #include <proto/stream_interface.h>
63 #include <proto/task.h>
64 #include <proto/tcp_rules.h>
65 #include <proto/vars.h>
66 
67 /* Lua uses longjmp to perform yield or throwing errors. This
68  * macro is used only for identifying the function that can
69  * not return because a longjmp is executed.
70  *   __LJMP marks a prototype of hlua file that can use longjmp.
71  *   WILL_LJMP() marks an lua function that will use longjmp.
72  *   MAY_LJMP() marks an lua function that may use longjmp.
73  */
74 #define __LJMP
75 #define WILL_LJMP(func) do { func; my_unreachable(); } while(0)
76 #define MAY_LJMP(func) func
77 
78 /* This couple of function executes securely some Lua calls outside of
79  * the lua runtime environment. Each Lua call can return a longjmp
80  * if it encounter a memory error.
81  *
82  * Lua documentation extract:
83  *
84  *   If an error happens outside any protected environment, Lua calls
85  *   a panic function (see lua_atpanic) and then calls abort, thus
86  *   exiting the host application. Your panic function can avoid this
87  *   exit by never returning (e.g., doing a long jump to your own
88  *   recovery point outside Lua).
89  *
90  *   The panic function runs as if it were a message handler (see
91  *   §2.3); in particular, the error message is at the top of the
92  *   stack. However, there is no guarantee about stack space. To push
93  *   anything on the stack, the panic function must first check the
94  *   available space (see §4.2).
95  *
96  * We must check all the Lua entry point. This includes:
97  *  - The include/proto/hlua.h exported functions
98  *  - the task wrapper function
99  *  - The action wrapper function
100  *  - The converters wrapper function
101  *  - The sample-fetch wrapper functions
102  *
103  * It is tolerated that the initilisation function returns an abort.
104  * Before each Lua abort, an error message is written on stderr.
105  *
106  * The macro SET_SAFE_LJMP initialise the longjmp. The Macro
107  * RESET_SAFE_LJMP reset the longjmp. These function must be macro
108  * because they must be exists in the program stack when the longjmp
109  * is called.
110  *
111  * Note that the Lua processing is not really thread safe. It provides
112  * heavy system which consists to add our own lock function in the Lua
113  * code and recompile the library. This system will probably not accepted
114  * by maintainers of various distribs.
115  *
116  * Our main excution point of the Lua is the function lua_resume(). A
117  * quick looking on the Lua sources displays a lua_lock() a the start
118  * of function and a lua_unlock() at the end of the function. So I
119  * conclude that the Lua thread safe mode just perform a mutex around
120  * all execution. So I prefer to do this in the HAProxy code, it will be
121  * easier for distro maintainers.
122  *
123  * Note that the HAProxy lua functions rounded by the macro SET_SAFE_LJMP
124  * and RESET_SAFE_LJMP manipulates the Lua stack, so it will be careful
125  * to set mutex around these functions.
126  */
127 __decl_spinlock(hlua_global_lock);
128 THREAD_LOCAL jmp_buf safe_ljmp_env;
hlua_panic_safe(lua_State * L)129 static int hlua_panic_safe(lua_State *L) { return 0; }
hlua_panic_ljmp(lua_State * L)130 static int hlua_panic_ljmp(lua_State *L) { longjmp(safe_ljmp_env, 1); }
131 
132 #define SET_SAFE_LJMP(__L) \
133 	({ \
134 		int ret; \
135 		HA_SPIN_LOCK(LUA_LOCK, &hlua_global_lock); \
136 		if (setjmp(safe_ljmp_env) != 0) { \
137 			lua_atpanic(__L, hlua_panic_safe); \
138 			ret = 0; \
139 			HA_SPIN_UNLOCK(LUA_LOCK, &hlua_global_lock); \
140 		} else { \
141 			lua_atpanic(__L, hlua_panic_ljmp); \
142 			ret = 1; \
143 		} \
144 		ret; \
145 	})
146 
147 /* If we are the last function catching Lua errors, we
148  * must reset the panic function.
149  */
150 #define RESET_SAFE_LJMP(__L) \
151 	do { \
152 		lua_atpanic(__L, hlua_panic_safe); \
153 		HA_SPIN_UNLOCK(LUA_LOCK, &hlua_global_lock); \
154 	} while(0)
155 
156 /* Applet status flags */
157 #define APPLET_DONE     0x01 /* applet processing is done. */
158 /* unused: 0x02 */
159 #define APPLET_HDR_SENT 0x04 /* Response header sent. */
160 /* unused: 0x08, 0x10 */
161 #define APPLET_HTTP11   0x20 /* Last chunk sent. */
162 #define APPLET_RSP_SENT 0x40 /* The response was fully sent */
163 
164 /* The main Lua execution context. */
165 struct hlua gL;
166 
167 /* This is the memory pool containing struct lua for applets
168  * (including cli).
169  */
170 DECLARE_STATIC_POOL(pool_head_hlua, "hlua", sizeof(struct hlua));
171 
172 /* Used for Socket connection. */
173 static struct proxy socket_proxy;
174 static struct server socket_tcp;
175 #ifdef USE_OPENSSL
176 static struct server socket_ssl;
177 #endif
178 
179 /* List head of the function called at the initialisation time. */
180 struct list hlua_init_functions = LIST_HEAD_INIT(hlua_init_functions);
181 
182 /* The following variables contains the reference of the different
183  * Lua classes. These references are useful for identify metadata
184  * associated with an object.
185  */
186 static int class_txn_ref;
187 static int class_socket_ref;
188 static int class_channel_ref;
189 static int class_fetches_ref;
190 static int class_converters_ref;
191 static int class_http_ref;
192 static int class_map_ref;
193 static int class_applet_tcp_ref;
194 static int class_applet_http_ref;
195 
196 /* Global Lua execution timeout. By default Lua, execution linked
197  * with stream (actions, sample-fetches and converters) have a
198  * short timeout. Lua linked with tasks doesn't have a timeout
199  * because a task may remain alive during all the haproxy execution.
200  */
201 static unsigned int hlua_timeout_session = 4000; /* session timeout. */
202 static unsigned int hlua_timeout_task = TICK_ETERNITY; /* task timeout. */
203 static unsigned int hlua_timeout_applet = 4000; /* applet timeout. */
204 
205 /* Interrupts the Lua processing each "hlua_nb_instruction" instructions.
206  * it is used for preventing infinite loops.
207  *
208  * I test the scheer with an infinite loop containing one incrementation
209  * and one test. I run this loop between 10 seconds, I raise a ceil of
210  * 710M loops from one interrupt each 9000 instructions, so I fix the value
211  * to one interrupt each 10 000 instructions.
212  *
213  *  configured    | Number of
214  *  instructions  | loops executed
215  *  between two   | in milions
216  *  forced yields |
217  * ---------------+---------------
218  *  10            | 160
219  *  500           | 670
220  *  1000          | 680
221  *  5000          | 700
222  *  7000          | 700
223  *  8000          | 700
224  *  9000          | 710 <- ceil
225  *  10000         | 710
226  *  100000        | 710
227  *  1000000       | 710
228  *
229  */
230 static unsigned int hlua_nb_instruction = 10000;
231 
232 /* Descriptor for the memory allocation state. If limit is not null, it will
233  * be enforced on any memory allocation.
234  */
235 struct hlua_mem_allocator {
236 	size_t allocated;
237 	size_t limit;
238 };
239 
240 static struct hlua_mem_allocator hlua_global_allocator;
241 
242 /* These functions converts types between HAProxy internal args or
243  * sample and LUA types. Another function permits to check if the
244  * LUA stack contains arguments according with an required ARG_T
245  * format.
246  */
247 static int hlua_arg2lua(lua_State *L, const struct arg *arg);
248 static int hlua_lua2arg(lua_State *L, int ud, struct arg *arg);
249 __LJMP static int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp,
250                                      uint64_t mask, struct proxy *p);
251 static int hlua_smp2lua(lua_State *L, struct sample *smp);
252 static int hlua_smp2lua_str(lua_State *L, struct sample *smp);
253 static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp);
254 
255 __LJMP static int hlua_http_get_headers(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg);
256 
257 #define SEND_ERR(__be, __fmt, __args...) \
258 	do { \
259 		send_log(__be, LOG_ERR, __fmt, ## __args); \
260 		if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) \
261 			ha_alert(__fmt, ## __args); \
262 	} while (0)
263 
264 /* Used to check an Lua function type in the stack. It creates and
265  * returns a reference of the function. This function throws an
266  * error if the rgument is not a "function".
267  */
hlua_checkfunction(lua_State * L,int argno)268 __LJMP unsigned int hlua_checkfunction(lua_State *L, int argno)
269 {
270 	if (!lua_isfunction(L, argno)) {
271 		const char *msg = lua_pushfstring(L, "function expected, got %s", luaL_typename(L, argno));
272 		WILL_LJMP(luaL_argerror(L, argno, msg));
273 	}
274 	lua_pushvalue(L, argno);
275 	return luaL_ref(L, LUA_REGISTRYINDEX);
276 }
277 
278 /* Return the string that is of the top of the stack. */
hlua_get_top_error_string(lua_State * L)279 const char *hlua_get_top_error_string(lua_State *L)
280 {
281 	if (lua_gettop(L) < 1)
282 		return "unknown error";
283 	if (lua_type(L, -1) != LUA_TSTRING)
284 		return "unknown error";
285 	return lua_tostring(L, -1);
286 }
287 
hlua_traceback(lua_State * L)288 __LJMP static const char *hlua_traceback(lua_State *L)
289 {
290 	lua_Debug ar;
291 	int level = 0;
292 	struct buffer *msg = get_trash_chunk();
293 	int filled = 0;
294 
295 	while (lua_getstack(L, level++, &ar)) {
296 
297 		/* Add separator */
298 		if (filled)
299 			chunk_appendf(msg, ", ");
300 		filled = 1;
301 
302 		/* Fill fields:
303 		 * 'S': fills in the fields source, short_src, linedefined, lastlinedefined, and what;
304 		 * 'l': fills in the field currentline;
305 		 * 'n': fills in the field name and namewhat;
306 		 * 't': fills in the field istailcall;
307 		 */
308 		lua_getinfo(L, "Slnt", &ar);
309 
310 		/* Append code localisation */
311 		if (ar.currentline > 0)
312 			chunk_appendf(msg, "%s:%d ", ar.short_src, ar.currentline);
313 		else
314 			chunk_appendf(msg, "%s ", ar.short_src);
315 
316 		/*
317 		 * Get function name
318 		 *
319 		 * if namewhat is no empty, name is defined.
320 		 * what contains "Lua" for Lua function, "C" for C function,
321 		 * or "main" for main code.
322 		 */
323 		if (*ar.namewhat != '\0' && ar.name != NULL)  /* is there a name from code? */
324 			chunk_appendf(msg, "%s '%s'", ar.namewhat, ar.name);  /* use it */
325 
326 		else if (*ar.what == 'm')  /* "main", the code is not executed in a function */
327 			chunk_appendf(msg, "main chunk");
328 
329 		else if (*ar.what != 'C')  /* for Lua functions, use <file:line> */
330 			chunk_appendf(msg, "C function line %d", ar.linedefined);
331 
332 		else  /* nothing left... */
333 			chunk_appendf(msg, "?");
334 
335 
336 		/* Display tailed call */
337 		if (ar.istailcall)
338 			chunk_appendf(msg, " ...");
339 	}
340 
341 	return msg->area;
342 }
343 
344 
345 /* This function check the number of arguments available in the
346  * stack. If the number of arguments available is not the same
347  * then <nb> an error is throwed.
348  */
check_args(lua_State * L,int nb,char * fcn)349 __LJMP static inline void check_args(lua_State *L, int nb, char *fcn)
350 {
351 	if (lua_gettop(L) == nb)
352 		return;
353 	WILL_LJMP(luaL_error(L, "'%s' needs %d arguments", fcn, nb));
354 }
355 
356 /* This function pushes an error string prefixed by the file name
357  * and the line number where the error is encountered.
358  */
hlua_pusherror(lua_State * L,const char * fmt,...)359 static int hlua_pusherror(lua_State *L, const char *fmt, ...)
360 {
361 	va_list argp;
362 	va_start(argp, fmt);
363 	luaL_where(L, 1);
364 	lua_pushvfstring(L, fmt, argp);
365 	va_end(argp);
366 	lua_concat(L, 2);
367 	return 1;
368 }
369 
370 /* This functions is used with sample fetch and converters. It
371  * converts the HAProxy configuration argument in a lua stack
372  * values.
373  *
374  * It takes an array of "arg", and each entry of the array is
375  * converted and pushed in the LUA stack.
376  */
hlua_arg2lua(lua_State * L,const struct arg * arg)377 static int hlua_arg2lua(lua_State *L, const struct arg *arg)
378 {
379 	switch (arg->type) {
380 	case ARGT_SINT:
381 	case ARGT_TIME:
382 	case ARGT_SIZE:
383 		lua_pushinteger(L, arg->data.sint);
384 		break;
385 
386 	case ARGT_STR:
387 		lua_pushlstring(L, arg->data.str.area, arg->data.str.data);
388 		break;
389 
390 	case ARGT_IPV4:
391 	case ARGT_IPV6:
392 	case ARGT_MSK4:
393 	case ARGT_MSK6:
394 	case ARGT_FE:
395 	case ARGT_BE:
396 	case ARGT_TAB:
397 	case ARGT_SRV:
398 	case ARGT_USR:
399 	case ARGT_MAP:
400 	default:
401 		lua_pushnil(L);
402 		break;
403 	}
404 	return 1;
405 }
406 
407 /* This function take one entrie in an LUA stack at the index "ud",
408  * and try to convert it in an HAProxy argument entry. This is useful
409  * with sample fetch wrappers. The input arguments are gived to the
410  * lua wrapper and converted as arg list by thi function.
411  */
hlua_lua2arg(lua_State * L,int ud,struct arg * arg)412 static int hlua_lua2arg(lua_State *L, int ud, struct arg *arg)
413 {
414 	switch (lua_type(L, ud)) {
415 
416 	case LUA_TNUMBER:
417 	case LUA_TBOOLEAN:
418 		arg->type = ARGT_SINT;
419 		arg->data.sint = lua_tointeger(L, ud);
420 		break;
421 
422 	case LUA_TSTRING:
423 		arg->type = ARGT_STR;
424 		arg->data.str.area = (char *)lua_tolstring(L, ud, &arg->data.str.data);
425 		/* We don't know the actual size of the underlying allocation, so be conservative. */
426 		arg->data.str.size = arg->data.str.data+1; /* count the terminating null byte */
427 		arg->data.str.head = 0;
428 		break;
429 
430 	case LUA_TUSERDATA:
431 	case LUA_TNIL:
432 	case LUA_TTABLE:
433 	case LUA_TFUNCTION:
434 	case LUA_TTHREAD:
435 	case LUA_TLIGHTUSERDATA:
436 		arg->type = ARGT_SINT;
437 		arg->data.sint = 0;
438 		break;
439 	}
440 	return 1;
441 }
442 
443 /* the following functions are used to convert a struct sample
444  * in Lua type. This useful to convert the return of the
445  * fetchs or converters.
446  */
hlua_smp2lua(lua_State * L,struct sample * smp)447 static int hlua_smp2lua(lua_State *L, struct sample *smp)
448 {
449 	switch (smp->data.type) {
450 	case SMP_T_SINT:
451 	case SMP_T_BOOL:
452 		lua_pushinteger(L, smp->data.u.sint);
453 		break;
454 
455 	case SMP_T_BIN:
456 	case SMP_T_STR:
457 		lua_pushlstring(L, smp->data.u.str.area, smp->data.u.str.data);
458 		break;
459 
460 	case SMP_T_METH:
461 		switch (smp->data.u.meth.meth) {
462 		case HTTP_METH_OPTIONS: lua_pushstring(L, "OPTIONS"); break;
463 		case HTTP_METH_GET:     lua_pushstring(L, "GET");     break;
464 		case HTTP_METH_HEAD:    lua_pushstring(L, "HEAD");    break;
465 		case HTTP_METH_POST:    lua_pushstring(L, "POST");    break;
466 		case HTTP_METH_PUT:     lua_pushstring(L, "PUT");     break;
467 		case HTTP_METH_DELETE:  lua_pushstring(L, "DELETE");  break;
468 		case HTTP_METH_TRACE:   lua_pushstring(L, "TRACE");   break;
469 		case HTTP_METH_CONNECT: lua_pushstring(L, "CONNECT"); break;
470 		case HTTP_METH_OTHER:
471 			lua_pushlstring(L, smp->data.u.meth.str.area, smp->data.u.meth.str.data);
472 			break;
473 		default:
474 			lua_pushnil(L);
475 			break;
476 		}
477 		break;
478 
479 	case SMP_T_IPV4:
480 	case SMP_T_IPV6:
481 	case SMP_T_ADDR: /* This type is never used to qualify a sample. */
482 		if (sample_casts[smp->data.type][SMP_T_STR] &&
483 		    sample_casts[smp->data.type][SMP_T_STR](smp))
484 			lua_pushlstring(L, smp->data.u.str.area, smp->data.u.str.data);
485 		else
486 			lua_pushnil(L);
487 		break;
488 	default:
489 		lua_pushnil(L);
490 		break;
491 	}
492 	return 1;
493 }
494 
495 /* the following functions are used to convert a struct sample
496  * in Lua strings. This is useful to convert the return of the
497  * fetchs or converters.
498  */
hlua_smp2lua_str(lua_State * L,struct sample * smp)499 static int hlua_smp2lua_str(lua_State *L, struct sample *smp)
500 {
501 	switch (smp->data.type) {
502 
503 	case SMP_T_BIN:
504 	case SMP_T_STR:
505 		lua_pushlstring(L, smp->data.u.str.area, smp->data.u.str.data);
506 		break;
507 
508 	case SMP_T_METH:
509 		switch (smp->data.u.meth.meth) {
510 		case HTTP_METH_OPTIONS: lua_pushstring(L, "OPTIONS"); break;
511 		case HTTP_METH_GET:     lua_pushstring(L, "GET");     break;
512 		case HTTP_METH_HEAD:    lua_pushstring(L, "HEAD");    break;
513 		case HTTP_METH_POST:    lua_pushstring(L, "POST");    break;
514 		case HTTP_METH_PUT:     lua_pushstring(L, "PUT");     break;
515 		case HTTP_METH_DELETE:  lua_pushstring(L, "DELETE");  break;
516 		case HTTP_METH_TRACE:   lua_pushstring(L, "TRACE");   break;
517 		case HTTP_METH_CONNECT: lua_pushstring(L, "CONNECT"); break;
518 		case HTTP_METH_OTHER:
519 			lua_pushlstring(L, smp->data.u.meth.str.area, smp->data.u.meth.str.data);
520 			break;
521 		default:
522 			lua_pushstring(L, "");
523 			break;
524 		}
525 		break;
526 
527 	case SMP_T_SINT:
528 	case SMP_T_BOOL:
529 	case SMP_T_IPV4:
530 	case SMP_T_IPV6:
531 	case SMP_T_ADDR: /* This type is never used to qualify a sample. */
532 		if (sample_casts[smp->data.type][SMP_T_STR] &&
533 		    sample_casts[smp->data.type][SMP_T_STR](smp))
534 			lua_pushlstring(L, smp->data.u.str.area, smp->data.u.str.data);
535 		else
536 			lua_pushstring(L, "");
537 		break;
538 	default:
539 		lua_pushstring(L, "");
540 		break;
541 	}
542 	return 1;
543 }
544 
545 /* the following functions are used to convert an Lua type in a
546  * struct sample. This is useful to provide data from a converter
547  * to the LUA code.
548  */
hlua_lua2smp(lua_State * L,int ud,struct sample * smp)549 static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp)
550 {
551 	switch (lua_type(L, ud)) {
552 
553 	case LUA_TNUMBER:
554 		smp->data.type = SMP_T_SINT;
555 		smp->data.u.sint = lua_tointeger(L, ud);
556 		break;
557 
558 
559 	case LUA_TBOOLEAN:
560 		smp->data.type = SMP_T_BOOL;
561 		smp->data.u.sint = lua_toboolean(L, ud);
562 		break;
563 
564 	case LUA_TSTRING:
565 		smp->data.type = SMP_T_STR;
566 		smp->flags |= SMP_F_CONST;
567 		smp->data.u.str.area = (char *)lua_tolstring(L, ud, &smp->data.u.str.data);
568 		/* We don't know the actual size of the underlying allocation, so be conservative. */
569 		smp->data.u.str.size = smp->data.u.str.data+1; /* count the terminating null byte */
570 		smp->data.u.str.head = 0;
571 		break;
572 
573 	case LUA_TUSERDATA:
574 	case LUA_TNIL:
575 	case LUA_TTABLE:
576 	case LUA_TFUNCTION:
577 	case LUA_TTHREAD:
578 	case LUA_TLIGHTUSERDATA:
579 	case LUA_TNONE:
580 	default:
581 		smp->data.type = SMP_T_BOOL;
582 		smp->data.u.sint = 0;
583 		break;
584 	}
585 	return 1;
586 }
587 
588 /* This function check the "argp" builded by another conversion function
589  * is in accord with the expected argp defined by the "mask". The function
590  * returns true or false. It can be adjust the types if there compatibles.
591  *
592  * This function assumes thant the argp argument contains ARGM_NBARGS + 1
593  * entries.
594  */
hlua_lua2arg_check(lua_State * L,int first,struct arg * argp,uint64_t mask,struct proxy * p)595 __LJMP int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp,
596                               uint64_t mask, struct proxy *p)
597 {
598 	int min_arg;
599 	int i, idx;
600 	struct proxy *px;
601 	const char *msg = NULL;
602 	char *sname, *pname;
603 
604 	idx = 0;
605 	min_arg = ARGM(mask);
606 	mask >>= ARGM_BITS;
607 
608 	while (1) {
609 		struct buffer tmp = BUF_NULL;
610 
611 		/* Check oversize. */
612 		if (idx >= ARGM_NBARGS && argp[idx].type != ARGT_STOP) {
613 			msg = "Malformed argument mask";
614 			goto error;
615 		}
616 
617 		/* Check for mandatory arguments. */
618 		if (argp[idx].type == ARGT_STOP) {
619 			if (idx < min_arg) {
620 
621 				/* If miss other argument than the first one, we return an error. */
622 				if (idx > 0) {
623 					msg = "Mandatory argument expected";
624 					goto error;
625 				}
626 
627 				/* If first argument have a certain type, some default values
628 				 * may be used. See the function smp_resolve_args().
629 				 */
630 				switch (mask & ARGT_MASK) {
631 
632 				case ARGT_FE:
633 					if (!(p->cap & PR_CAP_FE)) {
634 						msg = "Mandatory argument expected";
635 						goto error;
636 					}
637 					argp[idx].data.prx = p;
638 					argp[idx].type = ARGT_FE;
639 					argp[idx+1].type = ARGT_STOP;
640 					break;
641 
642 				case ARGT_BE:
643 					if (!(p->cap & PR_CAP_BE)) {
644 						msg = "Mandatory argument expected";
645 						goto error;
646 					}
647 					argp[idx].data.prx = p;
648 					argp[idx].type = ARGT_BE;
649 					argp[idx+1].type = ARGT_STOP;
650 					break;
651 
652 				case ARGT_TAB:
653 					argp[idx].data.prx = p;
654 					argp[idx].type = ARGT_TAB;
655 					argp[idx+1].type = ARGT_STOP;
656 					break;
657 
658 				default:
659 					msg = "Mandatory argument expected";
660 					goto error;
661 					break;
662 				}
663 			}
664 			break;
665 		}
666 
667 		/* Check for exceed the number of requiered argument. */
668 		if ((mask & ARGT_MASK) == ARGT_STOP &&
669 		    argp[idx].type != ARGT_STOP) {
670 			msg = "Last argument expected";
671 			goto error;
672 		}
673 
674 		if ((mask & ARGT_MASK) == ARGT_STOP &&
675 		    argp[idx].type == ARGT_STOP) {
676 			break;
677 		}
678 
679 		/* Convert some argument types. All string in argp[] are for not
680 		 * duplicated yet.
681 		 */
682 		switch (mask & ARGT_MASK) {
683 		case ARGT_SINT:
684 			if (argp[idx].type != ARGT_SINT) {
685 				msg = "integer expected";
686 				goto error;
687 			}
688 			argp[idx].type = ARGT_SINT;
689 			break;
690 
691 		case ARGT_TIME:
692 			if (argp[idx].type != ARGT_SINT) {
693 				msg = "integer expected";
694 				goto error;
695 			}
696 			argp[idx].type = ARGT_TIME;
697 			break;
698 
699 		case ARGT_SIZE:
700 			if (argp[idx].type != ARGT_SINT) {
701 				msg = "integer expected";
702 				goto error;
703 			}
704 			argp[idx].type = ARGT_SIZE;
705 			break;
706 
707 		case ARGT_FE:
708 			if (argp[idx].type != ARGT_STR) {
709 				msg = "string expected";
710 				goto error;
711 			}
712 			argp[idx].data.prx = proxy_fe_by_name(argp[idx].data.str.area);
713 			if (!argp[idx].data.prx) {
714 				msg = "frontend doesn't exist";
715 				goto error;
716 			}
717 			argp[idx].type = ARGT_FE;
718 			break;
719 
720 		case ARGT_BE:
721 			if (argp[idx].type != ARGT_STR) {
722 				msg = "string expected";
723 				goto error;
724 			}
725 			argp[idx].data.prx = proxy_be_by_name(argp[idx].data.str.area);
726 			if (!argp[idx].data.prx) {
727 				msg = "backend doesn't exist";
728 				goto error;
729 			}
730 			argp[idx].type = ARGT_BE;
731 			break;
732 
733 		case ARGT_TAB:
734 			if (argp[idx].type != ARGT_STR) {
735 				msg = "string expected";
736 				goto error;
737 			}
738 			argp[idx].data.t = stktable_find_by_name(argp[idx].data.str.area);
739 			if (!argp[idx].data.t) {
740 				msg = "table doesn't exist";
741 				goto error;
742 			}
743 			argp[idx].type = ARGT_TAB;
744 			break;
745 
746 		case ARGT_SRV:
747 			if (argp[idx].type != ARGT_STR) {
748 				msg = "string expected";
749 				goto error;
750 			}
751 			sname = strrchr(argp[idx].data.str.area, '/');
752 			if (sname) {
753 				*sname++ = '\0';
754 				pname = argp[idx].data.str.area;
755 				px = proxy_be_by_name(pname);
756 				if (!px) {
757 					msg = "backend doesn't exist";
758 					goto error;
759 				}
760 			}
761 			else {
762 				sname = argp[idx].data.str.area;
763 				px = p;
764 			}
765 			argp[idx].data.srv = findserver(px, sname);
766 			if (!argp[idx].data.srv) {
767 				msg = "server doesn't exist";
768 				goto error;
769 			}
770 			argp[idx].type = ARGT_SRV;
771 			break;
772 
773 		case ARGT_IPV4:
774 			if (argp[idx].type != ARGT_STR) {
775 				msg = "string expected";
776 				goto error;
777 			}
778 			if (inet_pton(AF_INET, argp[idx].data.str.area, &argp[idx].data.ipv4)) {
779 				msg = "invalid IPv4 address";
780 				goto error;
781 			}
782 			argp[idx].type = ARGT_IPV4;
783 			break;
784 
785 		case ARGT_MSK4:
786 			if (argp[idx].type == ARGT_SINT)
787 				len2mask4(argp[idx].data.sint, &argp[idx].data.ipv4);
788 			else if (argp[idx].type == ARGT_STR) {
789 				if (!str2mask(argp[idx].data.str.area, &argp[idx].data.ipv4)) {
790 					msg = "invalid IPv4 mask";
791 					goto error;
792 				}
793 			}
794 			else  {
795 				msg = "integer or string expected";
796 				goto error;
797 			}
798 			argp[idx].type = ARGT_MSK4;
799 			break;
800 
801 		case ARGT_IPV6:
802 			if (argp[idx].type != ARGT_STR) {
803 				msg = "string expected";
804 				goto error;
805 			}
806 			if (inet_pton(AF_INET6, argp[idx].data.str.area, &argp[idx].data.ipv6)) {
807 				msg = "invalid IPv6 address";
808 				goto error;
809 			}
810 			argp[idx].type = ARGT_IPV6;
811 			break;
812 
813 		case ARGT_MSK6:
814 			if (argp[idx].type == ARGT_SINT)
815 				len2mask6(argp[idx].data.sint, &argp[idx].data.ipv6);
816 			else if (argp[idx].type == ARGT_STR) {
817 				if (!str2mask6(argp[idx].data.str.area, &argp[idx].data.ipv6)) {
818 					msg = "invalid IPv6 mask";
819 					goto error;
820 				}
821 			}
822 			else {
823 				msg = "integer or string expected";
824 				goto error;
825 			}
826 			argp[idx].type = ARGT_MSK6;
827 			break;
828 
829 		case ARGT_MAP:
830 		case ARGT_REG:
831 		case ARGT_USR:
832 			msg = "type not yet supported";
833 			goto error;
834 			break;
835 
836 		case ARGT_STR:
837 			if (!chunk_dup(&tmp, &argp[idx].data.str)) {
838 				msg = "unable to duplicate string arg";
839 				goto error;
840 			}
841 			argp[idx].data.str = tmp;
842 			break;
843 
844 		}
845 
846 		/* Check for type of argument. */
847 		if ((mask & ARGT_MASK) != argp[idx].type) {
848 			msg = lua_pushfstring(L, "'%s' expected, got '%s'",
849 					      arg_type_names[(mask & ARGT_MASK)],
850 					      arg_type_names[argp[idx].type & ARGT_MASK]);
851 			goto error;
852 		}
853 
854 		/* Next argument. */
855 		mask >>= ARGT_BITS;
856 		idx++;
857 	}
858 	return 0;
859 
860   error:
861 	for (i = 0; i < idx; i++) {
862 		if (argp[i].type == ARGT_STR)
863 			chunk_destroy(&argp[i].data.str);
864 	}
865 	WILL_LJMP(luaL_argerror(L, first + idx, msg));
866 	return 0; /* Never reached */
867 }
868 
869 /*
870  * The following functions are used to make correspondance between the the
871  * executed lua pointer and the "struct hlua *" that contain the context.
872  *
873  *  - hlua_gethlua : return the hlua context associated with an lua_State.
874  *  - hlua_sethlua : create the association between hlua context and lua_state.
875  */
hlua_gethlua(lua_State * L)876 static inline struct hlua *hlua_gethlua(lua_State *L)
877 {
878 	struct hlua **hlua = lua_getextraspace(L);
879 	return *hlua;
880 }
hlua_sethlua(struct hlua * hlua)881 static inline void hlua_sethlua(struct hlua *hlua)
882 {
883 	struct hlua **hlua_store = lua_getextraspace(hlua->T);
884 	*hlua_store = hlua;
885 }
886 
887 /* This function is used to send logs. It try to send on screen (stderr)
888  * and on the default syslog server.
889  */
hlua_sendlog(struct proxy * px,int level,const char * msg)890 static inline void hlua_sendlog(struct proxy *px, int level, const char *msg)
891 {
892 	struct tm tm;
893 	char *p;
894 
895 	/* Cleanup the log message. */
896 	p = trash.area;
897 	for (; *msg != '\0'; msg++, p++) {
898 		if (p >= trash.area + trash.size - 1) {
899 			/* Break the message if exceed the buffer size. */
900 			*(p-4) = ' ';
901 			*(p-3) = '.';
902 			*(p-2) = '.';
903 			*(p-1) = '.';
904 			break;
905 		}
906 		if (isprint(*msg))
907 			*p = *msg;
908 		else
909 			*p = '.';
910 	}
911 	*p = '\0';
912 
913 	send_log(px, level, "%s\n", trash.area);
914 	if (!(global.mode & MODE_QUIET) || (global.mode & (MODE_VERBOSE | MODE_STARTING))) {
915 		if (level == LOG_DEBUG && !(global.mode & MODE_DEBUG))
916 			return;
917 
918 		get_localtime(date.tv_sec, &tm);
919 		fprintf(stderr, "[%s] %03d/%02d%02d%02d (%d) : %s\n",
920 		        log_levels[level], tm.tm_yday, tm.tm_hour, tm.tm_min, tm.tm_sec,
921 		        (int)getpid(), trash.area);
922 		fflush(stderr);
923 	}
924 }
925 
926 /* This function just ensure that the yield will be always
927  * returned with a timeout and permit to set some flags
928  */
hlua_yieldk(lua_State * L,int nresults,int ctx,lua_KFunction k,int timeout,unsigned int flags)929 __LJMP void hlua_yieldk(lua_State *L, int nresults, int ctx,
930                         lua_KFunction k, int timeout, unsigned int flags)
931 {
932 	struct hlua *hlua = hlua_gethlua(L);
933 
934 	/* Set the wake timeout. If timeout is required, we set
935 	 * the expiration time.
936 	 */
937 	hlua->wake_time = timeout;
938 
939 	hlua->flags |= flags;
940 
941 	/* Process the yield. */
942 	MAY_LJMP(lua_yieldk(L, nresults, ctx, k));
943 }
944 
945 /* This function initialises the Lua environment stored in the stream.
946  * It must be called at the start of the stream. This function creates
947  * an LUA coroutine. It can not be use to crete the main LUA context.
948  *
949  * This function is particular. it initialises a new Lua thread. If the
950  * initialisation fails (example: out of memory error), the lua function
951  * throws an error (longjmp).
952  *
953  * In some case (at least one), this function can be called from safe
954  * environement, so we must not initialise it. While the support of
955  * threads appear, the safe environment set a lock to ensure only one
956  * Lua execution at a time. If we initialize safe environment in another
957  * safe environmenet, we have a dead lock.
958  *
959  * set "already_safe" true if the context is initialized form safe
960  * Lua fonction.
961  *
962  * This function manipulates two Lua stacks: the main and the thread. Only
963  * the main stack can fail. The thread is not manipulated. This function
964  * MUST NOT manipulate the created thread stack state, because it is not
965  * proctected against errors thrown by the thread stack.
966  */
hlua_ctx_init(struct hlua * lua,struct task * task,int already_safe)967 int hlua_ctx_init(struct hlua *lua, struct task *task, int already_safe)
968 {
969 	if (!already_safe) {
970 		if (!SET_SAFE_LJMP(gL.T)) {
971 			lua->Tref = LUA_REFNIL;
972 			return 0;
973 		}
974 	}
975 	lua->Mref = LUA_REFNIL;
976 	lua->flags = 0;
977 	LIST_INIT(&lua->com);
978 	lua->T = lua_newthread(gL.T);
979 	if (!lua->T) {
980 		lua->Tref = LUA_REFNIL;
981 		if (!already_safe)
982 			RESET_SAFE_LJMP(gL.T);
983 		return 0;
984 	}
985 	hlua_sethlua(lua);
986 	lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
987 	lua->task = task;
988 	if (!already_safe)
989 		RESET_SAFE_LJMP(gL.T);
990 	return 1;
991 }
992 
993 /* Used to destroy the Lua coroutine when the attached stream or task
994  * is destroyed. The destroy also the memory context. The struct "lua"
995  * is not freed.
996  */
hlua_ctx_destroy(struct hlua * lua)997 void hlua_ctx_destroy(struct hlua *lua)
998 {
999 	if (!lua)
1000 		return;
1001 
1002 	if (!lua->T)
1003 		goto end;
1004 
1005 	/* Purge all the pending signals. */
1006 	notification_purge(&lua->com);
1007 
1008 	if (!SET_SAFE_LJMP(lua->T))
1009 		return;
1010 	luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
1011 	RESET_SAFE_LJMP(lua->T);
1012 
1013 	if (!SET_SAFE_LJMP(gL.T))
1014 		return;
1015 	luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
1016 	RESET_SAFE_LJMP(gL.T);
1017 	/* Forces a garbage collecting process. If the Lua program is finished
1018 	 * without error, we run the GC on the thread pointer. Its freed all
1019 	 * the unused memory.
1020 	 * If the thread is finnish with an error or is currently yielded,
1021 	 * it seems that the GC applied on the thread doesn't clean anything,
1022 	 * so e run the GC on the main thread.
1023 	 * NOTE: maybe this action locks all the Lua threads untiml the en of
1024 	 * the garbage collection.
1025 	 */
1026 	if (lua->flags & HLUA_MUST_GC) {
1027 		if (!SET_SAFE_LJMP(gL.T))
1028 			return;
1029 		lua_gc(gL.T, LUA_GCCOLLECT, 0);
1030 		RESET_SAFE_LJMP(gL.T);
1031 	}
1032 
1033 	lua->T = NULL;
1034 
1035 end:
1036 	pool_free(pool_head_hlua, lua);
1037 }
1038 
1039 /* This function is used to restore the Lua context when a coroutine
1040  * fails. This function copy the common memory between old coroutine
1041  * and the new coroutine. The old coroutine is destroyed, and its
1042  * replaced by the new coroutine.
1043  * If the flag "keep_msg" is set, the last entry of the old is assumed
1044  * as string error message and it is copied in the new stack.
1045  */
hlua_ctx_renew(struct hlua * lua,int keep_msg)1046 static int hlua_ctx_renew(struct hlua *lua, int keep_msg)
1047 {
1048 	lua_State *T;
1049 	int new_ref;
1050 
1051 	/* Renew the main LUA stack doesn't have sense. */
1052 	if (lua == &gL)
1053 		return 0;
1054 
1055 	/* New Lua coroutine. */
1056 	T = lua_newthread(gL.T);
1057 	if (!T)
1058 		return 0;
1059 
1060 	/* Copy last error message. */
1061 	if (keep_msg)
1062 		lua_xmove(lua->T, T, 1);
1063 
1064 	/* Copy data between the coroutines. */
1065 	lua_rawgeti(lua->T, LUA_REGISTRYINDEX, lua->Mref);
1066 	lua_xmove(lua->T, T, 1);
1067 	new_ref = luaL_ref(T, LUA_REGISTRYINDEX); /* Valur poped. */
1068 
1069 	/* Destroy old data. */
1070 	luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
1071 
1072 	/* The thread is garbage collected by Lua. */
1073 	luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
1074 
1075 	/* Fill the struct with the new coroutine values. */
1076 	lua->Mref = new_ref;
1077 	lua->T = T;
1078 	lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
1079 
1080 	/* Set context. */
1081 	hlua_sethlua(lua);
1082 
1083 	return 1;
1084 }
1085 
hlua_hook(lua_State * L,lua_Debug * ar)1086 void hlua_hook(lua_State *L, lua_Debug *ar)
1087 {
1088 	struct hlua *hlua = hlua_gethlua(L);
1089 
1090 	/* Lua cannot yield when its returning from a function,
1091 	 * so, we can fix the interrupt hook to 1 instruction,
1092 	 * expecting that the function is finnished.
1093 	 */
1094 	if (lua_gethookmask(L) & LUA_MASKRET) {
1095 		lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, 1);
1096 		return;
1097 	}
1098 
1099 	/* restore the interrupt condition. */
1100 	lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, hlua_nb_instruction);
1101 
1102 	/* If we interrupt the Lua processing in yieldable state, we yield.
1103 	 * If the state is not yieldable, trying yield causes an error.
1104 	 */
1105 	if (lua_isyieldable(L))
1106 		MAY_LJMP(hlua_yieldk(L, 0, 0, NULL, TICK_ETERNITY, HLUA_CTRLYIELD));
1107 
1108 	/* If we cannot yield, update the clock and check the timeout. */
1109 	tv_update_date(0, 1);
1110 	hlua->run_time += now_ms - hlua->start_time;
1111 	if (hlua->max_time && hlua->run_time >= hlua->max_time) {
1112 		lua_pushfstring(L, "execution timeout");
1113 		WILL_LJMP(lua_error(L));
1114 	}
1115 
1116 	/* Update the start time. */
1117 	hlua->start_time = now_ms;
1118 
1119 	/* Try to interrupt the process at the end of the current
1120 	 * unyieldable function.
1121 	 */
1122 	lua_sethook(hlua->T, hlua_hook, LUA_MASKRET|LUA_MASKCOUNT, hlua_nb_instruction);
1123 }
1124 
1125 /* This function start or resumes the Lua stack execution. If the flag
1126  * "yield_allowed" if no set and the  LUA stack execution returns a yield
1127  * The function return an error.
1128  *
1129  * The function can returns 4 values:
1130  *  - HLUA_E_OK     : The execution is terminated without any errors.
1131  *  - HLUA_E_AGAIN  : The execution must continue at the next associated
1132  *                    task wakeup.
1133  *  - HLUA_E_ERRMSG : An error has occurred, an error message is set in
1134  *                    the top of the stack.
1135  *  - HLUA_E_ERR    : An error has occurred without error message.
1136  *
1137  * If an error occurred, the stack is renewed and it is ready to run new
1138  * LUA code.
1139  */
hlua_ctx_resume(struct hlua * lua,int yield_allowed)1140 static enum hlua_exec hlua_ctx_resume(struct hlua *lua, int yield_allowed)
1141 {
1142 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 504
1143 	int nres;
1144 #endif
1145 	int ret;
1146 	const char *msg;
1147 	const char *trace;
1148 
1149 	/* Initialise run time counter. */
1150 	if (!HLUA_IS_RUNNING(lua))
1151 		lua->run_time = 0;
1152 
1153 	/* Lock the whole Lua execution. This lock must be before the
1154 	 * label "resume_execution".
1155 	 */
1156 	HA_SPIN_LOCK(LUA_LOCK, &hlua_global_lock);
1157 
1158 resume_execution:
1159 
1160 	/* This hook interrupts the Lua processing each 'hlua_nb_instruction'
1161 	 * instructions. it is used for preventing infinite loops.
1162 	 */
1163 	lua_sethook(lua->T, hlua_hook, LUA_MASKCOUNT, hlua_nb_instruction);
1164 
1165 	/* Remove all flags except the running flags. */
1166 	HLUA_SET_RUN(lua);
1167 	HLUA_CLR_CTRLYIELD(lua);
1168 	HLUA_CLR_WAKERESWR(lua);
1169 	HLUA_CLR_WAKEREQWR(lua);
1170 
1171 	/* Update the start time. */
1172 	lua->start_time = now_ms;
1173 
1174 	/* Call the function. */
1175 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 504
1176 	ret = lua_resume(lua->T, gL.T, lua->nargs, &nres);
1177 #else
1178 	ret = lua_resume(lua->T, gL.T, lua->nargs);
1179 #endif
1180 	switch (ret) {
1181 
1182 	case LUA_OK:
1183 		ret = HLUA_E_OK;
1184 		break;
1185 
1186 	case LUA_YIELD:
1187 		/* Check if the execution timeout is expired. It it is the case, we
1188 		 * break the Lua execution.
1189 		 */
1190 		tv_update_date(0, 1);
1191 		lua->run_time += now_ms - lua->start_time;
1192 		if (lua->max_time && lua->run_time > lua->max_time) {
1193 			lua_settop(lua->T, 0); /* Empty the stack. */
1194 			ret = HLUA_E_ETMOUT;
1195 			break;
1196 		}
1197 		/* Process the forced yield. if the general yield is not allowed or
1198 		 * if no task were associated this the current Lua execution
1199 		 * coroutine, we resume the execution. Else we want to return in the
1200 		 * scheduler and we want to be waked up again, to continue the
1201 		 * current Lua execution. So we schedule our own task.
1202 		 */
1203 		if (HLUA_IS_CTRLYIELDING(lua)) {
1204 			if (!yield_allowed || !lua->task)
1205 				goto resume_execution;
1206 			task_wakeup(lua->task, TASK_WOKEN_MSG);
1207 		}
1208 		if (!yield_allowed) {
1209 			lua_settop(lua->T, 0); /* Empty the stack. */
1210 			ret = HLUA_E_YIELD;
1211 			break;
1212 		}
1213 		ret = HLUA_E_AGAIN;
1214 		break;
1215 
1216 	case LUA_ERRRUN:
1217 
1218 		/* Special exit case. The traditional exit is returned as an error
1219 		 * because the errors ares the only one mean to return immediately
1220 		 * from and lua execution.
1221 		 */
1222 		if (lua->flags & HLUA_EXIT) {
1223 			ret = HLUA_E_OK;
1224 			hlua_ctx_renew(lua, 0);
1225 			break;
1226 		}
1227 
1228 		lua->wake_time = TICK_ETERNITY;
1229 		if (!lua_checkstack(lua->T, 1)) {
1230 			ret = HLUA_E_ERR;
1231 			break;
1232 		}
1233 		msg = lua_tostring(lua->T, -1);
1234 		lua_settop(lua->T, 0); /* Empty the stack. */
1235 		lua_pop(lua->T, 1);
1236 		trace = hlua_traceback(lua->T);
1237 		if (msg)
1238 			lua_pushfstring(lua->T, "runtime error: %s from %s", msg, trace);
1239 		else
1240 			lua_pushfstring(lua->T, "unknown runtime error from %s", trace);
1241 		ret = HLUA_E_ERRMSG;
1242 		break;
1243 
1244 	case LUA_ERRMEM:
1245 		lua->wake_time = TICK_ETERNITY;
1246 		lua_settop(lua->T, 0); /* Empty the stack. */
1247 		ret = HLUA_E_NOMEM;
1248 		break;
1249 
1250 	case LUA_ERRERR:
1251 		lua->wake_time = TICK_ETERNITY;
1252 		if (!lua_checkstack(lua->T, 1)) {
1253 			ret = HLUA_E_ERR;
1254 			break;
1255 		}
1256 		msg = lua_tostring(lua->T, -1);
1257 		lua_settop(lua->T, 0); /* Empty the stack. */
1258 		lua_pop(lua->T, 1);
1259 		if (msg)
1260 			lua_pushfstring(lua->T, "message handler error: %s", msg);
1261 		else
1262 			lua_pushfstring(lua->T, "message handler error");
1263 		ret = HLUA_E_ERRMSG;
1264 		break;
1265 
1266 	default:
1267 		lua->wake_time = TICK_ETERNITY;
1268 		lua_settop(lua->T, 0); /* Empty the stack. */
1269 		ret = HLUA_E_ERR;
1270 		break;
1271 	}
1272 
1273 	/* This GC permits to destroy some object when a Lua timeout strikes. */
1274 	if (lua->flags & HLUA_MUST_GC &&
1275 	    ret != HLUA_E_AGAIN)
1276 		lua_gc(lua->T, LUA_GCCOLLECT, 0);
1277 
1278 	switch (ret) {
1279 	case HLUA_E_AGAIN:
1280 		break;
1281 
1282 	case HLUA_E_ERRMSG:
1283 		notification_purge(&lua->com);
1284 		hlua_ctx_renew(lua, 1);
1285 		HLUA_CLR_RUN(lua);
1286 		break;
1287 
1288 	case HLUA_E_ETMOUT:
1289 	case HLUA_E_NOMEM:
1290 	case HLUA_E_YIELD:
1291 	case HLUA_E_ERR:
1292 		HLUA_CLR_RUN(lua);
1293 		notification_purge(&lua->com);
1294 		hlua_ctx_renew(lua, 0);
1295 		break;
1296 
1297 	case HLUA_E_OK:
1298 		HLUA_CLR_RUN(lua);
1299 		notification_purge(&lua->com);
1300 		break;
1301 	}
1302 
1303 	/* This is the main exit point, remove the Lua lock. */
1304 	HA_SPIN_UNLOCK(LUA_LOCK, &hlua_global_lock);
1305 
1306 	return ret;
1307 }
1308 
1309 /* This function exit the current code. */
hlua_done(lua_State * L)1310 __LJMP static int hlua_done(lua_State *L)
1311 {
1312 	struct hlua *hlua = hlua_gethlua(L);
1313 
1314 	hlua->flags |= HLUA_EXIT;
1315 	WILL_LJMP(lua_error(L));
1316 
1317 	return 0;
1318 }
1319 
1320 /* This function is an LUA binding. It provides a function
1321  * for deleting ACL from a referenced ACL file.
1322  */
hlua_del_acl(lua_State * L)1323 __LJMP static int hlua_del_acl(lua_State *L)
1324 {
1325 	const char *name;
1326 	const char *key;
1327 	struct pat_ref *ref;
1328 
1329 	MAY_LJMP(check_args(L, 2, "del_acl"));
1330 
1331 	name = MAY_LJMP(luaL_checkstring(L, 1));
1332 	key = MAY_LJMP(luaL_checkstring(L, 2));
1333 
1334 	ref = pat_ref_lookup(name);
1335 	if (!ref)
1336 		WILL_LJMP(luaL_error(L, "'del_acl': unknown acl file '%s'", name));
1337 
1338 	HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
1339 	pat_ref_delete(ref, key);
1340 	HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
1341 	return 0;
1342 }
1343 
1344 /* This function is an LUA binding. It provides a function
1345  * for deleting map entry from a referenced map file.
1346  */
hlua_del_map(lua_State * L)1347 static int hlua_del_map(lua_State *L)
1348 {
1349 	const char *name;
1350 	const char *key;
1351 	struct pat_ref *ref;
1352 
1353 	MAY_LJMP(check_args(L, 2, "del_map"));
1354 
1355 	name = MAY_LJMP(luaL_checkstring(L, 1));
1356 	key = MAY_LJMP(luaL_checkstring(L, 2));
1357 
1358 	ref = pat_ref_lookup(name);
1359 	if (!ref)
1360 		WILL_LJMP(luaL_error(L, "'del_map': unknown acl file '%s'", name));
1361 
1362 	HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
1363 	pat_ref_delete(ref, key);
1364 	HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
1365 	return 0;
1366 }
1367 
1368 /* This function is an LUA binding. It provides a function
1369  * for adding ACL pattern from a referenced ACL file.
1370  */
hlua_add_acl(lua_State * L)1371 static int hlua_add_acl(lua_State *L)
1372 {
1373 	const char *name;
1374 	const char *key;
1375 	struct pat_ref *ref;
1376 
1377 	MAY_LJMP(check_args(L, 2, "add_acl"));
1378 
1379 	name = MAY_LJMP(luaL_checkstring(L, 1));
1380 	key = MAY_LJMP(luaL_checkstring(L, 2));
1381 
1382 	ref = pat_ref_lookup(name);
1383 	if (!ref)
1384 		WILL_LJMP(luaL_error(L, "'add_acl': unknown acl file '%s'", name));
1385 
1386 	HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
1387 	if (pat_ref_find_elt(ref, key) == NULL)
1388 		pat_ref_add(ref, key, NULL, NULL);
1389 	HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
1390 	return 0;
1391 }
1392 
1393 /* This function is an LUA binding. It provides a function
1394  * for setting map pattern and sample from a referenced map
1395  * file.
1396  */
hlua_set_map(lua_State * L)1397 static int hlua_set_map(lua_State *L)
1398 {
1399 	const char *name;
1400 	const char *key;
1401 	const char *value;
1402 	struct pat_ref *ref;
1403 
1404 	MAY_LJMP(check_args(L, 3, "set_map"));
1405 
1406 	name = MAY_LJMP(luaL_checkstring(L, 1));
1407 	key = MAY_LJMP(luaL_checkstring(L, 2));
1408 	value = MAY_LJMP(luaL_checkstring(L, 3));
1409 
1410 	ref = pat_ref_lookup(name);
1411 	if (!ref)
1412 		WILL_LJMP(luaL_error(L, "'set_map': unknown map file '%s'", name));
1413 
1414 	HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
1415 	if (pat_ref_find_elt(ref, key) != NULL)
1416 		pat_ref_set(ref, key, value, NULL);
1417 	else
1418 		pat_ref_add(ref, key, value, NULL);
1419 	HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
1420 	return 0;
1421 }
1422 
1423 /* A class is a lot of memory that contain data. This data can be a table,
1424  * an integer or user data. This data is associated with a metatable. This
1425  * metatable have an original version registred in the global context with
1426  * the name of the object (_G[<name>] = <metable> ).
1427  *
1428  * A metable is a table that modify the standard behavior of a standard
1429  * access to the associated data. The entries of this new metatable are
1430  * defined as is:
1431  *
1432  * http://lua-users.org/wiki/MetatableEvents
1433  *
1434  *    __index
1435  *
1436  * we access an absent field in a table, the result is nil. This is
1437  * true, but it is not the whole truth. Actually, such access triggers
1438  * the interpreter to look for an __index metamethod: If there is no
1439  * such method, as usually happens, then the access results in nil;
1440  * otherwise, the metamethod will provide the result.
1441  *
1442  * Control 'prototype' inheritance. When accessing "myTable[key]" and
1443  * the key does not appear in the table, but the metatable has an __index
1444  * property:
1445  *
1446  * - if the value is a function, the function is called, passing in the
1447  *   table and the key; the return value of that function is returned as
1448  *   the result.
1449  *
1450  * - if the value is another table, the value of the key in that table is
1451  *   asked for and returned (and if it doesn't exist in that table, but that
1452  *   table's metatable has an __index property, then it continues on up)
1453  *
1454  * - Use "rawget(myTable,key)" to skip this metamethod.
1455  *
1456  * http://www.lua.org/pil/13.4.1.html
1457  *
1458  *    __newindex
1459  *
1460  * Like __index, but control property assignment.
1461  *
1462  *    __mode - Control weak references. A string value with one or both
1463  *             of the characters 'k' and 'v' which specifies that the the
1464  *             keys and/or values in the table are weak references.
1465  *
1466  *    __call - Treat a table like a function. When a table is followed by
1467  *             parenthesis such as "myTable( 'foo' )" and the metatable has
1468  *             a __call key pointing to a function, that function is invoked
1469  *             (passing any specified arguments) and the return value is
1470  *             returned.
1471  *
1472  *    __metatable - Hide the metatable. When "getmetatable( myTable )" is
1473  *                  called, if the metatable for myTable has a __metatable
1474  *                  key, the value of that key is returned instead of the
1475  *                  actual metatable.
1476  *
1477  *    __tostring - Control string representation. When the builtin
1478  *                 "tostring( myTable )" function is called, if the metatable
1479  *                 for myTable has a __tostring property set to a function,
1480  *                 that function is invoked (passing myTable to it) and the
1481  *                 return value is used as the string representation.
1482  *
1483  *    __len - Control table length. When the table length is requested using
1484  *            the length operator ( '#' ), if the metatable for myTable has
1485  *            a __len key pointing to a function, that function is invoked
1486  *            (passing myTable to it) and the return value used as the value
1487  *            of "#myTable".
1488  *
1489  *    __gc - Userdata finalizer code. When userdata is set to be garbage
1490  *           collected, if the metatable has a __gc field pointing to a
1491  *           function, that function is first invoked, passing the userdata
1492  *           to it. The __gc metamethod is not called for tables.
1493  *           (See http://lua-users.org/lists/lua-l/2006-11/msg00508.html)
1494  *
1495  * Special metamethods for redefining standard operators:
1496  * http://www.lua.org/pil/13.1.html
1497  *
1498  *    __add    "+"
1499  *    __sub    "-"
1500  *    __mul    "*"
1501  *    __div    "/"
1502  *    __unm    "!"
1503  *    __pow    "^"
1504  *    __concat ".."
1505  *
1506  * Special methods for redfining standar relations
1507  * http://www.lua.org/pil/13.2.html
1508  *
1509  *    __eq "=="
1510  *    __lt "<"
1511  *    __le "<="
1512  */
1513 
1514 /*
1515  *
1516  *
1517  * Class Map
1518  *
1519  *
1520  */
1521 
1522 /* Returns a struct hlua_map if the stack entry "ud" is
1523  * a class session, otherwise it throws an error.
1524  */
hlua_checkmap(lua_State * L,int ud)1525 __LJMP static struct map_descriptor *hlua_checkmap(lua_State *L, int ud)
1526 {
1527 	return MAY_LJMP(hlua_checkudata(L, ud, class_map_ref));
1528 }
1529 
1530 /* This function is the map constructor. It don't need
1531  * the class Map object. It creates and return a new Map
1532  * object. It must be called only during "body" or "init"
1533  * context because it process some filesystem accesses.
1534  */
hlua_map_new(struct lua_State * L)1535 __LJMP static int hlua_map_new(struct lua_State *L)
1536 {
1537 	const char *fn;
1538 	int match = PAT_MATCH_STR;
1539 	struct sample_conv conv;
1540 	const char *file = "";
1541 	int line = 0;
1542 	lua_Debug ar;
1543 	char *err = NULL;
1544 	struct arg args[2];
1545 
1546 	if (lua_gettop(L) < 1 || lua_gettop(L) > 2)
1547 		WILL_LJMP(luaL_error(L, "'new' needs at least 1 argument."));
1548 
1549 	fn = MAY_LJMP(luaL_checkstring(L, 1));
1550 
1551 	if (lua_gettop(L) >= 2) {
1552 		match = MAY_LJMP(luaL_checkinteger(L, 2));
1553 		if (match < 0 || match >= PAT_MATCH_NUM)
1554 			WILL_LJMP(luaL_error(L, "'new' needs a valid match method."));
1555 	}
1556 
1557 	/* Get Lua filename and line number. */
1558 	if (lua_getstack(L, 1, &ar)) {  /* check function at level */
1559 		lua_getinfo(L, "Sl", &ar);  /* get info about it */
1560 		if (ar.currentline > 0) {  /* is there info? */
1561 			file = ar.short_src;
1562 			line = ar.currentline;
1563 		}
1564 	}
1565 
1566 	/* fill fake sample_conv struct. */
1567 	conv.kw = ""; /* unused. */
1568 	conv.process = NULL; /* unused. */
1569 	conv.arg_mask = 0; /* unused. */
1570 	conv.val_args = NULL; /* unused. */
1571 	conv.out_type = SMP_T_STR;
1572 	conv.private = (void *)(long)match;
1573 	switch (match) {
1574 	case PAT_MATCH_STR: conv.in_type = SMP_T_STR;  break;
1575 	case PAT_MATCH_BEG: conv.in_type = SMP_T_STR;  break;
1576 	case PAT_MATCH_SUB: conv.in_type = SMP_T_STR;  break;
1577 	case PAT_MATCH_DIR: conv.in_type = SMP_T_STR;  break;
1578 	case PAT_MATCH_DOM: conv.in_type = SMP_T_STR;  break;
1579 	case PAT_MATCH_END: conv.in_type = SMP_T_STR;  break;
1580 	case PAT_MATCH_REG: conv.in_type = SMP_T_STR;  break;
1581 	case PAT_MATCH_INT: conv.in_type = SMP_T_SINT; break;
1582 	case PAT_MATCH_IP:  conv.in_type = SMP_T_ADDR; break;
1583 	default:
1584 		WILL_LJMP(luaL_error(L, "'new' doesn't support this match mode."));
1585 	}
1586 
1587 	/* fill fake args. */
1588 	args[0].type = ARGT_STR;
1589 	args[0].data.str.area = strdup(fn);
1590 	args[0].data.str.data = strlen(fn);
1591 	args[0].data.str.size = args[0].data.str.data+1;
1592 	args[1].type = ARGT_STOP;
1593 
1594 	/* load the map. */
1595 	if (!sample_load_map(args, &conv, file, line, &err)) {
1596 		/* error case: we cant use luaL_error because we must
1597 		 * free the err variable.
1598 		 */
1599 		luaL_where(L, 1);
1600 		lua_pushfstring(L, "'new': %s.", err);
1601 		lua_concat(L, 2);
1602 		free(err);
1603 		chunk_destroy(&args[0].data.str);
1604 		WILL_LJMP(lua_error(L));
1605 	}
1606 
1607 	/* create the lua object. */
1608 	lua_newtable(L);
1609 	lua_pushlightuserdata(L, args[0].data.map);
1610 	lua_rawseti(L, -2, 0);
1611 
1612 	/* Pop a class Map metatable and affect it to the userdata. */
1613 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_map_ref);
1614 	lua_setmetatable(L, -2);
1615 
1616 
1617 	return 1;
1618 }
1619 
_hlua_map_lookup(struct lua_State * L,int str)1620 __LJMP static inline int _hlua_map_lookup(struct lua_State *L, int str)
1621 {
1622 	struct map_descriptor *desc;
1623 	struct pattern *pat;
1624 	struct sample smp;
1625 
1626 	MAY_LJMP(check_args(L, 2, "lookup"));
1627 	desc = MAY_LJMP(hlua_checkmap(L, 1));
1628 	if (desc->pat.expect_type == SMP_T_SINT) {
1629 		smp.data.type = SMP_T_SINT;
1630 		smp.data.u.sint = MAY_LJMP(luaL_checkinteger(L, 2));
1631 	}
1632 	else {
1633 		smp.data.type = SMP_T_STR;
1634 		smp.flags = SMP_F_CONST;
1635 		smp.data.u.str.area = (char *)MAY_LJMP(luaL_checklstring(L, 2, (size_t *)&smp.data.u.str.data));
1636 		smp.data.u.str.size = smp.data.u.str.data + 1;
1637 	}
1638 
1639 	pat = pattern_exec_match(&desc->pat, &smp, 1);
1640 	if (!pat || !pat->data) {
1641 		if (str)
1642 			lua_pushstring(L, "");
1643 		else
1644 			lua_pushnil(L);
1645 		return 1;
1646 	}
1647 
1648 	/* The Lua pattern must return a string, so we can't check the returned type */
1649 	lua_pushlstring(L, pat->data->u.str.area, pat->data->u.str.data);
1650 	return 1;
1651 }
1652 
hlua_map_lookup(struct lua_State * L)1653 __LJMP static int hlua_map_lookup(struct lua_State *L)
1654 {
1655 	return _hlua_map_lookup(L, 0);
1656 }
1657 
hlua_map_slookup(struct lua_State * L)1658 __LJMP static int hlua_map_slookup(struct lua_State *L)
1659 {
1660 	return _hlua_map_lookup(L, 1);
1661 }
1662 
1663 /*
1664  *
1665  *
1666  * Class Socket
1667  *
1668  *
1669  */
1670 
hlua_checksocket(lua_State * L,int ud)1671 __LJMP static struct hlua_socket *hlua_checksocket(lua_State *L, int ud)
1672 {
1673 	return MAY_LJMP(hlua_checkudata(L, ud, class_socket_ref));
1674 }
1675 
1676 /* This function is the handler called for each I/O on the established
1677  * connection. It is used for notify space available to send or data
1678  * received.
1679  */
hlua_socket_handler(struct appctx * appctx)1680 static void hlua_socket_handler(struct appctx *appctx)
1681 {
1682 	struct stream_interface *si = appctx->owner;
1683 
1684 	if (appctx->ctx.hlua_cosocket.die) {
1685 		si_shutw(si);
1686 		si_shutr(si);
1687 		si_ic(si)->flags |= CF_READ_NULL;
1688 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read);
1689 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write);
1690 		stream_shutdown(si_strm(si), SF_ERR_KILLED);
1691 	}
1692 
1693 	/* If we cant write, wakeup the pending write signals. */
1694 	if (channel_output_closed(si_ic(si)))
1695 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write);
1696 
1697 	/* If we cant read, wakeup the pending read signals. */
1698 	if (channel_input_closed(si_oc(si)))
1699 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read);
1700 
1701 	/* if the connection is not established, inform the stream that we want
1702 	 * to be notified whenever the connection completes.
1703 	 */
1704 	if (si_opposite(si)->state < SI_ST_EST) {
1705 		si_cant_get(si);
1706 		si_rx_conn_blk(si);
1707 		si_rx_endp_more(si);
1708 		return;
1709 	}
1710 
1711 	/* This function is called after the connect. */
1712 	appctx->ctx.hlua_cosocket.connected = 1;
1713 
1714 	/* Wake the tasks which wants to write if the buffer have available space. */
1715 	if (channel_may_recv(si_ic(si)))
1716 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write);
1717 
1718 	/* Wake the tasks which wants to read if the buffer contains data. */
1719 	if (!channel_is_empty(si_oc(si)))
1720 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read);
1721 
1722 	/* Some data were injected in the buffer, notify the stream
1723 	 * interface.
1724 	 */
1725 	if (!channel_is_empty(si_ic(si)))
1726 		si_update(si);
1727 
1728 	/* If write notifications are registered, we considers we want
1729 	 * to write, so we clear the blocking flag.
1730 	 */
1731 	if (notification_registered(&appctx->ctx.hlua_cosocket.wake_on_write))
1732 		si_rx_endp_more(si);
1733 }
1734 
1735 /* This function is called when the "struct stream" is destroyed.
1736  * Remove the link from the object to this stream.
1737  * Wake all the pending signals.
1738  */
hlua_socket_release(struct appctx * appctx)1739 static void hlua_socket_release(struct appctx *appctx)
1740 {
1741 	struct xref *peer;
1742 
1743 	/* Remove my link in the original object. */
1744 	peer = xref_get_peer_and_lock(&appctx->ctx.hlua_cosocket.xref);
1745 	if (peer)
1746 		xref_disconnect(&appctx->ctx.hlua_cosocket.xref, peer);
1747 
1748 	/* Wake all the task waiting for me. */
1749 	notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read);
1750 	notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write);
1751 }
1752 
1753 /* If the garbage collectio of the object is launch, nobody
1754  * uses this object. If the stream does not exists, just quit.
1755  * Send the shutdown signal to the stream. In some cases,
1756  * pending signal can rest in the read and write lists. destroy
1757  * it.
1758  */
hlua_socket_gc(lua_State * L)1759 __LJMP static int hlua_socket_gc(lua_State *L)
1760 {
1761 	struct hlua_socket *socket;
1762 	struct appctx *appctx;
1763 	struct xref *peer;
1764 
1765 	MAY_LJMP(check_args(L, 1, "__gc"));
1766 
1767 	socket = MAY_LJMP(hlua_checksocket(L, 1));
1768 	peer = xref_get_peer_and_lock(&socket->xref);
1769 	if (!peer)
1770 		return 0;
1771 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
1772 
1773 	/* Set the flag which destroy the session. */
1774 	appctx->ctx.hlua_cosocket.die = 1;
1775 	appctx_wakeup(appctx);
1776 
1777 	/* Remove all reference between the Lua stack and the coroutine stream. */
1778 	xref_disconnect(&socket->xref, peer);
1779 	return 0;
1780 }
1781 
1782 /* The close function send shutdown signal and break the
1783  * links between the stream and the object.
1784  */
hlua_socket_close_helper(lua_State * L)1785 __LJMP static int hlua_socket_close_helper(lua_State *L)
1786 {
1787 	struct hlua_socket *socket;
1788 	struct appctx *appctx;
1789 	struct xref *peer;
1790 
1791 	socket = MAY_LJMP(hlua_checksocket(L, 1));
1792 
1793 	/* Check if we run on the same thread than the xreator thread.
1794 	 * We cannot access to the socket if the thread is different.
1795 	 */
1796 	if (socket->tid != tid)
1797 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
1798 
1799 	peer = xref_get_peer_and_lock(&socket->xref);
1800 	if (!peer)
1801 		return 0;
1802 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
1803 
1804 	/* Set the flag which destroy the session. */
1805 	appctx->ctx.hlua_cosocket.die = 1;
1806 	appctx_wakeup(appctx);
1807 
1808 	/* Remove all reference between the Lua stack and the coroutine stream. */
1809 	xref_disconnect(&socket->xref, peer);
1810 	return 0;
1811 }
1812 
1813 /* The close function calls close_helper.
1814  */
hlua_socket_close(lua_State * L)1815 __LJMP static int hlua_socket_close(lua_State *L)
1816 {
1817 	MAY_LJMP(check_args(L, 1, "close"));
1818 	return hlua_socket_close_helper(L);
1819 }
1820 
1821 /* This Lua function assumes that the stack contain three parameters.
1822  *  1 - USERDATA containing a struct socket
1823  *  2 - INTEGER with values of the macro defined below
1824  *      If the integer is -1, we must read at most one line.
1825  *      If the integer is -2, we ust read all the data until the
1826  *      end of the stream.
1827  *      If the integer is positive value, we must read a number of
1828  *      bytes corresponding to this value.
1829  */
1830 #define HLSR_READ_LINE (-1)
1831 #define HLSR_READ_ALL (-2)
hlua_socket_receive_yield(struct lua_State * L,int status,lua_KContext ctx)1832 __LJMP static int hlua_socket_receive_yield(struct lua_State *L, int status, lua_KContext ctx)
1833 {
1834 	struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1));
1835 	int wanted = lua_tointeger(L, 2);
1836 	struct hlua *hlua = hlua_gethlua(L);
1837 	struct appctx *appctx;
1838 	size_t len;
1839 	int nblk;
1840 	const char *blk1;
1841 	size_t len1;
1842 	const char *blk2;
1843 	size_t len2;
1844 	int skip_at_end = 0;
1845 	struct channel *oc;
1846 	struct stream_interface *si;
1847 	struct stream *s;
1848 	struct xref *peer;
1849 	int missing_bytes;
1850 
1851 	/* Check if this lua stack is schedulable. */
1852 	if (!hlua || !hlua->task)
1853 		WILL_LJMP(luaL_error(L, "The 'receive' function is only allowed in "
1854 		                      "'frontend', 'backend' or 'task'"));
1855 
1856 	/* Check if we run on the same thread than the xreator thread.
1857 	 * We cannot access to the socket if the thread is different.
1858 	 */
1859 	if (socket->tid != tid)
1860 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
1861 
1862 	/* check for connection break. If some data where read, return it. */
1863 	peer = xref_get_peer_and_lock(&socket->xref);
1864 	if (!peer)
1865 		goto no_peer;
1866 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
1867 	si = appctx->owner;
1868 	s = si_strm(si);
1869 
1870 	oc = &s->res;
1871 	if (wanted == HLSR_READ_LINE) {
1872 		/* Read line. */
1873 		nblk = co_getline_nc(oc, &blk1, &len1, &blk2, &len2);
1874 		if (nblk < 0) /* Connection close. */
1875 			goto connection_closed;
1876 		if (nblk == 0) /* No data available. */
1877 			goto connection_empty;
1878 
1879 		/* remove final \r\n. */
1880 		if (nblk == 1) {
1881 			if (blk1[len1-1] == '\n') {
1882 				len1--;
1883 				skip_at_end++;
1884 				if (blk1[len1-1] == '\r') {
1885 					len1--;
1886 					skip_at_end++;
1887 				}
1888 			}
1889 		}
1890 		else {
1891 			if (blk2[len2-1] == '\n') {
1892 				len2--;
1893 				skip_at_end++;
1894 				if (blk2[len2-1] == '\r') {
1895 					len2--;
1896 					skip_at_end++;
1897 				}
1898 			}
1899 		}
1900 	}
1901 
1902 	else if (wanted == HLSR_READ_ALL) {
1903 		/* Read all the available data. */
1904 		nblk = co_getblk_nc(oc, &blk1, &len1, &blk2, &len2);
1905 		if (nblk < 0) /* Connection close. */
1906 			goto connection_closed;
1907 		if (nblk == 0) /* No data available. */
1908 			goto connection_empty;
1909 	}
1910 
1911 	else {
1912 		/* Read a block of data. */
1913 		nblk = co_getblk_nc(oc, &blk1, &len1, &blk2, &len2);
1914 		if (nblk < 0) /* Connection close. */
1915 			goto connection_closed;
1916 		if (nblk == 0) /* No data available. */
1917 			goto connection_empty;
1918 
1919 		missing_bytes = wanted - socket->b.n;
1920 		if (len1 > missing_bytes) {
1921 			nblk = 1;
1922 			len1 = missing_bytes;
1923 		} if (nblk == 2 && len1 + len2 > missing_bytes)
1924 			len2 = missing_bytes - len1;
1925 	}
1926 
1927 	len = len1;
1928 
1929 	luaL_addlstring(&socket->b, blk1, len1);
1930 	if (nblk == 2) {
1931 		len += len2;
1932 		luaL_addlstring(&socket->b, blk2, len2);
1933 	}
1934 
1935 	/* Consume data. */
1936 	co_skip(oc, len + skip_at_end);
1937 
1938 	/* Don't wait anything. */
1939 	appctx_wakeup(appctx);
1940 
1941 	/* If the pattern reclaim to read all the data
1942 	 * in the connection, got out.
1943 	 */
1944 	if (wanted == HLSR_READ_ALL)
1945 		goto connection_empty;
1946 	else if (wanted >= 0 && socket->b.n < wanted)
1947 		goto connection_empty;
1948 
1949 	/* Return result. */
1950 	luaL_pushresult(&socket->b);
1951 	xref_unlock(&socket->xref, peer);
1952 	return 1;
1953 
1954 connection_closed:
1955 
1956 	xref_unlock(&socket->xref, peer);
1957 
1958 no_peer:
1959 
1960 	/* If the buffer containds data. */
1961 	if (socket->b.n > 0) {
1962 		luaL_pushresult(&socket->b);
1963 		return 1;
1964 	}
1965 	lua_pushnil(L);
1966 	lua_pushstring(L, "connection closed.");
1967 	return 2;
1968 
1969 connection_empty:
1970 
1971 	if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_read, hlua->task)) {
1972 		xref_unlock(&socket->xref, peer);
1973 		WILL_LJMP(luaL_error(L, "out of memory"));
1974 	}
1975 	xref_unlock(&socket->xref, peer);
1976 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_receive_yield, TICK_ETERNITY, 0));
1977 	return 0;
1978 }
1979 
1980 /* This Lua function gets two parameters. The first one can be string
1981  * or a number. If the string is "*l", the user requires one line. If
1982  * the string is "*a", the user requires all the contents of the stream.
1983  * If the value is a number, the user require a number of bytes equal
1984  * to the value. The default value is "*l" (a line).
1985  *
1986  * This parameter with a variable type is converted in integer. This
1987  * integer takes this values:
1988  *  -1 : read a line
1989  *  -2 : read all the stream
1990  *  >0 : amount of bytes.
1991  *
1992  * The second parameter is optional. It contains a string that must be
1993  * concatenated with the read data.
1994  */
hlua_socket_receive(struct lua_State * L)1995 __LJMP static int hlua_socket_receive(struct lua_State *L)
1996 {
1997 	int wanted = HLSR_READ_LINE;
1998 	const char *pattern;
1999 	int type;
2000 	char *error;
2001 	size_t len;
2002 	struct hlua_socket *socket;
2003 
2004 	if (lua_gettop(L) < 1 || lua_gettop(L) > 3)
2005 		WILL_LJMP(luaL_error(L, "The 'receive' function requires between 1 and 3 arguments."));
2006 
2007 	socket = MAY_LJMP(hlua_checksocket(L, 1));
2008 
2009 	/* Check if we run on the same thread than the xreator thread.
2010 	 * We cannot access to the socket if the thread is different.
2011 	 */
2012 	if (socket->tid != tid)
2013 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2014 
2015 	/* check for pattern. */
2016 	if (lua_gettop(L) >= 2) {
2017 		type = lua_type(L, 2);
2018 		if (type == LUA_TSTRING) {
2019 			pattern = lua_tostring(L, 2);
2020 			if (strcmp(pattern, "*a") == 0)
2021 				wanted = HLSR_READ_ALL;
2022 			else if (strcmp(pattern, "*l") == 0)
2023 				wanted = HLSR_READ_LINE;
2024 			else {
2025 				wanted = strtoll(pattern, &error, 10);
2026 				if (*error != '\0')
2027 					WILL_LJMP(luaL_error(L, "Unsupported pattern."));
2028 			}
2029 		}
2030 		else if (type == LUA_TNUMBER) {
2031 			wanted = lua_tointeger(L, 2);
2032 			if (wanted < 0)
2033 				WILL_LJMP(luaL_error(L, "Unsupported size."));
2034 		}
2035 	}
2036 
2037 	/* Set pattern. */
2038 	lua_pushinteger(L, wanted);
2039 
2040 	/* Check if we would replace the top by itself. */
2041 	if (lua_gettop(L) != 2)
2042 		lua_replace(L, 2);
2043 
2044 	/* init buffer, and fill it with prefix. */
2045 	luaL_buffinit(L, &socket->b);
2046 
2047 	/* Check prefix. */
2048 	if (lua_gettop(L) >= 3) {
2049 		if (lua_type(L, 3) != LUA_TSTRING)
2050 			WILL_LJMP(luaL_error(L, "Expect a 'string' for the prefix"));
2051 		pattern = lua_tolstring(L, 3, &len);
2052 		luaL_addlstring(&socket->b, pattern, len);
2053 	}
2054 
2055 	return __LJMP(hlua_socket_receive_yield(L, 0, 0));
2056 }
2057 
2058 /* Write the Lua input string in the output buffer.
2059  * This function returns a yield if no space is available.
2060  */
hlua_socket_write_yield(struct lua_State * L,int status,lua_KContext ctx)2061 static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext ctx)
2062 {
2063 	struct hlua_socket *socket;
2064 	struct hlua *hlua = hlua_gethlua(L);
2065 	struct appctx *appctx;
2066 	size_t buf_len;
2067 	const char *buf;
2068 	int len;
2069 	int send_len;
2070 	int sent;
2071 	struct xref *peer;
2072 	struct stream_interface *si;
2073 	struct stream *s;
2074 
2075 	/* Check if this lua stack is schedulable. */
2076 	if (!hlua || !hlua->task)
2077 		WILL_LJMP(luaL_error(L, "The 'write' function is only allowed in "
2078 		                      "'frontend', 'backend' or 'task'"));
2079 
2080 	/* Get object */
2081 	socket = MAY_LJMP(hlua_checksocket(L, 1));
2082 	buf = MAY_LJMP(luaL_checklstring(L, 2, &buf_len));
2083 	sent = MAY_LJMP(luaL_checkinteger(L, 3));
2084 
2085 	/* Check if we run on the same thread than the xreator thread.
2086 	 * We cannot access to the socket if the thread is different.
2087 	 */
2088 	if (socket->tid != tid)
2089 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2090 
2091 	/* check for connection break. If some data where read, return it. */
2092 	peer = xref_get_peer_and_lock(&socket->xref);
2093 	if (!peer) {
2094 		lua_pushinteger(L, -1);
2095 		return 1;
2096 	}
2097 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2098 	si = appctx->owner;
2099 	s = si_strm(si);
2100 
2101 	/* Check for connection close. */
2102 	if (channel_output_closed(&s->req)) {
2103 		xref_unlock(&socket->xref, peer);
2104 		lua_pushinteger(L, -1);
2105 		return 1;
2106 	}
2107 
2108 	/* Update the input buffer data. */
2109 	buf += sent;
2110 	send_len = buf_len - sent;
2111 
2112 	/* All the data are sent. */
2113 	if (sent >= buf_len) {
2114 		xref_unlock(&socket->xref, peer);
2115 		return 1; /* Implicitly return the length sent. */
2116 	}
2117 
2118 	/* Check if the buffer is available because HAProxy doesn't allocate
2119 	 * the request buffer if its not required.
2120 	 */
2121 	if (s->req.buf.size == 0) {
2122 		if (!si_alloc_ibuf(si, &appctx->buffer_wait))
2123 			goto hlua_socket_write_yield_return;
2124 	}
2125 
2126 	/* Check for available space. */
2127 	len = b_room(&s->req.buf);
2128 	if (len <= 0) {
2129 		goto hlua_socket_write_yield_return;
2130 	}
2131 
2132 	/* send data */
2133 	if (len < send_len)
2134 		send_len = len;
2135 	len = ci_putblk(&s->req, buf, send_len);
2136 
2137 	/* "Not enough space" (-1), "Buffer too little to contain
2138 	 * the data" (-2) are not expected because the available length
2139 	 * is tested.
2140 	 * Other unknown error are also not expected.
2141 	 */
2142 	if (len <= 0) {
2143 		if (len == -1)
2144 			s->req.flags |= CF_WAKE_WRITE;
2145 
2146 		MAY_LJMP(hlua_socket_close_helper(L));
2147 		lua_pop(L, 1);
2148 		lua_pushinteger(L, -1);
2149 		xref_unlock(&socket->xref, peer);
2150 		return 1;
2151 	}
2152 
2153 	/* update buffers. */
2154 	appctx_wakeup(appctx);
2155 
2156 	s->req.rex = TICK_ETERNITY;
2157 	s->res.wex = TICK_ETERNITY;
2158 
2159 	/* Update length sent. */
2160 	lua_pop(L, 1);
2161 	lua_pushinteger(L, sent + len);
2162 
2163 	/* All the data buffer is sent ? */
2164 	if (sent + len >= buf_len) {
2165 		xref_unlock(&socket->xref, peer);
2166 		return 1;
2167 	}
2168 
2169 hlua_socket_write_yield_return:
2170 	if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) {
2171 		xref_unlock(&socket->xref, peer);
2172 		WILL_LJMP(luaL_error(L, "out of memory"));
2173 	}
2174 	xref_unlock(&socket->xref, peer);
2175 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_write_yield, TICK_ETERNITY, 0));
2176 	return 0;
2177 }
2178 
2179 /* This function initiate the send of data. It just check the input
2180  * parameters and push an integer in the Lua stack that contain the
2181  * amount of data written to the buffer. This is used by the function
2182  * "hlua_socket_write_yield" that can yield.
2183  *
2184  * The Lua function gets between 3 and 4 parameters. The first one is
2185  * the associated object. The second is a string buffer. The third is
2186  * a facultative integer that represents where is the buffer position
2187  * of the start of the data that can send. The first byte is the
2188  * position "1". The default value is "1". The fourth argument is a
2189  * facultative integer that represents where is the buffer position
2190  * of the end of the data that can send. The default is the last byte.
2191  */
hlua_socket_send(struct lua_State * L)2192 static int hlua_socket_send(struct lua_State *L)
2193 {
2194 	int i;
2195 	int j;
2196 	const char *buf;
2197 	size_t buf_len;
2198 
2199 	/* Check number of arguments. */
2200 	if (lua_gettop(L) < 2 || lua_gettop(L) > 4)
2201 		WILL_LJMP(luaL_error(L, "'send' needs between 2 and 4 arguments"));
2202 
2203 	/* Get the string. */
2204 	buf = MAY_LJMP(luaL_checklstring(L, 2, &buf_len));
2205 
2206 	/* Get and check j. */
2207 	if (lua_gettop(L) == 4) {
2208 		j = MAY_LJMP(luaL_checkinteger(L, 4));
2209 		if (j < 0)
2210 			j = buf_len + j + 1;
2211 		if (j > buf_len)
2212 			j = buf_len + 1;
2213 		lua_pop(L, 1);
2214 	}
2215 	else
2216 		j = buf_len;
2217 
2218 	/* Get and check i. */
2219 	if (lua_gettop(L) == 3) {
2220 		i = MAY_LJMP(luaL_checkinteger(L, 3));
2221 		if (i < 0)
2222 			i = buf_len + i + 1;
2223 		if (i > buf_len)
2224 			i = buf_len + 1;
2225 		lua_pop(L, 1);
2226 	} else
2227 		i = 1;
2228 
2229 	/* Check bth i and j. */
2230 	if (i > j) {
2231 		lua_pushinteger(L, 0);
2232 		return 1;
2233 	}
2234 	if (i == 0 && j == 0) {
2235 		lua_pushinteger(L, 0);
2236 		return 1;
2237 	}
2238 	if (i == 0)
2239 		i = 1;
2240 	if (j == 0)
2241 		j = 1;
2242 
2243 	/* Pop the string. */
2244 	lua_pop(L, 1);
2245 
2246 	/* Update the buffer length. */
2247 	buf += i - 1;
2248 	buf_len = j - i + 1;
2249 	lua_pushlstring(L, buf, buf_len);
2250 
2251 	/* This unsigned is used to remember the amount of sent data. */
2252 	lua_pushinteger(L, 0);
2253 
2254 	return MAY_LJMP(hlua_socket_write_yield(L, 0, 0));
2255 }
2256 
2257 #define SOCKET_INFO_MAX_LEN sizeof("[0000:0000:0000:0000:0000:0000:0000:0000]:12345")
hlua_socket_info(struct lua_State * L,struct sockaddr_storage * addr)2258 __LJMP static inline int hlua_socket_info(struct lua_State *L, struct sockaddr_storage *addr)
2259 {
2260 	static char buffer[SOCKET_INFO_MAX_LEN];
2261 	int ret;
2262 	int len;
2263 	char *p;
2264 
2265 	ret = addr_to_str(addr, buffer+1, SOCKET_INFO_MAX_LEN-1);
2266 	if (ret <= 0) {
2267 		lua_pushnil(L);
2268 		return 1;
2269 	}
2270 
2271 	if (ret == AF_UNIX) {
2272 		lua_pushstring(L, buffer+1);
2273 		return 1;
2274 	}
2275 	else if (ret == AF_INET6) {
2276 		buffer[0] = '[';
2277 		len = strlen(buffer);
2278 		buffer[len] = ']';
2279 		len++;
2280 		buffer[len] = ':';
2281 		len++;
2282 		p = buffer;
2283 	}
2284 	else if (ret == AF_INET) {
2285 		p = buffer + 1;
2286 		len = strlen(p);
2287 		p[len] = ':';
2288 		len++;
2289 	}
2290 	else {
2291 		lua_pushnil(L);
2292 		return 1;
2293 	}
2294 
2295 	if (port_to_str(addr, p + len, SOCKET_INFO_MAX_LEN-1 - len) <= 0) {
2296 		lua_pushnil(L);
2297 		return 1;
2298 	}
2299 
2300 	lua_pushstring(L, p);
2301 	return 1;
2302 }
2303 
2304 /* Returns information about the peer of the connection. */
hlua_socket_getpeername(struct lua_State * L)2305 __LJMP static int hlua_socket_getpeername(struct lua_State *L)
2306 {
2307 	struct hlua_socket *socket;
2308 	struct xref *peer;
2309 	struct appctx *appctx;
2310 	struct stream_interface *si;
2311 	struct stream *s;
2312 	int ret;
2313 
2314 	MAY_LJMP(check_args(L, 1, "getpeername"));
2315 
2316 	socket = MAY_LJMP(hlua_checksocket(L, 1));
2317 
2318 	/* Check if we run on the same thread than the xreator thread.
2319 	 * We cannot access to the socket if the thread is different.
2320 	 */
2321 	if (socket->tid != tid)
2322 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2323 
2324 	/* check for connection break. If some data where read, return it. */
2325 	peer = xref_get_peer_and_lock(&socket->xref);
2326 	if (!peer) {
2327 		lua_pushnil(L);
2328 		return 1;
2329 	}
2330 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2331 	si = appctx->owner;
2332 	s = si_strm(si);
2333 
2334 	if (!s->target_addr) {
2335 		xref_unlock(&socket->xref, peer);
2336 		lua_pushnil(L);
2337 		return 1;
2338 	}
2339 
2340 	ret = MAY_LJMP(hlua_socket_info(L, s->target_addr));
2341 	xref_unlock(&socket->xref, peer);
2342 	return ret;
2343 }
2344 
2345 /* Returns information about my connection side. */
hlua_socket_getsockname(struct lua_State * L)2346 static int hlua_socket_getsockname(struct lua_State *L)
2347 {
2348 	struct hlua_socket *socket;
2349 	struct connection *conn;
2350 	struct appctx *appctx;
2351 	struct xref *peer;
2352 	struct stream_interface *si;
2353 	struct stream *s;
2354 	int ret;
2355 
2356 	MAY_LJMP(check_args(L, 1, "getsockname"));
2357 
2358 	socket = MAY_LJMP(hlua_checksocket(L, 1));
2359 
2360 	/* Check if we run on the same thread than the xreator thread.
2361 	 * We cannot access to the socket if the thread is different.
2362 	 */
2363 	if (socket->tid != tid)
2364 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2365 
2366 	/* check for connection break. If some data where read, return it. */
2367 	peer = xref_get_peer_and_lock(&socket->xref);
2368 	if (!peer) {
2369 		lua_pushnil(L);
2370 		return 1;
2371 	}
2372 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2373 	si = appctx->owner;
2374 	s = si_strm(si);
2375 
2376 	conn = cs_conn(objt_cs(s->si[1].end));
2377 	if (!conn || !conn_get_src(conn)) {
2378 		xref_unlock(&socket->xref, peer);
2379 		lua_pushnil(L);
2380 		return 1;
2381 	}
2382 
2383 	ret = hlua_socket_info(L, conn->src);
2384 	xref_unlock(&socket->xref, peer);
2385 	return ret;
2386 }
2387 
2388 /* This struct define the applet. */
2389 static struct applet update_applet = {
2390 	.obj_type = OBJ_TYPE_APPLET,
2391 	.name = "<LUA_TCP>",
2392 	.fct = hlua_socket_handler,
2393 	.release = hlua_socket_release,
2394 };
2395 
hlua_socket_connect_yield(struct lua_State * L,int status,lua_KContext ctx)2396 __LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua_KContext ctx)
2397 {
2398 	struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1));
2399 	struct hlua *hlua = hlua_gethlua(L);
2400 	struct xref *peer;
2401 	struct appctx *appctx;
2402 	struct stream_interface *si;
2403 	struct stream *s;
2404 
2405 	/* Check if we run on the same thread than the xreator thread.
2406 	 * We cannot access to the socket if the thread is different.
2407 	 */
2408 	if (socket->tid != tid)
2409 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2410 
2411 	/* check for connection break. If some data where read, return it. */
2412 	peer = xref_get_peer_and_lock(&socket->xref);
2413 	if (!peer) {
2414 		lua_pushnil(L);
2415 		lua_pushstring(L, "Can't connect");
2416 		return 2;
2417 	}
2418 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2419 	si = appctx->owner;
2420 	s = si_strm(si);
2421 
2422 	/* Check if we run on the same thread than the xreator thread.
2423 	 * We cannot access to the socket if the thread is different.
2424 	 */
2425 	if (socket->tid != tid) {
2426 		xref_unlock(&socket->xref, peer);
2427 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2428 	}
2429 
2430 	/* Check for connection close. */
2431 	if (!hlua || channel_output_closed(&s->req)) {
2432 		xref_unlock(&socket->xref, peer);
2433 		lua_pushnil(L);
2434 		lua_pushstring(L, "Can't connect");
2435 		return 2;
2436 	}
2437 
2438 	appctx = __objt_appctx(s->si[0].end);
2439 
2440 	/* Check for connection established. */
2441 	if (appctx->ctx.hlua_cosocket.connected) {
2442 		xref_unlock(&socket->xref, peer);
2443 		lua_pushinteger(L, 1);
2444 		return 1;
2445 	}
2446 
2447 	if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) {
2448 		xref_unlock(&socket->xref, peer);
2449 		WILL_LJMP(luaL_error(L, "out of memory error"));
2450 	}
2451 	xref_unlock(&socket->xref, peer);
2452 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0));
2453 	return 0;
2454 }
2455 
2456 /* This function fail or initite the connection. */
hlua_socket_connect(struct lua_State * L)2457 __LJMP static int hlua_socket_connect(struct lua_State *L)
2458 {
2459 	struct hlua_socket *socket;
2460 	int port = -1;
2461 	const char *ip;
2462 	struct hlua *hlua;
2463 	struct appctx *appctx;
2464 	int low, high;
2465 	struct sockaddr_storage *addr;
2466 	struct xref *peer;
2467 	struct stream_interface *si;
2468 	struct stream *s;
2469 
2470 	if (lua_gettop(L) < 2)
2471 		WILL_LJMP(luaL_error(L, "connect: need at least 2 arguments"));
2472 
2473 	/* Get args. */
2474 	socket  = MAY_LJMP(hlua_checksocket(L, 1));
2475 
2476 	/* Check if we run on the same thread than the xreator thread.
2477 	 * We cannot access to the socket if the thread is different.
2478 	 */
2479 	if (socket->tid != tid)
2480 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2481 
2482 	ip      = MAY_LJMP(luaL_checkstring(L, 2));
2483 	if (lua_gettop(L) >= 3) {
2484 		luaL_Buffer b;
2485 		port = MAY_LJMP(luaL_checkinteger(L, 3));
2486 
2487 		/* Force the ip to end with a colon, to support IPv6 addresses
2488 		 * that are not enclosed within square brackets.
2489 		 */
2490 		if (port > 0) {
2491 			luaL_buffinit(L, &b);
2492 			luaL_addstring(&b, ip);
2493 			luaL_addchar(&b, ':');
2494 			luaL_pushresult(&b);
2495 			ip = lua_tolstring(L, lua_gettop(L), NULL);
2496 		}
2497 	}
2498 
2499 	/* check for connection break. If some data where read, return it. */
2500 	peer = xref_get_peer_and_lock(&socket->xref);
2501 	if (!peer) {
2502 		lua_pushnil(L);
2503 		return 1;
2504 	}
2505 
2506 	/* Parse ip address. */
2507 	addr = str2sa_range(ip, NULL, &low, &high, NULL, NULL, NULL, 0);
2508 	if (!addr) {
2509 		xref_unlock(&socket->xref, peer);
2510 		WILL_LJMP(luaL_error(L, "connect: cannot parse destination address '%s'", ip));
2511 	}
2512 	if (low != high) {
2513 		xref_unlock(&socket->xref, peer);
2514 		WILL_LJMP(luaL_error(L, "connect: port ranges not supported : address '%s'", ip));
2515 	}
2516 
2517 	/* Set port. */
2518 	if (low == 0) {
2519 		if (addr->ss_family == AF_INET) {
2520 			if (port == -1) {
2521 				xref_unlock(&socket->xref, peer);
2522 				WILL_LJMP(luaL_error(L, "connect: port missing"));
2523 			}
2524 			((struct sockaddr_in *)addr)->sin_port = htons(port);
2525 		} else if (addr->ss_family == AF_INET6) {
2526 			if (port == -1) {
2527 				xref_unlock(&socket->xref, peer);
2528 				WILL_LJMP(luaL_error(L, "connect: port missing"));
2529 			}
2530 			((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
2531 		}
2532 	}
2533 
2534 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2535 	si = appctx->owner;
2536 	s = si_strm(si);
2537 
2538 	if (!sockaddr_alloc(&s->target_addr)) {
2539 		xref_unlock(&socket->xref, peer);
2540 		WILL_LJMP(luaL_error(L, "connect: internal error"));
2541 	}
2542 	*s->target_addr = *addr;
2543 	s->flags |= SF_ADDR_SET;
2544 
2545 	hlua = hlua_gethlua(L);
2546 
2547 	/* inform the stream that we want to be notified whenever the
2548 	 * connection completes.
2549 	 */
2550 	si_cant_get(&s->si[0]);
2551 	si_rx_endp_more(&s->si[0]);
2552 	appctx_wakeup(appctx);
2553 
2554 	hlua->flags |= HLUA_MUST_GC;
2555 
2556 	if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) {
2557 		xref_unlock(&socket->xref, peer);
2558 		WILL_LJMP(luaL_error(L, "out of memory"));
2559 	}
2560 	xref_unlock(&socket->xref, peer);
2561 
2562 	task_wakeup(s->task, TASK_WOKEN_INIT);
2563 	/* Return yield waiting for connection. */
2564 
2565 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0));
2566 
2567 	return 0;
2568 }
2569 
2570 #ifdef USE_OPENSSL
hlua_socket_connect_ssl(struct lua_State * L)2571 __LJMP static int hlua_socket_connect_ssl(struct lua_State *L)
2572 {
2573 	struct hlua_socket *socket;
2574 	struct xref *peer;
2575 	struct appctx *appctx;
2576 	struct stream_interface *si;
2577 	struct stream *s;
2578 
2579 	MAY_LJMP(check_args(L, 3, "connect_ssl"));
2580 	socket  = MAY_LJMP(hlua_checksocket(L, 1));
2581 
2582 	/* check for connection break. If some data where read, return it. */
2583 	peer = xref_get_peer_and_lock(&socket->xref);
2584 	if (!peer) {
2585 		lua_pushnil(L);
2586 		return 1;
2587 	}
2588 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2589 	si = appctx->owner;
2590 	s = si_strm(si);
2591 
2592 	s->target = &socket_ssl.obj_type;
2593 	xref_unlock(&socket->xref, peer);
2594 	return MAY_LJMP(hlua_socket_connect(L));
2595 }
2596 #endif
2597 
hlua_socket_setoption(struct lua_State * L)2598 __LJMP static int hlua_socket_setoption(struct lua_State *L)
2599 {
2600 	return 0;
2601 }
2602 
hlua_socket_settimeout(struct lua_State * L)2603 __LJMP static int hlua_socket_settimeout(struct lua_State *L)
2604 {
2605 	struct hlua_socket *socket;
2606 	int tmout;
2607 	double dtmout;
2608 	struct xref *peer;
2609 	struct appctx *appctx;
2610 	struct stream_interface *si;
2611 	struct stream *s;
2612 
2613 	MAY_LJMP(check_args(L, 2, "settimeout"));
2614 
2615 	socket = MAY_LJMP(hlua_checksocket(L, 1));
2616 
2617 	/* convert the timeout to millis */
2618 	dtmout = MAY_LJMP(luaL_checknumber(L, 2)) * 1000;
2619 
2620 	/* Check for negative values */
2621 	if (dtmout < 0)
2622 		WILL_LJMP(luaL_error(L, "settimeout: cannot set negatives values"));
2623 
2624 	if (dtmout > INT_MAX) /* overflow check */
2625 		WILL_LJMP(luaL_error(L, "settimeout: cannot set values larger than %d ms", INT_MAX));
2626 
2627 	tmout = MS_TO_TICKS((int)dtmout);
2628 	if (tmout == 0)
2629 		tmout++; /* very small timeouts are adjusted to a minium of 1ms */
2630 
2631 	/* Check if we run on the same thread than the xreator thread.
2632 	 * We cannot access to the socket if the thread is different.
2633 	 */
2634 	if (socket->tid != tid)
2635 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2636 
2637 	/* check for connection break. If some data were read, return it. */
2638 	peer = xref_get_peer_and_lock(&socket->xref);
2639 	if (!peer) {
2640 		hlua_pusherror(L, "socket: not yet initialised, you can't set timeouts.");
2641 		WILL_LJMP(lua_error(L));
2642 		return 0;
2643 	}
2644 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2645 	si = appctx->owner;
2646 	s = si_strm(si);
2647 
2648 	s->sess->fe->timeout.connect = tmout;
2649 	s->req.rto = tmout;
2650 	s->req.wto = tmout;
2651 	s->res.rto = tmout;
2652 	s->res.wto = tmout;
2653 	s->req.rex = tick_add_ifset(now_ms, tmout);
2654 	s->req.wex = tick_add_ifset(now_ms, tmout);
2655 	s->res.rex = tick_add_ifset(now_ms, tmout);
2656 	s->res.wex = tick_add_ifset(now_ms, tmout);
2657 
2658 	s->task->expire = tick_add_ifset(now_ms, tmout);
2659 	task_queue(s->task);
2660 
2661 	xref_unlock(&socket->xref, peer);
2662 
2663 	lua_pushinteger(L, 1);
2664 	return 1;
2665 }
2666 
hlua_socket_new(lua_State * L)2667 __LJMP static int hlua_socket_new(lua_State *L)
2668 {
2669 	struct hlua_socket *socket;
2670 	struct appctx *appctx;
2671 	struct session *sess;
2672 	struct stream *strm;
2673 
2674 	/* Check stack size. */
2675 	if (!lua_checkstack(L, 3)) {
2676 		hlua_pusherror(L, "socket: full stack");
2677 		goto out_fail_conf;
2678 	}
2679 
2680 	/* Create the object: obj[0] = userdata. */
2681 	lua_newtable(L);
2682 	socket = MAY_LJMP(lua_newuserdata(L, sizeof(*socket)));
2683 	lua_rawseti(L, -2, 0);
2684 	memset(socket, 0, sizeof(*socket));
2685 	socket->tid = tid;
2686 
2687 	/* Check if the various memory pools are intialized. */
2688 	if (!pool_head_stream || !pool_head_buffer) {
2689 		hlua_pusherror(L, "socket: uninitialized pools.");
2690 		goto out_fail_conf;
2691 	}
2692 
2693 	/* Pop a class stream metatable and affect it to the userdata. */
2694 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_socket_ref);
2695 	lua_setmetatable(L, -2);
2696 
2697 	/* Create the applet context */
2698 	appctx = appctx_new(&update_applet, tid_bit);
2699 	if (!appctx) {
2700 		hlua_pusherror(L, "socket: out of memory");
2701 		goto out_fail_conf;
2702 	}
2703 
2704 	appctx->ctx.hlua_cosocket.connected = 0;
2705 	appctx->ctx.hlua_cosocket.die = 0;
2706 	LIST_INIT(&appctx->ctx.hlua_cosocket.wake_on_write);
2707 	LIST_INIT(&appctx->ctx.hlua_cosocket.wake_on_read);
2708 
2709 	/* Now create a session, task and stream for this applet */
2710 	sess = session_new(&socket_proxy, NULL, &appctx->obj_type);
2711 	if (!sess) {
2712 		hlua_pusherror(L, "socket: out of memory");
2713 		goto out_fail_sess;
2714 	}
2715 
2716 	strm = stream_new(sess, &appctx->obj_type);
2717 	if (!strm) {
2718 		hlua_pusherror(L, "socket: out of memory");
2719 		goto out_fail_stream;
2720 	}
2721 
2722 	/* Initialise cross reference between stream and Lua socket object. */
2723 	xref_create(&socket->xref, &appctx->ctx.hlua_cosocket.xref);
2724 
2725 	/* Configure "right" stream interface. this "si" is used to connect
2726 	 * and retrieve data from the server. The connection is initialized
2727 	 * with the "struct server".
2728 	 */
2729 	si_set_state(&strm->si[1], SI_ST_ASS);
2730 
2731 	/* Force destination server. */
2732 	strm->flags |= SF_DIRECT | SF_ASSIGNED | SF_BE_ASSIGNED;
2733 	strm->target = &socket_tcp.obj_type;
2734 
2735 	return 1;
2736 
2737  out_fail_stream:
2738 	session_free(sess);
2739  out_fail_sess:
2740 	appctx_free(appctx);
2741  out_fail_conf:
2742 	WILL_LJMP(lua_error(L));
2743 	return 0;
2744 }
2745 
2746 /*
2747  *
2748  *
2749  * Class Channel
2750  *
2751  *
2752  */
2753 
2754 /* This function is called before the Lua execution. It stores
2755  * the differents parsers state before executing some Lua code.
2756  */
consistency_set(struct stream * stream,int opt,struct hlua_consistency * c)2757 static inline void consistency_set(struct stream *stream, int opt, struct hlua_consistency *c)
2758 {
2759 	c->mode = stream->be->mode;
2760 	switch (c->mode) {
2761 	case PR_MODE_HTTP:
2762 		c->data.http.dir = opt & SMP_OPT_DIR;
2763 		if (c->data.http.dir == SMP_OPT_DIR_REQ)
2764 			c->data.http.state = stream->txn->req.msg_state;
2765 		else
2766 			c->data.http.state = stream->txn->rsp.msg_state;
2767 		break;
2768 	default:
2769 		break;
2770 	}
2771 }
2772 
2773 /* This function is called after the Lua execution. it
2774  * returns true if the parser state is consistent, otherwise,
2775  * it return false.
2776  *
2777  * In HTTP mode, the parser state must be in the same state
2778  * or greater when we exit the function. Even if we do a
2779  * control yield. This prevent to break the HTTP message
2780  * from the Lua code.
2781  */
consistency_check(struct stream * stream,int opt,struct hlua_consistency * c)2782 static inline int consistency_check(struct stream *stream, int opt, struct hlua_consistency *c)
2783 {
2784 	if (c->mode != stream->be->mode)
2785 		return 0;
2786 
2787 	switch (c->mode) {
2788 	case PR_MODE_HTTP:
2789 		if (c->data.http.dir != (opt & SMP_OPT_DIR))
2790 			return 0;
2791 		if (c->data.http.dir == SMP_OPT_DIR_REQ)
2792 			return stream->txn->req.msg_state >= c->data.http.state;
2793 		else
2794 			return stream->txn->rsp.msg_state >= c->data.http.state;
2795 	default:
2796 		return 1;
2797 	}
2798 	return 1;
2799 }
2800 
2801 /* Returns the struct hlua_channel join to the class channel in the
2802  * stack entry "ud" or throws an argument error.
2803  */
hlua_checkchannel(lua_State * L,int ud)2804 __LJMP static struct channel *hlua_checkchannel(lua_State *L, int ud)
2805 {
2806 	return MAY_LJMP(hlua_checkudata(L, ud, class_channel_ref));
2807 }
2808 
2809 /* Pushes the channel onto the top of the stack. If the stask does not have a
2810  * free slots, the function fails and returns 0;
2811  */
hlua_channel_new(lua_State * L,struct channel * channel)2812 static int hlua_channel_new(lua_State *L, struct channel *channel)
2813 {
2814 	/* Check stack size. */
2815 	if (!lua_checkstack(L, 3))
2816 		return 0;
2817 
2818 	lua_newtable(L);
2819 	lua_pushlightuserdata(L, channel);
2820 	lua_rawseti(L, -2, 0);
2821 
2822 	/* Pop a class sesison metatable and affect it to the userdata. */
2823 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_channel_ref);
2824 	lua_setmetatable(L, -2);
2825 	return 1;
2826 }
2827 
2828 /* Duplicate all the data present in the input channel and put it
2829  * in a string LUA variables. Returns -1 and push a nil value in
2830  * the stack if the channel is closed and all the data are consumed,
2831  * returns 0 if no data are available, otherwise it returns the length
2832  * of the builded string.
2833  */
_hlua_channel_dup(struct channel * chn,lua_State * L)2834 static inline int _hlua_channel_dup(struct channel *chn, lua_State *L)
2835 {
2836 	char *blk1;
2837 	char *blk2;
2838 	size_t len1;
2839 	size_t len2;
2840 	int ret;
2841 	luaL_Buffer b;
2842 
2843 	ret = ci_getblk_nc(chn, &blk1, &len1, &blk2, &len2);
2844 	if (unlikely(ret == 0))
2845 		return 0;
2846 
2847 	if (unlikely(ret < 0)) {
2848 		lua_pushnil(L);
2849 		return -1;
2850 	}
2851 
2852 	luaL_buffinit(L, &b);
2853 	luaL_addlstring(&b, blk1, len1);
2854 	if (unlikely(ret == 2))
2855 		luaL_addlstring(&b, blk2, len2);
2856 	luaL_pushresult(&b);
2857 
2858 	if (unlikely(ret == 2))
2859 		return len1 + len2;
2860 	return len1;
2861 }
2862 
2863 /* "_hlua_channel_dup" wrapper. If no data are available, it returns
2864  * a yield. This function keep the data in the buffer.
2865  */
hlua_channel_dup_yield(lua_State * L,int status,lua_KContext ctx)2866 __LJMP static int hlua_channel_dup_yield(lua_State *L, int status, lua_KContext ctx)
2867 {
2868 	struct channel *chn;
2869 
2870 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
2871 
2872 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP)
2873 		WILL_LJMP(lua_error(L));
2874 
2875 	if (_hlua_channel_dup(chn, L) == 0)
2876 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_dup_yield, TICK_ETERNITY, 0));
2877 	return 1;
2878 }
2879 
2880 /* Check arguments for the function "hlua_channel_dup_yield". */
hlua_channel_dup(lua_State * L)2881 __LJMP static int hlua_channel_dup(lua_State *L)
2882 {
2883 	MAY_LJMP(check_args(L, 1, "dup"));
2884 	MAY_LJMP(hlua_checkchannel(L, 1));
2885 	return MAY_LJMP(hlua_channel_dup_yield(L, 0, 0));
2886 }
2887 
2888 /* "_hlua_channel_dup" wrapper. If no data are available, it returns
2889  * a yield. This function consumes the data in the buffer. It returns
2890  * a string containing the data or a nil pointer if no data are available
2891  * and the channel is closed.
2892  */
hlua_channel_get_yield(lua_State * L,int status,lua_KContext ctx)2893 __LJMP static int hlua_channel_get_yield(lua_State *L, int status, lua_KContext ctx)
2894 {
2895 	struct channel *chn;
2896 	int ret;
2897 
2898 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
2899 
2900 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP)
2901 		WILL_LJMP(lua_error(L));
2902 
2903 	ret = _hlua_channel_dup(chn, L);
2904 	if (unlikely(ret == 0))
2905 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_get_yield, TICK_ETERNITY, 0));
2906 
2907 	if (unlikely(ret == -1))
2908 		return 1;
2909 
2910 	b_sub(&chn->buf, ret);
2911 	return 1;
2912 }
2913 
2914 /* Check arguments for the function "hlua_channel_get_yield". */
hlua_channel_get(lua_State * L)2915 __LJMP static int hlua_channel_get(lua_State *L)
2916 {
2917 	MAY_LJMP(check_args(L, 1, "get"));
2918 	MAY_LJMP(hlua_checkchannel(L, 1));
2919 	return MAY_LJMP(hlua_channel_get_yield(L, 0, 0));
2920 }
2921 
2922 /* This functions consumes and returns one line. If the channel is closed,
2923  * and the last data does not contains a final '\n', the data are returned
2924  * without the final '\n'. When no more data are available, it returns nil
2925  * value.
2926  */
hlua_channel_getline_yield(lua_State * L,int status,lua_KContext ctx)2927 __LJMP static int hlua_channel_getline_yield(lua_State *L, int status, lua_KContext ctx)
2928 {
2929 	char *blk1;
2930 	char *blk2;
2931 	size_t len1;
2932 	size_t len2;
2933 	size_t len;
2934 	struct channel *chn;
2935 	int ret;
2936 	luaL_Buffer b;
2937 
2938 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
2939 
2940 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP)
2941 		WILL_LJMP(lua_error(L));
2942 
2943 	ret = ci_getline_nc(chn, &blk1, &len1, &blk2, &len2);
2944 	if (ret == 0)
2945 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_getline_yield, TICK_ETERNITY, 0));
2946 
2947 	if (ret == -1) {
2948 		lua_pushnil(L);
2949 		return 1;
2950 	}
2951 
2952 	luaL_buffinit(L, &b);
2953 	luaL_addlstring(&b, blk1, len1);
2954 	len = len1;
2955 	if (unlikely(ret == 2)) {
2956 		luaL_addlstring(&b, blk2, len2);
2957 		len += len2;
2958 	}
2959 	luaL_pushresult(&b);
2960 	b_rep_blk(&chn->buf, ci_head(chn), ci_head(chn) + len,  NULL, 0);
2961 	return 1;
2962 }
2963 
2964 /* Check arguments for the function "hlua_channel_getline_yield". */
hlua_channel_getline(lua_State * L)2965 __LJMP static int hlua_channel_getline(lua_State *L)
2966 {
2967 	MAY_LJMP(check_args(L, 1, "getline"));
2968 	MAY_LJMP(hlua_checkchannel(L, 1));
2969 	return MAY_LJMP(hlua_channel_getline_yield(L, 0, 0));
2970 }
2971 
2972 /* This function takes a string as input, and append it at the
2973  * input side of channel. If the data is too big, but a space
2974  * is probably available after sending some data, the function
2975  * yields. If the data is bigger than the buffer, or if the
2976  * channel is closed, it returns -1. Otherwise, it returns the
2977  * amount of data written.
2978  */
hlua_channel_append_yield(lua_State * L,int status,lua_KContext ctx)2979 __LJMP static int hlua_channel_append_yield(lua_State *L, int status, lua_KContext ctx)
2980 {
2981 	struct channel *chn = MAY_LJMP(hlua_checkchannel(L, 1));
2982 	size_t len;
2983 	const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
2984 	int l = MAY_LJMP(luaL_checkinteger(L, 3));
2985 	int ret;
2986 	int max;
2987 
2988 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP)
2989 		WILL_LJMP(lua_error(L));
2990 
2991 	/* Check if the buffer is available because HAProxy doesn't allocate
2992 	 * the request buffer if its not required.
2993 	 */
2994 	if (chn->buf.size == 0) {
2995 		si_rx_buff_blk(chn_prod(chn));
2996 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
2997 	}
2998 
2999 	max = channel_recv_limit(chn) - b_data(&chn->buf);
3000 	if (max > len - l)
3001 		max = len - l;
3002 
3003 	ret = ci_putblk(chn, str + l, max);
3004 	if (ret == -2 || ret == -3) {
3005 		lua_pushinteger(L, -1);
3006 		return 1;
3007 	}
3008 	if (ret == -1) {
3009 		chn->flags |= CF_WAKE_WRITE;
3010 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
3011 	}
3012 	l += ret;
3013 	lua_pop(L, 1);
3014 	lua_pushinteger(L, l);
3015 
3016 	max = channel_recv_limit(chn) - b_data(&chn->buf);
3017 	if (max == 0 && co_data(chn) == 0) {
3018 		/* There are no space available, and the output buffer is empty.
3019 		 * in this case, we cannot add more data, so we cannot yield,
3020 		 * we return the amount of copyied data.
3021 		 */
3022 		return 1;
3023 	}
3024 	if (l < len)
3025 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
3026 	return 1;
3027 }
3028 
3029 /* Just a wrapper of "hlua_channel_append_yield". It returns the length
3030  * of the written string, or -1 if the channel is closed or if the
3031  * buffer size is too little for the data.
3032  */
hlua_channel_append(lua_State * L)3033 __LJMP static int hlua_channel_append(lua_State *L)
3034 {
3035 	size_t len;
3036 
3037 	MAY_LJMP(check_args(L, 2, "append"));
3038 	MAY_LJMP(hlua_checkchannel(L, 1));
3039 	MAY_LJMP(luaL_checklstring(L, 2, &len));
3040 	MAY_LJMP(luaL_checkinteger(L, 3));
3041 	lua_pushinteger(L, 0);
3042 
3043 	return MAY_LJMP(hlua_channel_append_yield(L, 0, 0));
3044 }
3045 
3046 /* Just a wrapper of "hlua_channel_append_yield". This wrapper starts
3047  * his process by cleaning the buffer. The result is a replacement
3048  * of the current data. It returns the length of the written string,
3049  * or -1 if the channel is closed or if the buffer size is too
3050  * little for the data.
3051  */
hlua_channel_set(lua_State * L)3052 __LJMP static int hlua_channel_set(lua_State *L)
3053 {
3054 	struct channel *chn;
3055 
3056 	MAY_LJMP(check_args(L, 2, "set"));
3057 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
3058 	lua_pushinteger(L, 0);
3059 
3060 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP)
3061 		WILL_LJMP(lua_error(L));
3062 
3063 	b_set_data(&chn->buf, co_data(chn));
3064 
3065 	return MAY_LJMP(hlua_channel_append_yield(L, 0, 0));
3066 }
3067 
3068 /* Append data in the output side of the buffer. This data is immediately
3069  * sent. The function returns the amount of data written. If the buffer
3070  * cannot contain the data, the function yields. The function returns -1
3071  * if the channel is closed.
3072  */
hlua_channel_send_yield(lua_State * L,int status,lua_KContext ctx)3073 __LJMP static int hlua_channel_send_yield(lua_State *L, int status, lua_KContext ctx)
3074 {
3075 	struct channel *chn = MAY_LJMP(hlua_checkchannel(L, 1));
3076 	size_t len;
3077 	const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
3078 	int l = MAY_LJMP(luaL_checkinteger(L, 3));
3079 	int max;
3080 	struct hlua *hlua = hlua_gethlua(L);
3081 
3082 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP)
3083 		WILL_LJMP(lua_error(L));
3084 
3085 	if (unlikely(channel_output_closed(chn))) {
3086 		lua_pushinteger(L, -1);
3087 		return 1;
3088 	}
3089 
3090 	/* Check if the buffer is available because HAProxy doesn't allocate
3091 	 * the request buffer if its not required.
3092 	 */
3093 	if (chn->buf.size == 0) {
3094 		si_rx_buff_blk(chn_prod(chn));
3095 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
3096 	}
3097 
3098 	/* The written data will be immediately sent, so we can check
3099 	 * the available space without taking in account the reserve.
3100 	 * The reserve is guaranteed for the processing of incoming
3101 	 * data, because the buffer will be flushed.
3102 	 */
3103 	max = b_room(&chn->buf);
3104 
3105 	/* If there is no space available, and the output buffer is empty.
3106 	 * in this case, we cannot add more data, so we cannot yield,
3107 	 * we return the amount of copyied data.
3108 	 */
3109 	if (max == 0 && co_data(chn) == 0)
3110 		return 1;
3111 
3112 	/* Adjust the real required length. */
3113 	if (max > len - l)
3114 		max = len - l;
3115 
3116 	/* The buffer available size may be not contiguous. This test
3117 	 * detects a non contiguous buffer and realign it.
3118 	 */
3119 	if (ci_space_for_replace(chn) < max)
3120 		channel_slow_realign(chn, trash.area);
3121 
3122 	/* Copy input data in the buffer. */
3123 	max = b_rep_blk(&chn->buf, ci_head(chn), ci_head(chn), str + l, max);
3124 
3125 	/* buffer replace considers that the input part is filled.
3126 	 * so, I must forward these new data in the output part.
3127 	 */
3128 	c_adv(chn, max);
3129 
3130 	l += max;
3131 	lua_pop(L, 1);
3132 	lua_pushinteger(L, l);
3133 
3134 	/* If there is no space available, and the output buffer is empty.
3135 	 * in this case, we cannot add more data, so we cannot yield,
3136 	 * we return the amount of copyied data.
3137 	 */
3138 	max = b_room(&chn->buf);
3139 	if (max == 0 && co_data(chn) == 0)
3140 		return 1;
3141 
3142 	if (l < len) {
3143 		/* If we are waiting for space in the response buffer, we
3144 		 * must set the flag WAKERESWR. This flag required the task
3145 		 * wake up if any activity is detected on the response buffer.
3146 		 */
3147 		if (chn->flags & CF_ISRESP)
3148 			HLUA_SET_WAKERESWR(hlua);
3149 		else
3150 			HLUA_SET_WAKEREQWR(hlua);
3151 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
3152 	}
3153 
3154 	return 1;
3155 }
3156 
3157 /* Just a wraper of "_hlua_channel_send". This wrapper permits
3158  * yield the LUA process, and resume it without checking the
3159  * input arguments.
3160  */
hlua_channel_send(lua_State * L)3161 __LJMP static int hlua_channel_send(lua_State *L)
3162 {
3163 	MAY_LJMP(check_args(L, 2, "send"));
3164 	lua_pushinteger(L, 0);
3165 
3166 	return MAY_LJMP(hlua_channel_send_yield(L, 0, 0));
3167 }
3168 
3169 /* This function forward and amount of butes. The data pass from
3170  * the input side of the buffer to the output side, and can be
3171  * forwarded. This function never fails.
3172  *
3173  * The Lua function takes an amount of bytes to be forwarded in
3174  * imput. It returns the number of bytes forwarded.
3175  */
hlua_channel_forward_yield(lua_State * L,int status,lua_KContext ctx)3176 __LJMP static int hlua_channel_forward_yield(lua_State *L, int status, lua_KContext ctx)
3177 {
3178 	struct channel *chn;
3179 	int len;
3180 	int l;
3181 	int max;
3182 	struct hlua *hlua = hlua_gethlua(L);
3183 
3184 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
3185 
3186 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP)
3187 		WILL_LJMP(lua_error(L));
3188 
3189 	len = MAY_LJMP(luaL_checkinteger(L, 2));
3190 	l = MAY_LJMP(luaL_checkinteger(L, -1));
3191 
3192 	max = len - l;
3193 	if (max > ci_data(chn))
3194 		max = ci_data(chn);
3195 	channel_forward(chn, max);
3196 	l += max;
3197 
3198 	lua_pop(L, 1);
3199 	lua_pushinteger(L, l);
3200 
3201 	/* Check if it miss bytes to forward. */
3202 	if (l < len) {
3203 		/* The the input channel or the output channel are closed, we
3204 		 * must return the amount of data forwarded.
3205 		 */
3206 		if (channel_input_closed(chn) || channel_output_closed(chn))
3207 			return 1;
3208 
3209 		/* If we are waiting for space data in the response buffer, we
3210 		 * must set the flag WAKERESWR. This flag required the task
3211 		 * wake up if any activity is detected on the response buffer.
3212 		 */
3213 		if (chn->flags & CF_ISRESP)
3214 			HLUA_SET_WAKERESWR(hlua);
3215 		else
3216 			HLUA_SET_WAKEREQWR(hlua);
3217 
3218 		/* Otherwise, we can yield waiting for new data in the inpout side. */
3219 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_forward_yield, TICK_ETERNITY, 0));
3220 	}
3221 
3222 	return 1;
3223 }
3224 
3225 /* Just check the input and prepare the stack for the previous
3226  * function "hlua_channel_forward_yield"
3227  */
hlua_channel_forward(lua_State * L)3228 __LJMP static int hlua_channel_forward(lua_State *L)
3229 {
3230 	MAY_LJMP(check_args(L, 2, "forward"));
3231 	MAY_LJMP(hlua_checkchannel(L, 1));
3232 	MAY_LJMP(luaL_checkinteger(L, 2));
3233 
3234 	lua_pushinteger(L, 0);
3235 	return MAY_LJMP(hlua_channel_forward_yield(L, 0, 0));
3236 }
3237 
3238 /* Just returns the number of bytes available in the input
3239  * side of the buffer. This function never fails.
3240  */
hlua_channel_get_in_len(lua_State * L)3241 __LJMP static int hlua_channel_get_in_len(lua_State *L)
3242 {
3243 	struct channel *chn;
3244 
3245 	MAY_LJMP(check_args(L, 1, "get_in_len"));
3246 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
3247 	if (IS_HTX_STRM(chn_strm(chn))) {
3248 		struct htx *htx = htxbuf(&chn->buf);
3249 		lua_pushinteger(L, htx->data - co_data(chn));
3250 	}
3251 	else
3252 		lua_pushinteger(L, ci_data(chn));
3253 	return 1;
3254 }
3255 
3256 /* Returns true if the channel is full. */
hlua_channel_is_full(lua_State * L)3257 __LJMP static int hlua_channel_is_full(lua_State *L)
3258 {
3259 	struct channel *chn;
3260 
3261 	MAY_LJMP(check_args(L, 1, "is_full"));
3262 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
3263 	/* ignore the reserve, we are not on a producer side (ie in an
3264 	 * applet).
3265 	 */
3266 	lua_pushboolean(L, channel_full(chn, 0));
3267 	return 1;
3268 }
3269 
3270 /* Just returns the number of bytes available in the output
3271  * side of the buffer. This function never fails.
3272  */
hlua_channel_get_out_len(lua_State * L)3273 __LJMP static int hlua_channel_get_out_len(lua_State *L)
3274 {
3275 	struct channel *chn;
3276 
3277 	MAY_LJMP(check_args(L, 1, "get_out_len"));
3278 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
3279 	lua_pushinteger(L, co_data(chn));
3280 	return 1;
3281 }
3282 
3283 /*
3284  *
3285  *
3286  * Class Fetches
3287  *
3288  *
3289  */
3290 
3291 /* Returns a struct hlua_session if the stack entry "ud" is
3292  * a class stream, otherwise it throws an error.
3293  */
hlua_checkfetches(lua_State * L,int ud)3294 __LJMP static struct hlua_smp *hlua_checkfetches(lua_State *L, int ud)
3295 {
3296 	return MAY_LJMP(hlua_checkudata(L, ud, class_fetches_ref));
3297 }
3298 
3299 /* This function creates and push in the stack a fetch object according
3300  * with a current TXN.
3301  */
hlua_fetches_new(lua_State * L,struct hlua_txn * txn,unsigned int flags)3302 static int hlua_fetches_new(lua_State *L, struct hlua_txn *txn, unsigned int flags)
3303 {
3304 	struct hlua_smp *hsmp;
3305 
3306 	/* Check stack size. */
3307 	if (!lua_checkstack(L, 3))
3308 		return 0;
3309 
3310 	/* Create the object: obj[0] = userdata.
3311 	 * Note that the base of the Fetches object is the
3312 	 * transaction object.
3313 	 */
3314 	lua_newtable(L);
3315 	hsmp = lua_newuserdata(L, sizeof(*hsmp));
3316 	lua_rawseti(L, -2, 0);
3317 
3318 	hsmp->s = txn->s;
3319 	hsmp->p = txn->p;
3320 	hsmp->dir = txn->dir;
3321 	hsmp->flags = flags;
3322 
3323 	/* Pop a class sesison metatable and affect it to the userdata. */
3324 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_fetches_ref);
3325 	lua_setmetatable(L, -2);
3326 
3327 	return 1;
3328 }
3329 
3330 /* This function is an LUA binding. It is called with each sample-fetch.
3331  * It uses closure argument to store the associated sample-fetch. It
3332  * returns only one argument or throws an error. An error is thrown
3333  * only if an error is encountered during the argument parsing. If
3334  * the "sample-fetch" function fails, nil is returned.
3335  */
hlua_run_sample_fetch(lua_State * L)3336 __LJMP static int hlua_run_sample_fetch(lua_State *L)
3337 {
3338 	struct hlua_smp *hsmp;
3339 	struct sample_fetch *f;
3340 	struct arg args[ARGM_NBARGS + 1] = {{0}};
3341 	int i;
3342 	struct sample smp;
3343 
3344 	/* Get closure arguments. */
3345 	f = lua_touserdata(L, lua_upvalueindex(1));
3346 
3347 	/* Get traditional arguments. */
3348 	hsmp = MAY_LJMP(hlua_checkfetches(L, 1));
3349 
3350 	/* Check execution authorization. */
3351 	if (f->use & SMP_USE_HTTP_ANY &&
3352 	    !(hsmp->flags & HLUA_F_MAY_USE_HTTP)) {
3353 		lua_pushfstring(L, "the sample-fetch '%s' needs an HTTP parser which "
3354 		                   "is not available in Lua services", f->kw);
3355 		WILL_LJMP(lua_error(L));
3356 	}
3357 
3358 	/* Get extra arguments. */
3359 	for (i = 0; i < lua_gettop(L) - 1; i++) {
3360 		if (i >= ARGM_NBARGS)
3361 			break;
3362 		hlua_lua2arg(L, i + 2, &args[i]);
3363 	}
3364 	args[i].type = ARGT_STOP;
3365 	args[i].data.str.area = NULL;
3366 
3367 	/* Check arguments. */
3368 	MAY_LJMP(hlua_lua2arg_check(L, 2, args, f->arg_mask, hsmp->p));
3369 
3370 	/* Run the special args checker. */
3371 	if (f->val_args && !f->val_args(args, NULL)) {
3372 		lua_pushfstring(L, "error in arguments");
3373 		goto error;
3374 	}
3375 
3376 	/* Initialise the sample. */
3377 	memset(&smp, 0, sizeof(smp));
3378 
3379 	/* Run the sample fetch process. */
3380 	smp_set_owner(&smp, hsmp->p, hsmp->s->sess, hsmp->s, hsmp->dir & SMP_OPT_DIR);
3381 	if (!f->process(args, &smp, f->kw, f->private)) {
3382 		if (hsmp->flags & HLUA_F_AS_STRING)
3383 			lua_pushstring(L, "");
3384 		else
3385 			lua_pushnil(L);
3386 		goto end;
3387 	}
3388 
3389 	/* Convert the returned sample in lua value. */
3390 	if (hsmp->flags & HLUA_F_AS_STRING)
3391 		hlua_smp2lua_str(L, &smp);
3392 	else
3393 		hlua_smp2lua(L, &smp);
3394 
3395   end:
3396 	for (i = 0; args[i].type != ARGT_STOP; i++) {
3397 		if (args[i].type == ARGT_STR)
3398 			chunk_destroy(&args[i].data.str);
3399 	}
3400 	return 1;
3401 
3402   error:
3403 	for (i = 0; args[i].type != ARGT_STOP; i++) {
3404 		if (args[i].type == ARGT_STR)
3405 			chunk_destroy(&args[i].data.str);
3406 	}
3407 	WILL_LJMP(lua_error(L));
3408 	return 0; /* Never reached */
3409 }
3410 
3411 /*
3412  *
3413  *
3414  * Class Converters
3415  *
3416  *
3417  */
3418 
3419 /* Returns a struct hlua_session if the stack entry "ud" is
3420  * a class stream, otherwise it throws an error.
3421  */
hlua_checkconverters(lua_State * L,int ud)3422 __LJMP static struct hlua_smp *hlua_checkconverters(lua_State *L, int ud)
3423 {
3424 	return MAY_LJMP(hlua_checkudata(L, ud, class_converters_ref));
3425 }
3426 
3427 /* This function creates and push in the stack a Converters object
3428  * according with a current TXN.
3429  */
hlua_converters_new(lua_State * L,struct hlua_txn * txn,unsigned int flags)3430 static int hlua_converters_new(lua_State *L, struct hlua_txn *txn, unsigned int flags)
3431 {
3432 	struct hlua_smp *hsmp;
3433 
3434 	/* Check stack size. */
3435 	if (!lua_checkstack(L, 3))
3436 		return 0;
3437 
3438 	/* Create the object: obj[0] = userdata.
3439 	 * Note that the base of the Converters object is the
3440 	 * same than the TXN object.
3441 	 */
3442 	lua_newtable(L);
3443 	hsmp = lua_newuserdata(L, sizeof(*hsmp));
3444 	lua_rawseti(L, -2, 0);
3445 
3446 	hsmp->s = txn->s;
3447 	hsmp->p = txn->p;
3448 	hsmp->dir = txn->dir;
3449 	hsmp->flags = flags;
3450 
3451 	/* Pop a class stream metatable and affect it to the table. */
3452 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_converters_ref);
3453 	lua_setmetatable(L, -2);
3454 
3455 	return 1;
3456 }
3457 
3458 /* This function is an LUA binding. It is called with each converter.
3459  * It uses closure argument to store the associated converter. It
3460  * returns only one argument or throws an error. An error is thrown
3461  * only if an error is encountered during the argument parsing. If
3462  * the converter function function fails, nil is returned.
3463  */
hlua_run_sample_conv(lua_State * L)3464 __LJMP static int hlua_run_sample_conv(lua_State *L)
3465 {
3466 	struct hlua_smp *hsmp;
3467 	struct sample_conv *conv;
3468 	struct arg args[ARGM_NBARGS + 1] = {{0}};
3469 	int i;
3470 	struct sample smp;
3471 
3472 	/* Get closure arguments. */
3473 	conv = lua_touserdata(L, lua_upvalueindex(1));
3474 
3475 	/* Get traditional arguments. */
3476 	hsmp = MAY_LJMP(hlua_checkconverters(L, 1));
3477 
3478 	/* Get extra arguments. */
3479 	for (i = 0; i < lua_gettop(L) - 2; i++) {
3480 		if (i >= ARGM_NBARGS)
3481 			break;
3482 		hlua_lua2arg(L, i + 3, &args[i]);
3483 	}
3484 	args[i].type = ARGT_STOP;
3485 	args[i].data.str.area = NULL;
3486 
3487 	/* Check arguments. */
3488 	MAY_LJMP(hlua_lua2arg_check(L, 3, args, conv->arg_mask, hsmp->p));
3489 
3490 	/* Run the special args checker. */
3491 	if (conv->val_args && !conv->val_args(args, conv, "", 0, NULL)) {
3492 		hlua_pusherror(L, "error in arguments");
3493 		goto error;
3494 	}
3495 
3496 	/* Initialise the sample. */
3497 	memset(&smp, 0, sizeof(smp));
3498 	if (!hlua_lua2smp(L, 2, &smp)) {
3499 		hlua_pusherror(L, "error in the input argument");
3500 		goto error;
3501 	}
3502 
3503 	smp_set_owner(&smp, hsmp->p, hsmp->s->sess, hsmp->s, hsmp->dir & SMP_OPT_DIR);
3504 
3505 	/* Apply expected cast. */
3506 	if (!sample_casts[smp.data.type][conv->in_type]) {
3507 		hlua_pusherror(L, "invalid input argument: cannot cast '%s' to '%s'",
3508 		               smp_to_type[smp.data.type], smp_to_type[conv->in_type]);
3509 		goto error;
3510 	}
3511 	if (sample_casts[smp.data.type][conv->in_type] != c_none &&
3512 	    !sample_casts[smp.data.type][conv->in_type](&smp)) {
3513 		hlua_pusherror(L, "error during the input argument casting");
3514 		goto error;
3515 	}
3516 
3517 	/* Run the sample conversion process. */
3518 	if (!conv->process(args, &smp, conv->private)) {
3519 		if (hsmp->flags & HLUA_F_AS_STRING)
3520 			lua_pushstring(L, "");
3521 		else
3522 			lua_pushnil(L);
3523 		goto end;
3524 	}
3525 
3526 	/* Convert the returned sample in lua value. */
3527 	if (hsmp->flags & HLUA_F_AS_STRING)
3528 		hlua_smp2lua_str(L, &smp);
3529 	else
3530 		hlua_smp2lua(L, &smp);
3531   end:
3532 	for (i = 0; args[i].type != ARGT_STOP; i++) {
3533 		if (args[i].type == ARGT_STR)
3534 			chunk_destroy(&args[i].data.str);
3535 	}
3536 	return 1;
3537 
3538   error:
3539 	for (i = 0; args[i].type != ARGT_STOP; i++) {
3540 		if (args[i].type == ARGT_STR)
3541 			chunk_destroy(&args[i].data.str);
3542 	}
3543 	WILL_LJMP(lua_error(L));
3544 	return 0; /* Never reached */
3545 }
3546 
3547 /*
3548  *
3549  *
3550  * Class AppletTCP
3551  *
3552  *
3553  */
3554 
3555 /* Returns a struct hlua_txn if the stack entry "ud" is
3556  * a class stream, otherwise it throws an error.
3557  */
hlua_checkapplet_tcp(lua_State * L,int ud)3558 __LJMP static struct hlua_appctx *hlua_checkapplet_tcp(lua_State *L, int ud)
3559 {
3560 	return MAY_LJMP(hlua_checkudata(L, ud, class_applet_tcp_ref));
3561 }
3562 
3563 /* This function creates and push in the stack an Applet object
3564  * according with a current TXN.
3565  */
hlua_applet_tcp_new(lua_State * L,struct appctx * ctx)3566 static int hlua_applet_tcp_new(lua_State *L, struct appctx *ctx)
3567 {
3568 	struct hlua_appctx *appctx;
3569 	struct stream_interface *si = ctx->owner;
3570 	struct stream *s = si_strm(si);
3571 	struct proxy *p = s->be;
3572 
3573 	/* Check stack size. */
3574 	if (!lua_checkstack(L, 3))
3575 		return 0;
3576 
3577 	/* Create the object: obj[0] = userdata.
3578 	 * Note that the base of the Converters object is the
3579 	 * same than the TXN object.
3580 	 */
3581 	lua_newtable(L);
3582 	appctx = lua_newuserdata(L, sizeof(*appctx));
3583 	lua_rawseti(L, -2, 0);
3584 	appctx->appctx = ctx;
3585 	appctx->htxn.s = s;
3586 	appctx->htxn.p = p;
3587 
3588 	/* Create the "f" field that contains a list of fetches. */
3589 	lua_pushstring(L, "f");
3590 	if (!hlua_fetches_new(L, &appctx->htxn, 0))
3591 		return 0;
3592 	lua_settable(L, -3);
3593 
3594 	/* Create the "sf" field that contains a list of stringsafe fetches. */
3595 	lua_pushstring(L, "sf");
3596 	if (!hlua_fetches_new(L, &appctx->htxn, HLUA_F_AS_STRING))
3597 		return 0;
3598 	lua_settable(L, -3);
3599 
3600 	/* Create the "c" field that contains a list of converters. */
3601 	lua_pushstring(L, "c");
3602 	if (!hlua_converters_new(L, &appctx->htxn, 0))
3603 		return 0;
3604 	lua_settable(L, -3);
3605 
3606 	/* Create the "sc" field that contains a list of stringsafe converters. */
3607 	lua_pushstring(L, "sc");
3608 	if (!hlua_converters_new(L, &appctx->htxn, HLUA_F_AS_STRING))
3609 		return 0;
3610 	lua_settable(L, -3);
3611 
3612 	/* Pop a class stream metatable and affect it to the table. */
3613 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_applet_tcp_ref);
3614 	lua_setmetatable(L, -2);
3615 
3616 	return 1;
3617 }
3618 
hlua_applet_tcp_set_var(lua_State * L)3619 __LJMP static int hlua_applet_tcp_set_var(lua_State *L)
3620 {
3621 	struct hlua_appctx *appctx;
3622 	struct stream *s;
3623 	const char *name;
3624 	size_t len;
3625 	struct sample smp;
3626 
3627 	MAY_LJMP(check_args(L, 3, "set_var"));
3628 
3629 	/* It is useles to retrieve the stream, but this function
3630 	 * runs only in a stream context.
3631 	 */
3632 	appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3633 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
3634 	s = appctx->htxn.s;
3635 
3636 	/* Converts the third argument in a sample. */
3637 	memset(&smp, 0, sizeof(smp));
3638 	hlua_lua2smp(L, 3, &smp);
3639 
3640 	/* Store the sample in a variable. */
3641 	smp_set_owner(&smp, s->be, s->sess, s, 0);
3642 	vars_set_by_name(name, len, &smp);
3643 	return 0;
3644 }
3645 
hlua_applet_tcp_unset_var(lua_State * L)3646 __LJMP static int hlua_applet_tcp_unset_var(lua_State *L)
3647 {
3648 	struct hlua_appctx *appctx;
3649 	struct stream *s;
3650 	const char *name;
3651 	size_t len;
3652 	struct sample smp;
3653 
3654 	MAY_LJMP(check_args(L, 2, "unset_var"));
3655 
3656 	/* It is useles to retrieve the stream, but this function
3657 	 * runs only in a stream context.
3658 	 */
3659 	appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3660 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
3661 	s = appctx->htxn.s;
3662 
3663 	/* Unset the variable. */
3664 	smp_set_owner(&smp, s->be, s->sess, s, 0);
3665 	vars_unset_by_name(name, len, &smp);
3666 	return 0;
3667 }
3668 
hlua_applet_tcp_get_var(lua_State * L)3669 __LJMP static int hlua_applet_tcp_get_var(lua_State *L)
3670 {
3671 	struct hlua_appctx *appctx;
3672 	struct stream *s;
3673 	const char *name;
3674 	size_t len;
3675 	struct sample smp;
3676 
3677 	MAY_LJMP(check_args(L, 2, "get_var"));
3678 
3679 	/* It is useles to retrieve the stream, but this function
3680 	 * runs only in a stream context.
3681 	 */
3682 	appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3683 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
3684 	s = appctx->htxn.s;
3685 
3686 	smp_set_owner(&smp, s->be, s->sess, s, 0);
3687 	if (!vars_get_by_name(name, len, &smp)) {
3688 		lua_pushnil(L);
3689 		return 1;
3690 	}
3691 
3692 	return hlua_smp2lua(L, &smp);
3693 }
3694 
hlua_applet_tcp_set_priv(lua_State * L)3695 __LJMP static int hlua_applet_tcp_set_priv(lua_State *L)
3696 {
3697 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3698 	struct stream *s = appctx->htxn.s;
3699 	struct hlua *hlua;
3700 
3701 	/* Note that this hlua struct is from the session and not from the applet. */
3702 	if (!s->hlua)
3703 		return 0;
3704 	hlua = s->hlua;
3705 
3706 	MAY_LJMP(check_args(L, 2, "set_priv"));
3707 
3708 	/* Remove previous value. */
3709 	luaL_unref(L, LUA_REGISTRYINDEX, hlua->Mref);
3710 
3711 	/* Get and store new value. */
3712 	lua_pushvalue(L, 2); /* Copy the element 2 at the top of the stack. */
3713 	hlua->Mref = luaL_ref(L, LUA_REGISTRYINDEX); /* pop the previously pushed value. */
3714 
3715 	return 0;
3716 }
3717 
hlua_applet_tcp_get_priv(lua_State * L)3718 __LJMP static int hlua_applet_tcp_get_priv(lua_State *L)
3719 {
3720 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3721 	struct stream *s = appctx->htxn.s;
3722 	struct hlua *hlua;
3723 
3724 	/* Note that this hlua struct is from the session and not from the applet. */
3725 	if (!s->hlua) {
3726 		lua_pushnil(L);
3727 		return 1;
3728 	}
3729 	hlua = s->hlua;
3730 
3731 	/* Push configuration index in the stack. */
3732 	lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
3733 
3734 	return 1;
3735 }
3736 
3737 /* If expected data not yet available, it returns a yield. This function
3738  * consumes the data in the buffer. It returns a string containing the
3739  * data. This string can be empty.
3740  */
hlua_applet_tcp_getline_yield(lua_State * L,int status,lua_KContext ctx)3741 __LJMP static int hlua_applet_tcp_getline_yield(lua_State *L, int status, lua_KContext ctx)
3742 {
3743 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3744 	struct stream_interface *si = appctx->appctx->owner;
3745 	int ret;
3746 	const char *blk1;
3747 	size_t len1;
3748 	const char *blk2;
3749 	size_t len2;
3750 
3751 	/* Read the maximum amount of data available. */
3752 	ret = co_getline_nc(si_oc(si), &blk1, &len1, &blk2, &len2);
3753 
3754 	/* Data not yet available. return yield. */
3755 	if (ret == 0) {
3756 		si_cant_get(si);
3757 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_getline_yield, TICK_ETERNITY, 0));
3758 	}
3759 
3760 	/* End of data: commit the total strings and return. */
3761 	if (ret < 0) {
3762 		luaL_pushresult(&appctx->b);
3763 		return 1;
3764 	}
3765 
3766 	/* Ensure that the block 2 length is usable. */
3767 	if (ret == 1)
3768 		len2 = 0;
3769 
3770 	/* dont check the max length read and dont check. */
3771 	luaL_addlstring(&appctx->b, blk1, len1);
3772 	luaL_addlstring(&appctx->b, blk2, len2);
3773 
3774 	/* Consume input channel output buffer data. */
3775 	co_skip(si_oc(si), len1 + len2);
3776 	luaL_pushresult(&appctx->b);
3777 	return 1;
3778 }
3779 
3780 /* Check arguments for the function "hlua_channel_get_yield". */
hlua_applet_tcp_getline(lua_State * L)3781 __LJMP static int hlua_applet_tcp_getline(lua_State *L)
3782 {
3783 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3784 
3785 	/* Initialise the string catenation. */
3786 	luaL_buffinit(L, &appctx->b);
3787 
3788 	return MAY_LJMP(hlua_applet_tcp_getline_yield(L, 0, 0));
3789 }
3790 
3791 /* If expected data not yet available, it returns a yield. This function
3792  * consumes the data in the buffer. It returns a string containing the
3793  * data. This string can be empty.
3794  */
hlua_applet_tcp_recv_yield(lua_State * L,int status,lua_KContext ctx)3795 __LJMP static int hlua_applet_tcp_recv_yield(lua_State *L, int status, lua_KContext ctx)
3796 {
3797 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3798 	struct stream_interface *si = appctx->appctx->owner;
3799 	size_t len = MAY_LJMP(luaL_checkinteger(L, 2));
3800 	int ret;
3801 	const char *blk1;
3802 	size_t len1;
3803 	const char *blk2;
3804 	size_t len2;
3805 
3806 	/* Read the maximum amount of data available. */
3807 	ret = co_getblk_nc(si_oc(si), &blk1, &len1, &blk2, &len2);
3808 
3809 	/* Data not yet available. return yield. */
3810 	if (ret == 0) {
3811 		si_cant_get(si);
3812 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, TICK_ETERNITY, 0));
3813 	}
3814 
3815 	/* End of data: commit the total strings and return. */
3816 	if (ret < 0) {
3817 		luaL_pushresult(&appctx->b);
3818 		return 1;
3819 	}
3820 
3821 	/* Ensure that the block 2 length is usable. */
3822 	if (ret == 1)
3823 		len2 = 0;
3824 
3825 	if (len == -1) {
3826 
3827 		/* If len == -1, catenate all the data avalaile and
3828 		 * yield because we want to get all the data until
3829 		 * the end of data stream.
3830 		 */
3831 		luaL_addlstring(&appctx->b, blk1, len1);
3832 		luaL_addlstring(&appctx->b, blk2, len2);
3833 		co_skip(si_oc(si), len1 + len2);
3834 		si_cant_get(si);
3835 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, TICK_ETERNITY, 0));
3836 
3837 	} else {
3838 
3839 		/* Copy the fisrt block caping to the length required. */
3840 		if (len1 > len)
3841 			len1 = len;
3842 		luaL_addlstring(&appctx->b, blk1, len1);
3843 		len -= len1;
3844 
3845 		/* Copy the second block. */
3846 		if (len2 > len)
3847 			len2 = len;
3848 		luaL_addlstring(&appctx->b, blk2, len2);
3849 		len -= len2;
3850 
3851 		/* Consume input channel output buffer data. */
3852 		co_skip(si_oc(si), len1 + len2);
3853 
3854 		/* If there is no other data available, yield waiting for new data. */
3855 		if (len > 0) {
3856 			lua_pushinteger(L, len);
3857 			lua_replace(L, 2);
3858 			si_cant_get(si);
3859 			MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, TICK_ETERNITY, 0));
3860 		}
3861 
3862 		/* return the result. */
3863 		luaL_pushresult(&appctx->b);
3864 		return 1;
3865 	}
3866 
3867 	/* we never execute this */
3868 	hlua_pusherror(L, "Lua: internal error");
3869 	WILL_LJMP(lua_error(L));
3870 	return 0;
3871 }
3872 
3873 /* Check arguments for the function "hlua_channel_get_yield". */
hlua_applet_tcp_recv(lua_State * L)3874 __LJMP static int hlua_applet_tcp_recv(lua_State *L)
3875 {
3876 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3877 	int len = -1;
3878 
3879 	if (lua_gettop(L) > 2)
3880 		WILL_LJMP(luaL_error(L, "The 'recv' function requires between 1 and 2 arguments."));
3881 	if (lua_gettop(L) >= 2) {
3882 		len = MAY_LJMP(luaL_checkinteger(L, 2));
3883 		lua_pop(L, 1);
3884 	}
3885 
3886 	/* Confirm or set the required length */
3887 	lua_pushinteger(L, len);
3888 
3889 	/* Initialise the string catenation. */
3890 	luaL_buffinit(L, &appctx->b);
3891 
3892 	return MAY_LJMP(hlua_applet_tcp_recv_yield(L, 0, 0));
3893 }
3894 
3895 /* Append data in the output side of the buffer. This data is immediately
3896  * sent. The function returns the amount of data written. If the buffer
3897  * cannot contain the data, the function yields. The function returns -1
3898  * if the channel is closed.
3899  */
hlua_applet_tcp_send_yield(lua_State * L,int status,lua_KContext ctx)3900 __LJMP static int hlua_applet_tcp_send_yield(lua_State *L, int status, lua_KContext ctx)
3901 {
3902 	size_t len;
3903 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3904 	const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
3905 	int l = MAY_LJMP(luaL_checkinteger(L, 3));
3906 	struct stream_interface *si = appctx->appctx->owner;
3907 	struct channel *chn = si_ic(si);
3908 	int max;
3909 
3910 	/* Get the max amount of data which can write as input in the channel. */
3911 	max = channel_recv_max(chn);
3912 	if (max > (len - l))
3913 		max = len - l;
3914 
3915 	/* Copy data. */
3916 	ci_putblk(chn, str + l, max);
3917 
3918 	/* update counters. */
3919 	l += max;
3920 	lua_pop(L, 1);
3921 	lua_pushinteger(L, l);
3922 
3923 	/* If some data is not send, declares the situation to the
3924 	 * applet, and returns a yield.
3925 	 */
3926 	if (l < len) {
3927 		si_rx_room_blk(si);
3928 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_send_yield, TICK_ETERNITY, 0));
3929 	}
3930 
3931 	return 1;
3932 }
3933 
3934 /* Just a wraper of "hlua_applet_tcp_send_yield". This wrapper permits
3935  * yield the LUA process, and resume it without checking the
3936  * input arguments.
3937  */
hlua_applet_tcp_send(lua_State * L)3938 __LJMP static int hlua_applet_tcp_send(lua_State *L)
3939 {
3940 	MAY_LJMP(check_args(L, 2, "send"));
3941 	lua_pushinteger(L, 0);
3942 
3943 	return MAY_LJMP(hlua_applet_tcp_send_yield(L, 0, 0));
3944 }
3945 
3946 /*
3947  *
3948  *
3949  * Class AppletHTTP
3950  *
3951  *
3952  */
3953 
3954 /* Returns a struct hlua_txn if the stack entry "ud" is
3955  * a class stream, otherwise it throws an error.
3956  */
hlua_checkapplet_http(lua_State * L,int ud)3957 __LJMP static struct hlua_appctx *hlua_checkapplet_http(lua_State *L, int ud)
3958 {
3959 	return MAY_LJMP(hlua_checkudata(L, ud, class_applet_http_ref));
3960 }
3961 
3962 /* This function creates and push in the stack an Applet object
3963  * according with a current TXN.
3964  */
hlua_applet_http_new(lua_State * L,struct appctx * ctx)3965 static int hlua_applet_http_new(lua_State *L, struct appctx *ctx)
3966 {
3967 	struct hlua_appctx *appctx;
3968 	struct hlua_txn htxn;
3969 	struct stream_interface *si = ctx->owner;
3970 	struct stream *s = si_strm(si);
3971 	struct proxy *px = s->be;
3972 	struct htx *htx;
3973 	struct htx_blk *blk;
3974 	struct htx_sl *sl;
3975 	struct ist path;
3976 	unsigned long long len = 0;
3977 	int32_t pos;
3978 
3979 	/* Check stack size. */
3980 	if (!lua_checkstack(L, 3))
3981 		return 0;
3982 
3983 	/* Create the object: obj[0] = userdata.
3984 	 * Note that the base of the Converters object is the
3985 	 * same than the TXN object.
3986 	 */
3987 	lua_newtable(L);
3988 	appctx = lua_newuserdata(L, sizeof(*appctx));
3989 	lua_rawseti(L, -2, 0);
3990 	appctx->appctx = ctx;
3991 	appctx->appctx->ctx.hlua_apphttp.status = 200; /* Default status code returned. */
3992 	appctx->appctx->ctx.hlua_apphttp.reason = NULL; /* Use default reason based on status */
3993 	appctx->htxn.s = s;
3994 	appctx->htxn.p = px;
3995 
3996 	/* Create the "f" field that contains a list of fetches. */
3997 	lua_pushstring(L, "f");
3998 	if (!hlua_fetches_new(L, &appctx->htxn, 0))
3999 		return 0;
4000 	lua_settable(L, -3);
4001 
4002 	/* Create the "sf" field that contains a list of stringsafe fetches. */
4003 	lua_pushstring(L, "sf");
4004 	if (!hlua_fetches_new(L, &appctx->htxn, HLUA_F_AS_STRING))
4005 		return 0;
4006 	lua_settable(L, -3);
4007 
4008 	/* Create the "c" field that contains a list of converters. */
4009 	lua_pushstring(L, "c");
4010 	if (!hlua_converters_new(L, &appctx->htxn, 0))
4011 		return 0;
4012 	lua_settable(L, -3);
4013 
4014 	/* Create the "sc" field that contains a list of stringsafe converters. */
4015 	lua_pushstring(L, "sc");
4016 	if (!hlua_converters_new(L, &appctx->htxn, HLUA_F_AS_STRING))
4017 		return 0;
4018 	lua_settable(L, -3);
4019 
4020 	htx = htxbuf(&s->req.buf);
4021 	blk = htx_get_first_blk(htx);
4022 	BUG_ON(!blk || htx_get_blk_type(blk) != HTX_BLK_REQ_SL);
4023 	sl = htx_get_blk_ptr(htx, blk);
4024 
4025 	/* Stores the request method. */
4026 	lua_pushstring(L, "method");
4027 	lua_pushlstring(L, HTX_SL_REQ_MPTR(sl), HTX_SL_REQ_MLEN(sl));
4028 	lua_settable(L, -3);
4029 
4030 	/* Stores the http version. */
4031 	lua_pushstring(L, "version");
4032 	lua_pushlstring(L, HTX_SL_REQ_VPTR(sl), HTX_SL_REQ_VLEN(sl));
4033 	lua_settable(L, -3);
4034 
4035 	/* creates an array of headers. hlua_http_get_headers() crates and push
4036 	 * the array on the top of the stack.
4037 	 */
4038 	lua_pushstring(L, "headers");
4039 	htxn.s = s;
4040 	htxn.p = px;
4041 	htxn.dir = SMP_OPT_DIR_REQ;
4042 	if (!hlua_http_get_headers(L, &htxn, &htxn.s->txn->req))
4043 		return 0;
4044 	lua_settable(L, -3);
4045 
4046 	path = http_get_path(htx_sl_req_uri(sl));
4047 	if (path.ptr) {
4048 		char *p, *q, *end;
4049 
4050 		p = path.ptr;
4051 		end = path.ptr + path.len;
4052 		q = p;
4053 		while (q < end && *q != '?')
4054 			q++;
4055 
4056 		/* Stores the request path. */
4057 		lua_pushstring(L, "path");
4058 		lua_pushlstring(L, p, q - p);
4059 		lua_settable(L, -3);
4060 
4061 		/* Stores the query string. */
4062 		lua_pushstring(L, "qs");
4063 		if (*q == '?')
4064 			q++;
4065 		lua_pushlstring(L, q, end - q);
4066 		lua_settable(L, -3);
4067 	}
4068 
4069 	for (pos = htx_get_first(htx); pos != -1; pos = htx_get_next(htx, pos)) {
4070 		struct htx_blk *blk = htx_get_blk(htx, pos);
4071 		enum htx_blk_type type = htx_get_blk_type(blk);
4072 
4073 		if (type == HTX_BLK_EOM || type == HTX_BLK_TLR || type == HTX_BLK_EOT)
4074 			break;
4075 		if (type == HTX_BLK_DATA)
4076 			len += htx_get_blksz(blk);
4077 	}
4078 	if (htx->extra != ULLONG_MAX)
4079 		len += htx->extra;
4080 
4081 	/* Stores the request path. */
4082 	lua_pushstring(L, "length");
4083 	lua_pushinteger(L, len);
4084 	lua_settable(L, -3);
4085 
4086 	/* Create an empty array of HTTP request headers. */
4087 	lua_pushstring(L, "response");
4088 	lua_newtable(L);
4089 	lua_settable(L, -3);
4090 
4091 	/* Pop a class stream metatable and affect it to the table. */
4092 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_applet_http_ref);
4093 	lua_setmetatable(L, -2);
4094 
4095 	return 1;
4096 }
4097 
hlua_applet_http_set_var(lua_State * L)4098 __LJMP static int hlua_applet_http_set_var(lua_State *L)
4099 {
4100 	struct hlua_appctx *appctx;
4101 	struct stream *s;
4102 	const char *name;
4103 	size_t len;
4104 	struct sample smp;
4105 
4106 	MAY_LJMP(check_args(L, 3, "set_var"));
4107 
4108 	/* It is useles to retrieve the stream, but this function
4109 	 * runs only in a stream context.
4110 	 */
4111 	appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4112 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
4113 	s = appctx->htxn.s;
4114 
4115 	/* Converts the third argument in a sample. */
4116 	memset(&smp, 0, sizeof(smp));
4117 	hlua_lua2smp(L, 3, &smp);
4118 
4119 	/* Store the sample in a variable. */
4120 	smp_set_owner(&smp, s->be, s->sess, s, 0);
4121 	vars_set_by_name(name, len, &smp);
4122 	return 0;
4123 }
4124 
hlua_applet_http_unset_var(lua_State * L)4125 __LJMP static int hlua_applet_http_unset_var(lua_State *L)
4126 {
4127 	struct hlua_appctx *appctx;
4128 	struct stream *s;
4129 	const char *name;
4130 	size_t len;
4131 	struct sample smp;
4132 
4133 	MAY_LJMP(check_args(L, 2, "unset_var"));
4134 
4135 	/* It is useles to retrieve the stream, but this function
4136 	 * runs only in a stream context.
4137 	 */
4138 	appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4139 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
4140 	s = appctx->htxn.s;
4141 
4142 	/* Unset the variable. */
4143 	smp_set_owner(&smp, s->be, s->sess, s, 0);
4144 	vars_unset_by_name(name, len, &smp);
4145 	return 0;
4146 }
4147 
hlua_applet_http_get_var(lua_State * L)4148 __LJMP static int hlua_applet_http_get_var(lua_State *L)
4149 {
4150 	struct hlua_appctx *appctx;
4151 	struct stream *s;
4152 	const char *name;
4153 	size_t len;
4154 	struct sample smp;
4155 
4156 	MAY_LJMP(check_args(L, 2, "get_var"));
4157 
4158 	/* It is useles to retrieve the stream, but this function
4159 	 * runs only in a stream context.
4160 	 */
4161 	appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4162 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
4163 	s = appctx->htxn.s;
4164 
4165 	smp_set_owner(&smp, s->be, s->sess, s, 0);
4166 	if (!vars_get_by_name(name, len, &smp)) {
4167 		lua_pushnil(L);
4168 		return 1;
4169 	}
4170 
4171 	return hlua_smp2lua(L, &smp);
4172 }
4173 
hlua_applet_http_set_priv(lua_State * L)4174 __LJMP static int hlua_applet_http_set_priv(lua_State *L)
4175 {
4176 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4177 	struct stream *s = appctx->htxn.s;
4178 	struct hlua *hlua;
4179 
4180 	/* Note that this hlua struct is from the session and not from the applet. */
4181 	if (!s->hlua)
4182 		return 0;
4183 	hlua = s->hlua;
4184 
4185 	MAY_LJMP(check_args(L, 2, "set_priv"));
4186 
4187 	/* Remove previous value. */
4188 	luaL_unref(L, LUA_REGISTRYINDEX, hlua->Mref);
4189 
4190 	/* Get and store new value. */
4191 	lua_pushvalue(L, 2); /* Copy the element 2 at the top of the stack. */
4192 	hlua->Mref = luaL_ref(L, LUA_REGISTRYINDEX); /* pop the previously pushed value. */
4193 
4194 	return 0;
4195 }
4196 
hlua_applet_http_get_priv(lua_State * L)4197 __LJMP static int hlua_applet_http_get_priv(lua_State *L)
4198 {
4199 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4200 	struct stream *s = appctx->htxn.s;
4201 	struct hlua *hlua;
4202 
4203 	/* Note that this hlua struct is from the session and not from the applet. */
4204 	if (!s->hlua) {
4205 		lua_pushnil(L);
4206 		return 1;
4207 	}
4208 	hlua = s->hlua;
4209 
4210 	/* Push configuration index in the stack. */
4211 	lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
4212 
4213 	return 1;
4214 }
4215 
4216 /* If expected data not yet available, it returns a yield. This function
4217  * consumes the data in the buffer. It returns a string containing the
4218  * data. This string can be empty.
4219  */
hlua_applet_http_getline_yield(lua_State * L,int status,lua_KContext ctx)4220 __LJMP static int hlua_applet_http_getline_yield(lua_State *L, int status, lua_KContext ctx)
4221 {
4222 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4223 	struct stream_interface *si = appctx->appctx->owner;
4224 	struct channel *req = si_oc(si);
4225 	struct htx *htx;
4226 	struct htx_blk *blk;
4227 	size_t count;
4228 	int stop = 0;
4229 
4230 	htx = htx_from_buf(&req->buf);
4231 	count = co_data(req);
4232 	blk = htx_get_first_blk(htx);
4233 
4234 	while (count && !stop && blk) {
4235 		enum htx_blk_type type = htx_get_blk_type(blk);
4236 		uint32_t sz = htx_get_blksz(blk);
4237 		struct ist v;
4238 		uint32_t vlen;
4239 		char *nl;
4240 
4241 		if (type == HTX_BLK_EOM) {
4242 			stop = 1;
4243 			break;
4244 		}
4245 
4246 		vlen = sz;
4247 		if (vlen > count) {
4248 			if (type != HTX_BLK_DATA)
4249 				break;
4250 			vlen = count;
4251 		}
4252 
4253 		switch (type) {
4254 			case HTX_BLK_UNUSED:
4255 				break;
4256 
4257 			case HTX_BLK_DATA:
4258 				v = htx_get_blk_value(htx, blk);
4259 				v.len = vlen;
4260 				nl = istchr(v, '\n');
4261 				if (nl != NULL) {
4262 					stop = 1;
4263 					vlen = nl - v.ptr + 1;
4264 				}
4265 				luaL_addlstring(&appctx->b, v.ptr, vlen);
4266 				break;
4267 
4268 			case HTX_BLK_TLR:
4269 			case HTX_BLK_EOM:
4270 				stop = 1;
4271 				break;
4272 
4273 			default:
4274 				break;
4275 		}
4276 
4277 		co_set_data(req, co_data(req) - vlen);
4278 		count -= vlen;
4279 		if (sz == vlen)
4280 			blk = htx_remove_blk(htx, blk);
4281 		else {
4282 			htx_cut_data_blk(htx, blk, vlen);
4283 			break;
4284 		}
4285 	}
4286 
4287 	htx_to_buf(htx, &req->buf);
4288 	if (!stop) {
4289 		si_cant_get(si);
4290 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_http_getline_yield, TICK_ETERNITY, 0));
4291 	}
4292 
4293 	/* return the result. */
4294 	luaL_pushresult(&appctx->b);
4295 	return 1;
4296 }
4297 
4298 
4299 /* Check arguments for the function "hlua_channel_get_yield". */
hlua_applet_http_getline(lua_State * L)4300 __LJMP static int hlua_applet_http_getline(lua_State *L)
4301 {
4302 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4303 
4304 	/* Initialise the string catenation. */
4305 	luaL_buffinit(L, &appctx->b);
4306 
4307 	return MAY_LJMP(hlua_applet_http_getline_yield(L, 0, 0));
4308 }
4309 
4310 /* If expected data not yet available, it returns a yield. This function
4311  * consumes the data in the buffer. It returns a string containing the
4312  * data. This string can be empty.
4313  */
hlua_applet_http_recv_yield(lua_State * L,int status,lua_KContext ctx)4314 __LJMP static int hlua_applet_http_recv_yield(lua_State *L, int status, lua_KContext ctx)
4315 {
4316 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4317 	struct stream_interface *si = appctx->appctx->owner;
4318 	struct channel *req = si_oc(si);
4319 	struct htx *htx;
4320 	struct htx_blk *blk;
4321 	size_t count;
4322 	int len;
4323 
4324 	htx = htx_from_buf(&req->buf);
4325 	len = MAY_LJMP(luaL_checkinteger(L, 2));
4326 	count = co_data(req);
4327 	blk = htx_get_head_blk(htx);
4328 	while (count && len && blk) {
4329 		enum htx_blk_type type = htx_get_blk_type(blk);
4330 		uint32_t sz = htx_get_blksz(blk);
4331 		struct ist v;
4332 		uint32_t vlen;
4333 
4334 		if (type == HTX_BLK_EOM) {
4335 			len = 0;
4336 			break;
4337 		}
4338 
4339 		vlen = sz;
4340 		if (len > 0 && vlen > len)
4341 			vlen = len;
4342 		if (vlen > count) {
4343 			if (type != HTX_BLK_DATA)
4344 				break;
4345 			vlen = count;
4346 		}
4347 
4348 		switch (type) {
4349 			case HTX_BLK_UNUSED:
4350 				break;
4351 
4352 			case HTX_BLK_DATA:
4353 				v = htx_get_blk_value(htx, blk);
4354 				luaL_addlstring(&appctx->b, v.ptr, vlen);
4355 				break;
4356 
4357 			case HTX_BLK_TLR:
4358 			case HTX_BLK_EOM:
4359 				len = 0;
4360 				break;
4361 
4362 			default:
4363 				break;
4364 		}
4365 
4366 		co_set_data(req, co_data(req) - vlen);
4367 		count -= vlen;
4368 		if (len > 0)
4369 			len -= vlen;
4370 		if (sz == vlen)
4371 			blk = htx_remove_blk(htx, blk);
4372 		else {
4373 			htx_cut_data_blk(htx, blk, vlen);
4374 			break;
4375 		}
4376 	}
4377 
4378 	htx_to_buf(htx, &req->buf);
4379 
4380 	/* If we are no other data available, yield waiting for new data. */
4381 	if (len) {
4382 		if (len > 0) {
4383 			lua_pushinteger(L, len);
4384 			lua_replace(L, 2);
4385 		}
4386 		si_cant_get(si);
4387 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_http_recv_yield, TICK_ETERNITY, 0));
4388 	}
4389 
4390 	/* return the result. */
4391 	luaL_pushresult(&appctx->b);
4392 	return 1;
4393 }
4394 
4395 /* Check arguments for the function "hlua_channel_get_yield". */
hlua_applet_http_recv(lua_State * L)4396 __LJMP static int hlua_applet_http_recv(lua_State *L)
4397 {
4398 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4399 	int len = -1;
4400 
4401 	/* Check arguments. */
4402 	if (lua_gettop(L) > 2)
4403 		WILL_LJMP(luaL_error(L, "The 'recv' function requires between 1 and 2 arguments."));
4404 	if (lua_gettop(L) >= 2) {
4405 		len = MAY_LJMP(luaL_checkinteger(L, 2));
4406 		lua_pop(L, 1);
4407 	}
4408 
4409 	lua_pushinteger(L, len);
4410 
4411 	/* Initialise the string catenation. */
4412 	luaL_buffinit(L, &appctx->b);
4413 
4414 	return MAY_LJMP(hlua_applet_http_recv_yield(L, 0, 0));
4415 }
4416 
4417 /* Append data in the output side of the buffer. This data is immediately
4418  * sent. The function returns the amount of data written. If the buffer
4419  * cannot contain the data, the function yields. The function returns -1
4420  * if the channel is closed.
4421  */
hlua_applet_http_send_yield(lua_State * L,int status,lua_KContext ctx)4422 __LJMP static int hlua_applet_http_send_yield(lua_State *L, int status, lua_KContext ctx)
4423 {
4424 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4425 	struct stream_interface *si = appctx->appctx->owner;
4426 	struct channel *res = si_ic(si);
4427 	struct htx *htx = htx_from_buf(&res->buf);
4428 	const char *data;
4429 	size_t len;
4430 	int l = MAY_LJMP(luaL_checkinteger(L, 3));
4431 	int max;
4432 
4433 	max = htx_get_max_blksz(htx, channel_htx_recv_max(res, htx));
4434 	if (!max)
4435 		goto snd_yield;
4436 
4437 	data = MAY_LJMP(luaL_checklstring(L, 2, &len));
4438 
4439 	/* Get the max amount of data which can write as input in the channel. */
4440 	if (max > (len - l))
4441 		max = len - l;
4442 
4443 	/* Copy data. */
4444 	max = htx_add_data(htx, ist2(data + l, max));
4445 	channel_add_input(res, max);
4446 
4447 	/* update counters. */
4448 	l += max;
4449 	lua_pop(L, 1);
4450 	lua_pushinteger(L, l);
4451 
4452 	/* If some data is not send, declares the situation to the
4453 	 * applet, and returns a yield.
4454 	 */
4455 	if (l < len) {
4456 	  snd_yield:
4457 		htx_to_buf(htx, &res->buf);
4458 		si_rx_room_blk(si);
4459 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_http_send_yield, TICK_ETERNITY, 0));
4460 	}
4461 
4462 	htx_to_buf(htx, &res->buf);
4463 	return 1;
4464 }
4465 
4466 /* Just a wraper of "hlua_applet_send_yield". This wrapper permits
4467  * yield the LUA process, and resume it without checking the
4468  * input arguments.
4469  */
hlua_applet_http_send(lua_State * L)4470 __LJMP static int hlua_applet_http_send(lua_State *L)
4471 {
4472 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4473 
4474 	/* We want to send some data. Headers must be sent. */
4475 	if (!(appctx->appctx->ctx.hlua_apphttp.flags & APPLET_HDR_SENT)) {
4476 		hlua_pusherror(L, "Lua: 'send' you must call start_response() before sending data.");
4477 		WILL_LJMP(lua_error(L));
4478 	}
4479 
4480 	/* This interger is used for followinf the amount of data sent. */
4481 	lua_pushinteger(L, 0);
4482 
4483 	return MAY_LJMP(hlua_applet_http_send_yield(L, 0, 0));
4484 }
4485 
hlua_applet_http_addheader(lua_State * L)4486 __LJMP static int hlua_applet_http_addheader(lua_State *L)
4487 {
4488 	const char *name;
4489 	int ret;
4490 
4491 	MAY_LJMP(hlua_checkapplet_http(L, 1));
4492 	name = MAY_LJMP(luaL_checkstring(L, 2));
4493 	MAY_LJMP(luaL_checkstring(L, 3));
4494 
4495 	/* Push in the stack the "response" entry. */
4496 	ret = lua_getfield(L, 1, "response");
4497 	if (ret != LUA_TTABLE) {
4498 		hlua_pusherror(L, "Lua: 'add_header' internal error: AppletHTTP['response'] "
4499 		                  "is expected as an array. %s found", lua_typename(L, ret));
4500 		WILL_LJMP(lua_error(L));
4501 	}
4502 
4503 	/* check if the header is already registered if it is not
4504 	 * the case, register it.
4505 	 */
4506 	ret = lua_getfield(L, -1, name);
4507 	if (ret == LUA_TNIL) {
4508 
4509 		/* Entry not found. */
4510 		lua_pop(L, 1); /* remove the nil. The "response" table is the top of the stack. */
4511 
4512 		/* Insert the new header name in the array in the top of the stack.
4513 		 * It left the new array in the top of the stack.
4514 		 */
4515 		lua_newtable(L);
4516 		lua_pushvalue(L, 2);
4517 		lua_pushvalue(L, -2);
4518 		lua_settable(L, -4);
4519 
4520 	} else if (ret != LUA_TTABLE) {
4521 
4522 		/* corruption error. */
4523 		hlua_pusherror(L, "Lua: 'add_header' internal error: AppletHTTP['response']['%s'] "
4524 		                  "is expected as an array. %s found", name, lua_typename(L, ret));
4525 		WILL_LJMP(lua_error(L));
4526 	}
4527 
4528 	/* Now the top od thestack is an array of values. We push
4529 	 * the header value as new entry.
4530 	 */
4531 	lua_pushvalue(L, 3);
4532 	ret = lua_rawlen(L, -2);
4533 	lua_rawseti(L, -2, ret + 1);
4534 	lua_pushboolean(L, 1);
4535 	return 1;
4536 }
4537 
hlua_applet_http_status(lua_State * L)4538 __LJMP static int hlua_applet_http_status(lua_State *L)
4539 {
4540 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4541 	int status = MAY_LJMP(luaL_checkinteger(L, 2));
4542 	const char *reason = MAY_LJMP(luaL_optlstring(L, 3, NULL, NULL));
4543 
4544 	if (status < 100 || status > 599) {
4545 		lua_pushboolean(L, 0);
4546 		return 1;
4547 	}
4548 
4549 	appctx->appctx->ctx.hlua_apphttp.status = status;
4550 	appctx->appctx->ctx.hlua_apphttp.reason = reason;
4551 	lua_pushboolean(L, 1);
4552 	return 1;
4553 }
4554 
4555 
hlua_applet_http_send_response(lua_State * L)4556 __LJMP static int hlua_applet_http_send_response(lua_State *L)
4557 {
4558 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4559 	struct stream_interface *si = appctx->appctx->owner;
4560 	struct channel *res = si_ic(si);
4561 	struct htx *htx;
4562 	struct htx_sl *sl;
4563 	struct h1m h1m;
4564 	const char *status, *reason;
4565 	const char *name, *value;
4566 	size_t nlen, vlen;
4567         unsigned int flags;
4568 
4569 	/* Send the message at once. */
4570 	htx = htx_from_buf(&res->buf);
4571 	h1m_init_res(&h1m);
4572 
4573 	/* Use the same http version than the request. */
4574 	status = ultoa_r(appctx->appctx->ctx.hlua_apphttp.status, trash.area, trash.size);
4575 	reason = appctx->appctx->ctx.hlua_apphttp.reason;
4576 	if (reason == NULL)
4577 		reason = http_get_reason(appctx->appctx->ctx.hlua_apphttp.status);
4578 	if (appctx->appctx->ctx.hlua_apphttp.flags & APPLET_HTTP11) {
4579 		flags = (HTX_SL_F_IS_RESP|HTX_SL_F_VER_11);
4580 		sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags, ist("HTTP/1.1"), ist(status), ist(reason));
4581 	}
4582 	else {
4583 		flags = HTX_SL_F_IS_RESP;
4584 		sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags, ist("HTTP/1.0"), ist(status), ist(reason));
4585 	}
4586 	if (!sl) {
4587 		hlua_pusherror(L, "Lua applet http '%s': Failed to create response.\n",
4588 		               appctx->appctx->rule->arg.hlua_rule->fcn.name);
4589 		WILL_LJMP(lua_error(L));
4590 	}
4591 	sl->info.res.status = appctx->appctx->ctx.hlua_apphttp.status;
4592 
4593 	/* Get the array associated to the field "response" in the object AppletHTTP. */
4594 	lua_pushvalue(L, 0);
4595 	if (lua_getfield(L, 1, "response") != LUA_TTABLE) {
4596 		hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response'] missing.\n",
4597 		               appctx->appctx->rule->arg.hlua_rule->fcn.name);
4598 		WILL_LJMP(lua_error(L));
4599 	}
4600 
4601 	/* Browse the list of headers. */
4602 	lua_pushnil(L);
4603 	while(lua_next(L, -2) != 0) {
4604 		/* We expect a string as -2. */
4605 		if (lua_type(L, -2) != LUA_TSTRING) {
4606 			hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response'][] element must be a string. got %s.\n",
4607 				       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4608 			               lua_typename(L, lua_type(L, -2)));
4609 			WILL_LJMP(lua_error(L));
4610 		}
4611 		name = lua_tolstring(L, -2, &nlen);
4612 
4613 		/* We expect an array as -1. */
4614 		if (lua_type(L, -1) != LUA_TTABLE) {
4615 			hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response']['%s'] element must be an table. got %s.\n",
4616 				       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4617 				       name,
4618 			               lua_typename(L, lua_type(L, -1)));
4619 			WILL_LJMP(lua_error(L));
4620 		}
4621 
4622 		/* Browse the table who is on the top of the stack. */
4623 		lua_pushnil(L);
4624 		while(lua_next(L, -2) != 0) {
4625 			int id;
4626 
4627 			/* We expect a number as -2. */
4628 			if (lua_type(L, -2) != LUA_TNUMBER) {
4629 				hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response']['%s'][] element must be a number. got %s.\n",
4630 					       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4631 					       name,
4632 				               lua_typename(L, lua_type(L, -2)));
4633 				WILL_LJMP(lua_error(L));
4634 			}
4635 			id = lua_tointeger(L, -2);
4636 
4637 			/* We expect a string as -2. */
4638 			if (lua_type(L, -1) != LUA_TSTRING) {
4639 				hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response']['%s'][%d] element must be a string. got %s.\n",
4640 					       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4641 					       name, id,
4642 				               lua_typename(L, lua_type(L, -1)));
4643 				WILL_LJMP(lua_error(L));
4644 			}
4645 			value = lua_tolstring(L, -1, &vlen);
4646 
4647 			/* Simple Protocol checks. */
4648 			if (isteqi(ist2(name, nlen), ist("transfer-encoding")))
4649 				h1_parse_xfer_enc_header(&h1m, ist2(name, nlen));
4650 			else if (isteqi(ist2(name, nlen), ist("content-length"))) {
4651 				struct ist v = ist2(value, vlen);
4652 				int ret;
4653 
4654 				ret = h1_parse_cont_len_header(&h1m, &v);
4655 				if (ret < 0) {
4656 					hlua_pusherror(L, "Lua applet http '%s': Invalid '%s' header.\n",
4657 						       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4658 						       name);
4659 					WILL_LJMP(lua_error(L));
4660 				}
4661 				else if (ret == 0)
4662 					goto next; /* Skip it */
4663 			}
4664 
4665 			/* Add a new header */
4666 			if (!htx_add_header(htx, ist2(name, nlen), ist2(value, vlen))) {
4667 				hlua_pusherror(L, "Lua applet http '%s': Failed to add header '%s' in the response.\n",
4668 					       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4669 					       name);
4670 				WILL_LJMP(lua_error(L));
4671 			}
4672 		  next:
4673 			/* Remove the array from the stack, and get next element with a remaining string. */
4674 			lua_pop(L, 1);
4675 		}
4676 
4677 		/* Remove the array from the stack, and get next element with a remaining string. */
4678 		lua_pop(L, 1);
4679 	}
4680 
4681 	if (h1m.flags & H1_MF_CHNK)
4682 		h1m.flags &= ~H1_MF_CLEN;
4683 	if (h1m.flags & (H1_MF_CLEN|H1_MF_CHNK))
4684 		h1m.flags |= H1_MF_XFER_LEN;
4685 
4686 	/* Uset HTX start-line flags */
4687 	if (h1m.flags & H1_MF_XFER_ENC)
4688 		flags |= HTX_SL_F_XFER_ENC;
4689 	if (h1m.flags & H1_MF_XFER_LEN) {
4690 		flags |= HTX_SL_F_XFER_LEN;
4691 		if (h1m.flags & H1_MF_CHNK)
4692 			flags |= HTX_SL_F_CHNK;
4693 		else if (h1m.flags & H1_MF_CLEN)
4694 			flags |= HTX_SL_F_CLEN;
4695 		if (h1m.body_len == 0)
4696 			flags |= HTX_SL_F_BODYLESS;
4697 	}
4698 	sl->flags |= flags;
4699 
4700 	/* If we dont have a content-length set, and the HTTP version is 1.1
4701 	 * and the status code implies the presence of a message body, we must
4702 	 * announce a transfer encoding chunked. This is required by haproxy
4703 	 * for the keepalive compliance. If the applet annouces a transfer-encoding
4704 	 * chunked itslef, don't do anything.
4705 	 */
4706 	if ((flags & (HTX_SL_F_VER_11|HTX_SL_F_XFER_LEN)) == HTX_SL_F_VER_11 &&
4707 	    appctx->appctx->ctx.hlua_apphttp.status >= 200 &&
4708 	    appctx->appctx->ctx.hlua_apphttp.status != 204 &&
4709 	    appctx->appctx->ctx.hlua_apphttp.status != 304) {
4710 		/* Add a new header */
4711 		sl->flags |= (HTX_SL_F_XFER_ENC|H1_MF_CHNK|H1_MF_XFER_LEN);
4712 		if (!htx_add_header(htx, ist("transfer-encoding"), ist("chunked"))) {
4713 			hlua_pusherror(L, "Lua applet http '%s': Failed to add header 'transfer-encoding' in the response.\n",
4714 				       appctx->appctx->rule->arg.hlua_rule->fcn.name);
4715 			WILL_LJMP(lua_error(L));
4716 		}
4717 	}
4718 
4719 	/* Finalize headers. */
4720 	if (!htx_add_endof(htx, HTX_BLK_EOH)) {
4721 		hlua_pusherror(L, "Lua applet http '%s': Failed create the response.\n",
4722 			       appctx->appctx->rule->arg.hlua_rule->fcn.name);
4723 		WILL_LJMP(lua_error(L));
4724 	}
4725 
4726 	if (htx_used_space(htx) > b_size(&res->buf) - global.tune.maxrewrite) {
4727 		b_reset(&res->buf);
4728 		hlua_pusherror(L, "Lua: 'start_response': response header block too big");
4729 		WILL_LJMP(lua_error(L));
4730 	}
4731 
4732 	htx_to_buf(htx, &res->buf);
4733 	channel_add_input(res, htx->data);
4734 
4735 	/* Headers sent, set the flag. */
4736 	appctx->appctx->ctx.hlua_apphttp.flags |= APPLET_HDR_SENT;
4737 	return 0;
4738 
4739 }
4740 /* We will build the status line and the headers of the HTTP response.
4741  * We will try send at once if its not possible, we give back the hand
4742  * waiting for more room.
4743  */
hlua_applet_http_start_response_yield(lua_State * L,int status,lua_KContext ctx)4744 __LJMP static int hlua_applet_http_start_response_yield(lua_State *L, int status, lua_KContext ctx)
4745 {
4746 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4747 	struct stream_interface *si = appctx->appctx->owner;
4748 	struct channel *res = si_ic(si);
4749 
4750 	if (co_data(res)) {
4751 		si_rx_room_blk(si);
4752 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_http_start_response_yield, TICK_ETERNITY, 0));
4753 	}
4754 	return MAY_LJMP(hlua_applet_http_send_response(L));
4755 }
4756 
4757 
hlua_applet_http_start_response(lua_State * L)4758 __LJMP static int hlua_applet_http_start_response(lua_State *L)
4759 {
4760 	return MAY_LJMP(hlua_applet_http_start_response_yield(L, 0, 0));
4761 }
4762 
4763 /*
4764  *
4765  *
4766  * Class HTTP
4767  *
4768  *
4769  */
4770 
4771 /* Returns a struct hlua_txn if the stack entry "ud" is
4772  * a class stream, otherwise it throws an error.
4773  */
hlua_checkhttp(lua_State * L,int ud)4774 __LJMP static struct hlua_txn *hlua_checkhttp(lua_State *L, int ud)
4775 {
4776 	return MAY_LJMP(hlua_checkudata(L, ud, class_http_ref));
4777 }
4778 
4779 /* This function creates and push in the stack a HTTP object
4780  * according with a current TXN.
4781  */
hlua_http_new(lua_State * L,struct hlua_txn * txn)4782 static int hlua_http_new(lua_State *L, struct hlua_txn *txn)
4783 {
4784 	struct hlua_txn *htxn;
4785 
4786 	/* Check stack size. */
4787 	if (!lua_checkstack(L, 3))
4788 		return 0;
4789 
4790 	/* Create the object: obj[0] = userdata.
4791 	 * Note that the base of the Converters object is the
4792 	 * same than the TXN object.
4793 	 */
4794 	lua_newtable(L);
4795 	htxn = lua_newuserdata(L, sizeof(*htxn));
4796 	lua_rawseti(L, -2, 0);
4797 
4798 	htxn->s = txn->s;
4799 	htxn->p = txn->p;
4800 	htxn->dir = txn->dir;
4801 	htxn->flags = txn->flags;
4802 
4803 	/* Pop a class stream metatable and affect it to the table. */
4804 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_http_ref);
4805 	lua_setmetatable(L, -2);
4806 
4807 	return 1;
4808 }
4809 
4810 /* This function creates ans returns an array of HTTP headers.
4811  * This function does not fails. It is used as wrapper with the
4812  * 2 following functions.
4813  */
hlua_http_get_headers(lua_State * L,struct hlua_txn * htxn,struct http_msg * msg)4814 __LJMP static int hlua_http_get_headers(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
4815 {
4816 	struct htx *htx;
4817 	int32_t pos;
4818 
4819 	/* Create the table. */
4820 	lua_newtable(L);
4821 
4822 	if (!htxn->s->txn)
4823 		return 1;
4824 
4825 	htx = htxbuf(&msg->chn->buf);
4826 	for (pos = htx_get_first(htx); pos != -1; pos = htx_get_next(htx, pos)) {
4827 		struct htx_blk *blk = htx_get_blk(htx, pos);
4828 		enum htx_blk_type type = htx_get_blk_type(blk);
4829 		struct ist n, v;
4830 		int len;
4831 
4832 		if (type == HTX_BLK_HDR) {
4833 			n = htx_get_blk_name(htx,blk);
4834 			v = htx_get_blk_value(htx, blk);
4835 		}
4836 		else if (type == HTX_BLK_EOH)
4837 			break;
4838 		else
4839 			continue;
4840 
4841 		/* Check for existing entry:
4842 		 * assume that the table is on the top of the stack, and
4843 		 * push the key in the stack, the function lua_gettable()
4844 		 * perform the lookup.
4845 		 */
4846 		lua_pushlstring(L, n.ptr, n.len);
4847 		lua_gettable(L, -2);
4848 
4849 		switch (lua_type(L, -1)) {
4850 			case LUA_TNIL:
4851 				/* Table not found, create it. */
4852 				lua_pop(L, 1); /* remove the nil value. */
4853 				lua_pushlstring(L, n.ptr, n.len);  /* push the header name as key. */
4854 				lua_newtable(L); /* create and push empty table. */
4855 				lua_pushlstring(L, v.ptr, v.len); /* push header value. */
4856 				lua_rawseti(L, -2, 0); /* index header value (pop it). */
4857 				lua_rawset(L, -3); /* index new table with header name (pop the values). */
4858 				break;
4859 
4860 			case LUA_TTABLE:
4861 				/* Entry found: push the value in the table. */
4862 				len = lua_rawlen(L, -1);
4863 				lua_pushlstring(L, v.ptr, v.len); /* push header value. */
4864 				lua_rawseti(L, -2, len+1); /* index header value (pop it). */
4865 				lua_pop(L, 1); /* remove the table (it is stored in the main table). */
4866 				break;
4867 
4868 			default:
4869 				/* Other cases are errors. */
4870 				hlua_pusherror(L, "internal error during the parsing of headers.");
4871 				WILL_LJMP(lua_error(L));
4872 		}
4873 	}
4874 	return 1;
4875 }
4876 
hlua_http_req_get_headers(lua_State * L)4877 __LJMP static int hlua_http_req_get_headers(lua_State *L)
4878 {
4879 	struct hlua_txn *htxn;
4880 
4881 	MAY_LJMP(check_args(L, 1, "req_get_headers"));
4882 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
4883 
4884 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
4885 		WILL_LJMP(lua_error(L));
4886 
4887 	return hlua_http_get_headers(L, htxn, &htxn->s->txn->req);
4888 }
4889 
hlua_http_res_get_headers(lua_State * L)4890 __LJMP static int hlua_http_res_get_headers(lua_State *L)
4891 {
4892 	struct hlua_txn *htxn;
4893 
4894 	MAY_LJMP(check_args(L, 1, "res_get_headers"));
4895 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
4896 
4897 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
4898 		WILL_LJMP(lua_error(L));
4899 
4900 	return hlua_http_get_headers(L, htxn, &htxn->s->txn->rsp);
4901 }
4902 
4903 /* This function replace full header, or just a value in
4904  * the request or in the response. It is a wrapper fir the
4905  * 4 following functions.
4906  */
hlua_http_rep_hdr(lua_State * L,struct hlua_txn * htxn,struct http_msg * msg,int action)4907 __LJMP static inline int hlua_http_rep_hdr(lua_State *L, struct hlua_txn *htxn,
4908                                            struct http_msg *msg, int action)
4909 {
4910 	size_t name_len;
4911 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
4912 	const char *reg = MAY_LJMP(luaL_checkstring(L, 3));
4913 	const char *value = MAY_LJMP(luaL_checkstring(L, 4));
4914 	struct htx *htx;
4915 	struct my_regex *re;
4916 
4917 	if (!(re = regex_comp(reg, 1, 1, NULL)))
4918 		WILL_LJMP(luaL_argerror(L, 3, "invalid regex"));
4919 
4920 	htx = htxbuf(&msg->chn->buf);
4921 	http_transform_header_str(htxn->s, msg->chn, htx, ist2(name, name_len), value, re, action);
4922 	regex_free(re);
4923 	return 0;
4924 }
4925 
hlua_http_req_rep_hdr(lua_State * L)4926 __LJMP static int hlua_http_req_rep_hdr(lua_State *L)
4927 {
4928 	struct hlua_txn *htxn;
4929 
4930 	MAY_LJMP(check_args(L, 4, "req_rep_hdr"));
4931 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
4932 
4933 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
4934 		WILL_LJMP(lua_error(L));
4935 
4936 	return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->req, ACT_HTTP_REPLACE_HDR));
4937 }
4938 
hlua_http_res_rep_hdr(lua_State * L)4939 __LJMP static int hlua_http_res_rep_hdr(lua_State *L)
4940 {
4941 	struct hlua_txn *htxn;
4942 
4943 	MAY_LJMP(check_args(L, 4, "res_rep_hdr"));
4944 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
4945 
4946 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
4947 		WILL_LJMP(lua_error(L));
4948 
4949 	return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->rsp, ACT_HTTP_REPLACE_HDR));
4950 }
4951 
hlua_http_req_rep_val(lua_State * L)4952 __LJMP static int hlua_http_req_rep_val(lua_State *L)
4953 {
4954 	struct hlua_txn *htxn;
4955 
4956 	MAY_LJMP(check_args(L, 4, "req_rep_hdr"));
4957 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
4958 
4959 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
4960 		WILL_LJMP(lua_error(L));
4961 
4962 	return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->req, ACT_HTTP_REPLACE_VAL));
4963 }
4964 
hlua_http_res_rep_val(lua_State * L)4965 __LJMP static int hlua_http_res_rep_val(lua_State *L)
4966 {
4967 	struct hlua_txn *htxn;
4968 
4969 	MAY_LJMP(check_args(L, 4, "res_rep_val"));
4970 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
4971 
4972 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
4973 		WILL_LJMP(lua_error(L));
4974 
4975 	return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->rsp, ACT_HTTP_REPLACE_VAL));
4976 }
4977 
4978 /* This function deletes all the occurrences of an header.
4979  * It is a wrapper for the 2 following functions.
4980  */
hlua_http_del_hdr(lua_State * L,struct hlua_txn * htxn,struct http_msg * msg)4981 __LJMP static inline int hlua_http_del_hdr(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
4982 {
4983 	size_t len;
4984 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &len));
4985 	struct htx *htx = htxbuf(&msg->chn->buf);
4986 	struct http_hdr_ctx ctx;
4987 
4988 	ctx.blk = NULL;
4989 	while (http_find_header(htx, ist2(name, len), &ctx, 1))
4990 		http_remove_header(htx, &ctx);
4991 	return 0;
4992 }
4993 
hlua_http_req_del_hdr(lua_State * L)4994 __LJMP static int hlua_http_req_del_hdr(lua_State *L)
4995 {
4996 	struct hlua_txn *htxn;
4997 
4998 	MAY_LJMP(check_args(L, 2, "req_del_hdr"));
4999 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5000 
5001 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5002 		WILL_LJMP(lua_error(L));
5003 
5004 	return hlua_http_del_hdr(L, htxn, &htxn->s->txn->req);
5005 }
5006 
hlua_http_res_del_hdr(lua_State * L)5007 __LJMP static int hlua_http_res_del_hdr(lua_State *L)
5008 {
5009 	struct hlua_txn *htxn;
5010 
5011 	MAY_LJMP(check_args(L, 2, "res_del_hdr"));
5012 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5013 
5014 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5015 		WILL_LJMP(lua_error(L));
5016 
5017 	return hlua_http_del_hdr(L, htxn, &htxn->s->txn->rsp);
5018 }
5019 
5020 /* This function adds an header. It is a wrapper used by
5021  * the 2 following functions.
5022  */
hlua_http_add_hdr(lua_State * L,struct hlua_txn * htxn,struct http_msg * msg)5023 __LJMP static inline int hlua_http_add_hdr(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
5024 {
5025 	size_t name_len;
5026 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
5027 	size_t value_len;
5028 	const char *value = MAY_LJMP(luaL_checklstring(L, 3, &value_len));
5029 	struct htx *htx = htxbuf(&msg->chn->buf);
5030 
5031 	lua_pushboolean(L, http_add_header(htx, ist2(name, name_len),
5032 					   ist2(value, value_len)));
5033 	return 0;
5034 }
5035 
hlua_http_req_add_hdr(lua_State * L)5036 __LJMP static int hlua_http_req_add_hdr(lua_State *L)
5037 {
5038 	struct hlua_txn *htxn;
5039 
5040 	MAY_LJMP(check_args(L, 3, "req_add_hdr"));
5041 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5042 
5043 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5044 		WILL_LJMP(lua_error(L));
5045 
5046 	return hlua_http_add_hdr(L, htxn, &htxn->s->txn->req);
5047 }
5048 
hlua_http_res_add_hdr(lua_State * L)5049 __LJMP static int hlua_http_res_add_hdr(lua_State *L)
5050 {
5051 	struct hlua_txn *htxn;
5052 
5053 	MAY_LJMP(check_args(L, 3, "res_add_hdr"));
5054 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5055 
5056 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5057 		WILL_LJMP(lua_error(L));
5058 
5059 	return hlua_http_add_hdr(L, htxn, &htxn->s->txn->rsp);
5060 }
5061 
hlua_http_req_set_hdr(lua_State * L)5062 static int hlua_http_req_set_hdr(lua_State *L)
5063 {
5064 	struct hlua_txn *htxn;
5065 
5066 	MAY_LJMP(check_args(L, 3, "req_set_hdr"));
5067 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5068 
5069 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5070 		WILL_LJMP(lua_error(L));
5071 
5072 	hlua_http_del_hdr(L, htxn, &htxn->s->txn->req);
5073 	return hlua_http_add_hdr(L, htxn, &htxn->s->txn->req);
5074 }
5075 
hlua_http_res_set_hdr(lua_State * L)5076 static int hlua_http_res_set_hdr(lua_State *L)
5077 {
5078 	struct hlua_txn *htxn;
5079 
5080 	MAY_LJMP(check_args(L, 3, "res_set_hdr"));
5081 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5082 
5083 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5084 		WILL_LJMP(lua_error(L));
5085 
5086 	hlua_http_del_hdr(L, htxn, &htxn->s->txn->rsp);
5087 	return hlua_http_add_hdr(L, htxn, &htxn->s->txn->rsp);
5088 }
5089 
5090 /* This function set the method. */
hlua_http_req_set_meth(lua_State * L)5091 static int hlua_http_req_set_meth(lua_State *L)
5092 {
5093 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5094 	size_t name_len;
5095 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
5096 
5097 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5098 		WILL_LJMP(lua_error(L));
5099 
5100 	lua_pushboolean(L, http_req_replace_stline(0, name, name_len, htxn->p, htxn->s) != -1);
5101 	return 1;
5102 }
5103 
5104 /* This function set the method. */
hlua_http_req_set_path(lua_State * L)5105 static int hlua_http_req_set_path(lua_State *L)
5106 {
5107 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5108 	size_t name_len;
5109 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
5110 
5111 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5112 		WILL_LJMP(lua_error(L));
5113 
5114 	lua_pushboolean(L, http_req_replace_stline(1, name, name_len, htxn->p, htxn->s) != -1);
5115 	return 1;
5116 }
5117 
5118 /* This function set the query-string. */
hlua_http_req_set_query(lua_State * L)5119 static int hlua_http_req_set_query(lua_State *L)
5120 {
5121 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5122 	size_t name_len;
5123 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
5124 
5125 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5126 		WILL_LJMP(lua_error(L));
5127 
5128 	/* Check length. */
5129 	if (name_len > trash.size - 1) {
5130 		lua_pushboolean(L, 0);
5131 		return 1;
5132 	}
5133 
5134 	/* Add the mark question as prefix. */
5135 	chunk_reset(&trash);
5136 	trash.area[trash.data++] = '?';
5137 	memcpy(trash.area + trash.data, name, name_len);
5138 	trash.data += name_len;
5139 
5140 	lua_pushboolean(L,
5141 			http_req_replace_stline(2, trash.area, trash.data, htxn->p, htxn->s) != -1);
5142 	return 1;
5143 }
5144 
5145 /* This function set the uri. */
hlua_http_req_set_uri(lua_State * L)5146 static int hlua_http_req_set_uri(lua_State *L)
5147 {
5148 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5149 	size_t name_len;
5150 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
5151 
5152 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5153 		WILL_LJMP(lua_error(L));
5154 
5155 	lua_pushboolean(L, http_req_replace_stline(3, name, name_len, htxn->p, htxn->s) != -1);
5156 	return 1;
5157 }
5158 
5159 /* This function set the response code & optionally reason. */
hlua_http_res_set_status(lua_State * L)5160 static int hlua_http_res_set_status(lua_State *L)
5161 {
5162 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5163 	unsigned int code = MAY_LJMP(luaL_checkinteger(L, 2));
5164 	const char *reason = MAY_LJMP(luaL_optlstring(L, 3, NULL, NULL));
5165 
5166 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5167 		WILL_LJMP(lua_error(L));
5168 
5169 	http_res_set_status(code, reason, htxn->s);
5170 	return 0;
5171 }
5172 
5173 /*
5174  *
5175  *
5176  * Class TXN
5177  *
5178  *
5179  */
5180 
5181 /* Returns a struct hlua_session if the stack entry "ud" is
5182  * a class stream, otherwise it throws an error.
5183  */
hlua_checktxn(lua_State * L,int ud)5184 __LJMP static struct hlua_txn *hlua_checktxn(lua_State *L, int ud)
5185 {
5186 	return MAY_LJMP(hlua_checkudata(L, ud, class_txn_ref));
5187 }
5188 
hlua_set_var(lua_State * L)5189 __LJMP static int hlua_set_var(lua_State *L)
5190 {
5191 	struct hlua_txn *htxn;
5192 	const char *name;
5193 	size_t len;
5194 	struct sample smp;
5195 
5196 	MAY_LJMP(check_args(L, 3, "set_var"));
5197 
5198 	/* It is useles to retrieve the stream, but this function
5199 	 * runs only in a stream context.
5200 	 */
5201 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5202 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
5203 
5204 	/* Converts the third argument in a sample. */
5205 	memset(&smp, 0, sizeof(smp));
5206 	hlua_lua2smp(L, 3, &smp);
5207 
5208 	/* Store the sample in a variable. */
5209 	smp_set_owner(&smp, htxn->p, htxn->s->sess, htxn->s, htxn->dir & SMP_OPT_DIR);
5210 	vars_set_by_name(name, len, &smp);
5211 	return 0;
5212 }
5213 
hlua_unset_var(lua_State * L)5214 __LJMP static int hlua_unset_var(lua_State *L)
5215 {
5216 	struct hlua_txn *htxn;
5217 	const char *name;
5218 	size_t len;
5219 	struct sample smp;
5220 
5221 	MAY_LJMP(check_args(L, 2, "unset_var"));
5222 
5223 	/* It is useles to retrieve the stream, but this function
5224 	 * runs only in a stream context.
5225 	 */
5226 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5227 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
5228 
5229 	/* Unset the variable. */
5230 	smp_set_owner(&smp, htxn->p, htxn->s->sess, htxn->s, htxn->dir & SMP_OPT_DIR);
5231 	vars_unset_by_name(name, len, &smp);
5232 	return 0;
5233 }
5234 
hlua_get_var(lua_State * L)5235 __LJMP static int hlua_get_var(lua_State *L)
5236 {
5237 	struct hlua_txn *htxn;
5238 	const char *name;
5239 	size_t len;
5240 	struct sample smp;
5241 
5242 	MAY_LJMP(check_args(L, 2, "get_var"));
5243 
5244 	/* It is useles to retrieve the stream, but this function
5245 	 * runs only in a stream context.
5246 	 */
5247 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5248 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
5249 
5250 	smp_set_owner(&smp, htxn->p, htxn->s->sess, htxn->s, htxn->dir & SMP_OPT_DIR);
5251 	if (!vars_get_by_name(name, len, &smp)) {
5252 		lua_pushnil(L);
5253 		return 1;
5254 	}
5255 
5256 	return hlua_smp2lua(L, &smp);
5257 }
5258 
hlua_set_priv(lua_State * L)5259 __LJMP static int hlua_set_priv(lua_State *L)
5260 {
5261 	struct hlua *hlua;
5262 
5263 	MAY_LJMP(check_args(L, 2, "set_priv"));
5264 
5265 	/* It is useles to retrieve the stream, but this function
5266 	 * runs only in a stream context.
5267 	 */
5268 	MAY_LJMP(hlua_checktxn(L, 1));
5269 	hlua = hlua_gethlua(L);
5270 
5271 	/* Remove previous value. */
5272 	luaL_unref(L, LUA_REGISTRYINDEX, hlua->Mref);
5273 
5274 	/* Get and store new value. */
5275 	lua_pushvalue(L, 2); /* Copy the element 2 at the top of the stack. */
5276 	hlua->Mref = luaL_ref(L, LUA_REGISTRYINDEX); /* pop the previously pushed value. */
5277 
5278 	return 0;
5279 }
5280 
hlua_get_priv(lua_State * L)5281 __LJMP static int hlua_get_priv(lua_State *L)
5282 {
5283 	struct hlua *hlua;
5284 
5285 	MAY_LJMP(check_args(L, 1, "get_priv"));
5286 
5287 	/* It is useles to retrieve the stream, but this function
5288 	 * runs only in a stream context.
5289 	 */
5290 	MAY_LJMP(hlua_checktxn(L, 1));
5291 	hlua = hlua_gethlua(L);
5292 
5293 	/* Push configuration index in the stack. */
5294 	lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
5295 
5296 	return 1;
5297 }
5298 
5299 /* Create stack entry containing a class TXN. This function
5300  * return 0 if the stack does not contains free slots,
5301  * otherwise it returns 1.
5302  */
hlua_txn_new(lua_State * L,struct stream * s,struct proxy * p,int dir,int flags)5303 static int hlua_txn_new(lua_State *L, struct stream *s, struct proxy *p, int dir, int flags)
5304 {
5305 	struct hlua_txn *htxn;
5306 
5307 	/* Check stack size. */
5308 	if (!lua_checkstack(L, 3))
5309 		return 0;
5310 
5311 	/* NOTE: The allocation never fails. The failure
5312 	 * throw an error, and the function never returns.
5313 	 * if the throw is not available, the process is aborted.
5314 	 */
5315 	/* Create the object: obj[0] = userdata. */
5316 	lua_newtable(L);
5317 	htxn = lua_newuserdata(L, sizeof(*htxn));
5318 	lua_rawseti(L, -2, 0);
5319 
5320 	htxn->s = s;
5321 	htxn->p = p;
5322 	htxn->dir = dir;
5323 	htxn->flags = flags;
5324 
5325 	/* Create the "f" field that contains a list of fetches. */
5326 	lua_pushstring(L, "f");
5327 	if (!hlua_fetches_new(L, htxn, HLUA_F_MAY_USE_HTTP))
5328 		return 0;
5329 	lua_rawset(L, -3);
5330 
5331 	/* Create the "sf" field that contains a list of stringsafe fetches. */
5332 	lua_pushstring(L, "sf");
5333 	if (!hlua_fetches_new(L, htxn, HLUA_F_MAY_USE_HTTP | HLUA_F_AS_STRING))
5334 		return 0;
5335 	lua_rawset(L, -3);
5336 
5337 	/* Create the "c" field that contains a list of converters. */
5338 	lua_pushstring(L, "c");
5339 	if (!hlua_converters_new(L, htxn, 0))
5340 		return 0;
5341 	lua_rawset(L, -3);
5342 
5343 	/* Create the "sc" field that contains a list of stringsafe converters. */
5344 	lua_pushstring(L, "sc");
5345 	if (!hlua_converters_new(L, htxn, HLUA_F_AS_STRING))
5346 		return 0;
5347 	lua_rawset(L, -3);
5348 
5349 	/* Create the "req" field that contains the request channel object. */
5350 	lua_pushstring(L, "req");
5351 	if (!hlua_channel_new(L, &s->req))
5352 		return 0;
5353 	lua_rawset(L, -3);
5354 
5355 	/* Create the "res" field that contains the response channel object. */
5356 	lua_pushstring(L, "res");
5357 	if (!hlua_channel_new(L, &s->res))
5358 		return 0;
5359 	lua_rawset(L, -3);
5360 
5361 	/* Creates the HTTP object is the current proxy allows http. */
5362 	lua_pushstring(L, "http");
5363 	if (p->mode == PR_MODE_HTTP) {
5364 		if (!hlua_http_new(L, htxn))
5365 			return 0;
5366 	}
5367 	else
5368 		lua_pushnil(L);
5369 	lua_rawset(L, -3);
5370 
5371 	/* Pop a class sesison metatable and affect it to the userdata. */
5372 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_txn_ref);
5373 	lua_setmetatable(L, -2);
5374 
5375 	return 1;
5376 }
5377 
hlua_txn_deflog(lua_State * L)5378 __LJMP static int hlua_txn_deflog(lua_State *L)
5379 {
5380 	const char *msg;
5381 	struct hlua_txn *htxn;
5382 
5383 	MAY_LJMP(check_args(L, 2, "deflog"));
5384 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5385 	msg = MAY_LJMP(luaL_checkstring(L, 2));
5386 
5387 	hlua_sendlog(htxn->s->be, htxn->s->logs.level, msg);
5388 	return 0;
5389 }
5390 
hlua_txn_log(lua_State * L)5391 __LJMP static int hlua_txn_log(lua_State *L)
5392 {
5393 	int level;
5394 	const char *msg;
5395 	struct hlua_txn *htxn;
5396 
5397 	MAY_LJMP(check_args(L, 3, "log"));
5398 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5399 	level = MAY_LJMP(luaL_checkinteger(L, 2));
5400 	msg = MAY_LJMP(luaL_checkstring(L, 3));
5401 
5402 	if (level < 0 || level >= NB_LOG_LEVELS)
5403 		WILL_LJMP(luaL_argerror(L, 1, "Invalid loglevel."));
5404 
5405 	hlua_sendlog(htxn->s->be, level, msg);
5406 	return 0;
5407 }
5408 
hlua_txn_log_debug(lua_State * L)5409 __LJMP static int hlua_txn_log_debug(lua_State *L)
5410 {
5411 	const char *msg;
5412 	struct hlua_txn *htxn;
5413 
5414 	MAY_LJMP(check_args(L, 2, "Debug"));
5415 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5416 	msg = MAY_LJMP(luaL_checkstring(L, 2));
5417 	hlua_sendlog(htxn->s->be, LOG_DEBUG, msg);
5418 	return 0;
5419 }
5420 
hlua_txn_log_info(lua_State * L)5421 __LJMP static int hlua_txn_log_info(lua_State *L)
5422 {
5423 	const char *msg;
5424 	struct hlua_txn *htxn;
5425 
5426 	MAY_LJMP(check_args(L, 2, "Info"));
5427 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5428 	msg = MAY_LJMP(luaL_checkstring(L, 2));
5429 	hlua_sendlog(htxn->s->be, LOG_INFO, msg);
5430 	return 0;
5431 }
5432 
hlua_txn_log_warning(lua_State * L)5433 __LJMP static int hlua_txn_log_warning(lua_State *L)
5434 {
5435 	const char *msg;
5436 	struct hlua_txn *htxn;
5437 
5438 	MAY_LJMP(check_args(L, 2, "Warning"));
5439 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5440 	msg = MAY_LJMP(luaL_checkstring(L, 2));
5441 	hlua_sendlog(htxn->s->be, LOG_WARNING, msg);
5442 	return 0;
5443 }
5444 
hlua_txn_log_alert(lua_State * L)5445 __LJMP static int hlua_txn_log_alert(lua_State *L)
5446 {
5447 	const char *msg;
5448 	struct hlua_txn *htxn;
5449 
5450 	MAY_LJMP(check_args(L, 2, "Alert"));
5451 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5452 	msg = MAY_LJMP(luaL_checkstring(L, 2));
5453 	hlua_sendlog(htxn->s->be, LOG_ALERT, msg);
5454 	return 0;
5455 }
5456 
hlua_txn_set_loglevel(lua_State * L)5457 __LJMP static int hlua_txn_set_loglevel(lua_State *L)
5458 {
5459 	struct hlua_txn *htxn;
5460 	int ll;
5461 
5462 	MAY_LJMP(check_args(L, 2, "set_loglevel"));
5463 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5464 	ll = MAY_LJMP(luaL_checkinteger(L, 2));
5465 
5466 	if (ll < 0 || ll > 7)
5467 		WILL_LJMP(luaL_argerror(L, 2, "Bad log level. It must be between 0 and 7"));
5468 
5469 	htxn->s->logs.level = ll;
5470 	return 0;
5471 }
5472 
hlua_txn_set_tos(lua_State * L)5473 __LJMP static int hlua_txn_set_tos(lua_State *L)
5474 {
5475 	struct hlua_txn *htxn;
5476 	int tos;
5477 
5478 	MAY_LJMP(check_args(L, 2, "set_tos"));
5479 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5480 	tos = MAY_LJMP(luaL_checkinteger(L, 2));
5481 
5482 	conn_set_tos(objt_conn(htxn->s->sess->origin), tos);
5483 	return 0;
5484 }
5485 
hlua_txn_set_mark(lua_State * L)5486 __LJMP static int hlua_txn_set_mark(lua_State *L)
5487 {
5488 	struct hlua_txn *htxn;
5489 	int mark;
5490 
5491 	MAY_LJMP(check_args(L, 2, "set_mark"));
5492 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5493 	mark = MAY_LJMP(luaL_checkinteger(L, 2));
5494 
5495 	conn_set_mark(objt_conn(htxn->s->sess->origin), mark);
5496 	return 0;
5497 }
5498 
hlua_txn_set_priority_class(lua_State * L)5499 __LJMP static int hlua_txn_set_priority_class(lua_State *L)
5500 {
5501 	struct hlua_txn *htxn;
5502 
5503 	MAY_LJMP(check_args(L, 2, "set_priority_class"));
5504 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5505 	htxn->s->priority_class = queue_limit_class(MAY_LJMP(luaL_checkinteger(L, 2)));
5506 	return 0;
5507 }
5508 
hlua_txn_set_priority_offset(lua_State * L)5509 __LJMP static int hlua_txn_set_priority_offset(lua_State *L)
5510 {
5511 	struct hlua_txn *htxn;
5512 
5513 	MAY_LJMP(check_args(L, 2, "set_priority_offset"));
5514 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5515 	htxn->s->priority_offset = queue_limit_offset(MAY_LJMP(luaL_checkinteger(L, 2)));
5516 	return 0;
5517 }
5518 
5519 /* This function is an Lua binding that send pending data
5520  * to the client, and close the stream interface.
5521  */
hlua_txn_done(lua_State * L)5522 __LJMP static int hlua_txn_done(lua_State *L)
5523 {
5524 	struct hlua_txn *htxn;
5525 	struct hlua *hlua;
5526 	struct channel *ic, *oc;
5527 
5528 	MAY_LJMP(check_args(L, 1, "close"));
5529 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5530 	hlua = hlua_gethlua(L);
5531 
5532 	/* If the flags NOTERM is set, we cannot terminate the http
5533 	 * session, so we just end the execution of the current
5534 	 * lua code.
5535 	 */
5536 	if (htxn->flags & HLUA_TXN_NOTERM) {
5537 		WILL_LJMP(hlua_done(L));
5538 		return 0;
5539 	}
5540 
5541 	ic = &htxn->s->req;
5542 	oc = &htxn->s->res;
5543 
5544 	if (IS_HTX_STRM(htxn->s)) {
5545 		htxn->s->txn->status = 0;
5546 		http_reply_and_close(htxn->s, 0, NULL);
5547 	}
5548 	else {
5549 		channel_auto_read(ic);
5550 		channel_abort(ic);
5551 		channel_auto_close(ic);
5552 		channel_erase(ic);
5553 
5554 		oc->wex = tick_add_ifset(now_ms, oc->wto);
5555 		channel_auto_read(oc);
5556 		channel_auto_close(oc);
5557 		channel_shutr_now(oc);
5558 
5559 	}
5560 
5561 	ic->analysers &= AN_REQ_FLT_END;
5562 	oc->analysers &= AN_RES_FLT_END;
5563 
5564 	if (!(htxn->s->flags & SF_ERR_MASK))      // this is not really an error but it is
5565 		htxn->s->flags |= SF_ERR_LOCAL;   // to mark that it comes from the proxy
5566 
5567 	hlua->flags |= HLUA_STOP;
5568 	WILL_LJMP(hlua_done(L));
5569 	return 0;
5570 }
5571 
hlua_log(lua_State * L)5572 __LJMP static int hlua_log(lua_State *L)
5573 {
5574 	int level;
5575 	const char *msg;
5576 
5577 	MAY_LJMP(check_args(L, 2, "log"));
5578 	level = MAY_LJMP(luaL_checkinteger(L, 1));
5579 	msg = MAY_LJMP(luaL_checkstring(L, 2));
5580 
5581 	if (level < 0 || level >= NB_LOG_LEVELS)
5582 		WILL_LJMP(luaL_argerror(L, 1, "Invalid loglevel."));
5583 
5584 	hlua_sendlog(NULL, level, msg);
5585 	return 0;
5586 }
5587 
hlua_log_debug(lua_State * L)5588 __LJMP static int hlua_log_debug(lua_State *L)
5589 {
5590 	const char *msg;
5591 
5592 	MAY_LJMP(check_args(L, 1, "debug"));
5593 	msg = MAY_LJMP(luaL_checkstring(L, 1));
5594 	hlua_sendlog(NULL, LOG_DEBUG, msg);
5595 	return 0;
5596 }
5597 
hlua_log_info(lua_State * L)5598 __LJMP static int hlua_log_info(lua_State *L)
5599 {
5600 	const char *msg;
5601 
5602 	MAY_LJMP(check_args(L, 1, "info"));
5603 	msg = MAY_LJMP(luaL_checkstring(L, 1));
5604 	hlua_sendlog(NULL, LOG_INFO, msg);
5605 	return 0;
5606 }
5607 
hlua_log_warning(lua_State * L)5608 __LJMP static int hlua_log_warning(lua_State *L)
5609 {
5610 	const char *msg;
5611 
5612 	MAY_LJMP(check_args(L, 1, "warning"));
5613 	msg = MAY_LJMP(luaL_checkstring(L, 1));
5614 	hlua_sendlog(NULL, LOG_WARNING, msg);
5615 	return 0;
5616 }
5617 
hlua_log_alert(lua_State * L)5618 __LJMP static int hlua_log_alert(lua_State *L)
5619 {
5620 	const char *msg;
5621 
5622 	MAY_LJMP(check_args(L, 1, "alert"));
5623 	msg = MAY_LJMP(luaL_checkstring(L, 1));
5624 	hlua_sendlog(NULL, LOG_ALERT, msg);
5625 	return 0;
5626 }
5627 
hlua_sleep_yield(lua_State * L,int status,lua_KContext ctx)5628 __LJMP static int hlua_sleep_yield(lua_State *L, int status, lua_KContext ctx)
5629 {
5630 	int wakeup_ms = lua_tointeger(L, -1);
5631 	if (now_ms < wakeup_ms)
5632 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
5633 	return 0;
5634 }
5635 
hlua_sleep(lua_State * L)5636 __LJMP static int hlua_sleep(lua_State *L)
5637 {
5638 	unsigned int delay;
5639 	unsigned int wakeup_ms;
5640 
5641 	MAY_LJMP(check_args(L, 1, "sleep"));
5642 
5643 	delay = MAY_LJMP(luaL_checkinteger(L, 1)) * 1000;
5644 	wakeup_ms = tick_add(now_ms, delay);
5645 	lua_pushinteger(L, wakeup_ms);
5646 
5647 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
5648 	return 0;
5649 }
5650 
hlua_msleep(lua_State * L)5651 __LJMP static int hlua_msleep(lua_State *L)
5652 {
5653 	unsigned int delay;
5654 	unsigned int wakeup_ms;
5655 
5656 	MAY_LJMP(check_args(L, 1, "msleep"));
5657 
5658 	delay = MAY_LJMP(luaL_checkinteger(L, 1));
5659 	wakeup_ms = tick_add(now_ms, delay);
5660 	lua_pushinteger(L, wakeup_ms);
5661 
5662 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
5663 	return 0;
5664 }
5665 
5666 /* This functionis an LUA binding. it permits to give back
5667  * the hand at the HAProxy scheduler. It is used when the
5668  * LUA processing consumes a lot of time.
5669  */
hlua_yield_yield(lua_State * L,int status,lua_KContext ctx)5670 __LJMP static int hlua_yield_yield(lua_State *L, int status, lua_KContext ctx)
5671 {
5672 	return 0;
5673 }
5674 
hlua_yield(lua_State * L)5675 __LJMP static int hlua_yield(lua_State *L)
5676 {
5677 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_yield_yield, TICK_ETERNITY, HLUA_CTRLYIELD));
5678 	return 0;
5679 }
5680 
5681 /* This function change the nice of the currently executed
5682  * task. It is used set low or high priority at the current
5683  * task.
5684  */
hlua_set_nice(lua_State * L)5685 __LJMP static int hlua_set_nice(lua_State *L)
5686 {
5687 	struct hlua *hlua;
5688 	int nice;
5689 
5690 	MAY_LJMP(check_args(L, 1, "set_nice"));
5691 	hlua = hlua_gethlua(L);
5692 	nice = MAY_LJMP(luaL_checkinteger(L, 1));
5693 
5694 	/* If he task is not set, I'm in a start mode. */
5695 	if (!hlua || !hlua->task)
5696 		return 0;
5697 
5698 	if (nice < -1024)
5699 		nice = -1024;
5700 	else if (nice > 1024)
5701 		nice = 1024;
5702 
5703 	hlua->task->nice = nice;
5704 	return 0;
5705 }
5706 
5707 /* This function is used as a callback of a task. It is called by the
5708  * HAProxy task subsystem when the task is awaked. The LUA runtime can
5709  * return an E_AGAIN signal, the emmiter of this signal must set a
5710  * signal to wake the task.
5711  *
5712  * Task wrapper are longjmp safe because the only one Lua code
5713  * executed is the safe hlua_ctx_resume();
5714  */
hlua_process_task(struct task * task,void * context,unsigned short state)5715 struct task *hlua_process_task(struct task *task, void *context, unsigned short state)
5716 {
5717 	struct hlua *hlua = context;
5718 	enum hlua_exec status;
5719 
5720 	if (task->thread_mask == MAX_THREADS_MASK)
5721 		task_set_affinity(task, tid_bit);
5722 
5723 	/* If it is the first call to the task, we must initialize the
5724 	 * execution timeouts.
5725 	 */
5726 	if (!HLUA_IS_RUNNING(hlua))
5727 		hlua->max_time = hlua_timeout_task;
5728 
5729 	/* Execute the Lua code. */
5730 	status = hlua_ctx_resume(hlua, 1);
5731 
5732 	switch (status) {
5733 	/* finished or yield */
5734 	case HLUA_E_OK:
5735 		hlua_ctx_destroy(hlua);
5736 		task_destroy(task);
5737 		task = NULL;
5738 		break;
5739 
5740 	case HLUA_E_AGAIN: /* co process or timeout wake me later. */
5741 		notification_gc(&hlua->com);
5742 		task->expire = hlua->wake_time;
5743 		break;
5744 
5745 	/* finished with error. */
5746 	case HLUA_E_ERRMSG:
5747 		SEND_ERR(NULL, "Lua task: %s.\n", lua_tostring(hlua->T, -1));
5748 		hlua_ctx_destroy(hlua);
5749 		task_destroy(task);
5750 		task = NULL;
5751 		break;
5752 
5753 	case HLUA_E_ERR:
5754 	default:
5755 		SEND_ERR(NULL, "Lua task: unknown error.\n");
5756 		hlua_ctx_destroy(hlua);
5757 		task_destroy(task);
5758 		task = NULL;
5759 		break;
5760 	}
5761 	return task;
5762 }
5763 
5764 /* This function is an LUA binding that register LUA function to be
5765  * executed after the HAProxy configuration parsing and before the
5766  * HAProxy scheduler starts. This function expect only one LUA
5767  * argument that is a function. This function returns nothing, but
5768  * throws if an error is encountered.
5769  */
hlua_register_init(lua_State * L)5770 __LJMP static int hlua_register_init(lua_State *L)
5771 {
5772 	struct hlua_init_function *init;
5773 	int ref;
5774 
5775 	MAY_LJMP(check_args(L, 1, "register_init"));
5776 
5777 	ref = MAY_LJMP(hlua_checkfunction(L, 1));
5778 
5779 	init = calloc(1, sizeof(*init));
5780 	if (!init)
5781 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
5782 
5783 	init->function_ref = ref;
5784 	LIST_ADDQ(&hlua_init_functions, &init->l);
5785 	return 0;
5786 }
5787 
5788 /* This functio is an LUA binding. It permits to register a task
5789  * executed in parallel of the main HAroxy activity. The task is
5790  * created and it is set in the HAProxy scheduler. It can be called
5791  * from the "init" section, "post init" or during the runtime.
5792  *
5793  * Lua prototype:
5794  *
5795  *   <none> core.register_task(<function>)
5796  */
hlua_register_task(lua_State * L)5797 static int hlua_register_task(lua_State *L)
5798 {
5799 	struct hlua *hlua;
5800 	struct task *task;
5801 	int ref;
5802 
5803 	MAY_LJMP(check_args(L, 1, "register_task"));
5804 
5805 	ref = MAY_LJMP(hlua_checkfunction(L, 1));
5806 
5807 	hlua = pool_alloc(pool_head_hlua);
5808 	if (!hlua)
5809 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
5810 
5811 	task = task_new(MAX_THREADS_MASK);
5812 	if (!task)
5813 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
5814 
5815 	task->context = hlua;
5816 	task->process = hlua_process_task;
5817 
5818 	if (!hlua_ctx_init(hlua, task, 1))
5819 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
5820 
5821 	/* Restore the function in the stack. */
5822 	lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ref);
5823 	hlua->nargs = 0;
5824 
5825 	/* Schedule task. */
5826 	task_schedule(task, now_ms);
5827 
5828 	return 0;
5829 }
5830 
5831 /* Wrapper called by HAProxy to execute an LUA converter. This wrapper
5832  * doesn't allow "yield" functions because the HAProxy engine cannot
5833  * resume converters.
5834  */
hlua_sample_conv_wrapper(const struct arg * arg_p,struct sample * smp,void * private)5835 static int hlua_sample_conv_wrapper(const struct arg *arg_p, struct sample *smp, void *private)
5836 {
5837 	struct hlua_function *fcn = private;
5838 	struct stream *stream = smp->strm;
5839 	const char *error;
5840 
5841 	if (!stream)
5842 		return 0;
5843 
5844 	/* In the execution wrappers linked with a stream, the
5845 	 * Lua context can be not initialized. This behavior
5846 	 * permits to save performances because a systematic
5847 	 * Lua initialization cause 5% performances loss.
5848 	 */
5849 	if (!stream->hlua) {
5850 		stream->hlua = pool_alloc(pool_head_hlua);
5851 		if (!stream->hlua) {
5852 			SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
5853 			return 0;
5854 		}
5855 		if (!hlua_ctx_init(stream->hlua, stream->task, 0)) {
5856 			SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
5857 			return 0;
5858 		}
5859 	}
5860 
5861 	/* If it is the first run, initialize the data for the call. */
5862 	if (!HLUA_IS_RUNNING(stream->hlua)) {
5863 
5864 		/* The following Lua calls can fail. */
5865 		if (!SET_SAFE_LJMP(stream->hlua->T)) {
5866 			if (lua_type(stream->hlua->T, -1) == LUA_TSTRING)
5867 				error = lua_tostring(stream->hlua->T, -1);
5868 			else
5869 				error = "critical error";
5870 			SEND_ERR(stream->be, "Lua converter '%s': %s.\n", fcn->name, error);
5871 			return 0;
5872 		}
5873 
5874 		/* Check stack available size. */
5875 		if (!lua_checkstack(stream->hlua->T, 1)) {
5876 			SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
5877 			RESET_SAFE_LJMP(stream->hlua->T);
5878 			return 0;
5879 		}
5880 
5881 		/* Restore the function in the stack. */
5882 		lua_rawgeti(stream->hlua->T, LUA_REGISTRYINDEX, fcn->function_ref);
5883 
5884 		/* convert input sample and pust-it in the stack. */
5885 		if (!lua_checkstack(stream->hlua->T, 1)) {
5886 			SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
5887 			RESET_SAFE_LJMP(stream->hlua->T);
5888 			return 0;
5889 		}
5890 		hlua_smp2lua(stream->hlua->T, smp);
5891 		stream->hlua->nargs = 1;
5892 
5893 		/* push keywords in the stack. */
5894 		if (arg_p) {
5895 			for (; arg_p->type != ARGT_STOP; arg_p++) {
5896 				if (!lua_checkstack(stream->hlua->T, 1)) {
5897 					SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
5898 					RESET_SAFE_LJMP(stream->hlua->T);
5899 					return 0;
5900 				}
5901 				hlua_arg2lua(stream->hlua->T, arg_p);
5902 				stream->hlua->nargs++;
5903 			}
5904 		}
5905 
5906 		/* We must initialize the execution timeouts. */
5907 		stream->hlua->max_time = hlua_timeout_session;
5908 
5909 		/* At this point the execution is safe. */
5910 		RESET_SAFE_LJMP(stream->hlua->T);
5911 	}
5912 
5913 	/* Execute the function. */
5914 	switch (hlua_ctx_resume(stream->hlua, 0)) {
5915 	/* finished. */
5916 	case HLUA_E_OK:
5917 		/* If the stack is empty, the function fails. */
5918 		if (lua_gettop(stream->hlua->T) <= 0)
5919 			return 0;
5920 
5921 		/* Convert the returned value in sample. */
5922 		hlua_lua2smp(stream->hlua->T, -1, smp);
5923 		lua_pop(stream->hlua->T, 1);
5924 		return 1;
5925 
5926 	/* yield. */
5927 	case HLUA_E_AGAIN:
5928 		SEND_ERR(stream->be, "Lua converter '%s': cannot use yielded functions.\n", fcn->name);
5929 		return 0;
5930 
5931 	/* finished with error. */
5932 	case HLUA_E_ERRMSG:
5933 		/* Display log. */
5934 		SEND_ERR(stream->be, "Lua converter '%s': %s.\n",
5935 		         fcn->name, lua_tostring(stream->hlua->T, -1));
5936 		lua_pop(stream->hlua->T, 1);
5937 		return 0;
5938 
5939 	case HLUA_E_ETMOUT:
5940 		SEND_ERR(stream->be, "Lua converter '%s': execution timeout.\n", fcn->name);
5941 		return 0;
5942 
5943 	case HLUA_E_NOMEM:
5944 		SEND_ERR(stream->be, "Lua converter '%s': out of memory error.\n", fcn->name);
5945 		return 0;
5946 
5947 	case HLUA_E_YIELD:
5948 		SEND_ERR(stream->be, "Lua converter '%s': yield functions like core.tcp() or core.sleep() are not allowed.\n", fcn->name);
5949 		return 0;
5950 
5951 	case HLUA_E_ERR:
5952 		/* Display log. */
5953 		SEND_ERR(stream->be, "Lua converter '%s' returns an unknown error.\n", fcn->name);
5954 
5955 	default:
5956 		return 0;
5957 	}
5958 }
5959 
5960 /* Wrapper called by HAProxy to execute a sample-fetch. this wrapper
5961  * doesn't allow "yield" functions because the HAProxy engine cannot
5962  * resume sample-fetches. This function will be called by the sample
5963  * fetch engine to call lua-based fetch operations.
5964  */
hlua_sample_fetch_wrapper(const struct arg * arg_p,struct sample * smp,const char * kw,void * private)5965 static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp,
5966                                      const char *kw, void *private)
5967 {
5968 	struct hlua_function *fcn = private;
5969 	struct stream *stream = smp->strm;
5970 	const char *error;
5971 	const struct buffer msg = { };
5972 	unsigned int hflags = HLUA_TXN_NOTERM;
5973 
5974 	if (!stream)
5975 		return 0;
5976 
5977 	/* In the execution wrappers linked with a stream, the
5978 	 * Lua context can be not initialized. This behavior
5979 	 * permits to save performances because a systematic
5980 	 * Lua initialization cause 5% performances loss.
5981 	 */
5982 	if (!stream->hlua) {
5983 		stream->hlua = pool_alloc(pool_head_hlua);
5984 		if (!stream->hlua) {
5985 			SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
5986 			return 0;
5987 		}
5988 		if (!hlua_ctx_init(stream->hlua, stream->task, 0)) {
5989 			SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
5990 			return 0;
5991 		}
5992 	}
5993 
5994 	consistency_set(stream, smp->opt, &stream->hlua->cons);
5995 
5996 	if (stream->be->mode == PR_MODE_HTTP) {
5997 		if ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ)
5998 			hflags |= ((stream->txn->req.msg_state < HTTP_MSG_BODY) ? 0 : HLUA_TXN_HTTP_RDY);
5999 		else
6000 			hflags |= ((stream->txn->rsp.msg_state < HTTP_MSG_BODY) ? 0 : HLUA_TXN_HTTP_RDY);
6001 	}
6002 
6003 	/* If it is the first run, initialize the data for the call. */
6004 	if (!HLUA_IS_RUNNING(stream->hlua)) {
6005 
6006 		/* The following Lua calls can fail. */
6007 		if (!SET_SAFE_LJMP(stream->hlua->T)) {
6008 			if (lua_type(stream->hlua->T, -1) == LUA_TSTRING)
6009 				error = lua_tostring(stream->hlua->T, -1);
6010 			else
6011 				error = "critical error";
6012 			SEND_ERR(smp->px, "Lua sample-fetch '%s': %s.\n", fcn->name, error);
6013 			return 0;
6014 		}
6015 
6016 		/* Check stack available size. */
6017 		if (!lua_checkstack(stream->hlua->T, 2)) {
6018 			SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
6019 			RESET_SAFE_LJMP(stream->hlua->T);
6020 			return 0;
6021 		}
6022 
6023 		/* Restore the function in the stack. */
6024 		lua_rawgeti(stream->hlua->T, LUA_REGISTRYINDEX, fcn->function_ref);
6025 
6026 		/* push arguments in the stack. */
6027 		if (!hlua_txn_new(stream->hlua->T, stream, smp->px, smp->opt & SMP_OPT_DIR, hflags)) {
6028 			SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
6029 			RESET_SAFE_LJMP(stream->hlua->T);
6030 			return 0;
6031 		}
6032 		stream->hlua->nargs = 1;
6033 
6034 		/* push keywords in the stack. */
6035 		for (; arg_p && arg_p->type != ARGT_STOP; arg_p++) {
6036 			/* Check stack available size. */
6037 			if (!lua_checkstack(stream->hlua->T, 1)) {
6038 				SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
6039 				RESET_SAFE_LJMP(stream->hlua->T);
6040 				return 0;
6041 			}
6042 			hlua_arg2lua(stream->hlua->T, arg_p);
6043 			stream->hlua->nargs++;
6044 		}
6045 
6046 		/* We must initialize the execution timeouts. */
6047 		stream->hlua->max_time = hlua_timeout_session;
6048 
6049 		/* At this point the execution is safe. */
6050 		RESET_SAFE_LJMP(stream->hlua->T);
6051 	}
6052 
6053 	/* Execute the function. */
6054 	switch (hlua_ctx_resume(stream->hlua, 0)) {
6055 	/* finished. */
6056 	case HLUA_E_OK:
6057 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons)) {
6058 			si_retnclose(&stream->si[0], &msg);
6059 			return 0;
6060 		}
6061 		/* If the stack is empty, the function fails. */
6062 		if (lua_gettop(stream->hlua->T) <= 0)
6063 			return 0;
6064 
6065 		/* Convert the returned value in sample. */
6066 		hlua_lua2smp(stream->hlua->T, -1, smp);
6067 		lua_pop(stream->hlua->T, 1);
6068 
6069 		/* Set the end of execution flag. */
6070 		smp->flags &= ~SMP_F_MAY_CHANGE;
6071 		return 1;
6072 
6073 	/* yield. */
6074 	case HLUA_E_AGAIN:
6075 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6076 			si_retnclose(&stream->si[0], &msg);
6077 		SEND_ERR(smp->px, "Lua sample-fetch '%s': cannot use yielded functions.\n", fcn->name);
6078 		return 0;
6079 
6080 	/* finished with error. */
6081 	case HLUA_E_ERRMSG:
6082 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6083 			si_retnclose(&stream->si[0], &msg);
6084 		/* Display log. */
6085 		SEND_ERR(smp->px, "Lua sample-fetch '%s': %s.\n",
6086 		         fcn->name, lua_tostring(stream->hlua->T, -1));
6087 		lua_pop(stream->hlua->T, 1);
6088 		return 0;
6089 
6090 	case HLUA_E_ETMOUT:
6091 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6092 			si_retnclose(&stream->si[0], &msg);
6093 		SEND_ERR(smp->px, "Lua sample-fetch '%s': execution timeout.\n", fcn->name);
6094 		return 0;
6095 
6096 	case HLUA_E_NOMEM:
6097 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6098 			si_retnclose(&stream->si[0], &msg);
6099 		SEND_ERR(smp->px, "Lua sample-fetch '%s': out of memory error.\n", fcn->name);
6100 		return 0;
6101 
6102 	case HLUA_E_YIELD:
6103 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6104 			si_retnclose(&stream->si[0], &msg);
6105 		SEND_ERR(smp->px, "Lua sample-fetch '%s': yield not allowed.\n", fcn->name);
6106 		return 0;
6107 
6108 	case HLUA_E_ERR:
6109 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6110 			si_retnclose(&stream->si[0], &msg);
6111 		/* Display log. */
6112 		SEND_ERR(smp->px, "Lua sample-fetch '%s' returns an unknown error.\n", fcn->name);
6113 
6114 	default:
6115 		return 0;
6116 	}
6117 }
6118 
6119 /* This function is an LUA binding used for registering
6120  * "sample-conv" functions. It expects a converter name used
6121  * in the haproxy configuration file, and an LUA function.
6122  */
hlua_register_converters(lua_State * L)6123 __LJMP static int hlua_register_converters(lua_State *L)
6124 {
6125 	struct sample_conv_kw_list *sck;
6126 	const char *name;
6127 	int ref;
6128 	int len;
6129 	struct hlua_function *fcn;
6130 	struct sample_conv *sc;
6131 	struct buffer *trash;
6132 
6133 	MAY_LJMP(check_args(L, 2, "register_converters"));
6134 
6135 	/* First argument : converter name. */
6136 	name = MAY_LJMP(luaL_checkstring(L, 1));
6137 
6138 	/* Second argument : lua function. */
6139 	ref = MAY_LJMP(hlua_checkfunction(L, 2));
6140 
6141 	/* Check if the converter is already registered */
6142 	trash = get_trash_chunk();
6143 	chunk_printf(trash, "lua.%s", name);
6144 	sc = find_sample_conv(trash->area, trash->data);
6145 	if (sc != NULL) {
6146 		ha_warning("Trying to register converter 'lua.%s' more than once. "
6147 		           "This will become a hard error in version 2.5.\n", name);
6148 	}
6149 
6150 	/* Allocate and fill the sample fetch keyword struct. */
6151 	sck = calloc(1, sizeof(*sck) + sizeof(struct sample_conv) * 2);
6152 	if (!sck)
6153 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6154 	fcn = calloc(1, sizeof(*fcn));
6155 	if (!fcn)
6156 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6157 
6158 	/* Fill fcn. */
6159 	fcn->name = strdup(name);
6160 	if (!fcn->name)
6161 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6162 	fcn->function_ref = ref;
6163 
6164 	/* List head */
6165 	sck->list.n = sck->list.p = NULL;
6166 
6167 	/* converter keyword. */
6168 	len = strlen("lua.") + strlen(name) + 1;
6169 	sck->kw[0].kw = calloc(1, len);
6170 	if (!sck->kw[0].kw)
6171 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6172 
6173 	snprintf((char *)sck->kw[0].kw, len, "lua.%s", name);
6174 	sck->kw[0].process = hlua_sample_conv_wrapper;
6175 	sck->kw[0].arg_mask = ARG12(0,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR);
6176 	sck->kw[0].val_args = NULL;
6177 	sck->kw[0].in_type = SMP_T_STR;
6178 	sck->kw[0].out_type = SMP_T_STR;
6179 	sck->kw[0].private = fcn;
6180 
6181 	/* Register this new converter */
6182 	sample_register_convs(sck);
6183 
6184 	return 0;
6185 }
6186 
6187 /* This function is an LUA binding used for registering
6188  * "sample-fetch" functions. It expects a converter name used
6189  * in the haproxy configuration file, and an LUA function.
6190  */
hlua_register_fetches(lua_State * L)6191 __LJMP static int hlua_register_fetches(lua_State *L)
6192 {
6193 	const char *name;
6194 	int ref;
6195 	int len;
6196 	struct sample_fetch_kw_list *sfk;
6197 	struct hlua_function *fcn;
6198 	struct sample_fetch *sf;
6199 	struct buffer *trash;
6200 
6201 	MAY_LJMP(check_args(L, 2, "register_fetches"));
6202 
6203 	/* First argument : sample-fetch name. */
6204 	name = MAY_LJMP(luaL_checkstring(L, 1));
6205 
6206 	/* Second argument : lua function. */
6207 	ref = MAY_LJMP(hlua_checkfunction(L, 2));
6208 
6209 	/* Check if the sample-fetch is already registered */
6210 	trash = get_trash_chunk();
6211 	chunk_printf(trash, "lua.%s", name);
6212 	sf = find_sample_fetch(trash->area, trash->data);
6213 	if (sf != NULL) {
6214 		ha_warning("Trying to register sample-fetch 'lua.%s' more than once. "
6215 		           "This will become a hard error in version 2.5.\n", name);
6216 	}
6217 
6218 	/* Allocate and fill the sample fetch keyword struct. */
6219 	sfk = calloc(1, sizeof(*sfk) + sizeof(struct sample_fetch) * 2);
6220 	if (!sfk)
6221 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6222 	fcn = calloc(1, sizeof(*fcn));
6223 	if (!fcn)
6224 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6225 
6226 	/* Fill fcn. */
6227 	fcn->name = strdup(name);
6228 	if (!fcn->name)
6229 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6230 	fcn->function_ref = ref;
6231 
6232 	/* List head */
6233 	sfk->list.n = sfk->list.p = NULL;
6234 
6235 	/* sample-fetch keyword. */
6236 	len = strlen("lua.") + strlen(name) + 1;
6237 	sfk->kw[0].kw = calloc(1, len);
6238 	if (!sfk->kw[0].kw)
6239 		return luaL_error(L, "Lua out of memory error.");
6240 
6241 	snprintf((char *)sfk->kw[0].kw, len, "lua.%s", name);
6242 	sfk->kw[0].process = hlua_sample_fetch_wrapper;
6243 	sfk->kw[0].arg_mask = ARG12(0,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR);
6244 	sfk->kw[0].val_args = NULL;
6245 	sfk->kw[0].out_type = SMP_T_STR;
6246 	sfk->kw[0].use = SMP_USE_HTTP_ANY;
6247 	sfk->kw[0].val = 0;
6248 	sfk->kw[0].private = fcn;
6249 
6250 	/* Register this new fetch. */
6251 	sample_register_fetches(sfk);
6252 
6253 	return 0;
6254 }
6255 
6256 /* This function is a wrapper to execute each LUA function declared
6257  * as an action wrapper during the initialisation period. This function
6258  * return ACT_RET_CONT if the processing is finished (with or without
6259  * error) and return ACT_RET_YIELD if the function must be called again
6260  * because the LUA returns a yield.
6261  */
hlua_action(struct act_rule * rule,struct proxy * px,struct session * sess,struct stream * s,int flags)6262 static enum act_return hlua_action(struct act_rule *rule, struct proxy *px,
6263                                    struct session *sess, struct stream *s, int flags)
6264 {
6265 	char **arg;
6266 	unsigned int hflags = 0;
6267 	int dir;
6268 	const char *error;
6269 	const struct buffer msg = { };
6270 
6271 	switch (rule->from) {
6272 	case ACT_F_TCP_REQ_CNT:                            ; dir = SMP_OPT_DIR_REQ; break;
6273 	case ACT_F_TCP_RES_CNT:                            ; dir = SMP_OPT_DIR_RES; break;
6274 	case ACT_F_HTTP_REQ:    hflags = HLUA_TXN_HTTP_RDY ; dir = SMP_OPT_DIR_REQ; break;
6275 	case ACT_F_HTTP_RES:    hflags = HLUA_TXN_HTTP_RDY ; dir = SMP_OPT_DIR_RES; break;
6276 	default:
6277 		SEND_ERR(px, "Lua: internal error while execute action.\n");
6278 		return ACT_RET_CONT;
6279 	}
6280 
6281 	/* In the execution wrappers linked with a stream, the
6282 	 * Lua context can be not initialized. This behavior
6283 	 * permits to save performances because a systematic
6284 	 * Lua initialization cause 5% performances loss.
6285 	 */
6286 	if (!s->hlua) {
6287 		s->hlua = pool_alloc(pool_head_hlua);
6288 		if (!s->hlua) {
6289 			SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
6290 			         rule->arg.hlua_rule->fcn.name);
6291 			return ACT_RET_CONT;
6292 		}
6293 		if (!hlua_ctx_init(s->hlua, s->task, 0)) {
6294 			SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
6295 			         rule->arg.hlua_rule->fcn.name);
6296 			return ACT_RET_CONT;
6297 		}
6298 	}
6299 
6300 	consistency_set(s, dir, &s->hlua->cons);
6301 
6302 	/* If it is the first run, initialize the data for the call. */
6303 	if (!HLUA_IS_RUNNING(s->hlua)) {
6304 
6305 		/* The following Lua calls can fail. */
6306 		if (!SET_SAFE_LJMP(s->hlua->T)) {
6307 			if (lua_type(s->hlua->T, -1) == LUA_TSTRING)
6308 				error = lua_tostring(s->hlua->T, -1);
6309 			else
6310 				error = "critical error";
6311 			SEND_ERR(px, "Lua function '%s': %s.\n",
6312 			         rule->arg.hlua_rule->fcn.name, error);
6313 			return ACT_RET_CONT;
6314 		}
6315 
6316 		/* Check stack available size. */
6317 		if (!lua_checkstack(s->hlua->T, 1)) {
6318 			SEND_ERR(px, "Lua function '%s': full stack.\n",
6319 			         rule->arg.hlua_rule->fcn.name);
6320 			RESET_SAFE_LJMP(s->hlua->T);
6321 			return ACT_RET_CONT;
6322 		}
6323 
6324 		/* Restore the function in the stack. */
6325 		lua_rawgeti(s->hlua->T, LUA_REGISTRYINDEX, rule->arg.hlua_rule->fcn.function_ref);
6326 
6327 		/* Create and and push object stream in the stack. */
6328 		if (!hlua_txn_new(s->hlua->T, s, px, dir, hflags)) {
6329 			SEND_ERR(px, "Lua function '%s': full stack.\n",
6330 			         rule->arg.hlua_rule->fcn.name);
6331 			RESET_SAFE_LJMP(s->hlua->T);
6332 			return ACT_RET_CONT;
6333 		}
6334 		s->hlua->nargs = 1;
6335 
6336 		/* push keywords in the stack. */
6337 		for (arg = rule->arg.hlua_rule->args; arg && *arg; arg++) {
6338 			if (!lua_checkstack(s->hlua->T, 1)) {
6339 				SEND_ERR(px, "Lua function '%s': full stack.\n",
6340 				         rule->arg.hlua_rule->fcn.name);
6341 				RESET_SAFE_LJMP(s->hlua->T);
6342 				return ACT_RET_CONT;
6343 			}
6344 			lua_pushstring(s->hlua->T, *arg);
6345 			s->hlua->nargs++;
6346 		}
6347 
6348 		/* Now the execution is safe. */
6349 		RESET_SAFE_LJMP(s->hlua->T);
6350 
6351 		/* We must initialize the execution timeouts. */
6352 		s->hlua->max_time = hlua_timeout_session;
6353 	}
6354 
6355 	/* Always reset the analyse expiration timeout for the corresponding
6356 	 * channel in case the lua script yield, to be sure to not keep an
6357 	 * expired timeout.
6358 	 */
6359 	if (dir == SMP_OPT_DIR_REQ)
6360 		s->req.analyse_exp = TICK_ETERNITY;
6361 	else
6362 		s->res.analyse_exp = TICK_ETERNITY;
6363 
6364 	/* Execute the function. */
6365 	switch (hlua_ctx_resume(s->hlua, !(flags & ACT_FLAG_FINAL))) {
6366 	/* finished. */
6367 	case HLUA_E_OK:
6368 		if (!consistency_check(s, dir, &s->hlua->cons)) {
6369 			si_retnclose(&s->si[0], &msg);
6370 			return ACT_RET_ERR;
6371 		}
6372 		if (s->hlua->flags & HLUA_STOP)
6373 			return ACT_RET_DONE;
6374 		return ACT_RET_CONT;
6375 
6376 	/* yield. */
6377 	case HLUA_E_AGAIN:
6378 		/* Set timeout in the required channel. */
6379 		if (s->hlua->wake_time != TICK_ETERNITY) {
6380 			if (dir == SMP_OPT_DIR_REQ)
6381 				s->req.analyse_exp = s->hlua->wake_time;
6382 			else
6383 				s->res.analyse_exp = s->hlua->wake_time;
6384 		}
6385 		/* Some actions can be wake up when a "write" event
6386 		 * is detected on a response channel. This is useful
6387 		 * only for actions targeted on the requests.
6388 		 */
6389 		if (HLUA_IS_WAKERESWR(s->hlua))
6390 			s->res.flags |= CF_WAKE_WRITE;
6391 		if (HLUA_IS_WAKEREQWR(s->hlua))
6392 			s->req.flags |= CF_WAKE_WRITE;
6393 		/* We can quit the function without consistency check
6394 		 * because HAProxy is not able to manipulate data, it
6395 		 * is only allowed to call me again. */
6396 		return ACT_RET_YIELD;
6397 
6398 	/* finished with error. */
6399 	case HLUA_E_ERRMSG:
6400 		if (!consistency_check(s, dir, &s->hlua->cons)) {
6401 			si_retnclose(&s->si[0], &msg);
6402 			return ACT_RET_ERR;
6403 		}
6404 		/* Display log. */
6405 		SEND_ERR(px, "Lua function '%s': %s.\n",
6406 		         rule->arg.hlua_rule->fcn.name, lua_tostring(s->hlua->T, -1));
6407 		lua_pop(s->hlua->T, 1);
6408 		return ACT_RET_CONT;
6409 
6410 	case HLUA_E_ETMOUT:
6411 		if (!consistency_check(s, dir, &s->hlua->cons)) {
6412 			si_retnclose(&s->si[0], &msg);
6413 			return ACT_RET_ERR;
6414 		}
6415 		SEND_ERR(px, "Lua function '%s': execution timeout.\n", rule->arg.hlua_rule->fcn.name);
6416 		return 0;
6417 
6418 	case HLUA_E_NOMEM:
6419 		if (!consistency_check(s, dir, &s->hlua->cons)) {
6420 			si_retnclose(&s->si[0], &msg);
6421 			return ACT_RET_ERR;
6422 		}
6423 		SEND_ERR(px, "Lua function '%s': out of memory error.\n", rule->arg.hlua_rule->fcn.name);
6424 		return 0;
6425 
6426 	case HLUA_E_YIELD:
6427 		if (!consistency_check(s, dir, &s->hlua->cons)) {
6428 			si_retnclose(&s->si[0], &msg);
6429 			return ACT_RET_ERR;
6430 		}
6431 		SEND_ERR(px, "Lua function '%s': aborting Lua processing on expired timeout.\n",
6432 		         rule->arg.hlua_rule->fcn.name);
6433 		return 0;
6434 
6435 	case HLUA_E_ERR:
6436 		if (!consistency_check(s, dir, &s->hlua->cons)) {
6437 			si_retnclose(&s->si[0], &msg);
6438 			return ACT_RET_ERR;
6439 		}
6440 		/* Display log. */
6441 		SEND_ERR(px, "Lua function '%s' return an unknown error.\n",
6442 		         rule->arg.hlua_rule->fcn.name);
6443 
6444 	default:
6445 		return ACT_RET_CONT;
6446 	}
6447 }
6448 
hlua_applet_wakeup(struct task * t,void * context,unsigned short state)6449 struct task *hlua_applet_wakeup(struct task *t, void *context, unsigned short state)
6450 {
6451 	struct appctx *ctx = context;
6452 
6453 	appctx_wakeup(ctx);
6454 	t->expire = TICK_ETERNITY;
6455 	return t;
6456 }
6457 
hlua_applet_tcp_init(struct appctx * ctx,struct proxy * px,struct stream * strm)6458 static int hlua_applet_tcp_init(struct appctx *ctx, struct proxy *px, struct stream *strm)
6459 {
6460 	struct stream_interface *si = ctx->owner;
6461 	struct hlua *hlua;
6462 	struct task *task;
6463 	char **arg;
6464 	const char *error;
6465 
6466 	hlua = pool_alloc(pool_head_hlua);
6467 	if (!hlua) {
6468 		SEND_ERR(px, "Lua applet tcp '%s': out of memory.\n",
6469 		         ctx->rule->arg.hlua_rule->fcn.name);
6470 		return 0;
6471 	}
6472 	HLUA_INIT(hlua);
6473 	ctx->ctx.hlua_apptcp.hlua = hlua;
6474 	ctx->ctx.hlua_apptcp.flags = 0;
6475 
6476 	/* Create task used by signal to wakeup applets. */
6477 	task = task_new(tid_bit);
6478 	if (!task) {
6479 		SEND_ERR(px, "Lua applet tcp '%s': out of memory.\n",
6480 		         ctx->rule->arg.hlua_rule->fcn.name);
6481 		return 0;
6482 	}
6483 	task->nice = 0;
6484 	task->context = ctx;
6485 	task->process = hlua_applet_wakeup;
6486 	ctx->ctx.hlua_apptcp.task = task;
6487 
6488 	/* In the execution wrappers linked with a stream, the
6489 	 * Lua context can be not initialized. This behavior
6490 	 * permits to save performances because a systematic
6491 	 * Lua initialization cause 5% performances loss.
6492 	 */
6493 	if (!hlua_ctx_init(hlua, task, 0)) {
6494 		SEND_ERR(px, "Lua applet tcp '%s': can't initialize Lua context.\n",
6495 		         ctx->rule->arg.hlua_rule->fcn.name);
6496 		return 0;
6497 	}
6498 
6499 	/* Set timeout according with the applet configuration. */
6500 	hlua->max_time = ctx->applet->timeout;
6501 
6502 	/* The following Lua calls can fail. */
6503 	if (!SET_SAFE_LJMP(hlua->T)) {
6504 		if (lua_type(hlua->T, -1) == LUA_TSTRING)
6505 			error = lua_tostring(hlua->T, -1);
6506 		else
6507 			error = "critical error";
6508 		SEND_ERR(px, "Lua applet tcp '%s': %s.\n",
6509 		         ctx->rule->arg.hlua_rule->fcn.name, error);
6510 		return 0;
6511 	}
6512 
6513 	/* Check stack available size. */
6514 	if (!lua_checkstack(hlua->T, 1)) {
6515 		SEND_ERR(px, "Lua applet tcp '%s': full stack.\n",
6516 		         ctx->rule->arg.hlua_rule->fcn.name);
6517 		RESET_SAFE_LJMP(hlua->T);
6518 		return 0;
6519 	}
6520 
6521 	/* Restore the function in the stack. */
6522 	lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ctx->rule->arg.hlua_rule->fcn.function_ref);
6523 
6524 	/* Create and and push object stream in the stack. */
6525 	if (!hlua_applet_tcp_new(hlua->T, ctx)) {
6526 		SEND_ERR(px, "Lua applet tcp '%s': full stack.\n",
6527 		         ctx->rule->arg.hlua_rule->fcn.name);
6528 		RESET_SAFE_LJMP(hlua->T);
6529 		return 0;
6530 	}
6531 	hlua->nargs = 1;
6532 
6533 	/* push keywords in the stack. */
6534 	for (arg = ctx->rule->arg.hlua_rule->args; arg && *arg; arg++) {
6535 		if (!lua_checkstack(hlua->T, 1)) {
6536 			SEND_ERR(px, "Lua applet tcp '%s': full stack.\n",
6537 			         ctx->rule->arg.hlua_rule->fcn.name);
6538 			RESET_SAFE_LJMP(hlua->T);
6539 			return 0;
6540 		}
6541 		lua_pushstring(hlua->T, *arg);
6542 		hlua->nargs++;
6543 	}
6544 
6545 	RESET_SAFE_LJMP(hlua->T);
6546 
6547 	/* Wakeup the applet ASAP. */
6548 	si_cant_get(si);
6549 	si_rx_endp_more(si);
6550 
6551 	return 1;
6552 }
6553 
hlua_applet_tcp_fct(struct appctx * ctx)6554 void hlua_applet_tcp_fct(struct appctx *ctx)
6555 {
6556 	struct stream_interface *si = ctx->owner;
6557 	struct stream *strm = si_strm(si);
6558 	struct channel *res = si_ic(si);
6559 	struct act_rule *rule = ctx->rule;
6560 	struct proxy *px = strm->be;
6561 	struct hlua *hlua = ctx->ctx.hlua_apptcp.hlua;
6562 
6563 	/* The applet execution is already done. */
6564 	if (ctx->ctx.hlua_apptcp.flags & APPLET_DONE) {
6565 		/* eat the whole request */
6566 		co_skip(si_oc(si), co_data(si_oc(si)));
6567 		return;
6568 	}
6569 
6570 	/* If the stream is disconnect or closed, ldo nothing. */
6571 	if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO))
6572 		return;
6573 
6574 	/* Execute the function. */
6575 	switch (hlua_ctx_resume(hlua, 1)) {
6576 	/* finished. */
6577 	case HLUA_E_OK:
6578 		ctx->ctx.hlua_apptcp.flags |= APPLET_DONE;
6579 
6580 		/* eat the whole request */
6581 		co_skip(si_oc(si), co_data(si_oc(si)));
6582 		res->flags |= CF_READ_NULL;
6583 		si_shutr(si);
6584 		return;
6585 
6586 	/* yield. */
6587 	case HLUA_E_AGAIN:
6588 		if (hlua->wake_time != TICK_ETERNITY)
6589 			task_schedule(ctx->ctx.hlua_apptcp.task, hlua->wake_time);
6590 		return;
6591 
6592 	/* finished with error. */
6593 	case HLUA_E_ERRMSG:
6594 		/* Display log. */
6595 		SEND_ERR(px, "Lua applet tcp '%s': %s.\n",
6596 		         rule->arg.hlua_rule->fcn.name, lua_tostring(hlua->T, -1));
6597 		lua_pop(hlua->T, 1);
6598 		goto error;
6599 
6600 	case HLUA_E_ETMOUT:
6601 		SEND_ERR(px, "Lua applet tcp '%s': execution timeout.\n",
6602 		         rule->arg.hlua_rule->fcn.name);
6603 		goto error;
6604 
6605 	case HLUA_E_NOMEM:
6606 		SEND_ERR(px, "Lua applet tcp '%s': out of memory error.\n",
6607 		         rule->arg.hlua_rule->fcn.name);
6608 		goto error;
6609 
6610 	case HLUA_E_YIELD: /* unexpected */
6611 		SEND_ERR(px, "Lua applet tcp '%s': yield not allowed.\n",
6612 		         rule->arg.hlua_rule->fcn.name);
6613 		goto error;
6614 
6615 	case HLUA_E_ERR:
6616 		/* Display log. */
6617 		SEND_ERR(px, "Lua applet tcp '%s' return an unknown error.\n",
6618 		         rule->arg.hlua_rule->fcn.name);
6619 		goto error;
6620 
6621 	default:
6622 		goto error;
6623 	}
6624 
6625 error:
6626 
6627 	/* For all other cases, just close the stream. */
6628 	si_shutw(si);
6629 	si_shutr(si);
6630 	ctx->ctx.hlua_apptcp.flags |= APPLET_DONE;
6631 }
6632 
hlua_applet_tcp_release(struct appctx * ctx)6633 static void hlua_applet_tcp_release(struct appctx *ctx)
6634 {
6635 	task_destroy(ctx->ctx.hlua_apptcp.task);
6636 	ctx->ctx.hlua_apptcp.task = NULL;
6637 	hlua_ctx_destroy(ctx->ctx.hlua_apptcp.hlua);
6638 	ctx->ctx.hlua_apptcp.hlua = NULL;
6639 }
6640 
6641 /* The function returns 1 if the initialisation is complete, 0 if
6642  * an errors occurs and -1 if more data are required for initializing
6643  * the applet.
6644  */
hlua_applet_http_init(struct appctx * ctx,struct proxy * px,struct stream * strm)6645 static int hlua_applet_http_init(struct appctx *ctx, struct proxy *px, struct stream *strm)
6646 {
6647 	struct stream_interface *si = ctx->owner;
6648 	struct http_txn *txn;
6649 	struct hlua *hlua;
6650 	char **arg;
6651 	struct task *task;
6652 	const char *error;
6653 
6654 	txn = strm->txn;
6655 	hlua = pool_alloc(pool_head_hlua);
6656 	if (!hlua) {
6657 		SEND_ERR(px, "Lua applet http '%s': out of memory.\n",
6658 		         ctx->rule->arg.hlua_rule->fcn.name);
6659 		return 0;
6660 	}
6661 	HLUA_INIT(hlua);
6662 	ctx->ctx.hlua_apphttp.hlua = hlua;
6663 	ctx->ctx.hlua_apphttp.left_bytes = -1;
6664 	ctx->ctx.hlua_apphttp.flags = 0;
6665 
6666 	if (txn->req.flags & HTTP_MSGF_VER_11)
6667 		ctx->ctx.hlua_apphttp.flags |= APPLET_HTTP11;
6668 
6669 	/* Create task used by signal to wakeup applets. */
6670 	task = task_new(tid_bit);
6671 	if (!task) {
6672 		SEND_ERR(px, "Lua applet http '%s': out of memory.\n",
6673 		         ctx->rule->arg.hlua_rule->fcn.name);
6674 		return 0;
6675 	}
6676 	task->nice = 0;
6677 	task->context = ctx;
6678 	task->process = hlua_applet_wakeup;
6679 	ctx->ctx.hlua_apphttp.task = task;
6680 
6681 	/* In the execution wrappers linked with a stream, the
6682 	 * Lua context can be not initialized. This behavior
6683 	 * permits to save performances because a systematic
6684 	 * Lua initialization cause 5% performances loss.
6685 	 */
6686 	if (!hlua_ctx_init(hlua, task, 0)) {
6687 		SEND_ERR(px, "Lua applet http '%s': can't initialize Lua context.\n",
6688 		         ctx->rule->arg.hlua_rule->fcn.name);
6689 		return 0;
6690 	}
6691 
6692 	/* Set timeout according with the applet configuration. */
6693 	hlua->max_time = ctx->applet->timeout;
6694 
6695 	/* The following Lua calls can fail. */
6696 	if (!SET_SAFE_LJMP(hlua->T)) {
6697 		if (lua_type(hlua->T, -1) == LUA_TSTRING)
6698 			error = lua_tostring(hlua->T, -1);
6699 		else
6700 			error = "critical error";
6701 		SEND_ERR(px, "Lua applet http '%s': %s.\n",
6702 		         ctx->rule->arg.hlua_rule->fcn.name, error);
6703 		return 0;
6704 	}
6705 
6706 	/* Check stack available size. */
6707 	if (!lua_checkstack(hlua->T, 1)) {
6708 		SEND_ERR(px, "Lua applet http '%s': full stack.\n",
6709 		         ctx->rule->arg.hlua_rule->fcn.name);
6710 		RESET_SAFE_LJMP(hlua->T);
6711 		return 0;
6712 	}
6713 
6714 	/* Restore the function in the stack. */
6715 	lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ctx->rule->arg.hlua_rule->fcn.function_ref);
6716 
6717 	/* Create and and push object stream in the stack. */
6718 	if (!hlua_applet_http_new(hlua->T, ctx)) {
6719 		SEND_ERR(px, "Lua applet http '%s': full stack.\n",
6720 		         ctx->rule->arg.hlua_rule->fcn.name);
6721 		RESET_SAFE_LJMP(hlua->T);
6722 		return 0;
6723 	}
6724 	hlua->nargs = 1;
6725 
6726 	/* push keywords in the stack. */
6727 	for (arg = ctx->rule->arg.hlua_rule->args; arg && *arg; arg++) {
6728 		if (!lua_checkstack(hlua->T, 1)) {
6729 			SEND_ERR(px, "Lua applet http '%s': full stack.\n",
6730 			         ctx->rule->arg.hlua_rule->fcn.name);
6731 			RESET_SAFE_LJMP(hlua->T);
6732 			return 0;
6733 		}
6734 		lua_pushstring(hlua->T, *arg);
6735 		hlua->nargs++;
6736 	}
6737 
6738 	RESET_SAFE_LJMP(hlua->T);
6739 
6740 	/* Wakeup the applet when data is ready for read. */
6741 	si_cant_get(si);
6742 
6743 	return 1;
6744 }
6745 
hlua_applet_http_fct(struct appctx * ctx)6746 void hlua_applet_http_fct(struct appctx *ctx)
6747 {
6748 	struct stream_interface *si = ctx->owner;
6749 	struct stream *strm = si_strm(si);
6750 	struct channel *req = si_oc(si);
6751 	struct channel *res = si_ic(si);
6752 	struct act_rule *rule = ctx->rule;
6753 	struct proxy *px = strm->be;
6754 	struct hlua *hlua = ctx->ctx.hlua_apphttp.hlua;
6755 	struct htx *req_htx, *res_htx;
6756 
6757 	res_htx = htx_from_buf(&res->buf);
6758 
6759 	/* If the stream is disconnect or closed, ldo nothing. */
6760 	if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO))
6761 		goto out;
6762 
6763 	/* Check if the input buffer is avalaible. */
6764 	if (!b_size(&res->buf)) {
6765 		si_rx_room_blk(si);
6766 		goto out;
6767 	}
6768 	/* check that the output is not closed */
6769 	if (res->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_SHUTR))
6770 		ctx->ctx.hlua_apphttp.flags |= APPLET_DONE;
6771 
6772 	/* Set the currently running flag. */
6773 	if (!HLUA_IS_RUNNING(hlua) &&
6774 	    !(ctx->ctx.hlua_apphttp.flags & APPLET_DONE)) {
6775 		struct htx_blk *blk;
6776 		size_t count = co_data(req);
6777 
6778 		if (!count) {
6779 			si_cant_get(si);
6780 			goto out;
6781 		}
6782 
6783 		/* We need to flush the request header. This left the body for
6784 		 * the Lua.
6785 		 */
6786 		req_htx = htx_from_buf(&req->buf);
6787 		blk = htx_get_first_blk(req_htx);
6788 		while (count && blk) {
6789 			enum htx_blk_type type = htx_get_blk_type(blk);
6790 			uint32_t sz = htx_get_blksz(blk);
6791 
6792 			if (sz > count) {
6793 				si_cant_get(si);
6794 				htx_to_buf(req_htx, &req->buf);
6795 				goto out;
6796 			}
6797 
6798 			count -= sz;
6799 			co_set_data(req, co_data(req) - sz);
6800 			blk = htx_remove_blk(req_htx, blk);
6801 
6802 			if (type == HTX_BLK_EOH)
6803 				break;
6804 		}
6805 		htx_to_buf(req_htx, &req->buf);
6806 	}
6807 
6808 	/* Executes The applet if it is not done. */
6809 	if (!(ctx->ctx.hlua_apphttp.flags & APPLET_DONE)) {
6810 
6811 		/* Execute the function. */
6812 		switch (hlua_ctx_resume(hlua, 1)) {
6813 		/* finished. */
6814 		case HLUA_E_OK:
6815 			ctx->ctx.hlua_apphttp.flags |= APPLET_DONE;
6816 			break;
6817 
6818 		/* yield. */
6819 		case HLUA_E_AGAIN:
6820 			if (hlua->wake_time != TICK_ETERNITY)
6821 				task_schedule(ctx->ctx.hlua_apphttp.task, hlua->wake_time);
6822 			goto out;
6823 
6824 		/* finished with error. */
6825 		case HLUA_E_ERRMSG:
6826 			/* Display log. */
6827 			SEND_ERR(px, "Lua applet http '%s': %s.\n",
6828 			         rule->arg.hlua_rule->fcn.name, lua_tostring(hlua->T, -1));
6829 			lua_pop(hlua->T, 1);
6830 			goto error;
6831 
6832 		case HLUA_E_ETMOUT:
6833 			SEND_ERR(px, "Lua applet http '%s': execution timeout.\n",
6834 			         rule->arg.hlua_rule->fcn.name);
6835 			goto error;
6836 
6837 		case HLUA_E_NOMEM:
6838 			SEND_ERR(px, "Lua applet http '%s': out of memory error.\n",
6839 			         rule->arg.hlua_rule->fcn.name);
6840 			goto error;
6841 
6842 		case HLUA_E_YIELD: /* unexpected */
6843 			SEND_ERR(px, "Lua applet http '%s': yield not allowed.\n",
6844 			         rule->arg.hlua_rule->fcn.name);
6845 			goto error;
6846 
6847 		case HLUA_E_ERR:
6848 			/* Display log. */
6849 			SEND_ERR(px, "Lua applet http '%s' return an unknown error.\n",
6850 			         rule->arg.hlua_rule->fcn.name);
6851 			goto error;
6852 
6853 		default:
6854 			goto error;
6855 		}
6856 	}
6857 
6858 	if (ctx->ctx.hlua_apphttp.flags & APPLET_DONE) {
6859 		if (ctx->ctx.hlua_apphttp.flags & APPLET_RSP_SENT)
6860 			goto done;
6861 
6862 		if (!(ctx->ctx.hlua_apphttp.flags & APPLET_HDR_SENT))
6863 			goto error;
6864 
6865 		/* Don't add TLR because mux-h1 will take care of it */
6866 		if (!htx_add_endof(res_htx, HTX_BLK_EOM)) {
6867 			si_rx_room_blk(si);
6868 			goto out;
6869 		}
6870 		channel_add_input(res, 1);
6871 		strm->txn->status = ctx->ctx.hlua_apphttp.status;
6872 		ctx->ctx.hlua_apphttp.flags |= APPLET_RSP_SENT;
6873 	}
6874 
6875   done:
6876 	if (ctx->ctx.hlua_apphttp.flags & APPLET_DONE) {
6877 		if (!(res->flags & CF_SHUTR)) {
6878 			res->flags |= CF_READ_NULL;
6879 			si_shutr(si);
6880 		}
6881 
6882 		/* eat the whole request */
6883 		if (co_data(req)) {
6884 			req_htx = htx_from_buf(&req->buf);
6885 			co_htx_skip(req, req_htx, co_data(req));
6886 			htx_to_buf(req_htx, &req->buf);
6887 		}
6888 	}
6889 
6890   out:
6891 	htx_to_buf(res_htx, &res->buf);
6892 	return;
6893 
6894   error:
6895 
6896 	/* If we are in HTTP mode, and we are not send any
6897 	 * data, return a 500 server error in best effort:
6898 	 * if there is no room available in the buffer,
6899 	 * just close the connection.
6900 	 */
6901 	if (!(ctx->ctx.hlua_apphttp.flags & APPLET_HDR_SENT)) {
6902 		struct buffer *err = &http_err_chunks[HTTP_ERR_500];
6903 
6904 		channel_erase(res);
6905 		res->buf.data = b_data(err);
6906                 memcpy(res->buf.area, b_head(err), b_data(err));
6907                 res_htx = htx_from_buf(&res->buf);
6908 		channel_add_input(res, res_htx->data);
6909 	}
6910 	if (!(strm->flags & SF_ERR_MASK))
6911 		strm->flags |= SF_ERR_RESOURCE;
6912 	ctx->ctx.hlua_apphttp.flags |= APPLET_DONE;
6913 	goto done;
6914 }
6915 
hlua_applet_http_release(struct appctx * ctx)6916 static void hlua_applet_http_release(struct appctx *ctx)
6917 {
6918 	task_destroy(ctx->ctx.hlua_apphttp.task);
6919 	ctx->ctx.hlua_apphttp.task = NULL;
6920 	hlua_ctx_destroy(ctx->ctx.hlua_apphttp.hlua);
6921 	ctx->ctx.hlua_apphttp.hlua = NULL;
6922 }
6923 
6924 /* global {tcp|http}-request parser. Return ACT_RET_PRS_OK in
6925  * succes case, else return ACT_RET_PRS_ERR.
6926  *
6927  * This function can fail with an abort() due to an Lua critical error.
6928  * We are in the configuration parsing process of HAProxy, this abort() is
6929  * tolerated.
6930  */
action_register_lua(const char ** args,int * cur_arg,struct proxy * px,struct act_rule * rule,char ** err)6931 static enum act_parse_ret action_register_lua(const char **args, int *cur_arg, struct proxy *px,
6932                                               struct act_rule *rule, char **err)
6933 {
6934 	struct hlua_function *fcn = rule->kw->private;
6935 	int i;
6936 
6937 	/* Memory for the rule. */
6938 	rule->arg.hlua_rule = calloc(1, sizeof(*rule->arg.hlua_rule));
6939 	if (!rule->arg.hlua_rule) {
6940 		memprintf(err, "out of memory error");
6941 		return ACT_RET_PRS_ERR;
6942 	}
6943 
6944 	/* Memory for arguments. */
6945 	rule->arg.hlua_rule->args = calloc(fcn->nargs + 1, sizeof(char *));
6946 	if (!rule->arg.hlua_rule->args) {
6947 		memprintf(err, "out of memory error");
6948 		return ACT_RET_PRS_ERR;
6949 	}
6950 
6951 	/* Reference the Lua function and store the reference. */
6952 	rule->arg.hlua_rule->fcn = *fcn;
6953 
6954 	/* Expect some arguments */
6955 	for (i = 0; i < fcn->nargs; i++) {
6956 		if (*args[*cur_arg] == '\0') {
6957 			memprintf(err, "expect %d arguments", fcn->nargs);
6958 			return ACT_RET_PRS_ERR;
6959 		}
6960 		rule->arg.hlua_rule->args[i] = strdup(args[*cur_arg]);
6961 		if (!rule->arg.hlua_rule->args[i]) {
6962 			memprintf(err, "out of memory error");
6963 			return ACT_RET_PRS_ERR;
6964 		}
6965 		(*cur_arg)++;
6966 	}
6967 	rule->arg.hlua_rule->args[i] = NULL;
6968 
6969 	rule->action = ACT_CUSTOM;
6970 	rule->action_ptr = hlua_action;
6971 	return ACT_RET_PRS_OK;
6972 }
6973 
action_register_service_http(const char ** args,int * cur_arg,struct proxy * px,struct act_rule * rule,char ** err)6974 static enum act_parse_ret action_register_service_http(const char **args, int *cur_arg, struct proxy *px,
6975                                                        struct act_rule *rule, char **err)
6976 {
6977 	struct hlua_function *fcn = rule->kw->private;
6978 
6979 	/* HTTP applets are forbidden in tcp-request rules.
6980 	 * HTTP applet request requires everything initilized by
6981 	 * "http_process_request" (analyzer flag AN_REQ_HTTP_INNER).
6982 	 * The applet will be immediately initilized, but its before
6983 	 * the call of this analyzer.
6984 	 */
6985 	if (rule->from != ACT_F_HTTP_REQ) {
6986 		memprintf(err, "HTTP applets are forbidden from 'tcp-request' rulesets");
6987 		return ACT_RET_PRS_ERR;
6988 	}
6989 
6990 	/* Memory for the rule. */
6991 	rule->arg.hlua_rule = calloc(1, sizeof(*rule->arg.hlua_rule));
6992 	if (!rule->arg.hlua_rule) {
6993 		memprintf(err, "out of memory error");
6994 		return ACT_RET_PRS_ERR;
6995 	}
6996 
6997 	/* Reference the Lua function and store the reference. */
6998 	rule->arg.hlua_rule->fcn = *fcn;
6999 
7000 	/* TODO: later accept arguments. */
7001 	rule->arg.hlua_rule->args = NULL;
7002 
7003 	/* Add applet pointer in the rule. */
7004 	rule->applet.obj_type = OBJ_TYPE_APPLET;
7005 	rule->applet.name = fcn->name;
7006 	rule->applet.init = hlua_applet_http_init;
7007 	rule->applet.fct = hlua_applet_http_fct;
7008 	rule->applet.release = hlua_applet_http_release;
7009 	rule->applet.timeout = hlua_timeout_applet;
7010 
7011 	return ACT_RET_PRS_OK;
7012 }
7013 
7014 /* This function is an LUA binding used for registering
7015  * "sample-conv" functions. It expects a converter name used
7016  * in the haproxy configuration file, and an LUA function.
7017  */
hlua_register_action(lua_State * L)7018 __LJMP static int hlua_register_action(lua_State *L)
7019 {
7020 	struct action_kw_list *akl;
7021 	const char *name;
7022 	int ref;
7023 	int len;
7024 	struct hlua_function *fcn;
7025 	int nargs;
7026 	struct buffer *trash;
7027 	struct action_kw *akw;
7028 
7029 	/* Initialise the number of expected arguments at 0. */
7030 	nargs = 0;
7031 
7032 	if (lua_gettop(L) < 3 || lua_gettop(L) > 4)
7033 		WILL_LJMP(luaL_error(L, "'register_action' needs between 3 and 4 arguments"));
7034 
7035 	/* First argument : converter name. */
7036 	name = MAY_LJMP(luaL_checkstring(L, 1));
7037 
7038 	/* Second argument : environment. */
7039 	if (lua_type(L, 2) != LUA_TTABLE)
7040 		WILL_LJMP(luaL_error(L, "register_action: second argument must be a table of strings"));
7041 
7042 	/* Third argument : lua function. */
7043 	ref = MAY_LJMP(hlua_checkfunction(L, 3));
7044 
7045 	/* Fourth argument : number of mandatory arguments expected on the configuration line. */
7046 	if (lua_gettop(L) >= 4)
7047 		nargs = MAY_LJMP(luaL_checkinteger(L, 4));
7048 
7049 	/* browse the second argument as an array. */
7050 	lua_pushnil(L);
7051 	while (lua_next(L, 2) != 0) {
7052 		if (lua_type(L, -1) != LUA_TSTRING)
7053 			WILL_LJMP(luaL_error(L, "register_action: second argument must be a table of strings"));
7054 
7055 		/* Check if action exists */
7056 		trash = get_trash_chunk();
7057 		chunk_printf(trash, "lua.%s", name);
7058 		if (strcmp(lua_tostring(L, -1), "tcp-req") == 0) {
7059 			akw = tcp_req_cont_action(trash->area);
7060 		} else if (strcmp(lua_tostring(L, -1), "tcp-res") == 0) {
7061 			akw = tcp_res_cont_action(trash->area);
7062 		} else if (strcmp(lua_tostring(L, -1), "http-req") == 0) {
7063 			akw = action_http_req_custom(trash->area);
7064 		} else if (strcmp(lua_tostring(L, -1), "http-res") == 0) {
7065 			akw = action_http_res_custom(trash->area);
7066 		} else {
7067 			akw = NULL;
7068 		}
7069 		if (akw != NULL) {
7070 			ha_warning("Trying to register action 'lua.%s' more than once. "
7071 			           "This will become a hard error in version 2.5.\n", name);
7072 		}
7073 
7074 		/* Check required environment. Only accepted "http" or "tcp". */
7075 		/* Allocate and fill the sample fetch keyword struct. */
7076 		akl = calloc(1, sizeof(*akl) + sizeof(struct action_kw) * 2);
7077 		if (!akl)
7078 			WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7079 		fcn = calloc(1, sizeof(*fcn));
7080 		if (!fcn)
7081 			WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7082 
7083 		/* Fill fcn. */
7084 		fcn->name = strdup(name);
7085 		if (!fcn->name)
7086 			WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7087 		fcn->function_ref = ref;
7088 
7089 		/* Set the expected number od arguments. */
7090 		fcn->nargs = nargs;
7091 
7092 		/* List head */
7093 		akl->list.n = akl->list.p = NULL;
7094 
7095 		/* action keyword. */
7096 		len = strlen("lua.") + strlen(name) + 1;
7097 		akl->kw[0].kw = calloc(1, len);
7098 		if (!akl->kw[0].kw)
7099 			WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7100 
7101 		snprintf((char *)akl->kw[0].kw, len, "lua.%s", name);
7102 
7103 		akl->kw[0].match_pfx = 0;
7104 		akl->kw[0].private = fcn;
7105 		akl->kw[0].parse = action_register_lua;
7106 
7107 		/* select the action registering point. */
7108 		if (strcmp(lua_tostring(L, -1), "tcp-req") == 0)
7109 			tcp_req_cont_keywords_register(akl);
7110 		else if (strcmp(lua_tostring(L, -1), "tcp-res") == 0)
7111 			tcp_res_cont_keywords_register(akl);
7112 		else if (strcmp(lua_tostring(L, -1), "http-req") == 0)
7113 			http_req_keywords_register(akl);
7114 		else if (strcmp(lua_tostring(L, -1), "http-res") == 0)
7115 			http_res_keywords_register(akl);
7116 		else
7117 			WILL_LJMP(luaL_error(L, "Lua action environment '%s' is unknown. "
7118 			                        "'tcp-req', 'tcp-res', 'http-req' or 'http-res' "
7119 			                        "are expected.", lua_tostring(L, -1)));
7120 
7121 		/* pop the environment string. */
7122 		lua_pop(L, 1);
7123 	}
7124 	return ACT_RET_PRS_OK;
7125 }
7126 
action_register_service_tcp(const char ** args,int * cur_arg,struct proxy * px,struct act_rule * rule,char ** err)7127 static enum act_parse_ret action_register_service_tcp(const char **args, int *cur_arg, struct proxy *px,
7128                                                       struct act_rule *rule, char **err)
7129 {
7130 	struct hlua_function *fcn = rule->kw->private;
7131 
7132 	if (px->mode == PR_MODE_HTTP) {
7133 		memprintf(err, "Lua TCP services cannot be used on HTTP proxies");
7134 		return ACT_RET_PRS_ERR;
7135 	}
7136 
7137 	/* Memory for the rule. */
7138 	rule->arg.hlua_rule = calloc(1, sizeof(*rule->arg.hlua_rule));
7139 	if (!rule->arg.hlua_rule) {
7140 		memprintf(err, "out of memory error");
7141 		return ACT_RET_PRS_ERR;
7142 	}
7143 
7144 	/* Reference the Lua function and store the reference. */
7145 	rule->arg.hlua_rule->fcn = *fcn;
7146 
7147 	/* TODO: later accept arguments. */
7148 	rule->arg.hlua_rule->args = NULL;
7149 
7150 	/* Add applet pointer in the rule. */
7151 	rule->applet.obj_type = OBJ_TYPE_APPLET;
7152 	rule->applet.name = fcn->name;
7153 	rule->applet.init = hlua_applet_tcp_init;
7154 	rule->applet.fct = hlua_applet_tcp_fct;
7155 	rule->applet.release = hlua_applet_tcp_release;
7156 	rule->applet.timeout = hlua_timeout_applet;
7157 
7158 	return 0;
7159 }
7160 
7161 /* This function is an LUA binding used for registering
7162  * "sample-conv" functions. It expects a converter name used
7163  * in the haproxy configuration file, and an LUA function.
7164  */
hlua_register_service(lua_State * L)7165 __LJMP static int hlua_register_service(lua_State *L)
7166 {
7167 	struct action_kw_list *akl;
7168 	const char *name;
7169 	const char *env;
7170 	int ref;
7171 	int len;
7172 	struct hlua_function *fcn;
7173 	struct buffer *trash;
7174 	struct action_kw *akw;
7175 
7176 	MAY_LJMP(check_args(L, 3, "register_service"));
7177 
7178 	/* First argument : converter name. */
7179 	name = MAY_LJMP(luaL_checkstring(L, 1));
7180 
7181 	/* Second argument : environment. */
7182 	env = MAY_LJMP(luaL_checkstring(L, 2));
7183 
7184 	/* Third argument : lua function. */
7185 	ref = MAY_LJMP(hlua_checkfunction(L, 3));
7186 
7187 	/* Check for service already registered */
7188 	trash = get_trash_chunk();
7189 	chunk_printf(trash, "lua.%s", name);
7190 	akw = service_find(trash->area);
7191 	if (akw != NULL) {
7192 		ha_warning("Trying to register service 'lua.%s' more than once. "
7193 		           "This will become a hard error in version 2.5.\n", name);
7194 	}
7195 
7196 	/* Allocate and fill the sample fetch keyword struct. */
7197 	akl = calloc(1, sizeof(*akl) + sizeof(struct action_kw) * 2);
7198 	if (!akl)
7199 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7200 	fcn = calloc(1, sizeof(*fcn));
7201 	if (!fcn)
7202 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7203 
7204 	/* Fill fcn. */
7205 	len = strlen("<lua.>") + strlen(name) + 1;
7206 	fcn->name = calloc(1, len);
7207 	if (!fcn->name)
7208 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7209 	snprintf((char *)fcn->name, len, "<lua.%s>", name);
7210 	fcn->function_ref = ref;
7211 
7212 	/* List head */
7213 	akl->list.n = akl->list.p = NULL;
7214 
7215 	/* converter keyword. */
7216 	len = strlen("lua.") + strlen(name) + 1;
7217 	akl->kw[0].kw = calloc(1, len);
7218 	if (!akl->kw[0].kw)
7219 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7220 
7221 	snprintf((char *)akl->kw[0].kw, len, "lua.%s", name);
7222 
7223 	/* Check required environment. Only accepted "http" or "tcp". */
7224 	if (strcmp(env, "tcp") == 0)
7225 		akl->kw[0].parse = action_register_service_tcp;
7226 	else if (strcmp(env, "http") == 0)
7227 		akl->kw[0].parse = action_register_service_http;
7228 	else
7229 		WILL_LJMP(luaL_error(L, "Lua service environment '%s' is unknown. "
7230 		                        "'tcp' or 'http' are expected.", env));
7231 
7232 	akl->kw[0].match_pfx = 0;
7233 	akl->kw[0].private = fcn;
7234 
7235 	/* End of array. */
7236 	memset(&akl->kw[1], 0, sizeof(*akl->kw));
7237 
7238 	/* Register this new converter */
7239 	service_keywords_register(akl);
7240 
7241 	return 0;
7242 }
7243 
7244 /* This function initialises Lua cli handler. It copies the
7245  * arguments in the Lua stack and create channel IO objects.
7246  */
hlua_cli_parse_fct(char ** args,char * payload,struct appctx * appctx,void * private)7247 static int hlua_cli_parse_fct(char **args, char *payload, struct appctx *appctx, void *private)
7248 {
7249 	struct hlua *hlua;
7250 	struct hlua_function *fcn;
7251 	int i;
7252 	const char *error;
7253 
7254 	fcn = private;
7255 	appctx->ctx.hlua_cli.fcn = private;
7256 
7257 	hlua = pool_alloc(pool_head_hlua);
7258 	if (!hlua) {
7259 		SEND_ERR(NULL, "Lua cli '%s': out of memory.\n", fcn->name);
7260 		return 1;
7261 	}
7262 	HLUA_INIT(hlua);
7263 	appctx->ctx.hlua_cli.hlua = hlua;
7264 
7265 	/* Create task used by signal to wakeup applets.
7266 	 * We use the same wakeup fonction than the Lua applet_tcp and
7267 	 * applet_http. It is absolutely compatible.
7268 	 */
7269 	appctx->ctx.hlua_cli.task = task_new(tid_bit);
7270 	if (!appctx->ctx.hlua_cli.task) {
7271 		SEND_ERR(NULL, "Lua cli '%s': out of memory.\n", fcn->name);
7272 		goto error;
7273 	}
7274 	appctx->ctx.hlua_cli.task->nice = 0;
7275 	appctx->ctx.hlua_cli.task->context = appctx;
7276 	appctx->ctx.hlua_cli.task->process = hlua_applet_wakeup;
7277 
7278 	/* Initialises the Lua context */
7279 	if (!hlua_ctx_init(hlua, appctx->ctx.hlua_cli.task, 0)) {
7280 		SEND_ERR(NULL, "Lua cli '%s': can't initialize Lua context.\n", fcn->name);
7281 		goto error;
7282 	}
7283 
7284 	/* The following Lua calls can fail. */
7285 	if (!SET_SAFE_LJMP(hlua->T)) {
7286 		if (lua_type(hlua->T, -1) == LUA_TSTRING)
7287 			error = lua_tostring(hlua->T, -1);
7288 		else
7289 			error = "critical error";
7290 		SEND_ERR(NULL, "Lua cli '%s': %s.\n", fcn->name, error);
7291 		goto error;
7292 	}
7293 
7294 	/* Check stack available size. */
7295 	if (!lua_checkstack(hlua->T, 2)) {
7296 		SEND_ERR(NULL, "Lua cli '%s': full stack.\n", fcn->name);
7297 		goto error;
7298 	}
7299 
7300 	/* Restore the function in the stack. */
7301 	lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, fcn->function_ref);
7302 
7303 	/* Once the arguments parsed, the CLI is like an AppletTCP,
7304 	 * so push AppletTCP in the stack.
7305 	 */
7306 	if (!hlua_applet_tcp_new(hlua->T, appctx)) {
7307 		SEND_ERR(NULL, "Lua cli '%s': full stack.\n", fcn->name);
7308 		goto error;
7309 	}
7310 	hlua->nargs = 1;
7311 
7312 	/* push keywords in the stack. */
7313 	for (i = 0; *args[i]; i++) {
7314 		/* Check stack available size. */
7315 		if (!lua_checkstack(hlua->T, 1)) {
7316 			SEND_ERR(NULL, "Lua cli '%s': full stack.\n", fcn->name);
7317 			goto error;
7318 		}
7319 		lua_pushstring(hlua->T, args[i]);
7320 		hlua->nargs++;
7321 	}
7322 
7323 	/* We must initialize the execution timeouts. */
7324 	hlua->max_time = hlua_timeout_session;
7325 
7326 	/* At this point the execution is safe. */
7327 	RESET_SAFE_LJMP(hlua->T);
7328 
7329 	/* It's ok */
7330 	return 0;
7331 
7332 	/* It's not ok. */
7333 error:
7334 	RESET_SAFE_LJMP(hlua->T);
7335 	hlua_ctx_destroy(hlua);
7336 	appctx->ctx.hlua_cli.hlua = NULL;
7337 	return 1;
7338 }
7339 
hlua_cli_io_handler_fct(struct appctx * appctx)7340 static int hlua_cli_io_handler_fct(struct appctx *appctx)
7341 {
7342 	struct hlua *hlua;
7343 	struct stream_interface *si;
7344 	struct hlua_function *fcn;
7345 
7346 	hlua = appctx->ctx.hlua_cli.hlua;
7347 	si = appctx->owner;
7348 	fcn = appctx->ctx.hlua_cli.fcn;
7349 
7350 	/* If the stream is disconnect or closed, ldo nothing. */
7351 	if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO))
7352 		return 1;
7353 
7354 	/* Execute the function. */
7355 	switch (hlua_ctx_resume(hlua, 1)) {
7356 
7357 	/* finished. */
7358 	case HLUA_E_OK:
7359 		return 1;
7360 
7361 	/* yield. */
7362 	case HLUA_E_AGAIN:
7363 		/* We want write. */
7364 		if (HLUA_IS_WAKERESWR(hlua))
7365 			si_rx_room_blk(si);
7366 		/* Set the timeout. */
7367 		if (hlua->wake_time != TICK_ETERNITY)
7368 			task_schedule(hlua->task, hlua->wake_time);
7369 		return 0;
7370 
7371 	/* finished with error. */
7372 	case HLUA_E_ERRMSG:
7373 		/* Display log. */
7374 		SEND_ERR(NULL, "Lua cli '%s': %s.\n",
7375 		         fcn->name, lua_tostring(hlua->T, -1));
7376 		lua_pop(hlua->T, 1);
7377 		return 1;
7378 
7379 	case HLUA_E_ETMOUT:
7380 		SEND_ERR(NULL, "Lua converter '%s': execution timeout.\n",
7381 		         fcn->name);
7382 		return 1;
7383 
7384 	case HLUA_E_NOMEM:
7385 		SEND_ERR(NULL, "Lua converter '%s': out of memory error.\n",
7386 		         fcn->name);
7387 		return 1;
7388 
7389 	case HLUA_E_YIELD: /* unexpected */
7390 		SEND_ERR(NULL, "Lua converter '%s': yield not allowed.\n",
7391 		         fcn->name);
7392 		return 1;
7393 
7394 	case HLUA_E_ERR:
7395 		/* Display log. */
7396 		SEND_ERR(NULL, "Lua cli '%s' return an unknown error.\n",
7397 		         fcn->name);
7398 		return 1;
7399 
7400 	default:
7401 		return 1;
7402 	}
7403 
7404 	return 1;
7405 }
7406 
hlua_cli_io_release_fct(struct appctx * appctx)7407 static void hlua_cli_io_release_fct(struct appctx *appctx)
7408 {
7409 	hlua_ctx_destroy(appctx->ctx.hlua_cli.hlua);
7410 	appctx->ctx.hlua_cli.hlua = NULL;
7411 }
7412 
7413 /* This function is an LUA binding used for registering
7414  * new keywords in the cli. It expects a list of keywords
7415  * which are the "path". It is limited to 5 keywords. A
7416  * description of the command, a function to be executed
7417  * for the parsing and a function for io handlers.
7418  */
hlua_register_cli(lua_State * L)7419 __LJMP static int hlua_register_cli(lua_State *L)
7420 {
7421 	struct cli_kw_list *cli_kws;
7422 	const char *message;
7423 	int ref_io;
7424 	int len;
7425 	struct hlua_function *fcn;
7426 	int index;
7427 	int i;
7428 	struct buffer *trash;
7429 	const char *kw[5];
7430 	struct cli_kw *cli_kw;
7431 
7432 	MAY_LJMP(check_args(L, 3, "register_cli"));
7433 
7434 	/* First argument : an array of maximum 5 keywords. */
7435 	if (!lua_istable(L, 1))
7436 		WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table"));
7437 
7438 	/* Second argument : string with contextual message. */
7439 	message = MAY_LJMP(luaL_checkstring(L, 2));
7440 
7441 	/* Third and fourth argument : lua function. */
7442 	ref_io = MAY_LJMP(hlua_checkfunction(L, 3));
7443 
7444 	/* Check for CLI service already registered */
7445 	trash = get_trash_chunk();
7446 	index = 0;
7447 	lua_pushnil(L);
7448 	memset(kw, 0, sizeof(kw));
7449 	while (lua_next(L, 1) != 0) {
7450 		if (index >= CLI_PREFIX_KW_NB)
7451 			WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table with a maximum of 5 entries"));
7452 		if (lua_type(L, -1) != LUA_TSTRING)
7453 			WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table filled with strings"));
7454 		kw[index] = lua_tostring(L, -1);
7455 		if (index == 0)
7456 			chunk_printf(trash, "%s", kw[index]);
7457 		else
7458 			chunk_appendf(trash, " %s", kw[index]);
7459 		index++;
7460 		lua_pop(L, 1);
7461 	}
7462 	cli_kw = cli_find_kw_exact((char **)kw);
7463 	if (cli_kw != NULL) {
7464 		ha_warning("Trying to register CLI keyword 'lua.%s' more than once. "
7465 		           "This will become a hard error in version 2.5.\n", trash->area);
7466 	}
7467 
7468 	/* Allocate and fill the sample fetch keyword struct. */
7469 	cli_kws = calloc(1, sizeof(*cli_kws) + sizeof(struct cli_kw) * 2);
7470 	if (!cli_kws)
7471 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7472 	fcn = calloc(1, sizeof(*fcn));
7473 	if (!fcn)
7474 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7475 
7476 	/* Fill path. */
7477 	index = 0;
7478 	lua_pushnil(L);
7479 	while(lua_next(L, 1) != 0) {
7480 		if (index >= 5)
7481 			WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table with a maximum of 5 entries"));
7482 		if (lua_type(L, -1) != LUA_TSTRING)
7483 			WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table filled with strings"));
7484 		cli_kws->kw[0].str_kw[index] = strdup(lua_tostring(L, -1));
7485 		if (!cli_kws->kw[0].str_kw[index])
7486 			WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7487 		index++;
7488 		lua_pop(L, 1);
7489 	}
7490 
7491 	/* Copy help message. */
7492 	cli_kws->kw[0].usage = strdup(message);
7493 	if (!cli_kws->kw[0].usage)
7494 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7495 
7496 	/* Fill fcn io handler. */
7497 	len = strlen("<lua.cli>") + 1;
7498 	for (i = 0; i < index; i++)
7499 		len += strlen(cli_kws->kw[0].str_kw[i]) + 1;
7500 	fcn->name = calloc(1, len);
7501 	if (!fcn->name)
7502 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7503 	strncat((char *)fcn->name, "<lua.cli", len);
7504 	for (i = 0; i < index; i++) {
7505 		strncat((char *)fcn->name, ".", len);
7506 		strncat((char *)fcn->name, cli_kws->kw[0].str_kw[i], len);
7507 	}
7508 	strncat((char *)fcn->name, ">", len);
7509 	fcn->function_ref = ref_io;
7510 
7511 	/* Fill last entries. */
7512 	cli_kws->kw[0].private = fcn;
7513 	cli_kws->kw[0].parse = hlua_cli_parse_fct;
7514 	cli_kws->kw[0].io_handler = hlua_cli_io_handler_fct;
7515 	cli_kws->kw[0].io_release = hlua_cli_io_release_fct;
7516 
7517 	/* Register this new converter */
7518 	cli_register_kw(cli_kws);
7519 
7520 	return 0;
7521 }
7522 
hlua_read_timeout(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err,unsigned int * timeout)7523 static int hlua_read_timeout(char **args, int section_type, struct proxy *curpx,
7524                              struct proxy *defpx, const char *file, int line,
7525                              char **err, unsigned int *timeout)
7526 {
7527 	const char *error;
7528 
7529 	error = parse_time_err(args[1], timeout, TIME_UNIT_MS);
7530 	if (error == PARSE_TIME_OVER) {
7531 		memprintf(err, "timer overflow in argument <%s> to <%s> (maximum value is 2147483647 ms or ~24.8 days)",
7532 			  args[1], args[0]);
7533 		return -1;
7534 	}
7535 	else if (error == PARSE_TIME_UNDER) {
7536 		memprintf(err, "timer underflow in argument <%s> to <%s> (minimum non-null value is 1 ms)",
7537 			  args[1], args[0]);
7538 		return -1;
7539 	}
7540 	else if (error) {
7541 		memprintf(err, "%s: invalid timeout", args[0]);
7542 		return -1;
7543 	}
7544 	return 0;
7545 }
7546 
hlua_session_timeout(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)7547 static int hlua_session_timeout(char **args, int section_type, struct proxy *curpx,
7548                                 struct proxy *defpx, const char *file, int line,
7549                                 char **err)
7550 {
7551 	return hlua_read_timeout(args, section_type, curpx, defpx,
7552 	                         file, line, err, &hlua_timeout_session);
7553 }
7554 
hlua_task_timeout(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)7555 static int hlua_task_timeout(char **args, int section_type, struct proxy *curpx,
7556                              struct proxy *defpx, const char *file, int line,
7557                              char **err)
7558 {
7559 	return hlua_read_timeout(args, section_type, curpx, defpx,
7560 	                         file, line, err, &hlua_timeout_task);
7561 }
7562 
hlua_applet_timeout(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)7563 static int hlua_applet_timeout(char **args, int section_type, struct proxy *curpx,
7564                                struct proxy *defpx, const char *file, int line,
7565                                char **err)
7566 {
7567 	return hlua_read_timeout(args, section_type, curpx, defpx,
7568 	                         file, line, err, &hlua_timeout_applet);
7569 }
7570 
hlua_forced_yield(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)7571 static int hlua_forced_yield(char **args, int section_type, struct proxy *curpx,
7572                              struct proxy *defpx, const char *file, int line,
7573                              char **err)
7574 {
7575 	char *error;
7576 
7577 	hlua_nb_instruction = strtoll(args[1], &error, 10);
7578 	if (*error != '\0') {
7579 		memprintf(err, "%s: invalid number", args[0]);
7580 		return -1;
7581 	}
7582 	return 0;
7583 }
7584 
hlua_parse_maxmem(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)7585 static int hlua_parse_maxmem(char **args, int section_type, struct proxy *curpx,
7586                              struct proxy *defpx, const char *file, int line,
7587                              char **err)
7588 {
7589 	char *error;
7590 
7591 	if (*(args[1]) == 0) {
7592 		memprintf(err, "'%s' expects an integer argument (Lua memory size in MB).\n", args[0]);
7593 		return -1;
7594 	}
7595 	hlua_global_allocator.limit = strtoll(args[1], &error, 10) * 1024L * 1024L;
7596 	if (*error != '\0') {
7597 		memprintf(err, "%s: invalid number %s (error at '%c')", args[0], args[1], *error);
7598 		return -1;
7599 	}
7600 	return 0;
7601 }
7602 
7603 
7604 /* This function is called by the main configuration key "lua-load". It loads and
7605  * execute an lua file during the parsing of the HAProxy configuration file. It is
7606  * the main lua entry point.
7607  *
7608  * This function runs with the HAProxy keywords API. It returns -1 if an error
7609  * occurs, otherwise it returns 0.
7610  *
7611  * In some error case, LUA set an error message in top of the stack. This function
7612  * returns this error message in the HAProxy logs and pop it from the stack.
7613  *
7614  * This function can fail with an abort() due to an Lua critical error.
7615  * We are in the configuration parsing process of HAProxy, this abort() is
7616  * tolerated.
7617  */
hlua_load(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)7618 static int hlua_load(char **args, int section_type, struct proxy *curpx,
7619                      struct proxy *defpx, const char *file, int line,
7620                      char **err)
7621 {
7622 	int error;
7623 
7624 	if (*(args[1]) == 0) {
7625 		memprintf(err, "'%s' expects a file name as parameter.\n", args[0]);
7626 		return -1;
7627 	}
7628 
7629 	/* Just load and compile the file. */
7630 	error = luaL_loadfile(gL.T, args[1]);
7631 	if (error) {
7632 		memprintf(err, "error in Lua file '%s': %s", args[1], lua_tostring(gL.T, -1));
7633 		lua_pop(gL.T, 1);
7634 		return -1;
7635 	}
7636 
7637 	/* If no syntax error where detected, execute the code. */
7638 	error = lua_pcall(gL.T, 0, LUA_MULTRET, 0);
7639 	switch (error) {
7640 	case LUA_OK:
7641 		break;
7642 	case LUA_ERRRUN:
7643 		memprintf(err, "Lua runtime error: %s\n", lua_tostring(gL.T, -1));
7644 		lua_pop(gL.T, 1);
7645 		return -1;
7646 	case LUA_ERRMEM:
7647 		memprintf(err, "Lua out of memory error\n");
7648 		return -1;
7649 	case LUA_ERRERR:
7650 		memprintf(err, "Lua message handler error: %s\n", lua_tostring(gL.T, -1));
7651 		lua_pop(gL.T, 1);
7652 		return -1;
7653 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 503
7654 	case LUA_ERRGCMM:
7655 		memprintf(err, "Lua garbage collector error: %s\n", lua_tostring(gL.T, -1));
7656 		lua_pop(gL.T, 1);
7657 		return -1;
7658 #endif
7659 	default:
7660 		memprintf(err, "Lua unknonwn error: %s\n", lua_tostring(gL.T, -1));
7661 		lua_pop(gL.T, 1);
7662 		return -1;
7663 	}
7664 
7665 	return 0;
7666 }
7667 
7668 /* Prepend the given <path> followed by a semicolon to the `package.<type>` variable
7669  * in the given <ctx>.
7670  */
hlua_prepend_path(struct hlua ctx,char * type,char * path)7671 static int hlua_prepend_path(struct hlua ctx, char *type, char *path)
7672 {
7673 	lua_getglobal(ctx.T, "package"); /* push package variable   */
7674 	lua_pushstring(ctx.T, path);     /* push given path         */
7675 	lua_pushstring(ctx.T, ";");      /* push semicolon          */
7676 	lua_getfield(ctx.T, -3, type);   /* push old path           */
7677 	lua_concat(ctx.T, 3);            /* concatenate to new path */
7678 	lua_setfield(ctx.T, -2, type);   /* store new path          */
7679 	lua_pop(ctx.T, 1);               /* pop package variable    */
7680 
7681 	return 0;
7682 }
7683 
hlua_config_prepend_path(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)7684 static int hlua_config_prepend_path(char **args, int section_type, struct proxy *curpx,
7685                                     struct proxy *defpx, const char *file, int line,
7686                                     char **err)
7687 {
7688 	char *path;
7689 	char *type = "path";
7690 	if (too_many_args(2, args, err, NULL)) {
7691 		return -1;
7692 	}
7693 
7694 	if (!(*args[1])) {
7695 		memprintf(err, "'%s' expects to receive a <path> as argument", args[0]);
7696 		return -1;
7697 	}
7698 	path = args[1];
7699 
7700 	if (*args[2]) {
7701 		if (strcmp(args[2], "path") != 0 && strcmp(args[2], "cpath") != 0) {
7702 			memprintf(err, "'%s' expects <type> to either be 'path' or 'cpath'", args[0]);
7703 			return -1;
7704 		}
7705 		type = args[2];
7706 	}
7707 
7708 	return hlua_prepend_path(gL, type, path);
7709 }
7710 
7711 /* configuration keywords declaration */
7712 static struct cfg_kw_list cfg_kws = {{ },{
7713 	{ CFG_GLOBAL, "lua-prepend-path",         hlua_config_prepend_path },
7714 	{ CFG_GLOBAL, "lua-load",                 hlua_load },
7715 	{ CFG_GLOBAL, "tune.lua.session-timeout", hlua_session_timeout },
7716 	{ CFG_GLOBAL, "tune.lua.task-timeout",    hlua_task_timeout },
7717 	{ CFG_GLOBAL, "tune.lua.service-timeout", hlua_applet_timeout },
7718 	{ CFG_GLOBAL, "tune.lua.forced-yield",    hlua_forced_yield },
7719 	{ CFG_GLOBAL, "tune.lua.maxmem",          hlua_parse_maxmem },
7720 	{ 0, NULL, NULL },
7721 }};
7722 
7723 INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
7724 
7725 
7726 /* This function can fail with an abort() due to an Lua critical error.
7727  * We are in the initialisation process of HAProxy, this abort() is
7728  * tolerated.
7729  */
hlua_post_init()7730 int hlua_post_init()
7731 {
7732 	struct hlua_init_function *init;
7733 	const char *msg;
7734 	enum hlua_exec ret;
7735 	const char *error;
7736 
7737 	/* Call post initialisation function in safe environement. */
7738 	if (!SET_SAFE_LJMP(gL.T)) {
7739 		if (lua_type(gL.T, -1) == LUA_TSTRING)
7740 			error = lua_tostring(gL.T, -1);
7741 		else
7742 			error = "critical error";
7743 		fprintf(stderr, "Lua post-init: %s.\n", error);
7744 		exit(1);
7745 	}
7746 
7747 #if USE_OPENSSL
7748 	/* Initialize SSL server. */
7749 	if (socket_ssl.xprt->prepare_srv) {
7750 		int saved_used_backed = global.ssl_used_backend;
7751 		// don't affect maxconn automatic computation
7752 		socket_ssl.xprt->prepare_srv(&socket_ssl);
7753 		global.ssl_used_backend = saved_used_backed;
7754 	}
7755 #endif
7756 
7757 	hlua_fcn_post_init(gL.T);
7758 	RESET_SAFE_LJMP(gL.T);
7759 
7760 	list_for_each_entry(init, &hlua_init_functions, l) {
7761 		lua_rawgeti(gL.T, LUA_REGISTRYINDEX, init->function_ref);
7762 		ret = hlua_ctx_resume(&gL, 0);
7763 		switch (ret) {
7764 		case HLUA_E_OK:
7765 			lua_pop(gL.T, -1);
7766 			break;
7767 		case HLUA_E_AGAIN:
7768 			ha_alert("Lua init: yield not allowed.\n");
7769 			return 0;
7770 		case HLUA_E_ERRMSG:
7771 			msg = lua_tostring(gL.T, -1);
7772 			ha_alert("lua init: %s.\n", msg);
7773 			return 0;
7774 		case HLUA_E_ERR:
7775 		default:
7776 			ha_alert("Lua init: unknown runtime error.\n");
7777 			return 0;
7778 		}
7779 	}
7780 	return 1;
7781 }
7782 
7783 /* The memory allocator used by the Lua stack. <ud> is a pointer to the
7784  * allocator's context. <ptr> is the pointer to alloc/free/realloc. <osize>
7785  * is the previously allocated size or the kind of object in case of a new
7786  * allocation. <nsize> is the requested new size.
7787  */
hlua_alloc(void * ud,void * ptr,size_t osize,size_t nsize)7788 static void *hlua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
7789 {
7790 	struct hlua_mem_allocator *zone = ud;
7791 
7792 	if (nsize == 0) {
7793 		/* it's a free */
7794 		if (ptr)
7795 			zone->allocated -= osize;
7796 		free(ptr);
7797 		return NULL;
7798 	}
7799 
7800 	if (!ptr) {
7801 		/* it's a new allocation */
7802 		if (zone->limit && zone->allocated + nsize > zone->limit)
7803 			return NULL;
7804 
7805 		ptr = malloc(nsize);
7806 		if (ptr)
7807 			zone->allocated += nsize;
7808 		return ptr;
7809 	}
7810 
7811 	/* it's a realloc */
7812 	if (zone->limit && zone->allocated + nsize - osize > zone->limit)
7813 		return NULL;
7814 
7815 	ptr = realloc(ptr, nsize);
7816 	if (ptr)
7817 		zone->allocated += nsize - osize;
7818 	return ptr;
7819 }
7820 
7821 /* Ithis function can fail with an abort() due to an Lua critical error.
7822  * We are in the initialisation process of HAProxy, this abort() is
7823  * tolerated.
7824  */
hlua_init(void)7825 void hlua_init(void)
7826 {
7827 	int i;
7828 	int idx;
7829 	struct sample_fetch *sf;
7830 	struct sample_conv *sc;
7831 	char *p;
7832 	const char *error_msg;
7833 #ifdef USE_OPENSSL
7834 	struct srv_kw *kw;
7835 	int tmp_error;
7836 	char *error;
7837 	char *args[] = { /* SSL client configuration. */
7838 		"ssl",
7839 		"verify",
7840 		"none",
7841 		NULL
7842 	};
7843 #endif
7844 
7845 	/* Init main lua stack. */
7846 	gL.Mref = LUA_REFNIL;
7847 	gL.flags = 0;
7848 	LIST_INIT(&gL.com);
7849 	gL.T = lua_newstate(hlua_alloc, &hlua_global_allocator);
7850 	hlua_sethlua(&gL);
7851 	gL.Tref = LUA_REFNIL;
7852 	gL.task = NULL;
7853 
7854 	/* From this point, until the end of the initialisation function,
7855 	 * the Lua function can fail with an abort. We are in the initialisation
7856 	 * process of HAProxy, this abort() is tolerated.
7857 	 */
7858 
7859 	/* Set safe environment for the initialisation. */
7860 	if (!SET_SAFE_LJMP(gL.T)) {
7861 		if (lua_type(gL.T, -1) == LUA_TSTRING)
7862 			error_msg = lua_tostring(gL.T, -1);
7863 		else
7864 			error_msg = "critical error";
7865 		fprintf(stderr, "Lua init: %s.\n", error_msg);
7866 		exit(1);
7867 	}
7868 
7869 	/* Initialise lua. */
7870 	luaL_openlibs(gL.T);
7871 #define HLUA_PREPEND_PATH_TOSTRING1(x) #x
7872 #define HLUA_PREPEND_PATH_TOSTRING(x) HLUA_PREPEND_PATH_TOSTRING1(x)
7873 #ifdef HLUA_PREPEND_PATH
7874 	hlua_prepend_path(gL, "path", HLUA_PREPEND_PATH_TOSTRING(HLUA_PREPEND_PATH));
7875 #endif
7876 #ifdef HLUA_PREPEND_CPATH
7877 	hlua_prepend_path(gL, "cpath", HLUA_PREPEND_PATH_TOSTRING(HLUA_PREPEND_CPATH));
7878 #endif
7879 #undef HLUA_PREPEND_PATH_TOSTRING
7880 #undef HLUA_PREPEND_PATH_TOSTRING1
7881 
7882 	/*
7883 	 *
7884 	 * Create "core" object.
7885 	 *
7886 	 */
7887 
7888 	/* This table entry is the object "core" base. */
7889 	lua_newtable(gL.T);
7890 
7891 	/* Push the loglevel constants. */
7892 	for (i = 0; i < NB_LOG_LEVELS; i++)
7893 		hlua_class_const_int(gL.T, log_levels[i], i);
7894 
7895 	/* Register special functions. */
7896 	hlua_class_function(gL.T, "register_init", hlua_register_init);
7897 	hlua_class_function(gL.T, "register_task", hlua_register_task);
7898 	hlua_class_function(gL.T, "register_fetches", hlua_register_fetches);
7899 	hlua_class_function(gL.T, "register_converters", hlua_register_converters);
7900 	hlua_class_function(gL.T, "register_action", hlua_register_action);
7901 	hlua_class_function(gL.T, "register_service", hlua_register_service);
7902 	hlua_class_function(gL.T, "register_cli", hlua_register_cli);
7903 	hlua_class_function(gL.T, "yield", hlua_yield);
7904 	hlua_class_function(gL.T, "set_nice", hlua_set_nice);
7905 	hlua_class_function(gL.T, "sleep", hlua_sleep);
7906 	hlua_class_function(gL.T, "msleep", hlua_msleep);
7907 	hlua_class_function(gL.T, "add_acl", hlua_add_acl);
7908 	hlua_class_function(gL.T, "del_acl", hlua_del_acl);
7909 	hlua_class_function(gL.T, "set_map", hlua_set_map);
7910 	hlua_class_function(gL.T, "del_map", hlua_del_map);
7911 	hlua_class_function(gL.T, "tcp", hlua_socket_new);
7912 	hlua_class_function(gL.T, "log", hlua_log);
7913 	hlua_class_function(gL.T, "Debug", hlua_log_debug);
7914 	hlua_class_function(gL.T, "Info", hlua_log_info);
7915 	hlua_class_function(gL.T, "Warning", hlua_log_warning);
7916 	hlua_class_function(gL.T, "Alert", hlua_log_alert);
7917 	hlua_class_function(gL.T, "done", hlua_done);
7918 	hlua_fcn_reg_core_fcn(gL.T);
7919 
7920 	lua_setglobal(gL.T, "core");
7921 
7922 	/*
7923 	 *
7924 	 * Register class Map
7925 	 *
7926 	 */
7927 
7928 	/* This table entry is the object "Map" base. */
7929 	lua_newtable(gL.T);
7930 
7931 	/* register pattern types. */
7932 	for (i=0; i<PAT_MATCH_NUM; i++)
7933 		hlua_class_const_int(gL.T, pat_match_names[i], i);
7934 	for (i=0; i<PAT_MATCH_NUM; i++) {
7935 		snprintf(trash.area, trash.size, "_%s", pat_match_names[i]);
7936 		hlua_class_const_int(gL.T, trash.area, i);
7937 	}
7938 
7939 	/* register constructor. */
7940 	hlua_class_function(gL.T, "new", hlua_map_new);
7941 
7942 	/* Create and fill the metatable. */
7943 	lua_newtable(gL.T);
7944 
7945 	/* Create and fille the __index entry. */
7946 	lua_pushstring(gL.T, "__index");
7947 	lua_newtable(gL.T);
7948 
7949 	/* Register . */
7950 	hlua_class_function(gL.T, "lookup", hlua_map_lookup);
7951 	hlua_class_function(gL.T, "slookup", hlua_map_slookup);
7952 
7953 	lua_rawset(gL.T, -3);
7954 
7955 	/* Register previous table in the registry with reference and named entry.
7956 	 * The function hlua_register_metatable() pops the stack, so we
7957 	 * previously create a copy of the table.
7958 	 */
7959 	lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
7960 	class_map_ref = hlua_register_metatable(gL.T, CLASS_MAP);
7961 
7962 	/* Assign the metatable to the mai Map object. */
7963 	lua_setmetatable(gL.T, -2);
7964 
7965 	/* Set a name to the table. */
7966 	lua_setglobal(gL.T, "Map");
7967 
7968 	/*
7969 	 *
7970 	 * Register class Channel
7971 	 *
7972 	 */
7973 
7974 	/* Create and fill the metatable. */
7975 	lua_newtable(gL.T);
7976 
7977 	/* Create and fille the __index entry. */
7978 	lua_pushstring(gL.T, "__index");
7979 	lua_newtable(gL.T);
7980 
7981 	/* Register . */
7982 	hlua_class_function(gL.T, "get",         hlua_channel_get);
7983 	hlua_class_function(gL.T, "dup",         hlua_channel_dup);
7984 	hlua_class_function(gL.T, "getline",     hlua_channel_getline);
7985 	hlua_class_function(gL.T, "set",         hlua_channel_set);
7986 	hlua_class_function(gL.T, "append",      hlua_channel_append);
7987 	hlua_class_function(gL.T, "send",        hlua_channel_send);
7988 	hlua_class_function(gL.T, "forward",     hlua_channel_forward);
7989 	hlua_class_function(gL.T, "get_in_len",  hlua_channel_get_in_len);
7990 	hlua_class_function(gL.T, "get_out_len", hlua_channel_get_out_len);
7991 	hlua_class_function(gL.T, "is_full",     hlua_channel_is_full);
7992 
7993 	lua_rawset(gL.T, -3);
7994 
7995 	/* Register previous table in the registry with reference and named entry. */
7996 	class_channel_ref = hlua_register_metatable(gL.T, CLASS_CHANNEL);
7997 
7998 	/*
7999 	 *
8000 	 * Register class Fetches
8001 	 *
8002 	 */
8003 
8004 	/* Create and fill the metatable. */
8005 	lua_newtable(gL.T);
8006 
8007 	/* Create and fille the __index entry. */
8008 	lua_pushstring(gL.T, "__index");
8009 	lua_newtable(gL.T);
8010 
8011 	/* Browse existing fetches and create the associated
8012 	 * object method.
8013 	 */
8014 	sf = NULL;
8015 	while ((sf = sample_fetch_getnext(sf, &idx)) != NULL) {
8016 		/* gL.Tua doesn't support '.' and '-' in the function names, replace it
8017 		 * by an underscore.
8018 		 */
8019 		strncpy(trash.area, sf->kw, trash.size);
8020 		trash.area[trash.size - 1] = '\0';
8021 		for (p = trash.area; *p; p++)
8022 			if (*p == '.' || *p == '-' || *p == '+')
8023 				*p = '_';
8024 
8025 		/* Register the function. */
8026 		lua_pushstring(gL.T, trash.area);
8027 		lua_pushlightuserdata(gL.T, sf);
8028 		lua_pushcclosure(gL.T, hlua_run_sample_fetch, 1);
8029 		lua_rawset(gL.T, -3);
8030 	}
8031 
8032 	lua_rawset(gL.T, -3);
8033 
8034 	/* Register previous table in the registry with reference and named entry. */
8035 	class_fetches_ref = hlua_register_metatable(gL.T, CLASS_FETCHES);
8036 
8037 	/*
8038 	 *
8039 	 * Register class Converters
8040 	 *
8041 	 */
8042 
8043 	/* Create and fill the metatable. */
8044 	lua_newtable(gL.T);
8045 
8046 	/* Create and fill the __index entry. */
8047 	lua_pushstring(gL.T, "__index");
8048 	lua_newtable(gL.T);
8049 
8050 	/* Browse existing converters and create the associated
8051 	 * object method.
8052 	 */
8053 	sc = NULL;
8054 	while ((sc = sample_conv_getnext(sc, &idx)) != NULL) {
8055 		/* gL.Tua doesn't support '.' and '-' in the function names, replace it
8056 		 * by an underscore.
8057 		 */
8058 		strncpy(trash.area, sc->kw, trash.size);
8059 		trash.area[trash.size - 1] = '\0';
8060 		for (p = trash.area; *p; p++)
8061 			if (*p == '.' || *p == '-' || *p == '+')
8062 				*p = '_';
8063 
8064 		/* Register the function. */
8065 		lua_pushstring(gL.T, trash.area);
8066 		lua_pushlightuserdata(gL.T, sc);
8067 		lua_pushcclosure(gL.T, hlua_run_sample_conv, 1);
8068 		lua_rawset(gL.T, -3);
8069 	}
8070 
8071 	lua_rawset(gL.T, -3);
8072 
8073 	/* Register previous table in the registry with reference and named entry. */
8074 	class_converters_ref = hlua_register_metatable(gL.T, CLASS_CONVERTERS);
8075 
8076 	/*
8077 	 *
8078 	 * Register class HTTP
8079 	 *
8080 	 */
8081 
8082 	/* Create and fill the metatable. */
8083 	lua_newtable(gL.T);
8084 
8085 	/* Create and fille the __index entry. */
8086 	lua_pushstring(gL.T, "__index");
8087 	lua_newtable(gL.T);
8088 
8089 	/* Register Lua functions. */
8090 	hlua_class_function(gL.T, "req_get_headers",hlua_http_req_get_headers);
8091 	hlua_class_function(gL.T, "req_del_header", hlua_http_req_del_hdr);
8092 	hlua_class_function(gL.T, "req_rep_header", hlua_http_req_rep_hdr);
8093 	hlua_class_function(gL.T, "req_rep_value",  hlua_http_req_rep_val);
8094 	hlua_class_function(gL.T, "req_add_header", hlua_http_req_add_hdr);
8095 	hlua_class_function(gL.T, "req_set_header", hlua_http_req_set_hdr);
8096 	hlua_class_function(gL.T, "req_set_method", hlua_http_req_set_meth);
8097 	hlua_class_function(gL.T, "req_set_path",   hlua_http_req_set_path);
8098 	hlua_class_function(gL.T, "req_set_query",  hlua_http_req_set_query);
8099 	hlua_class_function(gL.T, "req_set_uri",    hlua_http_req_set_uri);
8100 
8101 	hlua_class_function(gL.T, "res_get_headers",hlua_http_res_get_headers);
8102 	hlua_class_function(gL.T, "res_del_header", hlua_http_res_del_hdr);
8103 	hlua_class_function(gL.T, "res_rep_header", hlua_http_res_rep_hdr);
8104 	hlua_class_function(gL.T, "res_rep_value",  hlua_http_res_rep_val);
8105 	hlua_class_function(gL.T, "res_add_header", hlua_http_res_add_hdr);
8106 	hlua_class_function(gL.T, "res_set_header", hlua_http_res_set_hdr);
8107 	hlua_class_function(gL.T, "res_set_status", hlua_http_res_set_status);
8108 
8109 	lua_rawset(gL.T, -3);
8110 
8111 	/* Register previous table in the registry with reference and named entry. */
8112 	class_http_ref = hlua_register_metatable(gL.T, CLASS_HTTP);
8113 
8114 	/*
8115 	 *
8116 	 * Register class AppletTCP
8117 	 *
8118 	 */
8119 
8120 	/* Create and fill the metatable. */
8121 	lua_newtable(gL.T);
8122 
8123 	/* Create and fille the __index entry. */
8124 	lua_pushstring(gL.T, "__index");
8125 	lua_newtable(gL.T);
8126 
8127 	/* Register Lua functions. */
8128 	hlua_class_function(gL.T, "getline",   hlua_applet_tcp_getline);
8129 	hlua_class_function(gL.T, "receive",   hlua_applet_tcp_recv);
8130 	hlua_class_function(gL.T, "send",      hlua_applet_tcp_send);
8131 	hlua_class_function(gL.T, "set_priv",  hlua_applet_tcp_set_priv);
8132 	hlua_class_function(gL.T, "get_priv",  hlua_applet_tcp_get_priv);
8133 	hlua_class_function(gL.T, "set_var",   hlua_applet_tcp_set_var);
8134 	hlua_class_function(gL.T, "unset_var", hlua_applet_tcp_unset_var);
8135 	hlua_class_function(gL.T, "get_var",   hlua_applet_tcp_get_var);
8136 
8137 	lua_settable(gL.T, -3);
8138 
8139 	/* Register previous table in the registry with reference and named entry. */
8140 	class_applet_tcp_ref = hlua_register_metatable(gL.T, CLASS_APPLET_TCP);
8141 
8142 	/*
8143 	 *
8144 	 * Register class AppletHTTP
8145 	 *
8146 	 */
8147 
8148 	/* Create and fill the metatable. */
8149 	lua_newtable(gL.T);
8150 
8151 	/* Create and fille the __index entry. */
8152 	lua_pushstring(gL.T, "__index");
8153 	lua_newtable(gL.T);
8154 
8155 	/* Register Lua functions. */
8156 	hlua_class_function(gL.T, "set_priv",       hlua_applet_http_set_priv);
8157 	hlua_class_function(gL.T, "get_priv",       hlua_applet_http_get_priv);
8158 	hlua_class_function(gL.T, "set_var",        hlua_applet_http_set_var);
8159 	hlua_class_function(gL.T, "unset_var",      hlua_applet_http_unset_var);
8160 	hlua_class_function(gL.T, "get_var",        hlua_applet_http_get_var);
8161 	hlua_class_function(gL.T, "getline",        hlua_applet_http_getline);
8162 	hlua_class_function(gL.T, "receive",        hlua_applet_http_recv);
8163 	hlua_class_function(gL.T, "send",           hlua_applet_http_send);
8164 	hlua_class_function(gL.T, "add_header",     hlua_applet_http_addheader);
8165 	hlua_class_function(gL.T, "set_status",     hlua_applet_http_status);
8166 	hlua_class_function(gL.T, "start_response", hlua_applet_http_start_response);
8167 
8168 	lua_settable(gL.T, -3);
8169 
8170 	/* Register previous table in the registry with reference and named entry. */
8171 	class_applet_http_ref = hlua_register_metatable(gL.T, CLASS_APPLET_HTTP);
8172 
8173 	/*
8174 	 *
8175 	 * Register class TXN
8176 	 *
8177 	 */
8178 
8179 	/* Create and fill the metatable. */
8180 	lua_newtable(gL.T);
8181 
8182 	/* Create and fille the __index entry. */
8183 	lua_pushstring(gL.T, "__index");
8184 	lua_newtable(gL.T);
8185 
8186 	/* Register Lua functions. */
8187 	hlua_class_function(gL.T, "set_priv",            hlua_set_priv);
8188 	hlua_class_function(gL.T, "get_priv",            hlua_get_priv);
8189 	hlua_class_function(gL.T, "set_var",             hlua_set_var);
8190 	hlua_class_function(gL.T, "unset_var",           hlua_unset_var);
8191 	hlua_class_function(gL.T, "get_var",             hlua_get_var);
8192 	hlua_class_function(gL.T, "done",                hlua_txn_done);
8193 	hlua_class_function(gL.T, "set_loglevel",        hlua_txn_set_loglevel);
8194 	hlua_class_function(gL.T, "set_tos",             hlua_txn_set_tos);
8195 	hlua_class_function(gL.T, "set_mark",            hlua_txn_set_mark);
8196 	hlua_class_function(gL.T, "set_priority_class",  hlua_txn_set_priority_class);
8197 	hlua_class_function(gL.T, "set_priority_offset", hlua_txn_set_priority_offset);
8198 	hlua_class_function(gL.T, "deflog",              hlua_txn_deflog);
8199 	hlua_class_function(gL.T, "log",                 hlua_txn_log);
8200 	hlua_class_function(gL.T, "Debug",               hlua_txn_log_debug);
8201 	hlua_class_function(gL.T, "Info",                hlua_txn_log_info);
8202 	hlua_class_function(gL.T, "Warning",             hlua_txn_log_warning);
8203 	hlua_class_function(gL.T, "Alert",               hlua_txn_log_alert);
8204 
8205 	lua_rawset(gL.T, -3);
8206 
8207 	/* Register previous table in the registry with reference and named entry. */
8208 	class_txn_ref = hlua_register_metatable(gL.T, CLASS_TXN);
8209 
8210 	/*
8211 	 *
8212 	 * Register class Socket
8213 	 *
8214 	 */
8215 
8216 	/* Create and fill the metatable. */
8217 	lua_newtable(gL.T);
8218 
8219 	/* Create and fille the __index entry. */
8220 	lua_pushstring(gL.T, "__index");
8221 	lua_newtable(gL.T);
8222 
8223 #ifdef USE_OPENSSL
8224 	hlua_class_function(gL.T, "connect_ssl", hlua_socket_connect_ssl);
8225 #endif
8226 	hlua_class_function(gL.T, "connect",     hlua_socket_connect);
8227 	hlua_class_function(gL.T, "send",        hlua_socket_send);
8228 	hlua_class_function(gL.T, "receive",     hlua_socket_receive);
8229 	hlua_class_function(gL.T, "close",       hlua_socket_close);
8230 	hlua_class_function(gL.T, "getpeername", hlua_socket_getpeername);
8231 	hlua_class_function(gL.T, "getsockname", hlua_socket_getsockname);
8232 	hlua_class_function(gL.T, "setoption",   hlua_socket_setoption);
8233 	hlua_class_function(gL.T, "settimeout",  hlua_socket_settimeout);
8234 
8235 	lua_rawset(gL.T, -3); /* Push the last 2 entries in the table at index -3 */
8236 
8237 	/* Register the garbage collector entry. */
8238 	lua_pushstring(gL.T, "__gc");
8239 	lua_pushcclosure(gL.T, hlua_socket_gc, 0);
8240 	lua_rawset(gL.T, -3); /* Push the last 2 entries in the table at index -3 */
8241 
8242 	/* Register previous table in the registry with reference and named entry. */
8243 	class_socket_ref = hlua_register_metatable(gL.T, CLASS_SOCKET);
8244 
8245 	/* Proxy and server configuration initialisation. */
8246 	memset(&socket_proxy, 0, sizeof(socket_proxy));
8247 	init_new_proxy(&socket_proxy);
8248 	socket_proxy.parent = NULL;
8249 	socket_proxy.last_change = now.tv_sec;
8250 	socket_proxy.id = "LUA-SOCKET";
8251 	socket_proxy.cap = PR_CAP_FE | PR_CAP_BE;
8252 	socket_proxy.maxconn = 0;
8253 	socket_proxy.accept = NULL;
8254 	socket_proxy.options2 |= PR_O2_INDEPSTR;
8255 	socket_proxy.srv = NULL;
8256 	socket_proxy.conn_retries = 0;
8257 	socket_proxy.timeout.connect = 5000; /* By default the timeout connection is 5s. */
8258 
8259 	/* Init TCP server: unchanged parameters */
8260 	memset(&socket_tcp, 0, sizeof(socket_tcp));
8261 	socket_tcp.next = NULL;
8262 	socket_tcp.proxy = &socket_proxy;
8263 	socket_tcp.obj_type = OBJ_TYPE_SERVER;
8264 	LIST_INIT(&socket_tcp.actconns);
8265 	socket_tcp.pendconns = EB_ROOT;
8266 	socket_tcp.priv_conns = NULL;
8267 	socket_tcp.idle_conns = NULL;
8268 	socket_tcp.safe_conns = NULL;
8269 	socket_tcp.next_state = SRV_ST_RUNNING; /* early server setup */
8270 	socket_tcp.last_change = 0;
8271 	socket_tcp.id = "LUA-TCP-CONN";
8272 	socket_tcp.check.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
8273 	socket_tcp.agent.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
8274 	socket_tcp.pp_opts = 0; /* Remove proxy protocol. */
8275 
8276 	/* XXX: Copy default parameter from default server,
8277 	 * but the default server is not initialized.
8278 	 */
8279 	socket_tcp.maxqueue     = socket_proxy.defsrv.maxqueue;
8280 	socket_tcp.minconn      = socket_proxy.defsrv.minconn;
8281 	socket_tcp.maxconn      = socket_proxy.defsrv.maxconn;
8282 	socket_tcp.slowstart    = socket_proxy.defsrv.slowstart;
8283 	socket_tcp.onerror      = socket_proxy.defsrv.onerror;
8284 	socket_tcp.onmarkeddown = socket_proxy.defsrv.onmarkeddown;
8285 	socket_tcp.onmarkedup   = socket_proxy.defsrv.onmarkedup;
8286 	socket_tcp.consecutive_errors_limit = socket_proxy.defsrv.consecutive_errors_limit;
8287 	socket_tcp.uweight      = socket_proxy.defsrv.iweight;
8288 	socket_tcp.iweight      = socket_proxy.defsrv.iweight;
8289 
8290 	socket_tcp.check.status = HCHK_STATUS_INI;
8291 	socket_tcp.check.rise   = socket_proxy.defsrv.check.rise;
8292 	socket_tcp.check.fall   = socket_proxy.defsrv.check.fall;
8293 	socket_tcp.check.health = socket_tcp.check.rise;   /* socket, but will fall down at first failure */
8294 	socket_tcp.check.server = &socket_tcp;
8295 
8296 	socket_tcp.agent.status = HCHK_STATUS_INI;
8297 	socket_tcp.agent.rise   = socket_proxy.defsrv.agent.rise;
8298 	socket_tcp.agent.fall   = socket_proxy.defsrv.agent.fall;
8299 	socket_tcp.agent.health = socket_tcp.agent.rise;   /* socket, but will fall down at first failure */
8300 	socket_tcp.agent.server = &socket_tcp;
8301 
8302 	socket_tcp.xprt = xprt_get(XPRT_RAW);
8303 
8304 #ifdef USE_OPENSSL
8305 	/* Init TCP server: unchanged parameters */
8306 	memset(&socket_ssl, 0, sizeof(socket_ssl));
8307 	socket_ssl.next = NULL;
8308 	socket_ssl.proxy = &socket_proxy;
8309 	socket_ssl.obj_type = OBJ_TYPE_SERVER;
8310 	LIST_INIT(&socket_ssl.actconns);
8311 	socket_ssl.pendconns = EB_ROOT;
8312 	socket_ssl.priv_conns = NULL;
8313 	socket_ssl.idle_conns = NULL;
8314 	socket_ssl.safe_conns = NULL;
8315 	socket_ssl.next_state = SRV_ST_RUNNING; /* early server setup */
8316 	socket_ssl.last_change = 0;
8317 	socket_ssl.id = "LUA-SSL-CONN";
8318 	socket_ssl.check.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
8319 	socket_ssl.agent.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
8320 	socket_ssl.pp_opts = 0; /* Remove proxy protocol. */
8321 
8322 	/* XXX: Copy default parameter from default server,
8323 	 * but the default server is not initialized.
8324 	 */
8325 	socket_ssl.maxqueue     = socket_proxy.defsrv.maxqueue;
8326 	socket_ssl.minconn      = socket_proxy.defsrv.minconn;
8327 	socket_ssl.maxconn      = socket_proxy.defsrv.maxconn;
8328 	socket_ssl.slowstart    = socket_proxy.defsrv.slowstart;
8329 	socket_ssl.onerror      = socket_proxy.defsrv.onerror;
8330 	socket_ssl.onmarkeddown = socket_proxy.defsrv.onmarkeddown;
8331 	socket_ssl.onmarkedup   = socket_proxy.defsrv.onmarkedup;
8332 	socket_ssl.consecutive_errors_limit = socket_proxy.defsrv.consecutive_errors_limit;
8333 	socket_ssl.uweight      = socket_proxy.defsrv.iweight;
8334 	socket_ssl.iweight      = socket_proxy.defsrv.iweight;
8335 
8336 	socket_ssl.check.status = HCHK_STATUS_INI;
8337 	socket_ssl.check.rise   = socket_proxy.defsrv.check.rise;
8338 	socket_ssl.check.fall   = socket_proxy.defsrv.check.fall;
8339 	socket_ssl.check.health = socket_ssl.check.rise;   /* socket, but will fall down at first failure */
8340 	socket_ssl.check.server = &socket_ssl;
8341 
8342 	socket_ssl.agent.status = HCHK_STATUS_INI;
8343 	socket_ssl.agent.rise   = socket_proxy.defsrv.agent.rise;
8344 	socket_ssl.agent.fall   = socket_proxy.defsrv.agent.fall;
8345 	socket_ssl.agent.health = socket_ssl.agent.rise;   /* socket, but will fall down at first failure */
8346 	socket_ssl.agent.server = &socket_ssl;
8347 
8348 	socket_ssl.use_ssl = 1;
8349 	socket_ssl.xprt = xprt_get(XPRT_SSL);
8350 
8351 	for (idx = 0; args[idx] != NULL; idx++) {
8352 		if ((kw = srv_find_kw(args[idx])) != NULL) { /* Maybe it's registered server keyword */
8353 			/*
8354 			 *
8355 			 * If the keyword is not known, we can search in the registered
8356 			 * server keywords. This is useful to configure special SSL
8357 			 * features like client certificates and ssl_verify.
8358 			 *
8359 			 */
8360 			tmp_error = kw->parse(args, &idx, &socket_proxy, &socket_ssl, &error);
8361 			if (tmp_error != 0) {
8362 				fprintf(stderr, "INTERNAL ERROR: %s\n", error);
8363 				abort(); /* This must be never arrives because the command line
8364 				            not editable by the user. */
8365 			}
8366 			idx += kw->skip;
8367 		}
8368 	}
8369 #endif
8370 
8371 	RESET_SAFE_LJMP(gL.T);
8372 }
8373 
hlua_register_build_options(void)8374 static void hlua_register_build_options(void)
8375 {
8376 	char *ptr = NULL;
8377 
8378 	memprintf(&ptr, "Built with Lua version : %s", LUA_RELEASE);
8379 	hap_register_build_opts(ptr, 1);
8380 }
8381 
8382 INITCALL0(STG_REGISTER, hlua_register_build_options);
8383