]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add unit test for our DNS packet overlay
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 25 Jan 2022 15:32:48 +0000 (16:32 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 10 Oct 2022 07:57:06 +0000 (09:57 +0200)
pdns/dnsdistdist/Makefile.am
pdns/dnsdistdist/test-dnsdist-dnsparser.cc [new file with mode: 0644]

index a6c08bc813d2d4a4219cd63d4f94cf2b80ce4c72..58dc706400cba5271e2915b84a10c72e7dec4677 100644 (file)
@@ -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 (file)
index 0000000..a20dd82
--- /dev/null
@@ -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 <boost/test/unit_test.hpp>
+
+#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<PacketBuffer> 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<const char*>(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();