IPv6 support for the TNonBlockingServer

Summary: Need to use IPv6 compliant constructs here. Submitted by Paul Saab.

Reviewed By: dreiss

Test Plan: Rebuild Thrift TNonblockingServer with this patch and verify behaves just the same


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665353 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/server/TNonblockingServer.cpp b/lib/cpp/src/server/TNonblockingServer.cpp
index fcfe797..b7ed761 100644
--- a/lib/cpp/src/server/TNonblockingServer.cpp
+++ b/lib/cpp/src/server/TNonblockingServer.cpp
@@ -10,6 +10,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
+#include <netdb.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <assert.h>
@@ -551,8 +552,31 @@
           event_get_version(),
           event_get_method());
 
+  struct addrinfo hints, *res, *res0;
+  int error;
+  char port[sizeof("65536") + 1];
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = PF_UNSPEC;
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags = AI_PASSIVE;
+  sprintf(port, "%d", port_);
+
+  // Wildcard address
+  error = getaddrinfo(NULL, port, &hints, &res0);
+  if (error) {
+    GlobalOutput("TNonblockingServer::serve() getaddrinfo");
+    return;
+  }
+
+  // Pick the ipv6 address first since ipv4 addresses can be mapped
+  // into ipv6 space.
+  for (res = res0; res; res = res->ai_next) {
+    if (res->ai_family == AF_INET6 || res->ai_next == NULL)
+      break;
+  }
+
   // Create the server socket
-  serverSocket_ = socket(AF_INET, SOCK_STREAM, 0);
+  serverSocket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
   if (serverSocket_ == -1) {
     GlobalOutput("TNonblockingServer::serve() socket() -1");
     return;
@@ -585,12 +609,7 @@
   setsockopt(serverSocket_, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
   #endif
 
-  struct sockaddr_in addr;
-  addr.sin_family = AF_INET;
-  addr.sin_port = htons(port_);
-  addr.sin_addr.s_addr = INADDR_ANY;
-
-  if (bind(serverSocket_, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
+  if (bind(serverSocket_, res->ai_addr, res->ai_addrlen) == -1) {
     GlobalOutput("TNonblockingServer::serve() bind");
     close(serverSocket_);
     return;