From 54b21921f92e27ae004ef5b6e60c23d82ce6c18c Mon Sep 17 00:00:00 2001
From: Julien Boeuf <jboeuf@google.com>
Date: Wed, 4 Feb 2015 16:39:35 -0800
Subject: [PATCH] Adding call host (:authority header) check in the secure
 channel.

- Fixes #405.
- This change is not tested as it should (only end to end and no
  negative testing). Will do better when we have testing framework
  for filters.
---
 src/core/httpcli/httpcli_security_context.c   |  15 +-
 src/core/security/auth.c                      | 130 +++++++++++--
 src/core/security/secure_transport_setup.c    |   3 +-
 src/core/security/security_context.c          | 177 +++++++++++++-----
 src/core/security/security_context.h          |  38 ++--
 src/core/surface/secure_channel_create.c      |   7 +-
 test/core/end2end/dualstack_socket_test.c     |   7 +-
 test/core/end2end/tests/cancel_after_accept.c |   4 +-
 .../cancel_after_accept_and_writes_closed.c   |   6 +-
 ...el_after_accept_and_writes_closed_legacy.c |   4 +-
 .../tests/cancel_after_accept_legacy.c        |   4 +-
 test/core/end2end/tests/cancel_after_invoke.c |   4 +-
 .../tests/cancel_after_invoke_legacy.c        |   2 +-
 .../core/end2end/tests/cancel_before_invoke.c |   4 +-
 .../tests/cancel_before_invoke_legacy.c       |   2 +-
 test/core/end2end/tests/cancel_in_a_vacuum.c  |   4 +-
 .../end2end/tests/cancel_in_a_vacuum_legacy.c |   2 +-
 .../end2end/tests/census_simple_request.c     |   4 +-
 .../tests/census_simple_request_legacy.c      |   4 +-
 test/core/end2end/tests/disappearing_server.c |   6 +-
 .../tests/disappearing_server_legacy.c        |   4 +-
 ..._server_shutdown_finishes_inflight_calls.c |   6 +-
 ..._shutdown_finishes_inflight_calls_legacy.c |   4 +-
 .../end2end/tests/graceful_server_shutdown.c  |   6 +-
 .../tests/graceful_server_shutdown_legacy.c   |   4 +-
 .../core/end2end/tests/invoke_large_request.c |   6 +-
 .../tests/invoke_large_request_legacy.c       |   4 +-
 .../end2end/tests/max_concurrent_streams.c    |  14 +-
 .../tests/max_concurrent_streams_legacy.c     |  12 +-
 test/core/end2end/tests/ping_pong_streaming.c |   6 +-
 .../tests/ping_pong_streaming_legacy.c        |   4 +-
 ...esponse_with_binary_metadata_and_payload.c |   6 +-
 ..._with_binary_metadata_and_payload_legacy.c |   4 +-
 ...quest_response_with_metadata_and_payload.c |   6 +-
 ...esponse_with_metadata_and_payload_legacy.c |   4 +-
 .../tests/request_response_with_payload.c     |   6 +-
 .../request_response_with_payload_legacy.c    |   4 +-
 ...ponse_with_trailing_metadata_and_payload.c |   6 +-
 ...ith_trailing_metadata_and_payload_legacy.c |   4 +-
 .../tests/request_with_large_metadata.c       |   6 +-
 .../request_with_large_metadata_legacy.c      |   4 +-
 .../core/end2end/tests/request_with_payload.c |   6 +-
 .../tests/request_with_payload_legacy.c       |   4 +-
 .../end2end/tests/simple_delayed_request.c    |   6 +-
 .../tests/simple_delayed_request_legacy.c     |   4 +-
 test/core/end2end/tests/simple_request.c      |   6 +-
 .../end2end/tests/simple_request_legacy.c     |   8 +-
 test/core/end2end/tests/thread_stress.c       |   2 +-
 .../core/end2end/tests/thread_stress_legacy.c |   2 +-
 .../writes_done_hangs_with_pending_read.c     |   6 +-
 ...ites_done_hangs_with_pending_read_legacy.c |   6 +-
 51 files changed, 387 insertions(+), 210 deletions(-)

diff --git a/src/core/httpcli/httpcli_security_context.c b/src/core/httpcli/httpcli_security_context.c
index d074e163f1..53e887ccd1 100644
--- a/src/core/httpcli/httpcli_security_context.c
+++ b/src/core/httpcli/httpcli_security_context.c
@@ -73,20 +73,23 @@ static grpc_security_status httpcli_ssl_create_handshaker(
   return GRPC_SECURITY_OK;
 }
 
