blob: d9df99d2da0ad5a8d8b22cb8aee2ff5175785d29 [file] [log] [blame]
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001#include <sys/socket.h>
2
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +01003#include <lauxlib.h>
4#include <lua.h>
5#include <lualib.h>
6
Thierry FOURNIER463119c2015-03-10 00:35:36 +01007#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 503
8#error "Requires Lua 5.3 or later."
Cyril Bontédc0306e2015-03-02 00:08:40 +01009#endif
10
Thierry FOURNIER380d0932015-01-23 14:27:52 +010011#include <ebpttree.h>
12
13#include <common/cfgparse.h>
14
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010015#include <types/connection.h>
Thierry FOURNIER380d0932015-01-23 14:27:52 +010016#include <types/hlua.h>
Thierry FOURNIER65f34c62015-02-16 20:11:43 +010017#include <types/proto_tcp.h>
Thierry FOURNIER380d0932015-01-23 14:27:52 +010018#include <types/proxy.h>
19
Thierry FOURNIER55da1652015-01-23 11:36:30 +010020#include <proto/arg.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010021#include <proto/channel.h>
Thierry FOURNIER9a819e72015-02-16 20:22:55 +010022#include <proto/hdr_idx.h>
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +010023#include <proto/hlua.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010024#include <proto/obj_type.h>
Thierry FOURNIER83758bb2015-02-04 13:21:04 +010025#include <proto/pattern.h>
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +010026#include <proto/payload.h>
27#include <proto/proto_http.h>
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +010028#include <proto/proto_tcp.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010029#include <proto/raw_sock.h>
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +010030#include <proto/sample.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010031#include <proto/server.h>
32#include <proto/session.h>
33#include <proto/ssl_sock.h>
34#include <proto/stream_interface.h>
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +010035#include <proto/task.h>
36
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +010037/* Lua uses longjmp to perform yield or throwing errors. This
38 * macro is used only for identifying the function that can
39 * not return because a longjmp is executed.
40 * __LJMP marks a prototype of hlua file that can use longjmp.
41 * WILL_LJMP() marks an lua function that will use longjmp.
42 * MAY_LJMP() marks an lua function that may use longjmp.
43 */
44#define __LJMP
45#define WILL_LJMP(func) func
46#define MAY_LJMP(func) func
47
Thierry FOURNIER380d0932015-01-23 14:27:52 +010048/* The main Lua execution context. */
49struct hlua gL;
50
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +010051/* This is the memory pool containing all the signal structs. These
52 * struct are used to store each requiered signal between two tasks.
53 */
54struct pool_head *pool2_hlua_com;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +010055struct pool_head *pool2_hlua_sleep;
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +010056
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010057/* Used for Socket connection. */
58static struct proxy socket_proxy;
59static struct server socket_tcp;
60#ifdef USE_OPENSSL
61static struct server socket_ssl;
62#endif
63
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +010064/* List head of the function called at the initialisation time. */
65struct list hlua_init_functions = LIST_HEAD_INIT(hlua_init_functions);
66
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +010067/* The following variables contains the reference of the different
68 * Lua classes. These references are useful for identify metadata
69 * associated with an object.
70 */
Thierry FOURNIER65f34c62015-02-16 20:11:43 +010071static int class_txn_ref;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010072static int class_socket_ref;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +010073static int class_channel_ref;
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +010074
Thierry FOURNIERbd413492015-03-03 16:52:26 +010075/* Global Lua execution timeout. By default Lua, execution linked
76 * with session (actions, sample-fetches and converters) have a
77 * short timeout. Lua linked with tasks doesn't have a timeout
78 * because a task may remain alive during all the haproxy execution.
79 */
80static unsigned int hlua_timeout_session = 4000; /* session timeout. */
81static unsigned int hlua_timeout_task = TICK_ETERNITY; /* task timeout. */
82
Thierry FOURNIERee9f8022015-03-03 17:37:37 +010083/* Interrupts the Lua processing each "hlua_nb_instruction" instructions.
84 * it is used for preventing infinite loops.
85 *
86 * I test the scheer with an infinite loop containing one incrementation
87 * and one test. I run this loop between 10 seconds, I raise a ceil of
88 * 710M loops from one interrupt each 9000 instructions, so I fix the value
89 * to one interrupt each 10 000 instructions.
90 *
91 * configured | Number of
92 * instructions | loops executed
93 * between two | in milions
94 * forced yields |
95 * ---------------+---------------
96 * 10 | 160
97 * 500 | 670
98 * 1000 | 680
99 * 5000 | 700
100 * 7000 | 700
101 * 8000 | 700
102 * 9000 | 710 <- ceil
103 * 10000 | 710
104 * 100000 | 710
105 * 1000000 | 710
106 *
107 */
108static unsigned int hlua_nb_instruction = 10000;
109
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100110/* These functions converts types between HAProxy internal args or
111 * sample and LUA types. Another function permits to check if the
112 * LUA stack contains arguments according with an required ARG_T
113 * format.
114 */
115static int hlua_arg2lua(lua_State *L, const struct arg *arg);
116static int hlua_lua2arg(lua_State *L, int ud, struct arg *arg);
117__LJMP static int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp, unsigned int mask);
Willy Tarreau5eadada2015-03-10 17:28:54 +0100118static int hlua_smp2lua(lua_State *L, struct sample *smp);
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100119static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp);
120
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100121/* Used to check an Lua function type in the stack. It creates and
122 * returns a reference of the function. This function throws an
123 * error if the rgument is not a "function".
124 */
125__LJMP unsigned int hlua_checkfunction(lua_State *L, int argno)
126{
127 if (!lua_isfunction(L, argno)) {
128 const char *msg = lua_pushfstring(L, "function expected, got %s", luaL_typename(L, -1));
129 WILL_LJMP(luaL_argerror(L, argno, msg));
130 }
131 lua_pushvalue(L, argno);
132 return luaL_ref(L, LUA_REGISTRYINDEX);
133}
134
135/* The three following functions are useful for adding entries
136 * in a table. These functions takes a string and respectively an
137 * integer, a string or a function and add it to the table in the
138 * top of the stack.
139 *
140 * These functions throws an error if no more stack size is
141 * available.
142 */
143__LJMP static inline void hlua_class_const_int(lua_State *L, const char *name,
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100144 int value)
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100145{
146 if (!lua_checkstack(L, 2))
147 WILL_LJMP(luaL_error(L, "full stack"));
148 lua_pushstring(L, name);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100149 lua_pushinteger(L, value);
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100150 lua_settable(L, -3);
151}
152__LJMP static inline void hlua_class_const_str(lua_State *L, const char *name,
153 const char *value)
154{
155 if (!lua_checkstack(L, 2))
156 WILL_LJMP(luaL_error(L, "full stack"));
157 lua_pushstring(L, name);
158 lua_pushstring(L, value);
159 lua_settable(L, -3);
160}
161__LJMP static inline void hlua_class_function(lua_State *L, const char *name,
162 int (*function)(lua_State *L))
163{
164 if (!lua_checkstack(L, 2))
165 WILL_LJMP(luaL_error(L, "full stack"));
166 lua_pushstring(L, name);
167 lua_pushcclosure(L, function, 0);
168 lua_settable(L, -3);
169}
170
171/* This function check the number of arguments available in the
172 * stack. If the number of arguments available is not the same
173 * then <nb> an error is throwed.
174 */
175__LJMP static inline void check_args(lua_State *L, int nb, char *fcn)
176{
177 if (lua_gettop(L) == nb)
178 return;
179 WILL_LJMP(luaL_error(L, "'%s' needs %d arguments", fcn, nb));
180}
181
182/* Return true if the data in stack[<ud>] is an object of
183 * type <class_ref>.
184 */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +0100185static int hlua_metaistype(lua_State *L, int ud, int class_ref)
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100186{
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100187 if (!lua_getmetatable(L, ud))
188 return 0;
189
190 lua_rawgeti(L, LUA_REGISTRYINDEX, class_ref);
191 if (!lua_rawequal(L, -1, -2)) {
192 lua_pop(L, 2);
193 return 0;
194 }
195
196 lua_pop(L, 2);
197 return 1;
198}
199
200/* Return an object of the expected type, or throws an error. */
201__LJMP static void *hlua_checkudata(lua_State *L, int ud, int class_ref)
202{
Thierry FOURNIER2297bc22015-03-11 17:43:33 +0100203 void *p;
204
205 /* Check if the stack entry is an array. */
206 if (!lua_istable(L, ud))
207 WILL_LJMP(luaL_argerror(L, ud, NULL));
208 /* Check if the metadata have the expected type. */
209 if (!hlua_metaistype(L, ud, class_ref))
210 WILL_LJMP(luaL_argerror(L, ud, NULL));
211 /* Push on the stack at the entry [0] of the table. */
212 lua_rawgeti(L, ud, 0);
213 /* Check if this entry is userdata. */
214 p = lua_touserdata(L, -1);
215 if (!p)
216 WILL_LJMP(luaL_argerror(L, ud, NULL));
217 /* Remove the entry returned by lua_rawgeti(). */
218 lua_pop(L, 1);
219 /* Return the associated struct. */
220 return p;
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100221}
222
223/* This fucntion push an error string prefixed by the file name
224 * and the line number where the error is encountered.
225 */
226static int hlua_pusherror(lua_State *L, const char *fmt, ...)
227{
228 va_list argp;
229 va_start(argp, fmt);
230 luaL_where(L, 1);
231 lua_pushvfstring(L, fmt, argp);
232 va_end(argp);
233 lua_concat(L, 2);
234 return 1;
235}
236
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100237/* This function register a new signal. "lua" is the current lua
238 * execution context. It contains a pointer to the associated task.
239 * "link" is a list head attached to an other task that must be wake
240 * the lua task if an event occurs. This is useful with external
241 * events like TCP I/O or sleep functions. This funcion allocate
242 * memory for the signal.
243 */
244static int hlua_com_new(struct hlua *lua, struct list *link)
245{
246 struct hlua_com *com = pool_alloc2(pool2_hlua_com);
247 if (!com)
248 return 0;
249 LIST_ADDQ(&lua->com, &com->purge_me);
250 LIST_ADDQ(link, &com->wake_me);
251 com->task = lua->task;
252 return 1;
253}
254
255/* This function purge all the pending signals when the LUA execution
256 * is finished. This prevent than a coprocess try to wake a deleted
257 * task. This function remove the memory associated to the signal.
258 */
259static void hlua_com_purge(struct hlua *lua)
260{
261 struct hlua_com *com, *back;
262
263 /* Delete all pending communication signals. */
264 list_for_each_entry_safe(com, back, &lua->com, purge_me) {
265 LIST_DEL(&com->purge_me);
266 LIST_DEL(&com->wake_me);
267 pool_free2(pool2_hlua_com, com);
268 }
269}
270
271/* This function sends signals. It wakes all the tasks attached
272 * to a list head, and remove the signal, and free the used
273 * memory.
274 */
275static void hlua_com_wake(struct list *wake)
276{
277 struct hlua_com *com, *back;
278
279 /* Wake task and delete all pending communication signals. */
280 list_for_each_entry_safe(com, back, wake, wake_me) {
281 LIST_DEL(&com->purge_me);
282 LIST_DEL(&com->wake_me);
283 task_wakeup(com->task, TASK_WOKEN_MSG);
284 pool_free2(pool2_hlua_com, com);
285 }
286}
287
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100288/* This functions is used with sample fetch and converters. It
289 * converts the HAProxy configuration argument in a lua stack
290 * values.
291 *
292 * It takes an array of "arg", and each entry of the array is
293 * converted and pushed in the LUA stack.
294 */
295static int hlua_arg2lua(lua_State *L, const struct arg *arg)
296{
297 switch (arg->type) {
298 case ARGT_SINT:
299 lua_pushinteger(L, arg->data.sint);
300 break;
301
302 case ARGT_UINT:
303 case ARGT_TIME:
304 case ARGT_SIZE:
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100305 lua_pushinteger(L, arg->data.sint);
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100306 break;
307
308 case ARGT_STR:
309 lua_pushlstring(L, arg->data.str.str, arg->data.str.len);
310 break;
311
312 case ARGT_IPV4:
313 case ARGT_IPV6:
314 case ARGT_MSK4:
315 case ARGT_MSK6:
316 case ARGT_FE:
317 case ARGT_BE:
318 case ARGT_TAB:
319 case ARGT_SRV:
320 case ARGT_USR:
321 case ARGT_MAP:
322 default:
323 lua_pushnil(L);
324 break;
325 }
326 return 1;
327}
328
329/* This function take one entrie in an LUA stack at the index "ud",
330 * and try to convert it in an HAProxy argument entry. This is useful
331 * with sample fetch wrappers. The input arguments are gived to the
332 * lua wrapper and converted as arg list by thi function.
333 */
334static int hlua_lua2arg(lua_State *L, int ud, struct arg *arg)
335{
336 switch (lua_type(L, ud)) {
337
338 case LUA_TNUMBER:
339 case LUA_TBOOLEAN:
340 arg->type = ARGT_SINT;
341 arg->data.sint = lua_tointeger(L, ud);
342 break;
343
344 case LUA_TSTRING:
345 arg->type = ARGT_STR;
346 arg->data.str.str = (char *)lua_tolstring(L, ud, (size_t *)&arg->data.str.len);
347 break;
348
349 case LUA_TUSERDATA:
350 case LUA_TNIL:
351 case LUA_TTABLE:
352 case LUA_TFUNCTION:
353 case LUA_TTHREAD:
354 case LUA_TLIGHTUSERDATA:
355 arg->type = ARGT_SINT;
356 arg->data.uint = 0;
357 break;
358 }
359 return 1;
360}
361
362/* the following functions are used to convert a struct sample
363 * in Lua type. This useful to convert the return of the
364 * fetchs or converters.
365 */
Willy Tarreau5eadada2015-03-10 17:28:54 +0100366static int hlua_smp2lua(lua_State *L, struct sample *smp)
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100367{
368 switch (smp->type) {
369 case SMP_T_SINT:
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100370 case SMP_T_BOOL:
371 case SMP_T_UINT:
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100372 lua_pushinteger(L, smp->data.sint);
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100373 break;
374
375 case SMP_T_BIN:
376 case SMP_T_STR:
377 lua_pushlstring(L, smp->data.str.str, smp->data.str.len);
378 break;
379
380 case SMP_T_METH:
381 switch (smp->data.meth.meth) {
382 case HTTP_METH_OPTIONS: lua_pushstring(L, "OPTIONS"); break;
383 case HTTP_METH_GET: lua_pushstring(L, "GET"); break;
384 case HTTP_METH_HEAD: lua_pushstring(L, "HEAD"); break;
385 case HTTP_METH_POST: lua_pushstring(L, "POST"); break;
386 case HTTP_METH_PUT: lua_pushstring(L, "PUT"); break;
387 case HTTP_METH_DELETE: lua_pushstring(L, "DELETE"); break;
388 case HTTP_METH_TRACE: lua_pushstring(L, "TRACE"); break;
389 case HTTP_METH_CONNECT: lua_pushstring(L, "CONNECT"); break;
390 case HTTP_METH_OTHER:
391 lua_pushlstring(L, smp->data.meth.str.str, smp->data.meth.str.len);
392 break;
393 default:
394 lua_pushnil(L);
395 break;
396 }
397 break;
398
399 case SMP_T_IPV4:
400 case SMP_T_IPV6:
401 case SMP_T_ADDR: /* This type is never used to qualify a sample. */
Willy Tarreau5eadada2015-03-10 17:28:54 +0100402 if (sample_casts[smp->type][SMP_T_STR] &&
403 sample_casts[smp->type][SMP_T_STR](smp))
404 lua_pushlstring(L, smp->data.str.str, smp->data.str.len);
405 else
406 lua_pushnil(L);
407 break;
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100408 default:
409 lua_pushnil(L);
410 break;
411 }
412 return 1;
413}
414
415/* the following functions are used to convert an Lua type in a
416 * struct sample. This is useful to provide data from a converter
417 * to the LUA code.
418 */
419static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp)
420{
421 switch (lua_type(L, ud)) {
422
423 case LUA_TNUMBER:
424 smp->type = SMP_T_SINT;
425 smp->data.sint = lua_tointeger(L, ud);
426 break;
427
428
429 case LUA_TBOOLEAN:
430 smp->type = SMP_T_BOOL;
431 smp->data.uint = lua_toboolean(L, ud);
432 break;
433
434 case LUA_TSTRING:
435 smp->type = SMP_T_STR;
436 smp->flags |= SMP_F_CONST;
437 smp->data.str.str = (char *)lua_tolstring(L, ud, (size_t *)&smp->data.str.len);
438 break;
439
440 case LUA_TUSERDATA:
441 case LUA_TNIL:
442 case LUA_TTABLE:
443 case LUA_TFUNCTION:
444 case LUA_TTHREAD:
445 case LUA_TLIGHTUSERDATA:
446 smp->type = SMP_T_BOOL;
447 smp->data.uint = 0;
448 break;
449 }
450 return 1;
451}
452
453/* This function check the "argp" builded by another conversion function
454 * is in accord with the expected argp defined by the "mask". The fucntion
455 * returns true or false. It can be adjust the types if there compatibles.
456 */
457__LJMP int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp, unsigned int mask)
458{
459 int min_arg;
460 int idx;
461
462 idx = 0;
463 min_arg = ARGM(mask);
464 mask >>= ARGM_BITS;
465
466 while (1) {
467
468 /* Check oversize. */
469 if (idx >= ARGM_NBARGS && argp[idx].type != ARGT_STOP) {
Cyril Bonté577a36a2015-03-02 00:08:38 +0100470 WILL_LJMP(luaL_argerror(L, first + idx, "Malformed argument mask"));
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100471 }
472
473 /* Check for mandatory arguments. */
474 if (argp[idx].type == ARGT_STOP) {
475 if (idx + 1 < min_arg)
476 WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
477 return 0;
478 }
479
480 /* Check for exceed the number of requiered argument. */
481 if ((mask & ARGT_MASK) == ARGT_STOP &&
482 argp[idx].type != ARGT_STOP) {
483 WILL_LJMP(luaL_argerror(L, first + idx, "Last argument expected"));
484 }
485
486 if ((mask & ARGT_MASK) == ARGT_STOP &&
487 argp[idx].type == ARGT_STOP) {
488 return 0;
489 }
490
491 /* Compatibility mask. */
492 switch (argp[idx].type) {
493 case ARGT_SINT:
494 switch (mask & ARGT_MASK) {
495 case ARGT_UINT: argp[idx].type = mask & ARGT_MASK; break;
496 case ARGT_TIME: argp[idx].type = mask & ARGT_MASK; break;
497 case ARGT_SIZE: argp[idx].type = mask & ARGT_MASK; break;
498 }
499 break;
500 }
501
502 /* Check for type of argument. */
503 if ((mask & ARGT_MASK) != argp[idx].type) {
504 const char *msg = lua_pushfstring(L, "'%s' expected, got '%s'",
505 arg_type_names[(mask & ARGT_MASK)],
506 arg_type_names[argp[idx].type & ARGT_MASK]);
507 WILL_LJMP(luaL_argerror(L, first + idx, msg));
508 }
509
510 /* Next argument. */
511 mask >>= ARGT_BITS;
512 idx++;
513 }
514}
515
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100516/*
517 * The following functions are used to make correspondance between the the
518 * executed lua pointer and the "struct hlua *" that contain the context.
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100519 *
520 * - hlua_gethlua : return the hlua context associated with an lua_State.
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100521 * - hlua_sethlua : create the association between hlua context and lua_state.
522 */
523static inline struct hlua *hlua_gethlua(lua_State *L)
524{
Thierry FOURNIER38c5fd62015-03-10 02:40:29 +0100525 struct hlua **hlua = lua_getextraspace(L);
526 return *hlua;
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100527}
528static inline void hlua_sethlua(struct hlua *hlua)
529{
Thierry FOURNIER38c5fd62015-03-10 02:40:29 +0100530 struct hlua **hlua_store = lua_getextraspace(hlua->T);
531 *hlua_store = hlua;
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100532}
533
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100534/* This function just ensure that the yield will be always
535 * returned with a timeout and permit to set some flags
536 */
537__LJMP void hlua_yieldk(lua_State *L, int nresults, int ctx,
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100538 lua_KFunction k, int timeout, unsigned int flags)
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100539{
540 struct hlua *hlua = hlua_gethlua(L);
541
542 /* Set the wake timeout. If timeout is required, we set
543 * the expiration time.
544 */
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100545 hlua->wake_time = tick_first(timeout, hlua->expire);
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100546
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +0100547 hlua->flags |= flags;
548
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100549 /* Process the yield. */
550 WILL_LJMP(lua_yieldk(L, nresults, ctx, k));
551}
552
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100553/* This function initialises the Lua environment stored in the session.
554 * It must be called at the start of the session. This function creates
555 * an LUA coroutine. It can not be use to crete the main LUA context.
556 */
557int hlua_ctx_init(struct hlua *lua, struct task *task)
558{
559 lua->Mref = LUA_REFNIL;
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +0100560 lua->flags = 0;
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100561 LIST_INIT(&lua->com);
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100562 lua->T = lua_newthread(gL.T);
563 if (!lua->T) {
564 lua->Tref = LUA_REFNIL;
565 return 0;
566 }
567 hlua_sethlua(lua);
568 lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
569 lua->task = task;
570 return 1;
571}
572
573/* Used to destroy the Lua coroutine when the attached session or task
574 * is destroyed. The destroy also the memory context. The struct "lua"
575 * is not freed.
576 */
577void hlua_ctx_destroy(struct hlua *lua)
578{
Thierry FOURNIERa718b292015-03-04 16:48:34 +0100579 if (!lua->T)
580 return;
581
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100582 /* Purge all the pending signals. */
583 hlua_com_purge(lua);
584
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100585 /* The thread is garbage collected by Lua. */
586 luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
587 luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
588}
589
590/* This function is used to restore the Lua context when a coroutine
591 * fails. This function copy the common memory between old coroutine
592 * and the new coroutine. The old coroutine is destroyed, and its
593 * replaced by the new coroutine.
594 * If the flag "keep_msg" is set, the last entry of the old is assumed
595 * as string error message and it is copied in the new stack.
596 */
597static int hlua_ctx_renew(struct hlua *lua, int keep_msg)
598{
599 lua_State *T;
600 int new_ref;
601
602 /* Renew the main LUA stack doesn't have sense. */
603 if (lua == &gL)
604 return 0;
605
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100606 /* New Lua coroutine. */
607 T = lua_newthread(gL.T);
608 if (!T)
609 return 0;
610
611 /* Copy last error message. */
612 if (keep_msg)
613 lua_xmove(lua->T, T, 1);
614
615 /* Copy data between the coroutines. */
616 lua_rawgeti(lua->T, LUA_REGISTRYINDEX, lua->Mref);
617 lua_xmove(lua->T, T, 1);
618 new_ref = luaL_ref(T, LUA_REGISTRYINDEX); /* Valur poped. */
619
620 /* Destroy old data. */
621 luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
622
623 /* The thread is garbage collected by Lua. */
624 luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
625
626 /* Fill the struct with the new coroutine values. */
627 lua->Mref = new_ref;
628 lua->T = T;
629 lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
630
631 /* Set context. */
632 hlua_sethlua(lua);
633
634 return 1;
635}
636
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100637void hlua_hook(lua_State *L, lua_Debug *ar)
638{
Thierry FOURNIERcae49c92015-03-06 14:05:24 +0100639 struct hlua *hlua = hlua_gethlua(L);
640
641 /* Lua cannot yield when its returning from a function,
642 * so, we can fix the interrupt hook to 1 instruction,
643 * expecting that the function is finnished.
644 */
645 if (lua_gethookmask(L) & LUA_MASKRET) {
646 lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, 1);
647 return;
648 }
649
650 /* restore the interrupt condition. */
651 lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, hlua_nb_instruction);
652
653 /* If we interrupt the Lua processing in yieldable state, we yield.
654 * If the state is not yieldable, trying yield causes an error.
655 */
656 if (lua_isyieldable(L))
657 WILL_LJMP(hlua_yieldk(L, 0, 0, NULL, TICK_ETERNITY, HLUA_CTRLYIELD));
658
659 /* If we cannot yield, check the timeout. */
660 if (tick_is_expired(hlua->expire, now_ms)) {
661 lua_pushfstring(L, "execution timeout");
662 WILL_LJMP(lua_error(L));
663 }
664
665 /* Try to interrupt the process at the end of the current
666 * unyieldable function.
667 */
668 lua_sethook(hlua->T, hlua_hook, LUA_MASKRET|LUA_MASKCOUNT, hlua_nb_instruction);
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100669}
670
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100671/* This function start or resumes the Lua stack execution. If the flag
672 * "yield_allowed" if no set and the LUA stack execution returns a yield
673 * The function return an error.
674 *
675 * The function can returns 4 values:
676 * - HLUA_E_OK : The execution is terminated without any errors.
677 * - HLUA_E_AGAIN : The execution must continue at the next associated
678 * task wakeup.
679 * - HLUA_E_ERRMSG : An error has occured, an error message is set in
680 * the top of the stack.
681 * - HLUA_E_ERR : An error has occured without error message.
682 *
683 * If an error occured, the stack is renewed and it is ready to run new
684 * LUA code.
685 */
686static enum hlua_exec hlua_ctx_resume(struct hlua *lua, int yield_allowed)
687{
688 int ret;
689 const char *msg;
690
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +0100691 HLUA_SET_RUN(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100692
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100693 /* If we want to resume the task, then check first the execution timeout.
694 * if it is reached, we can interrupt the Lua processing.
695 */
696 if (tick_is_expired(lua->expire, now_ms))
697 goto timeout_reached;
698
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100699resume_execution:
700
701 /* This hook interrupts the Lua processing each 'hlua_nb_instruction'
702 * instructions. it is used for preventing infinite loops.
703 */
704 lua_sethook(lua->T, hlua_hook, LUA_MASKCOUNT, hlua_nb_instruction);
705
Thierry FOURNIER1bfc09b2015-03-05 17:10:14 +0100706 /* Remove all flags except the running flags. */
707 lua->flags = HLUA_RUN;
708
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100709 /* Call the function. */
710 ret = lua_resume(lua->T, gL.T, lua->nargs);
711 switch (ret) {
712
713 case LUA_OK:
714 ret = HLUA_E_OK;
715 break;
716
717 case LUA_YIELD:
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100718 /* Check if the execution timeout is expired. It it is the case, we
719 * break the Lua execution.
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100720 */
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100721 if (tick_is_expired(lua->expire, now_ms)) {
722
723timeout_reached:
724
725 lua_settop(lua->T, 0); /* Empty the stack. */
726 if (!lua_checkstack(lua->T, 1)) {
727 ret = HLUA_E_ERR;
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100728 break;
729 }
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100730 lua_pushfstring(lua->T, "execution timeout");
731 ret = HLUA_E_ERRMSG;
732 break;
733 }
734 /* Process the forced yield. if the general yield is not allowed or
735 * if no task were associated this the current Lua execution
736 * coroutine, we resume the execution. Else we want to return in the
737 * scheduler and we want to be waked up again, to continue the
738 * current Lua execution. So we schedule our own task.
739 */
740 if (HLUA_IS_CTRLYIELDING(lua)) {
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100741 if (!yield_allowed || !lua->task)
742 goto resume_execution;
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100743 task_wakeup(lua->task, TASK_WOKEN_MSG);
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100744 }
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100745 if (!yield_allowed) {
746 lua_settop(lua->T, 0); /* Empty the stack. */
747 if (!lua_checkstack(lua->T, 1)) {
748 ret = HLUA_E_ERR;
749 break;
750 }
751 lua_pushfstring(lua->T, "yield not allowed");
752 ret = HLUA_E_ERRMSG;
753 break;
754 }
755 ret = HLUA_E_AGAIN;
756 break;
757
758 case LUA_ERRRUN:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100759 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100760 if (!lua_checkstack(lua->T, 1)) {
761 ret = HLUA_E_ERR;
762 break;
763 }
764 msg = lua_tostring(lua->T, -1);
765 lua_settop(lua->T, 0); /* Empty the stack. */
766 lua_pop(lua->T, 1);
767 if (msg)
768 lua_pushfstring(lua->T, "runtime error: %s", msg);
769 else
770 lua_pushfstring(lua->T, "unknown runtime error");
771 ret = HLUA_E_ERRMSG;
772 break;
773
774 case LUA_ERRMEM:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100775 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100776 lua_settop(lua->T, 0); /* Empty the stack. */
777 if (!lua_checkstack(lua->T, 1)) {
778 ret = HLUA_E_ERR;
779 break;
780 }
781 lua_pushfstring(lua->T, "out of memory error");
782 ret = HLUA_E_ERRMSG;
783 break;
784
785 case LUA_ERRERR:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100786 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100787 if (!lua_checkstack(lua->T, 1)) {
788 ret = HLUA_E_ERR;
789 break;
790 }
791 msg = lua_tostring(lua->T, -1);
792 lua_settop(lua->T, 0); /* Empty the stack. */
793 lua_pop(lua->T, 1);
794 if (msg)
795 lua_pushfstring(lua->T, "message handler error: %s", msg);
796 else
797 lua_pushfstring(lua->T, "message handler error");
798 ret = HLUA_E_ERRMSG;
799 break;
800
801 default:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100802 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100803 lua_settop(lua->T, 0); /* Empty the stack. */
804 if (!lua_checkstack(lua->T, 1)) {
805 ret = HLUA_E_ERR;
806 break;
807 }
808 lua_pushfstring(lua->T, "unknonwn error");
809 ret = HLUA_E_ERRMSG;
810 break;
811 }
812
813 switch (ret) {
814 case HLUA_E_AGAIN:
815 break;
816
817 case HLUA_E_ERRMSG:
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100818 hlua_com_purge(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100819 hlua_ctx_renew(lua, 1);
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +0100820 HLUA_CLR_RUN(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100821 break;
822
823 case HLUA_E_ERR:
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +0100824 HLUA_CLR_RUN(lua);
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100825 hlua_com_purge(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100826 hlua_ctx_renew(lua, 0);
827 break;
828
829 case HLUA_E_OK:
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +0100830 HLUA_CLR_RUN(lua);
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100831 hlua_com_purge(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100832 break;
833 }
834
835 return ret;
836}
837
Thierry FOURNIER83758bb2015-02-04 13:21:04 +0100838/* This function is an LUA binding. It provides a function
839 * for deleting ACL from a referenced ACL file.
840 */
841__LJMP static int hlua_del_acl(lua_State *L)
842{
843 const char *name;
844 const char *key;
845 struct pat_ref *ref;
846
847 MAY_LJMP(check_args(L, 2, "del_acl"));
848
849 name = MAY_LJMP(luaL_checkstring(L, 1));
850 key = MAY_LJMP(luaL_checkstring(L, 2));
851
852 ref = pat_ref_lookup(name);
853 if (!ref)
854 WILL_LJMP(luaL_error(L, "'del_acl': unkown acl file '%s'", name));
855
856 pat_ref_delete(ref, key);
857 return 0;
858}
859
860/* This function is an LUA binding. It provides a function
861 * for deleting map entry from a referenced map file.
862 */
863static int hlua_del_map(lua_State *L)
864{
865 const char *name;
866 const char *key;
867 struct pat_ref *ref;
868
869 MAY_LJMP(check_args(L, 2, "del_map"));
870
871 name = MAY_LJMP(luaL_checkstring(L, 1));
872 key = MAY_LJMP(luaL_checkstring(L, 2));
873
874 ref = pat_ref_lookup(name);
875 if (!ref)
876 WILL_LJMP(luaL_error(L, "'del_map': unkown acl file '%s'", name));
877
878 pat_ref_delete(ref, key);
879 return 0;
880}
881
882/* This function is an LUA binding. It provides a function
883 * for adding ACL pattern from a referenced ACL file.
884 */
885static int hlua_add_acl(lua_State *L)
886{
887 const char *name;
888 const char *key;
889 struct pat_ref *ref;
890
891 MAY_LJMP(check_args(L, 2, "add_acl"));
892
893 name = MAY_LJMP(luaL_checkstring(L, 1));
894 key = MAY_LJMP(luaL_checkstring(L, 2));
895
896 ref = pat_ref_lookup(name);
897 if (!ref)
898 WILL_LJMP(luaL_error(L, "'add_acl': unkown acl file '%s'", name));
899
900 if (pat_ref_find_elt(ref, key) == NULL)
901 pat_ref_add(ref, key, NULL, NULL);
902 return 0;
903}
904
905/* This function is an LUA binding. It provides a function
906 * for setting map pattern and sample from a referenced map
907 * file.
908 */
909static int hlua_set_map(lua_State *L)
910{
911 const char *name;
912 const char *key;
913 const char *value;
914 struct pat_ref *ref;
915
916 MAY_LJMP(check_args(L, 3, "set_map"));
917
918 name = MAY_LJMP(luaL_checkstring(L, 1));
919 key = MAY_LJMP(luaL_checkstring(L, 2));
920 value = MAY_LJMP(luaL_checkstring(L, 3));
921
922 ref = pat_ref_lookup(name);
923 if (!ref)
924 WILL_LJMP(luaL_error(L, "'set_map': unkown map file '%s'", name));
925
926 if (pat_ref_find_elt(ref, key) != NULL)
927 pat_ref_set(ref, key, value, NULL);
928 else
929 pat_ref_add(ref, key, value, NULL);
930 return 0;
931}
932
Thierry FOURNIER65f34c62015-02-16 20:11:43 +0100933/* A class is a lot of memory that contain data. This data can be a table,
934 * an integer or user data. This data is associated with a metatable. This
935 * metatable have an original version registred in the global context with
936 * the name of the object (_G[<name>] = <metable> ).
937 *
938 * A metable is a table that modify the standard behavior of a standard
939 * access to the associated data. The entries of this new metatable are
940 * defined as is:
941 *
942 * http://lua-users.org/wiki/MetatableEvents
943 *
944 * __index
945 *
946 * we access an absent field in a table, the result is nil. This is
947 * true, but it is not the whole truth. Actually, such access triggers
948 * the interpreter to look for an __index metamethod: If there is no
949 * such method, as usually happens, then the access results in nil;
950 * otherwise, the metamethod will provide the result.
951 *
952 * Control 'prototype' inheritance. When accessing "myTable[key]" and
953 * the key does not appear in the table, but the metatable has an __index
954 * property:
955 *
956 * - if the value is a function, the function is called, passing in the
957 * table and the key; the return value of that function is returned as
958 * the result.
959 *
960 * - if the value is another table, the value of the key in that table is
961 * asked for and returned (and if it doesn't exist in that table, but that
962 * table's metatable has an __index property, then it continues on up)
963 *
964 * - Use "rawget(myTable,key)" to skip this metamethod.
965 *
966 * http://www.lua.org/pil/13.4.1.html
967 *
968 * __newindex
969 *
970 * Like __index, but control property assignment.
971 *
972 * __mode - Control weak references. A string value with one or both
973 * of the characters 'k' and 'v' which specifies that the the
974 * keys and/or values in the table are weak references.
975 *
976 * __call - Treat a table like a function. When a table is followed by
977 * parenthesis such as "myTable( 'foo' )" and the metatable has
978 * a __call key pointing to a function, that function is invoked
979 * (passing any specified arguments) and the return value is
980 * returned.
981 *
982 * __metatable - Hide the metatable. When "getmetatable( myTable )" is
983 * called, if the metatable for myTable has a __metatable
984 * key, the value of that key is returned instead of the
985 * actual metatable.
986 *
987 * __tostring - Control string representation. When the builtin
988 * "tostring( myTable )" function is called, if the metatable
989 * for myTable has a __tostring property set to a function,
990 * that function is invoked (passing myTable to it) and the
991 * return value is used as the string representation.
992 *
993 * __len - Control table length. When the table length is requested using
994 * the length operator ( '#' ), if the metatable for myTable has
995 * a __len key pointing to a function, that function is invoked
996 * (passing myTable to it) and the return value used as the value
997 * of "#myTable".
998 *
999 * __gc - Userdata finalizer code. When userdata is set to be garbage
1000 * collected, if the metatable has a __gc field pointing to a
1001 * function, that function is first invoked, passing the userdata
1002 * to it. The __gc metamethod is not called for tables.
1003 * (See http://lua-users.org/lists/lua-l/2006-11/msg00508.html)
1004 *
1005 * Special metamethods for redefining standard operators:
1006 * http://www.lua.org/pil/13.1.html
1007 *
1008 * __add "+"
1009 * __sub "-"
1010 * __mul "*"
1011 * __div "/"
1012 * __unm "!"
1013 * __pow "^"
1014 * __concat ".."
1015 *
1016 * Special methods for redfining standar relations
1017 * http://www.lua.org/pil/13.2.html
1018 *
1019 * __eq "=="
1020 * __lt "<"
1021 * __le "<="
1022 */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001023
1024/*
1025 *
1026 *
1027 * Class Socket
1028 *
1029 *
1030 */
1031
1032__LJMP static struct hlua_socket *hlua_checksocket(lua_State *L, int ud)
1033{
1034 return (struct hlua_socket *)MAY_LJMP(hlua_checkudata(L, ud, class_socket_ref));
1035}
1036
1037/* This function is the handler called for each I/O on the established
1038 * connection. It is used for notify space avalaible to send or data
1039 * received.
1040 */
1041static void hlua_socket_handler(struct stream_interface *si)
1042{
1043 struct appctx *appctx = objt_appctx(si->end);
1044 struct connection *c = objt_conn(si->ib->cons->end);
1045
1046 /* Wakeup the main session if the client connection is closed. */
1047 if (!c || channel_output_closed(si->ib) || channel_input_closed(si->ob)) {
1048 if (appctx->ctx.hlua.socket) {
1049 appctx->ctx.hlua.socket->s = NULL;
1050 appctx->ctx.hlua.socket = NULL;
1051 }
1052 si_shutw(si);
1053 si_shutr(si);
1054 si->ib->flags |= CF_READ_NULL;
1055 hlua_com_wake(&appctx->ctx.hlua.wake_on_read);
1056 hlua_com_wake(&appctx->ctx.hlua.wake_on_write);
1057 return;
1058 }
1059
1060 if (!(c->flags & CO_FL_CONNECTED))
1061 return;
1062
1063 /* This function is called after the connect. */
1064 appctx->ctx.hlua.connected = 1;
1065
1066 /* Wake the tasks which wants to write if the buffer have avalaible space. */
1067 if (channel_may_recv(si->ob))
1068 hlua_com_wake(&appctx->ctx.hlua.wake_on_write);
1069
1070 /* Wake the tasks which wants to read if the buffer contains data. */
1071 if (channel_is_empty(si->ib))
1072 hlua_com_wake(&appctx->ctx.hlua.wake_on_read);
1073}
1074
1075/* This function is called when the "struct session" is destroyed.
1076 * Remove the link from the object to this session.
1077 * Wake all the pending signals.
1078 */
1079static void hlua_socket_release(struct stream_interface *si)
1080{
1081 struct appctx *appctx = objt_appctx(si->end);
1082
1083 /* Remove my link in the original object. */
1084 if (appctx->ctx.hlua.socket)
1085 appctx->ctx.hlua.socket->s = NULL;
1086
1087 /* Wake all the task waiting for me. */
1088 hlua_com_wake(&appctx->ctx.hlua.wake_on_read);
1089 hlua_com_wake(&appctx->ctx.hlua.wake_on_write);
1090}
1091
1092/* If the garbage collectio of the object is launch, nobody
1093 * uses this object. If the session does not exists, just quit.
1094 * Send the shutdown signal to the session. In some cases,
1095 * pending signal can rest in the read and write lists. destroy
1096 * it.
1097 */
1098__LJMP static int hlua_socket_gc(lua_State *L)
1099{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001100 struct hlua_socket *socket;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001101 struct appctx *appctx;
1102
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001103 MAY_LJMP(check_args(L, 1, "__gc"));
1104
1105 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001106 if (!socket->s)
1107 return 0;
1108
1109 /* Remove all reference between the Lua stack and the coroutine session. */
1110 appctx = objt_appctx(socket->s->si[0].end);
1111 session_shutdown(socket->s, SN_ERR_KILLED);
1112 socket->s = NULL;
1113 appctx->ctx.hlua.socket = NULL;
1114
1115 return 0;
1116}
1117
1118/* The close function send shutdown signal and break the
1119 * links between the session and the object.
1120 */
1121__LJMP static int hlua_socket_close(lua_State *L)
1122{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001123 struct hlua_socket *socket;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001124 struct appctx *appctx;
1125
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001126 MAY_LJMP(check_args(L, 1, "close"));
1127
1128 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001129 if (!socket->s)
1130 return 0;
1131
1132 /* Close the session and remove the associated stop task. */
1133 session_shutdown(socket->s, SN_ERR_KILLED);
1134 appctx = objt_appctx(socket->s->si[0].end);
1135 appctx->ctx.hlua.socket = NULL;
1136 socket->s = NULL;
1137
1138 return 0;
1139}
1140
1141/* This Lua function assumes that the stack contain three parameters.
1142 * 1 - USERDATA containing a struct socket
1143 * 2 - INTEGER with values of the macro defined below
1144 * If the integer is -1, we must read at most one line.
1145 * If the integer is -2, we ust read all the data until the
1146 * end of the stream.
1147 * If the integer is positive value, we must read a number of
1148 * bytes corresponding to this value.
1149 */
1150#define HLSR_READ_LINE (-1)
1151#define HLSR_READ_ALL (-2)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001152__LJMP static int hlua_socket_receive_yield(struct lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001153{
1154 struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1));
1155 int wanted = lua_tointeger(L, 2);
1156 struct hlua *hlua = hlua_gethlua(L);
1157 struct appctx *appctx;
1158 int len;
1159 int nblk;
1160 char *blk1;
1161 int len1;
1162 char *blk2;
1163 int len2;
Thierry FOURNIER00543922015-03-09 18:35:06 +01001164 int skip_at_end = 0;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001165
1166 /* Check if this lua stack is schedulable. */
1167 if (!hlua || !hlua->task)
1168 WILL_LJMP(luaL_error(L, "The 'receive' function is only allowed in "
1169 "'frontend', 'backend' or 'task'"));
1170
1171 /* check for connection closed. If some data where read, return it. */
1172 if (!socket->s)
1173 goto connection_closed;
1174
1175 if (wanted == HLSR_READ_LINE) {
1176
1177 /* Read line. */
1178 nblk = bo_getline_nc(socket->s->si[0].ob, &blk1, &len1, &blk2, &len2);
1179 if (nblk < 0) /* Connection close. */
1180 goto connection_closed;
1181 if (nblk == 0) /* No data avalaible. */
1182 goto connection_empty;
Thierry FOURNIER00543922015-03-09 18:35:06 +01001183
1184 /* remove final \r\n. */
1185 if (nblk == 1) {
1186 if (blk1[len1-1] == '\n') {
1187 len1--;
1188 skip_at_end++;
1189 if (blk1[len1-1] == '\r') {
1190 len1--;
1191 skip_at_end++;
1192 }
1193 }
1194 }
1195 else {
1196 if (blk2[len2-1] == '\n') {
1197 len2--;
1198 skip_at_end++;
1199 if (blk2[len2-1] == '\r') {
1200 len2--;
1201 skip_at_end++;
1202 }
1203 }
1204 }
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001205 }
1206
1207 else if (wanted == HLSR_READ_ALL) {
1208
1209 /* Read all the available data. */
1210 nblk = bo_getblk_nc(socket->s->si[0].ob, &blk1, &len1, &blk2, &len2);
1211 if (nblk < 0) /* Connection close. */
1212 goto connection_closed;
1213 if (nblk == 0) /* No data avalaible. */
1214 goto connection_empty;
1215 }
1216
1217 else {
1218
1219 /* Read a block of data. */
1220 nblk = bo_getblk_nc(socket->s->si[0].ob, &blk1, &len1, &blk2, &len2);
1221 if (nblk < 0) /* Connection close. */
1222 goto connection_closed;
1223 if (nblk == 0) /* No data avalaible. */
1224 goto connection_empty;
1225
1226 if (len1 > wanted) {
1227 nblk = 1;
1228 len1 = wanted;
1229 } if (nblk == 2 && len1 + len2 > wanted)
1230 len2 = wanted - len1;
1231 }
1232
1233 len = len1;
1234
1235 luaL_addlstring(&socket->b, blk1, len1);
1236 if (nblk == 2) {
1237 len += len2;
1238 luaL_addlstring(&socket->b, blk2, len2);
1239 }
1240
1241 /* Consume data. */
Thierry FOURNIER00543922015-03-09 18:35:06 +01001242 bo_skip(socket->s->si[0].ob, len + skip_at_end);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001243
1244 /* Don't wait anything. */
1245 si_update(&socket->s->si[0]);
1246
1247 /* If the pattern reclaim to read all the data
1248 * in the connection, got out.
1249 */
1250 if (wanted == HLSR_READ_ALL)
1251 goto connection_empty;
1252 else if (wanted >= 0 && len < wanted)
1253 goto connection_empty;
1254
1255 /* Return result. */
1256 luaL_pushresult(&socket->b);
1257 return 1;
1258
1259connection_closed:
1260
1261 /* If the buffer containds data. */
1262 if (socket->b.n > 0) {
1263 luaL_pushresult(&socket->b);
1264 return 1;
1265 }
1266 lua_pushnil(L);
1267 lua_pushstring(L, "connection closed.");
1268 return 2;
1269
1270connection_empty:
1271
1272 appctx = objt_appctx(socket->s->si[0].end);
1273 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_read))
1274 WILL_LJMP(luaL_error(L, "out of memory"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01001275 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_receive_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001276 return 0;
1277}
1278
1279/* This Lus function gets two parameters. The first one can be string
1280 * or a number. If the string is "*l", the user require one line. If
1281 * the string is "*a", the user require all the content of the stream.
1282 * If the value is a number, the user require a number of bytes equal
1283 * to the value. The default value is "*l" (a line).
1284 *
1285 * This paraeter with a variable type is converted in integer. This
1286 * integer takes this values:
1287 * -1 : read a line
1288 * -2 : read all the stream
1289 * >0 : amount if bytes.
1290 *
1291 * The second parameter is optinal. It contains a string that must be
1292 * concatenated with the read data.
1293 */
1294__LJMP static int hlua_socket_receive(struct lua_State *L)
1295{
1296 int wanted = HLSR_READ_LINE;
1297 const char *pattern;
1298 int type;
1299 char *error;
1300 size_t len;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001301 struct hlua_socket *socket;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001302
1303 if (lua_gettop(L) < 1 || lua_gettop(L) > 3)
1304 WILL_LJMP(luaL_error(L, "The 'receive' function requires between 1 and 3 arguments."));
1305
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001306 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001307
1308 /* check for pattern. */
1309 if (lua_gettop(L) >= 2) {
1310 type = lua_type(L, 2);
1311 if (type == LUA_TSTRING) {
1312 pattern = lua_tostring(L, 2);
1313 if (strcmp(pattern, "*a") == 0)
1314 wanted = HLSR_READ_ALL;
1315 else if (strcmp(pattern, "*l") == 0)
1316 wanted = HLSR_READ_LINE;
1317 else {
1318 wanted = strtoll(pattern, &error, 10);
1319 if (*error != '\0')
1320 WILL_LJMP(luaL_error(L, "Unsupported pattern."));
1321 }
1322 }
1323 else if (type == LUA_TNUMBER) {
1324 wanted = lua_tointeger(L, 2);
1325 if (wanted < 0)
1326 WILL_LJMP(luaL_error(L, "Unsupported size."));
1327 }
1328 }
1329
1330 /* Set pattern. */
1331 lua_pushinteger(L, wanted);
1332 lua_replace(L, 2);
1333
1334 /* init bufffer, and fiil it wih prefix. */
1335 luaL_buffinit(L, &socket->b);
1336
1337 /* Check prefix. */
1338 if (lua_gettop(L) >= 3) {
1339 if (lua_type(L, 3) != LUA_TSTRING)
1340 WILL_LJMP(luaL_error(L, "Expect a 'string' for the prefix"));
1341 pattern = lua_tolstring(L, 3, &len);
1342 luaL_addlstring(&socket->b, pattern, len);
1343 }
1344
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001345 return __LJMP(hlua_socket_receive_yield(L, 0, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001346}
1347
1348/* Write the Lua input string in the output buffer.
1349 * This fucntion returns a yield if no space are available.
1350 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001351static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext ctx)
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001352{
1353 struct hlua_socket *socket;
1354 struct hlua *hlua = hlua_gethlua(L);
1355 struct appctx *appctx;
1356 size_t buf_len;
1357 const char *buf;
1358 int len;
1359 int send_len;
1360 int sent;
1361
1362 /* Check if this lua stack is schedulable. */
1363 if (!hlua || !hlua->task)
1364 WILL_LJMP(luaL_error(L, "The 'write' function is only allowed in "
1365 "'frontend', 'backend' or 'task'"));
1366
1367 /* Get object */
1368 socket = MAY_LJMP(hlua_checksocket(L, 1));
1369 buf = MAY_LJMP(luaL_checklstring(L, 2, &buf_len));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001370 sent = MAY_LJMP(luaL_checkinteger(L, 3));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001371
1372 /* Check for connection close. */
1373 if (!socket->s || channel_output_closed(socket->s->req)) {
1374 lua_pushinteger(L, -1);
1375 return 1;
1376 }
1377
1378 /* Update the input buffer data. */
1379 buf += sent;
1380 send_len = buf_len - sent;
1381
1382 /* All the data are sent. */
1383 if (sent >= buf_len)
1384 return 1; /* Implicitly return the length sent. */
1385
Thierry FOURNIER486d52a2015-03-09 17:51:43 +01001386 /* Check if the buffer is avalaible because HAProxy doesn't allocate
1387 * the request buffer if its not required.
1388 */
1389 if (socket->s->req->buf->size == 0) {
1390 if (!session_alloc_recv_buffer(socket->s, &socket->s->req->buf)) {
1391 socket->s->req->prod->flags |= SI_FL_WAIT_ROOM;
1392 goto hlua_socket_write_yield_return;
1393 }
1394 }
1395
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001396 /* Check for avalaible space. */
1397 len = buffer_total_space(socket->s->si[0].ib->buf);
1398 if (len <= 0)
1399 goto hlua_socket_write_yield_return;
1400
1401 /* send data */
1402 if (len < send_len)
1403 send_len = len;
1404 len = bi_putblk(socket->s->si[0].ib, buf+sent, send_len);
1405
1406 /* "Not enough space" (-1), "Buffer too little to contain
1407 * the data" (-2) are not expected because the available length
1408 * is tested.
1409 * Other unknown error are also not expected.
1410 */
1411 if (len <= 0) {
1412 MAY_LJMP(hlua_socket_close(L));
1413 lua_pop(L, 1);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001414 lua_pushinteger(L, -1);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001415 return 1;
1416 }
1417
1418 /* update buffers. */
1419 si_update(&socket->s->si[0]);
1420 socket->s->si[0].ib->rex = TICK_ETERNITY;
1421 socket->s->si[0].ob->wex = TICK_ETERNITY;
1422
1423 /* Update length sent. */
1424 lua_pop(L, 1);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001425 lua_pushinteger(L, sent + len);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001426
1427 /* All the data buffer is sent ? */
1428 if (sent + len >= buf_len)
1429 return 1;
1430
1431hlua_socket_write_yield_return:
1432 appctx = objt_appctx(socket->s->si[0].end);
1433 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_write))
1434 WILL_LJMP(luaL_error(L, "out of memory"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01001435 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_write_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001436 return 0;
1437}
1438
1439/* This function initiate the send of data. It just check the input
1440 * parameters and push an integer in the Lua stack that contain the
1441 * amount of data writed in the buffer. This is used by the function
1442 * "hlua_socket_write_yield" that can yield.
1443 *
1444 * The Lua function gets between 3 and 4 parameters. The first one is
1445 * the associated object. The second is a string buffer. The third is
1446 * a facultative integer that represents where is the buffer position
1447 * of the start of the data that can send. The first byte is the
1448 * position "1". The default value is "1". The fourth argument is a
1449 * facultative integer that represents where is the buffer position
1450 * of the end of the data that can send. The default is the last byte.
1451 */
1452static int hlua_socket_send(struct lua_State *L)
1453{
1454 int i;
1455 int j;
1456 const char *buf;
1457 size_t buf_len;
1458
1459 /* Check number of arguments. */
1460 if (lua_gettop(L) < 2 || lua_gettop(L) > 4)
1461 WILL_LJMP(luaL_error(L, "'send' needs between 2 and 4 arguments"));
1462
1463 /* Get the string. */
1464 buf = MAY_LJMP(luaL_checklstring(L, 2, &buf_len));
1465
1466 /* Get and check j. */
1467 if (lua_gettop(L) == 4) {
1468 j = MAY_LJMP(luaL_checkinteger(L, 4));
1469 if (j < 0)
1470 j = buf_len + j + 1;
1471 if (j > buf_len)
1472 j = buf_len + 1;
1473 lua_pop(L, 1);
1474 }
1475 else
1476 j = buf_len;
1477
1478 /* Get and check i. */
1479 if (lua_gettop(L) == 3) {
1480 i = MAY_LJMP(luaL_checkinteger(L, 3));
1481 if (i < 0)
1482 i = buf_len + i + 1;
1483 if (i > buf_len)
1484 i = buf_len + 1;
1485 lua_pop(L, 1);
1486 } else
1487 i = 1;
1488
1489 /* Check bth i and j. */
1490 if (i > j) {
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001491 lua_pushinteger(L, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001492 return 1;
1493 }
1494 if (i == 0 && j == 0) {
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001495 lua_pushinteger(L, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001496 return 1;
1497 }
1498 if (i == 0)
1499 i = 1;
1500 if (j == 0)
1501 j = 1;
1502
1503 /* Pop the string. */
1504 lua_pop(L, 1);
1505
1506 /* Update the buffer length. */
1507 buf += i - 1;
1508 buf_len = j - i + 1;
1509 lua_pushlstring(L, buf, buf_len);
1510
1511 /* This unsigned is used to remember the amount of sent data. */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001512 lua_pushinteger(L, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001513
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001514 return MAY_LJMP(hlua_socket_write_yield(L, 0, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001515}
1516
1517#define SOCKET_INFO_EXPANDED_FORM "[0000:0000:0000:0000:0000:0000:0000:0000]:12345"
1518static char _socket_info_expanded_form[] = SOCKET_INFO_EXPANDED_FORM;
1519#define SOCKET_INFO_MAX_LEN (sizeof(_socket_info_expanded_form))
1520__LJMP static inline int hlua_socket_info(struct lua_State *L, struct sockaddr_storage *addr)
1521{
1522 static char buffer[SOCKET_INFO_MAX_LEN];
1523 int ret;
1524 int len;
1525 char *p;
1526
1527 ret = addr_to_str(addr, buffer+1, SOCKET_INFO_MAX_LEN-1);
1528 if (ret <= 0) {
1529 lua_pushnil(L);
1530 return 1;
1531 }
1532
1533 if (ret == AF_UNIX) {
1534 lua_pushstring(L, buffer+1);
1535 return 1;
1536 }
1537 else if (ret == AF_INET6) {
1538 buffer[0] = '[';
1539 len = strlen(buffer);
1540 buffer[len] = ']';
1541 len++;
1542 buffer[len] = ':';
1543 len++;
1544 p = buffer;
1545 }
1546 else if (ret == AF_INET) {
1547 p = buffer + 1;
1548 len = strlen(p);
1549 p[len] = ':';
1550 len++;
1551 }
1552 else {
1553 lua_pushnil(L);
1554 return 1;
1555 }
1556
1557 if (port_to_str(addr, p + len, SOCKET_INFO_MAX_LEN-1 - len) <= 0) {
1558 lua_pushnil(L);
1559 return 1;
1560 }
1561
1562 lua_pushstring(L, p);
1563 return 1;
1564}
1565
1566/* Returns information about the peer of the connection. */
1567__LJMP static int hlua_socket_getpeername(struct lua_State *L)
1568{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001569 struct hlua_socket *socket;
1570 struct connection *conn;
1571
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001572 MAY_LJMP(check_args(L, 1, "getpeername"));
1573
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001574 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001575
1576 /* Check if the tcp object is avalaible. */
1577 if (!socket->s) {
1578 lua_pushnil(L);
1579 return 1;
1580 }
1581
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001582 conn = objt_conn(socket->s->si[1].end);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001583 if (!conn) {
1584 lua_pushnil(L);
1585 return 1;
1586 }
1587
1588 if (!(conn->flags & CO_FL_ADDR_TO_SET)) {
1589 unsigned int salen = sizeof(conn->addr.to);
1590 if (getpeername(conn->t.sock.fd, (struct sockaddr *)&conn->addr.to, &salen) == -1) {
1591 lua_pushnil(L);
1592 return 1;
1593 }
1594 conn->flags |= CO_FL_ADDR_TO_SET;
1595 }
1596
1597 return MAY_LJMP(hlua_socket_info(L, &conn->addr.to));
1598}
1599
1600/* Returns information about my connection side. */
1601static int hlua_socket_getsockname(struct lua_State *L)
1602{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001603 struct hlua_socket *socket;
1604 struct connection *conn;
1605
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001606 MAY_LJMP(check_args(L, 1, "getsockname"));
1607
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001608 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001609
1610 /* Check if the tcp object is avalaible. */
1611 if (!socket->s) {
1612 lua_pushnil(L);
1613 return 1;
1614 }
1615
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001616 conn = objt_conn(socket->s->si[1].end);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001617 if (!conn) {
1618 lua_pushnil(L);
1619 return 1;
1620 }
1621
1622 if (!(conn->flags & CO_FL_ADDR_FROM_SET)) {
1623 unsigned int salen = sizeof(conn->addr.from);
1624 if (getsockname(conn->t.sock.fd, (struct sockaddr *)&conn->addr.from, &salen) == -1) {
1625 lua_pushnil(L);
1626 return 1;
1627 }
1628 conn->flags |= CO_FL_ADDR_FROM_SET;
1629 }
1630
1631 return hlua_socket_info(L, &conn->addr.from);
1632}
1633
1634/* This struct define the applet. */
1635static struct si_applet update_applet = {
1636 .obj_type = OBJ_TYPE_APPLET,
1637 .name = "<LUA_TCP>",
1638 .fct = hlua_socket_handler,
1639 .release = hlua_socket_release,
1640};
1641
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001642__LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001643{
1644 struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1));
1645 struct hlua *hlua = hlua_gethlua(L);
1646 struct appctx *appctx;
1647
1648 /* Check for connection close. */
1649 if (!hlua || !socket->s || channel_output_closed(socket->s->req)) {
1650 lua_pushnil(L);
1651 lua_pushstring(L, "Can't connect");
1652 return 2;
1653 }
1654
1655 appctx = objt_appctx(socket->s->si[0].end);
1656
1657 /* Check for connection established. */
1658 if (appctx->ctx.hlua.connected) {
1659 lua_pushinteger(L, 1);
1660 return 1;
1661 }
1662
1663 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_write))
1664 WILL_LJMP(luaL_error(L, "out of memory error"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01001665 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001666 return 0;
1667}
1668
1669/* This function fail or initite the connection. */
1670__LJMP static int hlua_socket_connect(struct lua_State *L)
1671{
1672 struct hlua_socket *socket;
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001673 int port;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001674 const char *ip;
1675 struct connection *conn;
Thierry FOURNIER95ad96a2015-03-09 18:12:40 +01001676 struct hlua *hlua;
1677 struct appctx *appctx;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001678
1679 MAY_LJMP(check_args(L, 3, "connect"));
1680
1681 /* Get args. */
1682 socket = MAY_LJMP(hlua_checksocket(L, 1));
1683 ip = MAY_LJMP(luaL_checkstring(L, 2));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001684 port = MAY_LJMP(luaL_checkinteger(L, 3));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001685
1686 conn = si_alloc_conn(socket->s->req->cons, 0);
1687 if (!conn)
1688 WILL_LJMP(luaL_error(L, "connect: internal error"));
1689
1690 /* Parse ip address. */
1691 conn->addr.to.ss_family = AF_UNSPEC;
1692 if (!str2ip2(ip, &conn->addr.to, 0))
1693 WILL_LJMP(luaL_error(L, "connect: cannot parse ip address '%s'", ip));
1694
1695 /* Set port. */
1696 if (conn->addr.to.ss_family == AF_INET)
1697 ((struct sockaddr_in *)&conn->addr.to)->sin_port = htons(port);
1698 else if (conn->addr.to.ss_family == AF_INET6)
1699 ((struct sockaddr_in6 *)&conn->addr.to)->sin6_port = htons(port);
1700
1701 /* it is important not to call the wakeup function directly but to
1702 * pass through task_wakeup(), because this one knows how to apply
1703 * priorities to tasks.
1704 */
1705 task_wakeup(socket->s->task, TASK_WOKEN_INIT);
1706
Thierry FOURNIER95ad96a2015-03-09 18:12:40 +01001707 hlua = hlua_gethlua(L);
1708 appctx = objt_appctx(socket->s->si[0].end);
1709 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_write))
1710 WILL_LJMP(luaL_error(L, "out of memory"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01001711 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001712
1713 return 0;
1714}
1715
Baptiste Assmann84bb4932015-03-02 21:40:06 +01001716#ifdef USE_OPENSSL
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001717__LJMP static int hlua_socket_connect_ssl(struct lua_State *L)
1718{
1719 struct hlua_socket *socket;
1720
1721 MAY_LJMP(check_args(L, 3, "connect_ssl"));
1722 socket = MAY_LJMP(hlua_checksocket(L, 1));
1723 socket->s->target = &socket_ssl.obj_type;
1724 return MAY_LJMP(hlua_socket_connect(L));
1725}
Baptiste Assmann84bb4932015-03-02 21:40:06 +01001726#endif
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001727
1728__LJMP static int hlua_socket_setoption(struct lua_State *L)
1729{
1730 return 0;
1731}
1732
1733__LJMP static int hlua_socket_settimeout(struct lua_State *L)
1734{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001735 struct hlua_socket *socket;
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001736 int tmout;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001737
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001738 MAY_LJMP(check_args(L, 2, "settimeout"));
1739
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001740 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001741 tmout = MAY_LJMP(luaL_checkinteger(L, 2)) * 1000;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001742
1743 socket->s->req->rto = tmout;
1744 socket->s->req->wto = tmout;
1745 socket->s->rep->rto = tmout;
1746 socket->s->rep->wto = tmout;
1747
1748 return 0;
1749}
1750
1751__LJMP static int hlua_socket_new(lua_State *L)
1752{
1753 struct hlua_socket *socket;
1754 struct appctx *appctx;
1755
1756 /* Check stack size. */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01001757 if (!lua_checkstack(L, 3)) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001758 hlua_pusherror(L, "socket: full stack");
1759 goto out_fail_conf;
1760 }
1761
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01001762 /* Create the object: obj[0] = userdata. */
1763 lua_newtable(L);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001764 socket = MAY_LJMP(lua_newuserdata(L, sizeof(*socket)));
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01001765 lua_rawseti(L, -2, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001766 memset(socket, 0, sizeof(*socket));
1767
Thierry FOURNIER4a6170c2015-03-09 17:07:10 +01001768 /* Check if the various memory pools are intialized. */
1769 if (!pool2_session || !pool2_channel || !pool2_buffer) {
1770 hlua_pusherror(L, "socket: uninitialized pools.");
1771 goto out_fail_conf;
1772 }
1773
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001774 /* Pop a class session metatable and affect it to the userdata. */
1775 lua_rawgeti(L, LUA_REGISTRYINDEX, class_socket_ref);
1776 lua_setmetatable(L, -2);
1777
1778 /*
1779 *
1780 * Get memory for the request.
1781 *
1782 */
1783
1784 socket->s = pool_alloc2(pool2_session);
1785 if (!socket->s) {
1786 hlua_pusherror(L, "socket: out of memory");
1787 goto out_fail_conf;
1788 }
1789
1790 socket->s->task = task_new();
1791 if (!socket->s->task) {
1792 hlua_pusherror(L, "socket: out of memory");
1793 goto out_free_session;
1794 }
1795
1796 socket->s->req = pool_alloc2(pool2_channel);
1797 if (!socket->s->req) {
1798 hlua_pusherror(L, "socket: out of memory");
1799 goto out_fail_req;
1800 }
1801
1802 socket->s->req->buf = pool_alloc2(pool2_buffer);
1803 if (!socket->s->req->buf) {
1804 hlua_pusherror(L, "socket: out of memory");
1805 goto out_fail_req_buf;
1806 }
1807
1808 socket->s->rep = pool_alloc2(pool2_channel);
1809 if (!socket->s->rep) {
1810 hlua_pusherror(L, "socket: out of memory");
1811 goto out_fail_rep;
1812 }
1813
1814 socket->s->rep->buf = pool_alloc2(pool2_buffer);
1815 if (!socket->s->rep->buf) {
1816 hlua_pusherror(L, "socket: out of memory");
1817 goto out_fail_rep_buf;
1818 }
1819
1820 /* Configura empty Lua for the session. */
1821 socket->s->hlua.T = NULL;
1822 socket->s->hlua.Tref = LUA_REFNIL;
1823 socket->s->hlua.Mref = LUA_REFNIL;
1824 socket->s->hlua.nargs = 0;
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01001825 socket->s->hlua.flags = 0;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001826 LIST_INIT(&socket->s->hlua.com);
1827
1828 /* session initialisation. */
1829 session_init_srv_conn(socket->s);
1830
1831 /*
1832 *
1833 * Configure the associated task.
1834 *
1835 */
1836
1837 /* This is the dedicated function to process the session. This function
1838 * is able to establish the conection, process the timeouts, etc ...
1839 */
1840 socket->s->task->process = process_session;
1841
1842 /* Back reference to session. This is used by process_session(). */
1843 socket->s->task->context = socket->s;
1844
1845 /* The priority of the task is normal. */
1846 socket->s->task->nice = 0;
1847
1848 /* Init the next run to eternity. Later in this function, this task is
1849 * waked.
1850 */
1851 socket->s->task->expire = TICK_ETERNITY;
1852
1853 /*
1854 *
1855 * Initialize the attached buffers
1856 *
1857 */
1858 socket->s->req->buf->size = global.tune.bufsize;
1859 socket->s->rep->buf->size = global.tune.bufsize;
1860
1861 /*
1862 *
1863 * Initialize channels.
1864 *
1865 */
1866
1867 /* This function reset the struct. It must be called
1868 * before the configuration.
1869 */
1870 channel_init(socket->s->req);
1871 channel_init(socket->s->rep);
1872
1873 socket->s->req->prod = &socket->s->si[0];
1874 socket->s->req->cons = &socket->s->si[1];
1875
1876 socket->s->rep->prod = &socket->s->si[1];
1877 socket->s->rep->cons = &socket->s->si[0];
1878
1879 socket->s->si[0].ib = socket->s->req;
1880 socket->s->si[0].ob = socket->s->rep;
1881
1882 socket->s->si[1].ib = socket->s->rep;
1883 socket->s->si[1].ob = socket->s->req;
1884
1885 socket->s->req->analysers = 0;
1886 socket->s->req->rto = socket_proxy.timeout.client;
1887 socket->s->req->wto = socket_proxy.timeout.server;
1888 socket->s->req->rex = TICK_ETERNITY;
1889 socket->s->req->wex = TICK_ETERNITY;
1890 socket->s->req->analyse_exp = TICK_ETERNITY;
1891
1892 socket->s->rep->analysers = 0;
1893 socket->s->rep->rto = socket_proxy.timeout.server;
1894 socket->s->rep->wto = socket_proxy.timeout.client;
1895 socket->s->rep->rex = TICK_ETERNITY;
1896 socket->s->rep->wex = TICK_ETERNITY;
1897 socket->s->rep->analyse_exp = TICK_ETERNITY;
1898
1899 /*
1900 *
1901 * Configure the session.
1902 *
1903 */
1904
1905 /* The session dont have listener. The listener is used with real
1906 * proxies.
1907 */
1908 socket->s->listener = NULL;
1909
1910 /* The flags are initialized to 0. Values are setted later. */
1911 socket->s->flags = 0;
1912
1913 /* Assign the configured proxy to the new session. */
1914 socket->s->be = &socket_proxy;
1915 socket->s->fe = &socket_proxy;
1916
1917 /* XXX: Set namy variables */
1918 socket->s->store_count = 0;
1919 memset(socket->s->stkctr, 0, sizeof(socket->s->stkctr));
1920
1921 /* Configure logs. */
1922 socket->s->logs.logwait = 0;
1923 socket->s->logs.level = 0;
1924 socket->s->logs.accept_date = date; /* user-visible date for logging */
1925 socket->s->logs.tv_accept = now; /* corrected date for internal use */
1926 socket->s->do_log = NULL;
1927
1928 /* Function used if an error is occured. */
1929 socket->s->srv_error = default_srv_error;
1930
1931 /* Init the list of buffers. */
1932 LIST_INIT(&socket->s->buffer_wait);
1933
1934 /* Dont configure the unique ID. */
1935 socket->s->uniq_id = 0;
1936 socket->s->unique_id = NULL;
1937
1938 /* XXX: ? */
1939 socket->s->pend_pos = NULL;
1940
1941 /* XXX: See later. */
1942 socket->s->txn.sessid = NULL;
1943 socket->s->txn.srv_cookie = NULL;
1944 socket->s->txn.cli_cookie = NULL;
1945 socket->s->txn.uri = NULL;
1946 socket->s->txn.req.cap = NULL;
1947 socket->s->txn.rsp.cap = NULL;
1948 socket->s->txn.hdr_idx.v = NULL;
1949 socket->s->txn.hdr_idx.size = 0;
1950 socket->s->txn.hdr_idx.used = 0;
1951
1952 /* Configure "left" stream interface as applet. This "si" produce
1953 * and use the data received from the server. The applet is initialized
1954 * and is attached to the stream interface.
1955 */
1956
1957 /* The data producer is already connected. It is the applet. */
1958 socket->s->req->flags = CF_READ_ATTACHED;
1959
1960 channel_auto_connect(socket->s->req); /* don't wait to establish connection */
1961 channel_auto_close(socket->s->req); /* let the producer forward close requests */
1962
1963 si_reset(&socket->s->si[0], socket->s->task);
1964 si_set_state(&socket->s->si[0], SI_ST_EST); /* connection established (resource exists) */
1965
1966 appctx = stream_int_register_handler(&socket->s->si[0], &update_applet);
1967 if (!appctx)
1968 goto out_fail_conn1;
1969 appctx->ctx.hlua.socket = socket;
1970 appctx->ctx.hlua.connected = 0;
1971 LIST_INIT(&appctx->ctx.hlua.wake_on_write);
1972 LIST_INIT(&appctx->ctx.hlua.wake_on_read);
1973
1974 /* Configure "right" stream interface. this "si" is used to connect
1975 * and retrieve data from the server. The connection is initialized
1976 * with the "struct server".
1977 */
1978 si_reset(&socket->s->si[1], socket->s->task);
1979 si_set_state(&socket->s->si[1], SI_ST_INI);
1980 socket->s->si[1].conn_retries = socket_proxy.conn_retries;
1981
1982 /* Force destination server. */
1983 socket->s->flags |= SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET | SN_BE_ASSIGNED;
1984 socket->s->target = &socket_tcp.obj_type;
1985
1986 /* This session is added to te lists of alive sessions. */
1987 LIST_ADDQ(&sessions, &socket->s->list);
1988
1989 /* XXX: I think that this list is used by stats. */
1990 LIST_INIT(&socket->s->back_refs);
1991
1992 /* Update statistics counters. */
1993 socket_proxy.feconn++; /* beconn will be increased later */
1994 jobs++;
1995 totalconn++;
1996
1997 /* Return yield waiting for connection. */
1998 return 1;
1999
2000out_fail_conn1:
2001 pool_free2(pool2_buffer, socket->s->rep->buf);
2002out_fail_rep_buf:
2003 pool_free2(pool2_channel, socket->s->rep);
2004out_fail_rep:
2005 pool_free2(pool2_buffer, socket->s->req->buf);
2006out_fail_req_buf:
2007 pool_free2(pool2_channel, socket->s->req);
2008out_fail_req:
2009 task_free(socket->s->task);
2010out_free_session:
2011 pool_free2(pool2_session, socket->s);
2012out_fail_conf:
2013 WILL_LJMP(lua_error(L));
2014 return 0;
2015}
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01002016
2017/*
2018 *
2019 *
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002020 * Class Channel
2021 *
2022 *
2023 */
2024
2025/* Returns the struct hlua_channel join to the class channel in the
2026 * stack entry "ud" or throws an argument error.
2027 */
2028__LJMP static struct hlua_channel *hlua_checkchannel(lua_State *L, int ud)
2029{
2030 return (struct hlua_channel *)MAY_LJMP(hlua_checkudata(L, ud, class_channel_ref));
2031}
2032
2033/* Creates new channel object and put it on the top of the stack.
2034 * If the stask does not have a free slots, the function fails
2035 * and returns 0;
2036 */
Thierry FOURNIERbd1f1322015-03-05 17:04:41 +01002037static int hlua_channel_new(lua_State *L, struct session *s, struct channel *channel)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002038{
2039 struct hlua_channel *chn;
2040
2041 /* Check stack size. */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002042 if (!lua_checkstack(L, 3))
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002043 return 0;
2044
2045 /* NOTE: The allocation never fails. The failure
2046 * throw an error, and the function never returns.
2047 */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002048 lua_newtable(L);
2049 chn = MAY_LJMP(lua_newuserdata(L, sizeof(*chn)));
2050 lua_rawseti(L, -2, 0);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002051 chn->chn = channel;
Thierry FOURNIERbd1f1322015-03-05 17:04:41 +01002052 chn->s = s;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002053
2054 /* Pop a class sesison metatable and affect it to the userdata. */
2055 lua_rawgeti(L, LUA_REGISTRYINDEX, class_channel_ref);
2056 lua_setmetatable(L, -2);
2057
2058 return 1;
2059}
2060
2061/* Duplicate all the data present in the input channel and put it
2062 * in a string LUA variables. Returns -1 and push a nil value in
2063 * the stack if the channel is closed and all the data are consumed,
2064 * returns 0 if no data are available, otherwise it returns the length
2065 * of the builded string.
2066 */
2067static inline int _hlua_channel_dup(struct hlua_channel *chn, lua_State *L)
2068{
2069 char *blk1;
2070 char *blk2;
2071 int len1;
2072 int len2;
2073 int ret;
2074 luaL_Buffer b;
2075
2076 ret = bi_getblk_nc(chn->chn, &blk1, &len1, &blk2, &len2);
2077 if (unlikely(ret == 0))
2078 return 0;
2079
2080 if (unlikely(ret < 0)) {
2081 lua_pushnil(L);
2082 return -1;
2083 }
2084
2085 luaL_buffinit(L, &b);
2086 luaL_addlstring(&b, blk1, len1);
2087 if (unlikely(ret == 2))
2088 luaL_addlstring(&b, blk2, len2);
2089 luaL_pushresult(&b);
2090
2091 if (unlikely(ret == 2))
2092 return len1 + len2;
2093 return len1;
2094}
2095
2096/* "_hlua_channel_dup" wrapper. If no data are available, it returns
2097 * a yield. This function keep the data in the buffer.
2098 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002099__LJMP static int hlua_channel_dup_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002100{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002101 struct hlua_channel *chn;
2102
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002103 chn = MAY_LJMP(hlua_checkchannel(L, 1));
2104
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002105 if (_hlua_channel_dup(chn, L) == 0)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002106 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_dup_yield, TICK_ETERNITY, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002107 return 1;
2108}
2109
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002110/* Check arguments for the function "hlua_channel_dup_yield". */
2111__LJMP static int hlua_channel_dup(lua_State *L)
2112{
2113 MAY_LJMP(check_args(L, 1, "dup"));
2114 MAY_LJMP(hlua_checkchannel(L, 1));
2115 return MAY_LJMP(hlua_channel_dup_yield(L, 0, 0));
2116}
2117
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002118/* "_hlua_channel_dup" wrapper. If no data are available, it returns
2119 * a yield. This function consumes the data in the buffer. It returns
2120 * a string containing the data or a nil pointer if no data are available
2121 * and the channel is closed.
2122 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002123__LJMP static int hlua_channel_get_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002124{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002125 struct hlua_channel *chn;
2126 int ret;
2127
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002128 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002129
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002130 ret = _hlua_channel_dup(chn, L);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002131 if (unlikely(ret == 0))
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002132 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_get_yield, TICK_ETERNITY, 0));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002133
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002134 if (unlikely(ret == -1))
2135 return 1;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002136
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002137 chn->chn->buf->i -= ret;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002138 return 1;
2139}
2140
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002141/* Check arguments for the fucntion "hlua_channel_get_yield". */
2142__LJMP static int hlua_channel_get(lua_State *L)
2143{
2144 MAY_LJMP(check_args(L, 1, "get"));
2145 MAY_LJMP(hlua_checkchannel(L, 1));
2146 return MAY_LJMP(hlua_channel_get_yield(L, 0, 0));
2147}
2148
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002149/* This functions consumes and returns one line. If the channel is closed,
2150 * and the last data does not contains a final '\n', the data are returned
2151 * without the final '\n'. When no more data are avalaible, it returns nil
2152 * value.
2153 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002154__LJMP static int hlua_channel_getline_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002155{
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002156 char *blk1;
2157 char *blk2;
2158 int len1;
2159 int len2;
2160 int len;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002161 struct hlua_channel *chn;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002162 int ret;
2163 luaL_Buffer b;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002164
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002165 chn = MAY_LJMP(hlua_checkchannel(L, 1));
2166
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002167 ret = bi_getline_nc(chn->chn, &blk1, &len1, &blk2, &len2);
2168 if (ret == 0)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002169 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_getline_yield, TICK_ETERNITY, 0));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002170
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002171 if (ret == -1) {
2172 lua_pushnil(L);
2173 return 1;
2174 }
2175
2176 luaL_buffinit(L, &b);
2177 luaL_addlstring(&b, blk1, len1);
2178 len = len1;
2179 if (unlikely(ret == 2)) {
2180 luaL_addlstring(&b, blk2, len2);
2181 len += len2;
2182 }
2183 luaL_pushresult(&b);
2184 buffer_replace2(chn->chn->buf, chn->chn->buf->p, chn->chn->buf->p + len, NULL, 0);
2185 return 1;
2186}
2187
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002188/* Check arguments for the fucntion "hlua_channel_getline_yield". */
2189__LJMP static int hlua_channel_getline(lua_State *L)
2190{
2191 MAY_LJMP(check_args(L, 1, "getline"));
2192 MAY_LJMP(hlua_checkchannel(L, 1));
2193 return MAY_LJMP(hlua_channel_getline_yield(L, 0, 0));
2194}
2195
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002196/* This function takes a string as input, and append it at the
2197 * input side of channel. If the data is too big, but a space
2198 * is probably available after sending some data, the function
2199 * yield. If the data is bigger than the buffer, or if the
2200 * channel is closed, it returns -1. otherwise, it returns the
2201 * amount of data writed.
2202 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002203__LJMP static int hlua_channel_append_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002204{
2205 struct hlua_channel *chn = MAY_LJMP(hlua_checkchannel(L, 1));
2206 size_t len;
2207 const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
2208 int l = MAY_LJMP(luaL_checkinteger(L, 3));
2209 int ret;
2210 int max;
2211
2212 max = channel_recv_limit(chn->chn) - buffer_len(chn->chn->buf);
2213 if (max > len - l)
2214 max = len - l;
2215
2216 ret = bi_putblk(chn->chn, str+l, max);
2217 if (ret == -2 || ret == -3) {
2218 lua_pushinteger(L, -1);
2219 return 1;
2220 }
2221 if (ret == -1)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002222 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002223 l += ret;
2224 lua_pop(L, 1);
2225 lua_pushinteger(L, l);
2226
2227 max = channel_recv_limit(chn->chn) - buffer_len(chn->chn->buf);
2228 if (max == 0 && chn->chn->buf->o == 0) {
2229 /* There are no space avalaible, and the output buffer is empty.
2230 * in this case, we cannot add more data, so we cannot yield,
2231 * we return the amount of copyied data.
2232 */
2233 return 1;
2234 }
2235 if (l < len)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002236 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002237 return 1;
2238}
2239
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002240/* just a wrapper of "hlua_channel_append_yield". It returns the length
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002241 * of the writed string, or -1 if the channel is closed or if the
2242 * buffer size is too little for the data.
2243 */
2244__LJMP static int hlua_channel_append(lua_State *L)
2245{
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002246 size_t len;
2247
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002248 MAY_LJMP(check_args(L, 2, "append"));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002249 MAY_LJMP(hlua_checkchannel(L, 1));
2250 MAY_LJMP(luaL_checklstring(L, 2, &len));
2251 MAY_LJMP(luaL_checkinteger(L, 3));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002252 lua_pushinteger(L, 0);
2253
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002254 return MAY_LJMP(hlua_channel_append_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002255}
2256
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002257/* just a wrapper of "hlua_channel_append_yield". This wrapper starts
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002258 * his process by cleaning the buffer. The result is a replacement
2259 * of the current data. It returns the length of the writed string,
2260 * or -1 if the channel is closed or if the buffer size is too
2261 * little for the data.
2262 */
2263__LJMP static int hlua_channel_set(lua_State *L)
2264{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002265 struct hlua_channel *chn;
2266
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002267 MAY_LJMP(check_args(L, 2, "set"));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002268 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002269 lua_pushinteger(L, 0);
2270
2271 chn->chn->buf->i = 0;
2272
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002273 return MAY_LJMP(hlua_channel_append_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002274}
2275
2276/* Append data in the output side of the buffer. This data is immediatly
2277 * sent. The fcuntion returns the ammount of data writed. If the buffer
2278 * cannot contains the data, the function yield. The function returns -1
2279 * if the channel is closed.
2280 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002281__LJMP static int hlua_channel_send_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002282{
2283 struct hlua_channel *chn = MAY_LJMP(hlua_checkchannel(L, 1));
2284 size_t len;
2285 const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
2286 int l = MAY_LJMP(luaL_checkinteger(L, 3));
2287 int max;
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002288 struct hlua *hlua = hlua_gethlua(L);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002289
2290 if (unlikely(channel_output_closed(chn->chn))) {
2291 lua_pushinteger(L, -1);
2292 return 1;
2293 }
2294
Thierry FOURNIER3e3a6082015-03-05 17:06:12 +01002295 /* Check if the buffer is avalaible because HAProxy doesn't allocate
2296 * the request buffer if its not required.
2297 */
2298 if (chn->chn->buf->size == 0) {
2299 if (!session_alloc_recv_buffer(chn->s, &chn->chn->buf)) {
2300 chn->chn->prod->flags |= SI_FL_WAIT_ROOM;
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002301 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
Thierry FOURNIER3e3a6082015-03-05 17:06:12 +01002302 }
2303 }
2304
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002305 /* the writed data will be immediatly sent, so we can check
2306 * the avalaible space without taking in account the reserve.
2307 * The reserve is guaranted for the processing of incoming
2308 * data, because the buffer will be flushed.
2309 */
2310 max = chn->chn->buf->size - buffer_len(chn->chn->buf);
2311
2312 /* If there are no space avalaible, and the output buffer is empty.
2313 * in this case, we cannot add more data, so we cannot yield,
2314 * we return the amount of copyied data.
2315 */
2316 if (max == 0 && chn->chn->buf->o == 0)
2317 return 1;
2318
2319 /* Adjust the real required length. */
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002320 if (max > len - l)
2321 max = len - l;
2322
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002323 /* The buffer avalaible size may be not contiguous. This test
2324 * detects a non contiguous buffer and realign it.
2325 */
Thierry FOURNIERd2b597a2015-03-07 14:38:50 +01002326 if (bi_space_for_replace(chn->chn->buf) < max)
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002327 buffer_slow_realign(chn->chn->buf);
2328
2329 /* Copy input data in the buffer. */
Thierry FOURNIER506e46c2015-03-04 11:44:47 +01002330 max = buffer_replace2(chn->chn->buf, chn->chn->buf->p, chn->chn->buf->p, str+l, max);
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002331
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002332 /* buffer replace considers that the input part is filled.
2333 * so, I must forward these new data in the output part.
2334 */
2335 b_adv(chn->chn->buf, max);
2336
2337 l += max;
2338 lua_pop(L, 1);
2339 lua_pushinteger(L, l);
2340
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002341 /* If there are no space avalaible, and the output buffer is empty.
2342 * in this case, we cannot add more data, so we cannot yield,
2343 * we return the amount of copyied data.
2344 */
2345 max = chn->chn->buf->size - buffer_len(chn->chn->buf);
2346 if (max == 0 && chn->chn->buf->o == 0)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002347 return 1;
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002348
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002349 if (l < len) {
2350 /* If we are waiting for space in the response buffer, we
2351 * must set the flag WAKERESWR. This flag required the task
2352 * wake up if any activity is detected on the response buffer.
2353 */
2354 if (chn->chn == chn->s->rep)
2355 HLUA_SET_WAKERESWR(hlua);
Thierry FOURNIER53e08ec2015-03-06 00:35:53 +01002356 else
2357 HLUA_SET_WAKEREQWR(hlua);
2358 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002359 }
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002360
2361 return 1;
2362}
2363
2364/* Just a wraper of "_hlua_channel_send". This wrapper permits
2365 * yield the LUA process, and resume it without checking the
2366 * input arguments.
2367 */
2368__LJMP static int hlua_channel_send(lua_State *L)
2369{
2370 MAY_LJMP(check_args(L, 2, "send"));
2371 lua_pushinteger(L, 0);
2372
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002373 return MAY_LJMP(hlua_channel_send_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002374}
2375
2376/* This function forward and amount of butes. The data pass from
2377 * the input side of the buffer to the output side, and can be
2378 * forwarded. This function never fails.
2379 *
2380 * The Lua function takes an amount of bytes to be forwarded in
2381 * imput. It returns the number of bytes forwarded.
2382 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002383__LJMP static int hlua_channel_forward_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002384{
2385 struct hlua_channel *chn;
2386 int len;
2387 int l;
2388 int max;
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002389 struct hlua *hlua = hlua_gethlua(L);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002390
2391 chn = MAY_LJMP(hlua_checkchannel(L, 1));
2392 len = MAY_LJMP(luaL_checkinteger(L, 2));
2393 l = MAY_LJMP(luaL_checkinteger(L, -1));
2394
2395 max = len - l;
2396 if (max > chn->chn->buf->i)
2397 max = chn->chn->buf->i;
2398 channel_forward(chn->chn, max);
2399 l += max;
2400
2401 lua_pop(L, 1);
2402 lua_pushinteger(L, l);
2403
2404 /* Check if it miss bytes to forward. */
2405 if (l < len) {
2406 /* The the input channel or the output channel are closed, we
2407 * must return the amount of data forwarded.
2408 */
2409 if (channel_input_closed(chn->chn) || channel_output_closed(chn->chn))
2410 return 1;
2411
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002412 /* If we are waiting for space data in the response buffer, we
2413 * must set the flag WAKERESWR. This flag required the task
2414 * wake up if any activity is detected on the response buffer.
2415 */
2416 if (chn->chn == chn->s->rep)
2417 HLUA_SET_WAKERESWR(hlua);
Thierry FOURNIER53e08ec2015-03-06 00:35:53 +01002418 else
2419 HLUA_SET_WAKEREQWR(hlua);
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002420
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002421 /* Otherwise, we can yield waiting for new data in the inpout side. */
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01002422 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_forward_yield, TICK_ETERNITY, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002423 }
2424
2425 return 1;
2426}
2427
2428/* Just check the input and prepare the stack for the previous
2429 * function "hlua_channel_forward_yield"
2430 */
2431__LJMP static int hlua_channel_forward(lua_State *L)
2432{
2433 MAY_LJMP(check_args(L, 2, "forward"));
2434 MAY_LJMP(hlua_checkchannel(L, 1));
2435 MAY_LJMP(luaL_checkinteger(L, 2));
2436
2437 lua_pushinteger(L, 0);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002438 return MAY_LJMP(hlua_channel_forward_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002439}
2440
2441/* Just returns the number of bytes available in the input
2442 * side of the buffer. This function never fails.
2443 */
2444__LJMP static int hlua_channel_get_in_len(lua_State *L)
2445{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002446 struct hlua_channel *chn;
2447
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002448 MAY_LJMP(check_args(L, 1, "get_in_len"));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002449 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002450 lua_pushinteger(L, chn->chn->buf->i);
2451 return 1;
2452}
2453
2454/* Just returns the number of bytes available in the output
2455 * side of the buffer. This function never fails.
2456 */
2457__LJMP static int hlua_channel_get_out_len(lua_State *L)
2458{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002459 struct hlua_channel *chn;
2460
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002461 MAY_LJMP(check_args(L, 1, "get_out_len"));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002462 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002463 lua_pushinteger(L, chn->chn->buf->o);
2464 return 1;
2465}
2466
2467
2468/*
2469 *
2470 *
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01002471 * Class TXN
2472 *
2473 *
2474 */
2475
2476/* Returns a struct hlua_session if the stack entry "ud" is
2477 * a class session, otherwise it throws an error.
2478 */
2479__LJMP static struct hlua_txn *hlua_checktxn(lua_State *L, int ud)
2480{
2481 return (struct hlua_txn *)MAY_LJMP(hlua_checkudata(L, ud, class_txn_ref));
2482}
2483
Willy Tarreau59551662015-03-10 14:23:13 +01002484__LJMP static int hlua_set_priv(lua_State *L)
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01002485{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002486 struct hlua *hlua;
2487
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01002488 MAY_LJMP(check_args(L, 2, "set_priv"));
2489
2490 /* It is useles to retrieve the session, but this function
2491 * runs only in a session context.
2492 */
2493 MAY_LJMP(hlua_checktxn(L, 1));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002494 hlua = hlua_gethlua(L);
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01002495
2496 /* Remove previous value. */
2497 if (hlua->Mref != -1)
2498 luaL_unref(L, hlua->Mref, LUA_REGISTRYINDEX);
2499
2500 /* Get and store new value. */
2501 lua_pushvalue(L, 2); /* Copy the element 2 at the top of the stack. */
2502 hlua->Mref = luaL_ref(L, LUA_REGISTRYINDEX); /* pop the previously pushed value. */
2503
2504 return 0;
2505}
2506
Willy Tarreau59551662015-03-10 14:23:13 +01002507__LJMP static int hlua_get_priv(lua_State *L)
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01002508{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002509 struct hlua *hlua;
2510
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01002511 MAY_LJMP(check_args(L, 1, "get_priv"));
2512
2513 /* It is useles to retrieve the session, but this function
2514 * runs only in a session context.
2515 */
2516 MAY_LJMP(hlua_checktxn(L, 1));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002517 hlua = hlua_gethlua(L);
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01002518
2519 /* Push configuration index in the stack. */
2520 lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
2521
2522 return 1;
2523}
2524
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01002525/* Create stack entry containing a class TXN. This function
2526 * return 0 if the stack does not contains free slots,
2527 * otherwise it returns 1.
2528 */
2529static int hlua_txn_new(lua_State *L, struct session *s, struct proxy *p, void *l7)
2530{
2531 struct hlua_txn *hs;
2532
2533 /* Check stack size. */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002534 if (!lua_checkstack(L, 3))
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01002535 return 0;
2536
2537 /* NOTE: The allocation never fails. The failure
2538 * throw an error, and the function never returns.
2539 * if the throw is not avalaible, the process is aborted.
2540 */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002541 /* Create the object: obj[0] = userdata. */
2542 lua_newtable(L);
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01002543 hs = lua_newuserdata(L, sizeof(struct hlua_txn));
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002544 lua_rawseti(L, -2, 0);
2545
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01002546 hs->s = s;
2547 hs->p = p;
2548 hs->l7 = l7;
2549
2550 /* Pop a class sesison metatable and affect it to the userdata. */
2551 lua_rawgeti(L, LUA_REGISTRYINDEX, class_txn_ref);
2552 lua_setmetatable(L, -2);
2553
2554 return 1;
2555}
2556
Thierry FOURNIERe94e7742015-02-17 14:59:53 +01002557/* This function returns a channel object associated
2558 * with the request channel. This function never fails,
2559 * however if the stack is full, it throws an error.
2560 */
2561__LJMP static int hlua_txn_req_channel(lua_State *L)
2562{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002563 struct hlua_txn *s;
Thierry FOURNIERe94e7742015-02-17 14:59:53 +01002564
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002565 MAY_LJMP(check_args(L, 1, "req_channel"));
2566 s = MAY_LJMP(hlua_checktxn(L, 1));
Thierry FOURNIERe94e7742015-02-17 14:59:53 +01002567
Thierry FOURNIERbd1f1322015-03-05 17:04:41 +01002568 if (!hlua_channel_new(L, s->s, s->s->req))
Thierry FOURNIERe94e7742015-02-17 14:59:53 +01002569 WILL_LJMP(luaL_error(L, "full stack"));
2570
2571 return 1;
2572}
2573
2574/* This function returns a channel object associated
2575 * with the response channel. This function never fails,
2576 * however if the stack is full, it throws an error.
2577 */
2578__LJMP static int hlua_txn_res_channel(lua_State *L)
2579{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002580 struct hlua_txn *s;
Thierry FOURNIERe94e7742015-02-17 14:59:53 +01002581
Willy Tarreaueee45392015-03-10 14:22:28 +01002582 MAY_LJMP(check_args(L, 1, "res_channel"));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002583 s = MAY_LJMP(hlua_checktxn(L, 1));
Thierry FOURNIERe94e7742015-02-17 14:59:53 +01002584
Thierry FOURNIERbd1f1322015-03-05 17:04:41 +01002585 if (!hlua_channel_new(L, s->s, s->s->rep))
Thierry FOURNIERe94e7742015-02-17 14:59:53 +01002586 WILL_LJMP(luaL_error(L, "full stack"));
2587
2588 return 1;
2589}
2590
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01002591/* This function is an Lua binding that send pending data
2592 * to the client, and close the stream interface.
2593 */
2594__LJMP static int hlua_txn_close(lua_State *L)
2595{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002596 struct hlua_txn *s;
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01002597
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002598 MAY_LJMP(check_args(L, 1, "close"));
2599 s = MAY_LJMP(hlua_checktxn(L, 1));
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01002600
2601 channel_abort(s->s->si[0].ib);
2602 channel_auto_close(s->s->si[0].ib);
2603 channel_erase(s->s->si[0].ib);
2604 channel_auto_read(s->s->si[0].ob);
2605 channel_auto_close(s->s->si[0].ob);
2606 channel_shutr_now(s->s->si[0].ob);
2607
2608 return 0;
2609}
2610
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01002611/* This function is an LUA binding. It is called with each sample-fetch.
2612 * It uses closure argument to store the associated sample-fetch. It
Cyril Bonté928ae5c2015-03-02 00:08:41 +01002613 * returns only one argument or throws an error. An error is thrown
2614 * only if an error is encountered during the argument parsing. If
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01002615 * the "sample-fetch" function fails, nil is returned.
2616 */
2617__LJMP static int hlua_run_sample_fetch(lua_State *L)
2618{
2619 struct hlua_txn *s;
2620 struct hlua_sample_fetch *f;
Cyril Bonté928ae5c2015-03-02 00:08:41 +01002621 struct arg args[ARGM_NBARGS + 1];
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01002622 int i;
2623 struct sample smp;
2624
2625 /* Get closure arguments. */
2626 f = (struct hlua_sample_fetch *)lua_touserdata(L, lua_upvalueindex(1));
2627
2628 /* Get traditionnal arguments. */
2629 s = MAY_LJMP(hlua_checktxn(L, 1));
2630
2631 /* Get extra arguments. */
Cyril Bonté928ae5c2015-03-02 00:08:41 +01002632 for (i = 0; i < lua_gettop(L) - 1; i++) {
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01002633 if (i >= ARGM_NBARGS)
2634 break;
2635 hlua_lua2arg(L, i + 2, &args[i]);
2636 }
2637 args[i].type = ARGT_STOP;
2638
2639 /* Check arguments. */
2640 MAY_LJMP(hlua_lua2arg_check(L, 1, args, f->f->arg_mask));
2641
Cyril Bonté928ae5c2015-03-02 00:08:41 +01002642 /* Run the special args checker. */
2643 if (f->f->val_args && !f->f->val_args(args, NULL)) {
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01002644 lua_pushfstring(L, "error in arguments");
2645 WILL_LJMP(lua_error(L));
2646 }
2647
2648 /* Initialise the sample. */
2649 memset(&smp, 0, sizeof(smp));
2650
2651 /* Run the sample fetch process. */
2652 if (!f->f->process(s->p, s->s, s->l7, 0, args, &smp, f->f->kw, f->f->private)) {
2653 lua_pushnil(L);
2654 return 1;
2655 }
2656
2657 /* Convert the returned sample in lua value. */
2658 hlua_smp2lua(L, &smp);
2659 return 1;
2660}
2661
Thierry FOURNIER9a819e72015-02-16 20:22:55 +01002662/* This function is an LUA binding. It creates ans returns
2663 * an array of HTTP headers. This function does not fails.
2664 */
Willy Tarreau59551662015-03-10 14:23:13 +01002665static int hlua_session_get_headers(lua_State *L)
Thierry FOURNIER9a819e72015-02-16 20:22:55 +01002666{
2667 struct hlua_txn *s = MAY_LJMP(hlua_checktxn(L, 1));
2668 struct session *sess = s->s;
2669 const char *cur_ptr, *cur_next, *p;
2670 int old_idx, cur_idx;
2671 struct hdr_idx_elem *cur_hdr;
2672 const char *hn, *hv;
2673 int hnl, hvl;
2674
2675 /* Create the table. */
2676 lua_newtable(L);
2677
2678 /* Build array of headers. */
2679 old_idx = 0;
2680 cur_next = sess->req->buf->p + hdr_idx_first_pos(&sess->txn.hdr_idx);
2681
2682 while (1) {
2683 cur_idx = sess->txn.hdr_idx.v[old_idx].next;
2684 if (!cur_idx)
2685 break;
2686 old_idx = cur_idx;
2687
2688 cur_hdr = &sess->txn.hdr_idx.v[cur_idx];
2689 cur_ptr = cur_next;
2690 cur_next = cur_ptr + cur_hdr->len + cur_hdr->cr + 1;
2691
2692 /* Now we have one full header at cur_ptr of len cur_hdr->len,
2693 * and the next header starts at cur_next. We'll check
2694 * this header in the list as well as against the default
2695 * rule.
2696 */
2697
2698 /* look for ': *'. */
2699 hn = cur_ptr;
2700 for (p = cur_ptr; p < cur_ptr + cur_hdr->len && *p != ':'; p++);
2701 if (p >= cur_ptr+cur_hdr->len)
2702 continue;
2703 hnl = p - hn;
2704 p++;
2705 while (p < cur_ptr+cur_hdr->len && ( *p == ' ' || *p == '\t' ))
2706 p++;
2707 if (p >= cur_ptr+cur_hdr->len)
2708 continue;
2709 hv = p;
2710 hvl = cur_ptr+cur_hdr->len-p;
2711
2712 /* Push values in the table. */
2713 lua_pushlstring(L, hn, hnl);
2714 lua_pushlstring(L, hv, hvl);
2715 lua_settable(L, -3);
2716 }
2717
2718 return 1;
2719}
2720
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002721__LJMP static int hlua_sleep_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01002722{
2723 int wakeup_ms = lua_tointeger(L, -1);
2724 if (now_ms < wakeup_ms)
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002725 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01002726 return 0;
2727}
2728
2729__LJMP static int hlua_sleep(lua_State *L)
2730{
2731 unsigned int delay;
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002732 unsigned int wakeup_ms;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01002733
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002734 MAY_LJMP(check_args(L, 1, "sleep"));
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01002735
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002736 delay = MAY_LJMP(luaL_checkinteger(L, 1)) * 1000;
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002737 wakeup_ms = tick_add(now_ms, delay);
2738 lua_pushinteger(L, wakeup_ms);
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01002739
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002740 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
2741 return 0;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01002742}
2743
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002744__LJMP static int hlua_msleep(lua_State *L)
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01002745{
2746 unsigned int delay;
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002747 unsigned int wakeup_ms;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01002748
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002749 MAY_LJMP(check_args(L, 1, "msleep"));
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01002750
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002751 delay = MAY_LJMP(luaL_checkinteger(L, 1));
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002752 wakeup_ms = tick_add(now_ms, delay);
2753 lua_pushinteger(L, wakeup_ms);
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01002754
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002755 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
2756 return 0;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01002757}
2758
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01002759/* This functionis an LUA binding. it permits to give back
2760 * the hand at the HAProxy scheduler. It is used when the
2761 * LUA processing consumes a lot of time.
2762 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002763__LJMP static int hlua_yield_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002764{
2765 return 0;
2766}
2767
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01002768__LJMP static int hlua_yield(lua_State *L)
2769{
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01002770 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_yield_yield, TICK_ETERNITY, HLUA_CTRLYIELD));
2771 return 0;
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01002772}
2773
Thierry FOURNIER37196f42015-02-16 19:34:56 +01002774/* This function change the nice of the currently executed
2775 * task. It is used set low or high priority at the current
2776 * task.
2777 */
Willy Tarreau59551662015-03-10 14:23:13 +01002778__LJMP static int hlua_set_nice(lua_State *L)
Thierry FOURNIER37196f42015-02-16 19:34:56 +01002779{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002780 struct hlua *hlua;
2781 int nice;
Thierry FOURNIER37196f42015-02-16 19:34:56 +01002782
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002783 MAY_LJMP(check_args(L, 1, "set_nice"));
2784 hlua = hlua_gethlua(L);
2785 nice = MAY_LJMP(luaL_checkinteger(L, 1));
Thierry FOURNIER37196f42015-02-16 19:34:56 +01002786
2787 /* If he task is not set, I'm in a start mode. */
2788 if (!hlua || !hlua->task)
2789 return 0;
2790
2791 if (nice < -1024)
2792 nice = -1024;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002793 else if (nice > 1024)
Thierry FOURNIER37196f42015-02-16 19:34:56 +01002794 nice = 1024;
2795
2796 hlua->task->nice = nice;
2797 return 0;
2798}
2799
Thierry FOURNIER24f33532015-01-23 12:13:00 +01002800/* This function is used as a calback of a task. It is called by the
2801 * HAProxy task subsystem when the task is awaked. The LUA runtime can
2802 * return an E_AGAIN signal, the emmiter of this signal must set a
2803 * signal to wake the task.
2804 */
2805static struct task *hlua_process_task(struct task *task)
2806{
2807 struct hlua *hlua = task->context;
2808 enum hlua_exec status;
2809
2810 /* We need to remove the task from the wait queue before executing
2811 * the Lua code because we don't know if it needs to wait for
2812 * another timer or not in the case of E_AGAIN.
2813 */
2814 task_delete(task);
2815
Thierry FOURNIERbd413492015-03-03 16:52:26 +01002816 /* If it is the first call to the task, we must initialize the
2817 * execution timeouts.
2818 */
2819 if (!HLUA_IS_RUNNING(hlua))
2820 hlua->expire = tick_add(now_ms, hlua_timeout_task);
2821
Thierry FOURNIER24f33532015-01-23 12:13:00 +01002822 /* Execute the Lua code. */
2823 status = hlua_ctx_resume(hlua, 1);
2824
2825 switch (status) {
2826 /* finished or yield */
2827 case HLUA_E_OK:
2828 hlua_ctx_destroy(hlua);
2829 task_delete(task);
2830 task_free(task);
2831 break;
2832
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01002833 case HLUA_E_AGAIN: /* co process or timeout wake me later. */
2834 if (hlua->wake_time != TICK_ETERNITY)
2835 task_schedule(task, hlua->wake_time);
Thierry FOURNIER24f33532015-01-23 12:13:00 +01002836 break;
2837
2838 /* finished with error. */
2839 case HLUA_E_ERRMSG:
2840 send_log(NULL, LOG_ERR, "Lua task: %s.", lua_tostring(hlua->T, -1));
2841 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
2842 Alert("Lua task: %s.\n", lua_tostring(hlua->T, -1));
2843 hlua_ctx_destroy(hlua);
2844 task_delete(task);
2845 task_free(task);
2846 break;
2847
2848 case HLUA_E_ERR:
2849 default:
2850 send_log(NULL, LOG_ERR, "Lua task: unknown error.");
2851 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
2852 Alert("Lua task: unknown error.\n");
2853 hlua_ctx_destroy(hlua);
2854 task_delete(task);
2855 task_free(task);
2856 break;
2857 }
2858 return NULL;
2859}
2860
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01002861/* This function is an LUA binding that register LUA function to be
2862 * executed after the HAProxy configuration parsing and before the
2863 * HAProxy scheduler starts. This function expect only one LUA
2864 * argument that is a function. This function returns nothing, but
2865 * throws if an error is encountered.
2866 */
2867__LJMP static int hlua_register_init(lua_State *L)
2868{
2869 struct hlua_init_function *init;
2870 int ref;
2871
2872 MAY_LJMP(check_args(L, 1, "register_init"));
2873
2874 ref = MAY_LJMP(hlua_checkfunction(L, 1));
2875
2876 init = malloc(sizeof(*init));
2877 if (!init)
2878 WILL_LJMP(luaL_error(L, "lua out of memory error."));
2879
2880 init->function_ref = ref;
2881 LIST_ADDQ(&hlua_init_functions, &init->l);
2882 return 0;
2883}
2884
Thierry FOURNIER24f33532015-01-23 12:13:00 +01002885/* This functio is an LUA binding. It permits to register a task
2886 * executed in parallel of the main HAroxy activity. The task is
2887 * created and it is set in the HAProxy scheduler. It can be called
2888 * from the "init" section, "post init" or during the runtime.
2889 *
2890 * Lua prototype:
2891 *
2892 * <none> core.register_task(<function>)
2893 */
2894static int hlua_register_task(lua_State *L)
2895{
2896 struct hlua *hlua;
2897 struct task *task;
2898 int ref;
2899
2900 MAY_LJMP(check_args(L, 1, "register_task"));
2901
2902 ref = MAY_LJMP(hlua_checkfunction(L, 1));
2903
2904 hlua = malloc(sizeof(*hlua));
2905 if (!hlua)
2906 WILL_LJMP(luaL_error(L, "lua out of memory error."));
2907
2908 task = task_new();
2909 task->context = hlua;
2910 task->process = hlua_process_task;
2911
2912 if (!hlua_ctx_init(hlua, task))
2913 WILL_LJMP(luaL_error(L, "lua out of memory error."));
2914
2915 /* Restore the function in the stack. */
2916 lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ref);
2917 hlua->nargs = 0;
2918
2919 /* Schedule task. */
2920 task_schedule(task, now_ms);
2921
2922 return 0;
2923}
2924
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01002925/* Wrapper called by HAProxy to execute an LUA converter. This wrapper
2926 * doesn't allow "yield" functions because the HAProxy engine cannot
2927 * resume converters.
2928 */
2929static int hlua_sample_conv_wrapper(struct session *session, const struct arg *arg_p,
2930 struct sample *smp, void *private)
2931{
2932 struct hlua_function *fcn = (struct hlua_function *)private;
2933
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01002934 /* In the execution wrappers linked with a session, the
2935 * Lua context can be not initialized. This behavior
2936 * permits to save performances because a systematic
2937 * Lua initialization cause 5% performances loss.
2938 */
2939 if (!session->hlua.T && !hlua_ctx_init(&session->hlua, session->task)) {
2940 send_log(session->be, LOG_ERR, "Lua converter '%s': can't initialize Lua context.", fcn->name);
2941 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
2942 Alert("Lua converter '%s': can't initialize Lua context.\n", fcn->name);
2943 return 0;
2944 }
2945
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01002946 /* If it is the first run, initialize the data for the call. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01002947 if (!HLUA_IS_RUNNING(&session->hlua)) {
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01002948 /* Check stack available size. */
2949 if (!lua_checkstack(session->hlua.T, 1)) {
2950 send_log(session->be, LOG_ERR, "Lua converter '%s': full stack.", fcn->name);
2951 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
2952 Alert("Lua converter '%s': full stack.\n", fcn->name);
2953 return 0;
2954 }
2955
2956 /* Restore the function in the stack. */
2957 lua_rawgeti(session->hlua.T, LUA_REGISTRYINDEX, fcn->function_ref);
2958
2959 /* convert input sample and pust-it in the stack. */
2960 if (!lua_checkstack(session->hlua.T, 1)) {
2961 send_log(session->be, LOG_ERR, "Lua converter '%s': full stack.", fcn->name);
2962 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
2963 Alert("Lua converter '%s': full stack.\n", fcn->name);
2964 return 0;
2965 }
2966 hlua_smp2lua(session->hlua.T, smp);
2967 session->hlua.nargs = 2;
2968
2969 /* push keywords in the stack. */
2970 if (arg_p) {
2971 for (; arg_p->type != ARGT_STOP; arg_p++) {
2972 if (!lua_checkstack(session->hlua.T, 1)) {
2973 send_log(session->be, LOG_ERR, "Lua converter '%s': full stack.", fcn->name);
2974 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
2975 Alert("Lua converter '%s': full stack.\n", fcn->name);
2976 return 0;
2977 }
2978 hlua_arg2lua(session->hlua.T, arg_p);
2979 session->hlua.nargs++;
2980 }
2981 }
2982
Thierry FOURNIERbd413492015-03-03 16:52:26 +01002983 /* We must initialize the execution timeouts. */
2984 session->hlua.expire = tick_add(now_ms, hlua_timeout_session);
2985
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01002986 /* Set the currently running flag. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01002987 HLUA_SET_RUN(&session->hlua);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01002988 }
2989
2990 /* Execute the function. */
2991 switch (hlua_ctx_resume(&session->hlua, 0)) {
2992 /* finished. */
2993 case HLUA_E_OK:
2994 /* Convert the returned value in sample. */
2995 hlua_lua2smp(session->hlua.T, -1, smp);
2996 lua_pop(session->hlua.T, 1);
2997 return 1;
2998
2999 /* yield. */
3000 case HLUA_E_AGAIN:
3001 send_log(session->be, LOG_ERR, "Lua converter '%s': cannot use yielded functions.", fcn->name);
3002 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3003 Alert("Lua converter '%s': cannot use yielded functions.\n", fcn->name);
3004 return 0;
3005
3006 /* finished with error. */
3007 case HLUA_E_ERRMSG:
3008 /* Display log. */
3009 send_log(session->be, LOG_ERR, "Lua converter '%s': %s.", fcn->name, lua_tostring(session->hlua.T, -1));
3010 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3011 Alert("Lua converter '%s': %s.\n", fcn->name, lua_tostring(session->hlua.T, -1));
3012 lua_pop(session->hlua.T, 1);
3013 return 0;
3014
3015 case HLUA_E_ERR:
3016 /* Display log. */
3017 send_log(session->be, LOG_ERR, "Lua converter '%s' returns an unknown error.", fcn->name);
3018 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3019 Alert("Lua converter '%s' returns an unknown error.\n", fcn->name);
3020
3021 default:
3022 return 0;
3023 }
3024}
3025
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003026/* Wrapper called by HAProxy to execute a sample-fetch. this wrapper
3027 * doesn't allow "yield" functions because the HAProxy engine cannot
3028 * resume sample-fetches.
3029 */
3030static int hlua_sample_fetch_wrapper(struct proxy *px, struct session *s, void *l7,
3031 unsigned int opt, const struct arg *arg_p,
3032 struct sample *smp, const char *kw, void *private)
3033{
3034 struct hlua_function *fcn = (struct hlua_function *)private;
3035
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01003036 /* In the execution wrappers linked with a session, the
3037 * Lua context can be not initialized. This behavior
3038 * permits to save performances because a systematic
3039 * Lua initialization cause 5% performances loss.
3040 */
3041 if (!s->hlua.T && !hlua_ctx_init(&s->hlua, s->task)) {
3042 send_log(s->be, LOG_ERR, "Lua sample-fetch '%s': can't initialize Lua context.", fcn->name);
3043 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3044 Alert("Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
3045 return 0;
3046 }
3047
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003048 /* If it is the first run, initialize the data for the call. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01003049 if (!HLUA_IS_RUNNING(&s->hlua)) {
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003050 /* Check stack available size. */
3051 if (!lua_checkstack(s->hlua.T, 2)) {
3052 send_log(px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
3053 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3054 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
3055 return 0;
3056 }
3057
3058 /* Restore the function in the stack. */
3059 lua_rawgeti(s->hlua.T, LUA_REGISTRYINDEX, fcn->function_ref);
3060
3061 /* push arguments in the stack. */
3062 if (!hlua_txn_new(s->hlua.T, s, px, l7)) {
3063 send_log(px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
3064 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3065 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
3066 return 0;
3067 }
3068 s->hlua.nargs = 1;
3069
3070 /* push keywords in the stack. */
3071 for (; arg_p && arg_p->type != ARGT_STOP; arg_p++) {
3072 /* Check stack available size. */
3073 if (!lua_checkstack(s->hlua.T, 1)) {
3074 send_log(px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
3075 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3076 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
3077 return 0;
3078 }
3079 if (!lua_checkstack(s->hlua.T, 1)) {
3080 send_log(px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
3081 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3082 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
3083 return 0;
3084 }
3085 hlua_arg2lua(s->hlua.T, arg_p);
3086 s->hlua.nargs++;
3087 }
3088
Thierry FOURNIERbd413492015-03-03 16:52:26 +01003089 /* We must initialize the execution timeouts. */
3090 s->hlua.expire = tick_add(now_ms, hlua_timeout_session);
3091
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003092 /* Set the currently running flag. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01003093 HLUA_SET_RUN(&s->hlua);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003094 }
3095
3096 /* Execute the function. */
3097 switch (hlua_ctx_resume(&s->hlua, 0)) {
3098 /* finished. */
3099 case HLUA_E_OK:
3100 /* Convert the returned value in sample. */
3101 hlua_lua2smp(s->hlua.T, -1, smp);
3102 lua_pop(s->hlua.T, 1);
3103
3104 /* Set the end of execution flag. */
3105 smp->flags &= ~SMP_F_MAY_CHANGE;
3106 return 1;
3107
3108 /* yield. */
3109 case HLUA_E_AGAIN:
3110 send_log(px, LOG_ERR, "Lua sample-fetch '%s': cannot use yielded functions.", fcn->name);
3111 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3112 Alert("Lua sample-fetch '%s': cannot use yielded functions.\n", fcn->name);
3113 return 0;
3114
3115 /* finished with error. */
3116 case HLUA_E_ERRMSG:
3117 /* Display log. */
3118 send_log(px, LOG_ERR, "Lua sample-fetch '%s': %s.", fcn->name, lua_tostring(s->hlua.T, -1));
3119 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3120 Alert("Lua sample-fetch '%s': %s.\n", fcn->name, lua_tostring(s->hlua.T, -1));
3121 lua_pop(s->hlua.T, 1);
3122 return 0;
3123
3124 case HLUA_E_ERR:
3125 /* Display log. */
3126 send_log(px, LOG_ERR, "Lua sample-fetch '%s' returns an unknown error.", fcn->name);
3127 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3128 Alert("Lua sample-fetch '%s': returns an unknown error.\n", fcn->name);
3129
3130 default:
3131 return 0;
3132 }
3133}
3134
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003135/* This function is an LUA binding used for registering
3136 * "sample-conv" functions. It expects a converter name used
3137 * in the haproxy configuration file, and an LUA function.
3138 */
3139__LJMP static int hlua_register_converters(lua_State *L)
3140{
3141 struct sample_conv_kw_list *sck;
3142 const char *name;
3143 int ref;
3144 int len;
3145 struct hlua_function *fcn;
3146
3147 MAY_LJMP(check_args(L, 2, "register_converters"));
3148
3149 /* First argument : converter name. */
3150 name = MAY_LJMP(luaL_checkstring(L, 1));
3151
3152 /* Second argument : lua function. */
3153 ref = MAY_LJMP(hlua_checkfunction(L, 2));
3154
3155 /* Allocate and fill the sample fetch keyword struct. */
3156 sck = malloc(sizeof(struct sample_conv_kw_list) +
3157 sizeof(struct sample_conv) * 2);
3158 if (!sck)
3159 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3160 fcn = malloc(sizeof(*fcn));
3161 if (!fcn)
3162 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3163
3164 /* Fill fcn. */
3165 fcn->name = strdup(name);
3166 if (!fcn->name)
3167 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3168 fcn->function_ref = ref;
3169
3170 /* List head */
3171 sck->list.n = sck->list.p = NULL;
3172
3173 /* converter keyword. */
3174 len = strlen("lua.") + strlen(name) + 1;
3175 sck->kw[0].kw = malloc(len);
3176 if (!sck->kw[0].kw)
3177 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3178
3179 snprintf((char *)sck->kw[0].kw, len, "lua.%s", name);
3180 sck->kw[0].process = hlua_sample_conv_wrapper;
3181 sck->kw[0].arg_mask = ARG5(0,STR,STR,STR,STR,STR);
3182 sck->kw[0].val_args = NULL;
3183 sck->kw[0].in_type = SMP_T_STR;
3184 sck->kw[0].out_type = SMP_T_STR;
3185 sck->kw[0].private = fcn;
3186
3187 /* End of array. */
3188 memset(&sck->kw[1], 0, sizeof(struct sample_conv));
3189
3190 /* Register this new converter */
3191 sample_register_convs(sck);
3192
3193 return 0;
3194}
3195
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003196/* This fucntion is an LUA binding used for registering
3197 * "sample-fetch" functions. It expects a converter name used
3198 * in the haproxy configuration file, and an LUA function.
3199 */
3200__LJMP static int hlua_register_fetches(lua_State *L)
3201{
3202 const char *name;
3203 int ref;
3204 int len;
3205 struct sample_fetch_kw_list *sfk;
3206 struct hlua_function *fcn;
3207
3208 MAY_LJMP(check_args(L, 2, "register_fetches"));
3209
3210 /* First argument : sample-fetch name. */
3211 name = MAY_LJMP(luaL_checkstring(L, 1));
3212
3213 /* Second argument : lua function. */
3214 ref = MAY_LJMP(hlua_checkfunction(L, 2));
3215
3216 /* Allocate and fill the sample fetch keyword struct. */
3217 sfk = malloc(sizeof(struct sample_fetch_kw_list) +
3218 sizeof(struct sample_fetch) * 2);
3219 if (!sfk)
3220 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3221 fcn = malloc(sizeof(*fcn));
3222 if (!fcn)
3223 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3224
3225 /* Fill fcn. */
3226 fcn->name = strdup(name);
3227 if (!fcn->name)
3228 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3229 fcn->function_ref = ref;
3230
3231 /* List head */
3232 sfk->list.n = sfk->list.p = NULL;
3233
3234 /* sample-fetch keyword. */
3235 len = strlen("lua.") + strlen(name) + 1;
3236 sfk->kw[0].kw = malloc(len);
3237 if (!sfk->kw[0].kw)
3238 return luaL_error(L, "lua out of memory error.");
3239
3240 snprintf((char *)sfk->kw[0].kw, len, "lua.%s", name);
3241 sfk->kw[0].process = hlua_sample_fetch_wrapper;
3242 sfk->kw[0].arg_mask = ARG5(0,STR,STR,STR,STR,STR);
3243 sfk->kw[0].val_args = NULL;
3244 sfk->kw[0].out_type = SMP_T_STR;
3245 sfk->kw[0].use = SMP_USE_HTTP_ANY;
3246 sfk->kw[0].val = 0;
3247 sfk->kw[0].private = fcn;
3248
3249 /* End of array. */
3250 memset(&sfk->kw[1], 0, sizeof(struct sample_fetch));
3251
3252 /* Register this new fetch. */
3253 sample_register_fetches(sfk);
3254
3255 return 0;
3256}
3257
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003258/* global {tcp|http}-request parser. Return 1 in succes case, else return 0. */
3259static int hlua_parse_rule(const char **args, int *cur_arg, struct proxy *px,
3260 struct hlua_rule **rule_p, char **err)
3261{
3262 struct hlua_rule *rule;
3263
3264 /* Memory for the rule. */
3265 rule = malloc(sizeof(*rule));
3266 if (!rule) {
3267 memprintf(err, "out of memory error");
3268 return 0;
3269 }
3270 *rule_p = rule;
3271
3272 /* The requiered arg is a function name. */
3273 if (!args[*cur_arg]) {
3274 memprintf(err, "expect Lua function name");
3275 return 0;
3276 }
3277
3278 /* Lookup for the symbol, and check if it is a function. */
3279 lua_getglobal(gL.T, args[*cur_arg]);
3280 if (lua_isnil(gL.T, -1)) {
3281 lua_pop(gL.T, 1);
3282 memprintf(err, "Lua function '%s' not found", args[*cur_arg]);
3283 return 0;
3284 }
3285 if (!lua_isfunction(gL.T, -1)) {
3286 lua_pop(gL.T, 1);
3287 memprintf(err, "'%s' is not a function", args[*cur_arg]);
3288 return 0;
3289 }
3290
3291 /* Reference the Lua function and store the reference. */
3292 rule->fcn.function_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
3293 rule->fcn.name = strdup(args[*cur_arg]);
3294 if (!rule->fcn.name) {
3295 memprintf(err, "out of memory error.");
3296 return 0;
3297 }
3298 (*cur_arg)++;
3299
3300 /* TODO: later accept arguments. */
3301 rule->args = NULL;
3302
3303 return 1;
3304}
3305
3306/* This function is a wrapper to execute each LUA function declared
3307 * as an action wrapper during the initialisation period. This function
3308 * return 1 if the processing is finished (with oe without error) and
3309 * return 0 if the function must be called again because the LUA
3310 * returns a yield.
3311 */
3312static int hlua_request_act_wrapper(struct hlua_rule *rule, struct proxy *px,
3313 struct session *s, struct http_txn *http_txn,
3314 unsigned int analyzer)
3315{
3316 char **arg;
3317
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01003318 /* In the execution wrappers linked with a session, the
3319 * Lua context can be not initialized. This behavior
3320 * permits to save performances because a systematic
3321 * Lua initialization cause 5% performances loss.
3322 */
3323 if (!s->hlua.T && !hlua_ctx_init(&s->hlua, s->task)) {
3324 send_log(px, LOG_ERR, "Lua action '%s': can't initialize Lua context.", rule->fcn.name);
3325 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3326 Alert("Lua action '%s': can't initialize Lua context.\n", rule->fcn.name);
3327 return 0;
3328 }
3329
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003330 /* If it is the first run, initialize the data for the call. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01003331 if (!HLUA_IS_RUNNING(&s->hlua)) {
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003332 /* Check stack available size. */
3333 if (!lua_checkstack(s->hlua.T, 1)) {
3334 send_log(px, LOG_ERR, "Lua function '%s': full stack.", rule->fcn.name);
3335 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3336 Alert("Lua function '%s': full stack.\n", rule->fcn.name);
3337 return 0;
3338 }
3339
3340 /* Restore the function in the stack. */
3341 lua_rawgeti(s->hlua.T, LUA_REGISTRYINDEX, rule->fcn.function_ref);
3342
3343 /* Create and and push object session in the stack. */
3344 if (!hlua_txn_new(s->hlua.T, s, px, http_txn)) {
3345 send_log(px, LOG_ERR, "Lua function '%s': full stack.", rule->fcn.name);
3346 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3347 Alert("Lua function '%s': full stack.\n", rule->fcn.name);
3348 return 0;
3349 }
3350 s->hlua.nargs = 1;
3351
3352 /* push keywords in the stack. */
3353 for (arg = rule->args; arg && *arg; arg++) {
3354 if (!lua_checkstack(s->hlua.T, 1)) {
3355 send_log(px, LOG_ERR, "Lua function '%s': full stack.", rule->fcn.name);
3356 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3357 Alert("Lua function '%s': full stack.\n", rule->fcn.name);
3358 return 0;
3359 }
3360 lua_pushstring(s->hlua.T, *arg);
3361 s->hlua.nargs++;
3362 }
3363
Thierry FOURNIERbd413492015-03-03 16:52:26 +01003364 /* We must initialize the execution timeouts. */
3365 s->hlua.expire = tick_add(now_ms, hlua_timeout_session);
3366
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003367 /* Set the currently running flag. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01003368 HLUA_SET_RUN(&s->hlua);
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003369 }
3370
3371 /* Execute the function. */
3372 switch (hlua_ctx_resume(&s->hlua, 1)) {
3373 /* finished. */
3374 case HLUA_E_OK:
3375 return 1;
3376
3377 /* yield. */
3378 case HLUA_E_AGAIN:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01003379 /* Set timeout in the required channel. */
3380 if (s->hlua.wake_time != TICK_ETERNITY) {
3381 if (analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE))
3382 s->req->analyse_exp = s->hlua.wake_time;
3383 else if (analyzer & (AN_RES_INSPECT|AN_RES_HTTP_PROCESS_BE))
3384 s->rep->analyse_exp = s->hlua.wake_time;
3385 }
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003386 /* Some actions can be wake up when a "write" event
3387 * is detected on a response channel. This is useful
3388 * only for actions targetted on the requests.
3389 */
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01003390 if (HLUA_IS_WAKERESWR(&s->hlua)) {
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003391 s->rep->flags |= CF_WAKE_WRITE;
Willy Tarreau76bd97f2015-03-10 17:16:10 +01003392 if ((analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE)))
3393 s->rep->analysers |= analyzer;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003394 }
Thierry FOURNIER53e08ec2015-03-06 00:35:53 +01003395 if (HLUA_IS_WAKEREQWR(&s->hlua))
3396 s->req->flags |= CF_WAKE_WRITE;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003397 return 0;
3398
3399 /* finished with error. */
3400 case HLUA_E_ERRMSG:
3401 /* Display log. */
3402 send_log(px, LOG_ERR, "Lua function '%s': %s.", rule->fcn.name, lua_tostring(s->hlua.T, -1));
3403 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3404 Alert("Lua function '%s': %s.\n", rule->fcn.name, lua_tostring(s->hlua.T, -1));
3405 lua_pop(s->hlua.T, 1);
3406 return 1;
3407
3408 case HLUA_E_ERR:
3409 /* Display log. */
3410 send_log(px, LOG_ERR, "Lua function '%s' return an unknown error.", rule->fcn.name);
3411 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3412 Alert("Lua function '%s' return an unknown error.\n", rule->fcn.name);
3413
3414 default:
3415 return 1;
3416 }
3417}
3418
3419/* Lua execution wrapper for "tcp-request". This function uses
3420 * "hlua_request_act_wrapper" for executing the LUA code.
3421 */
3422int hlua_tcp_req_act_wrapper(struct tcp_rule *tcp_rule, struct proxy *px,
3423 struct session *s)
3424{
3425 return hlua_request_act_wrapper((struct hlua_rule *)tcp_rule->act_prm.data,
3426 px, s, NULL, AN_REQ_INSPECT_FE);
3427}
3428
3429/* Lua execution wrapper for "tcp-response". This function uses
3430 * "hlua_request_act_wrapper" for executing the LUA code.
3431 */
3432int hlua_tcp_res_act_wrapper(struct tcp_rule *tcp_rule, struct proxy *px,
3433 struct session *s)
3434{
3435 return hlua_request_act_wrapper((struct hlua_rule *)tcp_rule->act_prm.data,
3436 px, s, NULL, AN_RES_INSPECT);
3437}
3438
3439/* Lua execution wrapper for http-request.
3440 * This function uses "hlua_request_act_wrapper" for executing
3441 * the LUA code.
3442 */
3443int hlua_http_req_act_wrapper(struct http_req_rule *rule, struct proxy *px,
3444 struct session *s, struct http_txn *http_txn)
3445{
3446 return hlua_request_act_wrapper((struct hlua_rule *)rule->arg.data, px,
3447 s, http_txn, AN_REQ_HTTP_PROCESS_FE);
3448}
3449
3450/* Lua execution wrapper for http-response.
3451 * This function uses "hlua_request_act_wrapper" for executing
3452 * the LUA code.
3453 */
3454int hlua_http_res_act_wrapper(struct http_res_rule *rule, struct proxy *px,
3455 struct session *s, struct http_txn *http_txn)
3456{
3457 return hlua_request_act_wrapper((struct hlua_rule *)rule->arg.data, px,
3458 s, http_txn, AN_RES_HTTP_PROCESS_BE);
3459}
3460
3461/* tcp-request <*> configuration wrapper. */
3462static int tcp_req_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
3463 struct tcp_rule *rule, char **err)
3464{
3465 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->act_prm.data, err))
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003466 return 0;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003467 rule->action = TCP_ACT_CUSTOM;
3468 rule->action_ptr = hlua_tcp_req_act_wrapper;
3469 return 1;
3470}
3471
3472/* tcp-response <*> configuration wrapper. */
3473static int tcp_res_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
3474 struct tcp_rule *rule, char **err)
3475{
3476 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->act_prm.data, err))
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003477 return 0;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003478 rule->action = TCP_ACT_CUSTOM;
3479 rule->action_ptr = hlua_tcp_res_act_wrapper;
3480 return 1;
3481}
3482
3483/* http-request <*> configuration wrapper. */
3484static int http_req_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
3485 struct http_req_rule *rule, char **err)
3486{
3487 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->arg.data, err))
3488 return -1;
3489 rule->action = HTTP_REQ_ACT_CUSTOM_CONT;
3490 rule->action_ptr = hlua_http_req_act_wrapper;
3491 return 1;
3492}
3493
3494/* http-response <*> configuration wrapper. */
3495static int http_res_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
3496 struct http_res_rule *rule, char **err)
3497{
3498 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->arg.data, err))
3499 return -1;
3500 rule->action = HTTP_RES_ACT_CUSTOM_CONT;
3501 rule->action_ptr = hlua_http_res_act_wrapper;
3502 return 1;
3503}
3504
Thierry FOURNIERbd413492015-03-03 16:52:26 +01003505static int hlua_read_timeout(char **args, int section_type, struct proxy *curpx,
3506 struct proxy *defpx, const char *file, int line,
3507 char **err, unsigned int *timeout)
3508{
3509 const char *error;
3510
3511 error = parse_time_err(args[1], timeout, TIME_UNIT_MS);
3512 if (error && *error != '\0') {
3513 memprintf(err, "%s: invalid timeout", args[0]);
3514 return -1;
3515 }
3516 return 0;
3517}
3518
3519static int hlua_session_timeout(char **args, int section_type, struct proxy *curpx,
3520 struct proxy *defpx, const char *file, int line,
3521 char **err)
3522{
3523 return hlua_read_timeout(args, section_type, curpx, defpx,
3524 file, line, err, &hlua_timeout_session);
3525}
3526
3527static int hlua_task_timeout(char **args, int section_type, struct proxy *curpx,
3528 struct proxy *defpx, const char *file, int line,
3529 char **err)
3530{
3531 return hlua_read_timeout(args, section_type, curpx, defpx,
3532 file, line, err, &hlua_timeout_task);
3533}
3534
Thierry FOURNIERee9f8022015-03-03 17:37:37 +01003535static int hlua_forced_yield(char **args, int section_type, struct proxy *curpx,
3536 struct proxy *defpx, const char *file, int line,
3537 char **err)
3538{
3539 char *error;
3540
3541 hlua_nb_instruction = strtoll(args[1], &error, 10);
3542 if (*error != '\0') {
3543 memprintf(err, "%s: invalid number", args[0]);
3544 return -1;
3545 }
3546 return 0;
3547}
3548
Thierry FOURNIER6c9b52c2015-01-23 15:57:06 +01003549/* This function is called by the main configuration key "lua-load". It loads and
3550 * execute an lua file during the parsing of the HAProxy configuration file. It is
3551 * the main lua entry point.
3552 *
3553 * This funtion runs with the HAProxy keywords API. It returns -1 if an error is
3554 * occured, otherwise it returns 0.
3555 *
3556 * In some error case, LUA set an error message in top of the stack. This function
3557 * returns this error message in the HAProxy logs and pop it from the stack.
3558 */
3559static int hlua_load(char **args, int section_type, struct proxy *curpx,
3560 struct proxy *defpx, const char *file, int line,
3561 char **err)
3562{
3563 int error;
3564
3565 /* Just load and compile the file. */
3566 error = luaL_loadfile(gL.T, args[1]);
3567 if (error) {
3568 memprintf(err, "error in lua file '%s': %s", args[1], lua_tostring(gL.T, -1));
3569 lua_pop(gL.T, 1);
3570 return -1;
3571 }
3572
3573 /* If no syntax error where detected, execute the code. */
3574 error = lua_pcall(gL.T, 0, LUA_MULTRET, 0);
3575 switch (error) {
3576 case LUA_OK:
3577 break;
3578 case LUA_ERRRUN:
3579 memprintf(err, "lua runtime error: %s\n", lua_tostring(gL.T, -1));
3580 lua_pop(gL.T, 1);
3581 return -1;
3582 case LUA_ERRMEM:
3583 memprintf(err, "lua out of memory error\n");
3584 return -1;
3585 case LUA_ERRERR:
3586 memprintf(err, "lua message handler error: %s\n", lua_tostring(gL.T, -1));
3587 lua_pop(gL.T, 1);
3588 return -1;
3589 case LUA_ERRGCMM:
3590 memprintf(err, "lua garbage collector error: %s\n", lua_tostring(gL.T, -1));
3591 lua_pop(gL.T, 1);
3592 return -1;
3593 default:
3594 memprintf(err, "lua unknonwn error: %s\n", lua_tostring(gL.T, -1));
3595 lua_pop(gL.T, 1);
3596 return -1;
3597 }
3598
3599 return 0;
3600}
3601
3602/* configuration keywords declaration */
3603static struct cfg_kw_list cfg_kws = {{ },{
Thierry FOURNIERbd413492015-03-03 16:52:26 +01003604 { CFG_GLOBAL, "lua-load", hlua_load },
3605 { CFG_GLOBAL, "tune.lua.session-timeout", hlua_session_timeout },
3606 { CFG_GLOBAL, "tune.lua.task-timeout", hlua_task_timeout },
Thierry FOURNIERee9f8022015-03-03 17:37:37 +01003607 { CFG_GLOBAL, "tune.lua.forced-yield", hlua_forced_yield },
Thierry FOURNIER6c9b52c2015-01-23 15:57:06 +01003608 { 0, NULL, NULL },
3609}};
3610
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003611static struct http_req_action_kw_list http_req_kws = {"lua", { }, {
3612 { "lua", http_req_action_register_lua },
3613 { NULL, NULL }
3614}};
3615
3616static struct http_res_action_kw_list http_res_kws = {"lua", { }, {
3617 { "lua", http_res_action_register_lua },
3618 { NULL, NULL }
3619}};
3620
3621static struct tcp_action_kw_list tcp_req_cont_kws = {"lua", { }, {
3622 { "lua", tcp_req_action_register_lua },
3623 { NULL, NULL }
3624}};
3625
3626static struct tcp_action_kw_list tcp_res_cont_kws = {"lua", { }, {
3627 { "lua", tcp_res_action_register_lua },
3628 { NULL, NULL }
3629}};
3630
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01003631int hlua_post_init()
3632{
3633 struct hlua_init_function *init;
3634 const char *msg;
3635 enum hlua_exec ret;
3636
3637 list_for_each_entry(init, &hlua_init_functions, l) {
3638 lua_rawgeti(gL.T, LUA_REGISTRYINDEX, init->function_ref);
3639 ret = hlua_ctx_resume(&gL, 0);
3640 switch (ret) {
3641 case HLUA_E_OK:
3642 lua_pop(gL.T, -1);
3643 return 1;
3644 case HLUA_E_AGAIN:
3645 Alert("lua init: yield not allowed.\n");
3646 return 0;
3647 case HLUA_E_ERRMSG:
3648 msg = lua_tostring(gL.T, -1);
3649 Alert("lua init: %s.\n", msg);
3650 return 0;
3651 case HLUA_E_ERR:
3652 default:
3653 Alert("lua init: unknown runtime error.\n");
3654 return 0;
3655 }
3656 }
3657 return 1;
3658}
3659
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +01003660void hlua_init(void)
3661{
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01003662 int i;
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01003663 int idx;
3664 struct sample_fetch *sf;
3665 struct hlua_sample_fetch *hsf;
3666 char *p;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003667#ifdef USE_OPENSSL
3668 char *args[4];
3669 struct srv_kw *kw;
3670 int tmp_error;
3671 char *error;
3672#endif
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01003673
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01003674 /* Initialise com signals pool session. */
3675 pool2_hlua_com = create_pool("hlua_com", sizeof(struct hlua_com), MEM_F_SHARED);
3676
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003677 /* Initialise sleep pool. */
3678 pool2_hlua_sleep = create_pool("hlua_sleep", sizeof(struct hlua_sleep), MEM_F_SHARED);
3679
Thierry FOURNIER6c9b52c2015-01-23 15:57:06 +01003680 /* Register configuration keywords. */
3681 cfg_register_keywords(&cfg_kws);
3682
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01003683 /* Register custom HTTP rules. */
3684 http_req_keywords_register(&http_req_kws);
3685 http_res_keywords_register(&http_res_kws);
3686 tcp_req_cont_keywords_register(&tcp_req_cont_kws);
3687 tcp_res_cont_keywords_register(&tcp_res_cont_kws);
3688
Thierry FOURNIER380d0932015-01-23 14:27:52 +01003689 /* Init main lua stack. */
3690 gL.Mref = LUA_REFNIL;
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01003691 gL.flags = 0;
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01003692 LIST_INIT(&gL.com);
Thierry FOURNIER380d0932015-01-23 14:27:52 +01003693 gL.T = luaL_newstate();
3694 hlua_sethlua(&gL);
3695 gL.Tref = LUA_REFNIL;
3696 gL.task = NULL;
3697
3698 /* Initialise lua. */
3699 luaL_openlibs(gL.T);
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01003700
3701 /*
3702 *
3703 * Create "core" object.
3704 *
3705 */
3706
Thierry FOURNIERa2d8c652015-03-11 17:29:39 +01003707 /* This table entry is the object "core" base. */
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01003708 lua_newtable(gL.T);
3709
3710 /* Push the loglevel constants. */
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003711 for (i = 0; i < NB_LOG_LEVELS; i++)
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01003712 hlua_class_const_int(gL.T, log_levels[i], i);
3713
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01003714 /* Register special functions. */
3715 hlua_class_function(gL.T, "register_init", hlua_register_init);
Thierry FOURNIER24f33532015-01-23 12:13:00 +01003716 hlua_class_function(gL.T, "register_task", hlua_register_task);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003717 hlua_class_function(gL.T, "register_fetches", hlua_register_fetches);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003718 hlua_class_function(gL.T, "register_converters", hlua_register_converters);
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01003719 hlua_class_function(gL.T, "yield", hlua_yield);
Willy Tarreau59551662015-03-10 14:23:13 +01003720 hlua_class_function(gL.T, "set_nice", hlua_set_nice);
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003721 hlua_class_function(gL.T, "sleep", hlua_sleep);
3722 hlua_class_function(gL.T, "msleep", hlua_msleep);
Thierry FOURNIER83758bb2015-02-04 13:21:04 +01003723 hlua_class_function(gL.T, "add_acl", hlua_add_acl);
3724 hlua_class_function(gL.T, "del_acl", hlua_del_acl);
3725 hlua_class_function(gL.T, "set_map", hlua_set_map);
3726 hlua_class_function(gL.T, "del_map", hlua_del_map);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01003727 hlua_class_function(gL.T, "tcp", hlua_socket_new);
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01003728
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01003729 lua_setglobal(gL.T, "core");
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003730
3731 /*
3732 *
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01003733 * Register class Channel
3734 *
3735 */
3736
3737 /* Create and fill the metatable. */
3738 lua_newtable(gL.T);
3739
3740 /* Create and fille the __index entry. */
3741 lua_pushstring(gL.T, "__index");
3742 lua_newtable(gL.T);
3743
3744 /* Register . */
3745 hlua_class_function(gL.T, "get", hlua_channel_get);
3746 hlua_class_function(gL.T, "dup", hlua_channel_dup);
3747 hlua_class_function(gL.T, "getline", hlua_channel_getline);
3748 hlua_class_function(gL.T, "set", hlua_channel_set);
3749 hlua_class_function(gL.T, "append", hlua_channel_append);
3750 hlua_class_function(gL.T, "send", hlua_channel_send);
3751 hlua_class_function(gL.T, "forward", hlua_channel_forward);
3752 hlua_class_function(gL.T, "get_in_len", hlua_channel_get_in_len);
3753 hlua_class_function(gL.T, "get_out_len", hlua_channel_get_out_len);
3754
3755 lua_settable(gL.T, -3);
3756
3757 /* Register previous table in the registry with reference and named entry. */
3758 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
3759 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_CHANNEL); /* register class session. */
3760 class_channel_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
3761
3762 /*
3763 *
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003764 * Register class TXN
3765 *
3766 */
3767
3768 /* Create and fill the metatable. */
3769 lua_newtable(gL.T);
3770
3771 /* Create and fille the __index entry. */
3772 lua_pushstring(gL.T, "__index");
3773 lua_newtable(gL.T);
3774
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01003775 /* Browse existing fetches and create the associated
3776 * object method.
3777 */
3778 sf = NULL;
3779 while ((sf = sample_fetch_getnext(sf, &idx)) != NULL) {
3780
3781 /* Dont register the keywork if the arguments check function are
3782 * not safe during the runtime.
3783 */
3784 if ((sf->val_args != NULL) &&
3785 (sf->val_args != val_payload_lv) &&
3786 (sf->val_args != val_hdr))
3787 continue;
3788
3789 /* gL.Tua doesn't support '.' and '-' in the function names, replace it
3790 * by an underscore.
3791 */
3792 strncpy(trash.str, sf->kw, trash.size);
3793 trash.str[trash.size - 1] = '\0';
3794 for (p = trash.str; *p; p++)
3795 if (*p == '.' || *p == '-' || *p == '+')
3796 *p = '_';
3797
3798 /* Register the function. */
3799 lua_pushstring(gL.T, trash.str);
3800 hsf = lua_newuserdata(gL.T, sizeof(struct hlua_sample_fetch));
3801 hsf->f = sf;
3802 lua_pushcclosure(gL.T, hlua_run_sample_fetch, 1);
3803 lua_settable(gL.T, -3);
3804 }
3805
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003806 /* Register Lua functions. */
Willy Tarreau59551662015-03-10 14:23:13 +01003807 hlua_class_function(gL.T, "get_headers", hlua_session_get_headers);
3808 hlua_class_function(gL.T, "set_priv", hlua_set_priv);
3809 hlua_class_function(gL.T, "get_priv", hlua_get_priv);
Thierry FOURNIERe94e7742015-02-17 14:59:53 +01003810 hlua_class_function(gL.T, "req_channel", hlua_txn_req_channel);
3811 hlua_class_function(gL.T, "res_channel", hlua_txn_res_channel);
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003812 hlua_class_function(gL.T, "close", hlua_txn_close);
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003813
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003814 lua_settable(gL.T, -3);
3815
3816 /* Register previous table in the registry with reference and named entry. */
3817 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
3818 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_TXN); /* register class session. */
3819 class_txn_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01003820
3821 /*
3822 *
3823 * Register class Socket
3824 *
3825 */
3826
3827 /* Create and fill the metatable. */
3828 lua_newtable(gL.T);
3829
3830 /* Create and fille the __index entry. */
3831 lua_pushstring(gL.T, "__index");
3832 lua_newtable(gL.T);
3833
Baptiste Assmann84bb4932015-03-02 21:40:06 +01003834#ifdef USE_OPENSSL
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01003835 hlua_class_function(gL.T, "connect_ssl", hlua_socket_connect_ssl);
Baptiste Assmann84bb4932015-03-02 21:40:06 +01003836#endif
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01003837 hlua_class_function(gL.T, "connect", hlua_socket_connect);
3838 hlua_class_function(gL.T, "send", hlua_socket_send);
3839 hlua_class_function(gL.T, "receive", hlua_socket_receive);
3840 hlua_class_function(gL.T, "close", hlua_socket_close);
3841 hlua_class_function(gL.T, "getpeername", hlua_socket_getpeername);
3842 hlua_class_function(gL.T, "getsockname", hlua_socket_getsockname);
3843 hlua_class_function(gL.T, "setoption", hlua_socket_setoption);
3844 hlua_class_function(gL.T, "settimeout", hlua_socket_settimeout);
3845
3846 lua_settable(gL.T, -3); /* Push the last 2 entries in the table at index -3 */
3847
3848 /* Register the garbage collector entry. */
3849 lua_pushstring(gL.T, "__gc");
3850 lua_pushcclosure(gL.T, hlua_socket_gc, 0);
3851 lua_settable(gL.T, -3); /* Push the last 2 entries in the table at index -3 */
3852
3853 /* Register previous table in the registry with reference and named entry. */
3854 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
3855 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
3856 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_SOCKET); /* register class socket. */
3857 class_socket_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class socket. */
3858
3859 /* Proxy and server configuration initialisation. */
3860 memset(&socket_proxy, 0, sizeof(socket_proxy));
3861 init_new_proxy(&socket_proxy);
3862 socket_proxy.parent = NULL;
3863 socket_proxy.last_change = now.tv_sec;
3864 socket_proxy.id = "LUA-SOCKET";
3865 socket_proxy.cap = PR_CAP_FE | PR_CAP_BE;
3866 socket_proxy.maxconn = 0;
3867 socket_proxy.accept = NULL;
3868 socket_proxy.options2 |= PR_O2_INDEPSTR;
3869 socket_proxy.srv = NULL;
3870 socket_proxy.conn_retries = 0;
3871 socket_proxy.timeout.connect = 5000; /* By default the timeout connection is 5s. */
3872
3873 /* Init TCP server: unchanged parameters */
3874 memset(&socket_tcp, 0, sizeof(socket_tcp));
3875 socket_tcp.next = NULL;
3876 socket_tcp.proxy = &socket_proxy;
3877 socket_tcp.obj_type = OBJ_TYPE_SERVER;
3878 LIST_INIT(&socket_tcp.actconns);
3879 LIST_INIT(&socket_tcp.pendconns);
3880 socket_tcp.state = SRV_ST_RUNNING; /* early server setup */
3881 socket_tcp.last_change = 0;
3882 socket_tcp.id = "LUA-TCP-CONN";
3883 socket_tcp.check.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
3884 socket_tcp.agent.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
3885 socket_tcp.pp_opts = 0; /* Remove proxy protocol. */
3886
3887 /* XXX: Copy default parameter from default server,
3888 * but the default server is not initialized.
3889 */
3890 socket_tcp.maxqueue = socket_proxy.defsrv.maxqueue;
3891 socket_tcp.minconn = socket_proxy.defsrv.minconn;
3892 socket_tcp.maxconn = socket_proxy.defsrv.maxconn;
3893 socket_tcp.slowstart = socket_proxy.defsrv.slowstart;
3894 socket_tcp.onerror = socket_proxy.defsrv.onerror;
3895 socket_tcp.onmarkeddown = socket_proxy.defsrv.onmarkeddown;
3896 socket_tcp.onmarkedup = socket_proxy.defsrv.onmarkedup;
3897 socket_tcp.consecutive_errors_limit = socket_proxy.defsrv.consecutive_errors_limit;
3898 socket_tcp.uweight = socket_proxy.defsrv.iweight;
3899 socket_tcp.iweight = socket_proxy.defsrv.iweight;
3900
3901 socket_tcp.check.status = HCHK_STATUS_INI;
3902 socket_tcp.check.rise = socket_proxy.defsrv.check.rise;
3903 socket_tcp.check.fall = socket_proxy.defsrv.check.fall;
3904 socket_tcp.check.health = socket_tcp.check.rise; /* socket, but will fall down at first failure */
3905 socket_tcp.check.server = &socket_tcp;
3906
3907 socket_tcp.agent.status = HCHK_STATUS_INI;
3908 socket_tcp.agent.rise = socket_proxy.defsrv.agent.rise;
3909 socket_tcp.agent.fall = socket_proxy.defsrv.agent.fall;
3910 socket_tcp.agent.health = socket_tcp.agent.rise; /* socket, but will fall down at first failure */
3911 socket_tcp.agent.server = &socket_tcp;
3912
3913 socket_tcp.xprt = &raw_sock;
3914
3915#ifdef USE_OPENSSL
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01003916 /* Init TCP server: unchanged parameters */
3917 memset(&socket_ssl, 0, sizeof(socket_ssl));
3918 socket_ssl.next = NULL;
3919 socket_ssl.proxy = &socket_proxy;
3920 socket_ssl.obj_type = OBJ_TYPE_SERVER;
3921 LIST_INIT(&socket_ssl.actconns);
3922 LIST_INIT(&socket_ssl.pendconns);
3923 socket_ssl.state = SRV_ST_RUNNING; /* early server setup */
3924 socket_ssl.last_change = 0;
3925 socket_ssl.id = "LUA-SSL-CONN";
3926 socket_ssl.check.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
3927 socket_ssl.agent.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
3928 socket_ssl.pp_opts = 0; /* Remove proxy protocol. */
3929
3930 /* XXX: Copy default parameter from default server,
3931 * but the default server is not initialized.
3932 */
3933 socket_ssl.maxqueue = socket_proxy.defsrv.maxqueue;
3934 socket_ssl.minconn = socket_proxy.defsrv.minconn;
3935 socket_ssl.maxconn = socket_proxy.defsrv.maxconn;
3936 socket_ssl.slowstart = socket_proxy.defsrv.slowstart;
3937 socket_ssl.onerror = socket_proxy.defsrv.onerror;
3938 socket_ssl.onmarkeddown = socket_proxy.defsrv.onmarkeddown;
3939 socket_ssl.onmarkedup = socket_proxy.defsrv.onmarkedup;
3940 socket_ssl.consecutive_errors_limit = socket_proxy.defsrv.consecutive_errors_limit;
3941 socket_ssl.uweight = socket_proxy.defsrv.iweight;
3942 socket_ssl.iweight = socket_proxy.defsrv.iweight;
3943
3944 socket_ssl.check.status = HCHK_STATUS_INI;
3945 socket_ssl.check.rise = socket_proxy.defsrv.check.rise;
3946 socket_ssl.check.fall = socket_proxy.defsrv.check.fall;
3947 socket_ssl.check.health = socket_ssl.check.rise; /* socket, but will fall down at first failure */
3948 socket_ssl.check.server = &socket_ssl;
3949
3950 socket_ssl.agent.status = HCHK_STATUS_INI;
3951 socket_ssl.agent.rise = socket_proxy.defsrv.agent.rise;
3952 socket_ssl.agent.fall = socket_proxy.defsrv.agent.fall;
3953 socket_ssl.agent.health = socket_ssl.agent.rise; /* socket, but will fall down at first failure */
3954 socket_ssl.agent.server = &socket_ssl;
3955
3956 socket_ssl.xprt = &raw_sock;
3957
3958 args[0] = "ssl";
3959 args[1] = "verify";
3960 args[2] = "none";
3961 args[3] = NULL;
3962
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003963 for (idx = 0; idx < 3; idx++) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01003964 if ((kw = srv_find_kw(args[idx])) != NULL) { /* Maybe it's registered server keyword */
3965 /*
3966 *
3967 * If the keyword is not known, we can search in the registered
3968 * server keywords. This is usefull to configure special SSL
3969 * features like client certificates and ssl_verify.
3970 *
3971 */
3972 tmp_error = kw->parse(args, &idx, &socket_proxy, &socket_ssl, &error);
3973 if (tmp_error != 0) {
3974 fprintf(stderr, "INTERNAL ERROR: %s\n", error);
3975 abort(); /* This must be never arrives because the command line
3976 not editable by the user. */
3977 }
3978 idx += kw->skip;
3979 }
3980 }
3981
3982 /* Initialize SSL server. */
3983 if (socket_ssl.xprt == &ssl_sock) {
3984 socket_ssl.use_ssl = 1;
3985 ssl_sock_prepare_srv_ctx(&socket_ssl, &socket_proxy);
3986 }
3987#endif
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +01003988}