]> granicus.if.org Git - pdns/commitdiff
dnsdist: Don't reconnect the socket on healthcheck failure
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 24 May 2018 15:35:39 +0000 (17:35 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 25 May 2018 10:21:23 +0000 (12:21 +0200)
pdns/dnsdist.cc

index aeec6f39b8b53d49ed9f51907d1236c738085bc2..73b013655f1df27e85eea6c6e25cc65b54cbb72b 100644 (file)
@@ -1077,7 +1077,7 @@ bool processResponse(LocalStateHolder<vector<DNSDistResponseRuleAction> >& local
   return true;
 }
 
-static ssize_t udpClientSendRequestToBackend(DownstreamState* ss, const int sd, const char* request, const size_t requestLen)
+static ssize_t udpClientSendRequestToBackend(DownstreamState* ss, const int sd, const char* request, const size_t requestLen, bool healthCheck=false)
 {
   ssize_t result;
 
@@ -1098,8 +1098,11 @@ static ssize_t udpClientSendRequestToBackend(DownstreamState* ss, const int sd,
     vinfolog("Error sending request to backend %s: %d", ss->remote.toStringWithPort(), 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. */
-    if (savederrno == 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)) {
       ss->reconnect();
     }
   }
@@ -1679,7 +1682,7 @@ try
     sock.bind(ds.sourceAddr);
   }
   sock.connect(ds.remote);
-  ssize_t sent = udpClientSendRequestToBackend(&ds, sock.getHandle(), (char*)&packet[0], packet.size());
+  ssize_t sent = udpClientSendRequestToBackend(&ds, sock.getHandle(), (char*)&packet[0], packet.size(), true);
   if (sent < 0) {
     int ret = errno;
     if (g_verboseHealthChecks)