]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Properly account the failure to forward a query to a backend
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 19 Mar 2024 09:44:16 +0000 (10:44 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 19 Mar 2024 09:44:16 +0000 (10:44 +0100)
Manually backported from b0b3480b98d41db821f681183f45d5d08db02f93

pdns/dnsdist.cc

index 3c32201abafaaa0ac092fb95cb2a699828a4f735..7b421236cd01f9c3298512a7b203a96658eb8035 100644 (file)
@@ -1236,34 +1236,37 @@ static bool applyRulesToQuery(LocalHolders& holders, DNSQuestion& dq, const stru
   return true;
 }
 
-ssize_t udpClientSendRequestToBackend(const std::shared_ptr<DownstreamState>& ss, const int sd, const PacketBuffer& request, bool healthCheck)
+ssize_t udpClientSendRequestToBackend(const std::shared_ptr<DownstreamState>& backend, const int sd, const PacketBuffer& request, bool healthCheck)
 {
   ssize_t result;
 
-  if (ss->d_config.sourceItf == 0) {
+  if (backend->d_config.sourceItf == 0) {
     result = send(sd, request.data(), request.size(), 0);
   }
   else {
     struct msghdr msgh;
     struct iovec iov;
     cmsgbuf_aligned cbuf;
-    ComboAddress remote(ss->d_config.remote);
+    ComboAddress remote(backend->d_config.remote);
     fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), const_cast<char*>(reinterpret_cast<const char *>(request.data())), request.size(), &remote);
-    addCMsgSrcAddr(&msgh, &cbuf, &ss->d_config.sourceAddr, ss->d_config.sourceItf);
+    addCMsgSrcAddr(&msgh, &cbuf, &backend->d_config.sourceAddr, backend->d_config.sourceItf);
     result = sendmsg(sd, &msgh, 0);
   }
 
   if (result == -1) {
     int savederrno = errno;
-    vinfolog("Error sending request to backend %s: %s", ss->d_config.remote.toStringWithPort(), stringerror(savederrno));
+    vinfolog("Error sending request to backend %s: %s", backend->d_config.remote.toStringWithPort(), stringerror(savederrno));
 
     /* This might sound silly, but on Linux send() might fail with EINVAL
        if the interface the socket was bound to doesn't exist anymore.
        We don't want to reconnect the real socket if the healthcheck failed,
        because it's not using the same socket.
     */
-    if (!healthCheck && (savederrno == EINVAL || savederrno == ENODEV || savederrno == ENETUNREACH || savederrno == EBADF)) {
-      ss->reconnect();
+    if (!healthCheck) {
+      if (savederrno == EINVAL || savederrno == ENODEV || savederrno == ENETUNREACH || savederrno == EBADF) {
+        backend->reconnect();
+      }
+      backend->reportTimeoutOrError();
     }
   }