]> granicus.if.org Git - pdns/commitdiff
Keep track of forward-zones NS speeds by stuffing them into the nsspeed collection.
authorphonedph1 <phoned@gmail.com>
Wed, 10 Jan 2018 16:15:25 +0000 (16:15 +0000)
committerphonedph1 <phoned@gmail.com>
Wed, 10 Jan 2018 16:15:25 +0000 (16:15 +0000)
Use a similar method to shuffleInSpeedOrder for sorting and trace log printing.

pdns/syncres.cc
pdns/syncres.hh

index f31621e023dedd91eafaefdb81943e92231f39ba..2a1137f7ed78d674948d163f8df041b75d065b20 100644 (file)
@@ -1282,6 +1282,45 @@ inline vector<DNSName> SyncRes::shuffleInSpeedOrder(NsSet &tnameservers, const s
   return rnameservers;
 }
 
+inline vector<ComboAddress> SyncRes::shuffleForwardSpeed(vector<ComboAddress> &nameservers, const string &prefix, const bool wasRd)
+{
+  vector<ComboAddress> out_nameservers;
+  vector<DNSName> rnameservers;
+  for(const auto& ns:nameservers) {
+    rnameservers.push_back(DNSName(ns.toStringWithPort()));
+  }
+
+  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);
+  stable_sort(rnameservers.begin(),rnameservers.end(), so);
+
+  for(vector<DNSName>::const_iterator i=rnameservers.cbegin();i!=rnameservers.cend();++i) {
+    out_nameservers.push_back(ComboAddress(i->toStringNoDot()));
+  }
+
+  if(doLog()) {
+    LOG(prefix<<"Nameservers: ");
+    for(vector<DNSName>::const_iterator i=rnameservers.cbegin();i!=rnameservers.cend();++i) {
+      if(i!=rnameservers.cbegin()) {
+        LOG(", ");
+        if(!((i-rnameservers.cbegin())%3)) {
+          LOG(endl<<prefix<<"             ");
+        }
+      }
+      LOG((wasRd ? string("+") : string("-")) << i->toStringNoDot() <<"(" << (boost::format("%0.2f") % (speeds[*i]/1000.0)).str() <<"ms)");
+    }
+    LOG(endl);
+  }
+  return out_nameservers;
+}
+
 static uint32_t getRRSIGTTL(const time_t now, const std::shared_ptr<RRSIGRecordContent>& rrsig)
 {
   uint32_t res = 0;
@@ -1419,13 +1458,13 @@ vector<ComboAddress> SyncRes::retrieveAddressesForNS(const std::string& prefix,
   else {
     LOG(prefix<<qname<<": Domain has hardcoded nameserver");
 
-    result = nameservers[*tns].first;
-    if(result.size() > 1) {
+    if(nameservers[*tns].first.size() > 1) {
       LOG("s");
     }
     LOG(endl);
 
     sendRDQuery = nameservers[*tns].second;
+    result = shuffleForwardSpeed(nameservers[*tns].first, doLog() ? (prefix+qname.toString()+": ") : string(), sendRDQuery);
     pierceDontQuery=true;
   }
   return result;
@@ -2422,7 +2461,7 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname,
     }
 
     if(resolveret != -2) { // don't account for resource limits, they are our own fault
-      t_sstorage.nsSpeeds[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) >= s_serverdownmaxfails) {
@@ -2722,7 +2761,7 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con
           */
           //        cout<<"msec: "<<lwr.d_usec/1000.0<<", "<<g_avgLatency/1000.0<<'\n';
 
-          t_sstorage.nsSpeeds[*tns].submit(*remoteIP, lwr.d_usec, &d_now);
+          t_sstorage.nsSpeeds[tns->empty()? DNSName(remoteIP->toStringWithPort()) : *tns].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);
index 33dae04805802a6492774308baa1ce8acaa85687..89346906a285bfb6fc0b068b8f312c58a74641ee 100644 (file)
@@ -739,6 +739,7 @@ private:
   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<ComboAddress> shuffleForwardSpeed(vector<ComboAddress> &nameservers, 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);