]>
Commit | Line | Data |
---|---|---|
6a99b9a4 | 1 | #include "config.h" |
3e61e7f7 | 2 | #include "ext/luawrapper/include/LuaContext.hpp" |
6a99b9a4 | 3 | |
3e61e7f7 | 4 | #include <fstream> |
ad42489c | 5 | #include <thread> |
3e61e7f7 | 6 | #include "namespaces.hh" |
7 | #include "logger.hh" | |
f3c18728 | 8 | #include "rec-lua-conf.hh" |
3e61e7f7 | 9 | #include "sortlist.hh" |
ad42489c | 10 | #include "filterpo.hh" |
11 | #include "syncres.hh" | |
12 | #include "rpzloader.hh" | |
98c9ec39 | 13 | #include "base64.hh" |
aa7929a3 | 14 | #include "remote_logger.hh" |
52ad9eea | 15 | #include "validate.hh" |
e48c6b8a | 16 | #include "validate-recursor.hh" |
f2234140 | 17 | #include "root-dnssec.hh" |
3e61e7f7 | 18 | |
12ce523e | 19 | GlobalStateHolder<LuaConfigItems> g_luaconfs; |
f3c18728 | 20 | |
21 | /* SO HOW DOES THIS WORK! AND PLEASE PAY ATTENTION! | |
22 | This function can be called at any time. It is expected to overwrite all the contents | |
23 | of LuaConfigItems, which is held in a GlobalStateHolder for RCU properties. | |
24 | ||
25 | This function can be called again at a later date, so you must make sure that anything you | |
26 | allow to be configured from here lives in g_luaconfs AND NOWHERE ELSE. | |
27 | ||
28 | If someone loads an empty Lua file, the default LuaConfigItems struct MUST MAKE SENSE. | |
29 | ||
30 | To make this easy on you, here is a LuaConfigItems constructor where you | |
31 | can set sane defaults: | |
32 | */ | |
33 | ||
34 | LuaConfigItems::LuaConfigItems() | |
35 | { | |
03bf7abb | 36 | DNSName root("."); // don't use g_rootdnsname here, it might not exist yet |
f2234140 | 37 | for (const auto &dsRecord : rootDSs) { |
32122aab | 38 | auto ds=std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(dsRecord)); |
03bf7abb | 39 | dsAnchors[root].insert(*ds); |
f2234140 | 40 | } |
f3c18728 | 41 | } |
42 | ||
ad42489c | 43 | /* DID YOU READ THE STORY ABOVE? */ |
44 | ||
45 | template <typename C> | |
46 | typename C::value_type::second_type constGet(const C& c, const std::string& name) | |
47 | { | |
48 | auto iter = c.find(name); | |
49 | if(iter == c.end()) | |
50 | return 0; | |
51 | return iter->second; | |
52 | } | |
53 | ||
d122dac0 | 54 | typedef std::unordered_map<std::string, boost::variant<bool, uint32_t, std::string > > rpzOptions_t; |
6a99b9a4 | 55 | |
d122dac0 | 56 | static void parseRPZParameters(rpzOptions_t& have, std::string& polName, boost::optional<DNSFilterEngine::Policy>& defpol, bool& defpolOverrideLocal, uint32_t& maxTTL, size_t& zoneSizeHint) |
8f618901 RG |
57 | { |
58 | if(have.count("policyName")) { | |
d122dac0 | 59 | polName = boost::get<std::string>(have["policyName"]); |
8f618901 RG |
60 | } |
61 | if(have.count("defpol")) { | |
62 | defpol=DNSFilterEngine::Policy(); | |
d122dac0 | 63 | defpol->d_kind = (DNSFilterEngine::PolicyKind)boost::get<uint32_t>(have["defpol"]); |
8f618901 RG |
64 | defpol->d_name = std::make_shared<std::string>(polName); |
65 | if(defpol->d_kind == DNSFilterEngine::PolicyKind::Custom) { | |
6da513b2 | 66 | defpol->d_custom.push_back(DNSRecordContent::mastermake(QType::CNAME, QClass::IN, |
d122dac0 | 67 | boost::get<string>(have["defcontent"]))); |
8f618901 RG |
68 | |
69 | if(have.count("defttl")) | |
d122dac0 | 70 | defpol->d_ttl = static_cast<int32_t>(boost::get<uint32_t>(have["defttl"])); |
8f618901 RG |
71 | else |
72 | defpol->d_ttl = -1; // get it from the zone | |
73 | } | |
d122dac0 RG |
74 | |
75 | if (have.count("defpolOverrideLocalData")) { | |
76 | defpolOverrideLocal = boost::get<bool>(have["defpolOverrideLocalData"]); | |
77 | } | |
8f618901 RG |
78 | } |
79 | if(have.count("maxTTL")) { | |
d122dac0 | 80 | maxTTL = boost::get<uint32_t>(have["maxTTL"]); |
8f618901 RG |
81 | } |
82 | if(have.count("zoneSizeHint")) { | |
d122dac0 | 83 | zoneSizeHint = static_cast<size_t>(boost::get<uint32_t>(have["zoneSizeHint"])); |
8f618901 RG |
84 | } |
85 | } | |
86 | ||
abbf4bba | 87 | #if HAVE_PROTOBUF |
0bd2e252 | 88 | typedef std::unordered_map<std::string, boost::variant<bool, uint64_t, std::string, std::vector<std::pair<int,std::string> > > > protobufOptions_t; |
f1c7929a RG |
89 | |
90 | static void parseProtobufOptions(boost::optional<protobufOptions_t> vars, ProtobufExportConfig& config) | |
91 | { | |
92 | if (!vars) { | |
93 | return; | |
94 | } | |
95 | ||
96 | if (vars->count("timeout")) { | |
97 | config.timeout = boost::get<uint64_t>((*vars)["timeout"]); | |
98 | } | |
99 | ||
100 | if (vars->count("maxQueuedEntries")) { | |
101 | config.maxQueuedEntries = boost::get<uint64_t>((*vars)["maxQueuedEntries"]); | |
102 | } | |
103 | ||
104 | if (vars->count("reconnectWaitTime")) { | |
105 | config.reconnectWaitTime = boost::get<uint64_t>((*vars)["reconnectWaitTime"]); | |
106 | } | |
107 | ||
108 | if (vars->count("asyncConnect")) { | |
109 | config.asyncConnect = boost::get<bool>((*vars)["asyncConnect"]); | |
110 | } | |
111 | ||
112 | if (vars->count("taggedOnly")) { | |
113 | config.taggedOnly = boost::get<bool>((*vars)["taggedOnly"]); | |
114 | } | |
115 | ||
116 | if (vars->count("logQueries")) { | |
117 | config.logQueries = boost::get<bool>((*vars)["logQueries"]); | |
118 | } | |
119 | ||
120 | if (vars->count("logResponses")) { | |
121 | config.logResponses = boost::get<bool>((*vars)["logResponses"]); | |
122 | } | |
0bd2e252 RG |
123 | |
124 | if (vars->count("exportTypes")) { | |
125 | config.exportTypes.clear(); | |
126 | ||
127 | auto types = boost::get<std::vector<std::pair<int, std::string>>>((*vars)["exportTypes"]); | |
128 | for (const auto& pair : types) { | |
129 | const auto type = pair.second; | |
130 | bool found = false; | |
131 | ||
132 | for (const auto& entry : QType::names) { | |
133 | if (entry.first == type) { | |
134 | found = true; | |
135 | config.exportTypes.insert(entry.second); | |
136 | break; | |
137 | } | |
138 | } | |
139 | ||
140 | if (!found) { | |
141 | throw std::runtime_error("Unknown QType '" + type + "' in protobuf's export types"); | |
142 | } | |
143 | } | |
144 | } | |
f1c7929a | 145 | } |
abbf4bba | 146 | #endif /* HAVE_PROTOBUF */ |
f1c7929a | 147 | |
e6ec15bf | 148 | void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& delayedThreads) |
3e61e7f7 | 149 | { |
f3c18728 | 150 | LuaConfigItems lci; |
151 | ||
3e61e7f7 | 152 | LuaContext Lua; |
153 | if(fname.empty()) | |
154 | return; | |
155 | ifstream ifs(fname); | |
0f5785a6 PL |
156 | if(!ifs) |
157 | throw PDNSException("Cannot open file '"+fname+"': "+strerror(errno)); | |
158 | ||
63341e8d RG |
159 | auto luaconfsLocal = g_luaconfs.getLocal(); |
160 | lci.generation = luaconfsLocal->generation + 1; | |
161 | ||
c2cc36d8 CH |
162 | // pdnslog here is compatible with pdnslog in lua-base4.cc. |
163 | Lua.writeFunction("pdnslog", [](const std::string& msg, boost::optional<int> loglevel) { g_log << (Logger::Urgency)loglevel.get_value_or(Logger::Warning) << msg<<endl; }); | |
164 | std::unordered_map<string, std::unordered_map<string, int>> pdns_table; | |
165 | pdns_table["loglevels"] = std::unordered_map<string, int>{ | |
166 | {"Alert", LOG_ALERT}, | |
167 | {"Critical", LOG_CRIT}, | |
168 | {"Debug", LOG_DEBUG}, | |
169 | {"Emergency", LOG_EMERG}, | |
170 | {"Info", LOG_INFO}, | |
171 | {"Notice", LOG_NOTICE}, | |
172 | {"Warning", LOG_WARNING}, | |
173 | {"Error", LOG_ERR} | |
174 | }; | |
175 | Lua.writeVariable("pdns", pdns_table); | |
176 | ||
f3c18728 | 177 | Lua.writeFunction("clearSortlist", [&lci]() { lci.sortlist.clear(); }); |
3e61e7f7 | 178 | |
179 | /* we can get: "1.2.3.4" | |
180 | {"1.2.3.4", "4.5.6.7"} | |
181 | {"1.2.3.4", {"4.5.6.7", "8.9.10.11"}} | |
182 | */ | |
183 | ||
ad42489c | 184 | map<string,DNSFilterEngine::PolicyKind> pmap{ |
185 | {"NoAction", DNSFilterEngine::PolicyKind::NoAction}, | |
186 | {"Drop", DNSFilterEngine::PolicyKind::Drop}, | |
187 | {"NXDOMAIN", DNSFilterEngine::PolicyKind::NXDOMAIN}, | |
188 | {"NODATA", DNSFilterEngine::PolicyKind::NODATA}, | |
189 | {"Truncate", DNSFilterEngine::PolicyKind::Truncate}, | |
190 | {"Custom", DNSFilterEngine::PolicyKind::Custom} | |
191 | }; | |
192 | Lua.writeVariable("Policy", pmap); | |
193 | ||
d122dac0 | 194 | Lua.writeFunction("rpzFile", [&lci](const string& filename, boost::optional<rpzOptions_t> options) { |
ad42489c | 195 | try { |
563bbdca | 196 | boost::optional<DNSFilterEngine::Policy> defpol; |
d122dac0 | 197 | bool defpolOverrideLocal = true; |
563bbdca | 198 | std::string polName("rpzFile"); |
6b972d59 | 199 | std::shared_ptr<DNSFilterEngine::Zone> zone = std::make_shared<DNSFilterEngine::Zone>(); |
563bbdca RG |
200 | uint32_t maxTTL = std::numeric_limits<uint32_t>::max(); |
201 | if(options) { | |
202 | auto& have = *options; | |
8f618901 | 203 | size_t zoneSizeHint = 0; |
d122dac0 | 204 | parseRPZParameters(have, polName, defpol, defpolOverrideLocal, maxTTL, zoneSizeHint); |
8f618901 | 205 | if (zoneSizeHint > 0) { |
6b972d59 | 206 | zone->reserve(zoneSizeHint); |
a2d0450e | 207 | } |
563bbdca | 208 | } |
e6a9dde5 | 209 | g_log<<Logger::Warning<<"Loading RPZ from file '"<<filename<<"'"<<endl; |
6b972d59 | 210 | zone->setName(polName); |
d122dac0 | 211 | loadRPZFromFile(filename, zone, defpol, defpolOverrideLocal, maxTTL); |
6b972d59 | 212 | lci.dfe.addZone(zone); |
e6a9dde5 | 213 | g_log<<Logger::Warning<<"Done loading RPZ from file '"<<filename<<"'"<<endl; |
ad42489c | 214 | } |
6791663c | 215 | catch(const std::exception& e) { |
e6a9dde5 | 216 | g_log<<Logger::Error<<"Unable to load RPZ zone from '"<<filename<<"': "<<e.what()<<endl; |
ad42489c | 217 | } |
218 | }); | |
219 | ||
d122dac0 | 220 | Lua.writeFunction("rpzMaster", [&lci, &delayedThreads](const boost::variant<string, std::vector<std::pair<int, string> > >& masters_, const string& zoneName, boost::optional<rpzOptions_t> options) { |
209955c7 | 221 | |
222 | boost::optional<DNSFilterEngine::Policy> defpol; | |
d122dac0 | 223 | bool defpolOverrideLocal = true; |
209955c7 | 224 | std::shared_ptr<DNSFilterEngine::Zone> zone = std::make_shared<DNSFilterEngine::Zone>(); |
225 | TSIGTriplet tt; | |
226 | uint32_t refresh=0; | |
227 | size_t maxReceivedXFRMBytes = 0; | |
ea448a77 | 228 | uint16_t axfrTimeout = 20; |
209955c7 | 229 | uint32_t maxTTL = std::numeric_limits<uint32_t>::max(); |
230 | ComboAddress localAddress; | |
5f311886 RG |
231 | std::vector<ComboAddress> masters; |
232 | if (masters_.type() == typeid(string)) { | |
233 | masters.push_back(ComboAddress(boost::get<std::string>(masters_), 53)); | |
234 | } | |
235 | else { | |
236 | for (const auto& master : boost::get<std::vector<std::pair<int, std::string>>>(masters_)) { | |
237 | masters.push_back(ComboAddress(master.second, 53)); | |
238 | } | |
239 | } | |
240 | ||
209955c7 | 241 | size_t zoneIdx; |
23f886c0 | 242 | std::string dumpFile; |
a66c5cfa | 243 | std::shared_ptr<SOARecordContent> sr = nullptr; |
209955c7 | 244 | |
ad42489c | 245 | try { |
a66c5cfa | 246 | std::string seedFile; |
6b972d59 | 247 | std::string polName(zoneName); |
a66c5cfa RG |
248 | |
249 | if (options) { | |
563bbdca | 250 | auto& have = *options; |
8f618901 | 251 | size_t zoneSizeHint = 0; |
d122dac0 | 252 | parseRPZParameters(have, polName, defpol, defpolOverrideLocal, maxTTL, zoneSizeHint); |
8f618901 | 253 | if (zoneSizeHint > 0) { |
6b972d59 | 254 | zone->reserve(zoneSizeHint); |
a2d0450e | 255 | } |
a66c5cfa | 256 | |
563bbdca | 257 | if(have.count("tsigname")) { |
d122dac0 RG |
258 | tt.name=DNSName(toLower(boost::get<string>(have["tsigname"]))); |
259 | tt.algo=DNSName(toLower(boost::get<string>(have[ "tsigalgo"]))); | |
260 | if(B64Decode(boost::get<string>(have[ "tsigsecret"]), tt.secret)) | |
98c9ec39 | 261 | throw std::runtime_error("TSIG secret is not valid Base-64 encoded"); |
262 | } | |
a66c5cfa | 263 | |
98c9ec39 | 264 | if(have.count("refresh")) { |
d122dac0 | 265 | refresh = boost::get<uint32_t>(have["refresh"]); |
98c9ec39 | 266 | } |
a66c5cfa | 267 | |
db8f9152 | 268 | if(have.count("maxReceivedMBytes")) { |
d122dac0 | 269 | maxReceivedXFRMBytes = static_cast<size_t>(boost::get<uint32_t>(have["maxReceivedMBytes"])); |
db8f9152 | 270 | } |
a66c5cfa | 271 | |
f6a8f7d7 | 272 | if(have.count("localAddress")) { |
d122dac0 | 273 | localAddress = ComboAddress(boost::get<string>(have["localAddress"])); |
f6a8f7d7 | 274 | } |
a66c5cfa | 275 | |
ea448a77 | 276 | if(have.count("axfrTimeout")) { |
d122dac0 | 277 | axfrTimeout = static_cast<uint16_t>(boost::get<uint32_t>(have["axfrTimeout"])); |
ea448a77 | 278 | } |
a66c5cfa RG |
279 | |
280 | if(have.count("seedFile")) { | |
d122dac0 | 281 | seedFile = boost::get<std::string>(have["seedFile"]); |
a66c5cfa | 282 | } |
23f886c0 RG |
283 | |
284 | if(have.count("dumpFile")) { | |
d122dac0 | 285 | dumpFile = boost::get<std::string>(have["dumpFile"]); |
23f886c0 | 286 | } |
563bbdca | 287 | } |
a66c5cfa | 288 | |
5f311886 RG |
289 | if (localAddress != ComboAddress()) { |
290 | // We were passed a localAddress, check if its AF matches the masters' | |
291 | for (const auto& master : masters) { | |
292 | if (localAddress.sin4.sin_family != master.sin4.sin_family) { | |
293 | throw PDNSException("Master address("+master.toString()+") is not of the same Address Family as the local address ("+localAddress.toString()+")."); | |
294 | } | |
295 | } | |
6791663c RG |
296 | } |
297 | ||
a66c5cfa RG |
298 | DNSName domain(zoneName); |
299 | zone->setDomain(domain); | |
6b972d59 | 300 | zone->setName(polName); |
6791663c | 301 | zone->setRefresh(refresh); |
209955c7 | 302 | zoneIdx = lci.dfe.addZone(zone); |
a66c5cfa RG |
303 | |
304 | if (!seedFile.empty()) { | |
23f886c0 RG |
305 | g_log<<Logger::Info<<"Pre-loading RPZ zone "<<zoneName<<" from seed file '"<<seedFile<<"'"<<endl; |
306 | try { | |
d122dac0 | 307 | sr = loadRPZFromFile(seedFile, zone, defpol, defpolOverrideLocal, maxTTL); |
a66c5cfa | 308 | |
23f886c0 RG |
309 | if (zone->getDomain() != domain) { |
310 | throw PDNSException("The RPZ zone " + zoneName + " loaded from the seed file (" + zone->getDomain().toString() + ") does not match the one passed in parameter (" + domain.toString() + ")"); | |
311 | } | |
312 | ||
313 | if (sr == nullptr) { | |
314 | throw PDNSException("The RPZ zone " + zoneName + " loaded from the seed file (" + zone->getDomain().toString() + ") has no SOA record"); | |
315 | } | |
316 | } | |
317 | catch(const std::exception& e) { | |
318 | g_log<<Logger::Warning<<"Unable to pre-load RPZ zone "<<zoneName<<" from seed file '"<<seedFile<<"': "<<e.what()<<endl; | |
a66c5cfa RG |
319 | } |
320 | } | |
ad42489c | 321 | } |
6791663c | 322 | catch(const std::exception& e) { |
e6a9dde5 | 323 | g_log<<Logger::Error<<"Problem configuring 'rpzMaster': "<<e.what()<<endl; |
209955c7 | 324 | exit(1); // FIXME proper exit code? |
ad42489c | 325 | } |
6791663c | 326 | catch(const PDNSException& e) { |
e6a9dde5 | 327 | g_log<<Logger::Error<<"Problem configuring 'rpzMaster': "<<e.reason<<endl; |
209955c7 | 328 | exit(1); // FIXME proper exit code? |
ad42489c | 329 | } |
330 | ||
d122dac0 | 331 | delayedThreads.rpzMasterThreads.push_back(std::make_tuple(masters, defpol, defpolOverrideLocal, maxTTL, zoneIdx, tt, maxReceivedXFRMBytes, localAddress, axfrTimeout, sr, dumpFile)); |
ad42489c | 332 | }); |
333 | ||
3e61e7f7 | 334 | typedef vector<pair<int,boost::variant<string, vector<pair<int, string> > > > > argvec_t; |
335 | Lua.writeFunction("addSortList", | |
f3c18728 | 336 | [&lci](const std::string& formask_, |
3e61e7f7 | 337 | const boost::variant<string, argvec_t>& masks, |
338 | boost::optional<int> order_) | |
339 | { | |
340 | try { | |
341 | Netmask formask(formask_); | |
f3c18728 | 342 | int order = order_ ? (*order_) : lci.sortlist.getMaxOrder(formask)+1; |
3e61e7f7 | 343 | if(auto str = boost::get<string>(&masks)) |
f3c18728 | 344 | lci.sortlist.addEntry(formask, Netmask(*str), order); |
3e61e7f7 | 345 | else { |
346 | ||
347 | auto vec = boost::get<argvec_t>(&masks); | |
348 | for(const auto& e : *vec) { | |
349 | if(auto s = boost::get<string>(&e.second)) { | |
f3c18728 | 350 | lci.sortlist.addEntry(formask, Netmask(*s), order); |
3e61e7f7 | 351 | } |
352 | else { | |
353 | const auto& v =boost::get<vector<pair<int, string> > >(e.second); | |
dd079764 RG |
354 | for(const auto& entry : v) |
355 | lci.sortlist.addEntry(formask, Netmask(entry.second), order); | |
3e61e7f7 | 356 | } |
357 | ++order; | |
358 | } | |
359 | } | |
360 | } | |
361 | catch(std::exception& e) { | |
e6a9dde5 | 362 | g_log<<Logger::Error<<"Error in addSortList: "<<e.what()<<endl; |
3e61e7f7 | 363 | } |
364 | }); | |
2ac8ae89 | 365 | |
190e0d9a PL |
366 | Lua.writeFunction("addTA", [&lci](const std::string& who, const std::string& what) { |
367 | warnIfDNSSECDisabled("Warning: adding Trust Anchor for DNSSEC (addTA), but dnssec is set to 'off'!"); | |
368 | DNSName zone(who); | |
32122aab | 369 | auto ds = std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(what)); |
190e0d9a PL |
370 | lci.dsAnchors[zone].insert(*ds); |
371 | }); | |
372 | ||
373 | Lua.writeFunction("clearTA", [&lci](boost::optional<string> who) { | |
374 | warnIfDNSSECDisabled("Warning: removing Trust Anchor for DNSSEC (clearTA), but dnssec is set to 'off'!"); | |
375 | if(who) | |
376 | lci.dsAnchors.erase(DNSName(*who)); | |
377 | else | |
378 | lci.dsAnchors.clear(); | |
379 | }); | |
380 | ||
381 | /* Remove in 4.3 */ | |
2ac8ae89 | 382 | Lua.writeFunction("addDS", [&lci](const std::string& who, const std::string& what) { |
e48c6b8a | 383 | warnIfDNSSECDisabled("Warning: adding Trust Anchor for DNSSEC (addDS), but dnssec is set to 'off'!"); |
190e0d9a | 384 | g_log<<Logger::Warning<<"addDS is deprecated and will be removed in the future, switch to addTA"<<endl; |
52ad9eea | 385 | DNSName zone(who); |
32122aab | 386 | auto ds = std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(what)); |
64a4a928 | 387 | lci.dsAnchors[zone].insert(*ds); |
52ad9eea | 388 | }); |
2ac8ae89 | 389 | |
190e0d9a | 390 | /* Remove in 4.3 */ |
2ac8ae89 | 391 | Lua.writeFunction("clearDS", [&lci](boost::optional<string> who) { |
190e0d9a | 392 | g_log<<Logger::Warning<<"clearDS is deprecated and will be removed in the future, switch to clearTA"<<endl; |
e48c6b8a | 393 | warnIfDNSSECDisabled("Warning: removing Trust Anchor for DNSSEC (clearDS), but dnssec is set to 'off'!"); |
2ac8ae89 | 394 | if(who) |
395 | lci.dsAnchors.erase(DNSName(*who)); | |
396 | else | |
397 | lci.dsAnchors.clear(); | |
398 | }); | |
399 | ||
1bd49828 | 400 | Lua.writeFunction("addNTA", [&lci](const std::string& who, const boost::optional<std::string> why) { |
e48c6b8a | 401 | warnIfDNSSECDisabled("Warning: adding Negative Trust Anchor for DNSSEC (addNTA), but dnssec is set to 'off'!"); |
1bd49828 PL |
402 | if(why) |
403 | lci.negAnchors[DNSName(who)] = static_cast<string>(*why); | |
404 | else | |
405 | lci.negAnchors[DNSName(who)] = ""; | |
406 | }); | |
407 | ||
408 | Lua.writeFunction("clearNTA", [&lci](boost::optional<string> who) { | |
e48c6b8a | 409 | warnIfDNSSECDisabled("Warning: removing Negative Trust Anchor for DNSSEC (clearNTA), but dnssec is set to 'off'!"); |
1bd49828 PL |
410 | if(who) |
411 | lci.negAnchors.erase(DNSName(*who)); | |
412 | else | |
413 | lci.negAnchors.clear(); | |
414 | }); | |
415 | ||
e4ae55e5 PL |
416 | Lua.writeFunction("readTrustAnchorsFromFile", [&lci](const std::string& fname, const boost::optional<uint32_t> interval) { |
417 | uint32_t realInterval = 24; | |
418 | if (interval) { | |
419 | realInterval = static_cast<uint32_t>(*interval); | |
8f29eeaa | 420 | } |
e4ae55e5 PL |
421 | warnIfDNSSECDisabled("Warning: reading Trust Anchors from file (readTrustAnchorsFromFile), but dnssec is set to 'off'!"); |
422 | lci.trustAnchorFileInfo.fname = fname; | |
423 | lci.trustAnchorFileInfo.interval = realInterval; | |
424 | updateTrustAnchorsFromFile(fname, lci.dsAnchors); | |
8f29eeaa PL |
425 | }); |
426 | ||
aa7929a3 | 427 | #if HAVE_PROTOBUF |
f1c7929a RG |
428 | Lua.writeFunction("setProtobufMasks", [&lci](const uint8_t maskV4, uint8_t maskV6) { |
429 | lci.protobufMaskV4 = maskV4; | |
430 | lci.protobufMaskV6 = maskV6; | |
431 | }); | |
432 | ||
b773359c | 433 | Lua.writeFunction("protobufServer", [&lci](boost::variant<const std::string, const std::unordered_map<int, std::string>> servers, boost::optional<protobufOptions_t> vars) { |
63341e8d | 434 | if (!lci.protobufExportConfig.enabled) { |
b773359c | 435 | |
63341e8d | 436 | lci.protobufExportConfig.enabled = true; |
b773359c RG |
437 | |
438 | try { | |
439 | if (servers.type() == typeid(std::string)) { | |
440 | auto server = boost::get<const std::string>(servers); | |
441 | ||
442 | lci.protobufExportConfig.servers.emplace_back(server); | |
443 | } | |
444 | else { | |
445 | auto serversMap = boost::get<const std::unordered_map<int,std::string>>(servers); | |
446 | for (const auto& serverPair : serversMap) { | |
447 | lci.protobufExportConfig.servers.emplace_back(serverPair.second); | |
448 | } | |
449 | } | |
450 | ||
451 | parseProtobufOptions(vars, lci.protobufExportConfig); | |
452 | } | |
453 | catch(std::exception& e) { | |
454 | g_log<<Logger::Error<<"Error while adding protobuf logger: "<<e.what()<<endl; | |
455 | } | |
456 | catch(PDNSException& e) { | |
457 | g_log<<Logger::Error<<"Error while adding protobuf logger: "<<e.reason<<endl; | |
458 | } | |
aa7929a3 RG |
459 | } |
460 | else { | |
b773359c | 461 | g_log<<Logger::Error<<"Only one protobufServer() directive can be configured, we already have "<<lci.protobufExportConfig.servers.at(0).toString()<<endl; |
aa7929a3 | 462 | } |
4898a348 RG |
463 | }); |
464 | ||
b773359c RG |
465 | Lua.writeFunction("outgoingProtobufServer", [&lci](boost::variant<const std::string, const std::unordered_map<int, std::string>> servers, boost::optional<protobufOptions_t> vars) { |
466 | if (!lci.outgoingProtobufExportConfig.enabled) { | |
467 | ||
468 | lci.outgoingProtobufExportConfig.enabled = true; | |
469 | ||
470 | try { | |
471 | if (servers.type() == typeid(std::string)) { | |
472 | auto server = boost::get<const std::string>(servers); | |
473 | ||
474 | lci.outgoingProtobufExportConfig.servers.emplace_back(server); | |
475 | } | |
476 | else { | |
477 | auto serversMap = boost::get<const std::unordered_map<int,std::string>>(servers); | |
478 | for (const auto& serverPair : serversMap) { | |
479 | lci.outgoingProtobufExportConfig.servers.emplace_back(serverPair.second); | |
480 | } | |
481 | } | |
482 | ||
483 | parseProtobufOptions(vars, lci.outgoingProtobufExportConfig); | |
484 | } | |
485 | catch(std::exception& e) { | |
486 | g_log<<Logger::Error<<"Error while starting outgoing protobuf logger: "<<e.what()<<endl; | |
487 | } | |
488 | catch(PDNSException& e) { | |
489 | g_log<<Logger::Error<<"Error while starting outgoing protobuf logger: "<<e.reason<<endl; | |
490 | } | |
aa7929a3 | 491 | } |
b773359c RG |
492 | else { |
493 | g_log<<Logger::Error<<"Only one outgoingProtobufServer() directive can be configured, we already have "<<lci.outgoingProtobufExportConfig.servers.at(0).toString()<<endl; | |
aa7929a3 RG |
494 | } |
495 | }); | |
496 | #endif | |
497 | ||
ad42489c | 498 | try { |
499 | Lua.executeCode(ifs); | |
500 | g_luaconfs.setState(lci); | |
501 | } | |
2ac8ae89 | 502 | catch(const LuaContext::ExecutionErrorException& e) { |
e6a9dde5 | 503 | g_log<<Logger::Error<<"Unable to load Lua script from '"+fname+"': "; |
2ac8ae89 | 504 | try { |
505 | std::rethrow_if_nested(e); | |
dd079764 RG |
506 | } catch(const std::exception& exp) { |
507 | // exp is the exception that was thrown from inside the lambda | |
e6a9dde5 | 508 | g_log << exp.what() << std::endl; |
2ac8ae89 | 509 | } |
dd079764 RG |
510 | catch(const PDNSException& exp) { |
511 | // exp is the exception that was thrown from inside the lambda | |
e6a9dde5 | 512 | g_log << exp.reason << std::endl; |
2ac8ae89 | 513 | } |
514 | throw; | |
515 | ||
516 | } | |
ad42489c | 517 | catch(std::exception& err) { |
e6a9dde5 | 518 | g_log<<Logger::Error<<"Unable to load Lua script from '"+fname+"': "<<err.what()<<endl; |
2ac8ae89 | 519 | throw; |
ad42489c | 520 | } |
521 | ||
3e61e7f7 | 522 | } |
6a99b9a4 | 523 | |
e6ec15bf RG |
524 | void startLuaConfigDelayedThreads(const luaConfigDelayedThreads& delayedThreads, uint64_t generation) |
525 | { | |
526 | for (const auto& rpzMaster : delayedThreads.rpzMasterThreads) { | |
527 | try { | |
d122dac0 | 528 | std::thread t(RPZIXFRTracker, std::get<0>(rpzMaster), std::get<1>(rpzMaster), std::get<2>(rpzMaster), std::get<3>(rpzMaster), std::get<4>(rpzMaster), std::get<5>(rpzMaster), std::get<6>(rpzMaster) * 1024 * 1024, std::get<7>(rpzMaster), std::get<8>(rpzMaster), std::get<9>(rpzMaster), std::get<10>(rpzMaster), generation); |
e6ec15bf RG |
529 | t.detach(); |
530 | } | |
531 | catch(const std::exception& e) { | |
532 | g_log<<Logger::Error<<"Problem starting RPZIXFRTracker thread: "<<e.what()<<endl; | |
533 | exit(1); // FIXME proper exit code? | |
534 | } | |
535 | catch(const PDNSException& e) { | |
536 | g_log<<Logger::Error<<"Problem starting RPZIXFRTracker thread: "<<e.reason<<endl; | |
537 | exit(1); // FIXME proper exit code? | |
538 | } | |
539 | } | |
540 | } |