Przeglądaj źródła

added call_host_override test

David Garcia Quintas 7 lat temu
rodzic
commit
861363d618

+ 2 - 0
CMakeLists.txt

@@ -5119,6 +5119,7 @@ add_library(end2end_tests
   test/core/end2end/tests/bad_ping.cc
   test/core/end2end/tests/bad_ping.cc
   test/core/end2end/tests/binary_metadata.cc
   test/core/end2end/tests/binary_metadata.cc
   test/core/end2end/tests/call_creds.cc
   test/core/end2end/tests/call_creds.cc
+  test/core/end2end/tests/call_host_override.cc
   test/core/end2end/tests/cancel_after_accept.cc
   test/core/end2end/tests/cancel_after_accept.cc
   test/core/end2end/tests/cancel_after_client_done.cc
   test/core/end2end/tests/cancel_after_client_done.cc
   test/core/end2end/tests/cancel_after_invoke.cc
   test/core/end2end/tests/cancel_after_invoke.cc
@@ -5234,6 +5235,7 @@ add_library(end2end_nosec_tests
   test/core/end2end/tests/bad_hostname.cc
   test/core/end2end/tests/bad_hostname.cc
   test/core/end2end/tests/bad_ping.cc
   test/core/end2end/tests/bad_ping.cc
   test/core/end2end/tests/binary_metadata.cc
   test/core/end2end/tests/binary_metadata.cc
+  test/core/end2end/tests/call_host_override.cc
   test/core/end2end/tests/cancel_after_accept.cc
   test/core/end2end/tests/cancel_after_accept.cc
   test/core/end2end/tests/cancel_after_client_done.cc
   test/core/end2end/tests/cancel_after_client_done.cc
   test/core/end2end/tests/cancel_after_invoke.cc
   test/core/end2end/tests/cancel_after_invoke.cc

+ 2 - 0
Makefile

@@ -9756,6 +9756,7 @@ LIBEND2END_TESTS_SRC = \
     test/core/end2end/tests/bad_ping.cc \
     test/core/end2end/tests/bad_ping.cc \
     test/core/end2end/tests/binary_metadata.cc \
     test/core/end2end/tests/binary_metadata.cc \
     test/core/end2end/tests/call_creds.cc \
     test/core/end2end/tests/call_creds.cc \
+    test/core/end2end/tests/call_host_override.cc \
     test/core/end2end/tests/cancel_after_accept.cc \
     test/core/end2end/tests/cancel_after_accept.cc \
     test/core/end2end/tests/cancel_after_client_done.cc \
     test/core/end2end/tests/cancel_after_client_done.cc \
     test/core/end2end/tests/cancel_after_invoke.cc \
     test/core/end2end/tests/cancel_after_invoke.cc \
@@ -9870,6 +9871,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \
     test/core/end2end/tests/bad_hostname.cc \
     test/core/end2end/tests/bad_hostname.cc \
     test/core/end2end/tests/bad_ping.cc \
     test/core/end2end/tests/bad_ping.cc \
     test/core/end2end/tests/binary_metadata.cc \
     test/core/end2end/tests/binary_metadata.cc \
+    test/core/end2end/tests/call_host_override.cc \
     test/core/end2end/tests/cancel_after_accept.cc \
     test/core/end2end/tests/cancel_after_accept.cc \
     test/core/end2end/tests/cancel_after_client_done.cc \
     test/core/end2end/tests/cancel_after_client_done.cc \
     test/core/end2end/tests/cancel_after_invoke.cc \
     test/core/end2end/tests/cancel_after_invoke.cc \

+ 1 - 0
gRPC-Core.podspec

@@ -2080,6 +2080,7 @@ Pod::Spec.new do |s|
                       'test/core/end2end/tests/bad_ping.cc',
                       'test/core/end2end/tests/bad_ping.cc',
                       'test/core/end2end/tests/binary_metadata.cc',
                       'test/core/end2end/tests/binary_metadata.cc',
                       'test/core/end2end/tests/call_creds.cc',
                       'test/core/end2end/tests/call_creds.cc',
+                      'test/core/end2end/tests/call_host_override.cc',
                       'test/core/end2end/tests/cancel_after_accept.cc',
                       'test/core/end2end/tests/cancel_after_accept.cc',
                       'test/core/end2end/tests/cancel_after_client_done.cc',
                       'test/core/end2end/tests/cancel_after_client_done.cc',
                       'test/core/end2end/tests/cancel_after_invoke.cc',
                       'test/core/end2end/tests/cancel_after_invoke.cc',

+ 2 - 0
grpc.gyp

@@ -2568,6 +2568,7 @@
         'test/core/end2end/tests/bad_ping.cc',
         'test/core/end2end/tests/bad_ping.cc',
         'test/core/end2end/tests/binary_metadata.cc',
         'test/core/end2end/tests/binary_metadata.cc',
         'test/core/end2end/tests/call_creds.cc',
         'test/core/end2end/tests/call_creds.cc',
+        'test/core/end2end/tests/call_host_override.cc',
         'test/core/end2end/tests/cancel_after_accept.cc',
         'test/core/end2end/tests/cancel_after_accept.cc',
         'test/core/end2end/tests/cancel_after_client_done.cc',
         'test/core/end2end/tests/cancel_after_client_done.cc',
         'test/core/end2end/tests/cancel_after_invoke.cc',
         'test/core/end2end/tests/cancel_after_invoke.cc',
@@ -2656,6 +2657,7 @@
         'test/core/end2end/tests/bad_hostname.cc',
         'test/core/end2end/tests/bad_hostname.cc',
         'test/core/end2end/tests/bad_ping.cc',
         'test/core/end2end/tests/bad_ping.cc',
         'test/core/end2end/tests/binary_metadata.cc',
         'test/core/end2end/tests/binary_metadata.cc',
+        'test/core/end2end/tests/call_host_override.cc',
         'test/core/end2end/tests/cancel_after_accept.cc',
         'test/core/end2end/tests/cancel_after_accept.cc',
         'test/core/end2end/tests/cancel_after_client_done.cc',
         'test/core/end2end/tests/cancel_after_client_done.cc',
         'test/core/end2end/tests/cancel_after_invoke.cc',
         'test/core/end2end/tests/cancel_after_invoke.cc',

+ 10 - 0
include/grpc/impl/codegen/grpc_types.h

@@ -258,6 +258,16 @@ typedef struct {
     secure channel is an SSL channel). If this parameter is specified and the
     secure channel is an SSL channel). If this parameter is specified and the
     underlying is not an SSL channel, it will just be ignored. */
     underlying is not an SSL channel, it will just be ignored. */
 #define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
 #define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
+/** This *should* be used for testing only.
+    The caller of the secure_channel_create functions may override the target
+    name used for fake security host name checking using this channel argument
+    which is of type \a GRPC_ARG_STRING. If this argument is not specified, the
+    name used for fake security host name checking will be the target parameter
+    (assuming that the secure channel is a fake security channel). If this
+    parameter is specified and the underlying is not a fake security channel, it
+    will just be ignored. */
+#define GRPC_FAKE_SECURITY_TARGET_NAME_OVERRIDE_ARG \
+  "grpc.fake_security_target_name_override"
 /** If non-zero, a pointer to a session cache (a pointer of type
 /** If non-zero, a pointer to a session cache (a pointer of type
     grpc_ssl_session_cache*). (use grpc_ssl_session_cache_arg_vtable() to fetch
     grpc_ssl_session_cache*). (use grpc_ssl_session_cache_arg_vtable() to fetch
     an appropriate pointer arg vtable) */
     an appropriate pointer arg vtable) */

