From: Remi Gacogne Date: Mon, 18 Feb 2019 12:07:14 +0000 (+0100) Subject: Correctly interpret an empty AXFR response to an IXFR query X-Git-Tag: auth-4.1.8~1^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2c4a96285bedaa738c98da53bc93c02967d74ae5;p=pdns Correctly interpret an empty AXFR response to an IXFR query (cherry picked from commit 98b3317609b2783d1bfd5da99edc81af28f4e1d6) --- diff --git a/pdns/ixfr.cc b/pdns/ixfr.cc index 74982b518..ab13446f8 100644 --- a/pdns/ixfr.cc +++ b/pdns/ixfr.cc @@ -59,6 +59,12 @@ vector, vector > > 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; } diff --git a/pdns/test-ixfr_cc.cc b/pdns/test-ixfr_cc.cc index 63f4bdd95..95398e431 100644 --- a/pdns/test-ixfr_cc.cc +++ b/pdns/test-ixfr_cc.cc @@ -211,7 +211,14 @@ BOOST_AUTO_TEST_CASE(test_ixfr_same_serial) { auto ret = processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(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) {