]>
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 BH |
63 | LUABackend::~LUABackend() { |
64 | L<<Logger::Info<<backend_name<<"Closeing..." << endl; | |
119bcf6c | 65 | |
e18dbde1 BH |
66 | lua_close(lua); |
67 | } | |
68 | ||
119bcf6c | 69 | bool LUABackend::list(const DNSName &target, int domain_id, bool include_disabled) { |
e18dbde1 BH |
70 | if (logging) |
71 | L << Logger::Info << backend_name << "(list) BEGIN" << endl; | |
72 | ||
73 | lua_rawgeti(lua, LUA_REGISTRYINDEX, f_lua_list); | |
74 | ||
119bcf6c | 75 | lua_pushstring(lua, target.toString().c_str()); |
c03d545e | 76 | lua_pushinteger(lua, domain_id); |
e18dbde1 BH |
77 | |
78 | if(lua_pcall(lua, 2, 1, f_lua_exec_error) != 0) { | |
79 | string e = backend_name + lua_tostring(lua, -1); | |
80 | lua_pop(lua, 1); | |
119bcf6c | 81 | |
e18dbde1 | 82 | throw runtime_error(e); |
e18dbde1 | 83 | } |
119bcf6c | 84 | |
e18dbde1 BH |
85 | size_t returnedwhat = lua_type(lua, -1); |
86 | bool ok = false; | |
119bcf6c | 87 | |
e18dbde1 BH |
88 | if (returnedwhat == LUA_TBOOLEAN) |
89 | ok = lua_toboolean(lua, -1); | |
119bcf6c | 90 | |
e18dbde1 BH |
91 | lua_pop(lua, 1); |
92 | ||
93 | if (logging) | |
94 | L << Logger::Info << backend_name << "(list) END" << endl; | |
119bcf6c | 95 | |
e18dbde1 BH |
96 | return ok; |
97 | } | |
119bcf6c PD |
98 | |
99 | void LUABackend::lookup(const QType &qtype, const DNSName &qname, DNSPacket *p, int domain_id) { | |
e18dbde1 BH |
100 | if (logging) |
101 | L << Logger::Info << backend_name << "(lookup) BEGIN" << endl; | |
102 | ||
103 | dnspacket = p; | |
119bcf6c | 104 | |
e18dbde1 BH |
105 | lua_rawgeti(lua, LUA_REGISTRYINDEX, f_lua_lookup); |
106 | ||
107 | // lua_pushnumber(lua, qtype.getCode()); | |
108 | lua_pushstring(lua, qtype.getName().c_str()); | |
119bcf6c | 109 | lua_pushstring(lua, qname.toString(). c_str()); |
c03d545e | 110 | lua_pushinteger(lua, domain_id); |
e18dbde1 BH |
111 | |
112 | if(lua_pcall(lua, 3, 0, f_lua_exec_error) != 0) { | |
113 | string e = backend_name + lua_tostring(lua, -1); | |
114 | lua_pop(lua, 1); | |
119bcf6c | 115 | |
e18dbde1 | 116 | dnspacket = NULL; |
119bcf6c | 117 | |
e18dbde1 BH |
118 | throw runtime_error(e); |
119 | return; | |
120 | } | |
119bcf6c | 121 | |
e18dbde1 | 122 | dnspacket = NULL; |
119bcf6c | 123 | |
e18dbde1 BH |
124 | if (logging) |
125 | L << Logger::Info << backend_name << "(lookup) END" << endl; | |
126 | } | |
127 | ||
128 | bool LUABackend::get(DNSResourceRecord &rr) { | |
129 | if (logging) | |
130 | L << Logger::Info << backend_name << "(get) BEGIN" << endl; | |
119bcf6c | 131 | |
e18dbde1 | 132 | lua_rawgeti(lua, LUA_REGISTRYINDEX, f_lua_get); |
119bcf6c | 133 | |
e18dbde1 BH |
134 | if(lua_pcall(lua, 0, 1, f_lua_exec_error) != 0) { |
135 | string e = backend_name + lua_tostring(lua, -1); | |
136 | lua_pop(lua, 1); | |
119bcf6c | 137 | |
e18dbde1 BH |
138 | throw runtime_error(e); |
139 | return false; | |
140 | } | |
119bcf6c | 141 | |
e18dbde1 BH |
142 | size_t returnedwhat = lua_type(lua, -1); |
143 | if (returnedwhat != LUA_TTABLE) { | |
144 | lua_pop(lua, 1 ); | |
145 | return false; | |
146 | } | |
119bcf6c | 147 | |
e18dbde1 | 148 | rr.content.clear(); |
119bcf6c | 149 | |
e18dbde1 BH |
150 | // uint16_t qt; |
151 | string qt; | |
119bcf6c | 152 | |
e18dbde1 BH |
153 | if (getValueFromTable(lua, "type", qt) ) |
154 | rr.qtype = qt; | |
155 | getValueFromTable(lua, "name", rr.qname); | |
156 | getValueFromTable(lua, "domain_id", rr.domain_id); | |
157 | getValueFromTable(lua, "auth", rr.auth); | |
158 | getValueFromTable(lua, "last_modified", rr.last_modified); | |
e18dbde1 BH |
159 | |
160 | getValueFromTable(lua, "ttl", rr.ttl); | |
119bcf6c | 161 | if (rr.ttl == 0) |
e18dbde1 | 162 | rr.ttl = ::arg().asNum( "default-ttl" ); |
119bcf6c | 163 | |
e18dbde1 | 164 | getValueFromTable(lua, "content", rr.content); |
25d96f49 | 165 | getValueFromTable(lua, "scopeMask", rr.scopeMask); |
e18dbde1 BH |
166 | |
167 | lua_pop(lua, 1 ); | |
119bcf6c | 168 | |
e18dbde1 BH |
169 | if (logging) |
170 | L << Logger::Info << backend_name << "(get) END" << endl; | |
119bcf6c | 171 | |
e18dbde1 BH |
172 | return !rr.content.empty(); |
173 | } | |
174 | ||
175 | bool LUABackend::getSOA(const string &name, SOAData &soadata, DNSPacket *p) { | |
176 | if (logging) | |
177 | L << Logger::Info << backend_name << "(getsoa) BEGIN" << endl; | |
119bcf6c | 178 | |
e18dbde1 BH |
179 | dnspacket = p; |
180 | ||
181 | lua_rawgeti(lua, LUA_REGISTRYINDEX, f_lua_getsoa); | |
119bcf6c | 182 | |
e18dbde1 | 183 | lua_pushstring(lua, name.c_str()); |
119bcf6c | 184 | |
e18dbde1 BH |
185 | if(lua_pcall(lua, 1, 1, f_lua_exec_error) != 0) { |
186 | string e = backend_name + lua_tostring(lua, -1); | |
187 | lua_pop(lua, 1); | |
119bcf6c | 188 | |
e18dbde1 | 189 | dnspacket = NULL; |
119bcf6c | 190 | |
e18dbde1 BH |
191 | throw runtime_error(e); |
192 | return false; | |
193 | } | |
119bcf6c | 194 | |
e18dbde1 | 195 | dnspacket = NULL; |
119bcf6c | 196 | |
e18dbde1 BH |
197 | size_t returnedwhat = lua_type(lua, -1); |
198 | if (returnedwhat != LUA_TTABLE) { | |
199 | lua_pop(lua, 1 ); | |
200 | return false; | |
201 | } | |
202 | ||
203 | soadata.db = this; | |
204 | soadata.serial = 0; | |
205 | getValueFromTable(lua, "serial", soadata.serial); | |
206 | if (soadata.serial == 0) { | |
207 | lua_pop(lua, 1 ); | |
208 | return false; | |
209 | } | |
119bcf6c | 210 | |
e18dbde1 BH |
211 | getValueFromTable(lua, "refresh", soadata.refresh); |
212 | getValueFromTable(lua, "retry", soadata.retry); | |
213 | getValueFromTable(lua, "expire", soadata.expire); | |
214 | getValueFromTable(lua, "default_ttl", soadata.default_ttl); | |
215 | getValueFromTable(lua, "domain_id", soadata.domain_id); | |
119bcf6c | 216 | |
e18dbde1 | 217 | getValueFromTable(lua, "ttl", soadata.ttl); |
119bcf6c | 218 | if (soadata.ttl == 0 && soadata.default_ttl > 0) |
e18dbde1 | 219 | soadata.ttl = soadata.default_ttl; |
119bcf6c | 220 | |
e18dbde1 BH |
221 | if (soadata.ttl == 0) { |
222 | lua_pop(lua, 1 ); | |
223 | return false; | |
224 | } | |
119bcf6c | 225 | |
e18dbde1 | 226 | if (!getValueFromTable(lua, "nameserver", soadata.nameserver)) { |
b92c9416 | 227 | soadata.nameserver = DNSName(arg()["default-soa-name"]); |
e18dbde1 | 228 | if (soadata.nameserver.empty()) { |
119bcf6c | 229 | L<<Logger::Error << backend_name << "(getSOA)" << " Error: SOA Record is missing nameserver for the domain '" << name << "'" << endl; |
e18dbde1 BH |
230 | lua_pop(lua, 1 ); |
231 | return false; | |
232 | } | |
233 | } | |
119bcf6c | 234 | |
e18dbde1 | 235 | if (!getValueFromTable(lua, "hostmaster", soadata.hostmaster)) |
b92c9416 | 236 | soadata.hostmaster = DNSName("hostmaster")+DNSName(name); |
e18dbde1 BH |
237 | |
238 | lua_pop(lua, 1 ); | |
239 | ||
240 | if (logging) | |
241 | L << Logger::Info << backend_name << "(getsoa) END" << endl; | |
119bcf6c | 242 | |
e18dbde1 BH |
243 | return true; |
244 | } |