5 #include "rec_channel.hh"
6 #include <boost/bind.hpp>
9 #include "malloctrace.hh"
12 #include "recursor_cache.hh"
14 #include "negcache.hh"
15 #include <boost/function.hpp>
16 #include <boost/optional.hpp>
17 #include <boost/tuple/tuple.hpp>
18 #include <boost/format.hpp>
19 #include <boost/algorithm/string.hpp>
22 #include <sys/types.h>
26 #include "dnsparser.hh"
27 #include "arguments.hh"
28 #include <sys/resource.h>
31 #include "responsestats.hh"
32 #include "rec-lua-conf.hh"
34 #include "validate-recursor.hh"
35 #include "filterpo.hh"
37 #include "secpoll-recursor.hh"
38 #include "pubsuffix.hh"
39 #include "namespaces.hh"
40 pthread_mutex_t g_carbon_config_lock
=PTHREAD_MUTEX_INITIALIZER
;
42 static map
<string
, const uint32_t*> d_get32bitpointers
;
43 static map
<string
, const std::atomic
<uint64_t>*> d_getatomics
;
44 static map
<string
, function
< uint64_t() > > d_get64bitmembers
;
45 static pthread_mutex_t d_dynmetricslock
= PTHREAD_MUTEX_INITIALIZER
;
46 static map
<string
, std::atomic
<unsigned long>* > d_dynmetrics
;
48 static std::map
<StatComponent
, std::set
<std::string
>> s_blacklistedStats
;
50 bool isStatBlacklisted(StatComponent component
, const string
& name
)
52 return s_blacklistedStats
[component
].count(name
) != 0;
55 void blacklistStat(StatComponent component
, const string
& name
)
57 s_blacklistedStats
[component
].insert(name
);
60 void blacklistStats(StatComponent component
, const string
& stats
)
62 std::vector
<std::string
> blacklistedStats
;
63 stringtok(blacklistedStats
, stats
, ", ");
64 auto& map
= s_blacklistedStats
[component
];
65 for (const auto &st
: blacklistedStats
) {
70 static void addGetStat(const string
& name
, const uint32_t* place
)
72 d_get32bitpointers
[name
]=place
;
75 static void addGetStat(const string
& name
, const std::atomic
<uint64_t>* place
)
77 d_getatomics
[name
]=place
;
80 static void addGetStat(const string
& name
, function
<uint64_t ()> f
)
82 d_get64bitmembers
[name
]=f
;
85 std::atomic
<unsigned long>* getDynMetric(const std::string
& str
)
87 Lock
l(&d_dynmetricslock
);
88 auto f
= d_dynmetrics
.find(str
);
89 if(f
!= d_dynmetrics
.end())
92 auto ret
= new std::atomic
<unsigned long>();
93 d_dynmetrics
[str
]= ret
;
97 static optional
<uint64_t> get(const string
& name
)
99 optional
<uint64_t> ret
;
101 if(d_get32bitpointers
.count(name
))
102 return *d_get32bitpointers
.find(name
)->second
;
103 if(d_getatomics
.count(name
))
104 return d_getatomics
.find(name
)->second
->load();
105 if(d_get64bitmembers
.count(name
))
106 return d_get64bitmembers
.find(name
)->second();
108 Lock
l(&d_dynmetricslock
);
109 auto f
=rplookup(d_dynmetrics
, name
);
116 optional
<uint64_t> getStatByName(const std::string
& name
)
121 map
<string
,string
> getAllStatsMap(StatComponent component
)
123 map
<string
,string
> ret
;
124 const auto& blacklistMap
= s_blacklistedStats
.at(component
);
126 for(const auto& the32bits
: d_get32bitpointers
) {
127 if (blacklistMap
.count(the32bits
.first
) == 0) {
128 ret
.insert(make_pair(the32bits
.first
, std::to_string(*the32bits
.second
)));
131 for(const auto& atomic
: d_getatomics
) {
132 if (blacklistMap
.count(atomic
.first
) == 0) {
133 ret
.insert(make_pair(atomic
.first
, std::to_string(atomic
.second
->load())));
137 for(const auto& the64bitmembers
: d_get64bitmembers
) {
138 if (blacklistMap
.count(the64bitmembers
.first
) == 0) {
139 ret
.insert(make_pair(the64bitmembers
.first
, std::to_string(the64bitmembers
.second())));
144 Lock
l(&d_dynmetricslock
);
145 for(const auto& a
: d_dynmetrics
) {
146 if (blacklistMap
.count(a
.first
) == 0) {
147 ret
.insert({a
.first
, std::to_string(*a
.second
)});
155 static string
getAllStats()
157 typedef map
<string
, string
> varmap_t
;
158 varmap_t varmap
= getAllStatsMap(StatComponent::RecControl
);
160 for(varmap_t::value_type
& tup
: varmap
) {
161 ret
+= tup
.first
+ "\t" + tup
.second
+"\n";
167 static string
doGet(T begin
, T end
)
171 for(T i
=begin
; i
!= end
; ++i
) {
172 optional
<uint64_t> num
=get(*i
);
174 ret
+=std::to_string(*num
)+"\n";
182 string
static doGetParameter(T begin
, T end
)
186 using boost::replace_all
;
187 for(T i
=begin
; i
!= end
; ++i
) {
188 if(::arg().parmIsset(*i
)) {
190 replace_all(parm
, "\\", "\\\\");
191 replace_all(parm
, "\"", "\\\"");
192 replace_all(parm
, "\n", "\\n");
193 ret
+= *i
+"=\""+ parm
+"\"\n";
196 ret
+= *i
+" not known\n";
202 static uint64_t dumpNegCache(NegCache
& negcache
, int fd
)
204 auto fp
= std::unique_ptr
<FILE, int(*)(FILE*)>(fdopen(dup(fd
), "w"), fclose
);
205 if(!fp
) { // dup probably failed
209 fprintf(fp
.get(), "; negcache dump from thread follows\n;\n");
210 ret
= negcache
.dumpToFile(fp
.get());
214 static uint64_t* pleaseDump(int fd
)
216 return new uint64_t(t_RC
->doDump(fd
) + dumpNegCache(SyncRes::t_sstorage
.negcache
, fd
) + t_packetCache
->doDump(fd
));
219 static uint64_t* pleaseDumpEDNSMap(int fd
)
221 return new uint64_t(SyncRes::doEDNSDump(fd
));
224 static uint64_t* pleaseDumpNSSpeeds(int fd
)
226 return new uint64_t(SyncRes::doDumpNSSpeeds(fd
));
229 static uint64_t* pleaseDumpThrottleMap(int fd
)
231 return new uint64_t(SyncRes::doDumpThrottleMap(fd
));
235 static string
doDumpNSSpeeds(T begin
, T end
)
243 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
245 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
248 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpNSSpeeds
, fd
));
250 catch(std::exception
& e
)
253 return "error dumping NS speeds: "+string(e
.what())+"\n";
255 catch(PDNSException
& e
)
258 return "error dumping NS speeds: "+e
.reason
+"\n";
262 return "dumped "+std::to_string(total
)+" records\n";
266 static string
doDumpCache(T begin
, T end
)
274 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
276 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
279 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDump
, fd
));
284 return "dumped "+std::to_string(total
)+" records\n";
288 static string
doDumpEDNSStatus(T begin
, T end
)
296 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
298 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
301 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpEDNSMap
, fd
));
306 return "dumped "+std::to_string(total
)+" records\n";
310 static string
doDumpRPZ(T begin
, T end
)
315 return "No zone name specified\n";
317 string zoneName
= *i
;
321 return "No file name specified\n";
325 auto luaconf
= g_luaconfs
.getLocal();
326 const auto zone
= luaconf
->dfe
.getZone(zoneName
);
328 return "No RPZ zone named "+zoneName
+"\n";
331 int fd
= open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
334 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
337 auto fp
= std::unique_ptr
<FILE, int(*)(FILE*)>(fdopen(fd
, "w"), fclose
);
340 return "Error converting file descriptor: "+string(strerror(errno
))+"\n";
343 zone
->dump(fp
.get());
349 static string
doDumpThrottleMap(T begin
, T end
)
357 int fd
=open(fname
.c_str(), O_CREAT
| O_EXCL
| O_WRONLY
, 0660);
359 return "Error opening dump file for writing: "+string(strerror(errno
))+"\n";
362 total
= broadcastAccFunction
<uint64_t>(boost::bind(pleaseDumpThrottleMap
, fd
));
367 return "dumped "+std::to_string(total
)+" records\n";
370 uint64_t* pleaseWipeCache(const DNSName
& canon
, bool subtree
)
372 return new uint64_t(t_RC
->doWipeCache(canon
, subtree
));
375 uint64_t* pleaseWipePacketCache(const DNSName
& canon
, bool subtree
)
377 return new uint64_t(t_packetCache
->doWipePacketCache(canon
,0xffff, subtree
));
381 uint64_t* pleaseWipeAndCountNegCache(const DNSName
& canon
, bool subtree
)
383 uint64_t ret
= SyncRes::wipeNegCache(canon
, subtree
);
384 return new uint64_t(ret
);
389 static string
doWipeCache(T begin
, T end
)
391 vector
<pair
<DNSName
, bool> > toWipe
;
392 for(T i
=begin
; i
!= end
; ++i
) {
397 if(boost::ends_with(*i
, "$")) {
398 canon
=DNSName(i
->substr(0, i
->size()-1));
403 } catch (std::exception
&e
) {
404 return "Error: " + std::string(e
.what()) + ", nothing wiped\n";
406 toWipe
.push_back({canon
, subtree
});
409 int count
=0, pcount
=0, countNeg
=0;
410 for (auto wipe
: toWipe
) {
411 count
+= broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, wipe
.first
, wipe
.second
));
412 pcount
+= broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, wipe
.first
, wipe
.second
));
413 countNeg
+=broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, wipe
.first
, wipe
.second
));
416 return "wiped "+std::to_string(count
)+" records, "+std::to_string(countNeg
)+" negative records, "+std::to_string(pcount
)+" packets\n";
420 static string
doSetCarbonServer(T begin
, T end
)
422 Lock
l(&g_carbon_config_lock
);
424 ::arg().set("carbon-server").clear();
425 return "cleared carbon-server setting\n";
428 ::arg().set("carbon-server")=*begin
;
429 ret
="set carbon-server to '"+::arg()["carbon-server"]+"'\n";
432 ::arg().set("carbon-ourname")=*begin
;
433 ret
+="set carbon-ourname to '"+*begin
+"'\n";
439 ::arg().set("carbon-namespace")=*begin
;
440 ret
+="set carbon-namespace to '"+*begin
+"'\n";
446 ::arg().set("carbon-instance")=*begin
;
447 ret
+="set carbon-instance to '"+*begin
+"'\n";
453 static string
doSetDnssecLogBogus(T begin
, T end
)
455 if(checkDNSSECDisabled())
456 return "DNSSEC is disabled in the configuration, not changing the Bogus logging setting\n";
459 return "No DNSSEC Bogus logging setting specified\n";
461 if (pdns_iequals(*begin
, "on") || pdns_iequals(*begin
, "yes")) {
462 if (!g_dnssecLogBogus
) {
463 g_log
<<Logger::Warning
<<"Enabling DNSSEC Bogus logging, requested via control channel"<<endl
;
464 g_dnssecLogBogus
= true;
465 return "DNSSEC Bogus logging enabled\n";
467 return "DNSSEC Bogus logging was already enabled\n";
470 if (pdns_iequals(*begin
, "off") || pdns_iequals(*begin
, "no")) {
471 if (g_dnssecLogBogus
) {
472 g_log
<<Logger::Warning
<<"Disabling DNSSEC Bogus logging, requested via control channel"<<endl
;
473 g_dnssecLogBogus
= false;
474 return "DNSSEC Bogus logging disabled\n";
476 return "DNSSEC Bogus logging was already disabled\n";
479 return "Unknown DNSSEC Bogus setting: '" + *begin
+"'\n";
483 static string
doAddNTA(T begin
, T end
)
485 if(checkDNSSECDisabled())
486 return "DNSSEC is disabled in the configuration, not adding a Negative Trust Anchor\n";
489 return "No NTA specified, doing nothing\n";
493 who
= DNSName(*begin
);
495 catch(std::exception
&e
) {
496 string
ret("Can't add Negative Trust Anchor: ");
504 while (begin
!= end
) {
510 g_log
<<Logger::Warning
<<"Adding Negative Trust Anchor for "<<who
<<" with reason '"<<why
<<"', requested via control channel"<<endl
;
511 g_luaconfs
.modify([who
, why
](LuaConfigItems
& lci
) {
512 lci
.negAnchors
[who
] = why
;
514 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, who
, true));
515 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, who
, true));
516 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, who
, true));
517 return "Added Negative Trust Anchor for " + who
.toLogString() + " with reason '" + why
+ "'\n";
521 static string
doClearNTA(T begin
, T end
)
523 if(checkDNSSECDisabled())
524 return "DNSSEC is disabled in the configuration, not removing a Negative Trust Anchor\n";
527 return "No Negative Trust Anchor specified, doing nothing.\n";
529 if (begin
+ 1 == end
&& *begin
== "*"){
530 g_log
<<Logger::Warning
<<"Clearing all Negative Trust Anchors, requested via control channel"<<endl
;
531 g_luaconfs
.modify([](LuaConfigItems
& lci
) {
532 lci
.negAnchors
.clear();
534 return "Cleared all Negative Trust Anchors.\n";
537 vector
<DNSName
> toRemove
;
539 while (begin
!= end
) {
541 return "Don't mix all Negative Trust Anchor removal with multiple Negative Trust Anchor removal. Nothing removed\n";
543 who
= DNSName(*begin
);
545 catch(std::exception
&e
) {
546 string
ret("Error: ");
548 ret
+= ". No Negative Anchors removed\n";
551 toRemove
.push_back(who
);
557 for (auto const &entry
: toRemove
) {
558 g_log
<<Logger::Warning
<<"Clearing Negative Trust Anchor for "<<entry
<<", requested via control channel"<<endl
;
559 g_luaconfs
.modify([entry
](LuaConfigItems
& lci
) {
560 lci
.negAnchors
.erase(entry
);
562 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, entry
, true));
563 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, entry
, true));
564 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, entry
, true));
569 removed
+= " " + entry
.toStringRootDot();
571 return "Removed Negative Trust Anchors for " + removed
+ "\n";
574 static string
getNTAs()
576 if(checkDNSSECDisabled())
577 return "DNSSEC is disabled in the configuration\n";
579 string
ret("Configured Negative Trust Anchors:\n");
580 auto luaconf
= g_luaconfs
.getLocal();
581 for (auto negAnchor
: luaconf
->negAnchors
)
582 ret
+= negAnchor
.first
.toLogString() + "\t" + negAnchor
.second
+ "\n";
587 static string
doAddTA(T begin
, T end
)
589 if(checkDNSSECDisabled())
590 return "DNSSEC is disabled in the configuration, not adding a Trust Anchor\n";
593 return "No TA specified, doing nothing\n";
597 who
= DNSName(*begin
);
599 catch(std::exception
&e
) {
600 string
ret("Can't add Trust Anchor: ");
608 while (begin
!= end
) {
609 what
+= *begin
+ " ";
614 g_log
<<Logger::Warning
<<"Adding Trust Anchor for "<<who
<<" with data '"<<what
<<"', requested via control channel";
615 g_luaconfs
.modify([who
, what
](LuaConfigItems
& lci
) {
616 auto ds
=std::dynamic_pointer_cast
<DSRecordContent
>(DSRecordContent::make(what
));
617 lci
.dsAnchors
[who
].insert(*ds
);
619 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, who
, true));
620 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, who
, true));
621 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, who
, true));
622 g_log
<<Logger::Warning
<<endl
;
623 return "Added Trust Anchor for " + who
.toStringRootDot() + " with data " + what
+ "\n";
625 catch(std::exception
&e
) {
626 g_log
<<Logger::Warning
<<", failed: "<<e
.what()<<endl
;
627 return "Unable to add Trust Anchor for " + who
.toStringRootDot() + ": " + e
.what() + "\n";
632 static string
doClearTA(T begin
, T end
)
634 if(checkDNSSECDisabled())
635 return "DNSSEC is disabled in the configuration, not removing a Trust Anchor\n";
638 return "No Trust Anchor to clear\n";
640 vector
<DNSName
> toRemove
;
642 while (begin
!= end
) {
644 who
= DNSName(*begin
);
646 catch(std::exception
&e
) {
647 string
ret("Error: ");
649 ret
+= ". No Anchors removed\n";
653 return "Refusing to remove root Trust Anchor, no Anchors removed\n";
654 toRemove
.push_back(who
);
660 for (auto const &entry
: toRemove
) {
661 g_log
<<Logger::Warning
<<"Removing Trust Anchor for "<<entry
<<", requested via control channel"<<endl
;
662 g_luaconfs
.modify([entry
](LuaConfigItems
& lci
) {
663 lci
.dsAnchors
.erase(entry
);
665 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeCache
, entry
, true));
666 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipePacketCache
, entry
, true));
667 broadcastAccFunction
<uint64_t>(boost::bind(pleaseWipeAndCountNegCache
, entry
, true));
672 removed
+= " " + entry
.toStringRootDot();
674 return "Removed Trust Anchor(s) for" + removed
+ "\n";
677 static string
getTAs()
679 if(checkDNSSECDisabled())
680 return "DNSSEC is disabled in the configuration\n";
682 string
ret("Configured Trust Anchors:\n");
683 auto luaconf
= g_luaconfs
.getLocal();
684 for (auto anchor
: luaconf
->dsAnchors
) {
685 ret
+= anchor
.first
.toLogString() + "\n";
686 for (auto e
: anchor
.second
) {
687 ret
+="\t\t"+e
.getZoneRepresentation() + "\n";
695 static string
setMinimumTTL(T begin
, T end
)
698 return "Need to supply new minimum TTL number\n";
700 SyncRes::s_minimumTTL
= pdns_stou(*begin
);
701 return "New minimum TTL: " + std::to_string(SyncRes::s_minimumTTL
) + "\n";
703 catch (const std::exception
& e
) {
704 return "Error parsing the new minimum TTL number: " + std::string(e
.what()) + "\n";
709 static string
setMinimumECSTTL(T begin
, T end
)
712 return "Need to supply new ECS minimum TTL number\n";
714 SyncRes::s_minimumECSTTL
= pdns_stou(*begin
);
715 return "New minimum ECS TTL: " + std::to_string(SyncRes::s_minimumECSTTL
) + "\n";
717 catch (const std::exception
& e
) {
718 return "Error parsing the new ECS minimum TTL number: " + std::string(e
.what()) + "\n";
723 static string
setMaxCacheEntries(T begin
, T end
)
726 return "Need to supply new cache size\n";
728 g_maxCacheEntries
= pdns_stou(*begin
);
729 return "New max cache entries: " + std::to_string(g_maxCacheEntries
) + "\n";
731 catch (const std::exception
& e
) {
732 return "Error parsing the new cache size: " + std::string(e
.what()) + "\n";
737 static string
setMaxPacketCacheEntries(T begin
, T end
)
740 return "Need to supply new packet cache size\n";
742 g_maxPacketCacheEntries
= pdns_stou(*begin
);
743 return "New max packetcache entries: " + std::to_string(g_maxPacketCacheEntries
) + "\n";
745 catch (const std::exception
& e
) {
746 return "Error parsing the new packet cache size: " + std::string(e
.what()) + "\n";
751 static uint64_t getSysTimeMsec()
754 getrusage(RUSAGE_SELF
, &ru
);
755 return (ru
.ru_stime
.tv_sec
*1000ULL + ru
.ru_stime
.tv_usec
/1000);
758 static uint64_t getUserTimeMsec()
761 getrusage(RUSAGE_SELF
, &ru
);
762 return (ru
.ru_utime
.tv_sec
*1000ULL + ru
.ru_utime
.tv_usec
/1000);
765 /* This is a pretty weird set of functions. To get per-thread cpu usage numbers,
766 we have to ask a thread over a pipe. We could do so surgically, so if you want to know about
767 thread 3, we pick pipe 3, but we lack that infrastructure.
769 We can however ask "execute this function on all threads and add up the results".
770 This is what the first function does using a custom object ThreadTimes, which if you add
771 to each other keeps filling the first one with CPU usage numbers
774 static ThreadTimes
* pleaseGetThreadCPUMsec()
779 getrusage(RUSAGE_THREAD
, &ru
);
780 ret
= (ru
.ru_utime
.tv_sec
*1000ULL + ru
.ru_utime
.tv_usec
/1000);
781 ret
+= (ru
.ru_stime
.tv_sec
*1000ULL + ru
.ru_stime
.tv_usec
/1000);
783 return new ThreadTimes
{ret
};
786 /* Next up, when you want msec data for a specific thread, we check
787 if we recently executed pleaseGetThreadCPUMsec. If we didn't we do so
788 now and consult all threads.
790 We then answer you from the (re)fresh(ed) ThreadTimes.
792 static uint64_t doGetThreadCPUMsec(int n
)
794 static std::mutex s_mut
;
795 static time_t last
= 0;
796 static ThreadTimes tt
;
798 std::lock_guard
<std::mutex
> l(s_mut
);
799 if(last
!= time(nullptr)) {
800 tt
= broadcastAccFunction
<ThreadTimes
>(pleaseGetThreadCPUMsec
);
801 last
= time(nullptr);
804 return tt
.times
.at(n
);
807 static uint64_t calculateUptime()
809 return time(nullptr) - g_stats
.startupTime
;
812 static string
* pleaseGetCurrentQueries()
816 gettimeofday(&now
, 0);
818 ostr
<< getMT()->d_waiters
.size() <<" currently outstanding questions\n";
820 boost::format
fmt("%1% %|40t|%2% %|47t|%3% %|63t|%4% %|68t|%5% %|78t|%6%\n");
822 ostr
<< (fmt
% "qname" % "qtype" % "remote" % "tcp" % "chained" % "spent(ms)");
824 for(const auto& mthread
: getMT()->d_waiters
) {
825 const PacketID
& pident
= mthread
.key
;
826 const double spent
= g_networkTimeoutMsec
- (DiffTime(now
, mthread
.ttd
) * 1000);
828 % pident
.domain
.toLogString() /* ?? */ % DNSRecordContent::NumberToType(pident
.type
)
829 % pident
.remote
.toString() % (pident
.sock
? 'Y' : 'n')
830 % (pident
.fd
== -1 ? 'Y' : 'n')
831 % (spent
> 0 ? spent
: '0')
838 return new string(ostr
.str());
841 static string
doCurrentQueries()
843 return broadcastAccFunction
<string
>(pleaseGetCurrentQueries
);
846 uint64_t* pleaseGetThrottleSize()
848 return new uint64_t(SyncRes::getThrottledServersSize());
851 static uint64_t getThrottleSize()
853 return broadcastAccFunction
<uint64_t>(pleaseGetThrottleSize
);
856 uint64_t* pleaseGetNegCacheSize()
858 uint64_t tmp
=(SyncRes::getNegCacheSize());
859 return new uint64_t(tmp
);
862 static uint64_t getNegCacheSize()
864 return broadcastAccFunction
<uint64_t>(pleaseGetNegCacheSize
);
867 static uint64_t* pleaseGetFailedHostsSize()
869 uint64_t tmp
=(SyncRes::getThrottledServersSize());
870 return new uint64_t(tmp
);
873 static uint64_t getFailedHostsSize()
875 return broadcastAccFunction
<uint64_t>(pleaseGetFailedHostsSize
);
878 uint64_t* pleaseGetNsSpeedsSize()
880 return new uint64_t(SyncRes::getNSSpeedsSize());
883 static uint64_t getNsSpeedsSize()
885 return broadcastAccFunction
<uint64_t>(pleaseGetNsSpeedsSize
);
888 uint64_t* pleaseGetConcurrentQueries()
890 return new uint64_t(getMT() ? getMT()->numProcesses() : 0);
893 static uint64_t getConcurrentQueries()
895 return broadcastAccFunction
<uint64_t>(pleaseGetConcurrentQueries
);
898 uint64_t* pleaseGetCacheSize()
900 return new uint64_t(t_RC
? t_RC
->size() : 0);
903 static uint64_t* pleaseGetCacheBytes()
905 return new uint64_t(t_RC
? t_RC
->bytes() : 0);
908 static uint64_t doGetCacheSize()
910 return broadcastAccFunction
<uint64_t>(pleaseGetCacheSize
);
913 static uint64_t doGetAvgLatencyUsec()
915 return (uint64_t) g_stats
.avgLatencyUsec
;
918 static uint64_t doGetCacheBytes()
920 return broadcastAccFunction
<uint64_t>(pleaseGetCacheBytes
);
923 uint64_t* pleaseGetCacheHits()
925 return new uint64_t(t_RC
? t_RC
->cacheHits
: 0);
928 static uint64_t doGetCacheHits()
930 return broadcastAccFunction
<uint64_t>(pleaseGetCacheHits
);
933 uint64_t* pleaseGetCacheMisses()
935 return new uint64_t(t_RC
? t_RC
->cacheMisses
: 0);
938 static uint64_t doGetCacheMisses()
940 return broadcastAccFunction
<uint64_t>(pleaseGetCacheMisses
);
943 uint64_t* pleaseGetPacketCacheSize()
945 return new uint64_t(t_packetCache
? t_packetCache
->size() : 0);
948 static uint64_t* pleaseGetPacketCacheBytes()
950 return new uint64_t(t_packetCache
? t_packetCache
->bytes() : 0);
953 static uint64_t doGetPacketCacheSize()
955 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheSize
);
958 static uint64_t doGetPacketCacheBytes()
960 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheBytes
);
963 uint64_t* pleaseGetPacketCacheHits()
965 return new uint64_t(t_packetCache
? t_packetCache
->d_hits
: 0);
968 static uint64_t doGetPacketCacheHits()
970 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheHits
);
973 static uint64_t* pleaseGetPacketCacheMisses()
975 return new uint64_t(t_packetCache
? t_packetCache
->d_misses
: 0);
978 static uint64_t doGetPacketCacheMisses()
980 return broadcastAccFunction
<uint64_t>(pleaseGetPacketCacheMisses
);
983 static uint64_t doGetMallocated()
985 // this turned out to be broken
986 /* struct mallinfo mi = mallinfo();
987 return mi.uordblks; */
991 extern ResponseStats g_rs
;
993 void registerAllStats()
995 static std::atomic_flag s_init
= ATOMIC_FLAG_INIT
;
996 if(s_init
.test_and_set())
999 addGetStat("questions", &g_stats
.qcounter
);
1000 addGetStat("ipv6-questions", &g_stats
.ipv6qcounter
);
1001 addGetStat("tcp-questions", &g_stats
.tcpqcounter
);
1003 addGetStat("cache-hits", doGetCacheHits
);
1004 addGetStat("cache-misses", doGetCacheMisses
);
1005 addGetStat("cache-entries", doGetCacheSize
);
1006 addGetStat("max-cache-entries", []() { return g_maxCacheEntries
.load(); });
1007 addGetStat("max-packetcache-entries", []() { return g_maxPacketCacheEntries
.load();});
1008 addGetStat("cache-bytes", doGetCacheBytes
);
1010 addGetStat("packetcache-hits", doGetPacketCacheHits
);
1011 addGetStat("packetcache-misses", doGetPacketCacheMisses
);
1012 addGetStat("packetcache-entries", doGetPacketCacheSize
);
1013 addGetStat("packetcache-bytes", doGetPacketCacheBytes
);
1015 addGetStat("malloc-bytes", doGetMallocated
);
1017 addGetStat("servfail-answers", &g_stats
.servFails
);
1018 addGetStat("nxdomain-answers", &g_stats
.nxDomains
);
1019 addGetStat("noerror-answers", &g_stats
.noErrors
);
1021 addGetStat("unauthorized-udp", &g_stats
.unauthorizedUDP
);
1022 addGetStat("unauthorized-tcp", &g_stats
.unauthorizedTCP
);
1023 addGetStat("tcp-client-overflow", &g_stats
.tcpClientOverflow
);
1025 addGetStat("client-parse-errors", &g_stats
.clientParseError
);
1026 addGetStat("server-parse-errors", &g_stats
.serverParseError
);
1027 addGetStat("too-old-drops", &g_stats
.tooOldDrops
);
1028 addGetStat("truncated-drops", &g_stats
.truncatedDrops
);
1029 addGetStat("query-pipe-full-drops", &g_stats
.queryPipeFullDrops
);
1031 addGetStat("answers0-1", &g_stats
.answers0_1
);
1032 addGetStat("answers1-10", &g_stats
.answers1_10
);
1033 addGetStat("answers10-100", &g_stats
.answers10_100
);
1034 addGetStat("answers100-1000", &g_stats
.answers100_1000
);
1035 addGetStat("answers-slow", &g_stats
.answersSlow
);
1037 addGetStat("x-ourtime0-1", &g_stats
.ourtime0_1
);
1038 addGetStat("x-ourtime1-2", &g_stats
.ourtime1_2
);
1039 addGetStat("x-ourtime2-4", &g_stats
.ourtime2_4
);
1040 addGetStat("x-ourtime4-8", &g_stats
.ourtime4_8
);
1041 addGetStat("x-ourtime8-16", &g_stats
.ourtime8_16
);
1042 addGetStat("x-ourtime16-32", &g_stats
.ourtime16_32
);
1043 addGetStat("x-ourtime-slow", &g_stats
.ourtimeSlow
);
1045 addGetStat("auth4-answers0-1", &g_stats
.auth4Answers0_1
);
1046 addGetStat("auth4-answers1-10", &g_stats
.auth4Answers1_10
);
1047 addGetStat("auth4-answers10-100", &g_stats
.auth4Answers10_100
);
1048 addGetStat("auth4-answers100-1000", &g_stats
.auth4Answers100_1000
);
1049 addGetStat("auth4-answers-slow", &g_stats
.auth4AnswersSlow
);
1051 addGetStat("auth6-answers0-1", &g_stats
.auth6Answers0_1
);
1052 addGetStat("auth6-answers1-10", &g_stats
.auth6Answers1_10
);
1053 addGetStat("auth6-answers10-100", &g_stats
.auth6Answers10_100
);
1054 addGetStat("auth6-answers100-1000", &g_stats
.auth6Answers100_1000
);
1055 addGetStat("auth6-answers-slow", &g_stats
.auth6AnswersSlow
);
1058 addGetStat("qa-latency", doGetAvgLatencyUsec
);
1059 addGetStat("x-our-latency", []() { return g_stats
.avgLatencyOursUsec
; });
1060 addGetStat("unexpected-packets", &g_stats
.unexpectedCount
);
1061 addGetStat("case-mismatches", &g_stats
.caseMismatchCount
);
1062 addGetStat("spoof-prevents", &g_stats
.spoofCount
);
1064 addGetStat("nsset-invalidations", &g_stats
.nsSetInvalidations
);
1066 addGetStat("resource-limits", &g_stats
.resourceLimits
);
1067 addGetStat("over-capacity-drops", &g_stats
.overCapacityDrops
);
1068 addGetStat("policy-drops", &g_stats
.policyDrops
);
1069 addGetStat("no-packet-error", &g_stats
.noPacketError
);
1070 addGetStat("dlg-only-drops", &SyncRes::s_nodelegated
);
1071 addGetStat("ignored-packets", &g_stats
.ignoredCount
);
1072 addGetStat("empty-queries", &g_stats
.emptyQueriesCount
);
1073 addGetStat("max-mthread-stack", &g_stats
.maxMThreadStackUsage
);
1075 addGetStat("negcache-entries", getNegCacheSize
);
1076 addGetStat("throttle-entries", getThrottleSize
);
1078 addGetStat("nsspeeds-entries", getNsSpeedsSize
);
1079 addGetStat("failed-host-entries", getFailedHostsSize
);
1081 addGetStat("concurrent-queries", getConcurrentQueries
);
1082 addGetStat("security-status", &g_security_status
);
1083 addGetStat("outgoing-timeouts", &SyncRes::s_outgoingtimeouts
);
1084 addGetStat("outgoing4-timeouts", &SyncRes::s_outgoing4timeouts
);
1085 addGetStat("outgoing6-timeouts", &SyncRes::s_outgoing6timeouts
);
1086 addGetStat("auth-zone-queries", &SyncRes::s_authzonequeries
);
1087 addGetStat("tcp-outqueries", &SyncRes::s_tcpoutqueries
);
1088 addGetStat("all-outqueries", &SyncRes::s_outqueries
);
1089 addGetStat("ipv6-outqueries", &g_stats
.ipv6queries
);
1090 addGetStat("throttled-outqueries", &SyncRes::s_throttledqueries
);
1091 addGetStat("dont-outqueries", &SyncRes::s_dontqueries
);
1092 addGetStat("throttled-out", &SyncRes::s_throttledqueries
);
1093 addGetStat("unreachables", &SyncRes::s_unreachables
);
1094 addGetStat("ecs-queries", &SyncRes::s_ecsqueries
);
1095 addGetStat("ecs-responses", &SyncRes::s_ecsresponses
);
1096 addGetStat("chain-resends", &g_stats
.chainResends
);
1097 addGetStat("tcp-clients", boost::bind(TCPConnection::getCurrentConnections
));
1100 addGetStat("udp-recvbuf-errors", boost::bind(udpErrorStats
, "udp-recvbuf-errors"));
1101 addGetStat("udp-sndbuf-errors", boost::bind(udpErrorStats
, "udp-sndbuf-errors"));
1102 addGetStat("udp-noport-errors", boost::bind(udpErrorStats
, "udp-noport-errors"));
1103 addGetStat("udp-in-errors", boost::bind(udpErrorStats
, "udp-in-errors"));
1106 addGetStat("edns-ping-matches", &g_stats
.ednsPingMatches
);
1107 addGetStat("edns-ping-mismatches", &g_stats
.ednsPingMismatches
);
1108 addGetStat("dnssec-queries", &g_stats
.dnssecQueries
);
1110 addGetStat("dnssec-authentic-data-queries", &g_stats
.dnssecAuthenticDataQueries
);
1111 addGetStat("dnssec-check-disabled-queries", &g_stats
.dnssecCheckDisabledQueries
);
1113 addGetStat("variable-responses", &g_stats
.variableResponses
);
1115 addGetStat("noping-outqueries", &g_stats
.noPingOutQueries
);
1116 addGetStat("noedns-outqueries", &g_stats
.noEdnsOutQueries
);
1118 addGetStat("uptime", calculateUptime
);
1119 addGetStat("real-memory-usage", boost::bind(getRealMemoryUsage
, string()));
1120 addGetStat("special-memory-usage", boost::bind(getSpecialMemoryUsage
, string()));
1121 addGetStat("fd-usage", boost::bind(getOpenFileDescriptors
, string()));
1123 // addGetStat("query-rate", getQueryRate);
1124 addGetStat("user-msec", getUserTimeMsec
);
1125 addGetStat("sys-msec", getSysTimeMsec
);
1127 for(unsigned int n
=0; n
< g_numThreads
; ++n
)
1128 addGetStat("cpu-msec-thread-"+std::to_string(n
), boost::bind(&doGetThreadCPUMsec
, n
));
1131 addGetStat("memory-allocs", boost::bind(&MallocTracer::getAllocs
, g_mtracer
, string()));
1132 addGetStat("memory-alloc-flux", boost::bind(&MallocTracer::getAllocFlux
, g_mtracer
, string()));
1133 addGetStat("memory-allocated", boost::bind(&MallocTracer::getTotAllocated
, g_mtracer
, string()));
1136 addGetStat("dnssec-validations", &g_stats
.dnssecValidations
);
1137 addGetStat("dnssec-result-insecure", &g_stats
.dnssecResults
[Insecure
]);
1138 addGetStat("dnssec-result-secure", &g_stats
.dnssecResults
[Secure
]);
1139 addGetStat("dnssec-result-bogus", &g_stats
.dnssecResults
[Bogus
]);
1140 addGetStat("dnssec-result-indeterminate", &g_stats
.dnssecResults
[Indeterminate
]);
1141 addGetStat("dnssec-result-nta", &g_stats
.dnssecResults
[NTA
]);
1143 addGetStat("policy-result-noaction", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NoAction
]);
1144 addGetStat("policy-result-drop", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Drop
]);
1145 addGetStat("policy-result-nxdomain", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NXDOMAIN
]);
1146 addGetStat("policy-result-nodata", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::NODATA
]);
1147 addGetStat("policy-result-truncate", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Truncate
]);
1148 addGetStat("policy-result-custom", &g_stats
.policyResults
[DNSFilterEngine::PolicyKind::Custom
]);
1150 addGetStat("rebalanced-queries", &g_stats
.rebalancedQueries
);
1152 /* make sure that the ECS stats are properly initialized */
1153 SyncRes::clearECSStats();
1154 for (size_t idx
= 0; idx
< SyncRes::s_ecsResponsesBySubnetSize4
.size(); idx
++) {
1155 const std::string name
= "ecs-v4-response-bits-" + std::to_string(idx
+ 1);
1156 addGetStat(name
, &(SyncRes::s_ecsResponsesBySubnetSize4
.at(idx
)));
1158 for (size_t idx
= 0; idx
< SyncRes::s_ecsResponsesBySubnetSize6
.size(); idx
++) {
1159 const std::string name
= "ecs-v6-response-bits-" + std::to_string(idx
+ 1);
1160 addGetStat(name
, &(SyncRes::s_ecsResponsesBySubnetSize6
.at(idx
)));
1164 static void doExitGeneric(bool nicely
)
1166 g_log
<<Logger::Error
<<"Exiting on user request"<<endl
;
1167 extern RecursorControlChannel s_rcc
;
1168 s_rcc
.~RecursorControlChannel();
1170 extern string s_pidfname
;
1171 if(!s_pidfname
.empty())
1172 unlink(s_pidfname
.c_str()); // we can at least try..
1179 static void doExit()
1181 doExitGeneric(false);
1184 static void doExitNicely()
1186 doExitGeneric(true);
1189 vector
<pair
<DNSName
, uint16_t> >* pleaseGetQueryRing()
1191 typedef pair
<DNSName
,uint16_t> query_t
;
1192 vector
<query_t
>* ret
= new vector
<query_t
>();
1195 ret
->reserve(t_queryring
->size());
1197 for(const query_t
& q
: *t_queryring
) {
1202 vector
<pair
<DNSName
,uint16_t> >* pleaseGetServfailQueryRing()
1204 typedef pair
<DNSName
,uint16_t> query_t
;
1205 vector
<query_t
>* ret
= new vector
<query_t
>();
1206 if(!t_servfailqueryring
)
1208 ret
->reserve(t_servfailqueryring
->size());
1209 for(const query_t
& q
: *t_servfailqueryring
) {
1214 vector
<pair
<DNSName
,uint16_t> >* pleaseGetBogusQueryRing()
1216 typedef pair
<DNSName
,uint16_t> query_t
;
1217 vector
<query_t
>* ret
= new vector
<query_t
>();
1218 if(!t_bogusqueryring
)
1220 ret
->reserve(t_bogusqueryring
->size());
1221 for(const query_t
& q
: *t_bogusqueryring
) {
1229 typedef boost::function
<vector
<ComboAddress
>*()> pleaseremotefunc_t
;
1230 typedef boost::function
<vector
<pair
<DNSName
,uint16_t> >*()> pleasequeryfunc_t
;
1232 vector
<ComboAddress
>* pleaseGetRemotes()
1234 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1238 ret
->reserve(t_remotes
->size());
1239 for(const ComboAddress
& ca
: *t_remotes
) {
1245 vector
<ComboAddress
>* pleaseGetServfailRemotes()
1247 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1248 if(!t_servfailremotes
)
1250 ret
->reserve(t_servfailremotes
->size());
1251 for(const ComboAddress
& ca
: *t_servfailremotes
) {
1257 vector
<ComboAddress
>* pleaseGetBogusRemotes()
1259 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1262 ret
->reserve(t_bogusremotes
->size());
1263 for(const ComboAddress
& ca
: *t_bogusremotes
) {
1269 vector
<ComboAddress
>* pleaseGetLargeAnswerRemotes()
1271 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1272 if(!t_largeanswerremotes
)
1274 ret
->reserve(t_largeanswerremotes
->size());
1275 for(const ComboAddress
& ca
: *t_largeanswerremotes
) {
1281 vector
<ComboAddress
>* pleaseGetTimeouts()
1283 vector
<ComboAddress
>* ret
= new vector
<ComboAddress
>();
1286 ret
->reserve(t_timeouts
->size());
1287 for(const ComboAddress
& ca
: *t_timeouts
) {
1293 string
doGenericTopRemotes(pleaseremotefunc_t func
)
1295 typedef map
<ComboAddress
, int, ComboAddress::addressOnlyLessThan
> counts_t
;
1298 vector
<ComboAddress
> remotes
=broadcastAccFunction
<vector
<ComboAddress
> >(func
);
1300 unsigned int total
=0;
1301 for(const ComboAddress
& ca
: remotes
) {
1306 typedef std::multimap
<int, ComboAddress
> rcounts_t
;
1309 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1310 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1313 ret
<<"Over last "<<total
<<" entries:\n";
1314 format
fmt("%.02f%%\t%s\n");
1315 int limit
=0, accounted
=0;
1317 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1318 ret
<< fmt
% (-100.0*i
->first
/total
) % i
->second
.toString();
1319 accounted
+= -i
->first
;
1321 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1326 // XXX DNSName Pain - this function should benefit from native DNSName methods
1327 DNSName
getRegisteredName(const DNSName
& dom
)
1329 auto parts
=dom
.getRawLabels();
1332 reverse(parts
.begin(), parts
.end());
1333 for(string
& str
: parts
) { str
=toLower(str
); };
1337 while(!parts
.empty()) {
1338 if(parts
.size()==1 || binary_search(g_pubs
.begin(), g_pubs
.end(), parts
)) {
1344 for(auto p
= parts
.crbegin(); p
!= parts
.crend(); ++p
) {
1347 return DNSName(ret
);
1350 last
=parts
[parts
.size()-1];
1351 parts
.resize(parts
.size()-1);
1353 return DNSName("??");
1356 static DNSName
nopFilter(const DNSName
& name
)
1361 string
doGenericTopQueries(pleasequeryfunc_t func
, boost::function
<DNSName(const DNSName
&)> filter
=nopFilter
)
1363 typedef pair
<DNSName
,uint16_t> query_t
;
1364 typedef map
<query_t
, int> counts_t
;
1366 vector
<query_t
> queries
=broadcastAccFunction
<vector
<query_t
> >(func
);
1368 unsigned int total
=0;
1369 for(const query_t
& q
: queries
) {
1371 counts
[make_pair(filter(q
.first
),q
.second
)]++;
1374 typedef std::multimap
<int, query_t
> rcounts_t
;
1377 for(counts_t::const_iterator i
=counts
.begin(); i
!= counts
.end(); ++i
)
1378 rcounts
.insert(make_pair(-i
->second
, i
->first
));
1381 ret
<<"Over last "<<total
<<" entries:\n";
1382 format
fmt("%.02f%%\t%s\n");
1383 int limit
=0, accounted
=0;
1385 for(rcounts_t::const_iterator i
=rcounts
.begin(); i
!= rcounts
.end() && limit
< 20; ++i
, ++limit
) {
1386 ret
<< fmt
% (-100.0*i
->first
/total
) % (i
->second
.first
.toLogString()+"|"+DNSRecordContent::NumberToType(i
->second
.second
));
1387 accounted
+= -i
->first
;
1389 ret
<< '\n' << fmt
% (100.0*(total
-accounted
)/total
) % "rest";
1396 static string
* nopFunction()
1398 return new string("pong\n");
1401 static string
getDontThrottleNames() {
1402 auto dtn
= g_dontThrottleNames
.getLocal();
1403 return dtn
->toString() + "\n";
1406 static string
getDontThrottleNetmasks() {
1407 auto dtn
= g_dontThrottleNetmasks
.getLocal();
1408 return dtn
->toString() + "\n";
1411 template<typename T
>
1412 static string
addDontThrottleNames(T begin
, T end
) {
1414 return "No names specified, keeping existing list\n";
1416 vector
<DNSName
> toAdd
;
1417 while (begin
!= end
) {
1419 auto d
= DNSName(*begin
);
1422 catch(const std::exception
&e
) {
1423 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1428 string ret
= "Added";
1429 auto dnt
= g_dontThrottleNames
.getCopy();
1431 for (auto const &d
: toAdd
) {
1436 ret
+= " " + d
.toLogString();
1440 g_dontThrottleNames
.setState(dnt
);
1442 ret
+= " to the list of nameservers that may not be throttled";
1443 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1447 template<typename T
>
1448 static string
addDontThrottleNetmasks(T begin
, T end
) {
1450 return "No netmasks specified, keeping existing list\n";
1452 vector
<Netmask
> toAdd
;
1453 while (begin
!= end
) {
1455 auto n
= Netmask(*begin
);
1458 catch(const std::exception
&e
) {
1459 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1461 catch(const PDNSException
&e
) {
1462 return "Problem parsing '" + *begin
+ "': "+ e
.reason
+ ", nothing added\n";
1467 string ret
= "Added";
1468 auto dnt
= g_dontThrottleNetmasks
.getCopy();
1470 for (auto const &t
: toAdd
) {
1475 ret
+= " " + t
.toString();
1479 g_dontThrottleNetmasks
.setState(dnt
);
1481 ret
+= " to the list of nameserver netmasks that may not be throttled";
1482 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1486 template<typename T
>
1487 static string
clearDontThrottleNames(T begin
, T end
) {
1489 return "No names specified, doing nothing.\n";
1491 if (begin
+ 1 == end
&& *begin
== "*"){
1492 SuffixMatchNode smn
;
1493 g_dontThrottleNames
.setState(smn
);
1494 string ret
= "Cleared list of nameserver names that may not be throttled";
1495 g_log
<<Logger::Warning
<<ret
<<", requested via control channel"<<endl
;
1499 vector
<DNSName
> toRemove
;
1500 while (begin
!= end
) {
1502 if (*begin
== "*") {
1503 return "Please don't mix '*' with other names, nothing removed\n";
1505 toRemove
.push_back(DNSName(*begin
));
1507 catch (const std::exception
&e
) {
1508 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing removed\n";
1513 string ret
= "Removed";
1515 auto dnt
= g_dontThrottleNames
.getCopy();
1516 for (const auto &name
: toRemove
) {
1521 ret
+= " " + name
.toLogString();
1525 g_dontThrottleNames
.setState(dnt
);
1527 ret
+= " from the list of nameservers that may not be throttled";
1528 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1532 template<typename T
>
1533 static string
clearDontThrottleNetmasks(T begin
, T end
) {
1535 return "No netmasks specified, doing nothing.\n";
1537 if (begin
+ 1 == end
&& *begin
== "*"){
1538 auto nmg
= g_dontThrottleNetmasks
.getCopy();
1540 g_dontThrottleNetmasks
.setState(nmg
);
1542 string ret
= "Cleared list of nameserver addresses that may not be throttled";
1543 g_log
<<Logger::Warning
<<ret
<<", requested via control channel"<<endl
;
1547 std::vector
<Netmask
> toRemove
;
1548 while (begin
!= end
) {
1550 if (*begin
== "*") {
1551 return "Please don't mix '*' with other netmasks, nothing removed\n";
1553 auto n
= Netmask(*begin
);
1554 toRemove
.push_back(n
);
1556 catch(const std::exception
&e
) {
1557 return "Problem parsing '" + *begin
+ "': "+ e
.what() + ", nothing added\n";
1559 catch(const PDNSException
&e
) {
1560 return "Problem parsing '" + *begin
+ "': "+ e
.reason
+ ", nothing added\n";
1565 string ret
= "Removed";
1567 auto dnt
= g_dontThrottleNetmasks
.getCopy();
1568 for (const auto &mask
: toRemove
) {
1573 ret
+= " " + mask
.toString();
1574 dnt
.deleteMask(mask
);
1577 g_dontThrottleNetmasks
.setState(dnt
);
1579 ret
+= " from the list of nameservers that may not be throttled";
1580 g_log
<<Logger::Info
<<ret
<<", requested via control channel"<<endl
;
1585 string
RecursorControlParser::getAnswer(const string
& question
, RecursorControlParser::func_t
** command
)
1588 vector
<string
> words
;
1589 stringtok(words
, question
);
1592 return "invalid command\n";
1594 string cmd
=toLower(words
[0]);
1595 vector
<string
>::const_iterator begin
=words
.begin()+1, end
=words
.end();
1597 // should probably have a smart dispatcher here, like auth has
1600 "add-dont-throttle-names [N...] add names that are not allowed to be throttled\n"
1601 "add-dont-throttle-netmasks [N...]\n"
1602 " add netmasks that are not allowed to be throttled\n"
1603 "add-nta DOMAIN [REASON] add a Negative Trust Anchor for DOMAIN with the comment REASON\n"
1604 "add-ta DOMAIN DSRECORD add a Trust Anchor for DOMAIN with data DSRECORD\n"
1605 "current-queries show currently active queries\n"
1606 "clear-dont-throttle-names [N...] remove names that are not allowed to be throttled. If N is '*', remove all\n"
1607 "clear-dont-throttle-netmasks [N...]\n"
1608 " remove netmasks that are not allowed to be throttled. If N is '*', remove all\n"
1609 "clear-nta [DOMAIN]... Clear the Negative Trust Anchor for DOMAINs, if no DOMAIN is specified, remove all\n"
1610 "clear-ta [DOMAIN]... Clear the Trust Anchor for DOMAINs\n"
1611 "dump-cache <filename> dump cache contents to the named file\n"
1612 "dump-edns [status] <filename> dump EDNS status to the named file\n"
1613 "dump-nsspeeds <filename> dump nsspeeds statistics to the named file\n"
1614 "dump-rpz <zone name> <filename> dump the content of a RPZ zone to the named file\n"
1615 "dump-throttlemap <filename> dump the contents of the throttle to the named file\n"
1616 "get [key1] [key2] .. get specific statistics\n"
1617 "get-all get all statistics\n"
1618 "get-dont-throttle-names get the list of names that are not allowed to be throttled\n"
1619 "get-dont-throttle-netmasks get the list of netmasks that are not allowed to be throttled\n"
1620 "get-ntas get all configured Negative Trust Anchors\n"
1621 "get-tas get all configured Trust Anchors\n"
1622 "get-parameter [key1] [key2] .. get configuration parameters\n"
1623 "get-qtypelist get QType statistics\n"
1624 " notice: queries from cache aren't being counted yet\n"
1625 "help get this list\n"
1626 "ping check that all threads are alive\n"
1627 "quit stop the recursor daemon\n"
1628 "quit-nicely stop the recursor daemon nicely\n"
1629 "reload-acls reload ACLS\n"
1630 "reload-lua-script [filename] (re)load Lua script\n"
1631 "reload-lua-config [filename] (re)load Lua configuration file\n"
1632 "reload-zones reload all auth and forward zones\n"
1633 "set-ecs-minimum-ttl value set ecs-minimum-ttl-override\n"
1634 "set-max-cache-entries value set new maximum cache size\n"
1635 "set-max-packetcache-entries val set new maximum packet cache size\n"
1636 "set-minimum-ttl value set minimum-ttl-override\n"
1637 "set-carbon-server set a carbon server for telemetry\n"
1638 "set-dnssec-log-bogus SETTING enable (SETTING=yes) or disable (SETTING=no) logging of DNSSEC validation failures\n"
1639 "trace-regex [regex] emit resolution trace for matching queries (empty regex to clear trace)\n"
1640 "top-largeanswer-remotes show top remotes receiving large answers\n"
1641 "top-queries show top queries\n"
1642 "top-pub-queries show top queries grouped by public suffix list\n"
1643 "top-remotes show top remotes\n"
1644 "top-timeouts show top downstream timeouts\n"
1645 "top-servfail-queries show top queries receiving servfail answers\n"
1646 "top-bogus-queries show top queries validating as bogus\n"
1647 "top-pub-servfail-queries show top queries receiving servfail answers grouped by public suffix list\n"
1648 "top-pub-bogus-queries show top queries validating as bogus grouped by public suffix list\n"
1649 "top-servfail-remotes show top remotes receiving servfail answers\n"
1650 "top-bogus-remotes show top remotes receiving bogus answers\n"
1651 "unload-lua-script unload Lua script\n"
1652 "version return Recursor version number\n"
1653 "wipe-cache domain0 [domain1] .. wipe domain data from cache\n";
1656 return getAllStats();
1659 return doGet(begin
, end
);
1661 if(cmd
=="get-parameter")
1662 return doGetParameter(begin
, end
);
1669 if(cmd
=="version") {
1670 return getPDNSVersion()+"\n";
1673 if(cmd
=="quit-nicely") {
1674 *command
=&doExitNicely
;
1675 return "bye nicely\n";
1678 if(cmd
=="dump-cache")
1679 return doDumpCache(begin
, end
);
1681 if(cmd
=="dump-ednsstatus" || cmd
=="dump-edns")
1682 return doDumpEDNSStatus(begin
, end
);
1684 if(cmd
=="dump-nsspeeds")
1685 return doDumpNSSpeeds(begin
, end
);
1687 if(cmd
=="dump-rpz") {
1688 return doDumpRPZ(begin
, end
);
1691 if(cmd
=="dump-throttlemap")
1692 return doDumpThrottleMap(begin
, end
);
1694 if(cmd
=="wipe-cache" || cmd
=="flushname")
1695 return doWipeCache(begin
, end
);
1697 if(cmd
=="reload-lua-script")
1698 return doQueueReloadLuaScript(begin
, end
);
1700 if(cmd
=="reload-lua-config") {
1702 ::arg().set("lua-config-file") = *begin
;
1705 luaConfigDelayedThreads delayedLuaThreads
;
1706 loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads
);
1707 startLuaConfigDelayedThreads(delayedLuaThreads
, g_luaconfs
.getCopy().generation
);
1708 g_log
<<Logger::Warning
<<"Reloaded Lua configuration file '"<<::arg()["lua-config-file"]<<"', requested via control channel"<<endl
;
1709 return "Reloaded Lua configuration file '"+::arg()["lua-config-file"]+"'\n";
1711 catch(std::exception
& e
) {
1712 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.what()+"\n";
1714 catch(const PDNSException
& e
) {
1715 return "Unable to load Lua script from '"+::arg()["lua-config-file"]+"': "+e
.reason
+"\n";
1719 if(cmd
=="set-carbon-server")
1720 return doSetCarbonServer(begin
, end
);
1722 if(cmd
=="trace-regex")
1723 return doTraceRegex(begin
, end
);
1725 if(cmd
=="unload-lua-script") {
1726 vector
<string
> empty
;
1727 empty
.push_back(string());
1728 return doQueueReloadLuaScript(empty
.begin(), empty
.end());
1731 if(cmd
=="reload-acls") {
1732 if(!::arg()["chroot"].empty()) {
1733 g_log
<<Logger::Error
<<"Unable to reload ACL when chroot()'ed, requested via control channel"<<endl
;
1734 return "Unable to reload ACL when chroot()'ed, please restart\n";
1740 catch(std::exception
& e
)
1742 g_log
<<Logger::Error
<<"Reloading ACLs failed (Exception: "<<e
.what()<<")"<<endl
;
1743 return e
.what() + string("\n");
1745 catch(PDNSException
& ae
)
1747 g_log
<<Logger::Error
<<"Reloading ACLs failed (PDNSException: "<<ae
.reason
<<")"<<endl
;
1748 return ae
.reason
+ string("\n");
1754 if(cmd
=="top-remotes")
1755 return doGenericTopRemotes(pleaseGetRemotes
);
1757 if(cmd
=="top-queries")
1758 return doGenericTopQueries(pleaseGetQueryRing
);
1760 if(cmd
=="top-pub-queries")
1761 return doGenericTopQueries(pleaseGetQueryRing
, getRegisteredName
);
1763 if(cmd
=="top-servfail-queries")
1764 return doGenericTopQueries(pleaseGetServfailQueryRing
);
1766 if(cmd
=="top-pub-servfail-queries")
1767 return doGenericTopQueries(pleaseGetServfailQueryRing
, getRegisteredName
);
1769 if(cmd
=="top-bogus-queries")
1770 return doGenericTopQueries(pleaseGetBogusQueryRing
);
1772 if(cmd
=="top-pub-bogus-queries")
1773 return doGenericTopQueries(pleaseGetBogusQueryRing
, getRegisteredName
);
1776 if(cmd
=="top-servfail-remotes")
1777 return doGenericTopRemotes(pleaseGetServfailRemotes
);
1779 if(cmd
=="top-bogus-remotes")
1780 return doGenericTopRemotes(pleaseGetBogusRemotes
);
1782 if(cmd
=="top-largeanswer-remotes")
1783 return doGenericTopRemotes(pleaseGetLargeAnswerRemotes
);
1785 if(cmd
=="top-timeouts")
1786 return doGenericTopRemotes(pleaseGetTimeouts
);
1789 if(cmd
=="current-queries")
1790 return doCurrentQueries();
1793 return broadcastAccFunction
<string
>(nopFunction
);
1796 if(cmd
=="reload-zones") {
1797 if(!::arg()["chroot"].empty()) {
1798 g_log
<<Logger::Error
<<"Unable to reload zones and forwards when chroot()'ed, requested via control channel"<<endl
;
1799 return "Unable to reload zones and forwards when chroot()'ed, please restart\n";
1801 return reloadAuthAndForwards();
1804 if(cmd
=="set-ecs-minimum-ttl") {
1805 return setMinimumECSTTL(begin
, end
);
1808 if(cmd
=="set-max-cache-entries") {
1809 return setMaxCacheEntries(begin
, end
);
1811 if(cmd
=="set-max-packetcache-entries") {
1812 return setMaxPacketCacheEntries(begin
, end
);
1815 if(cmd
=="set-minimum-ttl") {
1816 return setMinimumTTL(begin
, end
);
1819 if(cmd
=="get-qtypelist") {
1820 return g_rs
.getQTypeReport();
1823 if(cmd
=="add-nta") {
1824 return doAddNTA(begin
, end
);
1827 if(cmd
=="clear-nta") {
1828 return doClearNTA(begin
, end
);
1831 if(cmd
=="get-ntas") {
1836 return doAddTA(begin
, end
);
1839 if(cmd
=="clear-ta") {
1840 return doClearTA(begin
, end
);
1843 if(cmd
=="get-tas") {
1847 if (cmd
=="set-dnssec-log-bogus")
1848 return doSetDnssecLogBogus(begin
, end
);
1850 if (cmd
== "get-dont-throttle-names") {
1851 return getDontThrottleNames();
1854 if (cmd
== "get-dont-throttle-netmasks") {
1855 return getDontThrottleNetmasks();
1858 if (cmd
== "add-dont-throttle-names") {
1859 return addDontThrottleNames(begin
, end
);
1862 if (cmd
== "add-dont-throttle-netmasks") {
1863 return addDontThrottleNetmasks(begin
, end
);
1866 if (cmd
== "clear-dont-throttle-names") {
1867 return clearDontThrottleNames(begin
, end
);
1870 if (cmd
== "clear-dont-throttle-netmasks") {
1871 return clearDontThrottleNetmasks(begin
, end
);
1874 return "Unknown command '"+cmd
+"', try 'help'\n";