diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 0000000000000000000000000000000000000000..a4f757f9bdd4717cfc1304c7c9dcc2a195b10173
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,38 @@
+[MESSAGES CONTROL]
+
+#TODO: Enable missing-docstring
+#TODO: Enable too-few-public-methods
+#TODO: Enable too-many-arguments
+#TODO: Enable no-init
+#TODO: Enable duplicate-code
+#TODO: Enable invalid-name
+#TODO: Enable suppressed-message
+#TODO: Enable locally-disabled
+#TODO: Enable protected-access
+#TODO: Enable no-name-in-module
+#TODO: Enable unused-argument
+#TODO: Enable fixme
+#TODO: Enable wrong-import-order
+#TODO: Enable no-value-for-parameter
+#TODO: Enable cyclic-import
+#TODO: Enable unused-variable
+#TODO: Enable redefined-outer-name
+#TODO: Enable unused-import
+#TODO: Enable too-many-instance-attributes
+#TODO: Enable broad-except
+#TODO: Enable too-many-locals
+#TODO: Enable too-many-lines
+#TODO: Enable redefined-variable-type
+#TODO: Enable next-method-called
+#TODO: Enable import-error
+#TODO: Enable useless-else-on-loop
+#TODO: Enable too-many-return-statements
+#TODO: Enable too-many-nested-blocks
+#TODO: Enable super-init-not-called
+#TODO: Enable simplifiable-if-statement
+#TODO: Enable no-self-use
+#TODO: Enable no-member
+#TODO: Enable logging-format-interpolation
+#TODO: Enable dangerous-default-value
+
+disable=missing-docstring,too-few-public-methods,too-many-arguments,no-init,duplicate-code,invalid-name,suppressed-message,locally-disabled,protected-access,no-name-in-module,unused-argument,fixme,wrong-import-order,no-value-for-parameter,cyclic-import,unused-variable,redefined-outer-name,unused-import,too-many-instance-attributes,broad-except,too-many-locals,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-return-statements,too-many-nested-blocks,super-init-not-called,simplifiable-if-statement,no-self-use,no-member,logging-format-interpolation,dangerous-default-value
diff --git a/BUILD b/BUILD
index ba92279b8e77df53e7e666f0622cb41b7f241821..2f9bbbc5ac0c984fbae0056295e7809a5290c3f8 100644
--- a/BUILD
+++ b/BUILD
@@ -140,6 +140,7 @@ grpc_cc_library(
         "grpc++_base",
         "grpc++_codegen_base",
         "grpc++_codegen_base_src",
+        "grpc++_codegen_proto",
     ],
 )
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9d2040c36605374b0f398eebb5d94b3db0ef7cdb..101f0ad2ef98d2d09bdeea5c083cc06bad67142b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -700,6 +700,17 @@ add_library(gpr
   src/core/lib/support/wrap_memcpy.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(gpr PROPERTIES COMPILE_PDB_NAME "gpr"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gpr.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(gpr
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -778,6 +789,17 @@ add_library(gpr_test_util
   test/core/util/test_config.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(gpr_test_util PROPERTIES COMPILE_PDB_NAME "gpr_test_util"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gpr_test_util.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(gpr_test_util
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -1026,6 +1048,17 @@ add_library(grpc
   src/core/plugin_registry/grpc_plugin_registry.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc PROPERTIES COMPILE_PDB_NAME "grpc"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -1293,6 +1326,17 @@ add_library(grpc_cronet
   src/core/plugin_registry/grpc_cronet_plugin_registry.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc_cronet PROPERTIES COMPILE_PDB_NAME "grpc_cronet"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_cronet.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc_cronet
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -1504,6 +1548,17 @@ add_library(grpc_test_util
   src/core/lib/transport/transport_op_string.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc_test_util PROPERTIES COMPILE_PDB_NAME "grpc_test_util"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_test_util.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc_test_util
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -1582,6 +1637,17 @@ add_library(grpc_test_util_unsecure
   test/core/util/slice_splitter.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc_test_util_unsecure PROPERTIES COMPILE_PDB_NAME "grpc_test_util_unsecure"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_test_util_unsecure.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc_test_util_unsecure
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -1804,6 +1870,17 @@ add_library(grpc_unsecure
   src/core/plugin_registry/grpc_unsecure_plugin_registry.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc_unsecure PROPERTIES COMPILE_PDB_NAME "grpc_unsecure"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_unsecure.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc_unsecure
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -1875,6 +1952,17 @@ add_library(reconnect_server
   test/core/util/reconnect_server.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(reconnect_server PROPERTIES COMPILE_PDB_NAME "reconnect_server"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/reconnect_server.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(reconnect_server
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -1904,6 +1992,17 @@ add_library(test_tcp_server
   test/core/util/test_tcp_server.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(test_tcp_server PROPERTIES COMPILE_PDB_NAME "test_tcp_server"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/test_tcp_server.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(test_tcp_server
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -1967,6 +2066,17 @@ add_library(grpc++
   src/cpp/codegen/codegen_init.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc++ PROPERTIES COMPILE_PDB_NAME "grpc++"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc++
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -2080,6 +2190,8 @@ foreach(_hdr
   include/grpc/impl/codegen/sync_generic.h
   include/grpc/impl/codegen/sync_posix.h
   include/grpc/impl/codegen/sync_windows.h
+  include/grpc++/impl/codegen/proto_utils.h
+  include/grpc++/impl/codegen/config_protobuf.h
 )
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
@@ -2317,6 +2429,17 @@ add_library(grpc++_cronet
   third_party/nanopb/pb_encode.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc++_cronet PROPERTIES COMPILE_PDB_NAME "grpc++_cronet"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_cronet.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc++_cronet
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -2468,6 +2591,17 @@ add_library(grpc++_proto_reflection_desc_db
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc++_proto_reflection_desc_db PROPERTIES COMPILE_PDB_NAME "grpc++_proto_reflection_desc_db"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_proto_reflection_desc_db.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 protobuf_generate_grpc_cpp(
   src/proto/grpc/reflection/v1alpha/reflection.proto
 )
@@ -2513,6 +2647,17 @@ add_library(grpc++_reflection
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc++_reflection PROPERTIES COMPILE_PDB_NAME "grpc++_reflection"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_reflection.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 protobuf_generate_grpc_cpp(
   src/proto/grpc/reflection/v1alpha/reflection.proto
 )
@@ -2560,6 +2705,17 @@ add_library(grpc++_test
   src/cpp/test/server_context_test_spouse.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc++_test PROPERTIES COMPILE_PDB_NAME "grpc++_test"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_test.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc++_test
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -2589,6 +2745,17 @@ add_library(grpc++_test_config
   test/cpp/util/test_config_cc.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc++_test_config PROPERTIES COMPILE_PDB_NAME "grpc++_test_config"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_test_config.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc++_test_config
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -2635,6 +2802,17 @@ add_library(grpc++_test_util
   src/cpp/codegen/codegen_init.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc++_test_util PROPERTIES COMPILE_PDB_NAME "grpc++_test_util"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_test_util.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 protobuf_generate_grpc_cpp(
   src/proto/grpc/testing/echo_messages.proto
 )
@@ -2765,6 +2943,17 @@ add_library(grpc++_unsecure
   src/cpp/codegen/codegen_init.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc++_unsecure PROPERTIES COMPILE_PDB_NAME "grpc++_unsecure"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_unsecure.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc++_unsecure
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -2909,6 +3098,17 @@ add_library(grpc_cli_libs
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc_cli_libs PROPERTIES COMPILE_PDB_NAME "grpc_cli_libs"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_cli_libs.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 protobuf_generate_grpc_cpp(
   src/proto/grpc/reflection/v1alpha/reflection.proto
 )
@@ -2956,6 +3156,17 @@ add_library(grpc_plugin_support
   src/compiler/ruby_generator.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc_plugin_support PROPERTIES COMPILE_PDB_NAME "grpc_plugin_support"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_plugin_support.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc_plugin_support
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -3012,6 +3223,17 @@ add_library(http2_client_main
   test/cpp/interop/http2_client.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(http2_client_main PROPERTIES COMPILE_PDB_NAME "http2_client_main"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/http2_client_main.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 protobuf_generate_grpc_cpp(
   src/proto/grpc/testing/empty.proto
 )
@@ -3058,6 +3280,17 @@ add_library(interop_client_helper
   test/cpp/interop/client_helper.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(interop_client_helper PROPERTIES COMPILE_PDB_NAME "interop_client_helper"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/interop_client_helper.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 protobuf_generate_grpc_cpp(
   src/proto/grpc/testing/messages.proto
 )
@@ -3107,6 +3340,17 @@ add_library(interop_client_main
   test/cpp/interop/interop_client.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(interop_client_main PROPERTIES COMPILE_PDB_NAME "interop_client_main"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/interop_client_main.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 protobuf_generate_grpc_cpp(
   src/proto/grpc/testing/empty.proto
 )
@@ -3152,6 +3396,17 @@ add_library(interop_server_helper
   test/cpp/interop/server_helper.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(interop_server_helper PROPERTIES COMPILE_PDB_NAME "interop_server_helper"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/interop_server_helper.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(interop_server_helper
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -3197,6 +3452,17 @@ add_library(interop_server_lib
   test/cpp/interop/interop_server.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(interop_server_lib PROPERTIES COMPILE_PDB_NAME "interop_server_lib"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/interop_server_lib.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 protobuf_generate_grpc_cpp(
   src/proto/grpc/testing/empty.proto
 )
@@ -3242,6 +3508,17 @@ add_library(interop_server_main
   test/cpp/interop/interop_server_bootstrap.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(interop_server_main PROPERTIES COMPILE_PDB_NAME "interop_server_main"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/interop_server_main.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(interop_server_main
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -3300,6 +3577,17 @@ add_library(qps
   test/cpp/util/benchmark_config.cc
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(qps PROPERTIES COMPILE_PDB_NAME "qps"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qps.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 protobuf_generate_grpc_cpp(
   src/proto/grpc/testing/messages.proto
 )
@@ -3345,6 +3633,17 @@ add_library(grpc_csharp_ext SHARED
   src/csharp/ext/grpc_csharp_ext.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(grpc_csharp_ext PROPERTIES COMPILE_PDB_NAME "grpc_csharp_ext"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_csharp_ext.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(grpc_csharp_ext
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -3379,6 +3678,17 @@ add_library(bad_client_test
   test/core/bad_client/bad_client.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(bad_client_test PROPERTIES COMPILE_PDB_NAME "bad_client_test"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bad_client_test.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(bad_client_test
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -3407,6 +3717,17 @@ add_library(bad_ssl_test_server
   test/core/bad_ssl/server_common.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(bad_ssl_test_server PROPERTIES COMPILE_PDB_NAME "bad_ssl_test_server"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bad_ssl_test_server.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(bad_ssl_test_server
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -3485,6 +3806,17 @@ add_library(end2end_tests
   test/core/end2end/tests/write_buffering_at_end.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(end2end_tests PROPERTIES COMPILE_PDB_NAME "end2end_tests"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/end2end_tests.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(end2end_tests
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -3563,6 +3895,17 @@ add_library(end2end_nosec_tests
   test/core/end2end/tests/write_buffering_at_end.c
 )
 
+if(WIN32 AND MSVC)
+  set_target_properties(end2end_nosec_tests PROPERTIES COMPILE_PDB_NAME "end2end_nosec_tests"
+    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+  )
+  if (gRPC_INSTALL)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/end2end_nosec_tests.pdb
+      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
+    )
+  endif()
+endif()
+
 
 target_include_directories(end2end_nosec_tests
   PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
diff --git a/Makefile b/Makefile
index 125512307c2f509ca94740552c308efd0122698c..5dde577cca8e8e8c751c32ec0852632c84b60b9b 100644
--- a/Makefile
+++ b/Makefile
@@ -328,7 +328,7 @@ CXXFLAGS += -std=c++11
 else
 CXXFLAGS += -std=c++0x
 endif
-CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
+CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1
 LDFLAGS += -g
 
 CPPFLAGS += $(CPPFLAGS_$(CONFIG))
@@ -3960,6 +3960,8 @@ PUBLIC_HEADERS_CXX += \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
     include/grpc/impl/codegen/sync_windows.h \
+    include/grpc++/impl/codegen/proto_utils.h \
+    include/grpc++/impl/codegen/config_protobuf.h \
 
 LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
 
diff --git a/build.yaml b/build.yaml
index 62321fafc2620b28e4e6d5c2f3b79e5203e6361f..2fbaa2e2262375af965702b23e3351576642172d 100644
--- a/build.yaml
+++ b/build.yaml
@@ -1088,6 +1088,7 @@ libs:
   filegroups:
   - grpc++_base
   - grpc++_codegen_base
+  - grpc++_codegen_proto
   - grpc++_codegen_base_src
   secure: check
   vs_project_guid: '{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}'
@@ -3955,7 +3956,7 @@ defaults:
     CPPFLAGS: -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM
       -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
   global:
-    CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
+    CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1
     LDFLAGS: -g
   zlib:
     CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index bc0b2bd7f86b12759dd81a99f9e92ea794f9afd4..6661547f6b60f4fb1e6ac136df01e0e93ac97297 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -222,6 +222,8 @@ typedef struct {
 /** If non-zero, a pointer to a buffer pool (use grpc_resource_quota_arg_vtable
    to fetch an appropriate pointer arg vtable) */
 #define GRPC_ARG_RESOURCE_QUOTA "grpc.resource_quota"
+/** If non-zero, expand wildcard addresses to a list of local addresses. */
+#define GRPC_ARG_EXPAND_WILDCARD_ADDRS "grpc.expand_wildcard_addrs"
 /** Service config data in JSON form. Not intended for use outside of tests. */
 #define GRPC_ARG_SERVICE_CONFIG "grpc.service_config"
 /** LB policy name. */
diff --git a/src/core/ext/client_channel/http_proxy.c b/src/core/ext/client_channel/http_proxy.c
index 7daa0714951af8ed7e3a17fb54273a51a166b070..bbe4ff550c6539dc4d9f9c4ebc9cc4a6abb32d5f 100644
--- a/src/core/ext/client_channel/http_proxy.c
+++ b/src/core/ext/client_channel/http_proxy.c
@@ -87,6 +87,12 @@ static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
     if (uri != NULL) grpc_uri_destroy(uri);
     return false;
   }
+  if (strcmp(uri->scheme, "unix") == 0) {
+    gpr_log(GPR_INFO, "not using proxy for Unix domain socket '%s'",
+            server_uri);
+    grpc_uri_destroy(uri);
+    return false;
+  }
   grpc_arg new_arg;
   new_arg.key = GRPC_ARG_HTTP_CONNECT_SERVER;
   new_arg.type = GRPC_ARG_STRING;
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 8a9eaa8b6a2adf7d6884a92228e574eadebef82d..3ee5e976f8492ec59c930f43c728fcce37b689f6 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -168,7 +168,7 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
   grpc_chttp2_stream_map_destroy(&t->stream_map);
   grpc_connectivity_state_destroy(exec_ctx, &t->channel_callback.state_tracker);
 
-  grpc_combiner_destroy(exec_ctx, t->combiner);
+  GRPC_COMBINER_UNREF(exec_ctx, t->combiner, "chttp2_transport");
 
   cancel_pings(exec_ctx, t, GRPC_ERROR_CREATE("Transport destroyed"));
 
diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c
index ba6c7087a920cb5339346e67853b013e1237ed45..fa9966c3a6957b38d7fa47d983bc7783198cf8a5 100644
--- a/src/core/lib/iomgr/combiner.c
+++ b/src/core/lib/iomgr/combiner.c
@@ -72,6 +72,7 @@ struct grpc_combiner {
   bool final_list_covered_by_poller;
   grpc_closure_list final_list;
   grpc_closure offload;
+  gpr_refcount refs;
 };
 
 static void combiner_exec_uncovered(grpc_exec_ctx *exec_ctx,
@@ -126,6 +127,7 @@ static bool is_covered_by_poller(grpc_combiner *lock) {
 
 grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue) {
   grpc_combiner *lock = gpr_malloc(sizeof(*lock));
+  gpr_ref_init(&lock->refs, 1);
   lock->next_combiner_on_this_exec_ctx = NULL;
   lock->time_to_execute_final_list = false;
   lock->optional_workqueue = optional_workqueue;
@@ -152,7 +154,7 @@ static void really_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
   gpr_free(lock);
 }
 
-void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
+static void start_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
   gpr_atm old_state = gpr_atm_full_fetch_add(&lock->state, -STATE_UNORPHANED);
   GRPC_COMBINER_TRACE(gpr_log(
       GPR_DEBUG, "C:%p really_destroy old_state=%" PRIdPTR, lock, old_state));
@@ -161,6 +163,30 @@ void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
   }
 }
 
+#ifdef GRPC_COMBINER_REFCOUNT_DEBUG
+#define GRPC_COMBINER_DEBUG_SPAM(op, delta)                               \
+  gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,                             \
+          "combiner[%p] %s %" PRIdPTR " --> %" PRIdPTR " %s", lock, (op), \
+          gpr_atm_no_barrier_load(&lock->refs.count),                     \
+          gpr_atm_no_barrier_load(&lock->refs.count) + (delta), reason);
+#else
+#define GRPC_COMBINER_DEBUG_SPAM(op, delta)
+#endif
+
+void grpc_combiner_unref(grpc_exec_ctx *exec_ctx,
+                         grpc_combiner *lock GRPC_COMBINER_DEBUG_ARGS) {
+  GRPC_COMBINER_DEBUG_SPAM("UNREF", -1);
+  if (gpr_unref(&lock->refs)) {
+    start_destroy(exec_ctx, lock);
+  }
+}
+
+grpc_combiner *grpc_combiner_ref(grpc_combiner *lock GRPC_COMBINER_DEBUG_ARGS) {
+  GRPC_COMBINER_DEBUG_SPAM("  REF", 1);
+  gpr_ref(&lock->refs);
+  return lock;
+}
+
 static void push_last_on_exec_ctx(grpc_exec_ctx *exec_ctx,
                                   grpc_combiner *lock) {
   lock->next_combiner_on_this_exec_ctx = NULL;
diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h
index 81dff85d40268a1080cbd4446954f67e0df57970..75dcb0b70a4268e97c4c20b77dc3f28826d4539d 100644
--- a/src/core/lib/iomgr/combiner.h
+++ b/src/core/lib/iomgr/combiner.h
@@ -48,8 +48,27 @@
 // Initialize the lock, with an optional workqueue to shift load to when
 // necessary
 grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue);
-// Destroy the lock
-void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock);
+
+//#define GRPC_COMBINER_REFCOUNT_DEBUG
+#ifdef GRPC_COMBINER_REFCOUNT_DEBUG
+#define GRPC_COMBINER_DEBUG_ARGS \
+  , const char *file, int line, const char *reason
+#define GRPC_COMBINER_REF(combiner, reason) \
+  grpc_combiner_ref((combiner), __FILE__, __LINE__, (reason))
+#define GRPC_COMBINER_UNREF(exec_ctx, combiner, reason) \
+  grpc_combiner_unref((exec_ctx), (combiner), __FILE__, __LINE__, (reason))
+#else
+#define GRPC_COMBINER_DEBUG_ARGS
+#define GRPC_COMBINER_REF(combiner, reason) grpc_combiner_ref((combiner))
+#define GRPC_COMBINER_UNREF(exec_ctx, combiner, reason) \
+  grpc_combiner_unref((exec_ctx), (combiner))
+#endif
+
+// Ref/unref the lock, for when we're sharing the lock ownership
+// Prefer to use the macros above
+grpc_combiner *grpc_combiner_ref(grpc_combiner *lock GRPC_COMBINER_DEBUG_ARGS);
+void grpc_combiner_unref(grpc_exec_ctx *exec_ctx,
+                         grpc_combiner *lock GRPC_COMBINER_DEBUG_ARGS);
 // Fetch a scheduler to schedule closures against
 grpc_closure_scheduler *grpc_combiner_scheduler(grpc_combiner *lock,
                                                 bool covered_by_poller);
diff --git a/src/core/lib/iomgr/resource_quota.c b/src/core/lib/iomgr/resource_quota.c
index 2cc979467f67da235a505970ffeffd4bd5c6de9f..511ffdcdf13bc5c7736c53a3dd30aeb338c90a59 100644
--- a/src/core/lib/iomgr/resource_quota.c
+++ b/src/core/lib/iomgr/resource_quota.c
@@ -599,7 +599,7 @@ grpc_resource_quota *grpc_resource_quota_create(const char *name) {
 void grpc_resource_quota_unref_internal(grpc_exec_ctx *exec_ctx,
                                         grpc_resource_quota *resource_quota) {
   if (gpr_unref(&resource_quota->refs)) {
-    grpc_combiner_destroy(exec_ctx, resource_quota->combiner);
+    GRPC_COMBINER_UNREF(exec_ctx, resource_quota->combiner, "resource_quota");
     gpr_free(resource_quota->name);
     gpr_free(resource_quota);
   }
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index e9e7511c9cc40ca76136a1104c0fe3e419acab13..36f878fdd4ddb7912d6e0c9434f2c3d647198842 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -44,6 +44,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <ifaddrs.h>
 #include <limits.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
@@ -115,6 +116,8 @@ struct grpc_tcp_server {
   bool shutdown;
   /* use SO_REUSEPORT */
   bool so_reuseport;
+  /* expand wildcard addresses to a list of all local addresses */
+  bool expand_wildcard_addrs;
 
   /* linked list of server ports */
   grpc_tcp_listener *head;
@@ -161,6 +164,7 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
   grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
   s->so_reuseport = has_so_reuseport;
   s->resource_quota = grpc_resource_quota_create(NULL);
+  s->expand_wildcard_addrs = false;
   for (size_t i = 0; i < (args == NULL ? 0 : args->num_args); i++) {
     if (0 == strcmp(GRPC_ARG_ALLOW_REUSEPORT, args->args[i].key)) {
       if (args->args[i].type == GRPC_ARG_INTEGER) {
@@ -183,6 +187,15 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
         return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
                                  " must be a pointer to a buffer pool");
       }
+    } else if (0 == strcmp(GRPC_ARG_EXPAND_WILDCARD_ADDRS, args->args[i].key)) {
+      if (args->args[i].type == GRPC_ARG_INTEGER) {
+        s->expand_wildcard_addrs = (args->args[i].value.integer != 0);
+      } else {
+        grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
+        gpr_free(s);
+        return GRPC_ERROR_CREATE(GRPC_ARG_EXPAND_WILDCARD_ADDRS
+                                 " must be an integer");
+      }
     }
   }
   gpr_ref_init(&s->refs, 1);
@@ -504,9 +517,224 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd,
   return err;
 }
 
-/* Insert count new listeners after listener. Every new listener will have the
-   same listen address as listener (SO_REUSEPORT must be enabled). Every new
-   listener is a sibling of listener. */
+/* If successful, add a listener to s for addr, set *dsmode for the socket, and
+   return the *listener. */
+static grpc_error *add_addr_to_server(grpc_tcp_server *s,
+                                      const grpc_resolved_address *addr,
+                                      unsigned port_index, unsigned fd_index,
+                                      grpc_dualstack_mode *dsmode,
+                                      grpc_tcp_listener **listener) {
+  grpc_resolved_address addr4_copy;
+  int fd;
+  grpc_error *err =
+      grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, dsmode, &fd);
+  if (err != GRPC_ERROR_NONE) {
+    return err;
+  }
+  if (*dsmode == GRPC_DSMODE_IPV4 &&
+      grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
+    addr = &addr4_copy;
+  }
+  return add_socket_to_server(s, fd, addr, port_index, fd_index, listener);
+}
+
+/* Bind to "::" to get a port number not used by any address. */
+static grpc_error *get_unused_port(int *port) {
+  grpc_resolved_address wild;
+  grpc_sockaddr_make_wildcard6(0, &wild);
+  grpc_dualstack_mode dsmode;
+  int fd;
+  grpc_error *err =
+      grpc_create_dualstack_socket(&wild, SOCK_STREAM, 0, &dsmode, &fd);
+  if (err != GRPC_ERROR_NONE) {
+    return err;
+  }
+  if (dsmode == GRPC_DSMODE_IPV4) {
+    grpc_sockaddr_make_wildcard4(0, &wild);
+  }
+  if (bind(fd, (const struct sockaddr *)wild.addr, (socklen_t)wild.len) != 0) {
+    err = GRPC_OS_ERROR(errno, "bind");
+    close(fd);
+    return err;
+  }
+  if (getsockname(fd, (struct sockaddr *)wild.addr, (socklen_t *)&wild.len) !=
+      0) {
+    err = GRPC_OS_ERROR(errno, "getsockname");
+    close(fd);
+    return err;
+  }
+  close(fd);
+  *port = grpc_sockaddr_get_port(&wild);
+  return *port <= 0 ? GRPC_ERROR_CREATE("Bad port") : GRPC_ERROR_NONE;
+}
+
+/* Return the listener in s with address addr or NULL. */
+static grpc_tcp_listener *find_listener_with_addr(grpc_tcp_server *s,
+                                                  grpc_resolved_address *addr) {
+  grpc_tcp_listener *l;
+  gpr_mu_lock(&s->mu);
+  for (l = s->head; l != NULL; l = l->next) {
+    if (l->addr.len != addr->len) {
+      continue;
+    }
+    if (memcmp(l->addr.addr, addr->addr, addr->len) == 0) {
+      break;
+    }
+  }
+  gpr_mu_unlock(&s->mu);
+  return l;
+}
+
+/* Get all addresses assigned to network interfaces on the machine and create a
+   listener for each. requested_port is the port to use for every listener, or 0
+   to select one random port that will be used for every listener. Set *out_port
+   to the port selected. Return GRPC_ERROR_NONE only if all listeners were
+   added. */
+static grpc_error *add_all_local_addrs_to_server(grpc_tcp_server *s,
+                                                 unsigned port_index,
+                                                 int requested_port,
+                                                 int *out_port) {
+  struct ifaddrs *ifa = NULL;
+  struct ifaddrs *ifa_it;
+  unsigned fd_index = 0;
+  grpc_tcp_listener *sp = NULL;
+  grpc_error *err = GRPC_ERROR_NONE;
+  if (requested_port == 0) {
+    /* Note: There could be a race where some local addrs can listen on the
+       selected port and some can't. The sane way to handle this would be to
+       retry by recreating the whole grpc_tcp_server. Backing out individual
+       listeners and orphaning the FDs looks like too much trouble. */
+    if ((err = get_unused_port(&requested_port)) != GRPC_ERROR_NONE) {
+      return err;
+    } else if (requested_port <= 0) {
+      return GRPC_ERROR_CREATE("Bad get_unused_port()");
+    }
+    gpr_log(GPR_DEBUG, "Picked unused port %d", requested_port);
+  }
+  if (getifaddrs(&ifa) != 0 || ifa == NULL) {
+    return GRPC_OS_ERROR(errno, "getifaddrs");
+  }
+  for (ifa_it = ifa; ifa_it != NULL; ifa_it = ifa_it->ifa_next) {
+    grpc_resolved_address addr;
+    char *addr_str = NULL;
+    grpc_dualstack_mode dsmode;
+    grpc_tcp_listener *new_sp = NULL;
+    const char *ifa_name = (ifa_it->ifa_name ? ifa_it->ifa_name : "<unknown>");
+    if (ifa_it->ifa_addr == NULL) {
+      continue;
+    } else if (ifa_it->ifa_addr->sa_family == AF_INET) {
+      addr.len = sizeof(struct sockaddr_in);
+    } else if (ifa_it->ifa_addr->sa_family == AF_INET6) {
+      addr.len = sizeof(struct sockaddr_in6);
+    } else {
+      continue;
+    }
+    memcpy(addr.addr, ifa_it->ifa_addr, addr.len);
+    if (!grpc_sockaddr_set_port(&addr, requested_port)) {
+      /* Should never happen, because we check sa_family above. */
+      err = GRPC_ERROR_CREATE("Failed to set port");
+      break;
+    }
+    if (grpc_sockaddr_to_string(&addr_str, &addr, 0) < 0) {
+      addr_str = gpr_strdup("<error>");
+    }
+    gpr_log(GPR_DEBUG,
+            "Adding local addr from interface %s flags 0x%x to server: %s",
+            ifa_name, ifa_it->ifa_flags, addr_str);
+    /* We could have multiple interfaces with the same address (e.g., bonding),
+       so look for duplicates. */
+    if (find_listener_with_addr(s, &addr) != NULL) {
+      gpr_log(GPR_DEBUG, "Skipping duplicate addr %s on interface %s", addr_str,
+              ifa_name);
+      gpr_free(addr_str);
+      continue;
+    }
+    if ((err = add_addr_to_server(s, &addr, port_index, fd_index, &dsmode,
+                                  &new_sp)) != GRPC_ERROR_NONE) {
+      char *err_str = NULL;
+      grpc_error *root_err;
+      if (gpr_asprintf(&err_str, "Failed to add listener: %s", addr_str) < 0) {
+        err_str = gpr_strdup("Failed to add listener");
+      }
+      root_err = GRPC_ERROR_CREATE(err_str);
+      gpr_free(err_str);
+      gpr_free(addr_str);
+      err = grpc_error_add_child(root_err, err);
+      break;
+    } else {
+      GPR_ASSERT(requested_port == new_sp->port);
+      ++fd_index;
+      if (sp != NULL) {
+        new_sp->is_sibling = 1;
+        sp->sibling = new_sp;
+      }
+      sp = new_sp;
+    }
+    gpr_free(addr_str);
+  }
+  freeifaddrs(ifa);
+  if (err != GRPC_ERROR_NONE) {
+    return err;
+  } else if (sp == NULL) {
+    return GRPC_ERROR_CREATE("No local addresses");
+  } else {
+    *out_port = sp->port;
+    return GRPC_ERROR_NONE;
+  }
+}
+
+/* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
+static grpc_error *add_wildcard_addrs_to_server(grpc_tcp_server *s,
+                                                unsigned port_index,
+                                                int requested_port,
+                                                int *out_port) {
+  grpc_resolved_address wild4;
+  grpc_resolved_address wild6;
+  unsigned fd_index = 0;
+  grpc_dualstack_mode dsmode;
+  grpc_tcp_listener *sp = NULL;
+  grpc_tcp_listener *sp2 = NULL;
+  grpc_error *v6_err = GRPC_ERROR_NONE;
+  grpc_error *v4_err = GRPC_ERROR_NONE;
+  *out_port = -1;
+  if (s->expand_wildcard_addrs) {
+    return add_all_local_addrs_to_server(s, port_index, requested_port,
+                                         out_port);
+  }
+  grpc_sockaddr_make_wildcards(requested_port, &wild4, &wild6);
+  /* Try listening on IPv6 first. */
+  if ((v6_err = add_addr_to_server(s, &wild6, port_index, fd_index, &dsmode,
+                                   &sp)) == GRPC_ERROR_NONE) {
+    ++fd_index;
+    requested_port = *out_port = sp->port;
+    if (dsmode == GRPC_DSMODE_DUALSTACK || dsmode == GRPC_DSMODE_IPV4) {
+      return GRPC_ERROR_NONE;
+    }
+  }
+  /* If we got a v6-only socket or nothing, try adding 0.0.0.0. */
+  grpc_sockaddr_set_port(&wild4, requested_port);
+  if ((v4_err = add_addr_to_server(s, &wild4, port_index, fd_index, &dsmode,
+                                   &sp2)) == GRPC_ERROR_NONE) {
+    *out_port = sp2->port;
+    if (sp != NULL) {
+      sp2->is_sibling = 1;
+      sp->sibling = sp2;
+    }
+  }
+  if (*out_port > 0) {
+    GRPC_LOG_IF_ERROR("Failed to add :: listener", v6_err);
+    GRPC_LOG_IF_ERROR("Failed to add 0.0.0.0 listener", v4_err);
+    return GRPC_ERROR_NONE;
+  } else {
+    grpc_error *root_err =
+        GRPC_ERROR_CREATE("Failed to add any wildcard listeners");
+    GPR_ASSERT(v6_err != GRPC_ERROR_NONE && v4_err != GRPC_ERROR_NONE);
+    root_err = grpc_error_add_child(root_err, v6_err);
+    root_err = grpc_error_add_child(root_err, v4_err);
+    return root_err;
+  }
+}
+
 static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) {
   grpc_tcp_listener *sp = NULL;
   char *addr_str;
@@ -559,19 +787,13 @@ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s,
                                      const grpc_resolved_address *addr,
                                      int *out_port) {
   grpc_tcp_listener *sp;
-  grpc_tcp_listener *sp2 = NULL;
-  int fd;
-  grpc_dualstack_mode dsmode;
-  grpc_resolved_address addr6_v4mapped;
-  grpc_resolved_address wild4;
-  grpc_resolved_address wild6;
-  grpc_resolved_address addr4_copy;
-  grpc_resolved_address *allocated_addr = NULL;
   grpc_resolved_address sockname_temp;
-  int port;
+  grpc_resolved_address addr6_v4mapped;
+  int requested_port = grpc_sockaddr_get_port(addr);
   unsigned port_index = 0;
-  unsigned fd_index = 0;
-  grpc_error *errs[2] = {GRPC_ERROR_NONE, GRPC_ERROR_NONE};
+  grpc_dualstack_mode dsmode;
+  grpc_error *err;
+  *out_port = -1;
   if (s->tail != NULL) {
     port_index = s->tail->port_index + 1;
   }
@@ -579,85 +801,34 @@ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s,
 
   /* Check if this is a wildcard port, and if so, try to keep the port the same
      as some previously created listener. */
-  if (grpc_sockaddr_get_port(addr) == 0) {
+  if (requested_port == 0) {
     for (sp = s->head; sp; sp = sp->next) {
       sockname_temp.len = sizeof(struct sockaddr_storage);
-      if (0 == getsockname(sp->fd, (struct sockaddr *)sockname_temp.addr,
+      if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp.addr,
                            (socklen_t *)&sockname_temp.len)) {
-        port = grpc_sockaddr_get_port(&sockname_temp);
-        if (port > 0) {
-          allocated_addr = gpr_malloc(sizeof(grpc_resolved_address));
-          memcpy(allocated_addr, addr, addr->len);
-          grpc_sockaddr_set_port(allocated_addr, port);
-          addr = allocated_addr;
+        int used_port = grpc_sockaddr_get_port(&sockname_temp);
+        if (used_port > 0) {
+          memcpy(&sockname_temp, addr, sizeof(grpc_resolved_address));
+          grpc_sockaddr_set_port(&sockname_temp, used_port);
+          requested_port = used_port;
+          addr = &sockname_temp;
           break;
         }
       }
     }
   }
-
-  sp = NULL;
-
+  if (grpc_sockaddr_is_wildcard(addr, &requested_port)) {
+    return add_wildcard_addrs_to_server(s, port_index, requested_port,
+                                        out_port);
+  }
   if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
     addr = &addr6_v4mapped;
   }
-
-  /* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
-  if (grpc_sockaddr_is_wildcard(addr, &port)) {
-    grpc_sockaddr_make_wildcards(port, &wild4, &wild6);
-
-    /* Try listening on IPv6 first. */
-    addr = &wild6;
-    errs[0] = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
-    if (errs[0] == GRPC_ERROR_NONE) {
-      errs[0] = add_socket_to_server(s, fd, addr, port_index, fd_index, &sp);
-      if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
-        goto done;
-      }
-      if (sp != NULL) {
-        ++fd_index;
-      }
-      /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
-      if (port == 0 && sp != NULL) {
-        grpc_sockaddr_set_port(&wild4, sp->port);
-      }
-    }
-    addr = &wild4;
-  }
-
-  errs[1] = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
-  if (errs[1] == GRPC_ERROR_NONE) {
-    if (dsmode == GRPC_DSMODE_IPV4 &&
-        grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
-      addr = &addr4_copy;
-    }
-    sp2 = sp;
-    errs[1] = add_socket_to_server(s, fd, addr, port_index, fd_index, &sp);
-    if (sp2 != NULL && sp != NULL) {
-      sp2->sibling = sp;
-      sp->is_sibling = 1;
-    }
-  }
-
-done:
-  gpr_free(allocated_addr);
-  if (sp != NULL) {
+  if ((err = add_addr_to_server(s, addr, port_index, 0, &dsmode, &sp)) ==
+      GRPC_ERROR_NONE) {
     *out_port = sp->port;
-    GRPC_ERROR_UNREF(errs[0]);
-    GRPC_ERROR_UNREF(errs[1]);
-    return GRPC_ERROR_NONE;
-  } else {
-    *out_port = -1;
-    char *addr_str = grpc_sockaddr_to_uri(addr);
-    grpc_error *err = grpc_error_set_str(
-        GRPC_ERROR_CREATE_REFERENCING("Failed to add port to server", errs,
-                                      GPR_ARRAY_SIZE(errs)),
-        GRPC_ERROR_STR_TARGET_ADDRESS, addr_str);
-    GRPC_ERROR_UNREF(errs[0]);
-    GRPC_ERROR_UNREF(errs[1]);
-    gpr_free(addr_str);
-    return err;
   }
+  return err;
 }
 
 /* Return listener at port_index or NULL. Should only be called with s->mu
diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json
index 509084a71a6d698c01dbfdec3479ab992d578db1..045207a413dbb631504c1fffe581c954bbf21871 100644
--- a/src/csharp/Grpc.Core.Tests/project.json
+++ b/src/csharp/Grpc.Core.Tests/project.json
@@ -13,8 +13,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -31,8 +31,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/src/csharp/Grpc.Core/NativeDeps.Windows.targets b/src/csharp/Grpc.Core/NativeDeps.Windows.targets
index 93db0935bc10b84cd3a4747631e7caad2e6c0ce1..623f58b95b0b9353b6b5df86d4f6a68d7dc15c4a 100644
--- a/src/csharp/Grpc.Core/NativeDeps.Windows.targets
+++ b/src/csharp/Grpc.Core/NativeDeps.Windows.targets
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <Content Include="..\..\..\vsprojects\$(NativeDependenciesConfiguration)\grpc_csharp_ext.dll">
+    <Content Include="..\..\..\cmake\build\Win32\$(NativeDependenciesConfiguration)\grpc_csharp_ext.dll">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       <Link>grpc_csharp_ext.x86.dll</Link>
     </Content>
diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json
index 9a8880b5d422463547cf15e02dc508c5a1e74d65..81c17151aa5441569e09aba68d695ba9d0144c26 100644
--- a/src/csharp/Grpc.Examples.MathClient/project.json
+++ b/src/csharp/Grpc.Examples.MathClient/project.json
@@ -13,8 +13,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -31,8 +31,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json
index 9a8880b5d422463547cf15e02dc508c5a1e74d65..81c17151aa5441569e09aba68d695ba9d0144c26 100644
--- a/src/csharp/Grpc.Examples.MathServer/project.json
+++ b/src/csharp/Grpc.Examples.MathServer/project.json
@@ -13,8 +13,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -31,8 +31,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/src/csharp/Grpc.Examples.Tests/project.json b/src/csharp/Grpc.Examples.Tests/project.json
index 3e130beeac9c8ad23ab5fea46c731297b169082e..e509621a293218e967582c0baac423bb3c6ac385 100644
--- a/src/csharp/Grpc.Examples.Tests/project.json
+++ b/src/csharp/Grpc.Examples.Tests/project.json
@@ -13,8 +13,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -31,8 +31,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/src/csharp/Grpc.HealthCheck.Tests/project.json b/src/csharp/Grpc.HealthCheck.Tests/project.json
index addc782afe8ed3c0675322827af8feda69a7368a..654454d1cb7fcfa6fce71756da6bb2f72c18e1bd 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/project.json
+++ b/src/csharp/Grpc.HealthCheck.Tests/project.json
@@ -13,8 +13,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -31,8 +31,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/project.json b/src/csharp/Grpc.IntegrationTesting.Client/project.json
index ad81cbc48b36ef30d8830eb915232d75aa98e967..f90528151b4519b9dd5a63660fc71e157d0052a2 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.Client/project.json
@@ -16,8 +16,8 @@
             "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -37,8 +37,8 @@
             "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
index 2c7643b74f0c36ea84eda29113124d65b7a63d46..161e602abcab260288517890dee18588721ce455 100644
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
@@ -16,8 +16,8 @@
             "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -37,8 +37,8 @@
             "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/project.json b/src/csharp/Grpc.IntegrationTesting.Server/project.json
index ad81cbc48b36ef30d8830eb915232d75aa98e967..f90528151b4519b9dd5a63660fc71e157d0052a2 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.Server/project.json
@@ -16,8 +16,8 @@
             "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -37,8 +37,8 @@
             "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
index ad81cbc48b36ef30d8830eb915232d75aa98e967..f90528151b4519b9dd5a63660fc71e157d0052a2 100644
--- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
@@ -16,8 +16,8 @@
             "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -37,8 +37,8 @@
             "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/src/csharp/Grpc.IntegrationTesting/project.json b/src/csharp/Grpc.IntegrationTesting/project.json
index e47b5953da0431595c3f91046d582a72ef60c64f..eba54318a5beb4f632bed1c5fa5140fd0b98a77b 100644
--- a/src/csharp/Grpc.IntegrationTesting/project.json
+++ b/src/csharp/Grpc.IntegrationTesting/project.json
@@ -16,8 +16,8 @@
             "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -37,8 +37,8 @@
             "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/src/csharp/Grpc.Reflection.Tests/project.json b/src/csharp/Grpc.Reflection.Tests/project.json
index 61d3b7e47b7a9f01615f35036984753270c2068a..b90834a25eb255d7699577d4116c4bca6233f670 100644
--- a/src/csharp/Grpc.Reflection.Tests/project.json
+++ b/src/csharp/Grpc.Reflection.Tests/project.json
@@ -13,8 +13,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -31,8 +31,8 @@
         },
         "copyToOutput": {
           "mappings": {
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/src/csharp/README.md b/src/csharp/README.md
index 0405ff88a01c81e3fdfcccebbcf674e5b80f7975..8468eb991ec47b4290a5e177e3231b943bf3d3d0 100644
--- a/src/csharp/README.md
+++ b/src/csharp/README.md
@@ -37,23 +37,15 @@ BUILD FROM SOURCE
 You only need to go through these steps if you are planning to develop gRPC C#.
 If you are a user of gRPC C#, go to Usage section above.
 
-**Windows**
+**Windows, Linux or Mac OS X**
 
-- The grpc_csharp_ext native library needs to be built so you can build the gRPC C# solution. Open the
-  solution `vsprojects/grpc_csharp_ext.sln` in Visual Studio and build it.
-
-- Open `src\csharp\Grpc.sln` (path is relative to gRPC repository root)
-  using Visual Studio
-
-**Linux and Mac OS X**
-
-- The grpc_csharp_ext native library needs to be built so you can build the gRPC C# solution:
-  ```sh
+- The easiest way to build is using the `run_tests.py` script that will take care of building the `grpc_csharp_ext` native library:
+  ```
   # from the gRPC repository root
-  $ tools/run_tests/run_tests.py -c dbg -l csharp --build_only
+  $ python tools/run_tests/run_tests.py -c dbg -l csharp --build_only
   ```
 
-- Use MonoDevelop / Xamarin Studio to open the solution Grpc.sln
+- Use Visual Studio / MonoDevelop / Xamarin Studio to open the solution Grpc.sln
 
 RUNNING TESTS
 -------------
diff --git a/src/csharp/buildall.bat b/src/csharp/buildall.bat
deleted file mode 100644
index 0beb30c19895d3156c112c1abfa1f422265e8fb8..0000000000000000000000000000000000000000
--- a/src/csharp/buildall.bat
+++ /dev/null
@@ -1,59 +0,0 @@
-@rem Copyright 2016, Google Inc.
-@rem All rights reserved.
-@rem
-@rem Redistribution and use in source and binary forms, with or without
-@rem modification, are permitted provided that the following conditions are
-@rem met:
-@rem
-@rem     * Redistributions of source code must retain the above copyright
-@rem notice, this list of conditions and the following disclaimer.
-@rem     * Redistributions in binary form must reproduce the above
-@rem copyright notice, this list of conditions and the following disclaimer
-@rem in the documentation and/or other materials provided with the
-@rem distribution.
-@rem     * Neither the name of Google Inc. nor the names of its
-@rem contributors may be used to endorse or promote products derived from
-@rem this software without specific prior written permission.
-@rem
-@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-@rem Convenience script to build gRPC C# from command line
-
-setlocal
-
-@rem enter this directory
-cd /d %~dp0
-
-@rem Set VS variables (uses Visual Studio 2013)
-@call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
-
-@rem Fetch all dependencies
-nuget restore ..\..\vsprojects\grpc.sln || goto :error
-nuget restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error
-nuget restore ..\..\vsprojects\grpc_protoc_plugins.sln || goto :error
-nuget restore Grpc.sln || goto :error
-
-@rem Build the C# native extension
-msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:Configuration=Debug /p:PlatformToolset=v120 || goto :error
-msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:Configuration=Release /p:PlatformToolset=v120 || goto :error
-
-msbuild Grpc.sln /p:Configuration=Debug || goto :error
-msbuild Grpc.sln /p:Configuration=Release || goto :error
-
-endlocal
-
-goto :EOF
-
-:error
-echo Failed!
-exit /b %errorlevel%
diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
index c3935ce1e094915eb017e130deea9d575e7fbcc2..5584246ad94eb55a6d1c4c4cac9130c3428417a5 100644
--- a/src/objective-c/tests/InteropTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -169,6 +169,8 @@
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
 
+#ifndef GRPC_COMPILE_WITH_CRONET
+// TODO (mxyan): Fix this test
 - (void)testResponsesOverMaxSizeFailWithActionableMessage {
   XCTAssertNotNil(self.class.host);
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"];
@@ -189,6 +191,7 @@
 
   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
 }
+#endif
 
 - (void)testResponsesOver4MBAreAcceptedIfOptedIn {
   XCTAssertNotNil(self.class.host);
diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh
index 81c2885320512e2d89db2663e8c0bfdf9bd45133..677459e0822b25f64d428d33e5b6104838883938 100755
--- a/src/objective-c/tests/run_tests.sh
+++ b/src/objective-c/tests/run_tests.sh
@@ -61,3 +61,11 @@ xcodebuild \
     test \
     | egrep "$XCODEBUILD_FILTER" \
     | egrep -v "(GPBDictionary|GPBArray)" -
+
+xcodebuild \
+    -workspace Tests.xcworkspace \
+    -scheme InteropTestsRemoteWithCronet \
+    -destination name="iPhone 6" \
+    test \
+    | egrep "$XCODEBUILD_FILTER" \
+    | egrep -v "(GPBDictionary|GPBArray)" -
diff --git a/src/proto/grpc/testing/control.proto b/src/proto/grpc/testing/control.proto
index 529313cfb1ea5f38b0d9576838f2d1385acfe5f1..8f0d25c2c96007360d5783973a63aab9e76c16ba 100644
--- a/src/proto/grpc/testing/control.proto
+++ b/src/proto/grpc/testing/control.proto
@@ -139,7 +139,10 @@ message ServerConfig {
   int32 async_server_threads = 7;
   // Specify the number of cores to limit server to, if desired
   int32 core_limit = 8;
-  // payload config, used in generic server
+  // payload config, used in generic server.
+  // Note this must NOT be used in proto (non-generic) servers. For proto servers,
+  // 'response sizes' must be configured from the 'response_size' field of the
+  // 'SimpleRequest' objects in RPC requests.
   PayloadConfig payload_config = 9;
 
   // Specify the cores we should run the server on, if desired
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
index bcc01f39787a08644f7bee34b946c9547849f339..db938e65459c77a5cbc1a21889e575f7cbde4670 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py
@@ -48,6 +48,8 @@ from grpc_tools import protoc
 from tests.unit.framework.common import test_constants
 
 _MESSAGES_IMPORT = b'import "messages.proto";'
+_SPLIT_NAMESPACE = b'package grpc_protoc_plugin.invocation_testing.split;'
+_COMMON_NAMESPACE = b'package grpc_protoc_plugin.invocation_testing;'
 
 
 @contextlib.contextmanager
@@ -163,7 +165,10 @@ class SameSeparateTest(unittest.TestCase, SeparateTestMixin):
         os.makedirs(self.grpc_python_out_directory)
         same_proto_file = os.path.join(self.proto_directory,
                                        'same_separate.proto')
-        open(same_proto_file, 'wb').write(same_proto_contents)
+        open(same_proto_file, 'wb').write(
+            same_proto_contents.replace(
+                _COMMON_NAMESPACE,
+                b'package grpc_protoc_plugin.invocation_testing.same_separate;'))
         protoc_result = protoc.main([
             '',
             '--proto_path={}'.format(self.proto_directory),
@@ -199,7 +204,11 @@ class SameCommonTest(unittest.TestCase, CommonTestMixin):
         os.makedirs(self.python_out_directory)
         same_proto_file = os.path.join(self.proto_directory,
                                        'same_common.proto')
-        open(same_proto_file, 'wb').write(same_proto_contents)
+        open(same_proto_file, 'wb').write(
+            same_proto_contents.replace(
+                _COMMON_NAMESPACE,
+                b'package grpc_protoc_plugin.invocation_testing.same_common;'))
+
         protoc_result = protoc.main([
             '',
             '--proto_path={}'.format(self.proto_directory),
@@ -240,8 +249,14 @@ class SplitCommonTest(unittest.TestCase, CommonTestMixin):
                                            'split_common_messages.proto')
         open(services_proto_file, 'wb').write(
             services_proto_contents.replace(
-                _MESSAGES_IMPORT, b'import "split_common_messages.proto";'))
-        open(messages_proto_file, 'wb').write(messages_proto_contents)
+                _MESSAGES_IMPORT, b'import "split_common_messages.proto";')
+            .replace(
+                _SPLIT_NAMESPACE,
+                b'package grpc_protoc_plugin.invocation_testing.split_common;'))
+        open(messages_proto_file, 'wb').write(
+            messages_proto_contents.replace(
+                _SPLIT_NAMESPACE,
+                b'package grpc_protoc_plugin.invocation_testing.split_common;'))
         protoc_result = protoc.main([
             '',
             '--proto_path={}'.format(self.proto_directory),
@@ -285,8 +300,16 @@ class SplitSeparateTest(unittest.TestCase, SeparateTestMixin):
                                            'split_separate_messages.proto')
         open(services_proto_file, 'wb').write(
             services_proto_contents.replace(
-                _MESSAGES_IMPORT, b'import "split_separate_messages.proto";'))
-        open(messages_proto_file, 'wb').write(messages_proto_contents)
+                _MESSAGES_IMPORT, b'import "split_separate_messages.proto";')
+            .replace(
+                _SPLIT_NAMESPACE,
+                b'package grpc_protoc_plugin.invocation_testing.split_separate;'
+            ))
+        open(messages_proto_file, 'wb').write(
+            messages_proto_contents.replace(
+                _SPLIT_NAMESPACE,
+                b'package grpc_protoc_plugin.invocation_testing.split_separate;'
+            ))
         protoc_result = protoc.main([
             '',
             '--proto_path={}'.format(self.proto_directory),
diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template
index 444fb6a2dc30450516efa5bc865634f5aa81ee76..1c2ef0a9c16748c3af3b136098207090114f6483 100644
--- a/templates/CMakeLists.txt.template
+++ b/templates/CMakeLists.txt.template
@@ -442,7 +442,18 @@
   % endif
   % endfor
   )
-  
+
+  if(WIN32 AND MSVC)
+    set_target_properties(${lib.name} PROPERTIES COMPILE_PDB_NAME "${lib.name}"
+      COMPILE_PDB_OUTPUT_DIRECTORY <%text>"${CMAKE_BINARY_DIR}</%text>"
+    )
+    if (gRPC_INSTALL)
+      install(FILES <%text>${CMAKE_CURRENT_BINARY_DIR}/</%text>${lib.name}.pdb
+        DESTINATION <%text>${CMAKE_INSTALL_LIBDIR}</%text> OPTIONAL
+      )
+    endif()
+  endif()
+
   % for src in lib.src:
   % if proto_re.match(src):
   protobuf_generate_grpc_cpp(
diff --git a/templates/src/csharp/build_options.include b/templates/src/csharp/build_options.include
index 9a32b7c6f454876722e31338eeacc8bc0459f719..db4cc198039cc30ee666086e422d7fd4739d4fb3 100644
--- a/templates/src/csharp/build_options.include
+++ b/templates/src/csharp/build_options.include
@@ -21,8 +21,8 @@
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             % endif
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Debug/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
           }
@@ -44,8 +44,8 @@
             "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
             "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             % endif
-            "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
-            "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x64.dll": "../../../cmake/build/x64/Release/grpc_csharp_ext.dll",
+            "grpc_csharp_ext.x86.dll": "../../../cmake/build/Win32/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
             "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
           }
diff --git a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template
index 80420af7db2fceb54fc19bbca6622a9da9d87e44..3a10cfab3cca31e21c5e0ad2e572bd80c7a5cecd 100644
--- a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template
+++ b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template
@@ -103,7 +103,7 @@
     s.preserve_paths = plugin
 
     # Restrict the protoc version to the one supported by this plugin.
-    s.dependency '!ProtoCompiler', '3.0.2'
+    s.dependency '!ProtoCompiler', '3.1.0'
     # For the Protobuf dependency not to complain:
     s.ios.deployment_target = '7.1'
     s.osx.deployment_target = '10.9'
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5171071900712960 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5171071900712960
new file mode 100644
index 0000000000000000000000000000000000000000..70ca3a336e32e06e4c7fea6a0fed57c9d7e5eb2b
Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5171071900712960 differ
diff --git a/test/core/handshake/client_ssl.c b/test/core/handshake/client_ssl.c
index a22133e629f49cc40a9b81f44f8ad0c798063a92..1a06fd625581008b97b203d68f1e267e19f7ac51 100644
--- a/test/core/handshake/client_ssl.c
+++ b/test/core/handshake/client_ssl.c
@@ -59,13 +59,17 @@ typedef struct {
   char *alpn_preferred;
 } server_args;
 
-// From https://wiki.openssl.org/index.php/Simple_TLS_Server.
-static int create_socket(int port) {
+// Based on https://wiki.openssl.org/index.php/Simple_TLS_Server.
+// Pick an arbitrary unused port and return it in *out_port. Return
+// an fd>=0 on success.
+static int create_socket(int *out_port) {
   int s;
   struct sockaddr_in addr;
+  socklen_t addr_len;
+  *out_port = -1;
 
   addr.sin_family = AF_INET;
-  addr.sin_port = htons((uint16_t)port);
+  addr.sin_port = 0;
   addr.sin_addr.s_addr = htonl(INADDR_ANY);
 
   s = socket(AF_INET, SOCK_STREAM, 0);
@@ -76,7 +80,7 @@ static int create_socket(int port) {
 
   if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
     perror("Unable to bind");
-    gpr_log(GPR_ERROR, "Unable to bind to %d", port);
+    gpr_log(GPR_ERROR, "%s", "Unable to bind to any port");
     close(s);
     return -1;
   }
@@ -87,6 +91,16 @@ static int create_socket(int port) {
     return -1;
   }
 
+  addr_len = sizeof(addr);
+  if (getsockname(s, (struct sockaddr *)&addr, &addr_len) != 0 ||
+      addr_len > sizeof(addr)) {
+    perror("getsockname");
+    gpr_log(GPR_ERROR, "%s", "Unable to get socket local address");
+    close(s);
+    return -1;
+  }
+
+  *out_port = ntohs(addr.sin_port);
   return s;
 }
 
@@ -215,13 +229,12 @@ static bool client_ssl_test(char *server_alpn_preferred) {
   int server_socket = -1;
   int socket_retries = 30;
   while (server_socket == -1 && socket_retries-- > 0) {
-    port = grpc_pick_unused_port_or_die();
-    server_socket = create_socket(port);
+    server_socket = create_socket(&port);
     if (server_socket == -1) {
       sleep(1);
     }
   }
-  GPR_ASSERT(server_socket > 0);
+  GPR_ASSERT(server_socket > 0 && port > 0);
 
   // Launch the TLS server thread.
   gpr_thd_options thdopt = gpr_thd_options_default();
diff --git a/test/core/iomgr/combiner_test.c b/test/core/iomgr/combiner_test.c
index 4c9275a673278f249ec09482b876ae0a623cbf8b..bc4d2af8ac43ab6454a45eebd77eaccc37a76c9d 100644
--- a/test/core/iomgr/combiner_test.c
+++ b/test/core/iomgr/combiner_test.c
@@ -44,7 +44,7 @@
 static void test_no_op(void) {
   gpr_log(GPR_DEBUG, "test_no_op");
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_combiner_destroy(&exec_ctx, grpc_combiner_create(NULL));
+  GRPC_COMBINER_UNREF(&exec_ctx, grpc_combiner_create(NULL), "test_no_op");
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -65,7 +65,7 @@ static void test_execute_one(void) {
                      GRPC_ERROR_NONE);
   grpc_exec_ctx_flush(&exec_ctx);
   GPR_ASSERT(done);
-  grpc_combiner_destroy(&exec_ctx, lock);
+  GRPC_COMBINER_UNREF(&exec_ctx, lock, "test_execute_one");
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -125,7 +125,7 @@ static void test_execute_many(void) {
     gpr_thd_join(thds[i]);
   }
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_combiner_destroy(&exec_ctx, lock);
+  GRPC_COMBINER_UNREF(&exec_ctx, lock, "test_execute_many");
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -153,7 +153,7 @@ static void test_execute_finally(void) {
                      GRPC_ERROR_NONE);
   grpc_exec_ctx_flush(&exec_ctx);
   GPR_ASSERT(got_in_finally);
-  grpc_combiner_destroy(&exec_ctx, lock);
+  GRPC_COMBINER_UNREF(&exec_ctx, lock, "test_execute_finally");
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index 7122cd1e8697b25acb32eb021a2ebe7e7f811b4e..4a6570015f2a103daa4b5bb982ae6ac0c7e8bd59 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -39,9 +39,12 @@
 #include "src/core/lib/iomgr/tcp_server.h"
 
 #include <errno.h>
+#include <ifaddrs.h>
 #include <netinet/in.h>
+#include <stdio.h>
 #include <string.h>
 #include <sys/socket.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 #include <grpc/grpc.h>
@@ -50,6 +53,7 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
 
+#include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -62,7 +66,7 @@ static gpr_mu *g_mu;
 static grpc_pollset *g_pollset;
 static int g_nconnects = 0;
 
-typedef struct on_connect_result {
+typedef struct {
   /* Owns a ref to server. */
   grpc_tcp_server *server;
   unsigned port_index;
@@ -70,15 +74,41 @@ typedef struct on_connect_result {
   int server_fd;
 } on_connect_result;
 
-typedef struct server_weak_ref {
+typedef struct {
   grpc_tcp_server *server;
 
   /* arg is this server_weak_ref. */
   grpc_closure server_shutdown;
 } server_weak_ref;
 
+#define MAX_URI 1024
+typedef struct {
+  grpc_resolved_address addr;
+  char str[MAX_URI];
+} test_addr;
+
+#define MAX_ADDRS 100
+typedef struct {
+  size_t naddrs;
+  test_addr addrs[MAX_ADDRS];
+} test_addrs;
+
 static on_connect_result g_result = {NULL, 0, 0, -1};
 
+static char family_name_buf[1024];
+static const char *sock_family_name(int family) {
+  if (family == AF_INET) {
+    return "AF_INET";
+  } else if (family == AF_INET6) {
+    return "AF_INET6";
+  } else if (family == AF_UNSPEC) {
+    return "AF_UNSPEC";
+  } else {
+    sprintf(family_name_buf, "%d", family);
+    return family_name_buf;
+  }
+}
+
 static void on_connect_result_init(on_connect_result *result) {
   result->server = NULL;
   result->port_index = 0;
@@ -118,6 +148,18 @@ static void server_weak_ref_set(server_weak_ref *weak_ref,
   weak_ref->server = server;
 }
 
+static void test_addr_init_str(test_addr *addr) {
+  char *str = NULL;
+  if (grpc_sockaddr_to_string(&str, &addr->addr, 0) != -1) {
+    size_t str_len;
+    memcpy(addr->str, str, (str_len = strnlen(str, sizeof(addr->str) - 1)));
+    addr->str[str_len] = '\0';
+    gpr_free(str);
+  } else {
+    addr->str[0] = '\0';
+  }
+}
+
 static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
                        grpc_pollset *pollset,
                        grpc_tcp_server_acceptor *acceptor) {
@@ -168,7 +210,7 @@ static void test_no_op_with_port(void) {
   memset(&resolved_addr, 0, sizeof(resolved_addr));
   resolved_addr.len = sizeof(struct sockaddr_in);
   addr->sin_family = AF_INET;
-  int port;
+  int port = -1;
   GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr, &port) ==
                  GRPC_ERROR_NONE &&
              port > 0);
@@ -185,7 +227,7 @@ static void test_no_op_with_port_and_start(void) {
   GPR_ASSERT(GRPC_ERROR_NONE ==
              grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s));
   LOG_TEST("test_no_op_with_port_and_start");
-  int port;
+  int port = -1;
 
   memset(&resolved_addr, 0, sizeof(resolved_addr));
   resolved_addr.len = sizeof(struct sockaddr_in);
@@ -200,74 +242,115 @@ static void test_no_op_with_port_and_start(void) {
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
-static void tcp_connect(grpc_exec_ctx *exec_ctx, const struct sockaddr *remote,
-                        socklen_t remote_len, on_connect_result *result) {
+static grpc_error *tcp_connect(grpc_exec_ctx *exec_ctx, const test_addr *remote,
+                               on_connect_result *result) {
   gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10);
-  int clifd = socket(remote->sa_family, SOCK_STREAM, 0);
+  int clifd;
   int nconnects_before;
+  const struct sockaddr *remote_addr =
+      (const struct sockaddr *)remote->addr.addr;
 
+  gpr_log(GPR_INFO, "Connecting to %s", remote->str);
   gpr_mu_lock(g_mu);
   nconnects_before = g_nconnects;
   on_connect_result_init(&g_result);
-  GPR_ASSERT(clifd >= 0);
-  gpr_log(GPR_DEBUG, "start connect");
-  GPR_ASSERT(connect(clifd, remote, remote_len) == 0);
+  clifd = socket(remote_addr->sa_family, SOCK_STREAM, 0);
+  if (clifd < 0) {
+    gpr_mu_unlock(g_mu);
+    return GRPC_OS_ERROR(errno, "Failed to create socket");
+  }
+  gpr_log(GPR_DEBUG, "start connect to %s", remote->str);
+  if (connect(clifd, remote_addr, (socklen_t)remote->addr.len) != 0) {
+    gpr_mu_unlock(g_mu);
+    close(clifd);
+    return GRPC_OS_ERROR(errno, "connect");
+  }
   gpr_log(GPR_DEBUG, "wait");
   while (g_nconnects == nconnects_before &&
          gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) {
     grpc_pollset_worker *worker = NULL;
-    GPR_ASSERT(GRPC_LOG_IF_ERROR(
-        "pollset_work",
-        grpc_pollset_work(exec_ctx, g_pollset, &worker,
-                          gpr_now(GPR_CLOCK_MONOTONIC), deadline)));
+    grpc_error *err;
+    if ((err = grpc_pollset_work(exec_ctx, g_pollset, &worker,
+                                 gpr_now(GPR_CLOCK_MONOTONIC), deadline)) !=
+        GRPC_ERROR_NONE) {
+      gpr_mu_unlock(g_mu);
+      close(clifd);
+      return err;
+    }
     gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(exec_ctx);
     gpr_mu_lock(g_mu);
   }
   gpr_log(GPR_DEBUG, "wait done");
-  GPR_ASSERT(g_nconnects == nconnects_before + 1);
+  if (g_nconnects != nconnects_before + 1) {
+    gpr_mu_unlock(g_mu);
+    close(clifd);
+    return GRPC_ERROR_CREATE("Didn't connect");
+  }
   close(clifd);
   *result = g_result;
 
   gpr_mu_unlock(g_mu);
+  gpr_log(GPR_INFO, "Result (%d, %d) fd %d", result->port_index,
+          result->fd_index, result->server_fd);
+  grpc_tcp_server_unref(exec_ctx, result->server);
+  return GRPC_ERROR_NONE;
 }
 
-/* Tests a tcp server with multiple ports. TODO(daniel-j-born): Multiple fds for
-   the same port should be tested. */
-static void test_connect(unsigned n) {
+/* Tests a tcp server on "::" listeners with multiple ports. If channel_args is
+   non-NULL, pass them to the server. If dst_addrs is non-NULL, use valid addrs
+   as destination addrs (port is not set). If dst_addrs is NULL, use listener
+   addrs as destination addrs. If test_dst_addrs is true, test connectivity with
+   each destination address, set grpc_resolved_address::len=0 for failures, but
+   don't fail the overall unitest. */
+static void test_connect(size_t num_connects,
+                         const grpc_channel_args *channel_args,
+                         test_addrs *dst_addrs, bool test_dst_addrs) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_resolved_address resolved_addr;
   grpc_resolved_address resolved_addr1;
-  struct sockaddr_storage *addr = (struct sockaddr_storage *)resolved_addr.addr;
-  struct sockaddr_storage *addr1 =
+  struct sockaddr_storage *const addr =
+      (struct sockaddr_storage *)resolved_addr.addr;
+  struct sockaddr_storage *const addr1 =
       (struct sockaddr_storage *)resolved_addr1.addr;
   unsigned svr_fd_count;
+  int port;
   int svr_port;
   unsigned svr1_fd_count;
   int svr1_port;
   grpc_tcp_server *s;
+  const unsigned num_ports = 2;
   GPR_ASSERT(GRPC_ERROR_NONE ==
-             grpc_tcp_server_create(&exec_ctx, NULL, NULL, &s));
-  unsigned i;
+             grpc_tcp_server_create(&exec_ctx, NULL, channel_args, &s));
+  unsigned port_num;
   server_weak_ref weak_ref;
   server_weak_ref_init(&weak_ref);
+  server_weak_ref_set(&weak_ref, s);
   LOG_TEST("test_connect");
-  gpr_log(GPR_INFO, "clients=%d", n);
+  gpr_log(GPR_INFO,
+          "clients=%lu, num chan args=%lu, remote IP=%s, test_dst_addrs=%d",
+          (unsigned long)num_connects,
+          (unsigned long)(channel_args != NULL ? channel_args->num_args : 0),
+          dst_addrs != NULL ? "<specific>" : "::", test_dst_addrs);
   memset(&resolved_addr, 0, sizeof(resolved_addr));
   memset(&resolved_addr1, 0, sizeof(resolved_addr1));
   resolved_addr.len = sizeof(struct sockaddr_storage);
   resolved_addr1.len = sizeof(struct sockaddr_storage);
   addr->ss_family = addr1->ss_family = AF_INET;
-  GPR_ASSERT(GRPC_ERROR_NONE ==
-             grpc_tcp_server_add_port(s, &resolved_addr, &svr_port));
+  GPR_ASSERT(GRPC_LOG_IF_ERROR(
+      "grpc_tcp_server_add_port",
+      grpc_tcp_server_add_port(s, &resolved_addr, &svr_port)));
+  gpr_log(GPR_INFO, "Allocated port %d", svr_port);
   GPR_ASSERT(svr_port > 0);
   /* Cannot use wildcard (port==0), because add_port() will try to reuse the
      same port as a previous add_port(). */
   svr1_port = grpc_pick_unused_port_or_die();
+  GPR_ASSERT(svr1_port > 0);
+  gpr_log(GPR_INFO, "Picked unused port %d", svr1_port);
   grpc_sockaddr_set_port(&resolved_addr1, svr1_port);
-  GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr1, &svr_port) ==
+  GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr1, &port) ==
                  GRPC_ERROR_NONE &&
-             svr_port == svr1_port);
+             port == svr1_port);
 
   /* Bad port_index. */
   GPR_ASSERT(grpc_tcp_server_port_fd_count(s, 2) == 0);
@@ -283,58 +366,70 @@ static void test_connect(unsigned n) {
   svr1_fd_count = grpc_tcp_server_port_fd_count(s, 1);
   GPR_ASSERT(svr1_fd_count >= 1);
 
-  for (i = 0; i < svr_fd_count; ++i) {
-    int fd = grpc_tcp_server_port_fd(s, 0, i);
-    GPR_ASSERT(fd >= 0);
-    if (i == 0) {
-      GPR_ASSERT(getsockname(fd, (struct sockaddr *)addr,
-                             (socklen_t *)&resolved_addr.len) == 0);
-      GPR_ASSERT(resolved_addr.len <= sizeof(*addr));
-    }
-  }
-  for (i = 0; i < svr1_fd_count; ++i) {
-    int fd = grpc_tcp_server_port_fd(s, 1, i);
-    GPR_ASSERT(fd >= 0);
-    if (i == 0) {
-      GPR_ASSERT(getsockname(fd, (struct sockaddr *)addr1,
-                             (socklen_t *)&resolved_addr1.len) == 0);
-      GPR_ASSERT(resolved_addr1.len <= sizeof(*addr1));
-    }
-  }
-
   grpc_tcp_server_start(&exec_ctx, s, &g_pollset, 1, on_connect, NULL);
 
-  for (i = 0; i < n; i++) {
-    on_connect_result result;
-    int svr_fd;
-    on_connect_result_init(&result);
-    tcp_connect(&exec_ctx, (struct sockaddr *)addr,
-                (socklen_t)resolved_addr.len, &result);
-    GPR_ASSERT(result.server_fd >= 0);
-    svr_fd = result.server_fd;
-    GPR_ASSERT(grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) ==
-               result.server_fd);
-    GPR_ASSERT(result.port_index == 0);
-    GPR_ASSERT(result.fd_index < svr_fd_count);
-    GPR_ASSERT(result.server == s);
-    if (weak_ref.server == NULL) {
-      server_weak_ref_set(&weak_ref, result.server);
+  if (dst_addrs != NULL) {
+    int ports[] = {svr_port, svr1_port};
+    for (port_num = 0; port_num < num_ports; ++port_num) {
+      size_t dst_idx;
+      size_t num_tested = 0;
+      for (dst_idx = 0; dst_idx < dst_addrs->naddrs; ++dst_idx) {
+        test_addr dst = dst_addrs->addrs[dst_idx];
+        on_connect_result result;
+        grpc_error *err;
+        if (dst.addr.len == 0) {
+          gpr_log(GPR_DEBUG, "Skipping test of non-functional local IP %s",
+                  dst.str);
+          continue;
+        }
+        GPR_ASSERT(grpc_sockaddr_set_port(&dst.addr, ports[port_num]));
+        test_addr_init_str(&dst);
+        ++num_tested;
+        on_connect_result_init(&result);
+        if ((err = tcp_connect(&exec_ctx, &dst, &result)) == GRPC_ERROR_NONE &&
+            result.server_fd >= 0 && result.server == s) {
+          continue;
+        }
+        gpr_log(GPR_ERROR, "Failed to connect to %s: %s", dst.str,
+                grpc_error_string(err));
+        GPR_ASSERT(test_dst_addrs);
+        dst_addrs->addrs[dst_idx].addr.len = 0;
+        GRPC_ERROR_UNREF(err);
+      }
+      GPR_ASSERT(num_tested > 0);
+    }
+  } else {
+    for (port_num = 0; port_num < num_ports; ++port_num) {
+      const unsigned num_fds = grpc_tcp_server_port_fd_count(s, port_num);
+      unsigned fd_num;
+      for (fd_num = 0; fd_num < num_fds; ++fd_num) {
+        int fd = grpc_tcp_server_port_fd(s, port_num, fd_num);
+        size_t connect_num;
+        test_addr dst;
+        GPR_ASSERT(fd >= 0);
+        dst.addr.len = sizeof(dst.addr.addr);
+        GPR_ASSERT(getsockname(fd, (struct sockaddr *)dst.addr.addr,
+                               (socklen_t *)&dst.addr.len) == 0);
+        GPR_ASSERT(dst.addr.len <= sizeof(dst.addr.addr));
+        test_addr_init_str(&dst);
+        gpr_log(GPR_INFO, "(%d, %d) fd %d family %s listening on %s", port_num,
+                fd_num, fd, sock_family_name(addr->ss_family), dst.str);
+        for (connect_num = 0; connect_num < num_connects; ++connect_num) {
+          on_connect_result result;
+          on_connect_result_init(&result);
+          GPR_ASSERT(GRPC_LOG_IF_ERROR("tcp_connect",
+                                       tcp_connect(&exec_ctx, &dst, &result)));
+          GPR_ASSERT(result.server_fd == fd);
+          GPR_ASSERT(result.port_index == port_num);
+          GPR_ASSERT(result.fd_index == fd_num);
+          GPR_ASSERT(result.server == s);
+          GPR_ASSERT(
+              grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) ==
+              result.server_fd);
+        }
+      }
     }
-    grpc_tcp_server_unref(&exec_ctx, result.server);
-
-    on_connect_result_init(&result);
-    tcp_connect(&exec_ctx, (struct sockaddr *)addr1,
-                (socklen_t)resolved_addr1.len, &result);
-    GPR_ASSERT(result.server_fd >= 0);
-    GPR_ASSERT(result.server_fd != svr_fd);
-    GPR_ASSERT(grpc_tcp_server_port_fd(s, result.port_index, result.fd_index) ==
-               result.server_fd);
-    GPR_ASSERT(result.port_index == 1);
-    GPR_ASSERT(result.fd_index < svr_fd_count);
-    GPR_ASSERT(result.server == s);
-    grpc_tcp_server_unref(&exec_ctx, result.server);
   }
-
   /* Weak ref to server valid until final unref. */
   GPR_ASSERT(weak_ref.server != NULL);
   GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 0) >= 0);
@@ -354,6 +449,12 @@ static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p,
 int main(int argc, char **argv) {
   grpc_closure destroyed;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_arg chan_args[] = {
+      {GRPC_ARG_INTEGER, GRPC_ARG_EXPAND_WILDCARD_ADDRS, {.integer = 1}}};
+  const grpc_channel_args channel_args = {1, chan_args};
+  struct ifaddrs *ifa = NULL;
+  struct ifaddrs *ifa_it;
+  test_addrs dst_addrs;
   grpc_test_init(argc, argv);
   grpc_init();
   g_pollset = gpr_malloc(grpc_pollset_size());
@@ -363,8 +464,45 @@ int main(int argc, char **argv) {
   test_no_op_with_start();
   test_no_op_with_port();
   test_no_op_with_port_and_start();
-  test_connect(1);
-  test_connect(10);
+
+  if (getifaddrs(&ifa) != 0 || ifa == NULL) {
+    gpr_log(GPR_ERROR, "getifaddrs: %s", strerror(errno));
+    return EXIT_FAILURE;
+  }
+  dst_addrs.naddrs = 0;
+  for (ifa_it = ifa; ifa_it != NULL && dst_addrs.naddrs < MAX_ADDRS;
+       ifa_it = ifa_it->ifa_next) {
+    if (ifa_it->ifa_addr == NULL) {
+      continue;
+    } else if (ifa_it->ifa_addr->sa_family == AF_INET) {
+      dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in);
+    } else if (ifa_it->ifa_addr->sa_family == AF_INET6) {
+      dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in6);
+    } else {
+      continue;
+    }
+    memcpy(dst_addrs.addrs[dst_addrs.naddrs].addr.addr, ifa_it->ifa_addr,
+           dst_addrs.addrs[dst_addrs.naddrs].addr.len);
+    GPR_ASSERT(
+        grpc_sockaddr_set_port(&dst_addrs.addrs[dst_addrs.naddrs].addr, 0));
+    test_addr_init_str(&dst_addrs.addrs[dst_addrs.naddrs]);
+    ++dst_addrs.naddrs;
+  }
+  freeifaddrs(ifa);
+  ifa = NULL;
+
+  /* Connect to same addresses as listeners. */
+  test_connect(1, NULL, NULL, false);
+  test_connect(10, NULL, NULL, false);
+
+  /* Set dst_addrs.addrs[i].len=0 for dst_addrs that are unreachable with a "::"
+     listener. */
+  test_connect(1, NULL, &dst_addrs, true);
+
+  /* Test connect(2) with dst_addrs. */
+  test_connect(1, &channel_args, &dst_addrs, false);
+  /* Test connect(2) with dst_addrs. */
+  test_connect(10, &channel_args, &dst_addrs, false);
 
   grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
                     grpc_schedule_on_exec_ctx);
@@ -372,7 +510,7 @@ int main(int argc, char **argv) {
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
   gpr_free(g_pollset);
-  return 0;
+  return EXIT_SUCCESS;
 }
 
 #else /* GRPC_POSIX_SOCKET */
diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6369e605d5382ed4ee1cd4ab89f5894c62afa70c
--- /dev/null
+++ b/tools/distrib/pylint_code.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# Copyright 2017, 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.
+
+set -ex
+
+# change to root directory
+cd $(dirname $0)/../..
+
+DIRS=src/python/grpcio/grpc
+
+VIRTUALENV=python_pylint_venv
+
+virtualenv $VIRTUALENV
+PYTHON=`realpath $VIRTUALENV/bin/python`
+$PYTHON -m pip install pylint==1.6.5
+
+for dir in $DIRS; do
+  $PYTHON -m pylint --rcfile=.pylintrc -rn $dir || exit $?
+done
+
+exit 0
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index f215f1b5d1ad85b938805af429d891dd46a7573d..0706cdca0ff47bde0ccb68ac4679eb56c7eb7ec6 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -810,12 +810,14 @@ include/grpc++/impl/codegen/client_unary_call.h \
 include/grpc++/impl/codegen/completion_queue.h \
 include/grpc++/impl/codegen/completion_queue_tag.h \
 include/grpc++/impl/codegen/config.h \
+include/grpc++/impl/codegen/config_protobuf.h \
 include/grpc++/impl/codegen/core_codegen.h \
 include/grpc++/impl/codegen/core_codegen_interface.h \
 include/grpc++/impl/codegen/create_auth_context.h \
 include/grpc++/impl/codegen/grpc_library.h \
 include/grpc++/impl/codegen/metadata_map.h \
 include/grpc++/impl/codegen/method_handler_impl.h \
+include/grpc++/impl/codegen/proto_utils.h \
 include/grpc++/impl/codegen/rpc_method.h \
 include/grpc++/impl/codegen/rpc_service_method.h \
 include/grpc++/impl/codegen/security/auth_context.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 19b4a9b02d48288136594c6334a47f2c4ebaaf13..cb0a3e55f8d0093f62d8a96a29c0ea33f88f3b02 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -810,6 +810,7 @@ include/grpc++/impl/codegen/client_unary_call.h \
 include/grpc++/impl/codegen/completion_queue.h \
 include/grpc++/impl/codegen/completion_queue_tag.h \
 include/grpc++/impl/codegen/config.h \
+include/grpc++/impl/codegen/config_protobuf.h \
 include/grpc++/impl/codegen/core_codegen.h \
 include/grpc++/impl/codegen/core_codegen.h \
 include/grpc++/impl/codegen/core_codegen_interface.h \
@@ -817,6 +818,7 @@ include/grpc++/impl/codegen/create_auth_context.h \
 include/grpc++/impl/codegen/grpc_library.h \
 include/grpc++/impl/codegen/metadata_map.h \
 include/grpc++/impl/codegen/method_handler_impl.h \
+include/grpc++/impl/codegen/proto_utils.h \
 include/grpc++/impl/codegen/rpc_method.h \
 include/grpc++/impl/codegen/rpc_service_method.h \
 include/grpc++/impl/codegen/security/auth_context.h \
diff --git a/tools/profiling/latency_profile/run_latency_profile.sh b/tools/profiling/latency_profile/run_latency_profile.sh
index 715f525d2ffd55c91e09ded55d8411d056f8a5b8..e9baee09574aebdfb3392f5f66e6fe487a283b94 100755
--- a/tools/profiling/latency_profile/run_latency_profile.sh
+++ b/tools/profiling/latency_profile/run_latency_profile.sh
@@ -44,4 +44,4 @@ else
   PYTHON=python2.7
 fi
 
-$PYTHON tools/run_tests/run_microbenchmark.py bm_fullstack
+$PYTHON tools/run_tests/run_microbenchmark.py --collect summary perf latency --bigquery_upload
diff --git a/tools/profiling/microbenchmarks/bm2bq.py b/tools/profiling/microbenchmarks/bm2bq.py
new file mode 100755
index 0000000000000000000000000000000000000000..124dbdfec529d5f8d9106160aecca41d3cc29616
--- /dev/null
+++ b/tools/profiling/microbenchmarks/bm2bq.py
@@ -0,0 +1,162 @@
+#!/usr/bin/env python2.7
+#
+# Convert google-benchmark json output to something that can be uploaded to
+# BigQuery
+#
+#
+# Copyright 2017, 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.
+
+import sys
+import json
+import csv
+import os
+
+columns = [
+  ('jenkins_build', 'integer'),
+  ('jenkins_job', 'string'),
+  ('date', 'timestamp'),
+  ('cpu_scaling_enabled', 'boolean'),
+  ('num_cpus', 'integer'),
+  ('mhz_per_cpu', 'integer'),
+  ('library_build_type', 'string'),
+  ('name', 'string'),
+  ('fixture', 'string'),
+  ('client_mutator', 'string'),
+  ('server_mutator', 'string'),
+  ('request_size', 'integer'),
+  ('response_size', 'integer'),
+  ('request_count', 'integer'),
+  ('iterations', 'integer'),
+  ('time_unit', 'string'),
+  ('real_time', 'integer'),
+  ('cpu_time', 'integer'),
+  ('bytes_per_second', 'float'),
+  ('allocs_per_iteration', 'float'),
+  ('locks_per_iteration', 'float'),
+  ('writes_per_iteration', 'float'),
+]
+
+if sys.argv[1] == '--schema':
+  print ',\n'.join('%s:%s' % (k, t.upper()) for k, t in columns)
+  sys.exit(0)
+
+with open(sys.argv[1]) as f:
+  js = json.loads(f.read())
+
+writer = csv.DictWriter(sys.stdout, [c for c,t in columns])
+
+bm_specs = {
+  'BM_UnaryPingPong': {
+    'tpl': ['fixture', 'client_mutator', 'server_mutator'],
+    'dyn': ['request_size', 'response_size'],
+  },
+  'BM_PumpStreamClientToServer': {
+    'tpl': ['fixture'],
+    'dyn': ['request_size'],
+  },
+  'BM_PumpStreamServerToClient': {
+    'tpl': ['fixture'],
+    'dyn': ['request_size'],
+  },
+  'BM_StreamingPingPong': {
+    'tpl': ['fixture', 'client_mutator', 'server_mutator'],
+    'dyn': ['request_size', 'request_count'],
+  },
+  'BM_StreamingPingPongMsgs': {
+    'tpl': ['fixture', 'client_mutator', 'server_mutator'],
+    'dyn': ['request_size'],
+  }
+}
+
+def numericalize(s):
+  if not s: return ''
+  if s[-1] == 'k':
+    return int(s[:-1]) * 1024
+  if s[-1] == 'M':
+    return int(s[:-1]) * 1024 * 1024
+  if 0 <= (ord(s[-1]) - ord('0')) <= 9:
+    return int(s)
+  assert 'not a number: %s' % s
+
+def parse_name(name):
+  rest = name
+  out = {}
+  tpl_args = []
+  dyn_args = []
+  if '<' in rest:
+    tpl_bit = rest[rest.find('<') + 1 : rest.rfind('>')]
+    arg = ''
+    nesting = 0
+    for c in tpl_bit:
+      if c == '<':
+        nesting += 1
+        arg += c
+      elif c == '>':
+        nesting -= 1
+        arg += c
+      elif c == ',':
+        if nesting == 0:
+          tpl_args.append(arg.strip())
+          arg = ''
+        else:
+          arg += c
+      else:
+        arg += c
+    tpl_args.append(arg.strip())
+    rest = rest[:rest.find('<')] + rest[rest.rfind('>') + 1:]
+  if '/' in rest:
+    s = rest.split('/')
+    rest = s[0]
+    dyn_args = s[1:]
+  name = rest
+  assert name in bm_specs
+  assert len(dyn_args) == len(bm_specs[name]['dyn'])
+  assert len(tpl_args) == len(bm_specs[name]['tpl'])
+  out['name'] = name
+  out.update(dict((k, numericalize(v)) for k, v in zip(bm_specs[name]['dyn'], dyn_args)))
+  out.update(dict(zip(bm_specs[name]['tpl'], tpl_args)))
+  return out
+
+for bm in js['benchmarks']:
+  context = js['context']
+  labels_list = [s.split(':') for s in bm.get('label', '').split(' ')]
+  for el in labels_list:
+    el[0] = el[0].replace('/iter', '_per_iteration')
+  labels = dict(labels_list)
+  row = {
+    'jenkins_build': os.environ.get('BUILD_NUMBER', ''),
+    'jenkins_job': os.environ.get('JOB_NAME', ''),
+  }
+  row.update(context)
+  row.update(bm)
+  row.update(parse_name(row['name']))
+  row.update(labels)
+  del row['label']
+  writer.writerow(row)
diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py
index 005d99790ad90799f0f4e4526f8312cdff11581f..aba7b8a3054ba8b63ae387d09e85ce3aec0e4c9e 100644
--- a/tools/run_tests/artifacts/artifact_targets.py
+++ b/tools/run_tests/artifacts/artifact_targets.py
@@ -183,24 +183,14 @@ class CSharpExtArtifact:
     self.labels = ['artifact', 'csharp', platform, arch]
 
   def pre_build_jobspecs(self):
-    if self.platform == 'windows':
-      return [create_jobspec('prebuild_%s' % self.name,
-                             ['tools\\run_tests\\helper_scripts\\pre_build_c.bat'],
-                             shell=True,
-                             flake_retries=5,
-                             timeout_retries=2)]
-    else:
-      return []
+    return []
 
   def build_jobspec(self):
     if self.platform == 'windows':
-      msbuild_platform = 'Win32' if self.arch == 'x86' else self.arch
+      cmake_arch_option = 'Win32' if self.arch == 'x86' else self.arch
       return create_jobspec(self.name,
                             ['tools\\run_tests\\artifacts\\build_artifact_csharp.bat',
-                             'vsprojects\\grpc_csharp_ext.sln',
-                             '/p:Configuration=Release',
-                             '/p:PlatformToolset=v120',
-                             '/p:Platform=%s' % msbuild_platform],
+                             cmake_arch_option],
                             shell=True)
     else:
       environ = {'CONFIG': 'opt',
diff --git a/tools/run_tests/artifacts/build_artifact_csharp.bat b/tools/run_tests/artifacts/build_artifact_csharp.bat
index 24c8d485f9f07f6e59771352f989a1e42089136d..f84ebc5a3594632d29c2bff72076c081c754674b 100644
--- a/tools/run_tests/artifacts/build_artifact_csharp.bat
+++ b/tools/run_tests/artifacts/build_artifact_csharp.bat
@@ -29,10 +29,16 @@
 
 @rem Builds C# artifacts on Windows
 
-@call vsprojects\build_vs2013.bat %* || goto :error
+set ARCHITECTURE=%1
+
+@call tools\run_tests\helper_scripts\pre_build_csharp.bat %ARCHITECTURE% || goto :error
+
+cd cmake\build\%ARCHITECTURE%
+cmake --build . --target grpc_csharp_ext --config Release
+cd ..\..\..
 
 mkdir artifacts
-copy /Y vsprojects\Release\grpc_csharp_ext.dll artifacts || copy /Y vsprojects\x64\Release\grpc_csharp_ext.dll artifacts || goto :error
+copy /Y cmake\build\Win32\Release\grpc_csharp_ext.dll artifacts || copy /Y cmake\build\x64\Release\grpc_csharp_ext.dll artifacts || goto :error
 
 goto :EOF
 
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 046076bd105db45907f9650b25da76b971656ef5..0d5aeb233c4a3e5ad740edfbb159df4b6da38345 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -5380,7 +5380,8 @@
       "grpc", 
       "grpc++_base", 
       "grpc++_codegen_base", 
-      "grpc++_codegen_base_src"
+      "grpc++_codegen_base_src", 
+      "grpc++_codegen_proto"
     ], 
     "headers": [
       "include/grpc++/impl/codegen/core_codegen.h", 
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 9206d209b542e85b8fce6c0961039095f62fb9dd..80f7a30ee574c4586bbbb7d38cba25fe18f3622c 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -38487,7 +38487,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38514,7 +38514,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38541,7 +38541,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38566,7 +38566,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38591,7 +38591,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38616,7 +38616,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"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_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38641,7 +38641,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"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_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38666,7 +38666,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"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_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38691,7 +38691,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38716,7 +38716,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38741,7 +38741,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38766,7 +38766,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"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_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38791,7 +38791,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"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_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38816,7 +38816,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"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_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38916,7 +38916,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38943,7 +38943,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38970,7 +38970,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -38995,7 +38995,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39020,7 +39020,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39045,7 +39045,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39070,7 +39070,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39095,7 +39095,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39120,7 +39120,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39145,7 +39145,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39170,7 +39170,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39195,7 +39195,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39220,7 +39220,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39245,7 +39245,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39378,7 +39378,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39416,7 +39416,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": 10, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": 10, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39454,7 +39454,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39490,7 +39490,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39526,7 +39526,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39562,7 +39562,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"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_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39598,7 +39598,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"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_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39634,7 +39634,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"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_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39670,7 +39670,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39706,7 +39706,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39742,7 +39742,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"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\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"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\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39778,7 +39778,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"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_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39814,7 +39814,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"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_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39850,7 +39850,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"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_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -39994,7 +39994,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40032,7 +40032,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": 10, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"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\": 10, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40070,7 +40070,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40106,7 +40106,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40142,7 +40142,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40178,7 +40178,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40214,7 +40214,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40250,7 +40250,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40286,7 +40286,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 1, \"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\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40322,7 +40322,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40358,7 +40358,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"SYNC_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\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40394,7 +40394,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40430,7 +40430,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -40466,7 +40466,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"resource_quota_size\": 512000, \"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 0, \"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}}}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -79637,6 +79637,28 @@
     ], 
     "uses_polling": false
   }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5171071900712960"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "exclude_iomgrs": [
+      "uv"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
   {
     "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/crash-0597bbdd657fa4ed14443994c9147a1a7bbc205f"
diff --git a/tools/run_tests/helper_scripts/pre_build_csharp.bat b/tools/run_tests/helper_scripts/pre_build_csharp.bat
index 139955d4dae406eabca28e8c6881fdea00b0256a..f37f63b58404556e5ad2fe6df066ec081e79745f 100644
--- a/tools/run_tests/helper_scripts/pre_build_csharp.bat
+++ b/tools/run_tests/helper_scripts/pre_build_csharp.bat
@@ -31,9 +31,21 @@
 
 setlocal
 
+set ARCHITECTURE=%1
+
 @rem enter repo root
 cd /d %~dp0\..\..\..
 
+mkdir cmake
+cd cmake
+mkdir build
+cd build
+mkdir %ARCHITECTURE%
+cd %ARCHITECTURE%
+@rem TODO(jtattermusch): Stop hardcoding path to yasm once Jenkins workers can locate yasm correctly
+cmake -G "Visual Studio 14 2015" -A %ARCHITECTURE% -DgRPC_BUILD_TESTS=OFF -DCMAKE_ASM_NASM_COMPILER="C:/Program Files (x86)/yasm/yasm.exe" ../../.. || goto :error
+cd ..\..\..
+
 @rem Location of nuget.exe
 set NUGET=C:\nuget\nuget.exe
 
@@ -42,7 +54,6 @@ if exist %NUGET% (
   @rem Restore Grpc packages by packages since Nuget client 3.4.4 doesnt support restore
   @rem by solution
   @rem Moving into each directory to let the restores work based on per-project packages.config files
-  %NUGET% restore vsprojects/grpc_csharp_ext.sln || goto :error
 
   cd src/csharp
 
diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py
index 6d138186ced689b9d815f1af80a3d2d5b43b673f..865125fcd783478cc69cc48912a76040fbdf47a5 100644
--- a/tools/run_tests/performance/scenario_config.py
+++ b/tools/run_tests/performance/scenario_config.py
@@ -143,8 +143,9 @@ def _ping_pong_scenario(name, rpc_type,
   if use_generic_payload:
     if server_type != 'ASYNC_GENERIC_SERVER':
       raise Exception('Use ASYNC_GENERIC_SERVER for generic payload.')
+    scenario['server_config']['payload_config'] = _payload_type(use_generic_payload, req_size, resp_size)
+
   scenario['client_config']['payload_config'] = _payload_type(use_generic_payload, req_size, resp_size)
-  scenario['server_config']['payload_config'] = _payload_type(use_generic_payload, req_size, resp_size)
 
   if unconstrained_client:
     outstanding_calls = outstanding if outstanding is not None else OUTSTANDING_REQUESTS[unconstrained_client]
diff --git a/tools/run_tests/run_microbenchmark.py b/tools/run_tests/run_microbenchmark.py
index 096d7d78ab2b20ce20d111fc9883f172cee44ebf..ea87b6cd9861397d8fd3cf7a34ae4a0727cf50ac 100755
--- a/tools/run_tests/run_microbenchmark.py
+++ b/tools/run_tests/run_microbenchmark.py
@@ -32,6 +32,7 @@ import multiprocessing
 import os
 import subprocess
 import sys
+import argparse
 
 import python_utils.jobset as jobset
 import python_utils.start_port_server as start_port_server
@@ -72,12 +73,16 @@ def link(txt, tgt):
   global index_html
   index_html += "<p><a href=\"%s\">%s</a></p>\n" % (tgt, txt)
 
-benchmarks = []
-profile_analysis = []
-cleanup = []
+def text(txt):
+  global index_html
+  index_html += "<p><pre>%s</pre></p>\n" % txt
+
+def collect_latency(bm_name, args):
+  """generate latency profiles"""
+  benchmarks = []
+  profile_analysis = []
+  cleanup = []
 
-for bm_name in sys.argv[1:]:
-  # generate latency profiles
   heading('Latency Profiles: %s' % bm_name)
   subprocess.check_call(
       ['make', bm_name,
@@ -115,26 +120,68 @@ for bm_name in sys.argv[1:]:
     jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count())
     jobset.run(cleanup, maxjobs=multiprocessing.cpu_count())
 
-  # generate flamegraphs
+def collect_perf(bm_name, args):
+  """generate flamegraphs"""
   heading('Flamegraphs: %s' % bm_name)
   subprocess.check_call(
       ['make', bm_name,
        'CONFIG=mutrace', '-j', '%d' % multiprocessing.cpu_count()])
   for line in subprocess.check_output(['bins/mutrace/%s' % bm_name,
                                        '--benchmark_list_tests']).splitlines():
-    subprocess.check_call(['sudo', 'perf', 'record', '-g', '-c', '1000',
+    subprocess.check_call(['perf', 'record', '-o', '%s-perf.data' % fnize(line),
+                           '-g', '-c', '1000',
                            'bins/mutrace/%s' % bm_name,
                            '--benchmark_filter=^%s$' % line,
                            '--benchmark_min_time=20'])
-    with open('/tmp/bm.perf', 'w') as f:
-      f.write(subprocess.check_output(['sudo', 'perf', 'script']))
-    with open('/tmp/bm.folded', 'w') as f:
-      f.write(subprocess.check_output([
-          '%s/stackcollapse-perf.pl' % flamegraph_dir, '/tmp/bm.perf']))
-    link(line, '%s.svg' % fnize(line))
-    with open('reports/%s.svg' % fnize(line), 'w') as f:
-      f.write(subprocess.check_output([
-          '%s/flamegraph.pl' % flamegraph_dir, '/tmp/bm.folded']))
+    env = os.environ.copy()
+    env.update({
+      'PERF_BASE_NAME': fnize(line),
+      'OUTPUT_DIR': 'reports',
+      'OUTPUT_FILENAME': fnize(line),
+    })
+    subprocess.check_call(['tools/run_tests/performance/process_local_perf_flamegraphs.sh'],
+                          env=env)
+
+def collect_summary(bm_name, args):
+  heading('Summary: %s' % bm_name)
+  subprocess.check_call(
+      ['make', bm_name,
+       'CONFIG=counters', '-j', '%d' % multiprocessing.cpu_count()])
+  text(subprocess.check_output(['bins/counters/%s' % bm_name,
+                                '--benchmark_out=out.json',
+                                '--benchmark_out_format=json']))
+  if args.bigquery_upload:
+    with open('out.csv', 'w') as f:
+      f.write(subprocess.check_output(['tools/profiling/microbenchmarks/bm2bq.py', 'out.json']))
+    subprocess.check_call(['bq', 'load', 'microbenchmarks.microbenchmarks', 'out.csv'])
+
+collectors = {
+  'latency': collect_latency,
+  'perf': collect_perf,
+  'summary': collect_summary,
+}
+
+argp = argparse.ArgumentParser(description='Collect data from microbenchmarks')
+argp.add_argument('-c', '--collect',
+                  choices=sorted(collectors.keys()),
+                  nargs='+',
+                  default=sorted(collectors.keys()),
+                  help='Which collectors should be run against each benchmark')
+argp.add_argument('-b', '--benchmarks',
+                  default=['bm_fullstack'],
+                  nargs='+',
+                  type=str,
+                  help='Which microbenchmarks should be run')
+argp.add_argument('--bigquery_upload',
+                  default=False,
+                  action='store_const',
+                  const=True,
+                  help='Upload results from summary collection to bigquery')
+args = argp.parse_args()
+
+for bm_name in args.benchmarks:
+  for collect in args.collect:
+    collectors[collect](bm_name, args)
 
 index_html += "</body>\n</html>\n"
 with open('reports/index.html', 'w') as f:
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 75571aaadbea44d43e7846bb0b96141d8e96961d..8b76193cbe1bf676f0957775750420fd6a665b44 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -722,12 +722,10 @@ class CSharpLanguage(object):
     self.config = config
     self.args = args
     if self.platform == 'windows':
-      # Explicitly choosing between x86 and x64 arch doesn't work yet
+      _check_compiler(self.args.compiler, ['coreclr', 'default'])
       _check_arch(self.args.arch, ['default'])
-      # CoreCLR use 64bit runtime by default.
-      arch_option = 'x64' if self.args.compiler == 'coreclr' else self.args.arch
-      self._make_options = [_windows_toolset_option(self.args.compiler),
-                            _windows_arch_option(arch_option)]
+      self._cmake_arch_option = 'x64' if self.args.compiler == 'coreclr' else 'Win32'
+      self._make_options = []
     else:
       _check_compiler(self.args.compiler, ['default', 'coreclr'])
       if self.platform == 'linux' and self.args.compiler == 'coreclr':
@@ -799,7 +797,7 @@ class CSharpLanguage(object):
 
   def pre_build_steps(self):
     if self.platform == 'windows':
-      return [['tools\\run_tests\\helper_scripts\\pre_build_csharp.bat']]
+      return [['tools\\run_tests\\helper_scripts\\pre_build_csharp.bat', self._cmake_arch_option]]
     else:
       return [['tools/run_tests/helper_scripts/pre_build_csharp.sh']]
 
@@ -817,7 +815,7 @@ class CSharpLanguage(object):
         return [['tools/run_tests/helper_scripts/build_csharp_coreclr.sh']]
     else:
       if self.platform == 'windows':
-        return [[_windows_build_bat(self.args.compiler),
+        return [['vsprojects\\build_vs2015.bat',
                  'src/csharp/Grpc.sln',
                  '/p:Configuration=%s' % _MSBUILD_CONFIG[self.config.build_config]]]
       else:
@@ -830,7 +828,10 @@ class CSharpLanguage(object):
       return [['tools/run_tests/helper_scripts/post_tests_csharp.sh']]
 
   def makefile_name(self):
-    return 'Makefile'
+    if self.platform == 'windows':
+      return 'cmake/build/%s/Makefile' % self._cmake_arch_option
+    else:
+      return 'Makefile'
 
   def dockerfile_dir(self):
     return 'tools/dockerfile/test/csharp_%s_%s' % (self._docker_distro,
@@ -1038,12 +1039,10 @@ def _check_arch_option(arch):
 def _windows_build_bat(compiler):
   """Returns name of build.bat for selected compiler."""
   # For CoreCLR, fall back to the default compiler for C core
-  if compiler == 'default' or compiler == 'vs2013' or compiler == 'coreclr':
+  if compiler == 'default' or compiler == 'vs2013':
     return 'vsprojects\\build_vs2013.bat'
   elif compiler == 'vs2015':
     return 'vsprojects\\build_vs2015.bat'
-  elif compiler == 'vs2010':
-    return 'vsprojects\\build_vs2010.bat'
   else:
     print('Compiler %s not supported.' % compiler)
     sys.exit(1)
@@ -1056,8 +1055,6 @@ def _windows_toolset_option(compiler):
     return '/p:PlatformToolset=v120'
   elif compiler == 'vs2015':
     return '/p:PlatformToolset=v140'
-  elif compiler == 'vs2010':
-    return '/p:PlatformToolset=v100'
   else:
     print('Compiler %s not supported.' % compiler)
     sys.exit(1)
@@ -1147,7 +1144,7 @@ argp.add_argument('--compiler',
                   choices=['default',
                            'gcc4.4', 'gcc4.6', 'gcc4.8', 'gcc4.9', 'gcc5.3',
                            'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7',
-                           'vs2010', 'vs2013', 'vs2015',
+                           'vs2013', 'vs2015',
                            'python2.7', 'python3.4', 'python3.5', 'python3.6', 'pypy', 'pypy3',
                            'node0.12', 'node4', 'node5', 'node6', 'node7',
                            'electron1.3',
@@ -1292,7 +1289,7 @@ def make_jobspec(cfg, targets, makefile='Makefile'):
       return [jobset.JobSpec(['cmake', '--build', '.',
                               '--target', '%s' % target,
                               '--config', _MSBUILD_CONFIG[cfg]],
-                             cwd='cmake/build',
+                             cwd=os.path.dirname(makefile),
                              timeout_seconds=None) for target in targets]
     extra_args = []
     # better do parallel compilation
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index ce41da802d056bfcd3a5cd120b3037b50ae721c2..445f53e55588ae431bf37885d823d82fc3cc3e3a 100644
--- a/tools/run_tests/sanity/sanity_tests.yaml
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -12,6 +12,7 @@
 - script: tools/distrib/check_trailing_newlines.sh
 - script: tools/distrib/check_nanopb_output.sh
 - script: tools/distrib/check_include_guards.py
+- script: tools/distrib/pylint_code.sh
 - script: tools/distrib/yapf_code.sh
 - script: tools/distrib/python/check_grpcio_tools.py
 
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index fcd1d9def9a21a9a00c3d8a3bf53cb2e0509f153..58597744d8b2db87898ff953cd5cb849aabf7c23 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -349,6 +349,8 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index dbf3ad90c622535d34fa1cbd7ed44ce84ea5f7a4..4b501a1e74ea5ddd9afea2970b34fd176370d755 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -387,6 +387,12 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h">