-static grpc_security_status httpcli_ssl_check_peer(
-    grpc_security_context *ctx, const tsi_peer *peer,
-    grpc_security_check_peer_cb cb, void *user_data) {
+static grpc_security_status httpcli_ssl_check_peer(grpc_security_context *ctx,
+                                                   tsi_peer peer,
+                                                   grpc_security_check_cb cb,
+                                                   void *user_data) {
   grpc_httpcli_ssl_channel_security_context *c =
       (grpc_httpcli_ssl_channel_security_context *)ctx;
+  grpc_security_status status = GRPC_SECURITY_OK;
 
   /* Check the peer name. */
   if (c->secure_peer_name != NULL &&
-      !tsi_ssl_peer_matches_name(peer, c->secure_peer_name)) {
+      !tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) {
     gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate",
             c->secure_peer_name);
-    return GRPC_SECURITY_ERROR;
+    status = GRPC_SECURITY_ERROR;
   }
-  return GRPC_SECURITY_OK;
+  tsi_peer_destruct(&peer);
+  return status;
 }
 
 static grpc_security_context_vtable httpcli_ssl_vtable = {
diff --git a/src/core/security/auth.c b/src/core/security/auth.c
index 9d0c075bc3..18c32f90f4 100644
--- a/src/core/security/auth.c
+++ b/src/core/security/auth.c
@@ -35,22 +35,49 @@
 
 #include <string.h>
 
-#include "src/core/security/security_context.h"
-#include "src/core/security/credentials.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
+#include "src/core/support/string.h"
+#include "src/core/channel/channel_stack.h"
+#include "src/core/security/security_context.h"
+#include "src/core/security/credentials.h"
+#include "src/core/surface/call.h"
+
 /* We can have a per-call credentials. */
 typedef struct {
   grpc_credentials *creds;
+  grpc_mdstr *host;
   grpc_call_op op;
 } call_data;
 
 /* We can have a per-channel credentials. */
 typedef struct {
   grpc_channel_security_context *security_context;
+  grpc_mdctx *md_ctx;
+  grpc_mdstr *authority_string;
+  grpc_mdstr *error_msg_key;
 } channel_data;
 
+static void do_nothing(void *ignored, grpc_op_error error) {}
+
+static void bubbleup_error(grpc_call_element *elem, const char *error_msg) {
+  grpc_call_op finish_op;
+  channel_data *channeld = elem->channel_data;
+
+  gpr_log(GPR_ERROR, "%s", error_msg);
+  finish_op.type = GRPC_RECV_METADATA;
+  finish_op.dir = GRPC_CALL_UP;
+  finish_op.flags = 0;
+  finish_op.data.metadata = grpc_mdelem_from_metadata_strings(
+      channeld->md_ctx, channeld->error_msg_key,
+      grpc_mdstr_from_string(channeld->md_ctx, error_msg));
+  finish_op.done_cb = do_nothing;
+  finish_op.user_data = NULL;
+  grpc_call_next_op(elem, &finish_op);
+  grpc_call_element_send_cancel(elem);
+}
+
 static void on_credentials_metadata(void *user_data, grpc_mdelem **md_elems,
                                     size_t num_md,
                                     grpc_credentials_status status) {
@@ -62,6 +89,46 @@ static void on_credentials_metadata(void *user_data, grpc_mdelem **md_elems,
   grpc_call_next_op(elem, &((call_data *)elem->call_data)->op);
 }
 
+static void send_security_metadata(grpc_call_element *elem, grpc_call_op *op) {
+  /* grab pointers to our data from the call element */
+  call_data *calld = elem->call_data;
+  channel_data *channeld = elem->channel_data;
+
+  grpc_credentials *channel_creds =
+      channeld->security_context->request_metadata_creds;
+  /* TODO(jboeuf):
+     Decide on the policy in this case:
+     - populate both channel and call?
+     - the call takes precedence over the channel?
+     - leave this decision up to the channel credentials?  */
+  if (calld->creds != NULL) {
+    gpr_log(GPR_ERROR, "Ignoring per call credentials for now.");
+  }
+  if (channel_creds != NULL &&
+      grpc_credentials_has_request_metadata(channel_creds)) {
+    calld->op = *op; /* Copy op (originates from the caller's stack). */
+    grpc_credentials_get_request_metadata(channel_creds,
+                                          on_credentials_metadata, elem);
+  } else {
+    grpc_call_next_op(elem, op);
+  }
+}
+
+static void on_host_checked(void *user_data, grpc_security_status status) {
+  grpc_call_element *elem = (grpc_call_element *)user_data;
+  call_data *calld = elem->call_data;
+
+  if (status == GRPC_SECURITY_OK) {
+    send_security_metadata(elem, &calld->op);
+  } else {
+    char *error_msg;
+    gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.",
+                 grpc_mdstr_as_c_string(calld->host));
+    bubbleup_error(elem, error_msg);
+    gpr_free(error_msg);
+  }
+}
+
 /* Called either:
      - in response to an API call (or similar) from above, to send something
      - a network event (or similar) from below, to receive something
@@ -74,26 +141,36 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
   channel_data *channeld = elem->channel_data;
 
   switch (op->type) {
-    case GRPC_SEND_START: {
-      grpc_credentials *channel_creds =
-          channeld->security_context->request_metadata_creds;
-      /* TODO(jboeuf):
-         Decide on the policy in this case:
-         - populate both channel and call?
-         - the call takes precedence over the channel?
-         - leave this decision up to the channel credentials?  */
-      if (calld->creds != NULL) {
-        gpr_log(GPR_ERROR, "Ignoring per call credentials for now.");
+    case GRPC_SEND_METADATA:
+      /* Pointer comparison is OK for md_elems created from the same context. */
+      if (op->data.metadata->key == channeld->authority_string) {
+        if (calld->host != NULL) grpc_mdstr_unref(calld->host);
+        calld->host = grpc_mdstr_ref(op->data.metadata->value);
       }
-      if (channel_creds != NULL &&
-          grpc_credentials_has_request_metadata(channel_creds)) {
+      grpc_call_next_op(elem, op);
+      break;
+
+    case GRPC_SEND_START:
+      if (calld->host != NULL) {
+        grpc_security_status status;
+        const char *call_host = grpc_mdstr_as_c_string(calld->host);
         calld->op = *op; /* Copy op (originates from the caller's stack). */
-        grpc_credentials_get_request_metadata(channel_creds,
-                                              on_credentials_metadata, elem);
-        break;
+        status = grpc_channel_security_context_check_call_host(
+            channeld->security_context, call_host, on_host_checked, elem);
+        if (status != GRPC_SECURITY_OK) {
+          if (status == GRPC_SECURITY_ERROR) {
+            char *error_msg;
+            gpr_asprintf(&error_msg,
+                         "Invalid host %s set in :authority metadata.",
+                         call_host);
+            bubbleup_error(elem, error_msg);
+            gpr_free(error_msg);
+          }
+          break;
+        }
       }
-      /* FALLTHROUGH INTENDED. */
-    }
+      send_security_metadata(elem, op);
+      break;
 
     default:
       /* pass control up or down the stack depending on op->dir */
@@ -116,6 +193,7 @@ static void init_call_elem(grpc_call_element *elem,
      Find a way to pass-in the credentials from the caller here.  */
   call_data *calld = elem->call_data;
   calld->creds = NULL;
+  calld->host = NULL;
 }
 
 /* Destructor for call_data */
@@ -124,6 +202,9 @@ static void destroy_call_elem(grpc_call_element *elem) {
   if (calld->creds != NULL) {
     grpc_credentials_unref(calld->creds);
   }
+  if (calld->host != NULL) {
+    grpc_mdstr_unref(calld->host);
+  }
 }
 
 /* Constructor for channel_data */
@@ -146,6 +227,11 @@ static void init_channel_elem(grpc_channel_element *elem,
   GPR_ASSERT(ctx->is_client_side);
   channeld->security_context =
       (grpc_channel_security_context *)grpc_security_context_ref(ctx);
+  channeld->md_ctx = metadata_context;
+  channeld->authority_string =
+      grpc_mdstr_from_string(channeld->md_ctx, ":authority");
+  channeld->error_msg_key =
+      grpc_mdstr_from_string(channeld->md_ctx, "grpc-message");
 }
 
 /* Destructor for channel data */
@@ -154,6 +240,12 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
   channel_data *channeld = elem->channel_data;
   grpc_channel_security_context *ctx = channeld->security_context;
   if (ctx != NULL) grpc_security_context_unref(&ctx->base);
+  if (channeld->authority_string != NULL) {
+    grpc_mdstr_unref(channeld->authority_string);
+  }
+  if (channeld->error_msg_key != NULL) {
+    grpc_mdstr_unref(channeld->error_msg_key);
+  }
 }
 
 const grpc_channel_filter grpc_client_auth_filter = {
diff --git a/src/core/security/secure_transport_setup.c b/src/core/security/secure_transport_setup.c
index 50a6987fbf..59789a7e4d 100644
--- a/src/core/security/secure_transport_setup.c
+++ b/src/core/security/secure_transport_setup.c
@@ -113,8 +113,7 @@ static void check_peer(grpc_secure_transport_setup *s) {
     return;
   }
   peer_status =
-      grpc_security_context_check_peer(s->ctx, &peer, on_peer_checked, s);
-  tsi_peer_destruct(&peer);
+      grpc_security_context_check_peer(s->ctx, peer, on_peer_checked, s);
   if (peer_status == GRPC_SECURITY_ERROR) {
     gpr_log(GPR_ERROR, "Peer check failed.");
     secure_transport_setup_done(s, 0);
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index 1edec29775..adb0269792 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -69,12 +69,22 @@ grpc_security_status grpc_security_context_create_handshaker(
 }
 
 grpc_security_status grpc_security_context_check_peer(
-    grpc_security_context *ctx, const tsi_peer *peer,
-    grpc_security_check_peer_cb cb, void *user_data) {
-  if (ctx == NULL) return GRPC_SECURITY_ERROR;
+    grpc_security_context *ctx, tsi_peer peer, grpc_security_check_cb cb,
+    void *user_data) {
+  if (ctx == NULL) {
+    tsi_peer_destruct(&peer);
+    return GRPC_SECURITY_ERROR;
+  }
   return ctx->vtable->check_peer(ctx, peer, cb, user_data);
 }
 
+grpc_security_status grpc_channel_security_context_check_call_host(
+    grpc_channel_security_context *ctx, const char *host,
+    grpc_security_check_cb cb, void *user_data) {
+  if (ctx == NULL || ctx->check_call_host == NULL) return GRPC_SECURITY_ERROR;
+  return ctx->check_call_host(ctx, host, cb, user_data);
+}
+
 void grpc_security_context_unref(grpc_security_context *ctx) {
   if (ctx == NULL) return;
   if (gpr_unref(&ctx->refcount)) ctx->vtable->destroy(ctx);
@@ -137,6 +147,11 @@ static int check_request_metadata_creds(grpc_credentials *creds) {
 
 /* -- Fake implementation. -- */
 
+typedef struct {
+  grpc_channel_security_context base;
+  int call_host_check_is_async;
+} grpc_fake_channel_security_context;
+
 static void fake_channel_destroy(grpc_security_context *ctx) {
   grpc_channel_security_context *c = (grpc_channel_security_context *)ctx;
   grpc_credentials_unref(c->request_metadata_creds);
@@ -158,31 +173,51 @@ static grpc_security_status fake_server_create_handshaker(
 }
 
 static grpc_security_status fake_check_peer(grpc_security_context *ctx,
-                                            const tsi_peer *peer,
-                                            grpc_security_check_peer_cb cb,
+                                            tsi_peer peer,
+                                            grpc_security_check_cb cb,
                                             void *user_data) {
   const char *prop_name;
-  if (peer->property_count != 1) {
+  grpc_security_status status = GRPC_SECURITY_OK;
+  if (peer.property_count != 1) {
     gpr_log(GPR_ERROR, "Fake peers should only have 1 property.");
-    return GRPC_SECURITY_ERROR;
+    status = GRPC_SECURITY_ERROR;
+    goto end;
   }
-  prop_name = peer->properties[0].name;
+  prop_name = peer.properties[0].name;
   if (prop_name == NULL ||
       strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) {
     gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.",
             prop_name == NULL ? "<EMPTY>" : prop_name);
-    return GRPC_SECURITY_ERROR;
+    status = GRPC_SECURITY_ERROR;
+    goto end;
   }
-  if (peer->properties[0].type != TSI_PEER_PROPERTY_TYPE_STRING) {
+  if (peer.properties[0].type != TSI_PEER_PROPERTY_TYPE_STRING) {
     gpr_log(GPR_ERROR, "Invalid type of cert type property.");
-    return GRPC_SECURITY_ERROR;
+    status = GRPC_SECURITY_ERROR;
+    goto end;
   }
-  if (strncmp(peer->properties[0].value.string.data, TSI_FAKE_CERTIFICATE_TYPE,
-              peer->properties[0].value.string.length)) {
+  if (strncmp(peer.properties[0].value.string.data, TSI_FAKE_CERTIFICATE_TYPE,
+              peer.properties[0].value.string.length)) {
     gpr_log(GPR_ERROR, "Invalid value for cert type property.");
-    return GRPC_SECURITY_ERROR;
+    status = GRPC_SECURITY_ERROR;
+    goto end;
+  }
+end:
+  tsi_peer_destruct(&peer);
+  return status;
+}
+
+static grpc_security_status fake_channel_check_call_host(
+    grpc_channel_security_context *ctx, const char *host,
+    grpc_security_check_cb cb, void *user_data) {
+  grpc_fake_channel_security_context *c =
+      (grpc_fake_channel_security_context *)ctx;
+  if (c->call_host_check_is_async) {
+    cb(user_data, GRPC_SECURITY_OK);
+    return GRPC_SECURITY_PENDING;
+  } else {
+    return GRPC_SECURITY_OK;
   }
-  return GRPC_SECURITY_OK;
 }
 
 static grpc_security_context_vtable fake_channel_vtable = {
@@ -192,15 +227,17 @@ static grpc_security_context_vtable fake_server_vtable = {
     fake_server_destroy, fake_server_create_handshaker, fake_check_peer};
 
 grpc_channel_security_context *grpc_fake_channel_security_context_create(
-    grpc_credentials *request_metadata_creds) {
-  grpc_channel_security_context *c =
-      gpr_malloc(sizeof(grpc_channel_security_context));
-  gpr_ref_init(&c->base.refcount, 1);
-  c->base.is_client_side = 1;
-  c->base.vtable = &fake_channel_vtable;
+    grpc_credentials *request_metadata_creds, int call_host_check_is_async) {
+  grpc_fake_channel_security_context *c =
+      gpr_malloc(sizeof(grpc_fake_channel_security_context));
+  gpr_ref_init(&c->base.base.refcount, 1);
+  c->base.base.is_client_side = 1;
+  c->base.base.vtable = &fake_channel_vtable;
   GPR_ASSERT(check_request_metadata_creds(request_metadata_creds));
-  c->request_metadata_creds = grpc_credentials_ref(request_metadata_creds);
-  return c;
+  c->base.request_metadata_creds = grpc_credentials_ref(request_metadata_creds);
+  c->base.check_call_host = fake_channel_check_call_host;
+  c->call_host_check_is_async = call_host_check_is_async;
+  return &c->base;
 }
 
 grpc_security_context *grpc_fake_server_security_context_create(void) {
@@ -215,7 +252,9 @@ grpc_security_context *grpc_fake_server_security_context_create(void) {
 typedef struct {
   grpc_channel_security_context base;
   tsi_ssl_handshaker_factory *handshaker_factory;
-  char *secure_peer_name;
+  char *target_name;
+  char *overridden_target_name;
+  tsi_peer peer;
 } grpc_ssl_channel_security_context;
 
 typedef struct {
@@ -230,7 +269,9 @@ static void ssl_channel_destroy(grpc_security_context *ctx) {
   if (c->handshaker_factory != NULL) {
     tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
   }
-  if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name);
+  if (c->target_name != NULL) gpr_free(c->target_name);
+  if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
+  tsi_peer_destruct(&c->peer);
   gpr_free(ctx);
 }
 
@@ -244,11 +285,11 @@ static void ssl_server_destroy(grpc_security_context *ctx) {
 
 static grpc_security_status ssl_create_handshaker(
     tsi_ssl_handshaker_factory *handshaker_factory, int is_client,
-    const char *secure_peer_name, tsi_handshaker **handshaker) {
+    const char *peer_name, tsi_handshaker **handshaker) {
   tsi_result result = TSI_OK;
   if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
   result = tsi_ssl_handshaker_factory_create_handshaker(
-      handshaker_factory, is_client ? secure_peer_name : NULL, handshaker);
+      handshaker_factory, is_client ? peer_name : NULL, handshaker);
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
             tsi_result_to_string(result));
@@ -261,7 +302,10 @@ static grpc_security_status ssl_channel_create_handshaker(
     grpc_security_context *ctx, tsi_handshaker **handshaker) {
   grpc_ssl_channel_security_context *c =
       (grpc_ssl_channel_security_context *)ctx;
-  return ssl_create_handshaker(c->handshaker_factory, 1, c->secure_peer_name,
+  return ssl_create_handshaker(c->handshaker_factory, 1,
+                               c->overridden_target_name != NULL
+                                   ? c->overridden_target_name
+                                   : c->target_name,
                                handshaker);
 }
 
@@ -271,7 +315,7 @@ static grpc_security_status ssl_server_create_handshaker(
   return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker);
 }
 
-static grpc_security_status ssl_check_peer(const char *secure_peer_name,
+static grpc_security_status ssl_check_peer(const char *peer_name,
                                            const tsi_peer *peer) {
   /* Check the ALPN. */
   const tsi_peer_property *p =
@@ -291,28 +335,54 @@ static grpc_security_status ssl_check_peer(const char *secure_peer_name,
   }
 
   /* Check the peer name if specified. */
-  if (secure_peer_name != NULL &&
-      !tsi_ssl_peer_matches_name(peer, secure_peer_name)) {
-    gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate",
-            secure_peer_name);
+  if (peer_name != NULL &&
+      !tsi_ssl_peer_matches_name(peer, peer_name)) {
+    gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name);
     return GRPC_SECURITY_ERROR;
   }
   return GRPC_SECURITY_OK;
 }
 
-static grpc_security_status ssl_channel_check_peer(
-    grpc_security_context *ctx, const tsi_peer *peer,
-    grpc_security_check_peer_cb cb, void *user_data) {
+static grpc_security_status ssl_channel_check_peer(grpc_security_context *ctx,
+                                                   tsi_peer peer,
+                                                   grpc_security_check_cb cb,
+                                                   void *user_data) {
   grpc_ssl_channel_security_context *c =
       (grpc_ssl_channel_security_context *)ctx;
-  return ssl_check_peer(c->secure_peer_name, peer);
+  grpc_security_status status = ssl_check_peer(c->overridden_target_name != NULL
+                                                   ? c->overridden_target_name
+                                                   : c->target_name,
+                                               &peer);
+  c->peer = peer;
+  return status;
+}
+
+static grpc_security_status ssl_server_check_peer(grpc_security_context *ctx,
+                                                  tsi_peer peer,
+                                                  grpc_security_check_cb cb,
+                                                  void *user_data) {
+  /* TODO(jboeuf): Find a way to expose the peer to the authorization layer. */
+  grpc_security_status status = ssl_check_peer(NULL, &peer);
+  tsi_peer_destruct(&peer);
+  return status;
 }
 
-static grpc_security_status ssl_server_check_peer(
-    grpc_security_context *ctx, const tsi_peer *peer,
-    grpc_security_check_peer_cb cb, void *user_data) {
-  /* TODO(jboeuf): Find a way to expose the peer to the authorization layer. */
-  return ssl_check_peer(NULL, peer);
+static grpc_security_status ssl_channel_check_call_host(
+    grpc_channel_security_context *ctx, const char *host,
+    grpc_security_check_cb cb, void *user_data) {
+  grpc_ssl_channel_security_context *c =
+      (grpc_ssl_channel_security_context *)ctx;
+
+  if (tsi_ssl_peer_matches_name(&c->peer, host)) return GRPC_SECURITY_OK;
+
+  /* If the target name was overridden, then the original target_name was
+     'checked' transitively during the previous peer check at the end of the
+     handshake. */
+  if (c->overridden_target_name != NULL && !strcmp(host, c->target_name)) {
+    return GRPC_SECURITY_OK;
+  } else {
+    return GRPC_SECURITY_ERROR;
+  }
 }
 
 static grpc_security_context_vtable ssl_channel_vtable = {
@@ -345,7 +415,8 @@ static size_t get_default_pem_roots(const unsigned char **pem_root_certs) {
 
 grpc_security_status grpc_ssl_channel_security_context_create(
     grpc_credentials *request_metadata_creds, const grpc_ssl_config *config,
-    const char *secure_peer_name, grpc_channel_security_context **ctx) {
+    const char *target_name, const char *overridden_target_name,
+    grpc_channel_security_context **ctx) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
   const unsigned char **alpn_protocol_strings =
       gpr_malloc(sizeof(const char *) * num_alpn_protocols);
@@ -364,8 +435,8 @@ grpc_security_status grpc_ssl_channel_security_context_create(
         strlen(grpc_chttp2_get_alpn_version_index(i));
   }
 
-  if (config == NULL || secure_peer_name == NULL) {
-    gpr_log(GPR_ERROR, "An ssl channel needs a config and a secure name.");
+  if (config == NULL || target_name == NULL) {
+    gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
     goto error;
   }
   if (!check_request_metadata_creds(request_metadata_creds)) {
@@ -379,8 +450,12 @@ grpc_security_status grpc_ssl_channel_security_context_create(
   c->base.base.vtable = &ssl_channel_vtable;
   c->base.base.is_client_side = 1;
   c->base.request_metadata_creds = grpc_credentials_ref(request_metadata_creds);
-  if (secure_peer_name != NULL) {
-    c->secure_peer_name = gpr_strdup(secure_peer_name);
+  c->base.check_call_host = ssl_channel_check_call_host;
+  if (target_name != NULL) {
+    c->target_name = gpr_strdup(target_name);
+  }
+  if (overridden_target_name != NULL) {
+    c->overridden_target_name = gpr_strdup(overridden_target_name);
   }
   if (config->pem_root_certs == NULL) {
     pem_root_certs_size = get_default_pem_roots(&pem_root_certs);
@@ -478,7 +553,7 @@ grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
   grpc_channel *channel = NULL;
   grpc_security_status status = GRPC_SECURITY_OK;
   size_t i = 0;
-  const char *secure_peer_name = target;
+  const char *overridden_target_name = NULL;
   grpc_arg arg;
   grpc_channel_args *new_args;
 
@@ -486,13 +561,13 @@ grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
     grpc_arg *arg = &args->args[i];
     if (!strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) &&
         arg->type == GRPC_ARG_STRING) {
-      secure_peer_name = arg->value.string;
+      overridden_target_name = arg->value.string;
       break;
     }
   }
   status = grpc_ssl_channel_security_context_create(
       request_metadata_creds, grpc_ssl_credentials_get_config(ssl_creds),
-      secure_peer_name, &ctx);
+      target, overridden_target_name, &ctx);
   if (status != GRPC_SECURITY_OK) {
     return grpc_lame_client_channel_create();
   }
@@ -510,7 +585,7 @@ grpc_channel *grpc_fake_transport_security_channel_create(
     grpc_credentials *fake_creds, grpc_credentials *request_metadata_creds,
     const char *target, const grpc_channel_args *args) {
   grpc_channel_security_context *ctx =
-      grpc_fake_channel_security_context_create(request_metadata_creds);
+      grpc_fake_channel_security_context_create(request_metadata_creds, 1);
   grpc_channel *channel =
       grpc_secure_channel_create_internal(target, args, ctx);
   grpc_security_context_unref(&ctx->base);
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
index 2caa2d3690..25d467d717 100644
--- a/src/core/security/security_context.h
+++ b/src/core/security/security_context.h
@@ -56,16 +56,15 @@ typedef struct grpc_security_context grpc_security_context;
 
 #define GRPC_SECURITY_CONTEXT_ARG "grpc.security_context"
 
-typedef void (*grpc_security_check_peer_cb)(void *user_data,
-                                            grpc_security_status status);
+typedef void (*grpc_security_check_cb)(void *user_data,
+                                       grpc_security_status status);
 
 typedef struct {
   void (*destroy)(grpc_security_context *ctx);
   grpc_security_status (*create_handshaker)(grpc_security_context *ctx,
                                             tsi_handshaker **handshaker);
-  grpc_security_status (*check_peer)(grpc_security_context *ctx,
-                                     const tsi_peer *peer,
-                                     grpc_security_check_peer_cb,
+  grpc_security_status (*check_peer)(grpc_security_context *ctx, tsi_peer peer,
+                                     grpc_security_check_cb cb,
                                      void *user_data);
 } grpc_security_context_vtable;
 
@@ -87,18 +86,14 @@ grpc_security_status grpc_security_context_create_handshaker(
 
 /* Check the peer.
    Implementations can choose to check the peer either synchronously or
-   asynchronously. In the first case, a successful will return
+   asynchronously. In the first case, a successful call will return
    GRPC_SECURITY_OK. In the asynchronous case, the call will return
    GRPC_SECURITY_PENDING unless an error is detected early on.
-
-   Note:
-   Asynchronous implementations of this interface should make a copy of the
-   fields of the peer they want to check as there is no guarantee on the
-   lifetime of the peer object beyond this call.
+   Ownership of the peer is transfered.
 */
 grpc_security_status grpc_security_context_check_peer(
-    grpc_security_context *ctx, const tsi_peer *peer,
-    grpc_security_check_peer_cb cb, void *user_data);
+    grpc_security_context *ctx, tsi_peer peer,
+    grpc_security_check_cb cb, void *user_data);
 
 /* Util to encapsulate the context in a channel arg. */
 grpc_arg grpc_security_context_to_arg(grpc_security_context *ctx);
@@ -120,14 +115,26 @@ typedef struct grpc_channel_security_context grpc_channel_security_context;
 struct grpc_channel_security_context {
   grpc_security_context base; /* requires is_client_side to be non 0. */
   grpc_credentials *request_metadata_creds;
+  grpc_security_status (*check_call_host)(
+      grpc_channel_security_context *ctx, const char *host,
+      grpc_security_check_cb cb, void *user_data);
 };
 
+/* Checks that the host that will be set for a call is acceptable.
+   Implementations can choose do the check either synchronously or
+   asynchronously. In the first case, a successful call will return
+   GRPC_SECURITY_OK. In the asynchronous case, the call will return
+   GRPC_SECURITY_PENDING unless an error is detected early on. */
+grpc_security_status grpc_channel_security_context_check_call_host(
+    grpc_channel_security_context *ctx, const char *host,
+    grpc_security_check_cb cb, void *user_data);
+
 /* --- Creation security contexts. --- */
 
 /* For TESTING ONLY!
    Creates a fake context that emulates real channel security.  */
 grpc_channel_security_context *grpc_fake_channel_security_context_create(
-    grpc_credentials *request_metadata_creds);
+    grpc_credentials *request_metadata_creds, int call_host_check_is_async);
 
 /* For TESTING ONLY!
    Creates a fake context that emulates real server security.  */
@@ -148,7 +155,8 @@ grpc_security_context *grpc_fake_server_security_context_create(void);
 */
 grpc_security_status grpc_ssl_channel_security_context_create(
     grpc_credentials *request_metadata_creds, const grpc_ssl_config *config,
-    const char *secure_peer_name, grpc_channel_security_context **ctx);
+    const char *target_name, const char *overridden_target_name,
+    grpc_channel_security_context **ctx);
 
 /* Creates an SSL server_security_context.
    - config is the SSL config to be used for the SSL channel establishment.
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index defee79766..562e27ff6d 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -189,8 +189,8 @@ static void done_setup(void *sp) {
 static grpc_transport_setup_result complete_setup(void *channel_stack,
                                                   grpc_transport *transport,
                                                   grpc_mdctx *mdctx) {
-  static grpc_channel_filter const *extra_filters[] = {&grpc_http_client_filter,
-                                                       &grpc_http_filter};
+  static grpc_channel_filter const *extra_filters[] = {
+      &grpc_client_auth_filter, &grpc_http_client_filter, &grpc_http_filter};
   return grpc_client_channel_transport_setup_complete(
       channel_stack, transport, extra_filters, GPR_ARRAY_SIZE(extra_filters),
       mdctx);
@@ -208,7 +208,7 @@ grpc_channel *grpc_secure_channel_create_internal(
   grpc_arg context_arg;
   grpc_channel_args *args_copy;
   grpc_mdctx *mdctx = grpc_mdctx_create();
-#define MAX_FILTERS 4
+#define MAX_FILTERS 3
   const grpc_channel_filter *filters[MAX_FILTERS];
   int n = 0;
   if (grpc_find_security_context_in_args(args) != NULL) {
@@ -222,7 +222,6 @@ grpc_channel *grpc_secure_channel_create_internal(
   if (grpc_channel_args_is_census_enabled(args)) {
     filters[n++] = &grpc_client_census_filter;
   }
-  filters[n++] = &grpc_client_auth_filter;
   filters[n++] = &grpc_client_channel_filter;
   GPR_ASSERT(n <= MAX_FILTERS);
   channel = grpc_channel_create_from_filters(filters, n, args_copy, mdctx, 1);
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index 9d893f67a1..a61644f583 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -112,7 +112,8 @@ void test_connect(const char *server_host, const char *client_host, int port,
   }
 
   /* Send a trivial request. */
-  c = grpc_channel_create_call_old(client, "/foo", "test.google.com", deadline);
+  c = grpc_channel_create_call_old(client, "/foo", "foo.test.google.com",
+                                   deadline);
   GPR_ASSERT(c);
 
   GPR_ASSERT(GRPC_CALL_OK ==
@@ -124,8 +125,8 @@ void test_connect(const char *server_host, const char *client_host, int port,
     cq_verify(v_client);
 
     GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(server, tag(100)));
-    cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
-                             deadline, NULL);
+    cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
+                             "foo.test.google.com", deadline, NULL);
     cq_verify(v_server);
 
     GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index eb26ff14f0..18d6bcec06 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -131,8 +131,8 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
       grpc_byte_buffer_create(&response_payload_slice, 1);
   int was_cancelled = 2;
 
-  c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
-                                   deadline);
+  c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
index b8a1438ca4..889db54162 100644
--- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
+++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
@@ -113,7 +113,7 @@ static void test_cancel_after_accept_and_writes_closed(
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -121,8 +121,8 @@ static void test_cancel_after_accept_and_writes_closed(
              grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0));
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
-                           deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c
index b8a1438ca4..2459666242 100644
--- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c
+++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c
@@ -113,7 +113,7 @@ static void test_cancel_after_accept_and_writes_closed(
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -121,7 +121,7 @@ static void test_cancel_after_accept_and_writes_closed(
              grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0));
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/cancel_after_accept_legacy.c b/test/core/end2end/tests/cancel_after_accept_legacy.c
index f9bf9fabf4..e87f7d648c 100644
--- a/test/core/end2end/tests/cancel_after_accept_legacy.c
+++ b/test/core/end2end/tests/cancel_after_accept_legacy.c
@@ -113,7 +113,7 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -121,7 +121,7 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
              grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0));
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index 96a8186d15..7f7c1e6597 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -124,8 +124,8 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
   grpc_byte_buffer *request_payload =
       grpc_byte_buffer_create(&request_payload_slice, 1);
 
-  c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
-                                   deadline);
+  c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/cancel_after_invoke_legacy.c b/test/core/end2end/tests/cancel_after_invoke_legacy.c
index 8b28223040..7a656f1cb0 100644
--- a/test/core/end2end/tests/cancel_after_invoke_legacy.c
+++ b/test/core/end2end/tests/cancel_after_invoke_legacy.c
@@ -111,7 +111,7 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
   gpr_timespec deadline = five_seconds_time();
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c
index 63e7f09dd5..663db5290d 100644
--- a/test/core/end2end/tests/cancel_before_invoke.c
+++ b/test/core/end2end/tests/cancel_before_invoke.c
@@ -122,8 +122,8 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config, int test_
   grpc_byte_buffer *request_payload =
       grpc_byte_buffer_create(&request_payload_slice, 1);
 
-  c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
-                                   deadline);
+  c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_call_cancel(c));
diff --git a/test/core/end2end/tests/cancel_before_invoke_legacy.c b/test/core/end2end/tests/cancel_before_invoke_legacy.c
index 5851277d20..cdd4b43447 100644
--- a/test/core/end2end/tests/cancel_before_invoke_legacy.c
+++ b/test/core/end2end/tests/cancel_before_invoke_legacy.c
@@ -109,7 +109,7 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config) {
   gpr_timespec deadline = five_seconds_time();
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c
index e493941f0a..e19d28a41e 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum.c
@@ -109,8 +109,8 @@ static void test_cancel_in_a_vacuum(grpc_end2end_test_config config,
   gpr_timespec deadline = five_seconds_time();
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
 
-  c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
-                                   deadline);
+  c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c));
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c b/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c
index 6b5194fb07..c9870896c0 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c
@@ -109,7 +109,7 @@ static void test_cancel_in_a_vacuum(grpc_end2end_test_config config,
   gpr_timespec deadline = five_seconds_time();
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
diff --git a/test/core/end2end/tests/census_simple_request.c b/test/core/end2end/tests/census_simple_request.c
index 4cbaa65b32..f144cd17aa 100644
--- a/test/core/end2end/tests/census_simple_request.c
+++ b/test/core/end2end/tests/census_simple_request.c
@@ -106,7 +106,7 @@ static void test_body(grpc_end2end_test_fixture f) {
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
   tag(1);
@@ -118,7 +118,7 @@ static void test_body(grpc_end2end_test_fixture f) {
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/census_simple_request_legacy.c b/test/core/end2end/tests/census_simple_request_legacy.c
index 4cbaa65b32..f144cd17aa 100644
--- a/test/core/end2end/tests/census_simple_request_legacy.c
+++ b/test/core/end2end/tests/census_simple_request_legacy.c
@@ -106,7 +106,7 @@ static void test_body(grpc_end2end_test_fixture f) {
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
   tag(1);
@@ -118,7 +118,7 @@ static void test_body(grpc_end2end_test_fixture f) {
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c
index 9b2f16890b..07de01059c 100644
--- a/test/core/end2end/tests/disappearing_server.c
+++ b/test/core/end2end/tests/disappearing_server.c
@@ -97,7 +97,7 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f,
   grpc_call *s;
   gpr_timespec deadline = five_seconds_time();
 
-  c = grpc_channel_create_call_old(f->client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -109,8 +109,8 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f,
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
-                           deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/disappearing_server_legacy.c b/test/core/end2end/tests/disappearing_server_legacy.c
index 9b2f16890b..b75b268647 100644
--- a/test/core/end2end/tests/disappearing_server_legacy.c
+++ b/test/core/end2end/tests/disappearing_server_legacy.c
@@ -97,7 +97,7 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f,
   grpc_call *s;
   gpr_timespec deadline = five_seconds_time();
 
-  c = grpc_channel_create_call_old(f->client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -109,7 +109,7 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f,
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
index a9d34e2db5..65de02ac1f 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
@@ -111,7 +111,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -123,8 +123,8 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
-                           deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c
index a9d34e2db5..6b920bb4ad 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c
@@ -111,7 +111,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -123,7 +123,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c
index dcd6192799..65972a756e 100644
--- a/test/core/end2end/tests/graceful_server_shutdown.c
+++ b/test/core/end2end/tests/graceful_server_shutdown.c
@@ -110,7 +110,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -122,8 +122,8 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
-                           deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/graceful_server_shutdown_legacy.c b/test/core/end2end/tests/graceful_server_shutdown_legacy.c
index dcd6192799..20394965d3 100644
--- a/test/core/end2end/tests/graceful_server_shutdown_legacy.c
+++ b/test/core/end2end/tests/graceful_server_shutdown_legacy.c
@@ -110,7 +110,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -122,7 +122,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c
index 7774fe4521..10c1e0befb 100644
--- a/test/core/end2end/tests/invoke_large_request.c
+++ b/test/core/end2end/tests/invoke_large_request.c
@@ -122,7 +122,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) {
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -138,8 +138,8 @@ static void test_invoke_large_request(grpc_end2end_test_config config) {
      request (as this request is very large) */
   cq_verify_empty(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
-                           deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/invoke_large_request_legacy.c b/test/core/end2end/tests/invoke_large_request_legacy.c
index 7774fe4521..8982d02701 100644
--- a/test/core/end2end/tests/invoke_large_request_legacy.c
+++ b/test/core/end2end/tests/invoke_large_request_legacy.c
@@ -122,7 +122,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) {
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -138,7 +138,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) {
      request (as this request is very large) */
   cq_verify_empty(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c
index 4830b85f9b..2ea8645ea7 100644
--- a/test/core/end2end/tests/max_concurrent_streams.c
+++ b/test/core/end2end/tests/max_concurrent_streams.c
@@ -109,7 +109,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -121,8 +121,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
-                           deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
@@ -182,10 +182,10 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
   /* start two requests - ensuring that the second is not accepted until
      the first completes */
   deadline = five_seconds_time();
-  c1 = grpc_channel_create_call_old(f.client, "/alpha", "test.google.com",
+  c1 = grpc_channel_create_call_old(f.client, "/alpha", "foo.test.google.com",
                                     deadline);
   GPR_ASSERT(c1);
-  c2 = grpc_channel_create_call_old(f.client, "/beta", "test.google.com",
+  c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.com",
                                     deadline);
   GPR_ASSERT(c1);
 
@@ -211,7 +211,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
 
   cq_expect_server_rpc_new(v_server, &s1, tag(100),
                            live_call == 300 ? "/alpha" : "/beta",
-                           "test.google.com", deadline, NULL);
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
@@ -237,7 +237,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(200)));
   cq_expect_server_rpc_new(v_server, &s2, tag(200),
                            live_call == 300 ? "/alpha" : "/beta",
-                           "test.google.com", deadline, NULL);
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/max_concurrent_streams_legacy.c b/test/core/end2end/tests/max_concurrent_streams_legacy.c
index 4830b85f9b..d15368182a 100644
--- a/test/core/end2end/tests/max_concurrent_streams_legacy.c
+++ b/test/core/end2end/tests/max_concurrent_streams_legacy.c
@@ -109,7 +109,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -121,7 +121,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
@@ -182,10 +182,10 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
   /* start two requests - ensuring that the second is not accepted until
      the first completes */
   deadline = five_seconds_time();
-  c1 = grpc_channel_create_call_old(f.client, "/alpha", "test.google.com",
+  c1 = grpc_channel_create_call_old(f.client, "/alpha", "foo.test.google.com",
                                     deadline);
   GPR_ASSERT(c1);
-  c2 = grpc_channel_create_call_old(f.client, "/beta", "test.google.com",
+  c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.com",
                                     deadline);
   GPR_ASSERT(c1);
 
@@ -211,7 +211,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
 
   cq_expect_server_rpc_new(v_server, &s1, tag(100),
                            live_call == 300 ? "/alpha" : "/beta",
-                           "test.google.com", deadline, NULL);
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
@@ -237,7 +237,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(200)));
   cq_expect_server_rpc_new(v_server, &s2, tag(200),
                            live_call == 300 ? "/alpha" : "/beta",
-                           "test.google.com", deadline, NULL);
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c
index 0c034a1996..4e27be16b4 100644
--- a/test/core/end2end/tests/ping_pong_streaming.c
+++ b/test/core/end2end/tests/ping_pong_streaming.c
@@ -118,7 +118,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
   gpr_log(GPR_INFO, "testing with %d message pairs.", messages);
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -127,8 +127,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
-                           deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
   GPR_ASSERT(GRPC_CALL_OK ==
              grpc_call_server_accept_old(s, f.server_cq, tag(102)));
diff --git a/test/core/end2end/tests/ping_pong_streaming_legacy.c b/test/core/end2end/tests/ping_pong_streaming_legacy.c
index 0c034a1996..cd1d03e4cd 100644
--- a/test/core/end2end/tests/ping_pong_streaming_legacy.c
+++ b/test/core/end2end/tests/ping_pong_streaming_legacy.c
@@ -118,7 +118,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
   gpr_log(GPR_INFO, "testing with %d message pairs.", messages);
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -127,7 +127,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config,
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
index fa5df5f526..940e327d22 100644
--- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
@@ -139,8 +139,8 @@ static void test_request_response_with_metadata_and_payload(
   size_t details_capacity = 0;
   int was_cancelled = 2;
 
-  c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
-                               deadline);
+  c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -209,7 +209,7 @@ static void test_request_response_with_metadata_and_payload(
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
   GPR_ASSERT(was_cancelled == 0);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
   GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c
index daadcf619b..b5e4eea6c8 100644
--- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c
@@ -137,7 +137,7 @@ static void test_request_response_with_metadata_and_payload(
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -157,7 +157,7 @@ static void test_request_response_with_metadata_and_payload(
   cq_verify(v_client);
 
   cq_expect_server_rpc_new(
-      v_server, &s, tag(100), "/foo", "test.google.com", deadline, "key1-bin",
+      v_server, &s, tag(100), "/foo", "foo.test.google.com", deadline, "key1-bin",
       "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", "key2-bin",
       "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", NULL);
   cq_verify(v_server);
diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
index ad01fe7081..80cb629542 100644
--- a/test/core/end2end/tests/request_response_with_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
@@ -132,8 +132,8 @@ static void test_request_response_with_metadata_and_payload(
   size_t details_capacity = 0;
   int was_cancelled = 2;
 
-  c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
-                               deadline);
+  c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -202,7 +202,7 @@ static void test_request_response_with_metadata_and_payload(
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
   GPR_ASSERT(was_cancelled == 0);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
   GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c
index 0a58398c4a..a86e1aa7f9 100644
--- a/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c
@@ -128,7 +128,7 @@ static void test_request_response_with_metadata_and_payload(
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -147,7 +147,7 @@ static void test_request_response_with_metadata_and_payload(
   cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK);
   cq_verify(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, "key1", "val1", "key2", "val2", NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_response_with_payload.c b/test/core/end2end/tests/request_response_with_payload.c
index 6b60c4da65..b07f51da85 100644
--- a/test/core/end2end/tests/request_response_with_payload.c
+++ b/test/core/end2end/tests/request_response_with_payload.c
@@ -127,8 +127,8 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) {
   size_t details_capacity = 0;
   int was_cancelled = 2;
 
-  c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
-                               deadline);
+  c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -195,7 +195,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) {
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
   GPR_ASSERT(was_cancelled == 0);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
   GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
diff --git a/test/core/end2end/tests/request_response_with_payload_legacy.c b/test/core/end2end/tests/request_response_with_payload_legacy.c
index d3b237bc34..eaa88eb91a 100644
--- a/test/core/end2end/tests/request_response_with_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_payload_legacy.c
@@ -121,7 +121,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) {
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -136,7 +136,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) {
   cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK);
   cq_verify(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
index 5878058c98..e547604619 100644
--- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
@@ -133,8 +133,8 @@ static void test_request_response_with_metadata_and_payload(
   size_t details_capacity = 0;
   int was_cancelled = 2;
 
-  c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
-                               deadline);
+  c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -204,7 +204,7 @@ static void test_request_response_with_metadata_and_payload(
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
   GPR_ASSERT(was_cancelled == 1);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
   GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c
index f5f0e646ea..d6554b2792 100644
--- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c
@@ -130,7 +130,7 @@ static void test_request_response_with_metadata_and_payload(
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -149,7 +149,7 @@ static void test_request_response_with_metadata_and_payload(
   cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK);
   cq_verify(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, "key1", "val1", "key2", "val2", NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_with_large_metadata.c b/test/core/end2end/tests/request_with_large_metadata.c
index 7e7bec0160..eb6180c399 100644
--- a/test/core/end2end/tests/request_with_large_metadata.c
+++ b/test/core/end2end/tests/request_with_large_metadata.c
@@ -127,8 +127,8 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
   int was_cancelled = 2;
   const int large_size = 64 * 1024;
 
-  c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
-                               deadline);
+  c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   meta.key = "key";
@@ -196,7 +196,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
   GPR_ASSERT(was_cancelled == 0);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
   GPR_ASSERT(contains_metadata(&request_metadata_recv, "key", meta.value));
diff --git a/test/core/end2end/tests/request_with_large_metadata_legacy.c b/test/core/end2end/tests/request_with_large_metadata_legacy.c
index 560df5c4ab..d768f148ef 100644
--- a/test/core/end2end/tests/request_with_large_metadata_legacy.c
+++ b/test/core/end2end/tests/request_with_large_metadata_legacy.c
@@ -121,7 +121,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
   ((char*)meta.value)[large_size] = 0;
   meta.value_length = large_size;
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -131,7 +131,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) {
   GPR_ASSERT(GRPC_CALL_OK ==
              grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0));
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, "key", meta.value, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c
index 2c23f37e0c..2bf0fa3717 100644
--- a/test/core/end2end/tests/request_with_payload.c
+++ b/test/core/end2end/tests/request_with_payload.c
@@ -125,8 +125,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   size_t details_capacity = 0;
   int was_cancelled = 2;
 
-  c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
-                               deadline);
+  c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -187,7 +187,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
   GPR_ASSERT(was_cancelled == 0);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
 
diff --git a/test/core/end2end/tests/request_with_payload_legacy.c b/test/core/end2end/tests/request_with_payload_legacy.c
index 5cda853aa9..8d932afb35 100644
--- a/test/core/end2end/tests/request_with_payload_legacy.c
+++ b/test/core/end2end/tests/request_with_payload_legacy.c
@@ -116,7 +116,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   /* byte buffer holds the slice, we can unref it already */
   gpr_slice_unref(payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -132,7 +132,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) {
   cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK);
   cq_verify(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c
index 99d1a26386..80763fe6cd 100644
--- a/test/core/end2end/tests/simple_delayed_request.c
+++ b/test/core/end2end/tests/simple_delayed_request.c
@@ -113,8 +113,8 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
 
   config.init_client(f, client_args);
 
-  c = grpc_channel_create_call(f->client, f->client_cq, "/foo", "test.google.com",
-                               deadline);
+  c = grpc_channel_create_call(f->client, f->client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -171,7 +171,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
   GPR_ASSERT(was_cancelled == 0);
 
   gpr_free(details);
diff --git a/test/core/end2end/tests/simple_delayed_request_legacy.c b/test/core/end2end/tests/simple_delayed_request_legacy.c
index a982bb5e1b..6b211ecccf 100644
--- a/test/core/end2end/tests/simple_delayed_request_legacy.c
+++ b/test/core/end2end/tests/simple_delayed_request_legacy.c
@@ -103,7 +103,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
 
   config.init_client(f, client_args);
 
-  c = grpc_channel_create_call_old(f->client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -119,7 +119,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c
index 0f046ae2d2..968be74cfb 100644
--- a/test/core/end2end/tests/simple_request.c
+++ b/test/core/end2end/tests/simple_request.c
@@ -121,8 +121,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   size_t details_capacity = 0;
   int was_cancelled = 2;
 
-  c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "test.google.com",
-                               deadline);
+  c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
+                               "foo.test.google.com", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -177,7 +177,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
   GPR_ASSERT(was_cancelled == 0);
 
   gpr_free(details);
diff --git a/test/core/end2end/tests/simple_request_legacy.c b/test/core/end2end/tests/simple_request_legacy.c
index db0d6d8160..eb984cee97 100644
--- a/test/core/end2end/tests/simple_request_legacy.c
+++ b/test/core/end2end/tests/simple_request_legacy.c
@@ -110,7 +110,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -122,7 +122,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) {
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
@@ -157,7 +157,7 @@ static void simple_request_body2(grpc_end2end_test_fixture f) {
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -169,7 +169,7 @@ static void simple_request_body2(grpc_end2end_test_fixture f) {
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/thread_stress.c b/test/core/end2end/tests/thread_stress.c
index e950a984ce..8a5cdc7e92 100644
--- a/test/core/end2end/tests/thread_stress.c
+++ b/test/core/end2end/tests/thread_stress.c
@@ -109,7 +109,7 @@ static void start_request(void) {
   gpr_slice slice = gpr_slice_malloc(100);
   grpc_byte_buffer *buf;
   grpc_call *call = grpc_channel_create_call_old(
-      g_fixture.client, "/Foo", "test.google.com", g_test_end_time);
+      g_fixture.client, "/Foo", "foo.test.google.com", g_test_end_time);
 
   memset(GPR_SLICE_START_PTR(slice), 1, GPR_SLICE_LENGTH(slice));
   buf = grpc_byte_buffer_create(&slice, 1);
diff --git a/test/core/end2end/tests/thread_stress_legacy.c b/test/core/end2end/tests/thread_stress_legacy.c
index e950a984ce..8a5cdc7e92 100644
--- a/test/core/end2end/tests/thread_stress_legacy.c
+++ b/test/core/end2end/tests/thread_stress_legacy.c
@@ -109,7 +109,7 @@ static void start_request(void) {
   gpr_slice slice = gpr_slice_malloc(100);
   grpc_byte_buffer *buf;
   grpc_call *call = grpc_channel_create_call_old(
-      g_fixture.client, "/Foo", "test.google.com", g_test_end_time);
+      g_fixture.client, "/Foo", "foo.test.google.com", g_test_end_time);
 
   memset(GPR_SLICE_START_PTR(slice), 1, GPR_SLICE_LENGTH(slice));
   buf = grpc_byte_buffer_create(&slice, 1);
diff --git a/test/core/end2end/tests/writes_done_hangs_with_pending_read.c b/test/core/end2end/tests/writes_done_hangs_with_pending_read.c
index 0c77aa2b4e..e7b7da1756 100644
--- a/test/core/end2end/tests/writes_done_hangs_with_pending_read.c
+++ b/test/core/end2end/tests/writes_done_hangs_with_pending_read.c
@@ -124,7 +124,7 @@ static void test_writes_done_hangs_with_pending_read(
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -140,8 +140,8 @@ static void test_writes_done_hangs_with_pending_read(
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
-                           deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c b/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c
index 0c77aa2b4e..e7b7da1756 100644
--- a/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c
+++ b/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c
@@ -124,7 +124,7 @@ static void test_writes_done_hangs_with_pending_read(
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -140,8 +140,8 @@ static void test_writes_done_hangs_with_pending_read(
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
-                           deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
+                           "foo.test.google.com", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
-- 
GitLab