On Mon, 30 Nov 2015 08:37:00 +0100 joris dedieu <joris.ded...@gmail.com> wrote:
> Hi all, > > I started to drive into haproxy's lua interface. I produced a few code > that allows dnsbl lookup and it seems to work. > > First I have a C wrapper against the libc resolver.. > > #include <netdb.h> > #include <sys/types.h> > #include <sys/socket.h> > #include <netinet/in.h> > #include <arpa/inet.h> > > #include <lua53/lua.h> > #include <lua53/lauxlib.h> > > static int gethostbyname_wrapper(lua_State *L) > { > const char* query = luaL_checkstring(L, 1); > struct hostent *he; > if ((he = gethostbyname(query)) != NULL) { > const char *first_addr = > inet_ntoa(*(struct in_addr*)he->h_addr_list[0]); > lua_pushstring(L, first_addr); > return 1; > } > return 0; > } > > static const luaL_Reg sysdb_methods[] = { > {"gethostbyname", gethostbyname_wrapper}, > {NULL, NULL} > }; > > LUALIB_API int luaopen_sysdb(lua_State *L) { > luaL_newlib(L, sysdb_methods); > return 1; > } > > I have some doubts on the asyncness of libc operations but in other > side I don't want to reinvent the wheel. Should I prefer a resolver > implementation that uses lua socket ? As far as I tested libc seems to > do the job. Hello, I confirm your doubts: gethostbyname is synchronous and it is a blocking call. If your hostname resolution is in the /etc/hosts file, it blocks while reading file. It it is from DNS server, it blocks waiting for the server response (or worse: wainting for the timeout). So, this code seems to run, but your HAProxy will be not efficient because the entire haproxy process will be blocked during each resolution. For example: if your DNS fails after 3s timeout, during 3s, HAProxy doesn't process any data. Otherwise, your code is the good way to perform fast Lua/C libraries. There are no way to simulate blocking access out of the HAProxy core, all the functions writed for Lua must be non block. > Then the lua code > > local sysdb = require("sysdb") > > core.register_fetches("rbl", function(txn, rbl, ip) > if (not ip) then > ip = txn.sf:src() > end > if (not rbl) then > rbl = "zen.spamhaus.org" > end > local query = rbl > for x in string.gmatch(ip, "[^%.]+") do > query = x .. '.' .. query > end > if(sysdb.gethostbyname(query)) then > return 1 > else > return 0 > end > end) > > I want to use a sticky table as a local cache so my second question : > is there a way to set a gpt0 value from lua ? You can use the samples fetches mapper and use the sc_set_gpt0. The syntax is like this: For the read access: txn.sf:sc_set_gpt0() txn.sc:table_gpc0() For the write access, I don't have direct solution. You must use an Lua sample fetch and the following configuration directive: http-request sc-set-gpt0 lua.my_sample_fetch Maybe it will be a good idea to implement the stick table access in Lua. If you want a other maneer to store shared data inhaproxy, you can use maps. The maps are shared by all the HAProxy process including Lua with a special API (see Map class) Thierry