Adjust AsyncServerSocket to not use getsockname before it's connected
authorOrvid King <blah38621@gmail.com>
Fri, 29 Jan 2016 22:37:19 +0000 (14:37 -0800)
committerfacebook-github-bot-4 <folly-bot@fb.com>
Fri, 29 Jan 2016 23:20:24 +0000 (15:20 -0800)
Summary:
Winsock doesn't like it when you try to call getsockname on a socket that hasn't yet been connected or bound, because that socket doesn't have a name yet.
This only occurred because we were trying to get the family of the socket.
To solve this, I just passed the family in from the parent methods that already knew what the family was.

Reviewed By: yfeldblum

Differential Revision: D2871859

Pulled By: Orvid

fb-gh-sync-id: 7674f565a968aa0258355fc977c185a416e4fbe4

folly/io/async/AsyncServerSocket.cpp
folly/io/async/AsyncServerSocket.h

index e8f01393cb4f153a8f70683f78686724142f0165..f7aae2a420185b463c32930335981a703a461ebb 100644 (file)
@@ -270,7 +270,7 @@ void AsyncServerSocket::useExistingSockets(const std::vector<int>& fds) {
     SocketAddress address;
     address.setFromLocalAddress(fd);
 
-    setupSocket(fd);
+    setupSocket(fd, address.getFamily());
     sockets_.emplace_back(eventBase_, fd, this, address.getFamily());
     sockets_.back().changeHandlerFD(fd);
   }
@@ -377,7 +377,7 @@ void AsyncServerSocket::bind(uint16_t port) {
     CHECK_GE(s, 0);
 
     try {
-      setupSocket(s);
+      setupSocket(s, res->ai_family);
     } catch (...) {
       closeNoInt(s);
       throw;
@@ -633,7 +633,7 @@ int AsyncServerSocket::createSocket(int family) {
   }
 
   try {
-    setupSocket(fd);
+    setupSocket(fd, family);
   } catch (...) {
     closeNoInt(fd);
     throw;
@@ -641,11 +641,7 @@ int AsyncServerSocket::createSocket(int family) {
   return fd;
 }
 
-void AsyncServerSocket::setupSocket(int fd) {
-  // Get the address family
-  SocketAddress address;
-  address.setFromLocalAddress(fd);
-
+void AsyncServerSocket::setupSocket(int fd, int family) {
   // Put the socket in non-blocking mode
   if (fcntl(fd, F_SETFL, O_NONBLOCK) != 0) {
     folly::throwSystemError(errno,
@@ -665,9 +661,15 @@ void AsyncServerSocket::setupSocket(int fd) {
       setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(int)) != 0) {
     LOG(ERROR) << "failed to set SO_REUSEPORT on async server socket "
                << strerror(errno);
+#ifdef WIN32
+    folly::throwSystemError(errno, "failed to bind to the async server socket");
+#else
+    SocketAddress address;
+    address.setFromLocalAddress(fd);
     folly::throwSystemError(errno,
                             "failed to bind to async server socket: " +
                             address.describe());
+#endif
   }
 
   // Set keepalive as desired
@@ -687,7 +689,6 @@ void AsyncServerSocket::setupSocket(int fd) {
   // Set TCP nodelay if available, MAC OS X Hack
   // See http://lists.danga.com/pipermail/memcached/2005-March/001240.html
 #ifndef TCP_NOPUSH
-  auto family = address.getFamily();
   if (family != AF_UNIX) {
     if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) != 0) {
       // This isn't a fatal error; just log an error message and continue
index d423d5f35b68d2b49140791675f332c42eb87c4f..a83d330689564288a3cfbc63e6b32ce762f022d8 100644 (file)
@@ -760,7 +760,7 @@ class AsyncServerSocket : public DelayedDestruction
     uint16_t events, int socket, sa_family_t family) noexcept;
 
   int createSocket(int family);
-  void setupSocket(int fd);
+  void setupSocket(int fd, int family);
   void bindSocket(int fd, const SocketAddress& address, bool isExistingSocket);
   void dispatchSocket(int socket, SocketAddress&& address);
   void dispatchError(const char *msg, int errnoValue);