Merge branch 'master' of github.com:grpc/grpc into rr_with_registry
diff --git a/BUILD b/BUILD
index 424ba9f..9b39353 100644
--- a/BUILD
+++ b/BUILD
@@ -741,6 +741,7 @@
     "include/grpc++/create_channel.h",
     "include/grpc++/generic/async_generic_service.h",
     "include/grpc++/generic/generic_stub.h",
+    "include/grpc++/grpc++.h",
     "include/grpc++/impl/call.h",
     "include/grpc++/impl/client_unary_call.h",
     "include/grpc++/impl/grpc_library.h",
@@ -832,6 +833,7 @@
     "include/grpc++/create_channel.h",
     "include/grpc++/generic/async_generic_service.h",
     "include/grpc++/generic/generic_stub.h",
+    "include/grpc++/grpc++.h",
     "include/grpc++/impl/call.h",
     "include/grpc++/impl/client_unary_call.h",
     "include/grpc++/impl/grpc_library.h",
diff --git a/Makefile b/Makefile
index abca772..0cb6a12 100644
--- a/Makefile
+++ b/Makefile
@@ -4606,6 +4606,7 @@
     include/grpc++/create_channel.h \
     include/grpc++/generic/async_generic_service.h \
     include/grpc++/generic/generic_stub.h \
+    include/grpc++/grpc++.h \
     include/grpc++/impl/call.h \
     include/grpc++/impl/client_unary_call.h \
     include/grpc++/impl/grpc_library.h \
@@ -4851,6 +4852,7 @@
     include/grpc++/create_channel.h \
     include/grpc++/generic/async_generic_service.h \
     include/grpc++/generic/generic_stub.h \
+    include/grpc++/grpc++.h \
     include/grpc++/impl/call.h \
     include/grpc++/impl/client_unary_call.h \
     include/grpc++/impl/grpc_library.h \
diff --git a/build.yaml b/build.yaml
index b77d1a9..2985520 100644
--- a/build.yaml
+++ b/build.yaml
@@ -13,9 +13,9 @@
 - name: grpc++_base
   public_headers: [include/grpc++/channel.h, include/grpc++/client_context.h, include/grpc++/completion_queue.h,
     include/grpc++/create_channel.h, include/grpc++/generic/async_generic_service.h,
-    include/grpc++/generic/generic_stub.h, include/grpc++/impl/call.h, include/grpc++/impl/client_unary_call.h,
-    include/grpc++/impl/grpc_library.h, include/grpc++/impl/proto_utils.h, include/grpc++/impl/rpc_method.h,
-    include/grpc++/impl/rpc_service_method.h, include/grpc++/impl/serialization_traits.h,
+    include/grpc++/generic/generic_stub.h, include/grpc++/grpc++.h, include/grpc++/impl/call.h,
+    include/grpc++/impl/client_unary_call.h, include/grpc++/impl/grpc_library.h, include/grpc++/impl/proto_utils.h,
+    include/grpc++/impl/rpc_method.h, include/grpc++/impl/rpc_service_method.h, include/grpc++/impl/serialization_traits.h,
     include/grpc++/impl/service_type.h, include/grpc++/impl/sync.h, include/grpc++/impl/sync_cxx11.h,
     include/grpc++/impl/sync_no_cxx11.h, include/grpc++/impl/thd.h, include/grpc++/impl/thd_cxx11.h,
     include/grpc++/impl/thd_no_cxx11.h, include/grpc++/security/auth_context.h, include/grpc++/security/auth_metadata_processor.h,
diff --git a/doc/PROTOCOL-HTTP2.md b/doc/PROTOCOL-HTTP2.md
index d3fbb60..02d4f28 100644
--- a/doc/PROTOCOL-HTTP2.md
+++ b/doc/PROTOCOL-HTTP2.md
@@ -43,8 +43,9 @@
 * **User-Agent** → “user-agent” {_structured user-agent string_}
 * **Message-Type** → “grpc-message-type” {_type name for message schema_}
 * **Custom-Metadata** → Binary-Header / ASCII-Header
-* **Binary-Header** → {lowercase ASCII header name ending in “-bin” } {_base64 encoded value_}
-* **ASCII-Header** → {lowercase ASCII header name} {_value_}
+* **Binary-Header** → {Header-Name “-bin” } {_base64 encoded value_}
+* **ASCII-Header** → Header-Name {_value_}
+* **Header-Name** → 1*( %x30-39 / %x61-7A / “_” / “-”) ; 0-9 a-z 
 
 
 HTTP2 requires that reserved headers, ones starting with “:” appear before all other headers. Additionally implementations should send **Timeout** immediately after the reserved headers and they should send the **Call-Definition** headers before sending **Custom-Metadata**.
diff --git a/src/core/client_config/connector.c b/src/core/client_config/connector.c
index a8cd5fc..c1e583e 100644
--- a/src/core/client_config/connector.c
+++ b/src/core/client_config/connector.c
@@ -47,3 +47,7 @@
                             grpc_iomgr_closure *notify) {
   connector->vtable->connect(connector, in_args, out_args, notify);
 }
