]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Do not oversize the received buffer with `recvmmsg`
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 2 Apr 2026 08:17:41 +0000 (10:17 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 2 Apr 2026 08:17:41 +0000 (10:17 +0200)
Passing `MSG_TRUNC` to `recvmmsg` causes the Linux kernel to report
the real size of the datagram even if it was longer than the passed
buffer, which is not what we want here as it would be wasteful to
resize our internal buffer to this size.

This was reported by komaku in #YWH-PGM6095-172, many thanks!.

Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dnsdistdist/dnsdist.cc

index cb933605734a067b387fc8e3a79727a2a653e478..1475553932a24fb518b12d6597e1de4c0c6ac4d6 100644 (file)
@@ -2287,7 +2287,7 @@ static void MultipleMessagesUDPClientThread(ClientState* clientState)
 
     /* block until we have at least one message ready, but return
        as many as possible to save the syscall costs */
-    msgsGot = recvmmsg(clientState->udpFD, msgVec.data(), vectSize, MSG_WAITFORONE | MSG_TRUNC, nullptr);
+    msgsGot = recvmmsg(clientState->udpFD, msgVec.data(), vectSize, MSG_WAITFORONE, nullptr);
     if (msgsGot <= 0) {
       int savederrno = errno;
       VERBOSESLOG(infolog("Getting UDP messages via recvmmsg() failed with: %s", stringerror(savederrno)),
@@ -2311,6 +2311,13 @@ static void MultipleMessagesUDPClientThread(ClientState* clientState)
         continue;
       }
 
+      if ((msgh->msg_flags & MSG_TRUNC) != 0) {
+        /* message was too large for our buffer */
+        ++clientState->nonCompliantQueries;
+        ++dnsdist::metrics::g_stats.nonCompliantQueries;
+        continue;
+      }
+
       auto& data = recvData[msgIdx];
       data.packet.resize(got);
       dnsdist::configuration::refreshLocalRuntimeConfiguration();