From feccaf7f666238d707a1223f3d9013928b7893cd Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 22 May 2019 17:53:48 +0200 Subject: [PATCH] rec: Speed-up the shuffling of NS entries --- pdns/syncres.cc | 69 +++++++++++++++++++++++-------------------------- pdns/syncres.hh | 4 +-- 2 files changed, 34 insertions(+), 39 deletions(-) diff --git a/pdns/syncres.cc b/pdns/syncres.cc index 5dd3c98a39..dff2b3b164 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -764,7 +764,7 @@ vector SyncRes::getAddrs(const DNSName &qname, unsigned int depth, t_sstorage.nsSpeeds[qname].purge(speeds); if(ret.size() > 1) { - random_shuffle(ret.begin(), ret.end(), dns_random); + random_shuffle(ret.begin(), ret.end()); speedOrderCA so(speeds); stable_sort(ret.begin(), ret.end(), so); @@ -806,6 +806,8 @@ void SyncRes::getBestNSFromCache(const DNSName &qname, const QType& qtype, vecto *flawedNSSet = false; if(t_RC->get(d_now.tv_sec, subdomain, QType(QType::NS), false, &ns, d_cacheRemote) > 0) { + bestns.reserve(ns.size()); + for(auto k=ns.cbegin();k!=ns.cend(); ++k) { if(k->d_ttl > (unsigned int)d_now.tv_sec ) { vector aset; @@ -1381,44 +1383,37 @@ bool SyncRes::moreSpecificThan(const DNSName& a, const DNSName &b) const struct speedOrder { - speedOrder(map &speeds) : d_speeds(speeds) {} - bool operator()(const DNSName &a, const DNSName &b) const + bool operator()(const std::pair &a, const std::pair &b) const { - return d_speeds[a] < d_speeds[b]; + return a.second < b.second; } - map& d_speeds; }; -inline vector SyncRes::shuffleInSpeedOrder(NsSet &tnameservers, const string &prefix) +inline std::vector> SyncRes::shuffleInSpeedOrder(NsSet &tnameservers, const string &prefix) { - vector rnameservers; + std::vector> rnameservers; rnameservers.reserve(tnameservers.size()); for(const auto& tns: tnameservers) { - rnameservers.push_back(tns.first); + double 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; } - map speeds; - for(const auto& val: rnameservers) { - double speed; - speed=t_sstorage.nsSpeeds[val].get(&d_now); - speeds[val]=speed; - } - random_shuffle(rnameservers.begin(),rnameservers.end(), dns_random); - speedOrder so(speeds); + random_shuffle(rnameservers.begin(),rnameservers.end()); + speedOrder so; stable_sort(rnameservers.begin(),rnameservers.end(), so); if(doLog()) { LOG(prefix<<"Nameservers: "); - for(vector::const_iterator i=rnameservers.begin();i!=rnameservers.end();++i) { - if(i!=rnameservers.begin()) { + for(auto i=rnameservers.begin();i!=rnameservers.end();++i) { + if(i!=rnameservers.begin()) { LOG(", "); if(!((i-rnameservers.begin())%3)) { LOG(endl<toLogString()<<"(" << (boost::format("%0.2f") % (speeds[*i]/1000.0)).str() <<"ms)"); + LOG(i->first.toLogString()<<"(" << (boost::format("%0.2f") % (i->second/1000.0)).str() <<"ms)"); } LOG(endl); } @@ -1436,7 +1431,7 @@ inline vector SyncRes::shuffleForwardSpeed(const vector SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, vector::const_iterator& tns, const unsigned int depth, set& beenthere, const vector& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly) +vector SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, std::vector>::const_iterator& tns, const unsigned int depth, set& beenthere, const vector>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly) { vector result; - if(!tns->empty()) { - LOG(prefix<first.empty()) { + LOG(prefix<first<< "' ("<<1+tns-rnameservers.begin()<<"/"<<(unsigned int)rnameservers.size()<<")"<first, depth+2, beenthere, cacheOnly); pierceDontQuery=false; } else { LOG(prefix< 1) { + if(nameservers[tns->first].first.size() > 1) { LOG("s"); } LOG(endl); - sendRDQuery = nameservers[*tns].second; - result = shuffleForwardSpeed(nameservers[*tns].first, doLog() ? (prefix+qname.toString()+": ") : string(), sendRDQuery); + sendRDQuery = nameservers[tns->first].second; + result = shuffleForwardSpeed(nameservers[tns->first].first, doLog() ? (prefix+qname.toString()+": ") : string(), sendRDQuery); pierceDontQuery=true; } return result; @@ -3146,7 +3141,7 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con LOG(endl); for(;;) { // we may get more specific nameservers - vector rnameservers = shuffleInSpeedOrder(nameservers, doLog() ? (prefix+qname.toString()+": ") : string() ); + auto rnameservers = shuffleInSpeedOrder(nameservers, doLog() ? (prefix+qname.toString()+": ") : string() ); for(auto tns=rnameservers.cbegin();;++tns) { if(tns==rnameservers.cend()) { @@ -3162,7 +3157,7 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con bool cacheOnly = false; // this line needs to identify the 'self-resolving' behaviour - if(qname == *tns && (qtype.getCode() == QType::A || qtype.getCode() == QType::AAAA)) { + if(qname == tns->first && (qtype.getCode() == QType::A || qtype.getCode() == QType::AAAA)) { /* we might have a glue entry in cache so let's try this NS but only if we have enough in the cache to know how to reach it */ LOG(prefix< ednsmask; LWResult lwr; - const bool wasForwarded = tns->empty() && (!nameservers[*tns].first.empty()); + const bool wasForwarded = tns->first.empty() && (!nameservers[tns->first].first.empty()); int rcode = RCode::NoError; bool gotNewServers = false; - if(tns->empty() && !wasForwarded) { + if(tns->first.empty() && !wasForwarded) { LOG(prefix<first<<", trying next if available"<first<<" to: "); for(remoteIP = remoteIPs.cbegin(); remoteIP != remoteIPs.cend(); ++remoteIP) { if(remoteIP != remoteIPs.cbegin()) { LOG(", "); @@ -3233,18 +3228,18 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con bool truncated = false; bool gotAnswer = doResolveAtThisIP(prefix, qname, qtype, lwr, ednsmask, auth, sendRDQuery, - *tns, *remoteIP, false, &truncated); + tns->first, *remoteIP, false, &truncated); if (gotAnswer && truncated ) { /* retry, over TCP this time */ gotAnswer = doResolveAtThisIP(prefix, qname, qtype, lwr, ednsmask, auth, sendRDQuery, - *tns, *remoteIP, true, &truncated); + tns->first, *remoteIP, true, &truncated); } if (!gotAnswer) { continue; } - LOG(prefix<toString() <<"), rcode="<first<<" ("<< remoteIP->toString() <<"), rcode="<sin4.sin_family==AF_INET6) @@ -3252,7 +3247,7 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con */ // cout<<"msec: "<empty()? DNSName(remoteIP->toStringWithPort()) : *tns].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); diff --git a/pdns/syncres.hh b/pdns/syncres.hh index b316c92d4b..90cad0bd78 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -782,7 +782,7 @@ private: void getBestNSFromCache(const DNSName &qname, const QType &qtype, vector&bestns, bool* flawedNSSet, unsigned int depth, set& beenthere); DNSName getBestNSNamesFromCache(const DNSName &qname, const QType &qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, set&beenthere); - inline vector shuffleInSpeedOrder(NsSet &nameservers, const string &prefix); + inline vector> shuffleInSpeedOrder(NsSet &nameservers, const string &prefix); inline vector shuffleForwardSpeed(const vector &rnameservers, const string &prefix, const bool wasRd); bool moreSpecificThan(const DNSName& a, const DNSName &b) const; vector getAddrs(const DNSName &qname, unsigned int depth, set& beenthere, bool cacheOnly); @@ -791,7 +791,7 @@ private: 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 retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, vector::const_iterator& tns, const unsigned int depth, set& beenthere, const vector& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly); + vector retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, vector>::const_iterator& tns, const unsigned int depth, set& beenthere, const vector>& 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, vState& state, bool& needWildcardProof, bool& gatherWildcardProof, unsigned int& wildcardLabelsCount, bool sendRDQuery); -- 2.47.2