]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Refactor `DNSName::matches` around `pdns_ilexicographical_compare_three_way` 16020/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 21 Aug 2025 14:40:29 +0000 (16:40 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 22 Aug 2025 13:12:35 +0000 (15:12 +0200)
And rename it to hopefully prevent any confusion regarding when it can be used.

Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
(cherry picked from commit f78521d7f73d1f176602e33d03fae6e40fa86602)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dnsdistdist/dnsdist.cc
pdns/dnsname.cc
pdns/dnsname.hh
pdns/test-dnsname_cc.cc

index d8ef6def64c99923df9a6caf4d808f351c60409a..0392f4de5a79b9369331e421dce1362bae2b89ac 100644 (file)
@@ -294,7 +294,7 @@ bool responseContentMatches(const PacketBuffer& response, const DNSName& qname,
 
     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-bounds-pointer-arithmetic)
     const std::string_view packetView(reinterpret_cast<const char*>(response.data() + sizeof(dnsheader)), response.size() - sizeof(dnsheader));
-    if (qname.matches(packetView)) {
+    if (qname.matchesUncompressedName(packetView)) {
       size_t pos = sizeof(dnsheader) + qname.wirelength();
       rqtype = response.at(pos) * 256 + response.at(pos + 1);
       rqclass = response.at(pos + 2) * 256 + response.at(pos + 3);
index ceb93d43dcc8051990a024c26f98431315e03e8a..7794ff8e98171cc0d7fff0af0e6c11bb66c8c930 100644 (file)
@@ -732,22 +732,13 @@ bool DNSName::RawLabelsVisitor::empty() const
   return d_position == 0;
 }
 
-bool DNSName::matches(const std::string_view& wire_uncompressed) const
+bool DNSName::matchesUncompressedName(const std::string_view& wire_uncompressed) const
 {
   if (wire_uncompressed.empty() != empty() || wire_uncompressed.size() < d_storage.size()) {
     return false;
   }
 
-  const auto* our = d_storage.cbegin();
-  const auto* other = wire_uncompressed.cbegin();
-  // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
-  for (; our != d_storage.cend() && other != wire_uncompressed.cend(); ++our, ++other) {
-    if (dns_tolower(*other) != dns_tolower(*our)) {
-      return false;
-    }
-  }
-
-  return our == d_storage.cend();
+  return pdns_ilexicographical_compare_three_way(std::string_view(wire_uncompressed.data(), d_storage.size()), d_storage) == 0;
 }
 
 #if defined(PDNS_AUTH) // [
index b09a004b5c44c26343f869836de3ef29a42150e5..125aa92b666fa0f7beb5b0553c6343a44637cba7 100644 (file)
@@ -112,8 +112,8 @@ public:
   bool isPartOf(const DNSName& rhs) const;   //!< Are we part of the rhs name? Note that name.isPartOf(name).
   inline bool operator==(const DNSName& rhs) const; //!< DNS-native comparison (case insensitive) - empty compares to empty
   bool operator!=(const DNSName& other) const { return !(*this == other); }
-  // !< DNS-native (case insensitive) comparison against raw data in wire format. The view has to start with the DNS name, but does not have to contain only a DNS name. For example passing a view of a DNS packet starting just after the DNS header is OK.
-  bool matches(const std::string_view& wire_uncompressed) const;
+  // !< DNS-native (case insensitive) comparison against raw data in (uncompressed) wire format. The view has to start with the DNS name, but does not have to contain only a DNS name. Roughly, passing a view of a DNS packet starting just after the DNS header is OK, everything else is not because any names present later in the packet might be compressed.
+  bool matchesUncompressedName(const std::string_view& wire_uncompressed) const;
 
   std::string toString(const std::string& separator=".", const bool trailing=true) const;              //!< Our human-friendly, escaped, representation
   void toString(std::string& output, const std::string& separator=".", const bool trailing=true) const;
index 846e08a1a662dc2710dd0f8ccd34101810fef232..666327ac31cba4ee67254c1f4cb16703b13516e5 100644 (file)
@@ -1040,24 +1040,24 @@ BOOST_AUTO_TEST_CASE(test_raw_data_comparison) {
   {
     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-bounds-pointer-arithmetic)
     const std::string_view raw(reinterpret_cast<const char*>(query.data()) + sizeof(dnsheader), query.size() - sizeof(dnsheader));
-    BOOST_CHECK(aroot.matches(raw));
+    BOOST_CHECK(aroot.matchesUncompressedName(raw));
 
     const DNSName differentCase("A.RooT-Servers.NET");
-    BOOST_CHECK(differentCase.matches(raw));
+    BOOST_CHECK(differentCase.matchesUncompressedName(raw));
 
     const DNSName broot("b.root-servers.net");
-    BOOST_CHECK(!(broot.matches(raw)));
+    BOOST_CHECK(!(broot.matchesUncompressedName(raw)));
 
     /* last character differs */
     const DNSName notaroot("a.root-servers.nes");
-    BOOST_CHECK(!(notaroot.matches(raw)));
+    BOOST_CHECK(!(notaroot.matchesUncompressedName(raw)));
   }
 
   {
     /* too short */
     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-bounds-pointer-arithmetic)
     const std::string_view raw(reinterpret_cast<const char*>(query.data() + sizeof(dnsheader)), aroot.wirelength() - 1);
-    BOOST_CHECK(!(aroot.matches(raw)));
+    BOOST_CHECK(!(aroot.matchesUncompressedName(raw)));
   }
 }