]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Add unit tests for Extended DNS Errors
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 10 Nov 2020 11:39:13 +0000 (12:39 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 18 Nov 2020 08:18:51 +0000 (09:18 +0100)
pdns/recursordist/Makefile.am
pdns/recursordist/ednsextendederror.cc
pdns/recursordist/test-ednsoptions_cc.cc

index eb8fc7c39b8ebf49bd7b6da7e6eb04a4039e97a9..141fcf578083bd391a64c46a130b5f443d1eec58 100644 (file)
@@ -243,6 +243,7 @@ testrunner_SOURCES = \
        dnsseckeeper.hh \
        dnswriter.cc dnswriter.hh \
        ednscookies.cc ednscookies.hh \
+       ednsextendederror.cc ednsextendederror.hh \
        ednsoptions.cc ednsoptions.hh \
        ednssubnet.cc ednssubnet.hh \
        filterpo.cc filterpo.hh \
index 62d3bcc584b02421e1c1ae10461b8f19f35cbbda..9903a0770fd0045bf0c3b8fdb0fa5fc85bc395f1 100644 (file)
@@ -38,7 +38,7 @@ static bool getEDNSExtendedErrorOptFromString(const pdns_string_view option, EDN
 
 bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee)
 {
-  return getEDNSExtendedErrorOptFromString(option, eee);
+  return getEDNSExtendedErrorOptFromString(pdns_string_view(option), eee);
 }
 
 bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee)
@@ -48,6 +48,10 @@ bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDN
 
 string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee)
 {
+  if (eee.extraText.size() > static_cast<size_t>(std::numeric_limits<uint16_t>::max() - 2)) {
+    throw std::runtime_error("Trying to create an EDNS Extended Error option with an extra text of size " + std::to_string(eee.extraText.size()));
+  }
+
   string ret;
   ret.reserve(sizeof(uint16_t) + eee.extraText.size());
   ret.resize(sizeof(uint16_t));
index d653526d7a61258756d1b9d700aabb945754028c..433cb0b4c76837aa07f2a89558def840135c7060 100644 (file)
@@ -10,6 +10,7 @@
 #include "dnsname.hh"
 #include "dnswriter.hh"
 #include "ednscookies.hh"
+#include "ednsextendederror.hh"
 #include "ednsoptions.hh"
 #include "ednssubnet.hh"
 #include "iputils.hh"
@@ -162,7 +163,6 @@ static void checkECSOptionValidity(const std::string& sourceStr, uint8_t sourceM
 
 BOOST_AUTO_TEST_CASE(test_makeEDNSSubnetOptsString)
 {
-
   checkECSOptionValidity("192.0.2.255", 0, 0);
   checkECSOptionValidity("192.0.2.255", 8, 0);
   checkECSOptionValidity("255.255.255.255", 9, 0);
@@ -174,4 +174,42 @@ BOOST_AUTO_TEST_CASE(test_makeEDNSSubnetOptsString)
   checkECSOptionValidity("2001:DB8::FFFF", 128, 0);
 }
 
+static void checkExtendedErrorOptionValidity(EDNSExtendedError::code code, const std::string& extra)
+{
+  EDNSExtendedError eee;
+  eee.infoCode = static_cast<uint16_t>(code);
+  eee.extraText = extra;
+
+  const auto optionStr = makeEDNSExtendedErrorOptString(eee);
+  BOOST_REQUIRE_EQUAL(optionStr.size(), sizeof(code) + extra.size());
+
+  uint16_t u;
+  memcpy(&u, optionStr.c_str(), sizeof(u));
+  BOOST_CHECK_EQUAL(ntohs(u), static_cast<uint16_t>(code));
+  BOOST_CHECK_EQUAL(optionStr.substr(2), extra);
+
+  EDNSExtendedError parsed;
+  BOOST_REQUIRE(getEDNSExtendedErrorOptFromString(optionStr, parsed));
+  BOOST_CHECK_EQUAL(parsed.infoCode, static_cast<uint16_t>(code));
+  BOOST_CHECK_EQUAL(parsed.extraText, extra);
+}
+
+BOOST_AUTO_TEST_CASE(test_makeEDNSExtendedErrorOptString)
+{
+  checkExtendedErrorOptionValidity(EDNSExtendedError::code::Other, "");
+  checkExtendedErrorOptionValidity(static_cast<EDNSExtendedError::code>(255), "");
+
+  checkExtendedErrorOptionValidity(EDNSExtendedError::code::UnsupportedDNSKEYAlgorithm, "");
+  checkExtendedErrorOptionValidity(EDNSExtendedError::code::UnsupportedDSDigestType, "The digest type of this DS is not supported!");
+
+  std::string extra;
+  /* the size of an EDNS option is limited to 2^16-1, and in this case the code already adds 2 bytes */
+  extra.resize(65535);
+  BOOST_CHECK_THROW(checkExtendedErrorOptionValidity(EDNSExtendedError::code::Other, extra), std::runtime_error);
+
+  EDNSExtendedError parsed;
+  std::string empty;
+  BOOST_CHECK(!getEDNSExtendedErrorOptFromString(empty, parsed));
+}
+
 BOOST_AUTO_TEST_SUITE_END()