#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include "syncres.hh"
#include "utility.hh"
#include "rec_channel.hh"
#include <boost/bind.hpp>
#endif
#include "misc.hh"
#include "recursor_cache.hh"
-#include "syncres.hh"
#include "negcache.hh"
#include <boost/function.hpp>
#include <boost/optional.hpp>
#include "namespaces.hh"
pthread_mutex_t g_carbon_config_lock=PTHREAD_MUTEX_INITIALIZER;
-map<string, const uint32_t*> d_get32bitpointers;
-map<string, const uint64_t*> d_get64bitpointers;
-map<string, const std::atomic<uint64_t>*> d_getatomics;
-map<string, function< uint64_t() > > d_get64bitmembers;
-pthread_mutex_t d_dynmetricslock = PTHREAD_MUTEX_INITIALIZER;
-map<string, std::atomic<unsigned long>* > d_dynmetrics;
-void addGetStat(const string& name, const uint32_t* place)
+static map<string, const uint32_t*> d_get32bitpointers;
+static map<string, const uint64_t*> d_get64bitpointers;
+static map<string, const std::atomic<uint64_t>*> d_getatomics;
+static map<string, function< uint64_t() > > d_get64bitmembers;
+static pthread_mutex_t d_dynmetricslock = PTHREAD_MUTEX_INITIALIZER;
+static map<string, std::atomic<unsigned long>* > d_dynmetrics;
+
+static void addGetStat(const string& name, const uint32_t* place)
{
d_get32bitpointers[name]=place;
}
-void addGetStat(const string& name, const uint64_t* place)
-{
- d_get64bitpointers[name]=place;
-}
-void addGetStat(const string& name, const std::atomic<uint64_t>* place)
+static void addGetStat(const string& name, const std::atomic<uint64_t>* place)
{
d_getatomics[name]=place;
}
-
-void addGetStat(const string& name, function<uint64_t ()> f )
+static void addGetStat(const string& name, function<uint64_t ()> f )
{
d_get64bitmembers[name]=f;
}
-
std::atomic<unsigned long>* getDynMetric(const std::string& str)
{
Lock l(&d_dynmetricslock);
static uint64_t* pleaseDump(int fd)
{
- return new uint64_t(t_RC->doDump(fd) + dumpNegCache(t_sstorage->negcache, fd) + t_packetCache->doDump(fd));
+ return new uint64_t(t_RC->doDump(fd) + dumpNegCache(SyncRes::t_sstorage.negcache, fd) + t_packetCache->doDump(fd));
}
static uint64_t* pleaseDumpNSSpeeds(int fd)
{
- return new uint64_t(t_RC->doDumpNSSpeeds(fd));
+ return new uint64_t(SyncRes::doDumpNSSpeeds(fd));
}
template<typename T>
try {
total = broadcastAccFunction<uint64_t>(boost::bind(pleaseDumpNSSpeeds, fd));
}
- catch(...){}
+ catch(std::exception& e)
+ {
+ close(fd);
+ return "error dumping NS speeds: "+string(e.what())+"\n";
+ }
+ catch(PDNSException& e)
+ {
+ close(fd);
+ return "error dumping NS speeds: "+e.reason+"\n";
+ }
close(fd);
return "dumped "+std::to_string(total)+" records\n";
return "done\n";
}
+template<typename T>
+string doDumpRPZ(T begin, T end)
+{
+ T i=begin;
+
+ if (i == end) {
+ return "No zone name specified\n";
+ }
+ string zoneName = *i;
+ i++;
+
+ if (i == end) {
+ return "No file name specified\n";
+ }
+ string fname = *i;
+
+ auto luaconf = g_luaconfs.getLocal();
+ const auto zone = luaconf->dfe.getZone(zoneName);
+ if (!zone) {
+ return "No RPZ zone named "+zoneName+"\n";
+ }
+
+ int fd = open(fname.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0660);
+
+ if(fd < 0) {
+ return "Error opening dump file for writing: "+string(strerror(errno))+"\n";
+ }
+
+ FILE* fp = fdopen(fd, "w");
+ if (!fp) {
+ close(fd);
+ return "Error converting file descriptor: "+string(strerror(errno))+"\n";
+ }
+
+ zone->dump(fp);
+ fclose(fp);
+
+ return "done\n";
+}
+
uint64_t* pleaseWipeCache(const DNSName& canon, bool subtree)
{
return new uint64_t(t_RC->doWipeCache(canon, subtree));
uint64_t* pleaseWipeAndCountNegCache(const DNSName& canon, bool subtree)
{
- uint64_t ret = t_sstorage->negcache.wipe(canon, subtree);
+ uint64_t ret = SyncRes::wipeNegCache(canon, subtree);
return new uint64_t(ret);
}
g_luaconfs.modify([who, why](LuaConfigItems& lci) {
lci.negAnchors[who] = why;
});
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, who, true));
broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, who, true));
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, who, true));
return "Added Negative Trust Anchor for " + who.toLogString() + " with reason '" + why + "'\n";
}
g_luaconfs.modify([entry](LuaConfigItems& lci) {
lci.negAnchors.erase(entry);
});
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, entry, true));
broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, entry, true));
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, entry, true));
if (!first) {
first = false;
removed += ",";
auto ds = unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make(what)));
lci.dsAnchors[who].insert(*ds);
});
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, who, true));
broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, who, true));
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, who, true));
L<<Logger::Warning<<endl;
return "Added Trust Anchor for " + who.toStringRootDot() + " with data " + what + "\n";
}
g_luaconfs.modify([entry](LuaConfigItems& lci) {
lci.dsAnchors.erase(entry);
});
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, entry, true));
broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, entry, true));
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, entry, true));
if (!first) {
first = false;
removed += ",";
return "New minimum TTL: " + std::to_string(SyncRes::s_minimumTTL) + "\n";
}
+template<typename T>
+string setMaxCacheEntries(T begin, T end)
+{
+ if(end-begin != 1)
+ return "Need to supply new cache size\n";
+ g_maxCacheEntries = pdns_stou(*begin);
+ return "New max cache entries: " + std::to_string(g_maxCacheEntries) + "\n";
+}
+
+template<typename T>
+string setMaxPacketCacheEntries(T begin, T end)
+{
+ if(end-begin != 1)
+ return "Need to supply new packet cache size\n";
+ g_maxPacketCacheEntries = pdns_stou(*begin);
+ return "New max packetcache entries: " + std::to_string(g_maxPacketCacheEntries) + "\n";
+}
+
static uint64_t getSysTimeMsec()
{
{
ostringstream ostr;
- ostr << MT->d_waiters.size() <<" currently outstanding questions\n";
+ ostr << getMT()->d_waiters.size() <<" currently outstanding questions\n";
boost::format fmt("%1% %|40t|%2% %|47t|%3% %|63t|%4% %|68t|%5%\n");
ostr << (fmt % "qname" % "qtype" % "remote" % "tcp" % "chained");
- int n=0;
- for(MT_t::waiters_t::iterator mthread=MT->d_waiters.begin(); mthread!=MT->d_waiters.end() && n < 100; ++mthread, ++n) {
- const PacketID& pident = mthread->key;
+ unsigned int n=0;
+ for(const auto& mthread : getMT()->d_waiters) {
+ const PacketID& pident = mthread.key;
ostr << (fmt
% pident.domain.toLogString() /* ?? */ % DNSRecordContent::NumberToType(pident.type)
% pident.remote.toString() % (pident.sock ? 'Y' : 'n')
% (pident.fd == -1 ? 'Y' : 'n')
);
+ ++n;
+ if (n >= 100)
+ break;
}
ostr <<" - done\n";
return new string(ostr.str());
uint64_t* pleaseGetThrottleSize()
{
- return new uint64_t(t_sstorage ? t_sstorage->throttle.size() : 0);
+ return new uint64_t(SyncRes::getThrottledServersSize());
}
static uint64_t getThrottleSize()
uint64_t* pleaseGetNegCacheSize()
{
- uint64_t tmp=(t_sstorage ? t_sstorage->negcache.size() : 0);
+ uint64_t tmp=(SyncRes::getNegCacheSize());
return new uint64_t(tmp);
}
uint64_t* pleaseGetFailedHostsSize()
{
- uint64_t tmp=(t_sstorage ? t_sstorage->fails.size() : 0);
+ uint64_t tmp=(SyncRes::getThrottledServersSize());
return new uint64_t(tmp);
}
uint64_t getFailedHostsSize()
uint64_t* pleaseGetNsSpeedsSize()
{
- return new uint64_t(t_sstorage ? t_sstorage->nsSpeeds.size() : 0);
+ return new uint64_t(SyncRes::getNSSpeedsSize());
}
uint64_t getNsSpeedsSize()
uint64_t* pleaseGetConcurrentQueries()
{
- return new uint64_t(MT ? MT->numProcesses() : 0);
+ return new uint64_t(getMT() ? getMT()->numProcesses() : 0);
}
static uint64_t getConcurrentQueries()
void registerAllStats()
{
- static bool s_init = false;
- if(s_init)
+ static std::atomic_flag s_init = ATOMIC_FLAG_INIT;
+ if(s_init.test_and_set())
return;
- s_init=true;
addGetStat("questions", &g_stats.qcounter);
addGetStat("ipv6-questions", &g_stats.ipv6qcounter);
addGetStat("cache-hits", doGetCacheHits);
addGetStat("cache-misses", doGetCacheMisses);
- addGetStat("cache-entries", doGetCacheSize);
+ addGetStat("cache-entries", doGetCacheSize);
+ addGetStat("max-cache-entries", []() { return g_maxCacheEntries.load(); });
+ addGetStat("max-packetcache-entries", []() { return g_maxPacketCacheEntries.load();});
addGetStat("cache-bytes", doGetCacheBytes);
addGetStat("packetcache-hits", doGetPacketCacheHits);
addGetStat("client-parse-errors", &g_stats.clientParseError);
addGetStat("server-parse-errors", &g_stats.serverParseError);
addGetStat("too-old-drops", &g_stats.tooOldDrops);
+ addGetStat("query-pipe-full-drops", &g_stats.queryPipeFullDrops);
addGetStat("answers0-1", &g_stats.answers0_1);
addGetStat("answers1-10", &g_stats.answers1_10);
addGetStat("answers100-1000", &g_stats.answers100_1000);
addGetStat("answers-slow", &g_stats.answersSlow);
+ addGetStat("x-ourtime0-1", &g_stats.ourtime0_1);
+ addGetStat("x-ourtime1-2", &g_stats.ourtime1_2);
+ addGetStat("x-ourtime2-4", &g_stats.ourtime2_4);
+ addGetStat("x-ourtime4-8", &g_stats.ourtime4_8);
+ addGetStat("x-ourtime8-16", &g_stats.ourtime8_16);
+ addGetStat("x-ourtime16-32", &g_stats.ourtime16_32);
+ addGetStat("x-ourtime-slow", &g_stats.ourtimeSlow);
+
addGetStat("auth4-answers0-1", &g_stats.auth4Answers0_1);
addGetStat("auth4-answers1-10", &g_stats.auth4Answers1_10);
addGetStat("auth4-answers10-100", &g_stats.auth4Answers10_100);
addGetStat("qa-latency", doGetAvgLatencyUsec);
+ addGetStat("x-our-latency", []() { return g_stats.avgLatencyOursUsec; });
addGetStat("unexpected-packets", &g_stats.unexpectedCount);
addGetStat("case-mismatches", &g_stats.caseMismatchCount);
addGetStat("spoof-prevents", &g_stats.spoofCount);
addGetStat("outgoing-timeouts", &SyncRes::s_outgoingtimeouts);
addGetStat("outgoing4-timeouts", &SyncRes::s_outgoing4timeouts);
addGetStat("outgoing6-timeouts", &SyncRes::s_outgoing6timeouts);
+ addGetStat("auth-zone-queries", &SyncRes::s_authzonequeries);
addGetStat("tcp-outqueries", &SyncRes::s_tcpoutqueries);
addGetStat("all-outqueries", &SyncRes::s_outqueries);
addGetStat("ipv6-outqueries", &g_stats.ipv6queries);
addGetStat("dont-outqueries", &SyncRes::s_dontqueries);
addGetStat("throttled-out", &SyncRes::s_throttledqueries);
addGetStat("unreachables", &SyncRes::s_unreachables);
+ addGetStat("ecs-queries", &SyncRes::s_ecsqueries);
+ addGetStat("ecs-responses", &SyncRes::s_ecsresponses);
addGetStat("chain-resends", &g_stats.chainResends);
addGetStat("tcp-clients", boost::bind(TCPConnection::getCurrentConnections));
"dump-cache <filename> dump cache contents to the named file\n"
"dump-edns [status] <filename> dump EDNS status to the named file\n"
"dump-nsspeeds <filename> dump nsspeeds statistics to the named file\n"
+"dump-rpz <zone name> <filename> dump the content of a RPZ zone to the named file\n"
"get [key1] [key2] .. get specific statistics\n"
"get-all get all statistics\n"
"get-ntas get all configured Negative Trust Anchors\n"
"reload-lua-script [filename] (re)load Lua script\n"
"reload-lua-config [filename] (re)load Lua configuration file\n"
"reload-zones reload all auth and forward zones\n"
+"set-max-cache-entries value set new maximum cache size\n"
+"set-max-packetcache-entries val set new maximum packet cache size\n"
"set-minimum-ttl value set minimum-ttl-override\n"
"set-carbon-server set a carbon server for telemetry\n"
"set-dnssec-log-bogus SETTING enable (SETTING=yes) or disable (SETTING=no) logging of DNSSEC validation failures\n"
if(cmd=="get-all")
return getAllStats();
- if(cmd=="get")
+ if(cmd=="get")
return doGet(begin, end);
-
- if(cmd=="get-parameter")
+
+ if(cmd=="get-parameter")
return doGetParameter(begin, end);
if(cmd=="quit") {
if(cmd=="version") {
return getPDNSVersion()+"\n";
}
-
+
if(cmd=="quit-nicely") {
*command=&doExitNicely;
return "bye nicely\n";
- }
+ }
- if(cmd=="dump-cache")
+ if(cmd=="dump-cache")
return doDumpCache(begin, end);
- if(cmd=="dump-ednsstatus" || cmd=="dump-edns")
+ if(cmd=="dump-ednsstatus" || cmd=="dump-edns")
return doDumpEDNSStatus(begin, end);
if(cmd=="dump-nsspeeds")
return doDumpNSSpeeds(begin, end);
- if(cmd=="wipe-cache" || cmd=="flushname")
+ if(cmd=="dump-rpz") {
+ return doDumpRPZ(begin, end);
+ }
+
+ if(cmd=="wipe-cache" || cmd=="flushname")
return doWipeCache(begin, end);
- if(cmd=="reload-lua-script")
+ if(cmd=="reload-lua-script")
return doQueueReloadLuaScript(begin, end);
if(cmd=="reload-lua-config") {
::arg().set("lua-config-file") = *begin;
try {
- loadRecursorLuaConfig(::arg()["lua-config-file"], false);
+ luaConfigDelayedThreads delayedLuaThreads;
+ loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads);
+ startLuaConfigDelayedThreads(delayedLuaThreads);
L<<Logger::Warning<<"Reloaded Lua configuration file '"<<::arg()["lua-config-file"]<<"', requested via control channel"<<endl;
return "Reloaded Lua configuration file '"+::arg()["lua-config-file"]+"'\n";
}
}
}
- if(cmd=="set-carbon-server")
+ if(cmd=="set-carbon-server")
return doSetCarbonServer(begin, end);
- if(cmd=="trace-regex")
+ if(cmd=="trace-regex")
return doTraceRegex(begin, end);
if(cmd=="unload-lua-script") {
return reloadAuthAndForwards();
}
+ if(cmd=="set-max-cache-entries") {
+ return setMaxCacheEntries(begin, end);
+ }
+ if(cmd=="set-max-packetcache-entries") {
+ return setMaxPacketCacheEntries(begin, end);
+ }
+
if(cmd=="set-minimum-ttl") {
return setMinimumTTL(begin, end);
}