From 2c4a96285bedaa738c98da53bc93c02967d74ae5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 18 Feb 2019 13:07:14 +0100 Subject: [PATCH] Correctly interpret an empty AXFR response to an IXFR query (cherry picked from commit 98b3317609b2783d1bfd5da99edc81af28f4e1d6) --- pdns/ixfr.cc | 6 ++++++ pdns/test-ixfr_cc.cc | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) 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) { -- 2.40.0