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
)
399 return new uint64_t(t_RC
->doWipeCache(canon
, subtree
));
402 uint64_t* pleaseWipePacketCache(const DNSName
& canon
, bool subtree
)
404 return new uint64_t(t_packetCache
->doWipePacketCache(canon
,0xffff, 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
)
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
));
439 pcount
+= broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, wipe
.first
, wipe
.second
));
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));
542 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, who
, true));
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));
590 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, entry
, true));
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));
647 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, who
, true));
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));
693 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, entry
, true));
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
);
1165 for(unsigned int n
=0; n
< g_numThreads
; ++n
)
1166 addGetStat("cpu-msec-thread-"+std::to_string(n
), boost::bind(&doGetThreadCPUMsec
, n
));
1169 addGetStat("memory-allocs", boost::bind(&MallocTracer::getAllocs
, g_mtracer
, string()));
1170 addGetStat("memory-alloc-flux", boost::bind(&MallocTracer::getAllocFlux
, g_mtracer
, string()));
1171 addGetStat("memory-allocated", boost::bind(&MallocTracer::getTotAllocated
, g_mtracer
, string()));
1174 addGetStat("dnssec-validations", &g_stats
.dnssecValidations
);
1175 addGetStat("dnssec-result-insecure", &g_stats
.dnssecResults
[Insecure
]);
1176 addGetStat("dnssec-result-secure", &g_stats
.dnssecResults
[Secure
]);
1177 addGetStat("dnssec-result-bogus", &g_stats
.dnssecResults
[Bogus
]);
1178 addGetStat("dnssec-result-indeterminate", &g_stats
.dnssecResults
[Indeterminate
]);
1179 addGetStat("dnssec-result-nta", &g_stats
.dnssecResults
[NTA
]);
1181 addGetStat("policy-result-noaction", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NoAction
]);
1182 addGetStat("policy-result-drop", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Drop
]);
1183 addGetStat("policy-result-nxdomain", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NXDOMAIN
]);
1184 addGetStat("policy-result-nodata", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NODATA
]);
1185 addGetStat("policy-result-truncate", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Truncate
]);
1186 addGetStat("policy-result-custom", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Custom
]);
1188 addGetStat("rebalanced-queries", &g_stats
.rebalancedQueries
);
1190 /* make sure that the ECS stats are properly initialized */
1191 SyncRes::clearECSStats();
1192 for (size_t idx
= 0; idx
< SyncRes::s_ecsResponsesBySubnetSize4
.size(); idx
++) {
1193 const std::string name
= "ecs-v4-response-bits-" + std::to_string(idx
+ 1);
1194 addGetStat(name
, &(SyncRes::s_ecsResponsesBySubnetSize4
.at(idx
)));
1196 for (size_t idx
= 0; idx
< SyncRes::s_ecsResponsesBySubnetSize6
.size(); idx
++) {
1197 const std::string name
= "ecs-v6-response-bits-" + std::to_string(idx
+ 1);
1198 addGetStat(name
, &(SyncRes::s_ecsResponsesBySubnetSize6
.at(idx
)));
1202 void doExitGeneric(bool nicely
)
1204 g_log
<<Logger::Error
<<"Exiting on user request"<<endl
;
1205 extern RecursorControlChannel s_rcc
;
1206 s_rcc
.~RecursorControlChannel();
1208 extern string s_pidfname
;
1209 if(!s_pidfname
.empty())
1210 unlink(s_pidfname
.c_str()); // we can at least try..
1212 RecursorControlChannel::stop
= 1;
1220 doExitGeneric(false);
1225 doExitGeneric(true);
1228 vector
<pair
<DNSName
, uint16_t> >* pleaseGetQueryRing()
1230 typedef pair
<DNSName
,uint16_t> query_t
;
1231 vector
<query_t
>* ret
= new vector
<query_t
>();
1234 ret
->reserve(t_queryring
->size());
1236 for(const query_t
& q
: *t_queryring
) {
1241 vector
<pair
<DNSName
,uint16_t> >* pleaseGetServfailQueryRing()
1243 typedef pair
<DNSName
,uint16_t> query_t
;
1244 vector
<query_t
>* ret
= new vector
<query_t
>();
1245 if(!t_servfailqueryring
)
1247 ret
->reserve(t_servfailqueryring
->size());
1248 for(const query_t
& q
: *t_servfailqueryring
) {
1253 vector
<pair
<DNSName
,uint16_t> >* pleaseGetBogusQueryRing()
1255 typedef pair
<DNSName
,uint16_t> query_t
;
1256 vector
<query_t
>* ret
= new vector
<query_t
>();
1257 if(!t_bogusqueryring
)
1259 ret
->reserve(t_bogusqueryring
->size());
1260 for(const query_t
& q
: *t_bogusqueryring
) {
1268 typedef boost::function
<vector
<ComboAddress
>*()> pleaseremotefunc_t
;
1269 typedef boost::function
<vector
<pair
<DNSName
,uint16_t> >*()> pleasequeryfunc_t
;
1271 vector
<ComboAddress
>* pleaseGetRemotes()
1273 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1277 ret
->reserve(t_remotes
->size());
1278 for(const ComboAddress
& ca
: *t_remotes
) {
1284 vector
<ComboAddress
>* pleaseGetServfailRemotes()
1286 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1287 if(!t_servfailremotes
)
1289 ret
->reserve(t_servfailremotes
->size());
1290 for(const ComboAddress
& ca
: *t_servfailremotes
) {
1296 vector
<ComboAddress
>* pleaseGetBogusRemotes()
1298 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1301 ret
->reserve(t_bogusremotes
->size());
1302 for(const ComboAddress
& ca
: *t_bogusremotes
) {
1308 vector
<ComboAddress
>* pleaseGetLargeAnswerRemotes()
1310 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1311 if(!t_largeanswerremotes
)
1313 ret
->reserve(t_largeanswerremotes
->size());
1314 for(const ComboAddress
& ca
: *t_largeanswerremotes
) {
1320 vector
<ComboAddress
>* pleaseGetTimeouts()
1322 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1325 ret
->reserve(t_timeouts
->size());
1326 for(const ComboAddress
& ca
: *t_timeouts
) {
1332 string
doGenericTopRemotes(pleaseremotefunc_t func
)
1334 typedef map
<ComboAddress
, int, ComboAddress::addressOnlyLessThan
> counts_t
;
1337 vector
<ComboAddress
> remotes
=broadcastAccFunction
<vector
<ComboAddress
> >(func
);
1339 unsigned int total
=0;
1340 for(const ComboAddress
& ca
: remotes
) {
1345 typedef std::multimap
<int, ComboAddress
> rcounts_t
;
1348 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1349 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1352 ret
<<"Over last "<<total
<<" entries:\n";
1353 format
fmt("%.02f%%\t%s\n");
1354 int limit
=0, accounted
=0;
1356 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1357 ret
<< fmt
% (-100.0*i
->first
/total
) % i
->second
.toString();
1358 accounted
+= -i
->first
;
1360 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1365 // XXX DNSName Pain - this function should benefit from native DNSName methods
1366 DNSName
getRegisteredName(const DNSName
& dom
)
1368 auto parts
=dom
.getRawLabels();
1371 reverse(parts
.begin(), parts
.end());
1372 for(string
& str
: parts
) { str
=toLower(str
); };
1376 while(!parts
.empty()) {
1377 if(parts
.size()==1 || binary_search(g_pubs
.begin(), g_pubs
.end(), parts
)) {
1383 for(auto p
= parts
.crbegin(); p
!= parts
.crend(); ++p
) {
1386 return DNSName(ret
);
1389 last
=parts
[parts
.size()-1];
1390 parts
.resize(parts
.size()-1);
1392 return DNSName("??");
1395 static DNSName
nopFilter(const DNSName
& name
)
1400 string
doGenericTopQueries(pleasequeryfunc_t func
, boost::function
<DNSName(const DNSName
&)> filter
=nopFilter
)
1402 typedef pair
<DNSName
,uint16_t> query_t
;
1403 typedef map
<query_t
, int> counts_t
;
1405 vector
<query_t
> queries
=broadcastAccFunction
<vector
<query_t
> >(func
);
1407 unsigned int total
=0;
1408 for(const query_t
& q
: queries
) {
1410 counts
[make_pair(filter(q
.first
),q
.second
)]++;
1413 typedef std::multimap
<int, query_t
> rcounts_t
;
1416 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1417 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1420 ret
<<"Over last "<<total
<<" entries:\n";
1421 format
fmt("%.02f%%\t%s\n");
1422 int limit
=0, accounted
=0;
1424 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1425 ret
<< fmt
% (-100.0*i
->first
/total
) % (i
->second
.first
.toLogString()+"|"+DNSRecordContent::NumberToType(i
->second
.second
));
1426 accounted
+= -i
->first
;
1428 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1435 static string
* nopFunction()
1437 return new string("pong\n");
1440 static string
getDontThrottleNames() {
1441 auto dtn
= g_dontThrottleNames
.getLocal();
1442 return dtn
->toString() + "\n";
1445 static string
getDontThrottleNetmasks() {
1446 auto dtn
= g_dontThrottleNetmasks
.getLocal();
1447 return dtn
->toString() + "\n";
1450 template<typename T
>
1451 static string
addDontThrottleNames(T begin
, T end
) {
1453 return "No names specified, keeping existing list\n";
1455 vector
<DNSName
> toAdd
;
1456 while (begin
!= end
) {
1458 auto d
= DNSName(*begin
);
1461 catch(const std::exception
&e
) {
1462 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1467 string ret
= "Added";
1468 auto dnt
= g_dontThrottleNames
.getCopy();
1470 for (auto const &d
: toAdd
) {
1475 ret
+= " " + d
.toLogString();
1479 g_dontThrottleNames
.setState(dnt
);
1481 ret
+= " to the list of nameservers that may not be throttled";
1482 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1486 template<typename T
>
1487 static string
addDontThrottleNetmasks(T begin
, T end
) {
1489 return "No netmasks specified, keeping existing list\n";
1491 vector
<Netmask
> toAdd
;
1492 while (begin
!= end
) {
1494 auto n
= Netmask(*begin
);
1497 catch(const std::exception
&e
) {
1498 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1500 catch(const PDNSException
&e
) {
1501 return "Problem parsing '" + *begin
+ "': "+ e
.reason
+ ", nothing added\n";
1506 string ret
= "Added";
1507 auto dnt
= g_dontThrottleNetmasks
.getCopy();
1509 for (auto const &t
: toAdd
) {
1514 ret
+= " " + t
.toString();
1518 g_dontThrottleNetmasks
.setState(dnt
);
1520 ret
+= " to the list of nameserver netmasks that may not be throttled";
1521 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1525 template<typename T
>
1526 static string
clearDontThrottleNames(T begin
, T end
) {
1528 return "No names specified, doing nothing.\n";
1530 if (begin
+ 1 == end
&& *begin
== "*"){
1531 SuffixMatchNode smn
;
1532 g_dontThrottleNames
.setState(smn
);
1533 string ret
= "Cleared list of nameserver names that may not be throttled";
1534 g_log
<<Logger::Warning
<<ret
<<", requested via control channel"<<endl
;
1538 vector
<DNSName
> toRemove
;
1539 while (begin
!= end
) {
1541 if (*begin
== "*") {
1542 return "Please don't mix '*' with other names, nothing removed\n";
1544 toRemove
.push_back(DNSName(*begin
));
1546 catch (const std::exception
&e
) {
1547 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing removed\n";
1552 string ret
= "Removed";
1554 auto dnt
= g_dontThrottleNames
.getCopy();
1555 for (const auto &name
: toRemove
) {
1560 ret
+= " " + name
.toLogString();
1564 g_dontThrottleNames
.setState(dnt
);
1566 ret
+= " from the list of nameservers that may not be throttled";
1567 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1571 template<typename T
>
1572 static string
clearDontThrottleNetmasks(T begin
, T end
) {
1574 return "No netmasks specified, doing nothing.\n";
1576 if (begin
+ 1 == end
&& *begin
== "*"){
1577 auto nmg
= g_dontThrottleNetmasks
.getCopy();
1579 g_dontThrottleNetmasks
.setState(nmg
);
1581 string ret
= "Cleared list of nameserver addresses that may not be throttled";
1582 g_log
<<Logger::Warning
<<ret
<<", requested via control channel"<<endl
;
1586 std::vector
<Netmask
> toRemove
;
1587 while (begin
!= end
) {
1589 if (*begin
== "*") {
1590 return "Please don't mix '*' with other netmasks, nothing removed\n";
1592 auto n
= Netmask(*begin
);
1593 toRemove
.push_back(n
);
1595 catch(const std::exception
&e
) {
1596 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1598 catch(const PDNSException
&e
) {
1599 return "Problem parsing '" + *begin
+ "': "+ e
.reason
+ ", nothing added\n";
1604 string ret
= "Removed";
1606 auto dnt
= g_dontThrottleNetmasks
.getCopy();
1607 for (const auto &mask
: toRemove
) {
1612 ret
+= " " + mask
.toString();
1613 dnt
.deleteMask(mask
);
1616 g_dontThrottleNetmasks
.setState(dnt
);
1618 ret
+= " from the list of nameservers that may not be throttled";
1619 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1624 string
RecursorControlParser::getAnswer(const string
& question
, RecursorControlParser::func_t
** command
)
1627 vector
<string
> words
;
1628 stringtok(words
, question
);
1631 return "invalid command\n";
1633 string cmd
=toLower(words
[0]);
1634 vector
<string
>::const_iterator begin
=words
.begin()+1, end
=words
.end();
1636 // should probably have a smart dispatcher here, like auth has
1639 "add-dont-throttle-names [N...] add names that are not allowed to be throttled\n"
1640 "add-dont-throttle-netmasks [N...]\n"
1641 " add netmasks that are not allowed to be throttled\n"
1642 "add-nta DOMAIN [REASON] add a Negative Trust Anchor for DOMAIN with the comment REASON\n"
1643 "add-ta DOMAIN DSRECORD add a Trust Anchor for DOMAIN with data DSRECORD\n"
1644 "current-queries show currently active queries\n"
1645 "clear-dont-throttle-names [N...] remove names that are not allowed to be throttled. If N is '*', remove all\n"
1646 "clear-dont-throttle-netmasks [N...]\n"
1647 " remove netmasks that are not allowed to be throttled. If N is '*', remove all\n"
1648 "clear-nta [DOMAIN]... Clear the Negative Trust Anchor for DOMAINs, if no DOMAIN is specified, remove all\n"
1649 "clear-ta [DOMAIN]... Clear the Trust Anchor for DOMAINs\n"
1650 "dump-cache <filename> dump cache contents to the named file\n"
1651 "dump-edns [status] <filename> dump EDNS status to the named file\n"
1652 "dump-nsspeeds <filename> dump nsspeeds statistics to the named file\n"
1653 "dump-rpz <zone name> <filename> dump the content of a RPZ zone to the named file\n"
1654 "dump-throttlemap <filename> dump the contents of the throttle map to the named file\n"
1655 "dump-failedservers <filename> dump the failed servers to the named file\n"
1656 "get [key1] [key2] .. get specific statistics\n"
1657 "get-all get all statistics\n"
1658 "get-dont-throttle-names get the list of names that are not allowed to be throttled\n"
1659 "get-dont-throttle-netmasks get the list of netmasks that are not allowed to be throttled\n"
1660 "get-ntas get all configured Negative Trust Anchors\n"
1661 "get-tas get all configured Trust Anchors\n"
1662 "get-parameter [key1] [key2] .. get configuration parameters\n"
1663 "get-qtypelist get QType statistics\n"
1664 " notice: queries from cache aren't being counted yet\n"
1665 "help get this list\n"
1666 "ping check that all threads are alive\n"
1667 "quit stop the recursor daemon\n"
1668 "quit-nicely stop the recursor daemon nicely\n"
1669 "reload-acls reload ACLS\n"
1670 "reload-lua-script [filename] (re)load Lua script\n"
1671 "reload-lua-config [filename] (re)load Lua configuration file\n"
1672 "reload-zones reload all auth and forward zones\n"
1673 "set-ecs-minimum-ttl value set ecs-minimum-ttl-override\n"
1674 "set-max-cache-entries value set new maximum cache size\n"
1675 "set-max-packetcache-entries val set new maximum packet cache size\n"
1676 "set-minimum-ttl value set minimum-ttl-override\n"
1677 "set-carbon-server set a carbon server for telemetry\n"
1678 "set-dnssec-log-bogus SETTING enable (SETTING=yes) or disable (SETTING=no) logging of DNSSEC validation failures\n"
1679 "trace-regex [regex] emit resolution trace for matching queries (empty regex to clear trace)\n"
1680 "top-largeanswer-remotes show top remotes receiving large answers\n"
1681 "top-queries show top queries\n"
1682 "top-pub-queries show top queries grouped by public suffix list\n"
1683 "top-remotes show top remotes\n"
1684 "top-timeouts show top downstream timeouts\n"
1685 "top-servfail-queries show top queries receiving servfail answers\n"
1686 "top-bogus-queries show top queries validating as bogus\n"
1687 "top-pub-servfail-queries show top queries receiving servfail answers grouped by public suffix list\n"
1688 "top-pub-bogus-queries show top queries validating as bogus grouped by public suffix list\n"
1689 "top-servfail-remotes show top remotes receiving servfail answers\n"
1690 "top-bogus-remotes show top remotes receiving bogus answers\n"
1691 "unload-lua-script unload Lua script\n"
1692 "version return Recursor version number\n"
1693 "wipe-cache domain0 [domain1] .. wipe domain data from cache\n";
1696 return getAllStats();
1699 return doGet(begin
, end
);
1701 if(cmd
=="get-parameter")
1702 return doGetParameter(begin
, end
);
1709 if(cmd
=="version") {
1710 return getPDNSVersion()+"\n";
1713 if(cmd
=="quit-nicely") {
1714 *command
=&doExitNicely
;
1715 return "bye nicely\n";
1718 if(cmd
=="dump-cache")
1719 return doDumpCache(begin
, end
);
1721 if(cmd
=="dump-ednsstatus" || cmd
=="dump-edns")
1722 return doDumpEDNSStatus(begin
, end
);
1724 if(cmd
=="dump-nsspeeds")
1725 return doDumpNSSpeeds(begin
, end
);
1727 if(cmd
=="dump-failedservers")
1728 return doDumpFailedServers(begin
, end
);
1730 if(cmd
=="dump-rpz") {
1731 return doDumpRPZ(begin
, end
);
1734 if(cmd
=="dump-throttlemap")
1735 return doDumpThrottleMap(begin
, end
);
1737 if(cmd
=="wipe-cache" || cmd
=="flushname")
1738 return doWipeCache(begin
, end
);
1740 if(cmd
=="reload-lua-script")
1741 return doQueueReloadLuaScript(begin
, end
);
1743 if(cmd
=="reload-lua-config") {
1745 ::arg().set("lua-config-file") = *begin
;
1748 luaConfigDelayedThreads delayedLuaThreads
;
1749 loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads
);
1750 startLuaConfigDelayedThreads(delayedLuaThreads
, g_luaconfs
.getCopy().generation
);
1751 g_log
<<Logger::Warning
<<"Reloaded Lua configuration file '"<<::arg()["lua-config-file"]<<"', requested via control channel"<<endl
;
1752 return "Reloaded Lua configuration file '"+::arg()["lua-config-file"]+"'\n";
1754 catch(std::exception
& e
) {
1755 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.what()+"\n";
1757 catch(const PDNSException
& e
) {
1758 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.reason
+"\n";
1762 if(cmd
=="set-carbon-server")
1763 return doSetCarbonServer(begin
, end
);
1765 if(cmd
=="trace-regex")
1766 return doTraceRegex(begin
, end
);
1768 if(cmd
=="unload-lua-script") {
1769 vector
<string
> empty
;
1770 empty
.push_back(string());
1771 return doQueueReloadLuaScript(empty
.begin(), empty
.end());
1774 if(cmd
=="reload-acls") {
1775 if(!::arg()["chroot"].empty()) {
1776 g_log
<<Logger::Error
<<"Unable to reload ACL when chroot()'ed, requested via control channel"<<endl
;
1777 return "Unable to reload ACL when chroot()'ed, please restart\n";
1783 catch(std::exception
& e
)
1785 g_log
<<Logger::Error
<<"Reloading ACLs failed (Exception: "<<e
.what()<<")"<<endl
;
1786 return e
.what() + string("\n");
1788 catch(PDNSException
& ae
)
1790 g_log
<<Logger::Error
<<"Reloading ACLs failed (PDNSException: "<<ae
.reason
<<")"<<endl
;
1791 return ae
.reason
+ string("\n");
1797 if(cmd
=="top-remotes")
1798 return doGenericTopRemotes(pleaseGetRemotes
);
1800 if(cmd
=="top-queries")
1801 return doGenericTopQueries(pleaseGetQueryRing
);
1803 if(cmd
=="top-pub-queries")
1804 return doGenericTopQueries(pleaseGetQueryRing
, getRegisteredName
);
1806 if(cmd
=="top-servfail-queries")
1807 return doGenericTopQueries(pleaseGetServfailQueryRing
);
1809 if(cmd
=="top-pub-servfail-queries")
1810 return doGenericTopQueries(pleaseGetServfailQueryRing
, getRegisteredName
);
1812 if(cmd
=="top-bogus-queries")
1813 return doGenericTopQueries(pleaseGetBogusQueryRing
);
1815 if(cmd
=="top-pub-bogus-queries")
1816 return doGenericTopQueries(pleaseGetBogusQueryRing
, getRegisteredName
);
1819 if(cmd
=="top-servfail-remotes")
1820 return doGenericTopRemotes(pleaseGetServfailRemotes
);
1822 if(cmd
=="top-bogus-remotes")
1823 return doGenericTopRemotes(pleaseGetBogusRemotes
);
1825 if(cmd
=="top-largeanswer-remotes")
1826 return doGenericTopRemotes(pleaseGetLargeAnswerRemotes
);
1828 if(cmd
=="top-timeouts")
1829 return doGenericTopRemotes(pleaseGetTimeouts
);
1832 if(cmd
=="current-queries")
1833 return doCurrentQueries();
1836 return broadcastAccFunction
<string
>(nopFunction
);
1839 if(cmd
=="reload-zones") {
1840 if(!::arg()["chroot"].empty()) {
1841 g_log
<<Logger::Error
<<"Unable to reload zones and forwards when chroot()'ed, requested via control channel"<<endl
;
1842 return "Unable to reload zones and forwards when chroot()'ed, please restart\n";
1844 return reloadAuthAndForwards();
1847 if(cmd
=="set-ecs-minimum-ttl") {
1848 return setMinimumECSTTL(begin
, end
);
1851 if(cmd
=="set-max-cache-entries") {
1852 return setMaxCacheEntries(begin
, end
);
1854 if(cmd
=="set-max-packetcache-entries") {
1855 return setMaxPacketCacheEntries(begin
, end
);
1858 if(cmd
=="set-minimum-ttl") {
1859 return setMinimumTTL(begin
, end
);
1862 if(cmd
=="get-qtypelist") {
1863 return g_rs
.getQTypeReport();
1866 if(cmd
=="add-nta") {
1867 return doAddNTA(begin
, end
);
1870 if(cmd
=="clear-nta") {
1871 return doClearNTA(begin
, end
);
1874 if(cmd
=="get-ntas") {
1879 return doAddTA(begin
, end
);
1882 if(cmd
=="clear-ta") {
1883 return doClearTA(begin
, end
);
1886 if(cmd
=="get-tas") {
1890 if (cmd
=="set-dnssec-log-bogus")
1891 return doSetDnssecLogBogus(begin
, end
);
1893 if (cmd
== "get-dont-throttle-names") {
1894 return getDontThrottleNames();
1897 if (cmd
== "get-dont-throttle-netmasks") {
1898 return getDontThrottleNetmasks();
1901 if (cmd
== "add-dont-throttle-names") {
1902 return addDontThrottleNames(begin
, end
);
1905 if (cmd
== "add-dont-throttle-netmasks") {
1906 return addDontThrottleNetmasks(begin
, end
);
1909 if (cmd
== "clear-dont-throttle-names") {
1910 return clearDontThrottleNames(begin
, end
);
1913 if (cmd
== "clear-dont-throttle-netmasks") {
1914 return clearDontThrottleNetmasks(begin
, end
);
1917 return "Unknown command '"+cmd
+"', try 'help'\n";