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);
*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<DNSRecord> aset;
struct speedOrder
{
- speedOrder(map<DNSName,double> &speeds) : d_speeds(speeds) {}
- bool operator()(const DNSName &a, const DNSName &b) const
+ bool operator()(const std::pair<DNSName, double> &a, const std::pair<DNSName, double> &b) const
{
- return d_speeds[a] < d_speeds[b];
+ return a.second < b.second;
}
- map<DNSName, double>& d_speeds;
};
-inline vector<DNSName> SyncRes::shuffleInSpeedOrder(NsSet &tnameservers, const string &prefix)
+inline std::vector<std::pair<DNSName, double>> SyncRes::shuffleInSpeedOrder(NsSet &tnameservers, const string &prefix)
{
- vector<DNSName> rnameservers;
+ std::vector<std::pair<DNSName, double>> 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<DNSName, double> 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<DNSName>::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<<prefix<<" ");
}
}
- LOG(i->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);
}
speed=t_sstorage.nsSpeeds[nsName].get(&d_now);
speeds[val]=speed;
}
- random_shuffle(nameservers.begin(),nameservers.end(), dns_random);
+ random_shuffle(nameservers.begin(),nameservers.end());
speedOrderCA so(speeds);
stable_sort(nameservers.begin(),nameservers.end(), so);
return false;
}
-vector<ComboAddress> SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, vector<DNSName >::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<DNSName >& 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, 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> result;
- if(!tns->empty()) {
- LOG(prefix<<qname<<": Trying to resolve NS '"<<*tns<< "' ("<<1+tns-rnameservers.begin()<<"/"<<(unsigned int)rnameservers.size()<<")"<<endl);
- result = getAddrs(*tns, depth+2, beenthere, cacheOnly);
+ if(!tns->first.empty()) {
+ LOG(prefix<<qname<<": Trying to resolve NS '"<<tns->first<< "' ("<<1+tns-rnameservers.begin()<<"/"<<(unsigned int)rnameservers.size()<<")"<<endl);
+ result = getAddrs(tns->first, depth+2, beenthere, cacheOnly);
pierceDontQuery=false;
}
else {
LOG(prefix<<qname<<": Domain has hardcoded nameserver");
- if(nameservers[*tns].first.size() > 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;
LOG(endl);
for(;;) { // we may get more specific nameservers
- vector<DNSName > 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()) {
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<<qname<<": Using NS to resolve itself, but only using what we have in cache ("<<(1+tns-rnameservers.cbegin())<<"/"<<rnameservers.size()<<")"<<endl);
bool sendRDQuery=false;
boost::optional<Netmask> 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<<qname<<": Domain is out-of-band"<<endl);
/* setting state to indeterminate since validation is disabled for local auth zone,
and Insecure would be misleading. */
remoteIPs = retrieveAddressesForNS(prefix, qname, tns, depth, beenthere, rnameservers, nameservers, sendRDQuery, pierceDontQuery, flawedNSSet, cacheOnly);
if(remoteIPs.empty()) {
- LOG(prefix<<qname<<": Failed to get IP for NS "<<*tns<<", trying next if available"<<endl);
+ LOG(prefix<<qname<<": Failed to get IP for NS "<<tns->first<<", trying next if available"<<endl);
flawedNSSet=true;
continue;
}
else {
bool hitPolicy{false};
- LOG(prefix<<qname<<": Resolved '"<<auth<<"' NS "<<*tns<<" to: ");
+ LOG(prefix<<qname<<": Resolved '"<<auth<<"' NS "<<tns->first<<" to: ");
for(remoteIP = remoteIPs.cbegin(); remoteIP != remoteIPs.cend(); ++remoteIP) {
if(remoteIP != remoteIPs.cbegin()) {
LOG(", ");
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<<qname<<": Got "<<(unsigned int)lwr.d_records.size()<<" answers from "<<*tns<<" ("<< remoteIP->toString() <<"), rcode="<<lwr.d_rcode<<" ("<<RCode::to_s(lwr.d_rcode)<<"), aa="<<lwr.d_aabit<<", in "<<lwr.d_usec/1000<<"ms"<<endl);
+ LOG(prefix<<qname<<": Got "<<(unsigned int)lwr.d_records.size()<<" answers from "<<tns->first<<" ("<< remoteIP->toString() <<"), rcode="<<lwr.d_rcode<<" ("<<RCode::to_s(lwr.d_rcode)<<"), aa="<<lwr.d_aabit<<", in "<<lwr.d_usec/1000<<"ms"<<endl);
/* // for you IPv6 fanatics :-)
if(remoteIP->sin4.sin_family==AF_INET6)
*/
// cout<<"msec: "<<lwr.d_usec/1000.0<<", "<<g_avgLatency/1000.0<<'\n';
- t_sstorage.nsSpeeds[tns->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);
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<DNSName> shuffleInSpeedOrder(NsSet &nameservers, const string &prefix);
+ inline vector<std::pair<DNSName, double>> 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<DNSName >::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<DNSName >& 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, 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);
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);