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 uint64_t*> d_get64bitpointers
;
44 static map
<string
, const std::atomic
<uint64_t>*> d_getatomics
;
45 static map
<string
, function
< uint64_t() > > d_get64bitmembers
;
46 static pthread_mutex_t d_dynmetricslock
= PTHREAD_MUTEX_INITIALIZER
;
47 static map
<string
, std::atomic
<unsigned long>* > d_dynmetrics
;
49 static void addGetStat(const string
& name
, const uint32_t* place
)
51 d_get32bitpointers
[name
]=place
;
54 static void addGetStat(const string
& name
, const std::atomic
<uint64_t>* place
)
56 d_getatomics
[name
]=place
;
59 static void addGetStat(const string
& name
, function
<uint64_t ()> f
)
61 d_get64bitmembers
[name
]=f
;
64 std::atomic
<unsigned long>* getDynMetric(const std::string
& str
)
66 Lock
l(&d_dynmetricslock
);
67 auto f
= d_dynmetrics
.find(str
);
68 if(f
!= d_dynmetrics
.end())
71 auto ret
= new std::atomic
<unsigned long>();
72 d_dynmetrics
[str
]= ret
;
76 static optional
<uint64_t> get(const string
& name
)
78 optional
<uint64_t> ret
;
80 if(d_get32bitpointers
.count(name
))
81 return *d_get32bitpointers
.find(name
)->second
;
82 if(d_get64bitpointers
.count(name
))
83 return *d_get64bitpointers
.find(name
)->second
;
84 if(d_getatomics
.count(name
))
85 return d_getatomics
.find(name
)->second
->load();
86 if(d_get64bitmembers
.count(name
))
87 return d_get64bitmembers
.find(name
)->second();
89 Lock
l(&d_dynmetricslock
);
90 auto f
=rplookup(d_dynmetrics
, name
);
97 optional
<uint64_t> getStatByName(const std::string
& name
)
102 map
<string
,string
> getAllStatsMap()
104 map
<string
,string
> ret
;
106 for(const auto& the32bits
: d_get32bitpointers
) {
107 ret
.insert(make_pair(the32bits
.first
, std::to_string(*the32bits
.second
)));
109 for(const auto& the64bits
: d_get64bitpointers
) {
110 ret
.insert(make_pair(the64bits
.first
, std::to_string(*the64bits
.second
)));
112 for(const auto& atomic
: d_getatomics
) {
113 ret
.insert(make_pair(atomic
.first
, std::to_string(atomic
.second
->load())));
116 for(const auto& the64bitmembers
: d_get64bitmembers
) {
117 if(the64bitmembers
.first
== "cache-bytes" || the64bitmembers
.first
=="packetcache-bytes")
118 continue; // too slow for 'get-all'
119 ret
.insert(make_pair(the64bitmembers
.first
, std::to_string(the64bitmembers
.second())));
121 Lock
l(&d_dynmetricslock
);
122 for(const auto& a
: d_dynmetrics
)
123 ret
.insert({a
.first
, std::to_string(*a
.second
)});
129 typedef map
<string
, string
> varmap_t
;
130 varmap_t varmap
= getAllStatsMap();
132 for(varmap_t::value_type
& tup
: varmap
) {
133 ret
+= tup
.first
+ "\t" + tup
.second
+"\n";
139 string
doGet(T begin
, T end
)
143 for(T i
=begin
; i
!= end
; ++i
) {
144 optional
<uint64_t> num
=get(*i
);
146 ret
+=std::to_string(*num
)+"\n";
154 string
doGetParameter(T begin
, T end
)
158 using boost::replace_all
;
159 for(T i
=begin
; i
!= end
; ++i
) {
160 if(::arg().parmIsset(*i
)) {
162 replace_all(parm
, "\\", "\\\\");
163 replace_all(parm
, "\"", "\\\"");
164 replace_all(parm
, "\n", "\\n");
165 ret
+= *i
+"=\""+ parm
+"\"\n";
168 ret
+= *i
+" not known\n";
174 static uint64_t dumpNegCache(NegCache
& negcache
, int fd
)
176 FILE* fp
=fdopen(dup(fd
), "w");
177 if(!fp
) { // dup probably failed
181 fprintf(fp
, "; negcache dump from thread follows\n;\n");
182 ret
= negcache
.dumpToFile(fp
);
187 static uint64_t* pleaseDump(int fd
)
189 return new uint64_t(t_RC
->doDump(fd
) + dumpNegCache(SyncRes::t_sstorage
.negcache
, fd
) + t_packetCache
->doDump(fd
));
192 static uint64_t* pleaseDumpEDNSMap(int fd
)
194 return new uint64_t(SyncRes::doEDNSDump(fd
));
197 static uint64_t* pleaseDumpNSSpeeds(int fd
)
199 return new uint64_t(SyncRes::doDumpNSSpeeds(fd
));
202 static uint64_t* pleaseDumpThrottleMap(int fd
)
204 return new uint64_t(SyncRes::doDumpThrottleMap(fd
));
208 string
doDumpNSSpeeds(T begin
, T end
)
216 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
218 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
221 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpNSSpeeds
, fd
));
223 catch(std::exception
& e
)
226 return "error dumping NS speeds: "+string(e
.what())+"\n";
228 catch(PDNSException
& e
)
231 return "error dumping NS speeds: "+e
.reason
+"\n";
235 return "dumped "+std::to_string(total
)+" records\n";
239 string
doDumpCache(T begin
, T end
)
247 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
249 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
252 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDump
, fd
));
257 return "dumped "+std::to_string(total
)+" records\n";
261 string
doDumpEDNSStatus(T begin
, T end
)
269 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
271 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
274 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpEDNSMap
, fd
));
279 return "dumped "+std::to_string(total
)+" records\n";
283 string
doDumpRPZ(T begin
, T end
)
288 return "No zone name specified\n";
290 string zoneName
= *i
;
294 return "No file name specified\n";
298 auto luaconf
= g_luaconfs
.getLocal();
299 const auto zone
= luaconf
->dfe
.getZone(zoneName
);
301 return "No RPZ zone named "+zoneName
+"\n";
304 int fd
= open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
307 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
310 FILE* fp
= fdopen(fd
, "w");
313 return "Error converting file descriptor: "+string(strerror(errno
))+"\n";
323 string
doDumpThrottleMap(T begin
, T end
)
331 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
333 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
336 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpThrottleMap
, fd
));
341 return "dumped "+std::to_string(total
)+" records\n";
344 uint64_t* pleaseWipeCache(const DNSName
& canon
, bool subtree
)
346 return new uint64_t(t_RC
->doWipeCache(canon
, subtree
));
349 uint64_t* pleaseWipePacketCache(const DNSName
& canon
, bool subtree
)
351 return new uint64_t(t_packetCache
->doWipePacketCache(canon
,0xffff, subtree
));
355 uint64_t* pleaseWipeAndCountNegCache(const DNSName
& canon
, bool subtree
)
357 uint64_t ret
= SyncRes::wipeNegCache(canon
, subtree
);
358 return new uint64_t(ret
);
363 string
doWipeCache(T begin
, T end
)
365 vector
<pair
<DNSName
, bool> > toWipe
;
366 for(T i
=begin
; i
!= end
; ++i
) {
371 if(boost::ends_with(*i
, "$")) {
372 canon
=DNSName(i
->substr(0, i
->size()-1));
377 } catch (std::exception
&e
) {
378 return "Error: " + std::string(e
.what()) + ", nothing wiped\n";
380 toWipe
.push_back({canon
, subtree
});
383 int count
=0, pcount
=0, countNeg
=0;
384 for (auto wipe
: toWipe
) {
385 count
+= broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, wipe
.first
, wipe
.second
));
386 pcount
+= broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, wipe
.first
, wipe
.second
));
387 countNeg
+=broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, wipe
.first
, wipe
.second
));
390 return "wiped "+std::to_string(count
)+" records, "+std::to_string(countNeg
)+" negative records, "+std::to_string(pcount
)+" packets\n";
394 string
doSetCarbonServer(T begin
, T end
)
396 Lock
l(&g_carbon_config_lock
);
398 ::arg().set("carbon-server").clear();
399 return "cleared carbon-server setting\n";
402 ::arg().set("carbon-server")=*begin
;
403 ret
="set carbon-server to '"+::arg()["carbon-server"]+"'\n";
406 ::arg().set("carbon-ourname")=*begin
;
407 ret
+="set carbon-ourname to '"+*begin
+"'\n";
413 string
doSetDnssecLogBogus(T begin
, T end
)
415 if(checkDNSSECDisabled())
416 return "DNSSEC is disabled in the configuration, not changing the Bogus logging setting\n";
419 return "No DNSSEC Bogus logging setting specified\n";
421 if (pdns_iequals(*begin
, "on") || pdns_iequals(*begin
, "yes")) {
422 if (!g_dnssecLogBogus
) {
423 g_log
<<Logger::Warning
<<"Enabling DNSSEC Bogus logging, requested via control channel"<<endl
;
424 g_dnssecLogBogus
= true;
425 return "DNSSEC Bogus logging enabled\n";
427 return "DNSSEC Bogus logging was already enabled\n";
430 if (pdns_iequals(*begin
, "off") || pdns_iequals(*begin
, "no")) {
431 if (g_dnssecLogBogus
) {
432 g_log
<<Logger::Warning
<<"Disabling DNSSEC Bogus logging, requested via control channel"<<endl
;
433 g_dnssecLogBogus
= false;
434 return "DNSSEC Bogus logging disabled\n";
436 return "DNSSEC Bogus logging was already disabled\n";
439 return "Unknown DNSSEC Bogus setting: '" + *begin
+"'\n";
443 string
doAddNTA(T begin
, T end
)
445 if(checkDNSSECDisabled())
446 return "DNSSEC is disabled in the configuration, not adding a Negative Trust Anchor\n";
449 return "No NTA specified, doing nothing\n";
453 who
= DNSName(*begin
);
455 catch(std::exception
&e
) {
456 string
ret("Can't add Negative Trust Anchor: ");
464 while (begin
!= end
) {
470 g_log
<<Logger::Warning
<<"Adding Negative Trust Anchor for "<<who
<<" with reason '"<<why
<<"', requested via control channel"<<endl
;
471 g_luaconfs
.modify([who
, why
](LuaConfigItems
& lci
) {
472 lci
.negAnchors
[who
] = why
;
474 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, who
, true));
475 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, who
, true));
476 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, who
, true));
477 return "Added Negative Trust Anchor for " + who
.toLogString() + " with reason '" + why
+ "'\n";
481 string
doClearNTA(T begin
, T end
)
483 if(checkDNSSECDisabled())
484 return "DNSSEC is disabled in the configuration, not removing a Negative Trust Anchor\n";
487 return "No Negative Trust Anchor specified, doing nothing.\n";
489 if (begin
+ 1 == end
&& *begin
== "*"){
490 g_log
<<Logger::Warning
<<"Clearing all Negative Trust Anchors, requested via control channel"<<endl
;
491 g_luaconfs
.modify([](LuaConfigItems
& lci
) {
492 lci
.negAnchors
.clear();
494 return "Cleared all Negative Trust Anchors.\n";
497 vector
<DNSName
> toRemove
;
499 while (begin
!= end
) {
501 return "Don't mix all Negative Trust Anchor removal with multiple Negative Trust Anchor removal. Nothing removed\n";
503 who
= DNSName(*begin
);
505 catch(std::exception
&e
) {
506 string
ret("Error: ");
508 ret
+= ". No Negative Anchors removed\n";
511 toRemove
.push_back(who
);
517 for (auto const &entry
: toRemove
) {
518 g_log
<<Logger::Warning
<<"Clearing Negative Trust Anchor for "<<entry
<<", requested via control channel"<<endl
;
519 g_luaconfs
.modify([entry
](LuaConfigItems
& lci
) {
520 lci
.negAnchors
.erase(entry
);
522 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, entry
, true));
523 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, entry
, true));
524 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, entry
, true));
529 removed
+= " " + entry
.toStringRootDot();
531 return "Removed Negative Trust Anchors for " + removed
+ "\n";
534 static string
getNTAs()
536 if(checkDNSSECDisabled())
537 return "DNSSEC is disabled in the configuration\n";
539 string
ret("Configured Negative Trust Anchors:\n");
540 auto luaconf
= g_luaconfs
.getLocal();
541 for (auto negAnchor
: luaconf
->negAnchors
)
542 ret
+= negAnchor
.first
.toLogString() + "\t" + negAnchor
.second
+ "\n";
547 string
doAddTA(T begin
, T end
)
549 if(checkDNSSECDisabled())
550 return "DNSSEC is disabled in the configuration, not adding a Trust Anchor\n";
553 return "No TA specified, doing nothing\n";
557 who
= DNSName(*begin
);
559 catch(std::exception
&e
) {
560 string
ret("Can't add Trust Anchor: ");
568 while (begin
!= end
) {
569 what
+= *begin
+ " ";
574 g_log
<<Logger::Warning
<<"Adding Trust Anchor for "<<who
<<" with data '"<<what
<<"', requested via control channel";
575 g_luaconfs
.modify([who
, what
](LuaConfigItems
& lci
) {
576 auto ds
= unique_ptr
<DSRecordContent
>(dynamic_cast<DSRecordContent
*>(DSRecordContent::make(what
)));
577 lci
.dsAnchors
[who
].insert(*ds
);
579 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, who
, true));
580 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, who
, true));
581 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, who
, true));
582 g_log
<<Logger::Warning
<<endl
;
583 return "Added Trust Anchor for " + who
.toStringRootDot() + " with data " + what
+ "\n";
585 catch(std::exception
&e
) {
586 g_log
<<Logger::Warning
<<", failed: "<<e
.what()<<endl
;
587 return "Unable to add Trust Anchor for " + who
.toStringRootDot() + ": " + e
.what() + "\n";
592 string
doClearTA(T begin
, T end
)
594 if(checkDNSSECDisabled())
595 return "DNSSEC is disabled in the configuration, not removing a Trust Anchor\n";
598 return "No Trust Anchor to clear\n";
600 vector
<DNSName
> toRemove
;
602 while (begin
!= end
) {
604 who
= DNSName(*begin
);
606 catch(std::exception
&e
) {
607 string
ret("Error: ");
609 ret
+= ". No Anchors removed\n";
613 return "Refusing to remove root Trust Anchor, no Anchors removed\n";
614 toRemove
.push_back(who
);
620 for (auto const &entry
: toRemove
) {
621 g_log
<<Logger::Warning
<<"Removing Trust Anchor for "<<entry
<<", requested via control channel"<<endl
;
622 g_luaconfs
.modify([entry
](LuaConfigItems
& lci
) {
623 lci
.dsAnchors
.erase(entry
);
625 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, entry
, true));
626 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, entry
, true));
627 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, entry
, true));
632 removed
+= " " + entry
.toStringRootDot();
634 return "Removed Trust Anchor(s) for" + removed
+ "\n";
637 static string
getTAs()
639 if(checkDNSSECDisabled())
640 return "DNSSEC is disabled in the configuration\n";
642 string
ret("Configured Trust Anchors:\n");
643 auto luaconf
= g_luaconfs
.getLocal();
644 for (auto anchor
: luaconf
->dsAnchors
) {
645 ret
+= anchor
.first
.toLogString() + "\n";
646 for (auto e
: anchor
.second
) {
647 ret
+="\t\t"+e
.getZoneRepresentation() + "\n";
655 string
setMinimumTTL(T begin
, T end
)
658 return "Need to supply new minimum TTL number\n";
659 SyncRes::s_minimumTTL
= pdns_stou(*begin
);
660 return "New minimum TTL: " + std::to_string(SyncRes::s_minimumTTL
) + "\n";
664 string
setMaxCacheEntries(T begin
, T end
)
667 return "Need to supply new cache size\n";
668 g_maxCacheEntries
= pdns_stou(*begin
);
669 return "New max cache entries: " + std::to_string(g_maxCacheEntries
) + "\n";
673 string
setMaxPacketCacheEntries(T begin
, T end
)
676 return "Need to supply new packet cache size\n";
677 g_maxPacketCacheEntries
= pdns_stou(*begin
);
678 return "New max packetcache entries: " + std::to_string(g_maxPacketCacheEntries
) + "\n";
682 static uint64_t getSysTimeMsec()
685 getrusage(RUSAGE_SELF
, &ru
);
686 return (ru
.ru_stime
.tv_sec
*1000ULL + ru
.ru_stime
.tv_usec
/1000);
689 static uint64_t getUserTimeMsec()
692 getrusage(RUSAGE_SELF
, &ru
);
693 return (ru
.ru_utime
.tv_sec
*1000ULL + ru
.ru_utime
.tv_usec
/1000);
696 static uint64_t calculateUptime()
698 return time(0) - g_stats
.startupTime
;
701 static string
* pleaseGetCurrentQueries()
705 gettimeofday(&now
, 0);
707 ostr
<< getMT()->d_waiters
.size() <<" currently outstanding questions\n";
709 boost::format
fmt("%1% %|40t|%2% %|47t|%3% %|63t|%4% %|68t|%5% %|78t|%6%\n");
711 ostr
<< (fmt
% "qname" % "qtype" % "remote" % "tcp" % "chained" % "spent(ms)");
713 for(const auto& mthread
: getMT()->d_waiters
) {
714 const PacketID
& pident
= mthread
.key
;
715 const double spent
= g_networkTimeoutMsec
- (DiffTime(now
, mthread
.ttd
) * 1000);
717 % pident
.domain
.toLogString() /* ?? */ % DNSRecordContent::NumberToType(pident
.type
)
718 % pident
.remote
.toString() % (pident
.sock
? 'Y' : 'n')
719 % (pident
.fd
== -1 ? 'Y' : 'n')
720 % (spent
> 0 ? spent
: '0')
727 return new string(ostr
.str());
730 static string
doCurrentQueries()
732 return broadcastAccFunction
<string
>(pleaseGetCurrentQueries
);
735 uint64_t* pleaseGetThrottleSize()
737 return new uint64_t(SyncRes::getThrottledServersSize());
740 static uint64_t getThrottleSize()
742 return broadcastAccFunction
<uint64_t>(pleaseGetThrottleSize
);
745 uint64_t* pleaseGetNegCacheSize()
747 uint64_t tmp
=(SyncRes::getNegCacheSize());
748 return new uint64_t(tmp
);
751 uint64_t getNegCacheSize()
753 return broadcastAccFunction
<uint64_t>(pleaseGetNegCacheSize
);
756 uint64_t* pleaseGetFailedHostsSize()
758 uint64_t tmp
=(SyncRes::getThrottledServersSize());
759 return new uint64_t(tmp
);
761 uint64_t getFailedHostsSize()
763 return broadcastAccFunction
<uint64_t>(pleaseGetFailedHostsSize
);
766 uint64_t* pleaseGetNsSpeedsSize()
768 return new uint64_t(SyncRes::getNSSpeedsSize());
771 uint64_t getNsSpeedsSize()
773 return broadcastAccFunction
<uint64_t>(pleaseGetNsSpeedsSize
);
776 uint64_t* pleaseGetConcurrentQueries()
778 return new uint64_t(getMT() ? getMT()->numProcesses() : 0);
781 static uint64_t getConcurrentQueries()
783 return broadcastAccFunction
<uint64_t>(pleaseGetConcurrentQueries
);
786 uint64_t* pleaseGetCacheSize()
788 return new uint64_t(t_RC
? t_RC
->size() : 0);
791 uint64_t* pleaseGetCacheBytes()
793 return new uint64_t(t_RC
? t_RC
->bytes() : 0);
797 uint64_t doGetCacheSize()
799 return broadcastAccFunction
<uint64_t>(pleaseGetCacheSize
);
802 uint64_t doGetAvgLatencyUsec()
804 return (uint64_t) g_stats
.avgLatencyUsec
;
808 uint64_t doGetCacheBytes()
810 return broadcastAccFunction
<uint64_t>(pleaseGetCacheBytes
);
813 uint64_t* pleaseGetCacheHits()
815 return new uint64_t(t_RC
? t_RC
->cacheHits
: 0);
818 uint64_t doGetCacheHits()
820 return broadcastAccFunction
<uint64_t>(pleaseGetCacheHits
);
823 uint64_t* pleaseGetCacheMisses()
825 return new uint64_t(t_RC
? t_RC
->cacheMisses
: 0);
828 uint64_t doGetCacheMisses()
830 return broadcastAccFunction
<uint64_t>(pleaseGetCacheMisses
);
834 uint64_t* pleaseGetPacketCacheSize()
836 return new uint64_t(t_packetCache
? t_packetCache
->size() : 0);
839 uint64_t* pleaseGetPacketCacheBytes()
841 return new uint64_t(t_packetCache
? t_packetCache
->bytes() : 0);
845 uint64_t doGetPacketCacheSize()
847 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheSize
);
850 uint64_t doGetPacketCacheBytes()
852 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheBytes
);
856 uint64_t* pleaseGetPacketCacheHits()
858 return new uint64_t(t_packetCache
? t_packetCache
->d_hits
: 0);
861 uint64_t doGetPacketCacheHits()
863 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheHits
);
866 uint64_t* pleaseGetPacketCacheMisses()
868 return new uint64_t(t_packetCache
? t_packetCache
->d_misses
: 0);
871 uint64_t doGetPacketCacheMisses()
873 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheMisses
);
876 uint64_t doGetMallocated()
878 // this turned out to be broken
879 /* struct mallinfo mi = mallinfo();
880 return mi.uordblks; */
884 extern ResponseStats g_rs
;
886 void registerAllStats()
888 static std::atomic_flag s_init
= ATOMIC_FLAG_INIT
;
889 if(s_init
.test_and_set())
892 addGetStat("questions", &g_stats
.qcounter
);
893 addGetStat("ipv6-questions", &g_stats
.ipv6qcounter
);
894 addGetStat("tcp-questions", &g_stats
.tcpqcounter
);
896 addGetStat("cache-hits", doGetCacheHits
);
897 addGetStat("cache-misses", doGetCacheMisses
);
898 addGetStat("cache-entries", doGetCacheSize
);
899 addGetStat("max-cache-entries", []() { return g_maxCacheEntries
.load(); });
900 addGetStat("max-packetcache-entries", []() { return g_maxPacketCacheEntries
.load();});
901 addGetStat("cache-bytes", doGetCacheBytes
);
903 addGetStat("packetcache-hits", doGetPacketCacheHits
);
904 addGetStat("packetcache-misses", doGetPacketCacheMisses
);
905 addGetStat("packetcache-entries", doGetPacketCacheSize
);
906 addGetStat("packetcache-bytes", doGetPacketCacheBytes
);
908 addGetStat("malloc-bytes", doGetMallocated
);
910 addGetStat("servfail-answers", &g_stats
.servFails
);
911 addGetStat("nxdomain-answers", &g_stats
.nxDomains
);
912 addGetStat("noerror-answers", &g_stats
.noErrors
);
914 addGetStat("unauthorized-udp", &g_stats
.unauthorizedUDP
);
915 addGetStat("unauthorized-tcp", &g_stats
.unauthorizedTCP
);
916 addGetStat("tcp-client-overflow", &g_stats
.tcpClientOverflow
);
918 addGetStat("client-parse-errors", &g_stats
.clientParseError
);
919 addGetStat("server-parse-errors", &g_stats
.serverParseError
);
920 addGetStat("too-old-drops", &g_stats
.tooOldDrops
);
921 addGetStat("truncated-drops", &g_stats
.truncatedDrops
);
922 addGetStat("query-pipe-full-drops", &g_stats
.queryPipeFullDrops
);
924 addGetStat("answers0-1", &g_stats
.answers0_1
);
925 addGetStat("answers1-10", &g_stats
.answers1_10
);
926 addGetStat("answers10-100", &g_stats
.answers10_100
);
927 addGetStat("answers100-1000", &g_stats
.answers100_1000
);
928 addGetStat("answers-slow", &g_stats
.answersSlow
);
930 addGetStat("x-ourtime0-1", &g_stats
.ourtime0_1
);
931 addGetStat("x-ourtime1-2", &g_stats
.ourtime1_2
);
932 addGetStat("x-ourtime2-4", &g_stats
.ourtime2_4
);
933 addGetStat("x-ourtime4-8", &g_stats
.ourtime4_8
);
934 addGetStat("x-ourtime8-16", &g_stats
.ourtime8_16
);
935 addGetStat("x-ourtime16-32", &g_stats
.ourtime16_32
);
936 addGetStat("x-ourtime-slow", &g_stats
.ourtimeSlow
);
938 addGetStat("auth4-answers0-1", &g_stats
.auth4Answers0_1
);
939 addGetStat("auth4-answers1-10", &g_stats
.auth4Answers1_10
);
940 addGetStat("auth4-answers10-100", &g_stats
.auth4Answers10_100
);
941 addGetStat("auth4-answers100-1000", &g_stats
.auth4Answers100_1000
);
942 addGetStat("auth4-answers-slow", &g_stats
.auth4AnswersSlow
);
944 addGetStat("auth6-answers0-1", &g_stats
.auth6Answers0_1
);
945 addGetStat("auth6-answers1-10", &g_stats
.auth6Answers1_10
);
946 addGetStat("auth6-answers10-100", &g_stats
.auth6Answers10_100
);
947 addGetStat("auth6-answers100-1000", &g_stats
.auth6Answers100_1000
);
948 addGetStat("auth6-answers-slow", &g_stats
.auth6AnswersSlow
);
951 addGetStat("qa-latency", doGetAvgLatencyUsec
);
952 addGetStat("x-our-latency", []() { return g_stats
.avgLatencyOursUsec
; });
953 addGetStat("unexpected-packets", &g_stats
.unexpectedCount
);
954 addGetStat("case-mismatches", &g_stats
.caseMismatchCount
);
955 addGetStat("spoof-prevents", &g_stats
.spoofCount
);
957 addGetStat("nsset-invalidations", &g_stats
.nsSetInvalidations
);
959 addGetStat("resource-limits", &g_stats
.resourceLimits
);
960 addGetStat("over-capacity-drops", &g_stats
.overCapacityDrops
);
961 addGetStat("policy-drops", &g_stats
.policyDrops
);
962 addGetStat("no-packet-error", &g_stats
.noPacketError
);
963 addGetStat("dlg-only-drops", &SyncRes::s_nodelegated
);
964 addGetStat("ignored-packets", &g_stats
.ignoredCount
);
965 addGetStat("empty-queries", &g_stats
.emptyQueriesCount
);
966 addGetStat("max-mthread-stack", &g_stats
.maxMThreadStackUsage
);
968 addGetStat("negcache-entries", boost::bind(getNegCacheSize
));
969 addGetStat("throttle-entries", boost::bind(getThrottleSize
));
971 addGetStat("nsspeeds-entries", boost::bind(getNsSpeedsSize
));
972 addGetStat("failed-host-entries", boost::bind(getFailedHostsSize
));
974 addGetStat("concurrent-queries", boost::bind(getConcurrentQueries
));
975 addGetStat("security-status", &g_security_status
);
976 addGetStat("outgoing-timeouts", &SyncRes::s_outgoingtimeouts
);
977 addGetStat("outgoing4-timeouts", &SyncRes::s_outgoing4timeouts
);
978 addGetStat("outgoing6-timeouts", &SyncRes::s_outgoing6timeouts
);
979 addGetStat("auth-zone-queries", &SyncRes::s_authzonequeries
);
980 addGetStat("tcp-outqueries", &SyncRes::s_tcpoutqueries
);
981 addGetStat("all-outqueries", &SyncRes::s_outqueries
);
982 addGetStat("ipv6-outqueries", &g_stats
.ipv6queries
);
983 addGetStat("throttled-outqueries", &SyncRes::s_throttledqueries
);
984 addGetStat("dont-outqueries", &SyncRes::s_dontqueries
);
985 addGetStat("throttled-out", &SyncRes::s_throttledqueries
);
986 addGetStat("unreachables", &SyncRes::s_unreachables
);
987 addGetStat("ecs-queries", &SyncRes::s_ecsqueries
);
988 addGetStat("ecs-responses", &SyncRes::s_ecsresponses
);
989 addGetStat("chain-resends", &g_stats
.chainResends
);
990 addGetStat("tcp-clients", boost::bind(TCPConnection::getCurrentConnections
));
993 addGetStat("udp-recvbuf-errors", boost::bind(udpErrorStats
, "udp-recvbuf-errors"));
994 addGetStat("udp-sndbuf-errors", boost::bind(udpErrorStats
, "udp-sndbuf-errors"));
995 addGetStat("udp-noport-errors", boost::bind(udpErrorStats
, "udp-noport-errors"));
996 addGetStat("udp-in-errors", boost::bind(udpErrorStats
, "udp-in-errors"));
999 addGetStat("edns-ping-matches", &g_stats
.ednsPingMatches
);
1000 addGetStat("edns-ping-mismatches", &g_stats
.ednsPingMismatches
);
1001 addGetStat("dnssec-queries", &g_stats
.dnssecQueries
);
1003 addGetStat("noping-outqueries", &g_stats
.noPingOutQueries
);
1004 addGetStat("noedns-outqueries", &g_stats
.noEdnsOutQueries
);
1006 addGetStat("uptime", calculateUptime
);
1007 addGetStat("real-memory-usage", boost::bind(getRealMemoryUsage
, string()));
1008 addGetStat("fd-usage", boost::bind(getOpenFileDescriptors
, string()));
1010 // addGetStat("query-rate", getQueryRate);
1011 addGetStat("user-msec", getUserTimeMsec
);
1012 addGetStat("sys-msec", getSysTimeMsec
);
1015 addGetStat("memory-allocs", boost::bind(&MallocTracer::getAllocs
, g_mtracer
, string()));
1016 addGetStat("memory-alloc-flux", boost::bind(&MallocTracer::getAllocFlux
, g_mtracer
, string()));
1017 addGetStat("memory-allocated", boost::bind(&MallocTracer::getTotAllocated
, g_mtracer
, string()));
1020 addGetStat("dnssec-validations", &g_stats
.dnssecValidations
);
1021 addGetStat("dnssec-result-insecure", &g_stats
.dnssecResults
[Insecure
]);
1022 addGetStat("dnssec-result-secure", &g_stats
.dnssecResults
[Secure
]);
1023 addGetStat("dnssec-result-bogus", &g_stats
.dnssecResults
[Bogus
]);
1024 addGetStat("dnssec-result-indeterminate", &g_stats
.dnssecResults
[Indeterminate
]);
1025 addGetStat("dnssec-result-nta", &g_stats
.dnssecResults
[NTA
]);
1027 addGetStat("policy-result-noaction", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NoAction
]);
1028 addGetStat("policy-result-drop", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Drop
]);
1029 addGetStat("policy-result-nxdomain", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NXDOMAIN
]);
1030 addGetStat("policy-result-nodata", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NODATA
]);
1031 addGetStat("policy-result-truncate", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Truncate
]);
1032 addGetStat("policy-result-custom", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Custom
]);
1035 static void doExitGeneric(bool nicely
)
1037 g_log
<<Logger::Error
<<"Exiting on user request"<<endl
;
1038 extern RecursorControlChannel s_rcc
;
1039 s_rcc
.~RecursorControlChannel();
1041 extern string s_pidfname
;
1042 if(!s_pidfname
.empty())
1043 unlink(s_pidfname
.c_str()); // we can at least try..
1050 static void doExit()
1052 doExitGeneric(false);
1055 static void doExitNicely()
1057 doExitGeneric(true);
1060 vector
<pair
<DNSName
, uint16_t> >* pleaseGetQueryRing()
1062 typedef pair
<DNSName
,uint16_t> query_t
;
1063 vector
<query_t
>* ret
= new vector
<query_t
>();
1066 ret
->reserve(t_queryring
->size());
1068 for(const query_t
& q
: *t_queryring
) {
1073 vector
<pair
<DNSName
,uint16_t> >* pleaseGetServfailQueryRing()
1075 typedef pair
<DNSName
,uint16_t> query_t
;
1076 vector
<query_t
>* ret
= new vector
<query_t
>();
1077 if(!t_servfailqueryring
)
1079 ret
->reserve(t_servfailqueryring
->size());
1080 for(const query_t
& q
: *t_servfailqueryring
) {
1085 vector
<pair
<DNSName
,uint16_t> >* pleaseGetBogusQueryRing()
1087 typedef pair
<DNSName
,uint16_t> query_t
;
1088 vector
<query_t
>* ret
= new vector
<query_t
>();
1089 if(!t_bogusqueryring
)
1091 ret
->reserve(t_bogusqueryring
->size());
1092 for(const query_t
& q
: *t_bogusqueryring
) {
1100 typedef boost::function
<vector
<ComboAddress
>*()> pleaseremotefunc_t
;
1101 typedef boost::function
<vector
<pair
<DNSName
,uint16_t> >*()> pleasequeryfunc_t
;
1103 vector
<ComboAddress
>* pleaseGetRemotes()
1105 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1109 ret
->reserve(t_remotes
->size());
1110 for(const ComboAddress
& ca
: *t_remotes
) {
1116 vector
<ComboAddress
>* pleaseGetServfailRemotes()
1118 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1119 if(!t_servfailremotes
)
1121 ret
->reserve(t_servfailremotes
->size());
1122 for(const ComboAddress
& ca
: *t_servfailremotes
) {
1128 vector
<ComboAddress
>* pleaseGetBogusRemotes()
1130 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1133 ret
->reserve(t_bogusremotes
->size());
1134 for(const ComboAddress
& ca
: *t_bogusremotes
) {
1140 vector
<ComboAddress
>* pleaseGetLargeAnswerRemotes()
1142 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1143 if(!t_largeanswerremotes
)
1145 ret
->reserve(t_largeanswerremotes
->size());
1146 for(const ComboAddress
& ca
: *t_largeanswerremotes
) {
1152 vector
<ComboAddress
>* pleaseGetTimeouts()
1154 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1157 ret
->reserve(t_timeouts
->size());
1158 for(const ComboAddress
& ca
: *t_timeouts
) {
1164 string
doGenericTopRemotes(pleaseremotefunc_t func
)
1166 typedef map
<ComboAddress
, int, ComboAddress::addressOnlyLessThan
> counts_t
;
1169 vector
<ComboAddress
> remotes
=broadcastAccFunction
<vector
<ComboAddress
> >(func
);
1171 unsigned int total
=0;
1172 for(const ComboAddress
& ca
: remotes
) {
1177 typedef std::multimap
<int, ComboAddress
> rcounts_t
;
1180 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1181 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1184 ret
<<"Over last "<<total
<<" entries:\n";
1185 format
fmt("%.02f%%\t%s\n");
1186 int limit
=0, accounted
=0;
1188 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1189 ret
<< fmt
% (-100.0*i
->first
/total
) % i
->second
.toString();
1190 accounted
+= -i
->first
;
1192 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1198 typedef vector
<vector
<string
> > pubs_t
;
1202 void sortPublicSuffixList()
1204 for(const char** p
=g_pubsuffix
; *p
; ++p
) {
1205 string low
=toLower(*p
);
1207 vector
<string
> parts
;
1208 stringtok(parts
, low
, ".");
1209 reverse(parts
.begin(), parts
.end());
1210 g_pubs
.push_back(parts
);
1212 sort(g_pubs
.begin(), g_pubs
.end());
1215 // XXX DNSName Pain - this function should benefit from native DNSName methods
1216 DNSName
getRegisteredName(const DNSName
& dom
)
1218 auto parts
=dom
.getRawLabels();
1221 reverse(parts
.begin(), parts
.end());
1222 for(string
& str
: parts
) { str
=toLower(str
); };
1226 while(!parts
.empty()) {
1227 if(parts
.size()==1 || binary_search(g_pubs
.begin(), g_pubs
.end(), parts
)) {
1233 for(auto p
= parts
.crbegin(); p
!= parts
.crend(); ++p
) {
1236 return DNSName(ret
);
1239 last
=parts
[parts
.size()-1];
1240 parts
.resize(parts
.size()-1);
1242 return DNSName("??");
1245 static DNSName
nopFilter(const DNSName
& name
)
1250 string
doGenericTopQueries(pleasequeryfunc_t func
, boost::function
<DNSName(const DNSName
&)> filter
=nopFilter
)
1252 typedef pair
<DNSName
,uint16_t> query_t
;
1253 typedef map
<query_t
, int> counts_t
;
1255 vector
<query_t
> queries
=broadcastAccFunction
<vector
<query_t
> >(func
);
1257 unsigned int total
=0;
1258 for(const query_t
& q
: queries
) {
1260 counts
[make_pair(filter(q
.first
),q
.second
)]++;
1263 typedef std::multimap
<int, query_t
> rcounts_t
;
1266 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1267 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1270 ret
<<"Over last "<<total
<<" entries:\n";
1271 format
fmt("%.02f%%\t%s\n");
1272 int limit
=0, accounted
=0;
1274 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1275 ret
<< fmt
% (-100.0*i
->first
/total
) % (i
->second
.first
.toLogString()+"|"+DNSRecordContent::NumberToType(i
->second
.second
));
1276 accounted
+= -i
->first
;
1278 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1285 static string
* nopFunction()
1287 return new string("pong\n");
1290 string
RecursorControlParser::getAnswer(const string
& question
, RecursorControlParser::func_t
** command
)
1293 vector
<string
> words
;
1294 stringtok(words
, question
);
1297 return "invalid command\n";
1299 string cmd
=toLower(words
[0]);
1300 vector
<string
>::const_iterator begin
=words
.begin()+1, end
=words
.end();
1302 // should probably have a smart dispatcher here, like auth has
1305 "add-nta DOMAIN [REASON] add a Negative Trust Anchor for DOMAIN with the comment REASON\n"
1306 "add-ta DOMAIN DSRECORD add a Trust Anchor for DOMAIN with data DSRECORD\n"
1307 "current-queries show currently active queries\n"
1308 "clear-nta [DOMAIN]... Clear the Negative Trust Anchor for DOMAINs, if no DOMAIN is specified, remove all\n"
1309 "clear-ta [DOMAIN]... Clear the Trust Anchor for DOMAINs\n"
1310 "dump-cache <filename> dump cache contents to the named file\n"
1311 "dump-edns [status] <filename> dump EDNS status to the named file\n"
1312 "dump-nsspeeds <filename> dump nsspeeds statistics to the named file\n"
1313 "dump-rpz <zone name> <filename> dump the content of a RPZ zone to the named file\n"
1314 "dump-throttlemap <filename> dump the contents of the throttle to the named file\n"
1315 "get [key1] [key2] .. get specific statistics\n"
1316 "get-all get all statistics\n"
1317 "get-ntas get all configured Negative Trust Anchors\n"
1318 "get-tas get all configured Trust Anchors\n"
1319 "get-parameter [key1] [key2] .. get configuration parameters\n"
1320 "get-qtypelist get QType statistics\n"
1321 " notice: queries from cache aren't being counted yet\n"
1322 "help get this list\n"
1323 "ping check that all threads are alive\n"
1324 "quit stop the recursor daemon\n"
1325 "quit-nicely stop the recursor daemon nicely\n"
1326 "reload-acls reload ACLS\n"
1327 "reload-lua-script [filename] (re)load Lua script\n"
1328 "reload-lua-config [filename] (re)load Lua configuration file\n"
1329 "reload-zones reload all auth and forward zones\n"
1330 "set-max-cache-entries value set new maximum cache size\n"
1331 "set-max-packetcache-entries val set new maximum packet cache size\n"
1332 "set-minimum-ttl value set minimum-ttl-override\n"
1333 "set-carbon-server set a carbon server for telemetry\n"
1334 "set-dnssec-log-bogus SETTING enable (SETTING=yes) or disable (SETTING=no) logging of DNSSEC validation failures\n"
1335 "trace-regex [regex] emit resolution trace for matching queries (empty regex to clear trace)\n"
1336 "top-largeanswer-remotes show top remotes receiving large answers\n"
1337 "top-queries show top queries\n"
1338 "top-pub-queries show top queries grouped by public suffix list\n"
1339 "top-remotes show top remotes\n"
1340 "top-timeouts show top downstream timeouts\n"
1341 "top-servfail-queries show top queries receiving servfail answers\n"
1342 "top-bogus-queries show top queries validating as bogus\n"
1343 "top-pub-servfail-queries show top queries receiving servfail answers grouped by public suffix list\n"
1344 "top-pub-bogus-queries show top queries validating as bogus grouped by public suffix list\n"
1345 "top-servfail-remotes show top remotes receiving servfail answers\n"
1346 "top-bogus-remotes show top remotes receiving bogus answers\n"
1347 "unload-lua-script unload Lua script\n"
1348 "version return Recursor version number\n"
1349 "wipe-cache domain0 [domain1] .. wipe domain data from cache\n";
1352 return getAllStats();
1355 return doGet(begin
, end
);
1357 if(cmd
=="get-parameter")
1358 return doGetParameter(begin
, end
);
1365 if(cmd
=="version") {
1366 return getPDNSVersion()+"\n";
1369 if(cmd
=="quit-nicely") {
1370 *command
=&doExitNicely
;
1371 return "bye nicely\n";
1374 if(cmd
=="dump-cache")
1375 return doDumpCache(begin
, end
);
1377 if(cmd
=="dump-ednsstatus" || cmd
=="dump-edns")
1378 return doDumpEDNSStatus(begin
, end
);
1380 if(cmd
=="dump-nsspeeds")
1381 return doDumpNSSpeeds(begin
, end
);
1383 if(cmd
=="dump-rpz") {
1384 return doDumpRPZ(begin
, end
);
1387 if(cmd
=="dump-throttlemap")
1388 return doDumpThrottleMap(begin
, end
);
1390 if(cmd
=="wipe-cache" || cmd
=="flushname")
1391 return doWipeCache(begin
, end
);
1393 if(cmd
=="reload-lua-script")
1394 return doQueueReloadLuaScript(begin
, end
);
1396 if(cmd
=="reload-lua-config") {
1398 ::arg().set("lua-config-file") = *begin
;
1401 luaConfigDelayedThreads delayedLuaThreads
;
1402 loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads
);
1403 startLuaConfigDelayedThreads(delayedLuaThreads
, g_luaconfs
.getCopy().generation
);
1404 g_log
<<Logger::Warning
<<"Reloaded Lua configuration file '"<<::arg()["lua-config-file"]<<"', requested via control channel"<<endl
;
1405 return "Reloaded Lua configuration file '"+::arg()["lua-config-file"]+"'\n";
1407 catch(std::exception
& e
) {
1408 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.what()+"\n";
1410 catch(const PDNSException
& e
) {
1411 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.reason
+"\n";
1415 if(cmd
=="set-carbon-server")
1416 return doSetCarbonServer(begin
, end
);
1418 if(cmd
=="trace-regex")
1419 return doTraceRegex(begin
, end
);
1421 if(cmd
=="unload-lua-script") {
1422 vector
<string
> empty
;
1423 empty
.push_back(string());
1424 return doQueueReloadLuaScript(empty
.begin(), empty
.end());
1427 if(cmd
=="reload-acls") {
1428 if(!::arg()["chroot"].empty()) {
1429 g_log
<<Logger::Error
<<"Unable to reload ACL when chroot()'ed, requested via control channel"<<endl
;
1430 return "Unable to reload ACL when chroot()'ed, please restart\n";
1436 catch(std::exception
& e
)
1438 g_log
<<Logger::Error
<<"Reloading ACLs failed (Exception: "<<e
.what()<<")"<<endl
;
1439 return e
.what() + string("\n");
1441 catch(PDNSException
& ae
)
1443 g_log
<<Logger::Error
<<"Reloading ACLs failed (PDNSException: "<<ae
.reason
<<")"<<endl
;
1444 return ae
.reason
+ string("\n");
1450 if(cmd
=="top-remotes")
1451 return doGenericTopRemotes(pleaseGetRemotes
);
1453 if(cmd
=="top-queries")
1454 return doGenericTopQueries(pleaseGetQueryRing
);
1456 if(cmd
=="top-pub-queries")
1457 return doGenericTopQueries(pleaseGetQueryRing
, getRegisteredName
);
1459 if(cmd
=="top-servfail-queries")
1460 return doGenericTopQueries(pleaseGetServfailQueryRing
);
1462 if(cmd
=="top-pub-servfail-queries")
1463 return doGenericTopQueries(pleaseGetServfailQueryRing
, getRegisteredName
);
1465 if(cmd
=="top-bogus-queries")
1466 return doGenericTopQueries(pleaseGetBogusQueryRing
);
1468 if(cmd
=="top-pub-bogus-queries")
1469 return doGenericTopQueries(pleaseGetBogusQueryRing
, getRegisteredName
);
1472 if(cmd
=="top-servfail-remotes")
1473 return doGenericTopRemotes(pleaseGetServfailRemotes
);
1475 if(cmd
=="top-bogus-remotes")
1476 return doGenericTopRemotes(pleaseGetBogusRemotes
);
1478 if(cmd
=="top-largeanswer-remotes")
1479 return doGenericTopRemotes(pleaseGetLargeAnswerRemotes
);
1481 if(cmd
=="top-timeouts")
1482 return doGenericTopRemotes(pleaseGetTimeouts
);
1485 if(cmd
=="current-queries")
1486 return doCurrentQueries();
1489 return broadcastAccFunction
<string
>(nopFunction
);
1492 if(cmd
=="reload-zones") {
1493 if(!::arg()["chroot"].empty()) {
1494 g_log
<<Logger::Error
<<"Unable to reload zones and forwards when chroot()'ed, requested via control channel"<<endl
;
1495 return "Unable to reload zones and forwards when chroot()'ed, please restart\n";
1497 return reloadAuthAndForwards();
1500 if(cmd
=="set-max-cache-entries") {
1501 return setMaxCacheEntries(begin
, end
);
1503 if(cmd
=="set-max-packetcache-entries") {
1504 return setMaxPacketCacheEntries(begin
, end
);
1507 if(cmd
=="set-minimum-ttl") {
1508 return setMinimumTTL(begin
, end
);
1511 if(cmd
=="get-qtypelist") {
1512 return g_rs
.getQTypeReport();
1515 if(cmd
=="add-nta") {
1516 return doAddNTA(begin
, end
);
1519 if(cmd
=="clear-nta") {
1520 return doClearNTA(begin
, end
);
1523 if(cmd
=="get-ntas") {
1528 return doAddTA(begin
, end
);
1531 if(cmd
=="clear-ta") {
1532 return doClearTA(begin
, end
);
1535 if(cmd
=="get-tas") {
1539 if (cmd
=="set-dnssec-log-bogus")
1540 return doSetDnssecLogBogus(begin
, end
);
1542 return "Unknown command '"+cmd
+"', try 'help'\n";