]>
Commit | Line | Data |
---|---|---|
e18dbde1 | 1 | /* |
12471842 PL |
2 | * This file is part of PowerDNS or dnsdist. |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * originally authored by Fredrik Danerklint | |
5 | * | |
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. | |
9 | * | |
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. | |
13 | * | |
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. | |
18 | * | |
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. | |
22 | */ | |
870a0fe4 AT |
23 | #ifdef HAVE_CONFIG_H |
24 | #include "config.h" | |
25 | #endif | |
e18dbde1 BH |
26 | #include "luabackend.hh" |
27 | ||
28 | #include "pdns/logger.hh" | |
29 | #include "pdns/arguments.hh" | |
30 | ||
31 | //#include "lua_functions.hh" | |
32 | ||
33 | /* FIRST PART */ | |
34 | ||
35 | LUABackend::LUABackend(const string &suffix) { | |
36 | ||
37 | setArgPrefix("lua"+suffix); | |
119bcf6c | 38 | |
e18dbde1 BH |
39 | try { |
40 | ||
41 | if (pthread_equal(backend_pid, pthread_self())) { | |
42 | backend_count++; | |
43 | } else { | |
44 | backend_count = 1; | |
45 | backend_pid = pthread_self(); | |
46 | } | |
119bcf6c | 47 | |
e18dbde1 BH |
48 | // lb = NULL; |
49 | lua = NULL; | |
50 | dnspacket = NULL; | |
51 | dnssec = false; | |
52 | ||
53 | reload(); | |
54 | } | |
55 | ||
56 | catch(LUAException &e) { | |
57 | L<<Logger::Error<<backend_name<<"Error: "<<e.what<<endl; | |
3f81d239 | 58 | throw PDNSException(e.what); |
e18dbde1 BH |
59 | } |
60 | ||
61 | } | |
119bcf6c | 62 | |
e18dbde1 | 63 | LUABackend::~LUABackend() { |
737a287f RG |
64 | try { |
65 | L<<Logger::Info<<backend_name<<"Closing..." << endl; | |
66 | } | |
67 | catch (...) { | |
68 | } | |
119bcf6c | 69 | |
e18dbde1 BH |
70 | lua_close(lua); |
71 | } | |
72 | ||
119bcf6c | 73 | bool LUABackend::list(const DNSName &target, int domain_id, bool include_disabled) { |
e18dbde1 BH |
74 | if (logging) |
75 | L << Logger::Info << backend_name << "(list) BEGIN" << endl; | |
76 | ||
77 | lua_rawgeti(lua, LUA_REGISTRYINDEX, f_lua_list); | |
78 | ||
119bcf6c | 79 | lua_pushstring(lua, target.toString().c_str()); |
c03d545e | 80 | lua_pushinteger(lua, domain_id); |
e18dbde1 BH |
81 | |
82 | if(lua_pcall(lua, 2, 1, f_lua_exec_error) != 0) { | |
83 | string e = backend_name + lua_tostring(lua, -1); | |
84 | lua_pop(lua, 1); | |
119bcf6c | 85 | |
e18dbde1 | 86 | throw runtime_error(e); |
e18dbde1 | 87 | } |
119bcf6c | 88 | |
e18dbde1 BH |
89 | size_t returnedwhat = lua_type(lua, -1); |
90 | bool ok = false; | |
119bcf6c | 91 | |
e18dbde1 BH |
92 | if (returnedwhat == LUA_TBOOLEAN) |
93 | ok = lua_toboolean(lua, -1); | |
119bcf6c | 94 | |
e18dbde1 BH |
95 | lua_pop(lua, 1); |
96 | ||
97 | if (logging) | |
98 | L << Logger::Info << backend_name << "(list) END" << endl; | |
119bcf6c | 99 | |
e18dbde1 BH |
100 | return ok; |
101 | } | |
119bcf6c PD |
102 | |
103 | void LUABackend::lookup(const QType &qtype, const DNSName &qname, DNSPacket *p, int domain_id) { | |
e18dbde1 BH |
104 | if (logging) |
105 | L << Logger::Info << backend_name << "(lookup) BEGIN" << endl; | |
106 | ||
107 | dnspacket = p; | |
119bcf6c | 108 | |
e18dbde1 BH |
109 | lua_rawgeti(lua, LUA_REGISTRYINDEX, f_lua_lookup); |
110 | ||
111 | // lua_pushnumber(lua, qtype.getCode()); | |
112 | lua_pushstring(lua, qtype.getName().c_str()); | |
119bcf6c | 113 | lua_pushstring(lua, qname.toString(). c_str()); |
c03d545e | 114 | lua_pushinteger(lua, domain_id); |
e18dbde1 BH |
115 | |
116 | if(lua_pcall(lua, 3, 0, f_lua_exec_error) != 0) { | |
117 | string e = backend_name + lua_tostring(lua, -1); | |
118 | lua_pop(lua, 1); | |
119bcf6c | 119 | |
e18dbde1 | 120 | dnspacket = NULL; |
119bcf6c | 121 | |
e18dbde1 BH |
122 | throw runtime_error(e); |
123 | return; | |
124 | } | |
119bcf6c | 125 | |
e18dbde1 | 126 | dnspacket = NULL; |
119bcf6c | 127 | |
e18dbde1 BH |
128 | if (logging) |
129 | L << Logger::Info << backend_name << "(lookup) END" << endl; | |
130 | } | |
131 | ||
132 | bool LUABackend::get(DNSResourceRecord &rr) { | |
133 | if (logging) | |
134 | L << Logger::Info << backend_name << "(get) BEGIN" << endl; | |
119bcf6c | 135 | |
e18dbde1 | 136 | lua_rawgeti(lua, LUA_REGISTRYINDEX, f_lua_get); |
119bcf6c | 137 | |
e18dbde1 BH |
138 | if(lua_pcall(lua, 0, 1, f_lua_exec_error) != 0) { |
139 | string e = backend_name + lua_tostring(lua, -1); | |
140 | lua_pop(lua, 1); | |
119bcf6c | 141 | |
e18dbde1 BH |
142 | throw runtime_error(e); |
143 | return false; | |
144 | } | |
119bcf6c | 145 | |
e18dbde1 BH |
146 | size_t returnedwhat = lua_type(lua, -1); |
147 | if (returnedwhat != LUA_TTABLE) { | |
148 | lua_pop(lua, 1 ); | |
149 | return false; | |
150 | } | |
119bcf6c | 151 | |
e18dbde1 | 152 | rr.content.clear(); |
119bcf6c | 153 | |
e18dbde1 BH |
154 | // uint16_t qt; |
155 | string qt; | |
119bcf6c | 156 | |
e18dbde1 BH |
157 | if (getValueFromTable(lua, "type", qt) ) |
158 | rr.qtype = qt; | |
159 | getValueFromTable(lua, "name", rr.qname); | |
160 | getValueFromTable(lua, "domain_id", rr.domain_id); | |
161 | getValueFromTable(lua, "auth", rr.auth); | |
162 | getValueFromTable(lua, "last_modified", rr.last_modified); | |
e18dbde1 BH |
163 | |
164 | getValueFromTable(lua, "ttl", rr.ttl); | |
119bcf6c | 165 | if (rr.ttl == 0) |
e18dbde1 | 166 | rr.ttl = ::arg().asNum( "default-ttl" ); |
119bcf6c | 167 | |
e18dbde1 | 168 | getValueFromTable(lua, "content", rr.content); |
25d96f49 | 169 | getValueFromTable(lua, "scopeMask", rr.scopeMask); |
e18dbde1 BH |
170 | |
171 | lua_pop(lua, 1 ); | |
119bcf6c | 172 | |
e18dbde1 BH |
173 | if (logging) |
174 | L << Logger::Info << backend_name << "(get) END" << endl; | |
119bcf6c | 175 | |
e18dbde1 BH |
176 | return !rr.content.empty(); |
177 | } | |
178 | ||
13f9e280 | 179 | bool LUABackend::getSOA(const DNSName &name, SOAData &soadata, bool unmodifiedSerial) { |
e18dbde1 BH |
180 | if (logging) |
181 | L << Logger::Info << backend_name << "(getsoa) BEGIN" << endl; | |
119bcf6c | 182 | |
e18dbde1 | 183 | lua_rawgeti(lua, LUA_REGISTRYINDEX, f_lua_getsoa); |
119bcf6c | 184 | |
444f0add | 185 | lua_pushstring(lua, name.toString().c_str()); |
119bcf6c | 186 | |
e18dbde1 BH |
187 | if(lua_pcall(lua, 1, 1, f_lua_exec_error) != 0) { |
188 | string e = backend_name + lua_tostring(lua, -1); | |
189 | lua_pop(lua, 1); | |
119bcf6c | 190 | |
e18dbde1 BH |
191 | throw runtime_error(e); |
192 | return false; | |
193 | } | |
119bcf6c | 194 | |
e18dbde1 BH |
195 | size_t returnedwhat = lua_type(lua, -1); |
196 | if (returnedwhat != LUA_TTABLE) { | |
197 | lua_pop(lua, 1 ); | |
198 | return false; | |
199 | } | |
200 | ||
201 | soadata.db = this; | |
202 | soadata.serial = 0; | |
8b831366 | 203 | soadata.qname = name; |
e18dbde1 BH |
204 | getValueFromTable(lua, "serial", soadata.serial); |
205 | if (soadata.serial == 0) { | |
206 | lua_pop(lua, 1 ); | |
207 | return false; | |
208 | } | |
119bcf6c | 209 | |
e18dbde1 BH |
210 | getValueFromTable(lua, "refresh", soadata.refresh); |
211 | getValueFromTable(lua, "retry", soadata.retry); | |
212 | getValueFromTable(lua, "expire", soadata.expire); | |
213 | getValueFromTable(lua, "default_ttl", soadata.default_ttl); | |
214 | getValueFromTable(lua, "domain_id", soadata.domain_id); | |
119bcf6c | 215 | |
e18dbde1 | 216 | getValueFromTable(lua, "ttl", soadata.ttl); |
119bcf6c | 217 | if (soadata.ttl == 0 && soadata.default_ttl > 0) |
e18dbde1 | 218 | soadata.ttl = soadata.default_ttl; |
119bcf6c | 219 | |
e18dbde1 BH |
220 | if (soadata.ttl == 0) { |
221 | lua_pop(lua, 1 ); | |
222 | return false; | |
223 | } | |
119bcf6c | 224 | |
e18dbde1 | 225 | if (!getValueFromTable(lua, "nameserver", soadata.nameserver)) { |
b92c9416 | 226 | soadata.nameserver = DNSName(arg()["default-soa-name"]); |
e18dbde1 | 227 | if (soadata.nameserver.empty()) { |
119bcf6c | 228 | L<<Logger::Error << backend_name << "(getSOA)" << " Error: SOA Record is missing nameserver for the domain '" << name << "'" << endl; |
e18dbde1 BH |
229 | lua_pop(lua, 1 ); |
230 | return false; | |
231 | } | |
232 | } | |
119bcf6c | 233 | |
e18dbde1 | 234 | if (!getValueFromTable(lua, "hostmaster", soadata.hostmaster)) |
b92c9416 | 235 | soadata.hostmaster = DNSName("hostmaster")+DNSName(name); |
e18dbde1 BH |
236 | |
237 | lua_pop(lua, 1 ); | |
238 | ||
239 | if (logging) | |
240 | L << Logger::Info << backend_name << "(getsoa) END" << endl; | |
119bcf6c | 241 | |
e18dbde1 BH |
242 | return true; |
243 | } |