From: Remi Gacogne Date: Tue, 25 Jan 2022 15:32:48 +0000 (+0100) Subject: dnsdist: Add unit test for our DNS packet overlay X-Git-Tag: dnsdist-1.8.0-rc1~283^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f05fbb73ae678d6c1f6ac6cffb621382cd8919e3;p=thirdparty%2Fpdns.git dnsdist: Add unit test for our DNS packet overlay --- diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index a6c08bc813..58dc706400 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -301,6 +301,7 @@ testrunner_SOURCES = \ test-delaypipe_hh.cc \ test-dnscrypt_cc.cc \ test-dnsdist-connections-cache.cc \ + test-dnsdist-dnsparser.cc \ test-dnsdist_cc.cc \ test-dnsdistdynblocks_hh.cc \ test-dnsdistkvs_cc.cc \ diff --git a/pdns/dnsdistdist/test-dnsdist-dnsparser.cc b/pdns/dnsdistdist/test-dnsdist-dnsparser.cc new file mode 100644 index 0000000000..a20dd82650 --- /dev/null +++ b/pdns/dnsdistdist/test-dnsdist-dnsparser.cc @@ -0,0 +1,105 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_NO_MAIN + +#include + +#include "dnsdist-dnsparser.hh" +#include "dnswriter.hh" +#include "dnsparser.hh" + +BOOST_AUTO_TEST_SUITE(test_dnsdist_dnsparser) + +BOOST_AUTO_TEST_CASE(test_Overlay) +{ + const DNSName target("powerdns.com."); + + { + PacketBuffer response; + GenericDNSPacketWriter pwR(response, target, QType::ANY, QClass::IN, 0); + pwR.getHeader()->qr = 1; + pwR.getHeader()->rd = 1; + pwR.getHeader()->ra = 1; + pwR.getHeader()->id = htons(42); + pwR.startRecord(target, QType::A, 7200, QClass::IN, DNSResourceRecord::ANSWER); + ComboAddress v4("192.0.2.1"); + pwR.xfrCAWithoutPort(4, v4); + pwR.commit(); + pwR.startRecord(target, QType::AAAA, 7200, QClass::IN, DNSResourceRecord::ANSWER); + ComboAddress v6("2001:db8::1"); + pwR.xfrCAWithoutPort(6, v6); + pwR.commit(); + pwR.startRecord(target, QType::NS, 7200, QClass::IN, DNSResourceRecord::ANSWER); + pwR.xfrName(DNSName("pdns-public-ns1.powerdns.com.")); + pwR.commit(); + pwR.startRecord(target, QType::SOA, 7200, QClass::IN, DNSResourceRecord::ANSWER); + pwR.xfrName(DNSName("pdns-public-ns1.powerdns.com.")); + pwR.xfrName(DNSName("admin.powerdns.com.")); + pwR.xfr32BitInt(1); + pwR.xfr32BitInt(2); + pwR.xfr32BitInt(3); + pwR.xfr32BitInt(4); + pwR.xfr32BitInt(5); + pwR.commit(); + pwR.startRecord(target, QType::MX, 7200, QClass::IN, DNSResourceRecord::ANSWER); + pwR.xfr16BitInt(75); + pwR.xfrName(DNSName("download1.powerdns.com.")); + pwR.commit(); + pwR.startRecord(target, QType::TXT, 7200, QClass::IN, DNSResourceRecord::ANSWER); + pwR.xfrText("\"random text\""); + pwR.commit(); + pwR.addOpt(4096, 0, 0); + pwR.commit(); + + dnsdist::DNSPacketOverlay overlay(std::string_view(reinterpret_cast(response.data()), response.size())); + BOOST_CHECK_EQUAL(overlay.d_qname, target); + BOOST_CHECK_EQUAL(overlay.d_qtype, QType::ANY); + BOOST_CHECK_EQUAL(overlay.d_qclass, QClass::IN); + BOOST_CHECK_EQUAL(overlay.d_header.qr, 1U); + BOOST_CHECK_EQUAL(overlay.d_header.rd, 1U); + BOOST_CHECK_EQUAL(overlay.d_header.ra, 1U); + BOOST_CHECK_EQUAL(overlay.d_header.id, htons(42)); + BOOST_CHECK_EQUAL(ntohs(overlay.d_header.qdcount), 1U); + BOOST_CHECK_EQUAL(ntohs(overlay.d_header.ancount), 6U); + BOOST_CHECK_EQUAL(ntohs(overlay.d_header.nscount), 0U); + BOOST_CHECK_EQUAL(ntohs(overlay.d_header.arcount), 1U); + BOOST_CHECK_EQUAL(overlay.d_records.size(), 7U); + + /* this is off, of course, but we are only doing a sanity check here */ + uint16_t lastOffset = sizeof(dnsheader) + target.wirelength() + sizeof(uint16_t) + sizeof(uint16_t); + for (const auto& record : overlay.d_records) { + if (record.d_type == QType::OPT) { + continue; + } + + BOOST_CHECK_EQUAL(record.d_name, target); + BOOST_CHECK_EQUAL(record.d_class, QClass::IN); + BOOST_CHECK_EQUAL(record.d_ttl, 7200); + BOOST_CHECK_EQUAL(record.d_place, 1U); + BOOST_CHECK_GE(record.d_contentOffset, lastOffset); + lastOffset = record.d_contentOffset + record.d_contentLength; + } + } +} + +BOOST_AUTO_TEST_SUITE_END();