]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
four states: unknown, supported, unsupported and probing
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 21 Mar 2025 08:51:11 +0000 (09:51 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Thu, 4 Sep 2025 09:05:16 +0000 (11:05 +0200)
pdns/recursordist/lwres.cc
pdns/recursordist/meson.build
pdns/recursordist/rec-cookiestore.cc
pdns/recursordist/rec-cookiestore.hh

index b6786fede063b1e6539cbf3f2ffdf1ee5107c747..74a4f4c6f384550c201e4c33550923f471317faf 100644 (file)
@@ -485,24 +485,30 @@ static LWResult::Result asyncresolve(const ComboAddress& address, const DNSName&
       auto lock = s_cookiestore.lock();
       auto found = lock->find(address);
       if (found != lock->end()) {
-        if (found->d_support) {
+        switch (found->getSupport()) {
+        case CookieEntry::Support::Supported:
+        case CookieEntry::Support::Probing:
           cookieSentOut = found->d_cookie;
           addressToBindTo = found->d_localaddress;
           opts.emplace_back(EDNSOptionCode::COOKIE, cookieSentOut->makeOptString());
           found->d_lastupdate = now->tv_sec;
           cerr << "Sending stored cookie info to " << address.toString() << ": " << found->d_cookie.toDisplayString() << endl;
-        }
-        else {
-          cerr << "This server does not support cookies" << endl;
+          break;
+        case CookieEntry::Support::Unknown:
+          assert(0);
+        case CookieEntry::Support::Unsupported:
+        default:
+          cerr << "This server does not support cookies or we don't know yet:" << endl;
         }
       }
       else {
+        // Server not in table
         CookieEntry entry;
         entry.d_address = address;
         entry.d_cookie.makeClientCookie();
         cookieSentOut = entry.d_cookie;
         entry.d_lastupdate = now->tv_sec;
-        entry.d_support = false;
+        entry.setSupport(CookieEntry::Support::Probing);
         lock->emplace(entry);
         opts.emplace_back(EDNSOptionCode::COOKIE, cookieSentOut->makeOptString());
         cerr << "We're sending new client cookie info from to " << address.toString() << ": " << entry.d_cookie.toDisplayString() << endl;
@@ -735,7 +741,7 @@ static LWResult::Result asyncresolve(const ComboAddress& address, const DNSName&
                   found->d_localaddress = localip;
                   found->d_cookie = received;
                   found->d_lastupdate = now->tv_sec;
-                  found->d_support = true;
+                  found->setSupport(CookieEntry::Support::Supported);
                   uint16_t ercode = (edo.d_extRCode << 4) | lwr->d_rcode;
                   if (ercode == ERCode::BADCOOKIE) {
                     lwr->d_validpacket = true;
@@ -750,7 +756,7 @@ static LWResult::Result asyncresolve(const ComboAddress& address, const DNSName&
                 }
               }
               else {
-                // We sent a cookie out but forgot it?
+                // We sent a cookie out but it's not in the table?
                 cerr << "Cookie not found back"<< endl;
                 lwr->d_validpacket = true;
                 return LWResult::Result::BadCookie; // XXX
index 241d2665b3fd5db74df7d547c40f99e42891d06f..74dfd3d1434debc32f07966e516e698f9a2ed5ba 100644 (file)
@@ -153,6 +153,7 @@ common_sources += files(
   src_dir / 'rec-zonetocache.cc',
   src_dir / 'rec_channel.cc',
   src_dir / 'rec_channel_rec.cc',
+  src_dir / 'rec-cookiestore.cc',
   src_dir / 'rec-xfr.cc',
   src_dir / 'rec-xfrtracker.cc',
   src_dir / 'recpacketcache.cc',
index 321b9c0909189ab5747607011c0776d87637234b..adda2ecbb37b71c78d3f3af707f1dd258c9db617 100644 (file)
@@ -53,7 +53,7 @@ uint64_t CookieStore::dump(const CookieStore& copy, int fileDesc)
     fprintf(filePtr.get(), "%s\t%s\t%s\t%s\t%s\n",
             entry.d_address.toString().c_str(), entry.d_localaddress.toString().c_str(),
             entry.d_cookie.toDisplayString().c_str(),
-            entry.d_support ? "yes" : "no",
+            CookieEntry::toString(entry.d_support).c_str(),
             timestamp(entry.d_lastupdate, tmp));
   }
   return count;
index a78810ad535978b62a4af2dffbc0bf8e9d39810a..d79221c4c03b18a32f40e0f8db8e572653894fae 100644 (file)
@@ -52,11 +52,48 @@ using namespace ::boost::multi_index;
 
 struct CookieEntry
 {
+  enum class Support : uint8_t
+  {
+    Unknown,
+    Unsupported,
+    Supported,
+    Probing
+  };
+
+  static std::string toString(Support support)
+  {
+    static const std::array<std::string, 4> names = {
+      "Unknown",
+      "Unsupported",
+      "Supported",
+      "Probing"};
+    const auto index = static_cast<uint8_t>(support);
+    if (index >= names.size()) {
+      return "?";
+    }
+    return names.at(index);
+  }
+
+  Support getSupport() const
+  {
+    return d_support;
+  }
+
+  void setSupport(Support support) const // modifying mutable field
+  {
+    d_support = support;
+  }
+
+  bool supported() const
+  {
+    return d_support == Support::Supported;
+  }
+
   ComboAddress d_address;
   mutable ComboAddress d_localaddress; // The address we were bound to, see RFC 9018
   mutable EDNSCookiesOpt d_cookie; // Contains both client and server cookie
   mutable time_t d_lastupdate{};
-  mutable bool d_support;
+  mutable Support d_support{Support::Unknown};
 };
 
 class CookieStore : public multi_index_container < CookieEntry,