+ 20 - 18
src/core/lib/security/security_connector/security_connector.cc

@@ -306,7 +306,7 @@ typedef struct {
   char* target;
   char* target;
   char* expected_targets;
   char* expected_targets;
   bool is_lb_channel;
   bool is_lb_channel;
-  char* ssl_target_name_override;
+  char* target_name_override;
 } grpc_fake_channel_security_connector;
 } grpc_fake_channel_security_connector;
 
 
 static void fake_channel_destroy(grpc_security_connector* sc) {
 static void fake_channel_destroy(grpc_security_connector* sc) {
@@ -315,7 +315,7 @@ static void fake_channel_destroy(grpc_security_connector* sc) {
   grpc_call_credentials_unref(c->base.request_metadata_creds);
   grpc_call_credentials_unref(c->base.request_metadata_creds);
   gpr_free(c->target);
   gpr_free(c->target);
   gpr_free(c->expected_targets);
   gpr_free(c->expected_targets);
-  gpr_free(c->ssl_target_name_override);
+  gpr_free(c->target_name_override);
   gpr_free(c);
   gpr_free(c);
 }
 }
 
 
@@ -473,19 +473,21 @@ static bool fake_channel_check_call_host(grpc_channel_security_connector* sc,
   char* target_ignored_port = nullptr;
   char* target_ignored_port = nullptr;
   gpr_split_host_port(host, &authority_hostname, &authority_ignored_port);
   gpr_split_host_port(host, &authority_hostname, &authority_ignored_port);
   gpr_split_host_port(c->target, &target_hostname, &target_ignored_port);
   gpr_split_host_port(c->target, &target_hostname, &target_ignored_port);
-  if (c->ssl_target_name_override != nullptr) {
-    char* ssl_target_name_override_hostname = nullptr;
-    char* ssl_target_name_override_ignored_port = nullptr;
-    gpr_split_host_port(c->ssl_target_name_override,
-                        &ssl_target_name_override_hostname,
-                        &ssl_target_name_override_ignored_port);
-    if (strcmp(authority_hostname, ssl_target_name_override_hostname) != 0) {
-      gpr_log(GPR_ERROR, "Authority (host) '%s' != SSL Target override '%s'",
-              host, ssl_target_name_override_hostname);
+  if (c->target_name_override != nullptr) {
+    char* fake_security_target_name_override_hostname = nullptr;
+    char* fake_security_target_name_override_ignored_port = nullptr;
+    gpr_split_host_port(c->target_name_override,
+                        &fake_security_target_name_override_hostname,
+                        &fake_security_target_name_override_ignored_port);
+    if (strcmp(authority_hostname,
+               fake_security_target_name_override_hostname) != 0) {
+      gpr_log(GPR_ERROR,
+              "Authority (host) '%s' != Fake Security Target override '%s'",
+              host, fake_security_target_name_override_hostname);
       abort();
       abort();
     }
     }
-    gpr_free(ssl_target_name_override_hostname);
-    gpr_free(ssl_target_name_override_ignored_port);
+    gpr_free(fake_security_target_name_override_hostname);
+    gpr_free(fake_security_target_name_override_ignored_port);
   } else if (strcmp(authority_hostname, target_hostname) != 0) {
   } else if (strcmp(authority_hostname, target_hostname) != 0) {
     gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'",
     gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'",
             authority_hostname, target_hostname);
             authority_hostname, target_hostname);
@@ -547,11 +549,11 @@ grpc_channel_security_connector* grpc_fake_channel_security_connector_create(
   const char* expected_targets = grpc_fake_transport_get_expected_targets(args);
   const char* expected_targets = grpc_fake_transport_get_expected_targets(args);
   c->expected_targets = gpr_strdup(expected_targets);
   c->expected_targets = gpr_strdup(expected_targets);
   c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr;
   c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr;
-  const grpc_arg* ssl_target_name_override_arg =
-      grpc_channel_args_find(args, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
-  if (ssl_target_name_override_arg != nullptr) {
-    c->ssl_target_name_override =
-        grpc_channel_arg_get_string(ssl_target_name_override_arg);
+  const grpc_arg* target_name_override_arg =
+      grpc_channel_args_find(args, GRPC_FAKE_SECURITY_TARGET_NAME_OVERRIDE_ARG);
+  if (target_name_override_arg != nullptr) {
+    c->target_name_override =
+        gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg));
   }
   }
   return &c->base;
   return &c->base;
 }
 }

