}
// Generic dump to file command
-static RecursorControlChannel::Answer doDumpToFile(int s, uint64_t* (*function)(int s), const string& name)
+static RecursorControlChannel::Answer doDumpToFile(int s, uint64_t* (*function)(int s), const string& name, bool threads = true)
{
auto fdw = getfd(s);
uint64_t total = 0;
try {
- int fd = fdw;
- total = broadcastAccFunction<uint64_t>([function, fd] { return function(fd); });
+ if (threads) {
+ int fd = fdw;
+ total = broadcastAccFunction<uint64_t>([function, fd] { return function(fd); });
+ } else {
+ auto ret = function(fdw);
+ total = *ret;
+ delete ret;
+ }
}
catch (std::exception& e) {
return {1, name + ": error dumping data: " + string(e.what()) + "\n"};
return doDumpToFile(s, pleaseDumpNSSpeeds, cmd);
}
if (cmd == "dump-failedservers") {
- return doDumpToFile(s, pleaseDumpFailedServers, cmd);
+ return doDumpToFile(s, pleaseDumpFailedServers, cmd, false);
}
if (cmd == "dump-rpz") {
return doDumpRPZ(s, begin, end);
return doDumpToFile(s, pleaseDumpThrottleMap, cmd);
}
if (cmd == "dump-non-resolving") {
- return doDumpToFile(s, pleaseDumpNonResolvingNS, cmd);
+ return doDumpToFile(s, pleaseDumpNonResolvingNS, cmd, false);
}
if (cmd == "wipe-cache" || cmd == "flushname") {
return {0, doWipeCache(begin, end, 0xffff)};
string SyncRes::s_serverID;
SyncRes::LogMode SyncRes::s_lm;
const std::unordered_set<QType> SyncRes::s_redirectionQTypes = {QType::CNAME, QType::DNAME};
+LockGuarded<fails_t<ComboAddress>> SyncRes::s_fails;
+LockGuarded<fails_t<DNSName>> SyncRes::s_nonresolving;
unsigned int SyncRes::s_maxnegttl;
unsigned int SyncRes::s_maxbogusttl;
fprintf(fp.get(), "; remote IP\tcount\ttimestamp\n");
uint64_t count=0;
- for(const auto& i : t_sstorage.fails.getMap())
+ for(const auto& i : s_fails.lock()->getMap())
{
count++;
char tmp[26];
fprintf(fp.get(), "; name\tcount\ttimestamp\n");
uint64_t count=0;
- for(const auto& i : t_sstorage.nonresolving.getMap())
+ for(const auto& i : s_nonresolving.lock()->getMap())
{
count++;
char tmp[26];
size_t nonresolvingfails = 0;
if (!tns->first.empty()) {
if (s_nonresolvingnsmaxfails > 0) {
- nonresolvingfails = t_sstorage.nonresolving.value(tns->first);
+ nonresolvingfails = s_nonresolving.lock()->value(tns->first);
if (nonresolvingfails >= s_nonresolvingnsmaxfails) {
LOG(prefix<<qname<<": NS "<<tns->first<< " in non-resolving map, skipping"<<endl);
return result;
if (s_nonresolvingnsmaxfails > 0 && d_outqueries > oldOutQueries) {
auto dontThrottleNames = g_dontThrottleNames.getLocal();
if (!dontThrottleNames->check(tns->first)) {
- t_sstorage.nonresolving.incr(tns->first, d_now);
+ s_nonresolving.lock()->incr(tns->first, d_now);
}
}
throw ex;
if (result.empty()) {
auto dontThrottleNames = g_dontThrottleNames.getLocal();
if (!dontThrottleNames->check(tns->first)) {
- t_sstorage.nonresolving.incr(tns->first, d_now);
+ s_nonresolving.lock()->incr(tns->first, d_now);
}
}
else if (nonresolvingfails > 0) {
// Succeeding resolve, clear memory of recent failures
- t_sstorage.nonresolving.clear(tns->first);
+ s_nonresolving.lock()->clear(tns->first);
}
}
pierceDontQuery=false;
t_sstorage.nsSpeeds[nsName.empty()? DNSName(remoteIP.toStringWithPort()) : nsName].submit(remoteIP, 1000000, d_now); // 1 sec
// code below makes sure we don't filter COM or the root
- if (s_serverdownmaxfails > 0 && (auth != g_rootdnsname) && t_sstorage.fails.incr(remoteIP, d_now) >= s_serverdownmaxfails) {
+ if (s_serverdownmaxfails > 0 && (auth != g_rootdnsname) && s_fails.lock()->incr(remoteIP, d_now) >= s_serverdownmaxfails) {
LOG(prefix<<qname<<": Max fails reached resolving on "<< remoteIP.toString() <<". Going full throttle for "<< s_serverdownthrottletime <<" seconds" <<endl);
// mark server as down
t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(remoteIP, "", 0), s_serverdownthrottletime, 10000);
/* this server sent a valid answer, mark it backup up if it was down */
if(s_serverdownmaxfails > 0) {
- t_sstorage.fails.clear(remoteIP);
+ s_fails.lock()->clear(remoteIP);
}
if (lwr.d_tcbit) {
class fails_t : public boost::noncopyable
{
public:
- typedef unsigned long long counter_t;
+ typedef uint64_t counter_t;
struct value_t {
value_t(const T &a) : key(a) {}
T key;
ordered_non_unique<tag<time_t>, member<value_t, time_t, &value_t::last>>
>> cont_t;
- cont_t getMap() const {
+ const cont_t& getMap() const {
return d_cont;
}
counter_t value(const T& t) const
};
+ static LockGuarded<fails_t<ComboAddress>> s_fails;
+ static LockGuarded<fails_t<DNSName>> s_nonresolving;
+
struct ThreadLocalStorage {
nsspeeds_t nsSpeeds;
throttle_t throttle;
ednsstatus_t ednsstatus;
- fails_t<ComboAddress> fails;
- fails_t<DNSName> nonresolving;
std::shared_ptr<domainmap_t> domainmap;
};
}
static uint64_t getFailedServersSize()
{
- return t_sstorage.fails.size();
+ return s_fails.lock()->size();
}
static uint64_t getNonResolvingNSSize()
{
- return t_sstorage.nonresolving.size();
+ return s_nonresolving.lock()->size();
}
static void clearFailedServers()
{
- t_sstorage.fails.clear();
+ s_fails.lock()->clear();
}
static void clearNonResolvingNS()
{
- t_sstorage.nonresolving.clear();
+ s_nonresolving.lock()->clear();
}
static void pruneFailedServers(time_t cutoff)
{
- t_sstorage.fails.prune(cutoff);
+ s_fails.lock()->prune(cutoff);
}
static unsigned long getServerFailsCount(const ComboAddress& server)
{
- return t_sstorage.fails.value(server);
+ return s_fails.lock()->value(server);
}
static void pruneNonResolving(time_t cutoff)
{
- t_sstorage.nonresolving.prune(cutoff);
+ s_nonresolving.lock()->prune(cutoff);
}
static void setDomainMap(std::shared_ptr<domainmap_t> newMap)
{