]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Only set the proxy protocol payload size when actually added
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 7 May 2025 08:52:56 +0000 (10:52 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Sun, 18 May 2025 09:56:32 +0000 (11:56 +0200)
I can think of two cases where we got this wrong:
- the query was initially assigned to a backend using the proxy protocol
  payload, then later restarted and assigned to a backend not using it.
  The proxy protocol payload size was then kept from the first assignment.
- we failed to actually prepend the proxy protocol payload but the payload
  size was updated.

Both cases could cause a corrupted payload to be sent, or an exception to
be raised if the size of the proxy protocol payload was larger than the
size of the initial query.

(cherry picked from commit 8768b9176dafc793fc3f0867c2d8964eb65378f0)

pdns/dnsdist.cc
pdns/dnsdistdist/dnsdist-proxy-protocol.cc
pdns/dnsdistdist/dnsdist-proxy-protocol.hh

index cb08775fafe5aa444327866067e1b0f51b900af6..45ed3c3e78971d9ac41b91c05da125e1f1b77196 100644 (file)
@@ -1696,9 +1696,13 @@ bool assignOutgoingUDPQueryToBackend(std::shared_ptr<DownstreamState>& downstrea
   bool doh = dnsQuestion.ids.du != nullptr;
 
   bool failed = false;
+  dnsQuestion.ids.d_proxyProtocolPayloadSize = 0;
   if (downstream->d_config.useProxyProtocol) {
     try {
-      addProxyProtocol(dnsQuestion, &dnsQuestion.ids.d_proxyProtocolPayloadSize);
+      size_t proxyProtocolPayloadSize = 0;
+      if (addProxyProtocol(dnsQuestion, &proxyProtocolPayloadSize)) {
+        dnsQuestion.ids.d_proxyProtocolPayloadSize = proxyProtocolPayloadSize;
+      }
     }
     catch (const std::exception& e) {
       vinfolog("Adding proxy protocol payload to %s query from %s failed: %s", (dnsQuestion.ids.du ? "DoH" : ""), dnsQuestion.ids.origDest.toStringWithPort(), e.what());
index d19e87206e2f47249a97f4ec6e6a3efda17d2a5e..f78d86f78055a9b7421952ae6269bd3c10f1acd0 100644 (file)
@@ -42,14 +42,19 @@ bool addProxyProtocol(DNSQuestion& dq, const std::string& payload)
   return addProxyProtocol(dq.getMutableData(), payload);
 }
 
-bool addProxyProtocol(DNSQuestion& dq, size_t* payloadSize)
+bool addProxyProtocol(DNSQuestion& dnsQuestion, size_t* proxyProtocolPayloadSize)
 {
-  auto payload = getProxyProtocolPayload(dq);
-  if (payloadSize != nullptr) {
-    *payloadSize = payload.size();
+  auto payload = getProxyProtocolPayload(dnsQuestion);
+  size_t payloadSize = payload.size();
+
+  if (!addProxyProtocol(dnsQuestion, payload)) {
+    return false;
   }
 
-  return addProxyProtocol(dq, payload);
+  if (proxyProtocolPayloadSize != nullptr) {
+    *proxyProtocolPayloadSize = payloadSize;
+  }
+  return true;
 }
 
 bool addProxyProtocol(PacketBuffer& buffer, const std::string& payload)
index de7674a2dbaa27069bf0f79b32db85f62d6f3fd4..2775ed8cb0aa6f9a8278bb3698d74310dd963b8a 100644 (file)
@@ -29,7 +29,7 @@ extern bool g_applyACLToProxiedClients;
 
 std::string getProxyProtocolPayload(const DNSQuestion& dq);
 
-bool addProxyProtocol(DNSQuestion& dq, size_t* proxyProtocolPayloadSize = nullptr);
+bool addProxyProtocol(DNSQuestion& dnsQuestion, size_t* proxyProtocolPayloadSize = nullptr);
 bool addProxyProtocol(DNSQuestion& dq, const std::string& payload);
 bool addProxyProtocol(PacketBuffer& buffer, const std::string& payload);
 bool addProxyProtocol(PacketBuffer& buffer, bool tcp, const ComboAddress& source, const ComboAddress& destination, const std::vector<ProxyProtocolValue>& values);