5 #include "rec_channel.hh"
6 #include <boost/bind.hpp>
9 #include "malloctrace.hh"
12 #include "recursor_cache.hh"
14 #include "negcache.hh"
15 #include <boost/function.hpp>
16 #include <boost/optional.hpp>
17 #include <boost/tuple/tuple.hpp>
18 #include <boost/format.hpp>
19 #include <boost/algorithm/string.hpp>
22 #include <sys/types.h>
26 #include "dnsparser.hh"
27 #include "arguments.hh"
28 #include <sys/resource.h>
31 #include "responsestats.hh"
32 #include "rec-lua-conf.hh"
34 #include "validate-recursor.hh"
35 #include "filterpo.hh"
37 #include "secpoll-recursor.hh"
38 #include "pubsuffix.hh"
39 #include "namespaces.hh"
40 pthread_mutex_t g_carbon_config_lock
=PTHREAD_MUTEX_INITIALIZER
;
42 static map
<string
, const uint32_t*> d_get32bitpointers
;
43 static map
<string
, const std::atomic
<uint64_t>*> d_getatomics
;
44 static map
<string
, function
< uint64_t() > > d_get64bitmembers
;
45 static pthread_mutex_t d_dynmetricslock
= PTHREAD_MUTEX_INITIALIZER
;
46 static map
<string
, std::atomic
<unsigned long>* > d_dynmetrics
;
48 static std::map
<StatComponent
, std::set
<std::string
>> s_blacklistedStats
;
50 bool isStatBlacklisted(StatComponent component
, const string
& name
)
52 return s_blacklistedStats
[component
].count(name
) != 0;
55 void blacklistStat(StatComponent component
, const string
& name
)
57 s_blacklistedStats
[component
].insert(name
);
60 void blacklistStats(StatComponent component
, const string
& stats
)
62 std::vector
<std::string
> blacklistedStats
;
63 stringtok(blacklistedStats
, stats
, ", ");
64 auto& map
= s_blacklistedStats
[component
];
65 for (const auto &st
: blacklistedStats
) {
70 static void addGetStat(const string
& name
, const uint32_t* place
)
72 d_get32bitpointers
[name
]=place
;
75 static void addGetStat(const string
& name
, const std::atomic
<uint64_t>* place
)
77 d_getatomics
[name
]=place
;
80 static void addGetStat(const string
& name
, function
<uint64_t ()> f
)
82 d_get64bitmembers
[name
]=f
;
85 std::atomic
<unsigned long>* getDynMetric(const std::string
& str
)
87 Lock
l(&d_dynmetricslock
);
88 auto f
= d_dynmetrics
.find(str
);
89 if(f
!= d_dynmetrics
.end())
92 auto ret
= new std::atomic
<unsigned long>();
93 d_dynmetrics
[str
]= ret
;
97 static optional
<uint64_t> get(const string
& name
)
99 optional
<uint64_t> ret
;
101 if(d_get32bitpointers
.count(name
))
102 return *d_get32bitpointers
.find(name
)->second
;
103 if(d_getatomics
.count(name
))
104 return d_getatomics
.find(name
)->second
->load();
105 if(d_get64bitmembers
.count(name
))
106 return d_get64bitmembers
.find(name
)->second();
108 Lock
l(&d_dynmetricslock
);
109 auto f
=rplookup(d_dynmetrics
, name
);
116 optional
<uint64_t> getStatByName(const std::string
& name
)
121 map
<string
,string
> getAllStatsMap(StatComponent component
)
123 map
<string
,string
> ret
;
124 const auto& blacklistMap
= s_blacklistedStats
.at(component
);
126 for(const auto& the32bits
: d_get32bitpointers
) {
127 if (blacklistMap
.count(the32bits
.first
) == 0) {
128 ret
.insert(make_pair(the32bits
.first
, std::to_string(*the32bits
.second
)));
131 for(const auto& atomic
: d_getatomics
) {
132 if (blacklistMap
.count(atomic
.first
) == 0) {
133 ret
.insert(make_pair(atomic
.first
, std::to_string(atomic
.second
->load())));
137 for(const auto& the64bitmembers
: d_get64bitmembers
) {
138 if (blacklistMap
.count(the64bitmembers
.first
) == 0) {
139 ret
.insert(make_pair(the64bitmembers
.first
, std::to_string(the64bitmembers
.second())));
144 Lock
l(&d_dynmetricslock
);
145 for(const auto& a
: d_dynmetrics
) {
146 if (blacklistMap
.count(a
.first
) == 0) {
147 ret
.insert({a
.first
, std::to_string(*a
.second
)});
155 static string
getAllStats()
157 typedef map
<string
, string
> varmap_t
;
158 varmap_t varmap
= getAllStatsMap(StatComponent::RecControl
);
160 for(varmap_t::value_type
& tup
: varmap
) {
161 ret
+= tup
.first
+ "\t" + tup
.second
+"\n";
167 static string
doGet(T begin
, T end
)
171 for(T i
=begin
; i
!= end
; ++i
) {
172 optional
<uint64_t> num
=get(*i
);
174 ret
+=std::to_string(*num
)+"\n";
182 string
static doGetParameter(T begin
, T end
)
186 using boost::replace_all
;
187 for(T i
=begin
; i
!= end
; ++i
) {
188 if(::arg().parmIsset(*i
)) {
190 replace_all(parm
, "\\", "\\\\");
191 replace_all(parm
, "\"", "\\\"");
192 replace_all(parm
, "\n", "\\n");
193 ret
+= *i
+"=\""+ parm
+"\"\n";
196 ret
+= *i
+" not known\n";
202 static uint64_t dumpNegCache(NegCache
& negcache
, int fd
)
204 auto fp
= std::unique_ptr
<FILE, int(*)(FILE*)>(fdopen(dup(fd
), "w"), fclose
);
205 if(!fp
) { // dup probably failed
209 fprintf(fp
.get(), "; negcache dump from thread follows\n;\n");
210 ret
= negcache
.dumpToFile(fp
.get());
214 static uint64_t* pleaseDump(int fd
)
216 return new uint64_t(t_RC
->doDump(fd
) + dumpNegCache(SyncRes::t_sstorage
.negcache
, fd
) + t_packetCache
->doDump(fd
));
219 static uint64_t* pleaseDumpEDNSMap(int fd
)
221 return new uint64_t(SyncRes::doEDNSDump(fd
));
224 static uint64_t* pleaseDumpNSSpeeds(int fd
)
226 return new uint64_t(SyncRes::doDumpNSSpeeds(fd
));
229 static uint64_t* pleaseDumpThrottleMap(int fd
)
231 return new uint64_t(SyncRes::doDumpThrottleMap(fd
));
235 static string
doDumpNSSpeeds(T begin
, T end
)
243 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
245 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
248 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpNSSpeeds
, fd
));
250 catch(std::exception
& e
)
253 return "error dumping NS speeds: "+string(e
.what())+"\n";
255 catch(PDNSException
& e
)
258 return "error dumping NS speeds: "+e
.reason
+"\n";
262 return "dumped "+std::to_string(total
)+" records\n";
266 static string
doDumpCache(T begin
, T end
)
274 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
276 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
279 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDump
, fd
));
284 return "dumped "+std::to_string(total
)+" records\n";
288 static string
doDumpEDNSStatus(T begin
, T end
)
296 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
298 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
301 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpEDNSMap
, fd
));
306 return "dumped "+std::to_string(total
)+" records\n";
310 static string
doDumpRPZ(T begin
, T end
)
315 return "No zone name specified\n";
317 string zoneName
= *i
;
321 return "No file name specified\n";
325 auto luaconf
= g_luaconfs
.getLocal();
326 const auto zone
= luaconf
->dfe
.getZone(zoneName
);
328 return "No RPZ zone named "+zoneName
+"\n";
331 int fd
= open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
334 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
337 auto fp
= std::unique_ptr
<FILE, int(*)(FILE*)>(fdopen(fd
, "w"), fclose
);
340 return "Error converting file descriptor: "+string(strerror(errno
))+"\n";
343 zone
->dump(fp
.get());
349 static string
doDumpThrottleMap(T begin
, T end
)
357 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
359 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
362 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpThrottleMap
, fd
));
367 return "dumped "+std::to_string(total
)+" records\n";
370 uint64_t* pleaseWipeCache(const DNSName
& canon
, bool subtree
)
372 return new uint64_t(t_RC
->doWipeCache(canon
, subtree
));
375 uint64_t* pleaseWipePacketCache(const DNSName
& canon
, bool subtree
)
377 return new uint64_t(t_packetCache
->doWipePacketCache(canon
,0xffff, subtree
));
381 uint64_t* pleaseWipeAndCountNegCache(const DNSName
& canon
, bool subtree
)
383 uint64_t ret
= SyncRes::wipeNegCache(canon
, subtree
);
384 return new uint64_t(ret
);
389 static string
doWipeCache(T begin
, T end
)
391 vector
<pair
<DNSName
, bool> > toWipe
;
392 for(T i
=begin
; i
!= end
; ++i
) {
397 if(boost::ends_with(*i
, "$")) {
398 canon
=DNSName(i
->substr(0, i
->size()-1));
403 } catch (std::exception
&e
) {
404 return "Error: " + std::string(e
.what()) + ", nothing wiped\n";
406 toWipe
.push_back({canon
, subtree
});
409 int count
=0, pcount
=0, countNeg
=0;
410 for (auto wipe
: toWipe
) {
411 count
+= broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, wipe
.first
, wipe
.second
));
412 pcount
+= broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, wipe
.first
, wipe
.second
));
413 countNeg
+=broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, wipe
.first
, wipe
.second
));
416 return "wiped "+std::to_string(count
)+" records, "+std::to_string(countNeg
)+" negative records, "+std::to_string(pcount
)+" packets\n";
420 static string
doSetCarbonServer(T begin
, T end
)
422 Lock
l(&g_carbon_config_lock
);
424 ::arg().set("carbon-server").clear();
425 return "cleared carbon-server setting\n";
428 ::arg().set("carbon-server")=*begin
;
429 ret
="set carbon-server to '"+::arg()["carbon-server"]+"'\n";
432 ::arg().set("carbon-ourname")=*begin
;
433 ret
+="set carbon-ourname to '"+*begin
+"'\n";
439 ::arg().set("carbon-namespace")=*begin
;
440 ret
+="set carbon-namespace to '"+*begin
+"'\n";
446 ::arg().set("carbon-instance")=*begin
;
447 ret
+="set carbon-instance to '"+*begin
+"'\n";
453 static string
doSetDnssecLogBogus(T begin
, T end
)
455 if(checkDNSSECDisabled())
456 return "DNSSEC is disabled in the configuration, not changing the Bogus logging setting\n";
459 return "No DNSSEC Bogus logging setting specified\n";
461 if (pdns_iequals(*begin
, "on") || pdns_iequals(*begin
, "yes")) {
462 if (!g_dnssecLogBogus
) {
463 g_log
<<Logger::Warning
<<"Enabling DNSSEC Bogus logging, requested via control channel"<<endl
;
464 g_dnssecLogBogus
= true;
465 return "DNSSEC Bogus logging enabled\n";
467 return "DNSSEC Bogus logging was already enabled\n";
470 if (pdns_iequals(*begin
, "off") || pdns_iequals(*begin
, "no")) {
471 if (g_dnssecLogBogus
) {
472 g_log
<<Logger::Warning
<<"Disabling DNSSEC Bogus logging, requested via control channel"<<endl
;
473 g_dnssecLogBogus
= false;
474 return "DNSSEC Bogus logging disabled\n";
476 return "DNSSEC Bogus logging was already disabled\n";
479 return "Unknown DNSSEC Bogus setting: '" + *begin
+"'\n";
483 static string
doAddNTA(T begin
, T end
)
485 if(checkDNSSECDisabled())
486 return "DNSSEC is disabled in the configuration, not adding a Negative Trust Anchor\n";
489 return "No NTA specified, doing nothing\n";
493 who
= DNSName(*begin
);
495 catch(std::exception
&e
) {
496 string
ret("Can't add Negative Trust Anchor: ");
504 while (begin
!= end
) {
510 g_log
<<Logger::Warning
<<"Adding Negative Trust Anchor for "<<who
<<" with reason '"<<why
<<"', requested via control channel"<<endl
;
511 g_luaconfs
.modify([who
, why
](LuaConfigItems
& lci
) {
512 lci
.negAnchors
[who
] = why
;
514 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, who
, true));
515 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, who
, true));
516 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, who
, true));
517 return "Added Negative Trust Anchor for " + who
.toLogString() + " with reason '" + why
+ "'\n";
521 static string
doClearNTA(T begin
, T end
)
523 if(checkDNSSECDisabled())
524 return "DNSSEC is disabled in the configuration, not removing a Negative Trust Anchor\n";
527 return "No Negative Trust Anchor specified, doing nothing.\n";
529 if (begin
+ 1 == end
&& *begin
== "*"){
530 g_log
<<Logger::Warning
<<"Clearing all Negative Trust Anchors, requested via control channel"<<endl
;
531 g_luaconfs
.modify([](LuaConfigItems
& lci
) {
532 lci
.negAnchors
.clear();
534 return "Cleared all Negative Trust Anchors.\n";
537 vector
<DNSName
> toRemove
;
539 while (begin
!= end
) {
541 return "Don't mix all Negative Trust Anchor removal with multiple Negative Trust Anchor removal. Nothing removed\n";
543 who
= DNSName(*begin
);
545 catch(std::exception
&e
) {
546 string
ret("Error: ");
548 ret
+= ". No Negative Anchors removed\n";
551 toRemove
.push_back(who
);
557 for (auto const &entry
: toRemove
) {
558 g_log
<<Logger::Warning
<<"Clearing Negative Trust Anchor for "<<entry
<<", requested via control channel"<<endl
;
559 g_luaconfs
.modify([entry
](LuaConfigItems
& lci
) {
560 lci
.negAnchors
.erase(entry
);
562 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, entry
, true));
563 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, entry
, true));
564 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, entry
, true));
569 removed
+= " " + entry
.toStringRootDot();
571 return "Removed Negative Trust Anchors for " + removed
+ "\n";
574 static string
getNTAs()
576 if(checkDNSSECDisabled())
577 return "DNSSEC is disabled in the configuration\n";
579 string
ret("Configured Negative Trust Anchors:\n");
580 auto luaconf
= g_luaconfs
.getLocal();
581 for (auto negAnchor
: luaconf
->negAnchors
)
582 ret
+= negAnchor
.first
.toLogString() + "\t" + negAnchor
.second
+ "\n";
587 static string
doAddTA(T begin
, T end
)
589 if(checkDNSSECDisabled())
590 return "DNSSEC is disabled in the configuration, not adding a Trust Anchor\n";
593 return "No TA specified, doing nothing\n";
597 who
= DNSName(*begin
);
599 catch(std::exception
&e
) {
600 string
ret("Can't add Trust Anchor: ");
608 while (begin
!= end
) {
609 what
+= *begin
+ " ";
614 g_log
<<Logger::Warning
<<"Adding Trust Anchor for "<<who
<<" with data '"<<what
<<"', requested via control channel";
615 g_luaconfs
.modify([who
, what
](LuaConfigItems
& lci
) {
616 auto ds
=std::dynamic_pointer_cast
<DSRecordContent
>(DSRecordContent::make(what
));
617 lci
.dsAnchors
[who
].insert(*ds
);
619 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, who
, true));
620 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, who
, true));
621 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, who
, true));
622 g_log
<<Logger::Warning
<<endl
;
623 return "Added Trust Anchor for " + who
.toStringRootDot() + " with data " + what
+ "\n";
625 catch(std::exception
&e
) {
626 g_log
<<Logger::Warning
<<", failed: "<<e
.what()<<endl
;
627 return "Unable to add Trust Anchor for " + who
.toStringRootDot() + ": " + e
.what() + "\n";
632 static string
doClearTA(T begin
, T end
)
634 if(checkDNSSECDisabled())
635 return "DNSSEC is disabled in the configuration, not removing a Trust Anchor\n";
638 return "No Trust Anchor to clear\n";
640 vector
<DNSName
> toRemove
;
642 while (begin
!= end
) {
644 who
= DNSName(*begin
);
646 catch(std::exception
&e
) {
647 string
ret("Error: ");
649 ret
+= ". No Anchors removed\n";
653 return "Refusing to remove root Trust Anchor, no Anchors removed\n";
654 toRemove
.push_back(who
);
660 for (auto const &entry
: toRemove
) {
661 g_log
<<Logger::Warning
<<"Removing Trust Anchor for "<<entry
<<", requested via control channel"<<endl
;
662 g_luaconfs
.modify([entry
](LuaConfigItems
& lci
) {
663 lci
.dsAnchors
.erase(entry
);
665 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, entry
, true));
666 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, entry
, true));
667 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, entry
, true));
672 removed
+= " " + entry
.toStringRootDot();
674 return "Removed Trust Anchor(s) for" + removed
+ "\n";
677 static string
getTAs()
679 if(checkDNSSECDisabled())
680 return "DNSSEC is disabled in the configuration\n";
682 string
ret("Configured Trust Anchors:\n");
683 auto luaconf
= g_luaconfs
.getLocal();
684 for (auto anchor
: luaconf
->dsAnchors
) {
685 ret
+= anchor
.first
.toLogString() + "\n";
686 for (auto e
: anchor
.second
) {
687 ret
+="\t\t"+e
.getZoneRepresentation() + "\n";
695 static string
setMinimumTTL(T begin
, T end
)
698 return "Need to supply new minimum TTL number\n";
700 SyncRes::s_minimumTTL
= pdns_stou(*begin
);
701 return "New minimum TTL: " + std::to_string(SyncRes::s_minimumTTL
) + "\n";
703 catch (const std::exception
& e
) {
704 return "Error parsing the new minimum TTL number: " + std::string(e
.what()) + "\n";
709 static string
setMinimumECSTTL(T begin
, T end
)
712 return "Need to supply new ECS minimum TTL number\n";
714 SyncRes::s_minimumECSTTL
= pdns_stou(*begin
);
715 return "New minimum ECS TTL: " + std::to_string(SyncRes::s_minimumECSTTL
) + "\n";
717 catch (const std::exception
& e
) {
718 return "Error parsing the new ECS minimum TTL number: " + std::string(e
.what()) + "\n";
723 static string
setMaxCacheEntries(T begin
, T end
)
726 return "Need to supply new cache size\n";
728 g_maxCacheEntries
= pdns_stou(*begin
);
729 return "New max cache entries: " + std::to_string(g_maxCacheEntries
) + "\n";
731 catch (const std::exception
& e
) {
732 return "Error parsing the new cache size: " + std::string(e
.what()) + "\n";
737 static string
setMaxPacketCacheEntries(T begin
, T end
)
740 return "Need to supply new packet cache size\n";
742 g_maxPacketCacheEntries
= pdns_stou(*begin
);
743 return "New max packetcache entries: " + std::to_string(g_maxPacketCacheEntries
) + "\n";
745 catch (const std::exception
& e
) {
746 return "Error parsing the new packet cache size: " + std::string(e
.what()) + "\n";
751 static uint64_t getSysTimeMsec()
754 getrusage(RUSAGE_SELF
, &ru
);
755 return (ru
.ru_stime
.tv_sec
*1000ULL + ru
.ru_stime
.tv_usec
/1000);
758 static uint64_t getUserTimeMsec()
761 getrusage(RUSAGE_SELF
, &ru
);
762 return (ru
.ru_utime
.tv_sec
*1000ULL + ru
.ru_utime
.tv_usec
/1000);
765 static uint64_t calculateUptime()
767 return time(nullptr) - g_stats
.startupTime
;
770 static string
* pleaseGetCurrentQueries()
774 gettimeofday(&now
, 0);
776 ostr
<< getMT()->d_waiters
.size() <<" currently outstanding questions\n";
778 boost::format
fmt("%1% %|40t|%2% %|47t|%3% %|63t|%4% %|68t|%5% %|78t|%6%\n");
780 ostr
<< (fmt
% "qname" % "qtype" % "remote" % "tcp" % "chained" % "spent(ms)");
782 for(const auto& mthread
: getMT()->d_waiters
) {
783 const PacketID
& pident
= mthread
.key
;
784 const double spent
= g_networkTimeoutMsec
- (DiffTime(now
, mthread
.ttd
) * 1000);
786 % pident
.domain
.toLogString() /* ?? */ % DNSRecordContent::NumberToType(pident
.type
)
787 % pident
.remote
.toString() % (pident
.sock
? 'Y' : 'n')
788 % (pident
.fd
== -1 ? 'Y' : 'n')
789 % (spent
> 0 ? spent
: '0')
796 return new string(ostr
.str());
799 static string
doCurrentQueries()
801 return broadcastAccFunction
<string
>(pleaseGetCurrentQueries
);
804 uint64_t* pleaseGetThrottleSize()
806 return new uint64_t(SyncRes::getThrottledServersSize());
809 static uint64_t getThrottleSize()
811 return broadcastAccFunction
<uint64_t>(pleaseGetThrottleSize
);
814 uint64_t* pleaseGetNegCacheSize()
816 uint64_t tmp
=(SyncRes::getNegCacheSize());
817 return new uint64_t(tmp
);
820 static uint64_t getNegCacheSize()
822 return broadcastAccFunction
<uint64_t>(pleaseGetNegCacheSize
);
825 static uint64_t* pleaseGetFailedHostsSize()
827 uint64_t tmp
=(SyncRes::getThrottledServersSize());
828 return new uint64_t(tmp
);
831 static uint64_t getFailedHostsSize()
833 return broadcastAccFunction
<uint64_t>(pleaseGetFailedHostsSize
);
836 uint64_t* pleaseGetNsSpeedsSize()
838 return new uint64_t(SyncRes::getNSSpeedsSize());
841 static uint64_t getNsSpeedsSize()
843 return broadcastAccFunction
<uint64_t>(pleaseGetNsSpeedsSize
);
846 uint64_t* pleaseGetConcurrentQueries()
848 return new uint64_t(getMT() ? getMT()->numProcesses() : 0);
851 static uint64_t getConcurrentQueries()
853 return broadcastAccFunction
<uint64_t>(pleaseGetConcurrentQueries
);
856 uint64_t* pleaseGetCacheSize()
858 return new uint64_t(t_RC
? t_RC
->size() : 0);
861 static uint64_t* pleaseGetCacheBytes()
863 return new uint64_t(t_RC
? t_RC
->bytes() : 0);
866 static uint64_t doGetCacheSize()
868 return broadcastAccFunction
<uint64_t>(pleaseGetCacheSize
);
871 static uint64_t doGetAvgLatencyUsec()
873 return (uint64_t) g_stats
.avgLatencyUsec
;
876 static uint64_t doGetCacheBytes()
878 return broadcastAccFunction
<uint64_t>(pleaseGetCacheBytes
);
881 uint64_t* pleaseGetCacheHits()
883 return new uint64_t(t_RC
? t_RC
->cacheHits
: 0);
886 static uint64_t doGetCacheHits()
888 return broadcastAccFunction
<uint64_t>(pleaseGetCacheHits
);
891 uint64_t* pleaseGetCacheMisses()
893 return new uint64_t(t_RC
? t_RC
->cacheMisses
: 0);
896 static uint64_t doGetCacheMisses()
898 return broadcastAccFunction
<uint64_t>(pleaseGetCacheMisses
);
901 uint64_t* pleaseGetPacketCacheSize()
903 return new uint64_t(t_packetCache
? t_packetCache
->size() : 0);
906 static uint64_t* pleaseGetPacketCacheBytes()
908 return new uint64_t(t_packetCache
? t_packetCache
->bytes() : 0);
911 static uint64_t doGetPacketCacheSize()
913 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheSize
);
916 static uint64_t doGetPacketCacheBytes()
918 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheBytes
);
921 uint64_t* pleaseGetPacketCacheHits()
923 return new uint64_t(t_packetCache
? t_packetCache
->d_hits
: 0);
926 static uint64_t doGetPacketCacheHits()
928 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheHits
);
931 static uint64_t* pleaseGetPacketCacheMisses()
933 return new uint64_t(t_packetCache
? t_packetCache
->d_misses
: 0);
936 static uint64_t doGetPacketCacheMisses()
938 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheMisses
);
941 static uint64_t doGetMallocated()
943 // this turned out to be broken
944 /* struct mallinfo mi = mallinfo();
945 return mi.uordblks; */
949 extern ResponseStats g_rs
;
951 void registerAllStats()
953 static std::atomic_flag s_init
= ATOMIC_FLAG_INIT
;
954 if(s_init
.test_and_set())
957 addGetStat("questions", &g_stats
.qcounter
);
958 addGetStat("ipv6-questions", &g_stats
.ipv6qcounter
);
959 addGetStat("tcp-questions", &g_stats
.tcpqcounter
);
961 addGetStat("cache-hits", doGetCacheHits
);
962 addGetStat("cache-misses", doGetCacheMisses
);
963 addGetStat("cache-entries", doGetCacheSize
);
964 addGetStat("max-cache-entries", []() { return g_maxCacheEntries
.load(); });
965 addGetStat("max-packetcache-entries", []() { return g_maxPacketCacheEntries
.load();});
966 addGetStat("cache-bytes", doGetCacheBytes
);
968 addGetStat("packetcache-hits", doGetPacketCacheHits
);
969 addGetStat("packetcache-misses", doGetPacketCacheMisses
);
970 addGetStat("packetcache-entries", doGetPacketCacheSize
);
971 addGetStat("packetcache-bytes", doGetPacketCacheBytes
);
973 addGetStat("malloc-bytes", doGetMallocated
);
975 addGetStat("servfail-answers", &g_stats
.servFails
);
976 addGetStat("nxdomain-answers", &g_stats
.nxDomains
);
977 addGetStat("noerror-answers", &g_stats
.noErrors
);
979 addGetStat("unauthorized-udp", &g_stats
.unauthorizedUDP
);
980 addGetStat("unauthorized-tcp", &g_stats
.unauthorizedTCP
);
981 addGetStat("tcp-client-overflow", &g_stats
.tcpClientOverflow
);
983 addGetStat("client-parse-errors", &g_stats
.clientParseError
);
984 addGetStat("server-parse-errors", &g_stats
.serverParseError
);
985 addGetStat("too-old-drops", &g_stats
.tooOldDrops
);
986 addGetStat("truncated-drops", &g_stats
.truncatedDrops
);
987 addGetStat("query-pipe-full-drops", &g_stats
.queryPipeFullDrops
);
989 addGetStat("answers0-1", &g_stats
.answers0_1
);
990 addGetStat("answers1-10", &g_stats
.answers1_10
);
991 addGetStat("answers10-100", &g_stats
.answers10_100
);
992 addGetStat("answers100-1000", &g_stats
.answers100_1000
);
993 addGetStat("answers-slow", &g_stats
.answersSlow
);
995 addGetStat("x-ourtime0-1", &g_stats
.ourtime0_1
);
996 addGetStat("x-ourtime1-2", &g_stats
.ourtime1_2
);
997 addGetStat("x-ourtime2-4", &g_stats
.ourtime2_4
);
998 addGetStat("x-ourtime4-8", &g_stats
.ourtime4_8
);
999 addGetStat("x-ourtime8-16", &g_stats
.ourtime8_16
);
1000 addGetStat("x-ourtime16-32", &g_stats
.ourtime16_32
);
1001 addGetStat("x-ourtime-slow", &g_stats
.ourtimeSlow
);
1003 addGetStat("auth4-answers0-1", &g_stats
.auth4Answers0_1
);
1004 addGetStat("auth4-answers1-10", &g_stats
.auth4Answers1_10
);
1005 addGetStat("auth4-answers10-100", &g_stats
.auth4Answers10_100
);
1006 addGetStat("auth4-answers100-1000", &g_stats
.auth4Answers100_1000
);
1007 addGetStat("auth4-answers-slow", &g_stats
.auth4AnswersSlow
);
1009 addGetStat("auth6-answers0-1", &g_stats
.auth6Answers0_1
);
1010 addGetStat("auth6-answers1-10", &g_stats
.auth6Answers1_10
);
1011 addGetStat("auth6-answers10-100", &g_stats
.auth6Answers10_100
);
1012 addGetStat("auth6-answers100-1000", &g_stats
.auth6Answers100_1000
);
1013 addGetStat("auth6-answers-slow", &g_stats
.auth6AnswersSlow
);
1016 addGetStat("qa-latency", doGetAvgLatencyUsec
);
1017 addGetStat("x-our-latency", []() { return g_stats
.avgLatencyOursUsec
; });
1018 addGetStat("unexpected-packets", &g_stats
.unexpectedCount
);
1019 addGetStat("case-mismatches", &g_stats
.caseMismatchCount
);
1020 addGetStat("spoof-prevents", &g_stats
.spoofCount
);
1022 addGetStat("nsset-invalidations", &g_stats
.nsSetInvalidations
);
1024 addGetStat("resource-limits", &g_stats
.resourceLimits
);
1025 addGetStat("over-capacity-drops", &g_stats
.overCapacityDrops
);
1026 addGetStat("policy-drops", &g_stats
.policyDrops
);
1027 addGetStat("no-packet-error", &g_stats
.noPacketError
);
1028 addGetStat("dlg-only-drops", &SyncRes::s_nodelegated
);
1029 addGetStat("ignored-packets", &g_stats
.ignoredCount
);
1030 addGetStat("empty-queries", &g_stats
.emptyQueriesCount
);
1031 addGetStat("max-mthread-stack", &g_stats
.maxMThreadStackUsage
);
1033 addGetStat("negcache-entries", getNegCacheSize
);
1034 addGetStat("throttle-entries", getThrottleSize
);
1036 addGetStat("nsspeeds-entries", getNsSpeedsSize
);
1037 addGetStat("failed-host-entries", getFailedHostsSize
);
1039 addGetStat("concurrent-queries", getConcurrentQueries
);
1040 addGetStat("security-status", &g_security_status
);
1041 addGetStat("outgoing-timeouts", &SyncRes::s_outgoingtimeouts
);
1042 addGetStat("outgoing4-timeouts", &SyncRes::s_outgoing4timeouts
);
1043 addGetStat("outgoing6-timeouts", &SyncRes::s_outgoing6timeouts
);
1044 addGetStat("auth-zone-queries", &SyncRes::s_authzonequeries
);
1045 addGetStat("tcp-outqueries", &SyncRes::s_tcpoutqueries
);
1046 addGetStat("all-outqueries", &SyncRes::s_outqueries
);
1047 addGetStat("ipv6-outqueries", &g_stats
.ipv6queries
);
1048 addGetStat("throttled-outqueries", &SyncRes::s_throttledqueries
);
1049 addGetStat("dont-outqueries", &SyncRes::s_dontqueries
);
1050 addGetStat("throttled-out", &SyncRes::s_throttledqueries
);
1051 addGetStat("unreachables", &SyncRes::s_unreachables
);
1052 addGetStat("ecs-queries", &SyncRes::s_ecsqueries
);
1053 addGetStat("ecs-responses", &SyncRes::s_ecsresponses
);
1054 addGetStat("chain-resends", &g_stats
.chainResends
);
1055 addGetStat("tcp-clients", boost::bind(TCPConnection::getCurrentConnections
));
1058 addGetStat("udp-recvbuf-errors", boost::bind(udpErrorStats
, "udp-recvbuf-errors"));
1059 addGetStat("udp-sndbuf-errors", boost::bind(udpErrorStats
, "udp-sndbuf-errors"));
1060 addGetStat("udp-noport-errors", boost::bind(udpErrorStats
, "udp-noport-errors"));
1061 addGetStat("udp-in-errors", boost::bind(udpErrorStats
, "udp-in-errors"));
1064 addGetStat("edns-ping-matches", &g_stats
.ednsPingMatches
);
1065 addGetStat("edns-ping-mismatches", &g_stats
.ednsPingMismatches
);
1066 addGetStat("dnssec-queries", &g_stats
.dnssecQueries
);
1068 addGetStat("dnssec-authentic-data-queries", &g_stats
.dnssecAuthenticDataQueries
);
1069 addGetStat("dnssec-check-disabled-queries", &g_stats
.dnssecCheckDisabledQueries
);
1071 addGetStat("variable-responses", &g_stats
.variableResponses
);
1073 addGetStat("noping-outqueries", &g_stats
.noPingOutQueries
);
1074 addGetStat("noedns-outqueries", &g_stats
.noEdnsOutQueries
);
1076 addGetStat("uptime", calculateUptime
);
1077 addGetStat("real-memory-usage", boost::bind(getRealMemoryUsage
, string()));
1078 addGetStat("special-memory-usage", boost::bind(getSpecialMemoryUsage
, string()));
1079 addGetStat("fd-usage", boost::bind(getOpenFileDescriptors
, string()));
1081 // addGetStat("query-rate", getQueryRate);
1082 addGetStat("user-msec", getUserTimeMsec
);
1083 addGetStat("sys-msec", getSysTimeMsec
);
1086 addGetStat("memory-allocs", boost::bind(&MallocTracer::getAllocs
, g_mtracer
, string()));
1087 addGetStat("memory-alloc-flux", boost::bind(&MallocTracer::getAllocFlux
, g_mtracer
, string()));
1088 addGetStat("memory-allocated", boost::bind(&MallocTracer::getTotAllocated
, g_mtracer
, string()));
1091 addGetStat("dnssec-validations", &g_stats
.dnssecValidations
);
1092 addGetStat("dnssec-result-insecure", &g_stats
.dnssecResults
[Insecure
]);
1093 addGetStat("dnssec-result-secure", &g_stats
.dnssecResults
[Secure
]);
1094 addGetStat("dnssec-result-bogus", &g_stats
.dnssecResults
[Bogus
]);
1095 addGetStat("dnssec-result-indeterminate", &g_stats
.dnssecResults
[Indeterminate
]);
1096 addGetStat("dnssec-result-nta", &g_stats
.dnssecResults
[NTA
]);
1098 addGetStat("policy-result-noaction", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NoAction
]);
1099 addGetStat("policy-result-drop", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Drop
]);
1100 addGetStat("policy-result-nxdomain", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NXDOMAIN
]);
1101 addGetStat("policy-result-nodata", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NODATA
]);
1102 addGetStat("policy-result-truncate", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Truncate
]);
1103 addGetStat("policy-result-custom", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Custom
]);
1105 addGetStat("rebalanced-queries", &g_stats
.rebalancedQueries
);
1107 /* make sure that the ECS stats are properly initialized */
1108 SyncRes::clearECSStats();
1109 for (size_t idx
= 0; idx
< SyncRes::s_ecsResponsesBySubnetSize4
.size(); idx
++) {
1110 const std::string name
= "ecs-v4-response-bits-" + std::to_string(idx
+ 1);
1111 addGetStat(name
, &(SyncRes::s_ecsResponsesBySubnetSize4
.at(idx
)));
1113 for (size_t idx
= 0; idx
< SyncRes::s_ecsResponsesBySubnetSize6
.size(); idx
++) {
1114 const std::string name
= "ecs-v6-response-bits-" + std::to_string(idx
+ 1);
1115 addGetStat(name
, &(SyncRes::s_ecsResponsesBySubnetSize6
.at(idx
)));
1119 static void doExitGeneric(bool nicely
)
1121 g_log
<<Logger::Error
<<"Exiting on user request"<<endl
;
1122 extern RecursorControlChannel s_rcc
;
1123 s_rcc
.~RecursorControlChannel();
1125 extern string s_pidfname
;
1126 if(!s_pidfname
.empty())
1127 unlink(s_pidfname
.c_str()); // we can at least try..
1134 static void doExit()
1136 doExitGeneric(false);
1139 static void doExitNicely()
1141 doExitGeneric(true);
1144 vector
<pair
<DNSName
, uint16_t> >* pleaseGetQueryRing()
1146 typedef pair
<DNSName
,uint16_t> query_t
;
1147 vector
<query_t
>* ret
= new vector
<query_t
>();
1150 ret
->reserve(t_queryring
->size());
1152 for(const query_t
& q
: *t_queryring
) {
1157 vector
<pair
<DNSName
,uint16_t> >* pleaseGetServfailQueryRing()
1159 typedef pair
<DNSName
,uint16_t> query_t
;
1160 vector
<query_t
>* ret
= new vector
<query_t
>();
1161 if(!t_servfailqueryring
)
1163 ret
->reserve(t_servfailqueryring
->size());
1164 for(const query_t
& q
: *t_servfailqueryring
) {
1169 vector
<pair
<DNSName
,uint16_t> >* pleaseGetBogusQueryRing()
1171 typedef pair
<DNSName
,uint16_t> query_t
;
1172 vector
<query_t
>* ret
= new vector
<query_t
>();
1173 if(!t_bogusqueryring
)
1175 ret
->reserve(t_bogusqueryring
->size());
1176 for(const query_t
& q
: *t_bogusqueryring
) {
1184 typedef boost::function
<vector
<ComboAddress
>*()> pleaseremotefunc_t
;
1185 typedef boost::function
<vector
<pair
<DNSName
,uint16_t> >*()> pleasequeryfunc_t
;
1187 vector
<ComboAddress
>* pleaseGetRemotes()
1189 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1193 ret
->reserve(t_remotes
->size());
1194 for(const ComboAddress
& ca
: *t_remotes
) {
1200 vector
<ComboAddress
>* pleaseGetServfailRemotes()
1202 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1203 if(!t_servfailremotes
)
1205 ret
->reserve(t_servfailremotes
->size());
1206 for(const ComboAddress
& ca
: *t_servfailremotes
) {
1212 vector
<ComboAddress
>* pleaseGetBogusRemotes()
1214 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1217 ret
->reserve(t_bogusremotes
->size());
1218 for(const ComboAddress
& ca
: *t_bogusremotes
) {
1224 vector
<ComboAddress
>* pleaseGetLargeAnswerRemotes()
1226 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1227 if(!t_largeanswerremotes
)
1229 ret
->reserve(t_largeanswerremotes
->size());
1230 for(const ComboAddress
& ca
: *t_largeanswerremotes
) {
1236 vector
<ComboAddress
>* pleaseGetTimeouts()
1238 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1241 ret
->reserve(t_timeouts
->size());
1242 for(const ComboAddress
& ca
: *t_timeouts
) {
1248 string
doGenericTopRemotes(pleaseremotefunc_t func
)
1250 typedef map
<ComboAddress
, int, ComboAddress::addressOnlyLessThan
> counts_t
;
1253 vector
<ComboAddress
> remotes
=broadcastAccFunction
<vector
<ComboAddress
> >(func
);
1255 unsigned int total
=0;
1256 for(const ComboAddress
& ca
: remotes
) {
1261 typedef std::multimap
<int, ComboAddress
> rcounts_t
;
1264 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1265 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1268 ret
<<"Over last "<<total
<<" entries:\n";
1269 format
fmt("%.02f%%\t%s\n");
1270 int limit
=0, accounted
=0;
1272 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1273 ret
<< fmt
% (-100.0*i
->first
/total
) % i
->second
.toString();
1274 accounted
+= -i
->first
;
1276 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1281 // XXX DNSName Pain - this function should benefit from native DNSName methods
1282 DNSName
getRegisteredName(const DNSName
& dom
)
1284 auto parts
=dom
.getRawLabels();
1287 reverse(parts
.begin(), parts
.end());
1288 for(string
& str
: parts
) { str
=toLower(str
); };
1292 while(!parts
.empty()) {
1293 if(parts
.size()==1 || binary_search(g_pubs
.begin(), g_pubs
.end(), parts
)) {
1299 for(auto p
= parts
.crbegin(); p
!= parts
.crend(); ++p
) {
1302 return DNSName(ret
);
1305 last
=parts
[parts
.size()-1];
1306 parts
.resize(parts
.size()-1);
1308 return DNSName("??");
1311 static DNSName
nopFilter(const DNSName
& name
)
1316 string
doGenericTopQueries(pleasequeryfunc_t func
, boost::function
<DNSName(const DNSName
&)> filter
=nopFilter
)
1318 typedef pair
<DNSName
,uint16_t> query_t
;
1319 typedef map
<query_t
, int> counts_t
;
1321 vector
<query_t
> queries
=broadcastAccFunction
<vector
<query_t
> >(func
);
1323 unsigned int total
=0;
1324 for(const query_t
& q
: queries
) {
1326 counts
[make_pair(filter(q
.first
),q
.second
)]++;
1329 typedef std::multimap
<int, query_t
> rcounts_t
;
1332 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1333 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1336 ret
<<"Over last "<<total
<<" entries:\n";
1337 format
fmt("%.02f%%\t%s\n");
1338 int limit
=0, accounted
=0;
1340 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1341 ret
<< fmt
% (-100.0*i
->first
/total
) % (i
->second
.first
.toLogString()+"|"+DNSRecordContent::NumberToType(i
->second
.second
));
1342 accounted
+= -i
->first
;
1344 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1351 static string
* nopFunction()
1353 return new string("pong\n");
1356 string
RecursorControlParser::getAnswer(const string
& question
, RecursorControlParser::func_t
** command
)
1359 vector
<string
> words
;
1360 stringtok(words
, question
);
1363 return "invalid command\n";
1365 string cmd
=toLower(words
[0]);
1366 vector
<string
>::const_iterator begin
=words
.begin()+1, end
=words
.end();
1368 // should probably have a smart dispatcher here, like auth has
1371 "add-nta DOMAIN [REASON] add a Negative Trust Anchor for DOMAIN with the comment REASON\n"
1372 "add-ta DOMAIN DSRECORD add a Trust Anchor for DOMAIN with data DSRECORD\n"
1373 "current-queries show currently active queries\n"
1374 "clear-nta [DOMAIN]... Clear the Negative Trust Anchor for DOMAINs, if no DOMAIN is specified, remove all\n"
1375 "clear-ta [DOMAIN]... Clear the Trust Anchor for DOMAINs\n"
1376 "dump-cache <filename> dump cache contents to the named file\n"
1377 "dump-edns [status] <filename> dump EDNS status to the named file\n"
1378 "dump-nsspeeds <filename> dump nsspeeds statistics to the named file\n"
1379 "dump-rpz <zone name> <filename> dump the content of a RPZ zone to the named file\n"
1380 "dump-throttlemap <filename> dump the contents of the throttle to the named file\n"
1381 "get [key1] [key2] .. get specific statistics\n"
1382 "get-all get all statistics\n"
1383 "get-ntas get all configured Negative Trust Anchors\n"
1384 "get-tas get all configured Trust Anchors\n"
1385 "get-parameter [key1] [key2] .. get configuration parameters\n"
1386 "get-qtypelist get QType statistics\n"
1387 " notice: queries from cache aren't being counted yet\n"
1388 "help get this list\n"
1389 "ping check that all threads are alive\n"
1390 "quit stop the recursor daemon\n"
1391 "quit-nicely stop the recursor daemon nicely\n"
1392 "reload-acls reload ACLS\n"
1393 "reload-lua-script [filename] (re)load Lua script\n"
1394 "reload-lua-config [filename] (re)load Lua configuration file\n"
1395 "reload-zones reload all auth and forward zones\n"
1396 "set-ecs-minimum-ttl value set ecs-minimum-ttl-override\n"
1397 "set-max-cache-entries value set new maximum cache size\n"
1398 "set-max-packetcache-entries val set new maximum packet cache size\n"
1399 "set-minimum-ttl value set minimum-ttl-override\n"
1400 "set-carbon-server set a carbon server for telemetry\n"
1401 "set-dnssec-log-bogus SETTING enable (SETTING=yes) or disable (SETTING=no) logging of DNSSEC validation failures\n"
1402 "trace-regex [regex] emit resolution trace for matching queries (empty regex to clear trace)\n"
1403 "top-largeanswer-remotes show top remotes receiving large answers\n"
1404 "top-queries show top queries\n"
1405 "top-pub-queries show top queries grouped by public suffix list\n"
1406 "top-remotes show top remotes\n"
1407 "top-timeouts show top downstream timeouts\n"
1408 "top-servfail-queries show top queries receiving servfail answers\n"
1409 "top-bogus-queries show top queries validating as bogus\n"
1410 "top-pub-servfail-queries show top queries receiving servfail answers grouped by public suffix list\n"
1411 "top-pub-bogus-queries show top queries validating as bogus grouped by public suffix list\n"
1412 "top-servfail-remotes show top remotes receiving servfail answers\n"
1413 "top-bogus-remotes show top remotes receiving bogus answers\n"
1414 "unload-lua-script unload Lua script\n"
1415 "version return Recursor version number\n"
1416 "wipe-cache domain0 [domain1] .. wipe domain data from cache\n";
1419 return getAllStats();
1422 return doGet(begin
, end
);
1424 if(cmd
=="get-parameter")
1425 return doGetParameter(begin
, end
);
1432 if(cmd
=="version") {
1433 return getPDNSVersion()+"\n";
1436 if(cmd
=="quit-nicely") {
1437 *command
=&doExitNicely
;
1438 return "bye nicely\n";
1441 if(cmd
=="dump-cache")
1442 return doDumpCache(begin
, end
);
1444 if(cmd
=="dump-ednsstatus" || cmd
=="dump-edns")
1445 return doDumpEDNSStatus(begin
, end
);
1447 if(cmd
=="dump-nsspeeds")
1448 return doDumpNSSpeeds(begin
, end
);
1450 if(cmd
=="dump-rpz") {
1451 return doDumpRPZ(begin
, end
);
1454 if(cmd
=="dump-throttlemap")
1455 return doDumpThrottleMap(begin
, end
);
1457 if(cmd
=="wipe-cache" || cmd
=="flushname")
1458 return doWipeCache(begin
, end
);
1460 if(cmd
=="reload-lua-script")
1461 return doQueueReloadLuaScript(begin
, end
);
1463 if(cmd
=="reload-lua-config") {
1465 ::arg().set("lua-config-file") = *begin
;
1468 luaConfigDelayedThreads delayedLuaThreads
;
1469 loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads
);
1470 startLuaConfigDelayedThreads(delayedLuaThreads
, g_luaconfs
.getCopy().generation
);
1471 g_log
<<Logger::Warning
<<"Reloaded Lua configuration file '"<<::arg()["lua-config-file"]<<"', requested via control channel"<<endl
;
1472 return "Reloaded Lua configuration file '"+::arg()["lua-config-file"]+"'\n";
1474 catch(std::exception
& e
) {
1475 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.what()+"\n";
1477 catch(const PDNSException
& e
) {
1478 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.reason
+"\n";
1482 if(cmd
=="set-carbon-server")
1483 return doSetCarbonServer(begin
, end
);
1485 if(cmd
=="trace-regex")
1486 return doTraceRegex(begin
, end
);
1488 if(cmd
=="unload-lua-script") {
1489 vector
<string
> empty
;
1490 empty
.push_back(string());
1491 return doQueueReloadLuaScript(empty
.begin(), empty
.end());
1494 if(cmd
=="reload-acls") {
1495 if(!::arg()["chroot"].empty()) {
1496 g_log
<<Logger::Error
<<"Unable to reload ACL when chroot()'ed, requested via control channel"<<endl
;
1497 return "Unable to reload ACL when chroot()'ed, please restart\n";
1503 catch(std::exception
& e
)
1505 g_log
<<Logger::Error
<<"Reloading ACLs failed (Exception: "<<e
.what()<<")"<<endl
;
1506 return e
.what() + string("\n");
1508 catch(PDNSException
& ae
)
1510 g_log
<<Logger::Error
<<"Reloading ACLs failed (PDNSException: "<<ae
.reason
<<")"<<endl
;
1511 return ae
.reason
+ string("\n");
1517 if(cmd
=="top-remotes")
1518 return doGenericTopRemotes(pleaseGetRemotes
);
1520 if(cmd
=="top-queries")
1521 return doGenericTopQueries(pleaseGetQueryRing
);
1523 if(cmd
=="top-pub-queries")
1524 return doGenericTopQueries(pleaseGetQueryRing
, getRegisteredName
);
1526 if(cmd
=="top-servfail-queries")
1527 return doGenericTopQueries(pleaseGetServfailQueryRing
);
1529 if(cmd
=="top-pub-servfail-queries")
1530 return doGenericTopQueries(pleaseGetServfailQueryRing
, getRegisteredName
);
1532 if(cmd
=="top-bogus-queries")
1533 return doGenericTopQueries(pleaseGetBogusQueryRing
);
1535 if(cmd
=="top-pub-bogus-queries")
1536 return doGenericTopQueries(pleaseGetBogusQueryRing
, getRegisteredName
);
1539 if(cmd
=="top-servfail-remotes")
1540 return doGenericTopRemotes(pleaseGetServfailRemotes
);
1542 if(cmd
=="top-bogus-remotes")
1543 return doGenericTopRemotes(pleaseGetBogusRemotes
);
1545 if(cmd
=="top-largeanswer-remotes")
1546 return doGenericTopRemotes(pleaseGetLargeAnswerRemotes
);
1548 if(cmd
=="top-timeouts")
1549 return doGenericTopRemotes(pleaseGetTimeouts
);
1552 if(cmd
=="current-queries")
1553 return doCurrentQueries();
1556 return broadcastAccFunction
<string
>(nopFunction
);
1559 if(cmd
=="reload-zones") {
1560 if(!::arg()["chroot"].empty()) {
1561 g_log
<<Logger::Error
<<"Unable to reload zones and forwards when chroot()'ed, requested via control channel"<<endl
;
1562 return "Unable to reload zones and forwards when chroot()'ed, please restart\n";
1564 return reloadAuthAndForwards();
1567 if(cmd
=="set-ecs-minimum-ttl") {
1568 return setMinimumECSTTL(begin
, end
);
1571 if(cmd
=="set-max-cache-entries") {
1572 return setMaxCacheEntries(begin
, end
);
1574 if(cmd
=="set-max-packetcache-entries") {
1575 return setMaxPacketCacheEntries(begin
, end
);
1578 if(cmd
=="set-minimum-ttl") {
1579 return setMinimumTTL(begin
, end
);
1582 if(cmd
=="get-qtypelist") {
1583 return g_rs
.getQTypeReport();
1586 if(cmd
=="add-nta") {
1587 return doAddNTA(begin
, end
);
1590 if(cmd
=="clear-nta") {
1591 return doClearNTA(begin
, end
);
1594 if(cmd
=="get-ntas") {
1599 return doAddTA(begin
, end
);
1602 if(cmd
=="clear-ta") {
1603 return doClearTA(begin
, end
);
1606 if(cmd
=="get-tas") {
1610 if (cmd
=="set-dnssec-log-bogus")
1611 return doSetDnssecLogBogus(begin
, end
);
1613 return "Unknown command '"+cmd
+"', try 'help'\n";