From e503653f7d4c7e28b594336b37bcf602c7f5119a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 29 Jun 2017 15:29:40 +0200 Subject: [PATCH] rec: Add IXFR unit tests --- pdns/Makefile.am | 4 + pdns/recursordist/Makefile.am | 4 + pdns/recursordist/test-common.hh | 1 + pdns/recursordist/test-ixfr_cc.cc | 1 + pdns/recursordist/test-syncres_cc.cc | 40 +--- pdns/test-common.hh | 42 ++++ pdns/test-ixfr_cc.cc | 303 +++++++++++++++++++++++++++ 7 files changed, 356 insertions(+), 39 deletions(-) create mode 120000 pdns/recursordist/test-common.hh create mode 120000 pdns/recursordist/test-ixfr_cc.cc create mode 100644 pdns/test-common.hh create mode 100644 pdns/test-ixfr_cc.cc diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 43515c4410..4a3a41e766 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -1149,6 +1149,7 @@ testrunner_SOURCES = \ gettime.cc gettime.hh \ gss_context.cc gss_context.hh \ iputils.cc \ + ixfr.cc ixfr.hh \ logger.cc \ misc.cc \ nameserver.cc \ @@ -1163,6 +1164,7 @@ testrunner_SOURCES = \ test-base32_cc.cc \ test-base64_cc.cc \ test-bindparser_cc.cc \ + test-common.hh \ test-delaypipe_hh.cc \ test-dnsrecordcontent.cc \ test-distributor_hh.cc \ @@ -1171,6 +1173,7 @@ testrunner_SOURCES = \ test-dnsparser_hh.cc \ test-dnsrecords_cc.cc \ test-iputils_hh.cc \ + test-ixfr_cc.cc \ test-lock_hh.cc \ test-md5_hh.cc \ test-misc_hh.cc \ @@ -1184,6 +1187,7 @@ testrunner_SOURCES = \ test-tsig.cc \ test-zoneparser_tng_cc.cc \ testrunner.cc \ + tsigverifier.cc tsigverifier.hh \ ueberbackend.cc \ unix_utility.cc \ zoneparser-tng.cc zoneparser-tng.hh diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index f2c11e9983..8b9ec4e088 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -195,6 +195,7 @@ testrunner_SOURCES = \ gettime.cc gettime.hh \ gss_context.cc gss_context.hh \ iputils.cc iputils.hh \ + ixfr.cc ixfr.hh \ logger.cc logger.hh \ misc.cc misc.hh \ negcache.hh negcache.cc \ @@ -218,6 +219,7 @@ testrunner_SOURCES = \ test-arguments_cc.cc \ test-base32_cc.cc \ test-base64_cc.cc \ + test-common.hh \ test-dnsrecordcontent.cc \ test-dns_random_hh.cc \ test-dnsname_cc.cc \ @@ -225,6 +227,7 @@ testrunner_SOURCES = \ test-dnsrecords_cc.cc \ test-ednsoptions_cc.cc \ test-iputils_hh.cc \ + test-ixfr_cc.cc \ test-misc_hh.cc \ test-nmtree.cc \ test-negcache_cc.cc \ @@ -234,6 +237,7 @@ testrunner_SOURCES = \ test-syncres_cc.cc \ test-tsig.cc \ testrunner.cc \ + tsigverifier.cc tsigverifier.hh \ unix_utility.cc \ validate.cc validate.hh \ validate-recursor.cc validate-recursor.hh \ diff --git a/pdns/recursordist/test-common.hh b/pdns/recursordist/test-common.hh new file mode 120000 index 0000000000..c03711b8c3 --- /dev/null +++ b/pdns/recursordist/test-common.hh @@ -0,0 +1 @@ +../test-common.hh \ No newline at end of file diff --git a/pdns/recursordist/test-ixfr_cc.cc b/pdns/recursordist/test-ixfr_cc.cc new file mode 120000 index 0000000000..d033c39171 --- /dev/null +++ b/pdns/recursordist/test-ixfr_cc.cc @@ -0,0 +1 @@ +../test-ixfr_cc.cc \ No newline at end of file diff --git a/pdns/recursordist/test-syncres_cc.cc b/pdns/recursordist/test-syncres_cc.cc index 20553fd369..0e1e5051b0 100644 --- a/pdns/recursordist/test-syncres_cc.cc +++ b/pdns/recursordist/test-syncres_cc.cc @@ -10,6 +10,7 @@ #include "rec-lua-conf.hh" #include "root-dnssec.hh" #include "syncres.hh" +#include "test-common.hh" #include "utility.hh" #include "validate-recursor.hh" @@ -185,45 +186,6 @@ static void setLWResult(LWResult* res, int rcode, bool aa=false, bool tc=false, res->d_haveEDNS = edns; } -static std::shared_ptr getRecordContent(uint16_t type, const std::string& content) -{ - std::shared_ptr result = nullptr; - - if (type == QType::NS) { - result = std::make_shared(DNSName(content)); - } - else if (type == QType::A) { - result = std::make_shared(ComboAddress(content)); - } - else if (type == QType::AAAA) { - result = std::make_shared(ComboAddress(content)); - } - else if (type == QType::CNAME) { - result = std::make_shared(DNSName(content)); - } - else if (type == QType::OPT) { - result = std::make_shared(); - } - else { - result = DNSRecordContent::mastermake(type, QClass::IN, content); - } - - return result; -} - -static void addRecordToList(std::vector& records, const DNSName& name, uint16_t type, const std::string& content, DNSResourceRecord::Place place, uint32_t ttl) -{ - DNSRecord rec; - rec.d_place = place; - rec.d_name = name; - rec.d_type = type; - rec.d_ttl = ttl; - - rec.d_content = getRecordContent(type, content); - - records.push_back(rec); -} - static void addRecordToLW(LWResult* res, const DNSName& name, uint16_t type, const std::string& content, DNSResourceRecord::Place place=DNSResourceRecord::ANSWER, uint32_t ttl=60) { addRecordToList(res->d_records, name, type, content, place, ttl); diff --git a/pdns/test-common.hh b/pdns/test-common.hh new file mode 100644 index 0000000000..50de3b7ec0 --- /dev/null +++ b/pdns/test-common.hh @@ -0,0 +1,42 @@ + +#include "dnsrecords.hh" +#include "iputils.hh" + +static inline std::shared_ptr getRecordContent(uint16_t type, const std::string& content) +{ + std::shared_ptr result = nullptr; + + if (type == QType::NS) { + result = std::make_shared(DNSName(content)); + } + else if (type == QType::A) { + result = std::make_shared(ComboAddress(content)); + } + else if (type == QType::AAAA) { + result = std::make_shared(ComboAddress(content)); + } + else if (type == QType::CNAME) { + result = std::make_shared(DNSName(content)); + } + else if (type == QType::OPT) { + result = std::make_shared(); + } + else { + result = DNSRecordContent::mastermake(type, QClass::IN, content); + } + + return result; +} + +static inline void addRecordToList(std::vector& records, const DNSName& name, uint16_t type, const std::string& content, DNSResourceRecord::Place place=DNSResourceRecord::ANSWER, uint32_t ttl=3600) +{ + DNSRecord rec; + rec.d_place = place; + rec.d_name = name; + rec.d_type = type; + rec.d_ttl = ttl; + + rec.d_content = getRecordContent(type, content); + + records.push_back(rec); +} diff --git a/pdns/test-ixfr_cc.cc b/pdns/test-ixfr_cc.cc new file mode 100644 index 0000000000..63f4bdd956 --- /dev/null +++ b/pdns/test-ixfr_cc.cc @@ -0,0 +1,303 @@ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_NO_MAIN + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "test-common.hh" +#include "ixfr.hh" + +BOOST_AUTO_TEST_SUITE(ixfr_cc) + +BOOST_AUTO_TEST_CASE(test_ixfr_rfc1995_axfr) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); + + auto masterSOA = DNSRecordContent::mastermake(QType::SOA, QClass::IN, "NS.JAIN.AD.JP. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + vector records; + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::NS, "NS.JAIN.AD.JP."); + addRecordToList(records, DNSName("NS.JAIN.AD.JP."), QType::A, "133.69.136.1"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.3"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "192.41.197.2"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + + auto ret = processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(masterSOA)); + BOOST_CHECK_EQUAL(ret.size(), 1); + BOOST_CHECK_EQUAL(ret.at(0).first.size(), 0); + BOOST_REQUIRE_EQUAL(ret.at(0).second.size(), records.size()); + for (size_t idx = 0; idx < records.size(); idx++) { + BOOST_CHECK(ret.at(0).second.at(idx) == records.at(idx)); + } +} + +BOOST_AUTO_TEST_CASE(test_ixfr_rfc1995_incremental) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); + + auto masterSOA = DNSRecordContent::mastermake(QType::SOA, QClass::IN, "NS.JAIN.AD.JP. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + vector records; + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 1 600 600 3600000 604800"); + addRecordToList(records, DNSName("NEZU.JAIN.AD.JP."), QType::A, "133.69.136.5"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 2 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.4"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "192.41.197.2"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 2 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.4"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.3"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + + auto ret = processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(masterSOA)); + // two sequences + BOOST_CHECK_EQUAL(ret.size(), 2); + // the first one has one removal, two additions (plus the corresponding SOA removal/addition) + BOOST_CHECK_EQUAL(ret.at(0).first.size(), 1 + 1); + BOOST_CHECK_EQUAL(ret.at(0).second.size(), 2 + 1); + + // check removals + BOOST_CHECK_EQUAL(ret.at(0).first.at(0).d_type, QType(QType::SOA).getCode()); + BOOST_CHECK_EQUAL(ret.at(0).first.at(1).d_type, QType(QType::A).getCode()); + + // check additions + 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::A).getCode()); + BOOST_CHECK_EQUAL(ret.at(0).second.at(2).d_type, QType(QType::A).getCode()); + + // the second one has one removal, one addition + BOOST_CHECK_EQUAL(ret.at(1).first.size(), 1 + 1); + BOOST_CHECK_EQUAL(ret.at(1).second.size(), 1 + 1); + + // check removals + BOOST_CHECK_EQUAL(ret.at(1).first.at(0).d_type, QType(QType::SOA).getCode()); + BOOST_CHECK_EQUAL(ret.at(1).first.at(1).d_type, QType(QType::A).getCode()); + + // check additions + BOOST_CHECK_EQUAL(ret.at(1).second.at(0).d_type, QType(QType::SOA).getCode()); + BOOST_CHECK_EQUAL(ret.at(1).second.at(1).d_type, QType(QType::A).getCode()); +} + +BOOST_AUTO_TEST_CASE(test_ixfr_rfc1995_condensed_incremental) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); + + auto masterSOA = DNSRecordContent::mastermake(QType::SOA, QClass::IN, "NS.JAIN.AD.JP. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + vector records; + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 1 600 600 3600000 604800"); + addRecordToList(records, DNSName("NEZU.JAIN.AD.JP."), QType::A, "133.69.136.5"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.3"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "192.41.197.2"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + + auto ret = processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(masterSOA)); + // one sequence + BOOST_CHECK_EQUAL(ret.size(), 1); + // it has one removal, two additions (plus the corresponding SOA removal/addition) + BOOST_CHECK_EQUAL(ret.at(0).first.size(), 1 + 1); + BOOST_CHECK_EQUAL(ret.at(0).second.size(), 2 + 1); + + // check removals + BOOST_CHECK_EQUAL(ret.at(0).first.at(0).d_type, QType(QType::SOA).getCode()); + BOOST_CHECK_EQUAL(ret.at(0).first.at(1).d_type, QType(QType::A).getCode()); + + // check additions + 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::A).getCode()); + BOOST_CHECK_EQUAL(ret.at(0).second.at(2).d_type, QType(QType::A).getCode()); +} + +BOOST_AUTO_TEST_CASE(test_ixfr_no_additions_in_first_sequence) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); + + auto masterSOA = DNSRecordContent::mastermake(QType::SOA, QClass::IN, "NS.JAIN.AD.JP. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + vector records; + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 1 600 600 3600000 604800"); + addRecordToList(records, DNSName("NEZU.JAIN.AD.JP."), QType::A, "133.69.136.5"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 2 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 2 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.5"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.3"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + + auto ret = processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(masterSOA)); + // two sequences + BOOST_CHECK_EQUAL(ret.size(), 2); + // the first one has one removal, no additions (plus the corresponding SOA removal/addition) + BOOST_CHECK_EQUAL(ret.at(0).first.size(), 1 + 1); + BOOST_CHECK_EQUAL(ret.at(0).second.size(), 0 + 1); + + // check removals + BOOST_CHECK_EQUAL(ret.at(0).first.at(0).d_type, QType(QType::SOA).getCode()); + BOOST_CHECK_EQUAL(ret.at(0).first.at(1).d_type, QType(QType::A).getCode()); + + // check additions + BOOST_CHECK_EQUAL(ret.at(0).second.at(0).d_type, QType(QType::SOA).getCode()); + + // the second one has one removal, one addition + BOOST_CHECK_EQUAL(ret.at(1).first.size(), 1 + 1); + BOOST_CHECK_EQUAL(ret.at(1).second.size(), 1 + 1); + + // check removals + BOOST_CHECK_EQUAL(ret.at(1).first.at(0).d_type, QType(QType::SOA).getCode()); + BOOST_CHECK_EQUAL(ret.at(1).first.at(1).d_type, QType(QType::A).getCode()); + + // check additions + BOOST_CHECK_EQUAL(ret.at(1).second.at(0).d_type, QType(QType::SOA).getCode()); + BOOST_CHECK_EQUAL(ret.at(1).second.at(1).d_type, QType(QType::A).getCode()); +} + +BOOST_AUTO_TEST_CASE(test_ixfr_no_removals_in_first_sequence) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); + + auto masterSOA = DNSRecordContent::mastermake(QType::SOA, QClass::IN, "NS.JAIN.AD.JP. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + vector records; + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 1 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 2 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.4"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "192.41.197.2"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 2 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.4"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.3"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + + auto ret = processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(masterSOA)); + // two sequences + BOOST_CHECK_EQUAL(ret.size(), 2); + // the first one has no removal, two additions (plus the corresponding SOA removal/addition) + BOOST_CHECK_EQUAL(ret.at(0).first.size(), 0 + 1); + BOOST_CHECK_EQUAL(ret.at(0).second.size(), 2 + 1); + + // check removals + BOOST_CHECK_EQUAL(ret.at(0).first.at(0).d_type, QType(QType::SOA).getCode()); + + // check additions + 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::A).getCode()); + BOOST_CHECK_EQUAL(ret.at(0).second.at(1).d_type, QType(QType::A).getCode()); + + // the second one has one removal, one addition + BOOST_CHECK_EQUAL(ret.at(1).first.size(), 1 + 1); + BOOST_CHECK_EQUAL(ret.at(1).second.size(), 1 + 1); + + // check removals + BOOST_CHECK_EQUAL(ret.at(1).first.at(0).d_type, QType(QType::SOA).getCode()); + BOOST_CHECK_EQUAL(ret.at(1).first.at(1).d_type, QType(QType::A).getCode()); + + // check additions + BOOST_CHECK_EQUAL(ret.at(1).second.at(0).d_type, QType(QType::SOA).getCode()); + BOOST_CHECK_EQUAL(ret.at(1).second.at(1).d_type, QType(QType::A).getCode()); +} + +BOOST_AUTO_TEST_CASE(test_ixfr_same_serial) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); + + auto masterSOA = DNSRecordContent::mastermake(QType::SOA, QClass::IN, "NS.JAIN.AD.JP. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + vector records; + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + + auto ret = processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(masterSOA)); + + BOOST_CHECK_EQUAL(ret.size(), 0); +} + +BOOST_AUTO_TEST_CASE(test_ixfr_invalid_no_records) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); + + auto masterSOA = DNSRecordContent::mastermake(QType::SOA, QClass::IN, "NS.JAIN.AD.JP. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + vector records; + + auto ret = processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(masterSOA)); + BOOST_CHECK_EQUAL(ret.size(), 0); +} + +BOOST_AUTO_TEST_CASE(test_ixfr_invalid_no_master_soa) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); +; + vector records; + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + + auto ret = processIXFRRecords(master, zone, records, nullptr); + BOOST_CHECK_EQUAL(ret.size(), 0); +} + +BOOST_AUTO_TEST_CASE(test_ixfr_invalid_no_trailing_soa) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); + + auto masterSOA = DNSRecordContent::mastermake(QType::SOA, QClass::IN, "NS.JAIN.AD.JP. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + vector records; + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 1 600 600 3600000 604800"); + addRecordToList(records, DNSName("NEZU.JAIN.AD.JP."), QType::A, "133.69.136.5"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.3"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "192.41.197.2"); + + BOOST_CHECK_THROW(processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(masterSOA)), std::runtime_error); +} + +BOOST_AUTO_TEST_CASE(test_ixfr_invalid_no_soa_after_removals) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); + + auto masterSOA = DNSRecordContent::mastermake(QType::SOA, QClass::IN, "NS.JAIN.AD.JP. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + vector records; + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 1 600 600 3600000 604800"); + addRecordToList(records, DNSName("NEZU.JAIN.AD.JP."), QType::A, "133.69.136.5"); + + BOOST_CHECK_THROW(processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(masterSOA)), std::runtime_error); +} + +BOOST_AUTO_TEST_CASE(test_ixfr_mistmatching_serial_before_and_after_additions) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); + + auto masterSOA = DNSRecordContent::mastermake(QType::SOA, QClass::IN, "NS.JAIN.AD.JP. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + vector records; + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 1 600 600 3600000 604800"); + addRecordToList(records, DNSName("NEZU.JAIN.AD.JP."), QType::A, "133.69.136.5"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 2 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.3"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "192.41.197.2"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + + BOOST_CHECK_THROW(processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(masterSOA)), std::runtime_error); +} + +BOOST_AUTO_TEST_CASE(test_ixfr_trailing_record_after_end) { + const ComboAddress master("[2001:DB8::1]:53"); + const DNSName zone("JAIN.AD.JP."); + + auto masterSOA = DNSRecordContent::mastermake(QType::SOA, QClass::IN, "NS.JAIN.AD.JP. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + vector records; + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 1 600 600 3600000 604800"); + addRecordToList(records, DNSName("NEZU.JAIN.AD.JP."), QType::A, "133.69.136.5"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.3"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "192.41.197.2"); + addRecordToList(records, DNSName("JAIN.AD.JP."), QType::SOA, "ns.jain.ad.jp. mohta.jain.ad.jp. 3 600 600 3600000 604800"); + addRecordToList(records, DNSName("JAIN-BB.JAIN.AD.JP."), QType::A, "133.69.136.3"); + + BOOST_CHECK_THROW(processIXFRRecords(master, zone, records, std::dynamic_pointer_cast(masterSOA)), std::runtime_error); +} + +BOOST_AUTO_TEST_SUITE_END(); -- 2.47.2