+ 8 - 0
test/core/end2end/end2end_nosec_tests.cc

@@ -38,6 +38,8 @@ extern void bad_ping(grpc_end2end_test_config config);
 extern void bad_ping_pre_init(void);
 extern void bad_ping_pre_init(void);
 extern void binary_metadata(grpc_end2end_test_config config);
 extern void binary_metadata(grpc_end2end_test_config config);
 extern void binary_metadata_pre_init(void);
 extern void binary_metadata_pre_init(void);
+extern void call_host_override(grpc_end2end_test_config config);
+extern void call_host_override_pre_init(void);
 extern void cancel_after_accept(grpc_end2end_test_config config);
 extern void cancel_after_accept(grpc_end2end_test_config config);
 extern void cancel_after_accept_pre_init(void);
 extern void cancel_after_accept_pre_init(void);
 extern void cancel_after_client_done(grpc_end2end_test_config config);
 extern void cancel_after_client_done(grpc_end2end_test_config config);
@@ -187,6 +189,7 @@ void grpc_end2end_tests_pre_init(void) {
   bad_hostname_pre_init();
   bad_hostname_pre_init();
   bad_ping_pre_init();
   bad_ping_pre_init();
   binary_metadata_pre_init();
   binary_metadata_pre_init();
+  call_host_override_pre_init();
   cancel_after_accept_pre_init();
   cancel_after_accept_pre_init();
   cancel_after_client_done_pre_init();
   cancel_after_client_done_pre_init();
   cancel_after_invoke_pre_init();
   cancel_after_invoke_pre_init();
@@ -270,6 +273,7 @@ void grpc_end2end_tests(int argc, char **argv,
     bad_hostname(config);
     bad_hostname(config);
     bad_ping(config);
     bad_ping(config);
     binary_metadata(config);
     binary_metadata(config);
+    call_host_override(config);
     cancel_after_accept(config);
     cancel_after_accept(config);
     cancel_after_client_done(config);
     cancel_after_client_done(config);
     cancel_after_invoke(config);
     cancel_after_invoke(config);
@@ -360,6 +364,10 @@ void grpc_end2end_tests(int argc, char **argv,
       binary_metadata(config);
       binary_metadata(config);
       continue;
       continue;
     }
     }
+    if (0 == strcmp("call_host_override", argv[i])) {
+      call_host_override(config);
+      continue;
+    }
     if (0 == strcmp("cancel_after_accept", argv[i])) {
     if (0 == strcmp("cancel_after_accept", argv[i])) {
       cancel_after_accept(config);
       cancel_after_accept(config);
       continue;
       continue;

+ 8 - 0
test/core/end2end/end2end_tests.cc

@@ -40,6 +40,8 @@ extern void binary_metadata(grpc_end2end_test_config config);
 extern void binary_metadata_pre_init(void);
 extern void binary_metadata_pre_init(void);
 extern void call_creds(grpc_end2end_test_config config);
 extern void call_creds(grpc_end2end_test_config config);
 extern void call_creds_pre_init(void);
 extern void call_creds_pre_init(void);
+extern void call_host_override(grpc_end2end_test_config config);
+extern void call_host_override_pre_init(void);
 extern void cancel_after_accept(grpc_end2end_test_config config);
 extern void cancel_after_accept(grpc_end2end_test_config config);
 extern void cancel_after_accept_pre_init(void);
 extern void cancel_after_accept_pre_init(void);
 extern void cancel_after_client_done(grpc_end2end_test_config config);
 extern void cancel_after_client_done(grpc_end2end_test_config config);
@@ -190,6 +192,7 @@ void grpc_end2end_tests_pre_init(void) {
   bad_ping_pre_init();
   bad_ping_pre_init();
   binary_metadata_pre_init();
   binary_metadata_pre_init();
   call_creds_pre_init();
   call_creds_pre_init();
+  call_host_override_pre_init();
   cancel_after_accept_pre_init();
   cancel_after_accept_pre_init();
   cancel_after_client_done_pre_init();
   cancel_after_client_done_pre_init();
   cancel_after_invoke_pre_init();
   cancel_after_invoke_pre_init();
@@ -274,6 +277,7 @@ void grpc_end2end_tests(int argc, char **argv,
     bad_ping(config);
     bad_ping(config);
     binary_metadata(config);
     binary_metadata(config);
     call_creds(config);
     call_creds(config);
+    call_host_override(config);
     cancel_after_accept(config);
     cancel_after_accept(config);
     cancel_after_client_done(config);
     cancel_after_client_done(config);
     cancel_after_invoke(config);
     cancel_after_invoke(config);
@@ -368,6 +372,10 @@ void grpc_end2end_tests(int argc, char **argv,
       call_creds(config);
       call_creds(config);
       continue;
       continue;
     }
     }
+    if (0 == strcmp("call_host_override", argv[i])) {
+      call_host_override(config);
+      continue;
+    }
     if (0 == strcmp("cancel_after_accept", argv[i])) {
     if (0 == strcmp("cancel_after_accept", argv[i])) {
       cancel_after_accept(config);
       cancel_after_accept(config);
       continue;
       continue;

+ 1 - 4
test/core/end2end/fixtures/h2_ssl.cc

@@ -109,10 +109,7 @@ static void chttp2_init_client_simple_ssl_secure_fullstack(
   grpc_channel_args* new_client_args =
   grpc_channel_args* new_client_args =
       grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
       grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
   chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);
   chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);
-  {
-    grpc_core::ExecCtx exec_ctx;
-    grpc_channel_args_destroy(new_client_args);
-  }
+  grpc_channel_args_destroy(new_client_args);
 }
 }
 
 
 static int fail_server_auth_check(grpc_channel_args* server_args) {
 static int fail_server_auth_check(grpc_channel_args* server_args) {

+ 2 - 0
test/core/end2end/gen_build_yaml.py

@@ -108,6 +108,8 @@ END2END_TESTS = {
         proxyable=False, cpu_cost=LOWCPU, exclude_iomgrs=['uv']),
         proxyable=False, cpu_cost=LOWCPU, exclude_iomgrs=['uv']),
     'default_host': default_test_options._replace(
     'default_host': default_test_options._replace(
         needs_fullstack=True, needs_dns=True, needs_names=True),
         needs_fullstack=True, needs_dns=True, needs_names=True),
+    'call_host_override': default_test_options._replace(
+        needs_fullstack=True, needs_dns=True, needs_names=True),
     'disappearing_server': connectivity_test_options._replace(flaky=True,
     'disappearing_server': connectivity_test_options._replace(flaky=True,
                                                               needs_names=True),
                                                               needs_names=True),
     'empty_batch': default_test_options._replace(cpu_cost=LOWCPU),
     'empty_batch': default_test_options._replace(cpu_cost=LOWCPU),

+ 230 - 0
test/core/end2end/tests/call_host_override.cc

@@ -0,0 +1,230 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "test/core/end2end/cq_verifier.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+                                            const char* test_name,
+                                            grpc_channel_args* client_args,
+                                            grpc_channel_args* server_args) {
+  grpc_end2end_test_fixture f;
+  gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+  f = config.create_fixture(client_args, server_args);
+  grpc_arg fake_security_name_override = {
+      GRPC_ARG_STRING,
+      const_cast<char*>(GRPC_FAKE_SECURITY_TARGET_NAME_OVERRIDE_ARG),
+      {const_cast<char*>("foo.test.google.fr:1234")}};
+  grpc_channel_args* new_client_args = grpc_channel_args_copy_and_add(
+      client_args, &fake_security_name_override, 1);
+  config.init_client(&f, new_client_args);
+  grpc_channel_args_destroy(new_client_args);
+  config.init_server(&f, server_args);
+  return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+  return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+  return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+  grpc_event ev;
+  do {
+    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+  if (!f->server) return;
+  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+                                         grpc_timeout_seconds_to_deadline(5),
+                                         nullptr)
+                 .type == GRPC_OP_COMPLETE);
+  grpc_server_destroy(f->server);
+  f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+  if (!f->client) return;
+  grpc_channel_destroy(f->client);
+  f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+  shutdown_server(f);
+  shutdown_client(f);
+
+  grpc_completion_queue_shutdown(f->cq);
+  drain_cq(f->cq);
+  grpc_completion_queue_destroy(f->cq);
+  grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+static void test_invoke_simple_request(grpc_end2end_test_config config) {
+  grpc_end2end_test_fixture f =
+      begin_test(config, "test_invoke_simple_request", nullptr, nullptr);
+  grpc_call* c;
+  grpc_call* s;
+  cq_verifier* cqv = cq_verifier_create(f.cq);
+  grpc_op ops[6];
+  grpc_op* op;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_metadata_array request_metadata_recv;
+  grpc_call_details call_details;
+  grpc_status_code status;
+  grpc_call_error error;
+  grpc_slice details;
+  int was_cancelled = 2;
+  char* peer;
+
+  gpr_timespec deadline = five_seconds_from_now();
+  c = grpc_channel_create_call(
+      f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+      grpc_slice_from_static_string("/foo"),
+      get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+      nullptr);
+  GPR_ASSERT(c);
+
+  peer = grpc_call_get_peer(c);
+  GPR_ASSERT(peer != nullptr);
+  gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+  gpr_free(peer);
+
+  grpc_metadata_array_init(&initial_metadata_recv);
+  grpc_metadata_array_init(&trailing_metadata_recv);
+  grpc_metadata_array_init(&request_metadata_recv);
+  grpc_call_details_init(&call_details);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->flags = 0;
+  op->reserved = nullptr;
+  op++;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = nullptr;
+  op++;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = nullptr;
+  op++;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &status;
+  op->data.recv_status_on_client.status_details = &details;
+  op->flags = 0;
+  op->reserved = nullptr;
+  op++;
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
+  GPR_ASSERT(error == GRPC_CALL_OK);
+
+  error =
+      grpc_server_request_call(f.server, &s, &call_details,
+                               &request_metadata_recv, f.cq, f.cq, tag(101));
+  GPR_ASSERT(error == GRPC_CALL_OK);
+  CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
+  cq_verify(cqv);
+
+  peer = grpc_call_get_peer(s);
+  GPR_ASSERT(peer != nullptr);
+  gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+  gpr_free(peer);
+  peer = grpc_call_get_peer(c);
+  GPR_ASSERT(peer != nullptr);
+  gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+  gpr_free(peer);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->flags = 0;
+  op->reserved = nullptr;
+  op++;
+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  op->data.send_status_from_server.trailing_metadata_count = 0;
+  op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+  grpc_slice status_details = grpc_slice_from_static_string("xyz");
+  op->data.send_status_from_server.status_details = &status_details;
+  op->flags = 0;
+  op->reserved = nullptr;
+  op++;
+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  op->data.recv_close_on_server.cancelled = &was_cancelled;
+  op->flags = 0;
+  op->reserved = nullptr;
+  op++;
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
+  GPR_ASSERT(error == GRPC_CALL_OK);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
+  CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
+  cq_verify(cqv);
+
+  GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
+  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+  GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+  validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+                                config);
+  GPR_ASSERT(was_cancelled == 1);
+
+  grpc_slice_unref(details);
+  grpc_metadata_array_destroy(&initial_metadata_recv);
+  grpc_metadata_array_destroy(&trailing_metadata_recv);
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+
+  grpc_call_unref(c);
+  grpc_call_unref(s);
+
+  cq_verifier_destroy(cqv);
+
+  end_test(&f);
+  config.tear_down_data(&f);
+}
+
+void call_host_override(grpc_end2end_test_config config) {
+  test_invoke_simple_request(config);
+}
+
+void call_host_override_pre_init(void) {}

+ 2 - 0
tools/run_tests/generated/sources_and_headers.json

@@ -8452,6 +8452,7 @@
       "test/core/end2end/tests/bad_ping.cc", 
       "test/core/end2end/tests/bad_ping.cc", 
       "test/core/end2end/tests/binary_metadata.cc", 
       "test/core/end2end/tests/binary_metadata.cc", 
       "test/core/end2end/tests/call_creds.cc", 
       "test/core/end2end/tests/call_creds.cc", 
+      "test/core/end2end/tests/call_host_override.cc", 
       "test/core/end2end/tests/cancel_after_accept.cc", 
       "test/core/end2end/tests/cancel_after_accept.cc", 
       "test/core/end2end/tests/cancel_after_client_done.cc", 
       "test/core/end2end/tests/cancel_after_client_done.cc", 
       "test/core/end2end/tests/cancel_after_invoke.cc", 
       "test/core/end2end/tests/cancel_after_invoke.cc", 
@@ -8549,6 +8550,7 @@
       "test/core/end2end/tests/bad_hostname.cc", 
       "test/core/end2end/tests/bad_hostname.cc", 
       "test/core/end2end/tests/bad_ping.cc", 
       "test/core/end2end/tests/bad_ping.cc", 
       "test/core/end2end/tests/binary_metadata.cc", 
       "test/core/end2end/tests/binary_metadata.cc", 
+      "test/core/end2end/tests/call_host_override.cc", 
       "test/core/end2end/tests/cancel_after_accept.cc", 
       "test/core/end2end/tests/cancel_after_accept.cc", 
       "test/core/end2end/tests/cancel_after_client_done.cc", 
       "test/core/end2end/tests/cancel_after_client_done.cc", 
       "test/core/end2end/tests/cancel_after_invoke.cc", 
       "test/core/end2end/tests/cancel_after_invoke.cc", 

+ 503 - 0
tools/run_tests/generated/tests.json

@@ -6899,6 +6899,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -8605,6 +8628,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -10283,6 +10329,28 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fakesec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -13116,6 +13184,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -14802,6 +14893,25 @@
       "linux"
       "linux"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -16228,6 +16338,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -17888,6 +18021,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+workarounds_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -19599,6 +19755,30 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -21394,6 +21574,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -23105,6 +23308,30 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_oauth2_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -24857,6 +25084,30 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -29778,6 +30029,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -31465,6 +31739,30 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -35235,6 +35533,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -36918,6 +37239,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -39751,6 +40095,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -41418,6 +41785,25 @@
       "linux"
       "linux"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -42821,6 +43207,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -44458,6 +44867,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+workarounds_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -46145,6 +46577,30 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_http_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -47917,6 +48373,29 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"
@@ -49580,6 +50059,30 @@
       "posix"
       "posix"
     ]
     ]
   }, 
   }, 
+  {
+    "args": [
+      "call_host_override"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
   {
   {
     "args": [
     "args": [
       "cancel_after_accept"
       "cancel_after_accept"