]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: take into account that NSEC3 can be reversed
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 1 Oct 2025 09:55:40 +0000 (11:55 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 16 Feb 2026 13:13:46 +0000 (14:13 +0100)
In that case a short common prefix signifies a large range

Signed-off-by: Otto Moerbeek <otto.moerbeek@open-xchange.com>
pdns/recursordist/aggressive_nsec.cc
pdns/recursordist/test-aggressive_nsec_cc.cc

index 513b8665db92743d233a2e302d9b008bef4ae8d8..6f6f77e2506c619a28555fb25ee824834dcb86df 100644 (file)
@@ -23,6 +23,7 @@
 #include <climits>
 
 #include "aggressive_nsec.hh"
+#include "base64.hh"
 #include "cachecleaner.hh"
 #include "recursor_cache.hh"
 #include "logger.hh"
@@ -231,16 +232,19 @@ static bool commonPrefixIsLong(const string& one, const string& two, size_t boun
   const auto minLength = std::min(one.length(), two.length());
 
   for (size_t i = 0; i < minLength; i++) {
-    const auto byte1 = one.at(i);
-    const auto byte2 = two.at(i);
+    const uint8_t byte1 = one.at(i);
+    const uint8_t byte2 = two.at(i);
     // shortcut
     if (byte1 == byte2) {
       length += CHAR_BIT;
-      if (length > bound) {
-        return true;
-      }
       continue;
     }
+    if (byte1 > byte2) { // order is reversed, implies large number of hashes covered
+      return false;
+    }
+    if (length > bound) {
+      return true;
+    }
     // bytes differ, let's look at the bits
     for (ssize_t j = CHAR_BIT - 1; j >= 0; j--) {
       const auto bit1 = byte1 & (1 << j);
index 04a501e8df79d45e38621ac887c37966cb672708..63a44201e9b1cd2aa5cbdcee2ab0c919b08f8a9a 100644 (file)
@@ -24,6 +24,7 @@ BOOST_AUTO_TEST_CASE(test_small_covering_nsec3)
     {"8ujhshp2lhmnpoo9qde4blg4gq3hgl99", "8ujhshp2lhmnpoo9qde4blg4gq3hgl99", 0, false},
     {"8ujhshp2lhmnpoo9qde4blg4gq3hgl99", "8ujhshp2lhmnpoo9qde4blg4gq3hgl99", 1, false},
     {"8ujhshp2lhmnpoo9qde4blg4gq3hgl99", "8ujhshp2lhmnpoo9qde4blg4gq3hgl99", 157, false},
+    {"e731tdlrdip60smlihgnprqdspq0idlp", "e731tcnkl5al8t4r64b292blt4c37j3h", 1, false}, // note order: 1st > 2nd
   };
 
   for (const auto& [owner, next, boundary, result] : table) {