Merge github.com:grpc/grpc into expandification
diff --git a/BUILD b/BUILD
index fa9a120..e42505d 100644
--- a/BUILD
+++ b/BUILD
@@ -275,6 +275,7 @@
     "src/core/ext/client_config/lb_policy.h",
     "src/core/ext/client_config/lb_policy_factory.h",
     "src/core/ext/client_config/lb_policy_registry.h",
+    "src/core/ext/client_config/parse_address.h",
     "src/core/ext/client_config/resolver.h",
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_registry.h",
@@ -426,6 +427,7 @@
     "src/core/ext/client_config/lb_policy.c",
     "src/core/ext/client_config/lb_policy_factory.c",
     "src/core/ext/client_config/lb_policy_registry.c",
+    "src/core/ext/client_config/parse_address.c",
     "src/core/ext/client_config/resolver.c",
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_registry.c",
@@ -479,6 +481,7 @@
     "include/grpc/impl/codegen/sync_win32.h",
     "include/grpc/impl/codegen/time.h",
     "include/grpc/grpc_security.h",
+    "include/grpc/grpc_security_constants.h",
     "include/grpc/census.h",
   ],
   includes = [
@@ -603,6 +606,7 @@
     "src/core/ext/client_config/lb_policy.h",
     "src/core/ext/client_config/lb_policy_factory.h",
     "src/core/ext/client_config/lb_policy_registry.h",
+    "src/core/ext/client_config/parse_address.h",
     "src/core/ext/client_config/resolver.h",
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_registry.h",
@@ -736,6 +740,7 @@
     "src/core/ext/client_config/lb_policy.c",
     "src/core/ext/client_config/lb_policy_factory.c",
     "src/core/ext/client_config/lb_policy_registry.c",
+    "src/core/ext/client_config/parse_address.c",
     "src/core/ext/client_config/resolver.c",
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_registry.c",
@@ -1434,6 +1439,7 @@
     "src/core/ext/client_config/lb_policy.c",
     "src/core/ext/client_config/lb_policy_factory.c",
     "src/core/ext/client_config/lb_policy_registry.c",
+    "src/core/ext/client_config/parse_address.c",
     "src/core/ext/client_config/resolver.c",
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_registry.c",
@@ -1487,6 +1493,7 @@
     "include/grpc/impl/codegen/sync_win32.h",
     "include/grpc/impl/codegen/time.h",
     "include/grpc/grpc_security.h",
+    "include/grpc/grpc_security_constants.h",
     "include/grpc/census.h",
     "src/core/lib/channel/channel_args.h",
     "src/core/lib/channel/channel_stack.h",
@@ -1604,6 +1611,7 @@
     "src/core/ext/client_config/lb_policy.h",
     "src/core/ext/client_config/lb_policy_factory.h",
     "src/core/ext/client_config/lb_policy_registry.h",
+    "src/core/ext/client_config/parse_address.h",
     "src/core/ext/client_config/resolver.h",
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_registry.h",
diff --git a/Makefile b/Makefile
index 690b92f..ba6f893 100644
--- a/Makefile
+++ b/Makefile
@@ -1023,7 +1023,6 @@
 json_run_localhost: $(BINDIR)/$(CONFIG)/json_run_localhost
 metrics_client: $(BINDIR)/$(CONFIG)/metrics_client
 mock_test: $(BINDIR)/$(CONFIG)/mock_test
-qps_driver: $(BINDIR)/$(CONFIG)/qps_driver
 qps_interarrival_test: $(BINDIR)/$(CONFIG)/qps_interarrival_test
 qps_json_driver: $(BINDIR)/$(CONFIG)/qps_json_driver
 qps_openloop_test: $(BINDIR)/$(CONFIG)/qps_openloop_test
@@ -1077,6 +1076,7 @@
 boringssl_rsa_test: $(BINDIR)/$(CONFIG)/boringssl_rsa_test
 boringssl_thread_test: $(BINDIR)/$(CONFIG)/boringssl_thread_test
 boringssl_pkcs7_test: $(BINDIR)/$(CONFIG)/boringssl_pkcs7_test
+boringssl_x509_test: $(BINDIR)/$(CONFIG)/boringssl_x509_test
 boringssl_tab_test: $(BINDIR)/$(CONFIG)/boringssl_tab_test
 boringssl_v3name_test: $(BINDIR)/$(CONFIG)/boringssl_v3name_test
 boringssl_pqueue_test: $(BINDIR)/$(CONFIG)/boringssl_pqueue_test
@@ -1106,6 +1106,7 @@
 h2_sockpair+trace_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test
 h2_sockpair_1byte_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test
 h2_ssl_test: $(BINDIR)/$(CONFIG)/h2_ssl_test
+h2_ssl_cert_test: $(BINDIR)/$(CONFIG)/h2_ssl_cert_test
 h2_ssl_proxy_test: $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test
 h2_uds_test: $(BINDIR)/$(CONFIG)/h2_uds_test
 h2_census_nosec_test: $(BINDIR)/$(CONFIG)/h2_census_nosec_test
@@ -1197,7 +1198,7 @@
 
 pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc
 
-privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a
+privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a
 
 ifeq ($(HAS_ZOOKEEPER),true)
 privatelibs_zookeeper: 
@@ -1333,6 +1334,7 @@
   $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test \
   $(BINDIR)/$(CONFIG)/h2_ssl_test \
+  $(BINDIR)/$(CONFIG)/h2_ssl_cert_test \
   $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test \
   $(BINDIR)/$(CONFIG)/h2_uds_test \
   $(BINDIR)/$(CONFIG)/h2_census_nosec_test \
@@ -1435,6 +1437,7 @@
   $(BINDIR)/$(CONFIG)/boringssl_rsa_test \
   $(BINDIR)/$(CONFIG)/boringssl_thread_test \
   $(BINDIR)/$(CONFIG)/boringssl_pkcs7_test \
+  $(BINDIR)/$(CONFIG)/boringssl_x509_test \
   $(BINDIR)/$(CONFIG)/boringssl_tab_test \
   $(BINDIR)/$(CONFIG)/boringssl_v3name_test \
   $(BINDIR)/$(CONFIG)/boringssl_pqueue_test \
@@ -1764,7 +1767,7 @@
 
 tools_cxx: privatelibs_cxx
 
-buildbenchmarks: privatelibs $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark $(BINDIR)/$(CONFIG)/qps_driver
+buildbenchmarks: privatelibs $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark
 
 benchmarks: buildbenchmarks
 
@@ -2583,6 +2586,7 @@
     src/core/ext/client_config/lb_policy.c \
     src/core/ext/client_config/lb_policy_factory.c \
     src/core/ext/client_config/lb_policy_registry.c \
+    src/core/ext/client_config/parse_address.c \
     src/core/ext/client_config/resolver.c \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_registry.c \
@@ -2639,6 +2643,7 @@
     include/grpc/impl/codegen/sync_win32.h \
     include/grpc/impl/codegen/time.h \
     include/grpc/grpc_security.h \
+    include/grpc/grpc_security_constants.h \
     include/grpc/census.h \
 
 LIBGRPC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_SRC))))
@@ -2694,6 +2699,7 @@
 
 
 LIBGRPC_TEST_UTIL_SRC = \
+    test/core/end2end/data/client_certs.c \
     test/core/end2end/data/server1_cert.c \
     test/core/end2end/data/server1_key.c \
     test/core/end2end/data/test_root_cert.c \
@@ -2702,6 +2708,7 @@
     test/core/end2end/fixtures/proxy.c \
     test/core/iomgr/endpoint_tests.c \
     test/core/util/grpc_profiler.c \
+    test/core/util/memory_counters.c \
     test/core/util/mock_endpoint.c \
     test/core/util/parse_hexstring.c \
     test/core/util/port_posix.c \
@@ -2750,6 +2757,7 @@
     test/core/end2end/fixtures/proxy.c \
     test/core/iomgr/endpoint_tests.c \
     test/core/util/grpc_profiler.c \
+    test/core/util/memory_counters.c \
     test/core/util/mock_endpoint.c \
     test/core/util/parse_hexstring.c \
     test/core/util/port_posix.c \
@@ -2898,6 +2906,7 @@
     src/core/ext/client_config/lb_policy.c \
     src/core/ext/client_config/lb_policy_factory.c \
     src/core/ext/client_config/lb_policy_registry.c \
+    src/core/ext/client_config/parse_address.c \
     src/core/ext/client_config/resolver.c \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_registry.c \
@@ -4075,6 +4084,7 @@
     third_party/boringssl/crypto/bn/shift.c \
     third_party/boringssl/crypto/bn/sqrt.c \
     third_party/boringssl/crypto/buf/buf.c \
+    third_party/boringssl/crypto/bytestring/asn1_compat.c \
     third_party/boringssl/crypto/bytestring/ber.c \
     third_party/boringssl/crypto/bytestring/cbb.c \
     third_party/boringssl/crypto/bytestring/cbs.c \
@@ -4098,6 +4108,7 @@
     third_party/boringssl/crypto/cpu-intel.c \
     third_party/boringssl/crypto/crypto.c \
     third_party/boringssl/crypto/curve25519/curve25519.c \
+    third_party/boringssl/crypto/curve25519/x25519-x86_64.c \
     third_party/boringssl/crypto/des/des.c \
     third_party/boringssl/crypto/dh/check.c \
     third_party/boringssl/crypto/dh/dh.c \
@@ -4289,6 +4300,7 @@
     third_party/boringssl/ssl/ssl_buffer.c \
     third_party/boringssl/ssl/ssl_cert.c \
     third_party/boringssl/ssl/ssl_cipher.c \
+    third_party/boringssl/ssl/ssl_ecdh.c \
     third_party/boringssl/ssl/ssl_file.c \
     third_party/boringssl/ssl/ssl_lib.c \
     third_party/boringssl/ssl/ssl_rsa.c \
@@ -5517,6 +5529,44 @@
 endif
 
 
+LIBBORINGSSL_X509_TEST_LIB_SRC = \
+    third_party/boringssl/crypto/x509/x509_test.cc \
+
+PUBLIC_HEADERS_CXX += \
+
+LIBBORINGSSL_X509_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_X509_TEST_LIB_SRC))))
+
+$(LIBBORINGSSL_X509_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
+$(LIBBORINGSSL_X509_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a: protobuf_dep_error
+
+
+else
+
+$(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBBORINGSSL_X509_TEST_LIB_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a
+	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBBORINGSSL_X509_TEST_LIB_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a
+endif
+
+
+
+
+endif
+
+ifneq ($(NO_DEPS),true)
+-include $(LIBBORINGSSL_X509_TEST_LIB_OBJS:.o=.dep)
+endif
+
+
 LIBBORINGSSL_TAB_TEST_LIB_SRC = \
     third_party/boringssl/crypto/x509v3/tab_test.c \
 
@@ -10902,49 +10952,6 @@
 endif
 
 
-QPS_DRIVER_SRC = \
-    test/cpp/qps/qps_driver.cc \
-
-QPS_DRIVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_DRIVER_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/qps_driver: 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)/qps_driver: protobuf_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/qps_driver: $(PROTOBUF_DEP) $(QPS_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(QPS_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_driver
-
-endif
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_driver.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
-
-deps_qps_driver: $(QPS_DRIVER_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(QPS_DRIVER_OBJS:.o=.dep)
-endif
-endif
-
-
 QPS_INTERARRIVAL_TEST_SRC = \
     test/cpp/qps/qps_interarrival_test.cc \
 
@@ -12742,6 +12749,33 @@
 # boringssl needs an override to ensure that it does not include
 # system openssl headers regardless of other configuration
 # we do so here with a target specific variable assignment
+$(BORINGSSL_X509_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value
+$(BORINGSSL_X509_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS)
+$(BORINGSSL_X509_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
+
+
+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)/boringssl_x509_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/boringssl_x509_test:  $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_x509_test
+
+endif
+
+
+
+
+
+# boringssl needs an override to ensure that it does not include
+# system openssl headers regardless of other configuration
+# we do so here with a target specific variable assignment
 $(BORINGSSL_TAB_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value
 $(BORINGSSL_TAB_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS)
 $(BORINGSSL_TAB_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
@@ -13538,6 +13572,38 @@
 endif
 
 
+H2_SSL_CERT_TEST_SRC = \
+    test/core/end2end/fixtures/h2_ssl_cert.c \
+
+H2_SSL_CERT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SSL_CERT_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_cert_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_cert.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_h2_ssl_cert_test: $(H2_SSL_CERT_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(H2_SSL_CERT_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 H2_SSL_PROXY_TEST_SRC = \
     test/core/end2end/fixtures/h2_ssl_proxy.c \
 
@@ -14097,6 +14163,7 @@
 src/csharp/ext/grpc_csharp_ext.c: $(OPENSSL_DEP)
 test/core/bad_client/bad_client.c: $(OPENSSL_DEP)
 test/core/bad_ssl/server_common.c: $(OPENSSL_DEP)
+test/core/end2end/data/client_certs.c: $(OPENSSL_DEP)
 test/core/end2end/data/server1_cert.c: $(OPENSSL_DEP)
 test/core/end2end/data/server1_key.c: $(OPENSSL_DEP)
 test/core/end2end/data/test_root_cert.c: $(OPENSSL_DEP)
diff --git a/binding.gyp b/binding.gyp
index 8efc8a2..e6c31ed 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -223,6 +223,7 @@
             'third_party/boringssl/crypto/bn/shift.c',
             'third_party/boringssl/crypto/bn/sqrt.c',
             'third_party/boringssl/crypto/buf/buf.c',
+            'third_party/boringssl/crypto/bytestring/asn1_compat.c',
             'third_party/boringssl/crypto/bytestring/ber.c',
             'third_party/boringssl/crypto/bytestring/cbb.c',
             'third_party/boringssl/crypto/bytestring/cbs.c',
@@ -246,6 +247,7 @@
             'third_party/boringssl/crypto/cpu-intel.c',
             'third_party/boringssl/crypto/crypto.c',
             'third_party/boringssl/crypto/curve25519/curve25519.c',
+            'third_party/boringssl/crypto/curve25519/x25519-x86_64.c',
             'third_party/boringssl/crypto/des/des.c',
             'third_party/boringssl/crypto/dh/check.c',
             'third_party/boringssl/crypto/dh/dh.c',
@@ -437,6 +439,7 @@
             'third_party/boringssl/ssl/ssl_buffer.c',
             'third_party/boringssl/ssl/ssl_cert.c',
             'third_party/boringssl/ssl/ssl_cipher.c',
+            'third_party/boringssl/ssl/ssl_ecdh.c',
             'third_party/boringssl/ssl/ssl_file.c',
             'third_party/boringssl/ssl/ssl_lib.c',
             'third_party/boringssl/ssl/ssl_rsa.c',
@@ -694,6 +697,7 @@
         'src/core/ext/client_config/lb_policy.c',
         'src/core/ext/client_config/lb_policy_factory.c',
         'src/core/ext/client_config/lb_policy_registry.c',
+        'src/core/ext/client_config/parse_address.c',
         'src/core/ext/client_config/resolver.c',
         'src/core/ext/client_config/resolver_factory.c',
         'src/core/ext/client_config/resolver_registry.c',
diff --git a/build.yaml b/build.yaml
index e274b03..23bf4ae 100644
--- a/build.yaml
+++ b/build.yaml
@@ -442,6 +442,7 @@
   - src/core/ext/client_config/lb_policy.h
   - src/core/ext/client_config/lb_policy_factory.h
   - src/core/ext/client_config/lb_policy_registry.h
+  - src/core/ext/client_config/parse_address.h
   - src/core/ext/client_config/resolver.h
   - src/core/ext/client_config/resolver_factory.h
   - src/core/ext/client_config/resolver_registry.h
@@ -461,6 +462,7 @@
   - src/core/ext/client_config/lb_policy.c
   - src/core/ext/client_config/lb_policy_factory.c
   - src/core/ext/client_config/lb_policy_registry.c
+  - src/core/ext/client_config/parse_address.c
   - src/core/ext/client_config/resolver.c
   - src/core/ext/client_config/resolver_factory.c
   - src/core/ext/client_config/resolver_registry.c
@@ -523,6 +525,7 @@
 - name: grpc_secure
   public_headers:
   - include/grpc/grpc_security.h
+  - include/grpc/grpc_security_constants.h
   headers:
   - src/core/lib/security/auth_filters.h
   - src/core/lib/security/b64.h
@@ -567,6 +570,7 @@
   - test/core/end2end/fixtures/proxy.h
   - test/core/iomgr/endpoint_tests.h
   - test/core/util/grpc_profiler.h
+  - test/core/util/memory_counters.h
   - test/core/util/mock_endpoint.h
   - test/core/util/parse_hexstring.h
   - test/core/util/port.h
@@ -577,6 +581,7 @@
   - test/core/end2end/fixtures/proxy.c
   - test/core/iomgr/endpoint_tests.c
   - test/core/util/grpc_profiler.c
+  - test/core/util/memory_counters.c
   - test/core/util/mock_endpoint.c
   - test/core/util/parse_hexstring.c
   - test/core/util/port_posix.c
@@ -751,6 +756,7 @@
   - test/core/end2end/data/ssl_test_data.h
   - test/core/security/oauth2_utils.h
   src:
+  - test/core/end2end/data/client_certs.c
   - test/core/end2end/data/server1_cert.c
   - test/core/end2end/data/server1_key.c
   - test/core/end2end/data/test_root_cert.c
@@ -1183,6 +1189,7 @@
   - gpr
   corpus_dirs:
   - test/core/end2end/fuzzers/client_fuzzer_corpus
+  dict: test/core/end2end/fuzzers/hpack.dictionary
   maxlen: 2048
 - name: compression_test
   build: test
@@ -1672,6 +1679,7 @@
   - gpr
   corpus_dirs:
   - test/core/transport/chttp2/hpack_parser_corpus
+  dict: test/core/end2end/fuzzers/hpack.dictionary
   maxlen: 512
 - name: hpack_parser_test
   build: test
@@ -2023,6 +2031,7 @@
   - gpr
   corpus_dirs:
   - test/core/end2end/fuzzers/server_fuzzer_corpus
+  dict: test/core/end2end/fuzzers/hpack.dictionary
   maxlen: 2048
 - name: server_test
   build: test
@@ -2699,20 +2708,6 @@
   - grpc
   - gpr_test_util
   - gpr
-- name: qps_driver
-  build: benchmark
-  language: c++
-  src:
-  - test/cpp/qps/qps_driver.cc
-  deps:
-  - qps
-  - grpc++_test_util
-  - grpc_test_util
-  - grpc++
-  - grpc
-  - gpr_test_util
-  - gpr
-  - grpc++_test_config
 - name: qps_interarrival_test
   build: test
   run: false
diff --git a/config.m4 b/config.m4
index 7d3d899..d787614 100644
--- a/config.m4
+++ b/config.m4
@@ -216,6 +216,7 @@
     src/core/ext/client_config/lb_policy.c \
     src/core/ext/client_config/lb_policy_factory.c \
     src/core/ext/client_config/lb_policy_registry.c \
+    src/core/ext/client_config/parse_address.c \
     src/core/ext/client_config/resolver.c \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_registry.c \
@@ -316,6 +317,7 @@
     third_party/boringssl/crypto/bn/shift.c \
     third_party/boringssl/crypto/bn/sqrt.c \
     third_party/boringssl/crypto/buf/buf.c \
+    third_party/boringssl/crypto/bytestring/asn1_compat.c \
     third_party/boringssl/crypto/bytestring/ber.c \
     third_party/boringssl/crypto/bytestring/cbb.c \
     third_party/boringssl/crypto/bytestring/cbs.c \
@@ -339,6 +341,7 @@
     third_party/boringssl/crypto/cpu-intel.c \
     third_party/boringssl/crypto/crypto.c \
     third_party/boringssl/crypto/curve25519/curve25519.c \
+    third_party/boringssl/crypto/curve25519/x25519-x86_64.c \
     third_party/boringssl/crypto/des/des.c \
     third_party/boringssl/crypto/dh/check.c \
     third_party/boringssl/crypto/dh/dh.c \
@@ -530,6 +533,7 @@
     third_party/boringssl/ssl/ssl_buffer.c \
     third_party/boringssl/ssl/ssl_cert.c \
     third_party/boringssl/ssl/ssl_cipher.c \
+    third_party/boringssl/ssl/ssl_ecdh.c \
     third_party/boringssl/ssl/ssl_file.c \
     third_party/boringssl/ssl/ssl_lib.c \
     third_party/boringssl/ssl/ssl_rsa.c \
diff --git a/gRPC.podspec b/gRPC.podspec
index 82c5eaa..859c2c9 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -277,6 +277,7 @@
                       'src/core/ext/client_config/lb_policy.h',
                       'src/core/ext/client_config/lb_policy_factory.h',
                       'src/core/ext/client_config/lb_policy_registry.h',
+                      'src/core/ext/client_config/parse_address.h',
                       'src/core/ext/client_config/resolver.h',
                       'src/core/ext/client_config/resolver_factory.h',
                       'src/core/ext/client_config/resolver_registry.h',
@@ -322,6 +323,7 @@
                       'include/grpc/impl/codegen/sync_win32.h',
                       'include/grpc/impl/codegen/time.h',
                       'include/grpc/grpc_security.h',
+                      'include/grpc/grpc_security_constants.h',
                       'include/grpc/census.h',
                       'src/core/lib/channel/channel_args.c',
                       'src/core/lib/channel/channel_stack.c',
@@ -459,6 +461,7 @@
                       'src/core/ext/client_config/lb_policy.c',
                       'src/core/ext/client_config/lb_policy_factory.c',
                       'src/core/ext/client_config/lb_policy_registry.c',
+                      'src/core/ext/client_config/parse_address.c',
                       'src/core/ext/client_config/resolver.c',
                       'src/core/ext/client_config/resolver_factory.c',
                       'src/core/ext/client_config/resolver_registry.c',
@@ -616,6 +619,7 @@
                               'src/core/ext/client_config/lb_policy.h',
                               'src/core/ext/client_config/lb_policy_factory.h',
                               'src/core/ext/client_config/lb_policy_registry.h',
+                              'src/core/ext/client_config/parse_address.h',
                               'src/core/ext/client_config/resolver.h',
                               'src/core/ext/client_config/resolver_factory.h',
                               'src/core/ext/client_config/resolver_registry.h',
diff --git a/grpc.def b/grpc.def
index f81aa1b..6542c06 100644
--- a/grpc.def
+++ b/grpc.def
@@ -114,6 +114,7 @@
     grpc_secure_channel_create
     grpc_server_credentials_release
     grpc_ssl_server_credentials_create
+    grpc_ssl_server_credentials_create_ex
     grpc_server_add_secure_http2_port
     grpc_call_set_credentials
     grpc_server_credentials_set_auth_metadata_processor
@@ -136,6 +137,8 @@
     grpc_raw_byte_buffer_from_reader
     gpr_log
     gpr_log_message
+    gpr_set_log_verbosity
+    gpr_log_verbosity_init
     gpr_set_log_function
     gpr_slice_ref
     gpr_slice_unref
diff --git a/grpc.gemspec b/grpc.gemspec
index b05f238..e94294f 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -35,6 +35,7 @@
   s.add_dependency 'googleauth',      '~> 0.5.1'
 
   s.add_development_dependency 'bundler',            '~> 1.9'
+  s.add_development_dependency 'facter',             '~> 2.4'
   s.add_development_dependency 'logging',            '~> 2.0'
   s.add_development_dependency 'simplecov',          '~> 0.9'
   s.add_development_dependency 'rake',               '~> 10.4'
@@ -170,6 +171,7 @@
   s.files += %w( include/grpc/impl/codegen/sync_win32.h )
   s.files += %w( include/grpc/impl/codegen/time.h )
   s.files += %w( include/grpc/grpc_security.h )
+  s.files += %w( include/grpc/grpc_security_constants.h )
   s.files += %w( include/grpc/census.h )
   s.files += %w( src/core/lib/channel/channel_args.h )
   s.files += %w( src/core/lib/channel/channel_stack.h )
@@ -287,6 +289,7 @@
   s.files += %w( src/core/ext/client_config/lb_policy.h )
   s.files += %w( src/core/ext/client_config/lb_policy_factory.h )
   s.files += %w( src/core/ext/client_config/lb_policy_registry.h )
+  s.files += %w( src/core/ext/client_config/parse_address.h )
   s.files += %w( src/core/ext/client_config/resolver.h )
   s.files += %w( src/core/ext/client_config/resolver_factory.h )
   s.files += %w( src/core/ext/client_config/resolver_registry.h )
@@ -442,6 +445,7 @@
   s.files += %w( src/core/ext/client_config/lb_policy.c )
   s.files += %w( src/core/ext/client_config/lb_policy_factory.c )
   s.files += %w( src/core/ext/client_config/lb_policy_registry.c )
+  s.files += %w( src/core/ext/client_config/parse_address.c )
   s.files += %w( src/core/ext/client_config/resolver.c )
   s.files += %w( src/core/ext/client_config/resolver_factory.c )
   s.files += %w( src/core/ext/client_config/resolver_registry.c )
@@ -479,12 +483,12 @@
   s.files += %w( third_party/boringssl/crypto/cipher/internal.h )
   s.files += %w( third_party/boringssl/crypto/conf/conf_def.h )
   s.files += %w( third_party/boringssl/crypto/conf/internal.h )
+  s.files += %w( third_party/boringssl/crypto/curve25519/internal.h )
   s.files += %w( third_party/boringssl/crypto/des/internal.h )
   s.files += %w( third_party/boringssl/crypto/dh/internal.h )
   s.files += %w( third_party/boringssl/crypto/digest/internal.h )
   s.files += %w( third_party/boringssl/crypto/digest/md32_common.h )
   s.files += %w( third_party/boringssl/crypto/directory.h )
-  s.files += %w( third_party/boringssl/crypto/dsa/internal.h )
   s.files += %w( third_party/boringssl/crypto/ec/internal.h )
   s.files += %w( third_party/boringssl/crypto/ec/p256-x86_64-table.h )
   s.files += %w( third_party/boringssl/crypto/evp/internal.h )
@@ -649,6 +653,7 @@
   s.files += %w( third_party/boringssl/crypto/bn/shift.c )
   s.files += %w( third_party/boringssl/crypto/bn/sqrt.c )
   s.files += %w( third_party/boringssl/crypto/buf/buf.c )
+  s.files += %w( third_party/boringssl/crypto/bytestring/asn1_compat.c )
   s.files += %w( third_party/boringssl/crypto/bytestring/ber.c )
   s.files += %w( third_party/boringssl/crypto/bytestring/cbb.c )
   s.files += %w( third_party/boringssl/crypto/bytestring/cbs.c )
@@ -672,6 +677,7 @@
   s.files += %w( third_party/boringssl/crypto/cpu-intel.c )
   s.files += %w( third_party/boringssl/crypto/crypto.c )
   s.files += %w( third_party/boringssl/crypto/curve25519/curve25519.c )
+  s.files += %w( third_party/boringssl/crypto/curve25519/x25519-x86_64.c )
   s.files += %w( third_party/boringssl/crypto/des/des.c )
   s.files += %w( third_party/boringssl/crypto/dh/check.c )
   s.files += %w( third_party/boringssl/crypto/dh/dh.c )
@@ -863,6 +869,7 @@
   s.files += %w( third_party/boringssl/ssl/ssl_buffer.c )
   s.files += %w( third_party/boringssl/ssl/ssl_cert.c )
   s.files += %w( third_party/boringssl/ssl/ssl_cipher.c )
+  s.files += %w( third_party/boringssl/ssl/ssl_ecdh.c )
   s.files += %w( third_party/boringssl/ssl/ssl_file.c )
   s.files += %w( third_party/boringssl/ssl/ssl_lib.c )
   s.files += %w( third_party/boringssl/ssl/ssl_rsa.c )
diff --git a/include/grpc++/security/server_credentials.h b/include/grpc++/security/server_credentials.h
index 5a9f8a4..229bab8 100644
--- a/include/grpc++/security/server_credentials.h
+++ b/include/grpc++/security/server_credentials.h
@@ -39,6 +39,7 @@
 
 #include <grpc++/security/auth_metadata_processor.h>
 #include <grpc++/support/config.h>
+#include <grpc/grpc_security_constants.h>
 
 struct grpc_server;
 
@@ -69,7 +70,13 @@
 
 /// Options to create ServerCredentials with SSL
 struct SslServerCredentialsOptions {
-  SslServerCredentialsOptions() : force_client_auth(false) {}
+  // Deprecated
+  SslServerCredentialsOptions()
+      : force_client_auth(false),
+        client_certificate_request(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE) {}
+  SslServerCredentialsOptions(
+      grpc_ssl_client_certificate_request_type request_type)
+      : force_client_auth(false), client_certificate_request(request_type) {}
 
   struct PemKeyCertPair {
     grpc::string private_key;
@@ -77,7 +84,13 @@
   };
   grpc::string pem_root_certs;
   std::vector<PemKeyCertPair> pem_key_cert_pairs;
+  // Deprecated
   bool force_client_auth;
+
+  // If both force_client_auth and client_certificate_request fields are set,
+  // force_client_auth takes effect i.e
+  // REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY will be enforced.
+  grpc_ssl_client_certificate_request_type client_certificate_request;
 };
 
 /// Builds SSL ServerCredentials given SSL specific options
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index a36926b..79199cc 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -35,6 +35,7 @@
 #define GRPC_GRPC_SECURITY_H
 
 #include <grpc/grpc.h>
+#include <grpc/grpc_security_constants.h>
 #include <grpc/status.h>
 
 #ifdef __cplusplus
@@ -43,13 +44,6 @@
 
 /* --- Authentication Context. --- */
 
-#define GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME "transport_security_type"
-#define GRPC_SSL_TRANSPORT_SECURITY_TYPE "ssl"
-
-#define GRPC_X509_CN_PROPERTY_NAME "x509_common_name"
-#define GRPC_X509_SAN_PROPERTY_NAME "x509_subject_alternative_name"
-#define GRPC_X509_PEM_CERT_PROPERTY_NAME "x509_pem_cert"
-
 typedef struct grpc_auth_context grpc_auth_context;
 
 typedef struct grpc_auth_property_iterator {
@@ -130,29 +124,11 @@
    The creator of the credentials object is responsible for its release. */
 GRPCAPI void grpc_channel_credentials_release(grpc_channel_credentials *creds);
 
-/* Environment variable that points to the google default application
-   credentials json key or refresh token. Used in the
-   grpc_google_default_credentials_create function. */
-#define GRPC_GOOGLE_CREDENTIALS_ENV_VAR "GOOGLE_APPLICATION_CREDENTIALS"
-
 /* Creates default credentials to connect to a google gRPC service.
    WARNING: Do NOT use this credentials to connect to a non-google service as
    this could result in an oauth2 token leak. */
 GRPCAPI grpc_channel_credentials *grpc_google_default_credentials_create(void);
 
-/* Environment variable that points to the default SSL roots file. This file
-   must be a PEM encoded file with all the roots such as the one that can be
-   downloaded from https://pki.google.com/roots.pem.  */
-#define GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR \
-  "GRPC_DEFAULT_SSL_ROOTS_FILE_PATH"
-
-/* Results for the SSL roots override callback. */
-typedef enum {
-  GRPC_SSL_ROOTS_OVERRIDE_OK,
-  GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY, /* Do not try fallback options. */
-  GRPC_SSL_ROOTS_OVERRIDE_FAIL
-} grpc_ssl_roots_override_result;
-
 /* Callback for getting the SSL roots override from the application.
    In case of success, *pem_roots_certs must be set to a NULL terminated string
    containing the list of PEM encoded root certificates. The ownership is passed
@@ -334,7 +310,8 @@
    */
 GRPCAPI void grpc_server_credentials_release(grpc_server_credentials *creds);
 
-/* Creates an SSL server_credentials object.
+/* Deprecated in favor of grpc_ssl_server_credentials_create_ex.
+   Creates an SSL server_credentials object.
    - pem_roots_cert is the NULL-terminated string containing the PEM encoding of
      the client root certificates. This parameter may be NULL if the server does
      not want the client to be authenticated with SSL.
@@ -349,6 +326,15 @@
     const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
     size_t num_key_cert_pairs, int force_client_auth, void *reserved);
 
+/* Same as grpc_ssl_server_credentials_create method except uses
+   grpc_ssl_client_certificate_request_type enum to support more ways to
+   authenticate client cerificates.*/
+GRPCAPI grpc_server_credentials *grpc_ssl_server_credentials_create_ex(
+    const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+    size_t num_key_cert_pairs,
+    grpc_ssl_client_certificate_request_type client_certificate_request,
+    void *reserved);
+
 /* --- Server-side secure ports. --- */
 
 /* Add a HTTP2 over an encrypted link over tcp listener.
diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h
new file mode 100644
index 0000000..da05c5a
--- /dev/null
+++ b/include/grpc/grpc_security_constants.h
@@ -0,0 +1,114 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_GRPC_SECURITY_CONSTANTS_H
+#define GRPC_GRPC_SECURITY_CONSTANTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME "transport_security_type"
+#define GRPC_SSL_TRANSPORT_SECURITY_TYPE "ssl"
+
+#define GRPC_X509_CN_PROPERTY_NAME "x509_common_name"
+#define GRPC_X509_SAN_PROPERTY_NAME "x509_subject_alternative_name"
+#define GRPC_X509_PEM_CERT_PROPERTY_NAME "x509_pem_cert"
+
+/* Environment variable that points to the default SSL roots file. This file
+   must be a PEM encoded file with all the roots such as the one that can be
+   downloaded from https://pki.google.com/roots.pem.  */
+#define GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR \
+  "GRPC_DEFAULT_SSL_ROOTS_FILE_PATH"
+
+/* Environment variable that points to the google default application
+   credentials json key or refresh token. Used in the
+   grpc_google_default_credentials_create function. */
+#define GRPC_GOOGLE_CREDENTIALS_ENV_VAR "GOOGLE_APPLICATION_CREDENTIALS"
+
+/* Results for the SSL roots override callback. */
+typedef enum {
+  GRPC_SSL_ROOTS_OVERRIDE_OK,
+  GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY, /* Do not try fallback options. */
+  GRPC_SSL_ROOTS_OVERRIDE_FAIL
+} grpc_ssl_roots_override_result;
+
+typedef enum {
+  /* Server does not request client certificate. A client can present a self
+     signed or signed certificates if it wishes to do so and they would be
+     accepted. */
+  GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
+  /* Server requests client certificate but does not enforce that the client
+     presents a certificate.
+
+     If the client presents a certificate, the client authentication is left to
+     the application based on the metadata like certificate etc.
+
+     The key cert pair should still be valid for the SSL connection to be
+     established. */
+  GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY,
+  /* Server requests client certificate but does not enforce that the client
+     presents a certificate.
+
+     If the client presents a certificate, the client authentication is done by
+     grpc framework (The client needs to either present a signed cert or skip no
+     certificate for a successful connection).
+
+     The key cert pair should still be valid for the SSL connection to be
+     established. */
+  GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY,
+  /* Server requests client certificate but enforces that the client presents a
+     certificate.
+
+     If the client presents a certificate, the client authentication is left to
+     the application based on the metadata like certificate etc.
+
+     The key cert pair should still be valid for the SSL connection to be
+     established. */
+  GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY,
+  /* Server requests client certificate but enforces that the client presents a
+     certificate.
+
+     The cerificate presented by the client is verified by grpc framework (The
+     client needs to present signed certs for a successful connection).
+
+     The key cert pair should still be valid for the SSL connection to be
+     established. */
+  GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+} grpc_ssl_client_certificate_request_type;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_GRPC_SECURITY_CONSTANTS_H */
diff --git a/include/grpc/impl/codegen/log.h b/include/grpc/impl/codegen/log.h
index 0853350..aa86fc4 100644
--- a/include/grpc/impl/codegen/log.h
+++ b/include/grpc/impl/codegen/log.h
@@ -61,6 +61,8 @@
   GPR_LOG_SEVERITY_ERROR
 } gpr_log_severity;
 
+#define GPR_LOG_VERBOSITY_UNSET -1
+
 /* Returns a string representation of the log severity */
 const char *gpr_log_severity_string(gpr_log_severity severity);
 
@@ -77,6 +79,11 @@
 GPRAPI void gpr_log_message(const char *file, int line,
                             gpr_log_severity severity, const char *message);
 
+/* Set global log verbosity */
+GPRAPI void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print);
+
+GPRAPI void gpr_log_verbosity_init();
+
 /* Log overrides: applications can use this API to intercept logging calls
    and use their own implementations */
 
diff --git a/include/grpc/support/string_util.h b/include/grpc/support/string_util.h
index 0abdb4a..f981bc0 100644
--- a/include/grpc/support/string_util.h
+++ b/include/grpc/support/string_util.h
@@ -34,6 +34,8 @@
 #ifndef GRPC_SUPPORT_STRING_UTIL_H
 #define GRPC_SUPPORT_STRING_UTIL_H
 
+#include <grpc/support/port_platform.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/package.xml b/package.xml
index 2f4c625..716250c 100644
--- a/package.xml
+++ b/package.xml
@@ -174,6 +174,7 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_win32.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/time.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/grpc_security_constants.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/census.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_args.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_stack.h" role="src" />
@@ -291,6 +292,7 @@
     <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy_registry.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/client_config/parse_address.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_registry.h" role="src" />
@@ -446,6 +448,7 @@
     <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy_registry.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/client_config/parse_address.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_registry.c" role="src" />
@@ -483,12 +486,12 @@
     <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/internal.h" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/conf/conf_def.h" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/conf/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/curve25519/internal.h" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/des/internal.h" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/dh/internal.h" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/digest/internal.h" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/digest/md32_common.h" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/directory.h" role="src" />
-    <file baseinstalldir="/" name="third_party/boringssl/crypto/dsa/internal.h" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/internal.h" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/p256-x86_64-table.h" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/internal.h" role="src" />
@@ -653,6 +656,7 @@
     <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/shift.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/sqrt.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/buf/buf.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bytestring/asn1_compat.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/bytestring/ber.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/bytestring/cbb.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/bytestring/cbs.c" role="src" />
@@ -676,6 +680,7 @@
     <file baseinstalldir="/" name="third_party/boringssl/crypto/cpu-intel.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/crypto.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/curve25519/curve25519.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/curve25519/x25519-x86_64.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/des/des.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/dh/check.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/crypto/dh/dh.c" role="src" />
@@ -867,6 +872,7 @@
     <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_buffer.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_cert.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_cipher.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_ecdh.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_file.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_lib.c" role="src" />
     <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_rsa.c" role="src" />
diff --git a/src/boringssl/err_data.c b/src/boringssl/err_data.c
index 1a1d950..d4cc08b 100644
--- a/src/boringssl/err_data.c
+++ b/src/boringssl/err_data.c
@@ -54,30 +54,30 @@
 OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num);
 
 const uint32_t kOpenSSLReasonValues[] = {
-    0xc3207ba,
-    0xc3287d4,
-    0xc3307e3,
-    0xc3387f3,
-    0xc340802,
-    0xc34881b,
-    0xc350827,
-    0xc358844,
-    0xc360856,
-    0xc368864,
-    0xc370874,
-    0xc378881,
-    0xc380891,
-    0xc38889c,
-    0xc3908b2,
-    0xc3988c1,
-    0xc3a08d5,
-    0xc3a87c7,
+    0xc3207ab,
+    0xc3287c5,
+    0xc3307d4,
+    0xc3387e4,
+    0xc3407f3,
+    0xc34880c,
+    0xc350818,
+    0xc358835,
+    0xc360847,
+    0xc368855,
+    0xc370865,
+    0xc378872,
+    0xc380882,
+    0xc38888d,
+    0xc3908a3,
+    0xc3988b2,
+    0xc3a08c6,
+    0xc3a87b8,
     0xc3b00b0,
-    0x10321478,
-    0x10329484,
-    0x1033149d,
-    0x103394b0,
-    0x10340de1,
+    0x10321484,
+    0x10329490,
+    0x103314a9,
+    0x103394bc,
+    0x10340ded,
     0x103494cf,
     0x103514e4,
     0x10359516,
@@ -97,7 +97,7 @@
     0x103c9658,
     0x103d166f,
     0x103d9682,
-    0x103e0b6c,
+    0x103e0b5d,
     0x103e96b3,
     0x103f16c6,
     0x103f96e0,
@@ -108,87 +108,91 @@
     0x10421747,
     0x1042975b,
     0x1043176d,
-    0x104385d0,
-    0x104408c1,
+    0x104385c1,
+    0x104408b2,
     0x10449782,
     0x10451799,
     0x104597ae,
     0x104617bc,
     0x10469695,
     0x104714f7,
-    0x104787c7,
+    0x104787b8,
     0x104800b0,
-    0x104894c3,
-    0x14320b4f,
-    0x14328b5d,
-    0x14330b6c,
-    0x14338b7e,
+    0x10488b8c,
+    0x14320b40,
+    0x14328b4e,
+    0x14330b5d,
+    0x14338b6f,
     0x18320083,
-    0x18328e47,
-    0x18340e75,
-    0x18348e89,
-    0x18358ec0,
-    0x18368eed,
-    0x18370f00,
-    0x18378f14,
-    0x18380f38,
-    0x18388f46,
-    0x18390f5c,
-    0x18398f70,
-    0x183a0f80,
-    0x183b0f90,
-    0x183b8fa5,
-    0x183c8fd0,
-    0x183d0fe4,
-    0x183d8ff4,
-    0x183e0b9b,
-    0x183e9001,
-    0x183f1013,
-    0x183f901e,
-    0x1840102e,
-    0x1840903f,
-    0x18411050,
-    0x18419062,
-    0x1842108b,
-    0x184290bd,
-    0x184310cc,
-    0x18451135,
-    0x1845914b,
-    0x18461166,
-    0x18468ed8,
-    0x184709d9,
+    0x18328e53,
+    0x18340e81,
+    0x18348e95,
+    0x18358ecc,
+    0x18368ef9,
+    0x18370f0c,
+    0x18378f20,
+    0x18380f44,
+    0x18388f52,
+    0x18390f68,
+    0x18398f7c,
+    0x183a0f8c,
+    0x183b0f9c,
+    0x183b8fb1,
+    0x183c8fdc,
+    0x183d0ff0,
+    0x183d9000,
+    0x183e0b98,
+    0x183e900d,
+    0x183f101f,
+    0x183f902a,
+    0x1840103a,
+    0x1840904b,
+    0x1841105c,
+    0x1841906e,
+    0x18421097,
+    0x184290c9,
+    0x184310d8,
+    0x18451141,
+    0x18459157,
+    0x18461172,
+    0x18468ee4,
+    0x184709ca,
     0x18478094,
-    0x18480fbc,
-    0x18489101,
-    0x18490e5d,
-    0x18498e9e,
-    0x184a119c,
-    0x184a9119,
-    0x184b10e0,
-    0x184b8e37,
-    0x184c10a4,
-    0x184c866b,
-    0x184d1181,
-    0x203211c3,
-    0x243211cf,
-    0x24328907,
-    0x243311e1,
-    0x243391ee,
-    0x243411fb,
-    0x2434920d,
-    0x2435121c,
-    0x24359239,
-    0x24361246,
-    0x24369254,
-    0x24371262,
-    0x24379270,
-    0x24381279,
-    0x24389286,
-    0x24391299,
-    0x28320b8f,
-    0x28328b9b,
-    0x28330b6c,
-    0x28338bae,
+    0x18480fc8,
+    0x1848910d,
+    0x18490e69,
+    0x18498eaa,
+    0x184a11a8,
+    0x184a9125,
+    0x184b10ec,
+    0x184b8e43,
+    0x184c10b0,
+    0x184c865c,
+    0x184d118d,
+    0x184d80b0,
+    0x203211cf,
+    0x243211db,
+    0x243288f8,
+    0x243311ed,
+    0x243391fa,
+    0x24341207,
+    0x24349219,
+    0x24351228,
+    0x24359245,
+    0x24361252,
+    0x24369260,
+    0x2437126e,
+    0x2437927c,
+    0x24381285,
+    0x24389292,
+    0x243912a5,
+    0x28320b80,
+    0x28328b98,
+    0x28330b5d,
+    0x28338bab,
+    0x28340b8c,
+    0x28348094,
+    0x283500b0,
     0x2c32281d,
     0x2c32a82b,
     0x2c33283d,
@@ -207,7 +211,7 @@
     0x2c39a917,
     0x2c3a292b,
     0x2c3aa93c,
-    0x2c3b1359,
+    0x2c3b1365,
     0x2c3ba94d,
     0x2c3c2961,
     0x2c3ca977,
@@ -219,12 +223,12 @@
     0x2c3faa09,
     0x2c402a2c,
     0x2c40aa4b,
-    0x2c4111c3,
+    0x2c4111cf,
     0x2c41aa5c,
     0x2c422a6f,
-    0x2c429135,
+    0x2c429141,
     0x2c432a80,
-    0x2c4386a2,
+    0x2c438693,
     0x2c4429ad,
     0x30320000,
     0x30328015,
@@ -277,77 +281,79 @@
     0x304a03b4,
     0x304a83c7,
     0x304b03d2,
-    0x304b83e1,
-    0x304c03f2,
-    0x304c83fe,
-    0x304d0414,
-    0x304d8422,
-    0x304e0438,
-    0x304e844a,
-    0x304f045c,
-    0x304f846f,
-    0x30500482,
-    0x30508493,
-    0x305104a3,
-    0x305184bb,
-    0x305204d0,
-    0x305284e8,
-    0x305304fc,
-    0x30538514,
-    0x3054052d,
-    0x30548546,
-    0x30550563,
-    0x3055856e,
-    0x30560586,
-    0x30568596,
-    0x305705a7,
-    0x305785ba,
-    0x305805d0,
-    0x305885d9,
-    0x305905ee,
+    0x304b83e3,
+    0x304c03ef,
+    0x304c8405,
+    0x304d0413,
+    0x304d8429,
+    0x304e043b,
+    0x304e844d,
+    0x304f0460,
+    0x304f8473,
+    0x30500484,
+    0x30508494,
+    0x305104ac,
+    0x305184c1,
+    0x305204d9,
+    0x305284ed,
+    0x30530505,
+    0x3053851e,
+    0x30540537,
+    0x30548554,
+    0x3055055f,
+    0x30558577,
+    0x30560587,
+    0x30568598,
+    0x305705ab,
+    0x305785c1,
+    0x305805ca,
+    0x305885df,
+    0x305905f2,
     0x30598601,
-    0x305a0610,
+    0x305a0621,
     0x305a8630,
-    0x305b063f,
-    0x305b864b,
-    0x305c066b,
-    0x305c8687,
-    0x305d0698,
-    0x305d86a2,
-    0x34320ac9,
-    0x34328add,
-    0x34330afa,
-    0x34338b0d,
-    0x34340b1c,
-    0x34348b39,
+    0x305b063c,
+    0x305b865c,
+    0x305c0678,
+    0x305c8689,
+    0x305d0693,
+    0x34320aba,
+    0x34328ace,
+    0x34330aeb,
+    0x34338afe,
+    0x34340b0d,
+    0x34348b2a,
     0x3c320083,
-    0x3c328bd8,
-    0x3c330bf1,
-    0x3c338c0c,
-    0x3c340c29,
-    0x3c348c44,
-    0x3c350c5f,
-    0x3c358c74,
-    0x3c360c8d,
-    0x3c368ca5,
-    0x3c370cb6,
-    0x3c378cc4,
-    0x3c380cd1,
-    0x3c388ce5,
-    0x3c390b9b,
-    0x3c398cf9,
-    0x3c3a0d0d,
-    0x3c3a8881,
-    0x3c3b0d1d,
-    0x3c3b8d38,
-    0x3c3c0d4a,
-    0x3c3c8d60,
-    0x3c3d0d6a,
-    0x3c3d8d7e,
-    0x3c3e0d8c,
-    0x3c3e8db1,
-    0x3c3f0bc4,
-    0x3c3f8d9a,
+    0x3c328bd5,
+    0x3c330bee,
+    0x3c338c09,
+    0x3c340c26,
+    0x3c348c50,
+    0x3c350c6b,
+    0x3c358c80,
+    0x3c360c99,
+    0x3c368cb1,
+    0x3c370cc2,
+    0x3c378cd0,
+    0x3c380cdd,
+    0x3c388cf1,
+    0x3c390b98,
+    0x3c398d05,
+    0x3c3a0d19,
+    0x3c3a8872,
+    0x3c3b0d29,
+    0x3c3b8d44,
+    0x3c3c0d56,
+    0x3c3c8d6c,
+    0x3c3d0d76,
+    0x3c3d8d8a,
+    0x3c3e0d98,
+    0x3c3e8dbd,
+    0x3c3f0bc1,
+    0x3c3f8da6,
+    0x3c400094,
+    0x3c4080b0,
+    0x3c410c41,
     0x403217d3,
     0x403297e9,
     0x40331817,
@@ -362,7 +368,7 @@
     0x403798b8,
     0x403818c3,
     0x403898d5,
-    0x40390de1,
+    0x40390ded,
     0x403998e5,
     0x403a18f8,
     0x403a9919,
@@ -437,7 +443,7 @@
     0x405d1e9e,
     0x405d9eb5,
     0x405e1ed5,
-    0x405e8a17,
+    0x405e8a08,
     0x405f1ef6,
     0x405f9f03,
     0x40601f11,
@@ -474,18 +480,18 @@
     0x406fa60d,
     0x40702620,
     0x4070a63d,
-    0x40710782,
+    0x40710773,
     0x4071a64f,
     0x40722662,
     0x4072a67b,
     0x40732693,
-    0x407390bd,
+    0x407390c9,
     0x407426a7,
     0x4074a6c1,
     0x407526d2,
     0x4075a6e6,
     0x407626f4,
-    0x40769286,
+    0x40769292,
     0x40772719,
     0x4077a73b,
     0x40782756,
@@ -528,48 +534,48 @@
     0x422c251d,
     0x422ca4d8,
     0x422d24b7,
-    0x443206ad,
-    0x443286bc,
-    0x443306c8,
-    0x443386d6,
-    0x443406e9,
-    0x443486fa,
-    0x44350701,
-    0x4435870b,
-    0x4436071e,
-    0x44368734,
-    0x44370746,
-    0x44378753,
-    0x44380762,
-    0x4438876a,
-    0x44390782,
-    0x44398790,
-    0x443a07a3,
-    0x4c3212b0,
-    0x4c3292c0,
-    0x4c3312d3,
-    0x4c3392f3,
+    0x4432069e,
+    0x443286ad,
+    0x443306b9,
+    0x443386c7,
+    0x443406da,
+    0x443486eb,
+    0x443506f2,
+    0x443586fc,
+    0x4436070f,
+    0x44368725,
+    0x44370737,
+    0x44378744,
+    0x44380753,
+    0x4438875b,
+    0x44390773,
+    0x44398781,
+    0x443a0794,
+    0x4c3212bc,
+    0x4c3292cc,
+    0x4c3312df,
+    0x4c3392ff,
     0x4c340094,
     0x4c3480b0,
-    0x4c3512ff,
-    0x4c35930d,
-    0x4c361329,
-    0x4c36933c,
-    0x4c37134b,
-    0x4c379359,
-    0x4c38136e,
-    0x4c38937a,
-    0x4c39139a,
-    0x4c3993c4,
-    0x4c3a13dd,
-    0x4c3a93f6,
-    0x4c3b05d0,
-    0x4c3b940f,
-    0x4c3c1421,
-    0x4c3c9430,
-    0x4c3d10bd,
-    0x4c3d9449,
-    0x4c3e1456,
+    0x4c35130b,
+    0x4c359319,
+    0x4c361335,
+    0x4c369348,
+    0x4c371357,
+    0x4c379365,
+    0x4c38137a,
+    0x4c389386,
+    0x4c3913a6,
+    0x4c3993d0,
+    0x4c3a13e9,
+    0x4c3a9402,
+    0x4c3b05c1,
+    0x4c3b941b,
+    0x4c3c142d,
+    0x4c3c943c,
+    0x4c3d10c9,
+    0x4c3d9455,
+    0x4c3e1462,
     0x50322a92,
     0x5032aaa1,
     0x50332aac,
@@ -607,7 +613,7 @@
     0x50432d43,
     0x5043ad53,
     0x50442d62,
-    0x50448414,
+    0x50448405,
     0x50452d76,
     0x5045ad94,
     0x50462da7,
@@ -631,45 +637,45 @@
     0x504f2f62,
     0x504faf79,
     0x50502f88,
-    0x50508687,
+    0x50508678,
     0x50512f9b,
-    0x58320e1f,
-    0x68320de1,
-    0x68328b9b,
-    0x68330bae,
-    0x68338def,
-    0x68340dff,
+    0x58320e2b,
+    0x68320ded,
+    0x68328b98,
+    0x68330bab,
+    0x68338dfb,
+    0x68340e0b,
     0x683480b0,
-    0x6c320dbd,
-    0x6c328b7e,
-    0x6c330dc8,
-    0x7432098d,
-    0x783208f2,
-    0x78328907,
-    0x78330913,
+    0x6c320dc9,
+    0x6c328b6f,
+    0x6c330dd4,
+    0x7432097e,
+    0x783208e3,
+    0x783288f8,
+    0x78330904,
     0x78338083,
-    0x78340922,
-    0x78348937,
-    0x78350956,
-    0x78358978,
-    0x7836098d,
-    0x783689a3,
-    0x783709b3,
-    0x783789c6,
-    0x783809d9,
-    0x783889eb,
-    0x783909f8,
-    0x78398a17,
-    0x783a0a2c,
-    0x783a8a3a,
-    0x783b0a44,
-    0x783b8a58,
-    0x783c0a6f,
-    0x783c8a84,
-    0x783d0a9b,
-    0x783d8ab0,
-    0x783e0a06,
-    0x7c3211b2,
+    0x78340913,
+    0x78348928,
+    0x78350947,
+    0x78358969,
+    0x7836097e,
+    0x78368994,
+    0x783709a4,
+    0x783789b7,
+    0x783809ca,
+    0x783889dc,
+    0x783909e9,
+    0x78398a08,
+    0x783a0a1d,
+    0x783a8a2b,
+    0x783b0a35,
+    0x783b8a49,
+    0x783c0a60,
+    0x783c8a75,
+    0x783d0a8c,
+    0x783d8aa1,
+    0x783e09f7,
+    0x7c3211be,
 };
 
 const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]);
@@ -725,7 +731,6 @@
     "INVALID_UNIVERSALSTRING_LENGTH\0"
     "INVALID_UTF8STRING\0"
     "LIST_ERROR\0"
-    "MALLOC_FAILURE\0"
     "MISSING_ASN1_EOS\0"
     "MISSING_EOC\0"
     "MISSING_SECOND_NUMBER\0"
@@ -833,6 +838,7 @@
     "MODULUS_TOO_LARGE\0"
     "NO_PRIVATE_VALUE\0"
     "BAD_Q_VALUE\0"
+    "BAD_VERSION\0"
     "MISSING_PARAMETERS\0"
     "NEED_NEW_SETUP_VALUES\0"
     "BIGNUM_OUT_OF_RANGE\0"
@@ -840,6 +846,7 @@
     "D2I_ECPKPARAMETERS_FAILURE\0"
     "EC_GROUP_NEW_BY_NAME_FAILURE\0"
     "GROUP2PKPARAMETERS_FAILURE\0"
+    "GROUP_MISMATCH\0"
     "I2D_ECPKPARAMETERS_FAILURE\0"
     "INCOMPATIBLE_OBJECTS\0"
     "INVALID_COMPRESSED_POINT\0"
@@ -948,7 +955,6 @@
     "BAD_FIXED_HEADER_DECRYPT\0"
     "BAD_PAD_BYTE_COUNT\0"
     "BAD_RSA_PARAMETERS\0"
-    "BAD_VERSION\0"
     "BLOCK_TYPE_IS_NOT_01\0"
     "BN_NOT_INITIALIZED\0"
     "CANNOT_RECOVER_MULTI_PRIME_KEY\0"
diff --git a/src/core/ext/client_config/parse_address.c b/src/core/ext/client_config/parse_address.c
new file mode 100644
index 0000000..8b4abe2
--- /dev/null
+++ b/src/core/ext/client_config/parse_address.c
@@ -0,0 +1,137 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/ext/client_config/parse_address.h"
+
+#include <stdio.h>
+#include <string.h>
+#ifdef GPR_HAVE_UNIX_SOCKET
+#include <sys/un.h>
+#endif
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#ifdef GPR_HAVE_UNIX_SOCKET
+int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) {
+  struct sockaddr_un *un = (struct sockaddr_un *)addr;
+
+  un->sun_family = AF_UNIX;
+  strcpy(un->sun_path, uri->path);
+  *len = strlen(un->sun_path) + sizeof(un->sun_family) + 1;
+
+  return 1;
+}
+#endif
+
+int parse_ipv4(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) {
+  const char *host_port = uri->path;
+  char *host;
+  char *port;
+  int port_num;
+  int result = 0;
+  struct sockaddr_in *in = (struct sockaddr_in *)addr;
+
+  if (*host_port == '/') ++host_port;
+  if (!gpr_split_host_port(host_port, &host, &port)) {
+    return 0;
+  }
+
+  memset(in, 0, sizeof(*in));
+  *len = sizeof(*in);
+  in->sin_family = AF_INET;
+  if (inet_pton(AF_INET, host, &in->sin_addr) == 0) {
+    gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host);
+    goto done;
+  }
+
+  if (port != NULL) {
+    if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 ||
+        port_num > 65535) {
+      gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port);
+      goto done;
+    }
+    in->sin_port = htons((uint16_t)port_num);
+  } else {
+    gpr_log(GPR_ERROR, "no port given for ipv4 scheme");
+    goto done;
+  }
+
+  result = 1;
+done:
+  gpr_free(host);
+  gpr_free(port);
+  return result;
+}
+
+int parse_ipv6(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len) {
+  const char *host_port = uri->path;
+  char *host;
+  char *port;
+  int port_num;
+  int result = 0;
+  struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr;
+
+  if (*host_port == '/') ++host_port;
+  if (!gpr_split_host_port(host_port, &host, &port)) {
+    return 0;
+  }
+
+  memset(in6, 0, sizeof(*in6));
+  *len = sizeof(*in6);
+  in6->sin6_family = AF_INET6;
+  if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) {
+    gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host);
+    goto done;
+  }
+
+  if (port != NULL) {
+    if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 ||
+        port_num > 65535) {
+      gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port);
+      goto done;
+    }
+    in6->sin6_port = htons((uint16_t)port_num);
+  } else {
+    gpr_log(GPR_ERROR, "no port given for ipv6 scheme");
+    goto done;
+  }
+
+  result = 1;
+done:
+  gpr_free(host);
+  gpr_free(port);
+  return result;
+}
diff --git a/src/core/ext/client_config/parse_address.h b/src/core/ext/client_config/parse_address.h
new file mode 100644
index 0000000..74c86f4
--- /dev/null
+++ b/src/core/ext/client_config/parse_address.h
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_CLIENT_CONFIG_PARSE_ADDRESS_H
+#define GRPC_CORE_EXT_CLIENT_CONFIG_PARSE_ADDRESS_H
+
+#include <stddef.h>
+
+#include "src/core/ext/client_config/uri_parser.h"
+#include "src/core/lib/iomgr/sockaddr.h"
+
+#ifdef GPR_HAVE_UNIX_SOCKET
+/** Populate \a addr and \a len from \a uri, whose path is expected to contain a
+ * unix socket path. Returns true upon success. */
+int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len);
+#endif
+
+/** Populate /a addr and \a len from \a uri, whose path is expected to contain a
+ * host:port pair. Returns true upon success. */
+int parse_ipv4(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len);
+
+/** Populate /a addr and \a len from \a uri, whose path is expected to contain a
+ * host:port pair. Returns true upon success. */
+int parse_ipv6(grpc_uri *uri, struct sockaddr_storage *addr, size_t *len);
+
+#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_PARSE_ADDRESS_H */
diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/lb_policy/pick_first/pick_first.c
index 5926f9d..0d215cd 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/lb_policy/pick_first/pick_first.c
@@ -109,7 +109,7 @@
   if (selected != NULL) {
     grpc_connected_subchannel_notify_on_state_change(
         exec_ctx, selected, NULL, NULL, &p->connectivity_changed);
-  } else {
+  } else if (p->num_subchannels > 0) {
     grpc_subchannel_notify_on_state_change(
         exec_ctx, p->subchannels[p->checking_subchannel], NULL, NULL,
         &p->connectivity_changed);
diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
index 1d54a86..a4fa9ac 100644
--- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
+++ b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
@@ -40,11 +40,8 @@
 #include <grpc/support/port_platform.h>
 #include <grpc/support/string_util.h>
 
-#ifdef GPR_HAVE_UNIX_SOCKET
-#include <sys/un.h>
-#endif
-
 #include "src/core/ext/client_config/lb_policy_registry.h"
+#include "src/core/ext/client_config/parse_address.h"
 #include "src/core/ext/client_config/resolver_registry.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
@@ -167,105 +164,12 @@
 }
 
 #ifdef GPR_HAVE_UNIX_SOCKET
-static int parse_unix(grpc_uri *uri, struct sockaddr_storage *addr,
-                      size_t *len) {
-  struct sockaddr_un *un = (struct sockaddr_un *)addr;
-
-  un->sun_family = AF_UNIX;
-  strcpy(un->sun_path, uri->path);
-  *len = strlen(un->sun_path) + sizeof(un->sun_family) + 1;
-
-  return 1;
-}
-
 char *unix_get_default_authority(grpc_resolver_factory *factory,
                                  grpc_uri *uri) {
   return gpr_strdup("localhost");
 }
 #endif
 
-static int parse_ipv4(grpc_uri *uri, struct sockaddr_storage *addr,
-                      size_t *len) {
-  const char *host_port = uri->path;
-  char *host;
-  char *port;
-  int port_num;
-  int result = 0;
-  struct sockaddr_in *in = (struct sockaddr_in *)addr;
-
-  if (*host_port == '/') ++host_port;
-  if (!gpr_split_host_port(host_port, &host, &port)) {
-    return 0;
-  }
-
-  memset(in, 0, sizeof(*in));
-  *len = sizeof(*in);
-  in->sin_family = AF_INET;
-  if (inet_pton(AF_INET, host, &in->sin_addr) == 0) {
-    gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host);
-    goto done;
-  }
-
-  if (port != NULL) {
-    if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 ||
-        port_num > 65535) {
-      gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port);
-      goto done;
-    }
-    in->sin_port = htons((uint16_t)port_num);
-  } else {
-    gpr_log(GPR_ERROR, "no port given for ipv4 scheme");
-    goto done;
-  }
-
-  result = 1;
-done:
-  gpr_free(host);
-  gpr_free(port);
-  return result;
-}
-
-static int parse_ipv6(grpc_uri *uri, struct sockaddr_storage *addr,
-                      size_t *len) {
-  const char *host_port = uri->path;
-  char *host;
-  char *port;
-  int port_num;
-  int result = 0;
-  struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr;
-
-  if (*host_port == '/') ++host_port;
-  if (!gpr_split_host_port(host_port, &host, &port)) {
-    return 0;
-  }
-
-  memset(in6, 0, sizeof(*in6));
-  *len = sizeof(*in6);
-  in6->sin6_family = AF_INET6;
-  if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) {
-    gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host);
-    goto done;
-  }
-
-  if (port != NULL) {
-    if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 ||
-        port_num > 65535) {
-      gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port);
-      goto done;
-    }
-    in6->sin6_port = htons((uint16_t)port_num);
-  } else {
-    gpr_log(GPR_ERROR, "no port given for ipv6 scheme");
-    goto done;
-  }
-
-  result = 1;
-done:
-  gpr_free(host);
-  gpr_free(port);
-  return result;
-}
-
 static void do_nothing(void *ignored) {}
 
 static grpc_resolver *sockaddr_create(
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c
index a36d2fc..93c3e6d 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c
@@ -638,6 +638,10 @@
       return 0;
     }
   }
+  if (p->on_header == NULL) {
+    grpc_mdelem_unref(md);
+    return 0;
+  }
   p->on_header(p->on_header_user_data, md);
   return 1;
 }
@@ -1382,12 +1386,8 @@
 
 /* PUBLIC INTERFACE */
 
-static void on_header_not_set(void *user_data, grpc_mdelem *md) {
-  GPR_UNREACHABLE_CODE(return );
-}
-
 void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser *p) {
-  p->on_header = on_header_not_set;
+  p->on_header = NULL;
   p->on_header_user_data = NULL;
   p->state = parse_begin;
   p->key.str = NULL;
@@ -1455,7 +1455,7 @@
         stream_parsing->received_close = 1;
       }
     }
-    parser->on_header = on_header_not_set;
+    parser->on_header = NULL;
     parser->on_header_user_data = NULL;
     parser->is_boundary = 0xde;
     parser->is_eof = 0xde;
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index cfb5251..aaeb384 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -450,7 +450,7 @@
                            &sockname_len)) {
         port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
         if (port > 0) {
-          allocated_addr = malloc(addr_len);
+          allocated_addr = gpr_malloc(addr_len);
           memcpy(allocated_addr, addr, addr_len);
           grpc_sockaddr_set_port(allocated_addr, port);
           addr = allocated_addr;
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index 9f9d7dc..6940dec 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -467,7 +467,7 @@
                            (struct sockaddr *)&sockname_temp, &sockname_len)) {
         port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
         if (port > 0) {
-          allocated_addr = malloc(addr_len);
+          allocated_addr = gpr_malloc(addr_len);
           memcpy(allocated_addr, addr, addr_len);
           grpc_sockaddr_set_port(allocated_addr, port);
           addr = allocated_addr;
diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c
index a0b9709..2413117 100644
--- a/src/core/lib/iomgr/udp_server.c
+++ b/src/core/lib/iomgr/udp_server.c
@@ -328,7 +328,7 @@
                            &sockname_len)) {
         port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
         if (port > 0) {
-          allocated_addr = malloc(addr_len);
+          allocated_addr = gpr_malloc(addr_len);
           memcpy(allocated_addr, addr, addr_len);
           grpc_sockaddr_set_port(allocated_addr, port);
           addr = allocated_addr;
diff --git a/src/core/lib/profiling/basic_timers.c b/src/core/lib/profiling/basic_timers.c
index 93e0b99..50082cd 100644
--- a/src/core/lib/profiling/basic_timers.c
+++ b/src/core/lib/profiling/basic_timers.c
@@ -208,6 +208,7 @@
 }
 
 static void rotate_log() {
+  /* Using malloc here, as this code could end up being called by gpr_malloc */
   gpr_timer_log *new = malloc(sizeof(*new));
   gpr_once_init(&g_once_init, init_output);
   new->num_entries = 0;
diff --git a/src/core/lib/security/credentials.c b/src/core/lib/security/credentials.c
index 2c7d315..fd5ad35 100644
--- a/src/core/lib/security/credentials.c
+++ b/src/core/lib/security/credentials.c
@@ -338,10 +338,11 @@
 
 static void ssl_build_server_config(
     const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
-    size_t num_key_cert_pairs, int force_client_auth,
+    size_t num_key_cert_pairs,
+    grpc_ssl_client_certificate_request_type client_certificate_request,
     grpc_ssl_server_config *config) {
   size_t i;
-  config->force_client_auth = force_client_auth;
+  config->client_certificate_request = client_certificate_request;
   if (pem_root_certs != NULL) {
     ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
                           &config->pem_root_certs_size);
@@ -391,21 +392,35 @@
 grpc_server_credentials *grpc_ssl_server_credentials_create(
     const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
     size_t num_key_cert_pairs, int force_client_auth, void *reserved) {
+  return grpc_ssl_server_credentials_create_ex(
+      pem_root_certs, pem_key_cert_pairs, num_key_cert_pairs,
+      force_client_auth
+          ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+          : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
+      reserved);
+}
+
+grpc_server_credentials *grpc_ssl_server_credentials_create_ex(
+    const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+    size_t num_key_cert_pairs,
+    grpc_ssl_client_certificate_request_type client_certificate_request,
+    void *reserved) {
   grpc_ssl_server_credentials *c =
       gpr_malloc(sizeof(grpc_ssl_server_credentials));
   GRPC_API_TRACE(
-      "grpc_ssl_server_credentials_create("
+      "grpc_ssl_server_credentials_create_ex("
       "pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, "
-      "force_client_auth=%d, reserved=%p)",
+      "client_certificate_request=%d, reserved=%p)",
       5, (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs,
-          force_client_auth, reserved));
+          client_certificate_request, reserved));
   GPR_ASSERT(reserved == NULL);
   memset(c, 0, sizeof(grpc_ssl_server_credentials));
   c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
   gpr_ref_init(&c->base.refcount, 1);
   c->base.vtable = &ssl_server_vtable;
   ssl_build_server_config(pem_root_certs, pem_key_cert_pairs,
-                          num_key_cert_pairs, force_client_auth, &c->config);
+                          num_key_cert_pairs, client_certificate_request,
+                          &c->config);
   return &c->base;
 }
 
diff --git a/src/core/lib/security/security_connector.c b/src/core/lib/security/security_connector.c
index 59863ba..2d2023b 100644
--- a/src/core/lib/security/security_connector.c
+++ b/src/core/lib/security/security_connector.c
@@ -668,6 +668,31 @@
   return compute_default_pem_root_certs_once();
 }
 
+static tsi_client_certificate_request_type
+get_tsi_client_certificate_request_type(
+    grpc_ssl_client_certificate_request_type grpc_request_type) {
+  switch (grpc_request_type) {
+    case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE:
+      return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
+
+    case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+      return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
+
+    case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
+      return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY;
+
+    case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+      return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
+
+    case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
+      return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
+
+    default:
+      // Is this a sane default
+      return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
+  }
+}
+
 size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) {
   /* TODO(jboeuf@google.com): Maybe revisit the approach which consists in
      loading all the roots once for the lifetime of the process. */
@@ -782,15 +807,16 @@
   gpr_ref_init(&c->base.base.refcount, 1);
   c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
   c->base.base.vtable = &ssl_server_vtable;
-  result = tsi_create_ssl_server_handshaker_factory(
+  result = tsi_create_ssl_server_handshaker_factory_ex(
       (const unsigned char **)config->pem_private_keys,
       config->pem_private_keys_sizes,
       (const unsigned char **)config->pem_cert_chains,
       config->pem_cert_chains_sizes, config->num_key_cert_pairs,
       config->pem_root_certs, config->pem_root_certs_size,
-      config->force_client_auth, ssl_cipher_suites(), alpn_protocol_strings,
-      alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols,
-      &c->handshaker_factory);
+      get_tsi_client_certificate_request_type(
+          config->client_certificate_request),
+      ssl_cipher_suites(), alpn_protocol_strings, alpn_protocol_string_lengths,
+      (uint16_t)num_alpn_protocols, &c->handshaker_factory);
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
diff --git a/src/core/lib/security/security_connector.h b/src/core/lib/security/security_connector.h
index c9e262b..2c893cd 100644
--- a/src/core/lib/security/security_connector.h
+++ b/src/core/lib/security/security_connector.h
@@ -241,7 +241,7 @@
   size_t num_key_cert_pairs;
   unsigned char *pem_root_certs;
   size_t pem_root_certs_size;
-  int force_client_auth;
+  grpc_ssl_client_certificate_request_type client_certificate_request;
 } grpc_ssl_server_config;
 
 /* Creates an SSL server_security_connector.
diff --git a/src/core/lib/support/alloc.c b/src/core/lib/support/alloc.c
index 020917f..618c3f6 100644
--- a/src/core/lib/support/alloc.c
+++ b/src/core/lib/support/alloc.c
@@ -53,6 +53,7 @@
 
 void *gpr_malloc(size_t size) {
   void *p;
+  if (size == 0) return NULL;
   GPR_TIMER_BEGIN("gpr_malloc", 0);
   p = g_alloc_functions.malloc_fn(size);
   if (!p) {
@@ -69,6 +70,7 @@
 }
 
 void *gpr_realloc(void *p, size_t size) {
+  if ((size == 0) && (p == NULL)) return NULL;
   GPR_TIMER_BEGIN("gpr_realloc", 0);
   p = g_alloc_functions.realloc_fn(p, size);
   if (!p) {
diff --git a/src/core/lib/support/log.c b/src/core/lib/support/log.c
index 04156a5..882abf6 100644
--- a/src/core/lib/support/log.c
+++ b/src/core/lib/support/log.c
@@ -31,14 +31,20 @@
  *
  */
 
+#include <grpc/support/alloc.h>
+#include <grpc/support/atm.h>
 #include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
 
+#include "src/core/lib/support/env.h"
+#include "src/core/lib/support/string.h"
+
 #include <stdio.h>
 #include <string.h>
 
 extern void gpr_default_log(gpr_log_func_args *args);
 static gpr_log_func g_log_func = gpr_default_log;
+static gpr_atm g_min_severity_to_print = GPR_LOG_VERBOSITY_UNSET;
 
 const char *gpr_log_severity_string(gpr_log_severity severity) {
   switch (severity) {
@@ -54,6 +60,9 @@
 
 void gpr_log_message(const char *file, int line, gpr_log_severity severity,
                      const char *message) {
+  if ((gpr_atm)severity < gpr_atm_no_barrier_load(&g_min_severity_to_print))
+    return;
+
   gpr_log_func_args lfargs;
   memset(&lfargs, 0, sizeof(lfargs));
   lfargs.file = file;
@@ -63,4 +72,28 @@
   g_log_func(&lfargs);
 }
 
+void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) {
+  gpr_atm_no_barrier_store(&g_min_severity_to_print,
+                           (gpr_atm)min_severity_to_print);
+}
+
+void gpr_log_verbosity_init() {
+  char *verbosity = gpr_getenv("GRPC_VERBOSITY");
+  if (verbosity == NULL) return;
+
+  gpr_atm min_severity_to_print = GPR_LOG_VERBOSITY_UNSET;
+  if (strcmp(verbosity, "DEBUG") == 0) {
+    min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_DEBUG;
+  } else if (strcmp(verbosity, "INFO") == 0) {
+    min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_INFO;
+  } else if (strcmp(verbosity, "ERROR") == 0) {
+    min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_ERROR;
+  }
+  gpr_free(verbosity);
+  if ((gpr_atm_no_barrier_load(&g_min_severity_to_print)) ==
+      GPR_LOG_VERBOSITY_UNSET) {
+    gpr_atm_no_barrier_store(&g_min_severity_to_print, min_severity_to_print);
+  }
+}
+
 void gpr_set_log_function(gpr_log_func f) { g_log_func = f; }
diff --git a/src/core/lib/support/log_linux.c b/src/core/lib/support/log_linux.c
index 6d4b63b..ff3febb 100644
--- a/src/core/lib/support/log_linux.c
+++ b/src/core/lib/support/log_linux.c
@@ -68,6 +68,7 @@
   }
   va_end(args);
   gpr_log_message(file, line, severity, message);
+  /* message has been allocated by vasprintf above, and needs free */
   free(message);
 }
 
diff --git a/src/core/lib/support/thd_posix.c b/src/core/lib/support/thd_posix.c
index 89832e3..2fc23bf 100644
--- a/src/core/lib/support/thd_posix.c
+++ b/src/core/lib/support/thd_posix.c
@@ -81,6 +81,7 @@
   thread_started = (pthread_create(&p, &attr, &thread_body, a) == 0);
   GPR_ASSERT(pthread_attr_destroy(&attr) == 0);
   if (!thread_started) {
+    /* don't use gpr_free, as this was allocated using malloc (see above) */
     free(a);
   }
   *t = (gpr_thd_id)p;
diff --git a/src/core/lib/surface/byte_buffer.c b/src/core/lib/surface/byte_buffer.c
index fb39c45..a093a37 100644
--- a/src/core/lib/surface/byte_buffer.c
+++ b/src/core/lib/surface/byte_buffer.c
@@ -44,7 +44,7 @@
 grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create(
     gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression) {
   size_t i;
-  grpc_byte_buffer *bb = malloc(sizeof(grpc_byte_buffer));
+  grpc_byte_buffer *bb = gpr_malloc(sizeof(grpc_byte_buffer));
   bb->type = GRPC_BB_RAW;
   bb->data.raw.compression = compression;
   gpr_slice_buffer_init(&bb->data.raw.slice_buffer);
@@ -57,7 +57,7 @@
 
 grpc_byte_buffer *grpc_raw_byte_buffer_from_reader(
     grpc_byte_buffer_reader *reader) {
-  grpc_byte_buffer *bb = malloc(sizeof(grpc_byte_buffer));
+  grpc_byte_buffer *bb = gpr_malloc(sizeof(grpc_byte_buffer));
   gpr_slice slice;
   bb->type = GRPC_BB_RAW;
   bb->data.raw.compression = GRPC_COMPRESS_NONE;
@@ -85,7 +85,7 @@
       gpr_slice_buffer_destroy(&bb->data.raw.slice_buffer);
       break;
   }
-  free(bb);
+  gpr_free(bb);
 }
 
 size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) {
diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c
index ec75af6..d4eb2f8 100644
--- a/src/core/lib/surface/init.c
+++ b/src/core/lib/surface/init.c
@@ -38,6 +38,7 @@
 
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/channel/compress_filter.h"
@@ -69,6 +70,7 @@
 static int g_initializations;
 
 static void do_basic_init(void) {
+  gpr_log_verbosity_init();
   gpr_mu_init(&g_init_mu);
   grpc_register_built_in_plugins();
   g_initializations = 0;
diff --git a/src/core/lib/tsi/fake_transport_security.c b/src/core/lib/tsi/fake_transport_security.c
index 4b045b8..0e20d6f 100644
--- a/src/core/lib/tsi/fake_transport_security.c
+++ b/src/core/lib/tsi/fake_transport_security.c
@@ -36,6 +36,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
 #include <grpc/support/useful.h>
@@ -134,12 +135,12 @@
 static int tsi_fake_frame_ensure_size(tsi_fake_frame *frame) {
   if (frame->data == NULL) {
     frame->allocated_size = frame->size;
-    frame->data = malloc(frame->allocated_size);
+    frame->data = gpr_malloc(frame->allocated_size);
     if (frame->data == NULL) return 0;
   } else if (frame->size > frame->allocated_size) {
-    unsigned char *new_data = realloc(frame->data, frame->size);
+    unsigned char *new_data = gpr_realloc(frame->data, frame->size);
     if (new_data == NULL) {
-      free(frame->data);
+      gpr_free(frame->data);
       frame->data = NULL;
       return 0;
     }
@@ -160,7 +161,7 @@
   if (frame->needs_draining) return TSI_INTERNAL_ERROR;
   if (frame->data == NULL) {
     frame->allocated_size = TSI_FAKE_FRAME_INITIAL_ALLOCATED_SIZE;
-    frame->data = malloc(frame->allocated_size);
+    frame->data = gpr_malloc(frame->allocated_size);
     if (frame->data == NULL) return TSI_OUT_OF_RESOURCES;
   }
 
@@ -226,7 +227,7 @@
 }
 
 static void tsi_fake_frame_destruct(tsi_fake_frame *frame) {
-  if (frame->data != NULL) free(frame->data);
+  if (frame->data != NULL) gpr_free(frame->data);
 }
 
 /* --- tsi_frame_protector methods implementation. ---*/
@@ -366,7 +367,7 @@
   tsi_fake_frame_protector *impl = (tsi_fake_frame_protector *)self;
   tsi_fake_frame_destruct(&impl->protect_frame);
   tsi_fake_frame_destruct(&impl->unprotect_frame);
-  free(self);
+  gpr_free(self);
 }
 
 static const tsi_frame_protector_vtable frame_protector_vtable = {
@@ -488,7 +489,7 @@
   tsi_fake_handshaker *impl = (tsi_fake_handshaker *)self;
   tsi_fake_frame_destruct(&impl->incoming);
   tsi_fake_frame_destruct(&impl->outgoing);
-  free(self);
+  gpr_free(self);
 }
 
 static const tsi_handshaker_vtable handshaker_vtable = {
@@ -501,7 +502,8 @@
 };
 
 tsi_handshaker *tsi_create_fake_handshaker(int is_client) {
-  tsi_fake_handshaker *impl = calloc(1, sizeof(tsi_fake_handshaker));
+  tsi_fake_handshaker *impl = gpr_malloc(sizeof(*impl));
+  memset(impl, 0, sizeof(*impl));
   impl->base.vtable = &handshaker_vtable;
   impl->is_client = is_client;
   impl->result = TSI_HANDSHAKE_IN_PROGRESS;
@@ -517,8 +519,8 @@
 
 tsi_frame_protector *tsi_create_fake_protector(
     size_t *max_protected_frame_size) {
-  tsi_fake_frame_protector *impl = calloc(1, sizeof(tsi_fake_frame_protector));
-  if (impl == NULL) return NULL;
+  tsi_fake_frame_protector *impl = gpr_malloc(sizeof(*impl));
+  memset(impl, 0, sizeof(*impl));
   impl->max_frame_size = (max_protected_frame_size == NULL)
                              ? TSI_FAKE_DEFAULT_FRAME_SIZE
                              : *max_protected_frame_size;
diff --git a/src/core/lib/tsi/ssl_transport_security.c b/src/core/lib/tsi/ssl_transport_security.c
index d98b3e1..e91c631 100644
--- a/src/core/lib/tsi/ssl_transport_security.c
+++ b/src/core/lib/tsi/ssl_transport_security.c
@@ -45,6 +45,7 @@
 #include <arpa/inet.h>
 #endif
 
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
@@ -148,8 +149,7 @@
   OpenSSL_add_all_algorithms();
   num_locks = CRYPTO_num_locks();
   GPR_ASSERT(num_locks > 0);
-  openssl_mutexes = malloc((size_t)num_locks * sizeof(gpr_mu));
-  GPR_ASSERT(openssl_mutexes != NULL);
+  openssl_mutexes = gpr_malloc((size_t)num_locks * sizeof(gpr_mu));
   for (i = 0; i < CRYPTO_num_locks(); i++) {
     gpr_mu_init(&openssl_mutexes[i]);
   }
@@ -701,7 +701,7 @@
     }
     *protocol_name_list_length += (size_t)alpn_protocols_lengths[i] + 1;
   }
-  *protocol_name_list = malloc(*protocol_name_list_length);
+  *protocol_name_list = gpr_malloc(*protocol_name_list_length);
   if (*protocol_name_list == NULL) return TSI_OUT_OF_RESOURCES;
   current = *protocol_name_list;
   for (i = 0; i < num_alpn_protocols; i++) {
@@ -718,6 +718,14 @@
   return TSI_OK;
 }
 
+// The verification callback is used for clients that don't really care about
+// the server's certificate, but we need to pull it anyway, in case a higher
+// layer wants to look at it. In this case the verification may fail, but
+// we don't really care.
+static int NullVerifyCallback(int preverify_ok, X509_STORE_CTX *ctx) {
+  return 1;
+}
+
 /* --- tsi_frame_protector methods implementation. ---*/
 
 static tsi_result ssl_protector_protect(tsi_frame_protector *self,
@@ -852,9 +860,9 @@
 
 static void ssl_protector_destroy(tsi_frame_protector *self) {
   tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *)self;
-  if (impl->buffer != NULL) free(impl->buffer);
+  if (impl->buffer != NULL) gpr_free(impl->buffer);
   if (impl->ssl != NULL) SSL_free(impl->ssl);
-  free(self);
+  gpr_free(self);
 }
 
 static const tsi_frame_protector_vtable frame_protector_vtable = {
@@ -966,8 +974,9 @@
   if (alpn_selected != NULL) {
     size_t i;
     tsi_peer_property *new_properties =
-        calloc(1, sizeof(tsi_peer_property) * (peer->property_count + 1));
-    if (new_properties == NULL) return TSI_OUT_OF_RESOURCES;
+        gpr_malloc(sizeof(*new_properties) * (peer->property_count + 1));
+    memset(new_properties, 0,
+           sizeof(*new_properties) * (peer->property_count + 1));
     for (i = 0; i < peer->property_count; i++) {
       new_properties[i] = peer->properties[i];
     }
@@ -975,10 +984,10 @@
         TSI_SSL_ALPN_SELECTED_PROTOCOL, (const char *)alpn_selected,
         alpn_selected_len, &new_properties[peer->property_count]);
     if (result != TSI_OK) {
-      free(new_properties);
+      gpr_free(new_properties);
       return result;
     }
-    if (peer->properties != NULL) free(peer->properties);
+    if (peer->properties != NULL) gpr_free(peer->properties);
     peer->property_count++;
     peer->properties = new_properties;
   }
@@ -991,11 +1000,8 @@
   size_t actual_max_output_protected_frame_size =
       TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND;
   tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self;
-  tsi_ssl_frame_protector *protector_impl =
-      calloc(1, sizeof(tsi_ssl_frame_protector));
-  if (protector_impl == NULL) {
-    return TSI_OUT_OF_RESOURCES;
-  }
+  tsi_ssl_frame_protector *protector_impl = gpr_malloc(sizeof(*protector_impl));
+  memset(protector_impl, 0, sizeof(*protector_impl));
 
   if (max_output_protected_frame_size != NULL) {
     if (*max_output_protected_frame_size >
@@ -1011,11 +1017,11 @@
   }
   protector_impl->buffer_size =
       actual_max_output_protected_frame_size - TSI_SSL_MAX_PROTECTION_OVERHEAD;
-  protector_impl->buffer = malloc(protector_impl->buffer_size);
+  protector_impl->buffer = gpr_malloc(protector_impl->buffer_size);
   if (protector_impl->buffer == NULL) {
     gpr_log(GPR_ERROR,
             "Could not allocated buffer for tsi_ssl_frame_protector.");
-    free(protector_impl);
+    gpr_free(protector_impl);
     return TSI_INTERNAL_ERROR;
   }
 
@@ -1034,7 +1040,7 @@
 static void ssl_handshaker_destroy(tsi_handshaker *self) {
   tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self;
   SSL_free(impl->ssl); /* The BIO objects are owned by ssl */
-  free(impl);
+  gpr_free(impl);
 }
 
 static const tsi_handshaker_vtable handshaker_vtable = {
@@ -1111,11 +1117,8 @@
     SSL_set_accept_state(ssl);
   }
 
-  impl = calloc(1, sizeof(tsi_ssl_handshaker));
-  if (impl == NULL) {
-    SSL_free(ssl);
-    return TSI_OUT_OF_RESOURCES;
-  }
+  impl = gpr_malloc(sizeof(*impl));
+  memset(impl, 0, sizeof(*impl));
   impl->ssl = ssl;
   impl->into_ssl = into_ssl;
   impl->from_ssl = from_ssl;
@@ -1167,8 +1170,8 @@
   tsi_ssl_client_handshaker_factory *impl =
       (tsi_ssl_client_handshaker_factory *)self;
   if (impl->ssl_context != NULL) SSL_CTX_free(impl->ssl_context);
-  if (impl->alpn_protocol_list != NULL) free(impl->alpn_protocol_list);
-  free(impl);
+  if (impl->alpn_protocol_list != NULL) gpr_free(impl->alpn_protocol_list);
+  gpr_free(impl);
 }
 
 static int client_handshaker_factory_npn_callback(SSL *ssl, unsigned char **out,
@@ -1209,12 +1212,12 @@
       tsi_peer_destruct(&impl->ssl_context_x509_subject_names[i]);
     }
   }
-  if (impl->ssl_contexts != NULL) free(impl->ssl_contexts);
+  if (impl->ssl_contexts != NULL) gpr_free(impl->ssl_contexts);
   if (impl->ssl_context_x509_subject_names != NULL) {
-    free(impl->ssl_context_x509_subject_names);
+    gpr_free(impl->ssl_context_x509_subject_names);
   }
-  if (impl->alpn_protocol_list != NULL) free(impl->alpn_protocol_list);
-  free(impl);
+  if (impl->alpn_protocol_list != NULL) gpr_free(impl->alpn_protocol_list);
+  gpr_free(impl);
 }
 
 static int does_entry_match_name(const char *entry, size_t entry_length,
@@ -1333,11 +1336,8 @@
     return TSI_INVALID_ARGUMENT;
   }
 
-  impl = calloc(1, sizeof(tsi_ssl_client_handshaker_factory));
-  if (impl == NULL) {
-    SSL_CTX_free(ssl_context);
-    return TSI_OUT_OF_RESOURCES;
-  }
+  impl = gpr_malloc(sizeof(*impl));
+  memset(impl, 0, sizeof(*impl));
   impl->ssl_context = ssl_context;
 
   do {
@@ -1398,6 +1398,26 @@
     const char *cipher_list, const unsigned char **alpn_protocols,
     const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
     tsi_ssl_handshaker_factory **factory) {
+  return tsi_create_ssl_server_handshaker_factory_ex(
+      pem_private_keys, pem_private_keys_sizes, pem_cert_chains,
+      pem_cert_chains_sizes, key_cert_pair_count, pem_client_root_certs,
+      pem_client_root_certs_size,
+      force_client_auth ? TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+                        : TSI_DONT_REQUEST_CLIENT_CERTIFICATE,
+      cipher_list, alpn_protocols, alpn_protocols_lengths, num_alpn_protocols,
+      factory);
+}
+
+tsi_result tsi_create_ssl_server_handshaker_factory_ex(
+    const unsigned char **pem_private_keys,
+    const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains,
+    const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count,
+    const unsigned char *pem_client_root_certs,
+    size_t pem_client_root_certs_size,
+    tsi_client_certificate_request_type client_certificate_request,
+    const char *cipher_list, const unsigned char **alpn_protocols,
+    const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
+    tsi_ssl_handshaker_factory **factory) {
   tsi_ssl_server_handshaker_factory *impl = NULL;
   tsi_result result = TSI_OK;
   size_t i = 0;
@@ -1411,14 +1431,17 @@
     return TSI_INVALID_ARGUMENT;
   }
 
-  impl = calloc(1, sizeof(tsi_ssl_server_handshaker_factory));
-  if (impl == NULL) return TSI_OUT_OF_RESOURCES;
+  impl = gpr_malloc(sizeof(*impl));
+  memset(impl, 0, sizeof(*impl));
   impl->base.create_handshaker =
       ssl_server_handshaker_factory_create_handshaker;
   impl->base.destroy = ssl_server_handshaker_factory_destroy;
-  impl->ssl_contexts = calloc(key_cert_pair_count, sizeof(SSL_CTX *));
+  impl->ssl_contexts = gpr_malloc(key_cert_pair_count * sizeof(SSL_CTX *));
+  memset(impl->ssl_contexts, 0, key_cert_pair_count * sizeof(SSL_CTX *));
   impl->ssl_context_x509_subject_names =
-      calloc(key_cert_pair_count, sizeof(tsi_peer));
+      gpr_malloc(key_cert_pair_count * sizeof(tsi_peer));
+  memset(impl->ssl_context_x509_subject_names, 0,
+         key_cert_pair_count * sizeof(tsi_peer));
   if (impl->ssl_contexts == NULL ||
       impl->ssl_context_x509_subject_names == NULL) {
     tsi_ssl_handshaker_factory_destroy(&impl->base);
@@ -1450,7 +1473,6 @@
       if (result != TSI_OK) break;
 
       if (pem_client_root_certs != NULL) {
-        int flags = SSL_VERIFY_PEER;
         STACK_OF(X509_NAME) *root_names = NULL;
         result = ssl_ctx_load_verification_certs(
             impl->ssl_contexts[i], pem_client_root_certs,
@@ -1460,8 +1482,29 @@
           break;
         }
         SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names);
-        if (force_client_auth) flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
-        SSL_CTX_set_verify(impl->ssl_contexts[i], flags, NULL);
+        switch (client_certificate_request) {
+          case TSI_DONT_REQUEST_CLIENT_CERTIFICATE:
+            SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, NULL);
+            break;
+          case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+            SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER,
+                               NullVerifyCallback);
+            break;
+          case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
+            SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, NULL);
+            break;
+          case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+            SSL_CTX_set_verify(
+                impl->ssl_contexts[i],
+                SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+                NullVerifyCallback);
+            break;
+          case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
+            SSL_CTX_set_verify(
+                impl->ssl_contexts[i],
+                SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
+            break;
+        }
         /* TODO(jboeuf): Add revocation verification. */
       }
 
diff --git a/src/core/lib/tsi/ssl_transport_security.h b/src/core/lib/tsi/ssl_transport_security.h
index 211c8f9..7407246 100644
--- a/src/core/lib/tsi/ssl_transport_security.h
+++ b/src/core/lib/tsi/ssl_transport_security.h
@@ -142,6 +142,23 @@
     const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
     tsi_ssl_handshaker_factory **factory);
 
+/* Same as tsi_create_ssl_server_handshaker_factory method except uses
+   tsi_client_certificate_request_type to support more ways to handle client
+   certificate authentication.
+   - client_certificate_request, if set to non-zero will force the client to
+     authenticate with an SSL cert. Note that this option is ignored if
+     pem_client_root_certs is NULL or pem_client_roots_certs_size is 0 */
+tsi_result tsi_create_ssl_server_handshaker_factory_ex(
+    const unsigned char **pem_private_keys,
+    const size_t *pem_private_keys_sizes, const unsigned char **pem_cert_chains,
+    const size_t *pem_cert_chains_sizes, size_t key_cert_pair_count,
+    const unsigned char *pem_client_root_certs,
+    size_t pem_client_root_certs_size,
+    tsi_client_certificate_request_type client_certificate_request,
+    const char *cipher_suites, const unsigned char **alpn_protocols,
+    const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols,
+    tsi_ssl_handshaker_factory **factory);
+
 /* Creates a handshaker.
   - self is the factory from which the handshaker will be created.
   - server_name_indication indicates the name of the server the client is
diff --git a/src/core/lib/tsi/transport_security.c b/src/core/lib/tsi/transport_security.c
index 861fc79..830cf09 100644
--- a/src/core/lib/tsi/transport_security.c
+++ b/src/core/lib/tsi/transport_security.c
@@ -33,6 +33,9 @@
 
 #include "src/core/lib/tsi/transport_security.h"
 
+#include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
+
 #include <stdlib.h>
 #include <string.h>
 
@@ -40,19 +43,6 @@
 
 int tsi_tracing_enabled = 0;
 
-/* --- Utils. --- */
-
-char *tsi_strdup(const char *src) {
-  char *dst;
-  size_t len;
-  if (!src) return NULL;
-  len = strlen(src) + 1;
-  dst = malloc(len);
-  if (!dst) return NULL;
-  memcpy(dst, src, len);
-  return dst;
-}
-
 /* --- tsi_result common implementation. --- */
 
 const char *tsi_result_to_string(tsi_result result) {
@@ -214,15 +204,15 @@
   for (i = 0; i < child_count; i++) {
     tsi_peer_property_destruct(&children[i]);
   }
-  free(children);
+  gpr_free(children);
 }
 
 void tsi_peer_property_destruct(tsi_peer_property *property) {
   if (property->name != NULL) {
-    free(property->name);
+    gpr_free(property->name);
   }
   if (property->value.data != NULL) {
-    free(property->value.data);
+    gpr_free(property->value.data);
   }
   *property = tsi_init_peer_property(); /* Reset everything to 0. */
 }
@@ -239,16 +229,10 @@
 tsi_result tsi_construct_allocated_string_peer_property(
     const char *name, size_t value_length, tsi_peer_property *property) {
   *property = tsi_init_peer_property();
-  if (name != NULL) {
-    property->name = tsi_strdup(name);
-    if (property->name == NULL) return TSI_OUT_OF_RESOURCES;
-  }
+  if (name != NULL) property->name = gpr_strdup(name);
   if (value_length > 0) {
-    property->value.data = calloc(1, value_length);
-    if (property->value.data == NULL) {
-      tsi_peer_property_destruct(property);
-      return TSI_OUT_OF_RESOURCES;
-    }
+    property->value.data = gpr_malloc(value_length);
+    memset(property->value.data, 0, value_length);
     property->value.length = value_length;
   }
   return TSI_OK;
@@ -276,8 +260,8 @@
 tsi_result tsi_construct_peer(size_t property_count, tsi_peer *peer) {
   memset(peer, 0, sizeof(tsi_peer));
   if (property_count > 0) {
-    peer->properties = calloc(property_count, sizeof(tsi_peer_property));
-    if (peer->properties == NULL) return TSI_OUT_OF_RESOURCES;
+    peer->properties = gpr_malloc(property_count * sizeof(tsi_peer_property));
+    memset(peer->properties, 0, property_count * sizeof(tsi_peer_property));
     peer->property_count = property_count;
   }
   return TSI_OK;
diff --git a/src/core/lib/tsi/transport_security_interface.h b/src/core/lib/tsi/transport_security_interface.h
index d81ec09..3e8c9d7 100644
--- a/src/core/lib/tsi/transport_security_interface.h
+++ b/src/core/lib/tsi/transport_security_interface.h
@@ -59,6 +59,15 @@
   TSI_OUT_OF_RESOURCES = 12
 } tsi_result;
 
+typedef enum {
+  // Default option
+  TSI_DONT_REQUEST_CLIENT_CERTIFICATE,
+  TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY,
+  TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY,
+  TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY,
+  TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY,
+} tsi_client_certificate_request_type;
+
 const char *tsi_result_to_string(tsi_result result);
 
 /* --- tsi tracing --- */
diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc
index d472667..33bdc2a 100644
--- a/src/cpp/server/secure_server_credentials.cc
+++ b/src/cpp/server/secure_server_credentials.cc
@@ -130,10 +130,14 @@
                                     key_cert_pair->cert_chain.c_str()};
     pem_key_cert_pairs.push_back(p);
   }
-  grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create(
+  grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create_ex(
       options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
       pem_key_cert_pairs.empty() ? nullptr : &pem_key_cert_pairs[0],
-      pem_key_cert_pairs.size(), options.force_client_auth, nullptr);
+      pem_key_cert_pairs.size(),
+      options.force_client_auth
+          ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+          : options.client_certificate_request,
+      nullptr);
   return std::shared_ptr<ServerCredentials>(
       new SecureServerCredentials(c_creds));
 }
diff --git a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
index f954ca5..b457275 100644
--- a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
@@ -129,6 +129,7 @@
         public ClientRunnerImpl(List<Channel> channels, ClientType clientType, RpcType rpcType, int outstandingRpcsPerChannel, LoadParams loadParams, PayloadConfig payloadConfig, HistogramParams histogramParams)
         {
             GrpcPreconditions.CheckArgument(outstandingRpcsPerChannel > 0, "outstandingRpcsPerChannel");
+            GrpcPreconditions.CheckNotNull(histogramParams, "histogramParams");
             this.channels = new List<Channel>(channels);
             this.clientType = clientType;
             this.rpcType = rpcType;
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
index 291bc75..003d242 100644
--- a/src/csharp/Grpc.IntegrationTesting/Control.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -26,58 +26,67 @@
             "CiRzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL2NvbnRyb2wucHJvdG8SDGdycGMu",
             "dGVzdGluZxolc3JjL3Byb3RvL2dycGMvdGVzdGluZy9wYXlsb2Fkcy5wcm90",
             "bxoic3JjL3Byb3RvL2dycGMvdGVzdGluZy9zdGF0cy5wcm90byIlCg1Qb2lz",
-            "c29uUGFyYW1zEhQKDG9mZmVyZWRfbG9hZBgBIAEoASJBCg1Vbmlmb3JtUGFy",
-            "YW1zEhcKD2ludGVyYXJyaXZhbF9sbxgBIAEoARIXCg9pbnRlcmFycml2YWxf",
-            "aGkYAiABKAEiKwoTRGV0ZXJtaW5pc3RpY1BhcmFtcxIUCgxvZmZlcmVkX2xv",
-            "YWQYASABKAEiOAoMUGFyZXRvUGFyYW1zEhkKEWludGVyYXJyaXZhbF9iYXNl",
-            "GAEgASgBEg0KBWFscGhhGAIgASgBIhIKEENsb3NlZExvb3BQYXJhbXMijgIK",
-            "CkxvYWRQYXJhbXMSNQoLY2xvc2VkX2xvb3AYASABKAsyHi5ncnBjLnRlc3Rp",
-            "bmcuQ2xvc2VkTG9vcFBhcmFtc0gAEi4KB3BvaXNzb24YAiABKAsyGy5ncnBj",
-            "LnRlc3RpbmcuUG9pc3NvblBhcmFtc0gAEi4KB3VuaWZvcm0YAyABKAsyGy5n",
-            "cnBjLnRlc3RpbmcuVW5pZm9ybVBhcmFtc0gAEjMKBmRldGVybRgEIAEoCzIh",
-            "LmdycGMudGVzdGluZy5EZXRlcm1pbmlzdGljUGFyYW1zSAASLAoGcGFyZXRv",
-            "GAUgASgLMhouZ3JwYy50ZXN0aW5nLlBhcmV0b1BhcmFtc0gAQgYKBGxvYWQi",
-            "QwoOU2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2Vy",
-            "dmVyX2hvc3Rfb3ZlcnJpZGUYAiABKAki1gMKDENsaWVudENvbmZpZxIWCg5z",
-            "ZXJ2ZXJfdGFyZ2V0cxgBIAMoCRItCgtjbGllbnRfdHlwZRgCIAEoDjIYLmdy",
-            "cGMudGVzdGluZy5DbGllbnRUeXBlEjUKD3NlY3VyaXR5X3BhcmFtcxgDIAEo",
-            "CzIcLmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIkChxvdXRzdGFuZGlu",
-            "Z19ycGNzX3Blcl9jaGFubmVsGAQgASgFEhcKD2NsaWVudF9jaGFubmVscxgF",
-            "IAEoBRIcChRhc3luY19jbGllbnRfdGhyZWFkcxgHIAEoBRInCghycGNfdHlw",
-            "ZRgIIAEoDjIVLmdycGMudGVzdGluZy5ScGNUeXBlEi0KC2xvYWRfcGFyYW1z",
-            "GAogASgLMhguZ3JwYy50ZXN0aW5nLkxvYWRQYXJhbXMSMwoOcGF5bG9hZF9j",
-            "b25maWcYCyABKAsyGy5ncnBjLnRlc3RpbmcuUGF5bG9hZENvbmZpZxI3ChBo",
-            "aXN0b2dyYW1fcGFyYW1zGAwgASgLMh0uZ3JwYy50ZXN0aW5nLkhpc3RvZ3Jh",
-            "bVBhcmFtcxIRCgljb3JlX2xpc3QYDSADKAUSEgoKY29yZV9saW1pdBgOIAEo",
-            "BSI4CgxDbGllbnRTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBjLnRlc3Rp",
-            "bmcuQ2xpZW50U3RhdHMiFQoETWFyaxINCgVyZXNldBgBIAEoCCJoCgpDbGll",
-            "bnRBcmdzEisKBXNldHVwGAEgASgLMhouZ3JwYy50ZXN0aW5nLkNsaWVudENv",
-            "bmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBjLnRlc3RpbmcuTWFya0gAQgkK",
-            "B2FyZ3R5cGUi/AEKDFNlcnZlckNvbmZpZxItCgtzZXJ2ZXJfdHlwZRgBIAEo",
-            "DjIYLmdycGMudGVzdGluZy5TZXJ2ZXJUeXBlEjUKD3NlY3VyaXR5X3BhcmFt",
-            "cxgCIAEoCzIcLmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIMCgRwb3J0",
-            "GAQgASgFEhwKFGFzeW5jX3NlcnZlcl90aHJlYWRzGAcgASgFEhIKCmNvcmVf",
-            "bGltaXQYCCABKAUSMwoOcGF5bG9hZF9jb25maWcYCSABKAsyGy5ncnBjLnRl",
-            "c3RpbmcuUGF5bG9hZENvbmZpZxIRCgljb3JlX2xpc3QYCiADKAUiaAoKU2Vy",
-            "dmVyQXJncxIrCgVzZXR1cBgBIAEoCzIaLmdycGMudGVzdGluZy5TZXJ2ZXJD",
-            "b25maWdIABIiCgRtYXJrGAIgASgLMhIuZ3JwYy50ZXN0aW5nLk1hcmtIAEIJ",
-            "Cgdhcmd0eXBlIlUKDFNlcnZlclN0YXR1cxIoCgVzdGF0cxgBIAEoCzIZLmdy",
-            "cGMudGVzdGluZy5TZXJ2ZXJTdGF0cxIMCgRwb3J0GAIgASgFEg0KBWNvcmVz",
-            "GAMgASgFIg0KC0NvcmVSZXF1ZXN0Ih0KDENvcmVSZXNwb25zZRINCgVjb3Jl",
-            "cxgBIAEoBSIGCgRWb2lkKi8KCkNsaWVudFR5cGUSDwoLU1lOQ19DTElFTlQQ",
-            "ABIQCgxBU1lOQ19DTElFTlQQASpJCgpTZXJ2ZXJUeXBlEg8KC1NZTkNfU0VS",
-            "VkVSEAASEAoMQVNZTkNfU0VSVkVSEAESGAoUQVNZTkNfR0VORVJJQ19TRVJW",
-            "RVIQAiojCgdScGNUeXBlEgkKBVVOQVJZEAASDQoJU1RSRUFNSU5HEAFiBnBy",
-            "b3RvMw=="));
+            "c29uUGFyYW1zEhQKDG9mZmVyZWRfbG9hZBgBIAEoASISChBDbG9zZWRMb29w",
+            "UGFyYW1zInsKCkxvYWRQYXJhbXMSNQoLY2xvc2VkX2xvb3AYASABKAsyHi5n",
+            "cnBjLnRlc3RpbmcuQ2xvc2VkTG9vcFBhcmFtc0gAEi4KB3BvaXNzb24YAiAB",
+            "KAsyGy5ncnBjLnRlc3RpbmcuUG9pc3NvblBhcmFtc0gAQgYKBGxvYWQiQwoO",
+            "U2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2VydmVy",
+            "X2hvc3Rfb3ZlcnJpZGUYAiABKAki1gMKDENsaWVudENvbmZpZxIWCg5zZXJ2",
+            "ZXJfdGFyZ2V0cxgBIAMoCRItCgtjbGllbnRfdHlwZRgCIAEoDjIYLmdycGMu",
+            "dGVzdGluZy5DbGllbnRUeXBlEjUKD3NlY3VyaXR5X3BhcmFtcxgDIAEoCzIc",
+            "LmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIkChxvdXRzdGFuZGluZ19y",
+            "cGNzX3Blcl9jaGFubmVsGAQgASgFEhcKD2NsaWVudF9jaGFubmVscxgFIAEo",
+            "BRIcChRhc3luY19jbGllbnRfdGhyZWFkcxgHIAEoBRInCghycGNfdHlwZRgI",
+            "IAEoDjIVLmdycGMudGVzdGluZy5ScGNUeXBlEi0KC2xvYWRfcGFyYW1zGAog",
+            "ASgLMhguZ3JwYy50ZXN0aW5nLkxvYWRQYXJhbXMSMwoOcGF5bG9hZF9jb25m",
+            "aWcYCyABKAsyGy5ncnBjLnRlc3RpbmcuUGF5bG9hZENvbmZpZxI3ChBoaXN0",
+            "b2dyYW1fcGFyYW1zGAwgASgLMh0uZ3JwYy50ZXN0aW5nLkhpc3RvZ3JhbVBh",
+            "cmFtcxIRCgljb3JlX2xpc3QYDSADKAUSEgoKY29yZV9saW1pdBgOIAEoBSI4",
+            "CgxDbGllbnRTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBjLnRlc3Rpbmcu",
+            "Q2xpZW50U3RhdHMiFQoETWFyaxINCgVyZXNldBgBIAEoCCJoCgpDbGllbnRB",
+            "cmdzEisKBXNldHVwGAEgASgLMhouZ3JwYy50ZXN0aW5nLkNsaWVudENvbmZp",
+            "Z0gAEiIKBG1hcmsYAiABKAsyEi5ncnBjLnRlc3RpbmcuTWFya0gAQgkKB2Fy",
+            "Z3R5cGUi/AEKDFNlcnZlckNvbmZpZxItCgtzZXJ2ZXJfdHlwZRgBIAEoDjIY",
+            "LmdycGMudGVzdGluZy5TZXJ2ZXJUeXBlEjUKD3NlY3VyaXR5X3BhcmFtcxgC",
+            "IAEoCzIcLmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIMCgRwb3J0GAQg",
+            "ASgFEhwKFGFzeW5jX3NlcnZlcl90aHJlYWRzGAcgASgFEhIKCmNvcmVfbGlt",
+            "aXQYCCABKAUSMwoOcGF5bG9hZF9jb25maWcYCSABKAsyGy5ncnBjLnRlc3Rp",
+            "bmcuUGF5bG9hZENvbmZpZxIRCgljb3JlX2xpc3QYCiADKAUiaAoKU2VydmVy",
+            "QXJncxIrCgVzZXR1cBgBIAEoCzIaLmdycGMudGVzdGluZy5TZXJ2ZXJDb25m",
+            "aWdIABIiCgRtYXJrGAIgASgLMhIuZ3JwYy50ZXN0aW5nLk1hcmtIAEIJCgdh",
+            "cmd0eXBlIlUKDFNlcnZlclN0YXR1cxIoCgVzdGF0cxgBIAEoCzIZLmdycGMu",
+            "dGVzdGluZy5TZXJ2ZXJTdGF0cxIMCgRwb3J0GAIgASgFEg0KBWNvcmVzGAMg",
+            "ASgFIg0KC0NvcmVSZXF1ZXN0Ih0KDENvcmVSZXNwb25zZRINCgVjb3JlcxgB",
+            "IAEoBSIGCgRWb2lkIv0BCghTY2VuYXJpbxIMCgRuYW1lGAEgASgJEjEKDWNs",
+            "aWVudF9jb25maWcYAiABKAsyGi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmln",
+            "EhMKC251bV9jbGllbnRzGAMgASgFEjEKDXNlcnZlcl9jb25maWcYBCABKAsy",
+            "Gi5ncnBjLnRlc3RpbmcuU2VydmVyQ29uZmlnEhMKC251bV9zZXJ2ZXJzGAUg",
+            "ASgFEhYKDndhcm11cF9zZWNvbmRzGAYgASgFEhkKEWJlbmNobWFya19zZWNv",
+            "bmRzGAcgASgFEiAKGHNwYXduX2xvY2FsX3dvcmtlcl9jb3VudBgIIAEoBSI2",
+            "CglTY2VuYXJpb3MSKQoJc2NlbmFyaW9zGAEgAygLMhYuZ3JwYy50ZXN0aW5n",
+            "LlNjZW5hcmlvIpICChVTY2VuYXJpb1Jlc3VsdFN1bW1hcnkSCwoDcXBzGAEg",
+            "ASgBEhsKE3Fwc19wZXJfc2VydmVyX2NvcmUYAiABKAESGgoSc2VydmVyX3N5",
+            "c3RlbV90aW1lGAMgASgBEhgKEHNlcnZlcl91c2VyX3RpbWUYBCABKAESGgoS",
+            "Y2xpZW50X3N5c3RlbV90aW1lGAUgASgBEhgKEGNsaWVudF91c2VyX3RpbWUY",
+            "BiABKAESEgoKbGF0ZW5jeV81MBgHIAEoARISCgpsYXRlbmN5XzkwGAggASgB",
+            "EhIKCmxhdGVuY3lfOTUYCSABKAESEgoKbGF0ZW5jeV85ORgKIAEoARITCgts",
+            "YXRlbmN5Xzk5ORgLIAEoASKYAgoOU2NlbmFyaW9SZXN1bHQSKAoIc2NlbmFy",
+            "aW8YASABKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8SLgoJbGF0ZW5jaWVz",
+            "GAIgASgLMhsuZ3JwYy50ZXN0aW5nLkhpc3RvZ3JhbURhdGESLwoMY2xpZW50",
+            "X3N0YXRzGAMgAygLMhkuZ3JwYy50ZXN0aW5nLkNsaWVudFN0YXRzEi8KDHNl",
+            "cnZlcl9zdGF0cxgEIAMoCzIZLmdycGMudGVzdGluZy5TZXJ2ZXJTdGF0cxIU",
+            "CgxzZXJ2ZXJfY29yZXMYBSADKAUSNAoHc3VtbWFyeRgGIAEoCzIjLmdycGMu",
+            "dGVzdGluZy5TY2VuYXJpb1Jlc3VsdFN1bW1hcnkqLwoKQ2xpZW50VHlwZRIP",
+            "CgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5DX0NMSUVOVBABKkkKClNlcnZlclR5",
+            "cGUSDwoLU1lOQ19TRVJWRVIQABIQCgxBU1lOQ19TRVJWRVIQARIYChRBU1lO",
+            "Q19HRU5FUklDX1NFUlZFUhACKiMKB1JwY1R5cGUSCQoFVU5BUlkQABINCglT",
+            "VFJFQU1JTkcQAWIGcHJvdG8z"));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, },
           new pbr::GeneratedCodeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedCodeInfo[] {
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.PoissonParams), global::Grpc.Testing.PoissonParams.Parser, new[]{ "OfferedLoad" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.UniformParams), global::Grpc.Testing.UniformParams.Parser, new[]{ "InterarrivalLo", "InterarrivalHi" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.DeterministicParams), global::Grpc.Testing.DeterministicParams.Parser, new[]{ "OfferedLoad" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ParetoParams), global::Grpc.Testing.ParetoParams.Parser, new[]{ "InterarrivalBase", "Alpha" }, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClosedLoopParams), global::Grpc.Testing.ClosedLoopParams.Parser, null, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.LoadParams), global::Grpc.Testing.LoadParams.Parser, new[]{ "ClosedLoop", "Poisson", "Uniform", "Determ", "Pareto" }, new[]{ "Load" }, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.LoadParams), global::Grpc.Testing.LoadParams.Parser, new[]{ "ClosedLoop", "Poisson" }, new[]{ "Load" }, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.SecurityParams), global::Grpc.Testing.SecurityParams.Parser, new[]{ "UseTestCa", "ServerHostOverride" }, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit" }, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientStatus), global::Grpc.Testing.ClientStatus.Parser, new[]{ "Stats" }, null, null, null),
@@ -88,7 +97,11 @@
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerStatus), global::Grpc.Testing.ServerStatus.Parser, new[]{ "Stats", "Port", "Cores" }, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.CoreRequest), global::Grpc.Testing.CoreRequest.Parser, null, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.CoreResponse), global::Grpc.Testing.CoreResponse.Parser, new[]{ "Cores" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.Void), global::Grpc.Testing.Void.Parser, null, null, null, null)
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.Void), global::Grpc.Testing.Void.Parser, null, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.Scenario), global::Grpc.Testing.Scenario.Parser, new[]{ "Name", "ClientConfig", "NumClients", "ServerConfig", "NumServers", "WarmupSeconds", "BenchmarkSeconds", "SpawnLocalWorkerCount" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.Scenarios), global::Grpc.Testing.Scenarios.Parser, new[]{ "Scenarios_" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ScenarioResultSummary), global::Grpc.Testing.ScenarioResultSummary.Parser, new[]{ "Qps", "QpsPerServerCore", "ServerSystemTime", "ServerUserTime", "ClientSystemTime", "ClientUserTime", "Latency50", "Latency90", "Latency95", "Latency99", "Latency999" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ScenarioResult), global::Grpc.Testing.ScenarioResult.Parser, new[]{ "Scenario", "Latencies", "ClientStats", "ServerStats", "ServerCores", "Summary" }, null, null, null)
           }));
     }
     #endregion
@@ -224,369 +237,6 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class UniformParams : pb::IMessage<UniformParams> {
-    private static readonly pb::MessageParser<UniformParams> _parser = new pb::MessageParser<UniformParams>(() => new UniformParams());
-    public static pb::MessageParser<UniformParams> Parser { get { return _parser; } }
-
-    public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[1]; }
-    }
-
-    pbr::MessageDescriptor pb::IMessage.Descriptor {
-      get { return Descriptor; }
-    }
-
-    public UniformParams() {
-      OnConstruction();
-    }
-
-    partial void OnConstruction();
-
-    public UniformParams(UniformParams other) : this() {
-      interarrivalLo_ = other.interarrivalLo_;
-      interarrivalHi_ = other.interarrivalHi_;
-    }
-
-    public UniformParams Clone() {
-      return new UniformParams(this);
-    }
-
-    /// <summary>Field number for the "interarrival_lo" field.</summary>
-    public const int InterarrivalLoFieldNumber = 1;
-    private double interarrivalLo_;
-    public double InterarrivalLo {
-      get { return interarrivalLo_; }
-      set {
-        interarrivalLo_ = value;
-      }
-    }
-
-    /// <summary>Field number for the "interarrival_hi" field.</summary>
-    public const int InterarrivalHiFieldNumber = 2;
-    private double interarrivalHi_;
-    public double InterarrivalHi {
-      get { return interarrivalHi_; }
-      set {
-        interarrivalHi_ = value;
-      }
-    }
-
-    public override bool Equals(object other) {
-      return Equals(other as UniformParams);
-    }
-
-    public bool Equals(UniformParams other) {
-      if (ReferenceEquals(other, null)) {
-        return false;
-      }
-      if (ReferenceEquals(other, this)) {
-        return true;
-      }
-      if (InterarrivalLo != other.InterarrivalLo) return false;
-      if (InterarrivalHi != other.InterarrivalHi) return false;
-      return true;
-    }
-
-    public override int GetHashCode() {
-      int hash = 1;
-      if (InterarrivalLo != 0D) hash ^= InterarrivalLo.GetHashCode();
-      if (InterarrivalHi != 0D) hash ^= InterarrivalHi.GetHashCode();
-      return hash;
-    }
-
-    public override string ToString() {
-      return pb::JsonFormatter.ToDiagnosticString(this);
-    }
-
-    public void WriteTo(pb::CodedOutputStream output) {
-      if (InterarrivalLo != 0D) {
-        output.WriteRawTag(9);
-        output.WriteDouble(InterarrivalLo);
-      }
-      if (InterarrivalHi != 0D) {
-        output.WriteRawTag(17);
-        output.WriteDouble(InterarrivalHi);
-      }
-    }
-
-    public int CalculateSize() {
-      int size = 0;
-      if (InterarrivalLo != 0D) {
-        size += 1 + 8;
-      }
-      if (InterarrivalHi != 0D) {
-        size += 1 + 8;
-      }
-      return size;
-    }
-
-    public void MergeFrom(UniformParams other) {
-      if (other == null) {
-        return;
-      }
-      if (other.InterarrivalLo != 0D) {
-        InterarrivalLo = other.InterarrivalLo;
-      }
-      if (other.InterarrivalHi != 0D) {
-        InterarrivalHi = other.InterarrivalHi;
-      }
-    }
-
-    public void MergeFrom(pb::CodedInputStream input) {
-      uint tag;
-      while ((tag = input.ReadTag()) != 0) {
-        switch(tag) {
-          default:
-            input.SkipLastField();
-            break;
-          case 9: {
-            InterarrivalLo = input.ReadDouble();
-            break;
-          }
-          case 17: {
-            InterarrivalHi = input.ReadDouble();
-            break;
-          }
-        }
-      }
-    }
-
-  }
-
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class DeterministicParams : pb::IMessage<DeterministicParams> {
-    private static readonly pb::MessageParser<DeterministicParams> _parser = new pb::MessageParser<DeterministicParams>(() => new DeterministicParams());
-    public static pb::MessageParser<DeterministicParams> Parser { get { return _parser; } }
-
-    public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[2]; }
-    }
-
-    pbr::MessageDescriptor pb::IMessage.Descriptor {
-      get { return Descriptor; }
-    }
-
-    public DeterministicParams() {
-      OnConstruction();
-    }
-
-    partial void OnConstruction();
-
-    public DeterministicParams(DeterministicParams other) : this() {
-      offeredLoad_ = other.offeredLoad_;
-    }
-
-    public DeterministicParams Clone() {
-      return new DeterministicParams(this);
-    }
-
-    /// <summary>Field number for the "offered_load" field.</summary>
-    public const int OfferedLoadFieldNumber = 1;
-    private double offeredLoad_;
-    public double OfferedLoad {
-      get { return offeredLoad_; }
-      set {
-        offeredLoad_ = value;
-      }
-    }
-
-    public override bool Equals(object other) {
-      return Equals(other as DeterministicParams);
-    }
-
-    public bool Equals(DeterministicParams other) {
-      if (ReferenceEquals(other, null)) {
-        return false;
-      }
-      if (ReferenceEquals(other, this)) {
-        return true;
-      }
-      if (OfferedLoad != other.OfferedLoad) return false;
-      return true;
-    }
-
-    public override int GetHashCode() {
-      int hash = 1;
-      if (OfferedLoad != 0D) hash ^= OfferedLoad.GetHashCode();
-      return hash;
-    }
-
-    public override string ToString() {
-      return pb::JsonFormatter.ToDiagnosticString(this);
-    }
-
-    public void WriteTo(pb::CodedOutputStream output) {
-      if (OfferedLoad != 0D) {
-        output.WriteRawTag(9);
-        output.WriteDouble(OfferedLoad);
-      }
-    }
-
-    public int CalculateSize() {
-      int size = 0;
-      if (OfferedLoad != 0D) {
-        size += 1 + 8;
-      }
-      return size;
-    }
-
-    public void MergeFrom(DeterministicParams other) {
-      if (other == null) {
-        return;
-      }
-      if (other.OfferedLoad != 0D) {
-        OfferedLoad = other.OfferedLoad;
-      }
-    }
-
-    public void MergeFrom(pb::CodedInputStream input) {
-      uint tag;
-      while ((tag = input.ReadTag()) != 0) {
-        switch(tag) {
-          default:
-            input.SkipLastField();
-            break;
-          case 9: {
-            OfferedLoad = input.ReadDouble();
-            break;
-          }
-        }
-      }
-    }
-
-  }
-
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class ParetoParams : pb::IMessage<ParetoParams> {
-    private static readonly pb::MessageParser<ParetoParams> _parser = new pb::MessageParser<ParetoParams>(() => new ParetoParams());
-    public static pb::MessageParser<ParetoParams> Parser { get { return _parser; } }
-
-    public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[3]; }
-    }
-
-    pbr::MessageDescriptor pb::IMessage.Descriptor {
-      get { return Descriptor; }
-    }
-
-    public ParetoParams() {
-      OnConstruction();
-    }
-
-    partial void OnConstruction();
-
-    public ParetoParams(ParetoParams other) : this() {
-      interarrivalBase_ = other.interarrivalBase_;
-      alpha_ = other.alpha_;
-    }
-
-    public ParetoParams Clone() {
-      return new ParetoParams(this);
-    }
-
-    /// <summary>Field number for the "interarrival_base" field.</summary>
-    public const int InterarrivalBaseFieldNumber = 1;
-    private double interarrivalBase_;
-    public double InterarrivalBase {
-      get { return interarrivalBase_; }
-      set {
-        interarrivalBase_ = value;
-      }
-    }
-
-    /// <summary>Field number for the "alpha" field.</summary>
-    public const int AlphaFieldNumber = 2;
-    private double alpha_;
-    public double Alpha {
-      get { return alpha_; }
-      set {
-        alpha_ = value;
-      }
-    }
-
-    public override bool Equals(object other) {
-      return Equals(other as ParetoParams);
-    }
-
-    public bool Equals(ParetoParams other) {
-      if (ReferenceEquals(other, null)) {
-        return false;
-      }
-      if (ReferenceEquals(other, this)) {
-        return true;
-      }
-      if (InterarrivalBase != other.InterarrivalBase) return false;
-      if (Alpha != other.Alpha) return false;
-      return true;
-    }
-
-    public override int GetHashCode() {
-      int hash = 1;
-      if (InterarrivalBase != 0D) hash ^= InterarrivalBase.GetHashCode();
-      if (Alpha != 0D) hash ^= Alpha.GetHashCode();
-      return hash;
-    }
-
-    public override string ToString() {
-      return pb::JsonFormatter.ToDiagnosticString(this);
-    }
-
-    public void WriteTo(pb::CodedOutputStream output) {
-      if (InterarrivalBase != 0D) {
-        output.WriteRawTag(9);
-        output.WriteDouble(InterarrivalBase);
-      }
-      if (Alpha != 0D) {
-        output.WriteRawTag(17);
-        output.WriteDouble(Alpha);
-      }
-    }
-
-    public int CalculateSize() {
-      int size = 0;
-      if (InterarrivalBase != 0D) {
-        size += 1 + 8;
-      }
-      if (Alpha != 0D) {
-        size += 1 + 8;
-      }
-      return size;
-    }
-
-    public void MergeFrom(ParetoParams other) {
-      if (other == null) {
-        return;
-      }
-      if (other.InterarrivalBase != 0D) {
-        InterarrivalBase = other.InterarrivalBase;
-      }
-      if (other.Alpha != 0D) {
-        Alpha = other.Alpha;
-      }
-    }
-
-    public void MergeFrom(pb::CodedInputStream input) {
-      uint tag;
-      while ((tag = input.ReadTag()) != 0) {
-        switch(tag) {
-          default:
-            input.SkipLastField();
-            break;
-          case 9: {
-            InterarrivalBase = input.ReadDouble();
-            break;
-          }
-          case 17: {
-            Alpha = input.ReadDouble();
-            break;
-          }
-        }
-      }
-    }
-
-  }
-
   /// <summary>
   ///  Once an RPC finishes, immediately start a new one.
   ///  No configuration parameters needed.
@@ -597,7 +247,7 @@
     public static pb::MessageParser<ClosedLoopParams> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[4]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[1]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -673,7 +323,7 @@
     public static pb::MessageParser<LoadParams> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[5]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[2]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -694,15 +344,6 @@
         case LoadOneofCase.Poisson:
           Poisson = other.Poisson.Clone();
           break;
-        case LoadOneofCase.Uniform:
-          Uniform = other.Uniform.Clone();
-          break;
-        case LoadOneofCase.Determ:
-          Determ = other.Determ.Clone();
-          break;
-        case LoadOneofCase.Pareto:
-          Pareto = other.Pareto.Clone();
-          break;
       }
 
     }
@@ -731,45 +372,12 @@
       }
     }
 
-    /// <summary>Field number for the "uniform" field.</summary>
-    public const int UniformFieldNumber = 3;
-    public global::Grpc.Testing.UniformParams Uniform {
-      get { return loadCase_ == LoadOneofCase.Uniform ? (global::Grpc.Testing.UniformParams) load_ : null; }
-      set {
-        load_ = value;
-        loadCase_ = value == null ? LoadOneofCase.None : LoadOneofCase.Uniform;
-      }
-    }
-
-    /// <summary>Field number for the "determ" field.</summary>
-    public const int DetermFieldNumber = 4;
-    public global::Grpc.Testing.DeterministicParams Determ {
-      get { return loadCase_ == LoadOneofCase.Determ ? (global::Grpc.Testing.DeterministicParams) load_ : null; }
-      set {
-        load_ = value;
-        loadCase_ = value == null ? LoadOneofCase.None : LoadOneofCase.Determ;
-      }
-    }
-
-    /// <summary>Field number for the "pareto" field.</summary>
-    public const int ParetoFieldNumber = 5;
-    public global::Grpc.Testing.ParetoParams Pareto {
-      get { return loadCase_ == LoadOneofCase.Pareto ? (global::Grpc.Testing.ParetoParams) load_ : null; }
-      set {
-        load_ = value;
-        loadCase_ = value == null ? LoadOneofCase.None : LoadOneofCase.Pareto;
-      }
-    }
-
     private object load_;
     /// <summary>Enum of possible cases for the "load" oneof.</summary>
     public enum LoadOneofCase {
       None = 0,
       ClosedLoop = 1,
       Poisson = 2,
-      Uniform = 3,
-      Determ = 4,
-      Pareto = 5,
     }
     private LoadOneofCase loadCase_ = LoadOneofCase.None;
     public LoadOneofCase LoadCase {
@@ -794,9 +402,6 @@
       }
       if (!object.Equals(ClosedLoop, other.ClosedLoop)) return false;
       if (!object.Equals(Poisson, other.Poisson)) return false;
-      if (!object.Equals(Uniform, other.Uniform)) return false;
-      if (!object.Equals(Determ, other.Determ)) return false;
-      if (!object.Equals(Pareto, other.Pareto)) return false;
       if (LoadCase != other.LoadCase) return false;
       return true;
     }
@@ -805,9 +410,6 @@
       int hash = 1;
       if (loadCase_ == LoadOneofCase.ClosedLoop) hash ^= ClosedLoop.GetHashCode();
       if (loadCase_ == LoadOneofCase.Poisson) hash ^= Poisson.GetHashCode();
-      if (loadCase_ == LoadOneofCase.Uniform) hash ^= Uniform.GetHashCode();
-      if (loadCase_ == LoadOneofCase.Determ) hash ^= Determ.GetHashCode();
-      if (loadCase_ == LoadOneofCase.Pareto) hash ^= Pareto.GetHashCode();
       hash ^= (int) loadCase_;
       return hash;
     }
@@ -825,18 +427,6 @@
         output.WriteRawTag(18);
         output.WriteMessage(Poisson);
       }
-      if (loadCase_ == LoadOneofCase.Uniform) {
-        output.WriteRawTag(26);
-        output.WriteMessage(Uniform);
-      }
-      if (loadCase_ == LoadOneofCase.Determ) {
-        output.WriteRawTag(34);
-        output.WriteMessage(Determ);
-      }
-      if (loadCase_ == LoadOneofCase.Pareto) {
-        output.WriteRawTag(42);
-        output.WriteMessage(Pareto);
-      }
     }
 
     public int CalculateSize() {
@@ -847,15 +437,6 @@
       if (loadCase_ == LoadOneofCase.Poisson) {
         size += 1 + pb::CodedOutputStream.ComputeMessageSize(Poisson);
       }
-      if (loadCase_ == LoadOneofCase.Uniform) {
-        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Uniform);
-      }
-      if (loadCase_ == LoadOneofCase.Determ) {
-        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Determ);
-      }
-      if (loadCase_ == LoadOneofCase.Pareto) {
-        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Pareto);
-      }
       return size;
     }
 
@@ -870,15 +451,6 @@
         case LoadOneofCase.Poisson:
           Poisson = other.Poisson;
           break;
-        case LoadOneofCase.Uniform:
-          Uniform = other.Uniform;
-          break;
-        case LoadOneofCase.Determ:
-          Determ = other.Determ;
-          break;
-        case LoadOneofCase.Pareto:
-          Pareto = other.Pareto;
-          break;
       }
 
     }
@@ -908,33 +480,6 @@
             Poisson = subBuilder;
             break;
           }
-          case 26: {
-            global::Grpc.Testing.UniformParams subBuilder = new global::Grpc.Testing.UniformParams();
-            if (loadCase_ == LoadOneofCase.Uniform) {
-              subBuilder.MergeFrom(Uniform);
-            }
-            input.ReadMessage(subBuilder);
-            Uniform = subBuilder;
-            break;
-          }
-          case 34: {
-            global::Grpc.Testing.DeterministicParams subBuilder = new global::Grpc.Testing.DeterministicParams();
-            if (loadCase_ == LoadOneofCase.Determ) {
-              subBuilder.MergeFrom(Determ);
-            }
-            input.ReadMessage(subBuilder);
-            Determ = subBuilder;
-            break;
-          }
-          case 42: {
-            global::Grpc.Testing.ParetoParams subBuilder = new global::Grpc.Testing.ParetoParams();
-            if (loadCase_ == LoadOneofCase.Pareto) {
-              subBuilder.MergeFrom(Pareto);
-            }
-            input.ReadMessage(subBuilder);
-            Pareto = subBuilder;
-            break;
-          }
         }
       }
     }
@@ -950,7 +495,7 @@
     public static pb::MessageParser<SecurityParams> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[6]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[3]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1080,7 +625,7 @@
     public static pb::MessageParser<ClientConfig> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[7]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[4]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1509,7 +1054,7 @@
     public static pb::MessageParser<ClientStatus> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[8]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[5]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1621,7 +1166,7 @@
     public static pb::MessageParser<Mark> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[9]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[6]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1727,7 +1272,7 @@
     public static pb::MessageParser<ClientArgs> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[10]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[7]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1896,7 +1441,7 @@
     public static pb::MessageParser<ServerConfig> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[11]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[8]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2181,7 +1726,7 @@
     public static pb::MessageParser<ServerArgs> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[12]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[9]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2350,7 +1895,7 @@
     public static pb::MessageParser<ServerStatus> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[13]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[10]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2519,7 +2064,7 @@
     public static pb::MessageParser<CoreRequest> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[14]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[11]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2595,7 +2140,7 @@
     public static pb::MessageParser<CoreResponse> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[15]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[12]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2701,7 +2246,7 @@
     public static pb::MessageParser<Void> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[16]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[13]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2771,6 +2316,1087 @@
 
   }
 
+  /// <summary>
+  ///  A single performance scenario: input to qps_json_driver
+  /// </summary>
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class Scenario : pb::IMessage<Scenario> {
+    private static readonly pb::MessageParser<Scenario> _parser = new pb::MessageParser<Scenario>(() => new Scenario());
+    public static pb::MessageParser<Scenario> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[14]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public Scenario() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public Scenario(Scenario other) : this() {
+      name_ = other.name_;
+      ClientConfig = other.clientConfig_ != null ? other.ClientConfig.Clone() : null;
+      numClients_ = other.numClients_;
+      ServerConfig = other.serverConfig_ != null ? other.ServerConfig.Clone() : null;
+      numServers_ = other.numServers_;
+      warmupSeconds_ = other.warmupSeconds_;
+      benchmarkSeconds_ = other.benchmarkSeconds_;
+      spawnLocalWorkerCount_ = other.spawnLocalWorkerCount_;
+    }
+
+    public Scenario Clone() {
+      return new Scenario(this);
+    }
+
+    /// <summary>Field number for the "name" field.</summary>
+    public const int NameFieldNumber = 1;
+    private string name_ = "";
+    /// <summary>
+    ///  Human readable name for this scenario
+    /// </summary>
+    public string Name {
+      get { return name_; }
+      set {
+        name_ = pb::Preconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "client_config" field.</summary>
+    public const int ClientConfigFieldNumber = 2;
+    private global::Grpc.Testing.ClientConfig clientConfig_;
+    /// <summary>
+    ///  Client configuration
+    /// </summary>
+    public global::Grpc.Testing.ClientConfig ClientConfig {
+      get { return clientConfig_; }
+      set {
+        clientConfig_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "num_clients" field.</summary>
+    public const int NumClientsFieldNumber = 3;
+    private int numClients_;
+    /// <summary>
+    ///  Number of clients to start for the test
+    /// </summary>
+    public int NumClients {
+      get { return numClients_; }
+      set {
+        numClients_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "server_config" field.</summary>
+    public const int ServerConfigFieldNumber = 4;
+    private global::Grpc.Testing.ServerConfig serverConfig_;
+    /// <summary>
+    ///  Server configuration
+    /// </summary>
+    public global::Grpc.Testing.ServerConfig ServerConfig {
+      get { return serverConfig_; }
+      set {
+        serverConfig_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "num_servers" field.</summary>
+    public const int NumServersFieldNumber = 5;
+    private int numServers_;
+    /// <summary>
+    ///  Number of servers to start for the test
+    /// </summary>
+    public int NumServers {
+      get { return numServers_; }
+      set {
+        numServers_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "warmup_seconds" field.</summary>
+    public const int WarmupSecondsFieldNumber = 6;
+    private int warmupSeconds_;
+    /// <summary>
+    ///  Warmup period, in seconds
+    /// </summary>
+    public int WarmupSeconds {
+      get { return warmupSeconds_; }
+      set {
+        warmupSeconds_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "benchmark_seconds" field.</summary>
+    public const int BenchmarkSecondsFieldNumber = 7;
+    private int benchmarkSeconds_;
+    /// <summary>
+    ///  Benchmark time, in seconds
+    /// </summary>
+    public int BenchmarkSeconds {
+      get { return benchmarkSeconds_; }
+      set {
+        benchmarkSeconds_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "spawn_local_worker_count" field.</summary>
+    public const int SpawnLocalWorkerCountFieldNumber = 8;
+    private int spawnLocalWorkerCount_;
+    /// <summary>
+    ///  Number of workers to spawn locally (usually zero)
+    /// </summary>
+    public int SpawnLocalWorkerCount {
+      get { return spawnLocalWorkerCount_; }
+      set {
+        spawnLocalWorkerCount_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as Scenario);
+    }
+
+    public bool Equals(Scenario other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Name != other.Name) return false;
+      if (!object.Equals(ClientConfig, other.ClientConfig)) return false;
+      if (NumClients != other.NumClients) return false;
+      if (!object.Equals(ServerConfig, other.ServerConfig)) return false;
+      if (NumServers != other.NumServers) return false;
+      if (WarmupSeconds != other.WarmupSeconds) return false;
+      if (BenchmarkSeconds != other.BenchmarkSeconds) return false;
+      if (SpawnLocalWorkerCount != other.SpawnLocalWorkerCount) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Name.Length != 0) hash ^= Name.GetHashCode();
+      if (clientConfig_ != null) hash ^= ClientConfig.GetHashCode();
+      if (NumClients != 0) hash ^= NumClients.GetHashCode();
+      if (serverConfig_ != null) hash ^= ServerConfig.GetHashCode();
+      if (NumServers != 0) hash ^= NumServers.GetHashCode();
+      if (WarmupSeconds != 0) hash ^= WarmupSeconds.GetHashCode();
+      if (BenchmarkSeconds != 0) hash ^= BenchmarkSeconds.GetHashCode();
+      if (SpawnLocalWorkerCount != 0) hash ^= SpawnLocalWorkerCount.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Name.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Name);
+      }
+      if (clientConfig_ != null) {
+        output.WriteRawTag(18);
+        output.WriteMessage(ClientConfig);
+      }
+      if (NumClients != 0) {
+        output.WriteRawTag(24);
+        output.WriteInt32(NumClients);
+      }
+      if (serverConfig_ != null) {
+        output.WriteRawTag(34);
+        output.WriteMessage(ServerConfig);
+      }
+      if (NumServers != 0) {
+        output.WriteRawTag(40);
+        output.WriteInt32(NumServers);
+      }
+      if (WarmupSeconds != 0) {
+        output.WriteRawTag(48);
+        output.WriteInt32(WarmupSeconds);
+      }
+      if (BenchmarkSeconds != 0) {
+        output.WriteRawTag(56);
+        output.WriteInt32(BenchmarkSeconds);
+      }
+      if (SpawnLocalWorkerCount != 0) {
+        output.WriteRawTag(64);
+        output.WriteInt32(SpawnLocalWorkerCount);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (Name.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+      }
+      if (clientConfig_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(ClientConfig);
+      }
+      if (NumClients != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(NumClients);
+      }
+      if (serverConfig_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(ServerConfig);
+      }
+      if (NumServers != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(NumServers);
+      }
+      if (WarmupSeconds != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(WarmupSeconds);
+      }
+      if (BenchmarkSeconds != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(BenchmarkSeconds);
+      }
+      if (SpawnLocalWorkerCount != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(SpawnLocalWorkerCount);
+      }
+      return size;
+    }
+
+    public void MergeFrom(Scenario other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Name.Length != 0) {
+        Name = other.Name;
+      }
+      if (other.clientConfig_ != null) {
+        if (clientConfig_ == null) {
+          clientConfig_ = new global::Grpc.Testing.ClientConfig();
+        }
+        ClientConfig.MergeFrom(other.ClientConfig);
+      }
+      if (other.NumClients != 0) {
+        NumClients = other.NumClients;
+      }
+      if (other.serverConfig_ != null) {
+        if (serverConfig_ == null) {
+          serverConfig_ = new global::Grpc.Testing.ServerConfig();
+        }
+        ServerConfig.MergeFrom(other.ServerConfig);
+      }
+      if (other.NumServers != 0) {
+        NumServers = other.NumServers;
+      }
+      if (other.WarmupSeconds != 0) {
+        WarmupSeconds = other.WarmupSeconds;
+      }
+      if (other.BenchmarkSeconds != 0) {
+        BenchmarkSeconds = other.BenchmarkSeconds;
+      }
+      if (other.SpawnLocalWorkerCount != 0) {
+        SpawnLocalWorkerCount = other.SpawnLocalWorkerCount;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            Name = input.ReadString();
+            break;
+          }
+          case 18: {
+            if (clientConfig_ == null) {
+              clientConfig_ = new global::Grpc.Testing.ClientConfig();
+            }
+            input.ReadMessage(clientConfig_);
+            break;
+          }
+          case 24: {
+            NumClients = input.ReadInt32();
+            break;
+          }
+          case 34: {
+            if (serverConfig_ == null) {
+              serverConfig_ = new global::Grpc.Testing.ServerConfig();
+            }
+            input.ReadMessage(serverConfig_);
+            break;
+          }
+          case 40: {
+            NumServers = input.ReadInt32();
+            break;
+          }
+          case 48: {
+            WarmupSeconds = input.ReadInt32();
+            break;
+          }
+          case 56: {
+            BenchmarkSeconds = input.ReadInt32();
+            break;
+          }
+          case 64: {
+            SpawnLocalWorkerCount = input.ReadInt32();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  /// <summary>
+  ///  A set of scenarios to be run with qps_json_driver
+  /// </summary>
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class Scenarios : pb::IMessage<Scenarios> {
+    private static readonly pb::MessageParser<Scenarios> _parser = new pb::MessageParser<Scenarios>(() => new Scenarios());
+    public static pb::MessageParser<Scenarios> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[15]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public Scenarios() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public Scenarios(Scenarios other) : this() {
+      scenarios_ = other.scenarios_.Clone();
+    }
+
+    public Scenarios Clone() {
+      return new Scenarios(this);
+    }
+
+    /// <summary>Field number for the "scenarios" field.</summary>
+    public const int Scenarios_FieldNumber = 1;
+    private static readonly pb::FieldCodec<global::Grpc.Testing.Scenario> _repeated_scenarios_codec
+        = pb::FieldCodec.ForMessage(10, global::Grpc.Testing.Scenario.Parser);
+    private readonly pbc::RepeatedField<global::Grpc.Testing.Scenario> scenarios_ = new pbc::RepeatedField<global::Grpc.Testing.Scenario>();
+    public pbc::RepeatedField<global::Grpc.Testing.Scenario> Scenarios_ {
+      get { return scenarios_; }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as Scenarios);
+    }
+
+    public bool Equals(Scenarios other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if(!scenarios_.Equals(other.scenarios_)) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      hash ^= scenarios_.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      scenarios_.WriteTo(output, _repeated_scenarios_codec);
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      size += scenarios_.CalculateSize(_repeated_scenarios_codec);
+      return size;
+    }
+
+    public void MergeFrom(Scenarios other) {
+      if (other == null) {
+        return;
+      }
+      scenarios_.Add(other.scenarios_);
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            scenarios_.AddEntriesFrom(input, _repeated_scenarios_codec);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  /// <summary>
+  ///  Basic summary that can be computed from ClientStats and ServerStats
+  ///  once the scenario has finished.
+  /// </summary>
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ScenarioResultSummary : pb::IMessage<ScenarioResultSummary> {
+    private static readonly pb::MessageParser<ScenarioResultSummary> _parser = new pb::MessageParser<ScenarioResultSummary>(() => new ScenarioResultSummary());
+    public static pb::MessageParser<ScenarioResultSummary> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[16]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ScenarioResultSummary() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ScenarioResultSummary(ScenarioResultSummary other) : this() {
+      qps_ = other.qps_;
+      qpsPerServerCore_ = other.qpsPerServerCore_;
+      serverSystemTime_ = other.serverSystemTime_;
+      serverUserTime_ = other.serverUserTime_;
+      clientSystemTime_ = other.clientSystemTime_;
+      clientUserTime_ = other.clientUserTime_;
+      latency50_ = other.latency50_;
+      latency90_ = other.latency90_;
+      latency95_ = other.latency95_;
+      latency99_ = other.latency99_;
+      latency999_ = other.latency999_;
+    }
+
+    public ScenarioResultSummary Clone() {
+      return new ScenarioResultSummary(this);
+    }
+
+    /// <summary>Field number for the "qps" field.</summary>
+    public const int QpsFieldNumber = 1;
+    private double qps_;
+    /// <summary>
+    ///  Total number of operations per second over all clients.
+    /// </summary>
+    public double Qps {
+      get { return qps_; }
+      set {
+        qps_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "qps_per_server_core" field.</summary>
+    public const int QpsPerServerCoreFieldNumber = 2;
+    private double qpsPerServerCore_;
+    /// <summary>
+    ///  QPS per one server core.
+    /// </summary>
+    public double QpsPerServerCore {
+      get { return qpsPerServerCore_; }
+      set {
+        qpsPerServerCore_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "server_system_time" field.</summary>
+    public const int ServerSystemTimeFieldNumber = 3;
+    private double serverSystemTime_;
+    /// <summary>
+    ///  server load based on system_time (0.85 => 85%)
+    /// </summary>
+    public double ServerSystemTime {
+      get { return serverSystemTime_; }
+      set {
+        serverSystemTime_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "server_user_time" field.</summary>
+    public const int ServerUserTimeFieldNumber = 4;
+    private double serverUserTime_;
+    /// <summary>
+    ///  server load based on user_time (0.85 => 85%)
+    /// </summary>
+    public double ServerUserTime {
+      get { return serverUserTime_; }
+      set {
+        serverUserTime_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "client_system_time" field.</summary>
+    public const int ClientSystemTimeFieldNumber = 5;
+    private double clientSystemTime_;
+    /// <summary>
+    ///  client load based on system_time (0.85 => 85%)
+    /// </summary>
+    public double ClientSystemTime {
+      get { return clientSystemTime_; }
+      set {
+        clientSystemTime_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "client_user_time" field.</summary>
+    public const int ClientUserTimeFieldNumber = 6;
+    private double clientUserTime_;
+    /// <summary>
+    ///  client load based on user_time (0.85 => 85%)
+    /// </summary>
+    public double ClientUserTime {
+      get { return clientUserTime_; }
+      set {
+        clientUserTime_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "latency_50" field.</summary>
+    public const int Latency50FieldNumber = 7;
+    private double latency50_;
+    /// <summary>
+    ///  X% latency percentiles (in nanoseconds)
+    /// </summary>
+    public double Latency50 {
+      get { return latency50_; }
+      set {
+        latency50_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "latency_90" field.</summary>
+    public const int Latency90FieldNumber = 8;
+    private double latency90_;
+    public double Latency90 {
+      get { return latency90_; }
+      set {
+        latency90_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "latency_95" field.</summary>
+    public const int Latency95FieldNumber = 9;
+    private double latency95_;
+    public double Latency95 {
+      get { return latency95_; }
+      set {
+        latency95_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "latency_99" field.</summary>
+    public const int Latency99FieldNumber = 10;
+    private double latency99_;
+    public double Latency99 {
+      get { return latency99_; }
+      set {
+        latency99_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "latency_999" field.</summary>
+    public const int Latency999FieldNumber = 11;
+    private double latency999_;
+    public double Latency999 {
+      get { return latency999_; }
+      set {
+        latency999_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ScenarioResultSummary);
+    }
+
+    public bool Equals(ScenarioResultSummary other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Qps != other.Qps) return false;
+      if (QpsPerServerCore != other.QpsPerServerCore) return false;
+      if (ServerSystemTime != other.ServerSystemTime) return false;
+      if (ServerUserTime != other.ServerUserTime) return false;
+      if (ClientSystemTime != other.ClientSystemTime) return false;
+      if (ClientUserTime != other.ClientUserTime) return false;
+      if (Latency50 != other.Latency50) return false;
+      if (Latency90 != other.Latency90) return false;
+      if (Latency95 != other.Latency95) return false;
+      if (Latency99 != other.Latency99) return false;
+      if (Latency999 != other.Latency999) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Qps != 0D) hash ^= Qps.GetHashCode();
+      if (QpsPerServerCore != 0D) hash ^= QpsPerServerCore.GetHashCode();
+      if (ServerSystemTime != 0D) hash ^= ServerSystemTime.GetHashCode();
+      if (ServerUserTime != 0D) hash ^= ServerUserTime.GetHashCode();
+      if (ClientSystemTime != 0D) hash ^= ClientSystemTime.GetHashCode();
+      if (ClientUserTime != 0D) hash ^= ClientUserTime.GetHashCode();
+      if (Latency50 != 0D) hash ^= Latency50.GetHashCode();
+      if (Latency90 != 0D) hash ^= Latency90.GetHashCode();
+      if (Latency95 != 0D) hash ^= Latency95.GetHashCode();
+      if (Latency99 != 0D) hash ^= Latency99.GetHashCode();
+      if (Latency999 != 0D) hash ^= Latency999.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Qps != 0D) {
+        output.WriteRawTag(9);
+        output.WriteDouble(Qps);
+      }
+      if (QpsPerServerCore != 0D) {
+        output.WriteRawTag(17);
+        output.WriteDouble(QpsPerServerCore);
+      }
+      if (ServerSystemTime != 0D) {
+        output.WriteRawTag(25);
+        output.WriteDouble(ServerSystemTime);
+      }
+      if (ServerUserTime != 0D) {
+        output.WriteRawTag(33);
+        output.WriteDouble(ServerUserTime);
+      }
+      if (ClientSystemTime != 0D) {
+        output.WriteRawTag(41);
+        output.WriteDouble(ClientSystemTime);
+      }
+      if (ClientUserTime != 0D) {
+        output.WriteRawTag(49);
+        output.WriteDouble(ClientUserTime);
+      }
+      if (Latency50 != 0D) {
+        output.WriteRawTag(57);
+        output.WriteDouble(Latency50);
+      }
+      if (Latency90 != 0D) {
+        output.WriteRawTag(65);
+        output.WriteDouble(Latency90);
+      }
+      if (Latency95 != 0D) {
+        output.WriteRawTag(73);
+        output.WriteDouble(Latency95);
+      }
+      if (Latency99 != 0D) {
+        output.WriteRawTag(81);
+        output.WriteDouble(Latency99);
+      }
+      if (Latency999 != 0D) {
+        output.WriteRawTag(89);
+        output.WriteDouble(Latency999);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (Qps != 0D) {
+        size += 1 + 8;
+      }
+      if (QpsPerServerCore != 0D) {
+        size += 1 + 8;
+      }
+      if (ServerSystemTime != 0D) {
+        size += 1 + 8;
+      }
+      if (ServerUserTime != 0D) {
+        size += 1 + 8;
+      }
+      if (ClientSystemTime != 0D) {
+        size += 1 + 8;
+      }
+      if (ClientUserTime != 0D) {
+        size += 1 + 8;
+      }
+      if (Latency50 != 0D) {
+        size += 1 + 8;
+      }
+      if (Latency90 != 0D) {
+        size += 1 + 8;
+      }
+      if (Latency95 != 0D) {
+        size += 1 + 8;
+      }
+      if (Latency99 != 0D) {
+        size += 1 + 8;
+      }
+      if (Latency999 != 0D) {
+        size += 1 + 8;
+      }
+      return size;
+    }
+
+    public void MergeFrom(ScenarioResultSummary other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Qps != 0D) {
+        Qps = other.Qps;
+      }
+      if (other.QpsPerServerCore != 0D) {
+        QpsPerServerCore = other.QpsPerServerCore;
+      }
+      if (other.ServerSystemTime != 0D) {
+        ServerSystemTime = other.ServerSystemTime;
+      }
+      if (other.ServerUserTime != 0D) {
+        ServerUserTime = other.ServerUserTime;
+      }
+      if (other.ClientSystemTime != 0D) {
+        ClientSystemTime = other.ClientSystemTime;
+      }
+      if (other.ClientUserTime != 0D) {
+        ClientUserTime = other.ClientUserTime;
+      }
+      if (other.Latency50 != 0D) {
+        Latency50 = other.Latency50;
+      }
+      if (other.Latency90 != 0D) {
+        Latency90 = other.Latency90;
+      }
+      if (other.Latency95 != 0D) {
+        Latency95 = other.Latency95;
+      }
+      if (other.Latency99 != 0D) {
+        Latency99 = other.Latency99;
+      }
+      if (other.Latency999 != 0D) {
+        Latency999 = other.Latency999;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 9: {
+            Qps = input.ReadDouble();
+            break;
+          }
+          case 17: {
+            QpsPerServerCore = input.ReadDouble();
+            break;
+          }
+          case 25: {
+            ServerSystemTime = input.ReadDouble();
+            break;
+          }
+          case 33: {
+            ServerUserTime = input.ReadDouble();
+            break;
+          }
+          case 41: {
+            ClientSystemTime = input.ReadDouble();
+            break;
+          }
+          case 49: {
+            ClientUserTime = input.ReadDouble();
+            break;
+          }
+          case 57: {
+            Latency50 = input.ReadDouble();
+            break;
+          }
+          case 65: {
+            Latency90 = input.ReadDouble();
+            break;
+          }
+          case 73: {
+            Latency95 = input.ReadDouble();
+            break;
+          }
+          case 81: {
+            Latency99 = input.ReadDouble();
+            break;
+          }
+          case 89: {
+            Latency999 = input.ReadDouble();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  /// <summary>
+  ///  Results of a single benchmark scenario.
+  /// </summary>
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ScenarioResult : pb::IMessage<ScenarioResult> {
+    private static readonly pb::MessageParser<ScenarioResult> _parser = new pb::MessageParser<ScenarioResult>(() => new ScenarioResult());
+    public static pb::MessageParser<ScenarioResult> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[17]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ScenarioResult() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ScenarioResult(ScenarioResult other) : this() {
+      Scenario = other.scenario_ != null ? other.Scenario.Clone() : null;
+      Latencies = other.latencies_ != null ? other.Latencies.Clone() : null;
+      clientStats_ = other.clientStats_.Clone();
+      serverStats_ = other.serverStats_.Clone();
+      serverCores_ = other.serverCores_.Clone();
+      Summary = other.summary_ != null ? other.Summary.Clone() : null;
+    }
+
+    public ScenarioResult Clone() {
+      return new ScenarioResult(this);
+    }
+
+    /// <summary>Field number for the "scenario" field.</summary>
+    public const int ScenarioFieldNumber = 1;
+    private global::Grpc.Testing.Scenario scenario_;
+    /// <summary>
+    ///  Inputs used to run the scenario.
+    /// </summary>
+    public global::Grpc.Testing.Scenario Scenario {
+      get { return scenario_; }
+      set {
+        scenario_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "latencies" field.</summary>
+    public const int LatenciesFieldNumber = 2;
+    private global::Grpc.Testing.HistogramData latencies_;
+    /// <summary>
+    ///  Histograms from all clients merged into one histogram.
+    /// </summary>
+    public global::Grpc.Testing.HistogramData Latencies {
+      get { return latencies_; }
+      set {
+        latencies_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "client_stats" field.</summary>
+    public const int ClientStatsFieldNumber = 3;
+    private static readonly pb::FieldCodec<global::Grpc.Testing.ClientStats> _repeated_clientStats_codec
+        = pb::FieldCodec.ForMessage(26, global::Grpc.Testing.ClientStats.Parser);
+    private readonly pbc::RepeatedField<global::Grpc.Testing.ClientStats> clientStats_ = new pbc::RepeatedField<global::Grpc.Testing.ClientStats>();
+    /// <summary>
+    ///  Client stats for each client
+    /// </summary>
+    public pbc::RepeatedField<global::Grpc.Testing.ClientStats> ClientStats {
+      get { return clientStats_; }
+    }
+
+    /// <summary>Field number for the "server_stats" field.</summary>
+    public const int ServerStatsFieldNumber = 4;
+    private static readonly pb::FieldCodec<global::Grpc.Testing.ServerStats> _repeated_serverStats_codec
+        = pb::FieldCodec.ForMessage(34, global::Grpc.Testing.ServerStats.Parser);
+    private readonly pbc::RepeatedField<global::Grpc.Testing.ServerStats> serverStats_ = new pbc::RepeatedField<global::Grpc.Testing.ServerStats>();
+    /// <summary>
+    ///  Server stats for each server
+    /// </summary>
+    public pbc::RepeatedField<global::Grpc.Testing.ServerStats> ServerStats {
+      get { return serverStats_; }
+    }
+
+    /// <summary>Field number for the "server_cores" field.</summary>
+    public const int ServerCoresFieldNumber = 5;
+    private static readonly pb::FieldCodec<int> _repeated_serverCores_codec
+        = pb::FieldCodec.ForInt32(42);
+    private readonly pbc::RepeatedField<int> serverCores_ = new pbc::RepeatedField<int>();
+    /// <summary>
+    ///  Number of cores available to each server
+    /// </summary>
+    public pbc::RepeatedField<int> ServerCores {
+      get { return serverCores_; }
+    }
+
+    /// <summary>Field number for the "summary" field.</summary>
+    public const int SummaryFieldNumber = 6;
+    private global::Grpc.Testing.ScenarioResultSummary summary_;
+    /// <summary>
+    ///  An after-the-fact computed summary
+    /// </summary>
+    public global::Grpc.Testing.ScenarioResultSummary Summary {
+      get { return summary_; }
+      set {
+        summary_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ScenarioResult);
+    }
+
+    public bool Equals(ScenarioResult other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(Scenario, other.Scenario)) return false;
+      if (!object.Equals(Latencies, other.Latencies)) return false;
+      if(!clientStats_.Equals(other.clientStats_)) return false;
+      if(!serverStats_.Equals(other.serverStats_)) return false;
+      if(!serverCores_.Equals(other.serverCores_)) return false;
+      if (!object.Equals(Summary, other.Summary)) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (scenario_ != null) hash ^= Scenario.GetHashCode();
+      if (latencies_ != null) hash ^= Latencies.GetHashCode();
+      hash ^= clientStats_.GetHashCode();
+      hash ^= serverStats_.GetHashCode();
+      hash ^= serverCores_.GetHashCode();
+      if (summary_ != null) hash ^= Summary.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (scenario_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Scenario);
+      }
+      if (latencies_ != null) {
+        output.WriteRawTag(18);
+        output.WriteMessage(Latencies);
+      }
+      clientStats_.WriteTo(output, _repeated_clientStats_codec);
+      serverStats_.WriteTo(output, _repeated_serverStats_codec);
+      serverCores_.WriteTo(output, _repeated_serverCores_codec);
+      if (summary_ != null) {
+        output.WriteRawTag(50);
+        output.WriteMessage(Summary);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (scenario_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Scenario);
+      }
+      if (latencies_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Latencies);
+      }
+      size += clientStats_.CalculateSize(_repeated_clientStats_codec);
+      size += serverStats_.CalculateSize(_repeated_serverStats_codec);
+      size += serverCores_.CalculateSize(_repeated_serverCores_codec);
+      if (summary_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Summary);
+      }
+      return size;
+    }
+
+    public void MergeFrom(ScenarioResult other) {
+      if (other == null) {
+        return;
+      }
+      if (other.scenario_ != null) {
+        if (scenario_ == null) {
+          scenario_ = new global::Grpc.Testing.Scenario();
+        }
+        Scenario.MergeFrom(other.Scenario);
+      }
+      if (other.latencies_ != null) {
+        if (latencies_ == null) {
+          latencies_ = new global::Grpc.Testing.HistogramData();
+        }
+        Latencies.MergeFrom(other.Latencies);
+      }
+      clientStats_.Add(other.clientStats_);
+      serverStats_.Add(other.serverStats_);
+      serverCores_.Add(other.serverCores_);
+      if (other.summary_ != null) {
+        if (summary_ == null) {
+          summary_ = new global::Grpc.Testing.ScenarioResultSummary();
+        }
+        Summary.MergeFrom(other.Summary);
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            if (scenario_ == null) {
+              scenario_ = new global::Grpc.Testing.Scenario();
+            }
+            input.ReadMessage(scenario_);
+            break;
+          }
+          case 18: {
+            if (latencies_ == null) {
+              latencies_ = new global::Grpc.Testing.HistogramData();
+            }
+            input.ReadMessage(latencies_);
+            break;
+          }
+          case 26: {
+            clientStats_.AddEntriesFrom(input, _repeated_clientStats_codec);
+            break;
+          }
+          case 34: {
+            serverStats_.AddEntriesFrom(input, _repeated_serverStats_codec);
+            break;
+          }
+          case 42:
+          case 40: {
+            serverCores_.AddEntriesFrom(input, _repeated_serverCores_codec);
+            break;
+          }
+          case 50: {
+            if (summary_ == null) {
+              summary_ = new global::Grpc.Testing.ScenarioResultSummary();
+            }
+            input.ReadMessage(summary_);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
   #endregion
 
 }
diff --git a/src/csharp/Grpc.IntegrationTesting/Messages.cs b/src/csharp/Grpc.IntegrationTesting/Messages.cs
index 7ca4786..fcff475 100644
--- a/src/csharp/Grpc.IntegrationTesting/Messages.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Messages.cs
@@ -47,11 +47,12 @@
             "c3Npb24YBiABKA4yHS5ncnBjLnRlc3RpbmcuQ29tcHJlc3Npb25UeXBlEjEK",
             "D3Jlc3BvbnNlX3N0YXR1cxgHIAEoCzIYLmdycGMudGVzdGluZy5FY2hvU3Rh",
             "dHVzIkUKG1N0cmVhbWluZ091dHB1dENhbGxSZXNwb25zZRImCgdwYXlsb2Fk",
-            "GAEgASgLMhUuZ3JwYy50ZXN0aW5nLlBheWxvYWQiMwoNUmVjb25uZWN0SW5m",
-            "bxIOCgZwYXNzZWQYASABKAgSEgoKYmFja29mZl9tcxgCIAMoBSo/CgtQYXls",
-            "b2FkVHlwZRIQCgxDT01QUkVTU0FCTEUQABISCg5VTkNPTVBSRVNTQUJMRRAB",
-            "EgoKBlJBTkRPTRACKjIKD0NvbXByZXNzaW9uVHlwZRIICgROT05FEAASCAoE",
-            "R1pJUBABEgsKB0RFRkxBVEUQAmIGcHJvdG8z"));
+            "GAEgASgLMhUuZ3JwYy50ZXN0aW5nLlBheWxvYWQiMwoPUmVjb25uZWN0UGFy",
+            "YW1zEiAKGG1heF9yZWNvbm5lY3RfYmFja29mZl9tcxgBIAEoBSIzCg1SZWNv",
+            "bm5lY3RJbmZvEg4KBnBhc3NlZBgBIAEoCBISCgpiYWNrb2ZmX21zGAIgAygF",
+            "Kj8KC1BheWxvYWRUeXBlEhAKDENPTVBSRVNTQUJMRRAAEhIKDlVOQ09NUFJF",
+            "U1NBQkxFEAESCgoGUkFORE9NEAIqMgoPQ29tcHJlc3Npb25UeXBlEggKBE5P",
+            "TkUQABIICgRHWklQEAESCwoHREVGTEFURRACYgZwcm90bzM="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedCodeInfo(new[] {typeof(global::Grpc.Testing.PayloadType), typeof(global::Grpc.Testing.CompressionType), }, new pbr::GeneratedCodeInfo[] {
@@ -64,6 +65,7 @@
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ResponseParameters), global::Grpc.Testing.ResponseParameters.Parser, new[]{ "Size", "IntervalUs" }, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.StreamingOutputCallRequest), global::Grpc.Testing.StreamingOutputCallRequest.Parser, new[]{ "ResponseType", "ResponseParameters", "Payload", "ResponseCompression", "ResponseStatus" }, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.StreamingOutputCallResponse), global::Grpc.Testing.StreamingOutputCallResponse.Parser, new[]{ "Payload" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ReconnectParams), global::Grpc.Testing.ReconnectParams.Parser, new[]{ "MaxReconnectBackoffMs" }, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ReconnectInfo), global::Grpc.Testing.ReconnectInfo.Parser, new[]{ "Passed", "BackoffMs" }, null, null, null)
           }));
     }
@@ -1574,6 +1576,113 @@
 
   /// <summary>
   ///  For reconnect interop test only.
+  ///  Client tells server what reconnection parameters it used.
+  /// </summary>
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ReconnectParams : pb::IMessage<ReconnectParams> {
+    private static readonly pb::MessageParser<ReconnectParams> _parser = new pb::MessageParser<ReconnectParams>(() => new ReconnectParams());
+    public static pb::MessageParser<ReconnectParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[9]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ReconnectParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ReconnectParams(ReconnectParams other) : this() {
+      maxReconnectBackoffMs_ = other.maxReconnectBackoffMs_;
+    }
+
+    public ReconnectParams Clone() {
+      return new ReconnectParams(this);
+    }
+
+    /// <summary>Field number for the "max_reconnect_backoff_ms" field.</summary>
+    public const int MaxReconnectBackoffMsFieldNumber = 1;
+    private int maxReconnectBackoffMs_;
+    public int MaxReconnectBackoffMs {
+      get { return maxReconnectBackoffMs_; }
+      set {
+        maxReconnectBackoffMs_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ReconnectParams);
+    }
+
+    public bool Equals(ReconnectParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (MaxReconnectBackoffMs != other.MaxReconnectBackoffMs) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (MaxReconnectBackoffMs != 0) hash ^= MaxReconnectBackoffMs.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (MaxReconnectBackoffMs != 0) {
+        output.WriteRawTag(8);
+        output.WriteInt32(MaxReconnectBackoffMs);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (MaxReconnectBackoffMs != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(MaxReconnectBackoffMs);
+      }
+      return size;
+    }
+
+    public void MergeFrom(ReconnectParams other) {
+      if (other == null) {
+        return;
+      }
+      if (other.MaxReconnectBackoffMs != 0) {
+        MaxReconnectBackoffMs = other.MaxReconnectBackoffMs;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            MaxReconnectBackoffMs = input.ReadInt32();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  /// <summary>
+  ///  For reconnect interop test only.
   ///  Server tells client whether its reconnects are following the spec and the
   ///  reconnect backoffs it saw.
   /// </summary>
@@ -1583,7 +1692,7 @@
     public static pb::MessageParser<ReconnectInfo> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[9]; }
+      get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[10]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
diff --git a/src/csharp/Grpc.IntegrationTesting/Test.cs b/src/csharp/Grpc.IntegrationTesting/Test.cs
index 91e0a1e..363f644 100644
--- a/src/csharp/Grpc.IntegrationTesting/Test.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Test.cs
@@ -40,10 +40,10 @@
             "bWluZ091dHB1dENhbGxSZXF1ZXN0GikuZ3JwYy50ZXN0aW5nLlN0cmVhbWlu",
             "Z091dHB1dENhbGxSZXNwb25zZSgBMAEyVQoUVW5pbXBsZW1lbnRlZFNlcnZp",
             "Y2USPQoRVW5pbXBsZW1lbnRlZENhbGwSEy5ncnBjLnRlc3RpbmcuRW1wdHka",
-            "Ey5ncnBjLnRlc3RpbmcuRW1wdHkyfwoQUmVjb25uZWN0U2VydmljZRIxCgVT",
-            "dGFydBITLmdycGMudGVzdGluZy5FbXB0eRoTLmdycGMudGVzdGluZy5FbXB0",
-            "eRI4CgRTdG9wEhMuZ3JwYy50ZXN0aW5nLkVtcHR5GhsuZ3JwYy50ZXN0aW5n",
-            "LlJlY29ubmVjdEluZm9iBnByb3RvMw=="));
+            "Ey5ncnBjLnRlc3RpbmcuRW1wdHkyiQEKEFJlY29ubmVjdFNlcnZpY2USOwoF",
+            "U3RhcnQSHS5ncnBjLnRlc3RpbmcuUmVjb25uZWN0UGFyYW1zGhMuZ3JwYy50",
+            "ZXN0aW5nLkVtcHR5EjgKBFN0b3ASEy5ncnBjLnRlc3RpbmcuRW1wdHkaGy5n",
+            "cnBjLnRlc3RpbmcuUmVjb25uZWN0SW5mb2IGcHJvdG8z"));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Grpc.Testing.EmptyReflection.Descriptor, global::Grpc.Testing.MessagesReflection.Descriptor, },
           new pbr::GeneratedCodeInfo(null, null));
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index b84ec2d..31746cb 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -367,14 +367,15 @@
   {
     static readonly string __ServiceName = "grpc.testing.ReconnectService";
 
+    static readonly Marshaller<global::Grpc.Testing.ReconnectParams> __Marshaller_ReconnectParams = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ReconnectParams.Parser.ParseFrom);
     static readonly Marshaller<global::Grpc.Testing.Empty> __Marshaller_Empty = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
     static readonly Marshaller<global::Grpc.Testing.ReconnectInfo> __Marshaller_ReconnectInfo = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ReconnectInfo.Parser.ParseFrom);
 
-    static readonly Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty> __Method_Start = new Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty>(
+    static readonly Method<global::Grpc.Testing.ReconnectParams, global::Grpc.Testing.Empty> __Method_Start = new Method<global::Grpc.Testing.ReconnectParams, global::Grpc.Testing.Empty>(
         MethodType.Unary,
         __ServiceName,
         "Start",
-        __Marshaller_Empty,
+        __Marshaller_ReconnectParams,
         __Marshaller_Empty);
 
     static readonly Method<global::Grpc.Testing.Empty, global::Grpc.Testing.ReconnectInfo> __Method_Stop = new Method<global::Grpc.Testing.Empty, global::Grpc.Testing.ReconnectInfo>(
@@ -394,10 +395,10 @@
     [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
     public interface IReconnectServiceClient
     {
-      global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, CallOptions options);
-      AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, CallOptions options);
+      global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, CallOptions options);
+      AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, CallOptions options);
       global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
       global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, CallOptions options);
       AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
@@ -408,14 +409,14 @@
     [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
     public interface IReconnectService
     {
-      Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.Empty request, ServerCallContext context);
+      Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.ReconnectParams request, ServerCallContext context);
       Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context);
     }
 
     // server-side abstract class
     public abstract class ReconnectServiceBase
     {
-      public virtual Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.Empty request, ServerCallContext context)
+      public virtual Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.ReconnectParams request, ServerCallContext context)
       {
         throw new RpcException(new Status(StatusCode.Unimplemented, ""));
       }
@@ -445,19 +446,19 @@
       {
       }
 
-      public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return Start(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_Start, null, options, request);
       }
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return StartAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
-      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.Empty request, CallOptions options)
+      public virtual AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, CallOptions options)
       {
         return CallInvoker.AsyncUnaryCall(__Method_Start, null, options, request);
       }
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 8d769e5..aeef8a7 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -911,9 +911,12 @@
       key_cert_pairs[i].private_key = key_cert_pair_private_key_array[i];
     }
   }
-  creds = grpc_ssl_server_credentials_create(pem_root_certs, key_cert_pairs,
-                                             num_key_cert_pairs,
-                                             force_client_auth, NULL);
+  creds = grpc_ssl_server_credentials_create_ex(
+      pem_root_certs, key_cert_pairs, num_key_cert_pairs,
+      force_client_auth
+          ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+          : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
+      NULL);
   gpr_free(key_cert_pairs);
   return creds;
 }
diff --git a/src/node/ext/server_credentials.cc b/src/node/ext/server_credentials.cc
index 5285d53..cff821a 100644
--- a/src/node/ext/server_credentials.cc
+++ b/src/node/ext/server_credentials.cc
@@ -145,9 +145,13 @@
     return Nan::ThrowTypeError(
         "createSsl's second argument must be a list of objects");
   }
-  int force_client_auth = 0;
+
+  grpc_ssl_client_certificate_request_type client_certificate_request;
   if (info[2]->IsBoolean()) {
-    force_client_auth = (int)Nan::To<bool>(info[2]).FromJust();
+    client_certificate_request =
+        Nan::To<bool>(info[2]).FromJust()
+            ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+            : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE;
   } else if (!(info[2]->IsUndefined() || info[2]->IsNull())) {
     return Nan::ThrowTypeError(
         "createSsl's third argument must be a boolean if provided");
@@ -180,8 +184,9 @@
     key_cert_pairs[i].private_key = ::node::Buffer::Data(maybe_key);
     key_cert_pairs[i].cert_chain = ::node::Buffer::Data(maybe_cert);
   }
-  grpc_server_credentials *creds = grpc_ssl_server_credentials_create(
-      root_certs, key_cert_pairs, key_cert_pair_count, force_client_auth, NULL);
+  grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex(
+      root_certs, key_cert_pairs, key_cert_pair_count,
+      client_certificate_request, NULL);
   delete key_cert_pairs;
   if (creds == NULL) {
     info.GetReturnValue().SetNull();
diff --git a/src/node/performance/worker.js b/src/node/performance/worker.js
index 98577bd..7ef9b84 100644
--- a/src/node/performance/worker.js
+++ b/src/node/performance/worker.js
@@ -33,6 +33,7 @@
 
 'use strict';
 
+var console = require('console');
 var worker_service_impl = require('./worker_service_impl');
 
 var grpc = require('../../../');
@@ -48,6 +49,7 @@
   var address = '0.0.0.0:' + port;
   server.bind(address, server_creds);
   server.start();
+  console.log('running QPS worker on %s', address);
   return server;
 }
 
diff --git a/src/node/performance/worker_service_impl.js b/src/node/performance/worker_service_impl.js
index 17458e4..4b5cb8f 100644
--- a/src/node/performance/worker_service_impl.js
+++ b/src/node/performance/worker_service_impl.js
@@ -34,6 +34,7 @@
 'use strict';
 
 var os = require('os');
+var console = require('console');
 var BenchmarkClient = require('./benchmark_client');
 var BenchmarkServer = require('./benchmark_server');
 
@@ -49,6 +50,7 @@
     switch (request.argtype) {
       case 'setup':
       var setup = request.setup;
+      console.log('ClientConfig %j', setup);
       client = new BenchmarkClient(setup.server_targets,
                                    setup.client_channels,
                                    setup.histogram_params,
@@ -118,6 +120,7 @@
     var stats;
     switch (request.argtype) {
       case 'setup':
+      console.log('ServerConfig %j', request.setup);
       server = new BenchmarkServer('[::]', request.setup.port,
                                    request.setup.security_params);
       server.start();
diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c
index 7918824..f3951b3 100644
--- a/src/php/ext/grpc/server_credentials.c
+++ b/src/php/ext/grpc/server_credentials.c
@@ -115,10 +115,11 @@
                          "createSsl expects 3 strings", 1 TSRMLS_CC);
     return;
   }
-  /* TODO: add a force_client_auth field in ServerCredentials and pass it as
-   * the last parameter. */
-  grpc_server_credentials *creds = grpc_ssl_server_credentials_create(
-      pem_root_certs, &pem_key_cert_pair, 1, 0, NULL);
+  /* TODO: add a client_certificate_request field in ServerCredentials and pass
+   * it as the last parameter. */
+  grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex(
+      pem_root_certs, &pem_key_cert_pair, 1,
+      GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, NULL);
   zval *creds_object = grpc_php_wrap_server_credentials(creds);
   RETURN_DESTROY_ZVAL(creds_object);
 }
diff --git a/src/php/tests/bootstrap.php b/src/php/tests/bootstrap.php
index b61f2c4..8b3d434 100644
--- a/src/php/tests/bootstrap.php
+++ b/src/php/tests/bootstrap.php
@@ -17,5 +17,5 @@
  */
 
 error_reporting(E_ALL | E_STRICT);
-require dirname(__DIR__) . '/vendor/autoload.php';
+require dirname(__DIR__).'/vendor/autoload.php';
 date_default_timezone_set('UTC');
diff --git a/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php b/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
index 6bb1955..6b70b8a 100644
--- a/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
+++ b/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
@@ -46,7 +46,8 @@
                                 $a_copy['foo'] = ['bar'];
 
                                 return $a_copy;
-                              }]);
+                              },
+         ]);
     }
 
     public function tearDown()
diff --git a/src/php/tests/generated_code/math_client.php b/src/php/tests/generated_code/math_client.php
index b8652ce..6ee92bc 100644
--- a/src/php/tests/generated_code/math_client.php
+++ b/src/php/tests/generated_code/math_client.php
@@ -38,13 +38,13 @@
 
 function p($line)
 {
-    print("$line<br/>\n");
+    echo "$line<br/>\n";
 }
 
 $host = 'localhost:50051';
 p("Connecting to host: $host");
 $client = new math\MathClient($host, [
-    'credentials' => Grpc\ChannelCredentials::createInsecure()
+    'credentials' => Grpc\ChannelCredentials::createInsecure(),
 ]);
 p('Client class: '.get_class($client));
 p('');
diff --git a/src/php/tests/unit_tests/CallCredentials3Test.php b/src/php/tests/unit_tests/CallCredentials3Test.php
index 6d98815..8f5e109 100644
--- a/src/php/tests/unit_tests/CallCredentials3Test.php
+++ b/src/php/tests/unit_tests/CallCredentials3Test.php
@@ -132,5 +132,4 @@
         unset($call);
         unset($server_call);
     }
-
 }
diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php
index 1170a44..fa026f0 100755
--- a/src/php/tests/unit_tests/CallTest.php
+++ b/src/php/tests/unit_tests/CallTest.php
@@ -94,7 +94,7 @@
 
     public function testCancel()
     {
-      $this->assertNull($this->call->cancel());
+        $this->assertNull($this->call->cancel());
     }
 
     /**
@@ -118,5 +118,4 @@
         ];
         $result = $this->call->startBatch($batch);
     }
-
 }
diff --git a/src/php/tests/unit_tests/ChannelCredentialsTest.php b/src/php/tests/unit_tests/ChannelCredentialsTest.php
index 1a42d69..56c1d8f 100644
--- a/src/php/tests/unit_tests/ChannelCredentialsTest.php
+++ b/src/php/tests/unit_tests/ChannelCredentialsTest.php
@@ -70,4 +70,4 @@
         $channel_credentials = Grpc\ChannelCredentials::createInsecure();
         $this->assertNull($channel_credentials);
     }
-}
\ No newline at end of file
+}
diff --git a/src/php/tests/unit_tests/ChannelTest.php b/src/php/tests/unit_tests/ChannelTest.php
index b6eac31..a1f9053 100644
--- a/src/php/tests/unit_tests/ChannelTest.php
+++ b/src/php/tests/unit_tests/ChannelTest.php
@@ -78,5 +78,4 @@
             ]
         );
     }
-
-}
\ No newline at end of file
+}
diff --git a/src/php/tests/unit_tests/EndToEndTest.php b/src/php/tests/unit_tests/EndToEndTest.php
index 3fa92c9..2b09f9d 100755
--- a/src/php/tests/unit_tests/EndToEndTest.php
+++ b/src/php/tests/unit_tests/EndToEndTest.php
@@ -261,7 +261,8 @@
             Grpc\OP_SEND_INITIAL_METADATA => [],
             Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
             Grpc\OP_SEND_MESSAGE => ['message' => 'abc',
-                                     'flags' => 'invalid'],
+                                     'flags' => 'invalid',
+                                     ],
         ]);
     }
 
@@ -574,7 +575,7 @@
     public function testGetConnectivityStateInvalidParam()
     {
         $this->assertTrue($this->channel->getConnectivityState(
-            new Grpc\Timeval));
+            new Grpc\Timeval()));
     }
 
     /**
@@ -591,12 +592,11 @@
      */
     public function testChannelConstructorInvalidParam()
     {
-        $this->channel = new Grpc\Channel('localhost:'.$this->port, NULL);
+        $this->channel = new Grpc\Channel('localhost:'.$this->port, null);
     }
 
     public function testClose()
     {
         $this->assertNull($this->channel->close());
     }
-
 }
diff --git a/src/php/tests/unit_tests/ServerTest.php b/src/php/tests/unit_tests/ServerTest.php
index d18f9ab..76aaa06 100644
--- a/src/php/tests/unit_tests/ServerTest.php
+++ b/src/php/tests/unit_tests/ServerTest.php
@@ -67,5 +67,4 @@
         $this->server = new Grpc\Server([]);
         $this->port = $this->server->addSecureHttp2Port(['0.0.0.0:0']);
     }
-
-}
\ No newline at end of file
+}
diff --git a/src/php/tests/unit_tests/TimevalTest.php b/src/php/tests/unit_tests/TimevalTest.php
index 43abba1..a3dbce0 100755
--- a/src/php/tests/unit_tests/TimevalTest.php
+++ b/src/php/tests/unit_tests/TimevalTest.php
@@ -94,13 +94,13 @@
 
     public function testSimilar()
     {
-      $a = Grpc\Timeval::now();
-      $delta = new Grpc\Timeval(1000);
-      $b = $a->add($delta);
-      $thresh = new Grpc\Timeval(1100);
-      $this->assertTrue(Grpc\Timeval::similar($a, $b, $thresh));
-      $thresh = new Grpc\Timeval(900);
-      $this->assertFalse(Grpc\Timeval::similar($a, $b, $thresh));
+        $a = Grpc\Timeval::now();
+        $delta = new Grpc\Timeval(1000);
+        $b = $a->add($delta);
+        $thresh = new Grpc\Timeval(1100);
+        $this->assertTrue(Grpc\Timeval::similar($a, $b, $thresh));
+        $thresh = new Grpc\Timeval(900);
+        $this->assertFalse(Grpc\Timeval::similar($a, $b, $thresh));
     }
 
     public function testSleepUntil()
@@ -155,5 +155,4 @@
     {
         $a = Grpc\Timeval::similar(1000, 1100, 1200);
     }
-
 }
diff --git a/src/proto/grpc/binary_log/v1alpha/log.proto b/src/proto/grpc/binary_log/v1alpha/log.proto
index 6cc473b..83166cd 100644
--- a/src/proto/grpc/binary_log/v1alpha/log.proto
+++ b/src/proto/grpc/binary_log/v1alpha/log.proto
@@ -105,4 +105,4 @@
   // The contents of the message. May be a prefix instead of the complete
   // message.
   bytes data = 5;
-}
\ No newline at end of file
+}
diff --git a/src/proto/grpc/testing/control.proto b/src/proto/grpc/testing/control.proto
index 458b19c..28769ef 100644
--- a/src/proto/grpc/testing/control.proto
+++ b/src/proto/grpc/testing/control.proto
@@ -57,18 +57,6 @@
   double offered_load = 1;
 }
 
-message UniformParams {
-  double interarrival_lo = 1;
-  double interarrival_hi = 2;
-}
-
-message DeterministicParams { double offered_load = 1; }
-
-message ParetoParams {
-  double interarrival_base = 1;
-  double alpha = 2;
-}
-
 // Once an RPC finishes, immediately start a new one.
 // No configuration parameters needed.
 message ClosedLoopParams {}
@@ -77,9 +65,6 @@
   oneof load {
     ClosedLoopParams closed_loop = 1;
     PoissonParams poisson = 2;
-    UniformParams uniform = 3;
-    DeterministicParams determ = 4;
-    ParetoParams pareto = 5;
   };
 }
 
@@ -194,3 +179,44 @@
 message Scenarios {
   repeated Scenario scenarios = 1;
 }
+
+// Basic summary that can be computed from ClientStats and ServerStats
+// once the scenario has finished.
+message ScenarioResultSummary
+{
+  // Total number of operations per second over all clients.
+  double qps = 1;
+  // QPS per one server core.
+  double qps_per_server_core = 2;
+  // server load based on system_time (0.85 => 85%)
+  double server_system_time = 3;
+  // server load based on user_time (0.85 => 85%)
+  double server_user_time = 4;
+  // client load based on system_time (0.85 => 85%)
+  double client_system_time = 5;
+  // client load based on user_time (0.85 => 85%)
+  double client_user_time = 6;
+
+  // X% latency percentiles (in nanoseconds)
+  double latency_50 = 7;
+  double latency_90 = 8;
+  double latency_95 = 9;
+  double latency_99 = 10;
+  double latency_999 = 11;
+}
+
+// Results of a single benchmark scenario.
+message ScenarioResult {
+  // Inputs used to run the scenario.
+  Scenario scenario = 1;
+  // Histograms from all clients merged into one histogram.
+  HistogramData latencies = 2;
+  // Client stats for each client
+  repeated ClientStats client_stats = 3;
+  // Server stats for each server
+  repeated ServerStats server_stats = 4;
+  // Number of cores available to each server
+  repeated int32 server_cores = 5;
+  // An after-the-fact computed summary
+  ScenarioResultSummary summary = 6;
+}
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
index 842635f..94d13b5 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
@@ -302,6 +302,8 @@
         (<SslPemKeyCertPair>pem_key_cert_pairs[i]).c_pair)
   credentials.c_credentials = grpc_ssl_server_credentials_create(
       c_pem_root_certs, credentials.c_ssl_pem_key_cert_pairs,
-      credentials.c_ssl_pem_key_cert_pairs_count, force_client_auth, NULL)
+      credentials.c_ssl_pem_key_cert_pairs_count,
+      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY if force_client_auth else GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
+      NULL)
   return credentials
 
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index 7696f8c..3d158a7 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -105,6 +105,13 @@
     GRPC_SSL_ROOTS_OVERRIDE_FAILED_PERMANENTLY
     GRPC_SSL_ROOTS_OVERRIDE_FAILED
 
+  ctypedef enum grpc_ssl_client_certificate_request_type:
+    GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
+    GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY
+    GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY
+    GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY
+    GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+
   struct grpc_byte_buffer_reader:
     # We don't care about the internals
     pass
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.c b/src/python/grpcio/grpc/_cython/imports.generated.c
index 8bd6ae6..9ab0696 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.c
+++ b/src/python/grpcio/grpc/_cython/imports.generated.c
@@ -152,6 +152,7 @@
 grpc_secure_channel_create_type grpc_secure_channel_create_import;
 grpc_server_credentials_release_type grpc_server_credentials_release_import;
 grpc_ssl_server_credentials_create_type grpc_ssl_server_credentials_create_import;
+grpc_ssl_server_credentials_create_ex_type grpc_ssl_server_credentials_create_ex_import;
 grpc_server_add_secure_http2_port_type grpc_server_add_secure_http2_port_import;
 grpc_call_set_credentials_type grpc_call_set_credentials_import;
 grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import;
@@ -174,6 +175,8 @@
 grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
 gpr_log_type gpr_log_import;
 gpr_log_message_type gpr_log_message_import;
+gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
+gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
 gpr_set_log_function_type gpr_set_log_function_import;
 gpr_slice_ref_type gpr_slice_ref_import;
 gpr_slice_unref_type gpr_slice_unref_import;
@@ -418,6 +421,7 @@
   grpc_secure_channel_create_import = (grpc_secure_channel_create_type) GetProcAddress(library, "grpc_secure_channel_create");
   grpc_server_credentials_release_import = (grpc_server_credentials_release_type) GetProcAddress(library, "grpc_server_credentials_release");
   grpc_ssl_server_credentials_create_import = (grpc_ssl_server_credentials_create_type) GetProcAddress(library, "grpc_ssl_server_credentials_create");
+  grpc_ssl_server_credentials_create_ex_import = (grpc_ssl_server_credentials_create_ex_type) GetProcAddress(library, "grpc_ssl_server_credentials_create_ex");
   grpc_server_add_secure_http2_port_import = (grpc_server_add_secure_http2_port_type) GetProcAddress(library, "grpc_server_add_secure_http2_port");
   grpc_call_set_credentials_import = (grpc_call_set_credentials_type) GetProcAddress(library, "grpc_call_set_credentials");
   grpc_server_credentials_set_auth_metadata_processor_import = (grpc_server_credentials_set_auth_metadata_processor_type) GetProcAddress(library, "grpc_server_credentials_set_auth_metadata_processor");
@@ -440,6 +444,8 @@
   grpc_raw_byte_buffer_from_reader_import = (grpc_raw_byte_buffer_from_reader_type) GetProcAddress(library, "grpc_raw_byte_buffer_from_reader");
   gpr_log_import = (gpr_log_type) GetProcAddress(library, "gpr_log");
   gpr_log_message_import = (gpr_log_message_type) GetProcAddress(library, "gpr_log_message");
+  gpr_set_log_verbosity_import = (gpr_set_log_verbosity_type) GetProcAddress(library, "gpr_set_log_verbosity");
+  gpr_log_verbosity_init_import = (gpr_log_verbosity_init_type) GetProcAddress(library, "gpr_log_verbosity_init");
   gpr_set_log_function_import = (gpr_set_log_function_type) GetProcAddress(library, "gpr_set_log_function");
   gpr_slice_ref_import = (gpr_slice_ref_type) GetProcAddress(library, "gpr_slice_ref");
   gpr_slice_unref_import = (gpr_slice_unref_type) GetProcAddress(library, "gpr_slice_unref");
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/python/grpcio/grpc/_cython/imports.generated.h
index 272e85b..e50051d 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.h
+++ b/src/python/grpcio/grpc/_cython/imports.generated.h
@@ -406,6 +406,9 @@
 typedef grpc_server_credentials *(*grpc_ssl_server_credentials_create_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, size_t num_key_cert_pairs, int force_client_auth, void *reserved);
 extern grpc_ssl_server_credentials_create_type grpc_ssl_server_credentials_create_import;
 #define grpc_ssl_server_credentials_create grpc_ssl_server_credentials_create_import
+typedef grpc_server_credentials *(*grpc_ssl_server_credentials_create_ex_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, size_t num_key_cert_pairs, grpc_ssl_client_certificate_request_type client_certificate_request, void *reserved);
+extern grpc_ssl_server_credentials_create_ex_type grpc_ssl_server_credentials_create_ex_import;
+#define grpc_ssl_server_credentials_create_ex grpc_ssl_server_credentials_create_ex_import
 typedef int(*grpc_server_add_secure_http2_port_type)(grpc_server *server, const char *addr, grpc_server_credentials *creds);
 extern grpc_server_add_secure_http2_port_type grpc_server_add_secure_http2_port_import;
 #define grpc_server_add_secure_http2_port grpc_server_add_secure_http2_port_import
@@ -472,6 +475,12 @@
 typedef void(*gpr_log_message_type)(const char *file, int line, gpr_log_severity severity, const char *message);
 extern gpr_log_message_type gpr_log_message_import;
 #define gpr_log_message gpr_log_message_import
+typedef void(*gpr_set_log_verbosity_type)(gpr_log_severity min_severity_to_print);
+extern gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
+#define gpr_set_log_verbosity gpr_set_log_verbosity_import
+typedef void(*gpr_log_verbosity_init_type)();
+extern gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
+#define gpr_log_verbosity_init gpr_log_verbosity_init_import
 typedef void(*gpr_set_log_function_type)(gpr_log_func func);
 extern gpr_set_log_function_type gpr_set_log_function_import;
 #define gpr_set_log_function gpr_set_log_function_import
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 1f7f2a1..94e1807 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -210,6 +210,7 @@
   'src/core/ext/client_config/lb_policy.c',
   'src/core/ext/client_config/lb_policy_factory.c',
   'src/core/ext/client_config/lb_policy_registry.c',
+  'src/core/ext/client_config/parse_address.c',
   'src/core/ext/client_config/resolver.c',
   'src/core/ext/client_config/resolver_factory.c',
   'src/core/ext/client_config/resolver_registry.c',
@@ -310,6 +311,7 @@
   'third_party/boringssl/crypto/bn/shift.c',
   'third_party/boringssl/crypto/bn/sqrt.c',
   'third_party/boringssl/crypto/buf/buf.c',
+  'third_party/boringssl/crypto/bytestring/asn1_compat.c',
   'third_party/boringssl/crypto/bytestring/ber.c',
   'third_party/boringssl/crypto/bytestring/cbb.c',
   'third_party/boringssl/crypto/bytestring/cbs.c',
@@ -333,6 +335,7 @@
   'third_party/boringssl/crypto/cpu-intel.c',
   'third_party/boringssl/crypto/crypto.c',
   'third_party/boringssl/crypto/curve25519/curve25519.c',
+  'third_party/boringssl/crypto/curve25519/x25519-x86_64.c',
   'third_party/boringssl/crypto/des/des.c',
   'third_party/boringssl/crypto/dh/check.c',
   'third_party/boringssl/crypto/dh/dh.c',
@@ -524,6 +527,7 @@
   'third_party/boringssl/ssl/ssl_buffer.c',
   'third_party/boringssl/ssl/ssl_cert.c',
   'third_party/boringssl/ssl/ssl_cipher.c',
+  'third_party/boringssl/ssl/ssl_ecdh.c',
   'third_party/boringssl/ssl/ssl_file.c',
   'third_party/boringssl/ssl/ssl_lib.c',
   'third_party/boringssl/ssl/ssl_rsa.c',
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index 56db4ec..e2068d7 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -152,6 +152,7 @@
 grpc_secure_channel_create_type grpc_secure_channel_create_import;
 grpc_server_credentials_release_type grpc_server_credentials_release_import;
 grpc_ssl_server_credentials_create_type grpc_ssl_server_credentials_create_import;
+grpc_ssl_server_credentials_create_ex_type grpc_ssl_server_credentials_create_ex_import;
 grpc_server_add_secure_http2_port_type grpc_server_add_secure_http2_port_import;
 grpc_call_set_credentials_type grpc_call_set_credentials_import;
 grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import;
@@ -174,6 +175,8 @@
 grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
 gpr_log_type gpr_log_import;
 gpr_log_message_type gpr_log_message_import;
+gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
+gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
 gpr_set_log_function_type gpr_set_log_function_import;
 gpr_slice_ref_type gpr_slice_ref_import;
 gpr_slice_unref_type gpr_slice_unref_import;
@@ -414,6 +417,7 @@
   grpc_secure_channel_create_import = (grpc_secure_channel_create_type) GetProcAddress(library, "grpc_secure_channel_create");
   grpc_server_credentials_release_import = (grpc_server_credentials_release_type) GetProcAddress(library, "grpc_server_credentials_release");
   grpc_ssl_server_credentials_create_import = (grpc_ssl_server_credentials_create_type) GetProcAddress(library, "grpc_ssl_server_credentials_create");
+  grpc_ssl_server_credentials_create_ex_import = (grpc_ssl_server_credentials_create_ex_type) GetProcAddress(library, "grpc_ssl_server_credentials_create_ex");
   grpc_server_add_secure_http2_port_import = (grpc_server_add_secure_http2_port_type) GetProcAddress(library, "grpc_server_add_secure_http2_port");
   grpc_call_set_credentials_import = (grpc_call_set_credentials_type) GetProcAddress(library, "grpc_call_set_credentials");
   grpc_server_credentials_set_auth_metadata_processor_import = (grpc_server_credentials_set_auth_metadata_processor_type) GetProcAddress(library, "grpc_server_credentials_set_auth_metadata_processor");
@@ -436,6 +440,8 @@
   grpc_raw_byte_buffer_from_reader_import = (grpc_raw_byte_buffer_from_reader_type) GetProcAddress(library, "grpc_raw_byte_buffer_from_reader");
   gpr_log_import = (gpr_log_type) GetProcAddress(library, "gpr_log");
   gpr_log_message_import = (gpr_log_message_type) GetProcAddress(library, "gpr_log_message");
+  gpr_set_log_verbosity_import = (gpr_set_log_verbosity_type) GetProcAddress(library, "gpr_set_log_verbosity");
+  gpr_log_verbosity_init_import = (gpr_log_verbosity_init_type) GetProcAddress(library, "gpr_log_verbosity_init");
   gpr_set_log_function_import = (gpr_set_log_function_type) GetProcAddress(library, "gpr_set_log_function");
   gpr_slice_ref_import = (gpr_slice_ref_type) GetProcAddress(library, "gpr_slice_ref");
   gpr_slice_unref_import = (gpr_slice_unref_type) GetProcAddress(library, "gpr_slice_unref");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index c526f43..c8d2133 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -406,6 +406,9 @@
 typedef grpc_server_credentials *(*grpc_ssl_server_credentials_create_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, size_t num_key_cert_pairs, int force_client_auth, void *reserved);
 extern grpc_ssl_server_credentials_create_type grpc_ssl_server_credentials_create_import;
 #define grpc_ssl_server_credentials_create grpc_ssl_server_credentials_create_import
+typedef grpc_server_credentials *(*grpc_ssl_server_credentials_create_ex_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, size_t num_key_cert_pairs, grpc_ssl_client_certificate_request_type client_certificate_request, void *reserved);
+extern grpc_ssl_server_credentials_create_ex_type grpc_ssl_server_credentials_create_ex_import;
+#define grpc_ssl_server_credentials_create_ex grpc_ssl_server_credentials_create_ex_import
 typedef int(*grpc_server_add_secure_http2_port_type)(grpc_server *server, const char *addr, grpc_server_credentials *creds);
 extern grpc_server_add_secure_http2_port_type grpc_server_add_secure_http2_port_import;
 #define grpc_server_add_secure_http2_port grpc_server_add_secure_http2_port_import
@@ -472,6 +475,12 @@
 typedef void(*gpr_log_message_type)(const char *file, int line, gpr_log_severity severity, const char *message);
 extern gpr_log_message_type gpr_log_message_import;
 #define gpr_log_message gpr_log_message_import
+typedef void(*gpr_set_log_verbosity_type)(gpr_log_severity min_severity_to_print);
+extern gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
+#define gpr_set_log_verbosity gpr_set_log_verbosity_import
+typedef void(*gpr_log_verbosity_init_type)();
+extern gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
+#define gpr_log_verbosity_init gpr_log_verbosity_init_import
 typedef void(*gpr_set_log_function_type)(gpr_log_func func);
 extern gpr_set_log_function_type gpr_set_log_function_import;
 #define gpr_set_log_function gpr_set_log_function_import
diff --git a/src/ruby/ext/grpc/rb_server_credentials.c b/src/ruby/ext/grpc/rb_server_credentials.c
index 33b8372..b2d7280 100644
--- a/src/ruby/ext/grpc/rb_server_credentials.c
+++ b/src/ruby/ext/grpc/rb_server_credentials.c
@@ -90,9 +90,12 @@
 
 static const rb_data_type_t grpc_rb_server_credentials_data_type = {
     "grpc_server_credentials",
-    {grpc_rb_server_credentials_mark, grpc_rb_server_credentials_free,
-     GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}},
-    NULL, NULL,
+    {grpc_rb_server_credentials_mark,
+     grpc_rb_server_credentials_free,
+     GRPC_RB_MEMSIZE_UNAVAILABLE,
+     {NULL, NULL}},
+    NULL,
+    NULL,
 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
     RUBY_TYPED_FREE_IMMEDIATELY
 #endif
@@ -219,7 +222,9 @@
     }
   }
 
-  auth_client = TYPE(force_client_auth) == T_TRUE;
+  auth_client = TYPE(force_client_auth) == T_TRUE
+                    ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+                    : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE;
   key_cert_pairs = ALLOC_N(grpc_ssl_pem_key_cert_pair, num_key_certs);
   for (i = 0; i < num_key_certs; i++) {
     key_cert = rb_ary_entry(pem_key_certs, i);
@@ -233,13 +238,12 @@
                        &grpc_rb_server_credentials_data_type, wrapper);
 
   if (pem_root_certs == Qnil) {
-    creds = grpc_ssl_server_credentials_create(NULL, key_cert_pairs,
-                                               num_key_certs,
-                                               auth_client, NULL);
+    creds = grpc_ssl_server_credentials_create_ex(
+        NULL, key_cert_pairs, num_key_certs, auth_client, NULL);
   } else {
-    creds = grpc_ssl_server_credentials_create(RSTRING_PTR(pem_root_certs),
-                                               key_cert_pairs, num_key_certs,
-                                               auth_client, NULL);
+    creds = grpc_ssl_server_credentials_create_ex(RSTRING_PTR(pem_root_certs),
+                                                  key_cert_pairs, num_key_certs,
+                                                  auth_client, NULL);
   }
   xfree(key_cert_pairs);
   if (creds == NULL) {
diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb
index 98e83a8..a6bb92d 100644
--- a/src/ruby/lib/grpc/generic/client_stub.rb
+++ b/src/ruby/lib/grpc/generic/client_stub.rb
@@ -85,7 +85,8 @@
     # when present, this is the default timeout used for calls
     #
     # @param host [String] the host the stub connects to
-    # @param q [Core::CompletionQueue] used to wait for events
+    # @param q [Core::CompletionQueue] used to wait for events - now deprecated
+    #        since each new active call gets its own separately
     # @param creds [Core::ChannelCredentials|Symbol] the channel credentials, or
     #     :this_channel_is_insecure
     # @param channel_override [Core::Channel] a pre-created channel
@@ -97,7 +98,6 @@
                    propagate_mask: nil,
                    **kw)
       fail(TypeError, '!CompletionQueue') unless q.is_a?(Core::CompletionQueue)
-      @queue = q
       @ch = ClientStub.setup_channel(channel_override, host, creds, **kw)
       alt_host = kw[Core::Channel::SSL_TARGET]
       @host = alt_host.nil? ? host : alt_host
@@ -458,14 +458,17 @@
       if deadline.nil?
         deadline = from_relative_time(timeout.nil? ? @timeout : timeout)
       end
-      call = @ch.create_call(@queue,
+      # Provide each new client call with its own completion queue
+      call_queue = Core::CompletionQueue.new
+      call = @ch.create_call(call_queue,
                              parent, # parent call
                              @propagate_mask, # propagation options
                              method,
                              nil, # host use nil,
                              deadline)
       call.set_credentials! credentials unless credentials.nil?
-      ActiveCall.new(call, @queue, marshal, unmarshal, deadline, started: false)
+      ActiveCall.new(call, call_queue, marshal, unmarshal, deadline,
+                     started: false)
     end
   end
 end
diff --git a/src/ruby/qps/server.rb b/src/ruby/qps/server.rb
index 26f46a3..f05fbbd 100644
--- a/src/ruby/qps/server.rb
+++ b/src/ruby/qps/server.rb
@@ -88,4 +88,7 @@
   def get_port
     @port
   end
+  def stop
+    @server.stop
+  end
 end
diff --git a/src/ruby/qps/src/proto/grpc/testing/control.rb b/src/ruby/qps/src/proto/grpc/testing/control.rb
index d007123..b81e226 100644
--- a/src/ruby/qps/src/proto/grpc/testing/control.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/control.rb
@@ -9,26 +9,12 @@
   add_message "grpc.testing.PoissonParams" do
     optional :offered_load, :double, 1
   end
-  add_message "grpc.testing.UniformParams" do
-    optional :interarrival_lo, :double, 1
-    optional :interarrival_hi, :double, 2
-  end
-  add_message "grpc.testing.DeterministicParams" do
-    optional :offered_load, :double, 1
-  end
-  add_message "grpc.testing.ParetoParams" do
-    optional :interarrival_base, :double, 1
-    optional :alpha, :double, 2
-  end
   add_message "grpc.testing.ClosedLoopParams" do
   end
   add_message "grpc.testing.LoadParams" do
     oneof :load do
       optional :closed_loop, :message, 1, "grpc.testing.ClosedLoopParams"
       optional :poisson, :message, 2, "grpc.testing.PoissonParams"
-      optional :uniform, :message, 3, "grpc.testing.UniformParams"
-      optional :determ, :message, 4, "grpc.testing.DeterministicParams"
-      optional :pareto, :message, 5, "grpc.testing.ParetoParams"
     end
   end
   add_message "grpc.testing.SecurityParams" do
@@ -88,6 +74,40 @@
   end
   add_message "grpc.testing.Void" do
   end
+  add_message "grpc.testing.Scenario" do
+    optional :name, :string, 1
+    optional :client_config, :message, 2, "grpc.testing.ClientConfig"
+    optional :num_clients, :int32, 3
+    optional :server_config, :message, 4, "grpc.testing.ServerConfig"
+    optional :num_servers, :int32, 5
+    optional :warmup_seconds, :int32, 6
+    optional :benchmark_seconds, :int32, 7
+    optional :spawn_local_worker_count, :int32, 8
+  end
+  add_message "grpc.testing.Scenarios" do
+    repeated :scenarios, :message, 1, "grpc.testing.Scenario"
+  end
+  add_message "grpc.testing.ScenarioResultSummary" do
+    optional :qps, :double, 1
+    optional :qps_per_server_core, :double, 2
+    optional :server_system_time, :double, 3
+    optional :server_user_time, :double, 4
+    optional :client_system_time, :double, 5
+    optional :client_user_time, :double, 6
+    optional :latency_50, :double, 7
+    optional :latency_90, :double, 8
+    optional :latency_95, :double, 9
+    optional :latency_99, :double, 10
+    optional :latency_999, :double, 11
+  end
+  add_message "grpc.testing.ScenarioResult" do
+    optional :scenario, :message, 1, "grpc.testing.Scenario"
+    optional :latencies, :message, 2, "grpc.testing.HistogramData"
+    repeated :client_stats, :message, 3, "grpc.testing.ClientStats"
+    repeated :server_stats, :message, 4, "grpc.testing.ServerStats"
+    repeated :server_cores, :int32, 5
+    optional :summary, :message, 6, "grpc.testing.ScenarioResultSummary"
+  end
   add_enum "grpc.testing.ClientType" do
     value :SYNC_CLIENT, 0
     value :ASYNC_CLIENT, 1
@@ -106,9 +126,6 @@
 module Grpc
   module Testing
     PoissonParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PoissonParams").msgclass
-    UniformParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.UniformParams").msgclass
-    DeterministicParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.DeterministicParams").msgclass
-    ParetoParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ParetoParams").msgclass
     ClosedLoopParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClosedLoopParams").msgclass
     LoadParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadParams").msgclass
     SecurityParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SecurityParams").msgclass
@@ -122,6 +139,10 @@
     CoreRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.CoreRequest").msgclass
     CoreResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.CoreResponse").msgclass
     Void = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Void").msgclass
+    Scenario = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Scenario").msgclass
+    Scenarios = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Scenarios").msgclass
+    ScenarioResultSummary = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ScenarioResultSummary").msgclass
+    ScenarioResult = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ScenarioResult").msgclass
     ClientType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientType").enummodule
     ServerType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerType").enummodule
     RpcType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.RpcType").enummodule
diff --git a/src/ruby/qps/src/proto/grpc/testing/messages.rb b/src/ruby/qps/src/proto/grpc/testing/messages.rb
index b9c32db..2bdfe0e 100644
--- a/src/ruby/qps/src/proto/grpc/testing/messages.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/messages.rb
@@ -46,6 +46,9 @@
   add_message "grpc.testing.StreamingOutputCallResponse" do
     optional :payload, :message, 1, "grpc.testing.Payload"
   end
+  add_message "grpc.testing.ReconnectParams" do
+    optional :max_reconnect_backoff_ms, :int32, 1
+  end
   add_message "grpc.testing.ReconnectInfo" do
     optional :passed, :bool, 1
     repeated :backoff_ms, :int32, 2
@@ -73,6 +76,7 @@
     ResponseParameters = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ResponseParameters").msgclass
     StreamingOutputCallRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingOutputCallRequest").msgclass
     StreamingOutputCallResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingOutputCallResponse").msgclass
+    ReconnectParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ReconnectParams").msgclass
     ReconnectInfo = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ReconnectInfo").msgclass
     PayloadType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadType").enummodule
     CompressionType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.CompressionType").enummodule
diff --git a/src/ruby/qps/worker.rb b/src/ruby/qps/worker.rb
index 7c29204..665fb86 100755
--- a/src/ruby/qps/worker.rb
+++ b/src/ruby/qps/worker.rb
@@ -55,12 +55,12 @@
     Thread.new {
       bms = ''
       gtss = Grpc::Testing::ServerStatus
-      reqs.each do |req|        
+      reqs.each do |req|
         case req.argtype.to_s
         when 'setup'
           bms = BenchmarkServer.new(req.setup, @server_port)
           q.push(gtss.new(stats: bms.mark(false), port: bms.get_port))
-        when 'mark'         
+        when 'mark'
           q.push(gtss.new(stats: bms.mark(req.mark.reset), cores: cpu_cores))
         end
       end
diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template
index 701e1c7..6f8d1fb 100644
--- a/templates/grpc.gemspec.template
+++ b/templates/grpc.gemspec.template
@@ -37,6 +37,7 @@
     s.add_dependency 'googleauth',      '~> 0.5.1'
 
     s.add_development_dependency 'bundler',            '~> 1.9'
+    s.add_development_dependency 'facter',             '~> 2.4'
     s.add_development_dependency 'logging',            '~> 2.0'
     s.add_development_dependency 'simplecov',          '~> 0.9'
     s.add_development_dependency 'rake',               '~> 10.4'
diff --git a/templates/tools/dockerfile/go_path.include b/templates/tools/dockerfile/go_path.include
new file mode 100644
index 0000000..a41cc49
--- /dev/null
+++ b/templates/tools/dockerfile/go_path.include
@@ -0,0 +1,2 @@
+# Using login shell removes Go from path, so we add it.
+RUN ln -s /usr/local/go/bin/go /usr/local/bin
diff --git a/templates/tools/dockerfile/java_deps.include b/templates/tools/dockerfile/java_deps.include
new file mode 100644
index 0000000..40d70e0
--- /dev/null
+++ b/templates/tools/dockerfile/java_deps.include
@@ -0,0 +1,17 @@
+# Install JDK 8 and Git
+#
+RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && ${'\\'}
+  echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && ${'\\'}
+  echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && ${'\\'}
+  apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886
+
+RUN apt-get update && apt-get -y install ${'\\'}
+      git ${'\\'}
+      libapr1 ${'\\'}
+      oracle-java8-installer ${'\\'}
+      && ${'\\'}
+    apt-get clean && rm -r /var/cache/oracle-jdk8-installer/
+
+ENV JAVA_HOME /usr/lib/jvm/java-8-oracle
+ENV PATH $PATH:$JAVA_HOME/bin
+
diff --git a/templates/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile.template b/templates/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile.template
new file mode 100644
index 0000000..3ed3d65
--- /dev/null
+++ b/templates/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile.template
@@ -0,0 +1,37 @@
+%YAML 1.2
+--- |
+  # Copyright 2016, Google Inc.
+  # All rights reserved.
+  #
+  # Redistribution and use in source and binary forms, with or without
+  # modification, are permitted provided that the following conditions are
+  # met:
+  #
+  #     * Redistributions of source code must retain the above copyright
+  # notice, this list of conditions and the following disclaimer.
+  #     * Redistributions in binary form must reproduce the above
+  # copyright notice, this list of conditions and the following disclaimer
+  # in the documentation and/or other materials provided with the
+  # distribution.
+  #     * Neither the name of Google Inc. nor the names of its
+  # contributors may be used to endorse or promote products derived from
+  # this software without specific prior written permission.
+  #
+  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  
+  FROM golang:1.5
+  
+  <%include file="../../gcp_api_libraries.include"/>
+  <%include file="../../go_path.include"/>
+  # Define the default command.
+  CMD ["bash"]
diff --git a/templates/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile.template b/templates/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile.template
new file mode 100644
index 0000000..17ed99f
--- /dev/null
+++ b/templates/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile.template
@@ -0,0 +1,40 @@
+%YAML 1.2
+--- |
+  # Copyright 2016, Google Inc.
+  # All rights reserved.
+  #
+  # Redistribution and use in source and binary forms, with or without
+  # modification, are permitted provided that the following conditions are
+  # met:
+  #
+  #     * Redistributions of source code must retain the above copyright
+  # notice, this list of conditions and the following disclaimer.
+  #     * Redistributions in binary form must reproduce the above
+  # copyright notice, this list of conditions and the following disclaimer
+  # in the documentation and/or other materials provided with the
+  # distribution.
+  #     * Neither the name of Google Inc. nor the names of its
+  # contributors may be used to endorse or promote products derived from
+  # this software without specific prior written permission.
+  #
+  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  
+  FROM debian:jessie
+  
+  <%include file="../../apt_get_basic.include"/>
+  <%include file="../../ccache_setup.include"/>
+  <%include file="../../cxx_deps.include"/>
+  <%include file="../../gcp_api_libraries.include"/>
+  <%include file="../../java_deps.include"/>
+  # Define the default command.
+  CMD ["bash"]
diff --git a/templates/tools/fuzzer/runners.template b/templates/tools/fuzzer/runners.template
index 72d0b36..358d431 100644
--- a/templates/tools/fuzzer/runners.template
+++ b/templates/tools/fuzzer/runners.template
@@ -37,9 +37,13 @@
 
   flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=${selected.maxlen}"
   
+  %if selected.get('dict'):
+  flags="$flags -dict=${selected.dict}"
+  %endif
+
   if [ "$jobs" != "1" ]
   then
-    flags="-jobs=$jobs -workers=$jobs"
+    flags="-jobs=$jobs -workers=$jobs $flags"
   fi
 
   if [ "$config" == "asan-trace-cmp" ]
diff --git a/test/core/end2end/data/client_certs.c b/test/core/end2end/data/client_certs.c
new file mode 100644
index 0000000..9cdb704
--- /dev/null
+++ b/test/core/end2end/data/client_certs.c
@@ -0,0 +1,343 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+const char test_self_signed_client_cert[] = {
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x6f, 0x44, 0x43, 0x43,
+    0x41, 0x67, 0x6d, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4a,
+    0x41, 0x4e, 0x49, 0x7a, 0x32, 0x2f, 0x7a, 0x6f, 0x52, 0x69, 0x61, 0x70,
+    0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
+    0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x4d, 0x47, 0x6b, 0x78,
+    0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x59,
+    0x54, 0x41, 0x6b, 0x46, 0x56, 0x4d, 0x52, 0x4d, 0x77, 0x45, 0x51, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x49, 0x44, 0x41, 0x70, 0x54, 0x62, 0x32, 0x31,
+    0x6c, 0x4c, 0x56, 0x4e, 0x30, 0x59, 0x58, 0x52, 0x6c, 0x4d, 0x53, 0x45,
+    0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x42, 0x68,
+    0x4a, 0x62, 0x6e, 0x52, 0x6c, 0x63, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x42,
+    0x58, 0x0a, 0x61, 0x57, 0x52, 0x6e, 0x61, 0x58, 0x52, 0x7a, 0x49, 0x46,
+    0x42, 0x30, 0x65, 0x53, 0x42, 0x4d, 0x64, 0x47, 0x51, 0x78, 0x49, 0x6a,
+    0x41, 0x67, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x4d, 0x47, 0x57,
+    0x4a, 0x68, 0x5a, 0x47, 0x4e, 0x73, 0x61, 0x57, 0x56, 0x75, 0x64, 0x43,
+    0x35, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x64, 0x76, 0x62, 0x32,
+    0x64, 0x73, 0x5a, 0x53, 0x35, 0x6a, 0x0a, 0x62, 0x32, 0x30, 0x77, 0x48,
+    0x68, 0x63, 0x4e, 0x4d, 0x54, 0x51, 0x77, 0x4e, 0x7a, 0x49, 0x34, 0x4d,
+    0x6a, 0x41, 0x77, 0x4f, 0x44, 0x49, 0x31, 0x57, 0x68, 0x63, 0x4e, 0x4d,
+    0x6a, 0x51, 0x77, 0x4e, 0x7a, 0x49, 0x31, 0x4d, 0x6a, 0x41, 0x77, 0x4f,
+    0x44, 0x49, 0x31, 0x57, 0x6a, 0x42, 0x70, 0x4d, 0x51, 0x73, 0x77, 0x43,
+    0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x42, 0x0a,
+    0x56, 0x54, 0x45, 0x54, 0x4d, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x43, 0x41, 0x77, 0x4b, 0x55, 0x32, 0x39, 0x74, 0x5a, 0x53, 0x31, 0x54,
+    0x64, 0x47, 0x46, 0x30, 0x5a, 0x54, 0x45, 0x68, 0x4d, 0x42, 0x38, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x59, 0x53, 0x57, 0x35, 0x30,
+    0x5a, 0x58, 0x4a, 0x75, 0x5a, 0x58, 0x51, 0x67, 0x56, 0x32, 0x6c, 0x6b,
+    0x5a, 0x32, 0x6c, 0x30, 0x0a, 0x63, 0x79, 0x42, 0x51, 0x64, 0x48, 0x6b,
+    0x67, 0x54, 0x48, 0x52, 0x6b, 0x4d, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59,
+    0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x6c, 0x69, 0x59, 0x57, 0x52,
+    0x6a, 0x62, 0x47, 0x6c, 0x6c, 0x62, 0x6e, 0x51, 0x75, 0x64, 0x47, 0x56,
+    0x7a, 0x64, 0x43, 0x35, 0x6e, 0x62, 0x32, 0x39, 0x6e, 0x62, 0x47, 0x55,
+    0x75, 0x59, 0x32, 0x39, 0x74, 0x4d, 0x49, 0x47, 0x66, 0x0a, 0x4d, 0x41,
+    0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51,
+    0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x47, 0x4e, 0x41, 0x44,
+    0x43, 0x42, 0x69, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x43, 0x79, 0x58, 0x32,
+    0x4a, 0x78, 0x5a, 0x2b, 0x4a, 0x35, 0x49, 0x2b, 0x64, 0x6c, 0x68, 0x52,
+    0x4f, 0x56, 0x74, 0x71, 0x6c, 0x4d, 0x51, 0x6e, 0x34, 0x37, 0x42, 0x42,
+    0x63, 0x72, 0x0a, 0x6c, 0x32, 0x47, 0x43, 0x6b, 0x76, 0x39, 0x4f, 0x31,
+    0x44, 0x31, 0x72, 0x4c, 0x39, 0x34, 0x4b, 0x57, 0x59, 0x62, 0x59, 0x31,
+    0x34, 0x48, 0x58, 0x68, 0x69, 0x2f, 0x6e, 0x61, 0x63, 0x42, 0x41, 0x51,
+    0x74, 0x43, 0x45, 0x51, 0x77, 0x58, 0x78, 0x70, 0x35, 0x44, 0x4b, 0x65,
+    0x6d, 0x47, 0x4f, 0x55, 0x6a, 0x75, 0x36, 0x35, 0x78, 0x4d, 0x39, 0x46,
+    0x39, 0x36, 0x2f, 0x33, 0x37, 0x34, 0x47, 0x0a, 0x4d, 0x76, 0x6e, 0x52,
+    0x4a, 0x64, 0x6f, 0x35, 0x32, 0x67, 0x4f, 0x73, 0x34, 0x48, 0x4f, 0x30,
+    0x63, 0x7a, 0x42, 0x70, 0x66, 0x56, 0x4e, 0x64, 0x58, 0x65, 0x65, 0x6f,
+    0x44, 0x2f, 0x52, 0x59, 0x67, 0x77, 0x74, 0x74, 0x66, 0x64, 0x4a, 0x72,
+    0x7a, 0x2f, 0x34, 0x61, 0x61, 0x74, 0x73, 0x53, 0x32, 0x51, 0x6b, 0x32,
+    0x79, 0x4d, 0x59, 0x70, 0x71, 0x5a, 0x6d, 0x71, 0x45, 0x4d, 0x73, 0x62,
+    0x0a, 0x72, 0x68, 0x39, 0x57, 0x32, 0x32, 0x4c, 0x70, 0x33, 0x72, 0x43,
+    0x42, 0x76, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x31, 0x41,
+    0x77, 0x54, 0x6a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x34,
+    0x45, 0x46, 0x67, 0x51, 0x55, 0x35, 0x32, 0x33, 0x41, 0x4a, 0x4d, 0x52,
+    0x38, 0x44, 0x73, 0x39, 0x56, 0x38, 0x66, 0x68, 0x66, 0x37, 0x67, 0x75,
+    0x31, 0x69, 0x30, 0x4d, 0x4d, 0x0a, 0x55, 0x71, 0x41, 0x77, 0x48, 0x77,
+    0x59, 0x44, 0x56, 0x52, 0x30, 0x6a, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6f,
+    0x41, 0x55, 0x35, 0x32, 0x33, 0x41, 0x4a, 0x4d, 0x52, 0x38, 0x44, 0x73,
+    0x39, 0x56, 0x38, 0x66, 0x68, 0x66, 0x37, 0x67, 0x75, 0x31, 0x69, 0x30,
+    0x4d, 0x4d, 0x55, 0x71, 0x41, 0x77, 0x44, 0x41, 0x59, 0x44, 0x56, 0x52,
+    0x30, 0x54, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x0a, 0x2f,
+    0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39,
+    0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4f, 0x42, 0x67,
+    0x51, 0x43, 0x49, 0x2f, 0x74, 0x76, 0x53, 0x42, 0x59, 0x48, 0x31, 0x69,
+    0x79, 0x66, 0x4c, 0x61, 0x43, 0x54, 0x42, 0x4b, 0x77, 0x70, 0x64, 0x6a,
+    0x33, 0x36, 0x2b, 0x4d, 0x6b, 0x52, 0x39, 0x45, 0x65, 0x4a, 0x4a, 0x6d,
+    0x49, 0x6d, 0x78, 0x0a, 0x58, 0x2b, 0x62, 0x6a, 0x68, 0x4b, 0x57, 0x58,
+    0x77, 0x73, 0x42, 0x58, 0x34, 0x50, 0x44, 0x4d, 0x57, 0x76, 0x64, 0x75,
+    0x73, 0x72, 0x2b, 0x2b, 0x51, 0x47, 0x55, 0x59, 0x74, 0x79, 0x6f, 0x79,
+    0x61, 0x2b, 0x68, 0x66, 0x59, 0x4d, 0x58, 0x52, 0x68, 0x58, 0x75, 0x61,
+    0x33, 0x39, 0x6d, 0x44, 0x35, 0x34, 0x78, 0x67, 0x6c, 0x6f, 0x51, 0x4e,
+    0x75, 0x75, 0x39, 0x52, 0x45, 0x44, 0x77, 0x58, 0x0a, 0x46, 0x66, 0x74,
+    0x6f, 0x2b, 0x61, 0x4f, 0x77, 0x33, 0x42, 0x63, 0x59, 0x64, 0x75, 0x63,
+    0x7a, 0x36, 0x6f, 0x66, 0x78, 0x69, 0x63, 0x46, 0x4b, 0x2f, 0x59, 0x32,
+    0x56, 0x65, 0x58, 0x44, 0x75, 0x72, 0x53, 0x4d, 0x70, 0x52, 0x76, 0x35,
+    0x54, 0x66, 0x47, 0x66, 0x32, 0x51, 0x72, 0x36, 0x65, 0x4f, 0x4f, 0x64,
+    0x61, 0x52, 0x68, 0x6a, 0x36, 0x65, 0x64, 0x37, 0x42, 0x69, 0x62, 0x48,
+    0x6b, 0x0a, 0x58, 0x31, 0x56, 0x47, 0x5a, 0x41, 0x3d, 0x3d, 0x0a, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54,
+    0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    0x0a, 0x00};
+
+const char test_self_signed_client_key[] = {
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50,
+    0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x64, 0x77, 0x49, 0x42,
+    0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43,
+    0x41, 0x6d, 0x45, 0x77, 0x67, 0x67, 0x4a, 0x64, 0x41, 0x67, 0x45, 0x41,
+    0x41, 0x6f, 0x47, 0x42, 0x41, 0x4c, 0x4a, 0x66, 0x59, 0x6e, 0x46, 0x6e,
+    0x34, 0x6e, 0x6b, 0x6a, 0x35, 0x32, 0x57, 0x46, 0x0a, 0x45, 0x35, 0x57,
+    0x32, 0x71, 0x55, 0x78, 0x43, 0x66, 0x6a, 0x73, 0x45, 0x46, 0x79, 0x75,
+    0x58, 0x59, 0x59, 0x4b, 0x53, 0x2f, 0x30, 0x37, 0x55, 0x50, 0x57, 0x73,
+    0x76, 0x33, 0x67, 0x70, 0x5a, 0x68, 0x74, 0x6a, 0x58, 0x67, 0x64, 0x65,
+    0x47, 0x4c, 0x2b, 0x64, 0x70, 0x77, 0x45, 0x42, 0x43, 0x30, 0x49, 0x52,
+    0x44, 0x42, 0x66, 0x47, 0x6e, 0x6b, 0x4d, 0x70, 0x36, 0x59, 0x59, 0x35,
+    0x53, 0x0a, 0x4f, 0x37, 0x72, 0x6e, 0x45, 0x7a, 0x30, 0x58, 0x33, 0x72,
+    0x2f, 0x66, 0x76, 0x67, 0x59, 0x79, 0x2b, 0x64, 0x45, 0x6c, 0x32, 0x6a,
+    0x6e, 0x61, 0x41, 0x36, 0x7a, 0x67, 0x63, 0x37, 0x52, 0x7a, 0x4d, 0x47,
+    0x6c, 0x39, 0x55, 0x31, 0x31, 0x64, 0x35, 0x36, 0x67, 0x50, 0x39, 0x46,
+    0x69, 0x44, 0x43, 0x32, 0x31, 0x39, 0x30, 0x6d, 0x76, 0x50, 0x2f, 0x68,
+    0x70, 0x71, 0x32, 0x78, 0x4c, 0x5a, 0x0a, 0x43, 0x54, 0x62, 0x49, 0x78,
+    0x69, 0x6d, 0x70, 0x6d, 0x61, 0x6f, 0x51, 0x79, 0x78, 0x75, 0x75, 0x48,
+    0x31, 0x62, 0x62, 0x59, 0x75, 0x6e, 0x65, 0x73, 0x49, 0x47, 0x2f, 0x41,
+    0x67, 0x4d, 0x42, 0x41, 0x41, 0x45, 0x43, 0x67, 0x59, 0x41, 0x64, 0x71,
+    0x4a, 0x43, 0x45, 0x7a, 0x4d, 0x49, 0x79, 0x5a, 0x45, 0x37, 0x6f, 0x61,
+    0x57, 0x30, 0x74, 0x4f, 0x70, 0x63, 0x42, 0x30, 0x42, 0x69, 0x50, 0x0a,
+    0x46, 0x59, 0x6f, 0x49, 0x76, 0x48, 0x34, 0x42, 0x4b, 0x52, 0x48, 0x38,
+    0x65, 0x48, 0x76, 0x52, 0x34, 0x37, 0x36, 0x6d, 0x74, 0x2b, 0x59, 0x64,
+    0x44, 0x68, 0x42, 0x50, 0x31, 0x73, 0x63, 0x47, 0x55, 0x6d, 0x59, 0x65,
+    0x43, 0x54, 0x34, 0x45, 0x6a, 0x2b, 0x52, 0x67, 0x48, 0x76, 0x32, 0x4c,
+    0x50, 0x54, 0x67, 0x56, 0x59, 0x77, 0x54, 0x39, 0x65, 0x63, 0x69, 0x50,
+    0x32, 0x2b, 0x45, 0x2f, 0x0a, 0x43, 0x42, 0x43, 0x4e, 0x52, 0x65, 0x6c,
+    0x30, 0x53, 0x77, 0x39, 0x4a, 0x65, 0x70, 0x77, 0x57, 0x30, 0x72, 0x2b,
+    0x6a, 0x57, 0x4a, 0x74, 0x44, 0x59, 0x31, 0x70, 0x70, 0x36, 0x59, 0x58,
+    0x41, 0x67, 0x4e, 0x52, 0x47, 0x58, 0x32, 0x55, 0x66, 0x6c, 0x76, 0x55,
+    0x73, 0x54, 0x2b, 0x6f, 0x39, 0x6c, 0x5a, 0x76, 0x61, 0x67, 0x66, 0x39,
+    0x6d, 0x6f, 0x4c, 0x54, 0x4d, 0x79, 0x47, 0x76, 0x55, 0x0a, 0x75, 0x4c,
+    0x46, 0x6e, 0x73, 0x79, 0x66, 0x4c, 0x69, 0x6d, 0x31, 0x42, 0x34, 0x76,
+    0x58, 0x76, 0x57, 0x51, 0x4a, 0x42, 0x41, 0x4e, 0x6f, 0x75, 0x5a, 0x6c,
+    0x6c, 0x58, 0x47, 0x5a, 0x6f, 0x53, 0x72, 0x5a, 0x4c, 0x74, 0x52, 0x33,
+    0x56, 0x67, 0x56, 0x34, 0x74, 0x7a, 0x52, 0x51, 0x76, 0x4a, 0x78, 0x75,
+    0x38, 0x34, 0x6b, 0x4c, 0x65, 0x49, 0x6b, 0x36, 0x34, 0x4f, 0x76, 0x34,
+    0x37, 0x58, 0x0a, 0x70, 0x48, 0x56, 0x42, 0x4d, 0x54, 0x52, 0x42, 0x66,
+    0x7a, 0x50, 0x45, 0x68, 0x62, 0x42, 0x6f, 0x64, 0x6a, 0x72, 0x31, 0x6d,
+    0x35, 0x4f, 0x4c, 0x61, 0x56, 0x4c, 0x71, 0x6b, 0x46, 0x63, 0x58, 0x66,
+    0x74, 0x7a, 0x52, 0x43, 0x72, 0x62, 0x57, 0x6f, 0x4b, 0x73, 0x43, 0x51,
+    0x51, 0x44, 0x52, 0x53, 0x6f, 0x4c, 0x4c, 0x58, 0x4f, 0x69, 0x4c, 0x72,
+    0x74, 0x4a, 0x33, 0x44, 0x4c, 0x4a, 0x43, 0x0a, 0x72, 0x58, 0x37, 0x59,
+    0x38, 0x77, 0x72, 0x48, 0x5a, 0x72, 0x71, 0x6b, 0x35, 0x62, 0x4d, 0x64,
+    0x5a, 0x4c, 0x47, 0x61, 0x2f, 0x55, 0x58, 0x38, 0x52, 0x61, 0x6e, 0x68,
+    0x56, 0x77, 0x33, 0x2b, 0x58, 0x70, 0x2b, 0x75, 0x72, 0x64, 0x31, 0x37,
+    0x31, 0x31, 0x75, 0x6d, 0x65, 0x4e, 0x4a, 0x66, 0x7a, 0x75, 0x2f, 0x4d,
+    0x43, 0x6b, 0x34, 0x61, 0x31, 0x4b, 0x6b, 0x47, 0x2f, 0x43, 0x55, 0x30,
+    0x0a, 0x72, 0x71, 0x73, 0x39, 0x41, 0x6b, 0x41, 0x34, 0x63, 0x53, 0x78,
+    0x31, 0x44, 0x44, 0x31, 0x4a, 0x53, 0x47, 0x2b, 0x79, 0x78, 0x4d, 0x4e,
+    0x70, 0x73, 0x41, 0x53, 0x31, 0x78, 0x4a, 0x6f, 0x6d, 0x46, 0x49, 0x72,
+    0x73, 0x4d, 0x39, 0x76, 0x73, 0x50, 0x74, 0x37, 0x46, 0x64, 0x6e, 0x64,
+    0x44, 0x77, 0x72, 0x46, 0x2b, 0x79, 0x2b, 0x43, 0x6f, 0x76, 0x68, 0x44,
+    0x6b, 0x47, 0x59, 0x44, 0x6b, 0x0a, 0x52, 0x41, 0x48, 0x68, 0x2b, 0x73,
+    0x76, 0x47, 0x66, 0x5a, 0x67, 0x2f, 0x70, 0x51, 0x4b, 0x32, 0x4a, 0x52,
+    0x50, 0x69, 0x6d, 0x41, 0x6d, 0x48, 0x68, 0x7a, 0x71, 0x46, 0x41, 0x6b,
+    0x45, 0x41, 0x75, 0x36, 0x59, 0x61, 0x37, 0x30, 0x73, 0x32, 0x46, 0x55,
+    0x65, 0x42, 0x33, 0x4d, 0x75, 0x39, 0x61, 0x4a, 0x73, 0x32, 0x43, 0x44,
+    0x36, 0x68, 0x67, 0x33, 0x64, 0x51, 0x45, 0x56, 0x6b, 0x42, 0x0a, 0x35,
+    0x33, 0x44, 0x49, 0x37, 0x54, 0x58, 0x34, 0x38, 0x64, 0x39, 0x6b, 0x47,
+    0x57, 0x35, 0x38, 0x56, 0x58, 0x31, 0x78, 0x6e, 0x71, 0x53, 0x30, 0x32,
+    0x4c, 0x79, 0x57, 0x71, 0x41, 0x50, 0x63, 0x57, 0x35, 0x71, 0x6d, 0x31,
+    0x6b, 0x4c, 0x48, 0x46, 0x4c, 0x64, 0x6e, 0x64, 0x61, 0x50, 0x4e, 0x6d,
+    0x42, 0x61, 0x6a, 0x34, 0x51, 0x4a, 0x42, 0x41, 0x4a, 0x75, 0x67, 0x6c,
+    0x33, 0x36, 0x37, 0x0a, 0x39, 0x64, 0x39, 0x74, 0x2f, 0x51, 0x4c, 0x54,
+    0x53, 0x75, 0x55, 0x4c, 0x4c, 0x61, 0x6f, 0x59, 0x76, 0x32, 0x76, 0x4a,
+    0x54, 0x33, 0x73, 0x31, 0x79, 0x39, 0x48, 0x4e, 0x38, 0x39, 0x45, 0x6f,
+    0x61, 0x44, 0x44, 0x45, 0x6b, 0x50, 0x56, 0x66, 0x51, 0x75, 0x36, 0x47,
+    0x56, 0x45, 0x58, 0x67, 0x49, 0x42, 0x74, 0x69, 0x6d, 0x31, 0x73, 0x49,
+    0x2f, 0x56, 0x50, 0x53, 0x7a, 0x49, 0x38, 0x48, 0x0a, 0x61, 0x58, 0x76,
+    0x61, 0x54, 0x55, 0x77, 0x62, 0x6c, 0x46, 0x57, 0x53, 0x4d, 0x37, 0x30,
+    0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50,
+    0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x00};
+
+const char test_signed_client_cert[] = {
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
+    0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x48, 0x7a, 0x43, 0x43,
+    0x41, 0x59, 0x67, 0x43, 0x41, 0x51, 0x45, 0x77, 0x44, 0x51, 0x59, 0x4a,
+    0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46,
+    0x42, 0x51, 0x41, 0x77, 0x56, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47,
+    0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x51, 0x56, 0x55, 0x78,
+    0x45, 0x7a, 0x41, 0x52, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x67,
+    0x4d, 0x43, 0x6c, 0x4e, 0x76, 0x62, 0x57, 0x55, 0x74, 0x55, 0x33, 0x52,
+    0x68, 0x64, 0x47, 0x55, 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4e,
+    0x56, 0x42, 0x41, 0x6f, 0x4d, 0x47, 0x45, 0x6c, 0x75, 0x64, 0x47, 0x56,
+    0x79, 0x62, 0x6d, 0x56, 0x30, 0x49, 0x46, 0x64, 0x70, 0x5a, 0x47, 0x64,
+    0x70, 0x64, 0x48, 0x4d, 0x67, 0x55, 0x48, 0x52, 0x35, 0x49, 0x45, 0x78,
+    0x30, 0x0a, 0x5a, 0x44, 0x45, 0x50, 0x4d, 0x41, 0x30, 0x47, 0x41, 0x31,
+    0x55, 0x45, 0x41, 0x77, 0x77, 0x47, 0x64, 0x47, 0x56, 0x7a, 0x64, 0x47,
+    0x4e, 0x68, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x30, 0x4d, 0x44,
+    0x63, 0x78, 0x4e, 0x7a, 0x49, 0x7a, 0x4e, 0x54, 0x59, 0x77, 0x4d, 0x6c,
+    0x6f, 0x58, 0x44, 0x54, 0x49, 0x30, 0x4d, 0x44, 0x63, 0x78, 0x4e, 0x44,
+    0x49, 0x7a, 0x4e, 0x54, 0x59, 0x77, 0x0a, 0x4d, 0x6c, 0x6f, 0x77, 0x57,
+    0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42,
+    0x68, 0x4d, 0x43, 0x51, 0x56, 0x55, 0x78, 0x45, 0x7a, 0x41, 0x52, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x4d, 0x43, 0x6c, 0x4e, 0x76, 0x62,
+    0x57, 0x55, 0x74, 0x55, 0x33, 0x52, 0x68, 0x64, 0x47, 0x55, 0x78, 0x49,
+    0x54, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x0a,
+    0x47, 0x45, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x79, 0x62, 0x6d, 0x56, 0x30,
+    0x49, 0x46, 0x64, 0x70, 0x5a, 0x47, 0x64, 0x70, 0x64, 0x48, 0x4d, 0x67,
+    0x55, 0x48, 0x52, 0x35, 0x49, 0x45, 0x78, 0x30, 0x5a, 0x44, 0x45, 0x54,
+    0x4d, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x4b,
+    0x64, 0x47, 0x56, 0x7a, 0x64, 0x47, 0x4e, 0x73, 0x61, 0x57, 0x56, 0x75,
+    0x64, 0x44, 0x43, 0x42, 0x0a, 0x6e, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b,
+    0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45,
+    0x46, 0x41, 0x41, 0x4f, 0x42, 0x6a, 0x51, 0x41, 0x77, 0x67, 0x59, 0x6b,
+    0x43, 0x67, 0x59, 0x45, 0x41, 0x37, 0x46, 0x52, 0x48, 0x32, 0x36, 0x47,
+    0x2b, 0x46, 0x74, 0x35, 0x56, 0x51, 0x67, 0x79, 0x7a, 0x6c, 0x5a, 0x73,
+    0x66, 0x53, 0x6e, 0x48, 0x53, 0x5a, 0x36, 0x47, 0x58, 0x0a, 0x62, 0x37,
+    0x71, 0x78, 0x6d, 0x6b, 0x32, 0x50, 0x4f, 0x38, 0x54, 0x59, 0x71, 0x4b,
+    0x5a, 0x6d, 0x6b, 0x66, 0x4d, 0x77, 0x6b, 0x65, 0x36, 0x52, 0x55, 0x66,
+    0x51, 0x56, 0x2b, 0x53, 0x2b, 0x47, 0x7a, 0x52, 0x76, 0x7a, 0x35, 0x4c,
+    0x6c, 0x53, 0x33, 0x31, 0x55, 0x31, 0x51, 0x43, 0x70, 0x33, 0x63, 0x67,
+    0x77, 0x6b, 0x49, 0x49, 0x41, 0x51, 0x61, 0x31, 0x45, 0x32, 0x68, 0x43,
+    0x45, 0x7a, 0x0a, 0x57, 0x33, 0x31, 0x69, 0x76, 0x62, 0x4d, 0x42, 0x79,
+    0x52, 0x4b, 0x39, 0x74, 0x46, 0x70, 0x79, 0x6e, 0x34, 0x55, 0x76, 0x38,
+    0x4b, 0x50, 0x31, 0x34, 0x4f, 0x62, 0x4b, 0x6a, 0x54, 0x51, 0x71, 0x78,
+    0x55, 0x5a, 0x70, 0x35, 0x35, 0x38, 0x44, 0x67, 0x4f, 0x48, 0x67, 0x35,
+    0x62, 0x35, 0x6d, 0x47, 0x52, 0x4d, 0x30, 0x70, 0x79, 0x56, 0x31, 0x65,
+    0x71, 0x52, 0x4b, 0x36, 0x50, 0x57, 0x77, 0x0a, 0x52, 0x2f, 0x62, 0x6a,
+    0x67, 0x6c, 0x6c, 0x69, 0x36, 0x70, 0x6d, 0x6e, 0x72, 0x2b, 0x30, 0x43,
+    0x41, 0x77, 0x45, 0x41, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71,
+    0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46,
+    0x41, 0x41, 0x4f, 0x42, 0x67, 0x51, 0x41, 0x53, 0x74, 0x53, 0x6d, 0x35,
+    0x50, 0x4d, 0x37, 0x75, 0x62, 0x52, 0x4f, 0x69, 0x4b, 0x4b, 0x36, 0x2f,
+    0x0a, 0x54, 0x32, 0x46, 0x6b, 0x4b, 0x6c, 0x68, 0x69, 0x54, 0x4f, 0x78,
+    0x2b, 0x52, 0x79, 0x65, 0x6e, 0x6d, 0x33, 0x45, 0x69, 0x6f, 0x35, 0x39,
+    0x65, 0x6d, 0x71, 0x2b, 0x6a, 0x58, 0x6c, 0x2b, 0x31, 0x6e, 0x68, 0x50,
+    0x79, 0x53, 0x58, 0x35, 0x47, 0x32, 0x50, 0x51, 0x7a, 0x53, 0x52, 0x35,
+    0x76, 0x64, 0x31, 0x64, 0x49, 0x68, 0x77, 0x67, 0x5a, 0x53, 0x52, 0x34,
+    0x47, 0x79, 0x74, 0x74, 0x6b, 0x0a, 0x74, 0x52, 0x5a, 0x35, 0x37, 0x6b,
+    0x2f, 0x4e, 0x49, 0x31, 0x62, 0x72, 0x55, 0x57, 0x38, 0x6a, 0x6f, 0x69,
+    0x45, 0x4f, 0x4d, 0x4a, 0x41, 0x2f, 0x4d, 0x72, 0x37, 0x48, 0x37, 0x61,
+    0x73, 0x78, 0x37, 0x77, 0x49, 0x52, 0x59, 0x44, 0x45, 0x39, 0x31, 0x46,
+    0x73, 0x38, 0x47, 0x6b, 0x4b, 0x57, 0x64, 0x35, 0x4c, 0x68, 0x6f, 0x50,
+    0x41, 0x51, 0x6a, 0x2b, 0x71, 0x64, 0x47, 0x33, 0x35, 0x43, 0x0a, 0x4f,
+    0x4f, 0x2b, 0x73, 0x76, 0x64, 0x6b, 0x6d, 0x71, 0x48, 0x30, 0x4b, 0x5a,
+    0x6f, 0x33, 0x32, 0x30, 0x5a, 0x55, 0x71, 0x64, 0x6c, 0x32, 0x6f, 0x6f,
+    0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44,
+    0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x00};
+
+const char test_signed_client_key[] = {
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50,
+    0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x65, 0x51, 0x49, 0x42,
+    0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43,
+    0x41, 0x6d, 0x4d, 0x77, 0x67, 0x67, 0x4a, 0x66, 0x41, 0x67, 0x45, 0x41,
+    0x41, 0x6f, 0x47, 0x42, 0x41, 0x4f, 0x78, 0x55, 0x52, 0x39, 0x75, 0x68,
+    0x76, 0x68, 0x62, 0x65, 0x56, 0x55, 0x49, 0x4d, 0x0a, 0x73, 0x35, 0x57,
+    0x62, 0x48, 0x30, 0x70, 0x78, 0x30, 0x6d, 0x65, 0x68, 0x6c, 0x32, 0x2b,
+    0x36, 0x73, 0x5a, 0x70, 0x4e, 0x6a, 0x7a, 0x76, 0x45, 0x32, 0x4b, 0x69,
+    0x6d, 0x5a, 0x70, 0x48, 0x7a, 0x4d, 0x4a, 0x48, 0x75, 0x6b, 0x56, 0x48,
+    0x30, 0x46, 0x66, 0x6b, 0x76, 0x68, 0x73, 0x30, 0x62, 0x38, 0x2b, 0x53,
+    0x35, 0x55, 0x74, 0x39, 0x56, 0x4e, 0x55, 0x41, 0x71, 0x64, 0x33, 0x49,
+    0x4d, 0x0a, 0x4a, 0x43, 0x43, 0x41, 0x45, 0x47, 0x74, 0x52, 0x4e, 0x6f,
+    0x51, 0x68, 0x4d, 0x31, 0x74, 0x39, 0x59, 0x72, 0x32, 0x7a, 0x41, 0x63,
+    0x6b, 0x53, 0x76, 0x62, 0x52, 0x61, 0x63, 0x70, 0x2b, 0x46, 0x4c, 0x2f,
+    0x43, 0x6a, 0x39, 0x65, 0x44, 0x6d, 0x79, 0x6f, 0x30, 0x30, 0x4b, 0x73,
+    0x56, 0x47, 0x61, 0x65, 0x65, 0x66, 0x41, 0x34, 0x44, 0x68, 0x34, 0x4f,
+    0x57, 0x2b, 0x5a, 0x68, 0x6b, 0x54, 0x0a, 0x4e, 0x4b, 0x63, 0x6c, 0x64,
+    0x58, 0x71, 0x6b, 0x53, 0x75, 0x6a, 0x31, 0x73, 0x45, 0x66, 0x32, 0x34,
+    0x34, 0x4a, 0x5a, 0x59, 0x75, 0x71, 0x5a, 0x70, 0x36, 0x2f, 0x74, 0x41,
+    0x67, 0x4d, 0x42, 0x41, 0x41, 0x45, 0x43, 0x67, 0x59, 0x45, 0x41, 0x69,
+    0x32, 0x4e, 0x53, 0x56, 0x71, 0x70, 0x5a, 0x4d, 0x61, 0x66, 0x45, 0x35,
+    0x59, 0x59, 0x55, 0x54, 0x63, 0x4d, 0x47, 0x65, 0x36, 0x51, 0x53, 0x0a,
+    0x6b, 0x32, 0x6a, 0x74, 0x70, 0x73, 0x71, 0x59, 0x67, 0x67, 0x67, 0x49,
+    0x32, 0x52, 0x6e, 0x4c, 0x4a, 0x2f, 0x32, 0x74, 0x4e, 0x5a, 0x77, 0x59,
+    0x49, 0x35, 0x70, 0x77, 0x50, 0x38, 0x51, 0x56, 0x53, 0x62, 0x6e, 0x4d,
+    0x61, 0x69, 0x46, 0x34, 0x67, 0x6f, 0x6b, 0x44, 0x35, 0x68, 0x47, 0x64,
+    0x72, 0x4e, 0x44, 0x66, 0x54, 0x6e, 0x62, 0x32, 0x76, 0x2b, 0x79, 0x49,
+    0x77, 0x59, 0x45, 0x48, 0x0a, 0x30, 0x77, 0x38, 0x2b, 0x6f, 0x47, 0x37,
+    0x5a, 0x38, 0x31, 0x4b, 0x6f, 0x64, 0x73, 0x69, 0x5a, 0x53, 0x49, 0x44,
+    0x4a, 0x66, 0x54, 0x47, 0x73, 0x41, 0x5a, 0x68, 0x56, 0x4e, 0x77, 0x4f,
+    0x7a, 0x39, 0x79, 0x30, 0x56, 0x44, 0x38, 0x42, 0x42, 0x5a, 0x5a, 0x31,
+    0x2f, 0x32, 0x37, 0x34, 0x5a, 0x68, 0x35, 0x32, 0x41, 0x55, 0x4b, 0x4c,
+    0x6a, 0x5a, 0x53, 0x2f, 0x5a, 0x77, 0x49, 0x62, 0x53, 0x0a, 0x57, 0x32,
+    0x79, 0x77, 0x79, 0x61, 0x38, 0x35, 0x35, 0x64, 0x50, 0x6e, 0x48, 0x2f,
+    0x77, 0x6a, 0x2b, 0x30, 0x45, 0x43, 0x51, 0x51, 0x44, 0x39, 0x58, 0x38,
+    0x44, 0x39, 0x32, 0x30, 0x6b, 0x42, 0x79, 0x54, 0x4e, 0x48, 0x68, 0x42,
+    0x47, 0x31, 0x38, 0x62, 0x69, 0x41, 0x45, 0x5a, 0x34, 0x70, 0x78, 0x73,
+    0x39, 0x66, 0x30, 0x4f, 0x41, 0x47, 0x38, 0x33, 0x33, 0x33, 0x65, 0x56,
+    0x63, 0x49, 0x0a, 0x77, 0x32, 0x6c, 0x4a, 0x44, 0x4c, 0x73, 0x59, 0x44,
+    0x5a, 0x72, 0x43, 0x42, 0x32, 0x6f, 0x63, 0x67, 0x41, 0x33, 0x6c, 0x55,
+    0x64, 0x6f, 0x7a, 0x6c, 0x7a, 0x50, 0x43, 0x37, 0x59, 0x44, 0x59, 0x77,
+    0x38, 0x72, 0x65, 0x67, 0x30, 0x74, 0x6b, 0x69, 0x52, 0x59, 0x35, 0x41,
+    0x6b, 0x45, 0x41, 0x37, 0x73, 0x64, 0x4e, 0x7a, 0x4f, 0x65, 0x51, 0x73,
+    0x51, 0x52, 0x6e, 0x37, 0x2b, 0x2b, 0x35, 0x0a, 0x30, 0x62, 0x50, 0x39,
+    0x44, 0x74, 0x54, 0x2f, 0x69, 0x4f, 0x4e, 0x31, 0x67, 0x62, 0x66, 0x78,
+    0x52, 0x7a, 0x43, 0x66, 0x43, 0x66, 0x58, 0x64, 0x6f, 0x4f, 0x74, 0x66,
+    0x51, 0x57, 0x49, 0x7a, 0x54, 0x65, 0x50, 0x57, 0x74, 0x55, 0x52, 0x74,
+    0x39, 0x58, 0x2f, 0x35, 0x44, 0x39, 0x4e, 0x6f, 0x66, 0x49, 0x30, 0x52,
+    0x67, 0x35, 0x57, 0x32, 0x6f, 0x47, 0x79, 0x2f, 0x4d, 0x4c, 0x65, 0x35,
+    0x0a, 0x2f, 0x73, 0x58, 0x48, 0x56, 0x51, 0x4a, 0x42, 0x41, 0x49, 0x75,
+    0x70, 0x35, 0x58, 0x72, 0x4a, 0x44, 0x6b, 0x51, 0x79, 0x77, 0x4e, 0x5a,
+    0x79, 0x41, 0x55, 0x55, 0x32, 0x65, 0x63, 0x6e, 0x32, 0x62, 0x43, 0x57,
+    0x42, 0x46, 0x6a, 0x77, 0x74, 0x71, 0x64, 0x2b, 0x4c, 0x42, 0x6d, 0x75,
+    0x4d, 0x63, 0x69, 0x49, 0x39, 0x66, 0x4f, 0x4b, 0x73, 0x5a, 0x74, 0x45,
+    0x4b, 0x5a, 0x72, 0x7a, 0x2f, 0x0a, 0x55, 0x30, 0x6c, 0x6b, 0x65, 0x4d,
+    0x52, 0x6f, 0x53, 0x77, 0x76, 0x58, 0x45, 0x38, 0x77, 0x6d, 0x47, 0x4c,
+    0x6a, 0x6a, 0x72, 0x41, 0x62, 0x64, 0x66, 0x6f, 0x68, 0x72, 0x58, 0x46,
+    0x6b, 0x43, 0x51, 0x51, 0x44, 0x5a, 0x45, 0x78, 0x2f, 0x4c, 0x74, 0x49,
+    0x6c, 0x36, 0x4a, 0x49, 0x4e, 0x4a, 0x51, 0x69, 0x73, 0x77, 0x56, 0x65,
+    0x30, 0x74, 0x57, 0x72, 0x36, 0x6b, 0x2b, 0x41, 0x53, 0x50, 0x0a, 0x31,
+    0x57, 0x58, 0x6f, 0x54, 0x6d, 0x2b, 0x48, 0x59, 0x70, 0x6f, 0x46, 0x2f,
+    0x58, 0x55, 0x76, 0x76, 0x39, 0x4c, 0x63, 0x63, 0x4e, 0x46, 0x31, 0x49,
+    0x61, 0x7a, 0x46, 0x6a, 0x33, 0x34, 0x68, 0x77, 0x52, 0x51, 0x77, 0x68,
+    0x78, 0x37, 0x77, 0x2f, 0x56, 0x35, 0x32, 0x49, 0x65, 0x62, 0x2b, 0x70,
+    0x30, 0x6a, 0x55, 0x4d, 0x59, 0x47, 0x78, 0x41, 0x6b, 0x45, 0x41, 0x6a,
+    0x44, 0x68, 0x64, 0x0a, 0x39, 0x70, 0x42, 0x4f, 0x31, 0x66, 0x4b, 0x58,
+    0x57, 0x69, 0x58, 0x7a, 0x69, 0x39, 0x5a, 0x4b, 0x66, 0x6f, 0x79, 0x54,
+    0x4e, 0x63, 0x55, 0x71, 0x33, 0x65, 0x42, 0x53, 0x56, 0x4b, 0x77, 0x50,
+    0x47, 0x32, 0x6e, 0x49, 0x74, 0x67, 0x35, 0x79, 0x63, 0x58, 0x65, 0x6e,
+    0x67, 0x6a, 0x54, 0x35, 0x73, 0x67, 0x63, 0x57, 0x44, 0x6e, 0x63, 0x69,
+    0x49, 0x7a, 0x57, 0x37, 0x42, 0x49, 0x56, 0x49, 0x0a, 0x4a, 0x69, 0x71,
+    0x4f, 0x73, 0x7a, 0x71, 0x39, 0x47, 0x57, 0x45, 0x53, 0x45, 0x72, 0x41,
+    0x61, 0x74, 0x67, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b,
+    0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x00};
diff --git a/test/core/end2end/data/ssl_test_data.h b/test/core/end2end/data/ssl_test_data.h
index 675249d..4a64af1 100644
--- a/test/core/end2end/data/ssl_test_data.h
+++ b/test/core/end2end/data/ssl_test_data.h
@@ -37,5 +37,9 @@
 extern const char test_root_cert[];
 extern const char test_server1_cert[];
 extern const char test_server1_key[];
+extern const char test_self_signed_client_cert[];
+extern const char test_self_signed_client_key[];
+extern const char test_signed_client_cert[];
+extern const char test_signed_client_key[];
 
 #endif /* GRPC_TEST_CORE_END2END_DATA_SSL_TEST_DATA_H */
diff --git a/test/core/end2end/fixtures/h2_ssl_cert.c b/test/core/end2end/fixtures/h2_ssl_cert.c
new file mode 100644
index 0000000..cd031ca
--- /dev/null
+++ b/test/core/end2end/fixtures/h2_ssl_cert.c
@@ -0,0 +1,376 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/security/credentials.h"
+#include "src/core/lib/support/env.h"
+#include "src/core/lib/support/string.h"
+#include "src/core/lib/support/tmpfile.h"
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/data/ssl_test_data.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+extern void simple_request(grpc_end2end_test_config config);
+
+typedef struct fullstack_secure_fixture_data {
+  char *localaddr;
+} fullstack_secure_fixture_data;
+
+static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
+    grpc_channel_args *client_args, grpc_channel_args *server_args) {
+  grpc_end2end_test_fixture f;
+  int port = grpc_pick_unused_port_or_die();
+  fullstack_secure_fixture_data *ffd =
+      gpr_malloc(sizeof(fullstack_secure_fixture_data));
+  memset(&f, 0, sizeof(f));
+
+  gpr_join_host_port(&ffd->localaddr, "localhost", port);
+
+  f.fixture_data = ffd;
+  f.cq = grpc_completion_queue_create(NULL);
+
+  return f;
+}
+
+static void process_auth_failure(void *state, grpc_auth_context *ctx,
+                                 const grpc_metadata *md, size_t md_count,
+                                 grpc_process_auth_metadata_done_cb cb,
+                                 void *user_data) {
+  GPR_ASSERT(state == NULL);
+  cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL);
+}
+
+static void chttp2_init_client_secure_fullstack(
+    grpc_end2end_test_fixture *f, grpc_channel_args *client_args,
+    grpc_channel_credentials *creds) {
+  fullstack_secure_fixture_data *ffd = f->fixture_data;
+  f->client =
+      grpc_secure_channel_create(creds, ffd->localaddr, client_args, NULL);
+  GPR_ASSERT(f->client != NULL);
+  grpc_channel_credentials_release(creds);
+}
+
+static void chttp2_init_server_secure_fullstack(
+    grpc_end2end_test_fixture *f, grpc_channel_args *server_args,
+    grpc_server_credentials *server_creds) {
+  fullstack_secure_fixture_data *ffd = f->fixture_data;
+  if (f->server) {
+    grpc_server_destroy(f->server);
+  }
+  f->server = grpc_server_create(server_args, NULL);
+  grpc_server_register_completion_queue(f->server, f->cq, NULL);
+  GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr,
+                                               server_creds));
+  grpc_server_credentials_release(server_creds);
+  grpc_server_start(f->server);
+}
+
+void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) {
+  fullstack_secure_fixture_data *ffd = f->fixture_data;
+  gpr_free(ffd->localaddr);
+  gpr_free(ffd);
+}
+
+static int fail_server_auth_check(grpc_channel_args *server_args) {
+  size_t i;
+  if (server_args == NULL) return 0;
+  for (i = 0; i < server_args->num_args; i++) {
+    if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
+        0) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+#define SERVER_INIT_NAME(REQUEST_TYPE) \
+  chttp2_init_server_simple_ssl_secure_fullstack_##REQUEST_TYPE
+
+#define SERVER_INIT(REQUEST_TYPE)                                           \
+  static void SERVER_INIT_NAME(REQUEST_TYPE)(                               \
+      grpc_end2end_test_fixture * f, grpc_channel_args * server_args) {     \
+    grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,       \
+                                                    test_server1_cert};     \
+    grpc_server_credentials *ssl_creds =                                    \
+        grpc_ssl_server_credentials_create_ex(                              \
+            test_root_cert, &pem_cert_key_pair, 1, REQUEST_TYPE, NULL);     \
+    if (fail_server_auth_check(server_args)) {                              \
+      grpc_auth_metadata_processor processor = {process_auth_failure, NULL, \
+                                                NULL};                      \
+      grpc_server_credentials_set_auth_metadata_processor(ssl_creds,        \
+                                                          processor);       \
+    }                                                                       \
+    chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);         \
+  }
+
+SERVER_INIT(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
+SERVER_INIT(GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY);
+SERVER_INIT(GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY);
+SERVER_INIT(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY);
+SERVER_INIT(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
+
+#define CLIENT_INIT_NAME(cert_type) \
+  chttp2_init_client_simple_ssl_secure_fullstack_##cert_type
+
+typedef enum { NONE, SELF_SIGNED, SIGNED, BAD_CERT_PAIR } certtype;
+
+#define CLIENT_INIT(cert_type)                                               \
+  static void CLIENT_INIT_NAME(cert_type)(grpc_end2end_test_fixture * f,     \
+                                          grpc_channel_args * client_args) { \
+    grpc_channel_credentials *ssl_creds = NULL;                              \
+    grpc_ssl_pem_key_cert_pair self_signed_client_key_cert_pair = {          \
+        test_self_signed_client_key, test_self_signed_client_cert};          \
+    grpc_ssl_pem_key_cert_pair signed_client_key_cert_pair = {               \
+        test_signed_client_key, test_signed_client_cert};                    \
+    grpc_ssl_pem_key_cert_pair bad_client_key_cert_pair = {                  \
+        test_self_signed_client_key, test_signed_client_cert};               \
+    grpc_ssl_pem_key_cert_pair *key_cert_pair = NULL;                        \
+    switch (cert_type) {                                                     \
+      case SELF_SIGNED:                                                      \
+        key_cert_pair = &self_signed_client_key_cert_pair;                   \
+        break;                                                               \
+      case SIGNED:                                                           \
+        key_cert_pair = &signed_client_key_cert_pair;                        \
+        break;                                                               \
+      case BAD_CERT_PAIR:                                                    \
+        key_cert_pair = &bad_client_key_cert_pair;                           \
+        break;                                                               \
+      default:                                                               \
+        break;                                                               \
+    }                                                                        \
+    ssl_creds =                                                              \
+        grpc_ssl_credentials_create(test_root_cert, key_cert_pair, NULL);    \
+    grpc_arg ssl_name_override = {GRPC_ARG_STRING,                           \
+                                  GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,         \
+                                  {"foo.test.google.fr"}};                   \
+    grpc_channel_args *new_client_args =                                     \
+        grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);  \
+    chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);      \
+    grpc_channel_args_destroy(new_client_args);                              \
+  }
+
+CLIENT_INIT(NONE);
+CLIENT_INIT(SELF_SIGNED);
+CLIENT_INIT(SIGNED);
+CLIENT_INIT(BAD_CERT_PAIR);
+
+#define TEST_NAME(enum_name, cert_type, result) \
+  "chttp2/ssl_" #enum_name "_" #cert_type "_" #result "_"
+
+typedef enum { SUCCESS, FAIL } test_result;
+
+#define SSL_TEST(request_type, cert_type, result)                         \
+  {                                                                       \
+    {TEST_NAME(request_type, cert_type, result),                          \
+     FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |                           \
+         FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,                      \
+     chttp2_create_fixture_secure_fullstack, CLIENT_INIT_NAME(cert_type), \
+     SERVER_INIT_NAME(request_type), chttp2_tear_down_secure_fullstack},  \
+        result                                                            \
+  }
+
+/* All test configurations */
+typedef struct grpc_end2end_test_config_wrapper {
+  grpc_end2end_test_config config;
+  test_result result;
+} grpc_end2end_test_config_wrapper;
+
+static grpc_end2end_test_config_wrapper configs[] = {
+    SSL_TEST(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, NONE, SUCCESS),
+    SSL_TEST(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, SELF_SIGNED, SUCCESS),
+    SSL_TEST(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, SIGNED, SUCCESS),
+    SSL_TEST(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, BAD_CERT_PAIR, FAIL),
+
+    SSL_TEST(GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, NONE,
+             SUCCESS),
+    SSL_TEST(GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, SELF_SIGNED,
+             SUCCESS),
+    SSL_TEST(GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, SIGNED,
+             SUCCESS),
+    SSL_TEST(GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, BAD_CERT_PAIR,
+             FAIL),
+
+    SSL_TEST(GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, NONE, SUCCESS),
+    SSL_TEST(GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, SELF_SIGNED, FAIL),
+    SSL_TEST(GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, SIGNED, SUCCESS),
+    SSL_TEST(GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, BAD_CERT_PAIR,
+             FAIL),
+
+    SSL_TEST(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY,
+             NONE, FAIL),
+    SSL_TEST(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY,
+             SELF_SIGNED, SUCCESS),
+    SSL_TEST(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY,
+             SIGNED, SUCCESS),
+    SSL_TEST(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY,
+             BAD_CERT_PAIR, FAIL),
+
+    SSL_TEST(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY, NONE,
+             FAIL),
+    SSL_TEST(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY,
+             SELF_SIGNED, FAIL),
+    SSL_TEST(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY, SIGNED,
+             SUCCESS),
+    SSL_TEST(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY,
+             BAD_CERT_PAIR, FAIL),
+};
+
+static void *tag(intptr_t t) { return (void *)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+                                            const char *test_name,
+                                            grpc_channel_args *client_args,
+                                            grpc_channel_args *server_args) {
+  grpc_end2end_test_fixture f;
+  gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
+  f = config.create_fixture(client_args, server_args);
+  config.init_server(&f, server_args);
+  config.init_client(&f, client_args);
+  return f;
+}
+
+static gpr_timespec n_seconds_time(int n) {
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
+}
+
+static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+
+static void drain_cq(grpc_completion_queue *cq) {
+  grpc_event ev;
+  do {
+    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture *f) {
+  if (!f->server) return;
+  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(
+                 f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL)
+                 .type == GRPC_OP_COMPLETE);
+  grpc_server_destroy(f->server);
+  f->server = NULL;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture *f) {
+  if (!f->client) return;
+  grpc_channel_destroy(f->client);
+  f->client = NULL;
+}
+
+static void end_test(grpc_end2end_test_fixture *f) {
+  shutdown_server(f);
+  shutdown_client(f);
+
+  grpc_completion_queue_shutdown(f->cq);
+  drain_cq(f->cq);
+  grpc_completion_queue_destroy(f->cq);
+}
+
+static void simple_request_body(grpc_end2end_test_fixture f,
+                                test_result expected_result) {
+  grpc_call *c;
+  gpr_timespec deadline = five_seconds_time();
+  cq_verifier *cqv = cq_verifier_create(f.cq);
+  grpc_op ops[6];
+  grpc_op *op;
+  grpc_call_error error;
+
+  c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+                               "/foo", "foo.test.google.fr:1234", deadline,
+                               NULL);
+  GPR_ASSERT(c);
+
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  cq_expect_completion(cqv, tag(1), expected_result == SUCCESS);
+  cq_verify(cqv);
+
+  grpc_call_destroy(c);
+  cq_verifier_destroy(cqv);
+}
+
+int main(int argc, char **argv) {
+  size_t i;
+  FILE *roots_file;
+  size_t roots_size = strlen(test_root_cert);
+  char *roots_filename;
+
+  grpc_test_init(argc, argv);
+  grpc_end2end_tests_pre_init();
+
+  /* Set the SSL roots env var. */
+  roots_file =
+      gpr_tmpfile("chttp2_simple_ssl_cert_fullstack_test", &roots_filename);
+  GPR_ASSERT(roots_filename != NULL);
+  GPR_ASSERT(roots_file != NULL);
+  GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
+  fclose(roots_file);
+  gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
+
+  grpc_init();
+
+  for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+    grpc_end2end_test_fixture f =
+        begin_test(configs[i].config, "SSL_CERT_tests", NULL, NULL);
+
+    simple_request_body(f, configs[i].result);
+    end_test(&f);
+    configs[i].config.tear_down_data(&f);
+  }
+
+  grpc_shutdown();
+
+  /* Cleanup. */
+  remove(roots_filename);
+  gpr_free(roots_filename);
+
+  return 0;
+}
diff --git a/test/core/end2end/fuzzers/client_fuzzer.c b/test/core/end2end/fuzzers/client_fuzzer.c
index 4e22e26..afcf763 100644
--- a/test/core/end2end/fuzzers/client_fuzzer.c
+++ b/test/core/end2end/fuzzers/client_fuzzer.c
@@ -36,6 +36,7 @@
 
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/surface/channel.h"
+#include "test/core/util/memory_counters.h"
 #include "test/core/util/mock_endpoint.h"
 
 static const bool squelch = true;
@@ -48,7 +49,9 @@
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   grpc_test_only_set_metadata_hash_seed(0);
+  struct grpc_memory_counters counters;
   if (squelch) gpr_set_log_function(dont_log);
+  grpc_memory_counters_init();
   grpc_init();
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
@@ -150,5 +153,8 @@
     grpc_byte_buffer_destroy(response_payload_recv);
   }
   grpc_shutdown();
+  counters = grpc_memory_counters_snapshot();
+  grpc_memory_counters_destroy();
+  GPR_ASSERT(counters.total_size_relative == 0);
   return 0;
 }
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/025215e11687c7d2e0055e5b2b902d08e0436f78 b/test/core/end2end/fuzzers/client_fuzzer_corpus/025215e11687c7d2e0055e5b2b902d08e0436f78
new file mode 100644
index 0000000..bd442b3
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/025215e11687c7d2e0055e5b2b902d08e0436f78
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/02ba99615d1d69eb328adce99670f659959c1bc1 b/test/core/end2end/fuzzers/client_fuzzer_corpus/02ba99615d1d69eb328adce99670f659959c1bc1
new file mode 100644
index 0000000..6eae44d
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/02ba99615d1d69eb328adce99670f659959c1bc1
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/07048654244e377ddf246e8cc18f71443035cd2b b/test/core/end2end/fuzzers/client_fuzzer_corpus/07048654244e377ddf246e8cc18f71443035cd2b
new file mode 100644
index 0000000..142efb7
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/07048654244e377ddf246e8cc18f71443035cd2b
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/0c30868720d5e1a19ff23c53740749c37a43540d b/test/core/end2end/fuzzers/client_fuzzer_corpus/0c30868720d5e1a19ff23c53740749c37a43540d
new file mode 100644
index 0000000..e5a32af
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/0c30868720d5e1a19ff23c53740749c37a43540d
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/0d8c547f1d261ba07c2648bae009636c17709600 b/test/core/end2end/fuzzers/client_fuzzer_corpus/0d8c547f1d261ba07c2648bae009636c17709600
new file mode 100644
index 0000000..07d6767
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/0d8c547f1d261ba07c2648bae009636c17709600
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/0f98d7d56e9a99b97e5dc7eb122ef22e9684077b b/test/core/end2end/fuzzers/client_fuzzer_corpus/0f98d7d56e9a99b97e5dc7eb122ef22e9684077b
new file mode 100644
index 0000000..3a55723
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/0f98d7d56e9a99b97e5dc7eb122ef22e9684077b
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/0fd8859246740606c498755ab00d6147abcfec00 b/test/core/end2end/fuzzers/client_fuzzer_corpus/0fd8859246740606c498755ab00d6147abcfec00
new file mode 100644
index 0000000..88c3f42
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/0fd8859246740606c498755ab00d6147abcfec00
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/101305ccd08c7a8bd0c2913c37d3dd0d39d4bb64 b/test/core/end2end/fuzzers/client_fuzzer_corpus/101305ccd08c7a8bd0c2913c37d3dd0d39d4bb64
new file mode 100644
index 0000000..b6e8b42
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/101305ccd08c7a8bd0c2913c37d3dd0d39d4bb64
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1160214cdb23e8fc187078a8d6796656c1ade925 b/test/core/end2end/fuzzers/client_fuzzer_corpus/1160214cdb23e8fc187078a8d6796656c1ade925
new file mode 100644
index 0000000..cad5f5a
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/1160214cdb23e8fc187078a8d6796656c1ade925
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/118ffddb43ccf9dae8bdb4702232d1dc39b021f7 b/test/core/end2end/fuzzers/client_fuzzer_corpus/118ffddb43ccf9dae8bdb4702232d1dc39b021f7
new file mode 100644
index 0000000..508f927
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/118ffddb43ccf9dae8bdb4702232d1dc39b021f7
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1306c4c6ea714d4db0e4d814c944d8d40335e0fa b/test/core/end2end/fuzzers/client_fuzzer_corpus/1306c4c6ea714d4db0e4d814c944d8d40335e0fa
new file mode 100644
index 0000000..02aaaf9
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/1306c4c6ea714d4db0e4d814c944d8d40335e0fa
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/143e0d4f546bbb984a7c3ac1c60a37dcf85ea58d b/test/core/end2end/fuzzers/client_fuzzer_corpus/143e0d4f546bbb984a7c3ac1c60a37dcf85ea58d
new file mode 100644
index 0000000..8150470
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/143e0d4f546bbb984a7c3ac1c60a37dcf85ea58d
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/17b1758fc7cd69a00d140f113b1ac894023ff20b b/test/core/end2end/fuzzers/client_fuzzer_corpus/17b1758fc7cd69a00d140f113b1ac894023ff20b
new file mode 100644
index 0000000..e9781cd
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/17b1758fc7cd69a00d140f113b1ac894023ff20b
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1875a4acdcffe505ca92ea8af8d9d6b174736e80 b/test/core/end2end/fuzzers/client_fuzzer_corpus/1875a4acdcffe505ca92ea8af8d9d6b174736e80
new file mode 100644
index 0000000..9c35e25
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/1875a4acdcffe505ca92ea8af8d9d6b174736e80
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1aee32faadffa3c2ec508e8fd30006423665488f b/test/core/end2end/fuzzers/client_fuzzer_corpus/1aee32faadffa3c2ec508e8fd30006423665488f
new file mode 100644
index 0000000..a70fff3
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/1aee32faadffa3c2ec508e8fd30006423665488f
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1ca51ab2fefef4f549c4a8e7f4910c6b5a4b4b1d b/test/core/end2end/fuzzers/client_fuzzer_corpus/1ca51ab2fefef4f549c4a8e7f4910c6b5a4b4b1d
new file mode 100644
index 0000000..5763104
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/1ca51ab2fefef4f549c4a8e7f4910c6b5a4b4b1d
@@ -0,0 +1 @@
+!më¢!ÿÿÿÿÿÿÿÂ…
\ No newline at end of file
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1dc86d0febe4adc5353230cea24b5f7cce829283 b/test/core/end2end/fuzzers/client_fuzzer_corpus/1dc86d0febe4adc5353230cea24b5f7cce829283
new file mode 100644
index 0000000..3ea63ff
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/1dc86d0febe4adc5353230cea24b5f7cce829283
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/1f040e756f76357979f317e0c6541f72fd93df06 b/test/core/end2end/fuzzers/client_fuzzer_corpus/1f040e756f76357979f317e0c6541f72fd93df06
new file mode 100644
index 0000000..0a2a1b3
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/1f040e756f76357979f317e0c6541f72fd93df06
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/20216d27af2b3dcc83d944e5f7a489ed2eff98fd b/test/core/end2end/fuzzers/client_fuzzer_corpus/20216d27af2b3dcc83d944e5f7a489ed2eff98fd
new file mode 100644
index 0000000..f79cdf2
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/20216d27af2b3dcc83d944e5f7a489ed2eff98fd
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/205cf2b6994f10b783aa0a06938a5e47cb581126 b/test/core/end2end/fuzzers/client_fuzzer_corpus/205cf2b6994f10b783aa0a06938a5e47cb581126
new file mode 100644
index 0000000..eafa9e1
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/205cf2b6994f10b783aa0a06938a5e47cb581126
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/2166c7093c424a2136c4cb8b10d0b124047320d4 b/test/core/end2end/fuzzers/client_fuzzer_corpus/2166c7093c424a2136c4cb8b10d0b124047320d4
new file mode 100644
index 0000000..96ca5f7
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/2166c7093c424a2136c4cb8b10d0b124047320d4
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/2467fa0f8a9f4bd121f544892f0782498b2df533 b/test/core/end2end/fuzzers/client_fuzzer_corpus/2467fa0f8a9f4bd121f544892f0782498b2df533
new file mode 100644
index 0000000..0ee6efa
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/2467fa0f8a9f4bd121f544892f0782498b2df533
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/246dcf347eba7f4d4e04d97dabc002f0acf2164e b/test/core/end2end/fuzzers/client_fuzzer_corpus/246dcf347eba7f4d4e04d97dabc002f0acf2164e
new file mode 100644
index 0000000..eb01953
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/246dcf347eba7f4d4e04d97dabc002f0acf2164e
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/26110f21dcb0fde99942e631366ebbd9d895860d b/test/core/end2end/fuzzers/client_fuzzer_corpus/26110f21dcb0fde99942e631366ebbd9d895860d
new file mode 100644
index 0000000..ffa8aca
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/26110f21dcb0fde99942e631366ebbd9d895860d
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/28ee8cae75efa07da9649933a9482d00643b5395 b/test/core/end2end/fuzzers/client_fuzzer_corpus/28ee8cae75efa07da9649933a9482d00643b5395
new file mode 100644
index 0000000..66a1990
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/28ee8cae75efa07da9649933a9482d00643b5395
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/29be7d33920998bae7329d77d4c81989eae91647 b/test/core/end2end/fuzzers/client_fuzzer_corpus/29be7d33920998bae7329d77d4c81989eae91647
new file mode 100644
index 0000000..73ca084
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/29be7d33920998bae7329d77d4c81989eae91647
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/2dce4a1fc4bb00bfcd43d549a3785913c9280369 b/test/core/end2end/fuzzers/client_fuzzer_corpus/2dce4a1fc4bb00bfcd43d549a3785913c9280369
new file mode 100644
index 0000000..e113d82
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/2dce4a1fc4bb00bfcd43d549a3785913c9280369
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/31545e9fe4c6aa43329dc0d4a735842574fcaaed b/test/core/end2end/fuzzers/client_fuzzer_corpus/31545e9fe4c6aa43329dc0d4a735842574fcaaed
new file mode 100644
index 0000000..a505a18
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/31545e9fe4c6aa43329dc0d4a735842574fcaaed
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/3336748264594689041e4080b51bc56f716d0689 b/test/core/end2end/fuzzers/client_fuzzer_corpus/3336748264594689041e4080b51bc56f716d0689
new file mode 100644
index 0000000..d3eb5f7
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/3336748264594689041e4080b51bc56f716d0689
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/361c6f4374443671f039fd9659577e4460178020 b/test/core/end2end/fuzzers/client_fuzzer_corpus/361c6f4374443671f039fd9659577e4460178020
new file mode 100644
index 0000000..392bf57
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/361c6f4374443671f039fd9659577e4460178020
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/375c2462d6ae891222686f9519294811fa5de010 b/test/core/end2end/fuzzers/client_fuzzer_corpus/375c2462d6ae891222686f9519294811fa5de010
new file mode 100644
index 0000000..ae1b3af
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/375c2462d6ae891222686f9519294811fa5de010
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/42c395ab373346fb283ace021bdc1f6428f92f80 b/test/core/end2end/fuzzers/client_fuzzer_corpus/42c395ab373346fb283ace021bdc1f6428f92f80
new file mode 100644
index 0000000..35e2498
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/42c395ab373346fb283ace021bdc1f6428f92f80
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/4a4553c2e939cd50981bc38e8ddb1f2109ddb3a4 b/test/core/end2end/fuzzers/client_fuzzer_corpus/4a4553c2e939cd50981bc38e8ddb1f2109ddb3a4
new file mode 100644
index 0000000..ba96c64
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/4a4553c2e939cd50981bc38e8ddb1f2109ddb3a4
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/4b585eb75ebca2187c0aa5a6abe4c8125aa80127 b/test/core/end2end/fuzzers/client_fuzzer_corpus/4b585eb75ebca2187c0aa5a6abe4c8125aa80127
new file mode 100644
index 0000000..13a67df
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/4b585eb75ebca2187c0aa5a6abe4c8125aa80127
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/4f5b9d5c707a35084918c272efd1295d301ca0b5 b/test/core/end2end/fuzzers/client_fuzzer_corpus/4f5b9d5c707a35084918c272efd1295d301ca0b5
new file mode 100644
index 0000000..bf8cfc2
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/4f5b9d5c707a35084918c272efd1295d301ca0b5
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/50ece7ea16659b4e1a2284cea963fab662c19e6b b/test/core/end2end/fuzzers/client_fuzzer_corpus/50ece7ea16659b4e1a2284cea963fab662c19e6b
new file mode 100644
index 0000000..a70c07e
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/50ece7ea16659b4e1a2284cea963fab662c19e6b
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/51c6c5297acebf9d21a8a7d6261d0a17c2adfb56 b/test/core/end2end/fuzzers/client_fuzzer_corpus/51c6c5297acebf9d21a8a7d6261d0a17c2adfb56
new file mode 100644
index 0000000..efb8e23
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/51c6c5297acebf9d21a8a7d6261d0a17c2adfb56
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/534c900ade27c8f7fccb1f3b7e7703f77f13a8f5 b/test/core/end2end/fuzzers/client_fuzzer_corpus/534c900ade27c8f7fccb1f3b7e7703f77f13a8f5
new file mode 100644
index 0000000..2fc38ec
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/534c900ade27c8f7fccb1f3b7e7703f77f13a8f5
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/5482dc4af170def9c183315efaa48f9c186926a1 b/test/core/end2end/fuzzers/client_fuzzer_corpus/5482dc4af170def9c183315efaa48f9c186926a1
new file mode 100644
index 0000000..f6b3c8c
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/5482dc4af170def9c183315efaa48f9c186926a1
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/57ee6efc38f4c544a3ea3e5e73987e825bdf2980 b/test/core/end2end/fuzzers/client_fuzzer_corpus/57ee6efc38f4c544a3ea3e5e73987e825bdf2980
new file mode 100644
index 0000000..44854ee
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/57ee6efc38f4c544a3ea3e5e73987e825bdf2980
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/59d78f6397f0483d139f5bd0a9f264156f34acc4 b/test/core/end2end/fuzzers/client_fuzzer_corpus/59d78f6397f0483d139f5bd0a9f264156f34acc4
new file mode 100644
index 0000000..dafd670
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/59d78f6397f0483d139f5bd0a9f264156f34acc4
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/5a2447fdfdbf123f4592c1284007b7d50a01750b b/test/core/end2end/fuzzers/client_fuzzer_corpus/5a2447fdfdbf123f4592c1284007b7d50a01750b
new file mode 100644
index 0000000..2089c49
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/5a2447fdfdbf123f4592c1284007b7d50a01750b
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/5ca233a53e3e425cc12e04b466a49789291eaa00 b/test/core/end2end/fuzzers/client_fuzzer_corpus/5ca233a53e3e425cc12e04b466a49789291eaa00
new file mode 100644
index 0000000..2040605
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/5ca233a53e3e425cc12e04b466a49789291eaa00
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/5dc7b2086a39f56d8b9135f524d34a01fcabafd8 b/test/core/end2end/fuzzers/client_fuzzer_corpus/5dc7b2086a39f56d8b9135f524d34a01fcabafd8
new file mode 100644
index 0000000..ba7eec5
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/5dc7b2086a39f56d8b9135f524d34a01fcabafd8
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/605e474e9d9436488dfe084d348908e4dfab81a3 b/test/core/end2end/fuzzers/client_fuzzer_corpus/605e474e9d9436488dfe084d348908e4dfab81a3
new file mode 100644
index 0000000..d561e86
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/605e474e9d9436488dfe084d348908e4dfab81a3
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/611343a6b8879b393ba2f38ed41c7f5355355920 b/test/core/end2end/fuzzers/client_fuzzer_corpus/611343a6b8879b393ba2f38ed41c7f5355355920
new file mode 100644
index 0000000..3c9af3d
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/611343a6b8879b393ba2f38ed41c7f5355355920
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/636a19b8f50c4efccccea83ab78a933d999e41fa b/test/core/end2end/fuzzers/client_fuzzer_corpus/636a19b8f50c4efccccea83ab78a933d999e41fa
new file mode 100644
index 0000000..948b362
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/636a19b8f50c4efccccea83ab78a933d999e41fa
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/64c0e0b4d9c2d25fdcb1e2bdcb999487fc096dad b/test/core/end2end/fuzzers/client_fuzzer_corpus/64c0e0b4d9c2d25fdcb1e2bdcb999487fc096dad
new file mode 100644
index 0000000..741e688
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/64c0e0b4d9c2d25fdcb1e2bdcb999487fc096dad
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/64d27dc9f984c49d421a5b0cb0391992d5aac1a4 b/test/core/end2end/fuzzers/client_fuzzer_corpus/64d27dc9f984c49d421a5b0cb0391992d5aac1a4
new file mode 100644
index 0000000..f57336b
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/64d27dc9f984c49d421a5b0cb0391992d5aac1a4
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/653ec14661c40ea25bdbab4a7cb9371c669d10d9 b/test/core/end2end/fuzzers/client_fuzzer_corpus/653ec14661c40ea25bdbab4a7cb9371c669d10d9
new file mode 100644
index 0000000..1f963c2
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/653ec14661c40ea25bdbab4a7cb9371c669d10d9
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/6749752b02f7d14fff9ac35f6b68dd62f5b49fcd b/test/core/end2end/fuzzers/client_fuzzer_corpus/6749752b02f7d14fff9ac35f6b68dd62f5b49fcd
new file mode 100644
index 0000000..54b13f2
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/6749752b02f7d14fff9ac35f6b68dd62f5b49fcd
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/6bfd3679f4e30aaaa1808e96c980edcfa9cac1c0 b/test/core/end2end/fuzzers/client_fuzzer_corpus/6bfd3679f4e30aaaa1808e96c980edcfa9cac1c0
new file mode 100644
index 0000000..928473a
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/6bfd3679f4e30aaaa1808e96c980edcfa9cac1c0
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/6e71553967212dfea2c9995f3641e582d8c2105b b/test/core/end2end/fuzzers/client_fuzzer_corpus/6e71553967212dfea2c9995f3641e582d8c2105b
new file mode 100644
index 0000000..53641b3
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/6e71553967212dfea2c9995f3641e582d8c2105b
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/759a1e2e34cad14321a5e5790b1e6a783312fea1 b/test/core/end2end/fuzzers/client_fuzzer_corpus/759a1e2e34cad14321a5e5790b1e6a783312fea1
new file mode 100644
index 0000000..ebb0726
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/759a1e2e34cad14321a5e5790b1e6a783312fea1
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/7885df741c88ca4b539798d9985c445f41cc2929 b/test/core/end2end/fuzzers/client_fuzzer_corpus/7885df741c88ca4b539798d9985c445f41cc2929
new file mode 100644
index 0000000..1a40080
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/7885df741c88ca4b539798d9985c445f41cc2929
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/7af41e5391204f4596cb1461792e2e23f9390b7b b/test/core/end2end/fuzzers/client_fuzzer_corpus/7af41e5391204f4596cb1461792e2e23f9390b7b
new file mode 100644
index 0000000..898709a
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/7af41e5391204f4596cb1461792e2e23f9390b7b
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/807b8c4ca068cff4bc0fc8e854c1215a2fe65960 b/test/core/end2end/fuzzers/client_fuzzer_corpus/807b8c4ca068cff4bc0fc8e854c1215a2fe65960
new file mode 100644
index 0000000..a577c53
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/807b8c4ca068cff4bc0fc8e854c1215a2fe65960
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/813d2c34c0df8d4a918e68e58cf0ae3703d0d46f b/test/core/end2end/fuzzers/client_fuzzer_corpus/813d2c34c0df8d4a918e68e58cf0ae3703d0d46f
new file mode 100644
index 0000000..20b84c0
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/813d2c34c0df8d4a918e68e58cf0ae3703d0d46f
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/831248cea079b629bf0ef6d9d02c159d6f8ed41b b/test/core/end2end/fuzzers/client_fuzzer_corpus/831248cea079b629bf0ef6d9d02c159d6f8ed41b
new file mode 100644
index 0000000..4bf2f2b
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/831248cea079b629bf0ef6d9d02c159d6f8ed41b
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/850c639595eae3cc9c2cfef473e28fd4e8174dc8 b/test/core/end2end/fuzzers/client_fuzzer_corpus/850c639595eae3cc9c2cfef473e28fd4e8174dc8
new file mode 100644
index 0000000..9677158
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/850c639595eae3cc9c2cfef473e28fd4e8174dc8
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/8bacacba71bfa5c74fd74cb6577a49a7aec9cf1f b/test/core/end2end/fuzzers/client_fuzzer_corpus/8bacacba71bfa5c74fd74cb6577a49a7aec9cf1f
new file mode 100644
index 0000000..852d4d6
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/8bacacba71bfa5c74fd74cb6577a49a7aec9cf1f
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/90a9c3390752b94ca19a58cb2fe6267bc818f718 b/test/core/end2end/fuzzers/client_fuzzer_corpus/90a9c3390752b94ca19a58cb2fe6267bc818f718
new file mode 100644
index 0000000..19d7c4a
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/90a9c3390752b94ca19a58cb2fe6267bc818f718
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/9552c3f6304af40224b800f3a3a5df3887a530f6 b/test/core/end2end/fuzzers/client_fuzzer_corpus/9552c3f6304af40224b800f3a3a5df3887a530f6
new file mode 100644
index 0000000..0db7584
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/9552c3f6304af40224b800f3a3a5df3887a530f6
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/96e5126447131d3d59cc6547f6b91d3433ce37c8 b/test/core/end2end/fuzzers/client_fuzzer_corpus/96e5126447131d3d59cc6547f6b91d3433ce37c8
new file mode 100644
index 0000000..90f80d8
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/96e5126447131d3d59cc6547f6b91d3433ce37c8
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/98dddd3f679af150e9933bd864ae20e20b7aa25a b/test/core/end2end/fuzzers/client_fuzzer_corpus/98dddd3f679af150e9933bd864ae20e20b7aa25a
new file mode 100644
index 0000000..bea145a
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/98dddd3f679af150e9933bd864ae20e20b7aa25a
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/9a4da2a37a26c114e1226bfbe1cf80ec5ca99a66 b/test/core/end2end/fuzzers/client_fuzzer_corpus/9a4da2a37a26c114e1226bfbe1cf80ec5ca99a66
new file mode 100644
index 0000000..f07452e
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/9a4da2a37a26c114e1226bfbe1cf80ec5ca99a66
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/9b1355c6e2c43ce83001bbead09a79852e04feef b/test/core/end2end/fuzzers/client_fuzzer_corpus/9b1355c6e2c43ce83001bbead09a79852e04feef
new file mode 100644
index 0000000..27c512e
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/9b1355c6e2c43ce83001bbead09a79852e04feef
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/9d362d2aaeee243a5b54621d8187c4b16f87c9f5 b/test/core/end2end/fuzzers/client_fuzzer_corpus/9d362d2aaeee243a5b54621d8187c4b16f87c9f5
new file mode 100644
index 0000000..affe61a
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/9d362d2aaeee243a5b54621d8187c4b16f87c9f5
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/9dfdce1b090a559a14f9a5852f78547413b1d1ed b/test/core/end2end/fuzzers/client_fuzzer_corpus/9dfdce1b090a559a14f9a5852f78547413b1d1ed
new file mode 100644
index 0000000..7b32fee
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/9dfdce1b090a559a14f9a5852f78547413b1d1ed
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/9f0ab521c728be21e93112b2730c52bc1d6c0021 b/test/core/end2end/fuzzers/client_fuzzer_corpus/9f0ab521c728be21e93112b2730c52bc1d6c0021
new file mode 100644
index 0000000..bd1364c
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/9f0ab521c728be21e93112b2730c52bc1d6c0021
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/a30fc2605f4e74f7003f902ea4a4c994e3ce9bfd b/test/core/end2end/fuzzers/client_fuzzer_corpus/a30fc2605f4e74f7003f902ea4a4c994e3ce9bfd
new file mode 100644
index 0000000..47cea8e
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/a30fc2605f4e74f7003f902ea4a4c994e3ce9bfd
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/a3cd54d43d3b3bdfcf224d636dc11ce1b5ee4d30 b/test/core/end2end/fuzzers/client_fuzzer_corpus/a3cd54d43d3b3bdfcf224d636dc11ce1b5ee4d30
new file mode 100644
index 0000000..19ca739
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/a3cd54d43d3b3bdfcf224d636dc11ce1b5ee4d30
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/a706f2067bfbda7837eaad68972d60547e2957c3 b/test/core/end2end/fuzzers/client_fuzzer_corpus/a706f2067bfbda7837eaad68972d60547e2957c3
new file mode 100644
index 0000000..cf67f80
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/a706f2067bfbda7837eaad68972d60547e2957c3
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/a8e67676784506d2e6eab3a0dfa25e53a80b40a0 b/test/core/end2end/fuzzers/client_fuzzer_corpus/a8e67676784506d2e6eab3a0dfa25e53a80b40a0
new file mode 100644
index 0000000..24dc2db
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/a8e67676784506d2e6eab3a0dfa25e53a80b40a0
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/ade2d2f0e120a9527487e9b92458ee6844800e4e b/test/core/end2end/fuzzers/client_fuzzer_corpus/ade2d2f0e120a9527487e9b92458ee6844800e4e
new file mode 100644
index 0000000..d533eec
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/ade2d2f0e120a9527487e9b92458ee6844800e4e
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/af8b24ffaecdfaf96c0cd7c76f31dc9e1b4d0935 b/test/core/end2end/fuzzers/client_fuzzer_corpus/af8b24ffaecdfaf96c0cd7c76f31dc9e1b4d0935
new file mode 100644
index 0000000..eb20913
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/af8b24ffaecdfaf96c0cd7c76f31dc9e1b4d0935
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/b09f98e13e5b67a4dd7f74eff00bb247b9967844 b/test/core/end2end/fuzzers/client_fuzzer_corpus/b09f98e13e5b67a4dd7f74eff00bb247b9967844
new file mode 100644
index 0000000..5f2c006
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/b09f98e13e5b67a4dd7f74eff00bb247b9967844
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/b3f33b78433af7f607bc99b569b0cef95a1a6ca0 b/test/core/end2end/fuzzers/client_fuzzer_corpus/b3f33b78433af7f607bc99b569b0cef95a1a6ca0
new file mode 100644
index 0000000..e27af01
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/b3f33b78433af7f607bc99b569b0cef95a1a6ca0
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/ba942f8fb244b60561a067129c242c4bc4fdd5e1 b/test/core/end2end/fuzzers/client_fuzzer_corpus/ba942f8fb244b60561a067129c242c4bc4fdd5e1
new file mode 100644
index 0000000..4ed0662
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/ba942f8fb244b60561a067129c242c4bc4fdd5e1
@@ -0,0 +1 @@
+!mã!mm‘•N!‘‘NÿN'‘!)‘‘ÿÿÿÿÿNNÿÿÿ
\ No newline at end of file
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/baf7839388e10ff0c410a58797482cb83693b309 b/test/core/end2end/fuzzers/client_fuzzer_corpus/baf7839388e10ff0c410a58797482cb83693b309
new file mode 100644
index 0000000..5f51d62
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/baf7839388e10ff0c410a58797482cb83693b309
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/bc9e17fed43c5d0668a87e8d6354c344c5b4d00b b/test/core/end2end/fuzzers/client_fuzzer_corpus/bc9e17fed43c5d0668a87e8d6354c344c5b4d00b
new file mode 100644
index 0000000..2a279d9
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/bc9e17fed43c5d0668a87e8d6354c344c5b4d00b
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/c5d0c169d326d79fc4ee8521b282dbcbf33c1d5c b/test/core/end2end/fuzzers/client_fuzzer_corpus/c5d0c169d326d79fc4ee8521b282dbcbf33c1d5c
new file mode 100644
index 0000000..454fec8
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/c5d0c169d326d79fc4ee8521b282dbcbf33c1d5c
@@ -0,0 +1 @@
+!mm‘•N!‘‘N)ÿN'‘)‘‘NN
\ No newline at end of file
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/c685689a9d5b259afe237d857b7c6551dc95c176 b/test/core/end2end/fuzzers/client_fuzzer_corpus/c685689a9d5b259afe237d857b7c6551dc95c176
new file mode 100644
index 0000000..763b8dc
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/c685689a9d5b259afe237d857b7c6551dc95c176
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/c784ad2e205ba49b5bb1302746723dbc57320981 b/test/core/end2end/fuzzers/client_fuzzer_corpus/c784ad2e205ba49b5bb1302746723dbc57320981
new file mode 100644
index 0000000..3efda68
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/c784ad2e205ba49b5bb1302746723dbc57320981
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/cd4be18b1ae872c40580edc4fe8cbdf1fe2a3881 b/test/core/end2end/fuzzers/client_fuzzer_corpus/cd4be18b1ae872c40580edc4fe8cbdf1fe2a3881
new file mode 100644
index 0000000..70f2517
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/cd4be18b1ae872c40580edc4fe8cbdf1fe2a3881
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/ce990633c0f2b2a2ddb66144ed942d4bc9bcd8fb b/test/core/end2end/fuzzers/client_fuzzer_corpus/ce990633c0f2b2a2ddb66144ed942d4bc9bcd8fb
new file mode 100644
index 0000000..a2bab7f
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/ce990633c0f2b2a2ddb66144ed942d4bc9bcd8fb
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-8e546795782dffa5d5f5e94c9510aac178fcee39 b/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-8e546795782dffa5d5f5e94c9510aac178fcee39
new file mode 100644
index 0000000..53d6fd7
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/crash-8e546795782dffa5d5f5e94c9510aac178fcee39
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/d257c41db22b60cd937de16b9d90a44b9fa8e426 b/test/core/end2end/fuzzers/client_fuzzer_corpus/d257c41db22b60cd937de16b9d90a44b9fa8e426
new file mode 100644
index 0000000..975530c
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/d257c41db22b60cd937de16b9d90a44b9fa8e426
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/d727b7edb460c549d7b12b90f581048c9f4747e5 b/test/core/end2end/fuzzers/client_fuzzer_corpus/d727b7edb460c549d7b12b90f581048c9f4747e5
new file mode 100644
index 0000000..ce30807
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/d727b7edb460c549d7b12b90f581048c9f4747e5
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/d90c312791129dee8c5f85cb3308323d0c39b70d b/test/core/end2end/fuzzers/client_fuzzer_corpus/d90c312791129dee8c5f85cb3308323d0c39b70d
new file mode 100644
index 0000000..9ac4841
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/d90c312791129dee8c5f85cb3308323d0c39b70d
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/d91281daad9b821294db204dfc244b2d0d5496e4 b/test/core/end2end/fuzzers/client_fuzzer_corpus/d91281daad9b821294db204dfc244b2d0d5496e4
new file mode 100644
index 0000000..b802985
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/d91281daad9b821294db204dfc244b2d0d5496e4
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/da322a6b88da87babb52d1527fe54cb4ac214b32 b/test/core/end2end/fuzzers/client_fuzzer_corpus/da322a6b88da87babb52d1527fe54cb4ac214b32
new file mode 100644
index 0000000..5325844
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/da322a6b88da87babb52d1527fe54cb4ac214b32
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/dc815fd6d5e817898238481472f359bc50b510c4 b/test/core/end2end/fuzzers/client_fuzzer_corpus/dc815fd6d5e817898238481472f359bc50b510c4
new file mode 100644
index 0000000..0bee6ac
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/dc815fd6d5e817898238481472f359bc50b510c4
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/dccd1fd6d3394f5f68c87950ed7356a2e9ef0f6f b/test/core/end2end/fuzzers/client_fuzzer_corpus/dccd1fd6d3394f5f68c87950ed7356a2e9ef0f6f
new file mode 100644
index 0000000..9d01cd1
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/dccd1fd6d3394f5f68c87950ed7356a2e9ef0f6f
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/dd662353bad317cee7d16191a39e094bfa4898f2 b/test/core/end2end/fuzzers/client_fuzzer_corpus/dd662353bad317cee7d16191a39e094bfa4898f2
new file mode 100644
index 0000000..2683cbb
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/dd662353bad317cee7d16191a39e094bfa4898f2
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/e0d1ee5e2e169dcae87f790f5c27e84a3453cedb b/test/core/end2end/fuzzers/client_fuzzer_corpus/e0d1ee5e2e169dcae87f790f5c27e84a3453cedb
new file mode 100644
index 0000000..0be99ff
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/e0d1ee5e2e169dcae87f790f5c27e84a3453cedb
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/e309e21c69e4b96ab37f675f4e87a52453512ef8 b/test/core/end2end/fuzzers/client_fuzzer_corpus/e309e21c69e4b96ab37f675f4e87a52453512ef8
new file mode 100644
index 0000000..3e856ee
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/e309e21c69e4b96ab37f675f4e87a52453512ef8
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/e3422e8f5d63a9ef180aab552353955c7aba90b0 b/test/core/end2end/fuzzers/client_fuzzer_corpus/e3422e8f5d63a9ef180aab552353955c7aba90b0
new file mode 100644
index 0000000..56efea5
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/e3422e8f5d63a9ef180aab552353955c7aba90b0
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/e442f9fd63bc5345de1c14803d4ca4bb6f1152cf b/test/core/end2end/fuzzers/client_fuzzer_corpus/e442f9fd63bc5345de1c14803d4ca4bb6f1152cf
new file mode 100644
index 0000000..4a6060c
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/e442f9fd63bc5345de1c14803d4ca4bb6f1152cf
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/e4c0e27cfd3690b8255a8214d6dd055385d1d24e b/test/core/end2end/fuzzers/client_fuzzer_corpus/e4c0e27cfd3690b8255a8214d6dd055385d1d24e
new file mode 100644
index 0000000..3b67734
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/e4c0e27cfd3690b8255a8214d6dd055385d1d24e
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/e5a7c086208248a15ee6fa5195fc4ce22469de15 b/test/core/end2end/fuzzers/client_fuzzer_corpus/e5a7c086208248a15ee6fa5195fc4ce22469de15
new file mode 100644
index 0000000..00dd612
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/e5a7c086208248a15ee6fa5195fc4ce22469de15
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/e7c26599fb2e2b031346ff1ba09294fd758f7abe b/test/core/end2end/fuzzers/client_fuzzer_corpus/e7c26599fb2e2b031346ff1ba09294fd758f7abe
new file mode 100644
index 0000000..fc1dec3
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/e7c26599fb2e2b031346ff1ba09294fd758f7abe
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/ec180175f0edea0a6c3eea2ae719b006bc029ff8 b/test/core/end2end/fuzzers/client_fuzzer_corpus/ec180175f0edea0a6c3eea2ae719b006bc029ff8
new file mode 100644
index 0000000..8655cae
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/ec180175f0edea0a6c3eea2ae719b006bc029ff8
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/ed6358fbe6721c9ac01a6f4cab4d2df377eb1f11 b/test/core/end2end/fuzzers/client_fuzzer_corpus/ed6358fbe6721c9ac01a6f4cab4d2df377eb1f11
new file mode 100644
index 0000000..1c4e252
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/ed6358fbe6721c9ac01a6f4cab4d2df377eb1f11
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/ee436743977b8e31feec22a91b1ce23dee96665e b/test/core/end2end/fuzzers/client_fuzzer_corpus/ee436743977b8e31feec22a91b1ce23dee96665e
new file mode 100644
index 0000000..94abe36
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/ee436743977b8e31feec22a91b1ce23dee96665e
@@ -0,0 +1 @@
+!mã!ÿÿÿÿÿÿÿÿÂŒ
\ No newline at end of file
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f4499e3d4bf60ae3ae929c485a13ea4dc2713369 b/test/core/end2end/fuzzers/client_fuzzer_corpus/f4499e3d4bf60ae3ae929c485a13ea4dc2713369
new file mode 100644
index 0000000..0a9bf7c
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/f4499e3d4bf60ae3ae929c485a13ea4dc2713369
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f8467d9574de94b9bb904f75a6a7e2405c36f105 b/test/core/end2end/fuzzers/client_fuzzer_corpus/f8467d9574de94b9bb904f75a6a7e2405c36f105
new file mode 100644
index 0000000..a8a8292
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/f8467d9574de94b9bb904f75a6a7e2405c36f105
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f84f5d6188cf099465f0b70337b87ad8aa8efb78 b/test/core/end2end/fuzzers/client_fuzzer_corpus/f84f5d6188cf099465f0b70337b87ad8aa8efb78
new file mode 100644
index 0000000..bc36c65
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/f84f5d6188cf099465f0b70337b87ad8aa8efb78
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/f9c875c00b7327df5bf21c3e051b55b0d2ed3cc8 b/test/core/end2end/fuzzers/client_fuzzer_corpus/f9c875c00b7327df5bf21c3e051b55b0d2ed3cc8
new file mode 100644
index 0000000..b89a2b4
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/f9c875c00b7327df5bf21c3e051b55b0d2ed3cc8
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/fe1390762579b5c335bbdea73e251b95b979c3c9 b/test/core/end2end/fuzzers/client_fuzzer_corpus/fe1390762579b5c335bbdea73e251b95b979c3c9
new file mode 100644
index 0000000..7fe5a73
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/fe1390762579b5c335bbdea73e251b95b979c3c9
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/fecccfc70b1cf1a524b9f28a9ba2c153c8e14d0e b/test/core/end2end/fuzzers/client_fuzzer_corpus/fecccfc70b1cf1a524b9f28a9ba2c153c8e14d0e
new file mode 100644
index 0000000..4378c8e
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/fecccfc70b1cf1a524b9f28a9ba2c153c8e14d0e
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/fef80aa34c31700ac8e53bede4a97131176ceef0 b/test/core/end2end/fuzzers/client_fuzzer_corpus/fef80aa34c31700ac8e53bede4a97131176ceef0
new file mode 100644
index 0000000..db02dd6
--- /dev/null
+++ b/test/core/end2end/fuzzers/client_fuzzer_corpus/fef80aa34c31700ac8e53bede4a97131176ceef0
Binary files differ
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
new file mode 100644
index 0000000..b081368
--- /dev/null
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -0,0 +1,170 @@
+# hpack fuzzing dictionary
+"\x010"
+"\x011"
+"\x012"
+"\x03200"
+"\x03204"
+"\x03206"
+"\x03304"
+"\x03400"
+"\x03404"
+"\x03500"
+"\x06accept"
+"\x0Eaccept-charset"
+"\x0Faccept-encoding"
+"\x0Faccept-language"
+"\x0Daccept-ranges"
+"\x1Baccess-control-allow-origin"
+"\x03age"
+"\x05allow"
+"\x10application/grpc"
+"\x0A:authority"
+"\x0Dauthorization"
+"\x0Dcache-control"
+"\x0Acensus-bin"
+"\x11census-binary-bin"
+"\x13content-disposition"
+"\x10content-encoding"
+"\x10content-language"
+"\x0Econtent-length"
+"\x10content-location"
+"\x0Dcontent-range"
+"\x0Ccontent-type"
+"\x06cookie"
+"\x04date"
+"\x07deflate"
+"\x0Cdeflate,gzip"
+"\x00"
+"\x04etag"
+"\x06expect"
+"\x07expires"
+"\x04from"
+"\x03GET"
+"\x04grpc"
+"\x14grpc-accept-encoding"
+"\x0Dgrpc-encoding"
+"\x1Egrpc-internal-encoding-request"
+"\x0Cgrpc-message"
+"\x0Bgrpc-status"
+"\x0Cgrpc-timeout"
+"\x04gzip"
+"\x0Dgzip, deflate"
+"\x04host"
+"\x04http"
+"\x05https"
+"\x08identity"
+"\x10identity,deflate"
+"\x15identity,deflate,gzip"
+"\x0Didentity,gzip"
+"\x08if-match"
+"\x11if-modified-since"
+"\x0Dif-none-match"
+"\x08if-range"
+"\x13if-unmodified-since"
+"\x0Dlast-modified"
+"\x04link"
+"\x08location"
+"\x0Cmax-forwards"
+"\x07:method"
+"\x05:path"
+"\x04POST"
+"\x12proxy-authenticate"
+"\x13proxy-authorization"
+"\x03PUT"
+"\x05range"
+"\x07referer"
+"\x07refresh"
+"\x0Bretry-after"
+"\x07:scheme"
+"\x06server"
+"\x0Aset-cookie"
+"\x01/"
+"\x0B/index.html"
+"\x07:status"
+"\x19strict-transport-security"
+"\x02te"
+"\x08trailers"
+"\x11transfer-encoding"
+"\x0Auser-agent"
+"\x04vary"
+"\x03via"
+"\x10www-authenticate"
+"\x00\x0Eaccept-charset\x00"
+"\x00\x06accept\x00"
+"\x00\x0Faccept-encoding\x00"
+"\x00\x0Faccept-encoding\x0Dgzip, deflate"
+"\x00\x0Faccept-language\x00"
+"\x00\x0Daccept-ranges\x00"
+"\x00\x1Baccess-control-allow-origin\x00"
+"\x00\x03age\x00"
+"\x00\x05allow\x00"
+"\x00\x0A:authority\x00"
+"\x00\x0Dauthorization\x00"
+"\x00\x0Dcache-control\x00"
+"\x00\x13content-disposition\x00"
+"\x00\x10content-encoding\x00"
+"\x00\x10content-language\x00"
+"\x00\x0Econtent-length\x00"
+"\x00\x10content-location\x00"
+"\x00\x0Dcontent-range\x00"
+"\x00\x0Ccontent-type\x10application/grpc"
+"\x00\x0Ccontent-type\x00"
+"\x00\x06cookie\x00"
+"\x00\x04date\x00"
+"\x00\x04etag\x00"
+"\x00\x06expect\x00"
+"\x00\x07expires\x00"
+"\x00\x04from\x00"
+"\x00\x14grpc-accept-encoding\x07deflate"
+"\x00\x14grpc-accept-encoding\x0Cdeflate,gzip"
+"\x00\x14grpc-accept-encoding\x04gzip"
+"\x00\x14grpc-accept-encoding\x08identity"
+"\x00\x14grpc-accept-encoding\x10identity,deflate"
+"\x00\x14grpc-accept-encoding\x15identity,deflate,gzip"
+"\x00\x14grpc-accept-encoding\x0Didentity,gzip"
+"\x00\x0Dgrpc-encoding\x07deflate"
+"\x00\x0Dgrpc-encoding\x04gzip"
+"\x00\x0Dgrpc-encoding\x08identity"
+"\x00\x0Bgrpc-status\x010"
+"\x00\x0Bgrpc-status\x011"
+"\x00\x0Bgrpc-status\x012"
+"\x00\x04host\x00"
+"\x00\x08if-match\x00"
+"\x00\x11if-modified-since\x00"
+"\x00\x0Dif-none-match\x00"
+"\x00\x08if-range\x00"
+"\x00\x13if-unmodified-since\x00"
+"\x00\x0Dlast-modified\x00"
+"\x00\x04link\x00"
+"\x00\x08location\x00"
+"\x00\x0Cmax-forwards\x00"
+"\x00\x07:method\x03GET"
+"\x00\x07:method\x04POST"
+"\x00\x07:method\x03PUT"
+"\x00\x05:path\x01/"
+"\x00\x05:path\x0B/index.html"
+"\x00\x12proxy-authenticate\x00"
+"\x00\x13proxy-authorization\x00"
+"\x00\x05range\x00"
+"\x00\x07referer\x00"
+"\x00\x07refresh\x00"
+"\x00\x0Bretry-after\x00"
+"\x00\x07:scheme\x04grpc"
+"\x00\x07:scheme\x04http"
+"\x00\x07:scheme\x05https"
+"\x00\x06server\x00"
+"\x00\x0Aset-cookie\x00"
+"\x00\x07:status\x03200"
+"\x00\x07:status\x03204"
+"\x00\x07:status\x03206"
+"\x00\x07:status\x03304"
+"\x00\x07:status\x03400"
+"\x00\x07:status\x03404"
+"\x00\x07:status\x03500"
+"\x00\x19strict-transport-security\x00"
+"\x00\x02te\x08trailers"
+"\x00\x11transfer-encoding\x00"
+"\x00\x0Auser-agent\x00"
+"\x00\x04vary\x00"
+"\x00\x03via\x00"
+"\x00\x10www-authenticate\x00"
diff --git a/test/core/end2end/fuzzers/server_fuzzer.c b/test/core/end2end/fuzzers/server_fuzzer.c
index 393d330..4027371 100644
--- a/test/core/end2end/fuzzers/server_fuzzer.c
+++ b/test/core/end2end/fuzzers/server_fuzzer.c
@@ -35,6 +35,7 @@
 
 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
 #include "src/core/lib/surface/server.h"
+#include "test/core/util/memory_counters.h"
 #include "test/core/util/mock_endpoint.h"
 
 static const bool squelch = true;
@@ -48,7 +49,9 @@
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   grpc_test_only_set_metadata_hash_seed(0);
+  struct grpc_memory_counters counters;
   if (squelch) gpr_set_log_function(dont_log);
+  grpc_memory_counters_init();
   grpc_init();
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
@@ -117,5 +120,8 @@
   grpc_server_destroy(server);
   grpc_completion_queue_destroy(cq);
   grpc_shutdown();
+  counters = grpc_memory_counters_snapshot();
+  grpc_memory_counters_destroy();
+  GPR_ASSERT(counters.total_size_relative == 0);
   return 0;
 }
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/05efe6d81ce606557691432634e81f61e68b0b81 b/test/core/end2end/fuzzers/server_fuzzer_corpus/05efe6d81ce606557691432634e81f61e68b0b81
new file mode 100644
index 0000000..fd00271
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/05efe6d81ce606557691432634e81f61e68b0b81
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/07ad7e0ea2aaecba37f2429a64e946fc6e2556f1 b/test/core/end2end/fuzzers/server_fuzzer_corpus/07ad7e0ea2aaecba37f2429a64e946fc6e2556f1
new file mode 100644
index 0000000..c400e76
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/07ad7e0ea2aaecba37f2429a64e946fc6e2556f1
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/0c413d2b361b2221585026d42f3046ff4135d2ff b/test/core/end2end/fuzzers/server_fuzzer_corpus/0c413d2b361b2221585026d42f3046ff4135d2ff
new file mode 100644
index 0000000..34bee24
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/0c413d2b361b2221585026d42f3046ff4135d2ff
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/3292129aa7f6eba86b70fff64408f18fff895c12 b/test/core/end2end/fuzzers/server_fuzzer_corpus/3292129aa7f6eba86b70fff64408f18fff895c12
new file mode 100644
index 0000000..6e3f0e9
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/3292129aa7f6eba86b70fff64408f18fff895c12
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/38df7e63181cbd045e5af9dbee463360c8254618 b/test/core/end2end/fuzzers/server_fuzzer_corpus/38df7e63181cbd045e5af9dbee463360c8254618
new file mode 100644
index 0000000..c46dc83
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/38df7e63181cbd045e5af9dbee463360c8254618
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/3d7ef8c7b05f26e914c479dedb1bef5e378d2d94 b/test/core/end2end/fuzzers/server_fuzzer_corpus/3d7ef8c7b05f26e914c479dedb1bef5e378d2d94
new file mode 100644
index 0000000..fb9af0d
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/3d7ef8c7b05f26e914c479dedb1bef5e378d2d94
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/4271fbb36e03cee79b21a4a5a65f37ceef58a8cd b/test/core/end2end/fuzzers/server_fuzzer_corpus/4271fbb36e03cee79b21a4a5a65f37ceef58a8cd
new file mode 100644
index 0000000..a2ee89d
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/4271fbb36e03cee79b21a4a5a65f37ceef58a8cd
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/44516839d35af9ccaf8a2c62f3ce6a723482445e b/test/core/end2end/fuzzers/server_fuzzer_corpus/44516839d35af9ccaf8a2c62f3ce6a723482445e
new file mode 100644
index 0000000..890f934
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/44516839d35af9ccaf8a2c62f3ce6a723482445e
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/59d0b24d1acd01c749fb4bd6802a5f4dd003ce75 b/test/core/end2end/fuzzers/server_fuzzer_corpus/59d0b24d1acd01c749fb4bd6802a5f4dd003ce75
new file mode 100644
index 0000000..bdf76d5
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/59d0b24d1acd01c749fb4bd6802a5f4dd003ce75
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/61e798bdd49b339983fea4ccfe18efe44afbd69b b/test/core/end2end/fuzzers/server_fuzzer_corpus/61e798bdd49b339983fea4ccfe18efe44afbd69b
new file mode 100644
index 0000000..7179868
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/61e798bdd49b339983fea4ccfe18efe44afbd69b
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/6f3bd9f33ca05bebe3811f7b3ae6ed112e1e45b9 b/test/core/end2end/fuzzers/server_fuzzer_corpus/6f3bd9f33ca05bebe3811f7b3ae6ed112e1e45b9
new file mode 100644
index 0000000..4069f67
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/6f3bd9f33ca05bebe3811f7b3ae6ed112e1e45b9
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/8164d3c4af043c47cfd6966873bccd2353d072bf b/test/core/end2end/fuzzers/server_fuzzer_corpus/8164d3c4af043c47cfd6966873bccd2353d072bf
new file mode 100644
index 0000000..a60e270
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/8164d3c4af043c47cfd6966873bccd2353d072bf
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/8846918f967dd6513040c6d382fcd68ff7099873 b/test/core/end2end/fuzzers/server_fuzzer_corpus/8846918f967dd6513040c6d382fcd68ff7099873
new file mode 100644
index 0000000..b0cb61d
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/8846918f967dd6513040c6d382fcd68ff7099873
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/885fe25a0b441ef46ab176b88771c133e530cb73 b/test/core/end2end/fuzzers/server_fuzzer_corpus/885fe25a0b441ef46ab176b88771c133e530cb73
new file mode 100644
index 0000000..97896d1
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/885fe25a0b441ef46ab176b88771c133e530cb73
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/bc9545cebdcb3af82406a5f0c1b286d28f9d4f5a b/test/core/end2end/fuzzers/server_fuzzer_corpus/bc9545cebdcb3af82406a5f0c1b286d28f9d4f5a
new file mode 100644
index 0000000..4d02fcc
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/bc9545cebdcb3af82406a5f0c1b286d28f9d4f5a
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/cc97ece92b72cc2a4d045e16c0e2f2021bc014f8 b/test/core/end2end/fuzzers/server_fuzzer_corpus/cc97ece92b72cc2a4d045e16c0e2f2021bc014f8
new file mode 100644
index 0000000..76e26ec
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/cc97ece92b72cc2a4d045e16c0e2f2021bc014f8
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/d96da249094db51ea92b1413907abfd27a4f2426 b/test/core/end2end/fuzzers/server_fuzzer_corpus/d96da249094db51ea92b1413907abfd27a4f2426
new file mode 100644
index 0000000..9b3c751
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/d96da249094db51ea92b1413907abfd27a4f2426
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/df5d3cf5f05eab65ef9d385e263780ae73c42b19 b/test/core/end2end/fuzzers/server_fuzzer_corpus/df5d3cf5f05eab65ef9d385e263780ae73c42b19
new file mode 100644
index 0000000..3312090
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/df5d3cf5f05eab65ef9d385e263780ae73c42b19
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/e9bbe2fe47b7b9c2683e7f17f4a33625c6ffbd8c b/test/core/end2end/fuzzers/server_fuzzer_corpus/e9bbe2fe47b7b9c2683e7f17f4a33625c6ffbd8c
new file mode 100644
index 0000000..1972fa4
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/e9bbe2fe47b7b9c2683e7f17f4a33625c6ffbd8c
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1b6c4b5c1949adae3efd5e3264bb32a40eea524e b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1b6c4b5c1949adae3efd5e3264bb32a40eea524e
new file mode 100644
index 0000000..8831098
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1b6c4b5c1949adae3efd5e3264bb32a40eea524e
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-3991c873ba814d0cd03a67d25fff0c8fe8713aca b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-3991c873ba814d0cd03a67d25fff0c8fe8713aca
new file mode 100644
index 0000000..fbc7a0b
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-3991c873ba814d0cd03a67d25fff0c8fe8713aca
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-58f116dfba8d428a01ca596174fca63f4ac523f0 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-58f116dfba8d428a01ca596174fca63f4ac523f0
new file mode 100644
index 0000000..b0c854c
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-58f116dfba8d428a01ca596174fca63f4ac523f0
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-59f6edc7cf4aeed49b4dc024052db4846d5d7fc8 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-59f6edc7cf4aeed49b4dc024052db4846d5d7fc8
new file mode 100644
index 0000000..e01687e
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-59f6edc7cf4aeed49b4dc024052db4846d5d7fc8
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-63ebf780ee6c2003eba622686a4bf94c503ad96e b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-63ebf780ee6c2003eba622686a4bf94c503ad96e
new file mode 100644
index 0000000..071391b
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-63ebf780ee6c2003eba622686a4bf94c503ad96e
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-7233d53f94386b0339b2c2b01ef2d348f5862f1f b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-7233d53f94386b0339b2c2b01ef2d348f5862f1f
new file mode 100644
index 0000000..49dda96
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-7233d53f94386b0339b2c2b01ef2d348f5862f1f
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-7281d9eaed0d20b0b6b5e7709c57e78fefe9c315 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-7281d9eaed0d20b0b6b5e7709c57e78fefe9c315
new file mode 100644
index 0000000..44c3397
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-7281d9eaed0d20b0b6b5e7709c57e78fefe9c315
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-9a176b6f7e0dc5f681a1788d8954f76fabd08cad b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-9a176b6f7e0dc5f681a1788d8954f76fabd08cad
new file mode 100644
index 0000000..ef52cd7
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-9a176b6f7e0dc5f681a1788d8954f76fabd08cad
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-9de2e92150e54982d4e502b18f374f8cd8fd453b b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-9de2e92150e54982d4e502b18f374f8cd8fd453b
new file mode 100644
index 0000000..e7aa007
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-9de2e92150e54982d4e502b18f374f8cd8fd453b
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a61a28cf78149518466b87e5463ec5c771dc504e b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a61a28cf78149518466b87e5463ec5c771dc504e
new file mode 100644
index 0000000..2933607
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a61a28cf78149518466b87e5463ec5c771dc504e
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-aa23c18f6badd88a7bec65e8b04f7801ba624ec6 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-aa23c18f6badd88a7bec65e8b04f7801ba624ec6
new file mode 100644
index 0000000..3d7f426
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-aa23c18f6badd88a7bec65e8b04f7801ba624ec6
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-bda43d420a3e5d5228a5f5130207a1f11fc1c81f b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-bda43d420a3e5d5228a5f5130207a1f11fc1c81f
new file mode 100644
index 0000000..37b9287
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-bda43d420a3e5d5228a5f5130207a1f11fc1c81f
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-d3c3cba3897fafec97665411ea1f94a89bb4de7b b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-d3c3cba3897fafec97665411ea1f94a89bb4de7b
new file mode 100644
index 0000000..30ff86f
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-d3c3cba3897fafec97665411ea1f94a89bb4de7b
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-ddfe613d8791b2d377e14fbdffb18b84a89d49b6 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-ddfe613d8791b2d377e14fbdffb18b84a89d49b6
new file mode 100644
index 0000000..93bc416
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-ddfe613d8791b2d377e14fbdffb18b84a89d49b6
Binary files differ
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index 9a940a4..cffe599 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -65,6 +65,7 @@
     'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace(
         ci_mac=False, tracing=True),
     'h2_ssl': default_secure_fixture_options,
+    'h2_ssl_cert': default_secure_fixture_options,
     'h2_ssl_proxy': default_secure_fixture_options._replace(includes_proxy=True,
                                                             ci_mac=False),
     'h2_uds': uds_fixture_options,
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index e74d323..9f9ee85 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -207,10 +207,7 @@
   call_data *calld = elem->call_data;
   if (success) {
     // close the stream with an error.
-    gpr_slice message;
-    grpc_transport_stream_op close_op;
-    memset(&close_op, 0, sizeof(close_op));
-    message =
+    gpr_slice message =
         gpr_slice_from_copied_string("Random failure that's not preventable.");
     grpc_transport_stream_op op;
     memset(&op, 0, sizeof(op));
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 9b3b033..52082c3 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -89,7 +89,7 @@
 static gpr_slice *allocate_blocks(size_t num_bytes, size_t slice_size,
                                   size_t *num_blocks, uint8_t *current_data) {
   size_t nslices = num_bytes / slice_size + (num_bytes % slice_size ? 1 : 0);
-  gpr_slice *slices = malloc(sizeof(gpr_slice) * nslices);
+  gpr_slice *slices = gpr_malloc(sizeof(gpr_slice) * nslices);
   size_t num_bytes_left = num_bytes;
   size_t i;
   size_t j;
@@ -164,7 +164,7 @@
       gpr_slice_buffer_addn(&state->outgoing, slices, nslices);
       grpc_endpoint_write(exec_ctx, state->write_ep, &state->outgoing,
                           &state->done_write);
-      free(slices);
+      gpr_free(slices);
       return;
     }
   }
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index d51b6b7..7a98fa0 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -97,7 +97,7 @@
 static size_t fill_socket_partial(int fd, size_t bytes) {
   ssize_t write_bytes;
   size_t total_bytes = 0;
-  unsigned char *buf = malloc(bytes);
+  unsigned char *buf = gpr_malloc(bytes);
   unsigned i;
   for (i = 0; i < bytes; ++i) {
     buf[i] = (uint8_t)(i % 256);
@@ -292,7 +292,7 @@
 }
 
 void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) {
-  unsigned char *buf = malloc(read_size);
+  unsigned char *buf = gpr_malloc(read_size);
   ssize_t bytes_read;
   size_t bytes_left = num_bytes;
   int flags;
diff --git a/test/core/json/fuzzer.c b/test/core/json/fuzzer.c
index 044db97..e94b41c 100644
--- a/test/core/json/fuzzer.c
+++ b/test/core/json/fuzzer.c
@@ -38,42 +38,12 @@
 #include <grpc/support/log.h>
 
 #include "src/core/lib/json/json.h"
-
-static size_t g_total_size = 0;
-static gpr_allocation_functions g_old_allocs;
-
-void *guard_malloc(size_t size) {
-  size_t *ptr;
-  g_total_size += size;
-  ptr = g_old_allocs.malloc_fn(size + sizeof(size));
-  *ptr++ = size;
-  return ptr;
-}
-
-void *guard_realloc(void *vptr, size_t size) {
-  size_t *ptr = vptr;
-  --ptr;
-  g_total_size -= *ptr;
-  ptr = g_old_allocs.realloc_fn(ptr, size + sizeof(size));
-  g_total_size += size;
-  *ptr++ = size;
-  return ptr;
-}
-
-void guard_free(void *vptr) {
-  size_t *ptr = vptr;
-  --ptr;
-  g_total_size -= *ptr;
-  g_old_allocs.free_fn(ptr);
-}
-
-struct gpr_allocation_functions g_guard_allocs = {guard_malloc, guard_realloc,
-                                                  guard_free};
+#include "test/core/util/memory_counters.h"
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   char *s;
-  g_old_allocs = gpr_get_allocation_functions();
-  gpr_set_allocation_functions(g_guard_allocs);
+  struct grpc_memory_counters counters;
+  grpc_memory_counters_init();
   s = gpr_malloc(size);
   memcpy(s, data, size);
   grpc_json *x;
@@ -81,7 +51,8 @@
     grpc_json_destroy(x);
   }
   gpr_free(s);
-  gpr_set_allocation_functions(g_old_allocs);
-  GPR_ASSERT(g_total_size == 0);
+  counters = grpc_memory_counters_snapshot();
+  grpc_memory_counters_destroy();
+  GPR_ASSERT(counters.total_size_relative == 0);
   return 0;
 }
diff --git a/test/core/network_benchmarks/low_level_ping_pong.c b/test/core/network_benchmarks/low_level_ping_pong.c
index ac5ee72..1b40895 100644
--- a/test/core/network_benchmarks/low_level_ping_pong.c
+++ b/test/core/network_benchmarks/low_level_ping_pong.c
@@ -49,6 +49,7 @@
 #endif
 #include <sys/socket.h>
 
+#include <grpc/support/alloc.h>
 #include <grpc/support/cmdline.h>
 #include <grpc/support/histogram.h>
 #include <grpc/support/log.h>
@@ -265,19 +266,19 @@
 #endif
 
 static void server_thread(thread_args *args) {
-  char *buf = malloc(args->msg_size);
+  char *buf = gpr_malloc(args->msg_size);
   if (args->setup(args) < 0) {
     gpr_log(GPR_ERROR, "Setup failed");
   }
   for (;;) {
     if (args->read_bytes(args, buf) < 0) {
       gpr_log(GPR_ERROR, "Server read failed");
-      free(buf);
+      gpr_free(buf);
       return;
     }
     if (args->write_bytes(args, buf) < 0) {
       gpr_log(GPR_ERROR, "Server write failed");
-      free(buf);
+      gpr_free(buf);
       return;
     }
   }
@@ -304,7 +305,8 @@
 }
 
 static void client_thread(thread_args *args) {
-  char *buf = calloc(args->msg_size, sizeof(char));
+  char *buf = gpr_malloc(args->msg_size * sizeof(char));
+  memset(buf, 0, args->msg_size * sizeof(char));
   gpr_histogram *histogram = gpr_histogram_create(0.01, 60e9);
   double start_time;
   double end_time;
@@ -333,7 +335,7 @@
   }
   print_histogram(histogram);
 error:
-  free(buf);
+  gpr_free(buf);
   gpr_histogram_destroy(histogram);
 }
 
@@ -596,8 +598,8 @@
     test_strategy *strategy = &test_strategies[i];
     size_t j;
     for (j = 0; j < GPR_ARRAY_SIZE(socket_types); ++j) {
-      thread_args *client_args = malloc(sizeof(thread_args));
-      thread_args *server_args = malloc(sizeof(thread_args));
+      thread_args *client_args = gpr_malloc(sizeof(thread_args));
+      thread_args *server_args = gpr_malloc(sizeof(thread_args));
       char *socket_type = socket_types[j];
 
       client_args->read_bytes = strategy->read_strategy;
@@ -620,8 +622,8 @@
 }
 
 int main(int argc, char **argv) {
-  thread_args *client_args = malloc(sizeof(thread_args));
-  thread_args *server_args = malloc(sizeof(thread_args));
+  thread_args *client_args = gpr_malloc(sizeof(thread_args));
+  thread_args *server_args = gpr_malloc(sizeof(thread_args));
   int msg_size = -1;
   char *read_strategy = NULL;
   char *socket_type = NULL;
diff --git a/test/core/support/alloc_test.c b/test/core/support/alloc_test.c
index a7df197..451c580 100644
--- a/test/core/support/alloc_test.c
+++ b/test/core/support/alloc_test.c
@@ -46,7 +46,7 @@
 static void test_custom_allocs() {
   const gpr_allocation_functions default_fns = gpr_get_allocation_functions();
   intptr_t addr_to_free = 0;
-  int *i;
+  char *i;
   gpr_allocation_functions fns = {fake_malloc, fake_realloc, fake_free};
 
   gpr_set_allocation_functions(fns);
@@ -58,7 +58,7 @@
 
   /* Restore and check we don't get funky values and that we don't leak */
   gpr_set_allocation_functions(default_fns);
-  GPR_ASSERT((void *)1 != (i = gpr_malloc(sizeof(*i))));
+  GPR_ASSERT((void *)sizeof(*i) != (i = gpr_malloc(sizeof(*i))));
   GPR_ASSERT((void *)2 != (i = gpr_realloc(i, 2)));
   gpr_free(i);
 }
diff --git a/test/core/support/log_test.c b/test/core/support/log_test.c
index b39b069..0ae298a 100644
--- a/test/core/support/log_test.c
+++ b/test/core/support/log_test.c
@@ -33,16 +33,40 @@
 
 #include <grpc/support/log.h>
 
+#include <stdbool.h>
 #include <string.h>
 
+#include "src/core/lib/support/env.h"
 #include "test/core/util/test_config.h"
 
+static bool log_func_reached = false;
+
 static void test_callback(gpr_log_func_args *args) {
   GPR_ASSERT(0 == strcmp(__FILE__, args->file));
   GPR_ASSERT(args->severity == GPR_LOG_SEVERITY_INFO);
   GPR_ASSERT(0 == strcmp(args->message, "hello 1 2 3"));
 }
 
+static void test_should_log(gpr_log_func_args *args) {
+  log_func_reached = true;
+}
+
+static void test_should_not_log(gpr_log_func_args *args) { GPR_ASSERT(false); }
+
+#define test_log_function_reached(SEVERITY)     \
+  gpr_set_log_function(test_should_log);        \
+  log_func_reached = false;                     \
+  gpr_log_message(SEVERITY, "hello 1 2 3");     \
+  GPR_ASSERT(log_func_reached);                 \
+  log_func_reached = false;                     \
+  gpr_log(SEVERITY, "hello %d %d %d", 1, 2, 3); \
+  GPR_ASSERT(log_func_reached);
+
+#define test_log_function_unreached(SEVERITY) \
+  gpr_set_log_function(test_should_not_log);  \
+  gpr_log_message(SEVERITY, "hello 1 2 3");   \
+  gpr_log(SEVERITY, "hello %d %d %d", 1, 2, 3);
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   /* test logging at various verbosity levels */
@@ -54,6 +78,44 @@
   gpr_set_log_function(test_callback);
   gpr_log_message(GPR_INFO, "hello 1 2 3");
   gpr_log(GPR_INFO, "hello %d %d %d", 1, 2, 3);
+
+  /* gpr_log_verbosity_init() will be effective only once, and only before
+   * gpr_set_log_verbosity() is called */
+  gpr_setenv("GRPC_VERBOSITY", "ERROR");
+  gpr_log_verbosity_init();
+  test_log_function_reached(GPR_ERROR);
+  test_log_function_unreached(GPR_INFO);
+  test_log_function_unreached(GPR_DEBUG);
+
+  /* gpr_log_verbosity_init() should not be effective */
+  gpr_setenv("GRPC_VERBOSITY", "DEBUG");
+  gpr_log_verbosity_init();
+  test_log_function_reached(GPR_ERROR);
+  test_log_function_unreached(GPR_INFO);
+  test_log_function_unreached(GPR_DEBUG);
+
+  gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG);
+  test_log_function_reached(GPR_ERROR);
+  test_log_function_reached(GPR_INFO);
+  test_log_function_reached(GPR_DEBUG);
+
+  gpr_set_log_verbosity(GPR_LOG_SEVERITY_INFO);
+  test_log_function_reached(GPR_ERROR);
+  test_log_function_reached(GPR_INFO);
+  test_log_function_unreached(GPR_DEBUG);
+
+  gpr_set_log_verbosity(GPR_LOG_SEVERITY_ERROR);
+  test_log_function_reached(GPR_ERROR);
+  test_log_function_unreached(GPR_INFO);
+  test_log_function_unreached(GPR_DEBUG);
+
+  /* gpr_log_verbosity_init() should not be effective */
+  gpr_setenv("GRPC_VERBOSITY", "DEBUG");
+  gpr_log_verbosity_init();
+  test_log_function_reached(GPR_ERROR);
+  test_log_function_unreached(GPR_INFO);
+  test_log_function_unreached(GPR_DEBUG);
+
   /* TODO(ctiller): should we add a GPR_ASSERT failure test here */
   return 0;
 }
diff --git a/test/core/surface/concurrent_connectivity_test.c b/test/core/surface/concurrent_connectivity_test.c
index 96761b0..a2fdf73 100644
--- a/test/core/surface/concurrent_connectivity_test.c
+++ b/test/core/surface/concurrent_connectivity_test.c
@@ -31,12 +31,21 @@
 *
 */
 
+#include <memory.h>
 #include <stdio.h>
 
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
 #include <grpc/support/thd.h>
+
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/iomgr.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/iomgr/tcp_server.h"
+
+#include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
 #define NUM_THREADS 100
@@ -45,10 +54,13 @@
 #define DELAY_MILLIS 10
 #define POLL_MILLIS 3000
 
-void create_loop_destroy(void* unused) {
+static void *tag(int n) { return (void *)(uintptr_t)n; }
+static int detag(void *p) { return (int)(uintptr_t)p; }
+
+void create_loop_destroy(void *addr) {
   for (int i = 0; i < NUM_OUTER_LOOPS; ++i) {
-    grpc_completion_queue* cq = grpc_completion_queue_create(NULL);
-    grpc_channel* chan = grpc_insecure_channel_create("localhost", NULL, NULL);
+    grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
+    grpc_channel *chan = grpc_insecure_channel_create((char *)addr, NULL, NULL);
 
     for (int j = 0; j < NUM_INNER_LOOPS; ++j) {
       gpr_timespec later_time = GRPC_TIMEOUT_MILLIS_TO_DEADLINE(DELAY_MILLIS);
@@ -64,18 +76,140 @@
   }
 }
 
-int main(int argc, char** argv) {
+struct server_thread_args {
+  char *addr;
+  grpc_server *server;
+  grpc_completion_queue *cq;
+  grpc_pollset *pollset;
+  gpr_mu *mu;
+  gpr_event ready;
+  gpr_atm stop;
+};
+
+void server_thread(void *vargs) {
+  struct server_thread_args *args = (struct server_thread_args *)vargs;
+  grpc_event ev;
+  gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
+  ev = grpc_completion_queue_next(args->cq, deadline, NULL);
+  GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
+  GPR_ASSERT(detag(ev.tag) == 0xd1e);
+}
+
+static void on_connect(grpc_exec_ctx *exec_ctx, void *vargs, grpc_endpoint *tcp,
+                       grpc_tcp_server_acceptor *acceptor) {
+  struct server_thread_args *args = (struct server_thread_args *)vargs;
+  (void)acceptor;
+  grpc_endpoint_shutdown(exec_ctx, tcp);
+  grpc_endpoint_destroy(exec_ctx, tcp);
+  grpc_pollset_kick(args->pollset, NULL);
+}
+
+void bad_server_thread(void *vargs) {
+  struct server_thread_args *args = (struct server_thread_args *)vargs;
+
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  struct sockaddr_storage addr;
+  socklen_t addr_len = sizeof(addr);
+  int port;
+  grpc_tcp_server *s = grpc_tcp_server_create(NULL);
+  memset(&addr, 0, sizeof(addr));
+  addr.ss_family = AF_INET;
+  port = grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, addr_len);
+  GPR_ASSERT(port > 0);
+  gpr_asprintf(&args->addr, "localhost:%d", port);
+
+  grpc_tcp_server_start(&exec_ctx, s, &args->pollset, 1, on_connect, args);
+  gpr_event_set(&args->ready, (void *)1);
+
+  gpr_mu_lock(args->mu);
+  while (gpr_atm_acq_load(&args->stop) == 0) {
+    gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
+    gpr_timespec deadline =
+        gpr_time_add(now, gpr_time_from_millis(100, GPR_TIMESPAN));
+
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, args->pollset, &worker, now, deadline);
+    gpr_mu_unlock(args->mu);
+    grpc_exec_ctx_finish(&exec_ctx);
+    gpr_mu_lock(args->mu);
+  }
+  gpr_mu_unlock(args->mu);
+
+  grpc_tcp_server_unref(&exec_ctx, s);
+
+  grpc_exec_ctx_finish(&exec_ctx);
+
+  gpr_free(args->addr);
+}
+
+int main(int argc, char **argv) {
+  struct server_thread_args args;
+  memset(&args, 0, sizeof(args));
+
   grpc_test_init(argc, argv);
   grpc_init();
+
   gpr_thd_id threads[NUM_THREADS];
+  gpr_thd_id server;
+
+  char *localhost = gpr_strdup("localhost:54321");
+  gpr_thd_options options = gpr_thd_options_default();
+  gpr_thd_options_set_joinable(&options);
+
+  /* First round, no server */
+  gpr_log(GPR_DEBUG, "Wave 1");
   for (size_t i = 0; i < NUM_THREADS; ++i) {
-    gpr_thd_options options = gpr_thd_options_default();
-    gpr_thd_options_set_joinable(&options);
-    gpr_thd_new(&threads[i], create_loop_destroy, NULL, &options);
+    gpr_thd_new(&threads[i], create_loop_destroy, localhost, &options);
   }
   for (size_t i = 0; i < NUM_THREADS; ++i) {
     gpr_thd_join(threads[i]);
   }
+  gpr_free(localhost);
+
+  /* Second round, actual grpc server */
+  gpr_log(GPR_DEBUG, "Wave 2");
+  int port = grpc_pick_unused_port_or_die();
+  gpr_asprintf(&args.addr, "localhost:%d", port);
+  args.server = grpc_server_create(NULL, NULL);
+  grpc_server_add_insecure_http2_port(args.server, args.addr);
+  args.cq = grpc_completion_queue_create(NULL);
+  grpc_server_register_completion_queue(args.server, args.cq, NULL);
+  grpc_server_start(args.server);
+  gpr_thd_new(&server, server_thread, &args, &options);
+
+  for (size_t i = 0; i < NUM_THREADS; ++i) {
+    gpr_thd_new(&threads[i], create_loop_destroy, args.addr, &options);
+  }
+  for (size_t i = 0; i < NUM_THREADS; ++i) {
+    gpr_thd_join(threads[i]);
+  }
+  grpc_server_shutdown_and_notify(args.server, args.cq, tag(0xd1e));
+
+  gpr_thd_join(server);
+  grpc_server_destroy(args.server);
+  grpc_completion_queue_destroy(args.cq);
+  gpr_free(args.addr);
+
+  /* Third round, bogus tcp server */
+  gpr_log(GPR_DEBUG, "Wave 3");
+  args.pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(args.pollset, &args.mu);
+  gpr_event_init(&args.ready);
+  gpr_thd_new(&server, bad_server_thread, &args, &options);
+  gpr_event_wait(&args.ready, gpr_inf_future(GPR_CLOCK_MONOTONIC));
+
+  for (size_t i = 0; i < NUM_THREADS; ++i) {
+    gpr_thd_new(&threads[i], create_loop_destroy, args.addr, &options);
+  }
+  for (size_t i = 0; i < NUM_THREADS; ++i) {
+    gpr_thd_join(threads[i]);
+  }
+
+  gpr_atm_rel_store(&args.stop, 1);
+  gpr_thd_join(server);
+  grpc_pollset_destroy(args.pollset);
+  gpr_free(args.pollset);
+
   grpc_shutdown();
   return 0;
 }
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index 579faa4..0eede6c 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -37,6 +37,7 @@
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
+#include <grpc/grpc_security_constants.h>
 #include <grpc/impl/codegen/alloc.h>
 #include <grpc/impl/codegen/atm.h>
 #include <grpc/impl/codegen/byte_buffer.h>
diff --git a/test/core/util/memory_counters.c b/test/core/util/memory_counters.c
new file mode 100644
index 0000000..bebe94e
--- /dev/null
+++ b/test/core/util/memory_counters.c
@@ -0,0 +1,117 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/sync.h>
+
+#include "test/core/util/memory_counters.h"
+
+static gpr_mu g_memory_mutex;
+static struct grpc_memory_counters g_memory_counters;
+static gpr_allocation_functions g_old_allocs;
+
+static void *guard_malloc(size_t size);
+static void *guard_realloc(void *vptr, size_t size);
+static void guard_free(void *vptr);
+
+static void *guard_malloc(size_t size) {
+  size_t *ptr;
+  if (!size) return NULL;
+  gpr_mu_lock(&g_memory_mutex);
+  g_memory_counters.total_size_absolute += size;
+  g_memory_counters.total_size_relative += size;
+  g_memory_counters.total_allocs_absolute++;
+  g_memory_counters.total_allocs_relative++;
+  gpr_mu_unlock(&g_memory_mutex);
+  ptr = g_old_allocs.malloc_fn(size + sizeof(size));
+  *ptr++ = size;
+  return ptr;
+}
+
+static void *guard_realloc(void *vptr, size_t size) {
+  size_t *ptr = vptr;
+  if (vptr == NULL) {
+    return guard_malloc(size);
+  }
+  if (size == 0) {
+    guard_free(vptr);
+    return NULL;
+  }
+  --ptr;
+  gpr_mu_lock(&g_memory_mutex);
+  g_memory_counters.total_size_absolute += size;
+  g_memory_counters.total_size_relative -= *ptr;
+  g_memory_counters.total_size_relative += size;
+  g_memory_counters.total_allocs_absolute++;
+  gpr_mu_unlock(&g_memory_mutex);
+  ptr = g_old_allocs.realloc_fn(ptr, size + sizeof(size));
+  *ptr++ = size;
+  return ptr;
+}
+
+static void guard_free(void *vptr) {
+  size_t *ptr = vptr;
+  if (!vptr) return;
+  --ptr;
+  gpr_mu_lock(&g_memory_mutex);
+  g_memory_counters.total_size_relative -= *ptr;
+  g_memory_counters.total_allocs_relative--;
+  gpr_mu_unlock(&g_memory_mutex);
+  g_old_allocs.free_fn(ptr);
+}
+
+struct gpr_allocation_functions g_guard_allocs = {guard_malloc, guard_realloc,
+                                                  guard_free};
+
+void grpc_memory_counters_init() {
+  memset(&g_memory_counters, 0, sizeof(g_memory_counters));
+  gpr_mu_init(&g_memory_mutex);
+  g_old_allocs = gpr_get_allocation_functions();
+  gpr_set_allocation_functions(g_guard_allocs);
+}
+
+void grpc_memory_counters_destroy() {
+  gpr_set_allocation_functions(g_old_allocs);
+  gpr_mu_destroy(&g_memory_mutex);
+}
+
+struct grpc_memory_counters grpc_memory_counters_snapshot() {
+  struct grpc_memory_counters counters;
+  gpr_mu_lock(&g_memory_mutex);
+  counters = g_memory_counters;
+  gpr_mu_unlock(&g_memory_mutex);
+  return counters;
+}
diff --git a/test/core/util/memory_counters.h b/test/core/util/memory_counters.h
new file mode 100644
index 0000000..f332816
--- /dev/null
+++ b/test/core/util/memory_counters.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_TEST_CORE_UTIL_MEMORY_COUNTERS_H
+#define GRPC_TEST_CORE_UTIL_MEMORY_COUNTERS_H
+
+struct grpc_memory_counters {
+  size_t total_size_relative;
+  size_t total_size_absolute;
+  size_t total_allocs_relative;
+  size_t total_allocs_absolute;
+};
+
+void grpc_memory_counters_init();
+void grpc_memory_counters_destroy();
+struct grpc_memory_counters grpc_memory_counters_snapshot();
+
+#endif
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index e958141..5a9027a 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -173,20 +173,6 @@
         random_dist.reset(
             new ExpDist(load.poisson().offered_load() / num_threads));
         break;
-      case LoadParams::kUniform:
-        random_dist.reset(
-            new UniformDist(load.uniform().interarrival_lo() * num_threads,
-                            load.uniform().interarrival_hi() * num_threads));
-        break;
-      case LoadParams::kDeterm:
-        random_dist.reset(
-            new DetDist(num_threads / load.determ().offered_load()));
-        break;
-      case LoadParams::kPareto:
-        random_dist.reset(
-            new ParetoDist(load.pareto().interarrival_base() * num_threads,
-                           load.pareto().alpha()));
-        break;
       default:
         GPR_ASSERT(false);
     }
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index c87ad64..2583ceb 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -52,6 +52,7 @@
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/histogram.h"
 #include "test/cpp/qps/qps_worker.h"
+#include "test/cpp/qps/stats.h"
 
 using std::list;
 using std::thread;
@@ -115,6 +116,47 @@
   }
 }
 
+// helpers for postprocess_scenario_result
+static double WallTime(ClientStats s) { return s.time_elapsed(); }
+static double SystemTime(ClientStats s) { return s.time_system(); }
+static double UserTime(ClientStats s) { return s.time_user(); }
+static double ServerWallTime(ServerStats s) { return s.time_elapsed(); }
+static double ServerSystemTime(ServerStats s) { return s.time_system(); }
+static double ServerUserTime(ServerStats s) { return s.time_user(); }
+static int Cores(int n) { return n; }
+
+// Postprocess ScenarioResult and populate result summary.
+static void postprocess_scenario_result(ScenarioResult* result) {
+  Histogram histogram;
+  histogram.MergeProto(result->latencies());
+
+  auto qps = histogram.Count() / average(result->client_stats(), WallTime);
+  auto qps_per_server_core = qps / sum(result->server_cores(), Cores);
+
+  result->mutable_summary()->set_qps(qps);
+  result->mutable_summary()->set_qps_per_server_core(qps_per_server_core);
+  result->mutable_summary()->set_latency_50(histogram.Percentile(50));
+  result->mutable_summary()->set_latency_90(histogram.Percentile(90));
+  result->mutable_summary()->set_latency_95(histogram.Percentile(95));
+  result->mutable_summary()->set_latency_99(histogram.Percentile(99));
+  result->mutable_summary()->set_latency_999(histogram.Percentile(99.9));
+
+  auto server_system_time = 100.0 *
+                            sum(result->server_stats(), ServerSystemTime) /
+                            sum(result->server_stats(), ServerWallTime);
+  auto server_user_time = 100.0 * sum(result->server_stats(), ServerUserTime) /
+                          sum(result->server_stats(), ServerWallTime);
+  auto client_system_time = 100.0 * sum(result->client_stats(), SystemTime) /
+                            sum(result->client_stats(), WallTime);
+  auto client_user_time = 100.0 * sum(result->client_stats(), UserTime) /
+                          sum(result->client_stats(), WallTime);
+
+  result->mutable_summary()->set_server_system_time(server_system_time);
+  result->mutable_summary()->set_server_user_time(server_user_time);
+  result->mutable_summary()->set_client_system_time(client_system_time);
+  result->mutable_summary()->set_client_user_time(client_user_time);
+}
+
 // Namespace for classes and functions used only in RunScenario
 // Using this rather than local definitions to workaround gcc-4.4 limitations
 // regarding using templates without linkage
@@ -343,8 +385,8 @@
 
   // Finish a run
   std::unique_ptr<ScenarioResult> result(new ScenarioResult);
-  result->client_config = result_client_config;
-  result->server_config = result_server_config;
+  Histogram merged_latencies;
+
   gpr_log(GPR_INFO, "Finishing clients");
   for (auto client = &clients[0]; client != &clients[num_clients]; client++) {
     GPR_ASSERT(client->stream->Write(client_mark));
@@ -353,9 +395,8 @@
   for (auto client = &clients[0]; client != &clients[num_clients]; client++) {
     GPR_ASSERT(client->stream->Read(&client_status));
     const auto& stats = client_status.stats();
-    result->latencies.MergeProto(stats.latencies());
-    result->client_resources.emplace_back(
-        stats.time_elapsed(), stats.time_user(), stats.time_system(), -1);
+    merged_latencies.MergeProto(stats.latencies());
+    result->add_client_stats()->CopyFrom(stats);
     GPR_ASSERT(!client->stream->Read(&client_status));
   }
   for (auto client = &clients[0]; client != &clients[num_clients]; client++) {
@@ -363,6 +404,8 @@
   }
   delete[] clients;
 
+  merged_latencies.FillProto(result->mutable_latencies());
+
   gpr_log(GPR_INFO, "Finishing servers");
   for (auto server = &servers[0]; server != &servers[num_servers]; server++) {
     GPR_ASSERT(server->stream->Write(server_mark));
@@ -370,10 +413,8 @@
   }
   for (auto server = &servers[0]; server != &servers[num_servers]; server++) {
     GPR_ASSERT(server->stream->Read(&server_status));
-    const auto& stats = server_status.stats();
-    result->server_resources.emplace_back(
-        stats.time_elapsed(), stats.time_user(), stats.time_system(),
-        server_status.cores());
+    result->add_server_stats()->CopyFrom(server_status.stats());
+    result->add_server_cores(server_status.cores());
     GPR_ASSERT(!server->stream->Read(&server_status));
   }
   for (auto server = &servers[0]; server != &servers[num_servers]; server++) {
@@ -381,6 +422,8 @@
   }
 
   delete[] servers;
+
+  postprocess_scenario_result(result.get());
   return result;
 }
 
diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h
index 21e5152..3a5cf13 100644
--- a/test/cpp/qps/driver.h
+++ b/test/cpp/qps/driver.h
@@ -41,29 +41,6 @@
 
 namespace grpc {
 namespace testing {
-class ResourceUsage {
- public:
-  ResourceUsage(double w, double u, double s, int c)
-      : wall_time_(w), user_time_(u), system_time_(s), cores_(c) {}
-  double wall_time() const { return wall_time_; }
-  double user_time() const { return user_time_; }
-  double system_time() const { return system_time_; }
-  int cores() const { return cores_; }
-
- private:
-  double wall_time_;
-  double user_time_;
-  double system_time_;
-  int cores_;
-};
-
-struct ScenarioResult {
-  Histogram latencies;
-  std::vector<ResourceUsage> client_resources;
-  std::vector<ResourceUsage> server_resources;
-  ClientConfig client_config;
-  ServerConfig server_config;
-};
 
 std::unique_ptr<ScenarioResult> RunScenario(
     const grpc::testing::ClientConfig& client_config, size_t num_clients,
diff --git a/test/cpp/qps/interarrival.h b/test/cpp/qps/interarrival.h
index 0cc7853..0980d5e 100644
--- a/test/cpp/qps/interarrival.h
+++ b/test/cpp/qps/interarrival.h
@@ -82,62 +82,6 @@
   double lambda_recip_;
 };
 
-// UniformDist implements a random distribution that has
-// interarrival time uniformly spread between [lo,hi). The
-// mean interarrival time is (lo+hi)/2. For more information,
-// see http://en.wikipedia.org/wiki/Uniform_distribution_%28continuous%29
-
-class UniformDist GRPC_FINAL : public RandomDistInterface {
- public:
-  UniformDist(double lo, double hi) : lo_(lo), range_(hi - lo) {}
-  ~UniformDist() GRPC_OVERRIDE {}
-  double transform(double uni) const GRPC_OVERRIDE {
-    return uni * range_ + lo_;
-  }
-
- private:
-  double lo_;
-  double range_;
-};
-
-// DetDist provides a random distribution with interarrival time
-// of val. Note that this is not additive, so using this on multiple
-// flows of control (threads within the same client or separate
-// clients) will not preserve any deterministic interarrival gap across
-// requests.
-
-class DetDist GRPC_FINAL : public RandomDistInterface {
- public:
-  explicit DetDist(double val) : val_(val) {}
-  ~DetDist() GRPC_OVERRIDE {}
-  double transform(double uni) const GRPC_OVERRIDE { return val_; }
-
- private:
-  double val_;
-};
-
-// ParetoDist provides a random distribution with interarrival time
-// spread according to a Pareto (heavy-tailed) distribution. In this
-// model, many interarrival times are close to the base, but a sufficient
-// number will be high (up to infinity) as to disturb the mean. It is a
-// good representation of the response times of data center jobs. See
-// http://en.wikipedia.org/wiki/Pareto_distribution
-
-class ParetoDist GRPC_FINAL : public RandomDistInterface {
- public:
-  ParetoDist(double base, double alpha)
-      : base_(base), alpha_recip_(1.0 / alpha) {}
-  ~ParetoDist() GRPC_OVERRIDE {}
-  double transform(double uni) const GRPC_OVERRIDE {
-    // Note: Use 1.0-uni above to avoid div by zero if uni is 0
-    return base_ / pow(1.0 - uni, alpha_recip_);
-  }
-
- private:
-  double base_;
-  double alpha_recip_;
-};
-
 // A class library for generating pseudo-random interarrival times
 // in an efficient re-entrant way. The random table is built at construction
 // time, and each call must include the thread id of the invoker
diff --git a/test/cpp/qps/qps-sweep.sh b/test/cpp/qps/qps-sweep.sh
deleted file mode 100755
index 8f7fb92..0000000
--- a/test/cpp/qps/qps-sweep.sh
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/bin/sh
-
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-if [ x"$QPS_WORKERS" == x ]; then
-  echo Error: Must set QPS_WORKERS variable in form \
-    "host:port,host:port,..." 1>&2
-  exit 1
-fi
-
-bins=`find . .. ../.. ../../.. -name bins | head -1`
-
-# Print out each command that gets executed
-set -x
-
-#
-# Specify parameters used in some of the tests
-#
-
-# big is the size in bytes of large messages (0 is the size otherwise)
-big=65536
-
-# wide is the number of client channels in multi-channel tests (1 otherwise)
-wide=64
-
-# deep is the number of RPCs outstanding on a channel in non-ping-pong tests
-# (the value used is 1 otherwise)
-deep=100
-
-# half is half the count of worker processes, used in the crossbar scenario
-# that uses equal clients and servers. The other scenarios use only 1 server
-# and either 1 client or N-1 clients as appropriate
-half=`echo $QPS_WORKERS | awk -F, '{print int(NF/2)}'`
-
-for secure in true false; do
-  # Scenario 1: generic async streaming ping-pong (contentionless latency)
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=1 \
-    --client_channels=1 --bbuf_req_size=0 --bbuf_resp_size=0 \
-    --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
-    --num_servers=1 --num_clients=1
-
-  # Scenario 2: generic async streaming "unconstrained" (QPS)
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
-    --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
-    --num_servers=1 --num_clients=0 2>&1 | tee /tmp/qps-test.$$
-
-  # Scenario 2b: QPS with a single server core
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
-    --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
-    --num_servers=1 --num_clients=0 --server_core_limit=1
-
-  # Scenario 2c: protobuf-based QPS
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=$wide --simple_req_size=0 --simple_resp_size=0 \
-    --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
-    --num_servers=1 --num_clients=0
-
-  # Scenario 3: Latency at sub-peak load (all clients equally loaded)
-  for loadfactor in 0.2 0.5 0.7; do
-    "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-      --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
-      --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
-      --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
-      --num_servers=1 --num_clients=0 --poisson_load=`awk -v lf=$loadfactor \
-      '$5 == "QPS:" {print int(lf * $6); exit}' /tmp/qps-test.$$`
-  done
-
-  rm /tmp/qps-test.$$
-
-  # Scenario 4: Single-channel bidirectional throughput test (like TCP_STREAM).
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=1 --bbuf_req_size=$big --bbuf_resp_size=$big \
-    --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
-    --num_servers=1 --num_clients=1
-
-  # Scenario 5: Sync unary ping-pong with protobufs
-  "$bins"/opt/qps_driver --rpc_type=UNARY --client_type=SYNC_CLIENT \
-    --server_type=SYNC_SERVER --outstanding_rpcs_per_channel=1 \
-    --client_channels=1 --simple_req_size=0 --simple_resp_size=0 \
-    --secure_test=$secure --num_servers=1 --num_clients=1
-
-  # Scenario 6: Sync streaming ping-pong with protobufs
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=SYNC_CLIENT \
-    --server_type=SYNC_SERVER --outstanding_rpcs_per_channel=1 \
-    --client_channels=1 --simple_req_size=0 --simple_resp_size=0 \
-    --secure_test=$secure --num_servers=1 --num_clients=1
-
-  # Scenario 7: Async unary ping-pong with protobufs
-  "$bins"/opt/qps_driver --rpc_type=UNARY --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_SERVER --outstanding_rpcs_per_channel=1 \
-    --client_channels=1 --simple_req_size=0 --simple_resp_size=0 \
-    --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
-    --num_servers=1 --num_clients=1
-
-  # Scenario 8: Async streaming ping-pong with protobufs
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_SERVER --outstanding_rpcs_per_channel=1 \
-    --client_channels=1 --simple_req_size=0 --simple_resp_size=0 \
-    --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
-    --num_servers=1 --num_clients=1
-
-  # Scenario 9: Crossbar QPS test
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
-    --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
-    --num_servers=$half --num_clients=0
-
-  # Scenario 10: Multi-channel bidir throughput test
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=1 \
-    --client_channels=$wide --bbuf_req_size=$big --bbuf_resp_size=$big \
-    --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
-    --num_servers=1 --num_clients=1
-
-  # Scenario 11: Single-channel request throughput test
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=1 --bbuf_req_size=$big --bbuf_resp_size=0 \
-    --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
-    --num_servers=1 --num_clients=1
-
-  # Scenario 12: Single-channel response throughput test
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=1 --bbuf_req_size=0 --bbuf_resp_size=$big \
-    --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
-    --num_servers=1 --num_clients=1
-
-  # Scenario 13: Single-channel bidirectional protobuf throughput test
-  "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=1 --simple_req_size=$big --simple_resp_size=$big \
-    --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
-    --num_servers=1 --num_clients=1
-done
diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc
deleted file mode 100644
index e412c69..0000000
--- a/test/cpp/qps/qps_driver.cc
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <memory>
-#include <set>
-
-#include <gflags/gflags.h>
-#include <grpc/support/log.h>
-
-#include "test/cpp/qps/driver.h"
-#include "test/cpp/qps/report.h"
-#include "test/cpp/util/benchmark_config.h"
-
-DEFINE_int32(num_clients, 1, "Number of client binaries");
-DEFINE_int32(num_servers, 1, "Number of server binaries");
-
-DEFINE_int32(warmup_seconds, 5, "Warmup time (in seconds)");
-DEFINE_int32(benchmark_seconds, 30, "Benchmark time (in seconds)");
-DEFINE_int32(local_workers, 0, "Number of local workers to start");
-
-// Server config
-DEFINE_int32(async_server_threads, 1, "Number of threads for async servers");
-DEFINE_string(server_type, "SYNC_SERVER", "Server type");
-DEFINE_int32(server_core_limit, -1, "Limit on server cores to use");
-
-// Client config
-DEFINE_string(rpc_type, "UNARY", "Type of RPC: UNARY or STREAMING");
-DEFINE_int32(outstanding_rpcs_per_channel, 1,
-             "Number of outstanding rpcs per channel");
-DEFINE_int32(client_channels, 1, "Number of client channels");
-
-DEFINE_int32(simple_req_size, -1, "Simple proto request payload size");
-DEFINE_int32(simple_resp_size, -1, "Simple proto response payload size");
-DEFINE_int32(bbuf_req_size, -1, "Byte-buffer request payload size");
-DEFINE_int32(bbuf_resp_size, -1, "Byte-buffer response payload size");
-
-DEFINE_string(client_type, "SYNC_CLIENT", "Client type");
-DEFINE_int32(async_client_threads, 1, "Async client threads");
-
-DEFINE_double(poisson_load, -1.0, "Poisson offered load (qps)");
-DEFINE_double(uniform_lo, -1.0, "Uniform low interarrival time (us)");
-DEFINE_double(uniform_hi, -1.0, "Uniform high interarrival time (us)");
-DEFINE_double(determ_load, -1.0, "Deterministic offered load (qps)");
-DEFINE_double(pareto_base, -1.0, "Pareto base interarrival time (us)");
-DEFINE_double(pareto_alpha, -1.0, "Pareto alpha value");
-
-DEFINE_int32(client_core_limit, -1, "Limit on client cores to use");
-
-DEFINE_bool(secure_test, false, "Run a secure test");
-
-DEFINE_bool(quit, false, "Quit the workers");
-
-using grpc::testing::ClientConfig;
-using grpc::testing::ServerConfig;
-using grpc::testing::ClientType;
-using grpc::testing::ServerType;
-using grpc::testing::RpcType;
-using grpc::testing::ResourceUsage;
-using grpc::testing::SecurityParams;
-
-namespace grpc {
-namespace testing {
-
-static void QpsDriver() {
-  if (FLAGS_quit) {
-    RunQuit();
-    return;
-  }
-
-  RpcType rpc_type;
-  GPR_ASSERT(RpcType_Parse(FLAGS_rpc_type, &rpc_type));
-
-  ClientType client_type;
-  ServerType server_type;
-  GPR_ASSERT(ClientType_Parse(FLAGS_client_type, &client_type));
-  GPR_ASSERT(ServerType_Parse(FLAGS_server_type, &server_type));
-
-  ClientConfig client_config;
-  client_config.set_client_type(client_type);
-  client_config.set_outstanding_rpcs_per_channel(
-      FLAGS_outstanding_rpcs_per_channel);
-  client_config.set_client_channels(FLAGS_client_channels);
-
-  // Decide which type to use based on the response type
-  if (FLAGS_simple_resp_size >= 0) {
-    auto params =
-        client_config.mutable_payload_config()->mutable_simple_params();
-    params->set_resp_size(FLAGS_simple_resp_size);
-    if (FLAGS_simple_req_size >= 0) {
-      params->set_req_size(FLAGS_simple_req_size);
-    }
-  } else if (FLAGS_bbuf_resp_size >= 0) {
-    auto params =
-        client_config.mutable_payload_config()->mutable_bytebuf_params();
-    params->set_resp_size(FLAGS_bbuf_resp_size);
-    if (FLAGS_bbuf_req_size >= 0) {
-      params->set_req_size(FLAGS_bbuf_req_size);
-    }
-  } else {
-    // set a reasonable default: proto but no payload
-    client_config.mutable_payload_config()->mutable_simple_params();
-  }
-
-  client_config.set_async_client_threads(FLAGS_async_client_threads);
-  client_config.set_rpc_type(rpc_type);
-
-  // set up the load parameters
-  if (FLAGS_poisson_load > 0.0) {
-    auto poisson = client_config.mutable_load_params()->mutable_poisson();
-    poisson->set_offered_load(FLAGS_poisson_load);
-  } else if (FLAGS_uniform_lo > 0.0) {
-    auto uniform = client_config.mutable_load_params()->mutable_uniform();
-    uniform->set_interarrival_lo(FLAGS_uniform_lo / 1e6);
-    uniform->set_interarrival_hi(FLAGS_uniform_hi / 1e6);
-  } else if (FLAGS_determ_load > 0.0) {
-    auto determ = client_config.mutable_load_params()->mutable_determ();
-    determ->set_offered_load(FLAGS_determ_load);
-  } else if (FLAGS_pareto_base > 0.0) {
-    auto pareto = client_config.mutable_load_params()->mutable_pareto();
-    pareto->set_interarrival_base(FLAGS_pareto_base / 1e6);
-    pareto->set_alpha(FLAGS_pareto_alpha);
-  } else {
-    client_config.mutable_load_params()->mutable_closed_loop();
-    // No further load parameters to set up for closed loop
-  }
-
-  client_config.mutable_histogram_params()->set_resolution(
-      Histogram::default_resolution());
-  client_config.mutable_histogram_params()->set_max_possible(
-      Histogram::default_max_possible());
-
-  if (FLAGS_client_core_limit > 0) {
-    client_config.set_core_limit(FLAGS_client_core_limit);
-  }
-
-  ServerConfig server_config;
-  server_config.set_server_type(server_type);
-  server_config.set_async_server_threads(FLAGS_async_server_threads);
-
-  if (FLAGS_server_core_limit > 0) {
-    server_config.set_core_limit(FLAGS_server_core_limit);
-  }
-
-  if (FLAGS_bbuf_resp_size >= 0) {
-    *server_config.mutable_payload_config() = client_config.payload_config();
-  }
-
-  if (FLAGS_secure_test) {
-    // Set up security params
-    SecurityParams security;
-    security.set_use_test_ca(true);
-    security.set_server_host_override("foo.test.google.fr");
-    client_config.mutable_security_params()->CopyFrom(security);
-    server_config.mutable_security_params()->CopyFrom(security);
-  }
-
-  // Make sure that if we are performing a generic (bytebuf) test
-  // that we are also using async streaming
-  GPR_ASSERT(!client_config.payload_config().has_bytebuf_params() ||
-             (client_config.client_type() == ASYNC_CLIENT &&
-              client_config.rpc_type() == STREAMING &&
-              server_config.server_type() == ASYNC_GENERIC_SERVER));
-
-  const auto result = RunScenario(
-      client_config, FLAGS_num_clients, server_config, FLAGS_num_servers,
-      FLAGS_warmup_seconds, FLAGS_benchmark_seconds, FLAGS_local_workers);
-
-  GetReporter()->ReportQPS(*result);
-  GetReporter()->ReportQPSPerCore(*result);
-  GetReporter()->ReportLatency(*result);
-  GetReporter()->ReportTimes(*result);
-}
-
-}  // namespace testing
-}  // namespace grpc
-
-int main(int argc, char** argv) {
-  grpc::testing::InitBenchmark(&argc, &argv, true);
-
-  grpc::testing::QpsDriver();
-
-  return 0;
-}
diff --git a/test/cpp/qps/qps_interarrival_test.cc b/test/cpp/qps/qps_interarrival_test.cc
index 48585af..4055c8a 100644
--- a/test/cpp/qps/qps_interarrival_test.cc
+++ b/test/cpp/qps/qps_interarrival_test.cc
@@ -63,14 +63,8 @@
 }
 
 using grpc::testing::ExpDist;
-using grpc::testing::DetDist;
-using grpc::testing::UniformDist;
-using grpc::testing::ParetoDist;
 
 int main(int argc, char **argv) {
   RunTest(ExpDist(10.0), 5, std::string("Exponential(10)"));
-  RunTest(DetDist(5.0), 5, std::string("Det(5)"));
-  RunTest(UniformDist(0.0, 10.0), 5, std::string("Uniform(0,10)"));
-  RunTest(ParetoDist(1.0, 1.0), 5, std::string("Pareto(1,1)"));
   return 0;
 }
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index 8943a43..b2e2457 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -48,6 +48,7 @@
               "JSON file containing an array of Scenario objects");
 DEFINE_string(scenarios_json, "",
               "JSON string containing an array of Scenario objects");
+DEFINE_bool(quit, false, "Quit the workers");
 
 namespace grpc {
 namespace testing {
@@ -55,12 +56,17 @@
 static void QpsDriver() {
   grpc::string json;
 
-  if (FLAGS_scenarios_file != "") {
-    if (FLAGS_scenarios_json != "") {
-      gpr_log(GPR_ERROR,
-              "Only one of --scenarios_file or --scenarios_json must be set");
-      abort();
-    }
+  bool scfile = (FLAGS_scenarios_file != "");
+  bool scjson = (FLAGS_scenarios_json != "");
+  if ((!scfile && !scjson && !FLAGS_quit) ||
+      (scfile && (scjson || FLAGS_quit)) || (scjson && FLAGS_quit)) {
+    gpr_log(GPR_ERROR,
+            "Exactly one of --scenarios_file, --scenarios_json, "
+            "or --quit must be set");
+    abort();
+  }
+
+  if (scfile) {
     // Read the json data from disk
     FILE *json_file = fopen(FLAGS_scenarios_file.c_str(), "r");
     GPR_ASSERT(json_file != NULL);
@@ -72,12 +78,11 @@
     fclose(json_file);
     json = grpc::string(data, data + len);
     delete[] data;
-  } else if (FLAGS_scenarios_json != "") {
+  } else if (scjson) {
     json = FLAGS_scenarios_json.c_str();
-  } else {
-    gpr_log(GPR_ERROR,
-            "One of --scenarios_file or --scenarios_json must be set");
-    abort();
+  } else if (FLAGS_quit) {
+    RunQuit();
+    return;
   }
 
   // Parse into an array of scenarios
@@ -102,12 +107,16 @@
   for (int i = 0; i < scenarios.scenarios_size(); i++) {
     const Scenario &scenario = scenarios.scenarios(i);
     std::cerr << "RUNNING SCENARIO: " << scenario.name() << "\n";
-    const auto result =
+    auto result =
         RunScenario(scenario.client_config(), scenario.num_clients(),
                     scenario.server_config(), scenario.num_servers(),
                     scenario.warmup_seconds(), scenario.benchmark_seconds(),
                     scenario.spawn_local_worker_count());
 
+    // Amend the result with scenario config. Eventually we should adjust
+    // RunScenario contract so we don't need to touch the result here.
+    result->mutable_scenario()->CopyFrom(scenario);
+
     GetReporter()->ReportQPS(*result);
     GetReporter()->ReportQPSPerCore(*result);
     GetReporter()->ReportLatency(*result);
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
index b230eb4..3ae4139 100644
--- a/test/cpp/qps/report.cc
+++ b/test/cpp/qps/report.cc
@@ -33,6 +33,11 @@
 
 #include "test/cpp/qps/report.h"
 
+#include <fstream>
+
+#include <google/protobuf/util/json_util.h>
+#include <google/protobuf/util/type_resolver_util.h>
+
 #include <grpc/support/log.h>
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/stats.h"
@@ -40,11 +45,6 @@
 namespace grpc {
 namespace testing {
 
-static double WallTime(ResourceUsage u) { return u.wall_time(); }
-static double UserTime(ResourceUsage u) { return u.user_time(); }
-static double SystemTime(ResourceUsage u) { return u.system_time(); }
-static int Cores(ResourceUsage u) { return u.cores(); }
-
 void CompositeReporter::add(std::unique_ptr<Reporter> reporter) {
   reporters_.emplace_back(std::move(reporter));
 }
@@ -74,102 +74,63 @@
 }
 
 void GprLogReporter::ReportQPS(const ScenarioResult& result) {
-  gpr_log(
-      GPR_INFO, "QPS: %.1f",
-      result.latencies.Count() / average(result.client_resources, WallTime));
+  gpr_log(GPR_INFO, "QPS: %.1f", result.summary().qps());
 }
 
 void GprLogReporter::ReportQPSPerCore(const ScenarioResult& result) {
-  auto qps =
-      result.latencies.Count() / average(result.client_resources, WallTime);
-
-  gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", qps,
-          qps / sum(result.server_resources, Cores));
+  gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", result.summary().qps(),
+          result.summary().qps_per_server_core());
 }
 
 void GprLogReporter::ReportLatency(const ScenarioResult& result) {
   gpr_log(GPR_INFO,
           "Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us",
-          result.latencies.Percentile(50) / 1000,
-          result.latencies.Percentile(90) / 1000,
-          result.latencies.Percentile(95) / 1000,
-          result.latencies.Percentile(99) / 1000,
-          result.latencies.Percentile(99.9) / 1000);
+          result.summary().latency_50() / 1000,
+          result.summary().latency_90() / 1000,
+          result.summary().latency_95() / 1000,
+          result.summary().latency_99() / 1000,
+          result.summary().latency_999() / 1000);
 }
 
 void GprLogReporter::ReportTimes(const ScenarioResult& result) {
   gpr_log(GPR_INFO, "Server system time: %.2f%%",
-          100.0 * sum(result.server_resources, SystemTime) /
-              sum(result.server_resources, WallTime));
+          result.summary().server_system_time());
   gpr_log(GPR_INFO, "Server user time:   %.2f%%",
-          100.0 * sum(result.server_resources, UserTime) /
-              sum(result.server_resources, WallTime));
+          result.summary().server_user_time());
   gpr_log(GPR_INFO, "Client system time: %.2f%%",
-          100.0 * sum(result.client_resources, SystemTime) /
-              sum(result.client_resources, WallTime));
+          result.summary().client_system_time());
   gpr_log(GPR_INFO, "Client user time:   %.2f%%",
-          100.0 * sum(result.client_resources, UserTime) /
-              sum(result.client_resources, WallTime));
+          result.summary().client_user_time());
 }
 
-void PerfDbReporter::ReportQPS(const ScenarioResult& result) {
-  auto qps =
-      result.latencies.Count() / average(result.client_resources, WallTime);
+void JsonReporter::ReportQPS(const ScenarioResult& result) {
+  std::unique_ptr<google::protobuf::util::TypeResolver> type_resolver(
+      google::protobuf::util::NewTypeResolverForDescriptorPool(
+          "type.googleapis.com",
+          google::protobuf::DescriptorPool::generated_pool()));
+  grpc::string binary;
+  grpc::string json_string;
+  result.SerializeToString(&binary);
+  auto status = BinaryToJsonString(
+      type_resolver.get(), "type.googleapis.com/grpc.testing.ScenarioResult",
+      binary, &json_string);
+  GPR_ASSERT(status.ok());
 
-  perf_db_client_.setQps(qps);
-  perf_db_client_.setConfigs(result.client_config, result.server_config);
+  std::ofstream output_file(report_file_);
+  output_file << json_string;
+  output_file.close();
 }
 
-void PerfDbReporter::ReportQPSPerCore(const ScenarioResult& result) {
-  auto qps =
-      result.latencies.Count() / average(result.client_resources, WallTime);
-
-  auto qps_per_core = qps / sum(result.server_resources, Cores);
-
-  perf_db_client_.setQps(qps);
-  perf_db_client_.setQpsPerCore(qps_per_core);
-  perf_db_client_.setConfigs(result.client_config, result.server_config);
+void JsonReporter::ReportQPSPerCore(const ScenarioResult& result) {
+  // NOP - all reporting is handled by ReportQPS.
 }
 
-void PerfDbReporter::ReportLatency(const ScenarioResult& result) {
-  perf_db_client_.setLatencies(result.latencies.Percentile(50) / 1000,
-                               result.latencies.Percentile(90) / 1000,
-                               result.latencies.Percentile(95) / 1000,
-                               result.latencies.Percentile(99) / 1000,
-                               result.latencies.Percentile(99.9) / 1000);
-  perf_db_client_.setConfigs(result.client_config, result.server_config);
+void JsonReporter::ReportLatency(const ScenarioResult& result) {
+  // NOP - all reporting is handled by ReportQPS.
 }
 
-void PerfDbReporter::ReportTimes(const ScenarioResult& result) {
-  const double server_system_time = 100.0 *
-                                    sum(result.server_resources, SystemTime) /
-                                    sum(result.server_resources, WallTime);
-  const double server_user_time = 100.0 *
-                                  sum(result.server_resources, UserTime) /
-                                  sum(result.server_resources, WallTime);
-  const double client_system_time = 100.0 *
-                                    sum(result.client_resources, SystemTime) /
-                                    sum(result.client_resources, WallTime);
-  const double client_user_time = 100.0 *
-                                  sum(result.client_resources, UserTime) /
-                                  sum(result.client_resources, WallTime);
-
-  perf_db_client_.setTimes(server_system_time, server_user_time,
-                           client_system_time, client_user_time);
-  perf_db_client_.setConfigs(result.client_config, result.server_config);
-}
-
-void PerfDbReporter::SendData() {
-  // send data to performance database
-  bool data_state =
-      perf_db_client_.sendData(hashed_id_, test_name_, sys_info_, tag_);
-
-  // check state of data sending
-  if (data_state) {
-    gpr_log(GPR_INFO, "Data sent to performance database successfully");
-  } else {
-    gpr_log(GPR_INFO, "Data could not be sent to performance database");
-  }
+void JsonReporter::ReportTimes(const ScenarioResult& result) {
+  // NOP - all reporting is handled by ReportQPS.
 }
 
 }  // namespace testing
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
index 5caf3fe..8f04d84 100644
--- a/test/cpp/qps/report.h
+++ b/test/cpp/qps/report.h
@@ -104,33 +104,19 @@
   void ReportTimes(const ScenarioResult& result) GRPC_OVERRIDE;
 };
 
-/** Reporter for performance database tool */
-class PerfDbReporter : public Reporter {
+/** Dumps the report to a JSON file. */
+class JsonReporter : public Reporter {
  public:
-  PerfDbReporter(const string& name, const string& hashed_id,
-                 const string& test_name, const string& sys_info,
-                 const string& server_address, const string& tag)
-      : Reporter(name),
-        hashed_id_(hashed_id),
-        test_name_(test_name),
-        sys_info_(sys_info),
-        tag_(tag) {
-    perf_db_client_.init(grpc::CreateChannel(
-        server_address, grpc::InsecureChannelCredentials()));
-  }
-  ~PerfDbReporter() GRPC_OVERRIDE { SendData(); };
+  JsonReporter(const string& name, const string& report_file)
+      : Reporter(name), report_file_(report_file) {}
 
  private:
-  PerfDbClient perf_db_client_;
-  std::string hashed_id_;
-  std::string test_name_;
-  std::string sys_info_;
-  std::string tag_;
   void ReportQPS(const ScenarioResult& result) GRPC_OVERRIDE;
   void ReportQPSPerCore(const ScenarioResult& result) GRPC_OVERRIDE;
   void ReportLatency(const ScenarioResult& result) GRPC_OVERRIDE;
   void ReportTimes(const ScenarioResult& result) GRPC_OVERRIDE;
-  void SendData();
+
+  const string report_file_;
 };
 
 }  // namespace testing
diff --git a/test/cpp/util/benchmark_config.cc b/test/cpp/util/benchmark_config.cc
index 746d3d7..6fc8640 100644
--- a/test/cpp/util/benchmark_config.cc
+++ b/test/cpp/util/benchmark_config.cc
@@ -37,8 +37,8 @@
 DEFINE_bool(enable_log_reporter, true,
             "Enable reporting of benchmark results through GprLog");
 
-DEFINE_bool(report_metrics_db, false,
-            "True if metrics to be reported to performance database");
+DEFINE_string(scenario_result_file, "",
+              "Write JSON benchmark report to the file specified.");
 
 DEFINE_string(hashed_id, "", "Hash of the user id");
 
@@ -71,10 +71,9 @@
     composite_reporter->add(
         std::unique_ptr<Reporter>(new GprLogReporter("LogReporter")));
   }
-  if (FLAGS_report_metrics_db) {
+  if (FLAGS_scenario_result_file != "") {
     composite_reporter->add(std::unique_ptr<Reporter>(
-        new PerfDbReporter("PerfDbReporter", FLAGS_hashed_id, FLAGS_test_name,
-                           FLAGS_sys_info, FLAGS_server_address, FLAGS_tag)));
+        new JsonReporter("JsonReporter", FLAGS_scenario_result_file)));
   }
 
   return std::shared_ptr<Reporter>(composite_reporter);
diff --git a/third_party/boringssl b/third_party/boringssl
index 907ae62..c880e42 160000
--- a/third_party/boringssl
+++ b/third_party/boringssl
@@ -1 +1 @@
-Subproject commit 907ae62b9d81121cb86b604f83e6b811a43f7a87
+Subproject commit c880e42ba1c8032d4cdde2aba0541d8a9d9fa2e9
diff --git a/tools/codegen/core/gen_load_balancing_proto.sh b/tools/codegen/core/gen_nano_proto.sh
similarity index 78%
rename from tools/codegen/core/gen_load_balancing_proto.sh
rename to tools/codegen/core/gen_nano_proto.sh
index 339da0a..e2d2f67 100755
--- a/tools/codegen/core/gen_load_balancing_proto.sh
+++ b/tools/codegen/core/gen_nano_proto.sh
@@ -31,8 +31,16 @@
 
 #
 # Example usage:
-#   tools/codegen/core/gen_load_balancing_proto.sh \
+#   tools/codegen/core/gen_nano_proto.sh \
 #     src/proto/grpc/lb/v0/load_balancer.proto
+#     $PWD/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0
+#
+# Exit statuses:
+# 1: Incorrect number of arguments
+# 2: Input proto file (1st argument) doesn't exist or is not a regular file.
+# 3: Options file for nanopb not found in same dir as the input proto file.
+# 4: Output dir not an absolute path.
+# 5: Couldn't create output directory (2nd argument).
 
 read -r -d '' COPYRIGHT <<'EOF'
 /*
@@ -75,34 +83,37 @@
 echo "${COPYRIGHT/<YEAR>/$CURRENT_YEAR}" > $COPYRIGHT_FILE
 
 set -ex
-if [ $# -eq 0 ]; then
-  echo "Usage: $0 <load_balancer.proto> [output dir]"
+if [ $# -lt 2 ] || [ $# -gt 3 ]; then
+  echo "Usage: $0 <input.proto> <absolute path to output dir> [grpc path]"
   exit 1
 fi
 
-readonly GRPC_ROOT=$PWD
-
-OUTPUT_DIR="$GRPC_ROOT/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0"
-if [ $# -eq 2 ]; then
-  mkdir -p "$2"
-  if [ $? != 0 ]; then
-    echo "Error creating output directory $2"
-    exit 2
-  fi
-  OUTPUT_DIR="$2"
-fi
-
+readonly GRPC_ROOT="$PWD"
+readonly INPUT_PROTO="$1"
+readonly OUTPUT_DIR="$2"
+readonly GRPC_OUTPUT_DIR="${3:-$OUTPUT_DIR}"
 readonly EXPECTED_OPTIONS_FILE_PATH="${1%.*}.options"
 
-if [[ ! -f "$1" ]]; then
-  echo "Input proto file '$1' doesn't exist."
-  exit 3
+if [[ ! -f "$INPUT_PROTO" ]]; then
+  echo "Input proto file '$INPUT_PROTO' doesn't exist."
+  exit 2
 fi
 if [[ ! -f "${EXPECTED_OPTIONS_FILE_PATH}" ]]; then
   echo "Expected nanopb options file '${EXPECTED_OPTIONS_FILE_PATH}' missing"
+  exit 3
+fi
+
+if [[ "${OUTPUT_DIR:0:1}" != '/' ]]; then
+  echo "The output directory must be an absolute path. Got '$OUTPUT_DIR'"
   exit 4
 fi
 
+mkdir -p "$OUTPUT_DIR"
+if [ $? != 0 ]; then
+  echo "Error creating output directory $OUTPUT_DIR"
+  exit 5
+fi
+
 readonly VENV_DIR=$(mktemp -d)
 readonly VENV_NAME="nanopb-$(date '+%Y%m%d_%H%M%S_%N')"
 pushd $VENV_DIR
@@ -114,16 +125,16 @@
 # ideally we'd update this as a template to ensure that
 pip install protobuf==3.0.0b2
 
-pushd "$(dirname $1)" > /dev/null
+pushd "$(dirname $INPUT_PROTO)" > /dev/null
 
 protoc \
 --plugin=protoc-gen-nanopb="$GRPC_ROOT/third_party/nanopb/generator/protoc-gen-nanopb" \
 --nanopb_out='-T -L#include\ \"third_party/nanopb/pb.h\"'":$OUTPUT_DIR" \
-"$(basename $1)"
+"$(basename $INPUT_PROTO)"
 
-readonly PROTO_BASENAME=$(basename $1 .proto)
-sed -i "s:$PROTO_BASENAME.pb.h:src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/$PROTO_BASENAME.pb.h:g" \
-    "$OUTPUT_DIR/$PROTO_BASENAME.pb.c"
+readonly PROTO_BASENAME=$(basename $INPUT_PROTO .proto)
+sed -i "s:$PROTO_BASENAME.pb.h:${GRPC_OUTPUT_DIR}/$PROTO_BASENAME.pb.h:g" \
+  "$OUTPUT_DIR/$PROTO_BASENAME.pb.c"
 
 # prepend copyright
 TMPFILE=$(mktemp)
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index b4ba02b..b38555e 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -205,6 +205,7 @@
 args = sys.argv[1:]
 H = None
 C = None
+D = None
 if args:
   if 'header' in args:
     H = sys.stdout
@@ -214,11 +215,17 @@
     C = sys.stdout
   else:
     C = open('/dev/null', 'w')
+  if 'dictionary' in args:
+    D = sys.stdout
+  else:
+    D = open('/dev/null', 'w')
 else:
   H = open(os.path.join(
       os.path.dirname(sys.argv[0]), '../../../src/core/lib/transport/static_metadata.h'), 'w')
   C = open(os.path.join(
       os.path.dirname(sys.argv[0]), '../../../src/core/lib/transport/static_metadata.c'), 'w')
+  D = open(os.path.join(
+      os.path.dirname(sys.argv[0]), '../../../test/core/end2end/fuzzers/hpack.dictionary'), 'w')
 
 # copy-paste copyright notice from this file
 with open(sys.argv[0]) as my_source:
@@ -235,6 +242,22 @@
     copyright.append(line)
   put_banner([H,C], [line[2:].rstrip() for line in copyright])
 
+
+hex_bytes = [ord(c) for c in "abcdefABCDEF0123456789"]
+
+
+def esc_dict(line):
+  out = "\""
+  for c in line:
+    if 32 <= c < 127:
+      if c != ord('"'):
+        out += chr(c)
+      else:
+        out += "\\\""
+    else:
+      out += "\\x%02X" % c
+  return out + "\""
+
 put_banner([H,C],
 """WARNING: Auto-generated code.
 
@@ -263,6 +286,13 @@
 print >>C, 'grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];'
 print >>C
 
+print >>D, '# hpack fuzzing dictionary'
+for i, elem in enumerate(all_strs):
+  print >>D, '%s' % (esc_dict([len(elem)] + [ord(c) for c in elem]))
+for i, elem in enumerate(all_elems):
+  print >>D, '%s' % (esc_dict([0, len(elem[0])] + [ord(c) for c in elem[0]] +
+                              [len(elem[1])] + [ord(c) for c in elem[1]]))
+
 print >>H, '#define GRPC_STATIC_MDELEM_COUNT %d' % len(all_elems)
 print >>H, 'extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];'
 print >>H, 'extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];'
diff --git a/tools/distrib/check_nanopb_output.sh b/tools/distrib/check_nanopb_output.sh
index 4f68e4c..92cb8ec 100755
--- a/tools/distrib/check_nanopb_output.sh
+++ b/tools/distrib/check_nanopb_output.sh
@@ -31,36 +31,42 @@
 set -ex
 
 readonly NANOPB_TMP_OUTPUT="$(mktemp -d)"
+readonly PROTOBUF_INSTALL_PREFIX="$(mktemp -d)"
 
 # install protoc version 3
 pushd third_party/protobuf
 ./autogen.sh
-./configure
+./configure --prefix="$PROTOBUF_INSTALL_PREFIX"
 make
 make install
-ldconfig
+#ldconfig
 popd
 
-if [ ! -x "/usr/local/bin/protoc" ]; then
-  echo "Error: protoc not found in path"
+readonly PROTOC_BIN_PATH="$PROTOBUF_INSTALL_PREFIX/bin"
+if [ ! -x "$PROTOBUF_INSTALL_PREFIX/bin/protoc" ]; then
+  echo "Error: protoc not found in temp install dir '$PROTOBUF_INSTALL_PREFIX'"
   exit 1
 fi
-readonly PROTOC_PATH='/usr/local/bin'
+
 # stack up and change to nanopb's proto generator directory
 pushd third_party/nanopb/generator/proto
-PATH="$PROTOC_PATH:$PATH" make
-
+export PATH="$PROTOC_BIN_PATH:$PATH"
+make
 # back to the root directory
 popd
 
-
+#
+# Checks for load_balancer.proto
+#
+readonly LOAD_BALANCER_GRPC_OUTPUT_PATH='src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0'
 # nanopb-compile the proto to a temp location
-PATH="$PROTOC_PATH:$PATH" ./tools/codegen/core/gen_load_balancing_proto.sh \
+./tools/codegen/core/gen_nano_proto.sh \
   src/proto/grpc/lb/v0/load_balancer.proto \
-  $NANOPB_TMP_OUTPUT
+  "$NANOPB_TMP_OUTPUT" \
+  "$LOAD_BALANCER_GRPC_OUTPUT_PATH"
 
 # compare outputs to checked compiled code
 if ! diff -r $NANOPB_TMP_OUTPUT src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0; then
-  echo "Outputs differ: $NANOPB_TMP_OUTPUT vs src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0"
+  echo "Outputs differ: $NANOPB_TMP_OUTPUT vs $LOAD_BALANCER_GRPC_OUTPUT_PATH"
   exit 2
 fi
diff --git a/tools/dockerfile/grpc_interop_go/Dockerfile b/tools/dockerfile/grpc_interop_go/Dockerfile
index bb60f09..ec71a53 100644
--- a/tools/dockerfile/grpc_interop_go/Dockerfile
+++ b/tools/dockerfile/grpc_interop_go/Dockerfile
@@ -27,10 +27,10 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-FROM golang:1.4
+FROM golang:1.5
 
 # Using login shell removes Go from path, so we add it.
-RUN ln -s /usr/src/go/bin/go /usr/local/bin
+RUN ln -s /usr/local/go/bin/go /usr/local/bin
 
 # Define the default command.
 CMD ["bash"]
diff --git a/tools/dockerfile/grpc_interop_http2/Dockerfile b/tools/dockerfile/grpc_interop_http2/Dockerfile
index bb60f09..ec71a53 100644
--- a/tools/dockerfile/grpc_interop_http2/Dockerfile
+++ b/tools/dockerfile/grpc_interop_http2/Dockerfile
@@ -27,10 +27,10 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-FROM golang:1.4
+FROM golang:1.5
 
 # Using login shell removes Go from path, so we add it.
-RUN ln -s /usr/src/go/bin/go /usr/local/bin
+RUN ln -s /usr/local/go/bin/go /usr/local/bin
 
 # Define the default command.
 CMD ["bash"]
diff --git a/test/cpp/qps/single_run_localhost.sh b/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile
old mode 100755
new mode 100644
similarity index 73%
copy from test/cpp/qps/single_run_localhost.sh
copy to tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile
index f5356f1..2a875f5
--- a/test/cpp/qps/single_run_localhost.sh
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_go/Dockerfile
@@ -1,5 +1,4 @@
-#!/bin/sh
-# Copyright 2015, Google Inc.
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -28,29 +27,15 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-# performs a single qps run with one client and one server
+FROM golang:1.5
 
-set -ex
+# Google Cloud platform API libraries
+RUN apt-get update && apt-get install -y python-pip && apt-get clean
+RUN pip install --upgrade google-api-python-client
 
-cd $(dirname $0)/../../..
 
-killall qps_worker || true
+# Using login shell removes Go from path, so we add it.
+RUN ln -s /usr/local/go/bin/go /usr/local/bin
 
-config=opt
-
-NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'`
-
-make CONFIG=$config qps_worker qps_driver -j$NUMCPUS
-
-bins/$config/qps_worker -driver_port 10000 &
-PID1=$!
-bins/$config/qps_worker -driver_port 10010 &
-PID2=$!
-
-export QPS_WORKERS="localhost:10000,localhost:10010"
-
-bins/$config/qps_driver $*
-
-kill -2 $PID1 $PID2
-wait
-
+# Define the default command.
+CMD ["bash"]
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_go/build_interop_stress.sh b/tools/dockerfile/stress_test/grpc_interop_stress_go/build_interop_stress.sh
new file mode 100755
index 0000000..919d885
--- /dev/null
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_go/build_interop_stress.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Builds Go interop server, Stress client and metrics client in a base image.
+set -e
+
+# Clone just the grpc-go source code without any dependencies.
+# We are cloning from a local git repo that contains the right revision
+# to test instead of using "go get" to download from Github directly.
+git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc
+
+# Clone the 'grpc' repo. We just need this for the wrapper scripts under
+# grpc/tools/gcp/stress_tests
+git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+
+# copy service account keys if available
+cp -r /var/local/jenkins/service_account $HOME || true
+
+# Get dependencies from GitHub
+# NOTE: once grpc-go dependencies change, this needs to be updated manually
+# but we don't expect this to happen any time soon.
+go get github.com/golang/protobuf/proto
+go get golang.org/x/net/context
+go get golang.org/x/net/trace
+go get golang.org/x/oauth2
+go get google.golang.org/cloud
+
+# Build the interop server, stress client and stress metrics client
+(cd src/google.golang.org/grpc/interop/server && go install)
+(cd src/google.golang.org/grpc/stress/client && go install)
+(cd src/google.golang.org/grpc/stress/metrics_client && go install)
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile
new file mode 100644
index 0000000..69bef14
--- /dev/null
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_java/Dockerfile
@@ -0,0 +1,102 @@
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+FROM debian:jessie
+
+# Install Git and basic packages.
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  ccache \
+  curl \
+  gcc \
+  gcc-multilib \
+  git \
+  golang \
+  gyp \
+  lcov \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  perl \
+  strace \
+  python-dev \
+  python-setuptools \
+  python-yaml \
+  telnet \
+  unzip \
+  wget \
+  zip && apt-get clean
+
+#================
+# Build profiling
+RUN apt-get update && apt-get install -y time && apt-get clean
+
+# Prepare ccache
+RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
+RUN ln -s /usr/bin/ccache /usr/local/bin/g++
+RUN ln -s /usr/bin/ccache /usr/local/bin/cc
+RUN ln -s /usr/bin/ccache /usr/local/bin/c++
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
+
+#=================
+# C++ dependencies
+RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean
+
+# Google Cloud platform API libraries
+RUN apt-get update && apt-get install -y python-pip && apt-get clean
+RUN pip install --upgrade google-api-python-client
+
+
+# Install JDK 8 and Git
+#
+RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && \
+  echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && \
+  echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && \
+  apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886
+
+RUN apt-get update && apt-get -y install \
+      git \
+      libapr1 \
+      oracle-java8-installer \
+      && \
+    apt-get clean && rm -r /var/cache/oracle-jdk8-installer/
+
+ENV JAVA_HOME /usr/lib/jvm/java-8-oracle
+ENV PATH $PATH:$JAVA_HOME/bin
+
+
+# Define the default command.
+CMD ["bash"]
diff --git a/test/cpp/qps/single_run_localhost.sh b/tools/dockerfile/stress_test/grpc_interop_stress_java/build_interop_stress.sh
similarity index 67%
copy from test/cpp/qps/single_run_localhost.sh
copy to tools/dockerfile/stress_test/grpc_interop_stress_java/build_interop_stress.sh
index f5356f1..d4fdfbb 100755
--- a/test/cpp/qps/single_run_localhost.sh
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_java/build_interop_stress.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -27,30 +27,25 @@
 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Builds C++ interop server and client in a base image.
+set -e
 
-# performs a single qps run with one client and one server
+mkdir -p /var/local/git
+# grpc-java repo
+git clone --recursive --depth 1 /var/local/jenkins/grpc-java /var/local/git/grpc-java
 
-set -ex
+# grpc repo (for metrics client and for the stress test wrapper scripts)
+git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
 
-cd $(dirname $0)/../../..
+# Copy service account keys if available
+cp -r /var/local/jenkins/service_account $HOME || true
 
-killall qps_worker || true
+# First build the metrics client in grpc repo
+cd /var/local/git/grpc
+make metrics_client
 
-config=opt
-
-NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'`
-
-make CONFIG=$config qps_worker qps_driver -j$NUMCPUS
-
-bins/$config/qps_worker -driver_port 10000 &
-PID1=$!
-bins/$config/qps_worker -driver_port 10010 &
-PID2=$!
-
-export QPS_WORKERS="localhost:10000,localhost:10010"
-
-bins/$config/qps_driver $*
-
-kill -2 $PID1 $PID2
-wait
-
+# Build all interop test targets (which includes interop server and stress test
+# client) in grpc-java repo
+cd /var/local/git/grpc-java
+./gradlew :grpc-interop-testing:installDist -PskipCodegen=true
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index de6fd0d..034d9c6 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -786,6 +786,7 @@
 include/grpc/impl/codegen/sync_win32.h \
 include/grpc/impl/codegen/time.h \
 include/grpc/grpc_security.h \
+include/grpc/grpc_security_constants.h \
 include/grpc/census.h \
 include/grpc/support/alloc.h \
 include/grpc/support/atm.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index b131a55..4414758 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -786,6 +786,7 @@
 include/grpc/impl/codegen/sync_win32.h \
 include/grpc/impl/codegen/time.h \
 include/grpc/grpc_security.h \
+include/grpc/grpc_security_constants.h \
 include/grpc/census.h \
 src/core/lib/channel/channel_args.h \
 src/core/lib/channel/channel_stack.h \
@@ -903,6 +904,7 @@
 src/core/ext/client_config/lb_policy.h \
 src/core/ext/client_config/lb_policy_factory.h \
 src/core/ext/client_config/lb_policy_registry.h \
+src/core/ext/client_config/parse_address.h \
 src/core/ext/client_config/resolver.h \
 src/core/ext/client_config/resolver_factory.h \
 src/core/ext/client_config/resolver_registry.h \
@@ -1058,6 +1060,7 @@
 src/core/ext/client_config/lb_policy.c \
 src/core/ext/client_config/lb_policy_factory.c \
 src/core/ext/client_config/lb_policy_registry.c \
+src/core/ext/client_config/parse_address.c \
 src/core/ext/client_config/resolver.c \
 src/core/ext/client_config/resolver_factory.c \
 src/core/ext/client_config/resolver_registry.c \
diff --git a/tools/fuzzer/runners/client_fuzzer.sh b/tools/fuzzer/runners/client_fuzzer.sh
index 239d552..39bdbc8 100644
--- a/tools/fuzzer/runners/client_fuzzer.sh
+++ b/tools/fuzzer/runners/client_fuzzer.sh
@@ -31,9 +31,11 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=2048"
 
+flags="$flags -dict=test/core/end2end/fuzzers/hpack.dictionary"
+
 if [ "$jobs" != "1" ]
 then
-  flags="-jobs=$jobs -workers=$jobs"
+  flags="-jobs=$jobs -workers=$jobs $flags"
 fi
 
 if [ "$config" == "asan-trace-cmp" ]
diff --git a/tools/fuzzer/runners/hpack_parser_fuzzer_test.sh b/tools/fuzzer/runners/hpack_parser_fuzzer_test.sh
index e69b4b4..0cc468e 100644
--- a/tools/fuzzer/runners/hpack_parser_fuzzer_test.sh
+++ b/tools/fuzzer/runners/hpack_parser_fuzzer_test.sh
@@ -31,9 +31,11 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=512"
 
+flags="$flags -dict=test/core/end2end/fuzzers/hpack.dictionary"
+
 if [ "$jobs" != "1" ]
 then
-  flags="-jobs=$jobs -workers=$jobs"
+  flags="-jobs=$jobs -workers=$jobs $flags"
 fi
 
 if [ "$config" == "asan-trace-cmp" ]
diff --git a/tools/fuzzer/runners/http_fuzzer_test.sh b/tools/fuzzer/runners/http_fuzzer_test.sh
index c190ba4..a86d765 100644
--- a/tools/fuzzer/runners/http_fuzzer_test.sh
+++ b/tools/fuzzer/runners/http_fuzzer_test.sh
@@ -31,9 +31,10 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=2048"
 
+
 if [ "$jobs" != "1" ]
 then
-  flags="-jobs=$jobs -workers=$jobs"
+  flags="-jobs=$jobs -workers=$jobs $flags"
 fi
 
 if [ "$config" == "asan-trace-cmp" ]
diff --git a/tools/fuzzer/runners/json_fuzzer_test.sh b/tools/fuzzer/runners/json_fuzzer_test.sh
index 9fc6271..9d38ed8 100644
--- a/tools/fuzzer/runners/json_fuzzer_test.sh
+++ b/tools/fuzzer/runners/json_fuzzer_test.sh
@@ -31,9 +31,10 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=512"
 
+
 if [ "$jobs" != "1" ]
 then
-  flags="-jobs=$jobs -workers=$jobs"
+  flags="-jobs=$jobs -workers=$jobs $flags"
 fi
 
 if [ "$config" == "asan-trace-cmp" ]
diff --git a/tools/fuzzer/runners/nanopb_fuzzer_response_test.sh b/tools/fuzzer/runners/nanopb_fuzzer_response_test.sh
index bbcebf1..b55d23b 100644
--- a/tools/fuzzer/runners/nanopb_fuzzer_response_test.sh
+++ b/tools/fuzzer/runners/nanopb_fuzzer_response_test.sh
@@ -31,9 +31,10 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=128"
 
+
 if [ "$jobs" != "1" ]
 then
-  flags="-jobs=$jobs -workers=$jobs"
+  flags="-jobs=$jobs -workers=$jobs $flags"
 fi
 
 if [ "$config" == "asan-trace-cmp" ]
diff --git a/tools/fuzzer/runners/nanopb_fuzzer_serverlist_test.sh b/tools/fuzzer/runners/nanopb_fuzzer_serverlist_test.sh
index e9099ba..a75aad6 100644
--- a/tools/fuzzer/runners/nanopb_fuzzer_serverlist_test.sh
+++ b/tools/fuzzer/runners/nanopb_fuzzer_serverlist_test.sh
@@ -31,9 +31,10 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=128"
 
+
 if [ "$jobs" != "1" ]
 then
-  flags="-jobs=$jobs -workers=$jobs"
+  flags="-jobs=$jobs -workers=$jobs $flags"
 fi
 
 if [ "$config" == "asan-trace-cmp" ]
diff --git a/tools/fuzzer/runners/server_fuzzer.sh b/tools/fuzzer/runners/server_fuzzer.sh
index 28ca8b3..9d1d9dc 100644
--- a/tools/fuzzer/runners/server_fuzzer.sh
+++ b/tools/fuzzer/runners/server_fuzzer.sh
@@ -31,9 +31,11 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=2048"
 
+flags="$flags -dict=test/core/end2end/fuzzers/hpack.dictionary"
+
 if [ "$jobs" != "1" ]
 then
-  flags="-jobs=$jobs -workers=$jobs"
+  flags="-jobs=$jobs -workers=$jobs $flags"
 fi
 
 if [ "$config" == "asan-trace-cmp" ]
diff --git a/tools/fuzzer/runners/uri_fuzzer_test.sh b/tools/fuzzer/runners/uri_fuzzer_test.sh
index 7dac54e..8890a2b 100644
--- a/tools/fuzzer/runners/uri_fuzzer_test.sh
+++ b/tools/fuzzer/runners/uri_fuzzer_test.sh
@@ -31,9 +31,10 @@
 
 flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=128"
 
+
 if [ "$jobs" != "1" ]
 then
-  flags="-jobs=$jobs -workers=$jobs"
+  flags="-jobs=$jobs -workers=$jobs $flags"
 fi
 
 if [ "$config" == "asan-trace-cmp" ]
diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh
index c7272b6..478e04e 100755
--- a/tools/gce/linux_performance_worker_init.sh
+++ b/tools/gce/linux_performance_worker_init.sh
@@ -82,9 +82,12 @@
 
 # Python dependencies
 sudo pip install tabulate
+sudo pip install google-api-python-client
+
 curl -O https://bootstrap.pypa.io/get-pip.py
 sudo pypy get-pip.py
 sudo pypy -m pip install tabulate
+sudo pip install google-api-python-client
 
 # Node dependencies (nvm has to be installed under user jenkins)
 touch .profile
@@ -102,4 +105,8 @@
 gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
 curl -sSL https://get.rvm.io | bash -s stable --ruby
 
+# Install bundler (prerequisite for gRPC Ruby)
+source ~/.rvm/scripts/rvm
+gem install bundler
+
 # Java dependencies - nothing as we already have Java JDK 8
diff --git a/tools/gcp/stress_test/run_client.py b/tools/gcp/stress_test/run_client.py
index 9a4bc8a..2004bf6 100755
--- a/tools/gcp/stress_test/run_client.py
+++ b/tools/gcp/stress_test/run_client.py
@@ -31,6 +31,7 @@
 import datetime
 import os
 import re
+import resource
 import select
 import subprocess
 import sys
@@ -89,6 +90,11 @@
                examining logs). This is the reason why the script waits forever
                in case of failures
   """
+  # Set the 'core file' size to 'unlimited' so that 'core' files are generated
+  # if the client crashes (Note: This is not relevant for Java and Go clients)
+  resource.setrlimit(resource.RLIMIT_CORE,
+                     (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
+
   env = dict(os.environ)
   image_type = env['STRESS_TEST_IMAGE_TYPE']
   stress_client_cmd = env['STRESS_TEST_CMD'].split()
@@ -103,6 +109,11 @@
   dataset_id = env['DATASET_ID']
   summary_table_id = env['SUMMARY_TABLE_ID']
   qps_table_id = env['QPS_TABLE_ID']
+  # The following parameter is to inform us whether the stress client runs
+  # forever until forcefully stopped or will it naturally stop after sometime.
+  # This way, we know that the stress client process should not terminate (even
+  # if it does with a success exit code) and flag the termination as a failure
+  will_run_forever = env.get('WILL_RUN_FOREVER', '1')
 
   bq_helper = BigQueryHelper(run_id, image_type, pod_name, project_id,
                              dataset_id, summary_table_id, qps_table_id)
@@ -140,11 +151,12 @@
   while True:
     # Check if stress_client is still running. If so, collect metrics and upload
     # to BigQuery status table
+    # If stress_p.poll() is not None, it means that the stress client terminated
     if stress_p.poll() is not None:
       end_time = datetime.datetime.now().isoformat()
       event_type = EventType.SUCCESS
       details = 'End time: %s' % end_time
-      if stress_p.returncode != 0:
+      if will_run_forever == '1' or stress_p.returncode != 0:
         event_type = EventType.FAILURE
         details = 'Return code = %d. End time: %s' % (stress_p.returncode,
                                                       end_time)
diff --git a/tools/gcp/stress_test/run_server.py b/tools/gcp/stress_test/run_server.py
index 0d9a653..a666ae2 100755
--- a/tools/gcp/stress_test/run_server.py
+++ b/tools/gcp/stress_test/run_server.py
@@ -30,6 +30,7 @@
 
 import datetime
 import os
+import resource
 import select
 import subprocess
 import sys
@@ -56,6 +57,10 @@
          might want to connect to the pod for examining logs). This is the
          reason why the script waits forever in case of failures.
   """
+  # Set the 'core file' size to 'unlimited' so that 'core' files are generated
+  # if the server crashes (Note: This is not relevant for Java and Go servers)
+  resource.setrlimit(resource.RLIMIT_CORE,
+                     (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
 
   # Read the parameters from environment variables
   env = dict(os.environ)
@@ -69,13 +74,19 @@
   dataset_id = env['DATASET_ID']
   summary_table_id = env['SUMMARY_TABLE_ID']
   qps_table_id = env['QPS_TABLE_ID']
+  # The following parameter is to inform us whether the server runs forever
+  # until forcefully stopped or will it naturally stop after sometime.
+  # This way, we know that the process should not terminate (even if it does
+  # with a success exit code) and flag any termination as a failure.
+  will_run_forever = env.get('WILL_RUN_FOREVER', '1')
 
   logfile_name = env.get('LOGFILE_NAME')
 
   print('pod_name: %s, project_id: %s, run_id: %s, dataset_id: %s, '
-        'summary_table_id: %s, qps_table_id: %s') % (
-            pod_name, project_id, run_id, dataset_id, summary_table_id,
-            qps_table_id)
+        'summary_table_id: %s, qps_table_id: %s') % (pod_name, project_id,
+                                                     run_id, dataset_id,
+                                                     summary_table_id,
+                                                     qps_table_id)
 
   bq_helper = BigQueryHelper(run_id, image_type, pod_name, project_id,
                              dataset_id, summary_table_id, qps_table_id)
@@ -106,7 +117,8 @@
                               stderr=subprocess.STDOUT)
 
   returncode = stress_p.wait()
-  if returncode != 0:
+
+  if will_run_forever == '1' or returncode != 0:
     end_time = datetime.datetime.now().isoformat()
     event_type = EventType.FAILURE
     details = 'Returncode: %d; End time: %s' % (returncode, end_time)
diff --git a/tools/gcp/utils/big_query_utils.py b/tools/gcp/utils/big_query_utils.py
index c331a67..9dbc69c 100755
--- a/tools/gcp/utils/big_query_utils.py
+++ b/tools/gcp/utils/big_query_utils.py
@@ -71,16 +71,22 @@
 
 def create_table(big_query, project_id, dataset_id, table_id, table_schema,
                  description):
+  fields = [{'name': field_name,
+             'type': field_type,
+             'description': field_description
+             } for (field_name, field_type, field_description) in table_schema]
+  return create_table2(big_query, project_id, dataset_id, table_id,
+                       fields, description)
+
+
+def create_table2(big_query, project_id, dataset_id, table_id, fields_schema,
+                 description):
   is_success = True
 
   body = {
       'description': description,
       'schema': {
-          'fields': [{
-              'name': field_name,
-              'type': field_type,
-              'description': field_description
-          } for (field_name, field_type, field_description) in table_schema]
+          'fields': fields_schema
       },
       'tableReference': {
           'datasetId': dataset_id,
@@ -112,12 +118,14 @@
                                                  datasetId=dataset_id,
                                                  tableId=table_id,
                                                  body=body)
-    print body
     res = insert_req.execute(num_retries=NUM_RETRIES)
-    print res
+    if res.get('insertErrors', None):
+      print 'Error inserting rows! Response: %s' % res
+      is_success = False
   except HttpError as http_error:
-    print 'Error in inserting rows in the table %s' % table_id
+    print 'Error inserting rows to the table %s' % table_id
     is_success = False
+
   return is_success
 
 
diff --git a/tools/jenkins/build_interop_stress_image.sh b/tools/jenkins/build_interop_stress_image.sh
index 29c8ed6..31ffa75 100755
--- a/tools/jenkins/build_interop_stress_image.sh
+++ b/tools/jenkins/build_interop_stress_image.sh
@@ -48,6 +48,22 @@
 GRPC_ROOT=`pwd`
 MOUNT_ARGS="-v $GRPC_ROOT:/var/local/jenkins/grpc:ro"
 
+GRPC_JAVA_ROOT=`cd ../grpc-java && pwd`
+if [ "$GRPC_JAVA_ROOT" != "" ]
+then
+  MOUNT_ARGS+=" -v $GRPC_JAVA_ROOT:/var/local/jenkins/grpc-java:ro"
+else
+  echo "WARNING: grpc-java not found, it won't be mounted to the docker container."
+fi
+
+GRPC_GO_ROOT=`cd ../grpc-go && pwd`
+if [ "$GRPC_GO_ROOT" != "" ]
+then
+  MOUNT_ARGS+=" -v $GRPC_GO_ROOT:/var/local/jenkins/grpc-go:ro"
+else
+  echo "WARNING: grpc-go not found, it won't be mounted to the docker container."
+fi
+
 mkdir -p /tmp/ccache
 
 # Mount service account dir if available.
diff --git a/tools/jenkins/run_performance.sh b/tools/jenkins/run_performance.sh
index 8bbb894..903a144 100755
--- a/tools/jenkins/run_performance.sh
+++ b/tools/jenkins/run_performance.sh
@@ -34,103 +34,4 @@
 # Enter the gRPC repo root
 cd $(dirname $0)/../..
 
-[[ $* =~ '--latency_profile' ]] \
-	&& tools/profiling/latency_profile/run_latency_profile.sh \
-	|| true
-
-config=opt
-
-make CONFIG=$config qps_worker qps_driver -j8
-
-bins/$config/qps_worker -driver_port 10000 &
-PID1=$!
-bins/$config/qps_worker -driver_port 10010 &
-PID2=$!
-
-#
-# Put a timeout on these tests
-#
-((sleep 900; kill $$ && killall qps_worker && rm -f /tmp/qps-test.$$ )&)
-
-export QPS_WORKERS="localhost:10000,localhost:10010"
-
-# big is the size in bytes of large messages (0 is the size otherwise)
-big=65536
-
-# wide is the number of client channels in multi-channel tests (1 otherwise)
-wide=64
-
-# deep is the number of RPCs outstanding on a channel in non-ping-pong tests
-# (the value used is 1 otherwise)
-deep=100
-
-#
-# Get total core count
-cores=`grep -c ^processor /proc/cpuinfo`
-halfcores=`expr $cores / 2`
-
-for secure in true false; do
-  # Scenario 1: generic async streaming ping-pong (contentionless latency)
-  bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=1 \
-    --client_channels=1 --bbuf_req_size=0 --bbuf_resp_size=0 \
-    --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
-    --num_servers=1 --num_clients=1 \
-    --server_core_limit=$halfcores --client_core_limit=0
-
-  # Scenario 2: generic async streaming "unconstrained" (QPS)
-  bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
-    --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
-    --num_servers=1 --num_clients=0 \
-    --server_core_limit=$halfcores --client_core_limit=0 |& tee /tmp/qps-test.$$
-
-  # Scenario 2b: QPS with a single server core
-  bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
-    --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
-    --num_servers=1 --num_clients=0 --server_core_limit=1 --client_core_limit=0
-
-  # Scenario 2c: protobuf-based QPS
-  bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=$wide --simple_req_size=0 --simple_resp_size=0 \
-    --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
-    --num_servers=1 --num_clients=0 \
-    --server_core_limit=$halfcores --client_core_limit=0
-
-  # Scenario 3: Latency at sub-peak load (all clients equally loaded)
-  for loadfactor in 0.7; do
-    bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-      --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
-      --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
-      --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
-      --num_servers=1 --num_clients=0 --poisson_load=`awk -v lf=$loadfactor \
-      '$5 == "QPS:" {print int(lf * $6); exit}' /tmp/qps-test.$$` \
-      --server_core_limit=$halfcores --client_core_limit=0
-  done
-
-  rm /tmp/qps-test.$$
-
-  # Scenario 4: Single-channel bidirectional throughput test (like TCP_STREAM).
-  bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
-    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
-    --client_channels=1 --bbuf_req_size=$big --bbuf_resp_size=$big \
-    --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
-    --num_servers=1 --num_clients=1 \
-    --server_core_limit=$halfcores --client_core_limit=0
-
-  # Scenario 5: Sync unary ping-pong with protobufs
-  bins/$config/qps_driver --rpc_type=UNARY --client_type=SYNC_CLIENT \
-    --server_type=SYNC_SERVER --outstanding_rpcs_per_channel=1 \
-    --client_channels=1 --simple_req_size=0 --simple_resp_size=0 \
-    --secure_test=$secure --num_servers=1 --num_clients=1 \
-    --server_core_limit=$halfcores --client_core_limit=0
-
-done
-
-bins/$config/qps_driver --quit=true
-
-wait
+tools/run_tests/run_performance_tests.py -l c++ node ruby csharp
diff --git a/tools/run_tests/performance/bq_upload_result.py b/tools/run_tests/performance/bq_upload_result.py
new file mode 100755
index 0000000..ebd28f7
--- /dev/null
+++ b/tools/run_tests/performance/bq_upload_result.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python2.7
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Uploads performance benchmark result file to bigquery.
+
+import argparse
+import calendar
+import json
+import os
+import sys
+import time
+import uuid
+
+
+gcp_utils_dir = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), '../../gcp/utils'))
+sys.path.append(gcp_utils_dir)
+import big_query_utils
+
+
+_PROJECT_ID='grpc-testing'
+
+
+def _upload_scenario_result_to_bigquery(dataset_id, table_id, result_file):
+  bq = big_query_utils.create_big_query()
+  _create_results_table(bq, dataset_id, table_id)
+
+  with open(result_file, 'r') as f:
+    scenario_result = json.loads(f.read())
+
+  if not _insert_result(bq, dataset_id, table_id, scenario_result):
+    print 'Error uploading result to bigquery.'
+    sys.exit(1)
+
+
+def _insert_result(bq, dataset_id, table_id, scenario_result):
+  _flatten_result_inplace(scenario_result)
+  _populate_metadata_inplace(scenario_result)
+  row = big_query_utils.make_row(str(uuid.uuid4()), scenario_result)
+  return big_query_utils.insert_rows(bq,
+                                     _PROJECT_ID,
+                                     dataset_id,
+                                     table_id,
+                                     [row])
+
+
+def _create_results_table(bq, dataset_id, table_id):
+  with open(os.path.dirname(__file__) + '/scenario_result_schema.json', 'r') as f:
+    table_schema = json.loads(f.read())
+  desc = 'Results of performance benchmarks.'
+  return big_query_utils.create_table2(bq, _PROJECT_ID, dataset_id,
+                               table_id, table_schema, desc)
+
+
+def _flatten_result_inplace(scenario_result):
+  """Bigquery is not really great for handling deeply nested data
+  and repeated fields. To maintain values of some fields while keeping
+  the schema relatively simple, we artificially leave some of the fields
+  as JSON strings.
+  """
+  scenario_result['scenario']['clientConfig'] = json.dumps(scenario_result['scenario']['clientConfig'])
+  scenario_result['scenario']['serverConfig'] = json.dumps(scenario_result['scenario']['serverConfig'])
+  scenario_result['latencies'] = json.dumps(scenario_result['latencies'])
+  for stats in scenario_result['clientStats']:
+    stats['latencies'] = json.dumps(stats['latencies'])
+  scenario_result['serverCores'] = json.dumps(scenario_result['serverCores'])
+
+
+def _populate_metadata_inplace(scenario_result):
+  """Populates metadata based on environment variables set by Jenkins."""
+  # NOTE: Grabbing the Jenkins environment variables will only work if the
+  # driver is running locally on the same machine where Jenkins has started
+  # the job. For our setup, this is currently the case, so just assume that.
+  build_number = os.getenv('BUILD_NUMBER')
+  build_url = os.getenv('BUILD_URL')
+  job_name = os.getenv('JOB_NAME')
+  git_commit = os.getenv('GIT_COMMIT')
+  # actual commit is the actual head of PR that is getting tested
+  git_actual_commit = os.getenv('ghprbActualCommit')
+
+  utc_timestamp = str(calendar.timegm(time.gmtime()))
+  metadata = {'created': utc_timestamp}
+
+  if build_number:
+    metadata['buildNumber'] = build_number
+  if build_url:
+    metadata['buildUrl'] = build_url
+  if job_name:
+    metadata['jobName'] = job_name
+  if git_commit:
+    metadata['gitCommit'] = git_commit
+  if git_actual_commit:
+    metadata['gitActualCommit'] = git_actual_commit
+
+  scenario_result['metadata'] = metadata
+
+
+argp = argparse.ArgumentParser(description='Upload result to big query.')
+argp.add_argument('--bq_result_table', required=True, default=None, type=str,
+                  help='Bigquery "dataset.table" to upload results to.')
+argp.add_argument('--file_to_upload', default='scenario_result.json', type=str,
+                  help='Report file to upload.')
+
+args = argp.parse_args()
+
+dataset_id, table_id = args.bq_result_table.split('.', 2)
+_upload_scenario_result_to_bigquery(dataset_id, table_id, args.file_to_upload)
+print 'Successfully uploaded %s to BigQuery.\n' % args.file_to_upload
diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh
index 2c962cb..8cfe1c4 100755
--- a/tools/run_tests/performance/build_performance.sh
+++ b/tools/run_tests/performance/build_performance.sh
@@ -28,6 +28,7 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+source ~/.rvm/scripts/rvm
 set -ex
 
 cd $(dirname $0)/../../..
@@ -41,12 +42,19 @@
 # TODO(jtattermusch): not embedding OpenSSL breaks the C# build because
 # grpc_csharp_ext needs OpenSSL embedded and some intermediate files from
 # this build will be reused.
-make CONFIG=${CONFIG} EMBED_OPENSSL=true EMBED_ZLIB=true qps_worker qps_driver qps_json_driver -j8
+make CONFIG=${CONFIG} EMBED_OPENSSL=true EMBED_ZLIB=true qps_worker qps_json_driver -j8
 
 for language in $@
 do
-  if [ "$language" != "c++" ]
-  then
+  case "$language" in
+  "c++")
+    ;;  # C++ has already been built.
+  "java")
+    (cd ../grpc-java/ &&
+      ./gradlew -PskipCodegen=true :grpc-benchmarks:installDist)
+    ;;
+  *)
     tools/run_tests/run_tests.py -l $language -c $CONFIG --build_only -j 8
-  fi
+    ;;
+  esac
 done
diff --git a/tools/run_tests/performance/remote_host_prepare.sh b/tools/run_tests/performance/remote_host_prepare.sh
index 18633d1..17cfa1a 100755
--- a/tools/run_tests/performance/remote_host_prepare.sh
+++ b/tools/run_tests/performance/remote_host_prepare.sh
@@ -38,7 +38,12 @@
 # TODO(jtattermusch): To be sure there are no running processes that would
 # mess with the results, be rough and reboot the slave here
 # and wait for it to come back online.
-ssh "${USER_AT_HOST}" "killall qps_worker mono node || true"
+# could also kill jenkins.
+ssh "${USER_AT_HOST}" "killall -9 qps_worker mono node ruby || true"
+
+# Kill all java LoadWorker processes. We can't just killall java
+# as one of the processes might be jenkins.
+ssh "${USER_AT_HOST}" 'kill -9 $(jps | grep LoadWorker | cut -f1 -d" ") || true'
 
 # push the current sources to the slave and unpack it.
 scp ../grpc.tar "${USER_AT_HOST}:~/performance_workspace"
diff --git a/test/cpp/qps/single_run_localhost.sh b/tools/run_tests/performance/run_qps_driver.sh
similarity index 76%
copy from test/cpp/qps/single_run_localhost.sh
copy to tools/run_tests/performance/run_qps_driver.sh
index f5356f1..c8c6890 100755
--- a/test/cpp/qps/single_run_localhost.sh
+++ b/tools/run_tests/performance/run_qps_driver.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -28,29 +28,13 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-# performs a single qps run with one client and one server
-
 set -ex
 
 cd $(dirname $0)/../../..
 
-killall qps_worker || true
+bins/opt/qps_json_driver "$@"
 
-config=opt
-
-NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'`
-
-make CONFIG=$config qps_worker qps_driver -j$NUMCPUS
-
-bins/$config/qps_worker -driver_port 10000 &
-PID1=$!
-bins/$config/qps_worker -driver_port 10010 &
-PID2=$!
-
-export QPS_WORKERS="localhost:10000,localhost:10010"
-
-bins/$config/qps_driver $*
-
-kill -2 $PID1 $PID2
-wait
-
+if [ "$BQ_RESULT_TABLE" != "" ]
+then
+  tools/run_tests/performance/bq_upload_result.py --bq_result_table="$BQ_RESULT_TABLE"
+fi
diff --git a/test/cpp/qps/single_run_localhost.sh b/tools/run_tests/performance/run_worker_java.sh
similarity index 76%
rename from test/cpp/qps/single_run_localhost.sh
rename to tools/run_tests/performance/run_worker_java.sh
index f5356f1..d5503a1 100755
--- a/test/cpp/qps/single_run_localhost.sh
+++ b/tools/run_tests/performance/run_worker_java.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -28,29 +28,12 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-# performs a single qps run with one client and one server
-
 set -ex
 
+# Enter repo root
 cd $(dirname $0)/../../..
 
-killall qps_worker || true
+# Enter the grpc-java repo root (expected to be next to grpc repo root)
+cd ../grpc-java
 
-config=opt
-
-NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'`
-
-make CONFIG=$config qps_worker qps_driver -j$NUMCPUS
-
-bins/$config/qps_worker -driver_port 10000 &
-PID1=$!
-bins/$config/qps_worker -driver_port 10010 &
-PID2=$!
-
-export QPS_WORKERS="localhost:10000,localhost:10010"
-
-bins/$config/qps_driver $*
-
-kill -2 $PID1 $PID2
-wait
-
+benchmarks/build/install/grpc-benchmarks/bin/benchmark_worker $@
diff --git a/test/cpp/qps/single_run_localhost.sh b/tools/run_tests/performance/run_worker_ruby.sh
similarity index 76%
copy from test/cpp/qps/single_run_localhost.sh
copy to tools/run_tests/performance/run_worker_ruby.sh
index f5356f1..4318734 100755
--- a/test/cpp/qps/single_run_localhost.sh
+++ b/tools/run_tests/performance/run_worker_ruby.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -28,29 +28,9 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-# performs a single qps run with one client and one server
-
+source ~/.rvm/scripts/rvm
 set -ex
 
 cd $(dirname $0)/../../..
 
-killall qps_worker || true
-
-config=opt
-
-NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'`
-
-make CONFIG=$config qps_worker qps_driver -j$NUMCPUS
-
-bins/$config/qps_worker -driver_port 10000 &
-PID1=$!
-bins/$config/qps_worker -driver_port 10010 &
-PID2=$!
-
-export QPS_WORKERS="localhost:10000,localhost:10010"
-
-bins/$config/qps_driver $*
-
-kill -2 $PID1 $PID2
-wait
-
+ruby src/ruby/qps/worker.rb $@
diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py
index 7a82d25..cf3c8ae 100644
--- a/tools/run_tests/performance/scenario_config.py
+++ b/tools/run_tests/performance/scenario_config.py
@@ -31,8 +31,14 @@
 
 SINGLE_MACHINE_CORES=8
 WARMUP_SECONDS=5
+JAVA_WARMUP_SECONDS=15  # Java needs more warmup time for JIT to kick in.
 BENCHMARK_SECONDS=30
 
+HISTOGRAM_PARAMS = {
+  'resolution': 0.01,
+  'max_possible': 60e9,
+}
+
 EMPTY_GENERIC_PAYLOAD = {
   'bytebuf_params': {
     'req_size': 0,
@@ -83,7 +89,7 @@
         secargs = None
 
       yield {
-          'name': 'generic_async_streaming_ping_pong_%s'
+          'name': 'cpp_generic_async_streaming_ping_pong_%s'
                   % secstr,
           'num_servers': 1,
           'num_clients': 1,
@@ -98,60 +104,7 @@
               'closed_loop': {}
             },
             'payload_config': EMPTY_GENERIC_PAYLOAD,
-          },
-          'server_config': {
-            'server_type': 'ASYNC_GENERIC_SERVER',
-            'security_params': secargs,
-            'core_limit': SINGLE_MACHINE_CORES/2,
-            'async_server_threads': 1,
-            'payload_config': EMPTY_GENERIC_PAYLOAD,
-          },
-          'warmup_seconds': WARMUP_SECONDS,
-          'benchmark_seconds': BENCHMARK_SECONDS
-      }
-      yield {
-          'name': 'generic_async_streaming_qps_unconstrained_%s'
-                  % secstr,
-          'num_servers': 1,
-          'num_clients': 0,
-          'client_config': {
-            'client_type': 'ASYNC_CLIENT',
-            'security_params': secargs,
-            'outstanding_rpcs_per_channel': DEEP,
-            'client_channels': WIDE,
-            'async_client_threads': 1,
-            'rpc_type': 'STREAMING',
-            'load_params': {
-              'closed_loop': {}
-            },
-            'payload_config': EMPTY_GENERIC_PAYLOAD,
-          },
-          'server_config': {
-            'server_type': 'ASYNC_GENERIC_SERVER',
-            'security_params': secargs,
-            'core_limit': SINGLE_MACHINE_CORES/2,
-            'async_server_threads': 1,
-            'payload_config': EMPTY_GENERIC_PAYLOAD,
-          },
-          'warmup_seconds': WARMUP_SECONDS,
-          'benchmark_seconds': BENCHMARK_SECONDS
-      }
-      yield {
-          'name': 'generic_async_streaming_qps_one_server_core_%s'
-                  % secstr,
-          'num_servers': 1,
-          'num_clients': 0,
-          'client_config': {
-            'client_type': 'ASYNC_CLIENT',
-            'security_params': secargs,
-            'outstanding_rpcs_per_channel': DEEP,
-            'client_channels': WIDE,
-            'async_client_threads': 1,
-            'rpc_type': 'STREAMING',
-            'load_params': {
-              'closed_loop': {}
-            },
-            'payload_config': EMPTY_GENERIC_PAYLOAD,
+            'histogram_params': HISTOGRAM_PARAMS,
           },
           'server_config': {
             'server_type': 'ASYNC_GENERIC_SERVER',
@@ -164,7 +117,7 @@
           'benchmark_seconds': BENCHMARK_SECONDS
       }
       yield {
-          'name': 'protobuf_async_qps_unconstrained_%s'
+          'name': 'cpp_generic_async_streaming_qps_unconstrained_%s'
                   % secstr,
           'num_servers': 1,
           'num_clients': 0,
@@ -173,17 +126,46 @@
             'security_params': secargs,
             'outstanding_rpcs_per_channel': DEEP,
             'client_channels': WIDE,
-            'async_client_threads': 1,
+            'async_client_threads': 0,
             'rpc_type': 'STREAMING',
             'load_params': {
               'closed_loop': {}
             },
             'payload_config': EMPTY_GENERIC_PAYLOAD,
+            'histogram_params': HISTOGRAM_PARAMS,
           },
           'server_config': {
             'server_type': 'ASYNC_GENERIC_SERVER',
             'security_params': secargs,
             'core_limit': SINGLE_MACHINE_CORES/2,
+            'async_server_threads': 0,
+            'payload_config': EMPTY_GENERIC_PAYLOAD,
+          },
+          'warmup_seconds': WARMUP_SECONDS,
+          'benchmark_seconds': BENCHMARK_SECONDS
+      }
+      yield {
+          'name': 'cpp_generic_async_streaming_qps_one_server_core_%s'
+                  % secstr,
+          'num_servers': 1,
+          'num_clients': 0,
+          'client_config': {
+            'client_type': 'ASYNC_CLIENT',
+            'security_params': secargs,
+            'outstanding_rpcs_per_channel': DEEP,
+            'client_channels': WIDE,
+            'async_client_threads': 0,
+            'rpc_type': 'STREAMING',
+            'load_params': {
+              'closed_loop': {}
+            },
+            'payload_config': EMPTY_GENERIC_PAYLOAD,
+            'histogram_params': HISTOGRAM_PARAMS,
+          },
+          'server_config': {
+            'server_type': 'ASYNC_GENERIC_SERVER',
+            'security_params': secargs,
+            'core_limit': 1,
             'async_server_threads': 1,
             'payload_config': EMPTY_GENERIC_PAYLOAD,
           },
@@ -191,34 +173,62 @@
           'benchmark_seconds': BENCHMARK_SECONDS
       }
       yield {
-          'name': 'single_channel_throughput_%s'
+          'name': 'cpp_protobuf_async_streaming_qps_unconstrained_%s'
+                  % secstr,
+          'num_servers': 1,
+          'num_clients': 0,
+          'client_config': {
+            'client_type': 'ASYNC_CLIENT',
+            'security_params': secargs,
+            'outstanding_rpcs_per_channel': DEEP,
+            'client_channels': WIDE,
+            'async_client_threads': 0,
+            'rpc_type': 'STREAMING',
+            'load_params': {
+              'closed_loop': {}
+            },
+            'payload_config': EMPTY_PROTO_PAYLOAD,
+            'histogram_params': HISTOGRAM_PARAMS,
+          },
+          'server_config': {
+            'server_type': 'ASYNC_SERVER',
+            'security_params': secargs,
+            'core_limit': SINGLE_MACHINE_CORES/2,
+            'async_server_threads': 0,
+          },
+          'warmup_seconds': WARMUP_SECONDS,
+          'benchmark_seconds': BENCHMARK_SECONDS
+      }
+      yield {
+          'name': 'cpp_single_channel_throughput_%s'
                   % secstr,
           'num_servers': 1,
           'num_clients': 1,
           'client_config': {
             'client_type': 'ASYNC_CLIENT',
             'security_params': secargs,
-            'outstanding_rpcs_per_channel': 1,
+            'outstanding_rpcs_per_channel': DEEP,
             'client_channels': 1,
-            'async_client_threads': 1,
+            'async_client_threads': 0,
             'rpc_type': 'STREAMING',
             'load_params': {
               'closed_loop': {}
             },
             'payload_config': BIG_GENERIC_PAYLOAD,
+            'histogram_params': HISTOGRAM_PARAMS,
           },
           'server_config': {
             'server_type': 'ASYNC_GENERIC_SERVER',
             'security_params': secargs,
             'core_limit': SINGLE_MACHINE_CORES/2,
-            'async_server_threads': 1,
+            'async_server_threads': 0,
             'payload_config': BIG_GENERIC_PAYLOAD,
           },
           'warmup_seconds': WARMUP_SECONDS,
           'benchmark_seconds': BENCHMARK_SECONDS
       }
       yield {
-          'name': 'protobuf_async_ping_pong_%s'
+          'name': 'cpp_protobuf_async_streaming_ping_pong_%s'
                   % secstr,
           'num_servers': 1,
           'num_clients': 1,
@@ -233,13 +243,67 @@
               'closed_loop': {}
             },
             'payload_config': EMPTY_PROTO_PAYLOAD,
+            'histogram_params': HISTOGRAM_PARAMS,
           },
           'server_config': {
-            'server_type': 'ASYNC_GENERIC_SERVER',
+            'server_type': 'ASYNC_SERVER',
             'security_params': secargs,
-            'core_limit': SINGLE_MACHINE_CORES/2,
+            'core_limit': 1,
             'async_server_threads': 1,
+          },
+          'warmup_seconds': WARMUP_SECONDS,
+          'benchmark_seconds': BENCHMARK_SECONDS
+      }
+      yield {
+          'name': 'cpp_protobuf_sync_unary_ping_pong_%s'
+                  % secstr,
+          'num_servers': 1,
+          'num_clients': 1,
+          'client_config': {
+            'client_type': 'SYNC_CLIENT',
+            'security_params': secargs,
+            'outstanding_rpcs_per_channel': 1,
+            'client_channels': 1,
+            'async_client_threads': 0,
+            'rpc_type': 'UNARY',
+            'load_params': {
+              'closed_loop': {}
+            },
             'payload_config': EMPTY_PROTO_PAYLOAD,
+            'histogram_params': HISTOGRAM_PARAMS,
+          },
+          'server_config': {
+            'server_type': 'SYNC_SERVER',
+            'security_params': secargs,
+            'core_limit': 1,
+            'async_server_threads': 0,
+          },
+          'warmup_seconds': WARMUP_SECONDS,
+          'benchmark_seconds': BENCHMARK_SECONDS
+      }
+      yield {
+          'name': 'cpp_protobuf_async_unary_ping_pong_%s'
+                  % secstr,
+          'num_servers': 1,
+          'num_clients': 1,
+          'client_config': {
+            'client_type': 'ASYNC_CLIENT',
+            'security_params': secargs,
+            'outstanding_rpcs_per_channel': 1,
+            'client_channels': 1,
+            'async_client_threads': 1,
+            'rpc_type': 'UNARY',
+            'load_params': {
+              'closed_loop': {}
+            },
+            'payload_config': EMPTY_PROTO_PAYLOAD,
+            'histogram_params': HISTOGRAM_PARAMS,
+          },
+          'server_config': {
+            'server_type': 'ASYNC_SERVER',
+            'security_params': secargs,
+            'core_limit': 1,
+            'async_server_threads': 1,
           },
           'warmup_seconds': WARMUP_SECONDS,
           'benchmark_seconds': BENCHMARK_SECONDS
@@ -262,8 +326,9 @@
 
   def scenarios(self):
     # TODO(jtattermusch): add more scenarios
+    secargs = None
     yield {
-        'name': 'csharp_async_generic_streaming_ping_pong',
+        'name': 'csharp_generic_async_streaming_ping_pong',
         'num_servers': 1,
         'num_clients': 1,
         'client_config': {
@@ -277,17 +342,97 @@
             'closed_loop': {}
           },
           'payload_config': EMPTY_GENERIC_PAYLOAD,
+          'histogram_params': HISTOGRAM_PARAMS,
         },
         'server_config': {
           'server_type': 'ASYNC_GENERIC_SERVER',
           'security_params': secargs,
-          'core_limit': SINGLE_MACHINE_CORES/2,
+          'core_limit': 0,
           'async_server_threads': 1,
           'payload_config': EMPTY_GENERIC_PAYLOAD,
         },
         'warmup_seconds': WARMUP_SECONDS,
         'benchmark_seconds': BENCHMARK_SECONDS
     }
+    yield {
+        'name': 'csharp_protobuf_async_unary_ping_pong',
+        'num_servers': 1,
+        'num_clients': 1,
+        'client_config': {
+          'client_type': 'ASYNC_CLIENT',
+          'security_params': secargs,
+          'outstanding_rpcs_per_channel': 1,
+          'client_channels': 1,
+          'async_client_threads': 1,
+          'rpc_type': 'UNARY',
+          'load_params': {
+            'closed_loop': {}
+          },
+          'payload_config': EMPTY_PROTO_PAYLOAD,
+          'histogram_params': HISTOGRAM_PARAMS,
+        },
+        'server_config': {
+          'server_type': 'ASYNC_SERVER',
+          'security_params': secargs,
+          'core_limit': 0,
+          'async_server_threads': 1,
+        },
+        'warmup_seconds': WARMUP_SECONDS,
+        'benchmark_seconds': BENCHMARK_SECONDS
+    }
+    yield {
+        'name': 'csharp_protobuf_sync_to_async_unary_ping_pong',
+        'num_servers': 1,
+        'num_clients': 1,
+        'client_config': {
+          'client_type': 'SYNC_CLIENT',
+          'security_params': secargs,
+          'outstanding_rpcs_per_channel': 1,
+          'client_channels': 1,
+          'async_client_threads': 1,
+          'rpc_type': 'UNARY',
+          'load_params': {
+            'closed_loop': {}
+          },
+          'payload_config': EMPTY_PROTO_PAYLOAD,
+          'histogram_params': HISTOGRAM_PARAMS,
+        },
+        'server_config': {
+          'server_type': 'ASYNC_SERVER',
+          'security_params': secargs,
+          'core_limit': 0,
+          'async_server_threads': 1,
+        },
+        'warmup_seconds': WARMUP_SECONDS,
+        'benchmark_seconds': BENCHMARK_SECONDS
+    }
+    yield {
+        'name': 'csharp_to_cpp_protobuf_sync_unary_ping_pong',
+        'num_servers': 1,
+        'num_clients': 1,
+        'client_config': {
+          'client_type': 'SYNC_CLIENT',
+          'security_params': secargs,
+          'outstanding_rpcs_per_channel': 1,
+          'client_channels': 1,
+          'async_client_threads': 1,
+          'rpc_type': 'UNARY',
+          'load_params': {
+            'closed_loop': {}
+          },
+          'payload_config': EMPTY_PROTO_PAYLOAD,
+          'histogram_params': HISTOGRAM_PARAMS,
+        },
+        'server_config': {
+          'server_type': 'SYNC_SERVER',
+          'security_params': secargs,
+          'core_limit': 0,
+          'async_server_threads': 1,
+        },
+        'warmup_seconds': WARMUP_SECONDS,
+        'benchmark_seconds': BENCHMARK_SECONDS,
+        'SERVER_LANGUAGE': 'c++'  # recognized by run_performance_tests.py
+    }
 
   def __str__(self):
     return 'csharp'
@@ -307,8 +452,9 @@
 
   def scenarios(self):
     # TODO(jtattermusch): add more scenarios
+    secargs = None
     yield {
-        'name': 'node_sync_unary_ping_pong_protobuf',
+        'name': 'node_protobuf_unary_ping_pong',
         'num_servers': 1,
         'num_clients': 1,
         'client_config': {
@@ -317,18 +463,18 @@
           'outstanding_rpcs_per_channel': 1,
           'client_channels': 1,
           'async_client_threads': 1,
-          'rpc_type': 'STREAMING',
+          'rpc_type': 'UNARY',
           'load_params': {
             'closed_loop': {}
           },
           'payload_config': EMPTY_PROTO_PAYLOAD,
+          'histogram_params': HISTOGRAM_PARAMS,
         },
         'server_config': {
-          'server_type': 'ASYNC_GENERIC_SERVER',
+          'server_type': 'ASYNC_SERVER',
           'security_params': secargs,
-          'core_limit': SINGLE_MACHINE_CORES/2,
+          'core_limit': 0,
           'async_server_threads': 1,
-          'payload_config': EMPTY_PROTO_PAYLOAD,
         },
         'warmup_seconds': WARMUP_SECONDS,
         'benchmark_seconds': BENCHMARK_SECONDS
@@ -338,8 +484,102 @@
     return 'node'
 
 
+class RubyLanguage:
+
+  def __init__(self):
+    pass
+    self.safename = str(self)
+
+  def worker_cmdline(self):
+    return ['tools/run_tests/performance/run_worker_ruby.sh']
+
+  def worker_port_offset(self):
+    return 300
+
+  def scenarios(self):
+    # TODO(jtattermusch): add more scenarios
+    secargs = None
+    yield {
+        'name': 'ruby_protobuf_unary_ping_pong',
+        'num_servers': 1,
+        'num_clients': 1,
+        'client_config': {
+          'client_type': 'SYNC_CLIENT',
+          'security_params': secargs,
+          'outstanding_rpcs_per_channel': 1,
+          'client_channels': 1,
+          'async_client_threads': 1,
+          'rpc_type': 'UNARY',
+          'load_params': {
+            'closed_loop': {}
+          },
+          'payload_config': EMPTY_PROTO_PAYLOAD,
+          'histogram_params': HISTOGRAM_PARAMS,
+        },
+        'server_config': {
+          'server_type': 'SYNC_SERVER',
+          'security_params': secargs,
+          'core_limit': 0,
+          'async_server_threads': 1,
+        },
+        'warmup_seconds': WARMUP_SECONDS,
+        'benchmark_seconds': BENCHMARK_SECONDS
+    }
+
+  def __str__(self):
+    return 'ruby'
+
+
+class JavaLanguage:
+
+  def __init__(self):
+    pass
+    self.safename = str(self)
+
+  def worker_cmdline(self):
+    return ['tools/run_tests/performance/run_worker_java.sh']
+
+  def worker_port_offset(self):
+    return 400
+
+  def scenarios(self):
+    # TODO(jtattermusch): add more scenarios
+    secargs = None
+    yield {
+        'name': 'java_protobuf_unary_ping_pong',
+        'num_servers': 1,
+        'num_clients': 1,
+        'client_config': {
+          'client_type': 'SYNC_CLIENT',
+          'security_params': secargs,
+          'outstanding_rpcs_per_channel': 1,
+          'client_channels': 1,
+          'async_client_threads': 1,
+          'rpc_type': 'UNARY',
+          'load_params': {
+            'closed_loop': {}
+          },
+          'payload_config': EMPTY_PROTO_PAYLOAD,
+          'histogram_params': HISTOGRAM_PARAMS,
+        },
+        'server_config': {
+          'server_type': 'SYNC_SERVER',
+          'security_params': secargs,
+          'core_limit': 0,
+          'async_server_threads': 1,
+        },
+        'warmup_seconds': JAVA_WARMUP_SECONDS,
+        'benchmark_seconds': BENCHMARK_SECONDS
+    }
+
+  def __str__(self):
+    return 'java'
+
+
 LANGUAGES = {
     'c++' : CXXLanguage(),
     'csharp' : CSharpLanguage(),
     'node' : NodeLanguage(),
+    'ruby' : RubyLanguage(),
+    'java' : JavaLanguage(),
 }
diff --git a/tools/run_tests/performance/scenario_result_schema.json b/tools/run_tests/performance/scenario_result_schema.json
new file mode 100644
index 0000000..0325414
--- /dev/null
+++ b/tools/run_tests/performance/scenario_result_schema.json
@@ -0,0 +1,202 @@
+[
+  {
+    "name": "metadata",
+    "type": "RECORD",
+    "mode": "NULLABLE",
+    "fields": [
+      {
+        "name": "buildNumber",
+        "type": "INTEGER",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "buildUrl",
+        "type": "STRING",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "jobName",
+        "type": "STRING",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "gitCommit",
+        "type": "STRING",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "gitActualCommit",
+        "type": "STRING",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "created",
+        "type": "TIMESTAMP",
+        "mode": "NULLABLE"
+      }
+    ]
+  },
+  {
+    "name": "scenario",
+    "type": "RECORD",
+    "mode": "NULLABLE",
+    "fields": [
+      {
+        "name": "name",
+        "type": "STRING",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "clientConfig",
+        "type": "STRING",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "numClients",
+        "type": "INTEGER",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "serverConfig",
+        "type": "STRING",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "numServers",
+        "type": "INTEGER",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "warmupSeconds",
+        "type": "INTEGER",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "benchmarkSeconds",
+        "type": "INTEGER",
+        "mode": "NULLABLE"
+      }
+    ]
+  },
+  {
+    "name": "latencies",
+    "type": "STRING",
+    "mode": "NULLABLE"
+  },
+  {
+    "name": "clientStats",
+    "type": "RECORD",
+    "mode": "REPEATED",
+    "fields": [
+      {
+        "name": "latencies",
+        "type": "STRING",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "timeElapsed",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "timeUser",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "timeSystem",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      }
+    ]
+  },
+  {
+    "name": "serverStats",
+    "type": "RECORD",
+    "mode": "REPEATED",
+    "fields": [
+      {
+        "name": "timeElapsed",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "timeUser",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "timeSystem",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      }
+    ]
+  },
+  {
+    "name": "serverCores",
+    "type": "STRING",
+    "mode": "NULLABLE"
+  },
+  {
+    "name": "summary",
+    "type": "RECORD",
+    "mode": "NULLABLE",
+    "fields": [
+      {
+        "name": "qps",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "qpsPerServerCore",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "serverSystemTime",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "serverUserTime",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "clientSystemTime",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "clientUserTime",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "latency50",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "latency90",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "latency95",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "latency99",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "latency999",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      }
+    ]
+  }
+]
diff --git a/tools/run_tests/pre_build_ruby.sh b/tools/run_tests/pre_build_ruby.sh
index 569a1d0..e7074c4 100755
--- a/tools/run_tests/pre_build_ruby.sh
+++ b/tools/run_tests/pre_build_ruby.sh
@@ -33,7 +33,7 @@
 
 export GRPC_CONFIG=${CONFIG:-opt}
 
-# change to grpc's ruby directory
-cd $(dirname $0)/../../src/ruby
+# change to grpc repo root
+cd $(dirname $0)/../..
 
 bundle install
diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py
index 51ed35f..ada341a 100755
--- a/tools/run_tests/run_performance_tests.py
+++ b/tools/run_tests/run_performance_tests.py
@@ -37,10 +37,12 @@
 import multiprocessing
 import os
 import pipes
+import re
 import subprocess
 import sys
 import tempfile
 import time
+import traceback
 import uuid
 import performance.scenario_config as scenario_config
 
@@ -82,21 +84,28 @@
   else:
     host_and_port='localhost:%s' % port
 
+  # TODO(jtattermusch): with some care, we can calculate the right timeout
+  # of a worker from the sum of warmup + benchmark times for all the scenarios
   jobspec = jobset.JobSpec(
       cmdline=cmdline,
       shortname=shortname,
-      timeout_seconds=15*60)
+      timeout_seconds=30*60)
   return QpsWorkerJob(jobspec, language, host_and_port)
 
 
-def create_scenario_jobspec(scenario_json, workers, remote_host=None):
+def create_scenario_jobspec(scenario_json, workers, remote_host=None,
+                            bq_result_table=None):
   """Runs one scenario using QPS driver."""
   # setting QPS_WORKERS env variable here makes sure it works with SSH too.
-  cmd = 'QPS_WORKERS="%s" bins/opt/qps_json_driver ' % ','.join(workers)
-  cmd += '--scenarios_json=%s' % pipes.quote(json.dumps({'scenarios': [scenario_json]}))
+  cmd = 'QPS_WORKERS="%s" ' % ','.join(workers)
+  if bq_result_table:
+    cmd += 'BQ_RESULT_TABLE="%s" ' % bq_result_table
+  cmd += 'tools/run_tests/performance/run_qps_driver.sh '
+  cmd += '--scenarios_json=%s ' % pipes.quote(json.dumps({'scenarios': [scenario_json]}))
+  cmd += '--scenario_result_file=scenario_result.json'
   if remote_host:
     user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host)
-    cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && %s"' % (user_at_host, cmd)
+    cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && "%s' % (user_at_host, pipes.quote(cmd))
 
   return jobset.JobSpec(
       cmdline=[cmd],
@@ -109,24 +118,29 @@
 def create_quit_jobspec(workers, remote_host=None):
   """Runs quit using QPS driver."""
   # setting QPS_WORKERS env variable here makes sure it works with SSH too.
-  cmd = 'QPS_WORKERS="%s" bins/opt/qps_driver --quit' % ','.join(workers)
+  cmd = 'QPS_WORKERS="%s" bins/opt/qps_json_driver --quit' % ','.join(workers)
   if remote_host:
     user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host)
-    cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && %s"' % (user_at_host, cmd)
+    cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && "%s' % (user_at_host, pipes.quote(cmd))
 
   return jobset.JobSpec(
       cmdline=[cmd],
-      shortname='qps_driver.quit',
+      shortname='qps_json_driver.quit',
       timeout_seconds=3*60,
       shell=True,
       verbose_success=True)
 
 
-def archive_repo():
+def archive_repo(languages):
   """Archives local version of repo including submodules."""
-  # TODO: also archive grpc-go and grpc-java repos
+  cmdline=['tar', '-cf', '../grpc.tar', '../grpc/']
+  if 'java' in languages:
+    cmdline.append('../grpc-java')
+  if 'go' in languages:
+    cmdline.append('../grpc-go')
+
   archive_job = jobset.JobSpec(
-      cmdline=['tar', '-cf', '../grpc.tar', '../grpc/'],
+      cmdline=cmdline,
       shortname='archive_repo',
       timeout_seconds=3*60)
 
@@ -135,7 +149,7 @@
       [archive_job], newline_on_success=True, maxjobs=1)
   if num_failures == 0:
     jobset.message('SUCCESS',
-                   'Archive with local repository create successfully.',
+                   'Archive with local repository created successfully.',
                    do_newline=True)
   else:
     jobset.message('FAILED', 'Failed to archive local repository.',
@@ -221,15 +235,32 @@
           for worker_idx, worker in enumerate(workers)]
 
 
-def create_scenarios(languages, workers_by_lang, remote_host=None):
+def create_scenarios(languages, workers_by_lang, remote_host=None, regex='.*',
+                     bq_result_table=None):
   """Create jobspecs for scenarios to run."""
   scenarios = []
   for language in languages:
     for scenario_json in language.scenarios():
-      scenario = create_scenario_jobspec(scenario_json,
-                                         workers_by_lang[str(language)],
-                                         remote_host=remote_host)
-      scenarios.append(scenario)
+      if re.search(args.regex, scenario_json['name']):
+        workers = workers_by_lang[str(language)]
+        # 'SERVER_LANGUAGE' is an indicator for this script to pick
+        # a server in different language. It doesn't belong to the Scenario
+        # schema, so we also need to remove it.
+        custom_server_lang = scenario_json.pop('SERVER_LANGUAGE', None)
+        if custom_server_lang:
+          if not workers_by_lang.get(custom_server_lang, []):
+            print 'Warning: Skipping scenario %s as' % scenario_json['name']
+            print('SERVER_LANGUAGE is set to %s yet the language has '
+                  'not been selected with -l' % custom_server_lang)
+            continue
+          for idx in range(0, scenario_json['num_servers']):
+            # replace first X workers by workers of a different language
+            workers[idx] = workers_by_lang[custom_server_lang][idx]
+        scenario = create_scenario_jobspec(scenario_json,
+                                           workers,
+                                           remote_host=remote_host,
+                                           bq_result_table=bq_result_table)
+        scenarios.append(scenario)
 
   # the very last scenario requests shutting down the workers.
   all_workers = [worker
@@ -268,6 +299,10 @@
                   nargs='+',
                   default=[],
                   help='Worker hosts where to start QPS workers.')
+argp.add_argument('-r', '--regex', default='.*', type=str,
+                  help='Regex to select scenarios to run.')
+argp.add_argument('--bq_result_table', default=None, type=str,
+                  help='Bigquery "dataset.table" to upload results to.')
 
 args = argp.parse_args()
 
@@ -276,6 +311,7 @@
                       scenario_config.LANGUAGES.iterkeys() if x == 'all' else [x]
                       for x in args.language))
 
+
 # Put together set of remote hosts where to run and build
 remote_hosts = set()
 if args.remote_worker_host:
@@ -285,7 +321,7 @@
   remote_hosts.add(args.remote_driver_host)
 
 if remote_hosts:
-  archive_repo()
+  archive_repo(languages=[str(l) for l in languages])
   prepare_remote_hosts(remote_hosts)
 
 build_local = False
@@ -295,6 +331,9 @@
 
 qpsworker_jobs = start_qpsworkers(languages, args.remote_worker_host)
 
+# TODO(jtattermusch): see https://github.com/grpc/grpc/issues/6174
+time.sleep(5)
+
 # get list of worker addresses for each language.
 worker_addresses = dict([(str(language), []) for language in languages])
 for job in qpsworker_jobs:
@@ -303,7 +342,9 @@
 try:
   scenarios = create_scenarios(languages,
                                workers_by_lang=worker_addresses,
-                               remote_host=args.remote_driver_host)
+                               remote_host=args.remote_driver_host,
+                               regex=args.regex,
+                               bq_result_table=args.bq_result_table)
   if not scenarios:
     raise Exception('No scenarios to run')
 
@@ -318,5 +359,8 @@
     jobset.message('FAILED', 'Some of the scenarios failed.',
                    do_newline=True)
     sys.exit(1)
+except:
+  traceback.print_exc()
+  raise
 finally:
   finish_qps_workers(qpsworker_jobs)
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index 06e66f0..3349d28 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -41,7 +41,7 @@
 
 git submodule | awk '{ print $1 }' | sort > $submodules
 cat << EOF | awk '{ print $1 }' | sort > $want_submodules
- 907ae62b9d81121cb86b604f83e6b811a43f7a87 third_party/boringssl (version_for_cocoapods_1.0-72-g907ae62)
+ c880e42ba1c8032d4cdde2aba0541d8a9d9fa2e9 third_party/boringssl (heads/2661)
  05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f)
  c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0)
  f8ac463766281625ad710900479130c7fcb4d63b third_party/nanopb (nanopb-0.3.4-29-gf8ac463)
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index ca409e3..01ecfae 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -2348,26 +2348,6 @@
       "gpr_test_util", 
       "grpc", 
       "grpc++", 
-      "grpc++_test_config", 
-      "grpc++_test_util", 
-      "grpc_test_util", 
-      "qps"
-    ], 
-    "headers": [], 
-    "language": "c++", 
-    "name": "qps_driver", 
-    "src": [
-      "test/cpp/qps/qps_driver.cc"
-    ], 
-    "third_party": false, 
-    "type": "target"
-  }, 
-  {
-    "deps": [
-      "gpr", 
-      "gpr_test_util", 
-      "grpc", 
-      "grpc++", 
       "grpc++_test_util", 
       "grpc_test_util", 
       "qps"
@@ -3209,6 +3189,19 @@
   {
     "deps": [
       "boringssl", 
+      "boringssl_test_util", 
+      "boringssl_x509_test_lib"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_x509_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
       "boringssl_tab_test_lib", 
       "boringssl_test_util"
     ], 
@@ -3691,6 +3684,23 @@
     ], 
     "headers": [], 
     "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "src": [
+      "test/core/end2end/fixtures/h2_ssl_cert.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "end2end_tests", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
     "name": "h2_ssl_proxy_test", 
     "src": [
       "test/core/end2end/fixtures/h2_ssl_proxy.c"
@@ -4097,6 +4107,7 @@
     "language": "c", 
     "name": "grpc_test_util", 
     "src": [
+      "test/core/end2end/data/client_certs.c", 
       "test/core/end2end/data/server1_cert.c", 
       "test/core/end2end/data/server1_key.c", 
       "test/core/end2end/data/ssl_test_data.h", 
@@ -4544,12 +4555,12 @@
       "third_party/boringssl/crypto/cipher/internal.h", 
       "third_party/boringssl/crypto/conf/conf_def.h", 
       "third_party/boringssl/crypto/conf/internal.h", 
+      "third_party/boringssl/crypto/curve25519/internal.h", 
       "third_party/boringssl/crypto/des/internal.h", 
       "third_party/boringssl/crypto/dh/internal.h", 
       "third_party/boringssl/crypto/digest/internal.h", 
       "third_party/boringssl/crypto/digest/md32_common.h", 
       "third_party/boringssl/crypto/directory.h", 
-      "third_party/boringssl/crypto/dsa/internal.h", 
       "third_party/boringssl/crypto/ec/internal.h", 
       "third_party/boringssl/crypto/ec/p256-x86_64-table.h", 
       "third_party/boringssl/crypto/evp/internal.h", 
@@ -5062,6 +5073,18 @@
       "boringssl_test_util"
     ], 
     "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_x509_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
     "language": "c", 
     "name": "boringssl_tab_test_lib", 
     "src": [], 
@@ -5997,6 +6020,7 @@
       "src/core/ext/client_config/lb_policy.h", 
       "src/core/ext/client_config/lb_policy_factory.h", 
       "src/core/ext/client_config/lb_policy_registry.h", 
+      "src/core/ext/client_config/parse_address.h", 
       "src/core/ext/client_config/resolver.h", 
       "src/core/ext/client_config/resolver_factory.h", 
       "src/core/ext/client_config/resolver_registry.h", 
@@ -6027,6 +6051,8 @@
       "src/core/ext/client_config/lb_policy_factory.h", 
       "src/core/ext/client_config/lb_policy_registry.c", 
       "src/core/ext/client_config/lb_policy_registry.h", 
+      "src/core/ext/client_config/parse_address.c", 
+      "src/core/ext/client_config/parse_address.h", 
       "src/core/ext/client_config/resolver.c", 
       "src/core/ext/client_config/resolver.h", 
       "src/core/ext/client_config/resolver_factory.c", 
@@ -6160,6 +6186,7 @@
     ], 
     "headers": [
       "include/grpc/grpc_security.h", 
+      "include/grpc/grpc_security_constants.h", 
       "src/core/lib/security/auth_filters.h", 
       "src/core/lib/security/b64.h", 
       "src/core/lib/security/credentials.h", 
@@ -6179,6 +6206,7 @@
     "name": "grpc_secure", 
     "src": [
       "include/grpc/grpc_security.h", 
+      "include/grpc/grpc_security_constants.h", 
       "src/core/lib/http/httpcli_security_connector.c", 
       "src/core/lib/security/auth_filters.h", 
       "src/core/lib/security/b64.c", 
@@ -6226,6 +6254,7 @@
       "test/core/end2end/fixtures/proxy.h", 
       "test/core/iomgr/endpoint_tests.h", 
       "test/core/util/grpc_profiler.h", 
+      "test/core/util/memory_counters.h", 
       "test/core/util/mock_endpoint.h", 
       "test/core/util/parse_hexstring.h", 
       "test/core/util/port.h", 
@@ -6243,6 +6272,8 @@
       "test/core/iomgr/endpoint_tests.h", 
       "test/core/util/grpc_profiler.c", 
       "test/core/util/grpc_profiler.h", 
+      "test/core/util/memory_counters.c", 
+      "test/core/util/memory_counters.h", 
       "test/core/util/mock_endpoint.c", 
       "test/core/util/mock_endpoint.h", 
       "test/core/util/parse_hexstring.c", 
diff --git a/tools/run_tests/stress_test/configs/go.json b/tools/run_tests/stress_test/configs/go.json
new file mode 100644
index 0000000..36b465e
--- /dev/null
+++ b/tools/run_tests/stress_test/configs/go.json
@@ -0,0 +1,96 @@
+{
+  "dockerImages": {
+    "grpc_stress_go" : {
+      "buildScript": "tools/jenkins/build_interop_stress_image.sh",
+      "dockerFileDir": "grpc_interop_stress_go"
+    }
+  },
+
+  "clientTemplates": {
+    "baseTemplates": {
+      "default": {
+        "wrapperScriptPath": "/var/local/git/grpc/tools/gcp/stress_test/run_client.py",
+        "pollIntervalSecs": 60,
+        "clientArgs": {
+          "num_channels_per_server":5,
+          "num_stubs_per_channel":10,
+          "test_cases": "empty_unary:1,large_unary:1,client_streaming:1,server_streaming:1,empty_stream:1",
+          "metrics_port": 8081
+        },
+        "metricsPort": 8081,
+        "metricsArgs": {
+          "metrics_server_address": "localhost:8081",
+          "total_only": "true"
+        }
+      }
+    },
+    "templates": {
+      "go_client": {
+        "baseTemplate": "default",
+        "stressClientCmd": [
+          "go",
+          "run",
+          "/go/src/google.golang.org/grpc/stress/client/main.go"
+        ],
+        "metricsClientCmd": [
+          "go",
+          "run",
+          "/go/src/google.golang.org/grpc/stress/metrics_client/main.go"
+        ]
+      }
+    }
+  },
+
+  "serverTemplates": {
+    "baseTemplates":{
+      "default": {
+        "wrapperScriptPath": "/var/local/git/grpc/tools/gcp/stress_test/run_server.py",
+        "serverPort": 8080,
+        "serverArgs": {
+          "port": 8080
+        }
+      }
+    },
+    "templates": {
+      "go_server": {
+        "baseTemplate": "default",
+        "stressServerCmd": [
+          "go",
+          "run",
+          "/go/src/google.golang.org/grpc/interop/server/server.go"
+        ]
+      }
+    }
+  },
+
+  "testMatrix": {
+    "serverPodSpecs": {
+      "go-stress-server": {
+        "serverTemplate": "go_server",
+        "dockerImage": "grpc_stress_go",
+        "numInstances": 1
+      }
+    },
+
+    "clientPodSpecs": {
+      "go-stress-client": {
+        "clientTemplate": "go_client",
+        "dockerImage": "grpc_stress_go",
+        "numInstances": 15,
+        "serverPodSpec": "go-stress-server"
+      }
+    }
+  },
+
+  "globalSettings": {
+    "buildDockerImages": true,
+    "pollIntervalSecs": 60,
+    "testDurationSecs": 7200,
+    "kubernetesProxyPort": 8007,
+    "datasetIdNamePrefix": "stress_test_go",
+    "summaryTableId": "summary",
+    "qpsTableId": "qps",
+    "podWarmupSecs": 60
+  }
+}
+
diff --git a/tools/run_tests/stress_test/configs/java.json b/tools/run_tests/stress_test/configs/java.json
new file mode 100644
index 0000000..275384c
--- /dev/null
+++ b/tools/run_tests/stress_test/configs/java.json
@@ -0,0 +1,91 @@
+{
+  "dockerImages": {
+    "grpc_stress_java" : {
+      "buildScript": "tools/jenkins/build_interop_stress_image.sh",
+      "dockerFileDir": "grpc_interop_stress_java"
+    }
+  },
+
+  "clientTemplates": {
+    "baseTemplates": {
+      "default": {
+        "wrapperScriptPath": "/var/local/git/grpc/tools/gcp/stress_test/run_client.py",
+        "pollIntervalSecs": 60,
+        "clientArgs": {
+          "num_channels_per_server":5,
+          "num_stubs_per_channel":10,
+          "test_cases": "empty_unary:1,large_unary:1,client_streaming:1,server_streaming:1,empty_stream:1",
+          "metrics_port": 8081
+        },
+        "metricsPort": 8081,
+        "metricsArgs": {
+          "metrics_server_address": "localhost:8081",
+          "total_only": "true"
+        }
+      }
+    },
+    "templates": {
+      "java_client": {
+        "baseTemplate": "default",
+        "stressClientCmd": [
+          "/var/local/git/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/stresstest-client"
+        ],
+        "metricsClientCmd": [
+          "/var/local/git/grpc/bins/opt/metrics_client"
+        ]
+      }
+    }
+  },
+
+  "serverTemplates": {
+    "baseTemplates":{
+      "default": {
+        "wrapperScriptPath": "/var/local/git/grpc/tools/gcp/stress_test/run_server.py",
+        "serverPort": 8080,
+        "serverArgs": {
+          "port": 8080,
+		  "use_tls": "false"
+        }
+      }
+    },
+    "templates": {
+      "java_server": {
+        "baseTemplate": "default",
+        "stressServerCmd": [
+          "/var/local/git/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/test-server"
+        ]
+      }
+    }
+  },
+
+  "testMatrix": {
+    "serverPodSpecs": {
+      "java-stress-server": {
+        "serverTemplate": "java_server",
+        "dockerImage": "grpc_stress_java",
+        "numInstances": 1
+      }
+    },
+
+    "clientPodSpecs": {
+      "java-stress-client": {
+        "clientTemplate": "java_client",
+        "dockerImage": "grpc_stress_java",
+        "numInstances": 10,
+        "serverPodSpec": "java-stress-server"
+      }
+    }
+  },
+
+  "globalSettings": {
+    "buildDockerImages": true,
+    "pollIntervalSecs": 60,
+    "testDurationSecs": 7200,
+    "kubernetesProxyPort": 8008,
+    "datasetIdNamePrefix": "stress_test_java",
+    "summaryTableId": "summary",
+    "qpsTableId": "qps",
+    "podWarmupSecs": 60
+  }
+}
+
diff --git a/tools/run_tests/stress_test/run_on_gke.py b/tools/run_tests/stress_test/run_on_gke.py
index 916c890..d4f1c4a 100755
--- a/tools/run_tests/stress_test/run_on_gke.py
+++ b/tools/run_tests/stress_test/run_on_gke.py
@@ -69,7 +69,7 @@
 
   def __init__(self, name, stress_client_cmd, metrics_client_cmd, metrics_port,
                wrapper_script_path, poll_interval_secs, client_args_dict,
-               metrics_args_dict):
+               metrics_args_dict, will_run_forever):
     self.name = name
     self.stress_client_cmd = stress_client_cmd
     self.metrics_client_cmd = metrics_client_cmd
@@ -78,18 +78,20 @@
     self.poll_interval_secs = poll_interval_secs
     self.client_args_dict = client_args_dict
     self.metrics_args_dict = metrics_args_dict
+    self.will_run_forever = will_run_forever
 
 
 class ServerTemplate:
   """ Contains all the common settings used by a stress server """
 
   def __init__(self, name, server_cmd, wrapper_script_path, server_port,
-               server_args_dict):
+               server_args_dict, will_run_forever):
     self.name = name
     self.server_cmd = server_cmd
     self.wrapper_script_path = wrapper_script_path
     self.server_port = server_port
     self.server_args_dict = server_args_dict
+    self.will_run_forever = will_run_forever
 
 
 class DockerImage:
@@ -242,7 +244,8 @@
         'STRESS_TEST_IMAGE_TYPE': 'SERVER',
         'STRESS_TEST_CMD': server_pod_spec.template.server_cmd,
         'STRESS_TEST_ARGS_STR': self._args_dict_to_str(
-            server_pod_spec.template.server_args_dict)
+            server_pod_spec.template.server_args_dict),
+        'WILL_RUN_FOREVER': str(server_pod_spec.template.will_run_forever)
     })
 
     for pod_name in server_pod_spec.pod_names():
@@ -288,7 +291,8 @@
         'METRICS_CLIENT_CMD': client_pod_spec.template.metrics_client_cmd,
         'METRICS_CLIENT_ARGS_STR': self._args_dict_to_str(
             client_pod_spec.template.metrics_args_dict),
-        'POLL_INTERVAL_SECS': str(client_pod_spec.template.poll_interval_secs)
+        'POLL_INTERVAL_SECS': str(client_pod_spec.template.poll_interval_secs),
+        'WILL_RUN_FOREVER': str(client_pod_spec.template.will_run_forever)
     })
 
     for pod_name in client_pod_spec.pod_names():
@@ -421,7 +425,7 @@
           template_name, stress_client_cmd, metrics_client_cmd,
           temp_dict['metricsPort'], temp_dict['wrapperScriptPath'],
           temp_dict['pollIntervalSecs'], temp_dict['clientArgs'].copy(),
-          temp_dict['metricsArgs'].copy())
+          temp_dict['metricsArgs'].copy(), temp_dict.get('willRunForever', 1))
 
     return client_templates_dict
 
@@ -456,7 +460,8 @@
       stress_server_cmd = ' '.join(temp_dict['stressServerCmd'])
       server_templates_dict[template_name] = ServerTemplate(
           template_name, stress_server_cmd, temp_dict['wrapperScriptPath'],
-          temp_dict['serverPort'], temp_dict['serverArgs'].copy())
+          temp_dict['serverPort'], temp_dict['serverArgs'].copy(),
+          temp_dict.get('willRunForever', 1))
 
     return server_templates_dict
 
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 5b7e747..cbac102 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -4256,6 +4256,30 @@
     ], 
     "flaky": false, 
     "language": "c++", 
+    "name": "boringssl_x509_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "defaults": "boringssl", 
+    "exclude_configs": [
+      "asan"
+    ], 
+    "flaky": false, 
+    "language": "c++", 
     "name": "boringssl_tab_test", 
     "platforms": [
       "linux", 
@@ -13435,6 +13459,842 @@
     "ci_platforms": [
       "windows", 
       "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "call_creds"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_accept"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_client_done"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_invoke"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_before_invoke"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_in_a_vacuum"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_with_status"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "compressed_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "connectivity"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "default_host"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "disappearing_server"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "empty_batch"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "filter_causes_close"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "graceful_server_shutdown"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "high_initial_seqno"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "hpack_size"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "idempotent_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "invoke_large_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "large_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_concurrent_streams"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_message_length"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "negative_deadline"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "no_op"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping_pong_streaming"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "registered_call"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_flags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "server_finishes_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_calls"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_tags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_delayed_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "trailing_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "bad_hostname"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -22035,7 +22895,7 @@
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"generic_async_streaming_ping_pong_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 4, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 1}'"
+      "'{\"name\": \"cpp_generic_async_streaming_ping_pong_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22056,12 +22916,12 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:generic_async_streaming_ping_pong_secure"
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_secure"
   }, 
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 4, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 0}'"
+      "'{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 4, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22082,12 +22942,12 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:generic_async_streaming_qps_unconstrained_secure"
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_secure"
   }, 
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 0}'"
+      "'{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22108,12 +22968,12 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:generic_async_streaming_qps_one_server_core_secure"
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_secure"
   }, 
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"protobuf_async_qps_unconstrained_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 4, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 0}'"
+      "'{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 4, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22134,12 +22994,12 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:protobuf_async_qps_unconstrained_secure"
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure"
   }, 
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"single_channel_throughput_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 4, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 1}'"
+      "'{\"name\": \"cpp_single_channel_throughput_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 4, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22160,12 +23020,12 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:single_channel_throughput_secure"
+    "shortname": "json_run_localhost:cpp_single_channel_throughput_secure"
   }, 
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"protobuf_async_ping_pong_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 4, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 1}'"
+      "'{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22186,12 +23046,12 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:protobuf_async_ping_pong_secure"
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_secure"
   }, 
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 4, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 1}'"
+      "'{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22212,12 +23072,12 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:generic_async_streaming_ping_pong_insecure"
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_secure"
   }, 
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 4, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 0}'"
+      "'{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22238,12 +23098,12 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:generic_async_streaming_qps_unconstrained_insecure"
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure"
   }, 
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 0}'"
+      "'{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22264,12 +23124,12 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:generic_async_streaming_qps_one_server_core_insecure"
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_insecure"
   }, 
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"protobuf_async_qps_unconstrained_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 4, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 0}'"
+      "'{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 4, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22290,12 +23150,12 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:protobuf_async_qps_unconstrained_insecure"
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_insecure"
   }, 
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"single_channel_throughput_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 4, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 1}'"
+      "'{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22316,12 +23176,12 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:single_channel_throughput_insecure"
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_insecure"
   }, 
   {
     "args": [
       "--scenario_json", 
-      "'{\"name\": \"protobuf_async_ping_pong_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 4, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}}, \"num_clients\": 1}'"
+      "'{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 4, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}'"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -22342,7 +23202,111 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:protobuf_async_ping_pong_insecure"
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure"
+  }, 
+  {
+    "args": [
+      "--scenario_json", 
+      "'{\"name\": \"cpp_single_channel_throughput_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 4, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 65536, \"req_size\": 65536}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1000.0, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_single_channel_throughput_insecure"
+  }, 
+  {
+    "args": [
+      "--scenario_json", 
+      "'{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1000.0, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_insecure"
+  }, 
+  {
+    "args": [
+      "--scenario_json", 
+      "'{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1000.0, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_insecure"
+  }, 
+  {
+    "args": [
+      "--scenario_json", 
+      "'{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 5, \"benchmark_seconds\": 30, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}'"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1000.0, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure"
   }, 
   {
     "args": [
@@ -22434,6 +23398,50 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/025215e11687c7d2e0055e5b2b902d08e0436f78"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/02ba99615d1d69eb328adce99670f659959c1bc1"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/03abf728ac1d833c2d4a9ff7e0c912b949edc04c"
     ], 
     "ci_platforms": [
@@ -22522,6 +23530,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/07048654244e377ddf246e8cc18f71443035cd2b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/078232947d7ff25557e836b4e9e907214e99b320"
     ], 
     "ci_platforms": [
@@ -22566,6 +23596,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/0c30868720d5e1a19ff23c53740749c37a43540d"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/0c5e0660ddf5f14af8f3fbcc754a967506994c9b"
     ], 
     "ci_platforms": [
@@ -22610,6 +23662,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/0d8c547f1d261ba07c2648bae009636c17709600"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/0dd33527db106a3e84172e8f2189734b00ced4ed"
     ], 
     "ci_platforms": [
@@ -22676,6 +23750,50 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/0f98d7d56e9a99b97e5dc7eb122ef22e9684077b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/0fd8859246740606c498755ab00d6147abcfec00"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/100bb8f2e6a0b41da13f4edb5c15d4a04e564840"
     ], 
     "ci_platforms": [
@@ -22698,6 +23816,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/101305ccd08c7a8bd0c2913c37d3dd0d39d4bb64"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/10f5d1937cb068fee7f85e2654be2bfe77498bb9"
     ], 
     "ci_platforms": [
@@ -22720,6 +23860,72 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/1160214cdb23e8fc187078a8d6796656c1ade925"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/118ffddb43ccf9dae8bdb4702232d1dc39b021f7"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/1306c4c6ea714d4db0e4d814c944d8d40335e0fa"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/1402bbcac6fa24eeb0475250e33f704096e2fb45"
     ], 
     "ci_platforms": [
@@ -22742,6 +23948,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/143e0d4f546bbb984a7c3ac1c60a37dcf85ea58d"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/1576c915ee38f5bd19f285ed0ed47e36026518f2"
     ], 
     "ci_platforms": [
@@ -22786,6 +24014,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/17b1758fc7cd69a00d140f113b1ac894023ff20b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/18185cbf9e9cfc1fd28d27ed0d651d7cee6a2c06"
     ], 
     "ci_platforms": [
@@ -22808,6 +24058,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/1875a4acdcffe505ca92ea8af8d9d6b174736e80"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/18850965807039500c7f5450a907e86825cf823d"
     ], 
     "ci_platforms": [
@@ -22896,6 +24168,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/1aee32faadffa3c2ec508e8fd30006423665488f"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/1c222dae4e2cde1fca9f9bf6226200f70d625342"
     ], 
     "ci_platforms": [
@@ -22918,6 +24212,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/1ca51ab2fefef4f549c4a8e7f4910c6b5a4b4b1d"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/1cbcaad71950c62d41bab50f9c242d014cc0d904"
     ], 
     "ci_platforms": [
@@ -22962,6 +24278,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/1dc86d0febe4adc5353230cea24b5f7cce829283"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/1e84d42fcf18bbf81ef6e8a16a0c57abbf8d292a"
     ], 
     "ci_platforms": [
@@ -22984,6 +24322,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/1f040e756f76357979f317e0c6541f72fd93df06"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/1fe7d16ffc2084d5d3c5f23d16902ae8810a5393"
     ], 
     "ci_platforms": [
@@ -23028,6 +24388,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/20216d27af2b3dcc83d944e5f7a489ed2eff98fd"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/20539e464ced1a0a63d74bae731ca0a75db05967"
     ], 
     "ci_platforms": [
@@ -23050,6 +24432,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/205cf2b6994f10b783aa0a06938a5e47cb581126"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/207e12d6a84dc8fa020b3a60b3f75932ca4f8fa5"
     ], 
     "ci_platforms": [
@@ -23094,6 +24498,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/2166c7093c424a2136c4cb8b10d0b124047320d4"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/21a6a133f3d1e06c077032ba56a7df4161f62efe"
     ], 
     "ci_platforms": [
@@ -23138,6 +24564,50 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/2467fa0f8a9f4bd121f544892f0782498b2df533"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/246dcf347eba7f4d4e04d97dabc002f0acf2164e"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/25761748660a64111a8daa46f72ea1f336c2046a"
     ], 
     "ci_platforms": [
@@ -23204,6 +24674,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/26110f21dcb0fde99942e631366ebbd9d895860d"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/269afce3bfff993c05c2a3b28c6cf3dfb3f461d7"
     ], 
     "ci_platforms": [
@@ -23248,6 +24740,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/28ee8cae75efa07da9649933a9482d00643b5395"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/299034b9e0cc8d91c049c489dca6d1a2b8b08959"
     ], 
     "ci_platforms": [
@@ -23292,6 +24806,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/29be7d33920998bae7329d77d4c81989eae91647"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/2a8260b23460f90f770cedcafa14868d24db201e"
     ], 
     "ci_platforms": [
@@ -23424,6 +24960,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/2dce4a1fc4bb00bfcd43d549a3785913c9280369"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/2deb1aeb93c2abca4177b1fe886eb354c83fe8af"
     ], 
     "ci_platforms": [
@@ -23578,6 +25136,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/31545e9fe4c6aa43329dc0d4a735842574fcaaed"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/31d12a2b1378120d15b4097371d792daa95de0a9"
     ], 
     "ci_platforms": [
@@ -23622,6 +25202,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/3336748264594689041e4080b51bc56f716d0689"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/333d0554d91872e693d118d6988132d95b7920ae"
     ], 
     "ci_platforms": [
@@ -23710,6 +25312,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/361c6f4374443671f039fd9659577e4460178020"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/370b2c16cc353621091eda4964d4c4329205ffc3"
     ], 
     "ci_platforms": [
@@ -23754,6 +25378,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/375c2462d6ae891222686f9519294811fa5de010"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/379b177d55b1eb86ddb66dc3a037fd8283ee07c0"
     ], 
     "ci_platforms": [
@@ -24040,6 +25686,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/42c395ab373346fb283ace021bdc1f6428f92f80"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/43202ad9b1a689d919ab9ae91c2d0223394867bf"
     ], 
     "ci_platforms": [
@@ -24260,6 +25928,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/4a4553c2e939cd50981bc38e8ddb1f2109ddb3a4"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/4b2ce115b15082ed951f4dc0b432da6a9d37bf85"
     ], 
     "ci_platforms": [
@@ -24282,6 +25972,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/4b585eb75ebca2187c0aa5a6abe4c8125aa80127"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/4b611a3748757e2fa89fcd2fb22d34444fbf5b42"
     ], 
     "ci_platforms": [
@@ -24370,6 +26082,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/4f5b9d5c707a35084918c272efd1295d301ca0b5"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/4f8b5b7489cca36225acec0f9aa7f5c556d79d8d"
     ], 
     "ci_platforms": [
@@ -24392,6 +26126,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/50ece7ea16659b4e1a2284cea963fab662c19e6b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/514c9cd7b6519b596900d924ff2caa173d688f4b"
     ], 
     "ci_platforms": [
@@ -24414,6 +26170,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/51c6c5297acebf9d21a8a7d6261d0a17c2adfb56"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/52c00bde7f4af95a86deb0a6717d1faf2828a939"
     ], 
     "ci_platforms": [
@@ -24436,6 +26214,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/534c900ade27c8f7fccb1f3b7e7703f77f13a8f5"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/5360327e8bc8969f31b364df3081b51a1e03900c"
     ], 
     "ci_platforms": [
@@ -24458,6 +26258,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/5482dc4af170def9c183315efaa48f9c186926a1"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/54e67ed1036f3f5b315e0e3c02948c30eba900fd"
     ], 
     "ci_platforms": [
@@ -24524,6 +26346,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/57ee6efc38f4c544a3ea3e5e73987e825bdf2980"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/58a067ec6eda7191a5a910d8120633271d3af074"
     ], 
     "ci_platforms": [
@@ -24590,6 +26434,94 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/59d78f6397f0483d139f5bd0a9f264156f34acc4"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/5a2447fdfdbf123f4592c1284007b7d50a01750b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/5ca233a53e3e425cc12e04b466a49789291eaa00"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/5dc7b2086a39f56d8b9135f524d34a01fcabafd8"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/5e1659e7cd840ab3f958273ebffdd215f2c81da6"
     ], 
     "ci_platforms": [
@@ -24612,6 +26544,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/605e474e9d9436488dfe084d348908e4dfab81a3"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/6066fc9e28b4ce704230f0e8cf21e7c3195aa2a3"
     ], 
     "ci_platforms": [
@@ -24656,6 +26610,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/611343a6b8879b393ba2f38ed41c7f5355355920"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/62c843359941660da3fc9eea62a5732aaa3be283"
     ], 
     "ci_platforms": [
@@ -24678,6 +26654,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/636a19b8f50c4efccccea83ab78a933d999e41fa"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/64696e93ead18265cdac3fb37dae29ad3be6d764"
     ], 
     "ci_platforms": [
@@ -24700,6 +26698,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/64c0e0b4d9c2d25fdcb1e2bdcb999487fc096dad"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/64cad305e1858eae27cd723778fb9f4b7052eaa5"
     ], 
     "ci_platforms": [
@@ -24722,6 +26742,50 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/64d27dc9f984c49d421a5b0cb0391992d5aac1a4"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/653ec14661c40ea25bdbab4a7cb9371c669d10d9"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/66145518601b1405361df12570f6e0b2b9a2e5b3"
     ], 
     "ci_platforms": [
@@ -24744,6 +26808,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/6749752b02f7d14fff9ac35f6b68dd62f5b49fcd"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/67e72cea2b7042f08e8dfba5191d27bb390e4d00"
     ], 
     "ci_platforms": [
@@ -24832,6 +26918,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/6bfd3679f4e30aaaa1808e96c980edcfa9cac1c0"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/6e2796549e29e5066f780a5e926fd6e3bb362450"
     ], 
     "ci_platforms": [
@@ -24854,6 +26962,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/6e71553967212dfea2c9995f3641e582d8c2105b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/71106770243ccca03f5025aadb298ee3a825824b"
     ], 
     "ci_platforms": [
@@ -24964,6 +27094,50 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/759a1e2e34cad14321a5e5790b1e6a783312fea1"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/7885df741c88ca4b539798d9985c445f41cc2929"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/7af3156d286a32a6a6fede46d93ec12ded1ac138"
     ], 
     "ci_platforms": [
@@ -24986,6 +27160,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/7af41e5391204f4596cb1461792e2e23f9390b7b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/7c73c0671308e37a8075a20863e70e180ef8b6ea"
     ], 
     "ci_platforms": [
@@ -25030,6 +27226,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/807b8c4ca068cff4bc0fc8e854c1215a2fe65960"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/80bd4827db81a1da28fae8c150f5e2d46651c598"
     ], 
     "ci_platforms": [
@@ -25052,6 +27270,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/813d2c34c0df8d4a918e68e58cf0ae3703d0d46f"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/82c0e02a867a5fdfb805e01ebf1a008220311e27"
     ], 
     "ci_platforms": [
@@ -25074,6 +27314,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/831248cea079b629bf0ef6d9d02c159d6f8ed41b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/8382c249fc9c7a248833d89de554e63807c475f7"
     ], 
     "ci_platforms": [
@@ -25118,6 +27380,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/850c639595eae3cc9c2cfef473e28fd4e8174dc8"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/857ce08213a5106c746767352c6863d7bd134208"
     ], 
     "ci_platforms": [
@@ -25316,6 +27600,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/8bacacba71bfa5c74fd74cb6577a49a7aec9cf1f"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/8c527bdf0f304a31866f71cdb298511041ecd320"
     ], 
     "ci_platforms": [
@@ -25404,6 +27710,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/90a9c3390752b94ca19a58cb2fe6267bc818f718"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/9125277ed9ec5d59e51f3e1a8d97d25ef88a5d4f"
     ], 
     "ci_platforms": [
@@ -25558,6 +27886,50 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/9552c3f6304af40224b800f3a3a5df3887a530f6"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/96e5126447131d3d59cc6547f6b91d3433ce37c8"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/970fccda0b34b59ade44d52e1212699b4d2419a8"
     ], 
     "ci_platforms": [
@@ -25646,6 +28018,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/98dddd3f679af150e9933bd864ae20e20b7aa25a"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/999d0995c2f09beda8783eac95d7643a11d5c89a"
     ], 
     "ci_platforms": [
@@ -25690,6 +28084,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/9a4da2a37a26c114e1226bfbe1cf80ec5ca99a66"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/9abf980e8909aeb31936553ca22ccfd8680c4dab"
     ], 
     "ci_platforms": [
@@ -25712,6 +28128,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/9b1355c6e2c43ce83001bbead09a79852e04feef"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/9b4d4ce0457f5300d6b4b309762acfdbc41e3965"
     ], 
     "ci_platforms": [
@@ -25800,6 +28238,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/9d362d2aaeee243a5b54621d8187c4b16f87c9f5"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/9d6947df24c9ebcbec72c568d9708d7b1ecae63c"
     ], 
     "ci_platforms": [
@@ -25822,6 +28282,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/9dfdce1b090a559a14f9a5852f78547413b1d1ed"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/9e2ab07030bd35a4c31df32c79aca5e76c1d04f8"
     ], 
     "ci_platforms": [
@@ -25844,6 +28326,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/9f0ab521c728be21e93112b2730c52bc1d6c0021"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/9fee3212240d4bccfdab3696dbbc579b06d39982"
     ], 
     "ci_platforms": [
@@ -25888,6 +28392,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/a30fc2605f4e74f7003f902ea4a4c994e3ce9bfd"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/a33e1b28074a41fc5c2611a67161ae5638a47dd5"
     ], 
     "ci_platforms": [
@@ -25910,6 +28436,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/a3cd54d43d3b3bdfcf224d636dc11ce1b5ee4d30"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/a4874327383ca168f9d9d59cffe327f61e9a6610"
     ], 
     "ci_platforms": [
@@ -25998,6 +28546,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/a706f2067bfbda7837eaad68972d60547e2957c3"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/a814c5743d492b96d2b402f9e819bf8406262224"
     ], 
     "ci_platforms": [
@@ -26020,6 +28590,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/a8e67676784506d2e6eab3a0dfa25e53a80b40a0"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/a9d71e1ff2912d8874e38fc61cbd9a8ef28af4a9"
     ], 
     "ci_platforms": [
@@ -26174,6 +28766,50 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/ade2d2f0e120a9527487e9b92458ee6844800e4e"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/af8b24ffaecdfaf96c0cd7c76f31dc9e1b4d0935"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/afcce9e02e0696a2af073855a386f589cc12c94d"
     ], 
     "ci_platforms": [
@@ -26218,6 +28854,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/b09f98e13e5b67a4dd7f74eff00bb247b9967844"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/b24a0dd1bc0bfabb832f0d1c8410c018c4ddaf4e"
     ], 
     "ci_platforms": [
@@ -26306,6 +28964,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/b3f33b78433af7f607bc99b569b0cef95a1a6ca0"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/b46e762671a5e28c7061da3baee6fc41dcc0122b"
     ], 
     "ci_platforms": [
@@ -26416,6 +29096,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/ba942f8fb244b60561a067129c242c4bc4fdd5e1"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/baa28a5baedb645f4430940a4b4b1142f4b03e0f"
     ], 
     "ci_platforms": [
@@ -26438,6 +29140,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/baf7839388e10ff0c410a58797482cb83693b309"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/bbc03bf6274a79528d43e200e8f1aaa770a155d6"
     ], 
     "ci_platforms": [
@@ -26460,6 +29184,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/bc9e17fed43c5d0668a87e8d6354c344c5b4d00b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/bcc7340f8876a7dff381ca676efc39d30eed9f48"
     ], 
     "ci_platforms": [
@@ -26636,6 +29382,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/c5d0c169d326d79fc4ee8521b282dbcbf33c1d5c"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/c5dfb4a82f91d07041d4b0ca6cc34cfa1e9c7199"
     ], 
     "ci_platforms": [
@@ -26658,6 +29426,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/c685689a9d5b259afe237d857b7c6551dc95c176"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/c77087b4651f4c62a780d77a3b4c233490244e8a"
     ], 
     "ci_platforms": [
@@ -26680,6 +29470,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/c784ad2e205ba49b5bb1302746723dbc57320981"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/c84da54dacf04445b50448a70fb0ecdd08e9234a"
     ], 
     "ci_platforms": [
@@ -26812,6 +29624,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/cd4be18b1ae872c40580edc4fe8cbdf1fe2a3881"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/cd76ed6aff7e074b0cfdcc6305ec4e453d8304bb"
     ], 
     "ci_platforms": [
@@ -26834,6 +29668,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/ce990633c0f2b2a2ddb66144ed942d4bc9bcd8fb"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/ceb297908903ba0fc24982ad4e6010e79dfbdd5e"
     ], 
     "ci_platforms": [
@@ -27010,6 +29866,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-8e546795782dffa5d5f5e94c9510aac178fcee39"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-d5af12c391b7bf0ce63ee3dc656ee4410fe496eb"
     ], 
     "ci_platforms": [
@@ -27164,6 +30042,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/d257c41db22b60cd937de16b9d90a44b9fa8e426"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/d3386702918881101368cdba2c4967e86ff3a7b9"
     ], 
     "ci_platforms": [
@@ -27296,6 +30196,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/d727b7edb460c549d7b12b90f581048c9f4747e5"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/d89026894e6c5f8b5c88dec12950f56c4b6924ba"
     ], 
     "ci_platforms": [
@@ -27318,6 +30240,72 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/d90c312791129dee8c5f85cb3308323d0c39b70d"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/d91281daad9b821294db204dfc244b2d0d5496e4"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/da322a6b88da87babb52d1527fe54cb4ac214b32"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/da4d300d0a8e6f803ec053e3e7689c4b91eaef90"
     ], 
     "ci_platforms": [
@@ -27450,6 +30438,72 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/dc815fd6d5e817898238481472f359bc50b510c4"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/dccd1fd6d3394f5f68c87950ed7356a2e9ef0f6f"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/dd662353bad317cee7d16191a39e094bfa4898f2"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/df684493457bc8d87dec2ca0825f7b43978fecfd"
     ], 
     "ci_platforms": [
@@ -27472,6 +30526,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/e0d1ee5e2e169dcae87f790f5c27e84a3453cedb"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/e1bd70aa5c802cd4462ff4833c09ed432ce4c9fa"
     ], 
     "ci_platforms": [
@@ -27516,6 +30592,50 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/e309e21c69e4b96ab37f675f4e87a52453512ef8"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/e3422e8f5d63a9ef180aab552353955c7aba90b0"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/e40b0fa5d814be8f2081ca2c8e0a4090d4893831"
     ], 
     "ci_platforms": [
@@ -27538,6 +30658,50 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/e442f9fd63bc5345de1c14803d4ca4bb6f1152cf"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/e4c0e27cfd3690b8255a8214d6dd055385d1d24e"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/e4dc0a111e77dc495c5db07df5e2917adb674697"
     ], 
     "ci_platforms": [
@@ -27560,6 +30724,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/e5a7c086208248a15ee6fa5195fc4ce22469de15"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/e5ac3394971400b6636d029aec7ec665a94ecf29"
     ], 
     "ci_platforms": [
@@ -27648,6 +30834,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/e7c26599fb2e2b031346ff1ba09294fd758f7abe"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/e8323c817d18f0c920d3cf53be41a9bc0fd64b76"
     ], 
     "ci_platforms": [
@@ -27758,6 +30966,72 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/ec180175f0edea0a6c3eea2ae719b006bc029ff8"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/ed6358fbe6721c9ac01a6f4cab4d2df377eb1f11"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/ee436743977b8e31feec22a91b1ce23dee96665e"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/ef1984d6146670122c7a7246374bca460e7284e5"
     ], 
     "ci_platforms": [
@@ -27934,6 +31208,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/f4499e3d4bf60ae3ae929c485a13ea4dc2713369"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/f5b1eab444efb2664a295d4e6d087eb209c0c480"
     ], 
     "ci_platforms": [
@@ -28022,6 +31318,50 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/f8467d9574de94b9bb904f75a6a7e2405c36f105"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/f84f5d6188cf099465f0b70337b87ad8aa8efb78"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/f91f76fa45a23adfed48a10ec9512cf16bfb6636"
     ], 
     "ci_platforms": [
@@ -28088,6 +31428,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/f9c875c00b7327df5bf21c3e051b55b0d2ed3cc8"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/fb340fff42a4d7ebf6b82adb9345655ffeeb05d9"
     ], 
     "ci_platforms": [
@@ -28176,6 +31538,72 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/fe1390762579b5c335bbdea73e251b95b979c3c9"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/fecccfc70b1cf1a524b9f28a9ba2c153c8e14d0e"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/client_fuzzer_corpus/fef80aa34c31700ac8e53bede4a97131176ceef0"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "client_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/client_fuzzer_corpus/hdr_frame.bin"
     ], 
     "ci_platforms": [
@@ -52134,6 +55562,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/05efe6d81ce606557691432634e81f61e68b0b81"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/06bd2f82fefb9943787d63ea359f9b77072380c2"
     ], 
     "ci_platforms": [
@@ -52178,6 +55628,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/07ad7e0ea2aaecba37f2429a64e946fc6e2556f1"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/07c96c06eddbed5a3ce050436bc805f6821cbc9b"
     ], 
     "ci_platforms": [
@@ -52354,6 +55826,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/0c413d2b361b2221585026d42f3046ff4135d2ff"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/0d10bb63.bin"
     ], 
     "ci_platforms": [
@@ -53564,6 +57058,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/3292129aa7f6eba86b70fff64408f18fff895c12"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/32b11997.bin"
     ], 
     "ci_platforms": [
@@ -53762,6 +57278,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/38df7e63181cbd045e5af9dbee463360c8254618"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/39ea47bb.bin"
     ], 
     "ci_platforms": [
@@ -53828,6 +57366,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/3d7ef8c7b05f26e914c479dedb1bef5e378d2d94"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/3dc665f93db294b9ccb8fcec94bcc2a91f3a04e7"
     ], 
     "ci_platforms": [
@@ -54092,6 +57652,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/4271fbb36e03cee79b21a4a5a65f37ceef58a8cd"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/42b0afca.bin"
     ], 
     "ci_platforms": [
@@ -54136,6 +57718,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/44516839d35af9ccaf8a2c62f3ce6a723482445e"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/44f342a6.bin"
     ], 
     "ci_platforms": [
@@ -54862,6 +58466,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/59d0b24d1acd01c749fb4bd6802a5f4dd003ce75"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/59dcfde4.bin"
     ], 
     "ci_platforms": [
@@ -55016,6 +58642,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/61e798bdd49b339983fea4ccfe18efe44afbd69b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/62d05f336176a10a2c339c04d818f23b6e9a2637"
     ], 
     "ci_platforms": [
@@ -55368,6 +59016,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/6f3bd9f33ca05bebe3811f7b3ae6ed112e1e45b9"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/6f9d75e1af7ae7010d32872da888a582a25fddb4"
     ], 
     "ci_platforms": [
@@ -55676,6 +59346,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/8164d3c4af043c47cfd6966873bccd2353d072bf"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/81fb19dfcb3c3a18fd9e7c177356479503e75e6f"
     ], 
     "ci_platforms": [
@@ -55786,6 +59478,50 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/8846918f967dd6513040c6d382fcd68ff7099873"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/885fe25a0b441ef46ab176b88771c133e530cb73"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/88e1329b.bin"
     ], 
     "ci_platforms": [
@@ -57018,6 +60754,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/bc9545cebdcb3af82406a5f0c1b286d28f9d4f5a"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/bd63e44a3b004e7ed471c2367c3efae2c58a676d"
     ], 
     "ci_platforms": [
@@ -57546,6 +61304,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/cc97ece92b72cc2a4d045e16c0e2f2021bc014f8"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/cca29902.bin"
     ], 
     "ci_platforms": [
@@ -57854,6 +61634,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/d96da249094db51ea92b1413907abfd27a4f2426"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/da7e44a9.bin"
     ], 
     "ci_platforms": [
@@ -57942,6 +61744,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/df5d3cf5f05eab65ef9d385e263780ae73c42b19"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/e0d9a9a7.bin"
     ], 
     "ci_platforms": [
@@ -58052,6 +61876,28 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/e9bbe2fe47b7b9c2683e7f17f4a33625c6ffbd8c"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/e9d96662.bin"
     ], 
     "ci_platforms": [
@@ -58712,6 +62558,116 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1b6c4b5c1949adae3efd5e3264bb32a40eea524e"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-3991c873ba814d0cd03a67d25fff0c8fe8713aca"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-58f116dfba8d428a01ca596174fca63f4ac523f0"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-59f6edc7cf4aeed49b4dc024052db4846d5d7fc8"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-63ebf780ee6c2003eba622686a4bf94c503ad96e"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-6e980a9d12c392175b5f66683e608626ae983276"
     ], 
     "ci_platforms": [
@@ -58734,6 +62690,204 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-7233d53f94386b0339b2c2b01ef2d348f5862f1f"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-7281d9eaed0d20b0b6b5e7709c57e78fefe9c315"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-9a176b6f7e0dc5f681a1788d8954f76fabd08cad"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-9de2e92150e54982d4e502b18f374f8cd8fd453b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a61a28cf78149518466b87e5463ec5c771dc504e"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-aa23c18f6badd88a7bec65e8b04f7801ba624ec6"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-bda43d420a3e5d5228a5f5130207a1f11fc1c81f"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-d3c3cba3897fafec97665411ea1f94a89bb4de7b"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-ddfe613d8791b2d377e14fbdffb18b84a89d49b6"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "windows", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "test/core/client_config/uri_corpus/02d156dc5e6f2c11c90c2e06fcee04adf036a342"
     ], 
     "ci_platforms": [
diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln
index d26c1f8..2ffa186 100644
--- a/vsprojects/buildtests_c.sln
+++ b/vsprojects/buildtests_c.sln
@@ -1283,6 +1283,18 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_ssl_cert_test", "vcxproj\test/end2end/fixtures\h2_ssl_cert_test\h2_ssl_cert_test.vcxproj", "{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_ssl_proxy_test", "vcxproj\test/end2end/fixtures\h2_ssl_proxy_test\h2_ssl_proxy_test.vcxproj", "{A9092608-E45E-AC96-6533-A6E7DD98211D}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -3339,6 +3351,22 @@
 		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release-DLL|Win32.Build.0 = Release|Win32
 		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release-DLL|x64.ActiveCfg = Release|x64
 		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release-DLL|x64.Build.0 = Release|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|x64.ActiveCfg = Debug|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|Win32.ActiveCfg = Release|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|x64.ActiveCfg = Release|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|Win32.Build.0 = Debug|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|x64.Build.0 = Debug|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|Win32.Build.0 = Release|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|x64.Build.0 = Release|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|x64.Build.0 = Debug|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|Win32.Build.0 = Release|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|x64.ActiveCfg = Release|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|x64.Build.0 = Release|x64
 		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug|Win32.ActiveCfg = Debug|Win32
 		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug|x64.ActiveCfg = Debug|x64
 		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/vcxproj/boringssl/boringssl.vcxproj b/vsprojects/vcxproj/boringssl/boringssl.vcxproj
index 27125c4..59db775 100644
--- a/vsprojects/vcxproj/boringssl/boringssl.vcxproj
+++ b/vsprojects/vcxproj/boringssl/boringssl.vcxproj
@@ -156,12 +156,12 @@
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\cipher\internal.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\conf\conf_def.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\conf\internal.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\curve25519\internal.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\des\internal.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\dh\internal.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\digest\internal.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\digest\md32_common.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\directory.h" />
-    <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\dsa\internal.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\ec\internal.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\ec\p256-x86_64-table.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\evp\internal.h" />
@@ -400,6 +400,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\buf\buf.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\bytestring\asn1_compat.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\bytestring\ber.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\bytestring\cbb.c">
@@ -446,6 +448,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\curve25519\curve25519.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\curve25519\x25519-x86_64.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\des\des.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\dh\check.c">
@@ -828,6 +832,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\ssl\ssl_cipher.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\ssl\ssl_ecdh.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\ssl\ssl_file.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\ssl\ssl_lib.c">
diff --git a/vsprojects/vcxproj/boringssl/boringssl.vcxproj.filters b/vsprojects/vcxproj/boringssl/boringssl.vcxproj.filters
index 8cee094..bd996bd 100644
--- a/vsprojects/vcxproj/boringssl/boringssl.vcxproj.filters
+++ b/vsprojects/vcxproj/boringssl/boringssl.vcxproj.filters
@@ -217,6 +217,9 @@
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\buf\buf.c">
       <Filter>third_party\boringssl\crypto\buf</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\bytestring\asn1_compat.c">
+      <Filter>third_party\boringssl\crypto\bytestring</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\bytestring\ber.c">
       <Filter>third_party\boringssl\crypto\bytestring</Filter>
     </ClCompile>
@@ -286,6 +289,9 @@
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\curve25519\curve25519.c">
       <Filter>third_party\boringssl\crypto\curve25519</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\curve25519\x25519-x86_64.c">
+      <Filter>third_party\boringssl\crypto\curve25519</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\des\des.c">
       <Filter>third_party\boringssl\crypto\des</Filter>
     </ClCompile>
@@ -859,6 +865,9 @@
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\ssl\ssl_cipher.c">
       <Filter>third_party\boringssl\ssl</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\ssl\ssl_ecdh.c">
+      <Filter>third_party\boringssl\ssl</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\ssl\ssl_file.c">
       <Filter>third_party\boringssl\ssl</Filter>
     </ClCompile>
@@ -912,6 +921,9 @@
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\conf\internal.h">
       <Filter>third_party\boringssl\crypto\conf</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\curve25519\internal.h">
+      <Filter>third_party\boringssl\crypto\curve25519</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\des\internal.h">
       <Filter>third_party\boringssl\crypto\des</Filter>
     </ClInclude>
@@ -927,9 +939,6 @@
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\directory.h">
       <Filter>third_party\boringssl\crypto</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\dsa\internal.h">
-      <Filter>third_party\boringssl\crypto\dsa</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\third_party\boringssl\crypto\ec\internal.h">
       <Filter>third_party\boringssl\crypto\ec</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index f695468..2e4d151 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -293,6 +293,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\census.h" />
   </ItemGroup>
   <ItemGroup>
@@ -412,6 +413,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\parse_address.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver_registry.h" />
@@ -705,6 +707,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_registry.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\parse_address.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\resolver.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\resolver_factory.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 37bd1e6..63569df 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -409,6 +409,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_registry.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\parse_address.c">
+      <Filter>src\core\ext\client_config</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\resolver.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
@@ -573,6 +576,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\census.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
@@ -926,6 +932,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_registry.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\parse_address.h">
+      <Filter>src\core\ext\client_config</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index cb033a5..79e00e7 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -153,6 +153,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\grpc_profiler.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\core\util\memory_counters.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\mock_endpoint.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\parse_hexstring.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\port.h" />
@@ -160,6 +161,8 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\util\slice_splitter.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\client_certs.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\server1_cert.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\server1_key.c">
@@ -176,6 +179,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\grpc_profiler.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\util\memory_counters.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\mock_endpoint.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\parse_hexstring.c">
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index 81b2a81..e7c64c4 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -1,6 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\client_certs.c">
+      <Filter>test\core\end2end\data</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\server1_cert.c">
       <Filter>test\core\end2end\data</Filter>
     </ClCompile>
@@ -25,6 +28,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\util\grpc_profiler.c">
       <Filter>test\core\util</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\util\memory_counters.c">
+      <Filter>test\core\util</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\mock_endpoint.c">
       <Filter>test\core\util</Filter>
     </ClCompile>
@@ -63,6 +69,9 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\util\grpc_profiler.h">
       <Filter>test\core\util</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\test\core\util\memory_counters.h">
+      <Filter>test\core\util</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\core\util\mock_endpoint.h">
       <Filter>test\core\util</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
index bb93b2c..3368253 100644
--- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
@@ -151,6 +151,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\grpc_profiler.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\core\util\memory_counters.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\mock_endpoint.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\parse_hexstring.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\port.h" />
@@ -166,6 +167,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\grpc_profiler.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\util\memory_counters.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\mock_endpoint.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\parse_hexstring.c">
diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
index 4c4620a..5c2b961 100644
--- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
@@ -13,6 +13,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\util\grpc_profiler.c">
       <Filter>test\core\util</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\util\memory_counters.c">
+      <Filter>test\core\util</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\mock_endpoint.c">
       <Filter>test\core\util</Filter>
     </ClCompile>
@@ -45,6 +48,9 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\util\grpc_profiler.h">
       <Filter>test\core\util</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\test\core\util\memory_counters.h">
+      <Filter>test\core\util</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\core\util\mock_endpoint.h">
       <Filter>test\core\util</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index a866ddc..fa571d9 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -388,6 +388,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_registry.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\parse_address.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver_registry.h" />
@@ -645,6 +646,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_registry.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\parse_address.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\resolver.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\resolver_factory.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index bc4e06e..30dcb1b 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -355,6 +355,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_registry.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\parse_address.c">
+      <Filter>src\core\ext\client_config</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\resolver.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
@@ -821,6 +824,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_registry.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\parse_address.h">
+      <Filter>src\core\ext\client_config</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/boringssl/boringssl_x509_test/boringssl_x509_test.vcxproj b/vsprojects/vcxproj/test/boringssl/boringssl_x509_test/boringssl_x509_test.vcxproj
new file mode 100644
index 0000000..2bf7f71
--- /dev/null
+++ b/vsprojects/vcxproj/test/boringssl/boringssl_x509_test/boringssl_x509_test.vcxproj
@@ -0,0 +1,198 @@
+<?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>{0E1472A5-A857-7680-45C6-7C4DD2F6BE48}</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>boringssl_x509_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>boringssl_x509_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>false</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>false</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>false</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>false</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)\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/boringssl\boringssl_x509_test_lib\boringssl_x509_test_lib.vcxproj">
+      <Project>{62DBB3BA-05D6-D2CF-7EC5-253F2AC25892}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\boringssl_test_util\boringssl_test_util.vcxproj">
+      <Project>{427037B1-B51B-D6F1-5025-AD12B200266A}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\boringssl\boringssl.vcxproj">
+      <Project>{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}</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/boringssl/boringssl_x509_test/boringssl_x509_test.vcxproj.filters b/vsprojects/vcxproj/test/boringssl/boringssl_x509_test/boringssl_x509_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/boringssl/boringssl_x509_test/boringssl_x509_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/boringssl/boringssl_x509_test_lib/boringssl_x509_test_lib.vcxproj b/vsprojects/vcxproj/test/boringssl/boringssl_x509_test_lib/boringssl_x509_test_lib.vcxproj
new file mode 100644
index 0000000..f8b0e7a
--- /dev/null
+++ b/vsprojects/vcxproj/test/boringssl/boringssl_x509_test_lib/boringssl_x509_test_lib.vcxproj
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <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>{62DBB3BA-05D6-D2CF-7EC5-253F2AC25892}</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>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</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\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>boringssl_x509_test_lib</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>boringssl_x509_test_lib</TargetName>
+  </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>false</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</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>false</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</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>false</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</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>false</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\x509\x509_test.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\boringssl_test_util\boringssl_test_util.vcxproj">
+      <Project>{427037B1-B51B-D6F1-5025-AD12B200266A}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\boringssl\boringssl.vcxproj">
+      <Project>{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </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>
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/boringssl/boringssl_x509_test_lib/boringssl_x509_test_lib.vcxproj.filters b/vsprojects/vcxproj/test/boringssl/boringssl_x509_test_lib/boringssl_x509_test_lib.vcxproj.filters
new file mode 100644
index 0000000..216a56f
--- /dev/null
+++ b/vsprojects/vcxproj/test/boringssl/boringssl_x509_test_lib/boringssl_x509_test_lib.vcxproj.filters
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\third_party\boringssl\crypto\x509\x509_test.cc">
+      <Filter>third_party\boringssl\crypto\x509</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="third_party">
+      <UniqueIdentifier>{0a04403f-6935-8e9c-c271-cfcb728d6dd3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\boringssl">
+      <UniqueIdentifier>{8ffac2f8-0d1d-00df-018c-56100e9842f7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\boringssl\crypto">
+      <UniqueIdentifier>{2d1857b4-2355-6af6-b6c8-b33f3ec27013}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\boringssl\crypto\x509">
+      <UniqueIdentifier>{615f50f9-1415-e8e4-49ec-987a5772c7ee}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_cert_test/h2_ssl_cert_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_cert_test/h2_ssl_cert_test.vcxproj
new file mode 100644
index 0000000..d64c317
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_cert_test/h2_ssl_cert_test.vcxproj
@@ -0,0 +1,202 @@
+<?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>{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}</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\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_ssl_cert_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>h2_ssl_cert_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)\..\test\core\end2end\fixtures\h2_ssl_cert.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
+      <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</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\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</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\.\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/end2end/fixtures/h2_ssl_cert_test/h2_ssl_cert_test.vcxproj.filters b/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_cert_test/h2_ssl_cert_test.vcxproj.filters
new file mode 100644
index 0000000..532b0ae
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_cert_test/h2_ssl_cert_test.vcxproj.filters
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_ssl_cert.c">
+      <Filter>test\core\end2end\fixtures</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{2ad9c3be-3600-2475-3705-8927bd57651b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{5d5ee434-b892-585d-97ca-ae595eecbd0b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end">
+      <UniqueIdentifier>{903c738d-3c85-534d-d26e-01138f2e96c6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end\fixtures">
+      <UniqueIdentifier>{f5bca83d-8278-22b4-7999-c50cea11b90b}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+