]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
speed up IXFR transcation
authorLeon Xu <cassvin91@gmail.com>
Thu, 11 Jan 2018 10:00:32 +0000 (18:00 +0800)
committerPieter Lexis <pieter.lexis@powerdns.com>
Mon, 26 Mar 2018 09:19:23 +0000 (11:19 +0200)
IXFR client actively close connection to server once IXFR is done

(cherry picked from commit 397ed71dedda21effaaad2578b27fd316c00451d)

pdns/ixfr.cc

index 74982b518f779e2e13d24d345196c037cc4a2a07..152b512fd99d887a07f0e603159b9b729c742c6a 100644 (file)
@@ -168,8 +168,12 @@ vector<pair<vector<DNSRecord>, vector<DNSRecord> > > getIXFRDeltas(const ComboAd
   std::shared_ptr<SOARecordContent> masterSOA = nullptr;
   vector<DNSRecord> records;
   size_t receivedBytes = 0;
+  int8_t ixfrInProgress = -2;
 
   for(;;) {
+    if (!ixfrInProgress)
+      break;
+
     if(s.read((char*)&len, sizeof(len)) != sizeof(len))
       break;
 
@@ -203,9 +207,9 @@ vector<pair<vector<DNSRecord>, vector<DNSRecord> > > getIXFRDeltas(const ComboAd
           throw std::runtime_error("The first record of the IXFR answer for zone '"+zone.toString()+"' from master '"+master.toStringWithPort()+"' is not a SOA ("+QType(r.first.d_type).getName()+")");
         }
 
-       auto sr = getRR<SOARecordContent>(r.first);
-       if (!sr) {
-          throw std::runtime_error("Error getting the content of the first SOA record of the IXFR answer for zone '"+zone.toString()+"' from master '"+master.toStringWithPort()+"'");
+        auto sr = getRR<SOARecordContent>(r.first);
+        if (!sr) {
+          throw std::runtime_error("Error getting the content of the first SOA record of the IXFR answer for zone '"+zone.toLogString()+"' from master '"+master.toStringWithPort()+"'");
         }
 
         if(sr->d_st.serial == std::dynamic_pointer_cast<SOARecordContent>(oursr.d_content)->d_st.serial) {
@@ -213,6 +217,12 @@ vector<pair<vector<DNSRecord>, vector<DNSRecord> > > getIXFRDeltas(const ComboAd
           return ret;
         }
         masterSOA = sr;
+      } else {
+        // we hit the last SOA record
+        // ixfr is considered to be done if we hit the last SOA record twice
+        if (r.first.d_type == QType::SOA && masterSOA->d_st.serial == getRR<SOARecordContent>(r.first)->d_st.serial) {
+          ixfrInProgress++;
+        }
       }
 
       if(r.first.d_place != DNSResourceRecord::ANSWER) {