1 /*
2  * Lua safe functions
3  *
4  * Copyright 2015-2016 Thierry Fournier <tfournier@arpalert.org>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  *
11  *
12  * All the functions in this file runs with a Lua stack, and can
13  * return with a longjmp. All of these function must be launched
14  * in an environment able to catch a longjmp, otherwise a
15  * critical error can be raised.
16  */
17 #include <lauxlib.h>
18 #include <lua.h>
19 #include <lualib.h>
20 
21 #include <common/time.h>
22 #include <common/uri_auth.h>
23 
24 #include <types/cli.h>
25 #include <types/hlua.h>
26 #include <types/proxy.h>
27 #include <types/stats.h>
28 
29 #include <proto/proxy.h>
30 #include <proto/server.h>
31 #include <proto/stats.h>
32 #include <proto/stick_table.h>
33 
34 /* Contains the class reference of the concat object. */
35 static int class_concat_ref;
36 static int class_proxy_ref;
37 static int class_server_ref;
38 static int class_listener_ref;
39 static int class_regex_ref;
40 static int class_stktable_ref;
41 
42 #define MAX_STK_FILTER_LEN 4
43 #define STATS_LEN (MAX((int)ST_F_TOTAL_FIELDS, (int)INF_TOTAL_FIELDS))
44 
45 static THREAD_LOCAL struct field stats[STATS_LEN];
46 
hlua_checkboolean(lua_State * L,int index)47 int hlua_checkboolean(lua_State *L, int index)
48 {
49 	if (!lua_isboolean(L, index))
50 		luaL_argerror(L, index, "boolean expected");
51 	return lua_toboolean(L, index);
52 }
53 
54 /* Helper to push unsigned integers to Lua stack, respecting Lua limitations  */
hlua_fcn_pushunsigned(lua_State * L,unsigned int val)55 static int hlua_fcn_pushunsigned(lua_State *L, unsigned int val)
56 {
57 #if (LUA_MAXINTEGER == LLONG_MAX || ((LUA_MAXINTEGER == LONG_MAX) && (__WORDSIZE == 64)))
58 	lua_pushinteger(L, val);
59 #else
60 	if (val > INT_MAX)
61 		lua_pushnumber(L, (lua_Number)val);
62 	else
63 		lua_pushinteger(L, (int)val);
64 #endif
65 	return 1;
66 }
67 
68 /* Helper to push unsigned long long to Lua stack, respecting Lua limitations  */
hlua_fcn_pushunsigned_ll(lua_State * L,unsigned long long val)69 static int hlua_fcn_pushunsigned_ll(lua_State *L, unsigned long long val) {
70 #if (LUA_MAXINTEGER == LLONG_MAX || ((LUA_MAXINTEGER == LONG_MAX) && (__WORDSIZE == 64)))
71 	/* 64 bits case, U64 is supported until LLONG_MAX */
72 	if (val > LLONG_MAX)
73 		lua_pushnumber(L, (lua_Number)val);
74 	else
75 		lua_pushinteger(L, val);
76 #else
77 	/* 32 bits case, U64 is supported until INT_MAX */
78 	if (val > INT_MAX)
79 		lua_pushnumber(L, (lua_Number)val);
80 	else
81 		lua_pushinteger(L, (int)val);
82 #endif
83 	return 1;
84 }
85 
86 /* This function gets a struct field and converts it in Lua
87  * variable. The variable is pushed at the top of the stack.
88  */
hlua_fcn_pushfield(lua_State * L,struct field * field)89 int hlua_fcn_pushfield(lua_State *L, struct field *field)
90 {
91 	/* The lua_Integer is always signed. Its length depends on
92 	 * compilation options, so the following code is conditioned
93 	 * by some macros. Windows maros are not supported.
94 	 * If the number cannot be represented as integer, we try to
95 	 * convert to float.
96 	 */
97 	switch (field_format(field, 0)) {
98 
99 	case FF_EMPTY:
100 		lua_pushnil(L);
101 		return 1;
102 
103 	case FF_S32:
104 		/* S32 is always supported. */
105 		lua_pushinteger(L, field->u.s32);
106 		return 1;
107 
108 	case FF_U32:
109 #if (LUA_MAXINTEGER == LLONG_MAX || ((LUA_MAXINTEGER == LONG_MAX) && (__WORDSIZE == 64)))
110 		/* 64 bits case, U32 is always supported */
111 		lua_pushinteger(L, field->u.u32);
112 #else
113 		/* 32 bits case, U32 is supported until INT_MAX. */
114 		if (field->u.u32 > INT_MAX)
115 			lua_pushnumber(L, (lua_Number)field->u.u32);
116 		else
117 			lua_pushinteger(L, field->u.u32);
118 #endif
119 		return 1;
120 
121 	case FF_S64:
122 #if (LUA_MAXINTEGER == LLONG_MAX || ((LUA_MAXINTEGER == LONG_MAX) && (__WORDSIZE == 64)))
123 		/* 64 bits case, S64 is always supported */
124 		lua_pushinteger(L, field->u.s64);
125 #else
126 		/* 64 bits case, S64 is supported beetween INT_MIN and INT_MAX */
127 		if (field->u.s64 < INT_MIN || field->u.s64 > INT_MAX)
128 			lua_pushnumber(L, (lua_Number)field->u.s64);
129 		else
130 			lua_pushinteger(L, (int)field->u.s64);
131 #endif
132 		return 1;
133 
134 	case FF_U64:
135 #if (LUA_MAXINTEGER == LLONG_MAX || ((LUA_MAXINTEGER == LONG_MAX) && (__WORDSIZE == 64)))
136 		/* 64 bits case, U64 is supported until LLONG_MAX */
137 		if (field->u.u64 > LLONG_MAX)
138 			lua_pushnumber(L, (lua_Number)field->u.u64);
139 		else
140 			lua_pushinteger(L, field->u.u64);
141 #else
142 		/* 64 bits case, U64 is supported until INT_MAX */
143 		if (field->u.u64 > INT_MAX)
144 			lua_pushnumber(L, (lua_Number)field->u.u64);
145 		else
146 			lua_pushinteger(L, (int)field->u.u64);
147 #endif
148 		return 1;
149 
150 	case FF_STR:
151 		lua_pushstring(L, field->u.str);
152 		return 1;
153 
154 	default:
155 		break;
156 	}
157 
158 	/* Default case, never reached. */
159 	lua_pushnil(L);
160 	return 1;
161 }
162 
163 /* Some string are started or terminated by blank chars,
164  * this function removes the spaces, tabs, \r and
165  * \n at the begin and at the end of the string "str", and
166  * push the result in the lua stack.
167  * Returns a pointer to the Lua internal copy of the string.
168  */
hlua_pushstrippedstring(lua_State * L,const char * str)169 const char *hlua_pushstrippedstring(lua_State *L, const char *str)
170 {
171 	const char *p;
172 	const char *e;
173 
174 	for (p = str; HTTP_IS_LWS(*p); p++);
175 	for (e = p + strlen(p) - 1; e > p && HTTP_IS_LWS(*e); e--);
176 
177 	return lua_pushlstring(L, p, e - p);
178 }
179 
180 /* The three following functions are useful for adding entries
181  * in a table. These functions takes a string and respectively an
182  * integer, a string or a function and add it to the table in the
183  * top of the stack.
184  *
185  * These functions throws an error if no more stack size is
186  * available.
187  */
hlua_class_const_int(lua_State * L,const char * name,int value)188 void hlua_class_const_int(lua_State *L, const char *name, int value)
189 {
190 	lua_pushstring(L, name);
191 	lua_pushinteger(L, value);
192 	lua_rawset(L, -3);
193 }
hlua_class_const_str(lua_State * L,const char * name,const char * value)194 void hlua_class_const_str(lua_State *L, const char *name, const char *value)
195 {
196 	lua_pushstring(L, name);
197 	lua_pushstring(L, value);
198 	lua_rawset(L, -3);
199 }
hlua_class_function(lua_State * L,const char * name,int (* function)(lua_State * L))200 void hlua_class_function(lua_State *L, const char *name, int (*function)(lua_State *L))
201 {
202 	lua_pushstring(L, name);
203 	lua_pushcclosure(L, function, 0);
204 	lua_rawset(L, -3);
205 }
206 
207 /* This function returns a string containing the HAProxy object name. */
hlua_dump_object(struct lua_State * L)208 int hlua_dump_object(struct lua_State *L)
209 {
210 	const char *name = (const char *)lua_tostring(L, lua_upvalueindex(1));
211 	lua_pushfstring(L, "HAProxy class %s", name);
212 	return 1;
213 }
214 
215 /* This function register a table as metatable and. It names
216  * the metatable, and returns the associated reference.
217  * The original table is poped from the top of the stack.
218  * "name" is the referenced class name.
219  */
hlua_register_metatable(struct lua_State * L,char * name)220 int hlua_register_metatable(struct lua_State *L, char *name)
221 {
222 	/* Check the type of the top element. it must be
223 	 * a table.
224 	 */
225 	if (lua_type(L, -1) != LUA_TTABLE)
226 		luaL_error(L, "hlua_register_metatable() requires a type Table "
227 		              "in the top of the stack");
228 
229 	/* Add the __tostring function which identify the
230 	 * created object.
231 	 */
232 	lua_pushstring(L, "__tostring");
233 	lua_pushstring(L, name);
234 	lua_pushcclosure(L, hlua_dump_object, 1);
235 	lua_rawset(L, -3);
236 
237 	/* Register a named entry for the table. The table
238 	 * reference is copyed first because the function
239 	 * lua_setfield() pop the entry.
240 	 */
241 	lua_pushvalue(L, -1);
242 	lua_setfield(L, LUA_REGISTRYINDEX, name);
243 
244 	/* Creates the reference of the object. The
245 	 * function luaL_ref pop the top of the stack.
246 	 */
247 	return luaL_ref(L, LUA_REGISTRYINDEX);
248 }
249 
250 /* Return an object of the expected type, or throws an error. */
hlua_checkudata(lua_State * L,int ud,int class_ref)251 void *hlua_checkudata(lua_State *L, int ud, int class_ref)
252 {
253 	void *p;
254 	int ret;
255 
256 	/* Check if the stack entry is an array. */
257 	if (!lua_istable(L, ud))
258 		luaL_argerror(L, ud, NULL);
259 
260 	/* pop the metatable of the referencecd object. */
261 	if (!lua_getmetatable(L, ud))
262 		luaL_argerror(L, ud, NULL);
263 
264 	/* pop the expected metatable. */
265 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_ref);
266 
267 	/* Check if the metadata have the expected type. */
268 	ret = lua_rawequal(L, -1, -2);
269 	lua_pop(L, 2);
270 	if (!ret)
271 		luaL_argerror(L, ud, NULL);
272 
273 	/* Push on the stack at the entry [0] of the table. */
274 	lua_rawgeti(L, ud, 0);
275 
276 	/* Check if this entry is userdata. */
277 	p = lua_touserdata(L, -1);
278 	if (!p)
279 		luaL_argerror(L, ud, NULL);
280 
281 	/* Remove the entry returned by lua_rawgeti(). */
282 	lua_pop(L, 1);
283 
284 	/* Return the associated struct. */
285 	return p;
286 }
287 
288 /* This function return the current date at epoch format in milliseconds. */
hlua_now(lua_State * L)289 int hlua_now(lua_State *L)
290 {
291 	lua_newtable(L);
292 	lua_pushstring(L, "sec");
293 	lua_pushinteger(L, now.tv_sec);
294 	lua_rawset(L, -3);
295 	lua_pushstring(L, "usec");
296 	lua_pushinteger(L, now.tv_usec);
297 	lua_rawset(L, -3);
298 	return 1;
299 }
300 
301 /* This functions expects a Lua string as HTTP date, parse it and
302  * returns an integer containing the epoch format of the date, or
303  * nil if the parsing fails.
304  */
hlua_parse_date(lua_State * L,int (* fcn)(const char *,int,struct tm *))305 static int hlua_parse_date(lua_State *L, int (*fcn)(const char *, int, struct tm*))
306 {
307 	const char *str;
308 	size_t len;
309 	struct tm tm;
310 	time_t time;
311 
312 	str = luaL_checklstring(L, 1, &len);
313 
314 	if (!fcn(str, len, &tm)) {
315 		lua_pushnil(L);
316 		return 1;
317 	}
318 
319 	/* This function considers the content of the broken-down time
320 	 * is exprimed in the UTC timezone. timegm don't care about
321 	 * the gnu variable tm_gmtoff. If gmtoff is set, or if you know
322 	 * the timezone from the broken-down time, it must be fixed
323 	 * after the conversion.
324 	 */
325 	time = my_timegm(&tm);
326 	if (time == -1) {
327 		lua_pushnil(L);
328 		return 1;
329 	}
330 
331 	lua_pushinteger(L, (int)time);
332 	return 1;
333 }
hlua_http_date(lua_State * L)334 static int hlua_http_date(lua_State *L)
335 {
336 	return hlua_parse_date(L, parse_http_date);
337 }
hlua_imf_date(lua_State * L)338 static int hlua_imf_date(lua_State *L)
339 {
340 	return hlua_parse_date(L, parse_imf_date);
341 }
hlua_rfc850_date(lua_State * L)342 static int hlua_rfc850_date(lua_State *L)
343 {
344 	return hlua_parse_date(L, parse_rfc850_date);
345 }
hlua_asctime_date(lua_State * L)346 static int hlua_asctime_date(lua_State *L)
347 {
348 	return hlua_parse_date(L, parse_asctime_date);
349 }
350 
hlua_get_info(lua_State * L)351 static int hlua_get_info(lua_State *L)
352 {
353 	int i;
354 
355 	stats_fill_info(stats, STATS_LEN);
356 
357 	lua_newtable(L);
358 	for (i=0; i<INF_TOTAL_FIELDS; i++) {
359 		lua_pushstring(L, info_field_names[i]);
360 		hlua_fcn_pushfield(L, &stats[i]);
361 		lua_settable(L, -3);
362 	}
363 	return 1;
364 }
365 
hlua_check_concat(lua_State * L,int ud)366 static struct hlua_concat *hlua_check_concat(lua_State *L, int ud)
367 {
368 	return (hlua_checkudata(L, ud, class_concat_ref));
369 }
370 
hlua_concat_add(lua_State * L)371 static int hlua_concat_add(lua_State *L)
372 {
373 	struct hlua_concat *b;
374 	char *buffer;
375 	char *new;
376 	const char *str;
377 	size_t l;
378 
379 	/* First arg must be a concat object. */
380 	b = hlua_check_concat(L, 1);
381 
382 	/* Second arg must be a string. */
383 	str = luaL_checklstring(L, 2, &l);
384 
385 	/* Get the buffer. */
386 	lua_rawgeti(L, 1, 1);
387 	buffer = lua_touserdata(L, -1);
388 	lua_pop(L, 1);
389 
390 	/* Update the buffer size if it s required. The old buffer
391 	 * is crushed by the new in the object array, so it will
392 	 * be deleted by the GC.
393 	 * Note that in the first loop, the "new" variable is only
394 	 * used as a flag.
395 	 */
396 	new = NULL;
397 	while (b->size - b->len < l) {
398 		b->size += HLUA_CONCAT_BLOCSZ;
399 		new = buffer;
400 	}
401 	if (new) {
402 		new = lua_newuserdata(L, b->size);
403 		memcpy(new, buffer, b->len);
404 		lua_rawseti(L, 1, 1);
405 		buffer = new;
406 	}
407 
408 	/* Copy string, and update metadata. */
409 	memcpy(buffer + b->len, str, l);
410 	b->len += l;
411 	return 0;
412 }
413 
hlua_concat_dump(lua_State * L)414 static int hlua_concat_dump(lua_State *L)
415 {
416 	struct hlua_concat *b;
417 	char *buffer;
418 
419 	/* First arg must be a concat object. */
420 	b = hlua_check_concat(L, 1);
421 
422 	/* Get the buffer. */
423 	lua_rawgeti(L, 1, 1);
424 	buffer = lua_touserdata(L, -1);
425 	lua_pop(L, 1);
426 
427 	/* Push the soncatenated strng in the stack. */
428 	lua_pushlstring(L, buffer, b->len);
429 	return 1;
430 }
431 
hlua_concat_new(lua_State * L)432 int hlua_concat_new(lua_State *L)
433 {
434 	struct hlua_concat *b;
435 
436 	lua_newtable(L);
437 	b = lua_newuserdata(L, sizeof(*b));
438 	b->size = HLUA_CONCAT_BLOCSZ;
439 	b->len = 0;
440 	lua_rawseti(L, -2, 0);
441 	lua_newuserdata(L, HLUA_CONCAT_BLOCSZ);
442 	lua_rawseti(L, -2, 1);
443 
444 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_concat_ref);
445 	lua_setmetatable(L, -2);
446 
447 	return 1;
448 }
449 
concat_tostring(lua_State * L)450 static int concat_tostring(lua_State *L)
451 {
452 	const void *ptr = lua_topointer(L, 1);
453 	lua_pushfstring(L, "Concat object: %p", ptr);
454 	return 1;
455 }
456 
hlua_concat_init(lua_State * L)457 static int hlua_concat_init(lua_State *L)
458 {
459 	/* Creates the buffered concat object. */
460 	lua_newtable(L);
461 
462 	lua_pushstring(L, "__tostring");
463 	lua_pushcclosure(L, concat_tostring, 0);
464 	lua_settable(L, -3);
465 
466 	lua_pushstring(L, "__index"); /* Creates the index entry. */
467 	lua_newtable(L); /* The "__index" content. */
468 
469 	lua_pushstring(L, "add");
470 	lua_pushcclosure(L, hlua_concat_add, 0);
471 	lua_settable(L, -3);
472 
473 	lua_pushstring(L, "dump");
474 	lua_pushcclosure(L, hlua_concat_dump, 0);
475 	lua_settable(L, -3);
476 
477 	lua_settable(L, -3); /* Sets the __index entry. */
478 	class_concat_ref = luaL_ref(L, LUA_REGISTRYINDEX);
479 
480 	return 1;
481 }
482 
hlua_fcn_new_stktable(lua_State * L,struct stktable * tbl)483 int hlua_fcn_new_stktable(lua_State *L, struct stktable *tbl)
484 {
485 	lua_newtable(L);
486 
487 	/* Pop a class stktbl metatable and affect it to the userdata. */
488 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_stktable_ref);
489 	lua_setmetatable(L, -2);
490 
491 	lua_pushlightuserdata(L, tbl);
492 	lua_rawseti(L, -2, 0);
493 	return 1;
494 }
495 
hlua_check_stktable(lua_State * L,int ud)496 static struct stktable *hlua_check_stktable(lua_State *L, int ud)
497 {
498 	return hlua_checkudata(L, ud, class_stktable_ref);
499 }
500 
501 /* Extract stick table attributes into Lua table */
hlua_stktable_info(lua_State * L)502 int hlua_stktable_info(lua_State *L)
503 {
504 	struct stktable *tbl;
505 	int dt;
506 
507 	tbl = hlua_check_stktable(L, 1);
508 
509 	if (!tbl->id) {
510 		lua_pushnil(L);
511 		return 1;
512 	}
513 
514 	lua_newtable(L);
515 
516 	lua_pushstring(L, "type");
517 	lua_pushstring(L, stktable_types[tbl->type].kw);
518 	lua_settable(L, -3);
519 
520 	lua_pushstring(L, "length");
521 	lua_pushinteger(L, tbl->key_size);
522 	lua_settable(L, -3);
523 
524 	lua_pushstring(L, "size");
525 	hlua_fcn_pushunsigned(L, tbl->size);
526 	lua_settable(L, -3);
527 
528 	lua_pushstring(L, "used");
529 	hlua_fcn_pushunsigned(L, tbl->current);
530 	lua_settable(L, -3);
531 
532 	lua_pushstring(L, "nopurge");
533 	lua_pushboolean(L, tbl->nopurge > 0);
534 	lua_settable(L, -3);
535 
536 	lua_pushstring(L, "expire");
537 	lua_pushinteger(L, tbl->expire);
538 	lua_settable(L, -3);
539 
540 	/* Save data types periods (if applicable) in 'data' table */
541 	lua_pushstring(L, "data");
542 	lua_newtable(L);
543 
544 	for (dt = 0; dt < STKTABLE_DATA_TYPES; dt++) {
545 		if (tbl->data_ofs[dt] == 0)
546 			continue;
547 
548 		lua_pushstring(L, stktable_data_types[dt].name);
549 
550 		if (stktable_data_types[dt].arg_type == ARG_T_DELAY)
551 			lua_pushinteger(L, tbl->data_arg[dt].u);
552 		else
553 			lua_pushinteger(L, -1);
554 
555 		lua_settable(L, -3);
556 	}
557 
558 	lua_settable(L, -3);
559 
560 	return 1;
561 }
562 
563 /* Helper to get extract stick table entry into Lua table */
hlua_stktable_entry(lua_State * L,struct stktable * t,struct stksess * ts)564 static void hlua_stktable_entry(lua_State *L, struct stktable *t, struct stksess *ts)
565 {
566 	int dt;
567 	void *ptr;
568 
569 	for (dt = 0; dt < STKTABLE_DATA_TYPES; dt++) {
570 
571 		if (t->data_ofs[dt] == 0)
572 			continue;
573 
574 		lua_pushstring(L, stktable_data_types[dt].name);
575 
576 		ptr = stktable_data_ptr(t, ts, dt);
577 		switch (stktable_data_types[dt].std_type) {
578 		case STD_T_SINT:
579 			lua_pushinteger(L, stktable_data_cast(ptr, std_t_sint));
580 			break;
581 		case STD_T_UINT:
582 			hlua_fcn_pushunsigned(L, stktable_data_cast(ptr, std_t_uint));
583 			break;
584 		case STD_T_ULL:
585 			hlua_fcn_pushunsigned_ll(L, stktable_data_cast(ptr, std_t_ull));
586 			break;
587 		case STD_T_FRQP:
588 			lua_pushinteger(L, read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp),
589 			                t->data_arg[dt].u));
590 			break;
591 		}
592 
593 		lua_settable(L, -3);
594 	}
595 }
596 
597 /* Looks in table <t> for a sticky session matching key <key>
598  * Returns table with session data or nil
599  *
600  * The returned table always contains 'use' and 'expire' (integer) fields.
601  * For frequency/rate counters, each data entry is returned as table with
602  * 'value' and 'period' fields.
603  */
hlua_stktable_lookup(lua_State * L)604 int hlua_stktable_lookup(lua_State *L)
605 {
606 	struct stktable *t;
607 	struct sample smp;
608 	struct stktable_key *skey;
609 	struct stksess *ts;
610 
611 	t = hlua_check_stktable(L, 1);
612 	smp.data.type = SMP_T_STR;
613 	smp.flags = SMP_F_CONST;
614 	smp.data.u.str.area = (char *)lua_tolstring(L, 2, &smp.data.u.str.data);
615 
616 	skey = smp_to_stkey(&smp, t);
617 	if (!skey) {
618 		lua_pushnil(L);
619 		return 1;
620 	}
621 
622 	ts = stktable_lookup_key(t, skey);
623 	if (!ts) {
624 		lua_pushnil(L);
625 		return 1;
626 	}
627 
628 	lua_newtable(L);
629 	lua_pushstring(L, "use");
630 	lua_pushinteger(L, ts->ref_cnt - 1);
631 	lua_settable(L, -3);
632 
633 	lua_pushstring(L, "expire");
634 	lua_pushinteger(L, tick_remain(now_ms, ts->expire));
635 	lua_settable(L, -3);
636 
637 	hlua_stktable_entry(L, t, ts);
638 	HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
639 	ts->ref_cnt--;
640 	HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
641 
642 	return 1;
643 }
644 
645 struct stk_filter {
646 	long long val;
647 	int type;
648 	int op;
649 };
650 
651 
652 /* Helper for returning errors to callers using Lua convention (nil, err) */
hlua_error(lua_State * L,const char * fmt,...)653 static int hlua_error(lua_State *L, const char *fmt, ...)  {
654 	char buf[256];
655 	int len;
656 	va_list args;
657 	va_start(args, fmt);
658         len = vsnprintf(buf, sizeof(buf), fmt, args);
659 	va_end(args);
660 
661 	if (len < 0) {
662 		ha_alert("hlua_error(): Could not write error message.\n");
663 		lua_pushnil(L);
664 		return 1;
665 	} else if (len >= sizeof(buf))
666 		ha_alert("hlua_error(): Error message was truncated.\n");
667 
668 	lua_pushnil(L);
669 	lua_pushstring(L, buf);
670 
671 	return 2;
672 }
673 
674 /* Dump the contents of stick table <t>*/
hlua_stktable_dump(lua_State * L)675 int hlua_stktable_dump(lua_State *L)
676 {
677 	struct stktable *t;
678 	struct ebmb_node *eb;
679 	struct ebmb_node *n;
680 	struct stksess *ts;
681 	int type;
682 	int op;
683 	int dt;
684 	long long val;
685 	struct stk_filter filter[MAX_STK_FILTER_LEN];
686 	int filter_count = 0;
687 	int i;
688 	int skip_entry;
689 	void *ptr;
690 
691 	t = hlua_check_stktable(L, 1);
692 	type = lua_type(L, 2);
693 
694 	switch (type) {
695 	case LUA_TNONE:
696 	case LUA_TNIL:
697 		break;
698 	case LUA_TTABLE:
699 		lua_pushnil(L);
700 		while (lua_next(L, 2) != 0) {
701 			int entry_idx = 0;
702 
703 			if (filter_count >= MAX_STK_FILTER_LEN)
704 				return hlua_error(L, "Filter table too large (len > %d)", MAX_STK_FILTER_LEN);
705 
706 			if (lua_type(L, -1) != LUA_TTABLE  || lua_rawlen(L, -1) != 3)
707 				return hlua_error(L, "Filter table entry must be a triplet: {\"data_col\", \"op\", val} (entry #%d)", filter_count + 1);
708 
709 			lua_pushnil(L);
710 			while (lua_next(L, -2) != 0) {
711 				switch (entry_idx) {
712 				case 0:
713 					if (lua_type(L, -1) != LUA_TSTRING)
714 						return hlua_error(L, "Filter table data column must be string (entry #%d)", filter_count + 1);
715 
716 					dt = stktable_get_data_type((char *)lua_tostring(L, -1));
717 					if (dt < 0 || t->data_ofs[dt] == 0)
718 						return hlua_error(L, "Filter table data column not present in stick table (entry #%d)", filter_count + 1);
719 					filter[filter_count].type = dt;
720 					break;
721 				case 1:
722 					if (lua_type(L, -1) != LUA_TSTRING)
723 						return hlua_error(L, "Filter table operator must be string (entry #%d)", filter_count + 1);
724 
725 					op = get_std_op(lua_tostring(L, -1));
726 					if (op < 0)
727 						return hlua_error(L, "Unknown operator in filter table (entry #%d)", filter_count + 1);
728 					filter[filter_count].op = op;
729 					break;
730 				case 2:
731 					val = lua_tointeger(L, -1);
732 					filter[filter_count].val = val;
733 					filter_count++;
734 					break;
735 				default:
736 					break;
737 				}
738 				entry_idx++;
739 				lua_pop(L, 1);
740 			}
741 			lua_pop(L, 1);
742 		}
743 		break;
744 	default:
745 		return hlua_error(L, "filter table expected");
746 	}
747 
748 	lua_newtable(L);
749 
750 	HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
751 	eb = ebmb_first(&t->keys);
752 	for (n = eb; n; n = ebmb_next(n)) {
753 		ts = ebmb_entry(n, struct stksess, key);
754 		if (!ts) {
755 			HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
756 			return 1;
757 		}
758 		ts->ref_cnt++;
759 		HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
760 
761 		/* multi condition/value filter */
762 		skip_entry = 0;
763 		for (i = 0; i < filter_count; i++) {
764 			if (t->data_ofs[filter[i].type] == 0)
765 				continue;
766 
767 			ptr = stktable_data_ptr(t, ts, filter[i].type);
768 
769 			switch (stktable_data_types[filter[i].type].std_type) {
770 			case STD_T_SINT:
771 				val = stktable_data_cast(ptr, std_t_sint);
772 				break;
773 			case STD_T_UINT:
774 				val = stktable_data_cast(ptr, std_t_uint);
775 				break;
776 			case STD_T_ULL:
777 				val = stktable_data_cast(ptr, std_t_ull);
778 				break;
779 			case STD_T_FRQP:
780 				val = read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp),
781 						           t->data_arg[filter[i].type].u);
782 				break;
783 			default:
784 				continue;
785 				break;
786 			}
787 
788 			op = filter[i].op;
789 
790 			if ((val < filter[i].val && (op == STD_OP_EQ || op == STD_OP_GT || op == STD_OP_GE)) ||
791 			    (val == filter[i].val && (op == STD_OP_NE || op == STD_OP_GT || op == STD_OP_LT)) ||
792 			    (val > filter[i].val && (op == STD_OP_EQ || op == STD_OP_LT || op == STD_OP_LE))) {
793 				skip_entry = 1;
794 				break;
795 			}
796 		}
797 
798 		if (skip_entry) {
799 			HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
800 			ts->ref_cnt--;
801 			continue;
802 		}
803 
804 		if (t->type == SMP_T_IPV4) {
805 			char addr[INET_ADDRSTRLEN];
806 			inet_ntop(AF_INET, (const void *)&ts->key.key, addr, sizeof(addr));
807 			lua_pushstring(L, addr);
808 		} else if (t->type == SMP_T_IPV6) {
809 			char addr[INET6_ADDRSTRLEN];
810 			inet_ntop(AF_INET6, (const void *)&ts->key.key, addr, sizeof(addr));
811 			lua_pushstring(L, addr);
812 		} else if (t->type == SMP_T_SINT) {
813 			lua_pushinteger(L, *ts->key.key);
814 		} else if (t->type == SMP_T_STR) {
815 			lua_pushstring(L, (const char *)ts->key.key);
816 		} else {
817 			return hlua_error(L, "Unsupported stick table key type");
818 		}
819 
820 		lua_newtable(L);
821 		hlua_stktable_entry(L, t, ts);
822 		lua_settable(L, -3);
823 		HA_SPIN_LOCK(STK_TABLE_LOCK, &t->lock);
824 		ts->ref_cnt--;
825 	}
826 	HA_SPIN_UNLOCK(STK_TABLE_LOCK, &t->lock);
827 
828 	return 1;
829 }
830 
hlua_fcn_new_listener(lua_State * L,struct listener * lst)831 int hlua_fcn_new_listener(lua_State *L, struct listener *lst)
832 {
833 	lua_newtable(L);
834 
835 	/* Pop a class sesison metatable and affect it to the userdata. */
836 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_listener_ref);
837 	lua_setmetatable(L, -2);
838 
839 	lua_pushlightuserdata(L, lst);
840 	lua_rawseti(L, -2, 0);
841 	return 1;
842 }
843 
hlua_check_listener(lua_State * L,int ud)844 static struct listener *hlua_check_listener(lua_State *L, int ud)
845 {
846 	return hlua_checkudata(L, ud, class_listener_ref);
847 }
848 
hlua_listener_get_stats(lua_State * L)849 int hlua_listener_get_stats(lua_State *L)
850 {
851 	struct listener *li;
852 	int i;
853 
854 	li = hlua_check_listener(L, 1);
855 
856 	if (!li->bind_conf->frontend) {
857 		lua_pushnil(L);
858 		return 1;
859 	}
860 
861 	stats_fill_li_stats(li->bind_conf->frontend, li, ST_SHLGNDS, stats, STATS_LEN);
862 
863 	lua_newtable(L);
864 	for (i=0; i<ST_F_TOTAL_FIELDS; i++) {
865 		lua_pushstring(L, stat_field_names[i]);
866 		hlua_fcn_pushfield(L, &stats[i]);
867 		lua_settable(L, -3);
868 	}
869 	return 1;
870 
871 }
872 
hlua_fcn_new_server(lua_State * L,struct server * srv)873 int hlua_fcn_new_server(lua_State *L, struct server *srv)
874 {
875 	char buffer[12];
876 
877 	lua_newtable(L);
878 
879 	/* Pop a class sesison metatable and affect it to the userdata. */
880 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_server_ref);
881 	lua_setmetatable(L, -2);
882 
883 	lua_pushlightuserdata(L, srv);
884 	lua_rawseti(L, -2, 0);
885 
886 	/* Add server name. */
887 	lua_pushstring(L, "name");
888 	lua_pushstring(L, srv->id);
889 	lua_settable(L, -3);
890 
891 	/* Add server puid. */
892 	lua_pushstring(L, "puid");
893 	snprintf(buffer, sizeof(buffer), "%d", srv->puid);
894 	lua_pushstring(L, buffer);
895 	lua_settable(L, -3);
896 
897 	return 1;
898 }
899 
hlua_check_server(lua_State * L,int ud)900 static struct server *hlua_check_server(lua_State *L, int ud)
901 {
902 	return hlua_checkudata(L, ud, class_server_ref);
903 }
904 
hlua_server_get_stats(lua_State * L)905 int hlua_server_get_stats(lua_State *L)
906 {
907 	struct server *srv;
908 	int i;
909 
910 	srv = hlua_check_server(L, 1);
911 
912 	if (!srv->proxy) {
913 		lua_pushnil(L);
914 		return 1;
915 	}
916 
917 	stats_fill_sv_stats(srv->proxy, srv, ST_SHLGNDS, stats, STATS_LEN);
918 
919 	lua_newtable(L);
920 	for (i=0; i<ST_F_TOTAL_FIELDS; i++) {
921 		lua_pushstring(L, stat_field_names[i]);
922 		hlua_fcn_pushfield(L, &stats[i]);
923 		lua_settable(L, -3);
924 	}
925 	return 1;
926 
927 }
928 
hlua_server_get_addr(lua_State * L)929 int hlua_server_get_addr(lua_State *L)
930 {
931 	struct server *srv;
932 	char addr[INET6_ADDRSTRLEN];
933 	luaL_Buffer b;
934 
935 	srv = hlua_check_server(L, 1);
936 
937 	luaL_buffinit(L, &b);
938 
939 	switch (srv->addr.ss_family) {
940 	case AF_INET:
941 		inet_ntop(AF_INET, &((struct sockaddr_in *)&srv->addr)->sin_addr,
942 		          addr, INET_ADDRSTRLEN);
943 		luaL_addstring(&b, addr);
944 		luaL_addstring(&b, ":");
945 		snprintf(addr, INET_ADDRSTRLEN, "%d", srv->svc_port);
946 		luaL_addstring(&b, addr);
947 		break;
948 	case AF_INET6:
949 		inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&srv->addr)->sin6_addr,
950 		          addr, INET6_ADDRSTRLEN);
951 		luaL_addstring(&b, addr);
952 		luaL_addstring(&b, ":");
953 		snprintf(addr, INET_ADDRSTRLEN, "%d", srv->svc_port);
954 		luaL_addstring(&b, addr);
955 		break;
956 	case AF_UNIX:
957 		luaL_addstring(&b, (char *)((struct sockaddr_un *)&srv->addr)->sun_path);
958 		break;
959 	default:
960 		luaL_addstring(&b, "<unknown>");
961 		break;
962 	}
963 
964 	luaL_pushresult(&b);
965 	return 1;
966 }
967 
hlua_server_is_draining(lua_State * L)968 int hlua_server_is_draining(lua_State *L)
969 {
970 	struct server *srv;
971 
972 	srv = hlua_check_server(L, 1);
973 	lua_pushinteger(L, server_is_draining(srv));
974 	return 1;
975 }
976 
hlua_server_set_maxconn(lua_State * L)977 int hlua_server_set_maxconn(lua_State *L)
978 {
979 	struct server *srv;
980 	const char *maxconn;
981 	const char *err;
982 
983 	srv = hlua_check_server(L, 1);
984 	maxconn = luaL_checkstring(L, 2);
985 
986 	HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
987 	err = server_parse_maxconn_change_request(srv, maxconn);
988 	HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
989 	if (!err)
990 		lua_pushnil(L);
991 	else
992 		hlua_pushstrippedstring(L, err);
993 	return 1;
994 }
995 
hlua_server_get_maxconn(lua_State * L)996 int hlua_server_get_maxconn(lua_State *L)
997 {
998 	struct server *srv;
999 
1000 	srv = hlua_check_server(L, 1);
1001 	lua_pushinteger(L, srv->maxconn);
1002 	return 1;
1003 }
1004 
hlua_server_set_weight(lua_State * L)1005 int hlua_server_set_weight(lua_State *L)
1006 {
1007 	struct server *srv;
1008 	const char *weight;
1009 	const char *err;
1010 
1011 	srv = hlua_check_server(L, 1);
1012 	weight = luaL_checkstring(L, 2);
1013 
1014 	HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1015 	err = server_parse_weight_change_request(srv, weight);
1016 	HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
1017 	if (!err)
1018 		lua_pushnil(L);
1019 	else
1020 		hlua_pushstrippedstring(L, err);
1021 	return 1;
1022 }
1023 
hlua_server_get_weight(lua_State * L)1024 int hlua_server_get_weight(lua_State *L)
1025 {
1026 	struct server *srv;
1027 
1028 	srv = hlua_check_server(L, 1);
1029 	lua_pushinteger(L, srv->uweight);
1030 	return 1;
1031 }
1032 
hlua_server_set_addr(lua_State * L)1033 int hlua_server_set_addr(lua_State *L)
1034 {
1035 	struct server *srv;
1036 	const char *addr;
1037 	const char *err;
1038 
1039 	srv = hlua_check_server(L, 1);
1040 	addr = luaL_checkstring(L, 2);
1041 
1042 	HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1043 	err = server_parse_addr_change_request(srv, addr, "Lua script");
1044 	HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
1045 	if (!err)
1046 		lua_pushnil(L);
1047 	else
1048 		hlua_pushstrippedstring(L, err);
1049 	return 1;
1050 }
1051 
hlua_server_shut_sess(lua_State * L)1052 int hlua_server_shut_sess(lua_State *L)
1053 {
1054 	struct server *srv;
1055 
1056 	srv = hlua_check_server(L, 1);
1057 	HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1058 	srv_shutdown_streams(srv, SF_ERR_KILLED);
1059 	HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
1060 	return 0;
1061 }
1062 
hlua_server_set_drain(lua_State * L)1063 int hlua_server_set_drain(lua_State *L)
1064 {
1065 	struct server *srv;
1066 
1067 	srv = hlua_check_server(L, 1);
1068 	HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1069 	srv_adm_set_drain(srv);
1070 	HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
1071 	return 0;
1072 }
1073 
hlua_server_set_maint(lua_State * L)1074 int hlua_server_set_maint(lua_State *L)
1075 {
1076 	struct server *srv;
1077 
1078 	srv = hlua_check_server(L, 1);
1079 	HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1080 	srv_adm_set_maint(srv);
1081 	HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
1082 	return 0;
1083 }
1084 
hlua_server_set_ready(lua_State * L)1085 int hlua_server_set_ready(lua_State *L)
1086 {
1087 	struct server *srv;
1088 
1089 	srv = hlua_check_server(L, 1);
1090 	HA_SPIN_LOCK(SERVER_LOCK, &srv->lock);
1091 	srv_adm_set_ready(srv);
1092 	HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
1093 	return 0;
1094 }
1095 
hlua_server_check_enable(lua_State * L)1096 int hlua_server_check_enable(lua_State *L)
1097 {
1098 	struct server *sv;
1099 
1100 	sv = hlua_check_server(L, 1);
1101 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
1102 	if (sv->check.state & CHK_ST_CONFIGURED) {
1103 		sv->check.state |= CHK_ST_ENABLED;
1104 	}
1105 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
1106 	return 0;
1107 }
1108 
hlua_server_check_disable(lua_State * L)1109 int hlua_server_check_disable(lua_State *L)
1110 {
1111 	struct server *sv;
1112 
1113 	sv = hlua_check_server(L, 1);
1114 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
1115 	if (sv->check.state & CHK_ST_CONFIGURED) {
1116 		sv->check.state &= ~CHK_ST_ENABLED;
1117 	}
1118 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
1119 	return 0;
1120 }
1121 
hlua_server_check_force_up(lua_State * L)1122 int hlua_server_check_force_up(lua_State *L)
1123 {
1124 	struct server *sv;
1125 
1126 	sv = hlua_check_server(L, 1);
1127 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
1128 	if (!(sv->track)) {
1129 		sv->check.health = sv->check.rise + sv->check.fall - 1;
1130 		srv_set_running(sv, "changed from Lua script", NULL);
1131 	}
1132 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
1133 	return 0;
1134 }
1135 
hlua_server_check_force_nolb(lua_State * L)1136 int hlua_server_check_force_nolb(lua_State *L)
1137 {
1138 	struct server *sv;
1139 
1140 	sv = hlua_check_server(L, 1);
1141 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
1142 	if (!(sv->track)) {
1143 		sv->check.health = sv->check.rise + sv->check.fall - 1;
1144 		srv_set_stopping(sv, "changed from Lua script", NULL);
1145 	}
1146 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
1147 	return 0;
1148 }
1149 
hlua_server_check_force_down(lua_State * L)1150 int hlua_server_check_force_down(lua_State *L)
1151 {
1152 	struct server *sv;
1153 
1154 	sv = hlua_check_server(L, 1);
1155 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
1156 	if (!(sv->track)) {
1157 		sv->check.health = 0;
1158 		srv_set_stopped(sv, "changed from Lua script", NULL);
1159 	}
1160 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
1161 	return 0;
1162 }
1163 
hlua_server_agent_enable(lua_State * L)1164 int hlua_server_agent_enable(lua_State *L)
1165 {
1166 	struct server *sv;
1167 
1168 	sv = hlua_check_server(L, 1);
1169 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
1170 	if (sv->agent.state & CHK_ST_CONFIGURED) {
1171 		sv->agent.state |= CHK_ST_ENABLED;
1172 	}
1173 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
1174 	return 0;
1175 }
1176 
hlua_server_agent_disable(lua_State * L)1177 int hlua_server_agent_disable(lua_State *L)
1178 {
1179 	struct server *sv;
1180 
1181 	sv = hlua_check_server(L, 1);
1182 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
1183 	if (sv->agent.state & CHK_ST_CONFIGURED) {
1184 		sv->agent.state &= ~CHK_ST_ENABLED;
1185 	}
1186 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
1187 	return 0;
1188 }
1189 
hlua_server_agent_force_up(lua_State * L)1190 int hlua_server_agent_force_up(lua_State *L)
1191 {
1192 	struct server *sv;
1193 
1194 	sv = hlua_check_server(L, 1);
1195 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
1196 	if (sv->agent.state & CHK_ST_ENABLED) {
1197 		sv->agent.health = sv->agent.rise + sv->agent.fall - 1;
1198 		srv_set_running(sv, "changed from Lua script", NULL);
1199 	}
1200 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
1201 	return 0;
1202 }
1203 
hlua_server_agent_force_down(lua_State * L)1204 int hlua_server_agent_force_down(lua_State *L)
1205 {
1206 	struct server *sv;
1207 
1208 	sv = hlua_check_server(L, 1);
1209 	HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
1210 	if (sv->agent.state & CHK_ST_ENABLED) {
1211 		sv->agent.health = 0;
1212 		srv_set_stopped(sv, "changed from Lua script", NULL);
1213 	}
1214 	HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
1215 	return 0;
1216 }
1217 
hlua_fcn_new_proxy(lua_State * L,struct proxy * px)1218 int hlua_fcn_new_proxy(lua_State *L, struct proxy *px)
1219 {
1220 	struct server *srv;
1221 	struct listener *lst;
1222 	int lid;
1223 	char buffer[17];
1224 
1225 	lua_newtable(L);
1226 
1227 	/* Pop a class sesison metatable and affect it to the userdata. */
1228 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_proxy_ref);
1229 	lua_setmetatable(L, -2);
1230 
1231 	lua_pushlightuserdata(L, px);
1232 	lua_rawseti(L, -2, 0);
1233 
1234 	/* Add proxy name. */
1235 	lua_pushstring(L, "name");
1236 	lua_pushstring(L, px->id);
1237 	lua_settable(L, -3);
1238 
1239 	/* Add proxy uuid. */
1240 	lua_pushstring(L, "uuid");
1241 	snprintf(buffer, sizeof(buffer), "%d", px->uuid);
1242 	lua_pushstring(L, buffer);
1243 	lua_settable(L, -3);
1244 
1245 	/* Browse and register servers. */
1246 	lua_pushstring(L, "servers");
1247 	lua_newtable(L);
1248 	for (srv = px->srv; srv; srv = srv->next) {
1249 		lua_pushstring(L, srv->id);
1250 		hlua_fcn_new_server(L, srv);
1251 		lua_settable(L, -3);
1252 	}
1253 	lua_settable(L, -3);
1254 
1255 	/* Browse and register listeners. */
1256 	lua_pushstring(L, "listeners");
1257 	lua_newtable(L);
1258 	lid = 1;
1259 	list_for_each_entry(lst, &px->conf.listeners, by_fe) {
1260 		if (lst->name)
1261 			lua_pushstring(L, lst->name);
1262 		else {
1263 			snprintf(buffer, sizeof(buffer), "sock-%d", lid);
1264 			lid++;
1265 			lua_pushstring(L, buffer);
1266 		}
1267 		hlua_fcn_new_listener(L, lst);
1268 		lua_settable(L, -3);
1269 	}
1270 	lua_settable(L, -3);
1271 
1272 	if (px->table.id) {
1273 		lua_pushstring(L, "stktable");
1274 		hlua_fcn_new_stktable(L, &px->table);
1275 		lua_settable(L, -3);
1276 	}
1277 
1278 	return 1;
1279 }
1280 
hlua_check_proxy(lua_State * L,int ud)1281 static struct proxy *hlua_check_proxy(lua_State *L, int ud)
1282 {
1283 	return hlua_checkudata(L, ud, class_proxy_ref);
1284 }
1285 
hlua_proxy_pause(lua_State * L)1286 int hlua_proxy_pause(lua_State *L)
1287 {
1288 	struct proxy *px;
1289 
1290 	px = hlua_check_proxy(L, 1);
1291 	pause_proxy(px);
1292 	return 0;
1293 }
1294 
hlua_proxy_resume(lua_State * L)1295 int hlua_proxy_resume(lua_State *L)
1296 {
1297 	struct proxy *px;
1298 
1299 	px = hlua_check_proxy(L, 1);
1300 	resume_proxy(px);
1301 	return 0;
1302 }
1303 
hlua_proxy_stop(lua_State * L)1304 int hlua_proxy_stop(lua_State *L)
1305 {
1306 	struct proxy *px;
1307 
1308 	px = hlua_check_proxy(L, 1);
1309 	stop_proxy(px);
1310 	return 0;
1311 }
1312 
hlua_proxy_get_cap(lua_State * L)1313 int hlua_proxy_get_cap(lua_State *L)
1314 {
1315 	struct proxy *px;
1316 	const char *str;
1317 
1318 	px = hlua_check_proxy(L, 1);
1319 	str = proxy_cap_str(px->cap);
1320 	lua_pushstring(L, str);
1321 	return 1;
1322 }
1323 
hlua_proxy_get_stats(lua_State * L)1324 int hlua_proxy_get_stats(lua_State *L)
1325 {
1326 	struct proxy *px;
1327 	int i;
1328 
1329 	px = hlua_check_proxy(L, 1);
1330 	if (px->cap & PR_CAP_BE)
1331 		stats_fill_be_stats(px, ST_SHLGNDS, stats, STATS_LEN);
1332 	else
1333 		stats_fill_fe_stats(px, stats, STATS_LEN);
1334 	lua_newtable(L);
1335 	for (i=0; i<ST_F_TOTAL_FIELDS; i++) {
1336 		lua_pushstring(L, stat_field_names[i]);
1337 		hlua_fcn_pushfield(L, &stats[i]);
1338 		lua_settable(L, -3);
1339 	}
1340 	return 1;
1341 }
1342 
hlua_proxy_get_mode(lua_State * L)1343 int hlua_proxy_get_mode(lua_State *L)
1344 {
1345 	struct proxy *px;
1346 	const char *str;
1347 
1348 	px = hlua_check_proxy(L, 1);
1349 	str = proxy_mode_str(px->mode);
1350 	lua_pushstring(L, str);
1351 	return 1;
1352 }
1353 
hlua_proxy_shut_bcksess(lua_State * L)1354 int hlua_proxy_shut_bcksess(lua_State *L)
1355 {
1356 	struct proxy *px;
1357 
1358 	px = hlua_check_proxy(L, 1);
1359 	srv_shutdown_backup_streams(px, SF_ERR_KILLED);
1360 	return 0;
1361 }
1362 
hlua_fcn_post_init(lua_State * L)1363 int hlua_fcn_post_init(lua_State *L)
1364 {
1365 	struct proxy *px;
1366 
1367 	/* get core array. */
1368 	if (lua_getglobal(L, "core") != LUA_TTABLE)
1369 		lua_error(L);
1370 
1371 	/* Create proxies entry. */
1372 	lua_pushstring(L, "proxies");
1373 	lua_newtable(L);
1374 
1375 	/* List all proxies. */
1376 	for (px = proxies_list; px; px = px->next) {
1377 		lua_pushstring(L, px->id);
1378 		hlua_fcn_new_proxy(L, px);
1379 		lua_settable(L, -3);
1380 	}
1381 
1382 	/* push "proxies" in "core" */
1383 	lua_settable(L, -3);
1384 
1385 	/* Create proxies entry. */
1386 	lua_pushstring(L, "frontends");
1387 	lua_newtable(L);
1388 
1389 	/* List all proxies. */
1390 	for (px = proxies_list; px; px = px->next) {
1391 		if (!(px->cap & PR_CAP_FE))
1392 			continue;
1393 		lua_pushstring(L, px->id);
1394 		hlua_fcn_new_proxy(L, px);
1395 		lua_settable(L, -3);
1396 	}
1397 
1398 	/* push "frontends" in "core" */
1399 	lua_settable(L, -3);
1400 
1401 	/* Create proxies entry. */
1402 	lua_pushstring(L, "backends");
1403 	lua_newtable(L);
1404 
1405 	/* List all proxies. */
1406 	for (px = proxies_list; px; px = px->next) {
1407 		if (!(px->cap & PR_CAP_BE))
1408 			continue;
1409 		lua_pushstring(L, px->id);
1410 		hlua_fcn_new_proxy(L, px);
1411 		lua_settable(L, -3);
1412 	}
1413 
1414 	/* push "backend" in "core" */
1415 	lua_settable(L, -3);
1416 
1417 	return 1;
1418 }
1419 
1420 /* This Lua function take a string, a list of separators.
1421  * It tokenize the input string using the list of separators
1422  * as separator.
1423  *
1424  * The functionreturns a tablle filled with tokens.
1425  */
hlua_tokenize(lua_State * L)1426 int hlua_tokenize(lua_State *L)
1427 {
1428 	const char *str;
1429 	const char *sep;
1430 	int index;
1431 	const char *token;
1432 	const char *p;
1433 	const char *c;
1434 	int ignore_empty;
1435 
1436 	ignore_empty = 0;
1437 
1438 	str = luaL_checkstring(L, 1);
1439 	sep = luaL_checkstring(L, 2);
1440 	if (lua_gettop(L) == 3)
1441 		ignore_empty = hlua_checkboolean(L, 3);
1442 
1443 	lua_newtable(L);
1444 	index = 1;
1445 	token = str;
1446 	p = str;
1447 	while(1) {
1448 		for (c = sep; *c != '\0'; c++)
1449 			if (*p == *c)
1450 				break;
1451 		if (*p == *c) {
1452 			if ((!ignore_empty) || (p - token > 0)) {
1453 				lua_pushlstring(L, token, p - token);
1454 				lua_rawseti(L, -2, index);
1455 				index++;
1456 			}
1457 			token = p + 1;
1458 		}
1459 		if (*p == '\0')
1460 			break;
1461 		p++;
1462 	}
1463 
1464 	return 1;
1465 }
1466 
hlua_parse_addr(lua_State * L)1467 int hlua_parse_addr(lua_State *L)
1468 {
1469 	struct hlua_addr *addr;
1470 	const char *str = luaL_checkstring(L, 1);
1471 	unsigned char mask;
1472 
1473 	addr = lua_newuserdata(L, sizeof(struct hlua_addr));
1474 	if (!addr) {
1475 		lua_pushnil(L);
1476 		return 1;
1477 	}
1478 
1479 	if (str2net(str, PAT_MF_NO_DNS, &addr->addr.v4.ip, &addr->addr.v4.mask)) {
1480 		addr->type = AF_INET;
1481 		return 1;
1482 	}
1483 
1484 	if (str62net(str, &addr->addr.v6.ip, &mask)) {
1485 		len2mask6(mask, &addr->addr.v6.mask);
1486 		addr->type = AF_INET6;
1487 		return 1;
1488 	}
1489 
1490 	lua_pop(L, 1);
1491 	lua_pushnil(L);
1492 	return 1;
1493 }
1494 
hlua_match_addr(lua_State * L)1495 int hlua_match_addr(lua_State *L)
1496 {
1497 	struct hlua_addr *addr1;
1498 	struct hlua_addr *addr2;
1499 
1500 	if (!lua_isuserdata(L, 1) ||
1501 	    !lua_isuserdata(L, 2)) {
1502 		lua_pushboolean(L, 0);
1503 		return 1;
1504 	}
1505 
1506 	addr1 = lua_touserdata(L, 1);
1507 	addr2 = lua_touserdata(L, 2);
1508 
1509 	if (addr1->type != addr2->type) {
1510 		lua_pushboolean(L, 0);
1511 		return 1;
1512 	}
1513 
1514 	if (addr1->type == AF_INET) {
1515 		if ((addr1->addr.v4.ip.s_addr & addr2->addr.v4.mask.s_addr) ==
1516 		    (addr2->addr.v4.ip.s_addr & addr1->addr.v4.mask.s_addr)) {
1517 			lua_pushboolean(L, 1);
1518 			return 1;
1519 		}
1520 	} else {
1521 		int i;
1522 
1523 		for (i = 0; i < 16; i += 4) {
1524 			if ((*(uint32_t *)&addr1->addr.v6.ip.s6_addr[i] &
1525 			     *(uint32_t *)&addr2->addr.v6.mask.s6_addr[i]) !=
1526 			    (*(uint32_t *)&addr2->addr.v6.ip.s6_addr[i] &
1527 			     *(uint32_t *)&addr1->addr.v6.mask.s6_addr[i]))
1528 				break;
1529 		}
1530 		if (i == 16) {
1531 			lua_pushboolean(L, 1);
1532 			return 1;
1533 		}
1534 	}
1535 
1536 	lua_pushboolean(L, 0);
1537 	return 1;
1538 }
1539 
hlua_check_regex(lua_State * L,int ud)1540 static struct my_regex *hlua_check_regex(lua_State *L, int ud)
1541 {
1542 	return (hlua_checkudata(L, ud, class_regex_ref));
1543 }
1544 
hlua_regex_comp(struct lua_State * L)1545 static int hlua_regex_comp(struct lua_State *L)
1546 {
1547 	struct my_regex *regex;
1548 	const char *str;
1549 	int cs;
1550 	char *err;
1551 
1552 	str = luaL_checkstring(L, 1);
1553 	luaL_argcheck(L, lua_isboolean(L, 2), 2, NULL);
1554 	cs = lua_toboolean(L, 2);
1555 
1556 	regex = lua_newuserdata(L, sizeof(*regex));
1557 
1558 	err = NULL;
1559 	if (!regex_comp(str, regex, cs, 1, &err)) {
1560 		lua_pushboolean(L, 0); /* status error */
1561 		lua_pushstring(L, err); /* Reason */
1562 		free(err);
1563 		return 2;
1564 	}
1565 
1566 	lua_pushboolean(L, 1); /* Status ok */
1567 
1568 	/* Create object */
1569 	lua_newtable(L);
1570 	lua_pushvalue(L, -3); /* Get the userdata pointer. */
1571 	lua_rawseti(L, -2, 0);
1572 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_regex_ref);
1573 	lua_setmetatable(L, -2);
1574 	return 2;
1575 }
1576 
hlua_regex_exec(struct lua_State * L)1577 static int hlua_regex_exec(struct lua_State *L)
1578 {
1579 	struct my_regex *regex;
1580 	const char *str;
1581 	size_t len;
1582 	struct buffer *tmp;
1583 
1584 	regex = hlua_check_regex(L, 1);
1585 	str = luaL_checklstring(L, 2, &len);
1586 
1587 	/* Copy the string because regex_exec2 require a 'char *'
1588 	 * and not a 'const char *'.
1589 	 */
1590 	tmp = get_trash_chunk();
1591 	if (len >= tmp->size) {
1592 		lua_pushboolean(L, 0);
1593 		return 1;
1594 	}
1595 	memcpy(tmp->area, str, len);
1596 
1597 	lua_pushboolean(L, regex_exec2(regex, tmp->area, len));
1598 
1599 	return 1;
1600 }
1601 
hlua_regex_match(struct lua_State * L)1602 static int hlua_regex_match(struct lua_State *L)
1603 {
1604 	struct my_regex *regex;
1605 	const char *str;
1606 	size_t len;
1607 	regmatch_t pmatch[20];
1608 	int ret;
1609 	int i;
1610 	struct buffer *tmp;
1611 
1612 	regex = hlua_check_regex(L, 1);
1613 	str = luaL_checklstring(L, 2, &len);
1614 
1615 	/* Copy the string because regex_exec2 require a 'char *'
1616 	 * and not a 'const char *'.
1617 	 */
1618 	tmp = get_trash_chunk();
1619 	if (len >= tmp->size) {
1620 		lua_pushboolean(L, 0);
1621 		return 1;
1622 	}
1623 	memcpy(tmp->area, str, len);
1624 
1625 	ret = regex_exec_match2(regex, tmp->area, len, 20, pmatch, 0);
1626 	lua_pushboolean(L, ret);
1627 	lua_newtable(L);
1628 	if (ret) {
1629 		for (i = 0; i < 20 && pmatch[i].rm_so != -1; i++) {
1630 			lua_pushlstring(L, str + pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so);
1631 			lua_rawseti(L, -2, i + 1);
1632 		}
1633 	}
1634 	return 2;
1635 }
1636 
hlua_regex_free(struct lua_State * L)1637 static int hlua_regex_free(struct lua_State *L)
1638 {
1639 	struct my_regex *regex;
1640 
1641 	regex = hlua_check_regex(L, 1);
1642 	regex_free(regex);
1643 	return 0;
1644 }
1645 
hlua_fcn_reg_core_fcn(lua_State * L)1646 int hlua_fcn_reg_core_fcn(lua_State *L)
1647 {
1648 	if (!hlua_concat_init(L))
1649 		return 0;
1650 
1651 	hlua_class_function(L, "now", hlua_now);
1652 	hlua_class_function(L, "http_date", hlua_http_date);
1653 	hlua_class_function(L, "imf_date", hlua_imf_date);
1654 	hlua_class_function(L, "rfc850_date", hlua_rfc850_date);
1655 	hlua_class_function(L, "asctime_date", hlua_asctime_date);
1656 	hlua_class_function(L, "concat", hlua_concat_new);
1657 	hlua_class_function(L, "get_info", hlua_get_info);
1658 	hlua_class_function(L, "parse_addr", hlua_parse_addr);
1659 	hlua_class_function(L, "match_addr", hlua_match_addr);
1660 	hlua_class_function(L, "tokenize", hlua_tokenize);
1661 
1662 	/* Create regex object. */
1663 	lua_newtable(L);
1664 	hlua_class_function(L, "new", hlua_regex_comp);
1665 
1666 	lua_newtable(L); /* The metatable. */
1667 	lua_pushstring(L, "__index");
1668 	lua_newtable(L);
1669 	hlua_class_function(L, "exec", hlua_regex_exec);
1670 	hlua_class_function(L, "match", hlua_regex_match);
1671 	lua_rawset(L, -3); /* -> META["__index"] = TABLE */
1672 	hlua_class_function(L, "__gc", hlua_regex_free);
1673 
1674 	lua_pushvalue(L, -1); /* Duplicate the metatable reference. */
1675 	class_regex_ref = hlua_register_metatable(L, CLASS_REGEX);
1676 
1677 	lua_setmetatable(L, -2);
1678 	lua_setglobal(L, CLASS_REGEX); /* Create global object called Regex */
1679 
1680 	/* Create stktable object. */
1681 	lua_newtable(L);
1682 	lua_pushstring(L, "__index");
1683 	lua_newtable(L);
1684 	hlua_class_function(L, "info", hlua_stktable_info);
1685 	hlua_class_function(L, "lookup", hlua_stktable_lookup);
1686 	hlua_class_function(L, "dump", hlua_stktable_dump);
1687 	lua_settable(L, -3); /* -> META["__index"] = TABLE */
1688 	class_stktable_ref = hlua_register_metatable(L, CLASS_STKTABLE);
1689 
1690 	/* Create listener object. */
1691 	lua_newtable(L);
1692 	lua_pushstring(L, "__index");
1693 	lua_newtable(L);
1694 	hlua_class_function(L, "get_stats", hlua_listener_get_stats);
1695 	lua_settable(L, -3); /* -> META["__index"] = TABLE */
1696 	class_listener_ref = hlua_register_metatable(L, CLASS_LISTENER);
1697 
1698 	/* Create server object. */
1699 	lua_newtable(L);
1700 	lua_pushstring(L, "__index");
1701 	lua_newtable(L);
1702 	hlua_class_function(L, "is_draining", hlua_server_is_draining);
1703 	hlua_class_function(L, "set_maxconn", hlua_server_set_maxconn);
1704 	hlua_class_function(L, "get_maxconn", hlua_server_get_maxconn);
1705 	hlua_class_function(L, "set_weight", hlua_server_set_weight);
1706 	hlua_class_function(L, "get_weight", hlua_server_get_weight);
1707 	hlua_class_function(L, "set_addr", hlua_server_set_addr);
1708 	hlua_class_function(L, "get_addr", hlua_server_get_addr);
1709 	hlua_class_function(L, "get_stats", hlua_server_get_stats);
1710 	hlua_class_function(L, "shut_sess", hlua_server_shut_sess);
1711 	hlua_class_function(L, "set_drain", hlua_server_set_drain);
1712 	hlua_class_function(L, "set_maint", hlua_server_set_maint);
1713 	hlua_class_function(L, "set_ready", hlua_server_set_ready);
1714 	hlua_class_function(L, "check_enable", hlua_server_check_enable);
1715 	hlua_class_function(L, "check_disable", hlua_server_check_disable);
1716 	hlua_class_function(L, "check_force_up", hlua_server_check_force_up);
1717 	hlua_class_function(L, "check_force_nolb", hlua_server_check_force_nolb);
1718 	hlua_class_function(L, "check_force_down", hlua_server_check_force_down);
1719 	hlua_class_function(L, "agent_enable", hlua_server_agent_enable);
1720 	hlua_class_function(L, "agent_disable", hlua_server_agent_disable);
1721 	hlua_class_function(L, "agent_force_up", hlua_server_agent_force_up);
1722 	hlua_class_function(L, "agent_force_down", hlua_server_agent_force_down);
1723 	lua_settable(L, -3); /* -> META["__index"] = TABLE */
1724 	class_server_ref = hlua_register_metatable(L, CLASS_SERVER);
1725 
1726 	/* Create proxy object. */
1727 	lua_newtable(L);
1728 	lua_pushstring(L, "__index");
1729 	lua_newtable(L);
1730 	hlua_class_function(L, "pause", hlua_proxy_pause);
1731 	hlua_class_function(L, "resume", hlua_proxy_resume);
1732 	hlua_class_function(L, "stop", hlua_proxy_stop);
1733 	hlua_class_function(L, "shut_bcksess", hlua_proxy_shut_bcksess);
1734 	hlua_class_function(L, "get_cap", hlua_proxy_get_cap);
1735 	hlua_class_function(L, "get_mode", hlua_proxy_get_mode);
1736 	hlua_class_function(L, "get_stats", hlua_proxy_get_stats);
1737 	lua_settable(L, -3); /* -> META["__index"] = TABLE */
1738 	class_proxy_ref = hlua_register_metatable(L, CLASS_PROXY);
1739 
1740 	return 5;
1741 }
1742