Consistently move to float for nsspeeds, plus some minor cleanup.
static void houseKeeping(void *)
{
- static thread_local time_t last_rootupdate, last_prune, last_secpoll, last_trustAnchorUpdate{0};
+ static thread_local time_t last_rootupdate, last_secpoll, last_trustAnchorUpdate{0};
+ static thread_local timeval last_prune;
static thread_local int cleanCounter=0;
static thread_local bool s_running; // houseKeeping can get suspended in secpoll, and be restarted, which makes us do duplicate work
auto luaconfsLocal = g_luaconfs.getLocal();
}
s_running=true;
- struct timeval now;
- Utility::gettimeofday(&now, 0);
-
- if(now.tv_sec - last_prune > (time_t)(5 + t_id)) {
+ struct timeval now, past;
+ Utility::gettimeofday(&now, nullptr);
+ past = now;
+ past.tv_sec -= 5;
+ if (last_prune < past) {
t_RC->doPrune(g_maxCacheEntries / g_numThreads); // this function is local to a thread, so fine anyhow
t_packetCache->doPruneTo(g_maxPacketCacheEntries / g_numWorkerThreads);
SyncRes::pruneNegCache(g_maxCacheEntries / (g_numWorkerThreads * 10));
+ time_t limit;
if(!((cleanCounter++)%40)) { // this is a full scan!
- time_t limit=now.tv_sec-300;
+ limit=now.tv_sec-300;
SyncRes::pruneNSSpeeds(limit);
- limit = now.tv_sec - SyncRes::s_serverdownthrottletime * 10;
- SyncRes::pruneFailedServers(limit);
- limit = now.tv_sec - 2*3600;
- SyncRes::pruneEDNSStatuses(limit);
}
- last_prune=time(0);
+ limit = now.tv_sec - SyncRes::s_serverdownthrottletime * 10;
+ SyncRes::pruneFailedServers(limit);
+ limit = now.tv_sec - 2*3600;
+ SyncRes::pruneEDNSStatuses(limit);
+ SyncRes::pruneThrottledServers();
+ Utility::gettimeofday(&last_prune, nullptr);
}
if(now.tv_sec - last_rootupdate > 7200) {
/* make pdns-public-ns2.powerdns.com. the fastest NS, with its IPv6 address faster than the IPV4 one,
then pdns-public-ns1.powerdns.com. on IPv4 */
- SyncRes::submitNSSpeed(DNSName("pdns-public-ns1.powerdns.com."), ComboAddress("192.0.2.1:53"), 100, &now);
- SyncRes::submitNSSpeed(DNSName("pdns-public-ns1.powerdns.com."), ComboAddress("[2001:DB8::1]:53"), 10000, &now);
- SyncRes::submitNSSpeed(DNSName("pdns-public-ns2.powerdns.com."), ComboAddress("192.0.2.2:53"), 10, &now);
- SyncRes::submitNSSpeed(DNSName("pdns-public-ns2.powerdns.com."), ComboAddress("[2001:DB8::2]:53"), 1, &now);
- SyncRes::submitNSSpeed(DNSName("pdns-public-ns3.powerdns.com."), ComboAddress("192.0.2.3:53"), 10000, &now);
- SyncRes::submitNSSpeed(DNSName("pdns-public-ns3.powerdns.com."), ComboAddress("[2001:DB8::3]:53"), 10000, &now);
+ SyncRes::submitNSSpeed(DNSName("pdns-public-ns1.powerdns.com."), ComboAddress("192.0.2.1:53"), 100, now);
+ SyncRes::submitNSSpeed(DNSName("pdns-public-ns1.powerdns.com."), ComboAddress("[2001:DB8::1]:53"), 10000, now);
+ SyncRes::submitNSSpeed(DNSName("pdns-public-ns2.powerdns.com."), ComboAddress("192.0.2.2:53"), 10, now);
+ SyncRes::submitNSSpeed(DNSName("pdns-public-ns2.powerdns.com."), ComboAddress("[2001:DB8::2]:53"), 1, now);
+ SyncRes::submitNSSpeed(DNSName("pdns-public-ns3.powerdns.com."), ComboAddress("192.0.2.3:53"), 10000, now);
+ SyncRes::submitNSSpeed(DNSName("pdns-public-ns3.powerdns.com."), ComboAddress("[2001:DB8::3]:53"), 10000, now);
vector<DNSRecord> ret;
int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
for(const auto& eds : t_sstorage.ednsstatus) {
count++;
char tmp[26];
- fprintf(fp.get(), "%s\t%d\t%s", eds.first.toString().c_str(), (int)eds.second.mode, ctime_r(&eds.second.modeSetAt, tmp));
+ fprintf(fp.get(), "%s\t%d\t%s", eds.address.toString().c_str(), (int)eds.mode, ctime_r(&eds.modeSetAt, tmp));
}
return count;
}
uint64_t count=0;
const auto& throttleMap = t_sstorage.throttle.getThrottleMap();
- for(const auto& i : throttleMap)
+ for(const auto i : throttleMap)
{
count++;
char tmp[26];
// remote IP, dns name, qtype, count, ttd
- fprintf(fp.get(), "%s\t%s\t%d\t%u\t%s", i.first.get<0>().toString().c_str(), i.first.get<1>().toLogString().c_str(), i.first.get<2>(), i.second.count, ctime_r(&i.second.ttd, tmp));
+ fprintf(fp.get(), "%s\t%s\t%d\t%u\t%s", i.thing.get<0>().toString().c_str(), i.thing.get<1>().toLogString().c_str(), i.thing.get<2>(), i.count, ctime_r(&i.ttd, tmp));
}
return count;
{
count++;
char tmp[26];
- ctime_r(&i.second.last, tmp);
- fprintf(fp.get(), "%s\t%lld\t%s", i.first.toString().c_str(),
- static_cast<long long>(i.second.value), tmp);
+ ctime_r(&i.last, tmp);
+ fprintf(fp.get(), "%s\t%lld\t%s", i.address.toString().c_str(),
+ static_cast<long long>(i.value), tmp);
}
return count;
If '3', send bare queries
*/
- SyncRes::EDNSStatus* ednsstatus = &t_sstorage.ednsstatus[ip]; // does this include port? YES
-
+ auto ednsstatus = t_sstorage.ednsstatus.insert(ip).first; // does this include port? YES
+ auto &ind = t_sstorage.ednsstatus.get<ComboAddress>();
if (ednsstatus->modeSetAt && ednsstatus->modeSetAt + 3600 < d_now.tv_sec) {
- *ednsstatus = SyncRes::EDNSStatus();
+ t_sstorage.ednsstatus.reset(ind, ednsstatus);
// cerr<<"Resetting EDNS Status for "<<ip.toString()<<endl);
}
- SyncRes::EDNSStatus::EDNSMode *mode = &ednsstatus->mode;
- SyncRes::EDNSStatus::EDNSMode oldmode = *mode;
+ const SyncRes::EDNSStatus::EDNSMode *mode = &ednsstatus->mode;
+ const SyncRes::EDNSStatus::EDNSMode oldmode = *mode;
int EDNSLevel = 0;
auto luaconfsLocal = g_luaconfs.getLocal();
ResolveContext ctx;
ret=asyncresolve(ip, sendQname, type, doTCP, sendRDQuery, EDNSLevel, now, srcmask, ctx, d_outgoingProtobufServers, d_frameStreamServers, luaconfsLocal->outgoingProtobufExportConfig.exportTypes, res, chained);
}
// ednsstatus might be cleared, so do a new lookup
- ednsstatus = &t_sstorage.ednsstatus[ip]; // does this include port? YES
+ ednsstatus = t_sstorage.ednsstatus.insert(ip).first;
mode = &ednsstatus->mode;
if(ret < 0) {
return ret; // transport error, nothing to learn here
else if (*mode == EDNSStatus::UNKNOWN || *mode == EDNSStatus::EDNSOK || *mode == EDNSStatus::EDNSIGNORANT ) {
if(res->d_validpacket && !res->d_haveEDNS && res->d_rcode == RCode::FormErr) {
// cerr<<"Downgrading to NOEDNS because of "<<RCode::to_s(res->d_rcode)<<" for query to "<<ip.toString()<<" for '"<<domain<<"'"<<endl;
- *mode = EDNSStatus::NOEDNS;
+ t_sstorage.ednsstatus.setMode(ind, ednsstatus, EDNSStatus::NOEDNS);
continue;
}
else if(!res->d_haveEDNS) {
if (*mode != EDNSStatus::EDNSIGNORANT) {
- *mode = EDNSStatus::EDNSIGNORANT;
+ t_sstorage.ednsstatus.setMode(ind, ednsstatus, EDNSStatus::EDNSIGNORANT);
// cerr<<"We find that "<<ip.toString()<<" is an EDNS-ignorer for '"<<domain<<"', moving to mode 2"<<endl;
}
}
else {
- *mode = EDNSStatus::EDNSOK;
+ t_sstorage.ednsstatus.setMode(ind, ednsstatus, EDNSStatus::EDNSOK);
// cerr<<"We find that "<<ip.toString()<<" is EDNS OK!"<<endl;
}
}
if (oldmode != *mode || !ednsstatus->modeSetAt)
- ednsstatus->modeSetAt=d_now.tv_sec;
+ t_sstorage.ednsstatus.setTS(ind, ednsstatus, d_now.tv_sec);
// cerr<<"Result: ret="<<ret<<", EDNS-level: "<<EDNSLevel<<", haveEDNS: "<<res->d_haveEDNS<<", new mode: "<<mode<<endl;
return ret;
}
struct speedOrderCA
{
- speedOrderCA(std::map<ComboAddress,double>& speeds): d_speeds(speeds) {}
+ speedOrderCA(std::map<ComboAddress,float>& speeds): d_speeds(speeds) {}
bool operator()(const ComboAddress& a, const ComboAddress& b) const
{
return d_speeds[a] < d_speeds[b];
}
- std::map<ComboAddress, double>& d_speeds;
+ std::map<ComboAddress, float>& d_speeds;
};
/** This function explicitly goes out for A or AAAA addresses
for this nameserver that are no longer in the set, even if there
is only one or none at all in the current set.
*/
- map<ComboAddress, double> speeds;
+ map<ComboAddress, float> speeds;
auto& collection = t_sstorage.nsSpeeds[qname].d_collection;
for(const auto& val: ret) {
- speeds[val] = collection[val].get(&d_now);
+ speeds[val] = collection[val].get(d_now);
}
t_sstorage.nsSpeeds[qname].purge(speeds);
struct speedOrder
{
- bool operator()(const std::pair<DNSName, double> &a, const std::pair<DNSName, double> &b) const
+ bool operator()(const std::pair<DNSName, float> &a, const std::pair<DNSName, float> &b) const
{
return a.second < b.second;
}
};
-inline std::vector<std::pair<DNSName, double>> SyncRes::shuffleInSpeedOrder(NsSet &tnameservers, const string &prefix)
+inline std::vector<std::pair<DNSName, float>> SyncRes::shuffleInSpeedOrder(NsSet &tnameservers, const string &prefix)
{
- std::vector<std::pair<DNSName, double>> rnameservers;
+ std::vector<std::pair<DNSName, float>> rnameservers;
rnameservers.reserve(tnameservers.size());
for(const auto& tns: tnameservers) {
- double speed = t_sstorage.nsSpeeds[tns.first].get(&d_now);
+ float speed = t_sstorage.nsSpeeds[tns.first].get(d_now);
rnameservers.push_back({tns.first, speed});
if(tns.first.empty()) // this was an authoritative OOB zone, don't pollute the nsSpeeds with that
return rnameservers;
inline vector<ComboAddress> SyncRes::shuffleForwardSpeed(const vector<ComboAddress> &rnameservers, const string &prefix, const bool wasRd)
{
vector<ComboAddress> nameservers = rnameservers;
- map<ComboAddress, double> speeds;
+ map<ComboAddress, float> speeds;
for(const auto& val: nameservers) {
- double speed;
+ float speed;
DNSName nsName = DNSName(val.toStringWithPort());
- speed=t_sstorage.nsSpeeds[nsName].get(&d_now);
+ speed=t_sstorage.nsSpeeds[nsName].get(d_now);
speeds[val]=speed;
}
random_shuffle(nameservers.begin(),nameservers.end());
return false;
}
-vector<ComboAddress> SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, std::vector<std::pair<DNSName, double>>::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<std::pair<DNSName, double>>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly)
+vector<ComboAddress> SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, std::vector<std::pair<DNSName, float>>::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<std::pair<DNSName, float>>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly)
{
vector<ComboAddress> result;
if(resolveret != -2 && !chained && !dontThrottle) {
// don't account for resource limits, they are our own fault
// And don't throttle when the IP address is on the dontThrottleNetmasks list or the name is part of dontThrottleNames
- t_sstorage.nsSpeeds[nsName.empty()? DNSName(remoteIP.toStringWithPort()) : nsName].submit(remoteIP, 1000000, &d_now); // 1 sec
+ 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) {
*/
// cout<<"msec: "<<lwr.d_usec/1000.0<<", "<<g_avgLatency/1000.0<<'\n';
- t_sstorage.nsSpeeds[tns->first.empty()? DNSName(remoteIP->toStringWithPort()) : tns->first].submit(*remoteIP, lwr.d_usec, &d_now);
+ t_sstorage.nsSpeeds[tns->first.empty()? DNSName(remoteIP->toStringWithPort()) : tns->first].submit(*remoteIP, lwr.d_usec, d_now);
/* we have received an answer, are we done ? */
bool done = processAnswer(depth, lwr, qname, qtype, auth, wasForwarded, ednsmask, sendRDQuery, nameservers, ret, luaconfsLocal->dfe, &gotNewServers, &rcode, state);
template<class Thing> class Throttle : public boost::noncopyable
{
public:
- Throttle() : d_limit(3), d_ttl(60), d_last_clean(time(nullptr))
- {
- }
- struct entry
+ struct entry_t
{
+ Thing thing;
time_t ttd;
- unsigned int count;
+ mutable unsigned int count;
};
- typedef map<Thing,entry> cont_t;
+ typedef multi_index_container<entry_t,
+ indexed_by<
+ ordered_unique<tag<Thing>, member<entry_t, Thing, &entry_t::thing>>,
+ ordered_non_unique<tag<time_t>, member<entry_t, time_t, &entry_t::ttd>>
+ >> cont_t;
- bool shouldThrottle(time_t now, const Thing& t)
+ bool shouldThrottle(time_t now, const Thing &t)
{
- if(now > d_last_clean + 300 ) {
-
- d_last_clean=now;
- for(typename cont_t::iterator i=d_cont.begin();i!=d_cont.end();) {
- if( i->second.ttd < now) {
- d_cont.erase(i++);
- }
- else
- ++i;
- }
- }
-
- typename cont_t::iterator i=d_cont.find(t);
- if(i==d_cont.end())
+ auto i = d_cont.find(t);
+ if (i == d_cont.end()) {
return false;
- if(now > i->second.ttd || i->second.count == 0) {
+ }
+ if (now > i->ttd || i->count == 0) {
d_cont.erase(i);
return false;
}
- i->second.count--;
+ i->count--;
return true; // still listed, still blocked
}
- void throttle(time_t now, const Thing& t, time_t ttl=0, unsigned int tries=0)
- {
- typename cont_t::iterator i=d_cont.find(t);
- entry e={ now+(ttl ? ttl : d_ttl), tries ? tries : d_limit};
- if(i==d_cont.end()) {
- d_cont[t]=e;
+ void throttle(time_t now, const Thing &t, time_t ttl, unsigned int count)
+ {
+ auto i = d_cont.find(t);
+ time_t ttd = now + ttl;
+ if (i == d_cont.end()) {
+ entry_t e = { t, ttd, count };
+ d_cont.insert(e);
+ } else if (i->ttd > ttd || i->count < count) { // ????
+ auto &ind = d_cont.template get<Thing>();
+ ind.modify(i, [ttd,count](entry_t &e) { e.ttd = ttd; e.count = count; });
}
- else if(i->second.ttd > e.ttd || (i->second.count) < e.count)
- d_cont[t]=e;
}
- unsigned int size() const
+ size_t size() const
{
- return (unsigned int)d_cont.size();
+ return d_cont.size();
}
- const cont_t& getThrottleMap() const
+ const cont_t &getThrottleMap() const
{
return d_cont;
}
d_cont.clear();
}
+ void prune() {
+ time_t now = time(NULL);
+ auto &ind = d_cont.template get<time_t>();
+ ind.erase(ind.begin(), ind.upper_bound(now));
+ }
+
private:
- unsigned int d_limit;
- time_t d_ttl;
- time_t d_last_clean;
cont_t d_cont;
};
DecayingEwma(const DecayingEwma& orig) = delete;
DecayingEwma & operator=(const DecayingEwma& orig) = delete;
- void submit(int val, const struct timeval* tv)
+ void submit(int val, const struct timeval& now)
{
- struct timeval now=*tv;
-
if(d_needinit) {
d_last=now;
d_lastget=now;
}
}
- float get(const struct timeval* tv)
+ float get(const struct timeval &now)
{
- struct timeval now=*tv;
float diff=makeFloat(d_lastget-now);
d_lastget=now;
float factor=expf(diff/60.0f); // is 1.0 or less
bool d_needinit;
};
-template<class Thing> class Counters : public boost::noncopyable
+class fails_t : public boost::noncopyable
{
public:
typedef unsigned long counter_t;
struct value_t {
- counter_t value;
- time_t last;
+ value_t(const ComboAddress &a) : address(a) {}
+ ComboAddress address;
+ mutable counter_t value{0};
+ time_t last{0};
};
- typedef std::map<Thing, value_t> cont_t;
+
+ typedef multi_index_container<value_t,
+ indexed_by<
+ ordered_unique<tag<ComboAddress>, member<value_t, ComboAddress, &value_t::address>>,
+ ordered_non_unique<tag<time_t>, member<value_t, time_t, &value_t::last>>
+ >> cont_t;
cont_t getMap() const {
return d_cont;
}
- counter_t value(const Thing& t) const
+ counter_t value(const ComboAddress& t) const
{
- typename cont_t::const_iterator i = d_cont.find(t);
+ auto i = d_cont.find(t);
if (i == d_cont.end()) {
return 0;
}
- return i->second.value;
+ return i->value;
}
- counter_t incr(const Thing& t, const struct timeval & now)
+ counter_t incr(const ComboAddress& t, const struct timeval & now)
{
- typename cont_t::iterator i = d_cont.find(t);
+ auto i = d_cont.insert(t).first;
- if (i == d_cont.end()) {
- auto &r = d_cont[t];
- r.value = 1;
- r.last = now.tv_sec;
- return 1;
- }
- else {
- if (i->second.value < std::numeric_limits<counter_t>::max()) {
- i->second.value++;
- }
- i->second.last = now.tv_sec;
- return i->second.value;
+ if (i->value < std::numeric_limits<counter_t>::max()) {
+ i->value++;
}
+ auto &ind = d_cont.get<ComboAddress>();
+ ind.modify(i, [t = now.tv_sec](value_t &val) { val.last = t;});
+ return i->value;
}
- void clear(const Thing& t)
+ void clear(const ComboAddress& a)
{
- typename cont_t::iterator i = d_cont.find(t);
-
- if (i != d_cont.end()) {
- d_cont.erase(i);
- }
+ d_cont.erase(a);
}
void clear()
}
void prune(time_t cutoff) {
- for (auto it = d_cont.begin(); it != d_cont.end(); ) {
- if (it->second.last <= cutoff) {
- it = d_cont.erase(it);
- } else {
- ++it;
- }
- }
+ auto &ind = d_cont.get<time_t>();
+ ind.erase(ind.begin(), ind.upper_bound(cutoff));
}
private:
cont_t d_cont;
};
-
class SyncRes : public boost::noncopyable
{
public:
enum LogMode { LogNone, Log, Store};
typedef std::function<int(const ComboAddress& ip, const DNSName& qdomain, int qtype, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult *lwr, bool* chained)> asyncresolve_t;
- struct EDNSStatus
- {
- time_t modeSetAt{0};
- enum EDNSMode { UNKNOWN=0, EDNSOK=1, EDNSIGNORANT=2, NOEDNS=3 } mode{UNKNOWN};
- };
-
enum class HardenNXD { No, DNSSEC, Yes };
//! This represents a number of decaying Ewmas, used to store performance per nameserver-name.
d_best is filled out with the best address for this collection */
struct DecayingEwmaCollection
{
- void submit(const ComboAddress& remote, int usecs, const struct timeval* now)
+ void submit(const ComboAddress& remote, int usecs, const struct timeval& now)
{
d_collection[remote].submit(usecs, now);
}
- double get(const struct timeval* now)
+ float get(const struct timeval& now)
{
if(d_collection.empty())
return 0;
- double ret=std::numeric_limits<double>::max();
- double tmp;
+ float ret=std::numeric_limits<float>::max();
+ float tmp;
for (auto& entry : d_collection) {
if((tmp = entry.second.get(now)) < ret) {
ret=tmp;
return true;
}
- void purge(const std::map<ComboAddress, double>& keep)
+ void purge(const std::map<ComboAddress, float>& keep)
{
for (auto iter = d_collection.begin(); iter != d_collection.end(); ) {
if (keep.find(iter->first) != keep.end()) {
}
typedef std::map<ComboAddress, DecayingEwma> collection_t;
- collection_t d_collection;
ComboAddress d_best;
+ collection_t d_collection;
};
typedef std::unordered_map<DNSName, DecayingEwmaCollection> nsspeeds_t;
- typedef map<ComboAddress, EDNSStatus> ednsstatus_t;
vState getDSRecords(const DNSName& zone, dsmap_t& ds, bool onlyTA, unsigned int depth, bool bogusOnNXD=true, bool* foundCut=nullptr);
typedef std::unordered_map<DNSName, AuthDomain> domainmap_t;
typedef Throttle<boost::tuple<ComboAddress,DNSName,uint16_t> > throttle_t;
- typedef Counters<ComboAddress> fails_t;
+
+ struct EDNSStatus {
+ EDNSStatus(const ComboAddress &arg) : address(arg) {}
+ ComboAddress address;
+ time_t modeSetAt{0};
+ mutable enum EDNSMode { UNKNOWN=0, EDNSOK=1, EDNSIGNORANT=2, NOEDNS=3 } mode{UNKNOWN};
+ };
+
+ struct ednsstatus_t : public multi_index_container<EDNSStatus,
+ indexed_by<
+ ordered_unique<tag<ComboAddress>, member<EDNSStatus, ComboAddress, &EDNSStatus::address>>,
+ ordered_non_unique<tag<time_t>, member<EDNSStatus, time_t, &EDNSStatus::modeSetAt>>
+ >> {
+ void reset(index<ComboAddress>::type &ind, iterator it) {
+ ind.modify(it, [](EDNSStatus &s) { s.mode = EDNSStatus::EDNSMode::UNKNOWN; s.modeSetAt = 0; });
+ }
+ void setMode(index<ComboAddress>::type &ind, iterator it, EDNSStatus::EDNSMode mode) {
+ it->mode = mode;
+ }
+ void setTS(index<ComboAddress>::type &ind, iterator it, time_t ts) {
+ ind.modify(it, [ts](EDNSStatus &s) { s.modeSetAt = ts; });
+ }
+
+ void prune(time_t cutoff) {
+ auto &ind = get<time_t>();
+ ind.erase(ind.begin(), ind.upper_bound(cutoff));
+ }
+
+ };
struct ThreadLocalStorage {
NegCache negcache;
{
return t_sstorage.nsSpeeds.size();
}
- static void submitNSSpeed(const DNSName& server, const ComboAddress& ca, uint32_t usec, const struct timeval* now)
+ static void submitNSSpeed(const DNSName& server, const ComboAddress& ca, uint32_t usec, const struct timeval& now)
{
t_sstorage.nsSpeeds[server].submit(ca, usec, now);
}
if (it == t_sstorage.ednsstatus.end())
return EDNSStatus::UNKNOWN;
- return it->second.mode;
+ return it->mode;
}
static uint64_t getEDNSStatusesSize()
{
}
static void pruneEDNSStatuses(time_t cutoff)
{
- for (auto it = t_sstorage.ednsstatus.begin(); it != t_sstorage.ednsstatus.end(); ) {
- if (it->second.modeSetAt <= cutoff) {
- it = t_sstorage.ednsstatus.erase(it);
- } else {
- ++it;
- }
- }
+ t_sstorage.ednsstatus.prune(cutoff);
}
static uint64_t getThrottledServersSize()
{
return t_sstorage.throttle.size();
}
+ static void pruneThrottledServers()
+ {
+ t_sstorage.throttle.prune();
+ }
static void clearThrottle()
{
t_sstorage.throttle.clear();
void getBestNSFromCache(const DNSName &qname, const QType &qtype, vector<DNSRecord>&bestns, bool* flawedNSSet, unsigned int depth, set<GetBestNSAnswer>& beenthere);
DNSName getBestNSNamesFromCache(const DNSName &qname, const QType &qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, set<GetBestNSAnswer>&beenthere);
- inline vector<std::pair<DNSName, double>> shuffleInSpeedOrder(NsSet &nameservers, const string &prefix);
+ inline vector<std::pair<DNSName, float>> shuffleInSpeedOrder(NsSet &nameservers, const string &prefix);
inline vector<ComboAddress> shuffleForwardSpeed(const vector<ComboAddress> &rnameservers, const string &prefix, const bool wasRd);
bool moreSpecificThan(const DNSName& a, const DNSName &b) const;
vector<ComboAddress> getAddrs(const DNSName &qname, unsigned int depth, set<GetBestNSAnswer>& beenthere, bool cacheOnly);
bool nameserverIPBlockedByRPZ(const DNSFilterEngine& dfe, const ComboAddress&);
bool throttledOrBlocked(const std::string& prefix, const ComboAddress& remoteIP, const DNSName& qname, const QType& qtype, bool pierceDontQuery);
- vector<ComboAddress> retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, vector<std::pair<DNSName, double>>::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<std::pair<DNSName, double>>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly);
+ vector<ComboAddress> retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, vector<std::pair<DNSName, float>>::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<std::pair<DNSName, float>>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly);
void sanitizeRecords(const std::string& prefix, LWResult& lwr, const DNSName& qname, const QType& qtype, const DNSName& auth, bool wasForwarded, bool rdQuery);
RCode::rcodes_ updateCacheFromRecords(unsigned int depth, LWResult& lwr, const DNSName& qname, const QType& qtype, const DNSName& auth, bool wasForwarded, const boost::optional<Netmask>, vState& state, bool& needWildcardProof, bool& gatherWildcardProof, unsigned int& wildcardLabelsCount, bool sendRDQuery);