From: Remi Gacogne Date: Tue, 18 Dec 2018 08:26:43 +0000 (+0100) Subject: Add unit tests for the NSEC and NSEC3 types X-Git-Tag: rec-4.2.0-alpha1~54^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cbbc97eb9b806bd0f384096115d125813db1458c;p=thirdparty%2Fpdns.git Add unit tests for the NSEC and NSEC3 types --- diff --git a/pdns/test-dnsrecords_cc.cc b/pdns/test-dnsrecords_cc.cc index f4237cc81f..e28104721a 100644 --- a/pdns/test-dnsrecords_cc.cc +++ b/pdns/test-dnsrecords_cc.cc @@ -8,6 +8,8 @@ #include #include + +#include "base32.hh" #include "dnsrecords.hh" namespace { @@ -458,4 +460,101 @@ BOOST_AUTO_TEST_CASE(test_nsec_records_in) { } } +BOOST_AUTO_TEST_CASE(test_nsec_records_types) { + + { + auto validNSEC = DNSRecordContent::mastermake(QType::NSEC, QClass::IN, "host.example.com. A MX RRSIG NSEC TYPE1234"); + auto nsecContent = std::dynamic_pointer_cast(validNSEC); + BOOST_REQUIRE(nsecContent); + + for (const auto type : { QType::A, QType::MX, QType::RRSIG, QType::NSEC, static_cast(1234) }) { + BOOST_CHECK(nsecContent->isSet(type)); + } + BOOST_CHECK_EQUAL(nsecContent->isSet(QType::NSEC3), false); + BOOST_CHECK_EQUAL(nsecContent->numberOfTypesSet(), 5); + } + + { + auto nsecContent = std::make_shared(); + BOOST_CHECK_EQUAL(nsecContent->numberOfTypesSet(), 0); + BOOST_CHECK_EQUAL(nsecContent->isSet(QType::NSEC3), false); + + for (size_t idx = 0; idx < 65536; idx++) { + nsecContent->set(idx); + } + BOOST_CHECK_EQUAL(nsecContent->isSet(QType::NSEC3), true); + BOOST_CHECK_EQUAL(nsecContent->numberOfTypesSet(), 65536); + for (size_t idx = 0; idx < 65536; idx++) { + BOOST_CHECK(nsecContent->isSet(idx)); + } + } +} + +BOOST_AUTO_TEST_CASE(test_nsec3_records_types) { + + { + auto validNSEC3 = DNSRecordContent::mastermake(QType::NSEC3, QClass::IN, "1 1 12 aabbccdd 2vptu5timamqttgl4luu9kg21e0aor3s A MX RRSIG NSEC3 TYPE1234"); + auto nsec3Content = std::dynamic_pointer_cast(validNSEC3); + BOOST_REQUIRE(nsec3Content); + + for (const auto type : { QType::A, QType::MX, QType::RRSIG, QType::NSEC3, static_cast(1234) }) { + BOOST_CHECK(nsec3Content->isSet(type)); + } + BOOST_CHECK_EQUAL(nsec3Content->isSet(QType::NSEC), false); + BOOST_CHECK_EQUAL(nsec3Content->numberOfTypesSet(), 5); + } + + { + auto nsec3Content = std::make_shared(); + BOOST_CHECK_EQUAL(nsec3Content->numberOfTypesSet(), 0); + BOOST_CHECK_EQUAL(nsec3Content->isSet(QType::NSEC), false); + + for (size_t idx = 0; idx < 65536; idx++) { + nsec3Content->set(idx); + } + BOOST_CHECK_EQUAL(nsec3Content->isSet(QType::NSEC), true); + BOOST_CHECK_EQUAL(nsec3Content->numberOfTypesSet(), 65536); + for (size_t idx = 0; idx < 65536; idx++) { + BOOST_CHECK(nsec3Content->isSet(idx)); + } + } + + { + DNSName qname("powerdns.com."); + /* check that we can have a NSEC3 with 0 types covered */ + const std::string salt = "aabbccdd"; + const std::string hash = "2vptu5timamqttgl4luu9kg21e0aor3s"; + const std::string str = "1 1 12 " + salt + " " + hash; + auto validNSEC3=DNSRecordContent::mastermake(QType::NSEC3, QClass::IN, str); + + vector packet; + DNSPacketWriter writer(packet, qname, QType::NSEC3, QClass::IN, 0); + writer.getHeader()->qr = 1; + writer.startRecord(qname, QType::NSEC3, 100, QClass::IN, DNSResourceRecord::ANSWER); + validNSEC3->toPacket(writer); + writer.commit(); + + static const size_t expectedSize = sizeof(dnsheader) + qname.wirelength() + 2 /* QType */ + 2 /* QClass */ + + 2 /* name pointer */ + 2 /* QType */ + 2 /* QClass */ + + 2 /* rd length */ + 1 /* hash algo */ + 1 /* flags */ + 2 /*iterations */ + 1 /* salt length */ + salt.size() + + 1 /* hash length */ + fromBase32Hex(hash).size(); + BOOST_CHECK_EQUAL(packet.size(), expectedSize); + + MOADNSParser parser(false, reinterpret_cast(packet.data()), packet.size()); + BOOST_REQUIRE_EQUAL(parser.d_answers.size(), 1); + const auto& record = parser.d_answers.at(0).first; + BOOST_REQUIRE(record.d_type == QType::NSEC3); + BOOST_REQUIRE(record.d_class == QClass::IN); + auto content = std::dynamic_pointer_cast(record.d_content); + BOOST_REQUIRE(content); + BOOST_CHECK_EQUAL(content->numberOfTypesSet(), 0); + for (size_t idx = 0; idx < 65536; idx++) { + BOOST_CHECK_EQUAL(content->isSet(idx), false); + } + auto str2 = content->getZoneRepresentation(); + boost::to_lower(str2); + BOOST_CHECK_EQUAL(str2, str); + } +} + BOOST_AUTO_TEST_SUITE_END()