]> granicus.if.org Git - pdns/commitdiff
dnsdist: Don't leak a FD if the TCP connection to the backend fails
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 9 Dec 2016 16:09:25 +0000 (17:09 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 9 Dec 2016 16:09:25 +0000 (17:09 +0100)
pdns/dnsdist-tcp.cc

index a805b8906e414c532c40366d50a70ca7dc910791..13d2c8d3319f5757a66fc73a84a79a96dbe15579 100644 (file)
@@ -51,12 +51,19 @@ static int setupTCPDownstream(shared_ptr<DownstreamState> ds)
 {  
   vinfolog("TCP connecting to downstream %s", ds->remote.toStringWithPort());
   int sock = SSocket(ds->remote.sin4.sin_family, SOCK_STREAM, 0);
-  if (!IsAnyAddress(ds->sourceAddr)) {
-    SSetsockopt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
-    SBind(sock, ds->sourceAddr);
+  try {
+    if (!IsAnyAddress(ds->sourceAddr)) {
+      SSetsockopt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
+      SBind(sock, ds->sourceAddr);
+    }
+    SConnect(sock, ds->remote);
+    setNonBlocking(sock);
+  }
+  catch(const std::runtime_error& e) {
+    /* don't leak our file descriptor if SConnect() (for example) throws */
+    close(sock);
+    throw;
   }
-  SConnect(sock, ds->remote);
-  setNonBlocking(sock);
   return sock;
 }