return new uint64_t(SyncRes::doDumpThrottleMap(fd));
}
+static uint64_t* pleaseDumpFailedServers(int fd)
+{
+ return new uint64_t(SyncRes::doDumpFailedServers(fd));
+}
+
template<typename T>
static string doDumpNSSpeeds(T begin, T end)
{
return "dumped "+std::to_string(total)+" records\n";
}
-uint64_t* pleaseWipeCache(const DNSName& canon, bool subtree)
+template<typename T>
+static string doDumpFailedServers(T begin, T end)
{
- return new uint64_t(t_RC->doWipeCache(canon, subtree));
+ T i=begin;
+ string fname;
+
+ if(i!=end)
+ fname=*i;
+
+ int fd=open(fname.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0660);
+ if(fd < 0)
+ return "Error opening dump file for writing: "+stringerror()+"\n";
+ uint64_t total = 0;
+ try {
+ total = broadcastAccFunction<uint64_t>(boost::bind(pleaseDumpFailedServers, fd));
+ }
+ catch(...){}
+
+ close(fd);
+ return "dumped "+std::to_string(total)+" records\n";
}
-uint64_t* pleaseWipePacketCache(const DNSName& canon, bool subtree)
+uint64_t* pleaseWipeCache(const DNSName& canon, bool subtree, uint16_t qtype)
{
- return new uint64_t(t_packetCache->doWipePacketCache(canon,0xffff, subtree));
+ return new uint64_t(t_RC->doWipeCache(canon, subtree, qtype));
+}
+
+uint64_t* pleaseWipePacketCache(const DNSName& canon, bool subtree, uint16_t qtype)
+{
+ return new uint64_t(t_packetCache->doWipePacketCache(canon, qtype, subtree));
}
template<typename T>
-static string doWipeCache(T begin, T end)
+static string doWipeCache(T begin, T end, uint16_t qtype)
{
vector<pair<DNSName, bool> > toWipe;
for(T i=begin; i != end; ++i) {
int count=0, pcount=0, countNeg=0;
for (auto wipe : toWipe) {
- count+= broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, wipe.first, wipe.second));
- pcount+= broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, wipe.first, wipe.second));
+ count+= broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, wipe.first, wipe.second, qtype));
+ pcount+= broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, wipe.first, wipe.second, qtype));
countNeg+=broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, wipe.first, wipe.second));
}
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(pleaseWipeCache, who, true, 0xffff));
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, who, true, 0xffff));
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(pleaseWipeCache, entry, true, 0xffff));
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, entry, true, 0xffff));
broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, entry, true));
if (!first) {
first = false;
auto ds=std::dynamic_pointer_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(pleaseWipeCache, who, true, 0xffff));
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, who, true, 0xffff));
broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, who, true));
g_log<<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(pleaseWipeCache, entry, true, 0xffff));
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, entry, true, 0xffff));
broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, entry, true));
if (!first) {
first = false;
ret = (ru.ru_utime.tv_sec*1000ULL + ru.ru_utime.tv_usec/1000);
ret += (ru.ru_stime.tv_sec*1000ULL + ru.ru_stime.tv_usec/1000);
#endif
- return new ThreadTimes{ret};
+ return new ThreadTimes{ret, vector<uint64_t>()};
}
/* Next up, when you want msec data for a specific thread, we check
return broadcastAccFunction<uint64_t>(pleaseGetNsSpeedsSize);
}
+uint64_t* pleaseGetFailedServersSize()
+{
+ return new uint64_t(SyncRes::getFailedServersSize());
+}
+
+uint64_t* pleaseGetEDNSStatusesSize()
+{
+ return new uint64_t(SyncRes::getEDNSStatusesSize());
+}
+
uint64_t* pleaseGetConcurrentQueries()
{
return new uint64_t(getMT() ? getMT()->numProcesses() : 0);
addGetStat("ipv6-outqueries", &g_stats.ipv6queries);
addGetStat("throttled-outqueries", &SyncRes::s_throttledqueries);
addGetStat("dont-outqueries", &SyncRes::s_dontqueries);
+ addGetStat("qname-min-fallback-success", &SyncRes::s_qnameminfallbacksuccess);
addGetStat("throttled-out", &SyncRes::s_throttledqueries);
addGetStat("unreachables", &SyncRes::s_unreachables);
addGetStat("ecs-queries", &SyncRes::s_ecsqueries);
addGetStat("user-msec", getUserTimeMsec);
addGetStat("sys-msec", getSysTimeMsec);
+#ifdef __linux__
+ addGetStat("cpu-iowait", boost::bind(getCPUIOWait, string()));
+ addGetStat("cpu-steal", boost::bind(getCPUSteal, string()));
+#endif
+
for(unsigned int n=0; n < g_numThreads; ++n)
addGetStat("cpu-msec-thread-"+std::to_string(n), boost::bind(&doGetThreadCPUMsec, n));
}
}
-static void doExitGeneric(bool nicely)
+void doExitGeneric(bool nicely)
{
g_log<<Logger::Error<<"Exiting on user request"<<endl;
extern RecursorControlChannel s_rcc;
- s_rcc.~RecursorControlChannel();
+ s_rcc.~RecursorControlChannel();
extern string s_pidfname;
- if(!s_pidfname.empty())
+ if(!s_pidfname.empty())
unlink(s_pidfname.c_str()); // we can at least try..
- if(nicely)
- exit(1);
- else
+ if(nicely) {
+ RecursorControlChannel::stop = 1;
+ } else {
_exit(1);
+ }
}
-static void doExit()
+void doExit()
{
doExitGeneric(false);
}
-static void doExitNicely()
+void doExitNicely()
{
doExitGeneric(true);
}
dnt.add(d);
}
- g_dontThrottleNames.setState(dnt);
+ g_dontThrottleNames.setState(std::move(dnt));
ret += " to the list of nameservers that may not be throttled";
g_log<<Logger::Info<<ret<<", requested via control channel"<<endl;
dnt.addMask(t);
}
- g_dontThrottleNetmasks.setState(dnt);
+ g_dontThrottleNetmasks.setState(std::move(dnt));
ret += " to the list of nameserver netmasks that may not be throttled";
g_log<<Logger::Info<<ret<<", requested via control channel"<<endl;
if (begin + 1 == end && *begin == "*"){
SuffixMatchNode smn;
- g_dontThrottleNames.setState(smn);
+ g_dontThrottleNames.setState(std::move(smn));
string ret = "Cleared list of nameserver names that may not be throttled";
g_log<<Logger::Warning<<ret<<", requested via control channel"<<endl;
return ret + "\n";
dnt.remove(name);
}
- g_dontThrottleNames.setState(dnt);
+ g_dontThrottleNames.setState(std::move(dnt));
ret += " from the list of nameservers that may not be throttled";
g_log<<Logger::Info<<ret<<", requested via control channel"<<endl;
if (begin + 1 == end && *begin == "*"){
auto nmg = g_dontThrottleNetmasks.getCopy();
nmg.clear();
- g_dontThrottleNetmasks.setState(nmg);
+ g_dontThrottleNetmasks.setState(std::move(nmg));
string ret = "Cleared list of nameserver addresses that may not be throttled";
g_log<<Logger::Warning<<ret<<", requested via control channel"<<endl;
dnt.deleteMask(mask);
}
- g_dontThrottleNetmasks.setState(dnt);
+ g_dontThrottleNetmasks.setState(std::move(dnt));
ret += " from the list of nameservers that may not be throttled";
g_log<<Logger::Info<<ret<<", requested via control channel"<<endl;
"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"
-"dump-throttlemap <filename> dump the contents of the throttle to the named file\n"
+"dump-throttlemap <filename> dump the contents of the throttle map to the named file\n"
+"dump-failedservers <filename> dump the failed servers to the named file\n"
"get [key1] [key2] .. get specific statistics\n"
"get-all get all statistics\n"
"get-dont-throttle-names get the list of names that are not allowed to be throttled\n"
"top-bogus-remotes show top remotes receiving bogus answers\n"
"unload-lua-script unload Lua script\n"
"version return Recursor version number\n"
-"wipe-cache domain0 [domain1] .. wipe domain data from cache\n";
+"wipe-cache domain0 [domain1] .. wipe domain data from cache\n"
+"wipe-cache-typed type domain0 [domain1] .. wipe domain data with qtype from cache\n";
if(cmd=="get-all")
return getAllStats();
if(cmd=="dump-nsspeeds")
return doDumpNSSpeeds(begin, end);
+ if(cmd=="dump-failedservers")
+ return doDumpFailedServers(begin, end);
+
if(cmd=="dump-rpz") {
return doDumpRPZ(begin, end);
}
return doDumpThrottleMap(begin, end);
if(cmd=="wipe-cache" || cmd=="flushname")
- return doWipeCache(begin, end);
+ return doWipeCache(begin, end, 0xffff);
+
+ if(cmd=="wipe-cache-typed") {
+ uint16_t qtype = QType::chartocode(begin->c_str());
+ ++begin;
+ return doWipeCache(begin, end, qtype);
+ }
if(cmd=="reload-lua-script")
return doQueueReloadLuaScript(begin, end);