diff --git a/BUILD b/BUILD
index 9f1ab2a5384a09bb0effd22da8b11812d7efb25d..083639c856bf7dade8a465d801c7598467cf38a8 100644
--- a/BUILD
+++ b/BUILD
@@ -1404,12 +1404,14 @@ grpc_cc_library(
     name = "tsi",
     srcs = [
         "src/core/tsi/fake_transport_security.c",
+        "src/core/tsi/gts_transport_security.c",
         "src/core/tsi/ssl_transport_security.c",
         "src/core/tsi/transport_security.c",
         "src/core/tsi/transport_security_adapter.c",
     ],
     hdrs = [
         "src/core/tsi/fake_transport_security.h",
+        "src/core/tsi/gts_transport_security.h",
         "src/core/tsi/ssl_transport_security.h",
         "src/core/tsi/ssl_types.h",
         "src/core/tsi/transport_security.h",
@@ -1422,6 +1424,7 @@ grpc_cc_library(
     language = "c",
     deps = [
         "gpr",
+        "grpc_base",
         "grpc_trace",
     ],
 )
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5413bbcc0f3719088d991149f0f2dd72119ffc5c..0f87beb02b9235322bd91bb4f5d25c910486fd27 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -751,6 +751,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 add_dependencies(buildtests_cxx server_crash_test)
 endif()
 add_dependencies(buildtests_cxx server_crash_test_client)
+add_dependencies(buildtests_cxx server_request_call_test)
 add_dependencies(buildtests_cxx shutdown_test)
 add_dependencies(buildtests_cxx status_test)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@@ -1124,6 +1125,7 @@ add_library(grpc
   src/core/lib/security/util/json_util.c
   src/core/lib/surface/init_secure.c
   src/core/tsi/fake_transport_security.c
+  src/core/tsi/gts_transport_security.c
   src/core/tsi/ssl_transport_security.c
   src/core/tsi/transport_security.c
   src/core/tsi/transport_security_adapter.c
@@ -1490,6 +1492,7 @@ add_library(grpc_cronet
   src/core/lib/security/util/json_util.c
   src/core/lib/surface/init_secure.c
   src/core/tsi/fake_transport_security.c
+  src/core/tsi/gts_transport_security.c
   src/core/tsi/ssl_transport_security.c
   src/core/tsi/transport_security.c
   src/core/tsi/transport_security_adapter.c
@@ -12033,6 +12036,62 @@ target_link_libraries(server_crash_test_client
 endif (gRPC_BUILD_TESTS)
 if (gRPC_BUILD_TESTS)
 
+add_executable(server_request_call_test
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h
+  test/cpp/server/server_request_call_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/echo_messages.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/echo.proto
+)
+
+target_include_directories(server_request_call_test
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${BENCHMARK_ROOT_DIR}/include
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+  PRIVATE ${CARES_BUILD_INCLUDE_DIR}
+  PRIVATE ${CARES_INCLUDE_DIR}
+  PRIVATE ${CARES_PLATFORM_INCLUDE_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+  PRIVATE third_party/googletest/googletest/include
+  PRIVATE third_party/googletest/googletest
+  PRIVATE third_party/googletest/googlemock/include
+  PRIVATE third_party/googletest/googlemock
+  PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(server_request_call_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc++_test_util
+  grpc_test_util
+  gpr_test_util
+  grpc++
+  grpc
+  gpr
+  ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
 add_executable(shutdown_test
   test/cpp/end2end/shutdown_test.cc
   third_party/googletest/googletest/src/gtest-all.cc
diff --git a/Makefile b/Makefile
index 210d6768222e15a49cc11057135ac164e322a2f0..2ae022971654bb7528b099a6099dacfee67aa704 100644
--- a/Makefile
+++ b/Makefile
@@ -1167,6 +1167,7 @@ server_builder_test: $(BINDIR)/$(CONFIG)/server_builder_test
 server_context_test_spouse_test: $(BINDIR)/$(CONFIG)/server_context_test_spouse_test
 server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test
 server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
+server_request_call_test: $(BINDIR)/$(CONFIG)/server_request_call_test
 shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test
 status_test: $(BINDIR)/$(CONFIG)/status_test
 streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test
@@ -1595,6 +1596,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
   $(BINDIR)/$(CONFIG)/server_crash_test \
   $(BINDIR)/$(CONFIG)/server_crash_test_client \
+  $(BINDIR)/$(CONFIG)/server_request_call_test \
   $(BINDIR)/$(CONFIG)/shutdown_test \
   $(BINDIR)/$(CONFIG)/status_test \
   $(BINDIR)/$(CONFIG)/streaming_throughput_test \
@@ -1709,6 +1711,7 @@ buildtests_cxx: privatelibs_cxx \
   $(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
   $(BINDIR)/$(CONFIG)/server_crash_test \
   $(BINDIR)/$(CONFIG)/server_crash_test_client \
+  $(BINDIR)/$(CONFIG)/server_request_call_test \
   $(BINDIR)/$(CONFIG)/shutdown_test \
   $(BINDIR)/$(CONFIG)/status_test \
   $(BINDIR)/$(CONFIG)/streaming_throughput_test \
@@ -2103,6 +2106,8 @@ test_cxx: buildtests_cxx
 	$(Q) $(BINDIR)/$(CONFIG)/server_context_test_spouse_test || ( echo test server_context_test_spouse_test failed ; exit 1 )
 	$(E) "[RUN]     Testing server_crash_test"
 	$(Q) $(BINDIR)/$(CONFIG)/server_crash_test || ( echo test server_crash_test failed ; exit 1 )
+	$(E) "[RUN]     Testing server_request_call_test"
+	$(Q) $(BINDIR)/$(CONFIG)/server_request_call_test || ( echo test server_request_call_test failed ; exit 1 )
 	$(E) "[RUN]     Testing shutdown_test"
 	$(Q) $(BINDIR)/$(CONFIG)/shutdown_test || ( echo test shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing status_test"
@@ -3064,6 +3069,7 @@ LIBGRPC_SRC = \
     src/core/lib/security/util/json_util.c \
     src/core/lib/surface/init_secure.c \
     src/core/tsi/fake_transport_security.c \
+    src/core/tsi/gts_transport_security.c \
     src/core/tsi/ssl_transport_security.c \
     src/core/tsi/transport_security.c \
     src/core/tsi/transport_security_adapter.c \
@@ -3428,6 +3434,7 @@ LIBGRPC_CRONET_SRC = \
     src/core/lib/security/util/json_util.c \
     src/core/lib/surface/init_secure.c \
     src/core/tsi/fake_transport_security.c \
+    src/core/tsi/gts_transport_security.c \
     src/core/tsi/ssl_transport_security.c \
     src/core/tsi/transport_security.c \
     src/core/tsi/transport_security_adapter.c \
@@ -16010,6 +16017,56 @@ endif
 endif
 
 
+SERVER_REQUEST_CALL_TEST_SRC = \
+    $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
+    test/cpp/server/server_request_call_test.cc \
+
+SERVER_REQUEST_CALL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_REQUEST_CALL_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/server_request_call_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/server_request_call_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/server_request_call_test: $(PROTOBUF_DEP) $(SERVER_REQUEST_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(SERVER_REQUEST_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_request_call_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_server_request_call_test: $(SERVER_REQUEST_CALL_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(SERVER_REQUEST_CALL_TEST_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_test.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc
+
+
 SHUTDOWN_TEST_SRC = \
     test/cpp/end2end/shutdown_test.cc \
 
@@ -19174,6 +19231,7 @@ src/core/lib/surface/init_secure.c: $(OPENSSL_DEP)
 src/core/plugin_registry/grpc_cronet_plugin_registry.c: $(OPENSSL_DEP)
 src/core/plugin_registry/grpc_plugin_registry.c: $(OPENSSL_DEP)
 src/core/tsi/fake_transport_security.c: $(OPENSSL_DEP)
+src/core/tsi/gts_transport_security.c: $(OPENSSL_DEP)
 src/core/tsi/ssl_transport_security.c: $(OPENSSL_DEP)
 src/core/tsi/transport_security.c: $(OPENSSL_DEP)
 src/core/tsi/transport_security_adapter.c: $(OPENSSL_DEP)
diff --git a/binding.gyp b/binding.gyp
index ae78d931f2d884404bf49e491932bb9a9d06879b..d11a60a68afb3c629aa4c7bd707d6f8d6e61d368 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -814,6 +814,7 @@
         'src/core/lib/security/util/json_util.c',
         'src/core/lib/surface/init_secure.c',
         'src/core/tsi/fake_transport_security.c',
+        'src/core/tsi/gts_transport_security.c',
         'src/core/tsi/ssl_transport_security.c',
         'src/core/tsi/transport_security.c',
         'src/core/tsi/transport_security_adapter.c',
diff --git a/build.yaml b/build.yaml
index 1aa5c4e2d313615a2c8da4b44f9b34183996c36d..57608c60798a835916d3aed5cc5f3beee5fd696f 100644
--- a/build.yaml
+++ b/build.yaml
@@ -876,6 +876,7 @@ filegroups:
 - name: tsi
   headers:
   - src/core/tsi/fake_transport_security.h
+  - src/core/tsi/gts_transport_security.h
   - src/core/tsi/ssl_transport_security.h
   - src/core/tsi/ssl_types.h
   - src/core/tsi/transport_security.h
@@ -883,14 +884,17 @@ filegroups:
   - src/core/tsi/transport_security_interface.h
   src:
   - src/core/tsi/fake_transport_security.c
+  - src/core/tsi/gts_transport_security.c
   - src/core/tsi/ssl_transport_security.c
   - src/core/tsi/transport_security.c
   - src/core/tsi/transport_security_adapter.c
   deps:
   - gpr
+  plugin: grpc_tsi_gts
   secure: true
   uses:
   - grpc_trace
+  - grpc_base
 - name: grpc++_base
   language: c++
   public_headers:
@@ -4382,6 +4386,21 @@ targets:
   - grpc
   - gpr_test_util
   - gpr
+- name: server_request_call_test
+  gtest: true
+  build: test
+  language: c++
+  src:
+  - src/proto/grpc/testing/echo_messages.proto
+  - src/proto/grpc/testing/echo.proto
+  - test/cpp/server/server_request_call_test.cc
+  deps:
+  - grpc++_test_util
+  - grpc_test_util
+  - gpr_test_util
+  - grpc++
+  - grpc
+  - gpr
 - name: shutdown_test
   gtest: true
   build: test
diff --git a/config.m4 b/config.m4
index e214f9c5464eb63a2b84f67583b07a7b11d52462..f97baadde4d04acc8400b5e4cc76f6ec1847f296 100644
--- a/config.m4
+++ b/config.m4
@@ -264,6 +264,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/security/util/json_util.c \
     src/core/lib/surface/init_secure.c \
     src/core/tsi/fake_transport_security.c \
+    src/core/tsi/gts_transport_security.c \
     src/core/tsi/ssl_transport_security.c \
     src/core/tsi/transport_security.c \
     src/core/tsi/transport_security_adapter.c \
diff --git a/config.w32 b/config.w32
index 6d50712fb543144bcc1dde293ed166e9d7dd573e..c00f3f953d4569ca1570d756ed2f955da72b2c21 100644
--- a/config.w32
+++ b/config.w32
@@ -241,6 +241,7 @@ if (PHP_GRPC != "no") {
     "src\\core\\lib\\security\\util\\json_util.c " +
     "src\\core\\lib\\surface\\init_secure.c " +
     "src\\core\\tsi\\fake_transport_security.c " +
+    "src\\core\\tsi\\gts_transport_security.c " +
     "src\\core\\tsi\\ssl_transport_security.c " +
     "src\\core\\tsi\\transport_security.c " +
     "src\\core\\tsi\\transport_security_adapter.c " +
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index cf3fc3598a28bf9b5c1f318b3b97277542c3910f..57b6f92d1e0cb4f7ce9f9e8325241879295434f3 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -398,6 +398,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/security/transport/tsi_error.h',
                       'src/core/lib/security/util/json_util.h',
                       'src/core/tsi/fake_transport_security.h',
+                      'src/core/tsi/gts_transport_security.h',
                       'src/core/tsi/ssl_transport_security.h',
                       'src/core/tsi/ssl_types.h',
                       'src/core/tsi/transport_security.h',
@@ -637,6 +638,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/security/util/json_util.c',
                       'src/core/lib/surface/init_secure.c',
                       'src/core/tsi/fake_transport_security.c',
+                      'src/core/tsi/gts_transport_security.c',
                       'src/core/tsi/ssl_transport_security.c',
                       'src/core/tsi/transport_security.c',
                       'src/core/tsi/transport_security_adapter.c',
@@ -880,6 +882,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/security/transport/tsi_error.h',
                               'src/core/lib/security/util/json_util.h',
                               'src/core/tsi/fake_transport_security.h',
+                              'src/core/tsi/gts_transport_security.h',
                               'src/core/tsi/ssl_transport_security.h',
                               'src/core/tsi/ssl_types.h',
                               'src/core/tsi/transport_security.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index a87c113b04b17a4be8bac0139f92db69fe4c2dc3..dedee020b7d2be0d5b84f5842ef6be67888bf44c 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -330,6 +330,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/security/transport/tsi_error.h )
   s.files += %w( src/core/lib/security/util/json_util.h )
   s.files += %w( src/core/tsi/fake_transport_security.h )
+  s.files += %w( src/core/tsi/gts_transport_security.h )
   s.files += %w( src/core/tsi/ssl_transport_security.h )
   s.files += %w( src/core/tsi/ssl_types.h )
   s.files += %w( src/core/tsi/transport_security.h )
@@ -573,6 +574,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/security/util/json_util.c )
   s.files += %w( src/core/lib/surface/init_secure.c )
   s.files += %w( src/core/tsi/fake_transport_security.c )
+  s.files += %w( src/core/tsi/gts_transport_security.c )
   s.files += %w( src/core/tsi/ssl_transport_security.c )
   s.files += %w( src/core/tsi/transport_security.c )
   s.files += %w( src/core/tsi/transport_security_adapter.c )
diff --git a/include/grpc++/impl/codegen/core_codegen.h b/include/grpc++/impl/codegen/core_codegen.h
index 504c79cff94345587b33fd78c1de20d7ecad648e..2b15a018455bae4fbd09df77d4af73a47dde958f 100644
--- a/include/grpc++/impl/codegen/core_codegen.h
+++ b/include/grpc++/impl/codegen/core_codegen.h
@@ -60,6 +60,10 @@ class CoreCodegen final : public CoreCodegenInterface {
   void gpr_cv_signal(gpr_cv* cv) override;
   void gpr_cv_broadcast(gpr_cv* cv) override;
 
+  grpc_call_error grpc_call_cancel_with_status(grpc_call* call,
+                                               grpc_status_code status,
+                                               const char* description,
+                                               void* reserved) override;
   void grpc_call_ref(grpc_call* call) override;
   void grpc_call_unref(grpc_call* call) override;
   virtual void* grpc_call_arena_alloc(grpc_call* call, size_t length) override;
diff --git a/include/grpc++/impl/codegen/core_codegen_interface.h b/include/grpc++/impl/codegen/core_codegen_interface.h
index 930b116ddac5f56b01351ce49f85a108fb47b457..b4c771ac93aa860ccf21e6e84b9780b7a1bfc6db 100644
--- a/include/grpc++/impl/codegen/core_codegen_interface.h
+++ b/include/grpc++/impl/codegen/core_codegen_interface.h
@@ -89,6 +89,10 @@ class CoreCodegenInterface {
   virtual grpc_slice grpc_slice_new_with_user_data(void* p, size_t len,
                                                    void (*destroy)(void*),
                                                    void* user_data) = 0;
+  virtual grpc_call_error grpc_call_cancel_with_status(grpc_call* call,
+                                                       grpc_status_code status,
+                                                       const char* description,
+                                                       void* reserved) = 0;
   virtual void grpc_call_ref(grpc_call* call) = 0;
   virtual void grpc_call_unref(grpc_call* call) = 0;
   virtual void* grpc_call_arena_alloc(grpc_call* call, size_t length) = 0;
diff --git a/include/grpc++/impl/codegen/server_interface.h b/include/grpc++/impl/codegen/server_interface.h
index cc9bf0a108c26f2cd5295554491e53519fbcdf3d..3bcf4c87e7cd7a86195c338b1d023dc9e66af934 100644
--- a/include/grpc++/impl/codegen/server_interface.h
+++ b/include/grpc++/impl/codegen/server_interface.h
@@ -177,22 +177,49 @@ class ServerInterface : public internal::CallHook {
                         ServerCompletionQueue* notification_cq, void* tag,
                         Message* request)
         : RegisteredAsyncRequest(server, context, stream, call_cq, tag),
+          registered_method_(registered_method),
+          server_(server),
+          context_(context),
+          stream_(stream),
+          call_cq_(call_cq),
+          notification_cq_(notification_cq),
+          tag_(tag),
           request_(request) {
       IssueRequest(registered_method, &payload_, notification_cq);
     }
 
     bool FinalizeResult(void** tag, bool* status) override {
-      bool serialization_status =
-          *status && payload_ &&
-          SerializationTraits<Message>::Deserialize(payload_, request_).ok();
-      bool ret = RegisteredAsyncRequest::FinalizeResult(tag, status);
-      *status = serialization_status && *status;
-      return ret;
+      if (*status) {
+        if (payload_ == nullptr ||
+            !SerializationTraits<Message>::Deserialize(payload_, request_)
+                 .ok()) {
+          // If deserialization fails, we cancel the call and instantiate
+          // a new instance of ourselves to request another call.  We then
+          // return false, which prevents the call from being returned to
+          // the application.
+          g_core_codegen_interface->grpc_call_cancel_with_status(
+              call_, GRPC_STATUS_INTERNAL, "Unable to parse request", nullptr);
+          g_core_codegen_interface->grpc_call_unref(call_);
+          new PayloadAsyncRequest(registered_method_, server_, context_,
+                                  stream_, call_cq_, notification_cq_, tag_,
+                                  request_);
+          delete this;
+          return false;
+        }
+      }
+      return RegisteredAsyncRequest::FinalizeResult(tag, status);
     }
 
    private:
-    grpc_byte_buffer* payload_;
+    void* const registered_method_;
+    ServerInterface* const server_;
+    ServerContext* const context_;
+    internal::ServerAsyncStreamingInterface* const stream_;
+    CompletionQueue* const call_cq_;
+    ServerCompletionQueue* const notification_cq_;
+    void* const tag_;
     Message* const request_;
+    grpc_byte_buffer* payload_;
   };
 
   class GenericAsyncRequest : public BaseAsyncRequest {
diff --git a/include/grpc++/support/slice.h b/include/grpc++/support/slice.h
index db5cf942a0c9e64655b3570ad5722178425043f2..0b4ba7cecb4f780b931905c09ae56595dd101d9b 100644
--- a/include/grpc++/support/slice.h
+++ b/include/grpc++/support/slice.h
@@ -44,6 +44,20 @@ class Slice final {
   /// Construct a slice from \a slice, stealing a reference.
   Slice(grpc_slice slice, StealRef);
 
+  /// Allocate a slice of specified size
+  Slice(size_t len);
+
+  /// Construct a slice from a copied buffer
+  Slice(const void* buf, size_t len);
+
+  /// Construct a slice from a copied string
+  Slice(const grpc::string& str);
+
+  enum StaticSlice { STATIC_SLICE };
+
+  /// Construct a slice from a static buffer
+  Slice(const void* buf, size_t len, StaticSlice);
+
   /// Copy constructor, adds a reference.
   Slice(const Slice& other);
 
diff --git a/package.xml b/package.xml
index 256a21d017bd6a0a9e834cbc67f937244e362fd6..38f51424e6a654425cdd9a3330560850ae215999 100644
--- a/package.xml
+++ b/package.xml
@@ -344,6 +344,7 @@
     <file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/util/json_util.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.h" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/gts_transport_security.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl_transport_security.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl_types.h" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/transport_security.h" role="src" />
@@ -587,6 +588,7 @@
     <file baseinstalldir="/" name="src/core/lib/security/util/json_util.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/surface/init_secure.c" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.c" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/gts_transport_security.c" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/ssl_transport_security.c" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/transport_security.c" role="src" />
     <file baseinstalldir="/" name="src/core/tsi/transport_security_adapter.c" role="src" />
diff --git a/src/core/ext/filters/client_channel/http_proxy.c b/src/core/ext/filters/client_channel/http_proxy.c
index cfb5ec6f00eed71ca66cf103b1ff237480adc438..aa3f61c99171c57b848e3ef5400c6004c203ed5d 100644
--- a/src/core/ext/filters/client_channel/http_proxy.c
+++ b/src/core/ext/filters/client_channel/http_proxy.c
@@ -22,6 +22,7 @@
 #include <string.h>
 
 #include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
@@ -30,6 +31,7 @@
 #include "src/core/ext/filters/client_channel/uri_parser.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/support/env.h"
+#include "src/core/lib/support/string.h"
 
 static char* grpc_get_http_proxy_server(grpc_exec_ctx* exec_ctx) {
   char* uri_str = gpr_getenv("http_proxy");
@@ -80,6 +82,50 @@ static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
     grpc_uri_destroy(uri);
     return false;
   }
+  char* no_proxy_str = gpr_getenv("no_proxy");
+  if (no_proxy_str != NULL) {
+    static const char* NO_PROXY_SEPARATOR = ",";
+    bool use_proxy = true;
+    char* server_host;
+    char* server_port;
+    if (!gpr_split_host_port(uri->path[0] == '/' ? uri->path + 1 : uri->path,
+                             &server_host, &server_port)) {
+      gpr_log(GPR_INFO,
+              "unable to split host and port, not checking no_proxy list for "
+              "host '%s'",
+              server_uri);
+    } else {
+      size_t uri_len = strlen(server_host);
+      char** no_proxy_hosts;
+      size_t num_no_proxy_hosts;
+      gpr_string_split(no_proxy_str, NO_PROXY_SEPARATOR, &no_proxy_hosts,
+                       &num_no_proxy_hosts);
+      for (size_t i = 0; i < num_no_proxy_hosts; i++) {
+        char* no_proxy_entry = no_proxy_hosts[i];
+        size_t no_proxy_len = strlen(no_proxy_entry);
+        if (no_proxy_len <= uri_len &&
+            gpr_stricmp(no_proxy_entry, &server_host[uri_len - no_proxy_len]) ==
+                0) {
+          gpr_log(GPR_INFO, "not using proxy for host in no_proxy list '%s'",
+                  server_uri);
+          use_proxy = false;
+          break;
+        }
+      }
+      for (size_t i = 0; i < num_no_proxy_hosts; i++) {
+        gpr_free(no_proxy_hosts[i]);
+      }
+      gpr_free(no_proxy_hosts);
+      gpr_free(server_host);
+      gpr_free(server_port);
+      if (!use_proxy) {
+        grpc_uri_destroy(uri);
+        gpr_free(*name_to_resolve);
+        *name_to_resolve = NULL;
+        return false;
+      }
+    }
+  }
   grpc_arg new_arg = grpc_channel_arg_string_create(
       GRPC_ARG_HTTP_CONNECT_SERVER,
       uri->path[0] == '/' ? uri->path + 1 : uri->path);
diff --git a/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.c b/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.c
index 3c03f79ce0833b91545f2b37c9cf34ae2446c7fb..5166dc2ac2ed2f7f8d352a5b0e8ca4db0be6ebfd 100644
--- a/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.c
@@ -932,24 +932,12 @@ static int fd_wrapped_fd(grpc_fd *fd) {
 static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
                       grpc_closure *on_done, int *release_fd,
                       const char *reason) {
-  bool is_fd_closed = false;
   grpc_error *error = GRPC_ERROR_NONE;
   polling_island *unref_pi = NULL;
 
   gpr_mu_lock(&fd->po.mu);
   fd->on_done_closure = on_done;
 
-  /* If release_fd is not NULL, we should be relinquishing control of the file
-     descriptor fd->fd (but we still own the grpc_fd structure). */
-  if (release_fd != NULL) {
-    *release_fd = fd->fd;
-  } else {
-    close(fd->fd);
-    is_fd_closed = true;
-  }
-
-  fd->orphaned = true;
-
   /* Remove the active status but keep referenced. We want this grpc_fd struct
      to be alive (and not added to freelist) until the end of this function */
   REF_BY(fd, 1, reason);
@@ -964,13 +952,24 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
        before doing this.) */
   if (fd->po.pi != NULL) {
     polling_island *pi_latest = polling_island_lock(fd->po.pi);
-    polling_island_remove_fd_locked(pi_latest, fd, is_fd_closed, &error);
+    polling_island_remove_fd_locked(pi_latest, fd, false /* is_fd_closed */,
+                                    &error);
     gpr_mu_unlock(&pi_latest->mu);
 
     unref_pi = fd->po.pi;
     fd->po.pi = NULL;
   }
 
+  /* If release_fd is not NULL, we should be relinquishing control of the file
+     descriptor fd->fd (but we still own the grpc_fd structure). */
+  if (release_fd != NULL) {
+    *release_fd = fd->fd;
+  } else {
+    close(fd->fd);
+  }
+
+  fd->orphaned = true;
+
   GRPC_CLOSURE_SCHED(exec_ctx, fd->on_done_closure, GRPC_ERROR_REF(error));
 
   gpr_mu_unlock(&fd->po.mu);
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.c b/src/core/lib/iomgr/ev_epollsig_linux.c
index 4030f8f135a144c1b546abcfa4f4c251fce380ac..a84c208e1a75ba785266fd0c506360ccbb98bc7b 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.c
+++ b/src/core/lib/iomgr/ev_epollsig_linux.c
@@ -855,24 +855,12 @@ static int fd_wrapped_fd(grpc_fd *fd) {
 static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
                       grpc_closure *on_done, int *release_fd,
                       const char *reason) {
-  bool is_fd_closed = false;
   grpc_error *error = GRPC_ERROR_NONE;
   polling_island *unref_pi = NULL;
 
   gpr_mu_lock(&fd->po.mu);
   fd->on_done_closure = on_done;
 
-  /* If release_fd is not NULL, we should be relinquishing control of the file
-     descriptor fd->fd (but we still own the grpc_fd structure). */
-  if (release_fd != NULL) {
-    *release_fd = fd->fd;
-  } else {
-    close(fd->fd);
-    is_fd_closed = true;
-  }
-
-  fd->orphaned = true;
-
   /* Remove the active status but keep referenced. We want this grpc_fd struct
      to be alive (and not added to freelist) until the end of this function */
   REF_BY(fd, 1, reason);
@@ -887,13 +875,24 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
        before doing this.) */
   if (fd->po.pi != NULL) {
     polling_island *pi_latest = polling_island_lock(fd->po.pi);
-    polling_island_remove_fd_locked(pi_latest, fd, is_fd_closed, &error);
+    polling_island_remove_fd_locked(pi_latest, fd, false /* is_fd_closed */,
+                                    &error);
     gpr_mu_unlock(&pi_latest->mu);
 
     unref_pi = fd->po.pi;
     fd->po.pi = NULL;
   }
 
+  /* If release_fd is not NULL, we should be relinquishing control of the file
+     descriptor fd->fd (but we still own the grpc_fd structure). */
+  if (release_fd != NULL) {
+    *release_fd = fd->fd;
+  } else {
+    close(fd->fd);
+  }
+
+  fd->orphaned = true;
+
   GRPC_CLOSURE_SCHED(exec_ctx, fd->on_done_closure, GRPC_ERROR_REF(error));
 
   gpr_mu_unlock(&fd->po.mu);
diff --git a/src/core/plugin_registry/grpc_cronet_plugin_registry.c b/src/core/plugin_registry/grpc_cronet_plugin_registry.c
index b468c03aa3428db5522fb0ca50d9a74555809962..322ebea1115729e53e68d26bcfb7e215d7bf6286 100644
--- a/src/core/plugin_registry/grpc_cronet_plugin_registry.c
+++ b/src/core/plugin_registry/grpc_cronet_plugin_registry.c
@@ -26,6 +26,8 @@ extern void grpc_deadline_filter_init(void);
 extern void grpc_deadline_filter_shutdown(void);
 extern void grpc_client_channel_init(void);
 extern void grpc_client_channel_shutdown(void);
+extern void grpc_tsi_gts_init(void);
+extern void grpc_tsi_gts_shutdown(void);
 extern void grpc_load_reporting_plugin_init(void);
 extern void grpc_load_reporting_plugin_shutdown(void);
 
@@ -38,6 +40,8 @@ void grpc_register_built_in_plugins(void) {
                        grpc_deadline_filter_shutdown);
   grpc_register_plugin(grpc_client_channel_init,
                        grpc_client_channel_shutdown);
+  grpc_register_plugin(grpc_tsi_gts_init,
+                       grpc_tsi_gts_shutdown);
   grpc_register_plugin(grpc_load_reporting_plugin_init,
                        grpc_load_reporting_plugin_shutdown);
 }
diff --git a/src/core/plugin_registry/grpc_plugin_registry.c b/src/core/plugin_registry/grpc_plugin_registry.c
index b0d06a3f43a57fb9a7df2888670effe32dd2fefc..fa9974952c0d4e0c6068ce537fd2f8f78d74be9a 100644
--- a/src/core/plugin_registry/grpc_plugin_registry.c
+++ b/src/core/plugin_registry/grpc_plugin_registry.c
@@ -22,6 +22,8 @@ extern void grpc_http_filters_init(void);
 extern void grpc_http_filters_shutdown(void);
 extern void grpc_chttp2_plugin_init(void);
 extern void grpc_chttp2_plugin_shutdown(void);
+extern void grpc_tsi_gts_init(void);
+extern void grpc_tsi_gts_shutdown(void);
 extern void grpc_deadline_filter_init(void);
 extern void grpc_deadline_filter_shutdown(void);
 extern void grpc_client_channel_init(void);
@@ -58,6 +60,8 @@ void grpc_register_built_in_plugins(void) {
                        grpc_http_filters_shutdown);
   grpc_register_plugin(grpc_chttp2_plugin_init,
                        grpc_chttp2_plugin_shutdown);
+  grpc_register_plugin(grpc_tsi_gts_init,
+                       grpc_tsi_gts_shutdown);
   grpc_register_plugin(grpc_deadline_filter_init,
                        grpc_deadline_filter_shutdown);
   grpc_register_plugin(grpc_client_channel_init,
diff --git a/src/core/tsi/gts_transport_security.c b/src/core/tsi/gts_transport_security.c
new file mode 100644
index 0000000000000000000000000000000000000000..e2ac685e44134bb9d59bd5c6685185d4f96867b1
--- /dev/null
+++ b/src/core/tsi/gts_transport_security.c
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2017 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 "src/core/tsi/gts_transport_security.h"
+
+#include <string.h>
+
+static gts_shared_resource g_gts_resource;
+
+gts_shared_resource *gts_get_shared_resource(void) { return &g_gts_resource; }
+
+void grpc_tsi_gts_init() {
+  memset(&g_gts_resource, 0, sizeof(gts_shared_resource));
+  gpr_mu_init(&g_gts_resource.mu);
+}
+
+void grpc_tsi_gts_shutdown() {
+  gpr_mu_destroy(&g_gts_resource.mu);
+  if (g_gts_resource.cq == NULL) {
+    return;
+  }
+  grpc_completion_queue_destroy(g_gts_resource.cq);
+  grpc_channel_destroy(g_gts_resource.channel);
+  gpr_thd_join(g_gts_resource.thread_id);
+}
diff --git a/src/core/tsi/gts_transport_security.h b/src/core/tsi/gts_transport_security.h
new file mode 100644
index 0000000000000000000000000000000000000000..538e1030bc5a34d7a19e9b99faabe2db332448f3
--- /dev/null
+++ b/src/core/tsi/gts_transport_security.h
@@ -0,0 +1,37 @@
+/*
+ *
+ * Copyright 2017 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.
+ *
+ */
+
+#ifndef GRPC_CORE_TSI_GTS_TRANSPORT_SECURITY_H
+#define GRPC_CORE_TSI_GTS_TRANSPORT_SECURITY_H
+
+#include <grpc/grpc.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+
+typedef struct gts_shared_resource {
+  gpr_thd_id thread_id;
+  grpc_channel *channel;
+  grpc_completion_queue *cq;
+  gpr_mu mu;
+} gts_shared_resource;
+
+/* This method returns the address of gts_shared_resource object shared by all
+ *    TSI handshakes. */
+gts_shared_resource *gts_get_shared_resource(void);
+
+#endif /* GRPC_CORE_TSI_GTS_TRANSPORT_SECURITY_H */
diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc
index 71017407dea9c3ac57ec7894c85dcb7032349af7..c7c6b6b13b4e6bbe67ecb5580c4e8e8081f78760 100644
--- a/src/cpp/common/core_codegen.cc
+++ b/src/cpp/common/core_codegen.cc
@@ -93,6 +93,11 @@ void CoreCodegen::grpc_byte_buffer_destroy(grpc_byte_buffer* bb) {
   ::grpc_byte_buffer_destroy(bb);
 }
 
+grpc_call_error CoreCodegen::grpc_call_cancel_with_status(
+    grpc_call* call, grpc_status_code status, const char* description,
+    void* reserved) {
+  return ::grpc_call_cancel_with_status(call, status, description, reserved);
+}
 void CoreCodegen::grpc_call_ref(grpc_call* call) { ::grpc_call_ref(call); }
 void CoreCodegen::grpc_call_unref(grpc_call* call) { ::grpc_call_unref(call); }
 void* CoreCodegen::grpc_call_arena_alloc(grpc_call* call, size_t length) {
diff --git a/src/cpp/util/slice_cc.cc b/src/cpp/util/slice_cc.cc
index 80b4b3a4712e118014f25af924280d1162b9d454..56e0328b949bb55a1823ad1d25896af5867fc3aa 100644
--- a/src/cpp/util/slice_cc.cc
+++ b/src/cpp/util/slice_cc.cc
@@ -28,6 +28,19 @@ Slice::Slice(grpc_slice slice, AddRef) : slice_(grpc_slice_ref(slice)) {}
 
 Slice::Slice(grpc_slice slice, StealRef) : slice_(slice) {}
 
+Slice::Slice(size_t len) : slice_(grpc_slice_malloc(len)) {}
+
+Slice::Slice(const void* buf, size_t len)
+    : slice_(grpc_slice_from_copied_buffer(reinterpret_cast<const char*>(buf),
+                                           len)) {}
+
+Slice::Slice(const grpc::string& str)
+    : slice_(grpc_slice_from_copied_buffer(str.c_str(), str.length())) {}
+
+Slice::Slice(const void* buf, size_t len, StaticSlice)
+    : slice_(grpc_slice_from_static_buffer(reinterpret_cast<const char*>(buf),
+                                           len)) {}
+
 Slice::Slice(const Slice& other) : slice_(grpc_slice_ref(other.slice_)) {}
 
 }  // namespace grpc
diff --git a/src/proto/grpc/testing/control.proto b/src/proto/grpc/testing/control.proto
index 48016642f7477c0566b4b84ec00d74169c690f4d..2ff2e4e8a281cdc52aa7dbed49811c3851c5e5d8 100644
--- a/src/proto/grpc/testing/control.proto
+++ b/src/proto/grpc/testing/control.proto
@@ -64,6 +64,7 @@ message LoadParams {
 message SecurityParams {
   bool use_test_ca = 1;
   string server_host_override = 2;
+  string cred_type = 3;
 }
 
 message ChannelArg {
@@ -240,6 +241,10 @@ message ScenarioResultSummary
   // Number of polls called inside completion queue per request
   double client_polls_per_request = 15;
   double server_polls_per_request = 16;
+
+  // Queries per CPU-sec over all servers or clients
+  double server_queries_per_cpu_sec = 17;
+  double client_queries_per_cpu_sec = 18;
 }
 
 // Results of a single benchmark scenario.
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index e7f7332b99508ab469a3a721f8eef82862d4f8bb..605044b65e0ef48006e3670b976adc3fa17e7cc8 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -240,6 +240,7 @@ CORE_SOURCE_FILES = [
   'src/core/lib/security/util/json_util.c',
   'src/core/lib/surface/init_secure.c',
   'src/core/tsi/fake_transport_security.c',
+  'src/core/tsi/gts_transport_security.c',
   'src/core/tsi/ssl_transport_security.c',
   'src/core/tsi/transport_security.c',
   'src/core/tsi/transport_security_adapter.c',
diff --git a/src/python/grpcio_tests/.gitignore b/src/python/grpcio_tests/.gitignore
index dcba283a8ca0b96686e4526ea4a7edb3d02b6131..4f00cd9a7367fae9a753bdda17205e0f324aa8ae 100644
--- a/src/python/grpcio_tests/.gitignore
+++ b/src/python/grpcio_tests/.gitignore
@@ -1,5 +1 @@
-proto/
-src/
-*_pb2.py
-*_pb2_grpc.py
-*.egg-info/
+/src/
diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD
index 0de5a6f4da48382a700c9b7f01d2dc5cc1a7fe02..9123bd929ec0efd9e9963cfbb5a30fb4f77e97a9 100644
--- a/test/cpp/interop/BUILD
+++ b/test/cpp/interop/BUILD
@@ -88,13 +88,22 @@ grpc_cc_library(
     ],
 )
 
-grpc_cc_binary(
-    name = "interop_client",
+grpc_cc_library(
+    name = "interop_client_main",
     srcs = [
         "client.cc",
     ],
+    language = "C++",
     deps = [
         ":client_helper_lib",
+    ],
+)
+
+grpc_cc_binary(
+    name = "interop_client",
+    language = "C++",
+    deps = [
+        ":interop_client_main",
         "//:grpc++",
     ],
 )
diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD
index 93fb53446cb10520779643306061ff241ee5b7ca..b3348b76fab4e3624cd184bfba9aed030bbaf665 100644
--- a/test/cpp/qps/BUILD
+++ b/test/cpp/qps/BUILD
@@ -81,6 +81,7 @@ grpc_cc_library(
         "//src/proto/grpc/testing:services_proto",
         "//test/core/util:gpr_test_util",
         "//test/core/util:grpc_test_util",
+        "//test/cpp/util:test_util",
     ],
 )
 
@@ -148,6 +149,7 @@ grpc_cc_binary(
         ":driver_impl",
         "//:grpc++",
         "//test/cpp/util:test_config",
+        "//test/cpp/util:test_util",
     ],
     external_deps = [
         "gflags",
@@ -162,6 +164,7 @@ grpc_cc_test(
         ":driver_impl",
         ":qps_worker_impl",
         "//test/cpp/util:test_config",
+        "//test/cpp/util:test_util",
     ],
 )
 
@@ -173,6 +176,7 @@ grpc_cc_test(
         ":driver_impl",
         "//:grpc++",
         "//test/cpp/util:test_config",
+        "//test/cpp/util:test_util",
     ],
 )
 
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index e759446c1aea322b0a75db76099406621bb5b1db..6c4d92e8599ca61563a1849a5866a05a01a58c12 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -39,6 +39,7 @@
 #include "test/cpp/qps/interarrival.h"
 #include "test/cpp/qps/usage_timer.h"
 #include "test/cpp/util/create_test_channel.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 namespace grpc {
 namespace testing {
@@ -88,9 +89,7 @@ class ClientRequestCreator<ByteBuffer> {
     if (payload_config.has_bytebuf_params()) {
       std::unique_ptr<char[]> buf(
           new char[payload_config.bytebuf_params().req_size()]);
-      grpc_slice s = grpc_slice_from_copied_buffer(
-          buf.get(), payload_config.bytebuf_params().req_size());
-      Slice slice(s, Slice::STEAL_REF);
+      Slice slice(buf.get(), payload_config.bytebuf_params().req_size());
       *req = ByteBuffer(&slice, 1);
     } else {
       GPR_ASSERT(false);  // not appropriate for this specialization
@@ -407,9 +406,18 @@ class ClientImpl : public Client {
       ChannelArguments args;
       args.SetInt("shard_to_ensure_no_subchannel_merges", shard);
       set_channel_args(config, &args);
+
+      grpc::string type;
+      if (config.has_security_params() &&
+          config.security_params().cred_type().empty()) {
+        type = kTlsCredentialsType;
+      } else {
+        type = config.security_params().cred_type();
+      }
+
       channel_ = CreateTestChannel(
-          target, config.security_params().server_host_override(),
-          config.has_security_params(), !config.security_params().use_test_ca(),
+          target, type, config.security_params().server_host_override(),
+          !config.security_params().use_test_ca(),
           std::shared_ptr<CallCredentials>(), args);
       gpr_log(GPR_INFO, "Connecting to %s", target.c_str());
       GPR_ASSERT(channel_->WaitForConnected(
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index fbd8d1b1e769622dd2454db9dd38eec266290ab9..4458e389e7efdf10c49328b6297da1aa533cb2fd 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -40,6 +40,7 @@
 #include "test/cpp/qps/histogram.h"
 #include "test/cpp/qps/qps_worker.h"
 #include "test/cpp/qps/stats.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 using std::list;
 using std::thread;
@@ -172,13 +173,26 @@ static void postprocess_scenario_result(ScenarioResult* result) {
       sum(result->client_stats(), CliPollCount) / histogram.Count());
   result->mutable_summary()->set_server_polls_per_request(
       sum(result->server_stats(), SvrPollCount) / histogram.Count());
+
+  auto server_queries_per_cpu_sec =
+      histogram.Count() / (sum(result->server_stats(), ServerSystemTime) +
+                           sum(result->server_stats(), ServerUserTime));
+  auto client_queries_per_cpu_sec =
+      histogram.Count() / (sum(result->client_stats(), SystemTime) +
+                           sum(result->client_stats(), UserTime));
+
+  result->mutable_summary()->set_server_queries_per_cpu_sec(
+      server_queries_per_cpu_sec);
+  result->mutable_summary()->set_client_queries_per_cpu_sec(
+      client_queries_per_cpu_sec);
 }
 
 std::unique_ptr<ScenarioResult> RunScenario(
     const ClientConfig& initial_client_config, size_t num_clients,
     const ServerConfig& initial_server_config, size_t num_servers,
     int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count,
-    const char* qps_server_target_override) {
+    const grpc::string& qps_server_target_override,
+    const grpc::string& credential_type) {
   // Log everything from the driver
   gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG);
 
@@ -214,7 +228,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
     }
 
     int driver_port = grpc_pick_unused_port_or_die();
-    local_workers.emplace_back(new QpsWorker(driver_port));
+    local_workers.emplace_back(new QpsWorker(driver_port, 0, credential_type));
     char addr[256];
     sprintf(addr, "localhost:%d", driver_port);
     if (spawn_local_worker_count < 0) {
@@ -246,12 +260,14 @@ std::unique_ptr<ScenarioResult> RunScenario(
   };
   std::vector<ServerData> servers(num_servers);
   std::unordered_map<string, std::deque<int>> hosts_cores;
+  ChannelArguments channel_args;
 
   for (size_t i = 0; i < num_servers; i++) {
     gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")",
             workers[i].c_str(), i);
-    servers[i].stub = WorkerService::NewStub(
-        CreateChannel(workers[i], InsecureChannelCredentials()));
+    servers[i].stub = WorkerService::NewStub(CreateChannel(
+        workers[i], GetCredentialsProvider()->GetChannelCredentials(
+                        credential_type, &channel_args)));
 
     ServerConfig server_config = initial_server_config;
     if (server_config.core_limit() != 0) {
@@ -269,8 +285,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
     if (!servers[i].stream->Read(&init_status)) {
       gpr_log(GPR_ERROR, "Server %zu did not yield initial status", i);
     }
-    if (qps_server_target_override != NULL &&
-        strlen(qps_server_target_override) > 0) {
+    if (qps_server_target_override.length() > 0) {
       // overriding the qps server target only works if there is 1 server
       GPR_ASSERT(num_servers == 1);
       client_config.add_server_targets(qps_server_target_override);
@@ -298,7 +313,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
     gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")",
             worker.c_str(), i + num_servers);
     clients[i].stub = WorkerService::NewStub(
-        CreateChannel(worker, InsecureChannelCredentials()));
+        CreateChannel(worker, GetCredentialsProvider()->GetChannelCredentials(
+                                  credential_type, &channel_args)));
     ClientConfig per_client_config = client_config;
 
     if (initial_client_config.core_limit() != 0) {
@@ -483,16 +499,19 @@ std::unique_ptr<ScenarioResult> RunScenario(
   return result;
 }
 
-bool RunQuit() {
+bool RunQuit(const grpc::string& credential_type) {
   // Get client, server lists
   bool result = true;
   auto workers = get_workers("QPS_WORKERS");
   if (workers.size() == 0) {
     return false;
   }
+
+  ChannelArguments channel_args;
   for (size_t i = 0; i < workers.size(); i++) {
-    auto stub = WorkerService::NewStub(
-        CreateChannel(workers[i], InsecureChannelCredentials()));
+    auto stub = WorkerService::NewStub(CreateChannel(
+        workers[i], GetCredentialsProvider()->GetChannelCredentials(
+                        credential_type, &channel_args)));
     Void dummy;
     grpc::ClientContext ctx;
     ctx.set_wait_for_ready(true);
diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h
index def32c6f0ef12a8bbd04fa4eab989e7d1890c517..29f2776d791e9a5792defc68966da4ccfbba4b08 100644
--- a/test/cpp/qps/driver.h
+++ b/test/cpp/qps/driver.h
@@ -31,9 +31,10 @@ std::unique_ptr<ScenarioResult> RunScenario(
     const grpc::testing::ClientConfig& client_config, size_t num_clients,
     const grpc::testing::ServerConfig& server_config, size_t num_servers,
     int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count,
-    const char* qps_server_target_override = "");
+    const grpc::string& qps_server_target_override,
+    const grpc::string& credential_type);
 
-bool RunQuit();
+bool RunQuit(const grpc::string& credential_type);
 }  // namespace testing
 }  // namespace grpc
 
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index e1e5802d1365c74a7976769e60b258ea8f7a7f0b..cca59f64d8c4871d762aec5c6064dfc60231e60b 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -31,6 +31,7 @@
 #include "test/cpp/qps/parse_json.h"
 #include "test/cpp/qps/report.h"
 #include "test/cpp/util/test_config.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 DEFINE_string(scenarios_file, "",
               "JSON file containing an array of Scenario objects");
@@ -61,6 +62,9 @@ DEFINE_string(qps_server_target_override, "",
 
 DEFINE_string(json_file_out, "", "File to write the JSON output to.");
 
+DEFINE_string(credential_type, grpc::testing::kInsecureCredentialsType,
+              "Credential type for communication with workers");
+
 namespace grpc {
 namespace testing {
 
@@ -72,7 +76,7 @@ static std::unique_ptr<ScenarioResult> RunAndReport(const Scenario& scenario,
                   scenario.server_config(), scenario.num_servers(),
                   scenario.warmup_seconds(), scenario.benchmark_seconds(),
                   scenario.spawn_local_worker_count(),
-                  FLAGS_qps_server_target_override.c_str());
+                  FLAGS_qps_server_target_override, FLAGS_credential_type);
 
   // Amend the result with scenario config. Eventually we should adjust
   // RunScenario contract so we don't need to touch the result here.
@@ -84,6 +88,7 @@ static std::unique_ptr<ScenarioResult> RunAndReport(const Scenario& scenario,
   GetReporter()->ReportTimes(*result);
   GetReporter()->ReportCpuUsage(*result);
   GetReporter()->ReportPollCount(*result);
+  GetReporter()->ReportQueriesPerCpuSec(*result);
 
   for (int i = 0; *success && i < result->client_success_size(); i++) {
     *success = result->client_success(i);
@@ -185,7 +190,7 @@ static bool QpsDriver() {
   } else if (scjson) {
     json = FLAGS_scenarios_json.c_str();
   } else if (FLAGS_quit) {
-    return RunQuit();
+    return RunQuit(FLAGS_credential_type);
   }
 
   // Parse into an array of scenarios
diff --git a/test/cpp/qps/qps_openloop_test.cc b/test/cpp/qps/qps_openloop_test.cc
index 2f8a3d75f0c911a3775e55595a59c2891e565494..069b3fa0768e7057ef907a3052d87e4c758c1ac9 100644
--- a/test/cpp/qps/qps_openloop_test.cc
+++ b/test/cpp/qps/qps_openloop_test.cc
@@ -25,6 +25,7 @@
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
 #include "test/cpp/util/test_config.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 namespace grpc {
 namespace testing {
@@ -48,8 +49,8 @@ static void RunQPS() {
   server_config.set_server_type(ASYNC_SERVER);
   server_config.set_async_server_threads(8);
 
-  const auto result =
-      RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
+  const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP,
+                                  BENCHMARK, -2, "", kInsecureCredentialsType);
 
   GetReporter()->ReportQPSPerCore(*result);
   GetReporter()->ReportLatency(*result);
diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc
index 10bc5422e13a287f796eed54bc78490da631055d..d20bc1b074ee8308ff3ddb21c48997e690c96317 100644
--- a/test/cpp/qps/qps_worker.cc
+++ b/test/cpp/qps/qps_worker.cc
@@ -41,6 +41,7 @@
 #include "test/cpp/qps/client.h"
 #include "test/cpp/qps/server.h"
 #include "test/cpp/util/create_test_channel.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 namespace grpc {
 namespace testing {
@@ -263,7 +264,8 @@ class WorkerServiceImpl final : public WorkerService::Service {
   QpsWorker* worker_;
 };
 
-QpsWorker::QpsWorker(int driver_port, int server_port) {
+QpsWorker::QpsWorker(int driver_port, int server_port,
+                     const grpc::string& credential_type) {
   impl_.reset(new WorkerServiceImpl(server_port, this));
   gpr_atm_rel_store(&done_, static_cast<gpr_atm>(0));
 
@@ -271,7 +273,9 @@ QpsWorker::QpsWorker(int driver_port, int server_port) {
   gpr_join_host_port(&server_address, "::", driver_port);
 
   ServerBuilder builder;
-  builder.AddListeningPort(server_address, InsecureServerCredentials());
+  builder.AddListeningPort(
+      server_address,
+      GetCredentialsProvider()->GetServerCredentials(credential_type));
   builder.RegisterService(impl_.get());
 
   gpr_free(server_address);
diff --git a/test/cpp/qps/qps_worker.h b/test/cpp/qps/qps_worker.h
index c8a7be93605d94653d4068ecc8559fd656c35d83..360125fb1701711c9089ba170b63500f6877d2c0 100644
--- a/test/cpp/qps/qps_worker.h
+++ b/test/cpp/qps/qps_worker.h
@@ -21,6 +21,7 @@
 
 #include <memory>
 
+#include <grpc++/support/config.h>
 #include <grpc/support/atm.h>
 
 namespace grpc {
@@ -33,7 +34,8 @@ class WorkerServiceImpl;
 
 class QpsWorker {
  public:
-  explicit QpsWorker(int driver_port, int server_port = 0);
+  explicit QpsWorker(int driver_port, int server_port,
+                     const grpc::string& credential_type);
   ~QpsWorker();
 
   bool Done() const;
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
index 809c56304423393bd0a95e23f687490642444409..a45b10bcb81b30fdcba27c0e0997ebfbe05bd267 100644
--- a/test/cpp/qps/report.cc
+++ b/test/cpp/qps/report.cc
@@ -71,6 +71,12 @@ void CompositeReporter::ReportPollCount(const ScenarioResult& result) {
   }
 }
 
+void CompositeReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) {
+  for (size_t i = 0; i < reporters_.size(); ++i) {
+    reporters_[i]->ReportQueriesPerCpuSec(result);
+  }
+}
+
 void GprLogReporter::ReportQPS(const ScenarioResult& result) {
   gpr_log(GPR_INFO, "QPS: %.1f", result.summary().qps());
   if (result.summary().failed_requests_per_second() > 0) {
@@ -119,6 +125,13 @@ void GprLogReporter::ReportPollCount(const ScenarioResult& result) {
           result.summary().server_polls_per_request());
 }
 
+void GprLogReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) {
+  gpr_log(GPR_INFO, "Server Queries/CPU-sec: %.2f",
+          result.summary().server_queries_per_cpu_sec());
+  gpr_log(GPR_INFO, "Client Queries/CPU-sec: %.2f",
+          result.summary().client_queries_per_cpu_sec());
+}
+
 void JsonReporter::ReportQPS(const ScenarioResult& result) {
   grpc::string json_string =
       SerializeJson(result, "type.googleapis.com/grpc.testing.ScenarioResult");
@@ -147,6 +160,10 @@ void JsonReporter::ReportPollCount(const ScenarioResult& result) {
   // NOP - all reporting is handled by ReportQPS.
 }
 
+void JsonReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) {
+  // NOP - all reporting is handled by ReportQPS.
+}
+
 void RpcReporter::ReportQPS(const ScenarioResult& result) {
   grpc::ClientContext context;
   grpc::Status status;
@@ -183,5 +200,9 @@ void RpcReporter::ReportPollCount(const ScenarioResult& result) {
   // NOP - all reporting is handled by ReportQPS.
 }
 
+void RpcReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) {
+  // NOP - all reporting is handled by ReportQPS.
+}
+
 }  // namespace testing
 }  // namespace grpc
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
index 0bd398fd2a201ba4b3e06d62632d9c569fe2049d..321be2a97fae38b37a41e79ca45b2e33dbfd19ce 100644
--- a/test/cpp/qps/report.h
+++ b/test/cpp/qps/report.h
@@ -64,6 +64,9 @@ class Reporter {
   /** Reports client and server poll usage inside completion queue. */
   virtual void ReportPollCount(const ScenarioResult& result) = 0;
 
+  /** Reports queries per cpu-sec. */
+  virtual void ReportQueriesPerCpuSec(const ScenarioResult& result) = 0;
+
  private:
   const string name_;
 };
@@ -82,6 +85,7 @@ class CompositeReporter : public Reporter {
   void ReportTimes(const ScenarioResult& result) override;
   void ReportCpuUsage(const ScenarioResult& result) override;
   void ReportPollCount(const ScenarioResult& result) override;
+  void ReportQueriesPerCpuSec(const ScenarioResult& result) override;
 
  private:
   std::vector<std::unique_ptr<Reporter> > reporters_;
@@ -99,6 +103,7 @@ class GprLogReporter : public Reporter {
   void ReportTimes(const ScenarioResult& result) override;
   void ReportCpuUsage(const ScenarioResult& result) override;
   void ReportPollCount(const ScenarioResult& result) override;
+  void ReportQueriesPerCpuSec(const ScenarioResult& result) override;
 };
 
 /** Dumps the report to a JSON file. */
@@ -114,6 +119,7 @@ class JsonReporter : public Reporter {
   void ReportTimes(const ScenarioResult& result) override;
   void ReportCpuUsage(const ScenarioResult& result) override;
   void ReportPollCount(const ScenarioResult& result) override;
+  void ReportQueriesPerCpuSec(const ScenarioResult& result) override;
 
   const string report_file_;
 };
@@ -130,6 +136,7 @@ class RpcReporter : public Reporter {
   void ReportTimes(const ScenarioResult& result) override;
   void ReportCpuUsage(const ScenarioResult& result) override;
   void ReportPollCount(const ScenarioResult& result) override;
+  void ReportQueriesPerCpuSec(const ScenarioResult& result) override;
 
   std::unique_ptr<ReportQpsScenarioService::Stub> stub_;
 };
diff --git a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
index 1ee6e374749c8d3042809acda77fb3e5474df362..137b33ee25f4515325e552eb51ae2f3c3d13ac75 100644
--- a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
@@ -24,6 +24,7 @@
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
 #include "test/cpp/util/test_config.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 namespace grpc {
 namespace testing {
@@ -51,8 +52,8 @@ static void RunSynchronousUnaryPingPong() {
   client_config.mutable_security_params()->CopyFrom(security);
   server_config.mutable_security_params()->CopyFrom(security);
 
-  const auto result =
-      RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
+  const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP,
+                                  BENCHMARK, -2, "", kInsecureCredentialsType);
 
   GetReporter()->ReportQPS(*result);
   GetReporter()->ReportLatency(*result);
diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h
index 4b699e0708048413bb3caa09725e2ee161c70203..c0dac96d8b835a7cce501dfa1e973d773e7fe429 100644
--- a/test/cpp/qps/server.h
+++ b/test/cpp/qps/server.h
@@ -32,6 +32,7 @@
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/port.h"
 #include "test/cpp/qps/usage_timer.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 namespace grpc {
 namespace testing {
@@ -89,12 +90,14 @@ class Server {
   static std::shared_ptr<ServerCredentials> CreateServerCredentials(
       const ServerConfig& config) {
     if (config.has_security_params()) {
-      SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
-                                                          test_server1_cert};
-      SslServerCredentialsOptions ssl_opts;
-      ssl_opts.pem_root_certs = "";
-      ssl_opts.pem_key_cert_pairs.push_back(pkcp);
-      return SslServerCredentials(ssl_opts);
+      grpc::string type;
+      if (config.security_params().cred_type().empty()) {
+        type = kTlsCredentialsType;
+      } else {
+        type = config.security_params().cred_type();
+      }
+
+      return GetCredentialsProvider()->GetServerCredentials(type);
     } else {
       return InsecureServerCredentials();
     }
diff --git a/test/cpp/qps/worker.cc b/test/cpp/qps/worker.cc
index fd51d32db0d3b341a3d1e6a888b0dd058c528015..27010b7315292fc930849706bec618f96c1359b1 100644
--- a/test/cpp/qps/worker.cc
+++ b/test/cpp/qps/worker.cc
@@ -27,9 +27,12 @@
 
 #include "test/cpp/qps/qps_worker.h"
 #include "test/cpp/util/test_config.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 DEFINE_int32(driver_port, 0, "Port for communication with driver");
 DEFINE_int32(server_port, 0, "Port for operation as a server");
+DEFINE_string(credential_type, grpc::testing::kInsecureCredentialsType,
+              "Credential type for communication with driver");
 
 static bool got_sigint = false;
 
@@ -39,7 +42,7 @@ namespace grpc {
 namespace testing {
 
 static void RunServer() {
-  QpsWorker worker(FLAGS_driver_port, FLAGS_server_port);
+  QpsWorker worker(FLAGS_driver_port, FLAGS_server_port, FLAGS_credential_type);
 
   while (!got_sigint && !worker.Done()) {
     gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD
new file mode 100644
index 0000000000000000000000000000000000000000..512241e3504f5b189a8a9bd93fbc2f09e0df27de
--- /dev/null
+++ b/test/cpp/server/BUILD
@@ -0,0 +1,43 @@
+# Copyright 2017 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.
+
+licenses(["notice"])  # Apache v2
+
+load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_library", "grpc_cc_binary")
+
+grpc_cc_test(
+    name = "server_builder_test",
+    srcs = ["server_builder_test.cc"],
+    deps = [
+        "//:grpc++",
+        "//src/proto/grpc/testing:echo_proto",
+        "//test/core/util:grpc_test_util",
+    ],
+    external_deps = [
+        "gtest",
+    ],
+)
+
+grpc_cc_test(
+    name = "server_request_call_test",
+    srcs = ["server_request_call_test.cc"],
+    deps = [
+        "//:grpc++",
+        "//src/proto/grpc/testing:echo_proto",
+        "//test/core/util:grpc_test_util",
+    ],
+    external_deps = [
+        "gtest",
+    ],
+)
diff --git a/test/cpp/server/server_request_call_test.cc b/test/cpp/server/server_request_call_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1c64ddfc67cda4aca4a27fcf249bf96341e466a3
--- /dev/null
+++ b/test/cpp/server/server_request_call_test.cc
@@ -0,0 +1,162 @@
+/*
+ *
+ * Copyright 2017 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 <thread>
+
+#include <grpc++/impl/codegen/config.h>
+#include <gtest/gtest.h>
+
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+
+#include <grpc++/create_channel.h>
+#include <grpc++/security/credentials.h>
+
+#include <grpc/support/log.h>
+
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/core/util/port.h"
+
+namespace grpc {
+namespace {
+
+TEST(ServerRequestCallTest, ShortDeadlineDoesNotCauseOkayFalse) {
+  std::mutex mu;
+  bool shutting_down = false;
+
+  // grpc server config.
+  std::ostringstream s;
+  int p = grpc_pick_unused_port_or_die();
+  s << "[::1]:" << p;
+  const string address = s.str();
+  testing::EchoTestService::AsyncService service;
+  ServerBuilder builder;
+  builder.AddListeningPort(address, InsecureServerCredentials());
+  auto cq = builder.AddCompletionQueue();
+  builder.RegisterService(&service);
+  auto server = builder.BuildAndStart();
+
+  // server thread.
+  std::thread t([address, &service, &cq, &mu, &shutting_down] {
+    for (int n = 0; true; n++) {
+      ServerContext ctx;
+      testing::EchoRequest req;
+      ServerAsyncResponseWriter<testing::EchoResponse> responder(&ctx);
+
+      // if shutting down, don't enqueue a new request.
+      {
+        std::lock_guard<std::mutex> lock(mu);
+        if (!shutting_down) {
+          service.RequestEcho(&ctx, &req, &responder, cq.get(), cq.get(),
+                              (void*)1);
+        }
+      }
+
+      bool ok;
+      void* tag;
+      if (!cq->Next(&tag, &ok)) {
+        break;
+      }
+
+      EXPECT_EQ((void*)1, tag);
+      // If not shutting down, ok must be true for new requests.
+      {
+        std::lock_guard<std::mutex> lock(mu);
+        if (!shutting_down && !ok) {
+          gpr_log(GPR_INFO, "!ok on request %d", n);
+          abort();
+        }
+        if (shutting_down && !ok) {
+          // Failed connection due to shutdown, continue flushing the CQ.
+          continue;
+        }
+      }
+
+      // Send a simple response after a small delay that would ensure the client
+      // deadline is exceeded.
+      gpr_log(GPR_INFO, "Got request %d", n);
+      testing::EchoResponse response;
+      response.set_message("foobar");
+      // A bit of sleep to make sure the deadline elapses.
+      gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                                   gpr_time_from_millis(50, GPR_TIMESPAN)));
+      {
+        std::lock_guard<std::mutex> lock(mu);
+        if (shutting_down) {
+          gpr_log(GPR_INFO,
+                  "shut down while processing call, not calling Finish()");
+          // Continue flushing the CQ.
+          continue;
+        }
+        gpr_log(GPR_INFO, "Finishing request %d", n);
+        responder.Finish(response, grpc::Status::OK, (void*)2);
+        if (!cq->Next(&tag, &ok)) {
+          break;
+        }
+        EXPECT_EQ((void*)2, tag);
+      }
+    }
+  });
+
+  auto stub = testing::EchoTestService::NewStub(
+      CreateChannel(address, InsecureChannelCredentials()));
+
+  for (int i = 0; i < 100; i++) {
+    gpr_log(GPR_INFO, "Sending %d.", i);
+    testing::EchoRequest request;
+
+    /////////
+    // Comment out the following line to get ok=false due to invalid request.
+    // Otherwise, ok=false due to deadline being exceeded.
+    /////////
+    request.set_message("foobar");
+
+    // A simple request with a short deadline. The server will always exceed the
+    // deadline, whether due to the sleep or because the server was unable to
+    // even fetch the request from the CQ before the deadline elapsed.
+    testing::EchoResponse response;
+    ::grpc::ClientContext ctx;
+    ctx.set_fail_fast(false);
+    ctx.set_deadline(std::chrono::system_clock::now() +
+                     std::chrono::milliseconds(1));
+    grpc::Status status = stub->Echo(&ctx, request, &response);
+    EXPECT_EQ(DEADLINE_EXCEEDED, status.error_code());
+    gpr_log(GPR_INFO, "Success.");
+  }
+  gpr_log(GPR_INFO, "Done sending RPCs.");
+
+  // Shut down everything properly.
+  gpr_log(GPR_INFO, "Shutting down.");
+  {
+    std::lock_guard<std::mutex> lock(mu);
+    shutting_down = true;
+  }
+  server->Shutdown();
+  cq->Shutdown();
+  server->Wait();
+
+  t.join();
+}
+
+}  // namespace
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/util/byte_buffer_proto_helper.cc b/test/cpp/util/byte_buffer_proto_helper.cc
index 22dd074fe9355dfacf0769ef19f5133dfa86be55..bb5162f86e6190f86115c154ac815220c75920b5 100644
--- a/test/cpp/util/byte_buffer_proto_helper.cc
+++ b/test/cpp/util/byte_buffer_proto_helper.cc
@@ -36,8 +36,7 @@ std::unique_ptr<ByteBuffer> SerializeToByteBuffer(
     grpc::protobuf::Message* message) {
   grpc::string buf;
   message->SerializeToString(&buf);
-  grpc_slice s = grpc_slice_from_copied_string(buf.c_str());
-  Slice slice(s, Slice::STEAL_REF);
+  Slice slice(buf);
   return std::unique_ptr<ByteBuffer>(new ByteBuffer(&slice, 1));
 }
 
diff --git a/test/cpp/util/byte_buffer_test.cc b/test/cpp/util/byte_buffer_test.cc
index 6c077ddb2c36bad45170bf753b3349d3bb51df59..cac01a7307822705b4220f0aa972b4ee1b3638b7 100644
--- a/test/cpp/util/byte_buffer_test.cc
+++ b/test/cpp/util/byte_buffer_test.cc
@@ -34,33 +34,30 @@ const char* kContent2 = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy world";
 class ByteBufferTest : public ::testing::Test {};
 
 TEST_F(ByteBufferTest, CreateFromSingleSlice) {
-  grpc_slice hello = grpc_slice_from_copied_string(kContent1);
-  Slice s(hello, Slice::STEAL_REF);
+  Slice s(kContent1);
   ByteBuffer buffer(&s, 1);
+  EXPECT_EQ(strlen(kContent1), buffer.Length());
 }
 
 TEST_F(ByteBufferTest, CreateFromVector) {
-  grpc_slice hello = grpc_slice_from_copied_string(kContent1);
-  grpc_slice world = grpc_slice_from_copied_string(kContent2);
   std::vector<Slice> slices;
-  slices.push_back(Slice(hello, Slice::STEAL_REF));
-  slices.push_back(Slice(world, Slice::STEAL_REF));
+  slices.emplace_back(kContent1);
+  slices.emplace_back(kContent2);
   ByteBuffer buffer(&slices[0], 2);
+  EXPECT_EQ(strlen(kContent1) + strlen(kContent2), buffer.Length());
 }
 
 TEST_F(ByteBufferTest, Clear) {
-  grpc_slice hello = grpc_slice_from_copied_string(kContent1);
-  Slice s(hello, Slice::STEAL_REF);
+  Slice s(kContent1);
   ByteBuffer buffer(&s, 1);
   buffer.Clear();
+  EXPECT_EQ(static_cast<size_t>(0), buffer.Length());
 }
 
 TEST_F(ByteBufferTest, Length) {
-  grpc_slice hello = grpc_slice_from_copied_string(kContent1);
-  grpc_slice world = grpc_slice_from_copied_string(kContent2);
   std::vector<Slice> slices;
-  slices.push_back(Slice(hello, Slice::STEAL_REF));
-  slices.push_back(Slice(world, Slice::STEAL_REF));
+  slices.emplace_back(kContent1);
+  slices.emplace_back(kContent2);
   ByteBuffer buffer(&slices[0], 2);
   EXPECT_EQ(strlen(kContent1) + strlen(kContent2), buffer.Length());
 }
diff --git a/test/cpp/util/cli_call.cc b/test/cpp/util/cli_call.cc
index fb6d76bb9065b49554ce880d463fc392a6869019..c3220efa54473056f2fbeda5d49100e6297622be 100644
--- a/test/cpp/util/cli_call.cc
+++ b/test/cpp/util/cli_call.cc
@@ -119,8 +119,7 @@ void CliCall::WritesDone() {
 }
 
 void CliCall::WriteAndWait(const grpc::string& request) {
-  grpc_slice s = grpc_slice_from_copied_string(request.c_str());
-  grpc::Slice req_slice(s, grpc::Slice::STEAL_REF);
+  grpc::Slice req_slice(request);
   grpc::ByteBuffer send_buffer(&req_slice, 1);
 
   gpr_mu_lock(&write_mu_);
diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc
index 68c6fe4622e87beba20b40295271fe2622d9f562..34b6d60d014cf2deb3295a3ab8f9063884318c22 100644
--- a/test/cpp/util/create_test_channel.cc
+++ b/test/cpp/util/create_test_channel.cc
@@ -51,29 +51,31 @@ void AddProdSslType() {
 
 }  // namespace
 
-// When ssl is enabled, if server is empty, override_hostname is used to
+// When cred_type is 'ssl', if server is empty, override_hostname is used to
 // create channel. Otherwise, connect to server and override hostname if
 // override_hostname is provided.
-// When ssl is not enabled, override_hostname is ignored.
+// When cred_type is not 'ssl', override_hostname is ignored.
 // Set use_prod_root to true to use the SSL root for connecting to google.
 // In this case, path to the roots pem file must be set via environment variable
 // GRPC_DEFAULT_SSL_ROOTS_FILE_PATH.
 // Otherwise, root for test SSL cert will be used.
-// creds will be used to create a channel when enable_ssl is true.
+// creds will be used to create a channel when cred_type is 'ssl'.
 // Use examples:
 //   CreateTestChannel(
-//       "1.1.1.1:12345", "override.hostname.com", true, false, creds);
-//   CreateTestChannel("test.google.com:443", "", true, true, creds);
+//       "1.1.1.1:12345", "ssl", "override.hostname.com", false, creds);
+//   CreateTestChannel("test.google.com:443", "ssl", "", true, creds);
 //   same as above
-//   CreateTestChannel("", "test.google.com:443", true, true, creds);
+//   CreateTestChannel("", "ssl", "test.google.com:443", true, creds);
 std::shared_ptr<Channel> CreateTestChannel(
-    const grpc::string& server, const grpc::string& override_hostname,
-    bool enable_ssl, bool use_prod_roots,
+    const grpc::string& server, const grpc::string& cred_type,
+    const grpc::string& override_hostname, bool use_prod_roots,
     const std::shared_ptr<CallCredentials>& creds,
     const ChannelArguments& args) {
   ChannelArguments channel_args(args);
   std::shared_ptr<ChannelCredentials> channel_creds;
-  if (enable_ssl) {
+  if (cred_type.empty()) {
+    return CreateChannel(server, InsecureChannelCredentials());
+  } else if (cred_type == testing::kTlsCredentialsType) {  // cred_type == "ssl"
     if (use_prod_roots) {
       gpr_once_init(&g_once_init_add_prod_ssl_provider, &AddProdSslType);
       channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials(
@@ -95,10 +97,28 @@ std::shared_ptr<Channel> CreateTestChannel(
     }
     return CreateCustomChannel(connect_to, channel_creds, channel_args);
   } else {
-    return CreateChannel(server, InsecureChannelCredentials());
+    channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials(
+        cred_type, &channel_args);
+    GPR_ASSERT(channel_creds != nullptr);
+
+    return CreateChannel(server, channel_creds);
   }
 }
 
+std::shared_ptr<Channel> CreateTestChannel(
+    const grpc::string& server, const grpc::string& override_hostname,
+    bool enable_ssl, bool use_prod_roots,
+    const std::shared_ptr<CallCredentials>& creds,
+    const ChannelArguments& args) {
+  grpc::string type;
+  if (enable_ssl) {
+    type = testing::kTlsCredentialsType;
+  }
+
+  return CreateTestChannel(server, type, override_hostname, use_prod_roots,
+                           creds, args);
+}
+
 std::shared_ptr<Channel> CreateTestChannel(
     const grpc::string& server, const grpc::string& override_hostname,
     bool enable_ssl, bool use_prod_roots,
diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h
index 9b4b09171efad8c261e07918aa906879a39ec556..e2ca8f99b405789f6f8c2145ec03b5568210d251 100644
--- a/test/cpp/util/create_test_channel.h
+++ b/test/cpp/util/create_test_channel.h
@@ -44,6 +44,12 @@ std::shared_ptr<Channel> CreateTestChannel(
     const std::shared_ptr<CallCredentials>& creds,
     const ChannelArguments& args);
 
+std::shared_ptr<Channel> CreateTestChannel(
+    const grpc::string& server, const grpc::string& cred_type,
+    const grpc::string& override_hostname, bool use_prod_roots,
+    const std::shared_ptr<CallCredentials>& creds,
+    const ChannelArguments& args);
+
 std::shared_ptr<Channel> CreateTestChannel(
     const grpc::string& server, const grpc::string& credential_type,
     const std::shared_ptr<CallCredentials>& creds);
diff --git a/test/cpp/util/slice_test.cc b/test/cpp/util/slice_test.cc
index 0f800035801209e94143997504525870f2cedc97..9e3329fab02fc739c4b2b3575abb3052979ca0dc 100644
--- a/test/cpp/util/slice_test.cc
+++ b/test/cpp/util/slice_test.cc
@@ -28,6 +28,9 @@ const char* kContent = "hello xxxxxxxxxxxxxxxxxxxx world";
 
 class SliceTest : public ::testing::Test {
  protected:
+  void CheckSliceSize(const Slice& s, const grpc::string& content) {
+    EXPECT_EQ(content.size(), s.size());
+  }
   void CheckSlice(const Slice& s, const grpc::string& content) {
     EXPECT_EQ(content.size(), s.size());
     EXPECT_EQ(content,
@@ -35,6 +38,31 @@ class SliceTest : public ::testing::Test {
   }
 };
 
+TEST_F(SliceTest, Empty) {
+  Slice empty_slice;
+  CheckSlice(empty_slice, "");
+}
+
+TEST_F(SliceTest, Sized) {
+  Slice sized_slice(strlen(kContent));
+  CheckSliceSize(sized_slice, kContent);
+}
+
+TEST_F(SliceTest, String) {
+  Slice spp(kContent);
+  CheckSlice(spp, kContent);
+}
+
+TEST_F(SliceTest, Buf) {
+  Slice spp(kContent, strlen(kContent));
+  CheckSlice(spp, kContent);
+}
+
+TEST_F(SliceTest, StaticBuf) {
+  Slice spp(kContent, strlen(kContent), Slice::STATIC_SLICE);
+  CheckSlice(spp, kContent);
+}
+
 TEST_F(SliceTest, Steal) {
   grpc_slice s = grpc_slice_from_copied_string(kContent);
   Slice spp(s, Slice::STEAL_REF);
@@ -48,11 +76,6 @@ TEST_F(SliceTest, Add) {
   CheckSlice(spp, kContent);
 }
 
-TEST_F(SliceTest, Empty) {
-  Slice empty_slice;
-  CheckSlice(empty_slice, "");
-}
-
 TEST_F(SliceTest, Cslice) {
   grpc_slice s = grpc_slice_from_copied_string(kContent);
   Slice spp(s, Slice::STEAL_REF);
diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py
index bc24e4c462abc4461c0d2f4376435b3f2a410d0b..ddbb348e0cd3f30ecc09c9dca2a581e0b0cf4f5e 100644
--- a/tools/distrib/python/grpcio_tools/setup.py
+++ b/tools/distrib/python/grpcio_tools/setup.py
@@ -62,9 +62,9 @@ if EXTRA_ENV_COMPILE_ARGS is None:
       # envvars) without adding yet more GRPC-specific envvars.
       # See https://sourceforge.net/p/mingw-w64/bugs/363/
       if '32' in platform.architecture()[0]:
-        EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime32 -D_timeb=__timeb32 -D_ftime_s=_ftime32_s'
+        EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime32 -D_timeb=__timeb32 -D_ftime_s=_ftime32_s -D_hypot=hypot'
       else:
-        EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64'
+        EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64 -D_hypot=hypot'
     else:
       # We need to statically link the C++ Runtime, only the C runtime is
       # available dynamically
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 7c1e75a99cdd1d038e1cbe1ae674345d6a51d5d6..4ad8a0ddb4634167bc3f35f003f444c902032c6a 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1404,6 +1404,8 @@ src/core/plugin_registry/grpc_plugin_registry.c \
 src/core/tsi/README.md \
 src/core/tsi/fake_transport_security.c \
 src/core/tsi/fake_transport_security.h \
+src/core/tsi/gts_transport_security.c \
+src/core/tsi/gts_transport_security.h \
 src/core/tsi/ssl_transport_security.c \
 src/core/tsi/ssl_transport_security.h \
 src/core/tsi/ssl_types.h \
diff --git a/tools/internal_ci/windows/grpc_build_artifacts.bat b/tools/internal_ci/windows/grpc_build_artifacts.bat
index d5ade5a83d5bf3be6fb6ca8096118c538803cd1a..8cfa2fb0beaf4f714a161d6927f524a82c54a547 100644
--- a/tools/internal_ci/windows/grpc_build_artifacts.bat
+++ b/tools/internal_ci/windows/grpc_build_artifacts.bat
@@ -19,10 +19,13 @@ rename C:\Python34_32bit Python34_32bits
 rename C:\Python35_32bit Python35_32bits
 rename C:\Python36_32bit Python36_32bits
 
+pacman -S --noconfirm mingw64/mingw-w64-x86_64-gcc mingw32/mingw-w64-i686-gcc
+
 @rem make sure msys binaries are preferred over cygwin binaries
 @rem set path to python 2.7
 set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH%
 
+
 @rem enter repo root
 cd /d %~dp0\..\..\..
 
diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py
index 4394e32c0857cb7acb0bee022cbc57c11fc804d6..4d1b5f016951411139881b54f9fc89875e64b4ec 100644
--- a/tools/interop_matrix/client_matrix.py
+++ b/tools/interop_matrix/client_matrix.py
@@ -30,9 +30,27 @@ LANG_RUNTIME_MATRIX = {
 }
 
 # Dictionary of releases per language.  For each language, we need to provide
-# a tuple of release tag (used as the tag for the GCR image) and also github hash.
+# a release tag pointing to the latest build of the branch.
 LANG_RELEASE_MATRIX = {
-    'cxx': ['v1.0.1', 'v1.1.2'],
-    'go': ['v1.0.1-GA', 'v1.3.0'],
-    'java': ['v1.0.3', 'v1.1.2'],
+    'cxx': [
+        'v1.0.1',
+        'v1.1.4',
+        'v1.2.5',
+        'v1.3.9',
+        'v1.4.2',
+    ],
+    'go': [
+        'v1.0.5',
+        'v1.2.1',
+        'v1.3.0',
+        'v1.4.2',
+    ],
+    'java': [
+        'v1.0.3',
+        'v1.1.2',
+        'v1.2.0',
+        'v1.3.1',
+        'v1.4.0',
+        'v1.5.0',
+    ],
 }
diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py
index 28126ddf5cccdf466039ae4078412cf1d9f09231..4315c8277dfdda98f6d1e10bc747a16a89802454 100755
--- a/tools/interop_matrix/run_interop_matrix_tests.py
+++ b/tools/interop_matrix/run_interop_matrix_tests.py
@@ -168,7 +168,7 @@ def run_tests_for_lang(lang, runtime, images):
         _xml_report_tree,
         resultset,
         'grpc_interop_matrix',
-        '%s__%s:%s'%(lang,runtime,release),
+        '%s__%s %s'%(lang,runtime,release),
         str(uuid.uuid4()))
 
 _docker_images_cleanup = []
diff --git a/tools/run_tests/artifacts/build_artifact_python.bat b/tools/run_tests/artifacts/build_artifact_python.bat
index 4c34fc50f0400a596493c8b2a0ceca5d4a52c5c9..3a0564129cfd3d2d8c268ea1e1efd171252602a9 100644
--- a/tools/run_tests/artifacts/build_artifact_python.bat
+++ b/tools/run_tests/artifacts/build_artifact_python.bat
@@ -12,8 +12,8 @@
 @rem See the License for the specific language governing permissions and
 @rem limitations under the License.
 
-
-set PATH=C:\%1;C:\%1\scripts;C:\msys64\mingw%2\bin;%PATH%
+@rem set path to python & mingw compiler
+set PATH=C:\%1;C:\%1\scripts;C:\msys64\mingw%2\bin;C:\tools\msys64\mingw%2\bin;%PATH%
 
 pip install --upgrade six
 pip install --upgrade setuptools
diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh
index 77c7a84828efcefbcd0cc0c2da5fcfd927bdc524..9d8ad5325c1a827f49e311aa630e3c39c38aec74 100755
--- a/tools/run_tests/dockerize/build_interop_image.sh
+++ b/tools/run_tests/dockerize/build_interop_image.sh
@@ -69,8 +69,8 @@ fi
 
 if [ "$DOCKERHUB_ORGANIZATION" != "" ]
 then
-  DOCKER_IMAGE_NAME=$DOCKERHUB_ORGANIZATION/$BASE_IMAGE
-  docker pull $DOCKER_IMAGE_NAME
+  BASE_IMAGE=$DOCKERHUB_ORGANIZATION/$BASE_IMAGE
+  docker pull $BASE_IMAGE
 else
   # Make sure docker image has been built. Should be instantaneous if so.
   docker build -t $BASE_IMAGE --force-rm=true tools/dockerfile/interoptest/$BASE_NAME || exit $?
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index c7cc9cb6945bf5345996db3f73481f3f25ed942f..8993e9340ac3110621364c845add6842d1e50053 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -3950,6 +3950,32 @@
     "third_party": false, 
     "type": "target"
   }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_test_util"
+    ], 
+    "headers": [
+      "src/proto/grpc/testing/echo.grpc.pb.h", 
+      "src/proto/grpc/testing/echo.pb.h", 
+      "src/proto/grpc/testing/echo_messages.grpc.pb.h", 
+      "src/proto/grpc/testing/echo_messages.pb.h", 
+      "src/proto/grpc/testing/echo_messages_mock.grpc.pb.h", 
+      "src/proto/grpc/testing/echo_mock.grpc.pb.h"
+    ], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "server_request_call_test", 
+    "src": [
+      "test/cpp/server/server_request_call_test.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
   {
     "deps": [
       "gpr", 
@@ -8892,10 +8918,12 @@
   {
     "deps": [
       "gpr", 
+      "grpc_base", 
       "grpc_trace"
     ], 
     "headers": [
       "src/core/tsi/fake_transport_security.h", 
+      "src/core/tsi/gts_transport_security.h", 
       "src/core/tsi/ssl_transport_security.h", 
       "src/core/tsi/ssl_types.h", 
       "src/core/tsi/transport_security.h", 
@@ -8908,6 +8936,8 @@
     "src": [
       "src/core/tsi/fake_transport_security.c", 
       "src/core/tsi/fake_transport_security.h", 
+      "src/core/tsi/gts_transport_security.c", 
+      "src/core/tsi/gts_transport_security.h", 
       "src/core/tsi/ssl_transport_security.c", 
       "src/core/tsi/ssl_transport_security.h", 
       "src/core/tsi/ssl_types.h", 
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index fc14e47325ca25ca320f4f8fd865292524265917..d81164fe6c5c7e375652ef7b24c129b0de9d5e2a 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -3863,6 +3863,28 @@
       "posix"
     ]
   }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "exclude_iomgrs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "server_request_call_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
   {
     "args": [], 
     "ci_platforms": [
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index dbc148e0f81a6335647798b4bd98a649b1ca0946..41fe1b222b70dde5fe818d2f2ae227336377693e 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -455,6 +455,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\util\json_util.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\gts_transport_security.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_types.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security.h" />
@@ -879,6 +880,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\gts_transport_security.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\tsi\transport_security.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 45d11933c1a0ccdbd788e80f7df4896d7eeb02c6..00b8705826cd791353d14fdbcd219763bd6d1521 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -538,6 +538,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.c">
       <Filter>src\core\tsi</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\gts_transport_security.c">
+      <Filter>src\core\tsi</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.c">
       <Filter>src\core\tsi</Filter>
     </ClCompile>
@@ -1319,6 +1322,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.h">
       <Filter>src\core\tsi</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\gts_transport_security.h">
+      <Filter>src\core\tsi</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.h">
       <Filter>src\core\tsi</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/server_request_call_test/server_request_call_test.vcxproj b/vsprojects/vcxproj/test/server_request_call_test/server_request_call_test.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..55511759353878d71d0a64bec52c26837cf22c18
--- /dev/null
+++ b/vsprojects/vcxproj/test/server_request_call_test/server_request_call_test.vcxproj
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{F33164EE-1406-7E49-E894-7E795146B882}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\cpptest.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\protobuf.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>server_request_call_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>server_request_call_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\server\server_request_call_test.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
+      <Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/server_request_call_test/server_request_call_test.vcxproj.filters b/vsprojects/vcxproj/test/server_request_call_test/server_request_call_test.vcxproj.filters
new file mode 100644
index 0000000000000000000000000000000000000000..a82cfb16d5d53775932cb1e5aa3dca32b81228cd
--- /dev/null
+++ b/vsprojects/vcxproj/test/server_request_call_test/server_request_call_test.vcxproj.filters
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\server\server_request_call_test.cc">
+      <Filter>test\cpp\server</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="src">
+      <UniqueIdentifier>{48583c1d-014b-ecf7-ece7-98145537c913}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto">
+      <UniqueIdentifier>{f931e5e2-7d0e-a8d9-b072-1ed8095387a3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc">
+      <UniqueIdentifier>{55f7d797-a139-d9c5-8cc3-7fde09c1d28b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\testing">
+      <UniqueIdentifier>{1b39e313-5219-fbc1-9d88-9154b406e4ba}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test">
+      <UniqueIdentifier>{613e68e0-6bd4-3936-f8c2-34e255688225}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{871d6909-5ab9-336d-41ea-380563fcd3b3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\server">
+      <UniqueIdentifier>{4939f87e-df84-7c23-cd10-c23c06c72683}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+