From: Remi Gacogne Date: Thu, 21 Aug 2025 14:40:29 +0000 (+0200) Subject: Refactor `DNSName::matches` around `pdns_ilexicographical_compare_three_way` X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F15931%2Fhead;p=thirdparty%2Fpdns.git Refactor `DNSName::matches` around `pdns_ilexicographical_compare_three_way` And rename it to hopefully prevent any confusion regarding when it can be used. Signed-off-by: Remi Gacogne --- diff --git a/pdns/dnsdistdist/dnsdist.cc b/pdns/dnsdistdist/dnsdist.cc index 57ac5ac98..98c7006e9 100644 --- a/pdns/dnsdistdist/dnsdist.cc +++ b/pdns/dnsdistdist/dnsdist.cc @@ -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(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); diff --git a/pdns/dnsname.cc b/pdns/dnsname.cc index 9d2130410..ec0aef5e4 100644 --- a/pdns/dnsname.cc +++ b/pdns/dnsname.cc @@ -808,22 +808,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) // [ diff --git a/pdns/dnsname.hh b/pdns/dnsname.hh index 5d62f38ea..81cf1b1ae 100644 --- a/pdns/dnsname.hh +++ b/pdns/dnsname.hh @@ -115,8 +115,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; diff --git a/pdns/test-dnsname_cc.cc b/pdns/test-dnsname_cc.cc index 019e864e1..d7ee97b72 100644 --- a/pdns/test-dnsname_cc.cc +++ b/pdns/test-dnsname_cc.cc @@ -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(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(query.data() + sizeof(dnsheader)), aroot.wirelength() - 1); - BOOST_CHECK(!(aroot.matches(raw))); + BOOST_CHECK(!(aroot.matchesUncompressedName(raw))); } }