From df8f12203ce662860d514376af92c76237fd5b7f Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Fri, 13 Jan 2017 22:59:39 +0000
Subject: [PATCH] Fix API fuzzer tests.

---
 src/core/ext/client_channel/subchannel.c      | 35 ++++++++++++++-----
 src/core/ext/client_channel/subchannel.h      |  9 +++--
 .../ext/lb_policy/pick_first/pick_first.c     |  7 ++--
 .../ext/lb_policy/round_robin/round_robin.c   |  7 ++--
 .../chttp2/client/chttp2_connector.c          |  5 +--
 5 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index 7a2ad98433..f9de9993b7 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -38,6 +38,7 @@
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/avl.h>
+#include <grpc/support/string_util.h>
 
 #include "src/core/ext/client_channel/client_channel.h"
 #include "src/core/ext/client_channel/initial_connect_string.h"
@@ -328,21 +329,16 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
     c->filters = NULL;
   }
   c->pollset_set = grpc_pollset_set_create();
-  const grpc_arg *addr_arg =
-      grpc_channel_args_find(args->args, GRPC_ARG_SUBCHANNEL_ADDRESS);
-  GPR_ASSERT(addr_arg != NULL);  // Should have been set by LB policy.
   grpc_resolved_address *addr = gpr_malloc(sizeof(*addr));
-  grpc_uri_to_sockaddr(addr_arg->value.string, addr);
+  grpc_get_subchannel_address_arg(args->args, addr);
   grpc_set_initial_connect_string(&addr, &c->initial_connect_string);
   static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
-  grpc_arg new_arg;
-  new_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
-  new_arg.type = GRPC_ARG_STRING;
-  new_arg.value.string = grpc_sockaddr_to_uri(addr);
+  grpc_arg new_arg = grpc_create_subchannel_address_arg(addr);
   gpr_free(addr);
   c->args = grpc_channel_args_copy_and_add_and_remove(
       args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1);
   gpr_free(new_arg.value.string);
+
   c->root_external_state_watcher.next = c->root_external_state_watcher.prev =
       &c->root_external_state_watcher;
   grpc_closure_init(&c->connected, subchannel_connected, c,
@@ -781,7 +777,7 @@ grpc_call_stack *grpc_subchannel_call_get_call_stack(
   return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
 }
 
-void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
+static void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
   grpc_uri *uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */);
   GPR_ASSERT(uri != NULL);
   if (strcmp(uri->scheme, "ipv4") == 0) {
@@ -793,3 +789,24 @@ void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
   }
   grpc_uri_destroy(uri);
 }
+
+void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
+                                     grpc_resolved_address *addr) {
+  const grpc_arg *addr_arg =
+      grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS);
+  GPR_ASSERT(addr_arg != NULL);  // Should have been set by LB policy.
+  GPR_ASSERT(addr_arg->type == GRPC_ARG_STRING);
+  memset(addr, 0, sizeof(*addr));
+  if (*addr_arg->value.string != '\0') {
+    grpc_uri_to_sockaddr(addr_arg->value.string, addr);
+  }
+}
+
+grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) {
+  grpc_arg new_arg;
+  new_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
+  new_arg.type = GRPC_ARG_STRING;
+  new_arg.value.string =
+      addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("");
+  return new_arg;
+}
diff --git a/src/core/ext/client_channel/subchannel.h b/src/core/ext/client_channel/subchannel.h
index 4cc33fc79b..c7a9577ce9 100644
--- a/src/core/ext/client_channel/subchannel.h
+++ b/src/core/ext/client_channel/subchannel.h
@@ -174,7 +174,12 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
                                         grpc_connector *connector,
                                         const grpc_subchannel_args *args);
 
-/// Sets \a addr from \a uri_str.
-void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr);
+/// Sets \a addr from \a args.
+void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
+                                     grpc_resolved_address *addr);
+
+/// Returns a new channel arg encoding the subchannel address as a string.
+/// Caller is responsible for freeing the string.
+grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr);
 
 #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_SUBCHANNEL_H */
diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/lb_policy/pick_first/pick_first.c
index 4677fb2343..9f2aa461be 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/lb_policy/pick_first/pick_first.c
@@ -468,11 +468,8 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
     }
 
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
-    grpc_arg addr_arg;
-    addr_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
-    addr_arg.type = GRPC_ARG_STRING;
-    addr_arg.value.string =
-        grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+    grpc_arg addr_arg =
+        grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
     grpc_channel_args *new_args =
         grpc_channel_args_copy_and_add(args->args, &addr_arg, 1);
     gpr_free(addr_arg.value.string);
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index 3fe157a23c..d17d8fa057 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -731,11 +731,8 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
     if (addresses->addresses[i].is_balancer) continue;
 
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
-    grpc_arg addr_arg;
-    addr_arg.key = GRPC_ARG_SUBCHANNEL_ADDRESS;
-    addr_arg.type = GRPC_ARG_STRING;
-    addr_arg.value.string =
-        grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+    grpc_arg addr_arg =
+        grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
     grpc_channel_args *new_args =
         grpc_channel_args_copy_and_add(args->args, &addr_arg, 1);
     gpr_free(addr_arg.value.string);
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
index ebe884b115..013c96dc70 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.c
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -221,11 +221,8 @@ static void chttp2_connector_connect(grpc_exec_ctx *exec_ctx,
                                      grpc_connect_out_args *result,
                                      grpc_closure *notify) {
   chttp2_connector *c = (chttp2_connector *)con;
-  const grpc_arg *addr_arg =
-      grpc_channel_args_find(args->channel_args, GRPC_ARG_SUBCHANNEL_ADDRESS);
-  GPR_ASSERT(addr_arg != NULL);  // Should have been set by LB policy.
   grpc_resolved_address addr;
-  grpc_uri_to_sockaddr(addr_arg->value.string, &addr);
+  grpc_get_subchannel_address_arg(args->channel_args, &addr);
   gpr_mu_lock(&c->mu);
   GPR_ASSERT(c->notify == NULL);
   c->notify = notify;
-- 
GitLab