2 #include "ext/luawrapper/include/LuaContext.hpp"
6 #include "namespaces.hh"
8 #include "rec-lua-conf.hh"
10 #include "filterpo.hh"
12 #include "rpzloader.hh"
14 #include "remote_logger.hh"
15 #include "validate.hh"
16 #include "validate-recursor.hh"
17 #include "root-dnssec.hh"
19 GlobalStateHolder
<LuaConfigItems
> g_luaconfs
;
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.
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.
28 If someone loads an empty Lua file, the default LuaConfigItems struct MUST MAKE SENSE.
30 To make this easy on you, here is a LuaConfigItems constructor where you
31 can set sane defaults:
34 LuaConfigItems::LuaConfigItems()
36 DNSName
root("."); // don't use g_rootdnsname here, it might not exist yet
37 for (const auto &dsRecord
: rootDSs
) {
38 auto ds
=std::dynamic_pointer_cast
<DSRecordContent
>(DSRecordContent::make(dsRecord
));
39 dsAnchors
[root
].insert(*ds
);
43 /* DID YOU READ THE STORY ABOVE? */
46 typename
C::value_type::second_type
constGet(const C
& c
, const std::string
& name
)
48 auto iter
= c
.find(name
);
54 typedef std::unordered_map
<std::string
, boost::variant
<bool, uint32_t, std::string
> > rpzOptions_t
;
56 static void parseRPZParameters(rpzOptions_t
& have
, std::string
& polName
, boost::optional
<DNSFilterEngine::Policy
>& defpol
, bool& defpolOverrideLocal
, uint32_t& maxTTL
, size_t& zoneSizeHint
)
58 if(have
.count("policyName")) {
59 polName
= boost::get
<std::string
>(have
["policyName"]);
61 if(have
.count("defpol")) {
62 defpol
=DNSFilterEngine::Policy();
63 defpol
->d_kind
= (DNSFilterEngine::PolicyKind
)boost::get
<uint32_t>(have
["defpol"]);
64 defpol
->d_name
= std::make_shared
<std::string
>(polName
);
65 if(defpol
->d_kind
== DNSFilterEngine::PolicyKind::Custom
) {
66 defpol
->d_custom
.push_back(DNSRecordContent::mastermake(QType::CNAME
, QClass::IN
,
67 boost::get
<string
>(have
["defcontent"])));
69 if(have
.count("defttl"))
70 defpol
->d_ttl
= static_cast<int32_t>(boost::get
<uint32_t>(have
["defttl"]));
72 defpol
->d_ttl
= -1; // get it from the zone
75 if (have
.count("defpolOverrideLocalData")) {
76 defpolOverrideLocal
= boost::get
<bool>(have
["defpolOverrideLocalData"]);
79 if(have
.count("maxTTL")) {
80 maxTTL
= boost::get
<uint32_t>(have
["maxTTL"]);
82 if(have
.count("zoneSizeHint")) {
83 zoneSizeHint
= static_cast<size_t>(boost::get
<uint32_t>(have
["zoneSizeHint"]));
88 typedef std::unordered_map
<std::string
, boost::variant
<bool, uint64_t, std::string
, std::vector
<std::pair
<int,std::string
> > > > protobufOptions_t
;
90 static void parseProtobufOptions(boost::optional
<protobufOptions_t
> vars
, ProtobufExportConfig
& config
)
96 if (vars
->count("timeout")) {
97 config
.timeout
= boost::get
<uint64_t>((*vars
)["timeout"]);
100 if (vars
->count("maxQueuedEntries")) {
101 config
.maxQueuedEntries
= boost::get
<uint64_t>((*vars
)["maxQueuedEntries"]);
104 if (vars
->count("reconnectWaitTime")) {
105 config
.reconnectWaitTime
= boost::get
<uint64_t>((*vars
)["reconnectWaitTime"]);
108 if (vars
->count("asyncConnect")) {
109 config
.asyncConnect
= boost::get
<bool>((*vars
)["asyncConnect"]);
112 if (vars
->count("taggedOnly")) {
113 config
.taggedOnly
= boost::get
<bool>((*vars
)["taggedOnly"]);
116 if (vars
->count("logQueries")) {
117 config
.logQueries
= boost::get
<bool>((*vars
)["logQueries"]);
120 if (vars
->count("logResponses")) {
121 config
.logResponses
= boost::get
<bool>((*vars
)["logResponses"]);
124 if (vars
->count("exportTypes")) {
125 config
.exportTypes
.clear();
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
;
132 for (const auto& entry
: QType::names
) {
133 if (entry
.first
== type
) {
135 config
.exportTypes
.insert(entry
.second
);
141 throw std::runtime_error("Unknown QType '" + type
+ "' in protobuf's export types");
146 #endif /* HAVE_PROTOBUF */
149 typedef std::unordered_map
<std::string
, boost::variant
<bool, uint64_t, std::string
, std::vector
<std::pair
<int,std::string
> > > > frameStreamOptions_t
;
151 static void parseFrameStreamOptions(boost::optional
<frameStreamOptions_t
> vars
, FrameStreamExportConfig
& config
)
157 if (vars
->count("logQueries")) {
158 config
.logQueries
= boost::get
<bool>((*vars
)["logQueries"]);
160 if (vars
->count("logResponses")) {
161 config
.logResponses
= boost::get
<bool>((*vars
)["logResponses"]);
164 if (vars
->count("bufferHint")) {
165 config
.bufferHint
= boost::get
<uint64_t>((*vars
)["bufferHint"]);
167 if (vars
->count("flushTimeout")) {
168 config
.flushTimeout
= boost::get
<uint64_t>((*vars
)["flushTimeout"]);
170 if (vars
->count("inputQueueSize")) {
171 config
.inputQueueSize
= boost::get
<uint64_t>((*vars
)["inputQueueSize"]);
173 if (vars
->count("outputQueueSize")) {
174 config
.outputQueueSize
= boost::get
<uint64_t>((*vars
)["outputQueueSize"]);
176 if (vars
->count("queueNotifyThreshold")) {
177 config
.queueNotifyThreshold
= boost::get
<uint64_t>((*vars
)["queueNotifyThreshold"]);
179 if (vars
->count("reopenInterval")) {
180 config
.reopenInterval
= boost::get
<uint64_t>((*vars
)["reopenInterval"]);
183 #endif /* HAVE_FSTRM */
185 void loadRecursorLuaConfig(const std::string
& fname
, luaConfigDelayedThreads
& delayedThreads
)
194 throw PDNSException("Cannot open file '"+fname
+"': "+stringerror());
196 auto luaconfsLocal
= g_luaconfs
.getLocal();
197 lci
.generation
= luaconfsLocal
->generation
+ 1;
199 // pdnslog here is compatible with pdnslog in lua-base4.cc.
200 Lua
.writeFunction("pdnslog", [](const std::string
& msg
, boost::optional
<int> loglevel
) { g_log
<< (Logger::Urgency
)loglevel
.get_value_or(Logger::Warning
) << msg
<<endl
; });
201 std::unordered_map
<string
, std::unordered_map
<string
, int>> pdns_table
;
202 pdns_table
["loglevels"] = std::unordered_map
<string
, int>{
203 {"Alert", LOG_ALERT
},
204 {"Critical", LOG_CRIT
},
205 {"Debug", LOG_DEBUG
},
206 {"Emergency", LOG_EMERG
},
208 {"Notice", LOG_NOTICE
},
209 {"Warning", LOG_WARNING
},
212 Lua
.writeVariable("pdns", pdns_table
);
214 Lua
.writeFunction("clearSortlist", [&lci
]() { lci
.sortlist
.clear(); });
216 /* we can get: "1.2.3.4"
217 {"1.2.3.4", "4.5.6.7"}
218 {"1.2.3.4", {"4.5.6.7", "8.9.10.11"}}
221 map
<string
,DNSFilterEngine::PolicyKind
> pmap
{
222 {"NoAction", DNSFilterEngine::PolicyKind::NoAction
},
223 {"Drop", DNSFilterEngine::PolicyKind::Drop
},
224 {"NXDOMAIN", DNSFilterEngine::PolicyKind::NXDOMAIN
},
225 {"NODATA", DNSFilterEngine::PolicyKind::NODATA
},
226 {"Truncate", DNSFilterEngine::PolicyKind::Truncate
},
227 {"Custom", DNSFilterEngine::PolicyKind::Custom
}
229 Lua
.writeVariable("Policy", pmap
);
231 Lua
.writeFunction("rpzFile", [&lci
](const string
& filename
, boost::optional
<rpzOptions_t
> options
) {
233 boost::optional
<DNSFilterEngine::Policy
> defpol
;
234 bool defpolOverrideLocal
= true;
235 std::string
polName("rpzFile");
236 std::shared_ptr
<DNSFilterEngine::Zone
> zone
= std::make_shared
<DNSFilterEngine::Zone
>();
237 uint32_t maxTTL
= std::numeric_limits
<uint32_t>::max();
239 auto& have
= *options
;
240 size_t zoneSizeHint
= 0;
241 parseRPZParameters(have
, polName
, defpol
, defpolOverrideLocal
, maxTTL
, zoneSizeHint
);
242 if (zoneSizeHint
> 0) {
243 zone
->reserve(zoneSizeHint
);
246 g_log
<<Logger::Warning
<<"Loading RPZ from file '"<<filename
<<"'"<<endl
;
247 zone
->setName(polName
);
248 loadRPZFromFile(filename
, zone
, defpol
, defpolOverrideLocal
, maxTTL
);
249 lci
.dfe
.addZone(zone
);
250 g_log
<<Logger::Warning
<<"Done loading RPZ from file '"<<filename
<<"'"<<endl
;
252 catch(const std::exception
& e
) {
253 g_log
<<Logger::Error
<<"Unable to load RPZ zone from '"<<filename
<<"': "<<e
.what()<<endl
;
257 Lua
.writeFunction("rpzMaster", [&lci
, &delayedThreads
](const boost::variant
<string
, std::vector
<std::pair
<int, string
> > >& masters_
, const string
& zoneName
, boost::optional
<rpzOptions_t
> options
) {
259 boost::optional
<DNSFilterEngine::Policy
> defpol
;
260 bool defpolOverrideLocal
= true;
261 std::shared_ptr
<DNSFilterEngine::Zone
> zone
= std::make_shared
<DNSFilterEngine::Zone
>();
264 size_t maxReceivedXFRMBytes
= 0;
265 uint16_t axfrTimeout
= 20;
266 uint32_t maxTTL
= std::numeric_limits
<uint32_t>::max();
267 ComboAddress localAddress
;
268 std::vector
<ComboAddress
> masters
;
269 if (masters_
.type() == typeid(string
)) {
270 masters
.push_back(ComboAddress(boost::get
<std::string
>(masters_
), 53));
273 for (const auto& master
: boost::get
<std::vector
<std::pair
<int, std::string
>>>(masters_
)) {
274 masters
.push_back(ComboAddress(master
.second
, 53));
279 std::string dumpFile
;
280 std::shared_ptr
<SOARecordContent
> sr
= nullptr;
283 std::string seedFile
;
284 std::string
polName(zoneName
);
287 auto& have
= *options
;
288 size_t zoneSizeHint
= 0;
289 parseRPZParameters(have
, polName
, defpol
, defpolOverrideLocal
, maxTTL
, zoneSizeHint
);
290 if (zoneSizeHint
> 0) {
291 zone
->reserve(zoneSizeHint
);
294 if(have
.count("tsigname")) {
295 tt
.name
=DNSName(toLower(boost::get
<string
>(have
["tsigname"])));
296 tt
.algo
=DNSName(toLower(boost::get
<string
>(have
[ "tsigalgo"])));
297 if(B64Decode(boost::get
<string
>(have
[ "tsigsecret"]), tt
.secret
))
298 throw std::runtime_error("TSIG secret is not valid Base-64 encoded");
301 if(have
.count("refresh")) {
302 refresh
= boost::get
<uint32_t>(have
["refresh"]);
304 g_log
<<Logger::Warning
<<"rpzMaster refresh value of 0 ignored"<<endl
;
308 if(have
.count("maxReceivedMBytes")) {
309 maxReceivedXFRMBytes
= static_cast<size_t>(boost::get
<uint32_t>(have
["maxReceivedMBytes"]));
312 if(have
.count("localAddress")) {
313 localAddress
= ComboAddress(boost::get
<string
>(have
["localAddress"]));
316 if(have
.count("axfrTimeout")) {
317 axfrTimeout
= static_cast<uint16_t>(boost::get
<uint32_t>(have
["axfrTimeout"]));
320 if(have
.count("seedFile")) {
321 seedFile
= boost::get
<std::string
>(have
["seedFile"]);
324 if(have
.count("dumpFile")) {
325 dumpFile
= boost::get
<std::string
>(have
["dumpFile"]);
329 if (localAddress
!= ComboAddress()) {
330 // We were passed a localAddress, check if its AF matches the masters'
331 for (const auto& master
: masters
) {
332 if (localAddress
.sin4
.sin_family
!= master
.sin4
.sin_family
) {
333 throw PDNSException("Master address("+master
.toString()+") is not of the same Address Family as the local address ("+localAddress
.toString()+").");
338 DNSName
domain(zoneName
);
339 zone
->setDomain(domain
);
340 zone
->setName(polName
);
341 zoneIdx
= lci
.dfe
.addZone(zone
);
343 if (!seedFile
.empty()) {
344 g_log
<<Logger::Info
<<"Pre-loading RPZ zone "<<zoneName
<<" from seed file '"<<seedFile
<<"'"<<endl
;
346 sr
= loadRPZFromFile(seedFile
, zone
, defpol
, defpolOverrideLocal
, maxTTL
);
348 if (zone
->getDomain() != domain
) {
349 throw PDNSException("The RPZ zone " + zoneName
+ " loaded from the seed file (" + zone
->getDomain().toString() + ") does not match the one passed in parameter (" + domain
.toString() + ")");
353 throw PDNSException("The RPZ zone " + zoneName
+ " loaded from the seed file (" + zone
->getDomain().toString() + ") has no SOA record");
356 catch(const std::exception
& e
) {
357 g_log
<<Logger::Warning
<<"Unable to pre-load RPZ zone "<<zoneName
<<" from seed file '"<<seedFile
<<"': "<<e
.what()<<endl
;
361 catch(const std::exception
& e
) {
362 g_log
<<Logger::Error
<<"Problem configuring 'rpzMaster': "<<e
.what()<<endl
;
363 exit(1); // FIXME proper exit code?
365 catch(const PDNSException
& e
) {
366 g_log
<<Logger::Error
<<"Problem configuring 'rpzMaster': "<<e
.reason
<<endl
;
367 exit(1); // FIXME proper exit code?
370 delayedThreads
.rpzMasterThreads
.push_back(std::make_tuple(masters
, defpol
, defpolOverrideLocal
, maxTTL
, zoneIdx
, tt
, maxReceivedXFRMBytes
, localAddress
, axfrTimeout
, refresh
, sr
, dumpFile
));
373 typedef vector
<pair
<int,boost::variant
<string
, vector
<pair
<int, string
> > > > > argvec_t
;
374 Lua
.writeFunction("addSortList",
375 [&lci
](const std::string
& formask_
,
376 const boost::variant
<string
, argvec_t
>& masks
,
377 boost::optional
<int> order_
)
380 Netmask
formask(formask_
);
381 int order
= order_
? (*order_
) : lci
.sortlist
.getMaxOrder(formask
)+1;
382 if(auto str
= boost::get
<string
>(&masks
))
383 lci
.sortlist
.addEntry(formask
, Netmask(*str
), order
);
386 auto vec
= boost::get
<argvec_t
>(&masks
);
387 for(const auto& e
: *vec
) {
388 if(auto s
= boost::get
<string
>(&e
.second
)) {
389 lci
.sortlist
.addEntry(formask
, Netmask(*s
), order
);
392 const auto& v
=boost::get
<vector
<pair
<int, string
> > >(e
.second
);
393 for(const auto& entry
: v
)
394 lci
.sortlist
.addEntry(formask
, Netmask(entry
.second
), order
);
400 catch(std::exception
& e
) {
401 g_log
<<Logger::Error
<<"Error in addSortList: "<<e
.what()<<endl
;
405 Lua
.writeFunction("addTA", [&lci
](const std::string
& who
, const std::string
& what
) {
406 warnIfDNSSECDisabled("Warning: adding Trust Anchor for DNSSEC (addTA), but dnssec is set to 'off'!");
408 auto ds
= std::dynamic_pointer_cast
<DSRecordContent
>(DSRecordContent::make(what
));
409 lci
.dsAnchors
[zone
].insert(*ds
);
412 Lua
.writeFunction("clearTA", [&lci
](boost::optional
<string
> who
) {
413 warnIfDNSSECDisabled("Warning: removing Trust Anchor for DNSSEC (clearTA), but dnssec is set to 'off'!");
415 lci
.dsAnchors
.erase(DNSName(*who
));
417 lci
.dsAnchors
.clear();
421 Lua
.writeFunction("addDS", [&lci
](const std::string
& who
, const std::string
& what
) {
422 warnIfDNSSECDisabled("Warning: adding Trust Anchor for DNSSEC (addDS), but dnssec is set to 'off'!");
423 g_log
<<Logger::Warning
<<"addDS is deprecated and will be removed in the future, switch to addTA"<<endl
;
425 auto ds
= std::dynamic_pointer_cast
<DSRecordContent
>(DSRecordContent::make(what
));
426 lci
.dsAnchors
[zone
].insert(*ds
);
430 Lua
.writeFunction("clearDS", [&lci
](boost::optional
<string
> who
) {
431 g_log
<<Logger::Warning
<<"clearDS is deprecated and will be removed in the future, switch to clearTA"<<endl
;
432 warnIfDNSSECDisabled("Warning: removing Trust Anchor for DNSSEC (clearDS), but dnssec is set to 'off'!");
434 lci
.dsAnchors
.erase(DNSName(*who
));
436 lci
.dsAnchors
.clear();
439 Lua
.writeFunction("addNTA", [&lci
](const std::string
& who
, const boost::optional
<std::string
> why
) {
440 warnIfDNSSECDisabled("Warning: adding Negative Trust Anchor for DNSSEC (addNTA), but dnssec is set to 'off'!");
442 lci
.negAnchors
[DNSName(who
)] = static_cast<string
>(*why
);
444 lci
.negAnchors
[DNSName(who
)] = "";
447 Lua
.writeFunction("clearNTA", [&lci
](boost::optional
<string
> who
) {
448 warnIfDNSSECDisabled("Warning: removing Negative Trust Anchor for DNSSEC (clearNTA), but dnssec is set to 'off'!");
450 lci
.negAnchors
.erase(DNSName(*who
));
452 lci
.negAnchors
.clear();
455 Lua
.writeFunction("readTrustAnchorsFromFile", [&lci
](const std::string
& fnamearg
, const boost::optional
<uint32_t> interval
) {
456 uint32_t realInterval
= 24;
458 realInterval
= static_cast<uint32_t>(*interval
);
460 warnIfDNSSECDisabled("Warning: reading Trust Anchors from file (readTrustAnchorsFromFile), but dnssec is set to 'off'!");
461 lci
.trustAnchorFileInfo
.fname
= fnamearg
;
462 lci
.trustAnchorFileInfo
.interval
= realInterval
;
463 updateTrustAnchorsFromFile(fnamearg
, lci
.dsAnchors
);
467 Lua
.writeFunction("setProtobufMasks", [&lci
](const uint8_t maskV4
, uint8_t maskV6
) {
468 lci
.protobufMaskV4
= maskV4
;
469 lci
.protobufMaskV6
= maskV6
;
472 Lua
.writeFunction("protobufServer", [&lci
](boost::variant
<const std::string
, const std::unordered_map
<int, std::string
>> servers
, boost::optional
<protobufOptions_t
> vars
) {
473 if (!lci
.protobufExportConfig
.enabled
) {
475 lci
.protobufExportConfig
.enabled
= true;
478 if (servers
.type() == typeid(std::string
)) {
479 auto server
= boost::get
<const std::string
>(servers
);
481 lci
.protobufExportConfig
.servers
.emplace_back(server
);
484 auto serversMap
= boost::get
<const std::unordered_map
<int,std::string
>>(servers
);
485 for (const auto& serverPair
: serversMap
) {
486 lci
.protobufExportConfig
.servers
.emplace_back(serverPair
.second
);
490 parseProtobufOptions(vars
, lci
.protobufExportConfig
);
492 catch(std::exception
& e
) {
493 g_log
<<Logger::Error
<<"Error while adding protobuf logger: "<<e
.what()<<endl
;
495 catch(PDNSException
& e
) {
496 g_log
<<Logger::Error
<<"Error while adding protobuf logger: "<<e
.reason
<<endl
;
500 g_log
<<Logger::Error
<<"Only one protobufServer() directive can be configured, we already have "<<lci
.protobufExportConfig
.servers
.at(0).toString()<<endl
;
504 Lua
.writeFunction("outgoingProtobufServer", [&lci
](boost::variant
<const std::string
, const std::unordered_map
<int, std::string
>> servers
, boost::optional
<protobufOptions_t
> vars
) {
505 if (!lci
.outgoingProtobufExportConfig
.enabled
) {
507 lci
.outgoingProtobufExportConfig
.enabled
= true;
510 if (servers
.type() == typeid(std::string
)) {
511 auto server
= boost::get
<const std::string
>(servers
);
513 lci
.outgoingProtobufExportConfig
.servers
.emplace_back(server
);
516 auto serversMap
= boost::get
<const std::unordered_map
<int,std::string
>>(servers
);
517 for (const auto& serverPair
: serversMap
) {
518 lci
.outgoingProtobufExportConfig
.servers
.emplace_back(serverPair
.second
);
522 parseProtobufOptions(vars
, lci
.outgoingProtobufExportConfig
);
524 catch(std::exception
& e
) {
525 g_log
<<Logger::Error
<<"Error while starting outgoing protobuf logger: "<<e
.what()<<endl
;
527 catch(PDNSException
& e
) {
528 g_log
<<Logger::Error
<<"Error while starting outgoing protobuf logger: "<<e
.reason
<<endl
;
532 g_log
<<Logger::Error
<<"Only one outgoingProtobufServer() directive can be configured, we already have "<<lci
.outgoingProtobufExportConfig
.servers
.at(0).toString()<<endl
;
538 Lua
.writeFunction("dnstapFrameStreamServer", [&lci
](boost::variant
<const std::string
, const std::unordered_map
<int, std::string
>> servers
, boost::optional
<frameStreamOptions_t
> vars
) {
539 if (!lci
.frameStreamExportConfig
.enabled
) {
541 lci
.frameStreamExportConfig
.enabled
= true;
544 if (servers
.type() == typeid(std::string
)) {
545 auto server
= boost::get
<const std::string
>(servers
);
546 if (!boost::starts_with(server
, "/")) {
547 ComboAddress
parsecheck(server
);
549 lci
.frameStreamExportConfig
.servers
.emplace_back(server
);
552 auto serversMap
= boost::get
<const std::unordered_map
<int,std::string
>>(servers
);
553 for (const auto& serverPair
: serversMap
) {
554 lci
.frameStreamExportConfig
.servers
.emplace_back(serverPair
.second
);
558 parseFrameStreamOptions(vars
, lci
.frameStreamExportConfig
);
560 catch(std::exception
& e
) {
561 g_log
<<Logger::Error
<<"Error reading config for dnstap framestream logger: "<<e
.what()<<endl
;
563 catch(PDNSException
& e
) {
564 g_log
<<Logger::Error
<<"Error reading config for dnstap framestream logger: "<<e
.reason
<<endl
;
568 g_log
<<Logger::Error
<<"Only one dnstapFrameStreamServer() directive can be configured, we already have "<<lci
.frameStreamExportConfig
.servers
.at(0)<<endl
;
571 #endif /* HAVE_FSTRM */
574 Lua
.executeCode(ifs
);
575 g_luaconfs
.setState(std::move(lci
));
577 catch(const LuaContext::ExecutionErrorException
& e
) {
578 g_log
<<Logger::Error
<<"Unable to load Lua script from '"+fname
+"': ";
580 std::rethrow_if_nested(e
);
581 } catch(const std::exception
& exp
) {
582 // exp is the exception that was thrown from inside the lambda
583 g_log
<< exp
.what() << std::endl
;
585 catch(const PDNSException
& exp
) {
586 // exp is the exception that was thrown from inside the lambda
587 g_log
<< exp
.reason
<< std::endl
;
592 catch(std::exception
& err
) {
593 g_log
<<Logger::Error
<<"Unable to load Lua script from '"+fname
+"': "<<err
.what()<<endl
;
599 void startLuaConfigDelayedThreads(const luaConfigDelayedThreads
& delayedThreads
, uint64_t generation
)
601 for (const auto& rpzMaster
: delayedThreads
.rpzMasterThreads
) {
603 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
), std::get
<11>(rpzMaster
), generation
);
606 catch(const std::exception
& e
) {
607 g_log
<<Logger::Error
<<"Problem starting RPZIXFRTracker thread: "<<e
.what()<<endl
;
608 exit(1); // FIXME proper exit code?
610 catch(const PDNSException
& e
) {
611 g_log
<<Logger::Error
<<"Problem starting RPZIXFRTracker thread: "<<e
.reason
<<endl
;
612 exit(1); // FIXME proper exit code?