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