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(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
));
234 static uint64_t* pleaseDumpFailedServers(int fd
)
236 return new uint64_t(SyncRes::doDumpFailedServers(fd
));
240 static string
doDumpNSSpeeds(T begin
, T end
)
248 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
250 return "Error opening dump file for writing: "+stringerror()+"\n";
253 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpNSSpeeds
, fd
));
255 catch(std::exception
& e
)
258 return "error dumping NS speeds: "+string(e
.what())+"\n";
260 catch(PDNSException
& e
)
263 return "error dumping NS speeds: "+e
.reason
+"\n";
267 return "dumped "+std::to_string(total
)+" records\n";
271 static string
doDumpCache(T begin
, T end
)
279 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
281 return "Error opening dump file for writing: "+stringerror()+"\n";
284 total
= s_RC
->doDump(fd
) + broadcastAccFunction
<uint64_t>(boost::bind(pleaseDump
, fd
));
289 return "dumped "+std::to_string(total
)+" records\n";
293 static string
doDumpEDNSStatus(T begin
, T end
)
301 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
303 return "Error opening dump file for writing: "+stringerror()+"\n";
306 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpEDNSMap
, fd
));
311 return "dumped "+std::to_string(total
)+" records\n";
315 static string
doDumpRPZ(T begin
, T end
)
320 return "No zone name specified\n";
322 string zoneName
= *i
;
326 return "No file name specified\n";
330 auto luaconf
= g_luaconfs
.getLocal();
331 const auto zone
= luaconf
->dfe
.getZone(zoneName
);
333 return "No RPZ zone named "+zoneName
+"\n";
336 int fd
= open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
339 return "Error opening dump file for writing: "+stringerror()+"\n";
342 auto fp
= std::unique_ptr
<FILE, int(*)(FILE*)>(fdopen(fd
, "w"), fclose
);
345 return "Error converting file descriptor: "+stringerror()+"\n";
348 zone
->dump(fp
.get());
354 static string
doDumpThrottleMap(T begin
, T end
)
362 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
364 return "Error opening dump file for writing: "+stringerror()+"\n";
367 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpThrottleMap
, fd
));
372 return "dumped "+std::to_string(total
)+" records\n";
376 static string
doDumpFailedServers(T begin
, T end
)
384 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
386 return "Error opening dump file for writing: "+stringerror()+"\n";
389 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpFailedServers
, fd
));
394 return "dumped "+std::to_string(total
)+" records\n";
397 uint64_t* pleaseWipeCache(const DNSName
& canon
, bool subtree
, uint16_t qtype
)
399 return new uint64_t(s_RC
->doWipeCache(canon
, subtree
));
402 uint64_t* pleaseWipePacketCache(const DNSName
& canon
, bool subtree
, uint16_t qtype
)
404 return new uint64_t(t_packetCache
->doWipePacketCache(canon
, qtype
, subtree
));
408 uint64_t* pleaseWipeAndCountNegCache(const DNSName
& canon
, bool subtree
)
410 uint64_t ret
= SyncRes::wipeNegCache(canon
, subtree
);
411 return new uint64_t(ret
);
416 static string
doWipeCache(T begin
, T end
, uint16_t qtype
)
418 vector
<pair
<DNSName
, bool> > toWipe
;
419 for(T i
=begin
; i
!= end
; ++i
) {
424 if(boost::ends_with(*i
, "$")) {
425 canon
=DNSName(i
->substr(0, i
->size()-1));
430 } catch (std::exception
&e
) {
431 return "Error: " + std::string(e
.what()) + ", nothing wiped\n";
433 toWipe
.push_back({canon
, subtree
});
436 int count
=0, pcount
=0, countNeg
=0;
437 for (auto wipe
: toWipe
) {
438 count
+= broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, wipe
.first
, wipe
.second
, qtype
));
439 pcount
+= broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, wipe
.first
, wipe
.second
, qtype
));
440 countNeg
+=broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, wipe
.first
, wipe
.second
));
443 return "wiped "+std::to_string(count
)+" records, "+std::to_string(countNeg
)+" negative records, "+std::to_string(pcount
)+" packets\n";
447 static string
doSetCarbonServer(T begin
, T end
)
449 Lock
l(&g_carbon_config_lock
);
451 ::arg().set("carbon-server").clear();
452 return "cleared carbon-server setting\n";
455 ::arg().set("carbon-server")=*begin
;
456 ret
="set carbon-server to '"+::arg()["carbon-server"]+"'\n";
459 ::arg().set("carbon-ourname")=*begin
;
460 ret
+="set carbon-ourname to '"+*begin
+"'\n";
466 ::arg().set("carbon-namespace")=*begin
;
467 ret
+="set carbon-namespace to '"+*begin
+"'\n";
473 ::arg().set("carbon-instance")=*begin
;
474 ret
+="set carbon-instance to '"+*begin
+"'\n";
480 static string
doSetDnssecLogBogus(T begin
, T end
)
482 if(checkDNSSECDisabled())
483 return "DNSSEC is disabled in the configuration, not changing the Bogus logging setting\n";
486 return "No DNSSEC Bogus logging setting specified\n";
488 if (pdns_iequals(*begin
, "on") || pdns_iequals(*begin
, "yes")) {
489 if (!g_dnssecLogBogus
) {
490 g_log
<<Logger::Warning
<<"Enabling DNSSEC Bogus logging, requested via control channel"<<endl
;
491 g_dnssecLogBogus
= true;
492 return "DNSSEC Bogus logging enabled\n";
494 return "DNSSEC Bogus logging was already enabled\n";
497 if (pdns_iequals(*begin
, "off") || pdns_iequals(*begin
, "no")) {
498 if (g_dnssecLogBogus
) {
499 g_log
<<Logger::Warning
<<"Disabling DNSSEC Bogus logging, requested via control channel"<<endl
;
500 g_dnssecLogBogus
= false;
501 return "DNSSEC Bogus logging disabled\n";
503 return "DNSSEC Bogus logging was already disabled\n";
506 return "Unknown DNSSEC Bogus setting: '" + *begin
+"'\n";
510 static string
doAddNTA(T begin
, T end
)
512 if(checkDNSSECDisabled())
513 return "DNSSEC is disabled in the configuration, not adding a Negative Trust Anchor\n";
516 return "No NTA specified, doing nothing\n";
520 who
= DNSName(*begin
);
522 catch(std::exception
&e
) {
523 string
ret("Can't add Negative Trust Anchor: ");
531 while (begin
!= end
) {
537 g_log
<<Logger::Warning
<<"Adding Negative Trust Anchor for "<<who
<<" with reason '"<<why
<<"', requested via control channel"<<endl
;
538 g_luaconfs
.modify([who
, why
](LuaConfigItems
& lci
) {
539 lci
.negAnchors
[who
] = why
;
541 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, who
, true, 0xffff));
542 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, who
, true, 0xffff));
543 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, who
, true));
544 return "Added Negative Trust Anchor for " + who
.toLogString() + " with reason '" + why
+ "'\n";
548 static string
doClearNTA(T begin
, T end
)
550 if(checkDNSSECDisabled())
551 return "DNSSEC is disabled in the configuration, not removing a Negative Trust Anchor\n";
554 return "No Negative Trust Anchor specified, doing nothing.\n";
556 if (begin
+ 1 == end
&& *begin
== "*"){
557 g_log
<<Logger::Warning
<<"Clearing all Negative Trust Anchors, requested via control channel"<<endl
;
558 g_luaconfs
.modify([](LuaConfigItems
& lci
) {
559 lci
.negAnchors
.clear();
561 return "Cleared all Negative Trust Anchors.\n";
564 vector
<DNSName
> toRemove
;
566 while (begin
!= end
) {
568 return "Don't mix all Negative Trust Anchor removal with multiple Negative Trust Anchor removal. Nothing removed\n";
570 who
= DNSName(*begin
);
572 catch(std::exception
&e
) {
573 string
ret("Error: ");
575 ret
+= ". No Negative Anchors removed\n";
578 toRemove
.push_back(who
);
584 for (auto const &entry
: toRemove
) {
585 g_log
<<Logger::Warning
<<"Clearing Negative Trust Anchor for "<<entry
<<", requested via control channel"<<endl
;
586 g_luaconfs
.modify([entry
](LuaConfigItems
& lci
) {
587 lci
.negAnchors
.erase(entry
);
589 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, entry
, true, 0xffff));
590 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, entry
, true, 0xffff));
591 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, entry
, true));
596 removed
+= " " + entry
.toStringRootDot();
598 return "Removed Negative Trust Anchors for " + removed
+ "\n";
601 static string
getNTAs()
603 if(checkDNSSECDisabled())
604 return "DNSSEC is disabled in the configuration\n";
606 string
ret("Configured Negative Trust Anchors:\n");
607 auto luaconf
= g_luaconfs
.getLocal();
608 for (auto negAnchor
: luaconf
->negAnchors
)
609 ret
+= negAnchor
.first
.toLogString() + "\t" + negAnchor
.second
+ "\n";
614 static string
doAddTA(T begin
, T end
)
616 if(checkDNSSECDisabled())
617 return "DNSSEC is disabled in the configuration, not adding a Trust Anchor\n";
620 return "No TA specified, doing nothing\n";
624 who
= DNSName(*begin
);
626 catch(std::exception
&e
) {
627 string
ret("Can't add Trust Anchor: ");
635 while (begin
!= end
) {
636 what
+= *begin
+ " ";
641 g_log
<<Logger::Warning
<<"Adding Trust Anchor for "<<who
<<" with data '"<<what
<<"', requested via control channel";
642 g_luaconfs
.modify([who
, what
](LuaConfigItems
& lci
) {
643 auto ds
=std::dynamic_pointer_cast
<DSRecordContent
>(DSRecordContent::make(what
));
644 lci
.dsAnchors
[who
].insert(*ds
);
646 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, who
, true, 0xffff));
647 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, who
, true, 0xffff));
648 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, who
, true));
649 g_log
<<Logger::Warning
<<endl
;
650 return "Added Trust Anchor for " + who
.toStringRootDot() + " with data " + what
+ "\n";
652 catch(std::exception
&e
) {
653 g_log
<<Logger::Warning
<<", failed: "<<e
.what()<<endl
;
654 return "Unable to add Trust Anchor for " + who
.toStringRootDot() + ": " + e
.what() + "\n";
659 static string
doClearTA(T begin
, T end
)
661 if(checkDNSSECDisabled())
662 return "DNSSEC is disabled in the configuration, not removing a Trust Anchor\n";
665 return "No Trust Anchor to clear\n";
667 vector
<DNSName
> toRemove
;
669 while (begin
!= end
) {
671 who
= DNSName(*begin
);
673 catch(std::exception
&e
) {
674 string
ret("Error: ");
676 ret
+= ". No Anchors removed\n";
680 return "Refusing to remove root Trust Anchor, no Anchors removed\n";
681 toRemove
.push_back(who
);
687 for (auto const &entry
: toRemove
) {
688 g_log
<<Logger::Warning
<<"Removing Trust Anchor for "<<entry
<<", requested via control channel"<<endl
;
689 g_luaconfs
.modify([entry
](LuaConfigItems
& lci
) {
690 lci
.dsAnchors
.erase(entry
);
692 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, entry
, true, 0xffff));
693 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, entry
, true, 0xffff));
694 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, entry
, true));
699 removed
+= " " + entry
.toStringRootDot();
701 return "Removed Trust Anchor(s) for" + removed
+ "\n";
704 static string
getTAs()
706 if(checkDNSSECDisabled())
707 return "DNSSEC is disabled in the configuration\n";
709 string
ret("Configured Trust Anchors:\n");
710 auto luaconf
= g_luaconfs
.getLocal();
711 for (auto anchor
: luaconf
->dsAnchors
) {
712 ret
+= anchor
.first
.toLogString() + "\n";
713 for (auto e
: anchor
.second
) {
714 ret
+="\t\t"+e
.getZoneRepresentation() + "\n";
722 static string
setMinimumTTL(T begin
, T end
)
725 return "Need to supply new minimum TTL number\n";
727 SyncRes::s_minimumTTL
= pdns_stou(*begin
);
728 return "New minimum TTL: " + std::to_string(SyncRes::s_minimumTTL
) + "\n";
730 catch (const std::exception
& e
) {
731 return "Error parsing the new minimum TTL number: " + std::string(e
.what()) + "\n";
736 static string
setMinimumECSTTL(T begin
, T end
)
739 return "Need to supply new ECS minimum TTL number\n";
741 SyncRes::s_minimumECSTTL
= pdns_stou(*begin
);
742 return "New minimum ECS TTL: " + std::to_string(SyncRes::s_minimumECSTTL
) + "\n";
744 catch (const std::exception
& e
) {
745 return "Error parsing the new ECS minimum TTL number: " + std::string(e
.what()) + "\n";
750 static string
setMaxCacheEntries(T begin
, T end
)
753 return "Need to supply new cache size\n";
755 g_maxCacheEntries
= pdns_stou(*begin
);
756 return "New max cache entries: " + std::to_string(g_maxCacheEntries
) + "\n";
758 catch (const std::exception
& e
) {
759 return "Error parsing the new cache size: " + std::string(e
.what()) + "\n";
764 static string
setMaxPacketCacheEntries(T begin
, T end
)
767 return "Need to supply new packet cache size\n";
769 g_maxPacketCacheEntries
= pdns_stou(*begin
);
770 return "New max packetcache entries: " + std::to_string(g_maxPacketCacheEntries
) + "\n";
772 catch (const std::exception
& e
) {
773 return "Error parsing the new packet cache size: " + std::string(e
.what()) + "\n";
778 static uint64_t getSysTimeMsec()
781 getrusage(RUSAGE_SELF
, &ru
);
782 return (ru
.ru_stime
.tv_sec
*1000ULL + ru
.ru_stime
.tv_usec
/1000);
785 static uint64_t getUserTimeMsec()
788 getrusage(RUSAGE_SELF
, &ru
);
789 return (ru
.ru_utime
.tv_sec
*1000ULL + ru
.ru_utime
.tv_usec
/1000);
792 /* This is a pretty weird set of functions. To get per-thread cpu usage numbers,
793 we have to ask a thread over a pipe. We could do so surgically, so if you want to know about
794 thread 3, we pick pipe 3, but we lack that infrastructure.
796 We can however ask "execute this function on all threads and add up the results".
797 This is what the first function does using a custom object ThreadTimes, which if you add
798 to each other keeps filling the first one with CPU usage numbers
801 static ThreadTimes
* pleaseGetThreadCPUMsec()
806 getrusage(RUSAGE_THREAD
, &ru
);
807 ret
= (ru
.ru_utime
.tv_sec
*1000ULL + ru
.ru_utime
.tv_usec
/1000);
808 ret
+= (ru
.ru_stime
.tv_sec
*1000ULL + ru
.ru_stime
.tv_usec
/1000);
810 return new ThreadTimes
{ret
, vector
<uint64_t>()};
813 /* Next up, when you want msec data for a specific thread, we check
814 if we recently executed pleaseGetThreadCPUMsec. If we didn't we do so
815 now and consult all threads.
817 We then answer you from the (re)fresh(ed) ThreadTimes.
819 static uint64_t doGetThreadCPUMsec(int n
)
821 static std::mutex s_mut
;
822 static time_t last
= 0;
823 static ThreadTimes tt
;
825 std::lock_guard
<std::mutex
> l(s_mut
);
826 if(last
!= time(nullptr)) {
827 tt
= broadcastAccFunction
<ThreadTimes
>(pleaseGetThreadCPUMsec
);
828 last
= time(nullptr);
831 return tt
.times
.at(n
);
834 static uint64_t calculateUptime()
836 return time(nullptr) - g_stats
.startupTime
;
839 static string
* pleaseGetCurrentQueries()
843 gettimeofday(&now
, 0);
845 ostr
<< getMT()->d_waiters
.size() <<" currently outstanding questions\n";
847 boost::format
fmt("%1% %|40t|%2% %|47t|%3% %|63t|%4% %|68t|%5% %|78t|%6%\n");
849 ostr
<< (fmt
% "qname" % "qtype" % "remote" % "tcp" % "chained" % "spent(ms)");
851 for(const auto& mthread
: getMT()->d_waiters
) {
852 const PacketID
& pident
= mthread
.key
;
853 const double spent
= g_networkTimeoutMsec
- (DiffTime(now
, mthread
.ttd
) * 1000);
855 % pident
.domain
.toLogString() /* ?? */ % DNSRecordContent::NumberToType(pident
.type
)
856 % pident
.remote
.toString() % (pident
.sock
? 'Y' : 'n')
857 % (pident
.fd
== -1 ? 'Y' : 'n')
858 % (spent
> 0 ? spent
: '0')
865 return new string(ostr
.str());
868 static string
doCurrentQueries()
870 return broadcastAccFunction
<string
>(pleaseGetCurrentQueries
);
873 uint64_t* pleaseGetThrottleSize()
875 return new uint64_t(SyncRes::getThrottledServersSize());
878 static uint64_t getThrottleSize()
880 return broadcastAccFunction
<uint64_t>(pleaseGetThrottleSize
);
883 uint64_t* pleaseGetNegCacheSize()
885 uint64_t tmp
=(SyncRes::getNegCacheSize());
886 return new uint64_t(tmp
);
889 static uint64_t getNegCacheSize()
891 return broadcastAccFunction
<uint64_t>(pleaseGetNegCacheSize
);
894 static uint64_t* pleaseGetFailedHostsSize()
896 uint64_t tmp
=(SyncRes::getThrottledServersSize());
897 return new uint64_t(tmp
);
900 static uint64_t getFailedHostsSize()
902 return broadcastAccFunction
<uint64_t>(pleaseGetFailedHostsSize
);
905 uint64_t* pleaseGetNsSpeedsSize()
907 return new uint64_t(SyncRes::getNSSpeedsSize());
910 static uint64_t getNsSpeedsSize()
912 return broadcastAccFunction
<uint64_t>(pleaseGetNsSpeedsSize
);
915 uint64_t* pleaseGetFailedServersSize()
917 return new uint64_t(SyncRes::getFailedServersSize());
920 uint64_t* pleaseGetEDNSStatusesSize()
922 return new uint64_t(SyncRes::getEDNSStatusesSize());
925 uint64_t* pleaseGetConcurrentQueries()
927 return new uint64_t(getMT() ? getMT()->numProcesses() : 0);
930 static uint64_t getConcurrentQueries()
932 return broadcastAccFunction
<uint64_t>(pleaseGetConcurrentQueries
);
935 static uint64_t doGetCacheSize()
940 static uint64_t doGetAvgLatencyUsec()
942 return (uint64_t) g_stats
.avgLatencyUsec
;
945 static uint64_t doGetCacheBytes()
947 return s_RC
->bytes();
950 static uint64_t doGetCacheHits()
952 return s_RC
->cacheHits
;
955 static uint64_t doGetCacheMisses()
957 return s_RC
->cacheMisses
;
960 uint64_t* pleaseGetPacketCacheSize()
962 return new uint64_t(t_packetCache
? t_packetCache
->size() : 0);
965 static uint64_t* pleaseGetPacketCacheBytes()
967 return new uint64_t(t_packetCache
? t_packetCache
->bytes() : 0);
970 static uint64_t doGetPacketCacheSize()
972 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheSize
);
975 static uint64_t doGetPacketCacheBytes()
977 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheBytes
);
980 uint64_t* pleaseGetPacketCacheHits()
982 return new uint64_t(t_packetCache
? t_packetCache
->d_hits
: 0);
985 static uint64_t doGetPacketCacheHits()
987 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheHits
);
990 static uint64_t* pleaseGetPacketCacheMisses()
992 return new uint64_t(t_packetCache
? t_packetCache
->d_misses
: 0);
995 static uint64_t doGetPacketCacheMisses()
997 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheMisses
);
1000 static uint64_t doGetMallocated()
1002 // this turned out to be broken
1003 /* struct mallinfo mi = mallinfo();
1004 return mi.uordblks; */
1008 extern ResponseStats g_rs
;
1010 void registerAllStats()
1012 static std::atomic_flag s_init
= ATOMIC_FLAG_INIT
;
1013 if(s_init
.test_and_set())
1016 addGetStat("questions", &g_stats
.qcounter
);
1017 addGetStat("ipv6-questions", &g_stats
.ipv6qcounter
);
1018 addGetStat("tcp-questions", &g_stats
.tcpqcounter
);
1020 addGetStat("cache-hits", doGetCacheHits
);
1021 addGetStat("cache-misses", doGetCacheMisses
);
1022 addGetStat("cache-entries", doGetCacheSize
);
1023 addGetStat("max-cache-entries", []() { return g_maxCacheEntries
.load(); });
1024 addGetStat("max-packetcache-entries", []() { return g_maxPacketCacheEntries
.load();});
1025 addGetStat("cache-bytes", doGetCacheBytes
);
1027 addGetStat("packetcache-hits", doGetPacketCacheHits
);
1028 addGetStat("packetcache-misses", doGetPacketCacheMisses
);
1029 addGetStat("packetcache-entries", doGetPacketCacheSize
);
1030 addGetStat("packetcache-bytes", doGetPacketCacheBytes
);
1032 addGetStat("malloc-bytes", doGetMallocated
);
1034 addGetStat("servfail-answers", &g_stats
.servFails
);
1035 addGetStat("nxdomain-answers", &g_stats
.nxDomains
);
1036 addGetStat("noerror-answers", &g_stats
.noErrors
);
1038 addGetStat("unauthorized-udp", &g_stats
.unauthorizedUDP
);
1039 addGetStat("unauthorized-tcp", &g_stats
.unauthorizedTCP
);
1040 addGetStat("tcp-client-overflow", &g_stats
.tcpClientOverflow
);
1042 addGetStat("client-parse-errors", &g_stats
.clientParseError
);
1043 addGetStat("server-parse-errors", &g_stats
.serverParseError
);
1044 addGetStat("too-old-drops", &g_stats
.tooOldDrops
);
1045 addGetStat("truncated-drops", &g_stats
.truncatedDrops
);
1046 addGetStat("query-pipe-full-drops", &g_stats
.queryPipeFullDrops
);
1048 addGetStat("answers0-1", &g_stats
.answers0_1
);
1049 addGetStat("answers1-10", &g_stats
.answers1_10
);
1050 addGetStat("answers10-100", &g_stats
.answers10_100
);
1051 addGetStat("answers100-1000", &g_stats
.answers100_1000
);
1052 addGetStat("answers-slow", &g_stats
.answersSlow
);
1054 addGetStat("x-ourtime0-1", &g_stats
.ourtime0_1
);
1055 addGetStat("x-ourtime1-2", &g_stats
.ourtime1_2
);
1056 addGetStat("x-ourtime2-4", &g_stats
.ourtime2_4
);
1057 addGetStat("x-ourtime4-8", &g_stats
.ourtime4_8
);
1058 addGetStat("x-ourtime8-16", &g_stats
.ourtime8_16
);
1059 addGetStat("x-ourtime16-32", &g_stats
.ourtime16_32
);
1060 addGetStat("x-ourtime-slow", &g_stats
.ourtimeSlow
);
1062 addGetStat("auth4-answers0-1", &g_stats
.auth4Answers0_1
);
1063 addGetStat("auth4-answers1-10", &g_stats
.auth4Answers1_10
);
1064 addGetStat("auth4-answers10-100", &g_stats
.auth4Answers10_100
);
1065 addGetStat("auth4-answers100-1000", &g_stats
.auth4Answers100_1000
);
1066 addGetStat("auth4-answers-slow", &g_stats
.auth4AnswersSlow
);
1068 addGetStat("auth6-answers0-1", &g_stats
.auth6Answers0_1
);
1069 addGetStat("auth6-answers1-10", &g_stats
.auth6Answers1_10
);
1070 addGetStat("auth6-answers10-100", &g_stats
.auth6Answers10_100
);
1071 addGetStat("auth6-answers100-1000", &g_stats
.auth6Answers100_1000
);
1072 addGetStat("auth6-answers-slow", &g_stats
.auth6AnswersSlow
);
1075 addGetStat("qa-latency", doGetAvgLatencyUsec
);
1076 addGetStat("x-our-latency", []() { return g_stats
.avgLatencyOursUsec
; });
1077 addGetStat("unexpected-packets", &g_stats
.unexpectedCount
);
1078 addGetStat("case-mismatches", &g_stats
.caseMismatchCount
);
1079 addGetStat("spoof-prevents", &g_stats
.spoofCount
);
1081 addGetStat("nsset-invalidations", &g_stats
.nsSetInvalidations
);
1083 addGetStat("resource-limits", &g_stats
.resourceLimits
);
1084 addGetStat("over-capacity-drops", &g_stats
.overCapacityDrops
);
1085 addGetStat("policy-drops", &g_stats
.policyDrops
);
1086 addGetStat("no-packet-error", &g_stats
.noPacketError
);
1087 addGetStat("dlg-only-drops", &SyncRes::s_nodelegated
);
1088 addGetStat("ignored-packets", &g_stats
.ignoredCount
);
1089 addGetStat("empty-queries", &g_stats
.emptyQueriesCount
);
1090 addGetStat("max-mthread-stack", &g_stats
.maxMThreadStackUsage
);
1092 addGetStat("negcache-entries", getNegCacheSize
);
1093 addGetStat("throttle-entries", getThrottleSize
);
1095 addGetStat("nsspeeds-entries", getNsSpeedsSize
);
1096 addGetStat("failed-host-entries", getFailedHostsSize
);
1098 addGetStat("concurrent-queries", getConcurrentQueries
);
1099 addGetStat("security-status", &g_security_status
);
1100 addGetStat("outgoing-timeouts", &SyncRes::s_outgoingtimeouts
);
1101 addGetStat("outgoing4-timeouts", &SyncRes::s_outgoing4timeouts
);
1102 addGetStat("outgoing6-timeouts", &SyncRes::s_outgoing6timeouts
);
1103 addGetStat("auth-zone-queries", &SyncRes::s_authzonequeries
);
1104 addGetStat("tcp-outqueries", &SyncRes::s_tcpoutqueries
);
1105 addGetStat("all-outqueries", &SyncRes::s_outqueries
);
1106 addGetStat("ipv6-outqueries", &g_stats
.ipv6queries
);
1107 addGetStat("throttled-outqueries", &SyncRes::s_throttledqueries
);
1108 addGetStat("dont-outqueries", &SyncRes::s_dontqueries
);
1109 addGetStat("qname-min-fallback-success", &SyncRes::s_qnameminfallbacksuccess
);
1110 addGetStat("throttled-out", &SyncRes::s_throttledqueries
);
1111 addGetStat("unreachables", &SyncRes::s_unreachables
);
1112 addGetStat("ecs-queries", &SyncRes::s_ecsqueries
);
1113 addGetStat("ecs-responses", &SyncRes::s_ecsresponses
);
1114 addGetStat("chain-resends", &g_stats
.chainResends
);
1115 addGetStat("tcp-clients", boost::bind(TCPConnection::getCurrentConnections
));
1118 addGetStat("udp-recvbuf-errors", boost::bind(udpErrorStats
, "udp-recvbuf-errors"));
1119 addGetStat("udp-sndbuf-errors", boost::bind(udpErrorStats
, "udp-sndbuf-errors"));
1120 addGetStat("udp-noport-errors", boost::bind(udpErrorStats
, "udp-noport-errors"));
1121 addGetStat("udp-in-errors", boost::bind(udpErrorStats
, "udp-in-errors"));
1124 addGetStat("edns-ping-matches", &g_stats
.ednsPingMatches
);
1125 addGetStat("edns-ping-mismatches", &g_stats
.ednsPingMismatches
);
1126 addGetStat("dnssec-queries", &g_stats
.dnssecQueries
);
1128 addGetStat("dnssec-authentic-data-queries", &g_stats
.dnssecAuthenticDataQueries
);
1129 addGetStat("dnssec-check-disabled-queries", &g_stats
.dnssecCheckDisabledQueries
);
1131 addGetStat("variable-responses", &g_stats
.variableResponses
);
1133 addGetStat("noping-outqueries", &g_stats
.noPingOutQueries
);
1134 addGetStat("noedns-outqueries", &g_stats
.noEdnsOutQueries
);
1136 addGetStat("uptime", calculateUptime
);
1137 addGetStat("real-memory-usage", boost::bind(getRealMemoryUsage
, string()));
1138 addGetStat("special-memory-usage", boost::bind(getSpecialMemoryUsage
, string()));
1139 addGetStat("fd-usage", boost::bind(getOpenFileDescriptors
, string()));
1141 // addGetStat("query-rate", getQueryRate);
1142 addGetStat("user-msec", getUserTimeMsec
);
1143 addGetStat("sys-msec", getSysTimeMsec
);
1146 addGetStat("cpu-iowait", boost::bind(getCPUIOWait
, string()));
1147 addGetStat("cpu-steal", boost::bind(getCPUSteal
, string()));
1150 for(unsigned int n
=0; n
< g_numThreads
; ++n
)
1151 addGetStat("cpu-msec-thread-"+std::to_string(n
), boost::bind(&doGetThreadCPUMsec
, n
));
1154 addGetStat("memory-allocs", boost::bind(&MallocTracer::getAllocs
, g_mtracer
, string()));
1155 addGetStat("memory-alloc-flux", boost::bind(&MallocTracer::getAllocFlux
, g_mtracer
, string()));
1156 addGetStat("memory-allocated", boost::bind(&MallocTracer::getTotAllocated
, g_mtracer
, string()));
1159 addGetStat("dnssec-validations", &g_stats
.dnssecValidations
);
1160 addGetStat("dnssec-result-insecure", &g_stats
.dnssecResults
[Insecure
]);
1161 addGetStat("dnssec-result-secure", &g_stats
.dnssecResults
[Secure
]);
1162 addGetStat("dnssec-result-bogus", &g_stats
.dnssecResults
[Bogus
]);
1163 addGetStat("dnssec-result-indeterminate", &g_stats
.dnssecResults
[Indeterminate
]);
1164 addGetStat("dnssec-result-nta", &g_stats
.dnssecResults
[NTA
]);
1166 addGetStat("policy-result-noaction", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NoAction
]);
1167 addGetStat("policy-result-drop", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Drop
]);
1168 addGetStat("policy-result-nxdomain", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NXDOMAIN
]);
1169 addGetStat("policy-result-nodata", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NODATA
]);
1170 addGetStat("policy-result-truncate", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Truncate
]);
1171 addGetStat("policy-result-custom", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Custom
]);
1173 addGetStat("rebalanced-queries", &g_stats
.rebalancedQueries
);
1175 addGetStat("proxy-protocol-invalid", &g_stats
.proxyProtocolInvalidCount
);
1177 /* make sure that the ECS stats are properly initialized */
1178 SyncRes::clearECSStats();
1179 for (size_t idx
= 0; idx
< SyncRes::s_ecsResponsesBySubnetSize4
.size(); idx
++) {
1180 const std::string name
= "ecs-v4-response-bits-" + std::to_string(idx
+ 1);
1181 addGetStat(name
, &(SyncRes::s_ecsResponsesBySubnetSize4
.at(idx
)));
1183 for (size_t idx
= 0; idx
< SyncRes::s_ecsResponsesBySubnetSize6
.size(); idx
++) {
1184 const std::string name
= "ecs-v6-response-bits-" + std::to_string(idx
+ 1);
1185 addGetStat(name
, &(SyncRes::s_ecsResponsesBySubnetSize6
.at(idx
)));
1189 void doExitGeneric(bool nicely
)
1191 g_log
<<Logger::Error
<<"Exiting on user request"<<endl
;
1192 extern RecursorControlChannel s_rcc
;
1193 s_rcc
.~RecursorControlChannel();
1195 extern string s_pidfname
;
1196 if(!s_pidfname
.empty())
1197 unlink(s_pidfname
.c_str()); // we can at least try..
1199 RecursorControlChannel::stop
= 1;
1207 doExitGeneric(false);
1212 doExitGeneric(true);
1215 vector
<pair
<DNSName
, uint16_t> >* pleaseGetQueryRing()
1217 typedef pair
<DNSName
,uint16_t> query_t
;
1218 vector
<query_t
>* ret
= new vector
<query_t
>();
1221 ret
->reserve(t_queryring
->size());
1223 for(const query_t
& q
: *t_queryring
) {
1228 vector
<pair
<DNSName
,uint16_t> >* pleaseGetServfailQueryRing()
1230 typedef pair
<DNSName
,uint16_t> query_t
;
1231 vector
<query_t
>* ret
= new vector
<query_t
>();
1232 if(!t_servfailqueryring
)
1234 ret
->reserve(t_servfailqueryring
->size());
1235 for(const query_t
& q
: *t_servfailqueryring
) {
1240 vector
<pair
<DNSName
,uint16_t> >* pleaseGetBogusQueryRing()
1242 typedef pair
<DNSName
,uint16_t> query_t
;
1243 vector
<query_t
>* ret
= new vector
<query_t
>();
1244 if(!t_bogusqueryring
)
1246 ret
->reserve(t_bogusqueryring
->size());
1247 for(const query_t
& q
: *t_bogusqueryring
) {
1255 typedef boost::function
<vector
<ComboAddress
>*()> pleaseremotefunc_t
;
1256 typedef boost::function
<vector
<pair
<DNSName
,uint16_t> >*()> pleasequeryfunc_t
;
1258 vector
<ComboAddress
>* pleaseGetRemotes()
1260 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1264 ret
->reserve(t_remotes
->size());
1265 for(const ComboAddress
& ca
: *t_remotes
) {
1271 vector
<ComboAddress
>* pleaseGetServfailRemotes()
1273 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1274 if(!t_servfailremotes
)
1276 ret
->reserve(t_servfailremotes
->size());
1277 for(const ComboAddress
& ca
: *t_servfailremotes
) {
1283 vector
<ComboAddress
>* pleaseGetBogusRemotes()
1285 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1288 ret
->reserve(t_bogusremotes
->size());
1289 for(const ComboAddress
& ca
: *t_bogusremotes
) {
1295 vector
<ComboAddress
>* pleaseGetLargeAnswerRemotes()
1297 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1298 if(!t_largeanswerremotes
)
1300 ret
->reserve(t_largeanswerremotes
->size());
1301 for(const ComboAddress
& ca
: *t_largeanswerremotes
) {
1307 vector
<ComboAddress
>* pleaseGetTimeouts()
1309 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1312 ret
->reserve(t_timeouts
->size());
1313 for(const ComboAddress
& ca
: *t_timeouts
) {
1319 string
doGenericTopRemotes(pleaseremotefunc_t func
)
1321 typedef map
<ComboAddress
, int, ComboAddress::addressOnlyLessThan
> counts_t
;
1324 vector
<ComboAddress
> remotes
=broadcastAccFunction
<vector
<ComboAddress
> >(func
);
1326 unsigned int total
=0;
1327 for(const ComboAddress
& ca
: remotes
) {
1332 typedef std::multimap
<int, ComboAddress
> rcounts_t
;
1335 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1336 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1339 ret
<<"Over last "<<total
<<" entries:\n";
1340 format
fmt("%.02f%%\t%s\n");
1341 int limit
=0, accounted
=0;
1343 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1344 ret
<< fmt
% (-100.0*i
->first
/total
) % i
->second
.toString();
1345 accounted
+= -i
->first
;
1347 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1352 // XXX DNSName Pain - this function should benefit from native DNSName methods
1353 DNSName
getRegisteredName(const DNSName
& dom
)
1355 auto parts
=dom
.getRawLabels();
1358 reverse(parts
.begin(), parts
.end());
1359 for(string
& str
: parts
) { str
=toLower(str
); };
1363 while(!parts
.empty()) {
1364 if(parts
.size()==1 || binary_search(g_pubs
.begin(), g_pubs
.end(), parts
)) {
1370 for(auto p
= parts
.crbegin(); p
!= parts
.crend(); ++p
) {
1373 return DNSName(ret
);
1376 last
=parts
[parts
.size()-1];
1377 parts
.resize(parts
.size()-1);
1379 return DNSName("??");
1382 static DNSName
nopFilter(const DNSName
& name
)
1387 string
doGenericTopQueries(pleasequeryfunc_t func
, boost::function
<DNSName(const DNSName
&)> filter
=nopFilter
)
1389 typedef pair
<DNSName
,uint16_t> query_t
;
1390 typedef map
<query_t
, int> counts_t
;
1392 vector
<query_t
> queries
=broadcastAccFunction
<vector
<query_t
> >(func
);
1394 unsigned int total
=0;
1395 for(const query_t
& q
: queries
) {
1397 counts
[make_pair(filter(q
.first
),q
.second
)]++;
1400 typedef std::multimap
<int, query_t
> rcounts_t
;
1403 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1404 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1407 ret
<<"Over last "<<total
<<" entries:\n";
1408 format
fmt("%.02f%%\t%s\n");
1409 int limit
=0, accounted
=0;
1411 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1412 ret
<< fmt
% (-100.0*i
->first
/total
) % (i
->second
.first
.toLogString()+"|"+DNSRecordContent::NumberToType(i
->second
.second
));
1413 accounted
+= -i
->first
;
1415 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1422 static string
* nopFunction()
1424 return new string("pong\n");
1427 static string
getDontThrottleNames() {
1428 auto dtn
= g_dontThrottleNames
.getLocal();
1429 return dtn
->toString() + "\n";
1432 static string
getDontThrottleNetmasks() {
1433 auto dtn
= g_dontThrottleNetmasks
.getLocal();
1434 return dtn
->toString() + "\n";
1437 template<typename T
>
1438 static string
addDontThrottleNames(T begin
, T end
) {
1440 return "No names specified, keeping existing list\n";
1442 vector
<DNSName
> toAdd
;
1443 while (begin
!= end
) {
1445 auto d
= DNSName(*begin
);
1448 catch(const std::exception
&e
) {
1449 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1454 string ret
= "Added";
1455 auto dnt
= g_dontThrottleNames
.getCopy();
1457 for (auto const &d
: toAdd
) {
1462 ret
+= " " + d
.toLogString();
1466 g_dontThrottleNames
.setState(std::move(dnt
));
1468 ret
+= " to the list of nameservers that may not be throttled";
1469 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1473 template<typename T
>
1474 static string
addDontThrottleNetmasks(T begin
, T end
) {
1476 return "No netmasks specified, keeping existing list\n";
1478 vector
<Netmask
> toAdd
;
1479 while (begin
!= end
) {
1481 auto n
= Netmask(*begin
);
1484 catch(const std::exception
&e
) {
1485 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1487 catch(const PDNSException
&e
) {
1488 return "Problem parsing '" + *begin
+ "': "+ e
.reason
+ ", nothing added\n";
1493 string ret
= "Added";
1494 auto dnt
= g_dontThrottleNetmasks
.getCopy();
1496 for (auto const &t
: toAdd
) {
1501 ret
+= " " + t
.toString();
1505 g_dontThrottleNetmasks
.setState(std::move(dnt
));
1507 ret
+= " to the list of nameserver netmasks that may not be throttled";
1508 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1512 template<typename T
>
1513 static string
clearDontThrottleNames(T begin
, T end
) {
1515 return "No names specified, doing nothing.\n";
1517 if (begin
+ 1 == end
&& *begin
== "*"){
1518 SuffixMatchNode smn
;
1519 g_dontThrottleNames
.setState(std::move(smn
));
1520 string ret
= "Cleared list of nameserver names that may not be throttled";
1521 g_log
<<Logger::Warning
<<ret
<<", requested via control channel"<<endl
;
1525 vector
<DNSName
> toRemove
;
1526 while (begin
!= end
) {
1528 if (*begin
== "*") {
1529 return "Please don't mix '*' with other names, nothing removed\n";
1531 toRemove
.push_back(DNSName(*begin
));
1533 catch (const std::exception
&e
) {
1534 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing removed\n";
1539 string ret
= "Removed";
1541 auto dnt
= g_dontThrottleNames
.getCopy();
1542 for (const auto &name
: toRemove
) {
1547 ret
+= " " + name
.toLogString();
1551 g_dontThrottleNames
.setState(std::move(dnt
));
1553 ret
+= " from the list of nameservers that may not be throttled";
1554 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1558 template<typename T
>
1559 static string
clearDontThrottleNetmasks(T begin
, T end
) {
1561 return "No netmasks specified, doing nothing.\n";
1563 if (begin
+ 1 == end
&& *begin
== "*"){
1564 auto nmg
= g_dontThrottleNetmasks
.getCopy();
1566 g_dontThrottleNetmasks
.setState(std::move(nmg
));
1568 string ret
= "Cleared list of nameserver addresses that may not be throttled";
1569 g_log
<<Logger::Warning
<<ret
<<", requested via control channel"<<endl
;
1573 std::vector
<Netmask
> toRemove
;
1574 while (begin
!= end
) {
1576 if (*begin
== "*") {
1577 return "Please don't mix '*' with other netmasks, nothing removed\n";
1579 auto n
= Netmask(*begin
);
1580 toRemove
.push_back(n
);
1582 catch(const std::exception
&e
) {
1583 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1585 catch(const PDNSException
&e
) {
1586 return "Problem parsing '" + *begin
+ "': "+ e
.reason
+ ", nothing added\n";
1591 string ret
= "Removed";
1593 auto dnt
= g_dontThrottleNetmasks
.getCopy();
1594 for (const auto &mask
: toRemove
) {
1599 ret
+= " " + mask
.toString();
1600 dnt
.deleteMask(mask
);
1603 g_dontThrottleNetmasks
.setState(std::move(dnt
));
1605 ret
+= " from the list of nameservers that may not be throttled";
1606 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1611 string
RecursorControlParser::getAnswer(const string
& question
, RecursorControlParser::func_t
** command
)
1614 vector
<string
> words
;
1615 stringtok(words
, question
);
1618 return "invalid command\n";
1620 string cmd
=toLower(words
[0]);
1621 vector
<string
>::const_iterator begin
=words
.begin()+1, end
=words
.end();
1623 // should probably have a smart dispatcher here, like auth has
1626 "add-dont-throttle-names [N...] add names that are not allowed to be throttled\n"
1627 "add-dont-throttle-netmasks [N...]\n"
1628 " add netmasks that are not allowed to be throttled\n"
1629 "add-nta DOMAIN [REASON] add a Negative Trust Anchor for DOMAIN with the comment REASON\n"
1630 "add-ta DOMAIN DSRECORD add a Trust Anchor for DOMAIN with data DSRECORD\n"
1631 "current-queries show currently active queries\n"
1632 "clear-dont-throttle-names [N...] remove names that are not allowed to be throttled. If N is '*', remove all\n"
1633 "clear-dont-throttle-netmasks [N...]\n"
1634 " remove netmasks that are not allowed to be throttled. If N is '*', remove all\n"
1635 "clear-nta [DOMAIN]... Clear the Negative Trust Anchor for DOMAINs, if no DOMAIN is specified, remove all\n"
1636 "clear-ta [DOMAIN]... Clear the Trust Anchor for DOMAINs\n"
1637 "dump-cache <filename> dump cache contents to the named file\n"
1638 "dump-edns [status] <filename> dump EDNS status to the named file\n"
1639 "dump-nsspeeds <filename> dump nsspeeds statistics to the named file\n"
1640 "dump-rpz <zone name> <filename> dump the content of a RPZ zone to the named file\n"
1641 "dump-throttlemap <filename> dump the contents of the throttle map to the named file\n"
1642 "dump-failedservers <filename> dump the failed servers to the named file\n"
1643 "get [key1] [key2] .. get specific statistics\n"
1644 "get-all get all statistics\n"
1645 "get-dont-throttle-names get the list of names that are not allowed to be throttled\n"
1646 "get-dont-throttle-netmasks get the list of netmasks that are not allowed to be throttled\n"
1647 "get-ntas get all configured Negative Trust Anchors\n"
1648 "get-tas get all configured Trust Anchors\n"
1649 "get-parameter [key1] [key2] .. get configuration parameters\n"
1650 "get-qtypelist get QType statistics\n"
1651 " notice: queries from cache aren't being counted yet\n"
1652 "help get this list\n"
1653 "ping check that all threads are alive\n"
1654 "quit stop the recursor daemon\n"
1655 "quit-nicely stop the recursor daemon nicely\n"
1656 "reload-acls reload ACLS\n"
1657 "reload-lua-script [filename] (re)load Lua script\n"
1658 "reload-lua-config [filename] (re)load Lua configuration file\n"
1659 "reload-zones reload all auth and forward zones\n"
1660 "set-ecs-minimum-ttl value set ecs-minimum-ttl-override\n"
1661 "set-max-cache-entries value set new maximum cache size\n"
1662 "set-max-packetcache-entries val set new maximum packet cache size\n"
1663 "set-minimum-ttl value set minimum-ttl-override\n"
1664 "set-carbon-server set a carbon server for telemetry\n"
1665 "set-dnssec-log-bogus SETTING enable (SETTING=yes) or disable (SETTING=no) logging of DNSSEC validation failures\n"
1666 "trace-regex [regex] emit resolution trace for matching queries (empty regex to clear trace)\n"
1667 "top-largeanswer-remotes show top remotes receiving large answers\n"
1668 "top-queries show top queries\n"
1669 "top-pub-queries show top queries grouped by public suffix list\n"
1670 "top-remotes show top remotes\n"
1671 "top-timeouts show top downstream timeouts\n"
1672 "top-servfail-queries show top queries receiving servfail answers\n"
1673 "top-bogus-queries show top queries validating as bogus\n"
1674 "top-pub-servfail-queries show top queries receiving servfail answers grouped by public suffix list\n"
1675 "top-pub-bogus-queries show top queries validating as bogus grouped by public suffix list\n"
1676 "top-servfail-remotes show top remotes receiving servfail answers\n"
1677 "top-bogus-remotes show top remotes receiving bogus answers\n"
1678 "unload-lua-script unload Lua script\n"
1679 "version return Recursor version number\n"
1680 "wipe-cache domain0 [domain1] .. wipe domain data from cache\n"
1681 "wipe-cache-typed type domain0 [domain1] .. wipe domain data with qtype from cache\n";
1684 return getAllStats();
1687 return doGet(begin
, end
);
1689 if(cmd
=="get-parameter")
1690 return doGetParameter(begin
, end
);
1697 if(cmd
=="version") {
1698 return getPDNSVersion()+"\n";
1701 if(cmd
=="quit-nicely") {
1702 *command
=&doExitNicely
;
1703 return "bye nicely\n";
1706 if(cmd
=="dump-cache")
1707 return doDumpCache(begin
, end
);
1709 if(cmd
=="dump-ednsstatus" || cmd
=="dump-edns")
1710 return doDumpEDNSStatus(begin
, end
);
1712 if(cmd
=="dump-nsspeeds")
1713 return doDumpNSSpeeds(begin
, end
);
1715 if(cmd
=="dump-failedservers")
1716 return doDumpFailedServers(begin
, end
);
1718 if(cmd
=="dump-rpz") {
1719 return doDumpRPZ(begin
, end
);
1722 if(cmd
=="dump-throttlemap")
1723 return doDumpThrottleMap(begin
, end
);
1725 if(cmd
=="wipe-cache" || cmd
=="flushname")
1726 return doWipeCache(begin
, end
, 0xffff);
1728 if(cmd
=="wipe-cache-typed") {
1729 uint16_t qtype
= QType::chartocode(begin
->c_str());
1731 return doWipeCache(begin
, end
, qtype
);
1734 if(cmd
=="reload-lua-script")
1735 return doQueueReloadLuaScript(begin
, end
);
1737 if(cmd
=="reload-lua-config") {
1739 ::arg().set("lua-config-file") = *begin
;
1742 luaConfigDelayedThreads delayedLuaThreads
;
1743 loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads
);
1744 startLuaConfigDelayedThreads(delayedLuaThreads
, g_luaconfs
.getCopy().generation
);
1745 g_log
<<Logger::Warning
<<"Reloaded Lua configuration file '"<<::arg()["lua-config-file"]<<"', requested via control channel"<<endl
;
1746 return "Reloaded Lua configuration file '"+::arg()["lua-config-file"]+"'\n";
1748 catch(std::exception
& e
) {
1749 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.what()+"\n";
1751 catch(const PDNSException
& e
) {
1752 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.reason
+"\n";
1756 if(cmd
=="set-carbon-server")
1757 return doSetCarbonServer(begin
, end
);
1759 if(cmd
=="trace-regex")
1760 return doTraceRegex(begin
, end
);
1762 if(cmd
=="unload-lua-script") {
1763 vector
<string
> empty
;
1764 empty
.push_back(string());
1765 return doQueueReloadLuaScript(empty
.begin(), empty
.end());
1768 if(cmd
=="reload-acls") {
1769 if(!::arg()["chroot"].empty()) {
1770 g_log
<<Logger::Error
<<"Unable to reload ACL when chroot()'ed, requested via control channel"<<endl
;
1771 return "Unable to reload ACL when chroot()'ed, please restart\n";
1777 catch(std::exception
& e
)
1779 g_log
<<Logger::Error
<<"Reloading ACLs failed (Exception: "<<e
.what()<<")"<<endl
;
1780 return e
.what() + string("\n");
1782 catch(PDNSException
& ae
)
1784 g_log
<<Logger::Error
<<"Reloading ACLs failed (PDNSException: "<<ae
.reason
<<")"<<endl
;
1785 return ae
.reason
+ string("\n");
1791 if(cmd
=="top-remotes")
1792 return doGenericTopRemotes(pleaseGetRemotes
);
1794 if(cmd
=="top-queries")
1795 return doGenericTopQueries(pleaseGetQueryRing
);
1797 if(cmd
=="top-pub-queries")
1798 return doGenericTopQueries(pleaseGetQueryRing
, getRegisteredName
);
1800 if(cmd
=="top-servfail-queries")
1801 return doGenericTopQueries(pleaseGetServfailQueryRing
);
1803 if(cmd
=="top-pub-servfail-queries")
1804 return doGenericTopQueries(pleaseGetServfailQueryRing
, getRegisteredName
);
1806 if(cmd
=="top-bogus-queries")
1807 return doGenericTopQueries(pleaseGetBogusQueryRing
);
1809 if(cmd
=="top-pub-bogus-queries")
1810 return doGenericTopQueries(pleaseGetBogusQueryRing
, getRegisteredName
);
1813 if(cmd
=="top-servfail-remotes")
1814 return doGenericTopRemotes(pleaseGetServfailRemotes
);
1816 if(cmd
=="top-bogus-remotes")
1817 return doGenericTopRemotes(pleaseGetBogusRemotes
);
1819 if(cmd
=="top-largeanswer-remotes")
1820 return doGenericTopRemotes(pleaseGetLargeAnswerRemotes
);
1822 if(cmd
=="top-timeouts")
1823 return doGenericTopRemotes(pleaseGetTimeouts
);
1826 if(cmd
=="current-queries")
1827 return doCurrentQueries();
1830 return broadcastAccFunction
<string
>(nopFunction
);
1833 if(cmd
=="reload-zones") {
1834 if(!::arg()["chroot"].empty()) {
1835 g_log
<<Logger::Error
<<"Unable to reload zones and forwards when chroot()'ed, requested via control channel"<<endl
;
1836 return "Unable to reload zones and forwards when chroot()'ed, please restart\n";
1838 return reloadAuthAndForwards();
1841 if(cmd
=="set-ecs-minimum-ttl") {
1842 return setMinimumECSTTL(begin
, end
);
1845 if(cmd
=="set-max-cache-entries") {
1846 return setMaxCacheEntries(begin
, end
);
1848 if(cmd
=="set-max-packetcache-entries") {
1849 return setMaxPacketCacheEntries(begin
, end
);
1852 if(cmd
=="set-minimum-ttl") {
1853 return setMinimumTTL(begin
, end
);
1856 if(cmd
=="get-qtypelist") {
1857 return g_rs
.getQTypeReport();
1860 if(cmd
=="add-nta") {
1861 return doAddNTA(begin
, end
);
1864 if(cmd
=="clear-nta") {
1865 return doClearNTA(begin
, end
);
1868 if(cmd
=="get-ntas") {
1873 return doAddTA(begin
, end
);
1876 if(cmd
=="clear-ta") {
1877 return doClearTA(begin
, end
);
1880 if(cmd
=="get-tas") {
1884 if (cmd
=="set-dnssec-log-bogus")
1885 return doSetDnssecLogBogus(begin
, end
);
1887 if (cmd
== "get-dont-throttle-names") {
1888 return getDontThrottleNames();
1891 if (cmd
== "get-dont-throttle-netmasks") {
1892 return getDontThrottleNetmasks();
1895 if (cmd
== "add-dont-throttle-names") {
1896 return addDontThrottleNames(begin
, end
);
1899 if (cmd
== "add-dont-throttle-netmasks") {
1900 return addDontThrottleNetmasks(begin
, end
);
1903 if (cmd
== "clear-dont-throttle-names") {
1904 return clearDontThrottleNames(begin
, end
);
1907 if (cmd
== "clear-dont-throttle-netmasks") {
1908 return clearDontThrottleNetmasks(begin
, end
);
1911 return "Unknown command '"+cmd
+"', try 'help'\n";