2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 * originally authored by Fredrik Danerklint
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
10 * In addition, for the avoidance of any doubt, permission is granted to
11 * link this program with OpenSSL and to (re)distribute the binaries
12 * produced as the result of such linking.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "luabackend.hh"
28 #include "pdns/logger.hh"
29 #include "pdns/arguments.hh"
35 #include "lua_functions.hh"
38 virtual void reload();
39 virtual void rediscover(string* status=0);
42 void LUABackend::get_lua_function(lua_State
*lua
, const char *name
, int *function
) {
49 if (!::arg().isEmpty(f
))
52 lua_getglobal(lua
, arg
== "" ? name
: arg
.c_str());
53 if (!lua_isnil(lua
, -1)) {
54 lua_pushvalue(lua
, -1);
55 *function
= luaL_ref(lua
, LUA_REGISTRYINDEX
);
60 void LUABackend::reload() {
64 // backend_name = "[LUABackend: " + uitoa(backend_pid) + " (" + uitoa(backend_count) +")] ";
65 backend_name
= "[LUABackend: (" + uitoa(backend_count
) +")] ";
70 logging
= ::arg().mustDo("query-logging") || mustDo("logging-query");
72 #if LUA_VERSION_NUM >= 502
73 lua
= luaL_newstate();
79 lua_atpanic(lua
, my_lua_panic
);
81 string filename
= getArg("filename"); //"powerdns-luabackend.lua";
83 if (luaL_loadfile (lua
, filename
.c_str()) != 0) {
85 e
<< backend_name
<< "Error loading the file '" << filename
<< "' : " << lua_tostring(lua
,-1) << endl
;
88 throw LUAException (e
.str());
91 lua_pushlightuserdata(lua
, (void*)this);
92 lua_setfield(lua
, LUA_REGISTRYINDEX
, "__LUABACKEND");
94 register_lua_functions(lua
);
96 if(lua_pcall(lua
, 0, 0, 0)) {
98 e
<< backend_name
<< "Error running the file '" << filename
<< "' : " << lua_tostring(lua
,-1) << endl
;
101 throw LUAException (e
.str());
104 get_lua_function(lua
, "exec_error", &f_lua_exec_error
);
106 //minimal functions....
107 get_lua_function(lua
, "list", &f_lua_list
);
108 get_lua_function(lua
, "lookup", &f_lua_lookup
);
109 get_lua_function(lua
, "get", &f_lua_get
);
110 get_lua_function(lua
, "getsoa", &f_lua_getsoa
);
112 if (f_lua_list
== 0 || f_lua_lookup
== 0 || f_lua_get
== 0 || f_lua_getsoa
== 0) {
113 throw LUAException (backend_name
+ "MINIMAL BACKEND: Missing required function(s)!");
116 //master functions....
117 get_lua_function(lua
, "getupdatedmasters", &f_lua_getupdatedmasters
);
118 get_lua_function(lua
, "setnotified", &f_lua_setnotified
);
120 //slave functions....
121 get_lua_function(lua
, "getdomaininfo", &f_lua_getdomaininfo
);
122 get_lua_function(lua
, "ismaster", &f_lua_ismaster
);
123 get_lua_function(lua
, "getunfreshslaveinfos", &f_lua_getunfreshslaveinfos
);
124 get_lua_function(lua
, "setfresh", &f_lua_setfresh
);
125 get_lua_function(lua
, "starttransaction", &f_lua_starttransaction
);
126 get_lua_function(lua
, "committransaction", &f_lua_committransaction
);
127 get_lua_function(lua
, "aborttransaction", &f_lua_aborttransaction
);
128 get_lua_function(lua
, "feedrecord", &f_lua_feedrecord
);
130 //supermaster functions....
131 get_lua_function(lua
, "supermasterbackend", &f_lua_supermasterbackend
);
132 get_lua_function(lua
, "createslavedomain", &f_lua_createslavedomain
);
135 get_lua_function(lua
, "rediscover", &f_lua_rediscover
);
138 get_lua_function(lua
, "alsonotifies", &f_lua_alsonotifies
);
139 get_lua_function(lua
, "getdomainmetadata", &f_lua_getdomainmetadata
);
140 get_lua_function(lua
, "setdomainmetadata", &f_lua_setdomainmetadata
);
142 get_lua_function(lua
, "getdomainkeys", &f_lua_getdomainkeys
);
143 get_lua_function(lua
, "removedomainkey", &f_lua_removedomainkey
);
144 get_lua_function(lua
, "activatedomainkey", &f_lua_activatedomainkey
);
145 get_lua_function(lua
, "deactivatedomainkey", &f_lua_deactivatedomainkey
);
146 get_lua_function(lua
, "updatedomainkey", &f_lua_updatedomainkey
);
147 get_lua_function(lua
, "adddomainkey", &f_lua_adddomainkey
);
149 get_lua_function(lua
, "gettsigkey", &f_lua_gettsigkey
);
151 get_lua_function(lua
, "getbeforeandafternamesabsolute", &f_lua_getbeforeandafternamesabsolute
);
152 get_lua_function(lua
, "updatednssecorderandauthabsolute", &f_lua_updatednssecorderandauthabsolute
);
153 get_lua_function(lua
, "updatednssecorderandauth", &f_lua_updatednssecorderandauth
); // not needed...
159 throw LUAException (backend_name
+ "LUA OPEN FAILED!");
163 void LUABackend::rediscover(string
* status
) {
165 if (f_lua_rediscover
== 0)
169 g_log
<< Logger::Info
<< backend_name
<< "(rediscover) BEGIN" << endl
;
171 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_rediscover
);
173 if(lua_pcall(lua
, 0, 1, f_lua_exec_error
) != 0) {
174 string e
= backend_name
+ lua_tostring(lua
, -1);
177 throw runtime_error(e
);
180 size_t returnedwhat
= lua_type(lua
, -1);
181 if (returnedwhat
!= LUA_TSTRING
) {
186 string s
= lua_tostring(lua
, -1);
191 g_log
<< Logger::Info
<< backend_name
<< "(rediscover) END" << endl
;