+
+void grpc_connector_shutdown(grpc_connector *connector) {
+  connector->vtable->shutdown(connector);
+}
diff --git a/src/core/client_config/connector.h b/src/core/client_config/connector.h
index 39f3467..01aa716 100644
--- a/src/core/client_config/connector.h
+++ b/src/core/client_config/connector.h
@@ -70,6 +70,9 @@
 struct grpc_connector_vtable {
   void (*ref)(grpc_connector *connector);
   void (*unref)(grpc_connector *connector);
+  /** Implementation of grpc_connector_shutdown */
+  void (*shutdown)(grpc_connector *connector);
+  /** Implementation of grpc_connector_connect */
   void (*connect)(grpc_connector *connector,
                   const grpc_connect_in_args *in_args,
                   grpc_connect_out_args *out_args, grpc_iomgr_closure *notify);
@@ -77,9 +80,12 @@
 
 void grpc_connector_ref(grpc_connector *connector);
 void grpc_connector_unref(grpc_connector *connector);
+/** Connect using the connector: max one outstanding call at a time */
 void grpc_connector_connect(grpc_connector *connector,
                             const grpc_connect_in_args *in_args,
                             grpc_connect_out_args *out_args,
                             grpc_iomgr_closure *notify);
+/** Cancel any pending connection */
+void grpc_connector_shutdown(grpc_connector *connector);
 
 #endif
diff --git a/src/core/client_config/resolvers/zookeeper_resolver.c b/src/core/client_config/resolvers/zookeeper_resolver.c
index e425913..2594e6f 100644
--- a/src/core/client_config/resolvers/zookeeper_resolver.c
+++ b/src/core/client_config/resolvers/zookeeper_resolver.c
@@ -182,6 +182,7 @@
   grpc_lb_policy *lb_policy;
   size_t i;
   if (addresses != NULL) {
+    grpc_lb_policy_args lb_policy_args;
     config = grpc_client_config_create();
     subchannels = gpr_malloc(sizeof(grpc_subchannel *) * addresses->naddrs);
     for (i = 0; i < addresses->naddrs; i++) {
@@ -191,8 +192,10 @@
       subchannels[i] = grpc_subchannel_factory_create_subchannel(
           r->subchannel_factory, &args);
     }
+    lb_policy_args.subchannels = subchannels;
+    lb_policy_args.num_subchannels = addresses->naddrs;
     lb_policy =
-        grpc_lb_policy_create(r->lb_policy_name, subchannels, addresses->naddrs);
+        grpc_lb_policy_create(r->lb_policy_name, &lb_policy_args);
     grpc_client_config_set_lb_policy(config, lb_policy);
     GRPC_LB_POLICY_UNREF(lb_policy, "construction");
     grpc_resolved_addresses_destroy(addresses);
diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c
index ca52c75..876d2aa 100644
--- a/src/core/client_config/subchannel.c
+++ b/src/core/client_config/subchannel.c
@@ -439,6 +439,10 @@
   if (cancel_alarm) {
     grpc_alarm_cancel(&c->alarm);
   }
+
+  if (op->disconnect) {
+    grpc_connector_shutdown(c->connector);
+  }
 }
 
 static void on_state_changed(void *p, int iomgr_success) {
diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c
index 2d08a77..38a543e 100644
--- a/src/core/iomgr/fd_posix.c
+++ b/src/core/iomgr/fd_posix.c
@@ -213,10 +213,9 @@
                     const char *reason) {
   fd->on_done_closure = on_done;
   shutdown(fd->fd, SHUT_RDWR);
-  REF_BY(fd, 1, reason); /* remove active status, but keep referenced */
   gpr_mu_lock(&fd->watcher_mu);
+  REF_BY(fd, 1, reason); /* remove active status, but keep referenced */
   if (!has_watchers(fd)) {
-    GPR_ASSERT(!fd->closed);
     fd->closed = 1;
     close(fd->fd);
     if (fd->on_done_closure) {
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index 1dd0399..d6ca5d1 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -34,16 +34,18 @@
 #include "src/core/iomgr/iomgr.h"
 
 #include <stdlib.h>
+#include <string.h>
 
-#include "src/core/iomgr/iomgr_internal.h"
-#include "src/core/iomgr/alarm_internal.h"
-#include "src/core/support/string.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 
+#include "src/core/iomgr/iomgr_internal.h"
+#include "src/core/iomgr/alarm_internal.h"
+#include "src/core/support/string.h"
+
 static gpr_mu g_mu;
 static gpr_cv g_rcv;
 static grpc_iomgr_closure *g_cbs_head = NULL;
@@ -179,6 +181,8 @@
   }
   gpr_mu_unlock(&g_mu);
 
+  memset(&g_root_object, 0, sizeof(g_root_object));
+
   grpc_kick_poller();
   gpr_event_wait(&g_background_callback_executor_done,
                  gpr_inf_future(GPR_CLOCK_REALTIME));
diff --git a/src/core/iomgr/pollset_multipoller_with_epoll.c b/src/core/iomgr/pollset_multipoller_with_epoll.c
index 8f62ce2..481bdc4 100644
--- a/src/core/iomgr/pollset_multipoller_with_epoll.c
+++ b/src/core/iomgr/pollset_multipoller_with_epoll.c
@@ -72,7 +72,7 @@
      to this pollset whilst adding, but that should be benign. */
   GPR_ASSERT(grpc_fd_begin_poll(fd, pollset, 0, 0, &watcher) == 0);
   if (watcher.fd != NULL) {
-    ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
+    ev.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);
     ev.data.ptr = fd;
     err = epoll_ctl(h->epoll_fd, EPOLL_CTL_ADD, fd->fd, &ev);
     if (err < 0) {
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index dec2f54..f3e424e 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -187,6 +187,12 @@
   if (pollset->shutting_down) {
     goto done;
   }
+  if (pollset->in_flight_cbs) {
+    /* Give do_promote priority so we don't starve it out */
+    gpr_mu_unlock(&pollset->mu);
+    gpr_mu_lock(&pollset->mu);
+    goto done;
+  }
   if (!pollset->kicked_without_pollers) {
     push_front_worker(pollset, worker);
     added_worker = 1;
@@ -422,12 +428,6 @@
   int r;
   nfds_t nfds;
 
-  if (pollset->in_flight_cbs) {
-    /* Give do_promote priority so we don't starve it out */
-    gpr_mu_unlock(&pollset->mu);
-    gpr_mu_lock(&pollset->mu);
-    return;
-  }
   fd = pollset->data.ptr;
   if (fd && grpc_fd_is_orphaned(fd)) {
     GRPC_FD_UNREF(fd, "basicpoll");
diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c
index c3668f6..07fa44a 100644
--- a/src/core/iomgr/tcp_client_posix.c
+++ b/src/core/iomgr/tcp_client_posix.c
@@ -54,6 +54,8 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
+extern int grpc_tcp_trace;
+
 typedef struct {
   void (*cb)(void *arg, grpc_endpoint *tcp);
   void *cb_arg;
@@ -92,6 +94,10 @@
 static void tc_on_alarm(void *acp, int success) {
   int done;
   async_connect *ac = acp;
+  if (grpc_tcp_trace) {
+    gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: success=%d", ac->addr_str,
+            success);
+  }
   gpr_mu_lock(&ac->mu);
   if (ac->fd != NULL) {
     grpc_fd_shutdown(ac->fd);
@@ -116,6 +122,11 @@
   void *cb_arg = ac->cb_arg;
   grpc_fd *fd;
 
+  if (grpc_tcp_trace) {
+    gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_writable: success=%d",
+            ac->addr_str, success);
+  }
+
   gpr_mu_lock(&ac->mu);
   GPR_ASSERT(ac->fd);
   fd = ac->fd;
@@ -264,6 +275,11 @@
   ac->write_closure.cb = on_writable;
   ac->write_closure.cb_arg = ac;
 
+  if (grpc_tcp_trace) {
+    gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: asynchronously connecting",
+            ac->addr_str);
+  }
+
   gpr_mu_lock(&ac->mu);
   grpc_alarm_init(&ac->alarm,
                   gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
diff --git a/src/core/iomgr/tcp_client_windows.c b/src/core/iomgr/tcp_client_windows.c
index 05198db..a42ec7c 100644
--- a/src/core/iomgr/tcp_client_windows.c
+++ b/src/core/iomgr/tcp_client_windows.c
@@ -77,7 +77,6 @@
   async_connect *ac = acp;
   gpr_mu_lock(&ac->mu);
   /* If the alarm didn't occur, it got cancelled. */
-  gpr_log(GPR_DEBUG, "on_alarm: %p", ac->socket);
   if (ac->socket != NULL && occured) {
     grpc_winsocket_shutdown(ac->socket);
   }
@@ -96,8 +95,6 @@
 
   gpr_mu_lock(&ac->mu);
 
-  gpr_log(GPR_DEBUG, "on_connect: %p", ac->socket);
-
   if (from_iocp) {
     DWORD transfered_bytes = 0;
     DWORD flags;
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index bcbd0af..a3cd3bb 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -339,6 +339,10 @@
     addr_str = grpc_sockaddr_to_uri((struct sockaddr *)&addr);
     gpr_asprintf(&name, "tcp-server-connection:%s", addr_str);
 
+    if (grpc_tcp_trace) {
+      gpr_log(GPR_DEBUG, "SERVER_CONNECT: incoming connection: %s", addr_str);
+    }
+
     fdobj = grpc_fd_create(fd, name);
     /* TODO(ctiller): revise this when we have server-side sharding
        of channels -- we certainly should not be automatically adding every
diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c
index ed9eee8..7957066 100644
--- a/src/core/iomgr/udp_server.c
+++ b/src/core/iomgr/udp_server.c
@@ -94,9 +94,6 @@
 
 /* the overall server */
 struct grpc_udp_server {
-  grpc_udp_server_cb cb;
-  void *cb_arg;
-
   gpr_mu mu;
   gpr_cv cv;
 
@@ -130,8 +127,6 @@
   s->active_ports = 0;
   s->destroyed_ports = 0;
   s->shutdown = 0;
-  s->cb = NULL;
-  s->cb_arg = NULL;
   s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP);
   s->nports = 0;
   s->port_capacity = INIT_PORT_CAP;
@@ -232,6 +227,11 @@
     goto error;
   }
 
+  if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1)) {
+    gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd,
+            strerror(errno));
+  }
+
   get_local_ip = 1;
   rc = setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_local_ip,
                   sizeof(get_local_ip));
@@ -282,7 +282,7 @@
 
   /* Tell the registered callback that data is available to read. */
   GPR_ASSERT(sp->read_cb);
-  sp->read_cb(sp->fd, sp->server->cb, sp->server->cb_arg);
+  sp->read_cb(sp->fd);
 
   /* Re-arm the notification event so we get another chance to read. */
   grpc_fd_notify_on_read(sp->emfd, &sp->read_closure);
@@ -301,7 +301,6 @@
     grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1);
     gpr_asprintf(&name, "udp-server-listener:%s", addr_str);
     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;
@@ -407,15 +406,10 @@
 }
 
 void grpc_udp_server_start(grpc_udp_server *s, grpc_pollset **pollsets,
-                           size_t pollset_count,
-                           grpc_udp_server_cb new_transport_cb, void *cb_arg) {
+                           size_t pollset_count) {
   size_t i, j;
-  GPR_ASSERT(new_transport_cb);
   gpr_mu_lock(&s->mu);
-  GPR_ASSERT(!s->cb);
   GPR_ASSERT(s->active_ports == 0);
-  s->cb = new_transport_cb;
-  s->cb_arg = cb_arg;
   s->pollsets = pollsets;
   for (i = 0; i < s->nports; i++) {
     for (j = 0; j < pollset_count; j++) {
diff --git a/src/core/iomgr/udp_server.h b/src/core/iomgr/udp_server.h
index 389f84e..c930e81 100644
--- a/src/core/iomgr/udp_server.h
+++ b/src/core/iomgr/udp_server.h
@@ -39,21 +39,15 @@
 /* Forward decl of grpc_udp_server */
 typedef struct grpc_udp_server grpc_udp_server;
 
-/* New server callback: ep is the newly connected connection */
-typedef void (*grpc_udp_server_cb)(void *arg, grpc_endpoint *ep);
-
 /* Called when data is available to read from the socket. */
-typedef void (*grpc_udp_server_read_cb)(int fd,
-                                        grpc_udp_server_cb new_transport_cb,
-                                        void *cb_arg);
+typedef void (*grpc_udp_server_read_cb)(int fd);
 
 /* Create a server, initially not bound to any ports */
 grpc_udp_server *grpc_udp_server_create(void);
 
 /* Start listening to bound ports */
-void grpc_udp_server_start(grpc_udp_server *server, grpc_pollset **pollsets,
-                           size_t pollset_count, grpc_udp_server_cb cb,
-                           void *cb_arg);
+void grpc_udp_server_start(grpc_udp_server *udp_server, grpc_pollset **pollsets,
+                           size_t pollset_count);
 
 int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned index);
 
diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c
index 021c466..8b050db 100644
--- a/src/core/support/log_posix.c
+++ b/src/core/support/log_posix.c
@@ -64,7 +64,7 @@
   } else {
     message = allocated = gpr_malloc((size_t)ret + 1);
     va_start(args, format);
-    vsnprintf(message, ret + 1, format, args);
+    vsnprintf(message, (size_t)(ret + 1), format, args);
     va_end(args);
   }
   gpr_log_message(file, line, severity, message);
diff --git a/src/core/support/string.c b/src/core/support/string.c
index af0389e..e0ffeb8 100644
--- a/src/core/support/string.c
+++ b/src/core/support/string.c
@@ -101,7 +101,7 @@
     dump_out_append(out, '\'');
   }
   for (cur = beg; cur != end; ++cur) {
-    dump_out_append(out, isprint(*cur) ? *(char *)cur : '.');
+    dump_out_append(out, (char)(isprint(*cur) ? *(char *)cur : '.'));
   }
   if (!out_was_empty) {
     dump_out_append(out, '\'');
diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c
index 9e2cf1c..d323d0d 100644
--- a/src/core/surface/channel_create.c
+++ b/src/core/surface/channel_create.c
@@ -88,6 +88,8 @@
   grpc_iomgr_add_callback(notify);
 }
 
+static void connector_shutdown(grpc_connector *con) {}
+
 static void connector_connect(grpc_connector *con,
                               const grpc_connect_in_args *args,
                               grpc_connect_out_args *result,
@@ -103,7 +105,7 @@
 }
 
 static const grpc_connector_vtable connector_vtable = {
-    connector_ref, connector_unref, connector_connect};
+    connector_ref, connector_unref, connector_shutdown, connector_connect};
 
 typedef struct {
   grpc_subchannel_factory base;
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index 9b554ee..52c5e93 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -61,6 +61,9 @@
   grpc_iomgr_closure *notify;
   grpc_connect_in_args args;
   grpc_connect_out_args *result;
+
+  gpr_mu mu;
+  grpc_endpoint *connecting_endpoint;
 } connector;
 
 static void connector_ref(grpc_connector *con) {
@@ -81,10 +84,20 @@
                                            grpc_endpoint *secure_endpoint) {
   connector *c = arg;
   grpc_iomgr_closure *notify;
-  if (status != GRPC_SECURITY_OK) {
+  gpr_mu_lock(&c->mu);
+  if (c->connecting_endpoint == NULL) {
+    memset(c->result, 0, sizeof(*c->result));
+    gpr_mu_unlock(&c->mu);
+  } else if (status != GRPC_SECURITY_OK) {
+    GPR_ASSERT(c->connecting_endpoint == wrapped_endpoint);
     gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status);
     memset(c->result, 0, sizeof(*c->result));
+    c->connecting_endpoint = NULL;
+    gpr_mu_unlock(&c->mu);
   } else {
+    GPR_ASSERT(c->connecting_endpoint == wrapped_endpoint);
+    c->connecting_endpoint = NULL;
+    gpr_mu_unlock(&c->mu);
     c->result->transport = grpc_create_chttp2_transport(
         c->args.channel_args, secure_endpoint, c->args.metadata_context, 1);
     grpc_chttp2_transport_start_reading(c->result->transport, NULL, 0);
@@ -102,6 +115,10 @@
   connector *c = arg;
   grpc_iomgr_closure *notify;
   if (tcp != NULL) {
+    gpr_mu_lock(&c->mu);
+    GPR_ASSERT(c->connecting_endpoint == NULL);
+    c->connecting_endpoint = tcp;
+    gpr_mu_unlock(&c->mu);
     grpc_setup_secure_transport(&c->security_connector->base, tcp,
                                 on_secure_transport_setup_done, c);
   } else {
@@ -112,6 +129,18 @@
   }
 }
 
+static void connector_shutdown(grpc_connector *con) {
+  connector *c = (connector *)con;
+  grpc_endpoint *ep;
+  gpr_mu_lock(&c->mu);
+  ep = c->connecting_endpoint;
+  c->connecting_endpoint = NULL;
+  gpr_mu_unlock(&c->mu);
+  if (ep) {
+    grpc_endpoint_shutdown(ep);
+  }
+}
+
 static void connector_connect(grpc_connector *con,
                               const grpc_connect_in_args *args,
                               grpc_connect_out_args *result,
@@ -122,12 +151,15 @@
   c->notify = notify;
   c->args = *args;
   c->result = result;
+  gpr_mu_lock(&c->mu);
+  GPR_ASSERT(c->connecting_endpoint == NULL);
+  gpr_mu_unlock(&c->mu);
   grpc_tcp_client_connect(connected, c, args->interested_parties, args->addr,
                           args->addr_len, args->deadline);
 }
 
 static const grpc_connector_vtable connector_vtable = {
-    connector_ref, connector_unref, connector_connect};
+    connector_ref, connector_unref, connector_shutdown, connector_connect};
 
 typedef struct {
   grpc_subchannel_factory base;
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index a592ce7..f26f446 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -486,7 +486,7 @@
     transport_parsing->hpack_parser.on_header_user_data = NULL;
     transport_parsing->hpack_parser.is_boundary = is_eoh;
     transport_parsing->hpack_parser.is_eof =
-        is_eoh ? transport_parsing->header_eof : 0;
+        (gpr_uint8)(is_eoh ? transport_parsing->header_eof : 0);
   } else {
     transport_parsing->parser = skip_parser;
   }
