]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Enable PMTU discovery and disable fragmentation on QUIC binds 13676/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 8 Jan 2024 11:51:07 +0000 (12:51 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 8 Jan 2024 14:09:03 +0000 (15:09 +0100)
pdns/dnsdist.cc
pdns/iputils.cc
pdns/iputils.hh

index e4283a84cdfdaf50b65d5e73a5b256d81c912cea..378cd751c368c877a01ded8810f15a4c45a01cb6 100644 (file)
@@ -2360,10 +2360,20 @@ static void setupLocalSocket(ClientState& clientState, const ComboAddress& addr,
     }
   }
 
-  /* Only set this on IPv4 UDP sockets.
-     Don't set it for DNSCrypt binds. DNSCrypt pads queries for privacy
-     purposes, so we do receive large, sometimes fragmented datagrams. */
-  if (!tcp && !clientState.dnscryptCtx) {
+  const bool isQUIC = clientState.doqFrontend != nullptr || clientState.doh3Frontend != nullptr;
+  if (isQUIC) {
+    /* disable fragmentation and force PMTU discovery for QUIC-enabled sockets */
+    try {
+      setSocketForcePMTU(socket, addr.sin4.sin_family);
+    }
+    catch (const std::exception& e) {
+      warnlog("Failed to set IP_MTU_DISCOVER on QUIC server socket for local address '%s': %s", addr.toStringWithPort(), e.what());
+    }
+  }
+  else if (!tcp && !clientState.dnscryptCtx) {
+    /* Only set this on IPv4 UDP sockets.
+       Don't set it for DNSCrypt binds. DNSCrypt pads queries for privacy
+       purposes, so we do receive large, sometimes fragmented datagrams. */
     try {
       setSocketIgnorePMTU(socket, addr.sin4.sin_family);
     }
index 2f629cbfa19d4f49cf63399de03bb984771e0f5f..55d8daad5a363f5c54d92320c0118682ffb1447b 100644 (file)
@@ -192,6 +192,27 @@ void setSocketIgnorePMTU([[maybe_unused]] int sockfd, [[maybe_unused]] int famil
   }
 }
 
+void setSocketForcePMTU([[maybe_unused]] int sockfd, [[maybe_unused]] int family)
+{
+  if (family == AF_INET) {
+#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
+    /* IP_PMTUDISC_DO enables Path MTU discovery and prevents fragmentation */
+    SSetsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DO);
+#elif defined(IP_DONTFRAG)
+    /* at least this prevents fragmentation */
+    SSetsockopt(sockfd, IPPROTO_IP, IP_DONTFRAG, 1);
+#endif /* defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) */
+  }
+  else {
+#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
+    /* IPV6_PMTUDISC_DO enables Path MTU discovery and prevents fragmentation */
+    SSetsockopt(sockfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, IPV6_PMTUDISC_DO);
+#elif defined(IPV6_DONTFRAG)
+    /* at least this prevents fragmentation */
+    SSetsockopt(sockfd, IPPROTO_IPV6, IPV6_DONTFRAG, 1);
+#endif /* defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) */
+  }
+}
 
 bool setReusePort(int sockfd)
 {
index 2a5b21544eaab64eabaead765e1d96241b53587e..ade4c82a301888e0756960b13c63b20e4a73c65f 100644 (file)
@@ -1699,6 +1699,7 @@ int SAccept(int sockfd, ComboAddress& remote);
 int SListen(int sockfd, int limit);
 int SSetsockopt(int sockfd, int level, int opname, int value);
 void setSocketIgnorePMTU(int sockfd, int family);
+void setSocketForcePMTU(int sockfd, int family);
 bool setReusePort(int sockfd);
 
 #if defined(IP_PKTINFO)