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