5 #include "rec_channel.hh"
6 #include <boost/bind.hpp>
9 #include "malloctrace.hh"
12 #include "recursor_cache.hh"
14 #include "negcache.hh"
15 #include <boost/function.hpp>
16 #include <boost/optional.hpp>
17 #include <boost/tuple/tuple.hpp>
18 #include <boost/format.hpp>
19 #include <boost/algorithm/string.hpp>
22 #include <sys/types.h>
26 #include "dnsparser.hh"
27 #include "arguments.hh"
28 #include <sys/resource.h>
31 #include "responsestats.hh"
32 #include "rec-lua-conf.hh"
34 #include "validate-recursor.hh"
35 #include "filterpo.hh"
37 #include "secpoll-recursor.hh"
38 #include "pubsuffix.hh"
39 #include "namespaces.hh"
40 pthread_mutex_t g_carbon_config_lock
=PTHREAD_MUTEX_INITIALIZER
;
42 static map
<string
, const uint32_t*> d_get32bitpointers
;
43 static map
<string
, const std::atomic
<uint64_t>*> d_getatomics
;
44 static map
<string
, function
< uint64_t() > > d_get64bitmembers
;
45 static pthread_mutex_t d_dynmetricslock
= PTHREAD_MUTEX_INITIALIZER
;
46 static map
<string
, std::atomic
<unsigned long>* > d_dynmetrics
;
48 static std::map
<StatComponent
, std::set
<std::string
>> s_blacklistedStats
;
50 bool isStatBlacklisted(StatComponent component
, const string
& name
)
52 return s_blacklistedStats
[component
].count(name
) != 0;
55 void blacklistStat(StatComponent component
, const string
& name
)
57 s_blacklistedStats
[component
].insert(name
);
60 void blacklistStats(StatComponent component
, const string
& stats
)
62 std::vector
<std::string
> blacklistedStats
;
63 stringtok(blacklistedStats
, stats
, ", ");
64 auto& map
= s_blacklistedStats
[component
];
65 for (const auto &st
: blacklistedStats
) {
70 static void addGetStat(const string
& name
, const uint32_t* place
)
72 d_get32bitpointers
[name
]=place
;
75 static void addGetStat(const string
& name
, const std::atomic
<uint64_t>* place
)
77 d_getatomics
[name
]=place
;
80 static void addGetStat(const string
& name
, function
<uint64_t ()> f
)
82 d_get64bitmembers
[name
]=f
;
85 std::atomic
<unsigned long>* getDynMetric(const std::string
& str
)
87 Lock
l(&d_dynmetricslock
);
88 auto f
= d_dynmetrics
.find(str
);
89 if(f
!= d_dynmetrics
.end())
92 auto ret
= new std::atomic
<unsigned long>();
93 d_dynmetrics
[str
]= ret
;
97 static optional
<uint64_t> get(const string
& name
)
99 optional
<uint64_t> ret
;
101 if(d_get32bitpointers
.count(name
))
102 return *d_get32bitpointers
.find(name
)->second
;
103 if(d_getatomics
.count(name
))
104 return d_getatomics
.find(name
)->second
->load();
105 if(d_get64bitmembers
.count(name
))
106 return d_get64bitmembers
.find(name
)->second();
108 Lock
l(&d_dynmetricslock
);
109 auto f
=rplookup(d_dynmetrics
, name
);
116 optional
<uint64_t> getStatByName(const std::string
& name
)
121 map
<string
,string
> getAllStatsMap(StatComponent component
)
123 map
<string
,string
> ret
;
124 const auto& blacklistMap
= s_blacklistedStats
.at(component
);
126 for(const auto& the32bits
: d_get32bitpointers
) {
127 if (blacklistMap
.count(the32bits
.first
) == 0) {
128 ret
.insert(make_pair(the32bits
.first
, std::to_string(*the32bits
.second
)));
131 for(const auto& atomic
: d_getatomics
) {
132 if (blacklistMap
.count(atomic
.first
) == 0) {
133 ret
.insert(make_pair(atomic
.first
, std::to_string(atomic
.second
->load())));
137 for(const auto& the64bitmembers
: d_get64bitmembers
) {
138 if (blacklistMap
.count(the64bitmembers
.first
) == 0) {
139 ret
.insert(make_pair(the64bitmembers
.first
, std::to_string(the64bitmembers
.second())));
144 Lock
l(&d_dynmetricslock
);
145 for(const auto& a
: d_dynmetrics
) {
146 if (blacklistMap
.count(a
.first
) == 0) {
147 ret
.insert({a
.first
, std::to_string(*a
.second
)});
155 static string
getAllStats()
157 typedef map
<string
, string
> varmap_t
;
158 varmap_t varmap
= getAllStatsMap(StatComponent::RecControl
);
160 for(varmap_t::value_type
& tup
: varmap
) {
161 ret
+= tup
.first
+ "\t" + tup
.second
+"\n";
167 static string
doGet(T begin
, T end
)
171 for(T i
=begin
; i
!= end
; ++i
) {
172 optional
<uint64_t> num
=get(*i
);
174 ret
+=std::to_string(*num
)+"\n";
182 string
static doGetParameter(T begin
, T end
)
186 using boost::replace_all
;
187 for(T i
=begin
; i
!= end
; ++i
) {
188 if(::arg().parmIsset(*i
)) {
190 replace_all(parm
, "\\", "\\\\");
191 replace_all(parm
, "\"", "\\\"");
192 replace_all(parm
, "\n", "\\n");
193 ret
+= *i
+"=\""+ parm
+"\"\n";
196 ret
+= *i
+" not known\n";
202 static uint64_t dumpNegCache(NegCache
& negcache
, int fd
)
204 auto fp
= std::unique_ptr
<FILE, int(*)(FILE*)>(fdopen(dup(fd
), "w"), fclose
);
205 if(!fp
) { // dup probably failed
209 fprintf(fp
.get(), "; negcache dump from thread follows\n;\n");
210 ret
= negcache
.dumpToFile(fp
.get());
214 static uint64_t* pleaseDump(int fd
)
216 return new uint64_t(t_RC
->doDump(fd
) + dumpNegCache(SyncRes::t_sstorage
.negcache
, fd
) + t_packetCache
->doDump(fd
));
219 static uint64_t* pleaseDumpEDNSMap(int fd
)
221 return new uint64_t(SyncRes::doEDNSDump(fd
));
224 static uint64_t* pleaseDumpNSSpeeds(int fd
)
226 return new uint64_t(SyncRes::doDumpNSSpeeds(fd
));
229 static uint64_t* pleaseDumpThrottleMap(int fd
)
231 return new uint64_t(SyncRes::doDumpThrottleMap(fd
));
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
= 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(t_RC
->doWipeCache(canon
, subtree
, qtype
));
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 uint64_t* pleaseGetCacheSize()
937 return new uint64_t(t_RC
? t_RC
->size() : 0);
940 static uint64_t* pleaseGetCacheBytes()
942 return new uint64_t(t_RC
? t_RC
->bytes() : 0);
945 static uint64_t doGetCacheSize()
947 return broadcastAccFunction
<uint64_t>(pleaseGetCacheSize
);
950 static uint64_t doGetAvgLatencyUsec()
952 return (uint64_t) g_stats
.avgLatencyUsec
;
955 static uint64_t doGetCacheBytes()
957 return broadcastAccFunction
<uint64_t>(pleaseGetCacheBytes
);
960 uint64_t* pleaseGetCacheHits()
962 return new uint64_t(t_RC
? t_RC
->cacheHits
: 0);
965 static uint64_t doGetCacheHits()
967 return broadcastAccFunction
<uint64_t>(pleaseGetCacheHits
);
970 uint64_t* pleaseGetCacheMisses()
972 return new uint64_t(t_RC
? t_RC
->cacheMisses
: 0);
975 static uint64_t doGetCacheMisses()
977 return broadcastAccFunction
<uint64_t>(pleaseGetCacheMisses
);
980 uint64_t* pleaseGetPacketCacheSize()
982 return new uint64_t(t_packetCache
? t_packetCache
->size() : 0);
985 static uint64_t* pleaseGetPacketCacheBytes()
987 return new uint64_t(t_packetCache
? t_packetCache
->bytes() : 0);
990 static uint64_t doGetPacketCacheSize()
992 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheSize
);
995 static uint64_t doGetPacketCacheBytes()
997 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheBytes
);
1000 uint64_t* pleaseGetPacketCacheHits()
1002 return new uint64_t(t_packetCache
? t_packetCache
->d_hits
: 0);
1005 static uint64_t doGetPacketCacheHits()
1007 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheHits
);
1010 static uint64_t* pleaseGetPacketCacheMisses()
1012 return new uint64_t(t_packetCache
? t_packetCache
->d_misses
: 0);
1015 static uint64_t doGetPacketCacheMisses()
1017 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheMisses
);
1020 static uint64_t doGetMallocated()
1022 // this turned out to be broken
1023 /* struct mallinfo mi = mallinfo();
1024 return mi.uordblks; */
1028 extern ResponseStats g_rs
;
1030 void registerAllStats()
1032 static std::atomic_flag s_init
= ATOMIC_FLAG_INIT
;
1033 if(s_init
.test_and_set())
1036 addGetStat("questions", &g_stats
.qcounter
);
1037 addGetStat("ipv6-questions", &g_stats
.ipv6qcounter
);
1038 addGetStat("tcp-questions", &g_stats
.tcpqcounter
);
1040 addGetStat("cache-hits", doGetCacheHits
);
1041 addGetStat("cache-misses", doGetCacheMisses
);
1042 addGetStat("cache-entries", doGetCacheSize
);
1043 addGetStat("max-cache-entries", []() { return g_maxCacheEntries
.load(); });
1044 addGetStat("max-packetcache-entries", []() { return g_maxPacketCacheEntries
.load();});
1045 addGetStat("cache-bytes", doGetCacheBytes
);
1047 addGetStat("packetcache-hits", doGetPacketCacheHits
);
1048 addGetStat("packetcache-misses", doGetPacketCacheMisses
);
1049 addGetStat("packetcache-entries", doGetPacketCacheSize
);
1050 addGetStat("packetcache-bytes", doGetPacketCacheBytes
);
1052 addGetStat("malloc-bytes", doGetMallocated
);
1054 addGetStat("servfail-answers", &g_stats
.servFails
);
1055 addGetStat("nxdomain-answers", &g_stats
.nxDomains
);
1056 addGetStat("noerror-answers", &g_stats
.noErrors
);
1058 addGetStat("unauthorized-udp", &g_stats
.unauthorizedUDP
);
1059 addGetStat("unauthorized-tcp", &g_stats
.unauthorizedTCP
);
1060 addGetStat("tcp-client-overflow", &g_stats
.tcpClientOverflow
);
1062 addGetStat("client-parse-errors", &g_stats
.clientParseError
);
1063 addGetStat("server-parse-errors", &g_stats
.serverParseError
);
1064 addGetStat("too-old-drops", &g_stats
.tooOldDrops
);
1065 addGetStat("truncated-drops", &g_stats
.truncatedDrops
);
1066 addGetStat("query-pipe-full-drops", &g_stats
.queryPipeFullDrops
);
1068 addGetStat("answers0-1", &g_stats
.answers0_1
);
1069 addGetStat("answers1-10", &g_stats
.answers1_10
);
1070 addGetStat("answers10-100", &g_stats
.answers10_100
);
1071 addGetStat("answers100-1000", &g_stats
.answers100_1000
);
1072 addGetStat("answers-slow", &g_stats
.answersSlow
);
1074 addGetStat("x-ourtime0-1", &g_stats
.ourtime0_1
);
1075 addGetStat("x-ourtime1-2", &g_stats
.ourtime1_2
);
1076 addGetStat("x-ourtime2-4", &g_stats
.ourtime2_4
);
1077 addGetStat("x-ourtime4-8", &g_stats
.ourtime4_8
);
1078 addGetStat("x-ourtime8-16", &g_stats
.ourtime8_16
);
1079 addGetStat("x-ourtime16-32", &g_stats
.ourtime16_32
);
1080 addGetStat("x-ourtime-slow", &g_stats
.ourtimeSlow
);
1082 addGetStat("auth4-answers0-1", &g_stats
.auth4Answers0_1
);
1083 addGetStat("auth4-answers1-10", &g_stats
.auth4Answers1_10
);
1084 addGetStat("auth4-answers10-100", &g_stats
.auth4Answers10_100
);
1085 addGetStat("auth4-answers100-1000", &g_stats
.auth4Answers100_1000
);
1086 addGetStat("auth4-answers-slow", &g_stats
.auth4AnswersSlow
);
1088 addGetStat("auth6-answers0-1", &g_stats
.auth6Answers0_1
);
1089 addGetStat("auth6-answers1-10", &g_stats
.auth6Answers1_10
);
1090 addGetStat("auth6-answers10-100", &g_stats
.auth6Answers10_100
);
1091 addGetStat("auth6-answers100-1000", &g_stats
.auth6Answers100_1000
);
1092 addGetStat("auth6-answers-slow", &g_stats
.auth6AnswersSlow
);
1095 addGetStat("qa-latency", doGetAvgLatencyUsec
);
1096 addGetStat("x-our-latency", []() { return g_stats
.avgLatencyOursUsec
; });
1097 addGetStat("unexpected-packets", &g_stats
.unexpectedCount
);
1098 addGetStat("case-mismatches", &g_stats
.caseMismatchCount
);
1099 addGetStat("spoof-prevents", &g_stats
.spoofCount
);
1101 addGetStat("nsset-invalidations", &g_stats
.nsSetInvalidations
);
1103 addGetStat("resource-limits", &g_stats
.resourceLimits
);
1104 addGetStat("over-capacity-drops", &g_stats
.overCapacityDrops
);
1105 addGetStat("policy-drops", &g_stats
.policyDrops
);
1106 addGetStat("no-packet-error", &g_stats
.noPacketError
);
1107 addGetStat("dlg-only-drops", &SyncRes::s_nodelegated
);
1108 addGetStat("ignored-packets", &g_stats
.ignoredCount
);
1109 addGetStat("empty-queries", &g_stats
.emptyQueriesCount
);
1110 addGetStat("max-mthread-stack", &g_stats
.maxMThreadStackUsage
);
1112 addGetStat("negcache-entries", getNegCacheSize
);
1113 addGetStat("throttle-entries", getThrottleSize
);
1115 addGetStat("nsspeeds-entries", getNsSpeedsSize
);
1116 addGetStat("failed-host-entries", getFailedHostsSize
);
1118 addGetStat("concurrent-queries", getConcurrentQueries
);
1119 addGetStat("security-status", &g_security_status
);
1120 addGetStat("outgoing-timeouts", &SyncRes::s_outgoingtimeouts
);
1121 addGetStat("outgoing4-timeouts", &SyncRes::s_outgoing4timeouts
);
1122 addGetStat("outgoing6-timeouts", &SyncRes::s_outgoing6timeouts
);
1123 addGetStat("auth-zone-queries", &SyncRes::s_authzonequeries
);
1124 addGetStat("tcp-outqueries", &SyncRes::s_tcpoutqueries
);
1125 addGetStat("all-outqueries", &SyncRes::s_outqueries
);
1126 addGetStat("ipv6-outqueries", &g_stats
.ipv6queries
);
1127 addGetStat("throttled-outqueries", &SyncRes::s_throttledqueries
);
1128 addGetStat("dont-outqueries", &SyncRes::s_dontqueries
);
1129 addGetStat("qname-min-fallback-success", &SyncRes::s_qnameminfallbacksuccess
);
1130 addGetStat("throttled-out", &SyncRes::s_throttledqueries
);
1131 addGetStat("unreachables", &SyncRes::s_unreachables
);
1132 addGetStat("ecs-queries", &SyncRes::s_ecsqueries
);
1133 addGetStat("ecs-responses", &SyncRes::s_ecsresponses
);
1134 addGetStat("chain-resends", &g_stats
.chainResends
);
1135 addGetStat("tcp-clients", boost::bind(TCPConnection::getCurrentConnections
));
1138 addGetStat("udp-recvbuf-errors", boost::bind(udpErrorStats
, "udp-recvbuf-errors"));
1139 addGetStat("udp-sndbuf-errors", boost::bind(udpErrorStats
, "udp-sndbuf-errors"));
1140 addGetStat("udp-noport-errors", boost::bind(udpErrorStats
, "udp-noport-errors"));
1141 addGetStat("udp-in-errors", boost::bind(udpErrorStats
, "udp-in-errors"));
1144 addGetStat("edns-ping-matches", &g_stats
.ednsPingMatches
);
1145 addGetStat("edns-ping-mismatches", &g_stats
.ednsPingMismatches
);
1146 addGetStat("dnssec-queries", &g_stats
.dnssecQueries
);
1148 addGetStat("dnssec-authentic-data-queries", &g_stats
.dnssecAuthenticDataQueries
);
1149 addGetStat("dnssec-check-disabled-queries", &g_stats
.dnssecCheckDisabledQueries
);
1151 addGetStat("variable-responses", &g_stats
.variableResponses
);
1153 addGetStat("noping-outqueries", &g_stats
.noPingOutQueries
);
1154 addGetStat("noedns-outqueries", &g_stats
.noEdnsOutQueries
);
1156 addGetStat("uptime", calculateUptime
);
1157 addGetStat("real-memory-usage", boost::bind(getRealMemoryUsage
, string()));
1158 addGetStat("special-memory-usage", boost::bind(getSpecialMemoryUsage
, string()));
1159 addGetStat("fd-usage", boost::bind(getOpenFileDescriptors
, string()));
1161 // addGetStat("query-rate", getQueryRate);
1162 addGetStat("user-msec", getUserTimeMsec
);
1163 addGetStat("sys-msec", getSysTimeMsec
);
1166 addGetStat("cpu-iowait", boost::bind(getCPUIOWait
, string()));
1167 addGetStat("cpu-steal", boost::bind(getCPUSteal
, string()));
1170 for(unsigned int n
=0; n
< g_numThreads
; ++n
)
1171 addGetStat("cpu-msec-thread-"+std::to_string(n
), boost::bind(&doGetThreadCPUMsec
, n
));
1174 addGetStat("memory-allocs", boost::bind(&MallocTracer::getAllocs
, g_mtracer
, string()));
1175 addGetStat("memory-alloc-flux", boost::bind(&MallocTracer::getAllocFlux
, g_mtracer
, string()));
1176 addGetStat("memory-allocated", boost::bind(&MallocTracer::getTotAllocated
, g_mtracer
, string()));
1179 addGetStat("dnssec-validations", &g_stats
.dnssecValidations
);
1180 addGetStat("dnssec-result-insecure", &g_stats
.dnssecResults
[Insecure
]);
1181 addGetStat("dnssec-result-secure", &g_stats
.dnssecResults
[Secure
]);
1182 addGetStat("dnssec-result-bogus", &g_stats
.dnssecResults
[Bogus
]);
1183 addGetStat("dnssec-result-indeterminate", &g_stats
.dnssecResults
[Indeterminate
]);
1184 addGetStat("dnssec-result-nta", &g_stats
.dnssecResults
[NTA
]);
1186 addGetStat("policy-result-noaction", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NoAction
]);
1187 addGetStat("policy-result-drop", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Drop
]);
1188 addGetStat("policy-result-nxdomain", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NXDOMAIN
]);
1189 addGetStat("policy-result-nodata", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NODATA
]);
1190 addGetStat("policy-result-truncate", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Truncate
]);
1191 addGetStat("policy-result-custom", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Custom
]);
1193 addGetStat("rebalanced-queries", &g_stats
.rebalancedQueries
);
1195 /* make sure that the ECS stats are properly initialized */
1196 SyncRes::clearECSStats();
1197 for (size_t idx
= 0; idx
< SyncRes::s_ecsResponsesBySubnetSize4
.size(); idx
++) {
1198 const std::string name
= "ecs-v4-response-bits-" + std::to_string(idx
+ 1);
1199 addGetStat(name
, &(SyncRes::s_ecsResponsesBySubnetSize4
.at(idx
)));
1201 for (size_t idx
= 0; idx
< SyncRes::s_ecsResponsesBySubnetSize6
.size(); idx
++) {
1202 const std::string name
= "ecs-v6-response-bits-" + std::to_string(idx
+ 1);
1203 addGetStat(name
, &(SyncRes::s_ecsResponsesBySubnetSize6
.at(idx
)));
1207 void doExitGeneric(bool nicely
)
1209 g_log
<<Logger::Error
<<"Exiting on user request"<<endl
;
1210 extern RecursorControlChannel s_rcc
;
1211 s_rcc
.~RecursorControlChannel();
1213 extern string s_pidfname
;
1214 if(!s_pidfname
.empty())
1215 unlink(s_pidfname
.c_str()); // we can at least try..
1217 RecursorControlChannel::stop
= 1;
1225 doExitGeneric(false);
1230 doExitGeneric(true);
1233 vector
<pair
<DNSName
, uint16_t> >* pleaseGetQueryRing()
1235 typedef pair
<DNSName
,uint16_t> query_t
;
1236 vector
<query_t
>* ret
= new vector
<query_t
>();
1239 ret
->reserve(t_queryring
->size());
1241 for(const query_t
& q
: *t_queryring
) {
1246 vector
<pair
<DNSName
,uint16_t> >* pleaseGetServfailQueryRing()
1248 typedef pair
<DNSName
,uint16_t> query_t
;
1249 vector
<query_t
>* ret
= new vector
<query_t
>();
1250 if(!t_servfailqueryring
)
1252 ret
->reserve(t_servfailqueryring
->size());
1253 for(const query_t
& q
: *t_servfailqueryring
) {
1258 vector
<pair
<DNSName
,uint16_t> >* pleaseGetBogusQueryRing()
1260 typedef pair
<DNSName
,uint16_t> query_t
;
1261 vector
<query_t
>* ret
= new vector
<query_t
>();
1262 if(!t_bogusqueryring
)
1264 ret
->reserve(t_bogusqueryring
->size());
1265 for(const query_t
& q
: *t_bogusqueryring
) {
1273 typedef boost::function
<vector
<ComboAddress
>*()> pleaseremotefunc_t
;
1274 typedef boost::function
<vector
<pair
<DNSName
,uint16_t> >*()> pleasequeryfunc_t
;
1276 vector
<ComboAddress
>* pleaseGetRemotes()
1278 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1282 ret
->reserve(t_remotes
->size());
1283 for(const ComboAddress
& ca
: *t_remotes
) {
1289 vector
<ComboAddress
>* pleaseGetServfailRemotes()
1291 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1292 if(!t_servfailremotes
)
1294 ret
->reserve(t_servfailremotes
->size());
1295 for(const ComboAddress
& ca
: *t_servfailremotes
) {
1301 vector
<ComboAddress
>* pleaseGetBogusRemotes()
1303 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1306 ret
->reserve(t_bogusremotes
->size());
1307 for(const ComboAddress
& ca
: *t_bogusremotes
) {
1313 vector
<ComboAddress
>* pleaseGetLargeAnswerRemotes()
1315 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1316 if(!t_largeanswerremotes
)
1318 ret
->reserve(t_largeanswerremotes
->size());
1319 for(const ComboAddress
& ca
: *t_largeanswerremotes
) {
1325 vector
<ComboAddress
>* pleaseGetTimeouts()
1327 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1330 ret
->reserve(t_timeouts
->size());
1331 for(const ComboAddress
& ca
: *t_timeouts
) {
1337 string
doGenericTopRemotes(pleaseremotefunc_t func
)
1339 typedef map
<ComboAddress
, int, ComboAddress::addressOnlyLessThan
> counts_t
;
1342 vector
<ComboAddress
> remotes
=broadcastAccFunction
<vector
<ComboAddress
> >(func
);
1344 unsigned int total
=0;
1345 for(const ComboAddress
& ca
: remotes
) {
1350 typedef std::multimap
<int, ComboAddress
> rcounts_t
;
1353 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1354 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1357 ret
<<"Over last "<<total
<<" entries:\n";
1358 format
fmt("%.02f%%\t%s\n");
1359 int limit
=0, accounted
=0;
1361 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1362 ret
<< fmt
% (-100.0*i
->first
/total
) % i
->second
.toString();
1363 accounted
+= -i
->first
;
1365 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1370 // XXX DNSName Pain - this function should benefit from native DNSName methods
1371 DNSName
getRegisteredName(const DNSName
& dom
)
1373 auto parts
=dom
.getRawLabels();
1376 reverse(parts
.begin(), parts
.end());
1377 for(string
& str
: parts
) { str
=toLower(str
); };
1381 while(!parts
.empty()) {
1382 if(parts
.size()==1 || binary_search(g_pubs
.begin(), g_pubs
.end(), parts
)) {
1388 for(auto p
= parts
.crbegin(); p
!= parts
.crend(); ++p
) {
1391 return DNSName(ret
);
1394 last
=parts
[parts
.size()-1];
1395 parts
.resize(parts
.size()-1);
1397 return DNSName("??");
1400 static DNSName
nopFilter(const DNSName
& name
)
1405 string
doGenericTopQueries(pleasequeryfunc_t func
, boost::function
<DNSName(const DNSName
&)> filter
=nopFilter
)
1407 typedef pair
<DNSName
,uint16_t> query_t
;
1408 typedef map
<query_t
, int> counts_t
;
1410 vector
<query_t
> queries
=broadcastAccFunction
<vector
<query_t
> >(func
);
1412 unsigned int total
=0;
1413 for(const query_t
& q
: queries
) {
1415 counts
[make_pair(filter(q
.first
),q
.second
)]++;
1418 typedef std::multimap
<int, query_t
> rcounts_t
;
1421 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1422 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1425 ret
<<"Over last "<<total
<<" entries:\n";
1426 format
fmt("%.02f%%\t%s\n");
1427 int limit
=0, accounted
=0;
1429 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1430 ret
<< fmt
% (-100.0*i
->first
/total
) % (i
->second
.first
.toLogString()+"|"+DNSRecordContent::NumberToType(i
->second
.second
));
1431 accounted
+= -i
->first
;
1433 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1440 static string
* nopFunction()
1442 return new string("pong\n");
1445 static string
getDontThrottleNames() {
1446 auto dtn
= g_dontThrottleNames
.getLocal();
1447 return dtn
->toString() + "\n";
1450 static string
getDontThrottleNetmasks() {
1451 auto dtn
= g_dontThrottleNetmasks
.getLocal();
1452 return dtn
->toString() + "\n";
1455 template<typename T
>
1456 static string
addDontThrottleNames(T begin
, T end
) {
1458 return "No names specified, keeping existing list\n";
1460 vector
<DNSName
> toAdd
;
1461 while (begin
!= end
) {
1463 auto d
= DNSName(*begin
);
1466 catch(const std::exception
&e
) {
1467 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1472 string ret
= "Added";
1473 auto dnt
= g_dontThrottleNames
.getCopy();
1475 for (auto const &d
: toAdd
) {
1480 ret
+= " " + d
.toLogString();
1484 g_dontThrottleNames
.setState(std::move(dnt
));
1486 ret
+= " to the list of nameservers that may not be throttled";
1487 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1491 template<typename T
>
1492 static string
addDontThrottleNetmasks(T begin
, T end
) {
1494 return "No netmasks specified, keeping existing list\n";
1496 vector
<Netmask
> toAdd
;
1497 while (begin
!= end
) {
1499 auto n
= Netmask(*begin
);
1502 catch(const std::exception
&e
) {
1503 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1505 catch(const PDNSException
&e
) {
1506 return "Problem parsing '" + *begin
+ "': "+ e
.reason
+ ", nothing added\n";
1511 string ret
= "Added";
1512 auto dnt
= g_dontThrottleNetmasks
.getCopy();
1514 for (auto const &t
: toAdd
) {
1519 ret
+= " " + t
.toString();
1523 g_dontThrottleNetmasks
.setState(std::move(dnt
));
1525 ret
+= " to the list of nameserver netmasks that may not be throttled";
1526 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1530 template<typename T
>
1531 static string
clearDontThrottleNames(T begin
, T end
) {
1533 return "No names specified, doing nothing.\n";
1535 if (begin
+ 1 == end
&& *begin
== "*"){
1536 SuffixMatchNode smn
;
1537 g_dontThrottleNames
.setState(std::move(smn
));
1538 string ret
= "Cleared list of nameserver names that may not be throttled";
1539 g_log
<<Logger::Warning
<<ret
<<", requested via control channel"<<endl
;
1543 vector
<DNSName
> toRemove
;
1544 while (begin
!= end
) {
1546 if (*begin
== "*") {
1547 return "Please don't mix '*' with other names, nothing removed\n";
1549 toRemove
.push_back(DNSName(*begin
));
1551 catch (const std::exception
&e
) {
1552 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing removed\n";
1557 string ret
= "Removed";
1559 auto dnt
= g_dontThrottleNames
.getCopy();
1560 for (const auto &name
: toRemove
) {
1565 ret
+= " " + name
.toLogString();
1569 g_dontThrottleNames
.setState(std::move(dnt
));
1571 ret
+= " from the list of nameservers that may not be throttled";
1572 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1576 template<typename T
>
1577 static string
clearDontThrottleNetmasks(T begin
, T end
) {
1579 return "No netmasks specified, doing nothing.\n";
1581 if (begin
+ 1 == end
&& *begin
== "*"){
1582 auto nmg
= g_dontThrottleNetmasks
.getCopy();
1584 g_dontThrottleNetmasks
.setState(std::move(nmg
));
1586 string ret
= "Cleared list of nameserver addresses that may not be throttled";
1587 g_log
<<Logger::Warning
<<ret
<<", requested via control channel"<<endl
;
1591 std::vector
<Netmask
> toRemove
;
1592 while (begin
!= end
) {
1594 if (*begin
== "*") {
1595 return "Please don't mix '*' with other netmasks, nothing removed\n";
1597 auto n
= Netmask(*begin
);
1598 toRemove
.push_back(n
);
1600 catch(const std::exception
&e
) {
1601 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1603 catch(const PDNSException
&e
) {
1604 return "Problem parsing '" + *begin
+ "': "+ e
.reason
+ ", nothing added\n";
1609 string ret
= "Removed";
1611 auto dnt
= g_dontThrottleNetmasks
.getCopy();
1612 for (const auto &mask
: toRemove
) {
1617 ret
+= " " + mask
.toString();
1618 dnt
.deleteMask(mask
);
1621 g_dontThrottleNetmasks
.setState(std::move(dnt
));
1623 ret
+= " from the list of nameservers that may not be throttled";
1624 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1629 string
RecursorControlParser::getAnswer(const string
& question
, RecursorControlParser::func_t
** command
)
1632 vector
<string
> words
;
1633 stringtok(words
, question
);
1636 return "invalid command\n";
1638 string cmd
=toLower(words
[0]);
1639 vector
<string
>::const_iterator begin
=words
.begin()+1, end
=words
.end();
1641 // should probably have a smart dispatcher here, like auth has
1644 "add-dont-throttle-names [N...] add names that are not allowed to be throttled\n"
1645 "add-dont-throttle-netmasks [N...]\n"
1646 " add netmasks that are not allowed to be throttled\n"
1647 "add-nta DOMAIN [REASON] add a Negative Trust Anchor for DOMAIN with the comment REASON\n"
1648 "add-ta DOMAIN DSRECORD add a Trust Anchor for DOMAIN with data DSRECORD\n"
1649 "current-queries show currently active queries\n"
1650 "clear-dont-throttle-names [N...] remove names that are not allowed to be throttled. If N is '*', remove all\n"
1651 "clear-dont-throttle-netmasks [N...]\n"
1652 " remove netmasks that are not allowed to be throttled. If N is '*', remove all\n"
1653 "clear-nta [DOMAIN]... Clear the Negative Trust Anchor for DOMAINs, if no DOMAIN is specified, remove all\n"
1654 "clear-ta [DOMAIN]... Clear the Trust Anchor for DOMAINs\n"
1655 "dump-cache <filename> dump cache contents to the named file\n"
1656 "dump-edns [status] <filename> dump EDNS status to the named file\n"
1657 "dump-nsspeeds <filename> dump nsspeeds statistics to the named file\n"
1658 "dump-rpz <zone name> <filename> dump the content of a RPZ zone to the named file\n"
1659 "dump-throttlemap <filename> dump the contents of the throttle map to the named file\n"
1660 "dump-failedservers <filename> dump the failed servers to the named file\n"
1661 "get [key1] [key2] .. get specific statistics\n"
1662 "get-all get all statistics\n"
1663 "get-dont-throttle-names get the list of names that are not allowed to be throttled\n"
1664 "get-dont-throttle-netmasks get the list of netmasks that are not allowed to be throttled\n"
1665 "get-ntas get all configured Negative Trust Anchors\n"
1666 "get-tas get all configured Trust Anchors\n"
1667 "get-parameter [key1] [key2] .. get configuration parameters\n"
1668 "get-qtypelist get QType statistics\n"
1669 " notice: queries from cache aren't being counted yet\n"
1670 "help get this list\n"
1671 "ping check that all threads are alive\n"
1672 "quit stop the recursor daemon\n"
1673 "quit-nicely stop the recursor daemon nicely\n"
1674 "reload-acls reload ACLS\n"
1675 "reload-lua-script [filename] (re)load Lua script\n"
1676 "reload-lua-config [filename] (re)load Lua configuration file\n"
1677 "reload-zones reload all auth and forward zones\n"
1678 "set-ecs-minimum-ttl value set ecs-minimum-ttl-override\n"
1679 "set-max-cache-entries value set new maximum cache size\n"
1680 "set-max-packetcache-entries val set new maximum packet cache size\n"
1681 "set-minimum-ttl value set minimum-ttl-override\n"
1682 "set-carbon-server set a carbon server for telemetry\n"
1683 "set-dnssec-log-bogus SETTING enable (SETTING=yes) or disable (SETTING=no) logging of DNSSEC validation failures\n"
1684 "trace-regex [regex] emit resolution trace for matching queries (empty regex to clear trace)\n"
1685 "top-largeanswer-remotes show top remotes receiving large answers\n"
1686 "top-queries show top queries\n"
1687 "top-pub-queries show top queries grouped by public suffix list\n"
1688 "top-remotes show top remotes\n"
1689 "top-timeouts show top downstream timeouts\n"
1690 "top-servfail-queries show top queries receiving servfail answers\n"
1691 "top-bogus-queries show top queries validating as bogus\n"
1692 "top-pub-servfail-queries show top queries receiving servfail answers grouped by public suffix list\n"
1693 "top-pub-bogus-queries show top queries validating as bogus grouped by public suffix list\n"
1694 "top-servfail-remotes show top remotes receiving servfail answers\n"
1695 "top-bogus-remotes show top remotes receiving bogus answers\n"
1696 "unload-lua-script unload Lua script\n"
1697 "version return Recursor version number\n"
1698 "wipe-cache domain0 [domain1] .. wipe domain data from cache\n"
1699 "wipe-cache-typed type domain0 [domain1] .. wipe domain data with qtype from cache\n";
1702 return getAllStats();
1705 return doGet(begin
, end
);
1707 if(cmd
=="get-parameter")
1708 return doGetParameter(begin
, end
);
1715 if(cmd
=="version") {
1716 return getPDNSVersion()+"\n";
1719 if(cmd
=="quit-nicely") {
1720 *command
=&doExitNicely
;
1721 return "bye nicely\n";
1724 if(cmd
=="dump-cache")
1725 return doDumpCache(begin
, end
);
1727 if(cmd
=="dump-ednsstatus" || cmd
=="dump-edns")
1728 return doDumpEDNSStatus(begin
, end
);
1730 if(cmd
=="dump-nsspeeds")
1731 return doDumpNSSpeeds(begin
, end
);
1733 if(cmd
=="dump-failedservers")
1734 return doDumpFailedServers(begin
, end
);
1736 if(cmd
=="dump-rpz") {
1737 return doDumpRPZ(begin
, end
);
1740 if(cmd
=="dump-throttlemap")
1741 return doDumpThrottleMap(begin
, end
);
1743 if(cmd
=="wipe-cache" || cmd
=="flushname")
1744 return doWipeCache(begin
, end
, 0xffff);
1746 if(cmd
=="wipe-cache-typed") {
1747 uint16_t qtype
= QType::chartocode(begin
->c_str());
1749 return doWipeCache(begin
, end
, qtype
);
1752 if(cmd
=="reload-lua-script")
1753 return doQueueReloadLuaScript(begin
, end
);
1755 if(cmd
=="reload-lua-config") {
1757 ::arg().set("lua-config-file") = *begin
;
1760 luaConfigDelayedThreads delayedLuaThreads
;
1761 loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads
);
1762 startLuaConfigDelayedThreads(delayedLuaThreads
, g_luaconfs
.getCopy().generation
);
1763 g_log
<<Logger::Warning
<<"Reloaded Lua configuration file '"<<::arg()["lua-config-file"]<<"', requested via control channel"<<endl
;
1764 return "Reloaded Lua configuration file '"+::arg()["lua-config-file"]+"'\n";
1766 catch(std::exception
& e
) {
1767 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.what()+"\n";
1769 catch(const PDNSException
& e
) {
1770 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.reason
+"\n";
1774 if(cmd
=="set-carbon-server")
1775 return doSetCarbonServer(begin
, end
);
1777 if(cmd
=="trace-regex")
1778 return doTraceRegex(begin
, end
);
1780 if(cmd
=="unload-lua-script") {
1781 vector
<string
> empty
;
1782 empty
.push_back(string());
1783 return doQueueReloadLuaScript(empty
.begin(), empty
.end());
1786 if(cmd
=="reload-acls") {
1787 if(!::arg()["chroot"].empty()) {
1788 g_log
<<Logger::Error
<<"Unable to reload ACL when chroot()'ed, requested via control channel"<<endl
;
1789 return "Unable to reload ACL when chroot()'ed, please restart\n";
1795 catch(std::exception
& e
)
1797 g_log
<<Logger::Error
<<"Reloading ACLs failed (Exception: "<<e
.what()<<")"<<endl
;
1798 return e
.what() + string("\n");
1800 catch(PDNSException
& ae
)
1802 g_log
<<Logger::Error
<<"Reloading ACLs failed (PDNSException: "<<ae
.reason
<<")"<<endl
;
1803 return ae
.reason
+ string("\n");
1809 if(cmd
=="top-remotes")
1810 return doGenericTopRemotes(pleaseGetRemotes
);
1812 if(cmd
=="top-queries")
1813 return doGenericTopQueries(pleaseGetQueryRing
);
1815 if(cmd
=="top-pub-queries")
1816 return doGenericTopQueries(pleaseGetQueryRing
, getRegisteredName
);
1818 if(cmd
=="top-servfail-queries")
1819 return doGenericTopQueries(pleaseGetServfailQueryRing
);
1821 if(cmd
=="top-pub-servfail-queries")
1822 return doGenericTopQueries(pleaseGetServfailQueryRing
, getRegisteredName
);
1824 if(cmd
=="top-bogus-queries")
1825 return doGenericTopQueries(pleaseGetBogusQueryRing
);
1827 if(cmd
=="top-pub-bogus-queries")
1828 return doGenericTopQueries(pleaseGetBogusQueryRing
, getRegisteredName
);
1831 if(cmd
=="top-servfail-remotes")
1832 return doGenericTopRemotes(pleaseGetServfailRemotes
);
1834 if(cmd
=="top-bogus-remotes")
1835 return doGenericTopRemotes(pleaseGetBogusRemotes
);
1837 if(cmd
=="top-largeanswer-remotes")
1838 return doGenericTopRemotes(pleaseGetLargeAnswerRemotes
);
1840 if(cmd
=="top-timeouts")
1841 return doGenericTopRemotes(pleaseGetTimeouts
);
1844 if(cmd
=="current-queries")
1845 return doCurrentQueries();
1848 return broadcastAccFunction
<string
>(nopFunction
);
1851 if(cmd
=="reload-zones") {
1852 if(!::arg()["chroot"].empty()) {
1853 g_log
<<Logger::Error
<<"Unable to reload zones and forwards when chroot()'ed, requested via control channel"<<endl
;
1854 return "Unable to reload zones and forwards when chroot()'ed, please restart\n";
1856 return reloadAuthAndForwards();
1859 if(cmd
=="set-ecs-minimum-ttl") {
1860 return setMinimumECSTTL(begin
, end
);
1863 if(cmd
=="set-max-cache-entries") {
1864 return setMaxCacheEntries(begin
, end
);
1866 if(cmd
=="set-max-packetcache-entries") {
1867 return setMaxPacketCacheEntries(begin
, end
);
1870 if(cmd
=="set-minimum-ttl") {
1871 return setMinimumTTL(begin
, end
);
1874 if(cmd
=="get-qtypelist") {
1875 return g_rs
.getQTypeReport();
1878 if(cmd
=="add-nta") {
1879 return doAddNTA(begin
, end
);
1882 if(cmd
=="clear-nta") {
1883 return doClearNTA(begin
, end
);
1886 if(cmd
=="get-ntas") {
1891 return doAddTA(begin
, end
);
1894 if(cmd
=="clear-ta") {
1895 return doClearTA(begin
, end
);
1898 if(cmd
=="get-tas") {
1902 if (cmd
=="set-dnssec-log-bogus")
1903 return doSetDnssecLogBogus(begin
, end
);
1905 if (cmd
== "get-dont-throttle-names") {
1906 return getDontThrottleNames();
1909 if (cmd
== "get-dont-throttle-netmasks") {
1910 return getDontThrottleNetmasks();
1913 if (cmd
== "add-dont-throttle-names") {
1914 return addDontThrottleNames(begin
, end
);
1917 if (cmd
== "add-dont-throttle-netmasks") {
1918 return addDontThrottleNetmasks(begin
, end
);
1921 if (cmd
== "clear-dont-throttle-names") {
1922 return clearDontThrottleNames(begin
, end
);
1925 if (cmd
== "clear-dont-throttle-netmasks") {
1926 return clearDontThrottleNetmasks(begin
, end
);
1929 return "Unknown command '"+cmd
+"', try 'help'\n";