fix memory leak in AsyncServerSocket
authorMark McDuff <mcduff@fb.com>
Sat, 24 Jan 2015 09:23:20 +0000 (01:23 -0800)
committerwoo <woo@fb.com>
Mon, 2 Feb 2015 21:12:36 +0000 (13:12 -0800)
Test Plan: g-unittest

Reviewed By: philipp@fb.com

Subscribers: folly-diffs@

FB internal diff: D1801665

Signature: t1:1801665:1422093104:eecf86ea8c1ab39dcb3d01442ed66ae45ef3bede

folly/io/async/AsyncServerSocket.cpp

index 5b5ca6192e13bc428405ed7977d0f87e33c64903..11779e56c030a4ecc86c76b56441e93a1fe6cb9b 100644 (file)
@@ -397,13 +397,6 @@ void AsyncServerSocket::bind(uint16_t port) {
         errno,
         "failed to bind to async server socket for port");
     }
-
-    if (port == 0) {
-      address.setFromLocalAddress(s);
-      snprintf(sport, sizeof(sport), "%u", address.getPort());
-      CHECK(!getaddrinfo(nullptr, sport, &hints, &res0));
-    }
-
   };
 
   for (int tries = 1; true; tries++) {
@@ -419,6 +412,16 @@ void AsyncServerSocket::bind(uint16_t port) {
       }
     }
 
+    // If port == 0, then we should try to bind to the same port on ipv4 and
+    // ipv6.  So if we did bind to ipv6, figure out that port and use it.
+    if (!sockets_.empty() && port == 0) {
+      SocketAddress address;
+      address.setFromLocalAddress(sockets_.back().socket_);
+      snprintf(sport, sizeof(sport), "%u", address.getPort());
+      freeaddrinfo(res0);
+      CHECK_EQ(0, getaddrinfo(nullptr, sport, &hints, &res0));
+    }
+
     try {
       for (res = res0; res; res = res->ai_next) {
         if (res->ai_family != AF_INET6) {
@@ -432,12 +435,13 @@ void AsyncServerSocket::bind(uint16_t port) {
       if (port == 0 && !sockets_.empty() && tries != 3) {
         for (const auto& socket : sockets_) {
           if (socket.socket_ > 0) {
-            CHECK(::close(socket.socket_) == 0);
+            CHECK_EQ(0, ::close(socket.socket_));
           }
         }
         sockets_.clear();
         snprintf(sport, sizeof(sport), "%u", port);
-        CHECK(!getaddrinfo(nullptr, sport, &hints, &res0));
+        freeaddrinfo(res0);
+        CHECK_EQ(0, getaddrinfo(nullptr, sport, &hints, &res0));
         continue;
       }
       throw;