]> granicus.if.org Git - pdns/commitdiff
Correctly interpret an empty AXFR response to an IXFR query
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 18 Feb 2019 12:07:14 +0000 (13:07 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 20 Mar 2019 14:05:01 +0000 (15:05 +0100)
(cherry picked from commit 98b3317609b2783d1bfd5da99edc81af28f4e1d6)

pdns/ixfr.cc
pdns/test-ixfr_cc.cc

index 74982b518f779e2e13d24d345196c037cc4a2a07..ab13446f8d7a16ad69f84f54d500dd3de55714a4 100644 (file)
@@ -59,6 +59,12 @@ vector<pair<vector<DNSRecord>, vector<DNSRecord> > > processIXFRRecords(const Co
     // the serial of this SOA record is the serial of the
     // zone before the removals and updates of this sequence
     if (sr->d_st.serial == masterSOA->d_st.serial) {
+      if (records.size() == 2) {
+        // if the entire update is two SOAs records with the same
+        // serial, this is actually an empty AXFR!
+        return {{remove, records}};
+      }
+
       // if it's the final SOA, there is nothing for us to see
       break;
     }
index 63f4bdd956a812f6d331b3c9262cb2386c8e4163..95398e4311f6afbbbd25901a5b40d98c2fa9a0d3 100644 (file)
@@ -211,7 +211,14 @@ BOOST_AUTO_TEST_CASE(test_ixfr_same_serial) {
 
   auto ret = processIXFRRecords(master, zone, records, std::dynamic_pointer_cast<SOARecordContent>(masterSOA));
 
-  BOOST_CHECK_EQUAL(ret.size(), 0);
+  // this is actually an empty AXFR
+  BOOST_CHECK_EQUAL(ret.size(), 1);
+  // nothing in the deletion part then
+  BOOST_CHECK_EQUAL(ret.at(0).first.size(), 0);
+  // and the two SOAs in the addition part
+  BOOST_CHECK_EQUAL(ret.at(0).second.size(), 2);
+  BOOST_CHECK_EQUAL(ret.at(0).second.at(0).d_type, QType(QType::SOA).getCode());
+  BOOST_CHECK_EQUAL(ret.at(0).second.at(1).d_type, QType(QType::SOA).getCode());
 }
 
 BOOST_AUTO_TEST_CASE(test_ixfr_invalid_no_records) {