blob: a13b8ce1d50d54841899175cc5620cbddaf303a8 [file] [log] [blame]
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001#include <sys/socket.h>
2
Thierry FOURNIERc798b5d2015-03-17 01:09:57 +01003#include <ctype.h>
4
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +01005#include <lauxlib.h>
6#include <lua.h>
7#include <lualib.h>
8
Thierry FOURNIER463119c2015-03-10 00:35:36 +01009#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 503
10#error "Requires Lua 5.3 or later."
Cyril Bontédc0306e2015-03-02 00:08:40 +010011#endif
12
Thierry FOURNIER380d0932015-01-23 14:27:52 +010013#include <ebpttree.h>
14
15#include <common/cfgparse.h>
16
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010017#include <types/connection.h>
Thierry FOURNIER380d0932015-01-23 14:27:52 +010018#include <types/hlua.h>
Thierry FOURNIER65f34c62015-02-16 20:11:43 +010019#include <types/proto_tcp.h>
Thierry FOURNIER380d0932015-01-23 14:27:52 +010020#include <types/proxy.h>
21
Thierry FOURNIER55da1652015-01-23 11:36:30 +010022#include <proto/arg.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010023#include <proto/channel.h>
Thierry FOURNIER9a819e72015-02-16 20:22:55 +010024#include <proto/hdr_idx.h>
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +010025#include <proto/hlua.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010026#include <proto/obj_type.h>
Thierry FOURNIER83758bb2015-02-04 13:21:04 +010027#include <proto/pattern.h>
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +010028#include <proto/payload.h>
29#include <proto/proto_http.h>
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +010030#include <proto/proto_tcp.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010031#include <proto/raw_sock.h>
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +010032#include <proto/sample.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010033#include <proto/server.h>
Willy Tarreau87b09662015-04-03 00:22:06 +020034#include <proto/stream.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010035#include <proto/ssl_sock.h>
36#include <proto/stream_interface.h>
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +010037#include <proto/task.h>
38
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +010039/* Lua uses longjmp to perform yield or throwing errors. This
40 * macro is used only for identifying the function that can
41 * not return because a longjmp is executed.
42 * __LJMP marks a prototype of hlua file that can use longjmp.
43 * WILL_LJMP() marks an lua function that will use longjmp.
44 * MAY_LJMP() marks an lua function that may use longjmp.
45 */
46#define __LJMP
47#define WILL_LJMP(func) func
48#define MAY_LJMP(func) func
49
Thierry FOURNIER380d0932015-01-23 14:27:52 +010050/* The main Lua execution context. */
51struct hlua gL;
52
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +010053/* This is the memory pool containing all the signal structs. These
54 * struct are used to store each requiered signal between two tasks.
55 */
56struct pool_head *pool2_hlua_com;
57
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010058/* Used for Socket connection. */
59static struct proxy socket_proxy;
60static struct server socket_tcp;
61#ifdef USE_OPENSSL
62static struct server socket_ssl;
63#endif
64
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +010065/* List head of the function called at the initialisation time. */
66struct list hlua_init_functions = LIST_HEAD_INIT(hlua_init_functions);
67
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +010068/* The following variables contains the reference of the different
69 * Lua classes. These references are useful for identify metadata
70 * associated with an object.
71 */
Thierry FOURNIER65f34c62015-02-16 20:11:43 +010072static int class_txn_ref;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010073static int class_socket_ref;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +010074static int class_channel_ref;
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +010075static int class_fetches_ref;
Thierry FOURNIER594afe72015-03-10 23:58:30 +010076static int class_converters_ref;
Thierry FOURNIER08504f42015-03-16 14:17:08 +010077static int class_http_ref;
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +010078
Thierry FOURNIERbd413492015-03-03 16:52:26 +010079/* Global Lua execution timeout. By default Lua, execution linked
Willy Tarreau87b09662015-04-03 00:22:06 +020080 * with stream (actions, sample-fetches and converters) have a
Thierry FOURNIERbd413492015-03-03 16:52:26 +010081 * short timeout. Lua linked with tasks doesn't have a timeout
82 * because a task may remain alive during all the haproxy execution.
83 */
84static unsigned int hlua_timeout_session = 4000; /* session timeout. */
85static unsigned int hlua_timeout_task = TICK_ETERNITY; /* task timeout. */
86
Thierry FOURNIERee9f8022015-03-03 17:37:37 +010087/* Interrupts the Lua processing each "hlua_nb_instruction" instructions.
88 * it is used for preventing infinite loops.
89 *
90 * I test the scheer with an infinite loop containing one incrementation
91 * and one test. I run this loop between 10 seconds, I raise a ceil of
92 * 710M loops from one interrupt each 9000 instructions, so I fix the value
93 * to one interrupt each 10 000 instructions.
94 *
95 * configured | Number of
96 * instructions | loops executed
97 * between two | in milions
98 * forced yields |
99 * ---------------+---------------
100 * 10 | 160
101 * 500 | 670
102 * 1000 | 680
103 * 5000 | 700
104 * 7000 | 700
105 * 8000 | 700
106 * 9000 | 710 <- ceil
107 * 10000 | 710
108 * 100000 | 710
109 * 1000000 | 710
110 *
111 */
112static unsigned int hlua_nb_instruction = 10000;
113
Willy Tarreau32f61e22015-03-18 17:54:59 +0100114/* Descriptor for the memory allocation state. If limit is not null, it will
115 * be enforced on any memory allocation.
116 */
117struct hlua_mem_allocator {
118 size_t allocated;
119 size_t limit;
120};
121
122static struct hlua_mem_allocator hlua_global_allocator;
123
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100124/* These functions converts types between HAProxy internal args or
125 * sample and LUA types. Another function permits to check if the
126 * LUA stack contains arguments according with an required ARG_T
127 * format.
128 */
129static int hlua_arg2lua(lua_State *L, const struct arg *arg);
130static int hlua_lua2arg(lua_State *L, int ud, struct arg *arg);
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100131__LJMP static int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp,
132 unsigned int mask, struct proxy *p);
Willy Tarreau5eadada2015-03-10 17:28:54 +0100133static int hlua_smp2lua(lua_State *L, struct sample *smp);
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +0100134static int hlua_smp2lua_str(lua_State *L, struct sample *smp);
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100135static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp);
136
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100137/* Used to check an Lua function type in the stack. It creates and
138 * returns a reference of the function. This function throws an
139 * error if the rgument is not a "function".
140 */
141__LJMP unsigned int hlua_checkfunction(lua_State *L, int argno)
142{
143 if (!lua_isfunction(L, argno)) {
144 const char *msg = lua_pushfstring(L, "function expected, got %s", luaL_typename(L, -1));
145 WILL_LJMP(luaL_argerror(L, argno, msg));
146 }
147 lua_pushvalue(L, argno);
148 return luaL_ref(L, LUA_REGISTRYINDEX);
149}
150
151/* The three following functions are useful for adding entries
152 * in a table. These functions takes a string and respectively an
153 * integer, a string or a function and add it to the table in the
154 * top of the stack.
155 *
156 * These functions throws an error if no more stack size is
157 * available.
158 */
159__LJMP static inline void hlua_class_const_int(lua_State *L, const char *name,
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100160 int value)
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100161{
162 if (!lua_checkstack(L, 2))
163 WILL_LJMP(luaL_error(L, "full stack"));
164 lua_pushstring(L, name);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100165 lua_pushinteger(L, value);
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100166 lua_settable(L, -3);
167}
168__LJMP static inline void hlua_class_const_str(lua_State *L, const char *name,
169 const char *value)
170{
171 if (!lua_checkstack(L, 2))
172 WILL_LJMP(luaL_error(L, "full stack"));
173 lua_pushstring(L, name);
174 lua_pushstring(L, value);
175 lua_settable(L, -3);
176}
177__LJMP static inline void hlua_class_function(lua_State *L, const char *name,
178 int (*function)(lua_State *L))
179{
180 if (!lua_checkstack(L, 2))
181 WILL_LJMP(luaL_error(L, "full stack"));
182 lua_pushstring(L, name);
183 lua_pushcclosure(L, function, 0);
184 lua_settable(L, -3);
185}
186
187/* This function check the number of arguments available in the
188 * stack. If the number of arguments available is not the same
189 * then <nb> an error is throwed.
190 */
191__LJMP static inline void check_args(lua_State *L, int nb, char *fcn)
192{
193 if (lua_gettop(L) == nb)
194 return;
195 WILL_LJMP(luaL_error(L, "'%s' needs %d arguments", fcn, nb));
196}
197
198/* Return true if the data in stack[<ud>] is an object of
199 * type <class_ref>.
200 */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +0100201static int hlua_metaistype(lua_State *L, int ud, int class_ref)
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100202{
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100203 if (!lua_getmetatable(L, ud))
204 return 0;
205
206 lua_rawgeti(L, LUA_REGISTRYINDEX, class_ref);
207 if (!lua_rawequal(L, -1, -2)) {
208 lua_pop(L, 2);
209 return 0;
210 }
211
212 lua_pop(L, 2);
213 return 1;
214}
215
216/* Return an object of the expected type, or throws an error. */
217__LJMP static void *hlua_checkudata(lua_State *L, int ud, int class_ref)
218{
Thierry FOURNIER2297bc22015-03-11 17:43:33 +0100219 void *p;
220
221 /* Check if the stack entry is an array. */
222 if (!lua_istable(L, ud))
223 WILL_LJMP(luaL_argerror(L, ud, NULL));
224 /* Check if the metadata have the expected type. */
225 if (!hlua_metaistype(L, ud, class_ref))
226 WILL_LJMP(luaL_argerror(L, ud, NULL));
227 /* Push on the stack at the entry [0] of the table. */
228 lua_rawgeti(L, ud, 0);
229 /* Check if this entry is userdata. */
230 p = lua_touserdata(L, -1);
231 if (!p)
232 WILL_LJMP(luaL_argerror(L, ud, NULL));
233 /* Remove the entry returned by lua_rawgeti(). */
234 lua_pop(L, 1);
235 /* Return the associated struct. */
236 return p;
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100237}
238
239/* This fucntion push an error string prefixed by the file name
240 * and the line number where the error is encountered.
241 */
242static int hlua_pusherror(lua_State *L, const char *fmt, ...)
243{
244 va_list argp;
245 va_start(argp, fmt);
246 luaL_where(L, 1);
247 lua_pushvfstring(L, fmt, argp);
248 va_end(argp);
249 lua_concat(L, 2);
250 return 1;
251}
252
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100253/* This function register a new signal. "lua" is the current lua
254 * execution context. It contains a pointer to the associated task.
255 * "link" is a list head attached to an other task that must be wake
256 * the lua task if an event occurs. This is useful with external
257 * events like TCP I/O or sleep functions. This funcion allocate
258 * memory for the signal.
259 */
260static int hlua_com_new(struct hlua *lua, struct list *link)
261{
262 struct hlua_com *com = pool_alloc2(pool2_hlua_com);
263 if (!com)
264 return 0;
265 LIST_ADDQ(&lua->com, &com->purge_me);
266 LIST_ADDQ(link, &com->wake_me);
267 com->task = lua->task;
268 return 1;
269}
270
271/* This function purge all the pending signals when the LUA execution
272 * is finished. This prevent than a coprocess try to wake a deleted
273 * task. This function remove the memory associated to the signal.
274 */
275static void hlua_com_purge(struct hlua *lua)
276{
277 struct hlua_com *com, *back;
278
279 /* Delete all pending communication signals. */
280 list_for_each_entry_safe(com, back, &lua->com, purge_me) {
281 LIST_DEL(&com->purge_me);
282 LIST_DEL(&com->wake_me);
283 pool_free2(pool2_hlua_com, com);
284 }
285}
286
287/* This function sends signals. It wakes all the tasks attached
288 * to a list head, and remove the signal, and free the used
289 * memory.
290 */
291static void hlua_com_wake(struct list *wake)
292{
293 struct hlua_com *com, *back;
294
295 /* Wake task and delete all pending communication signals. */
296 list_for_each_entry_safe(com, back, wake, wake_me) {
297 LIST_DEL(&com->purge_me);
298 LIST_DEL(&com->wake_me);
299 task_wakeup(com->task, TASK_WOKEN_MSG);
300 pool_free2(pool2_hlua_com, com);
301 }
302}
303
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100304/* This functions is used with sample fetch and converters. It
305 * converts the HAProxy configuration argument in a lua stack
306 * values.
307 *
308 * It takes an array of "arg", and each entry of the array is
309 * converted and pushed in the LUA stack.
310 */
311static int hlua_arg2lua(lua_State *L, const struct arg *arg)
312{
313 switch (arg->type) {
314 case ARGT_SINT:
315 lua_pushinteger(L, arg->data.sint);
316 break;
317
318 case ARGT_UINT:
319 case ARGT_TIME:
320 case ARGT_SIZE:
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100321 lua_pushinteger(L, arg->data.sint);
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100322 break;
323
324 case ARGT_STR:
325 lua_pushlstring(L, arg->data.str.str, arg->data.str.len);
326 break;
327
328 case ARGT_IPV4:
329 case ARGT_IPV6:
330 case ARGT_MSK4:
331 case ARGT_MSK6:
332 case ARGT_FE:
333 case ARGT_BE:
334 case ARGT_TAB:
335 case ARGT_SRV:
336 case ARGT_USR:
337 case ARGT_MAP:
338 default:
339 lua_pushnil(L);
340 break;
341 }
342 return 1;
343}
344
345/* This function take one entrie in an LUA stack at the index "ud",
346 * and try to convert it in an HAProxy argument entry. This is useful
347 * with sample fetch wrappers. The input arguments are gived to the
348 * lua wrapper and converted as arg list by thi function.
349 */
350static int hlua_lua2arg(lua_State *L, int ud, struct arg *arg)
351{
352 switch (lua_type(L, ud)) {
353
354 case LUA_TNUMBER:
355 case LUA_TBOOLEAN:
356 arg->type = ARGT_SINT;
357 arg->data.sint = lua_tointeger(L, ud);
358 break;
359
360 case LUA_TSTRING:
361 arg->type = ARGT_STR;
362 arg->data.str.str = (char *)lua_tolstring(L, ud, (size_t *)&arg->data.str.len);
363 break;
364
365 case LUA_TUSERDATA:
366 case LUA_TNIL:
367 case LUA_TTABLE:
368 case LUA_TFUNCTION:
369 case LUA_TTHREAD:
370 case LUA_TLIGHTUSERDATA:
371 arg->type = ARGT_SINT;
372 arg->data.uint = 0;
373 break;
374 }
375 return 1;
376}
377
378/* the following functions are used to convert a struct sample
379 * in Lua type. This useful to convert the return of the
380 * fetchs or converters.
381 */
Willy Tarreau5eadada2015-03-10 17:28:54 +0100382static int hlua_smp2lua(lua_State *L, struct sample *smp)
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100383{
384 switch (smp->type) {
385 case SMP_T_SINT:
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100386 case SMP_T_BOOL:
387 case SMP_T_UINT:
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100388 lua_pushinteger(L, smp->data.sint);
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100389 break;
390
391 case SMP_T_BIN:
392 case SMP_T_STR:
393 lua_pushlstring(L, smp->data.str.str, smp->data.str.len);
394 break;
395
396 case SMP_T_METH:
397 switch (smp->data.meth.meth) {
398 case HTTP_METH_OPTIONS: lua_pushstring(L, "OPTIONS"); break;
399 case HTTP_METH_GET: lua_pushstring(L, "GET"); break;
400 case HTTP_METH_HEAD: lua_pushstring(L, "HEAD"); break;
401 case HTTP_METH_POST: lua_pushstring(L, "POST"); break;
402 case HTTP_METH_PUT: lua_pushstring(L, "PUT"); break;
403 case HTTP_METH_DELETE: lua_pushstring(L, "DELETE"); break;
404 case HTTP_METH_TRACE: lua_pushstring(L, "TRACE"); break;
405 case HTTP_METH_CONNECT: lua_pushstring(L, "CONNECT"); break;
406 case HTTP_METH_OTHER:
407 lua_pushlstring(L, smp->data.meth.str.str, smp->data.meth.str.len);
408 break;
409 default:
410 lua_pushnil(L);
411 break;
412 }
413 break;
414
415 case SMP_T_IPV4:
416 case SMP_T_IPV6:
417 case SMP_T_ADDR: /* This type is never used to qualify a sample. */
Willy Tarreau5eadada2015-03-10 17:28:54 +0100418 if (sample_casts[smp->type][SMP_T_STR] &&
419 sample_casts[smp->type][SMP_T_STR](smp))
420 lua_pushlstring(L, smp->data.str.str, smp->data.str.len);
421 else
422 lua_pushnil(L);
423 break;
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100424 default:
425 lua_pushnil(L);
426 break;
427 }
428 return 1;
429}
430
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +0100431/* the following functions are used to convert a struct sample
432 * in Lua strings. This is useful to convert the return of the
433 * fetchs or converters.
434 */
435static int hlua_smp2lua_str(lua_State *L, struct sample *smp)
436{
437 switch (smp->type) {
438
439 case SMP_T_BIN:
440 case SMP_T_STR:
441 lua_pushlstring(L, smp->data.str.str, smp->data.str.len);
442 break;
443
444 case SMP_T_METH:
445 switch (smp->data.meth.meth) {
446 case HTTP_METH_OPTIONS: lua_pushstring(L, "OPTIONS"); break;
447 case HTTP_METH_GET: lua_pushstring(L, "GET"); break;
448 case HTTP_METH_HEAD: lua_pushstring(L, "HEAD"); break;
449 case HTTP_METH_POST: lua_pushstring(L, "POST"); break;
450 case HTTP_METH_PUT: lua_pushstring(L, "PUT"); break;
451 case HTTP_METH_DELETE: lua_pushstring(L, "DELETE"); break;
452 case HTTP_METH_TRACE: lua_pushstring(L, "TRACE"); break;
453 case HTTP_METH_CONNECT: lua_pushstring(L, "CONNECT"); break;
454 case HTTP_METH_OTHER:
455 lua_pushlstring(L, smp->data.meth.str.str, smp->data.meth.str.len);
456 break;
457 default:
458 lua_pushstring(L, "");
459 break;
460 }
461 break;
462
463 case SMP_T_SINT:
464 case SMP_T_BOOL:
465 case SMP_T_UINT:
466 case SMP_T_IPV4:
467 case SMP_T_IPV6:
468 case SMP_T_ADDR: /* This type is never used to qualify a sample. */
469 if (sample_casts[smp->type][SMP_T_STR] &&
470 sample_casts[smp->type][SMP_T_STR](smp))
471 lua_pushlstring(L, smp->data.str.str, smp->data.str.len);
472 else
473 lua_pushstring(L, "");
474 break;
475 default:
476 lua_pushstring(L, "");
477 break;
478 }
479 return 1;
480}
481
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100482/* the following functions are used to convert an Lua type in a
483 * struct sample. This is useful to provide data from a converter
484 * to the LUA code.
485 */
486static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp)
487{
488 switch (lua_type(L, ud)) {
489
490 case LUA_TNUMBER:
491 smp->type = SMP_T_SINT;
492 smp->data.sint = lua_tointeger(L, ud);
493 break;
494
495
496 case LUA_TBOOLEAN:
497 smp->type = SMP_T_BOOL;
498 smp->data.uint = lua_toboolean(L, ud);
499 break;
500
501 case LUA_TSTRING:
502 smp->type = SMP_T_STR;
503 smp->flags |= SMP_F_CONST;
504 smp->data.str.str = (char *)lua_tolstring(L, ud, (size_t *)&smp->data.str.len);
505 break;
506
507 case LUA_TUSERDATA:
508 case LUA_TNIL:
509 case LUA_TTABLE:
510 case LUA_TFUNCTION:
511 case LUA_TTHREAD:
512 case LUA_TLIGHTUSERDATA:
513 smp->type = SMP_T_BOOL;
514 smp->data.uint = 0;
515 break;
516 }
517 return 1;
518}
519
520/* This function check the "argp" builded by another conversion function
521 * is in accord with the expected argp defined by the "mask". The fucntion
522 * returns true or false. It can be adjust the types if there compatibles.
Thierry FOURNIER3caa0392015-03-13 13:38:17 +0100523 *
524 * This function assumes thant the argp argument contains ARGM_NBARGS + 1
525 * entries.
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100526 */
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100527__LJMP int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp,
528 unsigned int mask, struct proxy *p)
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100529{
530 int min_arg;
531 int idx;
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100532 struct proxy *px;
533 char *sname, *pname;
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100534
535 idx = 0;
536 min_arg = ARGM(mask);
537 mask >>= ARGM_BITS;
538
539 while (1) {
540
541 /* Check oversize. */
542 if (idx >= ARGM_NBARGS && argp[idx].type != ARGT_STOP) {
Cyril Bonté577a36a2015-03-02 00:08:38 +0100543 WILL_LJMP(luaL_argerror(L, first + idx, "Malformed argument mask"));
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100544 }
545
546 /* Check for mandatory arguments. */
547 if (argp[idx].type == ARGT_STOP) {
Thierry FOURNIER3caa0392015-03-13 13:38:17 +0100548 if (idx < min_arg) {
549
550 /* If miss other argument than the first one, we return an error. */
551 if (idx > 0)
552 WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
553
554 /* If first argument have a certain type, some default values
555 * may be used. See the function smp_resolve_args().
556 */
557 switch (mask & ARGT_MASK) {
558
559 case ARGT_FE:
560 if (!(p->cap & PR_CAP_FE))
561 WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
562 argp[idx].data.prx = p;
563 argp[idx].type = ARGT_FE;
564 argp[idx+1].type = ARGT_STOP;
565 break;
566
567 case ARGT_BE:
568 if (!(p->cap & PR_CAP_BE))
569 WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
570 argp[idx].data.prx = p;
571 argp[idx].type = ARGT_BE;
572 argp[idx+1].type = ARGT_STOP;
573 break;
574
575 case ARGT_TAB:
576 argp[idx].data.prx = p;
577 argp[idx].type = ARGT_TAB;
578 argp[idx+1].type = ARGT_STOP;
579 break;
580
581 default:
582 WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
583 break;
584 }
585 }
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100586 return 0;
587 }
588
589 /* Check for exceed the number of requiered argument. */
590 if ((mask & ARGT_MASK) == ARGT_STOP &&
591 argp[idx].type != ARGT_STOP) {
592 WILL_LJMP(luaL_argerror(L, first + idx, "Last argument expected"));
593 }
594
595 if ((mask & ARGT_MASK) == ARGT_STOP &&
596 argp[idx].type == ARGT_STOP) {
597 return 0;
598 }
599
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100600 /* Convert some argument types. */
601 switch (mask & ARGT_MASK) {
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100602 case ARGT_SINT:
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100603 if (argp[idx].type != ARGT_SINT)
604 WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
605 argp[idx].type = ARGT_SINT;
606 break;
607
608 case ARGT_UINT:
609 if (argp[idx].type != ARGT_SINT)
610 WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
611 argp[idx].type = ARGT_SINT;
612 break;
613
614 case ARGT_TIME:
615 if (argp[idx].type != ARGT_SINT)
616 WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
617 argp[idx].type = ARGT_SINT;
618 break;
619
620 case ARGT_SIZE:
621 if (argp[idx].type != ARGT_SINT)
622 WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
623 argp[idx].type = ARGT_SINT;
624 break;
625
626 case ARGT_FE:
627 if (argp[idx].type != ARGT_STR)
628 WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
629 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
630 trash.str[argp[idx].data.str.len] = 0;
631 argp[idx].data.prx = findproxy(trash.str, PR_CAP_FE);
632 if (!argp[idx].data.prx)
633 WILL_LJMP(luaL_argerror(L, first + idx, "frontend doesn't exist"));
634 argp[idx].type = ARGT_FE;
635 break;
636
637 case ARGT_BE:
638 if (argp[idx].type != ARGT_STR)
639 WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
640 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
641 trash.str[argp[idx].data.str.len] = 0;
642 argp[idx].data.prx = findproxy(trash.str, PR_CAP_BE);
643 if (!argp[idx].data.prx)
644 WILL_LJMP(luaL_argerror(L, first + idx, "backend doesn't exist"));
645 argp[idx].type = ARGT_BE;
646 break;
647
648 case ARGT_TAB:
649 if (argp[idx].type != ARGT_STR)
650 WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
651 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
652 trash.str[argp[idx].data.str.len] = 0;
653 argp[idx].data.prx = find_stktable(trash.str);
654 if (!argp[idx].data.prx)
655 WILL_LJMP(luaL_argerror(L, first + idx, "table doesn't exist"));
656 argp[idx].type = ARGT_TAB;
657 break;
658
659 case ARGT_SRV:
660 if (argp[idx].type != ARGT_STR)
661 WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
662 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
663 trash.str[argp[idx].data.str.len] = 0;
664 sname = strrchr(trash.str, '/');
665 if (sname) {
666 *sname++ = '\0';
667 pname = trash.str;
668 px = findproxy(pname, PR_CAP_BE);
669 if (!px)
670 WILL_LJMP(luaL_argerror(L, first + idx, "backend doesn't exist"));
671 }
672 else {
673 sname = trash.str;
674 px = p;
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100675 }
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100676 argp[idx].data.srv = findserver(px, sname);
677 if (!argp[idx].data.srv)
678 WILL_LJMP(luaL_argerror(L, first + idx, "server doesn't exist"));
679 argp[idx].type = ARGT_SRV;
680 break;
681
682 case ARGT_IPV4:
683 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
684 trash.str[argp[idx].data.str.len] = 0;
685 if (inet_pton(AF_INET, trash.str, &argp[idx].data.ipv4))
686 WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv4 address"));
687 argp[idx].type = ARGT_IPV4;
688 break;
689
690 case ARGT_MSK4:
691 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
692 trash.str[argp[idx].data.str.len] = 0;
693 if (!str2mask(trash.str, &argp[idx].data.ipv4))
694 WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv4 mask"));
695 argp[idx].type = ARGT_MSK4;
696 break;
697
698 case ARGT_IPV6:
699 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
700 trash.str[argp[idx].data.str.len] = 0;
701 if (inet_pton(AF_INET6, trash.str, &argp[idx].data.ipv6))
702 WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv6 address"));
703 argp[idx].type = ARGT_IPV6;
704 break;
705
706 case ARGT_MSK6:
707 case ARGT_MAP:
708 case ARGT_REG:
709 case ARGT_USR:
710 WILL_LJMP(luaL_argerror(L, first + idx, "type not yet supported"));
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100711 break;
712 }
713
714 /* Check for type of argument. */
715 if ((mask & ARGT_MASK) != argp[idx].type) {
716 const char *msg = lua_pushfstring(L, "'%s' expected, got '%s'",
717 arg_type_names[(mask & ARGT_MASK)],
718 arg_type_names[argp[idx].type & ARGT_MASK]);
719 WILL_LJMP(luaL_argerror(L, first + idx, msg));
720 }
721
722 /* Next argument. */
723 mask >>= ARGT_BITS;
724 idx++;
725 }
726}
727
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100728/*
729 * The following functions are used to make correspondance between the the
730 * executed lua pointer and the "struct hlua *" that contain the context.
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100731 *
732 * - hlua_gethlua : return the hlua context associated with an lua_State.
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100733 * - hlua_sethlua : create the association between hlua context and lua_state.
734 */
735static inline struct hlua *hlua_gethlua(lua_State *L)
736{
Thierry FOURNIER38c5fd62015-03-10 02:40:29 +0100737 struct hlua **hlua = lua_getextraspace(L);
738 return *hlua;
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100739}
740static inline void hlua_sethlua(struct hlua *hlua)
741{
Thierry FOURNIER38c5fd62015-03-10 02:40:29 +0100742 struct hlua **hlua_store = lua_getextraspace(hlua->T);
743 *hlua_store = hlua;
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100744}
745
Thierry FOURNIERc798b5d2015-03-17 01:09:57 +0100746/* This function is used to send logs. It try to send on screen (stderr)
747 * and on the default syslog server.
748 */
749static inline void hlua_sendlog(struct proxy *px, int level, const char *msg)
750{
751 struct tm tm;
752 char *p;
753
754 /* Cleanup the log message. */
755 p = trash.str;
756 for (; *msg != '\0'; msg++, p++) {
757 if (p >= trash.str + trash.size - 1)
758 return;
759 if (isprint(*msg))
760 *p = *msg;
761 else
762 *p = '.';
763 }
764 *p = '\0';
765
766 send_log(px, level, "%s", trash.str);
767 if (!(global.mode & MODE_QUIET) || (global.mode & (MODE_VERBOSE | MODE_STARTING))) {
768 get_localtime(date.tv_sec, &tm);
769 fprintf(stderr, "[%s] %03d/%02d%02d%02d (%d) : %s\n",
770 log_levels[level], tm.tm_yday, tm.tm_hour, tm.tm_min, tm.tm_sec,
771 (int)getpid(), trash.str);
772 fflush(stderr);
773 }
774}
775
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100776/* This function just ensure that the yield will be always
777 * returned with a timeout and permit to set some flags
778 */
779__LJMP void hlua_yieldk(lua_State *L, int nresults, int ctx,
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100780 lua_KFunction k, int timeout, unsigned int flags)
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100781{
782 struct hlua *hlua = hlua_gethlua(L);
783
784 /* Set the wake timeout. If timeout is required, we set
785 * the expiration time.
786 */
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100787 hlua->wake_time = tick_first(timeout, hlua->expire);
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100788
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +0100789 hlua->flags |= flags;
790
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100791 /* Process the yield. */
792 WILL_LJMP(lua_yieldk(L, nresults, ctx, k));
793}
794
Willy Tarreau87b09662015-04-03 00:22:06 +0200795/* This function initialises the Lua environment stored in the stream.
796 * It must be called at the start of the stream. This function creates
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100797 * an LUA coroutine. It can not be use to crete the main LUA context.
798 */
799int hlua_ctx_init(struct hlua *lua, struct task *task)
800{
801 lua->Mref = LUA_REFNIL;
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +0100802 lua->flags = 0;
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100803 LIST_INIT(&lua->com);
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100804 lua->T = lua_newthread(gL.T);
805 if (!lua->T) {
806 lua->Tref = LUA_REFNIL;
807 return 0;
808 }
809 hlua_sethlua(lua);
810 lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
811 lua->task = task;
812 return 1;
813}
814
Willy Tarreau87b09662015-04-03 00:22:06 +0200815/* Used to destroy the Lua coroutine when the attached stream or task
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100816 * is destroyed. The destroy also the memory context. The struct "lua"
817 * is not freed.
818 */
819void hlua_ctx_destroy(struct hlua *lua)
820{
Thierry FOURNIERa718b292015-03-04 16:48:34 +0100821 if (!lua->T)
822 return;
823
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100824 /* Purge all the pending signals. */
825 hlua_com_purge(lua);
826
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100827 /* The thread is garbage collected by Lua. */
828 luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
829 luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
830}
831
832/* This function is used to restore the Lua context when a coroutine
833 * fails. This function copy the common memory between old coroutine
834 * and the new coroutine. The old coroutine is destroyed, and its
835 * replaced by the new coroutine.
836 * If the flag "keep_msg" is set, the last entry of the old is assumed
837 * as string error message and it is copied in the new stack.
838 */
839static int hlua_ctx_renew(struct hlua *lua, int keep_msg)
840{
841 lua_State *T;
842 int new_ref;
843
844 /* Renew the main LUA stack doesn't have sense. */
845 if (lua == &gL)
846 return 0;
847
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100848 /* New Lua coroutine. */
849 T = lua_newthread(gL.T);
850 if (!T)
851 return 0;
852
853 /* Copy last error message. */
854 if (keep_msg)
855 lua_xmove(lua->T, T, 1);
856
857 /* Copy data between the coroutines. */
858 lua_rawgeti(lua->T, LUA_REGISTRYINDEX, lua->Mref);
859 lua_xmove(lua->T, T, 1);
860 new_ref = luaL_ref(T, LUA_REGISTRYINDEX); /* Valur poped. */
861
862 /* Destroy old data. */
863 luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
864
865 /* The thread is garbage collected by Lua. */
866 luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
867
868 /* Fill the struct with the new coroutine values. */
869 lua->Mref = new_ref;
870 lua->T = T;
871 lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
872
873 /* Set context. */
874 hlua_sethlua(lua);
875
876 return 1;
877}
878
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100879void hlua_hook(lua_State *L, lua_Debug *ar)
880{
Thierry FOURNIERcae49c92015-03-06 14:05:24 +0100881 struct hlua *hlua = hlua_gethlua(L);
882
883 /* Lua cannot yield when its returning from a function,
884 * so, we can fix the interrupt hook to 1 instruction,
885 * expecting that the function is finnished.
886 */
887 if (lua_gethookmask(L) & LUA_MASKRET) {
888 lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, 1);
889 return;
890 }
891
892 /* restore the interrupt condition. */
893 lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, hlua_nb_instruction);
894
895 /* If we interrupt the Lua processing in yieldable state, we yield.
896 * If the state is not yieldable, trying yield causes an error.
897 */
898 if (lua_isyieldable(L))
899 WILL_LJMP(hlua_yieldk(L, 0, 0, NULL, TICK_ETERNITY, HLUA_CTRLYIELD));
900
Thierry FOURNIERa85cfb12015-03-13 14:50:06 +0100901 /* If we cannot yield, update the clock and check the timeout. */
902 tv_update_date(0, 1);
Thierry FOURNIERcae49c92015-03-06 14:05:24 +0100903 if (tick_is_expired(hlua->expire, now_ms)) {
904 lua_pushfstring(L, "execution timeout");
905 WILL_LJMP(lua_error(L));
906 }
907
908 /* Try to interrupt the process at the end of the current
909 * unyieldable function.
910 */
911 lua_sethook(hlua->T, hlua_hook, LUA_MASKRET|LUA_MASKCOUNT, hlua_nb_instruction);
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100912}
913
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100914/* This function start or resumes the Lua stack execution. If the flag
915 * "yield_allowed" if no set and the LUA stack execution returns a yield
916 * The function return an error.
917 *
918 * The function can returns 4 values:
919 * - HLUA_E_OK : The execution is terminated without any errors.
920 * - HLUA_E_AGAIN : The execution must continue at the next associated
921 * task wakeup.
922 * - HLUA_E_ERRMSG : An error has occured, an error message is set in
923 * the top of the stack.
924 * - HLUA_E_ERR : An error has occured without error message.
925 *
926 * If an error occured, the stack is renewed and it is ready to run new
927 * LUA code.
928 */
929static enum hlua_exec hlua_ctx_resume(struct hlua *lua, int yield_allowed)
930{
931 int ret;
932 const char *msg;
933
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +0100934 HLUA_SET_RUN(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100935
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100936 /* If we want to resume the task, then check first the execution timeout.
937 * if it is reached, we can interrupt the Lua processing.
938 */
939 if (tick_is_expired(lua->expire, now_ms))
940 goto timeout_reached;
941
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100942resume_execution:
943
944 /* This hook interrupts the Lua processing each 'hlua_nb_instruction'
945 * instructions. it is used for preventing infinite loops.
946 */
947 lua_sethook(lua->T, hlua_hook, LUA_MASKCOUNT, hlua_nb_instruction);
948
Thierry FOURNIER1bfc09b2015-03-05 17:10:14 +0100949 /* Remove all flags except the running flags. */
950 lua->flags = HLUA_RUN;
951
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100952 /* Call the function. */
953 ret = lua_resume(lua->T, gL.T, lua->nargs);
954 switch (ret) {
955
956 case LUA_OK:
957 ret = HLUA_E_OK;
958 break;
959
960 case LUA_YIELD:
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100961 /* Check if the execution timeout is expired. It it is the case, we
962 * break the Lua execution.
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100963 */
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100964 if (tick_is_expired(lua->expire, now_ms)) {
965
966timeout_reached:
967
968 lua_settop(lua->T, 0); /* Empty the stack. */
969 if (!lua_checkstack(lua->T, 1)) {
970 ret = HLUA_E_ERR;
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100971 break;
972 }
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100973 lua_pushfstring(lua->T, "execution timeout");
974 ret = HLUA_E_ERRMSG;
975 break;
976 }
977 /* Process the forced yield. if the general yield is not allowed or
978 * if no task were associated this the current Lua execution
979 * coroutine, we resume the execution. Else we want to return in the
980 * scheduler and we want to be waked up again, to continue the
981 * current Lua execution. So we schedule our own task.
982 */
983 if (HLUA_IS_CTRLYIELDING(lua)) {
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100984 if (!yield_allowed || !lua->task)
985 goto resume_execution;
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100986 task_wakeup(lua->task, TASK_WOKEN_MSG);
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100987 }
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100988 if (!yield_allowed) {
989 lua_settop(lua->T, 0); /* Empty the stack. */
990 if (!lua_checkstack(lua->T, 1)) {
991 ret = HLUA_E_ERR;
992 break;
993 }
994 lua_pushfstring(lua->T, "yield not allowed");
995 ret = HLUA_E_ERRMSG;
996 break;
997 }
998 ret = HLUA_E_AGAIN;
999 break;
1000
1001 case LUA_ERRRUN:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01001002 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001003 if (!lua_checkstack(lua->T, 1)) {
1004 ret = HLUA_E_ERR;
1005 break;
1006 }
1007 msg = lua_tostring(lua->T, -1);
1008 lua_settop(lua->T, 0); /* Empty the stack. */
1009 lua_pop(lua->T, 1);
1010 if (msg)
1011 lua_pushfstring(lua->T, "runtime error: %s", msg);
1012 else
1013 lua_pushfstring(lua->T, "unknown runtime error");
1014 ret = HLUA_E_ERRMSG;
1015 break;
1016
1017 case LUA_ERRMEM:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01001018 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001019 lua_settop(lua->T, 0); /* Empty the stack. */
1020 if (!lua_checkstack(lua->T, 1)) {
1021 ret = HLUA_E_ERR;
1022 break;
1023 }
1024 lua_pushfstring(lua->T, "out of memory error");
1025 ret = HLUA_E_ERRMSG;
1026 break;
1027
1028 case LUA_ERRERR:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01001029 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001030 if (!lua_checkstack(lua->T, 1)) {
1031 ret = HLUA_E_ERR;
1032 break;
1033 }
1034 msg = lua_tostring(lua->T, -1);
1035 lua_settop(lua->T, 0); /* Empty the stack. */
1036 lua_pop(lua->T, 1);
1037 if (msg)
1038 lua_pushfstring(lua->T, "message handler error: %s", msg);
1039 else
1040 lua_pushfstring(lua->T, "message handler error");
1041 ret = HLUA_E_ERRMSG;
1042 break;
1043
1044 default:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01001045 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001046 lua_settop(lua->T, 0); /* Empty the stack. */
1047 if (!lua_checkstack(lua->T, 1)) {
1048 ret = HLUA_E_ERR;
1049 break;
1050 }
1051 lua_pushfstring(lua->T, "unknonwn error");
1052 ret = HLUA_E_ERRMSG;
1053 break;
1054 }
1055
1056 switch (ret) {
1057 case HLUA_E_AGAIN:
1058 break;
1059
1060 case HLUA_E_ERRMSG:
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01001061 hlua_com_purge(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001062 hlua_ctx_renew(lua, 1);
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01001063 HLUA_CLR_RUN(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001064 break;
1065
1066 case HLUA_E_ERR:
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01001067 HLUA_CLR_RUN(lua);
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01001068 hlua_com_purge(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001069 hlua_ctx_renew(lua, 0);
1070 break;
1071
1072 case HLUA_E_OK:
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01001073 HLUA_CLR_RUN(lua);
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01001074 hlua_com_purge(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001075 break;
1076 }
1077
1078 return ret;
1079}
1080
Thierry FOURNIER83758bb2015-02-04 13:21:04 +01001081/* This function is an LUA binding. It provides a function
1082 * for deleting ACL from a referenced ACL file.
1083 */
1084__LJMP static int hlua_del_acl(lua_State *L)
1085{
1086 const char *name;
1087 const char *key;
1088 struct pat_ref *ref;
1089
1090 MAY_LJMP(check_args(L, 2, "del_acl"));
1091
1092 name = MAY_LJMP(luaL_checkstring(L, 1));
1093 key = MAY_LJMP(luaL_checkstring(L, 2));
1094
1095 ref = pat_ref_lookup(name);
1096 if (!ref)
1097 WILL_LJMP(luaL_error(L, "'del_acl': unkown acl file '%s'", name));
1098
1099 pat_ref_delete(ref, key);
1100 return 0;
1101}
1102
1103/* This function is an LUA binding. It provides a function
1104 * for deleting map entry from a referenced map file.
1105 */
1106static int hlua_del_map(lua_State *L)
1107{
1108 const char *name;
1109 const char *key;
1110 struct pat_ref *ref;
1111
1112 MAY_LJMP(check_args(L, 2, "del_map"));
1113
1114 name = MAY_LJMP(luaL_checkstring(L, 1));
1115 key = MAY_LJMP(luaL_checkstring(L, 2));
1116
1117 ref = pat_ref_lookup(name);
1118 if (!ref)
1119 WILL_LJMP(luaL_error(L, "'del_map': unkown acl file '%s'", name));
1120
1121 pat_ref_delete(ref, key);
1122 return 0;
1123}
1124
1125/* This function is an LUA binding. It provides a function
1126 * for adding ACL pattern from a referenced ACL file.
1127 */
1128static int hlua_add_acl(lua_State *L)
1129{
1130 const char *name;
1131 const char *key;
1132 struct pat_ref *ref;
1133
1134 MAY_LJMP(check_args(L, 2, "add_acl"));
1135
1136 name = MAY_LJMP(luaL_checkstring(L, 1));
1137 key = MAY_LJMP(luaL_checkstring(L, 2));
1138
1139 ref = pat_ref_lookup(name);
1140 if (!ref)
1141 WILL_LJMP(luaL_error(L, "'add_acl': unkown acl file '%s'", name));
1142
1143 if (pat_ref_find_elt(ref, key) == NULL)
1144 pat_ref_add(ref, key, NULL, NULL);
1145 return 0;
1146}
1147
1148/* This function is an LUA binding. It provides a function
1149 * for setting map pattern and sample from a referenced map
1150 * file.
1151 */
1152static int hlua_set_map(lua_State *L)
1153{
1154 const char *name;
1155 const char *key;
1156 const char *value;
1157 struct pat_ref *ref;
1158
1159 MAY_LJMP(check_args(L, 3, "set_map"));
1160
1161 name = MAY_LJMP(luaL_checkstring(L, 1));
1162 key = MAY_LJMP(luaL_checkstring(L, 2));
1163 value = MAY_LJMP(luaL_checkstring(L, 3));
1164
1165 ref = pat_ref_lookup(name);
1166 if (!ref)
1167 WILL_LJMP(luaL_error(L, "'set_map': unkown map file '%s'", name));
1168
1169 if (pat_ref_find_elt(ref, key) != NULL)
1170 pat_ref_set(ref, key, value, NULL);
1171 else
1172 pat_ref_add(ref, key, value, NULL);
1173 return 0;
1174}
1175
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01001176/* A class is a lot of memory that contain data. This data can be a table,
1177 * an integer or user data. This data is associated with a metatable. This
1178 * metatable have an original version registred in the global context with
1179 * the name of the object (_G[<name>] = <metable> ).
1180 *
1181 * A metable is a table that modify the standard behavior of a standard
1182 * access to the associated data. The entries of this new metatable are
1183 * defined as is:
1184 *
1185 * http://lua-users.org/wiki/MetatableEvents
1186 *
1187 * __index
1188 *
1189 * we access an absent field in a table, the result is nil. This is
1190 * true, but it is not the whole truth. Actually, such access triggers
1191 * the interpreter to look for an __index metamethod: If there is no
1192 * such method, as usually happens, then the access results in nil;
1193 * otherwise, the metamethod will provide the result.
1194 *
1195 * Control 'prototype' inheritance. When accessing "myTable[key]" and
1196 * the key does not appear in the table, but the metatable has an __index
1197 * property:
1198 *
1199 * - if the value is a function, the function is called, passing in the
1200 * table and the key; the return value of that function is returned as
1201 * the result.
1202 *
1203 * - if the value is another table, the value of the key in that table is
1204 * asked for and returned (and if it doesn't exist in that table, but that
1205 * table's metatable has an __index property, then it continues on up)
1206 *
1207 * - Use "rawget(myTable,key)" to skip this metamethod.
1208 *
1209 * http://www.lua.org/pil/13.4.1.html
1210 *
1211 * __newindex
1212 *
1213 * Like __index, but control property assignment.
1214 *
1215 * __mode - Control weak references. A string value with one or both
1216 * of the characters 'k' and 'v' which specifies that the the
1217 * keys and/or values in the table are weak references.
1218 *
1219 * __call - Treat a table like a function. When a table is followed by
1220 * parenthesis such as "myTable( 'foo' )" and the metatable has
1221 * a __call key pointing to a function, that function is invoked
1222 * (passing any specified arguments) and the return value is
1223 * returned.
1224 *
1225 * __metatable - Hide the metatable. When "getmetatable( myTable )" is
1226 * called, if the metatable for myTable has a __metatable
1227 * key, the value of that key is returned instead of the
1228 * actual metatable.
1229 *
1230 * __tostring - Control string representation. When the builtin
1231 * "tostring( myTable )" function is called, if the metatable
1232 * for myTable has a __tostring property set to a function,
1233 * that function is invoked (passing myTable to it) and the
1234 * return value is used as the string representation.
1235 *
1236 * __len - Control table length. When the table length is requested using
1237 * the length operator ( '#' ), if the metatable for myTable has
1238 * a __len key pointing to a function, that function is invoked
1239 * (passing myTable to it) and the return value used as the value
1240 * of "#myTable".
1241 *
1242 * __gc - Userdata finalizer code. When userdata is set to be garbage
1243 * collected, if the metatable has a __gc field pointing to a
1244 * function, that function is first invoked, passing the userdata
1245 * to it. The __gc metamethod is not called for tables.
1246 * (See http://lua-users.org/lists/lua-l/2006-11/msg00508.html)
1247 *
1248 * Special metamethods for redefining standard operators:
1249 * http://www.lua.org/pil/13.1.html
1250 *
1251 * __add "+"
1252 * __sub "-"
1253 * __mul "*"
1254 * __div "/"
1255 * __unm "!"
1256 * __pow "^"
1257 * __concat ".."
1258 *
1259 * Special methods for redfining standar relations
1260 * http://www.lua.org/pil/13.2.html
1261 *
1262 * __eq "=="
1263 * __lt "<"
1264 * __le "<="
1265 */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001266
1267/*
1268 *
1269 *
1270 * Class Socket
1271 *
1272 *
1273 */
1274
1275__LJMP static struct hlua_socket *hlua_checksocket(lua_State *L, int ud)
1276{
1277 return (struct hlua_socket *)MAY_LJMP(hlua_checkudata(L, ud, class_socket_ref));
1278}
1279
1280/* This function is the handler called for each I/O on the established
1281 * connection. It is used for notify space avalaible to send or data
1282 * received.
1283 */
1284static void hlua_socket_handler(struct stream_interface *si)
1285{
1286 struct appctx *appctx = objt_appctx(si->end);
Willy Tarreau50fe03b2014-11-28 13:59:31 +01001287 struct connection *c = objt_conn(si_opposite(si)->end);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001288
Willy Tarreau87b09662015-04-03 00:22:06 +02001289 /* Wakeup the main stream if the client connection is closed. */
Willy Tarreau2bb4a962014-11-28 11:11:05 +01001290 if (!c || channel_output_closed(si_ic(si)) || channel_input_closed(si_oc(si))) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001291 if (appctx->ctx.hlua.socket) {
1292 appctx->ctx.hlua.socket->s = NULL;
1293 appctx->ctx.hlua.socket = NULL;
1294 }
1295 si_shutw(si);
1296 si_shutr(si);
Willy Tarreau2bb4a962014-11-28 11:11:05 +01001297 si_ic(si)->flags |= CF_READ_NULL;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001298 hlua_com_wake(&appctx->ctx.hlua.wake_on_read);
1299 hlua_com_wake(&appctx->ctx.hlua.wake_on_write);
1300 return;
1301 }
1302
1303 if (!(c->flags & CO_FL_CONNECTED))
1304 return;
1305
1306 /* This function is called after the connect. */
1307 appctx->ctx.hlua.connected = 1;
1308
1309 /* Wake the tasks which wants to write if the buffer have avalaible space. */
Willy Tarreau2bb4a962014-11-28 11:11:05 +01001310 if (channel_may_recv(si_oc(si)))
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001311 hlua_com_wake(&appctx->ctx.hlua.wake_on_write);
1312
1313 /* Wake the tasks which wants to read if the buffer contains data. */
Willy Tarreau2bb4a962014-11-28 11:11:05 +01001314 if (channel_is_empty(si_ic(si)))
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001315 hlua_com_wake(&appctx->ctx.hlua.wake_on_read);
1316}
1317
Willy Tarreau87b09662015-04-03 00:22:06 +02001318/* This function is called when the "struct stream" is destroyed.
1319 * Remove the link from the object to this stream.
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001320 * Wake all the pending signals.
1321 */
1322static void hlua_socket_release(struct stream_interface *si)
1323{
1324 struct appctx *appctx = objt_appctx(si->end);
1325
1326 /* Remove my link in the original object. */
1327 if (appctx->ctx.hlua.socket)
1328 appctx->ctx.hlua.socket->s = NULL;
1329
1330 /* Wake all the task waiting for me. */
1331 hlua_com_wake(&appctx->ctx.hlua.wake_on_read);
1332 hlua_com_wake(&appctx->ctx.hlua.wake_on_write);
1333}
1334
1335/* If the garbage collectio of the object is launch, nobody
Willy Tarreau87b09662015-04-03 00:22:06 +02001336 * uses this object. If the stream does not exists, just quit.
1337 * Send the shutdown signal to the stream. In some cases,
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001338 * pending signal can rest in the read and write lists. destroy
1339 * it.
1340 */
1341__LJMP static int hlua_socket_gc(lua_State *L)
1342{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001343 struct hlua_socket *socket;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001344 struct appctx *appctx;
1345
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001346 MAY_LJMP(check_args(L, 1, "__gc"));
1347
1348 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001349 if (!socket->s)
1350 return 0;
1351
Willy Tarreau87b09662015-04-03 00:22:06 +02001352 /* Remove all reference between the Lua stack and the coroutine stream. */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001353 appctx = objt_appctx(socket->s->si[0].end);
Willy Tarreaue7dff022015-04-03 01:14:29 +02001354 stream_shutdown(socket->s, SF_ERR_KILLED);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001355 socket->s = NULL;
1356 appctx->ctx.hlua.socket = NULL;
1357
1358 return 0;
1359}
1360
1361/* The close function send shutdown signal and break the
Willy Tarreau87b09662015-04-03 00:22:06 +02001362 * links between the stream and the object.
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001363 */
1364__LJMP static int hlua_socket_close(lua_State *L)
1365{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001366 struct hlua_socket *socket;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001367 struct appctx *appctx;
1368
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001369 MAY_LJMP(check_args(L, 1, "close"));
1370
1371 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001372 if (!socket->s)
1373 return 0;
1374
Willy Tarreau87b09662015-04-03 00:22:06 +02001375 /* Close the stream and remove the associated stop task. */
Willy Tarreaue7dff022015-04-03 01:14:29 +02001376 stream_shutdown(socket->s, SF_ERR_KILLED);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001377 appctx = objt_appctx(socket->s->si[0].end);
1378 appctx->ctx.hlua.socket = NULL;
1379 socket->s = NULL;
1380
1381 return 0;
1382}
1383
1384/* This Lua function assumes that the stack contain three parameters.
1385 * 1 - USERDATA containing a struct socket
1386 * 2 - INTEGER with values of the macro defined below
1387 * If the integer is -1, we must read at most one line.
1388 * If the integer is -2, we ust read all the data until the
1389 * end of the stream.
1390 * If the integer is positive value, we must read a number of
1391 * bytes corresponding to this value.
1392 */
1393#define HLSR_READ_LINE (-1)
1394#define HLSR_READ_ALL (-2)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001395__LJMP static int hlua_socket_receive_yield(struct lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001396{
1397 struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1));
1398 int wanted = lua_tointeger(L, 2);
1399 struct hlua *hlua = hlua_gethlua(L);
1400 struct appctx *appctx;
1401 int len;
1402 int nblk;
1403 char *blk1;
1404 int len1;
1405 char *blk2;
1406 int len2;
Thierry FOURNIER00543922015-03-09 18:35:06 +01001407 int skip_at_end = 0;
Willy Tarreau81389672015-03-10 12:03:52 +01001408 struct channel *oc;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001409
1410 /* Check if this lua stack is schedulable. */
1411 if (!hlua || !hlua->task)
1412 WILL_LJMP(luaL_error(L, "The 'receive' function is only allowed in "
1413 "'frontend', 'backend' or 'task'"));
1414
1415 /* check for connection closed. If some data where read, return it. */
1416 if (!socket->s)
1417 goto connection_closed;
1418
Willy Tarreau94aa6172015-03-13 14:19:06 +01001419 oc = &socket->s->res;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001420 if (wanted == HLSR_READ_LINE) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001421 /* Read line. */
Willy Tarreau81389672015-03-10 12:03:52 +01001422 nblk = bo_getline_nc(oc, &blk1, &len1, &blk2, &len2);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001423 if (nblk < 0) /* Connection close. */
1424 goto connection_closed;
1425 if (nblk == 0) /* No data avalaible. */
1426 goto connection_empty;
Thierry FOURNIER00543922015-03-09 18:35:06 +01001427
1428 /* remove final \r\n. */
1429 if (nblk == 1) {
1430 if (blk1[len1-1] == '\n') {
1431 len1--;
1432 skip_at_end++;
1433 if (blk1[len1-1] == '\r') {
1434 len1--;
1435 skip_at_end++;
1436 }
1437 }
1438 }
1439 else {
1440 if (blk2[len2-1] == '\n') {
1441 len2--;
1442 skip_at_end++;
1443 if (blk2[len2-1] == '\r') {
1444 len2--;
1445 skip_at_end++;
1446 }
1447 }
1448 }
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001449 }
1450
1451 else if (wanted == HLSR_READ_ALL) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001452 /* Read all the available data. */
Willy Tarreau81389672015-03-10 12:03:52 +01001453 nblk = bo_getblk_nc(oc, &blk1, &len1, &blk2, &len2);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001454 if (nblk < 0) /* Connection close. */
1455 goto connection_closed;
1456 if (nblk == 0) /* No data avalaible. */
1457 goto connection_empty;
1458 }
1459
1460 else {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001461 /* Read a block of data. */
Willy Tarreau81389672015-03-10 12:03:52 +01001462 nblk = bo_getblk_nc(oc, &blk1, &len1, &blk2, &len2);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001463 if (nblk < 0) /* Connection close. */
1464 goto connection_closed;
1465 if (nblk == 0) /* No data avalaible. */
1466 goto connection_empty;
1467
1468 if (len1 > wanted) {
1469 nblk = 1;
1470 len1 = wanted;
1471 } if (nblk == 2 && len1 + len2 > wanted)
1472 len2 = wanted - len1;
1473 }
1474
1475 len = len1;
1476
1477 luaL_addlstring(&socket->b, blk1, len1);
1478 if (nblk == 2) {
1479 len += len2;
1480 luaL_addlstring(&socket->b, blk2, len2);
1481 }
1482
1483 /* Consume data. */
Willy Tarreau81389672015-03-10 12:03:52 +01001484 bo_skip(oc, len + skip_at_end);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001485
1486 /* Don't wait anything. */
1487 si_update(&socket->s->si[0]);
1488
1489 /* If the pattern reclaim to read all the data
1490 * in the connection, got out.
1491 */
1492 if (wanted == HLSR_READ_ALL)
1493 goto connection_empty;
1494 else if (wanted >= 0 && len < wanted)
1495 goto connection_empty;
1496
1497 /* Return result. */
1498 luaL_pushresult(&socket->b);
1499 return 1;
1500
1501connection_closed:
1502
1503 /* If the buffer containds data. */
1504 if (socket->b.n > 0) {
1505 luaL_pushresult(&socket->b);
1506 return 1;
1507 }
1508 lua_pushnil(L);
1509 lua_pushstring(L, "connection closed.");
1510 return 2;
1511
1512connection_empty:
1513
1514 appctx = objt_appctx(socket->s->si[0].end);
1515 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_read))
1516 WILL_LJMP(luaL_error(L, "out of memory"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01001517 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_receive_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001518 return 0;
1519}
1520
1521/* This Lus function gets two parameters. The first one can be string
1522 * or a number. If the string is "*l", the user require one line. If
1523 * the string is "*a", the user require all the content of the stream.
1524 * If the value is a number, the user require a number of bytes equal
1525 * to the value. The default value is "*l" (a line).
1526 *
1527 * This paraeter with a variable type is converted in integer. This
1528 * integer takes this values:
1529 * -1 : read a line
1530 * -2 : read all the stream
1531 * >0 : amount if bytes.
1532 *
1533 * The second parameter is optinal. It contains a string that must be
1534 * concatenated with the read data.
1535 */
1536__LJMP static int hlua_socket_receive(struct lua_State *L)
1537{
1538 int wanted = HLSR_READ_LINE;
1539 const char *pattern;
1540 int type;
1541 char *error;
1542 size_t len;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001543 struct hlua_socket *socket;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001544
1545 if (lua_gettop(L) < 1 || lua_gettop(L) > 3)
1546 WILL_LJMP(luaL_error(L, "The 'receive' function requires between 1 and 3 arguments."));
1547
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001548 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001549
1550 /* check for pattern. */
1551 if (lua_gettop(L) >= 2) {
1552 type = lua_type(L, 2);
1553 if (type == LUA_TSTRING) {
1554 pattern = lua_tostring(L, 2);
1555 if (strcmp(pattern, "*a") == 0)
1556 wanted = HLSR_READ_ALL;
1557 else if (strcmp(pattern, "*l") == 0)
1558 wanted = HLSR_READ_LINE;
1559 else {
1560 wanted = strtoll(pattern, &error, 10);
1561 if (*error != '\0')
1562 WILL_LJMP(luaL_error(L, "Unsupported pattern."));
1563 }
1564 }
1565 else if (type == LUA_TNUMBER) {
1566 wanted = lua_tointeger(L, 2);
1567 if (wanted < 0)
1568 WILL_LJMP(luaL_error(L, "Unsupported size."));
1569 }
1570 }
1571
1572 /* Set pattern. */
1573 lua_pushinteger(L, wanted);
1574 lua_replace(L, 2);
1575
1576 /* init bufffer, and fiil it wih prefix. */
1577 luaL_buffinit(L, &socket->b);
1578
1579 /* Check prefix. */
1580 if (lua_gettop(L) >= 3) {
1581 if (lua_type(L, 3) != LUA_TSTRING)
1582 WILL_LJMP(luaL_error(L, "Expect a 'string' for the prefix"));
1583 pattern = lua_tolstring(L, 3, &len);
1584 luaL_addlstring(&socket->b, pattern, len);
1585 }
1586
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001587 return __LJMP(hlua_socket_receive_yield(L, 0, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001588}
1589
1590/* Write the Lua input string in the output buffer.
1591 * This fucntion returns a yield if no space are available.
1592 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001593static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext ctx)
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001594{
1595 struct hlua_socket *socket;
1596 struct hlua *hlua = hlua_gethlua(L);
1597 struct appctx *appctx;
1598 size_t buf_len;
1599 const char *buf;
1600 int len;
1601 int send_len;
1602 int sent;
1603
1604 /* Check if this lua stack is schedulable. */
1605 if (!hlua || !hlua->task)
1606 WILL_LJMP(luaL_error(L, "The 'write' function is only allowed in "
1607 "'frontend', 'backend' or 'task'"));
1608
1609 /* Get object */
1610 socket = MAY_LJMP(hlua_checksocket(L, 1));
1611 buf = MAY_LJMP(luaL_checklstring(L, 2, &buf_len));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001612 sent = MAY_LJMP(luaL_checkinteger(L, 3));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001613
1614 /* Check for connection close. */
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01001615 if (!socket->s || channel_output_closed(&socket->s->req)) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001616 lua_pushinteger(L, -1);
1617 return 1;
1618 }
1619
1620 /* Update the input buffer data. */
1621 buf += sent;
1622 send_len = buf_len - sent;
1623
1624 /* All the data are sent. */
1625 if (sent >= buf_len)
1626 return 1; /* Implicitly return the length sent. */
1627
Thierry FOURNIER486d52a2015-03-09 17:51:43 +01001628 /* Check if the buffer is avalaible because HAProxy doesn't allocate
1629 * the request buffer if its not required.
1630 */
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01001631 if (socket->s->req.buf->size == 0) {
Willy Tarreau87b09662015-04-03 00:22:06 +02001632 if (!stream_alloc_recv_buffer(&socket->s->req)) {
Willy Tarreau350f4872014-11-28 14:42:25 +01001633 socket->s->si[0].flags |= SI_FL_WAIT_ROOM;
Thierry FOURNIER486d52a2015-03-09 17:51:43 +01001634 goto hlua_socket_write_yield_return;
1635 }
1636 }
1637
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001638 /* Check for avalaible space. */
Willy Tarreau94aa6172015-03-13 14:19:06 +01001639 len = buffer_total_space(socket->s->req.buf);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001640 if (len <= 0)
1641 goto hlua_socket_write_yield_return;
1642
1643 /* send data */
1644 if (len < send_len)
1645 send_len = len;
Willy Tarreau94aa6172015-03-13 14:19:06 +01001646 len = bi_putblk(&socket->s->req, buf+sent, send_len);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001647
1648 /* "Not enough space" (-1), "Buffer too little to contain
1649 * the data" (-2) are not expected because the available length
1650 * is tested.
1651 * Other unknown error are also not expected.
1652 */
1653 if (len <= 0) {
Willy Tarreaubc18da12015-03-13 14:00:47 +01001654 if (len == -1)
Willy Tarreau94aa6172015-03-13 14:19:06 +01001655 socket->s->req.flags |= CF_WAKE_WRITE;
Willy Tarreaubc18da12015-03-13 14:00:47 +01001656
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001657 MAY_LJMP(hlua_socket_close(L));
1658 lua_pop(L, 1);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001659 lua_pushinteger(L, -1);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001660 return 1;
1661 }
1662
1663 /* update buffers. */
1664 si_update(&socket->s->si[0]);
Willy Tarreau94aa6172015-03-13 14:19:06 +01001665 socket->s->req.rex = TICK_ETERNITY;
1666 socket->s->res.wex = TICK_ETERNITY;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001667
1668 /* Update length sent. */
1669 lua_pop(L, 1);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001670 lua_pushinteger(L, sent + len);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001671
1672 /* All the data buffer is sent ? */
1673 if (sent + len >= buf_len)
1674 return 1;
1675
1676hlua_socket_write_yield_return:
1677 appctx = objt_appctx(socket->s->si[0].end);
1678 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_write))
1679 WILL_LJMP(luaL_error(L, "out of memory"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01001680 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_write_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001681 return 0;
1682}
1683
1684/* This function initiate the send of data. It just check the input
1685 * parameters and push an integer in the Lua stack that contain the
1686 * amount of data writed in the buffer. This is used by the function
1687 * "hlua_socket_write_yield" that can yield.
1688 *
1689 * The Lua function gets between 3 and 4 parameters. The first one is
1690 * the associated object. The second is a string buffer. The third is
1691 * a facultative integer that represents where is the buffer position
1692 * of the start of the data that can send. The first byte is the
1693 * position "1". The default value is "1". The fourth argument is a
1694 * facultative integer that represents where is the buffer position
1695 * of the end of the data that can send. The default is the last byte.
1696 */
1697static int hlua_socket_send(struct lua_State *L)
1698{
1699 int i;
1700 int j;
1701 const char *buf;
1702 size_t buf_len;
1703
1704 /* Check number of arguments. */
1705 if (lua_gettop(L) < 2 || lua_gettop(L) > 4)
1706 WILL_LJMP(luaL_error(L, "'send' needs between 2 and 4 arguments"));
1707
1708 /* Get the string. */
1709 buf = MAY_LJMP(luaL_checklstring(L, 2, &buf_len));
1710
1711 /* Get and check j. */
1712 if (lua_gettop(L) == 4) {
1713 j = MAY_LJMP(luaL_checkinteger(L, 4));
1714 if (j < 0)
1715 j = buf_len + j + 1;
1716 if (j > buf_len)
1717 j = buf_len + 1;
1718 lua_pop(L, 1);
1719 }
1720 else
1721 j = buf_len;
1722
1723 /* Get and check i. */
1724 if (lua_gettop(L) == 3) {
1725 i = MAY_LJMP(luaL_checkinteger(L, 3));
1726 if (i < 0)
1727 i = buf_len + i + 1;
1728 if (i > buf_len)
1729 i = buf_len + 1;
1730 lua_pop(L, 1);
1731 } else
1732 i = 1;
1733
1734 /* Check bth i and j. */
1735 if (i > j) {
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001736 lua_pushinteger(L, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001737 return 1;
1738 }
1739 if (i == 0 && j == 0) {
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001740 lua_pushinteger(L, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001741 return 1;
1742 }
1743 if (i == 0)
1744 i = 1;
1745 if (j == 0)
1746 j = 1;
1747
1748 /* Pop the string. */
1749 lua_pop(L, 1);
1750
1751 /* Update the buffer length. */
1752 buf += i - 1;
1753 buf_len = j - i + 1;
1754 lua_pushlstring(L, buf, buf_len);
1755
1756 /* This unsigned is used to remember the amount of sent data. */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001757 lua_pushinteger(L, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001758
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001759 return MAY_LJMP(hlua_socket_write_yield(L, 0, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001760}
1761
1762#define SOCKET_INFO_EXPANDED_FORM "[0000:0000:0000:0000:0000:0000:0000:0000]:12345"
1763static char _socket_info_expanded_form[] = SOCKET_INFO_EXPANDED_FORM;
1764#define SOCKET_INFO_MAX_LEN (sizeof(_socket_info_expanded_form))
1765__LJMP static inline int hlua_socket_info(struct lua_State *L, struct sockaddr_storage *addr)
1766{
1767 static char buffer[SOCKET_INFO_MAX_LEN];
1768 int ret;
1769 int len;
1770 char *p;
1771
1772 ret = addr_to_str(addr, buffer+1, SOCKET_INFO_MAX_LEN-1);
1773 if (ret <= 0) {
1774 lua_pushnil(L);
1775 return 1;
1776 }
1777
1778 if (ret == AF_UNIX) {
1779 lua_pushstring(L, buffer+1);
1780 return 1;
1781 }
1782 else if (ret == AF_INET6) {
1783 buffer[0] = '[';
1784 len = strlen(buffer);
1785 buffer[len] = ']';
1786 len++;
1787 buffer[len] = ':';
1788 len++;
1789 p = buffer;
1790 }
1791 else if (ret == AF_INET) {
1792 p = buffer + 1;
1793 len = strlen(p);
1794 p[len] = ':';
1795 len++;
1796 }
1797 else {
1798 lua_pushnil(L);
1799 return 1;
1800 }
1801
1802 if (port_to_str(addr, p + len, SOCKET_INFO_MAX_LEN-1 - len) <= 0) {
1803 lua_pushnil(L);
1804 return 1;
1805 }
1806
1807 lua_pushstring(L, p);
1808 return 1;
1809}
1810
1811/* Returns information about the peer of the connection. */
1812__LJMP static int hlua_socket_getpeername(struct lua_State *L)
1813{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001814 struct hlua_socket *socket;
1815 struct connection *conn;
1816
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001817 MAY_LJMP(check_args(L, 1, "getpeername"));
1818
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001819 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001820
1821 /* Check if the tcp object is avalaible. */
1822 if (!socket->s) {
1823 lua_pushnil(L);
1824 return 1;
1825 }
1826
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001827 conn = objt_conn(socket->s->si[1].end);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001828 if (!conn) {
1829 lua_pushnil(L);
1830 return 1;
1831 }
1832
1833 if (!(conn->flags & CO_FL_ADDR_TO_SET)) {
1834 unsigned int salen = sizeof(conn->addr.to);
1835 if (getpeername(conn->t.sock.fd, (struct sockaddr *)&conn->addr.to, &salen) == -1) {
1836 lua_pushnil(L);
1837 return 1;
1838 }
1839 conn->flags |= CO_FL_ADDR_TO_SET;
1840 }
1841
1842 return MAY_LJMP(hlua_socket_info(L, &conn->addr.to));
1843}
1844
1845/* Returns information about my connection side. */
1846static int hlua_socket_getsockname(struct lua_State *L)
1847{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001848 struct hlua_socket *socket;
1849 struct connection *conn;
1850
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001851 MAY_LJMP(check_args(L, 1, "getsockname"));
1852
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001853 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001854
1855 /* Check if the tcp object is avalaible. */
1856 if (!socket->s) {
1857 lua_pushnil(L);
1858 return 1;
1859 }
1860
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001861 conn = objt_conn(socket->s->si[1].end);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001862 if (!conn) {
1863 lua_pushnil(L);
1864 return 1;
1865 }
1866
1867 if (!(conn->flags & CO_FL_ADDR_FROM_SET)) {
1868 unsigned int salen = sizeof(conn->addr.from);
1869 if (getsockname(conn->t.sock.fd, (struct sockaddr *)&conn->addr.from, &salen) == -1) {
1870 lua_pushnil(L);
1871 return 1;
1872 }
1873 conn->flags |= CO_FL_ADDR_FROM_SET;
1874 }
1875
1876 return hlua_socket_info(L, &conn->addr.from);
1877}
1878
1879/* This struct define the applet. */
1880static struct si_applet update_applet = {
1881 .obj_type = OBJ_TYPE_APPLET,
1882 .name = "<LUA_TCP>",
1883 .fct = hlua_socket_handler,
1884 .release = hlua_socket_release,
1885};
1886
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001887__LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001888{
1889 struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1));
1890 struct hlua *hlua = hlua_gethlua(L);
1891 struct appctx *appctx;
1892
1893 /* Check for connection close. */
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01001894 if (!hlua || !socket->s || channel_output_closed(&socket->s->req)) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001895 lua_pushnil(L);
1896 lua_pushstring(L, "Can't connect");
1897 return 2;
1898 }
1899
1900 appctx = objt_appctx(socket->s->si[0].end);
1901
1902 /* Check for connection established. */
1903 if (appctx->ctx.hlua.connected) {
1904 lua_pushinteger(L, 1);
1905 return 1;
1906 }
1907
1908 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_write))
1909 WILL_LJMP(luaL_error(L, "out of memory error"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01001910 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001911 return 0;
1912}
1913
1914/* This function fail or initite the connection. */
1915__LJMP static int hlua_socket_connect(struct lua_State *L)
1916{
1917 struct hlua_socket *socket;
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001918 int port;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001919 const char *ip;
1920 struct connection *conn;
Thierry FOURNIER95ad96a2015-03-09 18:12:40 +01001921 struct hlua *hlua;
1922 struct appctx *appctx;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001923
1924 MAY_LJMP(check_args(L, 3, "connect"));
1925
1926 /* Get args. */
1927 socket = MAY_LJMP(hlua_checksocket(L, 1));
1928 ip = MAY_LJMP(luaL_checkstring(L, 2));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001929 port = MAY_LJMP(luaL_checkinteger(L, 3));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001930
Willy Tarreau350f4872014-11-28 14:42:25 +01001931 conn = si_alloc_conn(&socket->s->si[1], 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001932 if (!conn)
1933 WILL_LJMP(luaL_error(L, "connect: internal error"));
1934
1935 /* Parse ip address. */
1936 conn->addr.to.ss_family = AF_UNSPEC;
1937 if (!str2ip2(ip, &conn->addr.to, 0))
1938 WILL_LJMP(luaL_error(L, "connect: cannot parse ip address '%s'", ip));
1939
1940 /* Set port. */
1941 if (conn->addr.to.ss_family == AF_INET)
1942 ((struct sockaddr_in *)&conn->addr.to)->sin_port = htons(port);
1943 else if (conn->addr.to.ss_family == AF_INET6)
1944 ((struct sockaddr_in6 *)&conn->addr.to)->sin6_port = htons(port);
1945
1946 /* it is important not to call the wakeup function directly but to
1947 * pass through task_wakeup(), because this one knows how to apply
1948 * priorities to tasks.
1949 */
1950 task_wakeup(socket->s->task, TASK_WOKEN_INIT);
1951
Thierry FOURNIER95ad96a2015-03-09 18:12:40 +01001952 hlua = hlua_gethlua(L);
1953 appctx = objt_appctx(socket->s->si[0].end);
1954 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_write))
1955 WILL_LJMP(luaL_error(L, "out of memory"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01001956 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001957
1958 return 0;
1959}
1960
Baptiste Assmann84bb4932015-03-02 21:40:06 +01001961#ifdef USE_OPENSSL
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001962__LJMP static int hlua_socket_connect_ssl(struct lua_State *L)
1963{
1964 struct hlua_socket *socket;
1965
1966 MAY_LJMP(check_args(L, 3, "connect_ssl"));
1967 socket = MAY_LJMP(hlua_checksocket(L, 1));
1968 socket->s->target = &socket_ssl.obj_type;
1969 return MAY_LJMP(hlua_socket_connect(L));
1970}
Baptiste Assmann84bb4932015-03-02 21:40:06 +01001971#endif
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001972
1973__LJMP static int hlua_socket_setoption(struct lua_State *L)
1974{
1975 return 0;
1976}
1977
1978__LJMP static int hlua_socket_settimeout(struct lua_State *L)
1979{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001980 struct hlua_socket *socket;
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001981 int tmout;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001982
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001983 MAY_LJMP(check_args(L, 2, "settimeout"));
1984
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001985 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001986 tmout = MAY_LJMP(luaL_checkinteger(L, 2)) * 1000;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001987
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01001988 socket->s->req.rto = tmout;
1989 socket->s->req.wto = tmout;
1990 socket->s->res.rto = tmout;
1991 socket->s->res.wto = tmout;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001992
1993 return 0;
1994}
1995
1996__LJMP static int hlua_socket_new(lua_State *L)
1997{
1998 struct hlua_socket *socket;
1999 struct appctx *appctx;
2000
2001 /* Check stack size. */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002002 if (!lua_checkstack(L, 3)) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002003 hlua_pusherror(L, "socket: full stack");
2004 goto out_fail_conf;
2005 }
2006
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002007 /* Create the object: obj[0] = userdata. */
2008 lua_newtable(L);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002009 socket = MAY_LJMP(lua_newuserdata(L, sizeof(*socket)));
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002010 lua_rawseti(L, -2, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002011 memset(socket, 0, sizeof(*socket));
2012
Thierry FOURNIER4a6170c2015-03-09 17:07:10 +01002013 /* Check if the various memory pools are intialized. */
Willy Tarreau87b09662015-04-03 00:22:06 +02002014 if (!pool2_stream || !pool2_buffer) {
Thierry FOURNIER4a6170c2015-03-09 17:07:10 +01002015 hlua_pusherror(L, "socket: uninitialized pools.");
2016 goto out_fail_conf;
2017 }
2018
Willy Tarreau87b09662015-04-03 00:22:06 +02002019 /* Pop a class stream metatable and affect it to the userdata. */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002020 lua_rawgeti(L, LUA_REGISTRYINDEX, class_socket_ref);
2021 lua_setmetatable(L, -2);
2022
2023 /*
2024 *
2025 * Get memory for the request.
2026 *
2027 */
2028
Willy Tarreau87b09662015-04-03 00:22:06 +02002029 socket->s = pool_alloc2(pool2_stream);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002030 if (!socket->s) {
2031 hlua_pusherror(L, "socket: out of memory");
2032 goto out_fail_conf;
2033 }
2034
2035 socket->s->task = task_new();
2036 if (!socket->s->task) {
2037 hlua_pusherror(L, "socket: out of memory");
2038 goto out_free_session;
2039 }
2040
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002041 socket->s->req.buf = pool_alloc2(pool2_buffer);
2042 if (!socket->s->req.buf) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002043 hlua_pusherror(L, "socket: out of memory");
2044 goto out_fail_req_buf;
2045 }
2046
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002047 socket->s->res.buf = pool_alloc2(pool2_buffer);
2048 if (!socket->s->res.buf) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002049 hlua_pusherror(L, "socket: out of memory");
2050 goto out_fail_rep_buf;
2051 }
2052
Willy Tarreau87b09662015-04-03 00:22:06 +02002053 /* Configura empty Lua for the stream. */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002054 socket->s->hlua.T = NULL;
2055 socket->s->hlua.Tref = LUA_REFNIL;
2056 socket->s->hlua.Mref = LUA_REFNIL;
2057 socket->s->hlua.nargs = 0;
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01002058 socket->s->hlua.flags = 0;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002059 LIST_INIT(&socket->s->hlua.com);
2060
Willy Tarreau87b09662015-04-03 00:22:06 +02002061 /* stream initialisation. */
2062 stream_init_srv_conn(socket->s);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002063
2064 /*
2065 *
2066 * Configure the associated task.
2067 *
2068 */
2069
Willy Tarreau87b09662015-04-03 00:22:06 +02002070 /* This is the dedicated function to process the stream. This function
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002071 * is able to establish the conection, process the timeouts, etc ...
2072 */
Willy Tarreau87b09662015-04-03 00:22:06 +02002073 socket->s->task->process = process_stream;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002074
Willy Tarreau87b09662015-04-03 00:22:06 +02002075 /* Back reference to stream. This is used by process_stream(). */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002076 socket->s->task->context = socket->s;
2077
2078 /* The priority of the task is normal. */
2079 socket->s->task->nice = 0;
2080
2081 /* Init the next run to eternity. Later in this function, this task is
2082 * waked.
2083 */
2084 socket->s->task->expire = TICK_ETERNITY;
2085
2086 /*
2087 *
2088 * Initialize the attached buffers
2089 *
2090 */
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002091 socket->s->req.buf->size = global.tune.bufsize;
2092 socket->s->res.buf->size = global.tune.bufsize;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002093
2094 /*
2095 *
2096 * Initialize channels.
2097 *
2098 */
2099
2100 /* This function reset the struct. It must be called
2101 * before the configuration.
2102 */
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002103 channel_init(&socket->s->req);
2104 channel_init(&socket->s->res);
Willy Tarreauef573c02014-11-28 14:17:09 +01002105 socket->s->res.flags |= CF_ISRESP;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002106
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002107 socket->s->req.analysers = 0;
2108 socket->s->req.rto = socket_proxy.timeout.client;
2109 socket->s->req.wto = socket_proxy.timeout.server;
2110 socket->s->req.rex = TICK_ETERNITY;
2111 socket->s->req.wex = TICK_ETERNITY;
2112 socket->s->req.analyse_exp = TICK_ETERNITY;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002113
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002114 socket->s->res.analysers = 0;
2115 socket->s->res.rto = socket_proxy.timeout.server;
2116 socket->s->res.wto = socket_proxy.timeout.client;
2117 socket->s->res.rex = TICK_ETERNITY;
2118 socket->s->res.wex = TICK_ETERNITY;
2119 socket->s->res.analyse_exp = TICK_ETERNITY;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002120
2121 /*
2122 *
Willy Tarreau87b09662015-04-03 00:22:06 +02002123 * Configure the stream.
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002124 *
2125 */
2126
Willy Tarreau87b09662015-04-03 00:22:06 +02002127 /* The stream dont have listener. The listener is used with real
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002128 * proxies.
2129 */
2130 socket->s->listener = NULL;
2131
2132 /* The flags are initialized to 0. Values are setted later. */
2133 socket->s->flags = 0;
2134
Willy Tarreau87b09662015-04-03 00:22:06 +02002135 /* Assign the configured proxy to the new stream. */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002136 socket->s->be = &socket_proxy;
2137 socket->s->fe = &socket_proxy;
2138
2139 /* XXX: Set namy variables */
2140 socket->s->store_count = 0;
2141 memset(socket->s->stkctr, 0, sizeof(socket->s->stkctr));
2142
2143 /* Configure logs. */
2144 socket->s->logs.logwait = 0;
2145 socket->s->logs.level = 0;
2146 socket->s->logs.accept_date = date; /* user-visible date for logging */
2147 socket->s->logs.tv_accept = now; /* corrected date for internal use */
2148 socket->s->do_log = NULL;
2149
2150 /* Function used if an error is occured. */
2151 socket->s->srv_error = default_srv_error;
2152
2153 /* Init the list of buffers. */
2154 LIST_INIT(&socket->s->buffer_wait);
2155
2156 /* Dont configure the unique ID. */
2157 socket->s->uniq_id = 0;
2158 socket->s->unique_id = NULL;
2159
2160 /* XXX: ? */
2161 socket->s->pend_pos = NULL;
2162
2163 /* XXX: See later. */
2164 socket->s->txn.sessid = NULL;
2165 socket->s->txn.srv_cookie = NULL;
2166 socket->s->txn.cli_cookie = NULL;
2167 socket->s->txn.uri = NULL;
2168 socket->s->txn.req.cap = NULL;
2169 socket->s->txn.rsp.cap = NULL;
2170 socket->s->txn.hdr_idx.v = NULL;
2171 socket->s->txn.hdr_idx.size = 0;
2172 socket->s->txn.hdr_idx.used = 0;
2173
2174 /* Configure "left" stream interface as applet. This "si" produce
2175 * and use the data received from the server. The applet is initialized
2176 * and is attached to the stream interface.
2177 */
2178
2179 /* The data producer is already connected. It is the applet. */
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002180 socket->s->req.flags = CF_READ_ATTACHED;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002181
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002182 channel_auto_connect(&socket->s->req); /* don't wait to establish connection */
2183 channel_auto_close(&socket->s->req); /* let the producer forward close requests */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002184
Willy Tarreaua5f5d8d2014-11-28 11:26:07 +01002185 socket->s->si[0].flags = SI_FL_NONE;
Willy Tarreau819d3322014-11-28 12:12:34 +01002186 si_reset(&socket->s->si[0]);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002187 si_set_state(&socket->s->si[0], SI_ST_EST); /* connection established (resource exists) */
2188
2189 appctx = stream_int_register_handler(&socket->s->si[0], &update_applet);
2190 if (!appctx)
2191 goto out_fail_conn1;
2192 appctx->ctx.hlua.socket = socket;
2193 appctx->ctx.hlua.connected = 0;
2194 LIST_INIT(&appctx->ctx.hlua.wake_on_write);
2195 LIST_INIT(&appctx->ctx.hlua.wake_on_read);
2196
2197 /* Configure "right" stream interface. this "si" is used to connect
2198 * and retrieve data from the server. The connection is initialized
2199 * with the "struct server".
2200 */
Willy Tarreaua5f5d8d2014-11-28 11:26:07 +01002201 socket->s->si[1].flags = SI_FL_ISBACK;
Willy Tarreau819d3322014-11-28 12:12:34 +01002202 si_reset(&socket->s->si[1]);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002203 si_set_state(&socket->s->si[1], SI_ST_INI);
2204 socket->s->si[1].conn_retries = socket_proxy.conn_retries;
2205
2206 /* Force destination server. */
Willy Tarreaue7dff022015-04-03 01:14:29 +02002207 socket->s->flags |= SF_DIRECT | SF_ASSIGNED | SF_ADDR_SET | SF_BE_ASSIGNED;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002208 socket->s->target = &socket_tcp.obj_type;
2209
Willy Tarreau87b09662015-04-03 00:22:06 +02002210 /* This stream is added to te lists of alive streams. */
2211 LIST_ADDQ(&streams, &socket->s->list);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002212
2213 /* XXX: I think that this list is used by stats. */
2214 LIST_INIT(&socket->s->back_refs);
2215
2216 /* Update statistics counters. */
2217 socket_proxy.feconn++; /* beconn will be increased later */
2218 jobs++;
2219 totalconn++;
2220
2221 /* Return yield waiting for connection. */
2222 return 1;
2223
2224out_fail_conn1:
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002225 pool_free2(pool2_buffer, socket->s->res.buf);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002226out_fail_rep_buf:
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002227 pool_free2(pool2_buffer, socket->s->req.buf);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002228out_fail_req_buf:
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002229 task_free(socket->s->task);
2230out_free_session:
Willy Tarreau87b09662015-04-03 00:22:06 +02002231 pool_free2(pool2_stream, socket->s);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002232out_fail_conf:
2233 WILL_LJMP(lua_error(L));
2234 return 0;
2235}
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01002236
2237/*
2238 *
2239 *
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002240 * Class Channel
2241 *
2242 *
2243 */
2244
2245/* Returns the struct hlua_channel join to the class channel in the
2246 * stack entry "ud" or throws an argument error.
2247 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002248__LJMP static struct channel *hlua_checkchannel(lua_State *L, int ud)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002249{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002250 return (struct channel *)MAY_LJMP(hlua_checkudata(L, ud, class_channel_ref));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002251}
2252
Willy Tarreau47860ed2015-03-10 14:07:50 +01002253/* Pushes the channel onto the top of the stack. If the stask does not have a
2254 * free slots, the function fails and returns 0;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002255 */
Willy Tarreau2a71af42015-03-10 13:51:50 +01002256static int hlua_channel_new(lua_State *L, struct channel *channel)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002257{
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002258 /* Check stack size. */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002259 if (!lua_checkstack(L, 3))
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002260 return 0;
2261
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002262 lua_newtable(L);
Willy Tarreau47860ed2015-03-10 14:07:50 +01002263 lua_pushlightuserdata(L, channel);
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002264 lua_rawseti(L, -2, 0);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002265
2266 /* Pop a class sesison metatable and affect it to the userdata. */
2267 lua_rawgeti(L, LUA_REGISTRYINDEX, class_channel_ref);
2268 lua_setmetatable(L, -2);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002269 return 1;
2270}
2271
2272/* Duplicate all the data present in the input channel and put it
2273 * in a string LUA variables. Returns -1 and push a nil value in
2274 * the stack if the channel is closed and all the data are consumed,
2275 * returns 0 if no data are available, otherwise it returns the length
2276 * of the builded string.
2277 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002278static inline int _hlua_channel_dup(struct channel *chn, lua_State *L)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002279{
2280 char *blk1;
2281 char *blk2;
2282 int len1;
2283 int len2;
2284 int ret;
2285 luaL_Buffer b;
2286
Willy Tarreau47860ed2015-03-10 14:07:50 +01002287 ret = bi_getblk_nc(chn, &blk1, &len1, &blk2, &len2);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002288 if (unlikely(ret == 0))
2289 return 0;
2290
2291 if (unlikely(ret < 0)) {
2292 lua_pushnil(L);
2293 return -1;
2294 }
2295
2296 luaL_buffinit(L, &b);
2297 luaL_addlstring(&b, blk1, len1);
2298 if (unlikely(ret == 2))
2299 luaL_addlstring(&b, blk2, len2);
2300 luaL_pushresult(&b);
2301
2302 if (unlikely(ret == 2))
2303 return len1 + len2;
2304 return len1;
2305}
2306
2307/* "_hlua_channel_dup" wrapper. If no data are available, it returns
2308 * a yield. This function keep the data in the buffer.
2309 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002310__LJMP static int hlua_channel_dup_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002311{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002312 struct channel *chn;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002313
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002314 chn = MAY_LJMP(hlua_checkchannel(L, 1));
2315
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002316 if (_hlua_channel_dup(chn, L) == 0)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002317 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_dup_yield, TICK_ETERNITY, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002318 return 1;
2319}
2320
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002321/* Check arguments for the function "hlua_channel_dup_yield". */
2322__LJMP static int hlua_channel_dup(lua_State *L)
2323{
2324 MAY_LJMP(check_args(L, 1, "dup"));
2325 MAY_LJMP(hlua_checkchannel(L, 1));
2326 return MAY_LJMP(hlua_channel_dup_yield(L, 0, 0));
2327}
2328
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002329/* "_hlua_channel_dup" wrapper. If no data are available, it returns
2330 * a yield. This function consumes the data in the buffer. It returns
2331 * a string containing the data or a nil pointer if no data are available
2332 * and the channel is closed.
2333 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002334__LJMP static int hlua_channel_get_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002335{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002336 struct channel *chn;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002337 int ret;
2338
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002339 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002340
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002341 ret = _hlua_channel_dup(chn, L);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002342 if (unlikely(ret == 0))
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002343 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_get_yield, TICK_ETERNITY, 0));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002344
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002345 if (unlikely(ret == -1))
2346 return 1;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002347
Willy Tarreau47860ed2015-03-10 14:07:50 +01002348 chn->buf->i -= ret;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002349 return 1;
2350}
2351
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002352/* Check arguments for the fucntion "hlua_channel_get_yield". */
2353__LJMP static int hlua_channel_get(lua_State *L)
2354{
2355 MAY_LJMP(check_args(L, 1, "get"));
2356 MAY_LJMP(hlua_checkchannel(L, 1));
2357 return MAY_LJMP(hlua_channel_get_yield(L, 0, 0));
2358}
2359
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002360/* This functions consumes and returns one line. If the channel is closed,
2361 * and the last data does not contains a final '\n', the data are returned
2362 * without the final '\n'. When no more data are avalaible, it returns nil
2363 * value.
2364 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002365__LJMP static int hlua_channel_getline_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002366{
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002367 char *blk1;
2368 char *blk2;
2369 int len1;
2370 int len2;
2371 int len;
Willy Tarreau47860ed2015-03-10 14:07:50 +01002372 struct channel *chn;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002373 int ret;
2374 luaL_Buffer b;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002375
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002376 chn = MAY_LJMP(hlua_checkchannel(L, 1));
2377
Willy Tarreau47860ed2015-03-10 14:07:50 +01002378 ret = bi_getline_nc(chn, &blk1, &len1, &blk2, &len2);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002379 if (ret == 0)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002380 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_getline_yield, TICK_ETERNITY, 0));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002381
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002382 if (ret == -1) {
2383 lua_pushnil(L);
2384 return 1;
2385 }
2386
2387 luaL_buffinit(L, &b);
2388 luaL_addlstring(&b, blk1, len1);
2389 len = len1;
2390 if (unlikely(ret == 2)) {
2391 luaL_addlstring(&b, blk2, len2);
2392 len += len2;
2393 }
2394 luaL_pushresult(&b);
Willy Tarreau47860ed2015-03-10 14:07:50 +01002395 buffer_replace2(chn->buf, chn->buf->p, chn->buf->p + len, NULL, 0);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002396 return 1;
2397}
2398
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002399/* Check arguments for the fucntion "hlua_channel_getline_yield". */
2400__LJMP static int hlua_channel_getline(lua_State *L)
2401{
2402 MAY_LJMP(check_args(L, 1, "getline"));
2403 MAY_LJMP(hlua_checkchannel(L, 1));
2404 return MAY_LJMP(hlua_channel_getline_yield(L, 0, 0));
2405}
2406
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002407/* This function takes a string as input, and append it at the
2408 * input side of channel. If the data is too big, but a space
2409 * is probably available after sending some data, the function
2410 * yield. If the data is bigger than the buffer, or if the
2411 * channel is closed, it returns -1. otherwise, it returns the
2412 * amount of data writed.
2413 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002414__LJMP static int hlua_channel_append_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002415{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002416 struct channel *chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002417 size_t len;
2418 const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
2419 int l = MAY_LJMP(luaL_checkinteger(L, 3));
2420 int ret;
2421 int max;
2422
Willy Tarreau47860ed2015-03-10 14:07:50 +01002423 max = channel_recv_limit(chn) - buffer_len(chn->buf);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002424 if (max > len - l)
2425 max = len - l;
2426
Willy Tarreau47860ed2015-03-10 14:07:50 +01002427 ret = bi_putblk(chn, str + l, max);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002428 if (ret == -2 || ret == -3) {
2429 lua_pushinteger(L, -1);
2430 return 1;
2431 }
Willy Tarreaubc18da12015-03-13 14:00:47 +01002432 if (ret == -1) {
2433 chn->flags |= CF_WAKE_WRITE;
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002434 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
Willy Tarreaubc18da12015-03-13 14:00:47 +01002435 }
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002436 l += ret;
2437 lua_pop(L, 1);
2438 lua_pushinteger(L, l);
2439
Willy Tarreau47860ed2015-03-10 14:07:50 +01002440 max = channel_recv_limit(chn) - buffer_len(chn->buf);
2441 if (max == 0 && chn->buf->o == 0) {
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002442 /* There are no space avalaible, and the output buffer is empty.
2443 * in this case, we cannot add more data, so we cannot yield,
2444 * we return the amount of copyied data.
2445 */
2446 return 1;
2447 }
2448 if (l < len)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002449 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002450 return 1;
2451}
2452
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002453/* just a wrapper of "hlua_channel_append_yield". It returns the length
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002454 * of the writed string, or -1 if the channel is closed or if the
2455 * buffer size is too little for the data.
2456 */
2457__LJMP static int hlua_channel_append(lua_State *L)
2458{
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002459 size_t len;
2460
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002461 MAY_LJMP(check_args(L, 2, "append"));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002462 MAY_LJMP(hlua_checkchannel(L, 1));
2463 MAY_LJMP(luaL_checklstring(L, 2, &len));
2464 MAY_LJMP(luaL_checkinteger(L, 3));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002465 lua_pushinteger(L, 0);
2466
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002467 return MAY_LJMP(hlua_channel_append_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002468}
2469
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002470/* just a wrapper of "hlua_channel_append_yield". This wrapper starts
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002471 * his process by cleaning the buffer. The result is a replacement
2472 * of the current data. It returns the length of the writed string,
2473 * or -1 if the channel is closed or if the buffer size is too
2474 * little for the data.
2475 */
2476__LJMP static int hlua_channel_set(lua_State *L)
2477{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002478 struct channel *chn;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002479
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002480 MAY_LJMP(check_args(L, 2, "set"));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002481 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002482 lua_pushinteger(L, 0);
2483
Willy Tarreau47860ed2015-03-10 14:07:50 +01002484 chn->buf->i = 0;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002485
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002486 return MAY_LJMP(hlua_channel_append_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002487}
2488
2489/* Append data in the output side of the buffer. This data is immediatly
2490 * sent. The fcuntion returns the ammount of data writed. If the buffer
2491 * cannot contains the data, the function yield. The function returns -1
2492 * if the channel is closed.
2493 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002494__LJMP static int hlua_channel_send_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002495{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002496 struct channel *chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002497 size_t len;
2498 const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
2499 int l = MAY_LJMP(luaL_checkinteger(L, 3));
2500 int max;
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002501 struct hlua *hlua = hlua_gethlua(L);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002502
Willy Tarreau47860ed2015-03-10 14:07:50 +01002503 if (unlikely(channel_output_closed(chn))) {
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002504 lua_pushinteger(L, -1);
2505 return 1;
2506 }
2507
Thierry FOURNIER3e3a6082015-03-05 17:06:12 +01002508 /* Check if the buffer is avalaible because HAProxy doesn't allocate
2509 * the request buffer if its not required.
2510 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002511 if (chn->buf->size == 0) {
Willy Tarreau87b09662015-04-03 00:22:06 +02002512 if (!stream_alloc_recv_buffer(chn)) {
Willy Tarreau47860ed2015-03-10 14:07:50 +01002513 chn_prod(chn)->flags |= SI_FL_WAIT_ROOM;
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002514 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
Thierry FOURNIER3e3a6082015-03-05 17:06:12 +01002515 }
2516 }
2517
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002518 /* the writed data will be immediatly sent, so we can check
2519 * the avalaible space without taking in account the reserve.
2520 * The reserve is guaranted for the processing of incoming
2521 * data, because the buffer will be flushed.
2522 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002523 max = chn->buf->size - buffer_len(chn->buf);
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002524
2525 /* If there are no space avalaible, and the output buffer is empty.
2526 * in this case, we cannot add more data, so we cannot yield,
2527 * we return the amount of copyied data.
2528 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002529 if (max == 0 && chn->buf->o == 0)
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002530 return 1;
2531
2532 /* Adjust the real required length. */
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002533 if (max > len - l)
2534 max = len - l;
2535
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002536 /* The buffer avalaible size may be not contiguous. This test
2537 * detects a non contiguous buffer and realign it.
2538 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002539 if (bi_space_for_replace(chn->buf) < max)
2540 buffer_slow_realign(chn->buf);
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002541
2542 /* Copy input data in the buffer. */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002543 max = buffer_replace2(chn->buf, chn->buf->p, chn->buf->p, str + l, max);
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002544
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002545 /* buffer replace considers that the input part is filled.
2546 * so, I must forward these new data in the output part.
2547 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002548 b_adv(chn->buf, max);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002549
2550 l += max;
2551 lua_pop(L, 1);
2552 lua_pushinteger(L, l);
2553
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002554 /* If there are no space avalaible, and the output buffer is empty.
2555 * in this case, we cannot add more data, so we cannot yield,
2556 * we return the amount of copyied data.
2557 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002558 max = chn->buf->size - buffer_len(chn->buf);
2559 if (max == 0 && chn->buf->o == 0)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002560 return 1;
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002561
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002562 if (l < len) {
2563 /* If we are waiting for space in the response buffer, we
2564 * must set the flag WAKERESWR. This flag required the task
2565 * wake up if any activity is detected on the response buffer.
2566 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002567 if (chn->flags & CF_ISRESP)
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002568 HLUA_SET_WAKERESWR(hlua);
Thierry FOURNIER53e08ec2015-03-06 00:35:53 +01002569 else
2570 HLUA_SET_WAKEREQWR(hlua);
2571 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002572 }
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002573
2574 return 1;
2575}
2576
2577/* Just a wraper of "_hlua_channel_send". This wrapper permits
2578 * yield the LUA process, and resume it without checking the
2579 * input arguments.
2580 */
2581__LJMP static int hlua_channel_send(lua_State *L)
2582{
2583 MAY_LJMP(check_args(L, 2, "send"));
2584 lua_pushinteger(L, 0);
2585
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002586 return MAY_LJMP(hlua_channel_send_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002587}
2588
2589/* This function forward and amount of butes. The data pass from
2590 * the input side of the buffer to the output side, and can be
2591 * forwarded. This function never fails.
2592 *
2593 * The Lua function takes an amount of bytes to be forwarded in
2594 * imput. It returns the number of bytes forwarded.
2595 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002596__LJMP static int hlua_channel_forward_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002597{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002598 struct channel *chn;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002599 int len;
2600 int l;
2601 int max;
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002602 struct hlua *hlua = hlua_gethlua(L);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002603
2604 chn = MAY_LJMP(hlua_checkchannel(L, 1));
2605 len = MAY_LJMP(luaL_checkinteger(L, 2));
2606 l = MAY_LJMP(luaL_checkinteger(L, -1));
2607
2608 max = len - l;
Willy Tarreau47860ed2015-03-10 14:07:50 +01002609 if (max > chn->buf->i)
2610 max = chn->buf->i;
2611 channel_forward(chn, max);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002612 l += max;
2613
2614 lua_pop(L, 1);
2615 lua_pushinteger(L, l);
2616
2617 /* Check if it miss bytes to forward. */
2618 if (l < len) {
2619 /* The the input channel or the output channel are closed, we
2620 * must return the amount of data forwarded.
2621 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002622 if (channel_input_closed(chn) || channel_output_closed(chn))
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002623 return 1;
2624
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002625 /* If we are waiting for space data in the response buffer, we
2626 * must set the flag WAKERESWR. This flag required the task
2627 * wake up if any activity is detected on the response buffer.
2628 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002629 if (chn->flags & CF_ISRESP)
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002630 HLUA_SET_WAKERESWR(hlua);
Thierry FOURNIER53e08ec2015-03-06 00:35:53 +01002631 else
2632 HLUA_SET_WAKEREQWR(hlua);
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002633
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002634 /* Otherwise, we can yield waiting for new data in the inpout side. */
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01002635 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_forward_yield, TICK_ETERNITY, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002636 }
2637
2638 return 1;
2639}
2640
2641/* Just check the input and prepare the stack for the previous
2642 * function "hlua_channel_forward_yield"
2643 */
2644__LJMP static int hlua_channel_forward(lua_State *L)
2645{
2646 MAY_LJMP(check_args(L, 2, "forward"));
2647 MAY_LJMP(hlua_checkchannel(L, 1));
2648 MAY_LJMP(luaL_checkinteger(L, 2));
2649
2650 lua_pushinteger(L, 0);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002651 return MAY_LJMP(hlua_channel_forward_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002652}
2653
2654/* Just returns the number of bytes available in the input
2655 * side of the buffer. This function never fails.
2656 */
2657__LJMP static int hlua_channel_get_in_len(lua_State *L)
2658{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002659 struct channel *chn;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002660
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002661 MAY_LJMP(check_args(L, 1, "get_in_len"));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002662 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Willy Tarreau47860ed2015-03-10 14:07:50 +01002663 lua_pushinteger(L, chn->buf->i);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002664 return 1;
2665}
2666
2667/* Just returns the number of bytes available in the output
2668 * side of the buffer. This function never fails.
2669 */
2670__LJMP static int hlua_channel_get_out_len(lua_State *L)
2671{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002672 struct channel *chn;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002673
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002674 MAY_LJMP(check_args(L, 1, "get_out_len"));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002675 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Willy Tarreau47860ed2015-03-10 14:07:50 +01002676 lua_pushinteger(L, chn->buf->o);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002677 return 1;
2678}
2679
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002680/*
2681 *
2682 *
2683 * Class Fetches
2684 *
2685 *
2686 */
2687
2688/* Returns a struct hlua_session if the stack entry "ud" is
Willy Tarreau87b09662015-04-03 00:22:06 +02002689 * a class stream, otherwise it throws an error.
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002690 */
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002691__LJMP static struct hlua_smp *hlua_checkfetches(lua_State *L, int ud)
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002692{
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002693 return (struct hlua_smp *)MAY_LJMP(hlua_checkudata(L, ud, class_fetches_ref));
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002694}
2695
2696/* This function creates and push in the stack a fetch object according
2697 * with a current TXN.
2698 */
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002699static int hlua_fetches_new(lua_State *L, struct hlua_txn *txn, int stringsafe)
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002700{
Willy Tarreau7073c472015-04-06 11:15:40 +02002701 struct hlua_smp *hsmp;
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002702
2703 /* Check stack size. */
2704 if (!lua_checkstack(L, 3))
2705 return 0;
2706
2707 /* Create the object: obj[0] = userdata.
2708 * Note that the base of the Fetches object is the
2709 * transaction object.
2710 */
2711 lua_newtable(L);
Willy Tarreau7073c472015-04-06 11:15:40 +02002712 hsmp = lua_newuserdata(L, sizeof(*hsmp));
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002713 lua_rawseti(L, -2, 0);
2714
Willy Tarreau7073c472015-04-06 11:15:40 +02002715 hsmp->s = txn->s;
2716 hsmp->p = txn->p;
2717 hsmp->l7 = txn->l7;
2718 hsmp->stringsafe = stringsafe;
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002719
2720 /* Pop a class sesison metatable and affect it to the userdata. */
2721 lua_rawgeti(L, LUA_REGISTRYINDEX, class_fetches_ref);
2722 lua_setmetatable(L, -2);
2723
2724 return 1;
2725}
2726
2727/* This function is an LUA binding. It is called with each sample-fetch.
2728 * It uses closure argument to store the associated sample-fetch. It
2729 * returns only one argument or throws an error. An error is thrown
2730 * only if an error is encountered during the argument parsing. If
2731 * the "sample-fetch" function fails, nil is returned.
2732 */
2733__LJMP static int hlua_run_sample_fetch(lua_State *L)
2734{
Willy Tarreaub2ccb562015-04-06 11:11:15 +02002735 struct hlua_smp *hsmp;
Willy Tarreau2ec22742015-03-10 14:27:20 +01002736 struct sample_fetch *f;
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002737 struct arg args[ARGM_NBARGS + 1];
2738 int i;
2739 struct sample smp;
2740
2741 /* Get closure arguments. */
Willy Tarreau2ec22742015-03-10 14:27:20 +01002742 f = (struct sample_fetch *)lua_touserdata(L, lua_upvalueindex(1));
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002743
2744 /* Get traditionnal arguments. */
Willy Tarreaub2ccb562015-04-06 11:11:15 +02002745 hsmp = MAY_LJMP(hlua_checkfetches(L, 1));
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002746
2747 /* Get extra arguments. */
2748 for (i = 0; i < lua_gettop(L) - 1; i++) {
2749 if (i >= ARGM_NBARGS)
2750 break;
2751 hlua_lua2arg(L, i + 2, &args[i]);
2752 }
2753 args[i].type = ARGT_STOP;
2754
2755 /* Check arguments. */
Willy Tarreaub2ccb562015-04-06 11:11:15 +02002756 MAY_LJMP(hlua_lua2arg_check(L, 2, args, f->arg_mask, hsmp->p));
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002757
2758 /* Run the special args checker. */
Willy Tarreau2ec22742015-03-10 14:27:20 +01002759 if (f->val_args && !f->val_args(args, NULL)) {
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002760 lua_pushfstring(L, "error in arguments");
2761 WILL_LJMP(lua_error(L));
2762 }
2763
2764 /* Initialise the sample. */
2765 memset(&smp, 0, sizeof(smp));
2766
2767 /* Run the sample fetch process. */
Willy Tarreaub2ccb562015-04-06 11:11:15 +02002768 if (!f->process(hsmp->p, hsmp->s, hsmp->l7, 0, args, &smp, f->kw, f->private)) {
2769 if (hsmp->stringsafe)
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002770 lua_pushstring(L, "");
2771 else
2772 lua_pushnil(L);
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002773 return 1;
2774 }
2775
2776 /* Convert the returned sample in lua value. */
Willy Tarreaub2ccb562015-04-06 11:11:15 +02002777 if (hsmp->stringsafe)
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002778 hlua_smp2lua_str(L, &smp);
2779 else
2780 hlua_smp2lua(L, &smp);
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002781 return 1;
2782}
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002783
2784/*
2785 *
2786 *
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002787 * Class Converters
2788 *
2789 *
2790 */
2791
2792/* Returns a struct hlua_session if the stack entry "ud" is
Willy Tarreau87b09662015-04-03 00:22:06 +02002793 * a class stream, otherwise it throws an error.
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002794 */
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002795__LJMP static struct hlua_smp *hlua_checkconverters(lua_State *L, int ud)
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002796{
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002797 return (struct hlua_smp *)MAY_LJMP(hlua_checkudata(L, ud, class_converters_ref));
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002798}
2799
2800/* This function creates and push in the stack a Converters object
2801 * according with a current TXN.
2802 */
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002803static int hlua_converters_new(lua_State *L, struct hlua_txn *txn, int stringsafe)
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002804{
Willy Tarreau7073c472015-04-06 11:15:40 +02002805 struct hlua_smp *hsmp;
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002806
2807 /* Check stack size. */
2808 if (!lua_checkstack(L, 3))
2809 return 0;
2810
2811 /* Create the object: obj[0] = userdata.
2812 * Note that the base of the Converters object is the
2813 * same than the TXN object.
2814 */
2815 lua_newtable(L);
Willy Tarreau7073c472015-04-06 11:15:40 +02002816 hsmp = lua_newuserdata(L, sizeof(*hsmp));
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002817 lua_rawseti(L, -2, 0);
2818
Willy Tarreau7073c472015-04-06 11:15:40 +02002819 hsmp->s = txn->s;
2820 hsmp->p = txn->p;
2821 hsmp->l7 = txn->l7;
2822 hsmp->stringsafe = stringsafe;
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002823
Willy Tarreau87b09662015-04-03 00:22:06 +02002824 /* Pop a class stream metatable and affect it to the table. */
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002825 lua_rawgeti(L, LUA_REGISTRYINDEX, class_converters_ref);
2826 lua_setmetatable(L, -2);
2827
2828 return 1;
2829}
2830
2831/* This function is an LUA binding. It is called with each converter.
2832 * It uses closure argument to store the associated converter. It
2833 * returns only one argument or throws an error. An error is thrown
2834 * only if an error is encountered during the argument parsing. If
2835 * the converter function function fails, nil is returned.
2836 */
2837__LJMP static int hlua_run_sample_conv(lua_State *L)
2838{
Willy Tarreauda5f1082015-04-06 11:17:13 +02002839 struct hlua_smp *hsmp;
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002840 struct sample_conv *conv;
2841 struct arg args[ARGM_NBARGS + 1];
2842 int i;
2843 struct sample smp;
2844
2845 /* Get closure arguments. */
2846 conv = (struct sample_conv *)lua_touserdata(L, lua_upvalueindex(1));
2847
2848 /* Get traditionnal arguments. */
Willy Tarreauda5f1082015-04-06 11:17:13 +02002849 hsmp = MAY_LJMP(hlua_checkconverters(L, 1));
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002850
2851 /* Get extra arguments. */
2852 for (i = 0; i < lua_gettop(L) - 2; i++) {
2853 if (i >= ARGM_NBARGS)
2854 break;
2855 hlua_lua2arg(L, i + 3, &args[i]);
2856 }
2857 args[i].type = ARGT_STOP;
2858
2859 /* Check arguments. */
Willy Tarreauda5f1082015-04-06 11:17:13 +02002860 MAY_LJMP(hlua_lua2arg_check(L, 3, args, conv->arg_mask, hsmp->p));
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002861
2862 /* Run the special args checker. */
2863 if (conv->val_args && !conv->val_args(args, conv, "", 0, NULL)) {
2864 hlua_pusherror(L, "error in arguments");
2865 WILL_LJMP(lua_error(L));
2866 }
2867
2868 /* Initialise the sample. */
2869 if (!hlua_lua2smp(L, 2, &smp)) {
2870 hlua_pusherror(L, "error in the input argument");
2871 WILL_LJMP(lua_error(L));
2872 }
2873
2874 /* Apply expected cast. */
2875 if (!sample_casts[smp.type][conv->in_type]) {
2876 hlua_pusherror(L, "invalid input argument: cannot cast '%s' to '%s'",
2877 smp_to_type[smp.type], smp_to_type[conv->in_type]);
2878 WILL_LJMP(lua_error(L));
2879 }
2880 if (sample_casts[smp.type][conv->in_type] != c_none &&
2881 !sample_casts[smp.type][conv->in_type](&smp)) {
2882 hlua_pusherror(L, "error during the input argument casting");
2883 WILL_LJMP(lua_error(L));
2884 }
2885
2886 /* Run the sample conversion process. */
Willy Tarreauda5f1082015-04-06 11:17:13 +02002887 if (!conv->process(hsmp->s, args, &smp, conv->private)) {
2888 if (hsmp->stringsafe)
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002889 lua_pushstring(L, "");
2890 else
2891 lua_pushnil(L);
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002892 return 1;
2893 }
2894
2895 /* Convert the returned sample in lua value. */
Willy Tarreauda5f1082015-04-06 11:17:13 +02002896 if (hsmp->stringsafe)
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002897 hlua_smp2lua_str(L, &smp);
2898 else
2899 hlua_smp2lua(L, &smp);
2900 return 1;
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002901}
2902
2903/*
2904 *
2905 *
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002906 * Class HTTP
2907 *
2908 *
2909 */
2910
2911/* Returns a struct hlua_txn if the stack entry "ud" is
Willy Tarreau87b09662015-04-03 00:22:06 +02002912 * a class stream, otherwise it throws an error.
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002913 */
2914__LJMP static struct hlua_txn *hlua_checkhttp(lua_State *L, int ud)
2915{
2916 return (struct hlua_txn *)MAY_LJMP(hlua_checkudata(L, ud, class_http_ref));
2917}
2918
2919/* This function creates and push in the stack a HTTP object
2920 * according with a current TXN.
2921 */
2922static int hlua_http_new(lua_State *L, struct hlua_txn *txn)
2923{
Willy Tarreau9a8ad862015-04-06 11:14:06 +02002924 struct hlua_txn *htxn;
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002925
2926 /* Check stack size. */
2927 if (!lua_checkstack(L, 3))
2928 return 0;
2929
2930 /* Create the object: obj[0] = userdata.
2931 * Note that the base of the Converters object is the
2932 * same than the TXN object.
2933 */
2934 lua_newtable(L);
Willy Tarreau9a8ad862015-04-06 11:14:06 +02002935 htxn = lua_newuserdata(L, sizeof(*htxn));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002936 lua_rawseti(L, -2, 0);
2937
Willy Tarreau9a8ad862015-04-06 11:14:06 +02002938 htxn->s = txn->s;
2939 htxn->p = txn->p;
2940 htxn->l7 = txn->l7;
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002941
Willy Tarreau87b09662015-04-03 00:22:06 +02002942 /* Pop a class stream metatable and affect it to the table. */
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002943 lua_rawgeti(L, LUA_REGISTRYINDEX, class_http_ref);
2944 lua_setmetatable(L, -2);
2945
2946 return 1;
2947}
2948
2949/* This function creates ans returns an array of HTTP headers.
2950 * This function does not fails. It is used as wrapper with the
2951 * 2 following functions.
2952 */
2953__LJMP static int hlua_http_get_headers(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
2954{
2955 const char *cur_ptr, *cur_next, *p;
2956 int old_idx, cur_idx;
2957 struct hdr_idx_elem *cur_hdr;
2958 const char *hn, *hv;
2959 int hnl, hvl;
2960
2961 /* Create the table. */
2962 lua_newtable(L);
2963
2964 /* Build array of headers. */
2965 old_idx = 0;
2966 cur_next = msg->chn->buf->p + hdr_idx_first_pos(&htxn->s->txn.hdr_idx);
2967
2968 while (1) {
2969 cur_idx = htxn->s->txn.hdr_idx.v[old_idx].next;
2970 if (!cur_idx)
2971 break;
2972 old_idx = cur_idx;
2973
2974 cur_hdr = &htxn->s->txn.hdr_idx.v[cur_idx];
2975 cur_ptr = cur_next;
2976 cur_next = cur_ptr + cur_hdr->len + cur_hdr->cr + 1;
2977
2978 /* Now we have one full header at cur_ptr of len cur_hdr->len,
2979 * and the next header starts at cur_next. We'll check
2980 * this header in the list as well as against the default
2981 * rule.
2982 */
2983
2984 /* look for ': *'. */
2985 hn = cur_ptr;
2986 for (p = cur_ptr; p < cur_ptr + cur_hdr->len && *p != ':'; p++);
2987 if (p >= cur_ptr+cur_hdr->len)
2988 continue;
2989 hnl = p - hn;
2990 p++;
2991 while (p < cur_ptr+cur_hdr->len && ( *p == ' ' || *p == '\t' ))
2992 p++;
2993 if (p >= cur_ptr+cur_hdr->len)
2994 continue;
2995 hv = p;
2996 hvl = cur_ptr+cur_hdr->len-p;
2997
2998 /* Push values in the table. */
2999 lua_pushlstring(L, hn, hnl);
3000 lua_pushlstring(L, hv, hvl);
3001 lua_settable(L, -3);
3002 }
3003
3004 return 1;
3005}
3006
3007__LJMP static int hlua_http_req_get_headers(lua_State *L)
3008{
3009 struct hlua_txn *htxn;
3010
3011 MAY_LJMP(check_args(L, 1, "req_get_headers"));
3012 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3013
3014 return hlua_http_get_headers(L, htxn, &htxn->s->txn.req);
3015}
3016
3017__LJMP static int hlua_http_res_get_headers(lua_State *L)
3018{
3019 struct hlua_txn *htxn;
3020
3021 MAY_LJMP(check_args(L, 1, "res_get_headers"));
3022 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3023
3024 return hlua_http_get_headers(L, htxn, &htxn->s->txn.rsp);
3025}
3026
3027/* This function replace full header, or just a value in
3028 * the request or in the response. It is a wrapper fir the
3029 * 4 following functions.
3030 */
3031__LJMP static inline int hlua_http_rep_hdr(lua_State *L, struct hlua_txn *htxn,
3032 struct http_msg *msg, int action)
3033{
3034 size_t name_len;
3035 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
3036 const char *reg = MAY_LJMP(luaL_checkstring(L, 3));
3037 const char *value = MAY_LJMP(luaL_checkstring(L, 4));
3038 struct my_regex re;
3039
3040 if (!regex_comp(reg, &re, 1, 1, NULL))
3041 WILL_LJMP(luaL_argerror(L, 3, "invalid regex"));
3042
3043 http_transform_header_str(htxn->s, msg, name, name_len, value, &re, action);
3044 regex_free(&re);
3045 return 0;
3046}
3047
3048__LJMP static int hlua_http_req_rep_hdr(lua_State *L)
3049{
3050 struct hlua_txn *htxn;
3051
3052 MAY_LJMP(check_args(L, 4, "req_rep_hdr"));
3053 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3054
3055 return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn.req, HTTP_REQ_ACT_REPLACE_HDR));
3056}
3057
3058__LJMP static int hlua_http_res_rep_hdr(lua_State *L)
3059{
3060 struct hlua_txn *htxn;
3061
3062 MAY_LJMP(check_args(L, 4, "res_rep_hdr"));
3063 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3064
3065 return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn.rsp, HTTP_RES_ACT_REPLACE_HDR));
3066}
3067
3068__LJMP static int hlua_http_req_rep_val(lua_State *L)
3069{
3070 struct hlua_txn *htxn;
3071
3072 MAY_LJMP(check_args(L, 4, "req_rep_hdr"));
3073 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3074
3075 return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn.req, HTTP_REQ_ACT_REPLACE_VAL));
3076}
3077
3078__LJMP static int hlua_http_res_rep_val(lua_State *L)
3079{
3080 struct hlua_txn *htxn;
3081
3082 MAY_LJMP(check_args(L, 4, "res_rep_val"));
3083 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3084
3085 return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn.rsp, HTTP_RES_ACT_REPLACE_VAL));
3086}
3087
3088/* This function deletes all the occurences of an header.
3089 * It is a wrapper for the 2 following functions.
3090 */
3091__LJMP static inline int hlua_http_del_hdr(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
3092{
3093 size_t len;
3094 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &len));
3095 struct hdr_ctx ctx;
3096 struct http_txn *txn = &htxn->s->txn;
3097
3098 ctx.idx = 0;
3099 while (http_find_header2(name, len, msg->chn->buf->p, &txn->hdr_idx, &ctx))
3100 http_remove_header2(msg, &txn->hdr_idx, &ctx);
3101 return 0;
3102}
3103
3104__LJMP static int hlua_http_req_del_hdr(lua_State *L)
3105{
3106 struct hlua_txn *htxn;
3107
3108 MAY_LJMP(check_args(L, 2, "req_del_hdr"));
3109 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3110
3111 return hlua_http_del_hdr(L, htxn, &htxn->s->txn.req);
3112}
3113
3114__LJMP static int hlua_http_res_del_hdr(lua_State *L)
3115{
3116 struct hlua_txn *htxn;
3117
3118 MAY_LJMP(check_args(L, 2, "req_del_hdr"));
3119 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3120
3121 return hlua_http_del_hdr(L, htxn, &htxn->s->txn.rsp);
3122}
3123
3124/* This function adds an header. It is a wrapper used by
3125 * the 2 following functions.
3126 */
3127__LJMP static inline int hlua_http_add_hdr(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
3128{
3129 size_t name_len;
3130 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
3131 size_t value_len;
3132 const char *value = MAY_LJMP(luaL_checklstring(L, 3, &value_len));
3133 char *p;
3134
3135 /* Check length. */
3136 trash.len = value_len + name_len + 2;
3137 if (trash.len > trash.size)
3138 return 0;
3139
3140 /* Creates the header string. */
3141 p = trash.str;
3142 memcpy(p, name, name_len);
3143 p += name_len;
3144 *p = ':';
3145 p++;
3146 *p = ' ';
3147 p++;
3148 memcpy(p, value, value_len);
3149
3150 lua_pushboolean(L, http_header_add_tail2(msg, &htxn->s->txn.hdr_idx,
3151 trash.str, trash.len) != 0);
3152
3153 return 0;
3154}
3155
3156__LJMP static int hlua_http_req_add_hdr(lua_State *L)
3157{
3158 struct hlua_txn *htxn;
3159
3160 MAY_LJMP(check_args(L, 3, "req_add_hdr"));
3161 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3162
3163 return hlua_http_add_hdr(L, htxn, &htxn->s->txn.req);
3164}
3165
3166__LJMP static int hlua_http_res_add_hdr(lua_State *L)
3167{
3168 struct hlua_txn *htxn;
3169
3170 MAY_LJMP(check_args(L, 3, "res_add_hdr"));
3171 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3172
3173 return hlua_http_add_hdr(L, htxn, &htxn->s->txn.rsp);
3174}
3175
3176static int hlua_http_req_set_hdr(lua_State *L)
3177{
3178 struct hlua_txn *htxn;
3179
3180 MAY_LJMP(check_args(L, 3, "req_set_hdr"));
3181 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3182
3183 hlua_http_del_hdr(L, htxn, &htxn->s->txn.req);
3184 return hlua_http_add_hdr(L, htxn, &htxn->s->txn.req);
3185}
3186
3187static int hlua_http_res_set_hdr(lua_State *L)
3188{
3189 struct hlua_txn *htxn;
3190
3191 MAY_LJMP(check_args(L, 3, "res_set_hdr"));
3192 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3193
3194 hlua_http_del_hdr(L, htxn, &htxn->s->txn.rsp);
3195 return hlua_http_add_hdr(L, htxn, &htxn->s->txn.rsp);
3196}
3197
3198/* This function set the method. */
3199static int hlua_http_req_set_meth(lua_State *L)
3200{
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003201 struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003202 size_t name_len;
3203 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003204 struct http_txn *txn = &htxn->s->txn;
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003205
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003206 lua_pushboolean(L, http_replace_req_line(0, name, name_len, htxn->p, htxn->s, txn) != -1);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003207 return 1;
3208}
3209
3210/* This function set the method. */
3211static int hlua_http_req_set_path(lua_State *L)
3212{
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003213 struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003214 size_t name_len;
3215 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003216 struct http_txn *txn = &htxn->s->txn;
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003217
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003218 lua_pushboolean(L, http_replace_req_line(1, name, name_len, htxn->p, htxn->s, txn) != -1);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003219 return 1;
3220}
3221
3222/* This function set the query-string. */
3223static int hlua_http_req_set_query(lua_State *L)
3224{
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003225 struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003226 size_t name_len;
3227 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003228 struct http_txn *txn = &htxn->s->txn;
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003229
3230 /* Check length. */
3231 if (name_len > trash.size - 1) {
3232 lua_pushboolean(L, 0);
3233 return 1;
3234 }
3235
3236 /* Add the mark question as prefix. */
3237 chunk_reset(&trash);
3238 trash.str[trash.len++] = '?';
3239 memcpy(trash.str + trash.len, name, name_len);
3240 trash.len += name_len;
3241
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003242 lua_pushboolean(L, http_replace_req_line(2, trash.str, trash.len, htxn->p, htxn->s, txn) != -1);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003243 return 1;
3244}
3245
3246/* This function set the uri. */
3247static int hlua_http_req_set_uri(lua_State *L)
3248{
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003249 struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003250 size_t name_len;
3251 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003252 struct http_txn *txn = &htxn->s->txn;
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003253
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003254 lua_pushboolean(L, http_replace_req_line(3, name, name_len, htxn->p, htxn->s, txn) != -1);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003255 return 1;
3256}
3257
3258/*
3259 *
3260 *
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003261 * Class TXN
3262 *
3263 *
3264 */
3265
3266/* Returns a struct hlua_session if the stack entry "ud" is
Willy Tarreau87b09662015-04-03 00:22:06 +02003267 * a class stream, otherwise it throws an error.
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003268 */
3269__LJMP static struct hlua_txn *hlua_checktxn(lua_State *L, int ud)
3270{
3271 return (struct hlua_txn *)MAY_LJMP(hlua_checkudata(L, ud, class_txn_ref));
3272}
3273
Willy Tarreau59551662015-03-10 14:23:13 +01003274__LJMP static int hlua_set_priv(lua_State *L)
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003275{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003276 struct hlua *hlua;
3277
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003278 MAY_LJMP(check_args(L, 2, "set_priv"));
3279
Willy Tarreau87b09662015-04-03 00:22:06 +02003280 /* It is useles to retrieve the stream, but this function
3281 * runs only in a stream context.
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003282 */
3283 MAY_LJMP(hlua_checktxn(L, 1));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003284 hlua = hlua_gethlua(L);
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003285
3286 /* Remove previous value. */
3287 if (hlua->Mref != -1)
3288 luaL_unref(L, hlua->Mref, LUA_REGISTRYINDEX);
3289
3290 /* Get and store new value. */
3291 lua_pushvalue(L, 2); /* Copy the element 2 at the top of the stack. */
3292 hlua->Mref = luaL_ref(L, LUA_REGISTRYINDEX); /* pop the previously pushed value. */
3293
3294 return 0;
3295}
3296
Willy Tarreau59551662015-03-10 14:23:13 +01003297__LJMP static int hlua_get_priv(lua_State *L)
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003298{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003299 struct hlua *hlua;
3300
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003301 MAY_LJMP(check_args(L, 1, "get_priv"));
3302
Willy Tarreau87b09662015-04-03 00:22:06 +02003303 /* It is useles to retrieve the stream, but this function
3304 * runs only in a stream context.
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003305 */
3306 MAY_LJMP(hlua_checktxn(L, 1));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003307 hlua = hlua_gethlua(L);
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003308
3309 /* Push configuration index in the stack. */
3310 lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
3311
3312 return 1;
3313}
3314
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003315/* Create stack entry containing a class TXN. This function
3316 * return 0 if the stack does not contains free slots,
3317 * otherwise it returns 1.
3318 */
Willy Tarreau87b09662015-04-03 00:22:06 +02003319static int hlua_txn_new(lua_State *L, struct stream *s, struct proxy *p, void *l7)
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003320{
Willy Tarreaude491382015-04-06 11:04:28 +02003321 struct hlua_txn *htxn;
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003322
3323 /* Check stack size. */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01003324 if (!lua_checkstack(L, 3))
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003325 return 0;
3326
3327 /* NOTE: The allocation never fails. The failure
3328 * throw an error, and the function never returns.
3329 * if the throw is not avalaible, the process is aborted.
3330 */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01003331 /* Create the object: obj[0] = userdata. */
3332 lua_newtable(L);
Willy Tarreaude491382015-04-06 11:04:28 +02003333 htxn = lua_newuserdata(L, sizeof(*htxn));
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01003334 lua_rawseti(L, -2, 0);
3335
Willy Tarreaude491382015-04-06 11:04:28 +02003336 htxn->s = s;
3337 htxn->p = p;
3338 htxn->l7 = l7;
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003339
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01003340 /* Create the "f" field that contains a list of fetches. */
3341 lua_pushstring(L, "f");
Willy Tarreaude491382015-04-06 11:04:28 +02003342 if (!hlua_fetches_new(L, htxn, 0))
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01003343 return 0;
3344 lua_settable(L, -3);
3345
3346 /* Create the "sf" field that contains a list of stringsafe fetches. */
3347 lua_pushstring(L, "sf");
Willy Tarreaude491382015-04-06 11:04:28 +02003348 if (!hlua_fetches_new(L, htxn, 1))
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01003349 return 0;
3350 lua_settable(L, -3);
3351
Thierry FOURNIER594afe72015-03-10 23:58:30 +01003352 /* Create the "c" field that contains a list of converters. */
3353 lua_pushstring(L, "c");
Willy Tarreaude491382015-04-06 11:04:28 +02003354 if (!hlua_converters_new(L, htxn, 0))
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01003355 return 0;
3356 lua_settable(L, -3);
3357
3358 /* Create the "sc" field that contains a list of stringsafe converters. */
3359 lua_pushstring(L, "sc");
Willy Tarreaude491382015-04-06 11:04:28 +02003360 if (!hlua_converters_new(L, htxn, 1))
Thierry FOURNIER594afe72015-03-10 23:58:30 +01003361 return 0;
3362 lua_settable(L, -3);
3363
Thierry FOURNIER397826a2015-03-11 19:39:09 +01003364 /* Create the "req" field that contains the request channel object. */
3365 lua_pushstring(L, "req");
Willy Tarreau2a71af42015-03-10 13:51:50 +01003366 if (!hlua_channel_new(L, &s->req))
Thierry FOURNIER397826a2015-03-11 19:39:09 +01003367 return 0;
3368 lua_settable(L, -3);
3369
3370 /* Create the "res" field that contains the response channel object. */
3371 lua_pushstring(L, "res");
Willy Tarreau2a71af42015-03-10 13:51:50 +01003372 if (!hlua_channel_new(L, &s->res))
Thierry FOURNIER397826a2015-03-11 19:39:09 +01003373 return 0;
3374 lua_settable(L, -3);
3375
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003376 /* Creates the HTTP object is the current proxy allows http. */
3377 lua_pushstring(L, "http");
3378 if (p->mode == PR_MODE_HTTP) {
Willy Tarreaude491382015-04-06 11:04:28 +02003379 if (!hlua_http_new(L, htxn))
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003380 return 0;
3381 }
3382 else
3383 lua_pushnil(L);
3384 lua_settable(L, -3);
3385
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003386 /* Pop a class sesison metatable and affect it to the userdata. */
3387 lua_rawgeti(L, LUA_REGISTRYINDEX, class_txn_ref);
3388 lua_setmetatable(L, -2);
3389
3390 return 1;
3391}
3392
Thierry FOURNIERc798b5d2015-03-17 01:09:57 +01003393__LJMP static int hlua_txn_deflog(lua_State *L)
3394{
3395 const char *msg;
3396 struct hlua_txn *htxn;
3397
3398 MAY_LJMP(check_args(L, 2, "deflog"));
3399 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3400 msg = MAY_LJMP(luaL_checkstring(L, 2));
3401
3402 hlua_sendlog(htxn->s->be, htxn->s->logs.level, msg);
3403 return 0;
3404}
3405
3406__LJMP static int hlua_txn_log(lua_State *L)
3407{
3408 int level;
3409 const char *msg;
3410 struct hlua_txn *htxn;
3411
3412 MAY_LJMP(check_args(L, 3, "log"));
3413 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3414 level = MAY_LJMP(luaL_checkinteger(L, 2));
3415 msg = MAY_LJMP(luaL_checkstring(L, 3));
3416
3417 if (level < 0 || level >= NB_LOG_LEVELS)
3418 WILL_LJMP(luaL_argerror(L, 1, "Invalid loglevel."));
3419
3420 hlua_sendlog(htxn->s->be, level, msg);
3421 return 0;
3422}
3423
3424__LJMP static int hlua_txn_log_debug(lua_State *L)
3425{
3426 const char *msg;
3427 struct hlua_txn *htxn;
3428
3429 MAY_LJMP(check_args(L, 2, "Debug"));
3430 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3431 msg = MAY_LJMP(luaL_checkstring(L, 2));
3432 hlua_sendlog(htxn->s->be, LOG_DEBUG, msg);
3433 return 0;
3434}
3435
3436__LJMP static int hlua_txn_log_info(lua_State *L)
3437{
3438 const char *msg;
3439 struct hlua_txn *htxn;
3440
3441 MAY_LJMP(check_args(L, 2, "Info"));
3442 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3443 msg = MAY_LJMP(luaL_checkstring(L, 2));
3444 hlua_sendlog(htxn->s->be, LOG_INFO, msg);
3445 return 0;
3446}
3447
3448__LJMP static int hlua_txn_log_warning(lua_State *L)
3449{
3450 const char *msg;
3451 struct hlua_txn *htxn;
3452
3453 MAY_LJMP(check_args(L, 2, "Warning"));
3454 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3455 msg = MAY_LJMP(luaL_checkstring(L, 2));
3456 hlua_sendlog(htxn->s->be, LOG_WARNING, msg);
3457 return 0;
3458}
3459
3460__LJMP static int hlua_txn_log_alert(lua_State *L)
3461{
3462 const char *msg;
3463 struct hlua_txn *htxn;
3464
3465 MAY_LJMP(check_args(L, 2, "Alert"));
3466 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3467 msg = MAY_LJMP(luaL_checkstring(L, 2));
3468 hlua_sendlog(htxn->s->be, LOG_ALERT, msg);
3469 return 0;
3470}
3471
Thierry FOURNIER2cce3532015-03-16 12:04:16 +01003472__LJMP static int hlua_txn_set_loglevel(lua_State *L)
3473{
3474 struct hlua_txn *htxn;
3475 int ll;
3476
3477 MAY_LJMP(check_args(L, 2, "set_loglevel"));
3478 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3479 ll = MAY_LJMP(luaL_checkinteger(L, 2));
3480
3481 if (ll < 0 || ll > 7)
3482 WILL_LJMP(luaL_argerror(L, 2, "Bad log level. It must be between 0 and 7"));
3483
3484 htxn->s->logs.level = ll;
3485 return 0;
3486}
3487
3488__LJMP static int hlua_txn_set_tos(lua_State *L)
3489{
3490 struct hlua_txn *htxn;
3491 struct connection *cli_conn;
3492 int tos;
3493
3494 MAY_LJMP(check_args(L, 2, "set_tos"));
3495 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3496 tos = MAY_LJMP(luaL_checkinteger(L, 2));
3497
3498 if ((cli_conn = objt_conn(htxn->s->si[0].end)) && conn_ctrl_ready(cli_conn))
3499 inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, tos);
3500
3501 return 0;
3502}
3503
3504__LJMP static int hlua_txn_set_mark(lua_State *L)
3505{
3506#ifdef SO_MARK
3507 struct hlua_txn *htxn;
3508 struct connection *cli_conn;
3509 int mark;
3510
3511 MAY_LJMP(check_args(L, 2, "set_mark"));
3512 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3513 mark = MAY_LJMP(luaL_checkinteger(L, 2));
3514
3515 if ((cli_conn = objt_conn(htxn->s->si[0].end)) && conn_ctrl_ready(cli_conn))
Willy Tarreau07081fe2015-04-06 10:59:20 +02003516 setsockopt(cli_conn->t.sock.fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
Thierry FOURNIER2cce3532015-03-16 12:04:16 +01003517#endif
3518 return 0;
3519}
3520
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003521/* This function is an Lua binding that send pending data
3522 * to the client, and close the stream interface.
3523 */
3524__LJMP static int hlua_txn_close(lua_State *L)
3525{
Willy Tarreaub2ccb562015-04-06 11:11:15 +02003526 struct hlua_txn *htxn;
Willy Tarreau81389672015-03-10 12:03:52 +01003527 struct channel *ic, *oc;
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003528
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003529 MAY_LJMP(check_args(L, 1, "close"));
Willy Tarreaub2ccb562015-04-06 11:11:15 +02003530 htxn = MAY_LJMP(hlua_checktxn(L, 1));
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003531
Willy Tarreaub2ccb562015-04-06 11:11:15 +02003532 ic = &htxn->s->req;
3533 oc = &htxn->s->res;
Willy Tarreau81389672015-03-10 12:03:52 +01003534
3535 channel_abort(ic);
3536 channel_auto_close(ic);
3537 channel_erase(ic);
3538 channel_auto_read(oc);
3539 channel_auto_close(oc);
3540 channel_shutr_now(oc);
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003541
Thierry FOURNIERc798b5d2015-03-17 01:09:57 +01003542 return 0;
3543}
3544
3545__LJMP static int hlua_log(lua_State *L)
3546{
3547 int level;
3548 const char *msg;
3549
3550 MAY_LJMP(check_args(L, 2, "log"));
3551 level = MAY_LJMP(luaL_checkinteger(L, 1));
3552 msg = MAY_LJMP(luaL_checkstring(L, 2));
3553
3554 if (level < 0 || level >= NB_LOG_LEVELS)
3555 WILL_LJMP(luaL_argerror(L, 1, "Invalid loglevel."));
3556
3557 hlua_sendlog(NULL, level, msg);
3558 return 0;
3559}
3560
3561__LJMP static int hlua_log_debug(lua_State *L)
3562{
3563 const char *msg;
3564
3565 MAY_LJMP(check_args(L, 1, "debug"));
3566 msg = MAY_LJMP(luaL_checkstring(L, 1));
3567 hlua_sendlog(NULL, LOG_DEBUG, msg);
3568 return 0;
3569}
3570
3571__LJMP static int hlua_log_info(lua_State *L)
3572{
3573 const char *msg;
3574
3575 MAY_LJMP(check_args(L, 1, "info"));
3576 msg = MAY_LJMP(luaL_checkstring(L, 1));
3577 hlua_sendlog(NULL, LOG_INFO, msg);
3578 return 0;
3579}
3580
3581__LJMP static int hlua_log_warning(lua_State *L)
3582{
3583 const char *msg;
3584
3585 MAY_LJMP(check_args(L, 1, "warning"));
3586 msg = MAY_LJMP(luaL_checkstring(L, 1));
3587 hlua_sendlog(NULL, LOG_WARNING, msg);
3588 return 0;
3589}
3590
3591__LJMP static int hlua_log_alert(lua_State *L)
3592{
3593 const char *msg;
3594
3595 MAY_LJMP(check_args(L, 1, "alert"));
3596 msg = MAY_LJMP(luaL_checkstring(L, 1));
3597 hlua_sendlog(NULL, LOG_ALERT, msg);
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003598 return 0;
3599}
3600
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01003601__LJMP static int hlua_sleep_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003602{
3603 int wakeup_ms = lua_tointeger(L, -1);
3604 if (now_ms < wakeup_ms)
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003605 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003606 return 0;
3607}
3608
3609__LJMP static int hlua_sleep(lua_State *L)
3610{
3611 unsigned int delay;
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003612 unsigned int wakeup_ms;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003613
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003614 MAY_LJMP(check_args(L, 1, "sleep"));
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003615
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01003616 delay = MAY_LJMP(luaL_checkinteger(L, 1)) * 1000;
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003617 wakeup_ms = tick_add(now_ms, delay);
3618 lua_pushinteger(L, wakeup_ms);
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003619
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003620 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
3621 return 0;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003622}
3623
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003624__LJMP static int hlua_msleep(lua_State *L)
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003625{
3626 unsigned int delay;
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003627 unsigned int wakeup_ms;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003628
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003629 MAY_LJMP(check_args(L, 1, "msleep"));
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003630
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01003631 delay = MAY_LJMP(luaL_checkinteger(L, 1));
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003632 wakeup_ms = tick_add(now_ms, delay);
3633 lua_pushinteger(L, wakeup_ms);
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003634
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003635 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
3636 return 0;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003637}
3638
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01003639/* This functionis an LUA binding. it permits to give back
3640 * the hand at the HAProxy scheduler. It is used when the
3641 * LUA processing consumes a lot of time.
3642 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01003643__LJMP static int hlua_yield_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003644{
3645 return 0;
3646}
3647
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01003648__LJMP static int hlua_yield(lua_State *L)
3649{
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003650 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_yield_yield, TICK_ETERNITY, HLUA_CTRLYIELD));
3651 return 0;
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01003652}
3653
Thierry FOURNIER37196f42015-02-16 19:34:56 +01003654/* This function change the nice of the currently executed
3655 * task. It is used set low or high priority at the current
3656 * task.
3657 */
Willy Tarreau59551662015-03-10 14:23:13 +01003658__LJMP static int hlua_set_nice(lua_State *L)
Thierry FOURNIER37196f42015-02-16 19:34:56 +01003659{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003660 struct hlua *hlua;
3661 int nice;
Thierry FOURNIER37196f42015-02-16 19:34:56 +01003662
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003663 MAY_LJMP(check_args(L, 1, "set_nice"));
3664 hlua = hlua_gethlua(L);
3665 nice = MAY_LJMP(luaL_checkinteger(L, 1));
Thierry FOURNIER37196f42015-02-16 19:34:56 +01003666
3667 /* If he task is not set, I'm in a start mode. */
3668 if (!hlua || !hlua->task)
3669 return 0;
3670
3671 if (nice < -1024)
3672 nice = -1024;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003673 else if (nice > 1024)
Thierry FOURNIER37196f42015-02-16 19:34:56 +01003674 nice = 1024;
3675
3676 hlua->task->nice = nice;
3677 return 0;
3678}
3679
Thierry FOURNIER24f33532015-01-23 12:13:00 +01003680/* This function is used as a calback of a task. It is called by the
3681 * HAProxy task subsystem when the task is awaked. The LUA runtime can
3682 * return an E_AGAIN signal, the emmiter of this signal must set a
3683 * signal to wake the task.
3684 */
3685static struct task *hlua_process_task(struct task *task)
3686{
3687 struct hlua *hlua = task->context;
3688 enum hlua_exec status;
3689
3690 /* We need to remove the task from the wait queue before executing
3691 * the Lua code because we don't know if it needs to wait for
3692 * another timer or not in the case of E_AGAIN.
3693 */
3694 task_delete(task);
3695
Thierry FOURNIERbd413492015-03-03 16:52:26 +01003696 /* If it is the first call to the task, we must initialize the
3697 * execution timeouts.
3698 */
3699 if (!HLUA_IS_RUNNING(hlua))
3700 hlua->expire = tick_add(now_ms, hlua_timeout_task);
3701
Thierry FOURNIER24f33532015-01-23 12:13:00 +01003702 /* Execute the Lua code. */
3703 status = hlua_ctx_resume(hlua, 1);
3704
3705 switch (status) {
3706 /* finished or yield */
3707 case HLUA_E_OK:
3708 hlua_ctx_destroy(hlua);
3709 task_delete(task);
3710 task_free(task);
3711 break;
3712
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01003713 case HLUA_E_AGAIN: /* co process or timeout wake me later. */
3714 if (hlua->wake_time != TICK_ETERNITY)
3715 task_schedule(task, hlua->wake_time);
Thierry FOURNIER24f33532015-01-23 12:13:00 +01003716 break;
3717
3718 /* finished with error. */
3719 case HLUA_E_ERRMSG:
3720 send_log(NULL, LOG_ERR, "Lua task: %s.", lua_tostring(hlua->T, -1));
3721 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3722 Alert("Lua task: %s.\n", lua_tostring(hlua->T, -1));
3723 hlua_ctx_destroy(hlua);
3724 task_delete(task);
3725 task_free(task);
3726 break;
3727
3728 case HLUA_E_ERR:
3729 default:
3730 send_log(NULL, LOG_ERR, "Lua task: unknown error.");
3731 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3732 Alert("Lua task: unknown error.\n");
3733 hlua_ctx_destroy(hlua);
3734 task_delete(task);
3735 task_free(task);
3736 break;
3737 }
3738 return NULL;
3739}
3740
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01003741/* This function is an LUA binding that register LUA function to be
3742 * executed after the HAProxy configuration parsing and before the
3743 * HAProxy scheduler starts. This function expect only one LUA
3744 * argument that is a function. This function returns nothing, but
3745 * throws if an error is encountered.
3746 */
3747__LJMP static int hlua_register_init(lua_State *L)
3748{
3749 struct hlua_init_function *init;
3750 int ref;
3751
3752 MAY_LJMP(check_args(L, 1, "register_init"));
3753
3754 ref = MAY_LJMP(hlua_checkfunction(L, 1));
3755
3756 init = malloc(sizeof(*init));
3757 if (!init)
3758 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3759
3760 init->function_ref = ref;
3761 LIST_ADDQ(&hlua_init_functions, &init->l);
3762 return 0;
3763}
3764
Thierry FOURNIER24f33532015-01-23 12:13:00 +01003765/* This functio is an LUA binding. It permits to register a task
3766 * executed in parallel of the main HAroxy activity. The task is
3767 * created and it is set in the HAProxy scheduler. It can be called
3768 * from the "init" section, "post init" or during the runtime.
3769 *
3770 * Lua prototype:
3771 *
3772 * <none> core.register_task(<function>)
3773 */
3774static int hlua_register_task(lua_State *L)
3775{
3776 struct hlua *hlua;
3777 struct task *task;
3778 int ref;
3779
3780 MAY_LJMP(check_args(L, 1, "register_task"));
3781
3782 ref = MAY_LJMP(hlua_checkfunction(L, 1));
3783
3784 hlua = malloc(sizeof(*hlua));
3785 if (!hlua)
3786 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3787
3788 task = task_new();
3789 task->context = hlua;
3790 task->process = hlua_process_task;
3791
3792 if (!hlua_ctx_init(hlua, task))
3793 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3794
3795 /* Restore the function in the stack. */
3796 lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ref);
3797 hlua->nargs = 0;
3798
3799 /* Schedule task. */
3800 task_schedule(task, now_ms);
3801
3802 return 0;
3803}
3804
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003805/* Wrapper called by HAProxy to execute an LUA converter. This wrapper
3806 * doesn't allow "yield" functions because the HAProxy engine cannot
3807 * resume converters.
3808 */
Willy Tarreau87b09662015-04-03 00:22:06 +02003809static int hlua_sample_conv_wrapper(struct stream *stream, const struct arg *arg_p,
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003810 struct sample *smp, void *private)
3811{
3812 struct hlua_function *fcn = (struct hlua_function *)private;
3813
Willy Tarreau87b09662015-04-03 00:22:06 +02003814 /* In the execution wrappers linked with a stream, the
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01003815 * Lua context can be not initialized. This behavior
3816 * permits to save performances because a systematic
3817 * Lua initialization cause 5% performances loss.
3818 */
Willy Tarreau87b09662015-04-03 00:22:06 +02003819 if (!stream->hlua.T && !hlua_ctx_init(&stream->hlua, stream->task)) {
3820 send_log(stream->be, LOG_ERR, "Lua converter '%s': can't initialize Lua context.", fcn->name);
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01003821 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3822 Alert("Lua converter '%s': can't initialize Lua context.\n", fcn->name);
3823 return 0;
3824 }
3825
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003826 /* If it is the first run, initialize the data for the call. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003827 if (!HLUA_IS_RUNNING(&stream->hlua)) {
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003828 /* Check stack available size. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003829 if (!lua_checkstack(stream->hlua.T, 1)) {
3830 send_log(stream->be, LOG_ERR, "Lua converter '%s': full stack.", fcn->name);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003831 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3832 Alert("Lua converter '%s': full stack.\n", fcn->name);
3833 return 0;
3834 }
3835
3836 /* Restore the function in the stack. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003837 lua_rawgeti(stream->hlua.T, LUA_REGISTRYINDEX, fcn->function_ref);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003838
3839 /* convert input sample and pust-it in the stack. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003840 if (!lua_checkstack(stream->hlua.T, 1)) {
3841 send_log(stream->be, LOG_ERR, "Lua converter '%s': full stack.", fcn->name);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003842 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3843 Alert("Lua converter '%s': full stack.\n", fcn->name);
3844 return 0;
3845 }
Willy Tarreau87b09662015-04-03 00:22:06 +02003846 hlua_smp2lua(stream->hlua.T, smp);
3847 stream->hlua.nargs = 2;
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003848
3849 /* push keywords in the stack. */
3850 if (arg_p) {
3851 for (; arg_p->type != ARGT_STOP; arg_p++) {
Willy Tarreau87b09662015-04-03 00:22:06 +02003852 if (!lua_checkstack(stream->hlua.T, 1)) {
3853 send_log(stream->be, LOG_ERR, "Lua converter '%s': full stack.", fcn->name);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003854 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3855 Alert("Lua converter '%s': full stack.\n", fcn->name);
3856 return 0;
3857 }
Willy Tarreau87b09662015-04-03 00:22:06 +02003858 hlua_arg2lua(stream->hlua.T, arg_p);
3859 stream->hlua.nargs++;
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003860 }
3861 }
3862
Thierry FOURNIERbd413492015-03-03 16:52:26 +01003863 /* We must initialize the execution timeouts. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003864 stream->hlua.expire = tick_add(now_ms, hlua_timeout_session);
Thierry FOURNIERbd413492015-03-03 16:52:26 +01003865
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003866 /* Set the currently running flag. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003867 HLUA_SET_RUN(&stream->hlua);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003868 }
3869
3870 /* Execute the function. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003871 switch (hlua_ctx_resume(&stream->hlua, 0)) {
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003872 /* finished. */
3873 case HLUA_E_OK:
3874 /* Convert the returned value in sample. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003875 hlua_lua2smp(stream->hlua.T, -1, smp);
3876 lua_pop(stream->hlua.T, 1);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003877 return 1;
3878
3879 /* yield. */
3880 case HLUA_E_AGAIN:
Willy Tarreau87b09662015-04-03 00:22:06 +02003881 send_log(stream->be, LOG_ERR, "Lua converter '%s': cannot use yielded functions.", fcn->name);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003882 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3883 Alert("Lua converter '%s': cannot use yielded functions.\n", fcn->name);
3884 return 0;
3885
3886 /* finished with error. */
3887 case HLUA_E_ERRMSG:
3888 /* Display log. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003889 send_log(stream->be, LOG_ERR, "Lua converter '%s': %s.", fcn->name, lua_tostring(stream->hlua.T, -1));
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003890 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
Willy Tarreau87b09662015-04-03 00:22:06 +02003891 Alert("Lua converter '%s': %s.\n", fcn->name, lua_tostring(stream->hlua.T, -1));
3892 lua_pop(stream->hlua.T, 1);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003893 return 0;
3894
3895 case HLUA_E_ERR:
3896 /* Display log. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003897 send_log(stream->be, LOG_ERR, "Lua converter '%s' returns an unknown error.", fcn->name);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003898 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3899 Alert("Lua converter '%s' returns an unknown error.\n", fcn->name);
3900
3901 default:
3902 return 0;
3903 }
3904}
3905
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003906/* Wrapper called by HAProxy to execute a sample-fetch. this wrapper
3907 * doesn't allow "yield" functions because the HAProxy engine cannot
3908 * resume sample-fetches.
3909 */
Willy Tarreau87b09662015-04-03 00:22:06 +02003910static int hlua_sample_fetch_wrapper(struct proxy *px, struct stream *s, void *l7,
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003911 unsigned int opt, const struct arg *arg_p,
3912 struct sample *smp, const char *kw, void *private)
3913{
3914 struct hlua_function *fcn = (struct hlua_function *)private;
3915
Willy Tarreau87b09662015-04-03 00:22:06 +02003916 /* In the execution wrappers linked with a stream, the
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01003917 * Lua context can be not initialized. This behavior
3918 * permits to save performances because a systematic
3919 * Lua initialization cause 5% performances loss.
3920 */
3921 if (!s->hlua.T && !hlua_ctx_init(&s->hlua, s->task)) {
3922 send_log(s->be, LOG_ERR, "Lua sample-fetch '%s': can't initialize Lua context.", fcn->name);
3923 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3924 Alert("Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
3925 return 0;
3926 }
3927
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003928 /* If it is the first run, initialize the data for the call. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01003929 if (!HLUA_IS_RUNNING(&s->hlua)) {
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003930 /* Check stack available size. */
3931 if (!lua_checkstack(s->hlua.T, 2)) {
3932 send_log(px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
3933 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3934 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
3935 return 0;
3936 }
3937
3938 /* Restore the function in the stack. */
3939 lua_rawgeti(s->hlua.T, LUA_REGISTRYINDEX, fcn->function_ref);
3940
3941 /* push arguments in the stack. */
3942 if (!hlua_txn_new(s->hlua.T, s, px, l7)) {
3943 send_log(px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
3944 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3945 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
3946 return 0;
3947 }
3948 s->hlua.nargs = 1;
3949
3950 /* push keywords in the stack. */
3951 for (; arg_p && arg_p->type != ARGT_STOP; arg_p++) {
3952 /* Check stack available size. */
3953 if (!lua_checkstack(s->hlua.T, 1)) {
3954 send_log(px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
3955 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3956 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
3957 return 0;
3958 }
3959 if (!lua_checkstack(s->hlua.T, 1)) {
3960 send_log(px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
3961 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3962 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
3963 return 0;
3964 }
3965 hlua_arg2lua(s->hlua.T, arg_p);
3966 s->hlua.nargs++;
3967 }
3968
Thierry FOURNIERbd413492015-03-03 16:52:26 +01003969 /* We must initialize the execution timeouts. */
3970 s->hlua.expire = tick_add(now_ms, hlua_timeout_session);
3971
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003972 /* Set the currently running flag. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01003973 HLUA_SET_RUN(&s->hlua);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003974 }
3975
3976 /* Execute the function. */
3977 switch (hlua_ctx_resume(&s->hlua, 0)) {
3978 /* finished. */
3979 case HLUA_E_OK:
3980 /* Convert the returned value in sample. */
3981 hlua_lua2smp(s->hlua.T, -1, smp);
3982 lua_pop(s->hlua.T, 1);
3983
3984 /* Set the end of execution flag. */
3985 smp->flags &= ~SMP_F_MAY_CHANGE;
3986 return 1;
3987
3988 /* yield. */
3989 case HLUA_E_AGAIN:
3990 send_log(px, LOG_ERR, "Lua sample-fetch '%s': cannot use yielded functions.", fcn->name);
3991 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3992 Alert("Lua sample-fetch '%s': cannot use yielded functions.\n", fcn->name);
3993 return 0;
3994
3995 /* finished with error. */
3996 case HLUA_E_ERRMSG:
3997 /* Display log. */
3998 send_log(px, LOG_ERR, "Lua sample-fetch '%s': %s.", fcn->name, lua_tostring(s->hlua.T, -1));
3999 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4000 Alert("Lua sample-fetch '%s': %s.\n", fcn->name, lua_tostring(s->hlua.T, -1));
4001 lua_pop(s->hlua.T, 1);
4002 return 0;
4003
4004 case HLUA_E_ERR:
4005 /* Display log. */
4006 send_log(px, LOG_ERR, "Lua sample-fetch '%s' returns an unknown error.", fcn->name);
4007 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4008 Alert("Lua sample-fetch '%s': returns an unknown error.\n", fcn->name);
4009
4010 default:
4011 return 0;
4012 }
4013}
4014
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01004015/* This function is an LUA binding used for registering
4016 * "sample-conv" functions. It expects a converter name used
4017 * in the haproxy configuration file, and an LUA function.
4018 */
4019__LJMP static int hlua_register_converters(lua_State *L)
4020{
4021 struct sample_conv_kw_list *sck;
4022 const char *name;
4023 int ref;
4024 int len;
4025 struct hlua_function *fcn;
4026
4027 MAY_LJMP(check_args(L, 2, "register_converters"));
4028
4029 /* First argument : converter name. */
4030 name = MAY_LJMP(luaL_checkstring(L, 1));
4031
4032 /* Second argument : lua function. */
4033 ref = MAY_LJMP(hlua_checkfunction(L, 2));
4034
4035 /* Allocate and fill the sample fetch keyword struct. */
Willy Tarreau07081fe2015-04-06 10:59:20 +02004036 sck = malloc(sizeof(*sck) + sizeof(struct sample_conv) * 2);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01004037 if (!sck)
4038 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4039 fcn = malloc(sizeof(*fcn));
4040 if (!fcn)
4041 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4042
4043 /* Fill fcn. */
4044 fcn->name = strdup(name);
4045 if (!fcn->name)
4046 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4047 fcn->function_ref = ref;
4048
4049 /* List head */
4050 sck->list.n = sck->list.p = NULL;
4051
4052 /* converter keyword. */
4053 len = strlen("lua.") + strlen(name) + 1;
4054 sck->kw[0].kw = malloc(len);
4055 if (!sck->kw[0].kw)
4056 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4057
4058 snprintf((char *)sck->kw[0].kw, len, "lua.%s", name);
4059 sck->kw[0].process = hlua_sample_conv_wrapper;
4060 sck->kw[0].arg_mask = ARG5(0,STR,STR,STR,STR,STR);
4061 sck->kw[0].val_args = NULL;
4062 sck->kw[0].in_type = SMP_T_STR;
4063 sck->kw[0].out_type = SMP_T_STR;
4064 sck->kw[0].private = fcn;
4065
4066 /* End of array. */
4067 memset(&sck->kw[1], 0, sizeof(struct sample_conv));
4068
4069 /* Register this new converter */
4070 sample_register_convs(sck);
4071
4072 return 0;
4073}
4074
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004075/* This fucntion is an LUA binding used for registering
4076 * "sample-fetch" functions. It expects a converter name used
4077 * in the haproxy configuration file, and an LUA function.
4078 */
4079__LJMP static int hlua_register_fetches(lua_State *L)
4080{
4081 const char *name;
4082 int ref;
4083 int len;
4084 struct sample_fetch_kw_list *sfk;
4085 struct hlua_function *fcn;
4086
4087 MAY_LJMP(check_args(L, 2, "register_fetches"));
4088
4089 /* First argument : sample-fetch name. */
4090 name = MAY_LJMP(luaL_checkstring(L, 1));
4091
4092 /* Second argument : lua function. */
4093 ref = MAY_LJMP(hlua_checkfunction(L, 2));
4094
4095 /* Allocate and fill the sample fetch keyword struct. */
Willy Tarreau07081fe2015-04-06 10:59:20 +02004096 sfk = malloc(sizeof(*sfk) + sizeof(struct sample_fetch) * 2);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004097 if (!sfk)
4098 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4099 fcn = malloc(sizeof(*fcn));
4100 if (!fcn)
4101 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4102
4103 /* Fill fcn. */
4104 fcn->name = strdup(name);
4105 if (!fcn->name)
4106 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4107 fcn->function_ref = ref;
4108
4109 /* List head */
4110 sfk->list.n = sfk->list.p = NULL;
4111
4112 /* sample-fetch keyword. */
4113 len = strlen("lua.") + strlen(name) + 1;
4114 sfk->kw[0].kw = malloc(len);
4115 if (!sfk->kw[0].kw)
4116 return luaL_error(L, "lua out of memory error.");
4117
4118 snprintf((char *)sfk->kw[0].kw, len, "lua.%s", name);
4119 sfk->kw[0].process = hlua_sample_fetch_wrapper;
4120 sfk->kw[0].arg_mask = ARG5(0,STR,STR,STR,STR,STR);
4121 sfk->kw[0].val_args = NULL;
4122 sfk->kw[0].out_type = SMP_T_STR;
4123 sfk->kw[0].use = SMP_USE_HTTP_ANY;
4124 sfk->kw[0].val = 0;
4125 sfk->kw[0].private = fcn;
4126
4127 /* End of array. */
4128 memset(&sfk->kw[1], 0, sizeof(struct sample_fetch));
4129
4130 /* Register this new fetch. */
4131 sample_register_fetches(sfk);
4132
4133 return 0;
4134}
4135
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004136/* global {tcp|http}-request parser. Return 1 in succes case, else return 0. */
4137static int hlua_parse_rule(const char **args, int *cur_arg, struct proxy *px,
4138 struct hlua_rule **rule_p, char **err)
4139{
4140 struct hlua_rule *rule;
4141
4142 /* Memory for the rule. */
4143 rule = malloc(sizeof(*rule));
4144 if (!rule) {
4145 memprintf(err, "out of memory error");
4146 return 0;
4147 }
4148 *rule_p = rule;
4149
4150 /* The requiered arg is a function name. */
4151 if (!args[*cur_arg]) {
4152 memprintf(err, "expect Lua function name");
4153 return 0;
4154 }
4155
4156 /* Lookup for the symbol, and check if it is a function. */
4157 lua_getglobal(gL.T, args[*cur_arg]);
4158 if (lua_isnil(gL.T, -1)) {
4159 lua_pop(gL.T, 1);
4160 memprintf(err, "Lua function '%s' not found", args[*cur_arg]);
4161 return 0;
4162 }
4163 if (!lua_isfunction(gL.T, -1)) {
4164 lua_pop(gL.T, 1);
4165 memprintf(err, "'%s' is not a function", args[*cur_arg]);
4166 return 0;
4167 }
4168
4169 /* Reference the Lua function and store the reference. */
4170 rule->fcn.function_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
4171 rule->fcn.name = strdup(args[*cur_arg]);
4172 if (!rule->fcn.name) {
4173 memprintf(err, "out of memory error.");
4174 return 0;
4175 }
4176 (*cur_arg)++;
4177
4178 /* TODO: later accept arguments. */
4179 rule->args = NULL;
4180
4181 return 1;
4182}
4183
4184/* This function is a wrapper to execute each LUA function declared
4185 * as an action wrapper during the initialisation period. This function
4186 * return 1 if the processing is finished (with oe without error) and
4187 * return 0 if the function must be called again because the LUA
4188 * returns a yield.
4189 */
4190static int hlua_request_act_wrapper(struct hlua_rule *rule, struct proxy *px,
Willy Tarreau87b09662015-04-03 00:22:06 +02004191 struct stream *s, struct http_txn *http_txn,
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004192 unsigned int analyzer)
4193{
4194 char **arg;
4195
Willy Tarreau87b09662015-04-03 00:22:06 +02004196 /* In the execution wrappers linked with a stream, the
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01004197 * Lua context can be not initialized. This behavior
4198 * permits to save performances because a systematic
4199 * Lua initialization cause 5% performances loss.
4200 */
4201 if (!s->hlua.T && !hlua_ctx_init(&s->hlua, s->task)) {
4202 send_log(px, LOG_ERR, "Lua action '%s': can't initialize Lua context.", rule->fcn.name);
4203 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4204 Alert("Lua action '%s': can't initialize Lua context.\n", rule->fcn.name);
4205 return 0;
4206 }
4207
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004208 /* If it is the first run, initialize the data for the call. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01004209 if (!HLUA_IS_RUNNING(&s->hlua)) {
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004210 /* Check stack available size. */
4211 if (!lua_checkstack(s->hlua.T, 1)) {
4212 send_log(px, LOG_ERR, "Lua function '%s': full stack.", rule->fcn.name);
4213 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4214 Alert("Lua function '%s': full stack.\n", rule->fcn.name);
4215 return 0;
4216 }
4217
4218 /* Restore the function in the stack. */
4219 lua_rawgeti(s->hlua.T, LUA_REGISTRYINDEX, rule->fcn.function_ref);
4220
Willy Tarreau87b09662015-04-03 00:22:06 +02004221 /* Create and and push object stream in the stack. */
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004222 if (!hlua_txn_new(s->hlua.T, s, px, http_txn)) {
4223 send_log(px, LOG_ERR, "Lua function '%s': full stack.", rule->fcn.name);
4224 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4225 Alert("Lua function '%s': full stack.\n", rule->fcn.name);
4226 return 0;
4227 }
4228 s->hlua.nargs = 1;
4229
4230 /* push keywords in the stack. */
4231 for (arg = rule->args; arg && *arg; arg++) {
4232 if (!lua_checkstack(s->hlua.T, 1)) {
4233 send_log(px, LOG_ERR, "Lua function '%s': full stack.", rule->fcn.name);
4234 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4235 Alert("Lua function '%s': full stack.\n", rule->fcn.name);
4236 return 0;
4237 }
4238 lua_pushstring(s->hlua.T, *arg);
4239 s->hlua.nargs++;
4240 }
4241
Thierry FOURNIERbd413492015-03-03 16:52:26 +01004242 /* We must initialize the execution timeouts. */
4243 s->hlua.expire = tick_add(now_ms, hlua_timeout_session);
4244
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004245 /* Set the currently running flag. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01004246 HLUA_SET_RUN(&s->hlua);
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004247 }
4248
4249 /* Execute the function. */
4250 switch (hlua_ctx_resume(&s->hlua, 1)) {
4251 /* finished. */
4252 case HLUA_E_OK:
4253 return 1;
4254
4255 /* yield. */
4256 case HLUA_E_AGAIN:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01004257 /* Set timeout in the required channel. */
4258 if (s->hlua.wake_time != TICK_ETERNITY) {
4259 if (analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE))
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01004260 s->req.analyse_exp = s->hlua.wake_time;
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01004261 else if (analyzer & (AN_RES_INSPECT|AN_RES_HTTP_PROCESS_BE))
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01004262 s->res.analyse_exp = s->hlua.wake_time;
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01004263 }
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004264 /* Some actions can be wake up when a "write" event
4265 * is detected on a response channel. This is useful
4266 * only for actions targetted on the requests.
4267 */
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01004268 if (HLUA_IS_WAKERESWR(&s->hlua)) {
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01004269 s->res.flags |= CF_WAKE_WRITE;
Willy Tarreau76bd97f2015-03-10 17:16:10 +01004270 if ((analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE)))
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01004271 s->res.analysers |= analyzer;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004272 }
Thierry FOURNIER53e08ec2015-03-06 00:35:53 +01004273 if (HLUA_IS_WAKEREQWR(&s->hlua))
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01004274 s->req.flags |= CF_WAKE_WRITE;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004275 return 0;
4276
4277 /* finished with error. */
4278 case HLUA_E_ERRMSG:
4279 /* Display log. */
4280 send_log(px, LOG_ERR, "Lua function '%s': %s.", rule->fcn.name, lua_tostring(s->hlua.T, -1));
4281 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4282 Alert("Lua function '%s': %s.\n", rule->fcn.name, lua_tostring(s->hlua.T, -1));
4283 lua_pop(s->hlua.T, 1);
4284 return 1;
4285
4286 case HLUA_E_ERR:
4287 /* Display log. */
4288 send_log(px, LOG_ERR, "Lua function '%s' return an unknown error.", rule->fcn.name);
4289 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4290 Alert("Lua function '%s' return an unknown error.\n", rule->fcn.name);
4291
4292 default:
4293 return 1;
4294 }
4295}
4296
4297/* Lua execution wrapper for "tcp-request". This function uses
4298 * "hlua_request_act_wrapper" for executing the LUA code.
4299 */
4300int hlua_tcp_req_act_wrapper(struct tcp_rule *tcp_rule, struct proxy *px,
Willy Tarreau87b09662015-04-03 00:22:06 +02004301 struct stream *s)
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004302{
4303 return hlua_request_act_wrapper((struct hlua_rule *)tcp_rule->act_prm.data,
4304 px, s, NULL, AN_REQ_INSPECT_FE);
4305}
4306
4307/* Lua execution wrapper for "tcp-response". This function uses
4308 * "hlua_request_act_wrapper" for executing the LUA code.
4309 */
4310int hlua_tcp_res_act_wrapper(struct tcp_rule *tcp_rule, struct proxy *px,
Willy Tarreau87b09662015-04-03 00:22:06 +02004311 struct stream *s)
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004312{
4313 return hlua_request_act_wrapper((struct hlua_rule *)tcp_rule->act_prm.data,
4314 px, s, NULL, AN_RES_INSPECT);
4315}
4316
4317/* Lua execution wrapper for http-request.
4318 * This function uses "hlua_request_act_wrapper" for executing
4319 * the LUA code.
4320 */
4321int hlua_http_req_act_wrapper(struct http_req_rule *rule, struct proxy *px,
Willy Tarreau87b09662015-04-03 00:22:06 +02004322 struct stream *s, struct http_txn *http_txn)
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004323{
4324 return hlua_request_act_wrapper((struct hlua_rule *)rule->arg.data, px,
4325 s, http_txn, AN_REQ_HTTP_PROCESS_FE);
4326}
4327
4328/* Lua execution wrapper for http-response.
4329 * This function uses "hlua_request_act_wrapper" for executing
4330 * the LUA code.
4331 */
4332int hlua_http_res_act_wrapper(struct http_res_rule *rule, struct proxy *px,
Willy Tarreau87b09662015-04-03 00:22:06 +02004333 struct stream *s, struct http_txn *http_txn)
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004334{
4335 return hlua_request_act_wrapper((struct hlua_rule *)rule->arg.data, px,
4336 s, http_txn, AN_RES_HTTP_PROCESS_BE);
4337}
4338
4339/* tcp-request <*> configuration wrapper. */
4340static int tcp_req_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
4341 struct tcp_rule *rule, char **err)
4342{
4343 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->act_prm.data, err))
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01004344 return 0;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004345 rule->action = TCP_ACT_CUSTOM;
4346 rule->action_ptr = hlua_tcp_req_act_wrapper;
4347 return 1;
4348}
4349
4350/* tcp-response <*> configuration wrapper. */
4351static int tcp_res_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
4352 struct tcp_rule *rule, char **err)
4353{
4354 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->act_prm.data, err))
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01004355 return 0;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004356 rule->action = TCP_ACT_CUSTOM;
4357 rule->action_ptr = hlua_tcp_res_act_wrapper;
4358 return 1;
4359}
4360
4361/* http-request <*> configuration wrapper. */
4362static int http_req_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
4363 struct http_req_rule *rule, char **err)
4364{
4365 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->arg.data, err))
4366 return -1;
4367 rule->action = HTTP_REQ_ACT_CUSTOM_CONT;
4368 rule->action_ptr = hlua_http_req_act_wrapper;
4369 return 1;
4370}
4371
4372/* http-response <*> configuration wrapper. */
4373static int http_res_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
4374 struct http_res_rule *rule, char **err)
4375{
4376 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->arg.data, err))
4377 return -1;
4378 rule->action = HTTP_RES_ACT_CUSTOM_CONT;
4379 rule->action_ptr = hlua_http_res_act_wrapper;
4380 return 1;
4381}
4382
Thierry FOURNIERbd413492015-03-03 16:52:26 +01004383static int hlua_read_timeout(char **args, int section_type, struct proxy *curpx,
4384 struct proxy *defpx, const char *file, int line,
4385 char **err, unsigned int *timeout)
4386{
4387 const char *error;
4388
4389 error = parse_time_err(args[1], timeout, TIME_UNIT_MS);
4390 if (error && *error != '\0') {
4391 memprintf(err, "%s: invalid timeout", args[0]);
4392 return -1;
4393 }
4394 return 0;
4395}
4396
4397static int hlua_session_timeout(char **args, int section_type, struct proxy *curpx,
4398 struct proxy *defpx, const char *file, int line,
4399 char **err)
4400{
4401 return hlua_read_timeout(args, section_type, curpx, defpx,
4402 file, line, err, &hlua_timeout_session);
4403}
4404
4405static int hlua_task_timeout(char **args, int section_type, struct proxy *curpx,
4406 struct proxy *defpx, const char *file, int line,
4407 char **err)
4408{
4409 return hlua_read_timeout(args, section_type, curpx, defpx,
4410 file, line, err, &hlua_timeout_task);
4411}
4412
Thierry FOURNIERee9f8022015-03-03 17:37:37 +01004413static int hlua_forced_yield(char **args, int section_type, struct proxy *curpx,
4414 struct proxy *defpx, const char *file, int line,
4415 char **err)
4416{
4417 char *error;
4418
4419 hlua_nb_instruction = strtoll(args[1], &error, 10);
4420 if (*error != '\0') {
4421 memprintf(err, "%s: invalid number", args[0]);
4422 return -1;
4423 }
4424 return 0;
4425}
4426
Willy Tarreau32f61e22015-03-18 17:54:59 +01004427static int hlua_parse_maxmem(char **args, int section_type, struct proxy *curpx,
4428 struct proxy *defpx, const char *file, int line,
4429 char **err)
4430{
4431 char *error;
4432
4433 if (*(args[1]) == 0) {
4434 memprintf(err, "'%s' expects an integer argument (Lua memory size in MB).\n", args[0]);
4435 return -1;
4436 }
4437 hlua_global_allocator.limit = strtoll(args[1], &error, 10) * 1024L * 1024L;
4438 if (*error != '\0') {
4439 memprintf(err, "%s: invalid number %s (error at '%c')", args[0], args[1], *error);
4440 return -1;
4441 }
4442 return 0;
4443}
4444
4445
Thierry FOURNIER6c9b52c2015-01-23 15:57:06 +01004446/* This function is called by the main configuration key "lua-load". It loads and
4447 * execute an lua file during the parsing of the HAProxy configuration file. It is
4448 * the main lua entry point.
4449 *
4450 * This funtion runs with the HAProxy keywords API. It returns -1 if an error is
4451 * occured, otherwise it returns 0.
4452 *
4453 * In some error case, LUA set an error message in top of the stack. This function
4454 * returns this error message in the HAProxy logs and pop it from the stack.
4455 */
4456static int hlua_load(char **args, int section_type, struct proxy *curpx,
4457 struct proxy *defpx, const char *file, int line,
4458 char **err)
4459{
4460 int error;
4461
4462 /* Just load and compile the file. */
4463 error = luaL_loadfile(gL.T, args[1]);
4464 if (error) {
4465 memprintf(err, "error in lua file '%s': %s", args[1], lua_tostring(gL.T, -1));
4466 lua_pop(gL.T, 1);
4467 return -1;
4468 }
4469
4470 /* If no syntax error where detected, execute the code. */
4471 error = lua_pcall(gL.T, 0, LUA_MULTRET, 0);
4472 switch (error) {
4473 case LUA_OK:
4474 break;
4475 case LUA_ERRRUN:
4476 memprintf(err, "lua runtime error: %s\n", lua_tostring(gL.T, -1));
4477 lua_pop(gL.T, 1);
4478 return -1;
4479 case LUA_ERRMEM:
4480 memprintf(err, "lua out of memory error\n");
4481 return -1;
4482 case LUA_ERRERR:
4483 memprintf(err, "lua message handler error: %s\n", lua_tostring(gL.T, -1));
4484 lua_pop(gL.T, 1);
4485 return -1;
4486 case LUA_ERRGCMM:
4487 memprintf(err, "lua garbage collector error: %s\n", lua_tostring(gL.T, -1));
4488 lua_pop(gL.T, 1);
4489 return -1;
4490 default:
4491 memprintf(err, "lua unknonwn error: %s\n", lua_tostring(gL.T, -1));
4492 lua_pop(gL.T, 1);
4493 return -1;
4494 }
4495
4496 return 0;
4497}
4498
4499/* configuration keywords declaration */
4500static struct cfg_kw_list cfg_kws = {{ },{
Thierry FOURNIERbd413492015-03-03 16:52:26 +01004501 { CFG_GLOBAL, "lua-load", hlua_load },
4502 { CFG_GLOBAL, "tune.lua.session-timeout", hlua_session_timeout },
4503 { CFG_GLOBAL, "tune.lua.task-timeout", hlua_task_timeout },
Thierry FOURNIERee9f8022015-03-03 17:37:37 +01004504 { CFG_GLOBAL, "tune.lua.forced-yield", hlua_forced_yield },
Willy Tarreau32f61e22015-03-18 17:54:59 +01004505 { CFG_GLOBAL, "tune.lua.maxmem", hlua_parse_maxmem },
Thierry FOURNIER6c9b52c2015-01-23 15:57:06 +01004506 { 0, NULL, NULL },
4507}};
4508
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004509static struct http_req_action_kw_list http_req_kws = {"lua", { }, {
4510 { "lua", http_req_action_register_lua },
4511 { NULL, NULL }
4512}};
4513
4514static struct http_res_action_kw_list http_res_kws = {"lua", { }, {
4515 { "lua", http_res_action_register_lua },
4516 { NULL, NULL }
4517}};
4518
4519static struct tcp_action_kw_list tcp_req_cont_kws = {"lua", { }, {
4520 { "lua", tcp_req_action_register_lua },
4521 { NULL, NULL }
4522}};
4523
4524static struct tcp_action_kw_list tcp_res_cont_kws = {"lua", { }, {
4525 { "lua", tcp_res_action_register_lua },
4526 { NULL, NULL }
4527}};
4528
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01004529int hlua_post_init()
4530{
4531 struct hlua_init_function *init;
4532 const char *msg;
4533 enum hlua_exec ret;
4534
4535 list_for_each_entry(init, &hlua_init_functions, l) {
4536 lua_rawgeti(gL.T, LUA_REGISTRYINDEX, init->function_ref);
4537 ret = hlua_ctx_resume(&gL, 0);
4538 switch (ret) {
4539 case HLUA_E_OK:
4540 lua_pop(gL.T, -1);
4541 return 1;
4542 case HLUA_E_AGAIN:
4543 Alert("lua init: yield not allowed.\n");
4544 return 0;
4545 case HLUA_E_ERRMSG:
4546 msg = lua_tostring(gL.T, -1);
4547 Alert("lua init: %s.\n", msg);
4548 return 0;
4549 case HLUA_E_ERR:
4550 default:
4551 Alert("lua init: unknown runtime error.\n");
4552 return 0;
4553 }
4554 }
4555 return 1;
4556}
4557
Willy Tarreau32f61e22015-03-18 17:54:59 +01004558/* The memory allocator used by the Lua stack. <ud> is a pointer to the
4559 * allocator's context. <ptr> is the pointer to alloc/free/realloc. <osize>
4560 * is the previously allocated size or the kind of object in case of a new
4561 * allocation. <nsize> is the requested new size.
4562 */
4563static void *hlua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
4564{
4565 struct hlua_mem_allocator *zone = ud;
4566
4567 if (nsize == 0) {
4568 /* it's a free */
4569 if (ptr)
4570 zone->allocated -= osize;
4571 free(ptr);
4572 return NULL;
4573 }
4574
4575 if (!ptr) {
4576 /* it's a new allocation */
4577 if (zone->limit && zone->allocated + nsize > zone->limit)
4578 return NULL;
4579
4580 ptr = malloc(nsize);
4581 if (ptr)
4582 zone->allocated += nsize;
4583 return ptr;
4584 }
4585
4586 /* it's a realloc */
4587 if (zone->limit && zone->allocated + nsize - osize > zone->limit)
4588 return NULL;
4589
4590 ptr = realloc(ptr, nsize);
4591 if (ptr)
4592 zone->allocated += nsize - osize;
4593 return ptr;
4594}
4595
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +01004596void hlua_init(void)
4597{
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004598 int i;
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01004599 int idx;
4600 struct sample_fetch *sf;
Thierry FOURNIER594afe72015-03-10 23:58:30 +01004601 struct sample_conv *sc;
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01004602 char *p;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01004603#ifdef USE_OPENSSL
Willy Tarreau80f5fae2015-02-27 16:38:20 +01004604 struct srv_kw *kw;
4605 int tmp_error;
4606 char *error;
Thierry FOURNIER36d13742015-03-17 16:48:53 +01004607 char *args[] = { /* SSL client configuration. */
4608 "ssl",
4609 "verify",
4610 "none",
4611 "force-sslv3",
4612 NULL
4613 };
Willy Tarreau80f5fae2015-02-27 16:38:20 +01004614#endif
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004615
Willy Tarreau87b09662015-04-03 00:22:06 +02004616 /* Initialise com signals pool */
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01004617 pool2_hlua_com = create_pool("hlua_com", sizeof(struct hlua_com), MEM_F_SHARED);
4618
Thierry FOURNIER6c9b52c2015-01-23 15:57:06 +01004619 /* Register configuration keywords. */
4620 cfg_register_keywords(&cfg_kws);
4621
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004622 /* Register custom HTTP rules. */
4623 http_req_keywords_register(&http_req_kws);
4624 http_res_keywords_register(&http_res_kws);
4625 tcp_req_cont_keywords_register(&tcp_req_cont_kws);
4626 tcp_res_cont_keywords_register(&tcp_res_cont_kws);
4627
Thierry FOURNIER380d0932015-01-23 14:27:52 +01004628 /* Init main lua stack. */
4629 gL.Mref = LUA_REFNIL;
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01004630 gL.flags = 0;
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01004631 LIST_INIT(&gL.com);
Thierry FOURNIER380d0932015-01-23 14:27:52 +01004632 gL.T = luaL_newstate();
4633 hlua_sethlua(&gL);
4634 gL.Tref = LUA_REFNIL;
4635 gL.task = NULL;
4636
Willy Tarreau32f61e22015-03-18 17:54:59 +01004637 /* change the memory allocators to track memory usage */
4638 lua_setallocf(gL.T, hlua_alloc, &hlua_global_allocator);
4639
Thierry FOURNIER380d0932015-01-23 14:27:52 +01004640 /* Initialise lua. */
4641 luaL_openlibs(gL.T);
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004642
4643 /*
4644 *
4645 * Create "core" object.
4646 *
4647 */
4648
Thierry FOURNIERa2d8c652015-03-11 17:29:39 +01004649 /* This table entry is the object "core" base. */
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004650 lua_newtable(gL.T);
4651
4652 /* Push the loglevel constants. */
Willy Tarreau80f5fae2015-02-27 16:38:20 +01004653 for (i = 0; i < NB_LOG_LEVELS; i++)
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004654 hlua_class_const_int(gL.T, log_levels[i], i);
4655
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01004656 /* Register special functions. */
4657 hlua_class_function(gL.T, "register_init", hlua_register_init);
Thierry FOURNIER24f33532015-01-23 12:13:00 +01004658 hlua_class_function(gL.T, "register_task", hlua_register_task);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004659 hlua_class_function(gL.T, "register_fetches", hlua_register_fetches);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01004660 hlua_class_function(gL.T, "register_converters", hlua_register_converters);
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01004661 hlua_class_function(gL.T, "yield", hlua_yield);
Willy Tarreau59551662015-03-10 14:23:13 +01004662 hlua_class_function(gL.T, "set_nice", hlua_set_nice);
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01004663 hlua_class_function(gL.T, "sleep", hlua_sleep);
4664 hlua_class_function(gL.T, "msleep", hlua_msleep);
Thierry FOURNIER83758bb2015-02-04 13:21:04 +01004665 hlua_class_function(gL.T, "add_acl", hlua_add_acl);
4666 hlua_class_function(gL.T, "del_acl", hlua_del_acl);
4667 hlua_class_function(gL.T, "set_map", hlua_set_map);
4668 hlua_class_function(gL.T, "del_map", hlua_del_map);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01004669 hlua_class_function(gL.T, "tcp", hlua_socket_new);
Thierry FOURNIERc798b5d2015-03-17 01:09:57 +01004670 hlua_class_function(gL.T, "log", hlua_log);
4671 hlua_class_function(gL.T, "Debug", hlua_log_debug);
4672 hlua_class_function(gL.T, "Info", hlua_log_info);
4673 hlua_class_function(gL.T, "Warning", hlua_log_warning);
4674 hlua_class_function(gL.T, "Alert", hlua_log_alert);
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01004675
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004676 lua_setglobal(gL.T, "core");
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01004677
4678 /*
4679 *
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01004680 * Register class Channel
4681 *
4682 */
4683
4684 /* Create and fill the metatable. */
4685 lua_newtable(gL.T);
4686
4687 /* Create and fille the __index entry. */
4688 lua_pushstring(gL.T, "__index");
4689 lua_newtable(gL.T);
4690
4691 /* Register . */
4692 hlua_class_function(gL.T, "get", hlua_channel_get);
4693 hlua_class_function(gL.T, "dup", hlua_channel_dup);
4694 hlua_class_function(gL.T, "getline", hlua_channel_getline);
4695 hlua_class_function(gL.T, "set", hlua_channel_set);
4696 hlua_class_function(gL.T, "append", hlua_channel_append);
4697 hlua_class_function(gL.T, "send", hlua_channel_send);
4698 hlua_class_function(gL.T, "forward", hlua_channel_forward);
4699 hlua_class_function(gL.T, "get_in_len", hlua_channel_get_in_len);
4700 hlua_class_function(gL.T, "get_out_len", hlua_channel_get_out_len);
4701
4702 lua_settable(gL.T, -3);
4703
4704 /* Register previous table in the registry with reference and named entry. */
4705 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4706 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_CHANNEL); /* register class session. */
4707 class_channel_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
4708
4709 /*
4710 *
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01004711 * Register class Fetches
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01004712 *
4713 */
4714
4715 /* Create and fill the metatable. */
4716 lua_newtable(gL.T);
4717
4718 /* Create and fille the __index entry. */
4719 lua_pushstring(gL.T, "__index");
4720 lua_newtable(gL.T);
4721
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01004722 /* Browse existing fetches and create the associated
4723 * object method.
4724 */
4725 sf = NULL;
4726 while ((sf = sample_fetch_getnext(sf, &idx)) != NULL) {
4727
4728 /* Dont register the keywork if the arguments check function are
4729 * not safe during the runtime.
4730 */
4731 if ((sf->val_args != NULL) &&
4732 (sf->val_args != val_payload_lv) &&
4733 (sf->val_args != val_hdr))
4734 continue;
4735
4736 /* gL.Tua doesn't support '.' and '-' in the function names, replace it
4737 * by an underscore.
4738 */
4739 strncpy(trash.str, sf->kw, trash.size);
4740 trash.str[trash.size - 1] = '\0';
4741 for (p = trash.str; *p; p++)
4742 if (*p == '.' || *p == '-' || *p == '+')
4743 *p = '_';
4744
4745 /* Register the function. */
4746 lua_pushstring(gL.T, trash.str);
Willy Tarreau2ec22742015-03-10 14:27:20 +01004747 lua_pushlightuserdata(gL.T, sf);
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01004748 lua_pushcclosure(gL.T, hlua_run_sample_fetch, 1);
4749 lua_settable(gL.T, -3);
4750 }
4751
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01004752 lua_settable(gL.T, -3);
4753
4754 /* Register previous table in the registry with reference and named entry. */
4755 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4756 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_FETCHES); /* register class session. */
4757 class_fetches_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
4758
4759 /*
4760 *
Thierry FOURNIER594afe72015-03-10 23:58:30 +01004761 * Register class Converters
4762 *
4763 */
4764
4765 /* Create and fill the metatable. */
4766 lua_newtable(gL.T);
4767
4768 /* Create and fill the __index entry. */
4769 lua_pushstring(gL.T, "__index");
4770 lua_newtable(gL.T);
4771
4772 /* Browse existing converters and create the associated
4773 * object method.
4774 */
4775 sc = NULL;
4776 while ((sc = sample_conv_getnext(sc, &idx)) != NULL) {
4777 /* Dont register the keywork if the arguments check function are
4778 * not safe during the runtime.
4779 */
4780 if (sc->val_args != NULL)
4781 continue;
4782
4783 /* gL.Tua doesn't support '.' and '-' in the function names, replace it
4784 * by an underscore.
4785 */
4786 strncpy(trash.str, sc->kw, trash.size);
4787 trash.str[trash.size - 1] = '\0';
4788 for (p = trash.str; *p; p++)
4789 if (*p == '.' || *p == '-' || *p == '+')
4790 *p = '_';
4791
4792 /* Register the function. */
4793 lua_pushstring(gL.T, trash.str);
4794 lua_pushlightuserdata(gL.T, sc);
4795 lua_pushcclosure(gL.T, hlua_run_sample_conv, 1);
4796 lua_settable(gL.T, -3);
4797 }
4798
4799 lua_settable(gL.T, -3);
4800
4801 /* Register previous table in the registry with reference and named entry. */
4802 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4803 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_CONVERTERS); /* register class session. */
4804 class_converters_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
4805
4806 /*
4807 *
Thierry FOURNIER08504f42015-03-16 14:17:08 +01004808 * Register class HTTP
4809 *
4810 */
4811
4812 /* Create and fill the metatable. */
4813 lua_newtable(gL.T);
4814
4815 /* Create and fille the __index entry. */
4816 lua_pushstring(gL.T, "__index");
4817 lua_newtable(gL.T);
4818
4819 /* Register Lua functions. */
4820 hlua_class_function(gL.T, "req_get_headers",hlua_http_req_get_headers);
4821 hlua_class_function(gL.T, "req_del_header", hlua_http_req_del_hdr);
4822 hlua_class_function(gL.T, "req_rep_header", hlua_http_req_rep_hdr);
4823 hlua_class_function(gL.T, "req_rep_value", hlua_http_req_rep_val);
4824 hlua_class_function(gL.T, "req_add_header", hlua_http_req_add_hdr);
4825 hlua_class_function(gL.T, "req_set_header", hlua_http_req_set_hdr);
4826 hlua_class_function(gL.T, "req_set_method", hlua_http_req_set_meth);
4827 hlua_class_function(gL.T, "req_set_path", hlua_http_req_set_path);
4828 hlua_class_function(gL.T, "req_set_query", hlua_http_req_set_query);
4829 hlua_class_function(gL.T, "req_set_uri", hlua_http_req_set_uri);
4830
4831 hlua_class_function(gL.T, "res_get_headers",hlua_http_res_get_headers);
4832 hlua_class_function(gL.T, "res_del_header", hlua_http_res_del_hdr);
4833 hlua_class_function(gL.T, "res_rep_header", hlua_http_res_rep_hdr);
4834 hlua_class_function(gL.T, "res_rep_value", hlua_http_res_rep_val);
4835 hlua_class_function(gL.T, "res_add_header", hlua_http_res_add_hdr);
4836 hlua_class_function(gL.T, "res_set_header", hlua_http_res_set_hdr);
4837
4838 lua_settable(gL.T, -3);
4839
4840 /* Register previous table in the registry with reference and named entry. */
4841 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4842 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_HTTP); /* register class session. */
4843 class_http_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
4844
4845 /*
4846 *
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01004847 * Register class TXN
4848 *
4849 */
4850
4851 /* Create and fill the metatable. */
4852 lua_newtable(gL.T);
4853
4854 /* Create and fille the __index entry. */
4855 lua_pushstring(gL.T, "__index");
4856 lua_newtable(gL.T);
4857
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01004858 /* Register Lua functions. */
Willy Tarreau59551662015-03-10 14:23:13 +01004859 hlua_class_function(gL.T, "set_priv", hlua_set_priv);
4860 hlua_class_function(gL.T, "get_priv", hlua_get_priv);
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01004861 hlua_class_function(gL.T, "close", hlua_txn_close);
Thierry FOURNIER2cce3532015-03-16 12:04:16 +01004862 hlua_class_function(gL.T, "set_loglevel",hlua_txn_set_loglevel);
4863 hlua_class_function(gL.T, "set_tos", hlua_txn_set_tos);
4864 hlua_class_function(gL.T, "set_mark", hlua_txn_set_mark);
Thierry FOURNIERc798b5d2015-03-17 01:09:57 +01004865 hlua_class_function(gL.T, "deflog", hlua_txn_deflog);
4866 hlua_class_function(gL.T, "log", hlua_txn_log);
4867 hlua_class_function(gL.T, "Debug", hlua_txn_log_debug);
4868 hlua_class_function(gL.T, "Info", hlua_txn_log_info);
4869 hlua_class_function(gL.T, "Warning", hlua_txn_log_warning);
4870 hlua_class_function(gL.T, "Alert", hlua_txn_log_alert);
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01004871
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01004872 lua_settable(gL.T, -3);
4873
4874 /* Register previous table in the registry with reference and named entry. */
4875 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4876 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_TXN); /* register class session. */
4877 class_txn_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01004878
4879 /*
4880 *
4881 * Register class Socket
4882 *
4883 */
4884
4885 /* Create and fill the metatable. */
4886 lua_newtable(gL.T);
4887
4888 /* Create and fille the __index entry. */
4889 lua_pushstring(gL.T, "__index");
4890 lua_newtable(gL.T);
4891
Baptiste Assmann84bb4932015-03-02 21:40:06 +01004892#ifdef USE_OPENSSL
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01004893 hlua_class_function(gL.T, "connect_ssl", hlua_socket_connect_ssl);
Baptiste Assmann84bb4932015-03-02 21:40:06 +01004894#endif
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01004895 hlua_class_function(gL.T, "connect", hlua_socket_connect);
4896 hlua_class_function(gL.T, "send", hlua_socket_send);
4897 hlua_class_function(gL.T, "receive", hlua_socket_receive);
4898 hlua_class_function(gL.T, "close", hlua_socket_close);
4899 hlua_class_function(gL.T, "getpeername", hlua_socket_getpeername);
4900 hlua_class_function(gL.T, "getsockname", hlua_socket_getsockname);
4901 hlua_class_function(gL.T, "setoption", hlua_socket_setoption);
4902 hlua_class_function(gL.T, "settimeout", hlua_socket_settimeout);
4903
4904 lua_settable(gL.T, -3); /* Push the last 2 entries in the table at index -3 */
4905
4906 /* Register the garbage collector entry. */
4907 lua_pushstring(gL.T, "__gc");
4908 lua_pushcclosure(gL.T, hlua_socket_gc, 0);
4909 lua_settable(gL.T, -3); /* Push the last 2 entries in the table at index -3 */
4910
4911 /* Register previous table in the registry with reference and named entry. */
4912 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4913 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4914 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_SOCKET); /* register class socket. */
4915 class_socket_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class socket. */
4916
4917 /* Proxy and server configuration initialisation. */
4918 memset(&socket_proxy, 0, sizeof(socket_proxy));
4919 init_new_proxy(&socket_proxy);
4920 socket_proxy.parent = NULL;
4921 socket_proxy.last_change = now.tv_sec;
4922 socket_proxy.id = "LUA-SOCKET";
4923 socket_proxy.cap = PR_CAP_FE | PR_CAP_BE;
4924 socket_proxy.maxconn = 0;
4925 socket_proxy.accept = NULL;
4926 socket_proxy.options2 |= PR_O2_INDEPSTR;
4927 socket_proxy.srv = NULL;
4928 socket_proxy.conn_retries = 0;
4929 socket_proxy.timeout.connect = 5000; /* By default the timeout connection is 5s. */
4930
4931 /* Init TCP server: unchanged parameters */
4932 memset(&socket_tcp, 0, sizeof(socket_tcp));
4933 socket_tcp.next = NULL;
4934 socket_tcp.proxy = &socket_proxy;
4935 socket_tcp.obj_type = OBJ_TYPE_SERVER;
4936 LIST_INIT(&socket_tcp.actconns);
4937 LIST_INIT(&socket_tcp.pendconns);
4938 socket_tcp.state = SRV_ST_RUNNING; /* early server setup */
4939 socket_tcp.last_change = 0;
4940 socket_tcp.id = "LUA-TCP-CONN";
4941 socket_tcp.check.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
4942 socket_tcp.agent.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
4943 socket_tcp.pp_opts = 0; /* Remove proxy protocol. */
4944
4945 /* XXX: Copy default parameter from default server,
4946 * but the default server is not initialized.
4947 */
4948 socket_tcp.maxqueue = socket_proxy.defsrv.maxqueue;
4949 socket_tcp.minconn = socket_proxy.defsrv.minconn;
4950 socket_tcp.maxconn = socket_proxy.defsrv.maxconn;
4951 socket_tcp.slowstart = socket_proxy.defsrv.slowstart;
4952 socket_tcp.onerror = socket_proxy.defsrv.onerror;
4953 socket_tcp.onmarkeddown = socket_proxy.defsrv.onmarkeddown;
4954 socket_tcp.onmarkedup = socket_proxy.defsrv.onmarkedup;
4955 socket_tcp.consecutive_errors_limit = socket_proxy.defsrv.consecutive_errors_limit;
4956 socket_tcp.uweight = socket_proxy.defsrv.iweight;
4957 socket_tcp.iweight = socket_proxy.defsrv.iweight;
4958
4959 socket_tcp.check.status = HCHK_STATUS_INI;
4960 socket_tcp.check.rise = socket_proxy.defsrv.check.rise;
4961 socket_tcp.check.fall = socket_proxy.defsrv.check.fall;
4962 socket_tcp.check.health = socket_tcp.check.rise; /* socket, but will fall down at first failure */
4963 socket_tcp.check.server = &socket_tcp;
4964
4965 socket_tcp.agent.status = HCHK_STATUS_INI;
4966 socket_tcp.agent.rise = socket_proxy.defsrv.agent.rise;
4967 socket_tcp.agent.fall = socket_proxy.defsrv.agent.fall;
4968 socket_tcp.agent.health = socket_tcp.agent.rise; /* socket, but will fall down at first failure */
4969 socket_tcp.agent.server = &socket_tcp;
4970
4971 socket_tcp.xprt = &raw_sock;
4972
4973#ifdef USE_OPENSSL
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01004974 /* Init TCP server: unchanged parameters */
4975 memset(&socket_ssl, 0, sizeof(socket_ssl));
4976 socket_ssl.next = NULL;
4977 socket_ssl.proxy = &socket_proxy;
4978 socket_ssl.obj_type = OBJ_TYPE_SERVER;
4979 LIST_INIT(&socket_ssl.actconns);
4980 LIST_INIT(&socket_ssl.pendconns);
4981 socket_ssl.state = SRV_ST_RUNNING; /* early server setup */
4982 socket_ssl.last_change = 0;
4983 socket_ssl.id = "LUA-SSL-CONN";
4984 socket_ssl.check.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
4985 socket_ssl.agent.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
4986 socket_ssl.pp_opts = 0; /* Remove proxy protocol. */
4987
4988 /* XXX: Copy default parameter from default server,
4989 * but the default server is not initialized.
4990 */
4991 socket_ssl.maxqueue = socket_proxy.defsrv.maxqueue;
4992 socket_ssl.minconn = socket_proxy.defsrv.minconn;
4993 socket_ssl.maxconn = socket_proxy.defsrv.maxconn;
4994 socket_ssl.slowstart = socket_proxy.defsrv.slowstart;
4995 socket_ssl.onerror = socket_proxy.defsrv.onerror;
4996 socket_ssl.onmarkeddown = socket_proxy.defsrv.onmarkeddown;
4997 socket_ssl.onmarkedup = socket_proxy.defsrv.onmarkedup;
4998 socket_ssl.consecutive_errors_limit = socket_proxy.defsrv.consecutive_errors_limit;
4999 socket_ssl.uweight = socket_proxy.defsrv.iweight;
5000 socket_ssl.iweight = socket_proxy.defsrv.iweight;
5001
5002 socket_ssl.check.status = HCHK_STATUS_INI;
5003 socket_ssl.check.rise = socket_proxy.defsrv.check.rise;
5004 socket_ssl.check.fall = socket_proxy.defsrv.check.fall;
5005 socket_ssl.check.health = socket_ssl.check.rise; /* socket, but will fall down at first failure */
5006 socket_ssl.check.server = &socket_ssl;
5007
5008 socket_ssl.agent.status = HCHK_STATUS_INI;
5009 socket_ssl.agent.rise = socket_proxy.defsrv.agent.rise;
5010 socket_ssl.agent.fall = socket_proxy.defsrv.agent.fall;
5011 socket_ssl.agent.health = socket_ssl.agent.rise; /* socket, but will fall down at first failure */
5012 socket_ssl.agent.server = &socket_ssl;
5013
Thierry FOURNIER36d13742015-03-17 16:48:53 +01005014 socket_ssl.use_ssl = 1;
5015 socket_ssl.xprt = &ssl_sock;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01005016
Thierry FOURNIER36d13742015-03-17 16:48:53 +01005017 for (idx = 0; args[idx] != NULL; idx++) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01005018 if ((kw = srv_find_kw(args[idx])) != NULL) { /* Maybe it's registered server keyword */
5019 /*
5020 *
5021 * If the keyword is not known, we can search in the registered
5022 * server keywords. This is usefull to configure special SSL
5023 * features like client certificates and ssl_verify.
5024 *
5025 */
5026 tmp_error = kw->parse(args, &idx, &socket_proxy, &socket_ssl, &error);
5027 if (tmp_error != 0) {
5028 fprintf(stderr, "INTERNAL ERROR: %s\n", error);
5029 abort(); /* This must be never arrives because the command line
5030 not editable by the user. */
5031 }
5032 idx += kw->skip;
5033 }
5034 }
5035
5036 /* Initialize SSL server. */
Thierry FOURNIER36d13742015-03-17 16:48:53 +01005037 ssl_sock_prepare_srv_ctx(&socket_ssl, &socket_proxy);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01005038#endif
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +01005039}