Return bound port number from grpc_server_add_http2_port.

Allows tests to bind to port 0 and still have clients connect to them.
	Change on 2015/01/12 by ctiller <ctiller@google.com>
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=83800669
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index 5ed5177..753e24c 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -154,6 +154,9 @@
 
 /* Prepare a recently-created socket for listening. */
 static int prepare_socket(int fd, const struct sockaddr *addr, int addr_len) {
+  struct sockaddr_storage sockname_temp;
+  socklen_t sockname_len;
+
   if (fd < 0) {
     goto error;
   }
@@ -179,13 +182,18 @@
     goto error;
   }
 
-  return 1;
+  sockname_len = sizeof(sockname_temp);
+  if (getsockname(fd, (struct sockaddr *)&sockname_temp, &sockname_len) < 0) {
+    goto error;
+  }
+
+  return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
 
 error:
   if (fd >= 0) {
     close(fd);
   }
-  return 0;
+  return -1;
 }
 
 /* event manager callback when reads are ready */
@@ -234,39 +242,64 @@
 static int add_socket_to_server(grpc_tcp_server *s, int fd,
                                 const struct sockaddr *addr, int addr_len) {
   server_port *sp;
+  int port;
 
-  if (!prepare_socket(fd, addr, addr_len)) {
-    return 0;
+  port = prepare_socket(fd, addr, addr_len);
+  if (port >= 0) {
+    gpr_mu_lock(&s->mu);
+    GPR_ASSERT(!s->cb && "must add ports before starting server");
+    /* append it to the list under a lock */
+    if (s->nports == s->port_capacity) {
+      s->port_capacity *= 2;
+      s->ports =
+          gpr_realloc(s->ports, sizeof(server_port *) * s->port_capacity);
+    }
+    sp = &s->ports[s->nports++];
+    sp->server = s;
+    sp->fd = fd;
+    sp->emfd = grpc_fd_create(fd);
+    GPR_ASSERT(sp->emfd);
+    gpr_mu_unlock(&s->mu);
   }
 
-  gpr_mu_lock(&s->mu);
-  GPR_ASSERT(!s->cb && "must add ports before starting server");
-  /* append it to the list under a lock */
-  if (s->nports == s->port_capacity) {
-    s->port_capacity *= 2;
-    s->ports = gpr_realloc(s->ports, sizeof(server_port *) * s->port_capacity);
-  }
-  sp = &s->ports[s->nports++];
-  sp->server = s;
-  sp->fd = fd;
-  sp->emfd = grpc_fd_create(fd);
-  GPR_ASSERT(sp->emfd);
-  gpr_mu_unlock(&s->mu);
-
-  return 1;
+  return port;
 }
 
 int grpc_tcp_server_add_port(grpc_tcp_server *s, const struct sockaddr *addr,
                              int addr_len) {
-  int ok = 0;
+  int allocated_port1 = -1;
+  int allocated_port2 = -1;
+  int i;
   int fd;
   grpc_dualstack_mode dsmode;
   struct sockaddr_in6 addr6_v4mapped;
   struct sockaddr_in wild4;
   struct sockaddr_in6 wild6;
   struct sockaddr_in addr4_copy;
+  struct sockaddr *allocated_addr = NULL;
+  struct sockaddr_storage sockname_temp;
+  socklen_t sockname_len;
   int port;
 
+  /* Check if this is a wildcard port, and if so, try to keep the port the same
+     as some previously created listener. */
+  if (grpc_sockaddr_get_port(addr) == 0) {
+    for (i = 0; i < s->nports; i++) {
+      sockname_len = sizeof(sockname_temp);
+      if (0 == getsockname(s->ports[i].fd, (struct sockaddr *)&sockname_temp,
+                           &sockname_len)) {
+        port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
+        if (port > 0) {
+          allocated_addr = malloc(addr_len);
+          memcpy(allocated_addr, addr, addr_len);
+          grpc_sockaddr_set_port(allocated_addr, port);
+          addr = allocated_addr;
+          break;
+        }
+      }
+    }
+  }
+
   if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
     addr = (const struct sockaddr *)&addr6_v4mapped;
     addr_len = sizeof(addr6_v4mapped);
@@ -280,12 +313,15 @@
     addr = (struct sockaddr *)&wild6;
     addr_len = sizeof(wild6);
     fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
-    ok |= add_socket_to_server(s, fd, addr, addr_len);
+    allocated_port1 = add_socket_to_server(s, fd, addr, addr_len);
     if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
-      return ok;
+      goto done;
     }
 
     /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
+    if (port == 0 && allocated_port1 > 0) {
+      grpc_sockaddr_set_port((struct sockaddr *)&wild4, allocated_port1);
+    }
     addr = (struct sockaddr *)&wild4;
     addr_len = sizeof(wild4);
   }
@@ -299,8 +335,11 @@
     addr = (struct sockaddr *)&addr4_copy;
     addr_len = sizeof(addr4_copy);
   }
-  ok |= add_socket_to_server(s, fd, addr, addr_len);
-  return ok;
+  allocated_port2 = add_socket_to_server(s, fd, addr, addr_len);
+
+done:
+  gpr_free(allocated_addr);
+  return allocated_port1 >= 0 ? allocated_port1 : allocated_port2;
 }
 
 int grpc_tcp_server_get_fd(grpc_tcp_server *s, int index) {