blob: 34e14e87d59b27282d20c1e30ddf5d6fffcfcbc0 [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>
Willy Tarreau8a8d83b2015-04-13 13:24:54 +020023#include <proto/applet.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010024#include <proto/channel.h>
Thierry FOURNIER9a819e72015-02-16 20:22:55 +010025#include <proto/hdr_idx.h>
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +010026#include <proto/hlua.h>
Thierry FOURNIER3def3932015-04-07 11:27:54 +020027#include <proto/map.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010028#include <proto/obj_type.h>
Thierry FOURNIER83758bb2015-02-04 13:21:04 +010029#include <proto/pattern.h>
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +010030#include <proto/payload.h>
31#include <proto/proto_http.h>
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +010032#include <proto/proto_tcp.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010033#include <proto/raw_sock.h>
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +010034#include <proto/sample.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010035#include <proto/server.h>
Willy Tarreaufeb76402015-04-03 14:10:06 +020036#include <proto/session.h>
Willy Tarreau87b09662015-04-03 00:22:06 +020037#include <proto/stream.h>
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010038#include <proto/ssl_sock.h>
39#include <proto/stream_interface.h>
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +010040#include <proto/task.h>
Thierry FOURNIER053ba8ad2015-06-08 13:05:33 +020041#include <proto/vars.h>
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +010042
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +010043/* Lua uses longjmp to perform yield or throwing errors. This
44 * macro is used only for identifying the function that can
45 * not return because a longjmp is executed.
46 * __LJMP marks a prototype of hlua file that can use longjmp.
47 * WILL_LJMP() marks an lua function that will use longjmp.
48 * MAY_LJMP() marks an lua function that may use longjmp.
49 */
50#define __LJMP
51#define WILL_LJMP(func) func
52#define MAY_LJMP(func) func
53
Thierry FOURNIER380d0932015-01-23 14:27:52 +010054/* The main Lua execution context. */
55struct hlua gL;
56
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +010057/* This is the memory pool containing all the signal structs. These
58 * struct are used to store each requiered signal between two tasks.
59 */
60struct pool_head *pool2_hlua_com;
61
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010062/* Used for Socket connection. */
63static struct proxy socket_proxy;
64static struct server socket_tcp;
65#ifdef USE_OPENSSL
66static struct server socket_ssl;
67#endif
68
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +010069/* List head of the function called at the initialisation time. */
70struct list hlua_init_functions = LIST_HEAD_INIT(hlua_init_functions);
71
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +010072/* The following variables contains the reference of the different
73 * Lua classes. These references are useful for identify metadata
74 * associated with an object.
75 */
Thierry FOURNIER65f34c62015-02-16 20:11:43 +010076static int class_txn_ref;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +010077static int class_socket_ref;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +010078static int class_channel_ref;
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +010079static int class_fetches_ref;
Thierry FOURNIER594afe72015-03-10 23:58:30 +010080static int class_converters_ref;
Thierry FOURNIER08504f42015-03-16 14:17:08 +010081static int class_http_ref;
Thierry FOURNIER3def3932015-04-07 11:27:54 +020082static int class_map_ref;
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +010083
Thierry FOURNIERbd413492015-03-03 16:52:26 +010084/* Global Lua execution timeout. By default Lua, execution linked
Willy Tarreau87b09662015-04-03 00:22:06 +020085 * with stream (actions, sample-fetches and converters) have a
Thierry FOURNIERbd413492015-03-03 16:52:26 +010086 * short timeout. Lua linked with tasks doesn't have a timeout
87 * because a task may remain alive during all the haproxy execution.
88 */
89static unsigned int hlua_timeout_session = 4000; /* session timeout. */
90static unsigned int hlua_timeout_task = TICK_ETERNITY; /* task timeout. */
91
Thierry FOURNIERee9f8022015-03-03 17:37:37 +010092/* Interrupts the Lua processing each "hlua_nb_instruction" instructions.
93 * it is used for preventing infinite loops.
94 *
95 * I test the scheer with an infinite loop containing one incrementation
96 * and one test. I run this loop between 10 seconds, I raise a ceil of
97 * 710M loops from one interrupt each 9000 instructions, so I fix the value
98 * to one interrupt each 10 000 instructions.
99 *
100 * configured | Number of
101 * instructions | loops executed
102 * between two | in milions
103 * forced yields |
104 * ---------------+---------------
105 * 10 | 160
106 * 500 | 670
107 * 1000 | 680
108 * 5000 | 700
109 * 7000 | 700
110 * 8000 | 700
111 * 9000 | 710 <- ceil
112 * 10000 | 710
113 * 100000 | 710
114 * 1000000 | 710
115 *
116 */
117static unsigned int hlua_nb_instruction = 10000;
118
Willy Tarreau32f61e22015-03-18 17:54:59 +0100119/* Descriptor for the memory allocation state. If limit is not null, it will
120 * be enforced on any memory allocation.
121 */
122struct hlua_mem_allocator {
123 size_t allocated;
124 size_t limit;
125};
126
127static struct hlua_mem_allocator hlua_global_allocator;
128
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100129/* These functions converts types between HAProxy internal args or
130 * sample and LUA types. Another function permits to check if the
131 * LUA stack contains arguments according with an required ARG_T
132 * format.
133 */
134static int hlua_arg2lua(lua_State *L, const struct arg *arg);
135static int hlua_lua2arg(lua_State *L, int ud, struct arg *arg);
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100136__LJMP static int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp,
137 unsigned int mask, struct proxy *p);
Willy Tarreau5eadada2015-03-10 17:28:54 +0100138static int hlua_smp2lua(lua_State *L, struct sample *smp);
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +0100139static int hlua_smp2lua_str(lua_State *L, struct sample *smp);
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100140static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp);
141
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100142/* Used to check an Lua function type in the stack. It creates and
143 * returns a reference of the function. This function throws an
144 * error if the rgument is not a "function".
145 */
146__LJMP unsigned int hlua_checkfunction(lua_State *L, int argno)
147{
148 if (!lua_isfunction(L, argno)) {
149 const char *msg = lua_pushfstring(L, "function expected, got %s", luaL_typename(L, -1));
150 WILL_LJMP(luaL_argerror(L, argno, msg));
151 }
152 lua_pushvalue(L, argno);
153 return luaL_ref(L, LUA_REGISTRYINDEX);
154}
155
156/* The three following functions are useful for adding entries
157 * in a table. These functions takes a string and respectively an
158 * integer, a string or a function and add it to the table in the
159 * top of the stack.
160 *
161 * These functions throws an error if no more stack size is
162 * available.
163 */
164__LJMP static inline void hlua_class_const_int(lua_State *L, const char *name,
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100165 int value)
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100166{
167 if (!lua_checkstack(L, 2))
168 WILL_LJMP(luaL_error(L, "full stack"));
169 lua_pushstring(L, name);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100170 lua_pushinteger(L, value);
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100171 lua_settable(L, -3);
172}
173__LJMP static inline void hlua_class_const_str(lua_State *L, const char *name,
174 const char *value)
175{
176 if (!lua_checkstack(L, 2))
177 WILL_LJMP(luaL_error(L, "full stack"));
178 lua_pushstring(L, name);
179 lua_pushstring(L, value);
180 lua_settable(L, -3);
181}
182__LJMP static inline void hlua_class_function(lua_State *L, const char *name,
183 int (*function)(lua_State *L))
184{
185 if (!lua_checkstack(L, 2))
186 WILL_LJMP(luaL_error(L, "full stack"));
187 lua_pushstring(L, name);
188 lua_pushcclosure(L, function, 0);
189 lua_settable(L, -3);
190}
191
192/* This function check the number of arguments available in the
193 * stack. If the number of arguments available is not the same
194 * then <nb> an error is throwed.
195 */
196__LJMP static inline void check_args(lua_State *L, int nb, char *fcn)
197{
198 if (lua_gettop(L) == nb)
199 return;
200 WILL_LJMP(luaL_error(L, "'%s' needs %d arguments", fcn, nb));
201}
202
203/* Return true if the data in stack[<ud>] is an object of
204 * type <class_ref>.
205 */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +0100206static int hlua_metaistype(lua_State *L, int ud, int class_ref)
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100207{
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100208 if (!lua_getmetatable(L, ud))
209 return 0;
210
211 lua_rawgeti(L, LUA_REGISTRYINDEX, class_ref);
212 if (!lua_rawequal(L, -1, -2)) {
213 lua_pop(L, 2);
214 return 0;
215 }
216
217 lua_pop(L, 2);
218 return 1;
219}
220
221/* Return an object of the expected type, or throws an error. */
222__LJMP static void *hlua_checkudata(lua_State *L, int ud, int class_ref)
223{
Thierry FOURNIER2297bc22015-03-11 17:43:33 +0100224 void *p;
225
226 /* Check if the stack entry is an array. */
227 if (!lua_istable(L, ud))
228 WILL_LJMP(luaL_argerror(L, ud, NULL));
229 /* Check if the metadata have the expected type. */
230 if (!hlua_metaistype(L, ud, class_ref))
231 WILL_LJMP(luaL_argerror(L, ud, NULL));
232 /* Push on the stack at the entry [0] of the table. */
233 lua_rawgeti(L, ud, 0);
234 /* Check if this entry is userdata. */
235 p = lua_touserdata(L, -1);
236 if (!p)
237 WILL_LJMP(luaL_argerror(L, ud, NULL));
238 /* Remove the entry returned by lua_rawgeti(). */
239 lua_pop(L, 1);
240 /* Return the associated struct. */
241 return p;
Thierry FOURNIERe8b9a402015-02-25 18:48:12 +0100242}
243
244/* This fucntion push an error string prefixed by the file name
245 * and the line number where the error is encountered.
246 */
247static int hlua_pusherror(lua_State *L, const char *fmt, ...)
248{
249 va_list argp;
250 va_start(argp, fmt);
251 luaL_where(L, 1);
252 lua_pushvfstring(L, fmt, argp);
253 va_end(argp);
254 lua_concat(L, 2);
255 return 1;
256}
257
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100258/* This function register a new signal. "lua" is the current lua
259 * execution context. It contains a pointer to the associated task.
260 * "link" is a list head attached to an other task that must be wake
261 * the lua task if an event occurs. This is useful with external
262 * events like TCP I/O or sleep functions. This funcion allocate
263 * memory for the signal.
264 */
265static int hlua_com_new(struct hlua *lua, struct list *link)
266{
267 struct hlua_com *com = pool_alloc2(pool2_hlua_com);
268 if (!com)
269 return 0;
270 LIST_ADDQ(&lua->com, &com->purge_me);
271 LIST_ADDQ(link, &com->wake_me);
272 com->task = lua->task;
273 return 1;
274}
275
276/* This function purge all the pending signals when the LUA execution
277 * is finished. This prevent than a coprocess try to wake a deleted
278 * task. This function remove the memory associated to the signal.
279 */
280static void hlua_com_purge(struct hlua *lua)
281{
282 struct hlua_com *com, *back;
283
284 /* Delete all pending communication signals. */
285 list_for_each_entry_safe(com, back, &lua->com, purge_me) {
286 LIST_DEL(&com->purge_me);
287 LIST_DEL(&com->wake_me);
288 pool_free2(pool2_hlua_com, com);
289 }
290}
291
292/* This function sends signals. It wakes all the tasks attached
293 * to a list head, and remove the signal, and free the used
294 * memory.
295 */
296static void hlua_com_wake(struct list *wake)
297{
298 struct hlua_com *com, *back;
299
300 /* Wake task and delete all pending communication signals. */
301 list_for_each_entry_safe(com, back, wake, wake_me) {
302 LIST_DEL(&com->purge_me);
303 LIST_DEL(&com->wake_me);
304 task_wakeup(com->task, TASK_WOKEN_MSG);
305 pool_free2(pool2_hlua_com, com);
306 }
307}
308
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100309/* This functions is used with sample fetch and converters. It
310 * converts the HAProxy configuration argument in a lua stack
311 * values.
312 *
313 * It takes an array of "arg", and each entry of the array is
314 * converted and pushed in the LUA stack.
315 */
316static int hlua_arg2lua(lua_State *L, const struct arg *arg)
317{
318 switch (arg->type) {
319 case ARGT_SINT:
320 lua_pushinteger(L, arg->data.sint);
321 break;
322
323 case ARGT_UINT:
324 case ARGT_TIME:
325 case ARGT_SIZE:
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100326 lua_pushinteger(L, arg->data.sint);
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100327 break;
328
329 case ARGT_STR:
330 lua_pushlstring(L, arg->data.str.str, arg->data.str.len);
331 break;
332
333 case ARGT_IPV4:
334 case ARGT_IPV6:
335 case ARGT_MSK4:
336 case ARGT_MSK6:
337 case ARGT_FE:
338 case ARGT_BE:
339 case ARGT_TAB:
340 case ARGT_SRV:
341 case ARGT_USR:
342 case ARGT_MAP:
343 default:
344 lua_pushnil(L);
345 break;
346 }
347 return 1;
348}
349
350/* This function take one entrie in an LUA stack at the index "ud",
351 * and try to convert it in an HAProxy argument entry. This is useful
352 * with sample fetch wrappers. The input arguments are gived to the
353 * lua wrapper and converted as arg list by thi function.
354 */
355static int hlua_lua2arg(lua_State *L, int ud, struct arg *arg)
356{
357 switch (lua_type(L, ud)) {
358
359 case LUA_TNUMBER:
360 case LUA_TBOOLEAN:
361 arg->type = ARGT_SINT;
362 arg->data.sint = lua_tointeger(L, ud);
363 break;
364
365 case LUA_TSTRING:
366 arg->type = ARGT_STR;
367 arg->data.str.str = (char *)lua_tolstring(L, ud, (size_t *)&arg->data.str.len);
368 break;
369
370 case LUA_TUSERDATA:
371 case LUA_TNIL:
372 case LUA_TTABLE:
373 case LUA_TFUNCTION:
374 case LUA_TTHREAD:
375 case LUA_TLIGHTUSERDATA:
376 arg->type = ARGT_SINT;
377 arg->data.uint = 0;
378 break;
379 }
380 return 1;
381}
382
383/* the following functions are used to convert a struct sample
384 * in Lua type. This useful to convert the return of the
385 * fetchs or converters.
386 */
Willy Tarreau5eadada2015-03-10 17:28:54 +0100387static int hlua_smp2lua(lua_State *L, struct sample *smp)
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100388{
389 switch (smp->type) {
390 case SMP_T_SINT:
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100391 case SMP_T_BOOL:
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100392 lua_pushinteger(L, smp->data.sint);
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100393 break;
394
395 case SMP_T_BIN:
396 case SMP_T_STR:
397 lua_pushlstring(L, smp->data.str.str, smp->data.str.len);
398 break;
399
400 case SMP_T_METH:
401 switch (smp->data.meth.meth) {
402 case HTTP_METH_OPTIONS: lua_pushstring(L, "OPTIONS"); break;
403 case HTTP_METH_GET: lua_pushstring(L, "GET"); break;
404 case HTTP_METH_HEAD: lua_pushstring(L, "HEAD"); break;
405 case HTTP_METH_POST: lua_pushstring(L, "POST"); break;
406 case HTTP_METH_PUT: lua_pushstring(L, "PUT"); break;
407 case HTTP_METH_DELETE: lua_pushstring(L, "DELETE"); break;
408 case HTTP_METH_TRACE: lua_pushstring(L, "TRACE"); break;
409 case HTTP_METH_CONNECT: lua_pushstring(L, "CONNECT"); break;
410 case HTTP_METH_OTHER:
411 lua_pushlstring(L, smp->data.meth.str.str, smp->data.meth.str.len);
412 break;
413 default:
414 lua_pushnil(L);
415 break;
416 }
417 break;
418
419 case SMP_T_IPV4:
420 case SMP_T_IPV6:
421 case SMP_T_ADDR: /* This type is never used to qualify a sample. */
Willy Tarreau5eadada2015-03-10 17:28:54 +0100422 if (sample_casts[smp->type][SMP_T_STR] &&
423 sample_casts[smp->type][SMP_T_STR](smp))
424 lua_pushlstring(L, smp->data.str.str, smp->data.str.len);
425 else
426 lua_pushnil(L);
427 break;
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100428 default:
429 lua_pushnil(L);
430 break;
431 }
432 return 1;
433}
434
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +0100435/* the following functions are used to convert a struct sample
436 * in Lua strings. This is useful to convert the return of the
437 * fetchs or converters.
438 */
439static int hlua_smp2lua_str(lua_State *L, struct sample *smp)
440{
441 switch (smp->type) {
442
443 case SMP_T_BIN:
444 case SMP_T_STR:
445 lua_pushlstring(L, smp->data.str.str, smp->data.str.len);
446 break;
447
448 case SMP_T_METH:
449 switch (smp->data.meth.meth) {
450 case HTTP_METH_OPTIONS: lua_pushstring(L, "OPTIONS"); break;
451 case HTTP_METH_GET: lua_pushstring(L, "GET"); break;
452 case HTTP_METH_HEAD: lua_pushstring(L, "HEAD"); break;
453 case HTTP_METH_POST: lua_pushstring(L, "POST"); break;
454 case HTTP_METH_PUT: lua_pushstring(L, "PUT"); break;
455 case HTTP_METH_DELETE: lua_pushstring(L, "DELETE"); break;
456 case HTTP_METH_TRACE: lua_pushstring(L, "TRACE"); break;
457 case HTTP_METH_CONNECT: lua_pushstring(L, "CONNECT"); break;
458 case HTTP_METH_OTHER:
459 lua_pushlstring(L, smp->data.meth.str.str, smp->data.meth.str.len);
460 break;
461 default:
462 lua_pushstring(L, "");
463 break;
464 }
465 break;
466
467 case SMP_T_SINT:
468 case SMP_T_BOOL:
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +0100469 case SMP_T_IPV4:
470 case SMP_T_IPV6:
471 case SMP_T_ADDR: /* This type is never used to qualify a sample. */
472 if (sample_casts[smp->type][SMP_T_STR] &&
473 sample_casts[smp->type][SMP_T_STR](smp))
474 lua_pushlstring(L, smp->data.str.str, smp->data.str.len);
475 else
476 lua_pushstring(L, "");
477 break;
478 default:
479 lua_pushstring(L, "");
480 break;
481 }
482 return 1;
483}
484
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100485/* the following functions are used to convert an Lua type in a
486 * struct sample. This is useful to provide data from a converter
487 * to the LUA code.
488 */
489static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp)
490{
491 switch (lua_type(L, ud)) {
492
493 case LUA_TNUMBER:
494 smp->type = SMP_T_SINT;
495 smp->data.sint = lua_tointeger(L, ud);
496 break;
497
498
499 case LUA_TBOOLEAN:
500 smp->type = SMP_T_BOOL;
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +0200501 smp->data.sint = lua_toboolean(L, ud);
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100502 break;
503
504 case LUA_TSTRING:
505 smp->type = SMP_T_STR;
506 smp->flags |= SMP_F_CONST;
507 smp->data.str.str = (char *)lua_tolstring(L, ud, (size_t *)&smp->data.str.len);
508 break;
509
510 case LUA_TUSERDATA:
511 case LUA_TNIL:
512 case LUA_TTABLE:
513 case LUA_TFUNCTION:
514 case LUA_TTHREAD:
515 case LUA_TLIGHTUSERDATA:
516 smp->type = SMP_T_BOOL;
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +0200517 smp->data.sint = 0;
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100518 break;
519 }
520 return 1;
521}
522
523/* This function check the "argp" builded by another conversion function
524 * is in accord with the expected argp defined by the "mask". The fucntion
525 * returns true or false. It can be adjust the types if there compatibles.
Thierry FOURNIER3caa0392015-03-13 13:38:17 +0100526 *
527 * This function assumes thant the argp argument contains ARGM_NBARGS + 1
528 * entries.
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100529 */
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100530__LJMP int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp,
531 unsigned int mask, struct proxy *p)
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100532{
533 int min_arg;
534 int idx;
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100535 struct proxy *px;
536 char *sname, *pname;
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100537
538 idx = 0;
539 min_arg = ARGM(mask);
540 mask >>= ARGM_BITS;
541
542 while (1) {
543
544 /* Check oversize. */
545 if (idx >= ARGM_NBARGS && argp[idx].type != ARGT_STOP) {
Cyril Bonté577a36a2015-03-02 00:08:38 +0100546 WILL_LJMP(luaL_argerror(L, first + idx, "Malformed argument mask"));
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100547 }
548
549 /* Check for mandatory arguments. */
550 if (argp[idx].type == ARGT_STOP) {
Thierry FOURNIER3caa0392015-03-13 13:38:17 +0100551 if (idx < min_arg) {
552
553 /* If miss other argument than the first one, we return an error. */
554 if (idx > 0)
555 WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
556
557 /* If first argument have a certain type, some default values
558 * may be used. See the function smp_resolve_args().
559 */
560 switch (mask & ARGT_MASK) {
561
562 case ARGT_FE:
563 if (!(p->cap & PR_CAP_FE))
564 WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
565 argp[idx].data.prx = p;
566 argp[idx].type = ARGT_FE;
567 argp[idx+1].type = ARGT_STOP;
568 break;
569
570 case ARGT_BE:
571 if (!(p->cap & PR_CAP_BE))
572 WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
573 argp[idx].data.prx = p;
574 argp[idx].type = ARGT_BE;
575 argp[idx+1].type = ARGT_STOP;
576 break;
577
578 case ARGT_TAB:
579 argp[idx].data.prx = p;
580 argp[idx].type = ARGT_TAB;
581 argp[idx+1].type = ARGT_STOP;
582 break;
583
584 default:
585 WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
586 break;
587 }
588 }
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100589 return 0;
590 }
591
592 /* Check for exceed the number of requiered argument. */
593 if ((mask & ARGT_MASK) == ARGT_STOP &&
594 argp[idx].type != ARGT_STOP) {
595 WILL_LJMP(luaL_argerror(L, first + idx, "Last argument expected"));
596 }
597
598 if ((mask & ARGT_MASK) == ARGT_STOP &&
599 argp[idx].type == ARGT_STOP) {
600 return 0;
601 }
602
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100603 /* Convert some argument types. */
604 switch (mask & ARGT_MASK) {
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100605 case ARGT_SINT:
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100606 if (argp[idx].type != ARGT_SINT)
607 WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
608 argp[idx].type = ARGT_SINT;
609 break;
610
611 case ARGT_UINT:
612 if (argp[idx].type != ARGT_SINT)
613 WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
614 argp[idx].type = ARGT_SINT;
615 break;
616
617 case ARGT_TIME:
618 if (argp[idx].type != ARGT_SINT)
619 WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
Thierry FOURNIER29176f32015-07-07 00:41:29 +0200620 argp[idx].type = ARGT_TIME;
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100621 break;
622
623 case ARGT_SIZE:
624 if (argp[idx].type != ARGT_SINT)
625 WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
Thierry FOURNIER29176f32015-07-07 00:41:29 +0200626 argp[idx].type = ARGT_SIZE;
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100627 break;
628
629 case ARGT_FE:
630 if (argp[idx].type != ARGT_STR)
631 WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
632 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
633 trash.str[argp[idx].data.str.len] = 0;
Willy Tarreau9e0bb102015-05-26 11:24:42 +0200634 argp[idx].data.prx = proxy_fe_by_name(trash.str);
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100635 if (!argp[idx].data.prx)
636 WILL_LJMP(luaL_argerror(L, first + idx, "frontend doesn't exist"));
637 argp[idx].type = ARGT_FE;
638 break;
639
640 case ARGT_BE:
641 if (argp[idx].type != ARGT_STR)
642 WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
643 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
644 trash.str[argp[idx].data.str.len] = 0;
Willy Tarreau9e0bb102015-05-26 11:24:42 +0200645 argp[idx].data.prx = proxy_be_by_name(trash.str);
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100646 if (!argp[idx].data.prx)
647 WILL_LJMP(luaL_argerror(L, first + idx, "backend doesn't exist"));
648 argp[idx].type = ARGT_BE;
649 break;
650
651 case ARGT_TAB:
652 if (argp[idx].type != ARGT_STR)
653 WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
654 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
655 trash.str[argp[idx].data.str.len] = 0;
Willy Tarreaue2dc1fa2015-05-26 12:08:07 +0200656 argp[idx].data.prx = proxy_tbl_by_name(trash.str);
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100657 if (!argp[idx].data.prx)
658 WILL_LJMP(luaL_argerror(L, first + idx, "table doesn't exist"));
659 argp[idx].type = ARGT_TAB;
660 break;
661
662 case ARGT_SRV:
663 if (argp[idx].type != ARGT_STR)
664 WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
665 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
666 trash.str[argp[idx].data.str.len] = 0;
667 sname = strrchr(trash.str, '/');
668 if (sname) {
669 *sname++ = '\0';
670 pname = trash.str;
Willy Tarreau9e0bb102015-05-26 11:24:42 +0200671 px = proxy_be_by_name(pname);
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100672 if (!px)
673 WILL_LJMP(luaL_argerror(L, first + idx, "backend doesn't exist"));
674 }
675 else {
676 sname = trash.str;
677 px = p;
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100678 }
Thierry FOURNIER7f4942a2015-03-12 18:28:50 +0100679 argp[idx].data.srv = findserver(px, sname);
680 if (!argp[idx].data.srv)
681 WILL_LJMP(luaL_argerror(L, first + idx, "server doesn't exist"));
682 argp[idx].type = ARGT_SRV;
683 break;
684
685 case ARGT_IPV4:
686 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
687 trash.str[argp[idx].data.str.len] = 0;
688 if (inet_pton(AF_INET, trash.str, &argp[idx].data.ipv4))
689 WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv4 address"));
690 argp[idx].type = ARGT_IPV4;
691 break;
692
693 case ARGT_MSK4:
694 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
695 trash.str[argp[idx].data.str.len] = 0;
696 if (!str2mask(trash.str, &argp[idx].data.ipv4))
697 WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv4 mask"));
698 argp[idx].type = ARGT_MSK4;
699 break;
700
701 case ARGT_IPV6:
702 memcpy(trash.str, argp[idx].data.str.str, argp[idx].data.str.len);
703 trash.str[argp[idx].data.str.len] = 0;
704 if (inet_pton(AF_INET6, trash.str, &argp[idx].data.ipv6))
705 WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv6 address"));
706 argp[idx].type = ARGT_IPV6;
707 break;
708
709 case ARGT_MSK6:
710 case ARGT_MAP:
711 case ARGT_REG:
712 case ARGT_USR:
713 WILL_LJMP(luaL_argerror(L, first + idx, "type not yet supported"));
Thierry FOURNIER55da1652015-01-23 11:36:30 +0100714 break;
715 }
716
717 /* Check for type of argument. */
718 if ((mask & ARGT_MASK) != argp[idx].type) {
719 const char *msg = lua_pushfstring(L, "'%s' expected, got '%s'",
720 arg_type_names[(mask & ARGT_MASK)],
721 arg_type_names[argp[idx].type & ARGT_MASK]);
722 WILL_LJMP(luaL_argerror(L, first + idx, msg));
723 }
724
725 /* Next argument. */
726 mask >>= ARGT_BITS;
727 idx++;
728 }
729}
730
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100731/*
732 * The following functions are used to make correspondance between the the
733 * executed lua pointer and the "struct hlua *" that contain the context.
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100734 *
735 * - hlua_gethlua : return the hlua context associated with an lua_State.
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100736 * - hlua_sethlua : create the association between hlua context and lua_state.
737 */
738static inline struct hlua *hlua_gethlua(lua_State *L)
739{
Thierry FOURNIER38c5fd62015-03-10 02:40:29 +0100740 struct hlua **hlua = lua_getextraspace(L);
741 return *hlua;
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100742}
743static inline void hlua_sethlua(struct hlua *hlua)
744{
Thierry FOURNIER38c5fd62015-03-10 02:40:29 +0100745 struct hlua **hlua_store = lua_getextraspace(hlua->T);
746 *hlua_store = hlua;
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100747}
748
Thierry FOURNIERc798b5d2015-03-17 01:09:57 +0100749/* This function is used to send logs. It try to send on screen (stderr)
750 * and on the default syslog server.
751 */
752static inline void hlua_sendlog(struct proxy *px, int level, const char *msg)
753{
754 struct tm tm;
755 char *p;
756
757 /* Cleanup the log message. */
758 p = trash.str;
759 for (; *msg != '\0'; msg++, p++) {
760 if (p >= trash.str + trash.size - 1)
761 return;
762 if (isprint(*msg))
763 *p = *msg;
764 else
765 *p = '.';
766 }
767 *p = '\0';
768
769 send_log(px, level, "%s", trash.str);
770 if (!(global.mode & MODE_QUIET) || (global.mode & (MODE_VERBOSE | MODE_STARTING))) {
771 get_localtime(date.tv_sec, &tm);
772 fprintf(stderr, "[%s] %03d/%02d%02d%02d (%d) : %s\n",
773 log_levels[level], tm.tm_yday, tm.tm_hour, tm.tm_min, tm.tm_sec,
774 (int)getpid(), trash.str);
775 fflush(stderr);
776 }
777}
778
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100779/* This function just ensure that the yield will be always
780 * returned with a timeout and permit to set some flags
781 */
782__LJMP void hlua_yieldk(lua_State *L, int nresults, int ctx,
Thierry FOURNIERf90838b2015-03-06 13:48:32 +0100783 lua_KFunction k, int timeout, unsigned int flags)
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100784{
785 struct hlua *hlua = hlua_gethlua(L);
786
787 /* Set the wake timeout. If timeout is required, we set
788 * the expiration time.
789 */
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100790 hlua->wake_time = tick_first(timeout, hlua->expire);
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100791
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +0100792 hlua->flags |= flags;
793
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +0100794 /* Process the yield. */
795 WILL_LJMP(lua_yieldk(L, nresults, ctx, k));
796}
797
Willy Tarreau87b09662015-04-03 00:22:06 +0200798/* This function initialises the Lua environment stored in the stream.
799 * It must be called at the start of the stream. This function creates
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100800 * an LUA coroutine. It can not be use to crete the main LUA context.
801 */
802int hlua_ctx_init(struct hlua *lua, struct task *task)
803{
804 lua->Mref = LUA_REFNIL;
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +0100805 lua->flags = 0;
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100806 LIST_INIT(&lua->com);
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100807 lua->T = lua_newthread(gL.T);
808 if (!lua->T) {
809 lua->Tref = LUA_REFNIL;
810 return 0;
811 }
812 hlua_sethlua(lua);
813 lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
814 lua->task = task;
815 return 1;
816}
817
Willy Tarreau87b09662015-04-03 00:22:06 +0200818/* Used to destroy the Lua coroutine when the attached stream or task
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100819 * is destroyed. The destroy also the memory context. The struct "lua"
820 * is not freed.
821 */
822void hlua_ctx_destroy(struct hlua *lua)
823{
Thierry FOURNIERa718b292015-03-04 16:48:34 +0100824 if (!lua->T)
825 return;
826
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +0100827 /* Purge all the pending signals. */
828 hlua_com_purge(lua);
829
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100830 /* The thread is garbage collected by Lua. */
831 luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
832 luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
833}
834
835/* This function is used to restore the Lua context when a coroutine
836 * fails. This function copy the common memory between old coroutine
837 * and the new coroutine. The old coroutine is destroyed, and its
838 * replaced by the new coroutine.
839 * If the flag "keep_msg" is set, the last entry of the old is assumed
840 * as string error message and it is copied in the new stack.
841 */
842static int hlua_ctx_renew(struct hlua *lua, int keep_msg)
843{
844 lua_State *T;
845 int new_ref;
846
847 /* Renew the main LUA stack doesn't have sense. */
848 if (lua == &gL)
849 return 0;
850
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100851 /* New Lua coroutine. */
852 T = lua_newthread(gL.T);
853 if (!T)
854 return 0;
855
856 /* Copy last error message. */
857 if (keep_msg)
858 lua_xmove(lua->T, T, 1);
859
860 /* Copy data between the coroutines. */
861 lua_rawgeti(lua->T, LUA_REGISTRYINDEX, lua->Mref);
862 lua_xmove(lua->T, T, 1);
863 new_ref = luaL_ref(T, LUA_REGISTRYINDEX); /* Valur poped. */
864
865 /* Destroy old data. */
866 luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
867
868 /* The thread is garbage collected by Lua. */
869 luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
870
871 /* Fill the struct with the new coroutine values. */
872 lua->Mref = new_ref;
873 lua->T = T;
874 lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
875
876 /* Set context. */
877 hlua_sethlua(lua);
878
879 return 1;
880}
881
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100882void hlua_hook(lua_State *L, lua_Debug *ar)
883{
Thierry FOURNIERcae49c92015-03-06 14:05:24 +0100884 struct hlua *hlua = hlua_gethlua(L);
885
886 /* Lua cannot yield when its returning from a function,
887 * so, we can fix the interrupt hook to 1 instruction,
888 * expecting that the function is finnished.
889 */
890 if (lua_gethookmask(L) & LUA_MASKRET) {
891 lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, 1);
892 return;
893 }
894
895 /* restore the interrupt condition. */
896 lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, hlua_nb_instruction);
897
898 /* If we interrupt the Lua processing in yieldable state, we yield.
899 * If the state is not yieldable, trying yield causes an error.
900 */
901 if (lua_isyieldable(L))
902 WILL_LJMP(hlua_yieldk(L, 0, 0, NULL, TICK_ETERNITY, HLUA_CTRLYIELD));
903
Thierry FOURNIERa85cfb12015-03-13 14:50:06 +0100904 /* If we cannot yield, update the clock and check the timeout. */
905 tv_update_date(0, 1);
Thierry FOURNIERcae49c92015-03-06 14:05:24 +0100906 if (tick_is_expired(hlua->expire, now_ms)) {
907 lua_pushfstring(L, "execution timeout");
908 WILL_LJMP(lua_error(L));
909 }
910
911 /* Try to interrupt the process at the end of the current
912 * unyieldable function.
913 */
914 lua_sethook(hlua->T, hlua_hook, LUA_MASKRET|LUA_MASKCOUNT, hlua_nb_instruction);
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100915}
916
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100917/* This function start or resumes the Lua stack execution. If the flag
918 * "yield_allowed" if no set and the LUA stack execution returns a yield
919 * The function return an error.
920 *
921 * The function can returns 4 values:
922 * - HLUA_E_OK : The execution is terminated without any errors.
923 * - HLUA_E_AGAIN : The execution must continue at the next associated
924 * task wakeup.
925 * - HLUA_E_ERRMSG : An error has occured, an error message is set in
926 * the top of the stack.
927 * - HLUA_E_ERR : An error has occured without error message.
928 *
929 * If an error occured, the stack is renewed and it is ready to run new
930 * LUA code.
931 */
932static enum hlua_exec hlua_ctx_resume(struct hlua *lua, int yield_allowed)
933{
934 int ret;
935 const char *msg;
936
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +0100937 HLUA_SET_RUN(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100938
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100939 /* If we want to resume the task, then check first the execution timeout.
940 * if it is reached, we can interrupt the Lua processing.
941 */
942 if (tick_is_expired(lua->expire, now_ms))
943 goto timeout_reached;
944
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100945resume_execution:
946
947 /* This hook interrupts the Lua processing each 'hlua_nb_instruction'
948 * instructions. it is used for preventing infinite loops.
949 */
950 lua_sethook(lua->T, hlua_hook, LUA_MASKCOUNT, hlua_nb_instruction);
951
Thierry FOURNIER1bfc09b2015-03-05 17:10:14 +0100952 /* Remove all flags except the running flags. */
953 lua->flags = HLUA_RUN;
954
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100955 /* Call the function. */
956 ret = lua_resume(lua->T, gL.T, lua->nargs);
957 switch (ret) {
958
959 case LUA_OK:
960 ret = HLUA_E_OK;
961 break;
962
963 case LUA_YIELD:
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100964 /* Check if the execution timeout is expired. It it is the case, we
965 * break the Lua execution.
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100966 */
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100967 if (tick_is_expired(lua->expire, now_ms)) {
968
969timeout_reached:
970
971 lua_settop(lua->T, 0); /* Empty the stack. */
972 if (!lua_checkstack(lua->T, 1)) {
973 ret = HLUA_E_ERR;
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100974 break;
975 }
Thierry FOURNIERdc9ca962015-03-05 11:16:52 +0100976 lua_pushfstring(lua->T, "execution timeout");
977 ret = HLUA_E_ERRMSG;
978 break;
979 }
980 /* Process the forced yield. if the general yield is not allowed or
981 * if no task were associated this the current Lua execution
982 * coroutine, we resume the execution. Else we want to return in the
983 * scheduler and we want to be waked up again, to continue the
984 * current Lua execution. So we schedule our own task.
985 */
986 if (HLUA_IS_CTRLYIELDING(lua)) {
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100987 if (!yield_allowed || !lua->task)
988 goto resume_execution;
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100989 task_wakeup(lua->task, TASK_WOKEN_MSG);
Thierry FOURNIERee9f8022015-03-03 17:37:37 +0100990 }
Thierry FOURNIER380d0932015-01-23 14:27:52 +0100991 if (!yield_allowed) {
992 lua_settop(lua->T, 0); /* Empty the stack. */
993 if (!lua_checkstack(lua->T, 1)) {
994 ret = HLUA_E_ERR;
995 break;
996 }
997 lua_pushfstring(lua->T, "yield not allowed");
998 ret = HLUA_E_ERRMSG;
999 break;
1000 }
1001 ret = HLUA_E_AGAIN;
1002 break;
1003
1004 case LUA_ERRRUN:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01001005 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001006 if (!lua_checkstack(lua->T, 1)) {
1007 ret = HLUA_E_ERR;
1008 break;
1009 }
1010 msg = lua_tostring(lua->T, -1);
1011 lua_settop(lua->T, 0); /* Empty the stack. */
1012 lua_pop(lua->T, 1);
1013 if (msg)
1014 lua_pushfstring(lua->T, "runtime error: %s", msg);
1015 else
1016 lua_pushfstring(lua->T, "unknown runtime error");
1017 ret = HLUA_E_ERRMSG;
1018 break;
1019
1020 case LUA_ERRMEM:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01001021 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001022 lua_settop(lua->T, 0); /* Empty the stack. */
1023 if (!lua_checkstack(lua->T, 1)) {
1024 ret = HLUA_E_ERR;
1025 break;
1026 }
1027 lua_pushfstring(lua->T, "out of memory error");
1028 ret = HLUA_E_ERRMSG;
1029 break;
1030
1031 case LUA_ERRERR:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01001032 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001033 if (!lua_checkstack(lua->T, 1)) {
1034 ret = HLUA_E_ERR;
1035 break;
1036 }
1037 msg = lua_tostring(lua->T, -1);
1038 lua_settop(lua->T, 0); /* Empty the stack. */
1039 lua_pop(lua->T, 1);
1040 if (msg)
1041 lua_pushfstring(lua->T, "message handler error: %s", msg);
1042 else
1043 lua_pushfstring(lua->T, "message handler error");
1044 ret = HLUA_E_ERRMSG;
1045 break;
1046
1047 default:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01001048 lua->wake_time = TICK_ETERNITY;
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001049 lua_settop(lua->T, 0); /* Empty the stack. */
1050 if (!lua_checkstack(lua->T, 1)) {
1051 ret = HLUA_E_ERR;
1052 break;
1053 }
1054 lua_pushfstring(lua->T, "unknonwn error");
1055 ret = HLUA_E_ERRMSG;
1056 break;
1057 }
1058
1059 switch (ret) {
1060 case HLUA_E_AGAIN:
1061 break;
1062
1063 case HLUA_E_ERRMSG:
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01001064 hlua_com_purge(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001065 hlua_ctx_renew(lua, 1);
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01001066 HLUA_CLR_RUN(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001067 break;
1068
1069 case HLUA_E_ERR:
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01001070 HLUA_CLR_RUN(lua);
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01001071 hlua_com_purge(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001072 hlua_ctx_renew(lua, 0);
1073 break;
1074
1075 case HLUA_E_OK:
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01001076 HLUA_CLR_RUN(lua);
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01001077 hlua_com_purge(lua);
Thierry FOURNIER380d0932015-01-23 14:27:52 +01001078 break;
1079 }
1080
1081 return ret;
1082}
1083
Thierry FOURNIER83758bb2015-02-04 13:21:04 +01001084/* This function is an LUA binding. It provides a function
1085 * for deleting ACL from a referenced ACL file.
1086 */
1087__LJMP static int hlua_del_acl(lua_State *L)
1088{
1089 const char *name;
1090 const char *key;
1091 struct pat_ref *ref;
1092
1093 MAY_LJMP(check_args(L, 2, "del_acl"));
1094
1095 name = MAY_LJMP(luaL_checkstring(L, 1));
1096 key = MAY_LJMP(luaL_checkstring(L, 2));
1097
1098 ref = pat_ref_lookup(name);
1099 if (!ref)
1100 WILL_LJMP(luaL_error(L, "'del_acl': unkown acl file '%s'", name));
1101
1102 pat_ref_delete(ref, key);
1103 return 0;
1104}
1105
1106/* This function is an LUA binding. It provides a function
1107 * for deleting map entry from a referenced map file.
1108 */
1109static int hlua_del_map(lua_State *L)
1110{
1111 const char *name;
1112 const char *key;
1113 struct pat_ref *ref;
1114
1115 MAY_LJMP(check_args(L, 2, "del_map"));
1116
1117 name = MAY_LJMP(luaL_checkstring(L, 1));
1118 key = MAY_LJMP(luaL_checkstring(L, 2));
1119
1120 ref = pat_ref_lookup(name);
1121 if (!ref)
1122 WILL_LJMP(luaL_error(L, "'del_map': unkown acl file '%s'", name));
1123
1124 pat_ref_delete(ref, key);
1125 return 0;
1126}
1127
1128/* This function is an LUA binding. It provides a function
1129 * for adding ACL pattern from a referenced ACL file.
1130 */
1131static int hlua_add_acl(lua_State *L)
1132{
1133 const char *name;
1134 const char *key;
1135 struct pat_ref *ref;
1136
1137 MAY_LJMP(check_args(L, 2, "add_acl"));
1138
1139 name = MAY_LJMP(luaL_checkstring(L, 1));
1140 key = MAY_LJMP(luaL_checkstring(L, 2));
1141
1142 ref = pat_ref_lookup(name);
1143 if (!ref)
1144 WILL_LJMP(luaL_error(L, "'add_acl': unkown acl file '%s'", name));
1145
1146 if (pat_ref_find_elt(ref, key) == NULL)
1147 pat_ref_add(ref, key, NULL, NULL);
1148 return 0;
1149}
1150
1151/* This function is an LUA binding. It provides a function
1152 * for setting map pattern and sample from a referenced map
1153 * file.
1154 */
1155static int hlua_set_map(lua_State *L)
1156{
1157 const char *name;
1158 const char *key;
1159 const char *value;
1160 struct pat_ref *ref;
1161
1162 MAY_LJMP(check_args(L, 3, "set_map"));
1163
1164 name = MAY_LJMP(luaL_checkstring(L, 1));
1165 key = MAY_LJMP(luaL_checkstring(L, 2));
1166 value = MAY_LJMP(luaL_checkstring(L, 3));
1167
1168 ref = pat_ref_lookup(name);
1169 if (!ref)
1170 WILL_LJMP(luaL_error(L, "'set_map': unkown map file '%s'", name));
1171
1172 if (pat_ref_find_elt(ref, key) != NULL)
1173 pat_ref_set(ref, key, value, NULL);
1174 else
1175 pat_ref_add(ref, key, value, NULL);
1176 return 0;
1177}
1178
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01001179/* A class is a lot of memory that contain data. This data can be a table,
1180 * an integer or user data. This data is associated with a metatable. This
1181 * metatable have an original version registred in the global context with
1182 * the name of the object (_G[<name>] = <metable> ).
1183 *
1184 * A metable is a table that modify the standard behavior of a standard
1185 * access to the associated data. The entries of this new metatable are
1186 * defined as is:
1187 *
1188 * http://lua-users.org/wiki/MetatableEvents
1189 *
1190 * __index
1191 *
1192 * we access an absent field in a table, the result is nil. This is
1193 * true, but it is not the whole truth. Actually, such access triggers
1194 * the interpreter to look for an __index metamethod: If there is no
1195 * such method, as usually happens, then the access results in nil;
1196 * otherwise, the metamethod will provide the result.
1197 *
1198 * Control 'prototype' inheritance. When accessing "myTable[key]" and
1199 * the key does not appear in the table, but the metatable has an __index
1200 * property:
1201 *
1202 * - if the value is a function, the function is called, passing in the
1203 * table and the key; the return value of that function is returned as
1204 * the result.
1205 *
1206 * - if the value is another table, the value of the key in that table is
1207 * asked for and returned (and if it doesn't exist in that table, but that
1208 * table's metatable has an __index property, then it continues on up)
1209 *
1210 * - Use "rawget(myTable,key)" to skip this metamethod.
1211 *
1212 * http://www.lua.org/pil/13.4.1.html
1213 *
1214 * __newindex
1215 *
1216 * Like __index, but control property assignment.
1217 *
1218 * __mode - Control weak references. A string value with one or both
1219 * of the characters 'k' and 'v' which specifies that the the
1220 * keys and/or values in the table are weak references.
1221 *
1222 * __call - Treat a table like a function. When a table is followed by
1223 * parenthesis such as "myTable( 'foo' )" and the metatable has
1224 * a __call key pointing to a function, that function is invoked
1225 * (passing any specified arguments) and the return value is
1226 * returned.
1227 *
1228 * __metatable - Hide the metatable. When "getmetatable( myTable )" is
1229 * called, if the metatable for myTable has a __metatable
1230 * key, the value of that key is returned instead of the
1231 * actual metatable.
1232 *
1233 * __tostring - Control string representation. When the builtin
1234 * "tostring( myTable )" function is called, if the metatable
1235 * for myTable has a __tostring property set to a function,
1236 * that function is invoked (passing myTable to it) and the
1237 * return value is used as the string representation.
1238 *
1239 * __len - Control table length. When the table length is requested using
1240 * the length operator ( '#' ), if the metatable for myTable has
1241 * a __len key pointing to a function, that function is invoked
1242 * (passing myTable to it) and the return value used as the value
1243 * of "#myTable".
1244 *
1245 * __gc - Userdata finalizer code. When userdata is set to be garbage
1246 * collected, if the metatable has a __gc field pointing to a
1247 * function, that function is first invoked, passing the userdata
1248 * to it. The __gc metamethod is not called for tables.
1249 * (See http://lua-users.org/lists/lua-l/2006-11/msg00508.html)
1250 *
1251 * Special metamethods for redefining standard operators:
1252 * http://www.lua.org/pil/13.1.html
1253 *
1254 * __add "+"
1255 * __sub "-"
1256 * __mul "*"
1257 * __div "/"
1258 * __unm "!"
1259 * __pow "^"
1260 * __concat ".."
1261 *
1262 * Special methods for redfining standar relations
1263 * http://www.lua.org/pil/13.2.html
1264 *
1265 * __eq "=="
1266 * __lt "<"
1267 * __le "<="
1268 */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001269
1270/*
1271 *
1272 *
Thierry FOURNIER3def3932015-04-07 11:27:54 +02001273 * Class Map
1274 *
1275 *
1276 */
1277
1278/* Returns a struct hlua_map if the stack entry "ud" is
1279 * a class session, otherwise it throws an error.
1280 */
1281__LJMP static struct map_descriptor *hlua_checkmap(lua_State *L, int ud)
1282{
1283 return (struct map_descriptor *)MAY_LJMP(hlua_checkudata(L, ud, class_map_ref));
1284}
1285
1286/* This function is the map constructor. It don't need
1287 * the class Map object. It creates and return a new Map
1288 * object. It must be called only during "body" or "init"
1289 * context because it process some filesystem accesses.
1290 */
1291__LJMP static int hlua_map_new(struct lua_State *L)
1292{
1293 const char *fn;
1294 int match = PAT_MATCH_STR;
1295 struct sample_conv conv;
1296 const char *file = "";
1297 int line = 0;
1298 lua_Debug ar;
1299 char *err = NULL;
1300 struct arg args[2];
1301
1302 if (lua_gettop(L) < 1 || lua_gettop(L) > 2)
1303 WILL_LJMP(luaL_error(L, "'new' needs at least 1 argument."));
1304
1305 fn = MAY_LJMP(luaL_checkstring(L, 1));
1306
1307 if (lua_gettop(L) >= 2) {
1308 match = MAY_LJMP(luaL_checkinteger(L, 2));
1309 if (match < 0 || match >= PAT_MATCH_NUM)
1310 WILL_LJMP(luaL_error(L, "'new' needs a valid match method."));
1311 }
1312
1313 /* Get Lua filename and line number. */
1314 if (lua_getstack(L, 1, &ar)) { /* check function at level */
1315 lua_getinfo(L, "Sl", &ar); /* get info about it */
1316 if (ar.currentline > 0) { /* is there info? */
1317 file = ar.short_src;
1318 line = ar.currentline;
1319 }
1320 }
1321
1322 /* fill fake sample_conv struct. */
1323 conv.kw = ""; /* unused. */
1324 conv.process = NULL; /* unused. */
1325 conv.arg_mask = 0; /* unused. */
1326 conv.val_args = NULL; /* unused. */
1327 conv.out_type = SMP_T_STR;
1328 conv.private = (void *)(long)match;
1329 switch (match) {
1330 case PAT_MATCH_STR: conv.in_type = SMP_T_STR; break;
1331 case PAT_MATCH_BEG: conv.in_type = SMP_T_STR; break;
1332 case PAT_MATCH_SUB: conv.in_type = SMP_T_STR; break;
1333 case PAT_MATCH_DIR: conv.in_type = SMP_T_STR; break;
1334 case PAT_MATCH_DOM: conv.in_type = SMP_T_STR; break;
1335 case PAT_MATCH_END: conv.in_type = SMP_T_STR; break;
1336 case PAT_MATCH_REG: conv.in_type = SMP_T_STR; break;
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02001337 case PAT_MATCH_INT: conv.in_type = SMP_T_SINT; break;
Thierry FOURNIER3def3932015-04-07 11:27:54 +02001338 case PAT_MATCH_IP: conv.in_type = SMP_T_ADDR; break;
1339 default:
1340 WILL_LJMP(luaL_error(L, "'new' doesn't support this match mode."));
1341 }
1342
1343 /* fill fake args. */
1344 args[0].type = ARGT_STR;
1345 args[0].data.str.str = (char *)fn;
1346 args[1].type = ARGT_STOP;
1347
1348 /* load the map. */
1349 if (!sample_load_map(args, &conv, file, line, &err)) {
1350 /* error case: we cant use luaL_error because we must
1351 * free the err variable.
1352 */
1353 luaL_where(L, 1);
1354 lua_pushfstring(L, "'new': %s.", err);
1355 lua_concat(L, 2);
1356 free(err);
1357 WILL_LJMP(lua_error(L));
1358 }
1359
1360 /* create the lua object. */
1361 lua_newtable(L);
1362 lua_pushlightuserdata(L, args[0].data.map);
1363 lua_rawseti(L, -2, 0);
1364
1365 /* Pop a class Map metatable and affect it to the userdata. */
1366 lua_rawgeti(L, LUA_REGISTRYINDEX, class_map_ref);
1367 lua_setmetatable(L, -2);
1368
1369
1370 return 1;
1371}
1372
1373__LJMP static inline int _hlua_map_lookup(struct lua_State *L, int str)
1374{
1375 struct map_descriptor *desc;
1376 struct pattern *pat;
1377 struct sample smp;
1378
1379 MAY_LJMP(check_args(L, 2, "lookup"));
1380 desc = MAY_LJMP(hlua_checkmap(L, 1));
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02001381 if (desc->pat.expect_type == SMP_T_SINT) {
1382 smp.type = SMP_T_SINT;
1383 smp.data.sint = MAY_LJMP(luaL_checkinteger(L, 2));
Thierry FOURNIER3def3932015-04-07 11:27:54 +02001384 }
1385 else {
1386 smp.type = SMP_T_STR;
1387 smp.flags = SMP_F_CONST;
1388 smp.data.str.str = (char *)MAY_LJMP(luaL_checklstring(L, 2, (size_t *)&smp.data.str.len));
1389 }
1390
1391 pat = pattern_exec_match(&desc->pat, &smp, 1);
1392 if (!pat || !pat->smp) {
1393 if (str)
1394 lua_pushstring(L, "");
1395 else
1396 lua_pushnil(L);
1397 return 1;
1398 }
1399
1400 /* The Lua pattern must return a string, so we can't check the returned type */
1401 lua_pushlstring(L, pat->smp->data.str.str, pat->smp->data.str.len);
1402 return 1;
1403}
1404
1405__LJMP static int hlua_map_lookup(struct lua_State *L)
1406{
1407 return _hlua_map_lookup(L, 0);
1408}
1409
1410__LJMP static int hlua_map_slookup(struct lua_State *L)
1411{
1412 return _hlua_map_lookup(L, 1);
1413}
1414
1415/*
1416 *
1417 *
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001418 * Class Socket
1419 *
1420 *
1421 */
1422
1423__LJMP static struct hlua_socket *hlua_checksocket(lua_State *L, int ud)
1424{
1425 return (struct hlua_socket *)MAY_LJMP(hlua_checkudata(L, ud, class_socket_ref));
1426}
1427
1428/* This function is the handler called for each I/O on the established
1429 * connection. It is used for notify space avalaible to send or data
1430 * received.
1431 */
Willy Tarreau00a37f02015-04-13 12:05:19 +02001432static void hlua_socket_handler(struct appctx *appctx)
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001433{
Willy Tarreau00a37f02015-04-13 12:05:19 +02001434 struct stream_interface *si = appctx->owner;
Willy Tarreau50fe03b2014-11-28 13:59:31 +01001435 struct connection *c = objt_conn(si_opposite(si)->end);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001436
Willy Tarreau87b09662015-04-03 00:22:06 +02001437 /* Wakeup the main stream if the client connection is closed. */
Willy Tarreau2bb4a962014-11-28 11:11:05 +01001438 if (!c || channel_output_closed(si_ic(si)) || channel_input_closed(si_oc(si))) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001439 if (appctx->ctx.hlua.socket) {
1440 appctx->ctx.hlua.socket->s = NULL;
1441 appctx->ctx.hlua.socket = NULL;
1442 }
1443 si_shutw(si);
1444 si_shutr(si);
Willy Tarreau2bb4a962014-11-28 11:11:05 +01001445 si_ic(si)->flags |= CF_READ_NULL;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001446 hlua_com_wake(&appctx->ctx.hlua.wake_on_read);
1447 hlua_com_wake(&appctx->ctx.hlua.wake_on_write);
Willy Tarreaud4da1962015-04-20 01:31:23 +02001448 return;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001449 }
1450
1451 if (!(c->flags & CO_FL_CONNECTED))
Willy Tarreaud4da1962015-04-20 01:31:23 +02001452 return;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001453
1454 /* This function is called after the connect. */
1455 appctx->ctx.hlua.connected = 1;
1456
1457 /* Wake the tasks which wants to write if the buffer have avalaible space. */
Willy Tarreau2bb4a962014-11-28 11:11:05 +01001458 if (channel_may_recv(si_oc(si)))
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001459 hlua_com_wake(&appctx->ctx.hlua.wake_on_write);
1460
1461 /* Wake the tasks which wants to read if the buffer contains data. */
Willy Tarreau2bb4a962014-11-28 11:11:05 +01001462 if (channel_is_empty(si_ic(si)))
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001463 hlua_com_wake(&appctx->ctx.hlua.wake_on_read);
1464}
1465
Willy Tarreau87b09662015-04-03 00:22:06 +02001466/* This function is called when the "struct stream" is destroyed.
1467 * Remove the link from the object to this stream.
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001468 * Wake all the pending signals.
1469 */
Willy Tarreau00a37f02015-04-13 12:05:19 +02001470static void hlua_socket_release(struct appctx *appctx)
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001471{
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001472 /* Remove my link in the original object. */
1473 if (appctx->ctx.hlua.socket)
1474 appctx->ctx.hlua.socket->s = NULL;
1475
1476 /* Wake all the task waiting for me. */
1477 hlua_com_wake(&appctx->ctx.hlua.wake_on_read);
1478 hlua_com_wake(&appctx->ctx.hlua.wake_on_write);
1479}
1480
1481/* If the garbage collectio of the object is launch, nobody
Willy Tarreau87b09662015-04-03 00:22:06 +02001482 * uses this object. If the stream does not exists, just quit.
1483 * Send the shutdown signal to the stream. In some cases,
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001484 * pending signal can rest in the read and write lists. destroy
1485 * it.
1486 */
1487__LJMP static int hlua_socket_gc(lua_State *L)
1488{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001489 struct hlua_socket *socket;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001490 struct appctx *appctx;
1491
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001492 MAY_LJMP(check_args(L, 1, "__gc"));
1493
1494 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001495 if (!socket->s)
1496 return 0;
1497
Willy Tarreau87b09662015-04-03 00:22:06 +02001498 /* Remove all reference between the Lua stack and the coroutine stream. */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001499 appctx = objt_appctx(socket->s->si[0].end);
Willy Tarreaue7dff022015-04-03 01:14:29 +02001500 stream_shutdown(socket->s, SF_ERR_KILLED);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001501 socket->s = NULL;
1502 appctx->ctx.hlua.socket = NULL;
1503
1504 return 0;
1505}
1506
1507/* The close function send shutdown signal and break the
Willy Tarreau87b09662015-04-03 00:22:06 +02001508 * links between the stream and the object.
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001509 */
1510__LJMP static int hlua_socket_close(lua_State *L)
1511{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001512 struct hlua_socket *socket;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001513 struct appctx *appctx;
1514
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001515 MAY_LJMP(check_args(L, 1, "close"));
1516
1517 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001518 if (!socket->s)
1519 return 0;
1520
Willy Tarreau87b09662015-04-03 00:22:06 +02001521 /* Close the stream and remove the associated stop task. */
Willy Tarreaue7dff022015-04-03 01:14:29 +02001522 stream_shutdown(socket->s, SF_ERR_KILLED);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001523 appctx = objt_appctx(socket->s->si[0].end);
1524 appctx->ctx.hlua.socket = NULL;
1525 socket->s = NULL;
1526
1527 return 0;
1528}
1529
1530/* This Lua function assumes that the stack contain three parameters.
1531 * 1 - USERDATA containing a struct socket
1532 * 2 - INTEGER with values of the macro defined below
1533 * If the integer is -1, we must read at most one line.
1534 * If the integer is -2, we ust read all the data until the
1535 * end of the stream.
1536 * If the integer is positive value, we must read a number of
1537 * bytes corresponding to this value.
1538 */
1539#define HLSR_READ_LINE (-1)
1540#define HLSR_READ_ALL (-2)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001541__LJMP static int hlua_socket_receive_yield(struct lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001542{
1543 struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1));
1544 int wanted = lua_tointeger(L, 2);
1545 struct hlua *hlua = hlua_gethlua(L);
1546 struct appctx *appctx;
1547 int len;
1548 int nblk;
1549 char *blk1;
1550 int len1;
1551 char *blk2;
1552 int len2;
Thierry FOURNIER00543922015-03-09 18:35:06 +01001553 int skip_at_end = 0;
Willy Tarreau81389672015-03-10 12:03:52 +01001554 struct channel *oc;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001555
1556 /* Check if this lua stack is schedulable. */
1557 if (!hlua || !hlua->task)
1558 WILL_LJMP(luaL_error(L, "The 'receive' function is only allowed in "
1559 "'frontend', 'backend' or 'task'"));
1560
1561 /* check for connection closed. If some data where read, return it. */
1562 if (!socket->s)
1563 goto connection_closed;
1564
Willy Tarreau94aa6172015-03-13 14:19:06 +01001565 oc = &socket->s->res;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001566 if (wanted == HLSR_READ_LINE) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001567 /* Read line. */
Willy Tarreau81389672015-03-10 12:03:52 +01001568 nblk = bo_getline_nc(oc, &blk1, &len1, &blk2, &len2);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001569 if (nblk < 0) /* Connection close. */
1570 goto connection_closed;
1571 if (nblk == 0) /* No data avalaible. */
1572 goto connection_empty;
Thierry FOURNIER00543922015-03-09 18:35:06 +01001573
1574 /* remove final \r\n. */
1575 if (nblk == 1) {
1576 if (blk1[len1-1] == '\n') {
1577 len1--;
1578 skip_at_end++;
1579 if (blk1[len1-1] == '\r') {
1580 len1--;
1581 skip_at_end++;
1582 }
1583 }
1584 }
1585 else {
1586 if (blk2[len2-1] == '\n') {
1587 len2--;
1588 skip_at_end++;
1589 if (blk2[len2-1] == '\r') {
1590 len2--;
1591 skip_at_end++;
1592 }
1593 }
1594 }
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001595 }
1596
1597 else if (wanted == HLSR_READ_ALL) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001598 /* Read all the available data. */
Willy Tarreau81389672015-03-10 12:03:52 +01001599 nblk = bo_getblk_nc(oc, &blk1, &len1, &blk2, &len2);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001600 if (nblk < 0) /* Connection close. */
1601 goto connection_closed;
1602 if (nblk == 0) /* No data avalaible. */
1603 goto connection_empty;
1604 }
1605
1606 else {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001607 /* Read a block of data. */
Willy Tarreau81389672015-03-10 12:03:52 +01001608 nblk = bo_getblk_nc(oc, &blk1, &len1, &blk2, &len2);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001609 if (nblk < 0) /* Connection close. */
1610 goto connection_closed;
1611 if (nblk == 0) /* No data avalaible. */
1612 goto connection_empty;
1613
1614 if (len1 > wanted) {
1615 nblk = 1;
1616 len1 = wanted;
1617 } if (nblk == 2 && len1 + len2 > wanted)
1618 len2 = wanted - len1;
1619 }
1620
1621 len = len1;
1622
1623 luaL_addlstring(&socket->b, blk1, len1);
1624 if (nblk == 2) {
1625 len += len2;
1626 luaL_addlstring(&socket->b, blk2, len2);
1627 }
1628
1629 /* Consume data. */
Willy Tarreau81389672015-03-10 12:03:52 +01001630 bo_skip(oc, len + skip_at_end);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001631
1632 /* Don't wait anything. */
Willy Tarreau828824a2015-04-19 17:20:03 +02001633 si_applet_done(&socket->s->si[0]);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001634
1635 /* If the pattern reclaim to read all the data
1636 * in the connection, got out.
1637 */
1638 if (wanted == HLSR_READ_ALL)
1639 goto connection_empty;
1640 else if (wanted >= 0 && len < wanted)
1641 goto connection_empty;
1642
1643 /* Return result. */
1644 luaL_pushresult(&socket->b);
1645 return 1;
1646
1647connection_closed:
1648
1649 /* If the buffer containds data. */
1650 if (socket->b.n > 0) {
1651 luaL_pushresult(&socket->b);
1652 return 1;
1653 }
1654 lua_pushnil(L);
1655 lua_pushstring(L, "connection closed.");
1656 return 2;
1657
1658connection_empty:
1659
1660 appctx = objt_appctx(socket->s->si[0].end);
1661 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_read))
1662 WILL_LJMP(luaL_error(L, "out of memory"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01001663 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_receive_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001664 return 0;
1665}
1666
1667/* This Lus function gets two parameters. The first one can be string
1668 * or a number. If the string is "*l", the user require one line. If
1669 * the string is "*a", the user require all the content of the stream.
1670 * If the value is a number, the user require a number of bytes equal
1671 * to the value. The default value is "*l" (a line).
1672 *
1673 * This paraeter with a variable type is converted in integer. This
1674 * integer takes this values:
1675 * -1 : read a line
1676 * -2 : read all the stream
1677 * >0 : amount if bytes.
1678 *
1679 * The second parameter is optinal. It contains a string that must be
1680 * concatenated with the read data.
1681 */
1682__LJMP static int hlua_socket_receive(struct lua_State *L)
1683{
1684 int wanted = HLSR_READ_LINE;
1685 const char *pattern;
1686 int type;
1687 char *error;
1688 size_t len;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001689 struct hlua_socket *socket;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001690
1691 if (lua_gettop(L) < 1 || lua_gettop(L) > 3)
1692 WILL_LJMP(luaL_error(L, "The 'receive' function requires between 1 and 3 arguments."));
1693
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001694 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001695
1696 /* check for pattern. */
1697 if (lua_gettop(L) >= 2) {
1698 type = lua_type(L, 2);
1699 if (type == LUA_TSTRING) {
1700 pattern = lua_tostring(L, 2);
1701 if (strcmp(pattern, "*a") == 0)
1702 wanted = HLSR_READ_ALL;
1703 else if (strcmp(pattern, "*l") == 0)
1704 wanted = HLSR_READ_LINE;
1705 else {
1706 wanted = strtoll(pattern, &error, 10);
1707 if (*error != '\0')
1708 WILL_LJMP(luaL_error(L, "Unsupported pattern."));
1709 }
1710 }
1711 else if (type == LUA_TNUMBER) {
1712 wanted = lua_tointeger(L, 2);
1713 if (wanted < 0)
1714 WILL_LJMP(luaL_error(L, "Unsupported size."));
1715 }
1716 }
1717
1718 /* Set pattern. */
1719 lua_pushinteger(L, wanted);
1720 lua_replace(L, 2);
1721
1722 /* init bufffer, and fiil it wih prefix. */
1723 luaL_buffinit(L, &socket->b);
1724
1725 /* Check prefix. */
1726 if (lua_gettop(L) >= 3) {
1727 if (lua_type(L, 3) != LUA_TSTRING)
1728 WILL_LJMP(luaL_error(L, "Expect a 'string' for the prefix"));
1729 pattern = lua_tolstring(L, 3, &len);
1730 luaL_addlstring(&socket->b, pattern, len);
1731 }
1732
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001733 return __LJMP(hlua_socket_receive_yield(L, 0, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001734}
1735
1736/* Write the Lua input string in the output buffer.
1737 * This fucntion returns a yield if no space are available.
1738 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001739static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext ctx)
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001740{
1741 struct hlua_socket *socket;
1742 struct hlua *hlua = hlua_gethlua(L);
1743 struct appctx *appctx;
1744 size_t buf_len;
1745 const char *buf;
1746 int len;
1747 int send_len;
1748 int sent;
1749
1750 /* Check if this lua stack is schedulable. */
1751 if (!hlua || !hlua->task)
1752 WILL_LJMP(luaL_error(L, "The 'write' function is only allowed in "
1753 "'frontend', 'backend' or 'task'"));
1754
1755 /* Get object */
1756 socket = MAY_LJMP(hlua_checksocket(L, 1));
1757 buf = MAY_LJMP(luaL_checklstring(L, 2, &buf_len));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001758 sent = MAY_LJMP(luaL_checkinteger(L, 3));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001759
1760 /* Check for connection close. */
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01001761 if (!socket->s || channel_output_closed(&socket->s->req)) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001762 lua_pushinteger(L, -1);
1763 return 1;
1764 }
1765
1766 /* Update the input buffer data. */
1767 buf += sent;
1768 send_len = buf_len - sent;
1769
1770 /* All the data are sent. */
1771 if (sent >= buf_len)
1772 return 1; /* Implicitly return the length sent. */
1773
Thierry FOURNIER486d52a2015-03-09 17:51:43 +01001774 /* Check if the buffer is avalaible because HAProxy doesn't allocate
1775 * the request buffer if its not required.
1776 */
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01001777 if (socket->s->req.buf->size == 0) {
Willy Tarreau87b09662015-04-03 00:22:06 +02001778 if (!stream_alloc_recv_buffer(&socket->s->req)) {
Willy Tarreau350f4872014-11-28 14:42:25 +01001779 socket->s->si[0].flags |= SI_FL_WAIT_ROOM;
Thierry FOURNIER486d52a2015-03-09 17:51:43 +01001780 goto hlua_socket_write_yield_return;
1781 }
1782 }
1783
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001784 /* Check for avalaible space. */
Willy Tarreau94aa6172015-03-13 14:19:06 +01001785 len = buffer_total_space(socket->s->req.buf);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001786 if (len <= 0)
1787 goto hlua_socket_write_yield_return;
1788
1789 /* send data */
1790 if (len < send_len)
1791 send_len = len;
Willy Tarreau94aa6172015-03-13 14:19:06 +01001792 len = bi_putblk(&socket->s->req, buf+sent, send_len);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001793
1794 /* "Not enough space" (-1), "Buffer too little to contain
1795 * the data" (-2) are not expected because the available length
1796 * is tested.
1797 * Other unknown error are also not expected.
1798 */
1799 if (len <= 0) {
Willy Tarreaubc18da12015-03-13 14:00:47 +01001800 if (len == -1)
Willy Tarreau94aa6172015-03-13 14:19:06 +01001801 socket->s->req.flags |= CF_WAKE_WRITE;
Willy Tarreaubc18da12015-03-13 14:00:47 +01001802
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001803 MAY_LJMP(hlua_socket_close(L));
1804 lua_pop(L, 1);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001805 lua_pushinteger(L, -1);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001806 return 1;
1807 }
1808
1809 /* update buffers. */
Willy Tarreau828824a2015-04-19 17:20:03 +02001810 si_applet_done(&socket->s->si[0]);
Willy Tarreau94aa6172015-03-13 14:19:06 +01001811 socket->s->req.rex = TICK_ETERNITY;
1812 socket->s->res.wex = TICK_ETERNITY;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001813
1814 /* Update length sent. */
1815 lua_pop(L, 1);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001816 lua_pushinteger(L, sent + len);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001817
1818 /* All the data buffer is sent ? */
1819 if (sent + len >= buf_len)
1820 return 1;
1821
1822hlua_socket_write_yield_return:
1823 appctx = objt_appctx(socket->s->si[0].end);
1824 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_write))
1825 WILL_LJMP(luaL_error(L, "out of memory"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01001826 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_write_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001827 return 0;
1828}
1829
1830/* This function initiate the send of data. It just check the input
1831 * parameters and push an integer in the Lua stack that contain the
1832 * amount of data writed in the buffer. This is used by the function
1833 * "hlua_socket_write_yield" that can yield.
1834 *
1835 * The Lua function gets between 3 and 4 parameters. The first one is
1836 * the associated object. The second is a string buffer. The third is
1837 * a facultative integer that represents where is the buffer position
1838 * of the start of the data that can send. The first byte is the
1839 * position "1". The default value is "1". The fourth argument is a
1840 * facultative integer that represents where is the buffer position
1841 * of the end of the data that can send. The default is the last byte.
1842 */
1843static int hlua_socket_send(struct lua_State *L)
1844{
1845 int i;
1846 int j;
1847 const char *buf;
1848 size_t buf_len;
1849
1850 /* Check number of arguments. */
1851 if (lua_gettop(L) < 2 || lua_gettop(L) > 4)
1852 WILL_LJMP(luaL_error(L, "'send' needs between 2 and 4 arguments"));
1853
1854 /* Get the string. */
1855 buf = MAY_LJMP(luaL_checklstring(L, 2, &buf_len));
1856
1857 /* Get and check j. */
1858 if (lua_gettop(L) == 4) {
1859 j = MAY_LJMP(luaL_checkinteger(L, 4));
1860 if (j < 0)
1861 j = buf_len + j + 1;
1862 if (j > buf_len)
1863 j = buf_len + 1;
1864 lua_pop(L, 1);
1865 }
1866 else
1867 j = buf_len;
1868
1869 /* Get and check i. */
1870 if (lua_gettop(L) == 3) {
1871 i = MAY_LJMP(luaL_checkinteger(L, 3));
1872 if (i < 0)
1873 i = buf_len + i + 1;
1874 if (i > buf_len)
1875 i = buf_len + 1;
1876 lua_pop(L, 1);
1877 } else
1878 i = 1;
1879
1880 /* Check bth i and j. */
1881 if (i > j) {
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001882 lua_pushinteger(L, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001883 return 1;
1884 }
1885 if (i == 0 && j == 0) {
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001886 lua_pushinteger(L, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001887 return 1;
1888 }
1889 if (i == 0)
1890 i = 1;
1891 if (j == 0)
1892 j = 1;
1893
1894 /* Pop the string. */
1895 lua_pop(L, 1);
1896
1897 /* Update the buffer length. */
1898 buf += i - 1;
1899 buf_len = j - i + 1;
1900 lua_pushlstring(L, buf, buf_len);
1901
1902 /* This unsigned is used to remember the amount of sent data. */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001903 lua_pushinteger(L, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001904
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01001905 return MAY_LJMP(hlua_socket_write_yield(L, 0, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001906}
1907
Willy Tarreau22b0a682015-06-17 19:43:49 +02001908#define SOCKET_INFO_MAX_LEN sizeof("[0000:0000:0000:0000:0000:0000:0000:0000]:12345")
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001909__LJMP static inline int hlua_socket_info(struct lua_State *L, struct sockaddr_storage *addr)
1910{
1911 static char buffer[SOCKET_INFO_MAX_LEN];
1912 int ret;
1913 int len;
1914 char *p;
1915
1916 ret = addr_to_str(addr, buffer+1, SOCKET_INFO_MAX_LEN-1);
1917 if (ret <= 0) {
1918 lua_pushnil(L);
1919 return 1;
1920 }
1921
1922 if (ret == AF_UNIX) {
1923 lua_pushstring(L, buffer+1);
1924 return 1;
1925 }
1926 else if (ret == AF_INET6) {
1927 buffer[0] = '[';
1928 len = strlen(buffer);
1929 buffer[len] = ']';
1930 len++;
1931 buffer[len] = ':';
1932 len++;
1933 p = buffer;
1934 }
1935 else if (ret == AF_INET) {
1936 p = buffer + 1;
1937 len = strlen(p);
1938 p[len] = ':';
1939 len++;
1940 }
1941 else {
1942 lua_pushnil(L);
1943 return 1;
1944 }
1945
1946 if (port_to_str(addr, p + len, SOCKET_INFO_MAX_LEN-1 - len) <= 0) {
1947 lua_pushnil(L);
1948 return 1;
1949 }
1950
1951 lua_pushstring(L, p);
1952 return 1;
1953}
1954
1955/* Returns information about the peer of the connection. */
1956__LJMP static int hlua_socket_getpeername(struct lua_State *L)
1957{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001958 struct hlua_socket *socket;
1959 struct connection *conn;
1960
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001961 MAY_LJMP(check_args(L, 1, "getpeername"));
1962
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001963 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001964
1965 /* Check if the tcp object is avalaible. */
1966 if (!socket->s) {
1967 lua_pushnil(L);
1968 return 1;
1969 }
1970
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001971 conn = objt_conn(socket->s->si[1].end);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001972 if (!conn) {
1973 lua_pushnil(L);
1974 return 1;
1975 }
1976
1977 if (!(conn->flags & CO_FL_ADDR_TO_SET)) {
1978 unsigned int salen = sizeof(conn->addr.to);
1979 if (getpeername(conn->t.sock.fd, (struct sockaddr *)&conn->addr.to, &salen) == -1) {
1980 lua_pushnil(L);
1981 return 1;
1982 }
1983 conn->flags |= CO_FL_ADDR_TO_SET;
1984 }
1985
1986 return MAY_LJMP(hlua_socket_info(L, &conn->addr.to));
1987}
1988
1989/* Returns information about my connection side. */
1990static int hlua_socket_getsockname(struct lua_State *L)
1991{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001992 struct hlua_socket *socket;
1993 struct connection *conn;
1994
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001995 MAY_LJMP(check_args(L, 1, "getsockname"));
1996
Willy Tarreau80f5fae2015-02-27 16:38:20 +01001997 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01001998
1999 /* Check if the tcp object is avalaible. */
2000 if (!socket->s) {
2001 lua_pushnil(L);
2002 return 1;
2003 }
2004
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002005 conn = objt_conn(socket->s->si[1].end);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002006 if (!conn) {
2007 lua_pushnil(L);
2008 return 1;
2009 }
2010
2011 if (!(conn->flags & CO_FL_ADDR_FROM_SET)) {
2012 unsigned int salen = sizeof(conn->addr.from);
2013 if (getsockname(conn->t.sock.fd, (struct sockaddr *)&conn->addr.from, &salen) == -1) {
2014 lua_pushnil(L);
2015 return 1;
2016 }
2017 conn->flags |= CO_FL_ADDR_FROM_SET;
2018 }
2019
2020 return hlua_socket_info(L, &conn->addr.from);
2021}
2022
2023/* This struct define the applet. */
Willy Tarreau30576452015-04-13 13:50:30 +02002024static struct applet update_applet = {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002025 .obj_type = OBJ_TYPE_APPLET,
2026 .name = "<LUA_TCP>",
2027 .fct = hlua_socket_handler,
2028 .release = hlua_socket_release,
2029};
2030
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002031__LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002032{
2033 struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1));
2034 struct hlua *hlua = hlua_gethlua(L);
2035 struct appctx *appctx;
2036
2037 /* Check for connection close. */
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002038 if (!hlua || !socket->s || channel_output_closed(&socket->s->req)) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002039 lua_pushnil(L);
2040 lua_pushstring(L, "Can't connect");
2041 return 2;
2042 }
2043
2044 appctx = objt_appctx(socket->s->si[0].end);
2045
2046 /* Check for connection established. */
2047 if (appctx->ctx.hlua.connected) {
2048 lua_pushinteger(L, 1);
2049 return 1;
2050 }
2051
2052 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_write))
2053 WILL_LJMP(luaL_error(L, "out of memory error"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01002054 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002055 return 0;
2056}
2057
2058/* This function fail or initite the connection. */
2059__LJMP static int hlua_socket_connect(struct lua_State *L)
2060{
2061 struct hlua_socket *socket;
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002062 int port;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002063 const char *ip;
2064 struct connection *conn;
Thierry FOURNIER95ad96a2015-03-09 18:12:40 +01002065 struct hlua *hlua;
2066 struct appctx *appctx;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002067
2068 MAY_LJMP(check_args(L, 3, "connect"));
2069
2070 /* Get args. */
2071 socket = MAY_LJMP(hlua_checksocket(L, 1));
2072 ip = MAY_LJMP(luaL_checkstring(L, 2));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002073 port = MAY_LJMP(luaL_checkinteger(L, 3));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002074
Willy Tarreau350f4872014-11-28 14:42:25 +01002075 conn = si_alloc_conn(&socket->s->si[1], 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002076 if (!conn)
2077 WILL_LJMP(luaL_error(L, "connect: internal error"));
2078
2079 /* Parse ip address. */
2080 conn->addr.to.ss_family = AF_UNSPEC;
2081 if (!str2ip2(ip, &conn->addr.to, 0))
2082 WILL_LJMP(luaL_error(L, "connect: cannot parse ip address '%s'", ip));
2083
2084 /* Set port. */
2085 if (conn->addr.to.ss_family == AF_INET)
2086 ((struct sockaddr_in *)&conn->addr.to)->sin_port = htons(port);
2087 else if (conn->addr.to.ss_family == AF_INET6)
2088 ((struct sockaddr_in6 *)&conn->addr.to)->sin6_port = htons(port);
2089
2090 /* it is important not to call the wakeup function directly but to
2091 * pass through task_wakeup(), because this one knows how to apply
2092 * priorities to tasks.
2093 */
2094 task_wakeup(socket->s->task, TASK_WOKEN_INIT);
2095
Thierry FOURNIER95ad96a2015-03-09 18:12:40 +01002096 hlua = hlua_gethlua(L);
2097 appctx = objt_appctx(socket->s->si[0].end);
2098 if (!hlua_com_new(hlua, &appctx->ctx.hlua.wake_on_write))
2099 WILL_LJMP(luaL_error(L, "out of memory"));
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01002100 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0));
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002101
2102 return 0;
2103}
2104
Baptiste Assmann84bb4932015-03-02 21:40:06 +01002105#ifdef USE_OPENSSL
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002106__LJMP static int hlua_socket_connect_ssl(struct lua_State *L)
2107{
2108 struct hlua_socket *socket;
2109
2110 MAY_LJMP(check_args(L, 3, "connect_ssl"));
2111 socket = MAY_LJMP(hlua_checksocket(L, 1));
2112 socket->s->target = &socket_ssl.obj_type;
2113 return MAY_LJMP(hlua_socket_connect(L));
2114}
Baptiste Assmann84bb4932015-03-02 21:40:06 +01002115#endif
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002116
2117__LJMP static int hlua_socket_setoption(struct lua_State *L)
2118{
2119 return 0;
2120}
2121
2122__LJMP static int hlua_socket_settimeout(struct lua_State *L)
2123{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002124 struct hlua_socket *socket;
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002125 int tmout;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002126
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002127 MAY_LJMP(check_args(L, 2, "settimeout"));
2128
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002129 socket = MAY_LJMP(hlua_checksocket(L, 1));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002130 tmout = MAY_LJMP(luaL_checkinteger(L, 2)) * 1000;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002131
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01002132 socket->s->req.rto = tmout;
2133 socket->s->req.wto = tmout;
2134 socket->s->res.rto = tmout;
2135 socket->s->res.wto = tmout;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002136
2137 return 0;
2138}
2139
2140__LJMP static int hlua_socket_new(lua_State *L)
2141{
2142 struct hlua_socket *socket;
2143 struct appctx *appctx;
Willy Tarreau15b5e142015-04-04 14:38:25 +02002144 struct session *sess;
Willy Tarreau61cf7c82015-04-06 00:48:33 +02002145 struct stream *strm;
Willy Tarreaud420a972015-04-06 00:39:18 +02002146 struct task *task;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002147
2148 /* Check stack size. */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002149 if (!lua_checkstack(L, 3)) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002150 hlua_pusherror(L, "socket: full stack");
2151 goto out_fail_conf;
2152 }
2153
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002154 /* Create the object: obj[0] = userdata. */
2155 lua_newtable(L);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002156 socket = MAY_LJMP(lua_newuserdata(L, sizeof(*socket)));
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002157 lua_rawseti(L, -2, 0);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002158 memset(socket, 0, sizeof(*socket));
2159
Thierry FOURNIER4a6170c2015-03-09 17:07:10 +01002160 /* Check if the various memory pools are intialized. */
Willy Tarreau87b09662015-04-03 00:22:06 +02002161 if (!pool2_stream || !pool2_buffer) {
Thierry FOURNIER4a6170c2015-03-09 17:07:10 +01002162 hlua_pusherror(L, "socket: uninitialized pools.");
2163 goto out_fail_conf;
2164 }
2165
Willy Tarreau87b09662015-04-03 00:22:06 +02002166 /* Pop a class stream metatable and affect it to the userdata. */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002167 lua_rawgeti(L, LUA_REGISTRYINDEX, class_socket_ref);
2168 lua_setmetatable(L, -2);
2169
Willy Tarreaud420a972015-04-06 00:39:18 +02002170 /* Create the applet context */
2171 appctx = appctx_new(&update_applet);
Willy Tarreau61cf7c82015-04-06 00:48:33 +02002172 if (!appctx) {
2173 hlua_pusherror(L, "socket: out of memory");
Willy Tarreaufeb76402015-04-03 14:10:06 +02002174 goto out_fail_conf;
Willy Tarreau61cf7c82015-04-06 00:48:33 +02002175 }
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002176
Willy Tarreaud420a972015-04-06 00:39:18 +02002177 appctx->ctx.hlua.socket = socket;
2178 appctx->ctx.hlua.connected = 0;
2179 LIST_INIT(&appctx->ctx.hlua.wake_on_write);
2180 LIST_INIT(&appctx->ctx.hlua.wake_on_read);
Willy Tarreaub2bf8332015-04-04 15:58:58 +02002181
Willy Tarreaud420a972015-04-06 00:39:18 +02002182 /* Now create a session, task and stream for this applet */
2183 sess = session_new(&socket_proxy, NULL, &appctx->obj_type);
2184 if (!sess) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002185 hlua_pusherror(L, "socket: out of memory");
Willy Tarreaud420a972015-04-06 00:39:18 +02002186 goto out_fail_sess;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002187 }
2188
Willy Tarreau61cf7c82015-04-06 00:48:33 +02002189 task = task_new();
2190 if (!task) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002191 hlua_pusherror(L, "socket: out of memory");
Willy Tarreaufeb76402015-04-03 14:10:06 +02002192 goto out_fail_task;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002193 }
Willy Tarreaud420a972015-04-06 00:39:18 +02002194 task->nice = 0;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002195
Willy Tarreau73b65ac2015-04-08 18:26:29 +02002196 strm = stream_new(sess, task, &appctx->obj_type);
Willy Tarreau61cf7c82015-04-06 00:48:33 +02002197 if (!strm) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002198 hlua_pusherror(L, "socket: out of memory");
Willy Tarreaud420a972015-04-06 00:39:18 +02002199 goto out_fail_stream;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002200 }
2201
Willy Tarreaud420a972015-04-06 00:39:18 +02002202 /* Configure an empty Lua for the stream. */
Willy Tarreau61cf7c82015-04-06 00:48:33 +02002203 socket->s = strm;
2204 strm->hlua.T = NULL;
2205 strm->hlua.Tref = LUA_REFNIL;
2206 strm->hlua.Mref = LUA_REFNIL;
2207 strm->hlua.nargs = 0;
2208 strm->hlua.flags = 0;
2209 LIST_INIT(&strm->hlua.com);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002210
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002211 /* Configure "right" stream interface. this "si" is used to connect
2212 * and retrieve data from the server. The connection is initialized
2213 * with the "struct server".
2214 */
Willy Tarreau61cf7c82015-04-06 00:48:33 +02002215 si_set_state(&strm->si[1], SI_ST_ASS);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002216
2217 /* Force destination server. */
Willy Tarreau61cf7c82015-04-06 00:48:33 +02002218 strm->flags |= SF_DIRECT | SF_ASSIGNED | SF_ADDR_SET | SF_BE_ASSIGNED;
2219 strm->target = &socket_tcp.obj_type;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002220
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002221 /* Update statistics counters. */
2222 socket_proxy.feconn++; /* beconn will be increased later */
2223 jobs++;
2224 totalconn++;
2225
2226 /* Return yield waiting for connection. */
2227 return 1;
2228
Willy Tarreaud420a972015-04-06 00:39:18 +02002229 out_fail_stream:
2230 task_free(task);
2231 out_fail_task:
Willy Tarreau11c36242015-04-04 15:54:03 +02002232 session_free(sess);
Willy Tarreaud420a972015-04-06 00:39:18 +02002233 out_fail_sess:
2234 appctx_free(appctx);
2235 out_fail_conf:
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01002236 WILL_LJMP(lua_error(L));
2237 return 0;
2238}
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01002239
2240/*
2241 *
2242 *
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002243 * Class Channel
2244 *
2245 *
2246 */
2247
2248/* Returns the struct hlua_channel join to the class channel in the
2249 * stack entry "ud" or throws an argument error.
2250 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002251__LJMP static struct channel *hlua_checkchannel(lua_State *L, int ud)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002252{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002253 return (struct channel *)MAY_LJMP(hlua_checkudata(L, ud, class_channel_ref));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002254}
2255
Willy Tarreau47860ed2015-03-10 14:07:50 +01002256/* Pushes the channel onto the top of the stack. If the stask does not have a
2257 * free slots, the function fails and returns 0;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002258 */
Willy Tarreau2a71af42015-03-10 13:51:50 +01002259static int hlua_channel_new(lua_State *L, struct channel *channel)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002260{
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002261 /* Check stack size. */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002262 if (!lua_checkstack(L, 3))
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002263 return 0;
2264
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002265 lua_newtable(L);
Willy Tarreau47860ed2015-03-10 14:07:50 +01002266 lua_pushlightuserdata(L, channel);
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01002267 lua_rawseti(L, -2, 0);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002268
2269 /* Pop a class sesison metatable and affect it to the userdata. */
2270 lua_rawgeti(L, LUA_REGISTRYINDEX, class_channel_ref);
2271 lua_setmetatable(L, -2);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002272 return 1;
2273}
2274
2275/* Duplicate all the data present in the input channel and put it
2276 * in a string LUA variables. Returns -1 and push a nil value in
2277 * the stack if the channel is closed and all the data are consumed,
2278 * returns 0 if no data are available, otherwise it returns the length
2279 * of the builded string.
2280 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002281static inline int _hlua_channel_dup(struct channel *chn, lua_State *L)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002282{
2283 char *blk1;
2284 char *blk2;
2285 int len1;
2286 int len2;
2287 int ret;
2288 luaL_Buffer b;
2289
Willy Tarreau47860ed2015-03-10 14:07:50 +01002290 ret = bi_getblk_nc(chn, &blk1, &len1, &blk2, &len2);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002291 if (unlikely(ret == 0))
2292 return 0;
2293
2294 if (unlikely(ret < 0)) {
2295 lua_pushnil(L);
2296 return -1;
2297 }
2298
2299 luaL_buffinit(L, &b);
2300 luaL_addlstring(&b, blk1, len1);
2301 if (unlikely(ret == 2))
2302 luaL_addlstring(&b, blk2, len2);
2303 luaL_pushresult(&b);
2304
2305 if (unlikely(ret == 2))
2306 return len1 + len2;
2307 return len1;
2308}
2309
2310/* "_hlua_channel_dup" wrapper. If no data are available, it returns
2311 * a yield. This function keep the data in the buffer.
2312 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002313__LJMP static int hlua_channel_dup_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002314{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002315 struct channel *chn;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002316
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002317 chn = MAY_LJMP(hlua_checkchannel(L, 1));
2318
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002319 if (_hlua_channel_dup(chn, L) == 0)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002320 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_dup_yield, TICK_ETERNITY, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002321 return 1;
2322}
2323
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002324/* Check arguments for the function "hlua_channel_dup_yield". */
2325__LJMP static int hlua_channel_dup(lua_State *L)
2326{
2327 MAY_LJMP(check_args(L, 1, "dup"));
2328 MAY_LJMP(hlua_checkchannel(L, 1));
2329 return MAY_LJMP(hlua_channel_dup_yield(L, 0, 0));
2330}
2331
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002332/* "_hlua_channel_dup" wrapper. If no data are available, it returns
2333 * a yield. This function consumes the data in the buffer. It returns
2334 * a string containing the data or a nil pointer if no data are available
2335 * and the channel is closed.
2336 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002337__LJMP static int hlua_channel_get_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002338{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002339 struct channel *chn;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002340 int ret;
2341
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002342 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002343
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002344 ret = _hlua_channel_dup(chn, L);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002345 if (unlikely(ret == 0))
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002346 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_get_yield, TICK_ETERNITY, 0));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002347
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002348 if (unlikely(ret == -1))
2349 return 1;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002350
Willy Tarreau47860ed2015-03-10 14:07:50 +01002351 chn->buf->i -= ret;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002352 return 1;
2353}
2354
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002355/* Check arguments for the fucntion "hlua_channel_get_yield". */
2356__LJMP static int hlua_channel_get(lua_State *L)
2357{
2358 MAY_LJMP(check_args(L, 1, "get"));
2359 MAY_LJMP(hlua_checkchannel(L, 1));
2360 return MAY_LJMP(hlua_channel_get_yield(L, 0, 0));
2361}
2362
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002363/* This functions consumes and returns one line. If the channel is closed,
2364 * and the last data does not contains a final '\n', the data are returned
2365 * without the final '\n'. When no more data are avalaible, it returns nil
2366 * value.
2367 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002368__LJMP static int hlua_channel_getline_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002369{
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002370 char *blk1;
2371 char *blk2;
2372 int len1;
2373 int len2;
2374 int len;
Willy Tarreau47860ed2015-03-10 14:07:50 +01002375 struct channel *chn;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002376 int ret;
2377 luaL_Buffer b;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002378
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002379 chn = MAY_LJMP(hlua_checkchannel(L, 1));
2380
Willy Tarreau47860ed2015-03-10 14:07:50 +01002381 ret = bi_getline_nc(chn, &blk1, &len1, &blk2, &len2);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002382 if (ret == 0)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002383 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_getline_yield, TICK_ETERNITY, 0));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002384
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002385 if (ret == -1) {
2386 lua_pushnil(L);
2387 return 1;
2388 }
2389
2390 luaL_buffinit(L, &b);
2391 luaL_addlstring(&b, blk1, len1);
2392 len = len1;
2393 if (unlikely(ret == 2)) {
2394 luaL_addlstring(&b, blk2, len2);
2395 len += len2;
2396 }
2397 luaL_pushresult(&b);
Willy Tarreau47860ed2015-03-10 14:07:50 +01002398 buffer_replace2(chn->buf, chn->buf->p, chn->buf->p + len, NULL, 0);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002399 return 1;
2400}
2401
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002402/* Check arguments for the fucntion "hlua_channel_getline_yield". */
2403__LJMP static int hlua_channel_getline(lua_State *L)
2404{
2405 MAY_LJMP(check_args(L, 1, "getline"));
2406 MAY_LJMP(hlua_checkchannel(L, 1));
2407 return MAY_LJMP(hlua_channel_getline_yield(L, 0, 0));
2408}
2409
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002410/* This function takes a string as input, and append it at the
2411 * input side of channel. If the data is too big, but a space
2412 * is probably available after sending some data, the function
2413 * yield. If the data is bigger than the buffer, or if the
2414 * channel is closed, it returns -1. otherwise, it returns the
2415 * amount of data writed.
2416 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002417__LJMP static int hlua_channel_append_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002418{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002419 struct channel *chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002420 size_t len;
2421 const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
2422 int l = MAY_LJMP(luaL_checkinteger(L, 3));
2423 int ret;
2424 int max;
2425
Willy Tarreau47860ed2015-03-10 14:07:50 +01002426 max = channel_recv_limit(chn) - buffer_len(chn->buf);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002427 if (max > len - l)
2428 max = len - l;
2429
Willy Tarreau47860ed2015-03-10 14:07:50 +01002430 ret = bi_putblk(chn, str + l, max);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002431 if (ret == -2 || ret == -3) {
2432 lua_pushinteger(L, -1);
2433 return 1;
2434 }
Willy Tarreaubc18da12015-03-13 14:00:47 +01002435 if (ret == -1) {
2436 chn->flags |= CF_WAKE_WRITE;
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002437 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
Willy Tarreaubc18da12015-03-13 14:00:47 +01002438 }
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002439 l += ret;
2440 lua_pop(L, 1);
2441 lua_pushinteger(L, l);
2442
Willy Tarreau47860ed2015-03-10 14:07:50 +01002443 max = channel_recv_limit(chn) - buffer_len(chn->buf);
2444 if (max == 0 && chn->buf->o == 0) {
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002445 /* There are no space avalaible, and the output buffer is empty.
2446 * in this case, we cannot add more data, so we cannot yield,
2447 * we return the amount of copyied data.
2448 */
2449 return 1;
2450 }
2451 if (l < len)
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002452 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002453 return 1;
2454}
2455
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002456/* just a wrapper of "hlua_channel_append_yield". It returns the length
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002457 * of the writed string, or -1 if the channel is closed or if the
2458 * buffer size is too little for the data.
2459 */
2460__LJMP static int hlua_channel_append(lua_State *L)
2461{
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002462 size_t len;
2463
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002464 MAY_LJMP(check_args(L, 2, "append"));
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002465 MAY_LJMP(hlua_checkchannel(L, 1));
2466 MAY_LJMP(luaL_checklstring(L, 2, &len));
2467 MAY_LJMP(luaL_checkinteger(L, 3));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002468 lua_pushinteger(L, 0);
2469
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002470 return MAY_LJMP(hlua_channel_append_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002471}
2472
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002473/* just a wrapper of "hlua_channel_append_yield". This wrapper starts
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002474 * his process by cleaning the buffer. The result is a replacement
2475 * of the current data. It returns the length of the writed string,
2476 * or -1 if the channel is closed or if the buffer size is too
2477 * little for the data.
2478 */
2479__LJMP static int hlua_channel_set(lua_State *L)
2480{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002481 struct channel *chn;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002482
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002483 MAY_LJMP(check_args(L, 2, "set"));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002484 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002485 lua_pushinteger(L, 0);
2486
Willy Tarreau47860ed2015-03-10 14:07:50 +01002487 chn->buf->i = 0;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002488
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002489 return MAY_LJMP(hlua_channel_append_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002490}
2491
2492/* Append data in the output side of the buffer. This data is immediatly
2493 * sent. The fcuntion returns the ammount of data writed. If the buffer
2494 * cannot contains the data, the function yield. The function returns -1
2495 * if the channel is closed.
2496 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002497__LJMP static int hlua_channel_send_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002498{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002499 struct channel *chn = MAY_LJMP(hlua_checkchannel(L, 1));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002500 size_t len;
2501 const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
2502 int l = MAY_LJMP(luaL_checkinteger(L, 3));
2503 int max;
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002504 struct hlua *hlua = hlua_gethlua(L);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002505
Willy Tarreau47860ed2015-03-10 14:07:50 +01002506 if (unlikely(channel_output_closed(chn))) {
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002507 lua_pushinteger(L, -1);
2508 return 1;
2509 }
2510
Thierry FOURNIER3e3a6082015-03-05 17:06:12 +01002511 /* Check if the buffer is avalaible because HAProxy doesn't allocate
2512 * the request buffer if its not required.
2513 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002514 if (chn->buf->size == 0) {
Willy Tarreau87b09662015-04-03 00:22:06 +02002515 if (!stream_alloc_recv_buffer(chn)) {
Willy Tarreau47860ed2015-03-10 14:07:50 +01002516 chn_prod(chn)->flags |= SI_FL_WAIT_ROOM;
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002517 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
Thierry FOURNIER3e3a6082015-03-05 17:06:12 +01002518 }
2519 }
2520
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002521 /* the writed data will be immediatly sent, so we can check
2522 * the avalaible space without taking in account the reserve.
2523 * The reserve is guaranted for the processing of incoming
2524 * data, because the buffer will be flushed.
2525 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002526 max = chn->buf->size - buffer_len(chn->buf);
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002527
2528 /* If there are no space avalaible, and the output buffer is empty.
2529 * in this case, we cannot add more data, so we cannot yield,
2530 * we return the amount of copyied data.
2531 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002532 if (max == 0 && chn->buf->o == 0)
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002533 return 1;
2534
2535 /* Adjust the real required length. */
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002536 if (max > len - l)
2537 max = len - l;
2538
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002539 /* The buffer avalaible size may be not contiguous. This test
2540 * detects a non contiguous buffer and realign it.
2541 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002542 if (bi_space_for_replace(chn->buf) < max)
2543 buffer_slow_realign(chn->buf);
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002544
2545 /* Copy input data in the buffer. */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002546 max = buffer_replace2(chn->buf, chn->buf->p, chn->buf->p, str + l, max);
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002547
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002548 /* buffer replace considers that the input part is filled.
2549 * so, I must forward these new data in the output part.
2550 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002551 b_adv(chn->buf, max);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002552
2553 l += max;
2554 lua_pop(L, 1);
2555 lua_pushinteger(L, l);
2556
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002557 /* If there are no space avalaible, and the output buffer is empty.
2558 * in this case, we cannot add more data, so we cannot yield,
2559 * we return the amount of copyied data.
2560 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002561 max = chn->buf->size - buffer_len(chn->buf);
2562 if (max == 0 && chn->buf->o == 0)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002563 return 1;
Thierry FOURNIERdeb5d732015-03-06 01:07:45 +01002564
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002565 if (l < len) {
2566 /* If we are waiting for space in the response buffer, we
2567 * must set the flag WAKERESWR. This flag required the task
2568 * wake up if any activity is detected on the response buffer.
2569 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002570 if (chn->flags & CF_ISRESP)
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002571 HLUA_SET_WAKERESWR(hlua);
Thierry FOURNIER53e08ec2015-03-06 00:35:53 +01002572 else
2573 HLUA_SET_WAKEREQWR(hlua);
2574 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002575 }
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002576
2577 return 1;
2578}
2579
2580/* Just a wraper of "_hlua_channel_send". This wrapper permits
2581 * yield the LUA process, and resume it without checking the
2582 * input arguments.
2583 */
2584__LJMP static int hlua_channel_send(lua_State *L)
2585{
2586 MAY_LJMP(check_args(L, 2, "send"));
2587 lua_pushinteger(L, 0);
2588
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002589 return MAY_LJMP(hlua_channel_send_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002590}
2591
2592/* This function forward and amount of butes. The data pass from
2593 * the input side of the buffer to the output side, and can be
2594 * forwarded. This function never fails.
2595 *
2596 * The Lua function takes an amount of bytes to be forwarded in
2597 * imput. It returns the number of bytes forwarded.
2598 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002599__LJMP static int hlua_channel_forward_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002600{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002601 struct channel *chn;
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002602 int len;
2603 int l;
2604 int max;
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002605 struct hlua *hlua = hlua_gethlua(L);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002606
2607 chn = MAY_LJMP(hlua_checkchannel(L, 1));
2608 len = MAY_LJMP(luaL_checkinteger(L, 2));
2609 l = MAY_LJMP(luaL_checkinteger(L, -1));
2610
2611 max = len - l;
Willy Tarreau47860ed2015-03-10 14:07:50 +01002612 if (max > chn->buf->i)
2613 max = chn->buf->i;
2614 channel_forward(chn, max);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002615 l += max;
2616
2617 lua_pop(L, 1);
2618 lua_pushinteger(L, l);
2619
2620 /* Check if it miss bytes to forward. */
2621 if (l < len) {
2622 /* The the input channel or the output channel are closed, we
2623 * must return the amount of data forwarded.
2624 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002625 if (channel_input_closed(chn) || channel_output_closed(chn))
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002626 return 1;
2627
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002628 /* If we are waiting for space data in the response buffer, we
2629 * must set the flag WAKERESWR. This flag required the task
2630 * wake up if any activity is detected on the response buffer.
2631 */
Willy Tarreau47860ed2015-03-10 14:07:50 +01002632 if (chn->flags & CF_ISRESP)
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002633 HLUA_SET_WAKERESWR(hlua);
Thierry FOURNIER53e08ec2015-03-06 00:35:53 +01002634 else
2635 HLUA_SET_WAKEREQWR(hlua);
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01002636
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002637 /* Otherwise, we can yield waiting for new data in the inpout side. */
Thierry FOURNIER4abd3ae2015-03-03 17:29:06 +01002638 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_forward_yield, TICK_ETERNITY, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002639 }
2640
2641 return 1;
2642}
2643
2644/* Just check the input and prepare the stack for the previous
2645 * function "hlua_channel_forward_yield"
2646 */
2647__LJMP static int hlua_channel_forward(lua_State *L)
2648{
2649 MAY_LJMP(check_args(L, 2, "forward"));
2650 MAY_LJMP(hlua_checkchannel(L, 1));
2651 MAY_LJMP(luaL_checkinteger(L, 2));
2652
2653 lua_pushinteger(L, 0);
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01002654 return MAY_LJMP(hlua_channel_forward_yield(L, 0, 0));
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002655}
2656
2657/* Just returns the number of bytes available in the input
2658 * side of the buffer. This function never fails.
2659 */
2660__LJMP static int hlua_channel_get_in_len(lua_State *L)
2661{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002662 struct channel *chn;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002663
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002664 MAY_LJMP(check_args(L, 1, "get_in_len"));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002665 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Willy Tarreau47860ed2015-03-10 14:07:50 +01002666 lua_pushinteger(L, chn->buf->i);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002667 return 1;
2668}
2669
2670/* Just returns the number of bytes available in the output
2671 * side of the buffer. This function never fails.
2672 */
2673__LJMP static int hlua_channel_get_out_len(lua_State *L)
2674{
Willy Tarreau47860ed2015-03-10 14:07:50 +01002675 struct channel *chn;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002676
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002677 MAY_LJMP(check_args(L, 1, "get_out_len"));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01002678 chn = MAY_LJMP(hlua_checkchannel(L, 1));
Willy Tarreau47860ed2015-03-10 14:07:50 +01002679 lua_pushinteger(L, chn->buf->o);
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002680 return 1;
2681}
2682
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002683/*
2684 *
2685 *
2686 * Class Fetches
2687 *
2688 *
2689 */
2690
2691/* Returns a struct hlua_session if the stack entry "ud" is
Willy Tarreau87b09662015-04-03 00:22:06 +02002692 * a class stream, otherwise it throws an error.
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002693 */
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002694__LJMP static struct hlua_smp *hlua_checkfetches(lua_State *L, int ud)
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002695{
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002696 return (struct hlua_smp *)MAY_LJMP(hlua_checkudata(L, ud, class_fetches_ref));
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002697}
2698
2699/* This function creates and push in the stack a fetch object according
2700 * with a current TXN.
2701 */
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002702static int hlua_fetches_new(lua_State *L, struct hlua_txn *txn, int stringsafe)
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002703{
Willy Tarreau7073c472015-04-06 11:15:40 +02002704 struct hlua_smp *hsmp;
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002705
2706 /* Check stack size. */
2707 if (!lua_checkstack(L, 3))
2708 return 0;
2709
2710 /* Create the object: obj[0] = userdata.
2711 * Note that the base of the Fetches object is the
2712 * transaction object.
2713 */
2714 lua_newtable(L);
Willy Tarreau7073c472015-04-06 11:15:40 +02002715 hsmp = lua_newuserdata(L, sizeof(*hsmp));
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002716 lua_rawseti(L, -2, 0);
2717
Willy Tarreau7073c472015-04-06 11:15:40 +02002718 hsmp->s = txn->s;
2719 hsmp->p = txn->p;
Willy Tarreau7073c472015-04-06 11:15:40 +02002720 hsmp->stringsafe = stringsafe;
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002721
2722 /* Pop a class sesison metatable and affect it to the userdata. */
2723 lua_rawgeti(L, LUA_REGISTRYINDEX, class_fetches_ref);
2724 lua_setmetatable(L, -2);
2725
2726 return 1;
2727}
2728
2729/* This function is an LUA binding. It is called with each sample-fetch.
2730 * It uses closure argument to store the associated sample-fetch. It
2731 * returns only one argument or throws an error. An error is thrown
2732 * only if an error is encountered during the argument parsing. If
2733 * the "sample-fetch" function fails, nil is returned.
2734 */
2735__LJMP static int hlua_run_sample_fetch(lua_State *L)
2736{
Willy Tarreaub2ccb562015-04-06 11:11:15 +02002737 struct hlua_smp *hsmp;
Willy Tarreau2ec22742015-03-10 14:27:20 +01002738 struct sample_fetch *f;
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002739 struct arg args[ARGM_NBARGS + 1];
2740 int i;
2741 struct sample smp;
2742
2743 /* Get closure arguments. */
Willy Tarreau2ec22742015-03-10 14:27:20 +01002744 f = (struct sample_fetch *)lua_touserdata(L, lua_upvalueindex(1));
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002745
2746 /* Get traditionnal arguments. */
Willy Tarreaub2ccb562015-04-06 11:11:15 +02002747 hsmp = MAY_LJMP(hlua_checkfetches(L, 1));
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002748
2749 /* Get extra arguments. */
2750 for (i = 0; i < lua_gettop(L) - 1; i++) {
2751 if (i >= ARGM_NBARGS)
2752 break;
2753 hlua_lua2arg(L, i + 2, &args[i]);
2754 }
2755 args[i].type = ARGT_STOP;
2756
2757 /* Check arguments. */
Willy Tarreaub2ccb562015-04-06 11:11:15 +02002758 MAY_LJMP(hlua_lua2arg_check(L, 2, args, f->arg_mask, hsmp->p));
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002759
2760 /* Run the special args checker. */
Willy Tarreau2ec22742015-03-10 14:27:20 +01002761 if (f->val_args && !f->val_args(args, NULL)) {
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002762 lua_pushfstring(L, "error in arguments");
2763 WILL_LJMP(lua_error(L));
2764 }
2765
2766 /* Initialise the sample. */
2767 memset(&smp, 0, sizeof(smp));
2768
2769 /* Run the sample fetch process. */
Thierry FOURNIER6879ad32015-05-11 11:54:58 +02002770 smp.px = hsmp->p;
2771 smp.sess = hsmp->s->sess;
2772 smp.strm = hsmp->s;
Thierry FOURNIER1d33b882015-05-11 15:25:29 +02002773 smp.opt = 0;
Thierry FOURNIER0786d052015-05-11 15:42:45 +02002774 if (!f->process(args, &smp, f->kw, f->private)) {
Willy Tarreaub2ccb562015-04-06 11:11:15 +02002775 if (hsmp->stringsafe)
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002776 lua_pushstring(L, "");
2777 else
2778 lua_pushnil(L);
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002779 return 1;
2780 }
2781
2782 /* Convert the returned sample in lua value. */
Willy Tarreaub2ccb562015-04-06 11:11:15 +02002783 if (hsmp->stringsafe)
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002784 hlua_smp2lua_str(L, &smp);
2785 else
2786 hlua_smp2lua(L, &smp);
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01002787 return 1;
2788}
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01002789
2790/*
2791 *
2792 *
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002793 * Class Converters
2794 *
2795 *
2796 */
2797
2798/* Returns a struct hlua_session if the stack entry "ud" is
Willy Tarreau87b09662015-04-03 00:22:06 +02002799 * a class stream, otherwise it throws an error.
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002800 */
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002801__LJMP static struct hlua_smp *hlua_checkconverters(lua_State *L, int ud)
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002802{
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002803 return (struct hlua_smp *)MAY_LJMP(hlua_checkudata(L, ud, class_converters_ref));
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002804}
2805
2806/* This function creates and push in the stack a Converters object
2807 * according with a current TXN.
2808 */
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002809static int hlua_converters_new(lua_State *L, struct hlua_txn *txn, int stringsafe)
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002810{
Willy Tarreau7073c472015-04-06 11:15:40 +02002811 struct hlua_smp *hsmp;
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002812
2813 /* Check stack size. */
2814 if (!lua_checkstack(L, 3))
2815 return 0;
2816
2817 /* Create the object: obj[0] = userdata.
2818 * Note that the base of the Converters object is the
2819 * same than the TXN object.
2820 */
2821 lua_newtable(L);
Willy Tarreau7073c472015-04-06 11:15:40 +02002822 hsmp = lua_newuserdata(L, sizeof(*hsmp));
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002823 lua_rawseti(L, -2, 0);
2824
Willy Tarreau7073c472015-04-06 11:15:40 +02002825 hsmp->s = txn->s;
2826 hsmp->p = txn->p;
Willy Tarreau7073c472015-04-06 11:15:40 +02002827 hsmp->stringsafe = stringsafe;
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002828
Willy Tarreau87b09662015-04-03 00:22:06 +02002829 /* Pop a class stream metatable and affect it to the table. */
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002830 lua_rawgeti(L, LUA_REGISTRYINDEX, class_converters_ref);
2831 lua_setmetatable(L, -2);
2832
2833 return 1;
2834}
2835
2836/* This function is an LUA binding. It is called with each converter.
2837 * It uses closure argument to store the associated converter. It
2838 * returns only one argument or throws an error. An error is thrown
2839 * only if an error is encountered during the argument parsing. If
2840 * the converter function function fails, nil is returned.
2841 */
2842__LJMP static int hlua_run_sample_conv(lua_State *L)
2843{
Willy Tarreauda5f1082015-04-06 11:17:13 +02002844 struct hlua_smp *hsmp;
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002845 struct sample_conv *conv;
2846 struct arg args[ARGM_NBARGS + 1];
2847 int i;
2848 struct sample smp;
2849
2850 /* Get closure arguments. */
2851 conv = (struct sample_conv *)lua_touserdata(L, lua_upvalueindex(1));
2852
2853 /* Get traditionnal arguments. */
Willy Tarreauda5f1082015-04-06 11:17:13 +02002854 hsmp = MAY_LJMP(hlua_checkconverters(L, 1));
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002855
2856 /* Get extra arguments. */
2857 for (i = 0; i < lua_gettop(L) - 2; i++) {
2858 if (i >= ARGM_NBARGS)
2859 break;
2860 hlua_lua2arg(L, i + 3, &args[i]);
2861 }
2862 args[i].type = ARGT_STOP;
2863
2864 /* Check arguments. */
Willy Tarreauda5f1082015-04-06 11:17:13 +02002865 MAY_LJMP(hlua_lua2arg_check(L, 3, args, conv->arg_mask, hsmp->p));
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002866
2867 /* Run the special args checker. */
2868 if (conv->val_args && !conv->val_args(args, conv, "", 0, NULL)) {
2869 hlua_pusherror(L, "error in arguments");
2870 WILL_LJMP(lua_error(L));
2871 }
2872
2873 /* Initialise the sample. */
2874 if (!hlua_lua2smp(L, 2, &smp)) {
2875 hlua_pusherror(L, "error in the input argument");
2876 WILL_LJMP(lua_error(L));
2877 }
2878
2879 /* Apply expected cast. */
2880 if (!sample_casts[smp.type][conv->in_type]) {
2881 hlua_pusherror(L, "invalid input argument: cannot cast '%s' to '%s'",
2882 smp_to_type[smp.type], smp_to_type[conv->in_type]);
2883 WILL_LJMP(lua_error(L));
2884 }
2885 if (sample_casts[smp.type][conv->in_type] != c_none &&
2886 !sample_casts[smp.type][conv->in_type](&smp)) {
2887 hlua_pusherror(L, "error during the input argument casting");
2888 WILL_LJMP(lua_error(L));
2889 }
2890
2891 /* Run the sample conversion process. */
Thierry FOURNIER6879ad32015-05-11 11:54:58 +02002892 smp.px = hsmp->p;
2893 smp.sess = hsmp->s->sess;
2894 smp.strm = hsmp->s;
Thierry FOURNIER1d33b882015-05-11 15:25:29 +02002895 smp.opt = 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02002896 if (!conv->process(args, &smp, conv->private)) {
Willy Tarreauda5f1082015-04-06 11:17:13 +02002897 if (hsmp->stringsafe)
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002898 lua_pushstring(L, "");
2899 else
2900 lua_pushnil(L);
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002901 return 1;
2902 }
2903
2904 /* Convert the returned sample in lua value. */
Willy Tarreauda5f1082015-04-06 11:17:13 +02002905 if (hsmp->stringsafe)
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01002906 hlua_smp2lua_str(L, &smp);
2907 else
2908 hlua_smp2lua(L, &smp);
2909 return 1;
Thierry FOURNIER594afe72015-03-10 23:58:30 +01002910}
2911
2912/*
2913 *
2914 *
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002915 * Class HTTP
2916 *
2917 *
2918 */
2919
2920/* Returns a struct hlua_txn if the stack entry "ud" is
Willy Tarreau87b09662015-04-03 00:22:06 +02002921 * a class stream, otherwise it throws an error.
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002922 */
2923__LJMP static struct hlua_txn *hlua_checkhttp(lua_State *L, int ud)
2924{
2925 return (struct hlua_txn *)MAY_LJMP(hlua_checkudata(L, ud, class_http_ref));
2926}
2927
2928/* This function creates and push in the stack a HTTP object
2929 * according with a current TXN.
2930 */
2931static int hlua_http_new(lua_State *L, struct hlua_txn *txn)
2932{
Willy Tarreau9a8ad862015-04-06 11:14:06 +02002933 struct hlua_txn *htxn;
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002934
2935 /* Check stack size. */
2936 if (!lua_checkstack(L, 3))
2937 return 0;
2938
2939 /* Create the object: obj[0] = userdata.
2940 * Note that the base of the Converters object is the
2941 * same than the TXN object.
2942 */
2943 lua_newtable(L);
Willy Tarreau9a8ad862015-04-06 11:14:06 +02002944 htxn = lua_newuserdata(L, sizeof(*htxn));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002945 lua_rawseti(L, -2, 0);
2946
Willy Tarreau9a8ad862015-04-06 11:14:06 +02002947 htxn->s = txn->s;
2948 htxn->p = txn->p;
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002949
Willy Tarreau87b09662015-04-03 00:22:06 +02002950 /* Pop a class stream metatable and affect it to the table. */
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002951 lua_rawgeti(L, LUA_REGISTRYINDEX, class_http_ref);
2952 lua_setmetatable(L, -2);
2953
2954 return 1;
2955}
2956
2957/* This function creates ans returns an array of HTTP headers.
2958 * This function does not fails. It is used as wrapper with the
2959 * 2 following functions.
2960 */
2961__LJMP static int hlua_http_get_headers(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
2962{
2963 const char *cur_ptr, *cur_next, *p;
2964 int old_idx, cur_idx;
2965 struct hdr_idx_elem *cur_hdr;
2966 const char *hn, *hv;
2967 int hnl, hvl;
Thierry FOURNIER04c57b32015-03-18 13:43:10 +01002968 int type;
2969 const char *in;
2970 char *out;
2971 int len;
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002972
2973 /* Create the table. */
2974 lua_newtable(L);
2975
Willy Tarreaueee5b512015-04-03 23:46:31 +02002976 if (!htxn->s->txn)
2977 return 1;
2978
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002979 /* Build array of headers. */
2980 old_idx = 0;
Willy Tarreaueee5b512015-04-03 23:46:31 +02002981 cur_next = msg->chn->buf->p + hdr_idx_first_pos(&htxn->s->txn->hdr_idx);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002982
2983 while (1) {
Willy Tarreaueee5b512015-04-03 23:46:31 +02002984 cur_idx = htxn->s->txn->hdr_idx.v[old_idx].next;
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002985 if (!cur_idx)
2986 break;
2987 old_idx = cur_idx;
2988
Willy Tarreaueee5b512015-04-03 23:46:31 +02002989 cur_hdr = &htxn->s->txn->hdr_idx.v[cur_idx];
Thierry FOURNIER08504f42015-03-16 14:17:08 +01002990 cur_ptr = cur_next;
2991 cur_next = cur_ptr + cur_hdr->len + cur_hdr->cr + 1;
2992
2993 /* Now we have one full header at cur_ptr of len cur_hdr->len,
2994 * and the next header starts at cur_next. We'll check
2995 * this header in the list as well as against the default
2996 * rule.
2997 */
2998
2999 /* look for ': *'. */
3000 hn = cur_ptr;
3001 for (p = cur_ptr; p < cur_ptr + cur_hdr->len && *p != ':'; p++);
3002 if (p >= cur_ptr+cur_hdr->len)
3003 continue;
3004 hnl = p - hn;
3005 p++;
3006 while (p < cur_ptr+cur_hdr->len && ( *p == ' ' || *p == '\t' ))
3007 p++;
3008 if (p >= cur_ptr+cur_hdr->len)
3009 continue;
3010 hv = p;
3011 hvl = cur_ptr+cur_hdr->len-p;
3012
Thierry FOURNIER04c57b32015-03-18 13:43:10 +01003013 /* Lowercase the key. Don't check the size of trash, it have
3014 * the size of one buffer and the input data contains in one
3015 * buffer.
3016 */
3017 out = trash.str;
3018 for (in=hn; in<hn+hnl; in++, out++)
3019 *out = tolower(*in);
3020 *out = '\0';
3021
3022 /* Check for existing entry:
3023 * assume that the table is on the top of the stack, and
3024 * push the key in the stack, the function lua_gettable()
3025 * perform the lookup.
3026 */
3027 lua_pushlstring(L, trash.str, hnl);
3028 lua_gettable(L, -2);
3029 type = lua_type(L, -1);
3030
3031 switch (type) {
3032 case LUA_TNIL:
3033 /* Table not found, create it. */
3034 lua_pop(L, 1); /* remove the nil value. */
3035 lua_pushlstring(L, trash.str, hnl); /* push the header name as key. */
3036 lua_newtable(L); /* create and push empty table. */
3037 lua_pushlstring(L, hv, hvl); /* push header value. */
3038 lua_rawseti(L, -2, 0); /* index header value (pop it). */
3039 lua_rawset(L, -3); /* index new table with header name (pop the values). */
3040 break;
3041
3042 case LUA_TTABLE:
3043 /* Entry found: push the value in the table. */
3044 len = lua_rawlen(L, -1);
3045 lua_pushlstring(L, hv, hvl); /* push header value. */
3046 lua_rawseti(L, -2, len+1); /* index header value (pop it). */
3047 lua_pop(L, 1); /* remove the table (it is stored in the main table). */
3048 break;
3049
3050 default:
3051 /* Other cases are errors. */
3052 hlua_pusherror(L, "internal error during the parsing of headers.");
3053 WILL_LJMP(lua_error(L));
3054 }
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003055 }
3056
3057 return 1;
3058}
3059
3060__LJMP static int hlua_http_req_get_headers(lua_State *L)
3061{
3062 struct hlua_txn *htxn;
3063
3064 MAY_LJMP(check_args(L, 1, "req_get_headers"));
3065 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3066
Willy Tarreaueee5b512015-04-03 23:46:31 +02003067 return hlua_http_get_headers(L, htxn, &htxn->s->txn->req);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003068}
3069
3070__LJMP static int hlua_http_res_get_headers(lua_State *L)
3071{
3072 struct hlua_txn *htxn;
3073
3074 MAY_LJMP(check_args(L, 1, "res_get_headers"));
3075 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3076
Willy Tarreaueee5b512015-04-03 23:46:31 +02003077 return hlua_http_get_headers(L, htxn, &htxn->s->txn->rsp);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003078}
3079
3080/* This function replace full header, or just a value in
3081 * the request or in the response. It is a wrapper fir the
3082 * 4 following functions.
3083 */
3084__LJMP static inline int hlua_http_rep_hdr(lua_State *L, struct hlua_txn *htxn,
3085 struct http_msg *msg, int action)
3086{
3087 size_t name_len;
3088 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
3089 const char *reg = MAY_LJMP(luaL_checkstring(L, 3));
3090 const char *value = MAY_LJMP(luaL_checkstring(L, 4));
3091 struct my_regex re;
3092
3093 if (!regex_comp(reg, &re, 1, 1, NULL))
3094 WILL_LJMP(luaL_argerror(L, 3, "invalid regex"));
3095
3096 http_transform_header_str(htxn->s, msg, name, name_len, value, &re, action);
3097 regex_free(&re);
3098 return 0;
3099}
3100
3101__LJMP static int hlua_http_req_rep_hdr(lua_State *L)
3102{
3103 struct hlua_txn *htxn;
3104
3105 MAY_LJMP(check_args(L, 4, "req_rep_hdr"));
3106 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3107
Willy Tarreaueee5b512015-04-03 23:46:31 +02003108 return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->req, HTTP_REQ_ACT_REPLACE_HDR));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003109}
3110
3111__LJMP static int hlua_http_res_rep_hdr(lua_State *L)
3112{
3113 struct hlua_txn *htxn;
3114
3115 MAY_LJMP(check_args(L, 4, "res_rep_hdr"));
3116 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3117
Willy Tarreaueee5b512015-04-03 23:46:31 +02003118 return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->rsp, HTTP_RES_ACT_REPLACE_HDR));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003119}
3120
3121__LJMP static int hlua_http_req_rep_val(lua_State *L)
3122{
3123 struct hlua_txn *htxn;
3124
3125 MAY_LJMP(check_args(L, 4, "req_rep_hdr"));
3126 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3127
Willy Tarreaueee5b512015-04-03 23:46:31 +02003128 return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->req, HTTP_REQ_ACT_REPLACE_VAL));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003129}
3130
3131__LJMP static int hlua_http_res_rep_val(lua_State *L)
3132{
3133 struct hlua_txn *htxn;
3134
3135 MAY_LJMP(check_args(L, 4, "res_rep_val"));
3136 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3137
Willy Tarreaueee5b512015-04-03 23:46:31 +02003138 return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->rsp, HTTP_RES_ACT_REPLACE_VAL));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003139}
3140
3141/* This function deletes all the occurences of an header.
3142 * It is a wrapper for the 2 following functions.
3143 */
3144__LJMP static inline int hlua_http_del_hdr(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
3145{
3146 size_t len;
3147 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &len));
3148 struct hdr_ctx ctx;
Willy Tarreaueee5b512015-04-03 23:46:31 +02003149 struct http_txn *txn = htxn->s->txn;
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003150
3151 ctx.idx = 0;
3152 while (http_find_header2(name, len, msg->chn->buf->p, &txn->hdr_idx, &ctx))
3153 http_remove_header2(msg, &txn->hdr_idx, &ctx);
3154 return 0;
3155}
3156
3157__LJMP static int hlua_http_req_del_hdr(lua_State *L)
3158{
3159 struct hlua_txn *htxn;
3160
3161 MAY_LJMP(check_args(L, 2, "req_del_hdr"));
3162 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3163
Willy Tarreaueee5b512015-04-03 23:46:31 +02003164 return hlua_http_del_hdr(L, htxn, &htxn->s->txn->req);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003165}
3166
3167__LJMP static int hlua_http_res_del_hdr(lua_State *L)
3168{
3169 struct hlua_txn *htxn;
3170
3171 MAY_LJMP(check_args(L, 2, "req_del_hdr"));
3172 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3173
Willy Tarreaueee5b512015-04-03 23:46:31 +02003174 return hlua_http_del_hdr(L, htxn, &htxn->s->txn->rsp);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003175}
3176
3177/* This function adds an header. It is a wrapper used by
3178 * the 2 following functions.
3179 */
3180__LJMP static inline int hlua_http_add_hdr(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
3181{
3182 size_t name_len;
3183 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
3184 size_t value_len;
3185 const char *value = MAY_LJMP(luaL_checklstring(L, 3, &value_len));
3186 char *p;
3187
3188 /* Check length. */
3189 trash.len = value_len + name_len + 2;
3190 if (trash.len > trash.size)
3191 return 0;
3192
3193 /* Creates the header string. */
3194 p = trash.str;
3195 memcpy(p, name, name_len);
3196 p += name_len;
3197 *p = ':';
3198 p++;
3199 *p = ' ';
3200 p++;
3201 memcpy(p, value, value_len);
3202
Willy Tarreaueee5b512015-04-03 23:46:31 +02003203 lua_pushboolean(L, http_header_add_tail2(msg, &htxn->s->txn->hdr_idx,
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003204 trash.str, trash.len) != 0);
3205
3206 return 0;
3207}
3208
3209__LJMP static int hlua_http_req_add_hdr(lua_State *L)
3210{
3211 struct hlua_txn *htxn;
3212
3213 MAY_LJMP(check_args(L, 3, "req_add_hdr"));
3214 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3215
Willy Tarreaueee5b512015-04-03 23:46:31 +02003216 return hlua_http_add_hdr(L, htxn, &htxn->s->txn->req);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003217}
3218
3219__LJMP static int hlua_http_res_add_hdr(lua_State *L)
3220{
3221 struct hlua_txn *htxn;
3222
3223 MAY_LJMP(check_args(L, 3, "res_add_hdr"));
3224 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3225
Willy Tarreaueee5b512015-04-03 23:46:31 +02003226 return hlua_http_add_hdr(L, htxn, &htxn->s->txn->rsp);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003227}
3228
3229static int hlua_http_req_set_hdr(lua_State *L)
3230{
3231 struct hlua_txn *htxn;
3232
3233 MAY_LJMP(check_args(L, 3, "req_set_hdr"));
3234 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3235
Willy Tarreaueee5b512015-04-03 23:46:31 +02003236 hlua_http_del_hdr(L, htxn, &htxn->s->txn->req);
3237 return hlua_http_add_hdr(L, htxn, &htxn->s->txn->req);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003238}
3239
3240static int hlua_http_res_set_hdr(lua_State *L)
3241{
3242 struct hlua_txn *htxn;
3243
3244 MAY_LJMP(check_args(L, 3, "res_set_hdr"));
3245 htxn = MAY_LJMP(hlua_checkhttp(L, 1));
3246
Willy Tarreaueee5b512015-04-03 23:46:31 +02003247 hlua_http_del_hdr(L, htxn, &htxn->s->txn->rsp);
3248 return hlua_http_add_hdr(L, htxn, &htxn->s->txn->rsp);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003249}
3250
3251/* This function set the method. */
3252static int hlua_http_req_set_meth(lua_State *L)
3253{
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003254 struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003255 size_t name_len;
3256 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003257
Willy Tarreau987e3fb2015-04-04 01:09:08 +02003258 lua_pushboolean(L, http_replace_req_line(0, name, name_len, htxn->p, htxn->s) != -1);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003259 return 1;
3260}
3261
3262/* This function set the method. */
3263static int hlua_http_req_set_path(lua_State *L)
3264{
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003265 struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003266 size_t name_len;
3267 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
Willy Tarreau987e3fb2015-04-04 01:09:08 +02003268 lua_pushboolean(L, http_replace_req_line(1, name, name_len, htxn->p, htxn->s) != -1);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003269 return 1;
3270}
3271
3272/* This function set the query-string. */
3273static int hlua_http_req_set_query(lua_State *L)
3274{
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003275 struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003276 size_t name_len;
3277 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003278
3279 /* Check length. */
3280 if (name_len > trash.size - 1) {
3281 lua_pushboolean(L, 0);
3282 return 1;
3283 }
3284
3285 /* Add the mark question as prefix. */
3286 chunk_reset(&trash);
3287 trash.str[trash.len++] = '?';
3288 memcpy(trash.str + trash.len, name, name_len);
3289 trash.len += name_len;
3290
Willy Tarreau987e3fb2015-04-04 01:09:08 +02003291 lua_pushboolean(L, http_replace_req_line(2, trash.str, trash.len, htxn->p, htxn->s) != -1);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003292 return 1;
3293}
3294
3295/* This function set the uri. */
3296static int hlua_http_req_set_uri(lua_State *L)
3297{
Willy Tarreaubcb39cc2015-04-06 11:21:44 +02003298 struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003299 size_t name_len;
3300 const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003301
Willy Tarreau987e3fb2015-04-04 01:09:08 +02003302 lua_pushboolean(L, http_replace_req_line(3, name, name_len, htxn->p, htxn->s) != -1);
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003303 return 1;
3304}
3305
3306/*
3307 *
3308 *
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003309 * Class TXN
3310 *
3311 *
3312 */
3313
3314/* Returns a struct hlua_session if the stack entry "ud" is
Willy Tarreau87b09662015-04-03 00:22:06 +02003315 * a class stream, otherwise it throws an error.
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003316 */
3317__LJMP static struct hlua_txn *hlua_checktxn(lua_State *L, int ud)
3318{
3319 return (struct hlua_txn *)MAY_LJMP(hlua_checkudata(L, ud, class_txn_ref));
3320}
3321
Thierry FOURNIER053ba8ad2015-06-08 13:05:33 +02003322__LJMP static int hlua_set_var(lua_State *L)
3323{
3324 struct hlua_txn *htxn;
3325 const char *name;
3326 size_t len;
3327 struct sample smp;
3328
3329 MAY_LJMP(check_args(L, 3, "set_var"));
3330
3331 /* It is useles to retrieve the stream, but this function
3332 * runs only in a stream context.
3333 */
3334 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3335 name = MAY_LJMP(luaL_checklstring(L, 2, &len));
3336
3337 /* Converts the third argument in a sample. */
3338 hlua_lua2smp(L, 3, &smp);
3339
3340 /* Store the sample in a variable. */
3341 vars_set_by_name(name, len, htxn->s, &smp);
3342 return 0;
3343}
3344
3345__LJMP static int hlua_get_var(lua_State *L)
3346{
3347 struct hlua_txn *htxn;
3348 const char *name;
3349 size_t len;
3350 struct sample smp;
3351
3352 MAY_LJMP(check_args(L, 2, "get_var"));
3353
3354 /* It is useles to retrieve the stream, but this function
3355 * runs only in a stream context.
3356 */
3357 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3358 name = MAY_LJMP(luaL_checklstring(L, 2, &len));
3359
3360 if (!vars_get_by_name(name, len, htxn->s, &smp)) {
3361 lua_pushnil(L);
3362 return 1;
3363 }
3364
3365 return hlua_smp2lua(L, &smp);
3366}
3367
Willy Tarreau59551662015-03-10 14:23:13 +01003368__LJMP static int hlua_set_priv(lua_State *L)
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003369{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003370 struct hlua *hlua;
3371
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003372 MAY_LJMP(check_args(L, 2, "set_priv"));
3373
Willy Tarreau87b09662015-04-03 00:22:06 +02003374 /* It is useles to retrieve the stream, but this function
3375 * runs only in a stream context.
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003376 */
3377 MAY_LJMP(hlua_checktxn(L, 1));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003378 hlua = hlua_gethlua(L);
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003379
3380 /* Remove previous value. */
3381 if (hlua->Mref != -1)
3382 luaL_unref(L, hlua->Mref, LUA_REGISTRYINDEX);
3383
3384 /* Get and store new value. */
3385 lua_pushvalue(L, 2); /* Copy the element 2 at the top of the stack. */
3386 hlua->Mref = luaL_ref(L, LUA_REGISTRYINDEX); /* pop the previously pushed value. */
3387
3388 return 0;
3389}
3390
Willy Tarreau59551662015-03-10 14:23:13 +01003391__LJMP static int hlua_get_priv(lua_State *L)
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003392{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003393 struct hlua *hlua;
3394
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003395 MAY_LJMP(check_args(L, 1, "get_priv"));
3396
Willy Tarreau87b09662015-04-03 00:22:06 +02003397 /* It is useles to retrieve the stream, but this function
3398 * runs only in a stream context.
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003399 */
3400 MAY_LJMP(hlua_checktxn(L, 1));
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003401 hlua = hlua_gethlua(L);
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01003402
3403 /* Push configuration index in the stack. */
3404 lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
3405
3406 return 1;
3407}
3408
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003409/* Create stack entry containing a class TXN. This function
3410 * return 0 if the stack does not contains free slots,
3411 * otherwise it returns 1.
3412 */
Willy Tarreau15e91e12015-04-04 00:52:09 +02003413static int hlua_txn_new(lua_State *L, struct stream *s, struct proxy *p)
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003414{
Willy Tarreaude491382015-04-06 11:04:28 +02003415 struct hlua_txn *htxn;
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003416
3417 /* Check stack size. */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01003418 if (!lua_checkstack(L, 3))
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003419 return 0;
3420
3421 /* NOTE: The allocation never fails. The failure
3422 * throw an error, and the function never returns.
3423 * if the throw is not avalaible, the process is aborted.
3424 */
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01003425 /* Create the object: obj[0] = userdata. */
3426 lua_newtable(L);
Willy Tarreaude491382015-04-06 11:04:28 +02003427 htxn = lua_newuserdata(L, sizeof(*htxn));
Thierry FOURNIER2297bc22015-03-11 17:43:33 +01003428 lua_rawseti(L, -2, 0);
3429
Willy Tarreaude491382015-04-06 11:04:28 +02003430 htxn->s = s;
3431 htxn->p = p;
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003432
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01003433 /* Create the "f" field that contains a list of fetches. */
3434 lua_pushstring(L, "f");
Willy Tarreaude491382015-04-06 11:04:28 +02003435 if (!hlua_fetches_new(L, htxn, 0))
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01003436 return 0;
3437 lua_settable(L, -3);
3438
3439 /* Create the "sf" field that contains a list of stringsafe fetches. */
3440 lua_pushstring(L, "sf");
Willy Tarreaude491382015-04-06 11:04:28 +02003441 if (!hlua_fetches_new(L, htxn, 1))
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01003442 return 0;
3443 lua_settable(L, -3);
3444
Thierry FOURNIER594afe72015-03-10 23:58:30 +01003445 /* Create the "c" field that contains a list of converters. */
3446 lua_pushstring(L, "c");
Willy Tarreaude491382015-04-06 11:04:28 +02003447 if (!hlua_converters_new(L, htxn, 0))
Thierry FOURNIER2694a1a2015-03-11 20:13:36 +01003448 return 0;
3449 lua_settable(L, -3);
3450
3451 /* Create the "sc" field that contains a list of stringsafe converters. */
3452 lua_pushstring(L, "sc");
Willy Tarreaude491382015-04-06 11:04:28 +02003453 if (!hlua_converters_new(L, htxn, 1))
Thierry FOURNIER594afe72015-03-10 23:58:30 +01003454 return 0;
3455 lua_settable(L, -3);
3456
Thierry FOURNIER397826a2015-03-11 19:39:09 +01003457 /* Create the "req" field that contains the request channel object. */
3458 lua_pushstring(L, "req");
Willy Tarreau2a71af42015-03-10 13:51:50 +01003459 if (!hlua_channel_new(L, &s->req))
Thierry FOURNIER397826a2015-03-11 19:39:09 +01003460 return 0;
3461 lua_settable(L, -3);
3462
3463 /* Create the "res" field that contains the response channel object. */
3464 lua_pushstring(L, "res");
Willy Tarreau2a71af42015-03-10 13:51:50 +01003465 if (!hlua_channel_new(L, &s->res))
Thierry FOURNIER397826a2015-03-11 19:39:09 +01003466 return 0;
3467 lua_settable(L, -3);
3468
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003469 /* Creates the HTTP object is the current proxy allows http. */
3470 lua_pushstring(L, "http");
3471 if (p->mode == PR_MODE_HTTP) {
Willy Tarreaude491382015-04-06 11:04:28 +02003472 if (!hlua_http_new(L, htxn))
Thierry FOURNIER08504f42015-03-16 14:17:08 +01003473 return 0;
3474 }
3475 else
3476 lua_pushnil(L);
3477 lua_settable(L, -3);
3478
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01003479 /* Pop a class sesison metatable and affect it to the userdata. */
3480 lua_rawgeti(L, LUA_REGISTRYINDEX, class_txn_ref);
3481 lua_setmetatable(L, -2);
3482
3483 return 1;
3484}
3485
Thierry FOURNIERc798b5d2015-03-17 01:09:57 +01003486__LJMP static int hlua_txn_deflog(lua_State *L)
3487{
3488 const char *msg;
3489 struct hlua_txn *htxn;
3490
3491 MAY_LJMP(check_args(L, 2, "deflog"));
3492 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3493 msg = MAY_LJMP(luaL_checkstring(L, 2));
3494
3495 hlua_sendlog(htxn->s->be, htxn->s->logs.level, msg);
3496 return 0;
3497}
3498
3499__LJMP static int hlua_txn_log(lua_State *L)
3500{
3501 int level;
3502 const char *msg;
3503 struct hlua_txn *htxn;
3504
3505 MAY_LJMP(check_args(L, 3, "log"));
3506 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3507 level = MAY_LJMP(luaL_checkinteger(L, 2));
3508 msg = MAY_LJMP(luaL_checkstring(L, 3));
3509
3510 if (level < 0 || level >= NB_LOG_LEVELS)
3511 WILL_LJMP(luaL_argerror(L, 1, "Invalid loglevel."));
3512
3513 hlua_sendlog(htxn->s->be, level, msg);
3514 return 0;
3515}
3516
3517__LJMP static int hlua_txn_log_debug(lua_State *L)
3518{
3519 const char *msg;
3520 struct hlua_txn *htxn;
3521
3522 MAY_LJMP(check_args(L, 2, "Debug"));
3523 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3524 msg = MAY_LJMP(luaL_checkstring(L, 2));
3525 hlua_sendlog(htxn->s->be, LOG_DEBUG, msg);
3526 return 0;
3527}
3528
3529__LJMP static int hlua_txn_log_info(lua_State *L)
3530{
3531 const char *msg;
3532 struct hlua_txn *htxn;
3533
3534 MAY_LJMP(check_args(L, 2, "Info"));
3535 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3536 msg = MAY_LJMP(luaL_checkstring(L, 2));
3537 hlua_sendlog(htxn->s->be, LOG_INFO, msg);
3538 return 0;
3539}
3540
3541__LJMP static int hlua_txn_log_warning(lua_State *L)
3542{
3543 const char *msg;
3544 struct hlua_txn *htxn;
3545
3546 MAY_LJMP(check_args(L, 2, "Warning"));
3547 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3548 msg = MAY_LJMP(luaL_checkstring(L, 2));
3549 hlua_sendlog(htxn->s->be, LOG_WARNING, msg);
3550 return 0;
3551}
3552
3553__LJMP static int hlua_txn_log_alert(lua_State *L)
3554{
3555 const char *msg;
3556 struct hlua_txn *htxn;
3557
3558 MAY_LJMP(check_args(L, 2, "Alert"));
3559 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3560 msg = MAY_LJMP(luaL_checkstring(L, 2));
3561 hlua_sendlog(htxn->s->be, LOG_ALERT, msg);
3562 return 0;
3563}
3564
Thierry FOURNIER2cce3532015-03-16 12:04:16 +01003565__LJMP static int hlua_txn_set_loglevel(lua_State *L)
3566{
3567 struct hlua_txn *htxn;
3568 int ll;
3569
3570 MAY_LJMP(check_args(L, 2, "set_loglevel"));
3571 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3572 ll = MAY_LJMP(luaL_checkinteger(L, 2));
3573
3574 if (ll < 0 || ll > 7)
3575 WILL_LJMP(luaL_argerror(L, 2, "Bad log level. It must be between 0 and 7"));
3576
3577 htxn->s->logs.level = ll;
3578 return 0;
3579}
3580
3581__LJMP static int hlua_txn_set_tos(lua_State *L)
3582{
3583 struct hlua_txn *htxn;
3584 struct connection *cli_conn;
3585 int tos;
3586
3587 MAY_LJMP(check_args(L, 2, "set_tos"));
3588 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3589 tos = MAY_LJMP(luaL_checkinteger(L, 2));
3590
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003591 if ((cli_conn = objt_conn(htxn->s->sess->origin)) && conn_ctrl_ready(cli_conn))
Thierry FOURNIER2cce3532015-03-16 12:04:16 +01003592 inet_set_tos(cli_conn->t.sock.fd, cli_conn->addr.from, tos);
3593
3594 return 0;
3595}
3596
3597__LJMP static int hlua_txn_set_mark(lua_State *L)
3598{
3599#ifdef SO_MARK
3600 struct hlua_txn *htxn;
3601 struct connection *cli_conn;
3602 int mark;
3603
3604 MAY_LJMP(check_args(L, 2, "set_mark"));
3605 htxn = MAY_LJMP(hlua_checktxn(L, 1));
3606 mark = MAY_LJMP(luaL_checkinteger(L, 2));
3607
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003608 if ((cli_conn = objt_conn(htxn->s->sess->origin)) && conn_ctrl_ready(cli_conn))
Willy Tarreau07081fe2015-04-06 10:59:20 +02003609 setsockopt(cli_conn->t.sock.fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
Thierry FOURNIER2cce3532015-03-16 12:04:16 +01003610#endif
3611 return 0;
3612}
3613
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003614/* This function is an Lua binding that send pending data
3615 * to the client, and close the stream interface.
3616 */
3617__LJMP static int hlua_txn_close(lua_State *L)
3618{
Willy Tarreaub2ccb562015-04-06 11:11:15 +02003619 struct hlua_txn *htxn;
Willy Tarreau81389672015-03-10 12:03:52 +01003620 struct channel *ic, *oc;
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003621
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003622 MAY_LJMP(check_args(L, 1, "close"));
Willy Tarreaub2ccb562015-04-06 11:11:15 +02003623 htxn = MAY_LJMP(hlua_checktxn(L, 1));
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003624
Willy Tarreaub2ccb562015-04-06 11:11:15 +02003625 ic = &htxn->s->req;
3626 oc = &htxn->s->res;
Willy Tarreau81389672015-03-10 12:03:52 +01003627
3628 channel_abort(ic);
3629 channel_auto_close(ic);
3630 channel_erase(ic);
3631 channel_auto_read(oc);
3632 channel_auto_close(oc);
3633 channel_shutr_now(oc);
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003634
Thierry FOURNIERc798b5d2015-03-17 01:09:57 +01003635 return 0;
3636}
3637
3638__LJMP static int hlua_log(lua_State *L)
3639{
3640 int level;
3641 const char *msg;
3642
3643 MAY_LJMP(check_args(L, 2, "log"));
3644 level = MAY_LJMP(luaL_checkinteger(L, 1));
3645 msg = MAY_LJMP(luaL_checkstring(L, 2));
3646
3647 if (level < 0 || level >= NB_LOG_LEVELS)
3648 WILL_LJMP(luaL_argerror(L, 1, "Invalid loglevel."));
3649
3650 hlua_sendlog(NULL, level, msg);
3651 return 0;
3652}
3653
3654__LJMP static int hlua_log_debug(lua_State *L)
3655{
3656 const char *msg;
3657
3658 MAY_LJMP(check_args(L, 1, "debug"));
3659 msg = MAY_LJMP(luaL_checkstring(L, 1));
3660 hlua_sendlog(NULL, LOG_DEBUG, msg);
3661 return 0;
3662}
3663
3664__LJMP static int hlua_log_info(lua_State *L)
3665{
3666 const char *msg;
3667
3668 MAY_LJMP(check_args(L, 1, "info"));
3669 msg = MAY_LJMP(luaL_checkstring(L, 1));
3670 hlua_sendlog(NULL, LOG_INFO, msg);
3671 return 0;
3672}
3673
3674__LJMP static int hlua_log_warning(lua_State *L)
3675{
3676 const char *msg;
3677
3678 MAY_LJMP(check_args(L, 1, "warning"));
3679 msg = MAY_LJMP(luaL_checkstring(L, 1));
3680 hlua_sendlog(NULL, LOG_WARNING, msg);
3681 return 0;
3682}
3683
3684__LJMP static int hlua_log_alert(lua_State *L)
3685{
3686 const char *msg;
3687
3688 MAY_LJMP(check_args(L, 1, "alert"));
3689 msg = MAY_LJMP(luaL_checkstring(L, 1));
3690 hlua_sendlog(NULL, LOG_ALERT, msg);
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01003691 return 0;
3692}
3693
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01003694__LJMP static int hlua_sleep_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003695{
3696 int wakeup_ms = lua_tointeger(L, -1);
3697 if (now_ms < wakeup_ms)
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003698 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003699 return 0;
3700}
3701
3702__LJMP static int hlua_sleep(lua_State *L)
3703{
3704 unsigned int delay;
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003705 unsigned int wakeup_ms;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003706
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003707 MAY_LJMP(check_args(L, 1, "sleep"));
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003708
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01003709 delay = MAY_LJMP(luaL_checkinteger(L, 1)) * 1000;
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003710 wakeup_ms = tick_add(now_ms, delay);
3711 lua_pushinteger(L, wakeup_ms);
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003712
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003713 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
3714 return 0;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003715}
3716
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003717__LJMP static int hlua_msleep(lua_State *L)
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003718{
3719 unsigned int delay;
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003720 unsigned int wakeup_ms;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003721
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003722 MAY_LJMP(check_args(L, 1, "msleep"));
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003723
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01003724 delay = MAY_LJMP(luaL_checkinteger(L, 1));
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003725 wakeup_ms = tick_add(now_ms, delay);
3726 lua_pushinteger(L, wakeup_ms);
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003727
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003728 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
3729 return 0;
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01003730}
3731
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01003732/* This functionis an LUA binding. it permits to give back
3733 * the hand at the HAProxy scheduler. It is used when the
3734 * LUA processing consumes a lot of time.
3735 */
Thierry FOURNIERf90838b2015-03-06 13:48:32 +01003736__LJMP static int hlua_yield_yield(lua_State *L, int status, lua_KContext ctx)
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003737{
3738 return 0;
3739}
3740
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01003741__LJMP static int hlua_yield(lua_State *L)
3742{
Thierry FOURNIERd44731f2015-03-04 15:51:09 +01003743 WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_yield_yield, TICK_ETERNITY, HLUA_CTRLYIELD));
3744 return 0;
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01003745}
3746
Thierry FOURNIER37196f42015-02-16 19:34:56 +01003747/* This function change the nice of the currently executed
3748 * task. It is used set low or high priority at the current
3749 * task.
3750 */
Willy Tarreau59551662015-03-10 14:23:13 +01003751__LJMP static int hlua_set_nice(lua_State *L)
Thierry FOURNIER37196f42015-02-16 19:34:56 +01003752{
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003753 struct hlua *hlua;
3754 int nice;
Thierry FOURNIER37196f42015-02-16 19:34:56 +01003755
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003756 MAY_LJMP(check_args(L, 1, "set_nice"));
3757 hlua = hlua_gethlua(L);
3758 nice = MAY_LJMP(luaL_checkinteger(L, 1));
Thierry FOURNIER37196f42015-02-16 19:34:56 +01003759
3760 /* If he task is not set, I'm in a start mode. */
3761 if (!hlua || !hlua->task)
3762 return 0;
3763
3764 if (nice < -1024)
3765 nice = -1024;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01003766 else if (nice > 1024)
Thierry FOURNIER37196f42015-02-16 19:34:56 +01003767 nice = 1024;
3768
3769 hlua->task->nice = nice;
3770 return 0;
3771}
3772
Thierry FOURNIER24f33532015-01-23 12:13:00 +01003773/* This function is used as a calback of a task. It is called by the
3774 * HAProxy task subsystem when the task is awaked. The LUA runtime can
3775 * return an E_AGAIN signal, the emmiter of this signal must set a
3776 * signal to wake the task.
3777 */
3778static struct task *hlua_process_task(struct task *task)
3779{
3780 struct hlua *hlua = task->context;
3781 enum hlua_exec status;
3782
3783 /* We need to remove the task from the wait queue before executing
3784 * the Lua code because we don't know if it needs to wait for
3785 * another timer or not in the case of E_AGAIN.
3786 */
3787 task_delete(task);
3788
Thierry FOURNIERbd413492015-03-03 16:52:26 +01003789 /* If it is the first call to the task, we must initialize the
3790 * execution timeouts.
3791 */
3792 if (!HLUA_IS_RUNNING(hlua))
3793 hlua->expire = tick_add(now_ms, hlua_timeout_task);
3794
Thierry FOURNIER24f33532015-01-23 12:13:00 +01003795 /* Execute the Lua code. */
3796 status = hlua_ctx_resume(hlua, 1);
3797
3798 switch (status) {
3799 /* finished or yield */
3800 case HLUA_E_OK:
3801 hlua_ctx_destroy(hlua);
3802 task_delete(task);
3803 task_free(task);
3804 break;
3805
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01003806 case HLUA_E_AGAIN: /* co process or timeout wake me later. */
3807 if (hlua->wake_time != TICK_ETERNITY)
3808 task_schedule(task, hlua->wake_time);
Thierry FOURNIER24f33532015-01-23 12:13:00 +01003809 break;
3810
3811 /* finished with error. */
3812 case HLUA_E_ERRMSG:
3813 send_log(NULL, LOG_ERR, "Lua task: %s.", lua_tostring(hlua->T, -1));
3814 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3815 Alert("Lua task: %s.\n", lua_tostring(hlua->T, -1));
3816 hlua_ctx_destroy(hlua);
3817 task_delete(task);
3818 task_free(task);
3819 break;
3820
3821 case HLUA_E_ERR:
3822 default:
3823 send_log(NULL, LOG_ERR, "Lua task: unknown error.");
3824 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3825 Alert("Lua task: unknown error.\n");
3826 hlua_ctx_destroy(hlua);
3827 task_delete(task);
3828 task_free(task);
3829 break;
3830 }
3831 return NULL;
3832}
3833
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01003834/* This function is an LUA binding that register LUA function to be
3835 * executed after the HAProxy configuration parsing and before the
3836 * HAProxy scheduler starts. This function expect only one LUA
3837 * argument that is a function. This function returns nothing, but
3838 * throws if an error is encountered.
3839 */
3840__LJMP static int hlua_register_init(lua_State *L)
3841{
3842 struct hlua_init_function *init;
3843 int ref;
3844
3845 MAY_LJMP(check_args(L, 1, "register_init"));
3846
3847 ref = MAY_LJMP(hlua_checkfunction(L, 1));
3848
3849 init = malloc(sizeof(*init));
3850 if (!init)
3851 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3852
3853 init->function_ref = ref;
3854 LIST_ADDQ(&hlua_init_functions, &init->l);
3855 return 0;
3856}
3857
Thierry FOURNIER24f33532015-01-23 12:13:00 +01003858/* This functio is an LUA binding. It permits to register a task
3859 * executed in parallel of the main HAroxy activity. The task is
3860 * created and it is set in the HAProxy scheduler. It can be called
3861 * from the "init" section, "post init" or during the runtime.
3862 *
3863 * Lua prototype:
3864 *
3865 * <none> core.register_task(<function>)
3866 */
3867static int hlua_register_task(lua_State *L)
3868{
3869 struct hlua *hlua;
3870 struct task *task;
3871 int ref;
3872
3873 MAY_LJMP(check_args(L, 1, "register_task"));
3874
3875 ref = MAY_LJMP(hlua_checkfunction(L, 1));
3876
3877 hlua = malloc(sizeof(*hlua));
3878 if (!hlua)
3879 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3880
3881 task = task_new();
3882 task->context = hlua;
3883 task->process = hlua_process_task;
3884
3885 if (!hlua_ctx_init(hlua, task))
3886 WILL_LJMP(luaL_error(L, "lua out of memory error."));
3887
3888 /* Restore the function in the stack. */
3889 lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ref);
3890 hlua->nargs = 0;
3891
3892 /* Schedule task. */
3893 task_schedule(task, now_ms);
3894
3895 return 0;
3896}
3897
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003898/* Wrapper called by HAProxy to execute an LUA converter. This wrapper
3899 * doesn't allow "yield" functions because the HAProxy engine cannot
3900 * resume converters.
3901 */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003902static int hlua_sample_conv_wrapper(const struct arg *arg_p, struct sample *smp, void *private)
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003903{
3904 struct hlua_function *fcn = (struct hlua_function *)private;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003905 struct stream *stream = smp->strm;
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003906
Willy Tarreau87b09662015-04-03 00:22:06 +02003907 /* In the execution wrappers linked with a stream, the
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01003908 * Lua context can be not initialized. This behavior
3909 * permits to save performances because a systematic
3910 * Lua initialization cause 5% performances loss.
3911 */
Willy Tarreau87b09662015-04-03 00:22:06 +02003912 if (!stream->hlua.T && !hlua_ctx_init(&stream->hlua, stream->task)) {
3913 send_log(stream->be, LOG_ERR, "Lua converter '%s': can't initialize Lua context.", fcn->name);
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01003914 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3915 Alert("Lua converter '%s': can't initialize Lua context.\n", fcn->name);
3916 return 0;
3917 }
3918
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003919 /* If it is the first run, initialize the data for the call. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003920 if (!HLUA_IS_RUNNING(&stream->hlua)) {
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003921 /* Check stack available size. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003922 if (!lua_checkstack(stream->hlua.T, 1)) {
3923 send_log(stream->be, LOG_ERR, "Lua converter '%s': full stack.", fcn->name);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003924 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3925 Alert("Lua converter '%s': full stack.\n", fcn->name);
3926 return 0;
3927 }
3928
3929 /* Restore the function in the stack. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003930 lua_rawgeti(stream->hlua.T, LUA_REGISTRYINDEX, fcn->function_ref);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003931
3932 /* convert input sample and pust-it in the stack. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003933 if (!lua_checkstack(stream->hlua.T, 1)) {
3934 send_log(stream->be, LOG_ERR, "Lua converter '%s': full stack.", fcn->name);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003935 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3936 Alert("Lua converter '%s': full stack.\n", fcn->name);
3937 return 0;
3938 }
Willy Tarreau87b09662015-04-03 00:22:06 +02003939 hlua_smp2lua(stream->hlua.T, smp);
3940 stream->hlua.nargs = 2;
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003941
3942 /* push keywords in the stack. */
3943 if (arg_p) {
3944 for (; arg_p->type != ARGT_STOP; arg_p++) {
Willy Tarreau87b09662015-04-03 00:22:06 +02003945 if (!lua_checkstack(stream->hlua.T, 1)) {
3946 send_log(stream->be, LOG_ERR, "Lua converter '%s': full stack.", fcn->name);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003947 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3948 Alert("Lua converter '%s': full stack.\n", fcn->name);
3949 return 0;
3950 }
Willy Tarreau87b09662015-04-03 00:22:06 +02003951 hlua_arg2lua(stream->hlua.T, arg_p);
3952 stream->hlua.nargs++;
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003953 }
3954 }
3955
Thierry FOURNIERbd413492015-03-03 16:52:26 +01003956 /* We must initialize the execution timeouts. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003957 stream->hlua.expire = tick_add(now_ms, hlua_timeout_session);
Thierry FOURNIERbd413492015-03-03 16:52:26 +01003958
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003959 /* Set the currently running flag. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003960 HLUA_SET_RUN(&stream->hlua);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003961 }
3962
3963 /* Execute the function. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003964 switch (hlua_ctx_resume(&stream->hlua, 0)) {
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003965 /* finished. */
3966 case HLUA_E_OK:
3967 /* Convert the returned value in sample. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003968 hlua_lua2smp(stream->hlua.T, -1, smp);
3969 lua_pop(stream->hlua.T, 1);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003970 return 1;
3971
3972 /* yield. */
3973 case HLUA_E_AGAIN:
Willy Tarreau87b09662015-04-03 00:22:06 +02003974 send_log(stream->be, LOG_ERR, "Lua converter '%s': cannot use yielded functions.", fcn->name);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003975 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3976 Alert("Lua converter '%s': cannot use yielded functions.\n", fcn->name);
3977 return 0;
3978
3979 /* finished with error. */
3980 case HLUA_E_ERRMSG:
3981 /* Display log. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003982 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 +01003983 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
Willy Tarreau87b09662015-04-03 00:22:06 +02003984 Alert("Lua converter '%s': %s.\n", fcn->name, lua_tostring(stream->hlua.T, -1));
3985 lua_pop(stream->hlua.T, 1);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003986 return 0;
3987
3988 case HLUA_E_ERR:
3989 /* Display log. */
Willy Tarreau87b09662015-04-03 00:22:06 +02003990 send_log(stream->be, LOG_ERR, "Lua converter '%s' returns an unknown error.", fcn->name);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01003991 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
3992 Alert("Lua converter '%s' returns an unknown error.\n", fcn->name);
3993
3994 default:
3995 return 0;
3996 }
3997}
3998
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01003999/* Wrapper called by HAProxy to execute a sample-fetch. this wrapper
4000 * doesn't allow "yield" functions because the HAProxy engine cannot
4001 * resume sample-fetches.
4002 */
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004003static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp,
4004 const char *kw, void *private)
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004005{
4006 struct hlua_function *fcn = (struct hlua_function *)private;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004007 struct stream *stream = smp->strm;
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004008
Willy Tarreau87b09662015-04-03 00:22:06 +02004009 /* In the execution wrappers linked with a stream, the
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01004010 * Lua context can be not initialized. This behavior
4011 * permits to save performances because a systematic
4012 * Lua initialization cause 5% performances loss.
4013 */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004014 if (!stream->hlua.T && !hlua_ctx_init(&stream->hlua, stream->task)) {
4015 send_log(stream->be, LOG_ERR, "Lua sample-fetch '%s': can't initialize Lua context.", fcn->name);
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01004016 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4017 Alert("Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
4018 return 0;
4019 }
4020
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004021 /* If it is the first run, initialize the data for the call. */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004022 if (!HLUA_IS_RUNNING(&stream->hlua)) {
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004023 /* Check stack available size. */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004024 if (!lua_checkstack(stream->hlua.T, 2)) {
4025 send_log(smp->px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004026 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4027 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
4028 return 0;
4029 }
4030
4031 /* Restore the function in the stack. */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004032 lua_rawgeti(stream->hlua.T, LUA_REGISTRYINDEX, fcn->function_ref);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004033
4034 /* push arguments in the stack. */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004035 if (!hlua_txn_new(stream->hlua.T, stream, smp->px)) {
4036 send_log(smp->px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004037 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4038 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
4039 return 0;
4040 }
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004041 stream->hlua.nargs = 1;
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004042
4043 /* push keywords in the stack. */
4044 for (; arg_p && arg_p->type != ARGT_STOP; arg_p++) {
4045 /* Check stack available size. */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004046 if (!lua_checkstack(stream->hlua.T, 1)) {
4047 send_log(smp->px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004048 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4049 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
4050 return 0;
4051 }
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004052 if (!lua_checkstack(stream->hlua.T, 1)) {
4053 send_log(smp->px, LOG_ERR, "Lua sample-fetch '%s': full stack.", fcn->name);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004054 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4055 Alert("Lua sample-fetch '%s': full stack.\n", fcn->name);
4056 return 0;
4057 }
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004058 hlua_arg2lua(stream->hlua.T, arg_p);
4059 stream->hlua.nargs++;
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004060 }
4061
Thierry FOURNIERbd413492015-03-03 16:52:26 +01004062 /* We must initialize the execution timeouts. */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004063 stream->hlua.expire = tick_add(now_ms, hlua_timeout_session);
Thierry FOURNIERbd413492015-03-03 16:52:26 +01004064
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004065 /* Set the currently running flag. */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004066 HLUA_SET_RUN(&stream->hlua);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004067 }
4068
4069 /* Execute the function. */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004070 switch (hlua_ctx_resume(&stream->hlua, 0)) {
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004071 /* finished. */
4072 case HLUA_E_OK:
4073 /* Convert the returned value in sample. */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004074 hlua_lua2smp(stream->hlua.T, -1, smp);
4075 lua_pop(stream->hlua.T, 1);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004076
4077 /* Set the end of execution flag. */
4078 smp->flags &= ~SMP_F_MAY_CHANGE;
4079 return 1;
4080
4081 /* yield. */
4082 case HLUA_E_AGAIN:
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004083 send_log(smp->px, LOG_ERR, "Lua sample-fetch '%s': cannot use yielded functions.", fcn->name);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004084 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4085 Alert("Lua sample-fetch '%s': cannot use yielded functions.\n", fcn->name);
4086 return 0;
4087
4088 /* finished with error. */
4089 case HLUA_E_ERRMSG:
4090 /* Display log. */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004091 send_log(smp->px, LOG_ERR, "Lua sample-fetch '%s': %s.", fcn->name, lua_tostring(stream->hlua.T, -1));
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004092 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004093 Alert("Lua sample-fetch '%s': %s.\n", fcn->name, lua_tostring(stream->hlua.T, -1));
4094 lua_pop(stream->hlua.T, 1);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004095 return 0;
4096
4097 case HLUA_E_ERR:
4098 /* Display log. */
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004099 send_log(smp->px, LOG_ERR, "Lua sample-fetch '%s' returns an unknown error.", fcn->name);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004100 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4101 Alert("Lua sample-fetch '%s': returns an unknown error.\n", fcn->name);
4102
4103 default:
4104 return 0;
4105 }
4106}
4107
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01004108/* This function is an LUA binding used for registering
4109 * "sample-conv" functions. It expects a converter name used
4110 * in the haproxy configuration file, and an LUA function.
4111 */
4112__LJMP static int hlua_register_converters(lua_State *L)
4113{
4114 struct sample_conv_kw_list *sck;
4115 const char *name;
4116 int ref;
4117 int len;
4118 struct hlua_function *fcn;
4119
4120 MAY_LJMP(check_args(L, 2, "register_converters"));
4121
4122 /* First argument : converter name. */
4123 name = MAY_LJMP(luaL_checkstring(L, 1));
4124
4125 /* Second argument : lua function. */
4126 ref = MAY_LJMP(hlua_checkfunction(L, 2));
4127
4128 /* Allocate and fill the sample fetch keyword struct. */
Willy Tarreau07081fe2015-04-06 10:59:20 +02004129 sck = malloc(sizeof(*sck) + sizeof(struct sample_conv) * 2);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01004130 if (!sck)
4131 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4132 fcn = malloc(sizeof(*fcn));
4133 if (!fcn)
4134 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4135
4136 /* Fill fcn. */
4137 fcn->name = strdup(name);
4138 if (!fcn->name)
4139 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4140 fcn->function_ref = ref;
4141
4142 /* List head */
4143 sck->list.n = sck->list.p = NULL;
4144
4145 /* converter keyword. */
4146 len = strlen("lua.") + strlen(name) + 1;
4147 sck->kw[0].kw = malloc(len);
4148 if (!sck->kw[0].kw)
4149 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4150
4151 snprintf((char *)sck->kw[0].kw, len, "lua.%s", name);
4152 sck->kw[0].process = hlua_sample_conv_wrapper;
4153 sck->kw[0].arg_mask = ARG5(0,STR,STR,STR,STR,STR);
4154 sck->kw[0].val_args = NULL;
4155 sck->kw[0].in_type = SMP_T_STR;
4156 sck->kw[0].out_type = SMP_T_STR;
4157 sck->kw[0].private = fcn;
4158
4159 /* End of array. */
4160 memset(&sck->kw[1], 0, sizeof(struct sample_conv));
4161
4162 /* Register this new converter */
4163 sample_register_convs(sck);
4164
4165 return 0;
4166}
4167
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004168/* This fucntion is an LUA binding used for registering
4169 * "sample-fetch" functions. It expects a converter name used
4170 * in the haproxy configuration file, and an LUA function.
4171 */
4172__LJMP static int hlua_register_fetches(lua_State *L)
4173{
4174 const char *name;
4175 int ref;
4176 int len;
4177 struct sample_fetch_kw_list *sfk;
4178 struct hlua_function *fcn;
4179
4180 MAY_LJMP(check_args(L, 2, "register_fetches"));
4181
4182 /* First argument : sample-fetch name. */
4183 name = MAY_LJMP(luaL_checkstring(L, 1));
4184
4185 /* Second argument : lua function. */
4186 ref = MAY_LJMP(hlua_checkfunction(L, 2));
4187
4188 /* Allocate and fill the sample fetch keyword struct. */
Willy Tarreau07081fe2015-04-06 10:59:20 +02004189 sfk = malloc(sizeof(*sfk) + sizeof(struct sample_fetch) * 2);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004190 if (!sfk)
4191 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4192 fcn = malloc(sizeof(*fcn));
4193 if (!fcn)
4194 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4195
4196 /* Fill fcn. */
4197 fcn->name = strdup(name);
4198 if (!fcn->name)
4199 WILL_LJMP(luaL_error(L, "lua out of memory error."));
4200 fcn->function_ref = ref;
4201
4202 /* List head */
4203 sfk->list.n = sfk->list.p = NULL;
4204
4205 /* sample-fetch keyword. */
4206 len = strlen("lua.") + strlen(name) + 1;
4207 sfk->kw[0].kw = malloc(len);
4208 if (!sfk->kw[0].kw)
4209 return luaL_error(L, "lua out of memory error.");
4210
4211 snprintf((char *)sfk->kw[0].kw, len, "lua.%s", name);
4212 sfk->kw[0].process = hlua_sample_fetch_wrapper;
4213 sfk->kw[0].arg_mask = ARG5(0,STR,STR,STR,STR,STR);
4214 sfk->kw[0].val_args = NULL;
4215 sfk->kw[0].out_type = SMP_T_STR;
4216 sfk->kw[0].use = SMP_USE_HTTP_ANY;
4217 sfk->kw[0].val = 0;
4218 sfk->kw[0].private = fcn;
4219
4220 /* End of array. */
4221 memset(&sfk->kw[1], 0, sizeof(struct sample_fetch));
4222
4223 /* Register this new fetch. */
4224 sample_register_fetches(sfk);
4225
4226 return 0;
4227}
4228
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004229/* global {tcp|http}-request parser. Return 1 in succes case, else return 0. */
4230static int hlua_parse_rule(const char **args, int *cur_arg, struct proxy *px,
4231 struct hlua_rule **rule_p, char **err)
4232{
4233 struct hlua_rule *rule;
4234
4235 /* Memory for the rule. */
4236 rule = malloc(sizeof(*rule));
4237 if (!rule) {
4238 memprintf(err, "out of memory error");
4239 return 0;
4240 }
4241 *rule_p = rule;
4242
4243 /* The requiered arg is a function name. */
4244 if (!args[*cur_arg]) {
4245 memprintf(err, "expect Lua function name");
4246 return 0;
4247 }
4248
4249 /* Lookup for the symbol, and check if it is a function. */
4250 lua_getglobal(gL.T, args[*cur_arg]);
4251 if (lua_isnil(gL.T, -1)) {
4252 lua_pop(gL.T, 1);
4253 memprintf(err, "Lua function '%s' not found", args[*cur_arg]);
4254 return 0;
4255 }
4256 if (!lua_isfunction(gL.T, -1)) {
4257 lua_pop(gL.T, 1);
4258 memprintf(err, "'%s' is not a function", args[*cur_arg]);
4259 return 0;
4260 }
4261
4262 /* Reference the Lua function and store the reference. */
4263 rule->fcn.function_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
4264 rule->fcn.name = strdup(args[*cur_arg]);
4265 if (!rule->fcn.name) {
4266 memprintf(err, "out of memory error.");
4267 return 0;
4268 }
4269 (*cur_arg)++;
4270
4271 /* TODO: later accept arguments. */
4272 rule->args = NULL;
4273
4274 return 1;
4275}
4276
4277/* This function is a wrapper to execute each LUA function declared
4278 * as an action wrapper during the initialisation period. This function
4279 * return 1 if the processing is finished (with oe without error) and
4280 * return 0 if the function must be called again because the LUA
4281 * returns a yield.
4282 */
4283static int hlua_request_act_wrapper(struct hlua_rule *rule, struct proxy *px,
Willy Tarreaufdcd2ae2015-04-04 01:11:28 +02004284 struct stream *s, unsigned int analyzer)
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004285{
4286 char **arg;
4287
Willy Tarreau87b09662015-04-03 00:22:06 +02004288 /* In the execution wrappers linked with a stream, the
Thierry FOURNIER05ac4242015-02-27 18:37:27 +01004289 * Lua context can be not initialized. This behavior
4290 * permits to save performances because a systematic
4291 * Lua initialization cause 5% performances loss.
4292 */
4293 if (!s->hlua.T && !hlua_ctx_init(&s->hlua, s->task)) {
4294 send_log(px, LOG_ERR, "Lua action '%s': can't initialize Lua context.", rule->fcn.name);
4295 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4296 Alert("Lua action '%s': can't initialize Lua context.\n", rule->fcn.name);
4297 return 0;
4298 }
4299
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004300 /* If it is the first run, initialize the data for the call. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01004301 if (!HLUA_IS_RUNNING(&s->hlua)) {
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004302 /* Check stack available size. */
4303 if (!lua_checkstack(s->hlua.T, 1)) {
4304 send_log(px, LOG_ERR, "Lua function '%s': full stack.", rule->fcn.name);
4305 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4306 Alert("Lua function '%s': full stack.\n", rule->fcn.name);
4307 return 0;
4308 }
4309
4310 /* Restore the function in the stack. */
4311 lua_rawgeti(s->hlua.T, LUA_REGISTRYINDEX, rule->fcn.function_ref);
4312
Willy Tarreau87b09662015-04-03 00:22:06 +02004313 /* Create and and push object stream in the stack. */
Willy Tarreau15e91e12015-04-04 00:52:09 +02004314 if (!hlua_txn_new(s->hlua.T, s, px)) {
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004315 send_log(px, LOG_ERR, "Lua function '%s': full stack.", rule->fcn.name);
4316 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4317 Alert("Lua function '%s': full stack.\n", rule->fcn.name);
4318 return 0;
4319 }
4320 s->hlua.nargs = 1;
4321
4322 /* push keywords in the stack. */
4323 for (arg = rule->args; arg && *arg; arg++) {
4324 if (!lua_checkstack(s->hlua.T, 1)) {
4325 send_log(px, LOG_ERR, "Lua function '%s': full stack.", rule->fcn.name);
4326 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4327 Alert("Lua function '%s': full stack.\n", rule->fcn.name);
4328 return 0;
4329 }
4330 lua_pushstring(s->hlua.T, *arg);
4331 s->hlua.nargs++;
4332 }
4333
Thierry FOURNIERbd413492015-03-03 16:52:26 +01004334 /* We must initialize the execution timeouts. */
4335 s->hlua.expire = tick_add(now_ms, hlua_timeout_session);
4336
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004337 /* Set the currently running flag. */
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01004338 HLUA_SET_RUN(&s->hlua);
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004339 }
4340
4341 /* Execute the function. */
4342 switch (hlua_ctx_resume(&s->hlua, 1)) {
4343 /* finished. */
4344 case HLUA_E_OK:
4345 return 1;
4346
4347 /* yield. */
4348 case HLUA_E_AGAIN:
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01004349 /* Set timeout in the required channel. */
4350 if (s->hlua.wake_time != TICK_ETERNITY) {
4351 if (analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE))
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01004352 s->req.analyse_exp = s->hlua.wake_time;
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01004353 else if (analyzer & (AN_RES_INSPECT|AN_RES_HTTP_PROCESS_BE))
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01004354 s->res.analyse_exp = s->hlua.wake_time;
Thierry FOURNIERc42c1ae2015-03-03 17:17:55 +01004355 }
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004356 /* Some actions can be wake up when a "write" event
4357 * is detected on a response channel. This is useful
4358 * only for actions targetted on the requests.
4359 */
Thierry FOURNIERef6a2112015-03-05 17:45:34 +01004360 if (HLUA_IS_WAKERESWR(&s->hlua)) {
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01004361 s->res.flags |= CF_WAKE_WRITE;
Willy Tarreau76bd97f2015-03-10 17:16:10 +01004362 if ((analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE)))
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01004363 s->res.analysers |= analyzer;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004364 }
Thierry FOURNIER53e08ec2015-03-06 00:35:53 +01004365 if (HLUA_IS_WAKEREQWR(&s->hlua))
Willy Tarreau22ec1ea2014-11-27 20:45:39 +01004366 s->req.flags |= CF_WAKE_WRITE;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004367 return 0;
4368
4369 /* finished with error. */
4370 case HLUA_E_ERRMSG:
4371 /* Display log. */
4372 send_log(px, LOG_ERR, "Lua function '%s': %s.", rule->fcn.name, lua_tostring(s->hlua.T, -1));
4373 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4374 Alert("Lua function '%s': %s.\n", rule->fcn.name, lua_tostring(s->hlua.T, -1));
4375 lua_pop(s->hlua.T, 1);
4376 return 1;
4377
4378 case HLUA_E_ERR:
4379 /* Display log. */
4380 send_log(px, LOG_ERR, "Lua function '%s' return an unknown error.", rule->fcn.name);
4381 if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
4382 Alert("Lua function '%s' return an unknown error.\n", rule->fcn.name);
4383
4384 default:
4385 return 1;
4386 }
4387}
4388
4389/* Lua execution wrapper for "tcp-request". This function uses
4390 * "hlua_request_act_wrapper" for executing the LUA code.
4391 */
4392int hlua_tcp_req_act_wrapper(struct tcp_rule *tcp_rule, struct proxy *px,
Willy Tarreau87b09662015-04-03 00:22:06 +02004393 struct stream *s)
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004394{
Thierry FOURNIERfbdb7752015-06-03 19:32:04 +02004395 return hlua_request_act_wrapper((struct hlua_rule *)tcp_rule->act_prm.data[0],
Willy Tarreaufdcd2ae2015-04-04 01:11:28 +02004396 px, s, AN_REQ_INSPECT_FE);
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004397}
4398
4399/* Lua execution wrapper for "tcp-response". This function uses
4400 * "hlua_request_act_wrapper" for executing the LUA code.
4401 */
4402int hlua_tcp_res_act_wrapper(struct tcp_rule *tcp_rule, struct proxy *px,
Willy Tarreau87b09662015-04-03 00:22:06 +02004403 struct stream *s)
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004404{
Thierry FOURNIERfbdb7752015-06-03 19:32:04 +02004405 return hlua_request_act_wrapper((struct hlua_rule *)tcp_rule->act_prm.data[0],
Willy Tarreaufdcd2ae2015-04-04 01:11:28 +02004406 px, s, AN_RES_INSPECT);
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004407}
4408
4409/* Lua execution wrapper for http-request.
4410 * This function uses "hlua_request_act_wrapper" for executing
4411 * the LUA code.
4412 */
4413int hlua_http_req_act_wrapper(struct http_req_rule *rule, struct proxy *px,
Willy Tarreau987e3fb2015-04-04 01:09:08 +02004414 struct stream *s)
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004415{
4416 return hlua_request_act_wrapper((struct hlua_rule *)rule->arg.data, px,
Willy Tarreaufdcd2ae2015-04-04 01:11:28 +02004417 s, AN_REQ_HTTP_PROCESS_FE);
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004418}
4419
4420/* Lua execution wrapper for http-response.
4421 * This function uses "hlua_request_act_wrapper" for executing
4422 * the LUA code.
4423 */
4424int hlua_http_res_act_wrapper(struct http_res_rule *rule, struct proxy *px,
Willy Tarreau987e3fb2015-04-04 01:09:08 +02004425 struct stream *s)
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004426{
4427 return hlua_request_act_wrapper((struct hlua_rule *)rule->arg.data, px,
Willy Tarreaufdcd2ae2015-04-04 01:11:28 +02004428 s, AN_RES_HTTP_PROCESS_BE);
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004429}
4430
4431/* tcp-request <*> configuration wrapper. */
4432static int tcp_req_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
4433 struct tcp_rule *rule, char **err)
4434{
Thierry FOURNIERfbdb7752015-06-03 19:32:04 +02004435 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->act_prm.data[0], err))
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01004436 return 0;
Thierry FOURNIER79318d72015-05-29 17:31:12 +02004437 rule->action = TCP_ACT_CUSTOM_CONT;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004438 rule->action_ptr = hlua_tcp_req_act_wrapper;
4439 return 1;
4440}
4441
4442/* tcp-response <*> configuration wrapper. */
4443static int tcp_res_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
4444 struct tcp_rule *rule, char **err)
4445{
Thierry FOURNIERfbdb7752015-06-03 19:32:04 +02004446 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->act_prm.data[0], err))
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01004447 return 0;
Thierry FOURNIER79318d72015-05-29 17:31:12 +02004448 rule->action = TCP_ACT_CUSTOM_CONT;
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004449 rule->action_ptr = hlua_tcp_res_act_wrapper;
4450 return 1;
4451}
4452
4453/* http-request <*> configuration wrapper. */
4454static int http_req_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
4455 struct http_req_rule *rule, char **err)
4456{
4457 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->arg.data, err))
4458 return -1;
4459 rule->action = HTTP_REQ_ACT_CUSTOM_CONT;
4460 rule->action_ptr = hlua_http_req_act_wrapper;
4461 return 1;
4462}
4463
4464/* http-response <*> configuration wrapper. */
4465static int http_res_action_register_lua(const char **args, int *cur_arg, struct proxy *px,
4466 struct http_res_rule *rule, char **err)
4467{
4468 if (!hlua_parse_rule(args, cur_arg, px, (struct hlua_rule **)&rule->arg.data, err))
4469 return -1;
4470 rule->action = HTTP_RES_ACT_CUSTOM_CONT;
4471 rule->action_ptr = hlua_http_res_act_wrapper;
4472 return 1;
4473}
4474
Thierry FOURNIERbd413492015-03-03 16:52:26 +01004475static int hlua_read_timeout(char **args, int section_type, struct proxy *curpx,
4476 struct proxy *defpx, const char *file, int line,
4477 char **err, unsigned int *timeout)
4478{
4479 const char *error;
4480
4481 error = parse_time_err(args[1], timeout, TIME_UNIT_MS);
4482 if (error && *error != '\0') {
4483 memprintf(err, "%s: invalid timeout", args[0]);
4484 return -1;
4485 }
4486 return 0;
4487}
4488
4489static int hlua_session_timeout(char **args, int section_type, struct proxy *curpx,
4490 struct proxy *defpx, const char *file, int line,
4491 char **err)
4492{
4493 return hlua_read_timeout(args, section_type, curpx, defpx,
4494 file, line, err, &hlua_timeout_session);
4495}
4496
4497static int hlua_task_timeout(char **args, int section_type, struct proxy *curpx,
4498 struct proxy *defpx, const char *file, int line,
4499 char **err)
4500{
4501 return hlua_read_timeout(args, section_type, curpx, defpx,
4502 file, line, err, &hlua_timeout_task);
4503}
4504
Thierry FOURNIERee9f8022015-03-03 17:37:37 +01004505static int hlua_forced_yield(char **args, int section_type, struct proxy *curpx,
4506 struct proxy *defpx, const char *file, int line,
4507 char **err)
4508{
4509 char *error;
4510
4511 hlua_nb_instruction = strtoll(args[1], &error, 10);
4512 if (*error != '\0') {
4513 memprintf(err, "%s: invalid number", args[0]);
4514 return -1;
4515 }
4516 return 0;
4517}
4518
Willy Tarreau32f61e22015-03-18 17:54:59 +01004519static int hlua_parse_maxmem(char **args, int section_type, struct proxy *curpx,
4520 struct proxy *defpx, const char *file, int line,
4521 char **err)
4522{
4523 char *error;
4524
4525 if (*(args[1]) == 0) {
4526 memprintf(err, "'%s' expects an integer argument (Lua memory size in MB).\n", args[0]);
4527 return -1;
4528 }
4529 hlua_global_allocator.limit = strtoll(args[1], &error, 10) * 1024L * 1024L;
4530 if (*error != '\0') {
4531 memprintf(err, "%s: invalid number %s (error at '%c')", args[0], args[1], *error);
4532 return -1;
4533 }
4534 return 0;
4535}
4536
4537
Thierry FOURNIER6c9b52c2015-01-23 15:57:06 +01004538/* This function is called by the main configuration key "lua-load". It loads and
4539 * execute an lua file during the parsing of the HAProxy configuration file. It is
4540 * the main lua entry point.
4541 *
4542 * This funtion runs with the HAProxy keywords API. It returns -1 if an error is
4543 * occured, otherwise it returns 0.
4544 *
4545 * In some error case, LUA set an error message in top of the stack. This function
4546 * returns this error message in the HAProxy logs and pop it from the stack.
4547 */
4548static int hlua_load(char **args, int section_type, struct proxy *curpx,
4549 struct proxy *defpx, const char *file, int line,
4550 char **err)
4551{
4552 int error;
4553
4554 /* Just load and compile the file. */
4555 error = luaL_loadfile(gL.T, args[1]);
4556 if (error) {
4557 memprintf(err, "error in lua file '%s': %s", args[1], lua_tostring(gL.T, -1));
4558 lua_pop(gL.T, 1);
4559 return -1;
4560 }
4561
4562 /* If no syntax error where detected, execute the code. */
4563 error = lua_pcall(gL.T, 0, LUA_MULTRET, 0);
4564 switch (error) {
4565 case LUA_OK:
4566 break;
4567 case LUA_ERRRUN:
4568 memprintf(err, "lua runtime error: %s\n", lua_tostring(gL.T, -1));
4569 lua_pop(gL.T, 1);
4570 return -1;
4571 case LUA_ERRMEM:
4572 memprintf(err, "lua out of memory error\n");
4573 return -1;
4574 case LUA_ERRERR:
4575 memprintf(err, "lua message handler error: %s\n", lua_tostring(gL.T, -1));
4576 lua_pop(gL.T, 1);
4577 return -1;
4578 case LUA_ERRGCMM:
4579 memprintf(err, "lua garbage collector error: %s\n", lua_tostring(gL.T, -1));
4580 lua_pop(gL.T, 1);
4581 return -1;
4582 default:
4583 memprintf(err, "lua unknonwn error: %s\n", lua_tostring(gL.T, -1));
4584 lua_pop(gL.T, 1);
4585 return -1;
4586 }
4587
4588 return 0;
4589}
4590
4591/* configuration keywords declaration */
4592static struct cfg_kw_list cfg_kws = {{ },{
Thierry FOURNIERbd413492015-03-03 16:52:26 +01004593 { CFG_GLOBAL, "lua-load", hlua_load },
4594 { CFG_GLOBAL, "tune.lua.session-timeout", hlua_session_timeout },
4595 { CFG_GLOBAL, "tune.lua.task-timeout", hlua_task_timeout },
Thierry FOURNIERee9f8022015-03-03 17:37:37 +01004596 { CFG_GLOBAL, "tune.lua.forced-yield", hlua_forced_yield },
Willy Tarreau32f61e22015-03-18 17:54:59 +01004597 { CFG_GLOBAL, "tune.lua.maxmem", hlua_parse_maxmem },
Thierry FOURNIER6c9b52c2015-01-23 15:57:06 +01004598 { 0, NULL, NULL },
4599}};
4600
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004601static struct http_req_action_kw_list http_req_kws = {"lua", { }, {
4602 { "lua", http_req_action_register_lua },
4603 { NULL, NULL }
4604}};
4605
4606static struct http_res_action_kw_list http_res_kws = {"lua", { }, {
4607 { "lua", http_res_action_register_lua },
4608 { NULL, NULL }
4609}};
4610
4611static struct tcp_action_kw_list tcp_req_cont_kws = {"lua", { }, {
4612 { "lua", tcp_req_action_register_lua },
4613 { NULL, NULL }
4614}};
4615
4616static struct tcp_action_kw_list tcp_res_cont_kws = {"lua", { }, {
4617 { "lua", tcp_res_action_register_lua },
4618 { NULL, NULL }
4619}};
4620
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01004621int hlua_post_init()
4622{
4623 struct hlua_init_function *init;
4624 const char *msg;
4625 enum hlua_exec ret;
4626
4627 list_for_each_entry(init, &hlua_init_functions, l) {
4628 lua_rawgeti(gL.T, LUA_REGISTRYINDEX, init->function_ref);
4629 ret = hlua_ctx_resume(&gL, 0);
4630 switch (ret) {
4631 case HLUA_E_OK:
4632 lua_pop(gL.T, -1);
4633 return 1;
4634 case HLUA_E_AGAIN:
4635 Alert("lua init: yield not allowed.\n");
4636 return 0;
4637 case HLUA_E_ERRMSG:
4638 msg = lua_tostring(gL.T, -1);
4639 Alert("lua init: %s.\n", msg);
4640 return 0;
4641 case HLUA_E_ERR:
4642 default:
4643 Alert("lua init: unknown runtime error.\n");
4644 return 0;
4645 }
4646 }
4647 return 1;
4648}
4649
Willy Tarreau32f61e22015-03-18 17:54:59 +01004650/* The memory allocator used by the Lua stack. <ud> is a pointer to the
4651 * allocator's context. <ptr> is the pointer to alloc/free/realloc. <osize>
4652 * is the previously allocated size or the kind of object in case of a new
4653 * allocation. <nsize> is the requested new size.
4654 */
4655static void *hlua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
4656{
4657 struct hlua_mem_allocator *zone = ud;
4658
4659 if (nsize == 0) {
4660 /* it's a free */
4661 if (ptr)
4662 zone->allocated -= osize;
4663 free(ptr);
4664 return NULL;
4665 }
4666
4667 if (!ptr) {
4668 /* it's a new allocation */
4669 if (zone->limit && zone->allocated + nsize > zone->limit)
4670 return NULL;
4671
4672 ptr = malloc(nsize);
4673 if (ptr)
4674 zone->allocated += nsize;
4675 return ptr;
4676 }
4677
4678 /* it's a realloc */
4679 if (zone->limit && zone->allocated + nsize - osize > zone->limit)
4680 return NULL;
4681
4682 ptr = realloc(ptr, nsize);
4683 if (ptr)
4684 zone->allocated += nsize - osize;
4685 return ptr;
4686}
4687
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +01004688void hlua_init(void)
4689{
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004690 int i;
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01004691 int idx;
4692 struct sample_fetch *sf;
Thierry FOURNIER594afe72015-03-10 23:58:30 +01004693 struct sample_conv *sc;
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01004694 char *p;
Willy Tarreau80f5fae2015-02-27 16:38:20 +01004695#ifdef USE_OPENSSL
Willy Tarreau80f5fae2015-02-27 16:38:20 +01004696 struct srv_kw *kw;
4697 int tmp_error;
4698 char *error;
Thierry FOURNIER36d13742015-03-17 16:48:53 +01004699 char *args[] = { /* SSL client configuration. */
4700 "ssl",
4701 "verify",
4702 "none",
4703 "force-sslv3",
4704 NULL
4705 };
Willy Tarreau80f5fae2015-02-27 16:38:20 +01004706#endif
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004707
Willy Tarreau87b09662015-04-03 00:22:06 +02004708 /* Initialise com signals pool */
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01004709 pool2_hlua_com = create_pool("hlua_com", sizeof(struct hlua_com), MEM_F_SHARED);
4710
Thierry FOURNIER6c9b52c2015-01-23 15:57:06 +01004711 /* Register configuration keywords. */
4712 cfg_register_keywords(&cfg_kws);
4713
Thierry FOURNIER258d8aa2015-02-16 20:23:40 +01004714 /* Register custom HTTP rules. */
4715 http_req_keywords_register(&http_req_kws);
4716 http_res_keywords_register(&http_res_kws);
4717 tcp_req_cont_keywords_register(&tcp_req_cont_kws);
4718 tcp_res_cont_keywords_register(&tcp_res_cont_kws);
4719
Thierry FOURNIER380d0932015-01-23 14:27:52 +01004720 /* Init main lua stack. */
4721 gL.Mref = LUA_REFNIL;
Thierry FOURNIERa097fdf2015-03-03 15:17:35 +01004722 gL.flags = 0;
Thierry FOURNIER9ff7e6e2015-01-23 11:08:20 +01004723 LIST_INIT(&gL.com);
Thierry FOURNIER380d0932015-01-23 14:27:52 +01004724 gL.T = luaL_newstate();
4725 hlua_sethlua(&gL);
4726 gL.Tref = LUA_REFNIL;
4727 gL.task = NULL;
4728
Willy Tarreau32f61e22015-03-18 17:54:59 +01004729 /* change the memory allocators to track memory usage */
4730 lua_setallocf(gL.T, hlua_alloc, &hlua_global_allocator);
4731
Thierry FOURNIER380d0932015-01-23 14:27:52 +01004732 /* Initialise lua. */
4733 luaL_openlibs(gL.T);
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004734
4735 /*
4736 *
4737 * Create "core" object.
4738 *
4739 */
4740
Thierry FOURNIERa2d8c652015-03-11 17:29:39 +01004741 /* This table entry is the object "core" base. */
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004742 lua_newtable(gL.T);
4743
4744 /* Push the loglevel constants. */
Willy Tarreau80f5fae2015-02-27 16:38:20 +01004745 for (i = 0; i < NB_LOG_LEVELS; i++)
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004746 hlua_class_const_int(gL.T, log_levels[i], i);
4747
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01004748 /* Register special functions. */
4749 hlua_class_function(gL.T, "register_init", hlua_register_init);
Thierry FOURNIER24f33532015-01-23 12:13:00 +01004750 hlua_class_function(gL.T, "register_task", hlua_register_task);
Thierry FOURNIERfa0e5dd2015-02-16 20:19:18 +01004751 hlua_class_function(gL.T, "register_fetches", hlua_register_fetches);
Thierry FOURNIER9be813f2015-02-16 20:21:12 +01004752 hlua_class_function(gL.T, "register_converters", hlua_register_converters);
Thierry FOURNIER13416fe2015-02-17 15:01:59 +01004753 hlua_class_function(gL.T, "yield", hlua_yield);
Willy Tarreau59551662015-03-10 14:23:13 +01004754 hlua_class_function(gL.T, "set_nice", hlua_set_nice);
Thierry FOURNIER5b8608f2015-02-16 19:43:25 +01004755 hlua_class_function(gL.T, "sleep", hlua_sleep);
4756 hlua_class_function(gL.T, "msleep", hlua_msleep);
Thierry FOURNIER83758bb2015-02-04 13:21:04 +01004757 hlua_class_function(gL.T, "add_acl", hlua_add_acl);
4758 hlua_class_function(gL.T, "del_acl", hlua_del_acl);
4759 hlua_class_function(gL.T, "set_map", hlua_set_map);
4760 hlua_class_function(gL.T, "del_map", hlua_del_map);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01004761 hlua_class_function(gL.T, "tcp", hlua_socket_new);
Thierry FOURNIERc798b5d2015-03-17 01:09:57 +01004762 hlua_class_function(gL.T, "log", hlua_log);
4763 hlua_class_function(gL.T, "Debug", hlua_log_debug);
4764 hlua_class_function(gL.T, "Info", hlua_log_info);
4765 hlua_class_function(gL.T, "Warning", hlua_log_warning);
4766 hlua_class_function(gL.T, "Alert", hlua_log_alert);
Thierry FOURNIERa4a0f3d2015-01-23 12:08:30 +01004767
Thierry FOURNIER2ba18a22015-01-23 14:07:08 +01004768 lua_setglobal(gL.T, "core");
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01004769
4770 /*
4771 *
Thierry FOURNIER3def3932015-04-07 11:27:54 +02004772 * Register class Map
4773 *
4774 */
4775
4776 /* This table entry is the object "Map" base. */
4777 lua_newtable(gL.T);
4778
4779 /* register pattern types. */
4780 for (i=0; i<PAT_MATCH_NUM; i++)
4781 hlua_class_const_int(gL.T, pat_match_names[i], i);
4782
4783 /* register constructor. */
4784 hlua_class_function(gL.T, "new", hlua_map_new);
4785
4786 /* Create and fill the metatable. */
4787 lua_newtable(gL.T);
4788
4789 /* Create and fille the __index entry. */
4790 lua_pushstring(gL.T, "__index");
4791 lua_newtable(gL.T);
4792
4793 /* Register . */
4794 hlua_class_function(gL.T, "lookup", hlua_map_lookup);
4795 hlua_class_function(gL.T, "slookup", hlua_map_slookup);
4796
4797 lua_settable(gL.T, -3);
4798
4799 /* Register previous table in the registry with reference and named entry. */
4800 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4801 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4802 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_MAP); /* register class session. */
4803 class_map_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
4804
4805 /* Assign the metatable to the mai Map object. */
4806 lua_setmetatable(gL.T, -2);
4807
4808 /* Set a name to the table. */
4809 lua_setglobal(gL.T, "Map");
4810
4811 /*
4812 *
Thierry FOURNIER5a6d3fd2015-02-09 16:38:34 +01004813 * Register class Channel
4814 *
4815 */
4816
4817 /* Create and fill the metatable. */
4818 lua_newtable(gL.T);
4819
4820 /* Create and fille the __index entry. */
4821 lua_pushstring(gL.T, "__index");
4822 lua_newtable(gL.T);
4823
4824 /* Register . */
4825 hlua_class_function(gL.T, "get", hlua_channel_get);
4826 hlua_class_function(gL.T, "dup", hlua_channel_dup);
4827 hlua_class_function(gL.T, "getline", hlua_channel_getline);
4828 hlua_class_function(gL.T, "set", hlua_channel_set);
4829 hlua_class_function(gL.T, "append", hlua_channel_append);
4830 hlua_class_function(gL.T, "send", hlua_channel_send);
4831 hlua_class_function(gL.T, "forward", hlua_channel_forward);
4832 hlua_class_function(gL.T, "get_in_len", hlua_channel_get_in_len);
4833 hlua_class_function(gL.T, "get_out_len", hlua_channel_get_out_len);
4834
4835 lua_settable(gL.T, -3);
4836
4837 /* Register previous table in the registry with reference and named entry. */
4838 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4839 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_CHANNEL); /* register class session. */
4840 class_channel_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
4841
4842 /*
4843 *
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01004844 * Register class Fetches
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01004845 *
4846 */
4847
4848 /* Create and fill the metatable. */
4849 lua_newtable(gL.T);
4850
4851 /* Create and fille the __index entry. */
4852 lua_pushstring(gL.T, "__index");
4853 lua_newtable(gL.T);
4854
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01004855 /* Browse existing fetches and create the associated
4856 * object method.
4857 */
4858 sf = NULL;
4859 while ((sf = sample_fetch_getnext(sf, &idx)) != NULL) {
4860
4861 /* Dont register the keywork if the arguments check function are
4862 * not safe during the runtime.
4863 */
4864 if ((sf->val_args != NULL) &&
4865 (sf->val_args != val_payload_lv) &&
4866 (sf->val_args != val_hdr))
4867 continue;
4868
4869 /* gL.Tua doesn't support '.' and '-' in the function names, replace it
4870 * by an underscore.
4871 */
4872 strncpy(trash.str, sf->kw, trash.size);
4873 trash.str[trash.size - 1] = '\0';
4874 for (p = trash.str; *p; p++)
4875 if (*p == '.' || *p == '-' || *p == '+')
4876 *p = '_';
4877
4878 /* Register the function. */
4879 lua_pushstring(gL.T, trash.str);
Willy Tarreau2ec22742015-03-10 14:27:20 +01004880 lua_pushlightuserdata(gL.T, sf);
Thierry FOURNIERd0fa5382015-02-16 20:14:51 +01004881 lua_pushcclosure(gL.T, hlua_run_sample_fetch, 1);
4882 lua_settable(gL.T, -3);
4883 }
4884
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01004885 lua_settable(gL.T, -3);
4886
4887 /* Register previous table in the registry with reference and named entry. */
4888 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4889 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_FETCHES); /* register class session. */
4890 class_fetches_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
4891
4892 /*
4893 *
Thierry FOURNIER594afe72015-03-10 23:58:30 +01004894 * Register class Converters
4895 *
4896 */
4897
4898 /* Create and fill the metatable. */
4899 lua_newtable(gL.T);
4900
4901 /* Create and fill the __index entry. */
4902 lua_pushstring(gL.T, "__index");
4903 lua_newtable(gL.T);
4904
4905 /* Browse existing converters and create the associated
4906 * object method.
4907 */
4908 sc = NULL;
4909 while ((sc = sample_conv_getnext(sc, &idx)) != NULL) {
4910 /* Dont register the keywork if the arguments check function are
4911 * not safe during the runtime.
4912 */
4913 if (sc->val_args != NULL)
4914 continue;
4915
4916 /* gL.Tua doesn't support '.' and '-' in the function names, replace it
4917 * by an underscore.
4918 */
4919 strncpy(trash.str, sc->kw, trash.size);
4920 trash.str[trash.size - 1] = '\0';
4921 for (p = trash.str; *p; p++)
4922 if (*p == '.' || *p == '-' || *p == '+')
4923 *p = '_';
4924
4925 /* Register the function. */
4926 lua_pushstring(gL.T, trash.str);
4927 lua_pushlightuserdata(gL.T, sc);
4928 lua_pushcclosure(gL.T, hlua_run_sample_conv, 1);
4929 lua_settable(gL.T, -3);
4930 }
4931
4932 lua_settable(gL.T, -3);
4933
4934 /* Register previous table in the registry with reference and named entry. */
4935 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4936 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_CONVERTERS); /* register class session. */
4937 class_converters_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
4938
4939 /*
4940 *
Thierry FOURNIER08504f42015-03-16 14:17:08 +01004941 * Register class HTTP
4942 *
4943 */
4944
4945 /* Create and fill the metatable. */
4946 lua_newtable(gL.T);
4947
4948 /* Create and fille the __index entry. */
4949 lua_pushstring(gL.T, "__index");
4950 lua_newtable(gL.T);
4951
4952 /* Register Lua functions. */
4953 hlua_class_function(gL.T, "req_get_headers",hlua_http_req_get_headers);
4954 hlua_class_function(gL.T, "req_del_header", hlua_http_req_del_hdr);
4955 hlua_class_function(gL.T, "req_rep_header", hlua_http_req_rep_hdr);
4956 hlua_class_function(gL.T, "req_rep_value", hlua_http_req_rep_val);
4957 hlua_class_function(gL.T, "req_add_header", hlua_http_req_add_hdr);
4958 hlua_class_function(gL.T, "req_set_header", hlua_http_req_set_hdr);
4959 hlua_class_function(gL.T, "req_set_method", hlua_http_req_set_meth);
4960 hlua_class_function(gL.T, "req_set_path", hlua_http_req_set_path);
4961 hlua_class_function(gL.T, "req_set_query", hlua_http_req_set_query);
4962 hlua_class_function(gL.T, "req_set_uri", hlua_http_req_set_uri);
4963
4964 hlua_class_function(gL.T, "res_get_headers",hlua_http_res_get_headers);
4965 hlua_class_function(gL.T, "res_del_header", hlua_http_res_del_hdr);
4966 hlua_class_function(gL.T, "res_rep_header", hlua_http_res_rep_hdr);
4967 hlua_class_function(gL.T, "res_rep_value", hlua_http_res_rep_val);
4968 hlua_class_function(gL.T, "res_add_header", hlua_http_res_add_hdr);
4969 hlua_class_function(gL.T, "res_set_header", hlua_http_res_set_hdr);
4970
4971 lua_settable(gL.T, -3);
4972
4973 /* Register previous table in the registry with reference and named entry. */
4974 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
4975 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_HTTP); /* register class session. */
4976 class_http_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
4977
4978 /*
4979 *
Thierry FOURNIERbb53c7b2015-03-11 18:28:02 +01004980 * Register class TXN
4981 *
4982 */
4983
4984 /* Create and fill the metatable. */
4985 lua_newtable(gL.T);
4986
4987 /* Create and fille the __index entry. */
4988 lua_pushstring(gL.T, "__index");
4989 lua_newtable(gL.T);
4990
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01004991 /* Register Lua functions. */
Willy Tarreau59551662015-03-10 14:23:13 +01004992 hlua_class_function(gL.T, "set_priv", hlua_set_priv);
4993 hlua_class_function(gL.T, "get_priv", hlua_get_priv);
Thierry FOURNIER053ba8ad2015-06-08 13:05:33 +02004994 hlua_class_function(gL.T, "set_var", hlua_set_var);
4995 hlua_class_function(gL.T, "get_var", hlua_get_var);
Thierry FOURNIER893bfa32015-02-17 18:42:34 +01004996 hlua_class_function(gL.T, "close", hlua_txn_close);
Thierry FOURNIER2cce3532015-03-16 12:04:16 +01004997 hlua_class_function(gL.T, "set_loglevel",hlua_txn_set_loglevel);
4998 hlua_class_function(gL.T, "set_tos", hlua_txn_set_tos);
4999 hlua_class_function(gL.T, "set_mark", hlua_txn_set_mark);
Thierry FOURNIERc798b5d2015-03-17 01:09:57 +01005000 hlua_class_function(gL.T, "deflog", hlua_txn_deflog);
5001 hlua_class_function(gL.T, "log", hlua_txn_log);
5002 hlua_class_function(gL.T, "Debug", hlua_txn_log_debug);
5003 hlua_class_function(gL.T, "Info", hlua_txn_log_info);
5004 hlua_class_function(gL.T, "Warning", hlua_txn_log_warning);
5005 hlua_class_function(gL.T, "Alert", hlua_txn_log_alert);
Thierry FOURNIER05c0b8a2015-02-25 11:43:21 +01005006
Thierry FOURNIER65f34c62015-02-16 20:11:43 +01005007 lua_settable(gL.T, -3);
5008
5009 /* Register previous table in the registry with reference and named entry. */
5010 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
5011 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_TXN); /* register class session. */
5012 class_txn_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class session. */
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01005013
5014 /*
5015 *
5016 * Register class Socket
5017 *
5018 */
5019
5020 /* Create and fill the metatable. */
5021 lua_newtable(gL.T);
5022
5023 /* Create and fille the __index entry. */
5024 lua_pushstring(gL.T, "__index");
5025 lua_newtable(gL.T);
5026
Baptiste Assmann84bb4932015-03-02 21:40:06 +01005027#ifdef USE_OPENSSL
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01005028 hlua_class_function(gL.T, "connect_ssl", hlua_socket_connect_ssl);
Baptiste Assmann84bb4932015-03-02 21:40:06 +01005029#endif
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01005030 hlua_class_function(gL.T, "connect", hlua_socket_connect);
5031 hlua_class_function(gL.T, "send", hlua_socket_send);
5032 hlua_class_function(gL.T, "receive", hlua_socket_receive);
5033 hlua_class_function(gL.T, "close", hlua_socket_close);
5034 hlua_class_function(gL.T, "getpeername", hlua_socket_getpeername);
5035 hlua_class_function(gL.T, "getsockname", hlua_socket_getsockname);
5036 hlua_class_function(gL.T, "setoption", hlua_socket_setoption);
5037 hlua_class_function(gL.T, "settimeout", hlua_socket_settimeout);
5038
5039 lua_settable(gL.T, -3); /* Push the last 2 entries in the table at index -3 */
5040
5041 /* Register the garbage collector entry. */
5042 lua_pushstring(gL.T, "__gc");
5043 lua_pushcclosure(gL.T, hlua_socket_gc, 0);
5044 lua_settable(gL.T, -3); /* Push the last 2 entries in the table at index -3 */
5045
5046 /* Register previous table in the registry with reference and named entry. */
5047 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
5048 lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
5049 lua_setfield(gL.T, LUA_REGISTRYINDEX, CLASS_SOCKET); /* register class socket. */
5050 class_socket_ref = luaL_ref(gL.T, LUA_REGISTRYINDEX); /* reference class socket. */
5051
5052 /* Proxy and server configuration initialisation. */
5053 memset(&socket_proxy, 0, sizeof(socket_proxy));
5054 init_new_proxy(&socket_proxy);
5055 socket_proxy.parent = NULL;
5056 socket_proxy.last_change = now.tv_sec;
5057 socket_proxy.id = "LUA-SOCKET";
5058 socket_proxy.cap = PR_CAP_FE | PR_CAP_BE;
5059 socket_proxy.maxconn = 0;
5060 socket_proxy.accept = NULL;
5061 socket_proxy.options2 |= PR_O2_INDEPSTR;
5062 socket_proxy.srv = NULL;
5063 socket_proxy.conn_retries = 0;
5064 socket_proxy.timeout.connect = 5000; /* By default the timeout connection is 5s. */
5065
5066 /* Init TCP server: unchanged parameters */
5067 memset(&socket_tcp, 0, sizeof(socket_tcp));
5068 socket_tcp.next = NULL;
5069 socket_tcp.proxy = &socket_proxy;
5070 socket_tcp.obj_type = OBJ_TYPE_SERVER;
5071 LIST_INIT(&socket_tcp.actconns);
5072 LIST_INIT(&socket_tcp.pendconns);
5073 socket_tcp.state = SRV_ST_RUNNING; /* early server setup */
5074 socket_tcp.last_change = 0;
5075 socket_tcp.id = "LUA-TCP-CONN";
5076 socket_tcp.check.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
5077 socket_tcp.agent.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
5078 socket_tcp.pp_opts = 0; /* Remove proxy protocol. */
5079
5080 /* XXX: Copy default parameter from default server,
5081 * but the default server is not initialized.
5082 */
5083 socket_tcp.maxqueue = socket_proxy.defsrv.maxqueue;
5084 socket_tcp.minconn = socket_proxy.defsrv.minconn;
5085 socket_tcp.maxconn = socket_proxy.defsrv.maxconn;
5086 socket_tcp.slowstart = socket_proxy.defsrv.slowstart;
5087 socket_tcp.onerror = socket_proxy.defsrv.onerror;
5088 socket_tcp.onmarkeddown = socket_proxy.defsrv.onmarkeddown;
5089 socket_tcp.onmarkedup = socket_proxy.defsrv.onmarkedup;
5090 socket_tcp.consecutive_errors_limit = socket_proxy.defsrv.consecutive_errors_limit;
5091 socket_tcp.uweight = socket_proxy.defsrv.iweight;
5092 socket_tcp.iweight = socket_proxy.defsrv.iweight;
5093
5094 socket_tcp.check.status = HCHK_STATUS_INI;
5095 socket_tcp.check.rise = socket_proxy.defsrv.check.rise;
5096 socket_tcp.check.fall = socket_proxy.defsrv.check.fall;
5097 socket_tcp.check.health = socket_tcp.check.rise; /* socket, but will fall down at first failure */
5098 socket_tcp.check.server = &socket_tcp;
5099
5100 socket_tcp.agent.status = HCHK_STATUS_INI;
5101 socket_tcp.agent.rise = socket_proxy.defsrv.agent.rise;
5102 socket_tcp.agent.fall = socket_proxy.defsrv.agent.fall;
5103 socket_tcp.agent.health = socket_tcp.agent.rise; /* socket, but will fall down at first failure */
5104 socket_tcp.agent.server = &socket_tcp;
5105
5106 socket_tcp.xprt = &raw_sock;
5107
5108#ifdef USE_OPENSSL
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01005109 /* Init TCP server: unchanged parameters */
5110 memset(&socket_ssl, 0, sizeof(socket_ssl));
5111 socket_ssl.next = NULL;
5112 socket_ssl.proxy = &socket_proxy;
5113 socket_ssl.obj_type = OBJ_TYPE_SERVER;
5114 LIST_INIT(&socket_ssl.actconns);
5115 LIST_INIT(&socket_ssl.pendconns);
5116 socket_ssl.state = SRV_ST_RUNNING; /* early server setup */
5117 socket_ssl.last_change = 0;
5118 socket_ssl.id = "LUA-SSL-CONN";
5119 socket_ssl.check.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
5120 socket_ssl.agent.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
5121 socket_ssl.pp_opts = 0; /* Remove proxy protocol. */
5122
5123 /* XXX: Copy default parameter from default server,
5124 * but the default server is not initialized.
5125 */
5126 socket_ssl.maxqueue = socket_proxy.defsrv.maxqueue;
5127 socket_ssl.minconn = socket_proxy.defsrv.minconn;
5128 socket_ssl.maxconn = socket_proxy.defsrv.maxconn;
5129 socket_ssl.slowstart = socket_proxy.defsrv.slowstart;
5130 socket_ssl.onerror = socket_proxy.defsrv.onerror;
5131 socket_ssl.onmarkeddown = socket_proxy.defsrv.onmarkeddown;
5132 socket_ssl.onmarkedup = socket_proxy.defsrv.onmarkedup;
5133 socket_ssl.consecutive_errors_limit = socket_proxy.defsrv.consecutive_errors_limit;
5134 socket_ssl.uweight = socket_proxy.defsrv.iweight;
5135 socket_ssl.iweight = socket_proxy.defsrv.iweight;
5136
5137 socket_ssl.check.status = HCHK_STATUS_INI;
5138 socket_ssl.check.rise = socket_proxy.defsrv.check.rise;
5139 socket_ssl.check.fall = socket_proxy.defsrv.check.fall;
5140 socket_ssl.check.health = socket_ssl.check.rise; /* socket, but will fall down at first failure */
5141 socket_ssl.check.server = &socket_ssl;
5142
5143 socket_ssl.agent.status = HCHK_STATUS_INI;
5144 socket_ssl.agent.rise = socket_proxy.defsrv.agent.rise;
5145 socket_ssl.agent.fall = socket_proxy.defsrv.agent.fall;
5146 socket_ssl.agent.health = socket_ssl.agent.rise; /* socket, but will fall down at first failure */
5147 socket_ssl.agent.server = &socket_ssl;
5148
Thierry FOURNIER36d13742015-03-17 16:48:53 +01005149 socket_ssl.use_ssl = 1;
5150 socket_ssl.xprt = &ssl_sock;
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01005151
Thierry FOURNIER36d13742015-03-17 16:48:53 +01005152 for (idx = 0; args[idx] != NULL; idx++) {
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01005153 if ((kw = srv_find_kw(args[idx])) != NULL) { /* Maybe it's registered server keyword */
5154 /*
5155 *
5156 * If the keyword is not known, we can search in the registered
5157 * server keywords. This is usefull to configure special SSL
5158 * features like client certificates and ssl_verify.
5159 *
5160 */
5161 tmp_error = kw->parse(args, &idx, &socket_proxy, &socket_ssl, &error);
5162 if (tmp_error != 0) {
5163 fprintf(stderr, "INTERNAL ERROR: %s\n", error);
5164 abort(); /* This must be never arrives because the command line
5165 not editable by the user. */
5166 }
5167 idx += kw->skip;
5168 }
5169 }
5170
5171 /* Initialize SSL server. */
Thierry FOURNIER36d13742015-03-17 16:48:53 +01005172 ssl_sock_prepare_srv_ctx(&socket_ssl, &socket_proxy);
Thierry FOURNIER7e7ac322015-02-16 19:27:16 +01005173#endif
Thierry FOURNIER6f1fd482015-01-23 14:06:13 +01005174}