@@ -696,7 +696,7 @@
   transport_parsing->hpack_parser.on_header_user_data = transport_parsing;
   transport_parsing->hpack_parser.is_boundary = is_eoh;
   transport_parsing->hpack_parser.is_eof =
-      is_eoh ? transport_parsing->header_eof : 0;
+      (gpr_uint8)(is_eoh ? transport_parsing->header_eof : 0);
   if (!is_continuation && (transport_parsing->incoming_frame_flags &
                            GRPC_CHTTP2_FLAG_HAS_PRIORITY)) {
     grpc_chttp2_hpack_parser_set_has_priority(&transport_parsing->hpack_parser);
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 70c0fbc..51e0728 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -252,7 +252,7 @@
   if (!ctx->recv_message) {
     return -1;
   }
-  return grpc_byte_buffer_length(ctx->recv_message);
+  return (gpr_intptr)grpc_byte_buffer_length(ctx->recv_message);
 }
 
 /*
diff --git a/templates/gRPC.podspec.template b/templates/gRPC.podspec.template
index 060961f..b1de0d7 100644
--- a/templates/gRPC.podspec.template
+++ b/templates/gRPC.podspec.template
@@ -63,17 +63,17 @@
   %>
   Pod::Spec.new do |s|
     s.name     = 'gRPC'
-    s.version  = '0.7.0'
+    s.version  = '0.11.0'
     s.summary  = 'gRPC client library for iOS/OSX'
     s.homepage = 'http://www.grpc.io'
     s.license  = 'New BSD'
     s.authors  = { 'The gRPC contributors' => 'grpc-packages@google.com' }
   
     # s.source = { :git => 'https://github.com/grpc/grpc.git',
-    #              :tag => 'release-0_10_0-objectivec-0.6.0' }
+    #              :tag => 'release-0_11_0-objectivec-0.11.0' }
   
-    s.ios.deployment_target = '6.0'
-    s.osx.deployment_target = '10.8'
+    s.ios.deployment_target = '7.1'
+    s.osx.deployment_target = '10.9'
     s.requires_arc = true
   
     objc_dir = 'src/objective-c'
@@ -152,6 +152,6 @@
   
       ss.dependency 'gRPC/GRPCClient'
       ss.dependency 'gRPC/RxLibrary'
-      ss.dependency 'Protobuf', '~> 3.0.0-alpha-3'
+      ss.dependency 'Protobuf', '~> 3.0.0-alpha-4'
     end
   end
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index ec3fb65..fec9667 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -267,7 +267,7 @@
 int external_dns_works(const char *host) {
   grpc_resolved_addresses *res = grpc_blocking_resolve_address(host, "80");
   if (res != NULL) {
-    gpr_free(res);
+    grpc_resolved_addresses_destroy(res);
     return 1;
   }
   return 0;
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index c4f1896..24b6b1c 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -49,9 +49,7 @@
 static int g_number_of_reads = 0;
 static int g_number_of_bytes_read = 0;
 
-static void on_connect(void *arg, grpc_endpoint *udp) {}
-
-static void on_read(int fd, grpc_udp_server_cb new_transport_cb, void *cb_arg) {
+static void on_read(int fd) {
   char read_buffer[512];
   ssize_t byte_count;
 
@@ -73,7 +71,7 @@
 static void test_no_op_with_start(void) {
   grpc_udp_server *s = grpc_udp_server_create();
   LOG_TEST("test_no_op_with_start");
-  grpc_udp_server_start(s, NULL, 0, on_connect, NULL);
+  grpc_udp_server_start(s, NULL, 0);
   grpc_udp_server_destroy(s, NULL, NULL);
 }
 
@@ -100,7 +98,7 @@
   GPR_ASSERT(grpc_udp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr),
                                       on_read));
 
-  grpc_udp_server_start(s, NULL, 0, on_connect, NULL);
+  grpc_udp_server_start(s, NULL, 0);
 
   grpc_udp_server_destroy(s, NULL, NULL);
 }
@@ -130,7 +128,7 @@
   GPR_ASSERT(addr_len <= sizeof(addr));
 
   pollsets[0] = &g_pollset;
-  grpc_udp_server_start(s, pollsets, 1, on_connect, NULL);
+  grpc_udp_server_start(s, pollsets, 1);
 
   gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
 
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index be45bae..03f4c49 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -47,6 +47,7 @@
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
 
 #include "src/core/httpcli/httpcli.h"
 #include "src/core/support/env.h"
@@ -66,7 +67,70 @@
   return 0;
 }
 
-static void free_chosen_ports() { gpr_free(chosen_ports); }
+typedef struct freereq {
+  grpc_pollset pollset;
+  int done;
+} freereq;
+
+static void destroy_pollset_and_shutdown(void *p) {
+  grpc_pollset_destroy(p);
+  grpc_shutdown();
+}
+
+static void freed_port_from_server(void *arg,
+                                   const grpc_httpcli_response *response) {
+  freereq *pr = arg;
+  gpr_mu_lock(GRPC_POLLSET_MU(&pr->pollset));
+  pr->done = 1;
+  grpc_pollset_kick(&pr->pollset, NULL);
+  gpr_mu_unlock(GRPC_POLLSET_MU(&pr->pollset));
+}
+
+static void free_port_using_server(char *server, int port) {
+  grpc_httpcli_context context;
+  grpc_httpcli_request req;
+  freereq pr;
+  char *path;
+
+  grpc_init();
+
+  memset(&pr, 0, sizeof(pr));
+  memset(&req, 0, sizeof(req));
+  grpc_pollset_init(&pr.pollset);
+
+  req.host = server;
+  gpr_asprintf(&path, "/drop/%d", port);
+  req.path = path;
+
+  grpc_httpcli_context_init(&context);
+  grpc_httpcli_get(&context, &pr.pollset, &req,
+                   GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), freed_port_from_server,
+                   &pr);
+  gpr_mu_lock(GRPC_POLLSET_MU(&pr.pollset));
+  while (!pr.done) {
+    grpc_pollset_worker worker;
+    grpc_pollset_work(&pr.pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC),
+                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
+  }
+  gpr_mu_unlock(GRPC_POLLSET_MU(&pr.pollset));
+
+  grpc_httpcli_context_destroy(&context);
+  grpc_pollset_shutdown(&pr.pollset, destroy_pollset_and_shutdown, &pr.pollset);
+  gpr_free(path);
+}
+
+static void free_chosen_ports() { 
+  char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
+  if (env != NULL) {
+    size_t i;
+    for (i = 0; i < num_chosen_ports; i++) {
+      free_port_using_server(env, chosen_ports[i]);
+    }
+    gpr_free(env);
+  }
+
+  gpr_free(chosen_ports); 
+}
 
 static void chose_port(int port) {
   if (chosen_ports == NULL) {
@@ -131,6 +195,9 @@
 typedef struct portreq {
   grpc_pollset pollset;
   int port;
+  int retries;
+  char *server;
+  grpc_httpcli_context *ctx;
 } portreq;
 
 static void got_port_from_server(void *arg,
@@ -138,6 +205,19 @@
   size_t i;
   int port = 0;
   portreq *pr = arg;
+  if (!response || response->status != 200) {
+    grpc_httpcli_request req;
+    memset(&req, 0, sizeof(req));
+    GPR_ASSERT(pr->retries < 10);
+    pr->retries++;
+    req.host = pr->server;
+    req.path = "/get";
+    gpr_log(GPR_DEBUG, "failed port pick from server: retrying");
+    sleep(1);
+    grpc_httpcli_get(pr->ctx, &pr->pollset, &req, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), 
+                     got_port_from_server, pr);
+    return;
+  }
   GPR_ASSERT(response);
   GPR_ASSERT(response->status == 200);
   for (i = 0; i < response->body_length; i++) {
@@ -151,11 +231,6 @@
   gpr_mu_unlock(GRPC_POLLSET_MU(&pr->pollset));
 }
 
-static void destroy_pollset_and_shutdown(void *p) {
-  grpc_pollset_destroy(p);
-  grpc_shutdown();
-}
-
 static int pick_port_using_server(char *server) {
   grpc_httpcli_context context;
   grpc_httpcli_request req;
@@ -167,6 +242,8 @@
   memset(&req, 0, sizeof(req));
   grpc_pollset_init(&pr.pollset);
   pr.port = -1;
+  pr.server = server;
+  pr.ctx = &context;
 
   req.host = server;
   req.path = "/get";
@@ -211,8 +288,9 @@
     int port = pick_port_using_server(env);
     gpr_free(env);
     if (port != 0) {
-      return port;
+      chose_port(port);
     }
+    return port;
   }
 
   for (;;) {
diff --git a/tools/dockerfile/grpc_java_base/Dockerfile b/tools/dockerfile/grpc_java_base/Dockerfile
index 7bf79c8..9b80bbf 100644
--- a/tools/dockerfile/grpc_java_base/Dockerfile
+++ b/tools/dockerfile/grpc_java_base/Dockerfile
@@ -40,6 +40,7 @@
   apt-get update && \
   apt-get -y install \
       git \
+      libapr1 \
       oracle-java8-installer \
       && \
   apt-get clean && rm -r /var/cache/oracle-jdk8-installer/
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index a352341..5d592c8 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -766,6 +766,7 @@
 include/grpc++/create_channel.h \
 include/grpc++/generic/async_generic_service.h \
 include/grpc++/generic/generic_stub.h \
+include/grpc++/grpc++.h \
 include/grpc++/impl/call.h \
 include/grpc++/impl/client_unary_call.h \
 include/grpc++/impl/grpc_library.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index dfaeb43..bbd1706 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -766,6 +766,7 @@
 include/grpc++/create_channel.h \
 include/grpc++/generic/async_generic_service.h \
 include/grpc++/generic/generic_stub.h \
+include/grpc++/grpc++.h \
 include/grpc++/impl/call.h \
 include/grpc++/impl/client_unary_call.h \
 include/grpc++/impl/grpc_library.h \
diff --git a/tools/jenkins/run_jenkins.sh b/tools/jenkins/run_jenkins.sh
index 0f15835..9ff588e 100755
--- a/tools/jenkins/run_jenkins.sh
+++ b/tools/jenkins/run_jenkins.sh
@@ -79,7 +79,6 @@
     -e "config=$config" \
     -e "language=$language" \
     -e "arch=$arch" \
-    -e "GRPC_ZOOKEEPER_SERVER_TEST=grpc-jenkins-master:2181" \
     -e CCACHE_DIR=/tmp/ccache \
     -i \
     -v "$git_root:/var/local/jenkins/grpc" \
diff --git a/tools/run_tests/port_server.py b/tools/run_tests/port_server.py
index 0f81470..d14c829 100755
--- a/tools/run_tests/port_server.py
+++ b/tools/run_tests/port_server.py
@@ -37,6 +37,7 @@
 import socket
 import sys
 import time
+import yaml
 
 argp = argparse.ArgumentParser(description='Server for httpcli_test')
 argp.add_argument('-p', '--port', default=12345, type=int)
@@ -51,16 +52,17 @@
   _MY_VERSION = hashlib.sha1(f.read()).hexdigest()
 
 
-def refill_pool():
+def refill_pool(max_timeout):
   """Scan for ports not marked for being in use"""
-  for i in range(10000, 65000):
+  for i in range(1025, 32767):
     if len(pool) > 100: break
     if i in in_use:
       age = time.time() - in_use[i]
-      if age < 600:
+      if age < max_timeout:
         continue
       del in_use[i]
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     try:
       s.bind(('localhost', i))
       pool.append(i)
@@ -73,8 +75,12 @@
 def allocate_port():
   global pool
   global in_use
-  if not pool:
-    refill_pool()
+  max_timeout = 600
+  while not pool:
+    refill_pool(max_timeout)
+    if not pool:
+      time.sleep(1)
+      max_timeout /= 2
   port = pool[0]
   pool = pool[1:]
   in_use[port] = time.time()
@@ -97,12 +103,26 @@
       p = allocate_port()
       self.log_message('allocated port %d' % p)
       self.wfile.write('%d' % p)
+    elif self.path[0:6] == '/drop/':
+      self.send_response(200)
+      self.send_header('Content-Type', 'text/plain')
+      self.end_headers()
+      p = int(self.path[6:])
+      del in_use[p]
+      pool.append(p)
+      self.log_message('drop port %d' % p)
     elif self.path == '/version':
       # fetch a version string and the current process pid
       self.send_response(200)
       self.send_header('Content-Type', 'text/plain')
       self.end_headers()
       self.wfile.write(_MY_VERSION)
+    elif self.path == '/dump':
+      self.send_response(200)
+      self.send_header('Content-Type', 'text/plain')
+      self.end_headers()
+      now = time.time()
+      self.wfile.write(yaml.dump({'pool': pool, 'in_use': dict((k, now - v) for k, v in in_use.iteritems())}))
     elif self.path == '/quit':
       self.send_response(200)
       self.end_headers()
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index c3d2da3..7acf0ff 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -13158,6 +13158,7 @@
       "include/grpc++/create_channel.h", 
       "include/grpc++/generic/async_generic_service.h", 
       "include/grpc++/generic/generic_stub.h", 
+      "include/grpc++/grpc++.h", 
       "include/grpc++/impl/call.h", 
       "include/grpc++/impl/client_unary_call.h", 
       "include/grpc++/impl/grpc_library.h", 
@@ -13210,6 +13211,7 @@
       "include/grpc++/create_channel.h", 
       "include/grpc++/generic/async_generic_service.h", 
       "include/grpc++/generic/generic_stub.h", 
+      "include/grpc++/grpc++.h", 
       "include/grpc++/impl/call.h", 
       "include/grpc++/impl/client_unary_call.h", 
       "include/grpc++/impl/grpc_library.h", 
@@ -13340,6 +13342,7 @@
       "include/grpc++/create_channel.h", 
       "include/grpc++/generic/async_generic_service.h", 
       "include/grpc++/generic/generic_stub.h", 
+      "include/grpc++/grpc++.h", 
       "include/grpc++/impl/call.h", 
       "include/grpc++/impl/client_unary_call.h", 
       "include/grpc++/impl/grpc_library.h", 
@@ -13389,6 +13392,7 @@
       "include/grpc++/create_channel.h", 
       "include/grpc++/generic/async_generic_service.h", 
       "include/grpc++/generic/generic_stub.h", 
+      "include/grpc++/grpc++.h", 
       "include/grpc++/impl/call.h", 
       "include/grpc++/impl/client_unary_call.h", 
       "include/grpc++/impl/grpc_library.h", 
diff --git a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
index 7e8ed44..acb62ac 100644
--- a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -219,6 +219,7 @@
     <ClInclude Include="..\..\..\include\grpc++\create_channel.h" />
     <ClInclude Include="..\..\..\include\grpc++\generic\async_generic_service.h" />
     <ClInclude Include="..\..\..\include\grpc++\generic\generic_stub.h" />
+    <ClInclude Include="..\..\..\include\grpc++\grpc++.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\call.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\client_unary_call.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\grpc_library.h" />
diff --git a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 7ef391a..96effe2 100644
--- a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -102,6 +102,9 @@
     <ClInclude Include="..\..\..\include\grpc++\generic\generic_stub.h">
       <Filter>include\grpc++\generic</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\include\grpc++\grpc++.h">
+      <Filter>include\grpc++</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\..\include\grpc++\impl\call.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 8b2d85d..3a7f559 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -219,6 +219,7 @@
     <ClInclude Include="..\..\..\include\grpc++\create_channel.h" />
     <ClInclude Include="..\..\..\include\grpc++\generic\async_generic_service.h" />
     <ClInclude Include="..\..\..\include\grpc++\generic\generic_stub.h" />
+    <ClInclude Include="..\..\..\include\grpc++\grpc++.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\call.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\client_unary_call.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\grpc_library.h" />
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index 74712fe..7d9cd47 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -117,6 +117,9 @@
     <ClInclude Include="..\..\..\include\grpc++\generic\generic_stub.h">
       <Filter>include\grpc++\generic</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\include\grpc++\grpc++.h">
+      <Filter>include\grpc++</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\..\include\grpc++\impl\call.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index 7e8ed44..acb62ac 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -219,6 +219,7 @@
     <ClInclude Include="..\..\..\include\grpc++\create_channel.h" />
     <ClInclude Include="..\..\..\include\grpc++\generic\async_generic_service.h" />
     <ClInclude Include="..\..\..\include\grpc++\generic\generic_stub.h" />
+    <ClInclude Include="..\..\..\include\grpc++\grpc++.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\call.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\client_unary_call.h" />
     <ClInclude Include="..\..\..\include\grpc++\impl\grpc_library.h" />
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 7ef391a..96effe2 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -102,6 +102,9 @@
     <ClInclude Include="..\..\..\include\grpc++\generic\generic_stub.h">
       <Filter>include\grpc++\generic</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\include\grpc++\grpc++.h">
+      <Filter>include\grpc++</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\..\include\grpc++\impl\call.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>