aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--BUILD355
-rw-r--r--CMakeLists.txt194
-rw-r--r--Makefile196
-rw-r--r--binding.gyp4
-rw-r--r--build.yaml27
-rw-r--r--config.m46
-rw-r--r--doc/connection-backoff.md7
-rw-r--r--gRPC-Core.podspec12
-rwxr-xr-xgrpc.gemspec8
-rw-r--r--package.xml8
-rw-r--r--src/compiler/python_generator.cc55
-rw-r--r--src/core/ext/client_channel/http_connect_handshaker.c182
-rw-r--r--src/core/ext/client_channel/subchannel.c156
-rw-r--r--src/core/ext/lb_policy/grpclb/grpclb.c18
-rw-r--r--src/core/ext/resolver/dns/native/dns_resolver.c16
-rw-r--r--src/core/ext/transport/chttp2/client/chttp2_connector.c261
-rw-r--r--src/core/ext/transport/chttp2/client/chttp2_connector.h52
-rw-r--r--src/core/ext/transport/chttp2/client/insecure/channel_create.c153
-rw-r--r--src/core/ext/transport/chttp2/client/secure/secure_channel_create.c221
-rw-r--r--src/core/ext/transport/chttp2/server/chttp2_server.c356
-rw-r--r--src/core/ext/transport/chttp2/server/chttp2_server.h79
-rw-r--r--src/core/ext/transport/chttp2/server/insecure/server_chttp2.c172
-rw-r--r--src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c338
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.c53
-rw-r--r--src/core/ext/transport/chttp2/transport/internal.h10
-rw-r--r--src/core/ext/transport/chttp2/transport/writing.c2
-rw-r--r--src/core/lib/channel/handshaker.c211
-rw-r--r--src/core/lib/channel/handshaker.h83
-rw-r--r--src/core/lib/channel/http_client_filter.c9
-rw-r--r--src/core/lib/http/httpcli_security_connector.c90
-rw-r--r--src/core/lib/iomgr/combiner.c11
-rw-r--r--src/core/lib/iomgr/ev_epoll_linux.c31
-rw-r--r--src/core/lib/iomgr/ev_poll_posix.c14
-rw-r--r--src/core/lib/iomgr/ev_posix.h1
-rw-r--r--src/core/lib/iomgr/iomgr.c1
-rw-r--r--src/core/lib/iomgr/resource_quota.c42
-rw-r--r--src/core/lib/iomgr/socket_windows.c8
-rw-r--r--src/core/lib/iomgr/socket_windows.h1
-rw-r--r--src/core/lib/iomgr/tcp_client_windows.c26
-rw-r--r--src/core/lib/iomgr/tcp_server_windows.c86
-rw-r--r--src/core/lib/iomgr/udp_server.c6
-rw-r--r--src/core/lib/security/transport/handshake.c374
-rw-r--r--src/core/lib/security/transport/security_connector.c242
-rw-r--r--src/core/lib/security/transport/security_connector.h58
-rw-r--r--src/core/lib/security/transport/security_handshaker.c450
-rw-r--r--src/core/lib/security/transport/security_handshaker.h (renamed from src/core/lib/security/transport/handshake.h)21
-rw-r--r--src/core/lib/support/backoff.c37
-rw-r--r--src/core/lib/support/backoff.h7
-rw-r--r--src/core/lib/support/subprocess_posix.c7
-rw-r--r--src/core/lib/transport/connectivity_state.c13
-rw-r--r--src/core/lib/transport/connectivity_state.h5
-rw-r--r--src/csharp/Grpc.Auth/Grpc.Auth.csproj1
-rw-r--r--src/csharp/Grpc.Auth/Grpc.Auth.nuspec28
-rw-r--r--src/csharp/Grpc.Core.Tests/CallOptionsTest.cs15
-rw-r--r--src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs10
-rw-r--r--src/csharp/Grpc.Core.Tests/SanityTest.cs3
-rw-r--r--src/csharp/Grpc.Core/CallOptions.cs46
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.csproj4
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.nuspec35
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCall.cs10
-rw-r--r--src/csharp/Grpc.Core/Internal/CallFlags.cs60
-rw-r--r--src/csharp/Grpc.Core/Internal/CallSafeHandle.cs20
-rw-r--r--src/csharp/Grpc.Core/Internal/INativeCall.cs17
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeMethods.cs10
-rw-r--r--src/csharp/Grpc.Dotnet.sln14
-rw-r--r--src/csharp/Grpc.Examples/Math.cs24
-rw-r--r--src/csharp/Grpc.Examples/MathGrpc.cs2
-rw-r--r--src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj5
-rw-r--r--src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec28
-rw-r--r--src/csharp/Grpc.HealthCheck/Health.cs22
-rw-r--r--src/csharp/Grpc.HealthCheck/HealthGrpc.cs2
-rw-r--r--src/csharp/Grpc.Reflection.Tests/.gitignore2
-rw-r--r--src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj94
-rw-r--r--src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.project.json8
-rw-r--r--src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.xproj18
-rw-r--r--src/csharp/Grpc.Reflection.Tests/NUnitMain.cs59
-rw-r--r--src/csharp/Grpc.Reflection.Tests/Properties/AssemblyInfo.cs44
-rw-r--r--src/csharp/Grpc.Reflection.Tests/ReflectionClientServerTest.cs154
-rw-r--r--src/csharp/Grpc.Reflection.Tests/SymbolRegistryTest.cs63
-rw-r--r--src/csharp/Grpc.Reflection.Tests/packages.config7
-rw-r--r--src/csharp/Grpc.Reflection.Tests/project.json65
-rw-r--r--src/csharp/Grpc.Reflection/.gitignore2
-rw-r--r--src/csharp/Grpc.Reflection/Grpc.Reflection.csproj83
-rw-r--r--src/csharp/Grpc.Reflection/Grpc.Reflection.project.json8
-rw-r--r--src/csharp/Grpc.Reflection/Grpc.Reflection.xproj18
-rw-r--r--src/csharp/Grpc.Reflection/Properties/AssemblyInfo.cs44
-rw-r--r--src/csharp/Grpc.Reflection/Reflection.cs1556
-rw-r--r--src/csharp/Grpc.Reflection/ReflectionGrpc.cs132
-rw-r--r--src/csharp/Grpc.Reflection/ReflectionServiceImpl.cs173
-rw-r--r--src/csharp/Grpc.Reflection/Settings.StyleCop10
-rw-r--r--src/csharp/Grpc.Reflection/SymbolRegistry.cs160
-rw-r--r--src/csharp/Grpc.Reflection/packages.config5
-rw-r--r--src/csharp/Grpc.Reflection/project.json40
-rw-r--r--src/csharp/Grpc.sln16
-rw-r--r--src/csharp/build_packages.bat91
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.bat7
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.sh1
-rw-r--r--src/csharp/ext/grpc_csharp_ext.c21
-rwxr-xr-xsrc/csharp/generate_proto_csharp.sh11
-rw-r--r--src/csharp/tests.json4
-rw-r--r--src/objective-c/tests/Podfile4
-rw-r--r--src/php/tests/unit_tests/ChannelTest.php2
-rw-r--r--src/php/tests/unit_tests/ServerTest.php4
-rw-r--r--src/python/grpcio/grpc/__init__.py30
-rw-r--r--src/python/grpcio/grpc/_server.py88
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py4
-rw-r--r--src/python/grpcio_tests/tests/protoc_plugin/_split_definitions_test.py6
-rw-r--r--src/python/grpcio_tests/tests/tests.json1
-rw-r--r--src/python/grpcio_tests/tests/unit/_exit_test.py23
-rw-r--r--templates/src/csharp/Grpc.Reflection.Tests/project.json.template26
-rw-r--r--templates/src/csharp/Grpc.Reflection/project.json.template42
-rwxr-xr-x[-rw-r--r--]templates/src/csharp/build_packages_dotnetcli.bat.template (renamed from templates/src/csharp/build_packages.bat.template)41
-rwxr-xr-xtemplates/src/csharp/build_packages_dotnetcli.sh.template1
-rw-r--r--templates/tools/dockerfile/test/sanity/Dockerfile.template9
-rw-r--r--test/core/client_channel/lb_policies_test.c119
-rw-r--r--test/core/end2end/fixtures/h2_sockpair_1byte.c2
-rw-r--r--test/core/end2end/goaway_server_test.c10
-rw-r--r--test/core/end2end/tests/connectivity.c10
-rw-r--r--test/core/end2end/tests/filter_latency.c30
-rw-r--r--test/core/end2end/tests/payload.c2
-rw-r--r--test/core/end2end/tests/resource_quota_server.c2
-rw-r--r--test/core/end2end/tests/simple_delayed_request.c19
-rw-r--r--test/core/handshake/client_ssl.c2
-rw-r--r--test/core/security/ssl_server_fuzzer.c24
-rw-r--r--test/core/support/backoff_test.c91
-rw-r--r--test/core/surface/server_chttp2_test.c5
-rw-r--r--test/core/util/port_posix.c14
-rw-r--r--test/core/util/test_config.c19
-rw-r--r--test/core/util/test_config.h3
-rw-r--r--test/cpp/grpclb/grpclb_test.cc59
-rw-r--r--test/cpp/microbenchmarks/bm_fullstack.cc15
-rwxr-xr-xtest/cpp/qps/gen_build_yaml.py61
-rw-r--r--test/cpp/qps/json_run_localhost.cc73
-rw-r--r--tools/README.md2
-rwxr-xr-xtools/dockerfile/push_testing_images.sh64
-rw-r--r--tools/dockerfile/test/sanity/Dockerfile8
-rw-r--r--tools/doxygen/Doxyfile.core.internal8
-rw-r--r--tools/internal_ci/README.md6
-rw-r--r--tools/internal_ci/linux/grpc_master.cfg34
-rwxr-xr-xtools/internal_ci/linux/run_tests.sh45
-rw-r--r--tools/jenkins/README.md5
-rwxr-xr-xtools/run_tests/dockerize/build_and_run_docker.sh11
-rwxr-xr-xtools/run_tests/jobset.py12
-rw-r--r--tools/run_tests/package_targets.py41
-rwxr-xr-xtools/run_tests/run_interop_tests.py13
-rwxr-xr-xtools/run_tests/run_tests.py13
-rw-r--r--tools/run_tests/sources_and_headers.json59
-rw-r--r--tools/run_tests/tests.json1544
-rw-r--r--vsprojects/vcxproj/grpc/grpc.vcxproj12
-rw-r--r--vsprojects/vcxproj/grpc/grpc.vcxproj.filters24
-rw-r--r--vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj6
-rw-r--r--vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters12
153 files changed, 8242 insertions, 2547 deletions
diff --git a/.gitignore b/.gitignore
index ed015b3c92..3cc35ff7cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,7 +17,7 @@ py27/
py34/
# Node installation output
-^node_modules
+node_modules
src/node/extension_binary/
# gcov coverage data
diff --git a/BUILD b/BUILD
index f80e5f0664..ab0fc237b7 100644
--- a/BUILD
+++ b/BUILD
@@ -287,9 +287,9 @@ cc_library(
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/transport/auth_filters.h",
- "src/core/lib/security/transport/handshake.h",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/security_connector.h",
+ "src/core/lib/security/transport/security_handshaker.h",
"src/core/lib/security/transport/tsi_error.h",
"src/core/lib/security/util/b64.h",
"src/core/lib/security/util/json_util.h",
@@ -298,6 +298,7 @@ cc_library(
"src/core/lib/tsi/ssl_types.h",
"src/core/lib/tsi/transport_security.h",
"src/core/lib/tsi/transport_security_interface.h",
+ "src/core/ext/transport/chttp2/server/chttp2_server.h",
"src/core/ext/client_channel/client_channel.h",
"src/core/ext/client_channel/client_channel_factory.h",
"src/core/ext/client_channel/connector.h",
@@ -313,6 +314,7 @@ cc_library(
"src/core/ext/client_channel/subchannel.h",
"src/core/ext/client_channel/subchannel_index.h",
"src/core/ext/client_channel/uri_parser.h",
+ "src/core/ext/transport/chttp2/client/chttp2_connector.h",
"src/core/ext/lb_policy/grpclb/grpclb.h",
"src/core/ext/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
@@ -481,9 +483,9 @@ cc_library(
"src/core/lib/security/credentials/plugin/plugin_credentials.c",
"src/core/lib/security/credentials/ssl/ssl_credentials.c",
"src/core/lib/security/transport/client_auth_filter.c",
- "src/core/lib/security/transport/handshake.c",
"src/core/lib/security/transport/secure_endpoint.c",
"src/core/lib/security/transport/security_connector.c",
+ "src/core/lib/security/transport/security_handshaker.c",
"src/core/lib/security/transport/server_auth_filter.c",
"src/core/lib/security/transport/tsi_error.c",
"src/core/lib/security/util/b64.c",
@@ -492,6 +494,7 @@ cc_library(
"src/core/lib/tsi/fake_transport_security.c",
"src/core/lib/tsi/ssl_transport_security.c",
"src/core/lib/tsi/transport_security.c",
+ "src/core/ext/transport/chttp2/server/chttp2_server.c",
"src/core/ext/transport/chttp2/client/secure/secure_channel_create.c",
"src/core/ext/client_channel/channel_connectivity.c",
"src/core/ext/client_channel/client_channel.c",
@@ -511,6 +514,7 @@ cc_library(
"src/core/ext/client_channel/subchannel.c",
"src/core/ext/client_channel/subchannel_index.c",
"src/core/ext/client_channel/uri_parser.c",
+ "src/core/ext/transport/chttp2/client/chttp2_connector.c",
"src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
"src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c",
"src/core/ext/transport/chttp2/client/insecure/channel_create.c",
@@ -737,9 +741,9 @@ cc_library(
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/transport/auth_filters.h",
- "src/core/lib/security/transport/handshake.h",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/security_connector.h",
+ "src/core/lib/security/transport/security_handshaker.h",
"src/core/lib/security/transport/tsi_error.h",
"src/core/lib/security/util/b64.h",
"src/core/lib/security/util/json_util.h",
@@ -748,6 +752,7 @@ cc_library(
"src/core/lib/tsi/ssl_types.h",
"src/core/lib/tsi/transport_security.h",
"src/core/lib/tsi/transport_security_interface.h",
+ "src/core/ext/transport/chttp2/client/chttp2_connector.h",
"src/core/lib/surface/init.c",
"src/core/lib/channel/channel_args.c",
"src/core/lib/channel/channel_stack.c",
@@ -921,9 +926,9 @@ cc_library(
"src/core/lib/security/credentials/plugin/plugin_credentials.c",
"src/core/lib/security/credentials/ssl/ssl_credentials.c",
"src/core/lib/security/transport/client_auth_filter.c",
- "src/core/lib/security/transport/handshake.c",
"src/core/lib/security/transport/secure_endpoint.c",
"src/core/lib/security/transport/security_connector.c",
+ "src/core/lib/security/transport/security_handshaker.c",
"src/core/lib/security/transport/server_auth_filter.c",
"src/core/lib/security/transport/tsi_error.c",
"src/core/lib/security/util/b64.c",
@@ -932,6 +937,7 @@ cc_library(
"src/core/lib/tsi/fake_transport_security.c",
"src/core/lib/tsi/ssl_transport_security.c",
"src/core/lib/tsi/transport_security.c",
+ "src/core/ext/transport/chttp2/client/chttp2_connector.c",
"src/core/plugin_registry/grpc_cronet_plugin_registry.c",
],
hdrs = [
@@ -1097,6 +1103,8 @@ cc_library(
"src/core/ext/transport/chttp2/transport/stream_map.h",
"src/core/ext/transport/chttp2/transport/varint.h",
"src/core/ext/transport/chttp2/alpn/alpn.h",
+ "src/core/ext/transport/chttp2/server/chttp2_server.h",
+ "src/core/ext/transport/chttp2/client/chttp2_connector.h",
"src/core/ext/client_channel/client_channel.h",
"src/core/ext/client_channel/client_channel_factory.h",
"src/core/ext/client_channel/connector.h",
@@ -1266,8 +1274,10 @@ cc_library(
"src/core/ext/transport/chttp2/transport/varint.c",
"src/core/ext/transport/chttp2/transport/writing.c",
"src/core/ext/transport/chttp2/alpn/alpn.c",
+ "src/core/ext/transport/chttp2/server/chttp2_server.c",
"src/core/ext/transport/chttp2/client/insecure/channel_create.c",
"src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c",
+ "src/core/ext/transport/chttp2/client/chttp2_connector.c",
"src/core/ext/client_channel/channel_connectivity.c",
"src/core/ext/client_channel/client_channel.c",
"src/core/ext/client_channel/client_channel_factory.c",
@@ -1515,6 +1525,152 @@ cc_library(
"src/cpp/server/dynamic_thread_pool.h",
"src/cpp/server/thread_pool_interface.h",
"src/cpp/thread_manager/thread_manager.h",
+ "src/core/ext/transport/chttp2/client/chttp2_connector.h",
+ "src/core/ext/transport/chttp2/transport/bin_decoder.h",
+ "src/core/ext/transport/chttp2/transport/bin_encoder.h",
+ "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
+ "src/core/ext/transport/chttp2/transport/frame.h",
+ "src/core/ext/transport/chttp2/transport/frame_data.h",
+ "src/core/ext/transport/chttp2/transport/frame_goaway.h",
+ "src/core/ext/transport/chttp2/transport/frame_ping.h",
+ "src/core/ext/transport/chttp2/transport/frame_rst_stream.h",
+ "src/core/ext/transport/chttp2/transport/frame_settings.h",
+ "src/core/ext/transport/chttp2/transport/frame_window_update.h",
+ "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
+ "src/core/ext/transport/chttp2/transport/hpack_parser.h",
+ "src/core/ext/transport/chttp2/transport/hpack_table.h",
+ "src/core/ext/transport/chttp2/transport/http2_errors.h",
+ "src/core/ext/transport/chttp2/transport/huffsyms.h",
+ "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
+ "src/core/ext/transport/chttp2/transport/internal.h",
+ "src/core/ext/transport/chttp2/transport/status_conversion.h",
+ "src/core/ext/transport/chttp2/transport/stream_map.h",
+ "src/core/ext/transport/chttp2/transport/varint.h",
+ "src/core/lib/channel/channel_args.h",
+ "src/core/lib/channel/channel_stack.h",
+ "src/core/lib/channel/channel_stack_builder.h",
+ "src/core/lib/channel/compress_filter.h",
+ "src/core/lib/channel/connected_channel.h",
+ "src/core/lib/channel/context.h",
+ "src/core/lib/channel/deadline_filter.h",
+ "src/core/lib/channel/handshaker.h",
+ "src/core/lib/channel/http_client_filter.h",
+ "src/core/lib/channel/http_server_filter.h",
+ "src/core/lib/channel/message_size_filter.h",
+ "src/core/lib/compression/algorithm_metadata.h",
+ "src/core/lib/compression/message_compress.h",
+ "src/core/lib/debug/trace.h",
+ "src/core/lib/http/format_request.h",
+ "src/core/lib/http/httpcli.h",
+ "src/core/lib/http/parser.h",
+ "src/core/lib/iomgr/closure.h",
+ "src/core/lib/iomgr/combiner.h",
+ "src/core/lib/iomgr/endpoint.h",
+ "src/core/lib/iomgr/endpoint_pair.h",
+ "src/core/lib/iomgr/error.h",
+ "src/core/lib/iomgr/ev_epoll_linux.h",
+ "src/core/lib/iomgr/ev_poll_posix.h",
+ "src/core/lib/iomgr/ev_posix.h",
+ "src/core/lib/iomgr/exec_ctx.h",
+ "src/core/lib/iomgr/executor.h",
+ "src/core/lib/iomgr/iocp_windows.h",
+ "src/core/lib/iomgr/iomgr.h",
+ "src/core/lib/iomgr/iomgr_internal.h",
+ "src/core/lib/iomgr/iomgr_posix.h",
+ "src/core/lib/iomgr/load_file.h",
+ "src/core/lib/iomgr/network_status_tracker.h",
+ "src/core/lib/iomgr/polling_entity.h",
+ "src/core/lib/iomgr/pollset.h",
+ "src/core/lib/iomgr/pollset_set.h",
+ "src/core/lib/iomgr/pollset_set_windows.h",
+ "src/core/lib/iomgr/pollset_uv.h",
+ "src/core/lib/iomgr/pollset_windows.h",
+ "src/core/lib/iomgr/port.h",
+ "src/core/lib/iomgr/resolve_address.h",
+ "src/core/lib/iomgr/resource_quota.h",
+ "src/core/lib/iomgr/sockaddr.h",
+ "src/core/lib/iomgr/sockaddr_posix.h",
+ "src/core/lib/iomgr/sockaddr_utils.h",
+ "src/core/lib/iomgr/sockaddr_windows.h",
+ "src/core/lib/iomgr/socket_mutator.h",
+ "src/core/lib/iomgr/socket_utils.h",
+ "src/core/lib/iomgr/socket_utils_posix.h",
+ "src/core/lib/iomgr/socket_windows.h",
+ "src/core/lib/iomgr/tcp_client.h",
+ "src/core/lib/iomgr/tcp_client_posix.h",
+ "src/core/lib/iomgr/tcp_posix.h",
+ "src/core/lib/iomgr/tcp_server.h",
+ "src/core/lib/iomgr/tcp_uv.h",
+ "src/core/lib/iomgr/tcp_windows.h",
+ "src/core/lib/iomgr/time_averaged_stats.h",
+ "src/core/lib/iomgr/timer.h",
+ "src/core/lib/iomgr/timer_generic.h",
+ "src/core/lib/iomgr/timer_heap.h",
+ "src/core/lib/iomgr/timer_uv.h",
+ "src/core/lib/iomgr/udp_server.h",
+ "src/core/lib/iomgr/unix_sockets_posix.h",
+ "src/core/lib/iomgr/wakeup_fd_cv.h",
+ "src/core/lib/iomgr/wakeup_fd_pipe.h",
+ "src/core/lib/iomgr/wakeup_fd_posix.h",
+ "src/core/lib/iomgr/workqueue.h",
+ "src/core/lib/iomgr/workqueue_uv.h",
+ "src/core/lib/iomgr/workqueue_windows.h",
+ "src/core/lib/json/json.h",
+ "src/core/lib/json/json_common.h",
+ "src/core/lib/json/json_reader.h",
+ "src/core/lib/json/json_writer.h",
+ "src/core/lib/slice/percent_encoding.h",
+ "src/core/lib/slice/slice_string_helpers.h",
+ "src/core/lib/surface/api_trace.h",
+ "src/core/lib/surface/call.h",
+ "src/core/lib/surface/call_test_only.h",
+ "src/core/lib/surface/channel.h",
+ "src/core/lib/surface/channel_init.h",
+ "src/core/lib/surface/channel_stack_type.h",
+ "src/core/lib/surface/completion_queue.h",
+ "src/core/lib/surface/event_string.h",
+ "src/core/lib/surface/init.h",
+ "src/core/lib/surface/lame_client.h",
+ "src/core/lib/surface/server.h",
+ "src/core/lib/transport/byte_stream.h",
+ "src/core/lib/transport/connectivity_state.h",
+ "src/core/lib/transport/mdstr_hash_table.h",
+ "src/core/lib/transport/metadata.h",
+ "src/core/lib/transport/metadata_batch.h",
+ "src/core/lib/transport/pid_controller.h",
+ "src/core/lib/transport/service_config.h",
+ "src/core/lib/transport/static_metadata.h",
+ "src/core/lib/transport/timeout_encoding.h",
+ "src/core/lib/transport/transport.h",
+ "src/core/lib/transport/transport_impl.h",
+ "src/core/ext/transport/chttp2/alpn/alpn.h",
+ "src/core/ext/client_channel/client_channel.h",
+ "src/core/ext/client_channel/client_channel_factory.h",
+ "src/core/ext/client_channel/connector.h",
+ "src/core/ext/client_channel/http_connect_handshaker.h",
+ "src/core/ext/client_channel/initial_connect_string.h",
+ "src/core/ext/client_channel/lb_policy.h",
+ "src/core/ext/client_channel/lb_policy_factory.h",
+ "src/core/ext/client_channel/lb_policy_registry.h",
+ "src/core/ext/client_channel/parse_address.h",
+ "src/core/ext/client_channel/resolver.h",
+ "src/core/ext/client_channel/resolver_factory.h",
+ "src/core/ext/client_channel/resolver_registry.h",
+ "src/core/ext/client_channel/subchannel.h",
+ "src/core/ext/client_channel/subchannel_index.h",
+ "src/core/ext/client_channel/uri_parser.h",
+ "src/core/ext/transport/chttp2/server/chttp2_server.h",
+ "src/core/ext/census/aggregation.h",
+ "src/core/ext/census/base_resources.h",
+ "src/core/ext/census/census_interface.h",
+ "src/core/ext/census/census_rpc_stats.h",
+ "src/core/ext/census/gen/census.pb.h",
+ "src/core/ext/census/gen/trace_context.pb.h",
+ "src/core/ext/census/grpc_filter.h",
+ "src/core/ext/census/mlog.h",
+ "src/core/ext/census/resource.h",
+ "src/core/ext/census/rpc_metric_id.h",
+ "src/core/ext/census/trace_context.h",
"src/cpp/client/cronet_credentials.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/common/insecure_create_auth_context.cc",
@@ -1548,6 +1704,178 @@ cc_library(
"src/cpp/util/string_ref.cc",
"src/cpp/util/time_cc.cc",
"src/cpp/codegen/codegen_init.cc",
+ "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
+ "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c",
+ "src/core/ext/transport/chttp2/client/chttp2_connector.c",
+ "src/core/ext/transport/chttp2/transport/bin_decoder.c",
+ "src/core/ext/transport/chttp2/transport/bin_encoder.c",
+ "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
+ "src/core/ext/transport/chttp2/transport/chttp2_transport.c",
+ "src/core/ext/transport/chttp2/transport/frame_data.c",
+ "src/core/ext/transport/chttp2/transport/frame_goaway.c",
+ "src/core/ext/transport/chttp2/transport/frame_ping.c",
+ "src/core/ext/transport/chttp2/transport/frame_rst_stream.c",
+ "src/core/ext/transport/chttp2/transport/frame_settings.c",
+ "src/core/ext/transport/chttp2/transport/frame_window_update.c",
+ "src/core/ext/transport/chttp2/transport/hpack_encoder.c",
+ "src/core/ext/transport/chttp2/transport/hpack_parser.c",
+ "src/core/ext/transport/chttp2/transport/hpack_table.c",
+ "src/core/ext/transport/chttp2/transport/huffsyms.c",
+ "src/core/ext/transport/chttp2/transport/incoming_metadata.c",
+ "src/core/ext/transport/chttp2/transport/parsing.c",
+ "src/core/ext/transport/chttp2/transport/status_conversion.c",
+ "src/core/ext/transport/chttp2/transport/stream_lists.c",
+ "src/core/ext/transport/chttp2/transport/stream_map.c",
+ "src/core/ext/transport/chttp2/transport/varint.c",
+ "src/core/ext/transport/chttp2/transport/writing.c",
+ "src/core/lib/channel/channel_args.c",
+ "src/core/lib/channel/channel_stack.c",
+ "src/core/lib/channel/channel_stack_builder.c",
+ "src/core/lib/channel/compress_filter.c",
+ "src/core/lib/channel/connected_channel.c",
+ "src/core/lib/channel/deadline_filter.c",
+ "src/core/lib/channel/handshaker.c",
+ "src/core/lib/channel/http_client_filter.c",
+ "src/core/lib/channel/http_server_filter.c",
+ "src/core/lib/channel/message_size_filter.c",
+ "src/core/lib/compression/compression.c",
+ "src/core/lib/compression/message_compress.c",
+ "src/core/lib/debug/trace.c",
+ "src/core/lib/http/format_request.c",
+ "src/core/lib/http/httpcli.c",
+ "src/core/lib/http/parser.c",
+ "src/core/lib/iomgr/closure.c",
+ "src/core/lib/iomgr/combiner.c",
+ "src/core/lib/iomgr/endpoint.c",
+ "src/core/lib/iomgr/endpoint_pair_posix.c",
+ "src/core/lib/iomgr/endpoint_pair_uv.c",
+ "src/core/lib/iomgr/endpoint_pair_windows.c",
+ "src/core/lib/iomgr/error.c",
+ "src/core/lib/iomgr/ev_epoll_linux.c",
+ "src/core/lib/iomgr/ev_poll_posix.c",
+ "src/core/lib/iomgr/ev_posix.c",
+ "src/core/lib/iomgr/exec_ctx.c",
+ "src/core/lib/iomgr/executor.c",
+ "src/core/lib/iomgr/iocp_windows.c",
+ "src/core/lib/iomgr/iomgr.c",
+ "src/core/lib/iomgr/iomgr_posix.c",
+ "src/core/lib/iomgr/iomgr_uv.c",
+ "src/core/lib/iomgr/iomgr_windows.c",
+ "src/core/lib/iomgr/load_file.c",
+ "src/core/lib/iomgr/network_status_tracker.c",
+ "src/core/lib/iomgr/polling_entity.c",
+ "src/core/lib/iomgr/pollset_set_uv.c",
+ "src/core/lib/iomgr/pollset_set_windows.c",
+ "src/core/lib/iomgr/pollset_uv.c",
+ "src/core/lib/iomgr/pollset_windows.c",
+ "src/core/lib/iomgr/resolve_address_posix.c",
+ "src/core/lib/iomgr/resolve_address_uv.c",
+ "src/core/lib/iomgr/resolve_address_windows.c",
+ "src/core/lib/iomgr/resource_quota.c",
+ "src/core/lib/iomgr/sockaddr_utils.c",
+ "src/core/lib/iomgr/socket_mutator.c",
+ "src/core/lib/iomgr/socket_utils_common_posix.c",
+ "src/core/lib/iomgr/socket_utils_linux.c",
+ "src/core/lib/iomgr/socket_utils_posix.c",
+ "src/core/lib/iomgr/socket_utils_uv.c",
+ "src/core/lib/iomgr/socket_utils_windows.c",
+ "src/core/lib/iomgr/socket_windows.c",
+ "src/core/lib/iomgr/tcp_client_posix.c",
+ "src/core/lib/iomgr/tcp_client_uv.c",
+ "src/core/lib/iomgr/tcp_client_windows.c",
+ "src/core/lib/iomgr/tcp_posix.c",
+ "src/core/lib/iomgr/tcp_server_posix.c",
+ "src/core/lib/iomgr/tcp_server_uv.c",
+ "src/core/lib/iomgr/tcp_server_windows.c",
+ "src/core/lib/iomgr/tcp_uv.c",
+ "src/core/lib/iomgr/tcp_windows.c",
+ "src/core/lib/iomgr/time_averaged_stats.c",
+ "src/core/lib/iomgr/timer_generic.c",
+ "src/core/lib/iomgr/timer_heap.c",
+ "src/core/lib/iomgr/timer_uv.c",
+ "src/core/lib/iomgr/udp_server.c",
+ "src/core/lib/iomgr/unix_sockets_posix.c",
+ "src/core/lib/iomgr/unix_sockets_posix_noop.c",
+ "src/core/lib/iomgr/wakeup_fd_cv.c",
+ "src/core/lib/iomgr/wakeup_fd_eventfd.c",
+ "src/core/lib/iomgr/wakeup_fd_nospecial.c",
+ "src/core/lib/iomgr/wakeup_fd_pipe.c",
+ "src/core/lib/iomgr/wakeup_fd_posix.c",
+ "src/core/lib/iomgr/workqueue_uv.c",
+ "src/core/lib/iomgr/workqueue_windows.c",
+ "src/core/lib/json/json.c",
+ "src/core/lib/json/json_reader.c",
+ "src/core/lib/json/json_string.c",
+ "src/core/lib/json/json_writer.c",
+ "src/core/lib/slice/percent_encoding.c",
+ "src/core/lib/slice/slice.c",
+ "src/core/lib/slice/slice_buffer.c",
+ "src/core/lib/slice/slice_string_helpers.c",
+ "src/core/lib/surface/alarm.c",
+ "src/core/lib/surface/api_trace.c",
+ "src/core/lib/surface/byte_buffer.c",
+ "src/core/lib/surface/byte_buffer_reader.c",
+ "src/core/lib/surface/call.c",
+ "src/core/lib/surface/call_details.c",
+ "src/core/lib/surface/call_log_batch.c",
+ "src/core/lib/surface/channel.c",
+ "src/core/lib/surface/channel_init.c",
+ "src/core/lib/surface/channel_ping.c",
+ "src/core/lib/surface/channel_stack_type.c",
+ "src/core/lib/surface/completion_queue.c",
+ "src/core/lib/surface/event_string.c",
+ "src/core/lib/surface/lame_client.c",
+ "src/core/lib/surface/metadata_array.c",
+ "src/core/lib/surface/server.c",
+ "src/core/lib/surface/validate_metadata.c",
+ "src/core/lib/surface/version.c",
+ "src/core/lib/transport/byte_stream.c",
+ "src/core/lib/transport/connectivity_state.c",
+ "src/core/lib/transport/mdstr_hash_table.c",
+ "src/core/lib/transport/metadata.c",
+ "src/core/lib/transport/metadata_batch.c",
+ "src/core/lib/transport/pid_controller.c",
+ "src/core/lib/transport/service_config.c",
+ "src/core/lib/transport/static_metadata.c",
+ "src/core/lib/transport/timeout_encoding.c",
+ "src/core/lib/transport/transport.c",
+ "src/core/lib/transport/transport_op_string.c",
+ "src/core/ext/transport/chttp2/alpn/alpn.c",
+ "src/core/ext/client_channel/channel_connectivity.c",
+ "src/core/ext/client_channel/client_channel.c",
+ "src/core/ext/client_channel/client_channel_factory.c",
+ "src/core/ext/client_channel/client_channel_plugin.c",
+ "src/core/ext/client_channel/connector.c",
+ "src/core/ext/client_channel/default_initial_connect_string.c",
+ "src/core/ext/client_channel/http_connect_handshaker.c",
+ "src/core/ext/client_channel/initial_connect_string.c",
+ "src/core/ext/client_channel/lb_policy.c",
+ "src/core/ext/client_channel/lb_policy_factory.c",
+ "src/core/ext/client_channel/lb_policy_registry.c",
+ "src/core/ext/client_channel/parse_address.c",
+ "src/core/ext/client_channel/resolver.c",
+ "src/core/ext/client_channel/resolver_factory.c",
+ "src/core/ext/client_channel/resolver_registry.c",
+ "src/core/ext/client_channel/subchannel.c",
+ "src/core/ext/client_channel/subchannel_index.c",
+ "src/core/ext/client_channel/uri_parser.c",
+ "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
+ "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c",
+ "src/core/ext/transport/chttp2/server/chttp2_server.c",
+ "src/core/ext/census/base_resources.c",
+ "src/core/ext/census/context.c",
+ "src/core/ext/census/gen/census.pb.c",
+ "src/core/ext/census/gen/trace_context.pb.c",
+ "src/core/ext/census/grpc_context.c",
+ "src/core/ext/census/grpc_filter.c",
+ "src/core/ext/census/grpc_plugin.c",
+ "src/core/ext/census/initialize.c",
+ "src/core/ext/census/mlog.c",
+ "src/core/ext/census/operation.c",
+ "src/core/ext/census/placeholders.c",
+ "src/core/ext/census/resource.c",
+ "src/core/ext/census/trace_context.c",
+ "src/core/ext/census/tracing.c",
],
hdrs = [
"include/grpc++/alarm.h",
@@ -1637,6 +1965,16 @@ cc_library(
"include/grpc/impl/codegen/sync_generic.h",
"include/grpc/impl/codegen/sync_posix.h",
"include/grpc/impl/codegen/sync_windows.h",
+ "include/grpc/byte_buffer.h",
+ "include/grpc/byte_buffer_reader.h",
+ "include/grpc/compression.h",
+ "include/grpc/grpc.h",
+ "include/grpc/grpc_posix.h",
+ "include/grpc/grpc_security_constants.h",
+ "include/grpc/slice.h",
+ "include/grpc/slice_buffer.h",
+ "include/grpc/status.h",
+ "include/grpc/census.h",
],
includes = [
"include",
@@ -1646,6 +1984,7 @@ cc_library(
"//external:libssl",
":gpr",
":grpc_cronet",
+ "//external:nanopb",
],
)
@@ -2142,9 +2481,9 @@ objc_library(
"src/core/lib/security/credentials/plugin/plugin_credentials.c",
"src/core/lib/security/credentials/ssl/ssl_credentials.c",
"src/core/lib/security/transport/client_auth_filter.c",
- "src/core/lib/security/transport/handshake.c",
"src/core/lib/security/transport/secure_endpoint.c",
"src/core/lib/security/transport/security_connector.c",
+ "src/core/lib/security/transport/security_handshaker.c",
"src/core/lib/security/transport/server_auth_filter.c",
"src/core/lib/security/transport/tsi_error.c",
"src/core/lib/security/util/b64.c",
@@ -2153,6 +2492,7 @@ objc_library(
"src/core/lib/tsi/fake_transport_security.c",
"src/core/lib/tsi/ssl_transport_security.c",
"src/core/lib/tsi/transport_security.c",
+ "src/core/ext/transport/chttp2/server/chttp2_server.c",
"src/core/ext/transport/chttp2/client/secure/secure_channel_create.c",
"src/core/ext/client_channel/channel_connectivity.c",
"src/core/ext/client_channel/client_channel.c",
@@ -2172,6 +2512,7 @@ objc_library(
"src/core/ext/client_channel/subchannel.c",
"src/core/ext/client_channel/subchannel_index.c",
"src/core/ext/client_channel/uri_parser.c",
+ "src/core/ext/transport/chttp2/client/chttp2_connector.c",
"src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
"src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c",
"src/core/ext/transport/chttp2/client/insecure/channel_create.c",
@@ -2361,9 +2702,9 @@ objc_library(
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/transport/auth_filters.h",
- "src/core/lib/security/transport/handshake.h",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/security_connector.h",
+ "src/core/lib/security/transport/security_handshaker.h",
"src/core/lib/security/transport/tsi_error.h",
"src/core/lib/security/util/b64.h",
"src/core/lib/security/util/json_util.h",
@@ -2372,6 +2713,7 @@ objc_library(
"src/core/lib/tsi/ssl_types.h",
"src/core/lib/tsi/transport_security.h",
"src/core/lib/tsi/transport_security_interface.h",
+ "src/core/ext/transport/chttp2/server/chttp2_server.h",
"src/core/ext/client_channel/client_channel.h",
"src/core/ext/client_channel/client_channel_factory.h",
"src/core/ext/client_channel/connector.h",
@@ -2387,6 +2729,7 @@ objc_library(
"src/core/ext/client_channel/subchannel.h",
"src/core/ext/client_channel/subchannel_index.h",
"src/core/ext/client_channel/uri_parser.h",
+ "src/core/ext/transport/chttp2/client/chttp2_connector.h",
"src/core/ext/lb_policy/grpclb/grpclb.h",
"src/core/ext/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cc9170038e..ff0927504a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -436,9 +436,9 @@ add_library(grpc
src/core/lib/security/credentials/plugin/plugin_credentials.c
src/core/lib/security/credentials/ssl/ssl_credentials.c
src/core/lib/security/transport/client_auth_filter.c
- src/core/lib/security/transport/handshake.c
src/core/lib/security/transport/secure_endpoint.c
src/core/lib/security/transport/security_connector.c
+ src/core/lib/security/transport/security_handshaker.c
src/core/lib/security/transport/server_auth_filter.c
src/core/lib/security/transport/tsi_error.c
src/core/lib/security/util/b64.c
@@ -447,6 +447,7 @@ add_library(grpc
src/core/lib/tsi/fake_transport_security.c
src/core/lib/tsi/ssl_transport_security.c
src/core/lib/tsi/transport_security.c
+ src/core/ext/transport/chttp2/server/chttp2_server.c
src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
src/core/ext/client_channel/channel_connectivity.c
src/core/ext/client_channel/client_channel.c
@@ -466,6 +467,7 @@ add_library(grpc
src/core/ext/client_channel/subchannel.c
src/core/ext/client_channel/subchannel_index.c
src/core/ext/client_channel/uri_parser.c
+ src/core/ext/transport/chttp2/client/chttp2_connector.c
src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -736,9 +738,9 @@ add_library(grpc_cronet
src/core/lib/security/credentials/plugin/plugin_credentials.c
src/core/lib/security/credentials/ssl/ssl_credentials.c
src/core/lib/security/transport/client_auth_filter.c
- src/core/lib/security/transport/handshake.c
src/core/lib/security/transport/secure_endpoint.c
src/core/lib/security/transport/security_connector.c
+ src/core/lib/security/transport/security_handshaker.c
src/core/lib/security/transport/server_auth_filter.c
src/core/lib/security/transport/tsi_error.c
src/core/lib/security/util/b64.c
@@ -747,6 +749,7 @@ add_library(grpc_cronet
src/core/lib/tsi/fake_transport_security.c
src/core/lib/tsi/ssl_transport_security.c
src/core/lib/tsi/transport_security.c
+ src/core/ext/transport/chttp2/client/chttp2_connector.c
src/core/plugin_registry/grpc_cronet_plugin_registry.c
)
@@ -951,8 +954,10 @@ add_library(grpc_unsecure
src/core/ext/transport/chttp2/transport/varint.c
src/core/ext/transport/chttp2/transport/writing.c
src/core/ext/transport/chttp2/alpn/alpn.c
+ src/core/ext/transport/chttp2/server/chttp2_server.c
src/core/ext/transport/chttp2/client/insecure/channel_create.c
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
+ src/core/ext/transport/chttp2/client/chttp2_connector.c
src/core/ext/client_channel/channel_connectivity.c
src/core/ext/client_channel/client_channel.c
src/core/ext/client_channel/client_channel_factory.c
@@ -1256,6 +1261,181 @@ add_library(grpc++_cronet
src/cpp/util/string_ref.cc
src/cpp/util/time_cc.cc
src/cpp/codegen/codegen_init.cc
+ src/core/ext/transport/chttp2/client/insecure/channel_create.c
+ src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
+ src/core/ext/transport/chttp2/client/chttp2_connector.c
+ src/core/ext/transport/chttp2/transport/bin_decoder.c
+ src/core/ext/transport/chttp2/transport/bin_encoder.c
+ src/core/ext/transport/chttp2/transport/chttp2_plugin.c
+ src/core/ext/transport/chttp2/transport/chttp2_transport.c
+ src/core/ext/transport/chttp2/transport/frame_data.c
+ src/core/ext/transport/chttp2/transport/frame_goaway.c
+ src/core/ext/transport/chttp2/transport/frame_ping.c
+ src/core/ext/transport/chttp2/transport/frame_rst_stream.c
+ src/core/ext/transport/chttp2/transport/frame_settings.c
+ src/core/ext/transport/chttp2/transport/frame_window_update.c
+ src/core/ext/transport/chttp2/transport/hpack_encoder.c
+ src/core/ext/transport/chttp2/transport/hpack_parser.c
+ src/core/ext/transport/chttp2/transport/hpack_table.c
+ src/core/ext/transport/chttp2/transport/huffsyms.c
+ src/core/ext/transport/chttp2/transport/incoming_metadata.c
+ src/core/ext/transport/chttp2/transport/parsing.c
+ src/core/ext/transport/chttp2/transport/status_conversion.c
+ src/core/ext/transport/chttp2/transport/stream_lists.c
+ src/core/ext/transport/chttp2/transport/stream_map.c
+ src/core/ext/transport/chttp2/transport/varint.c
+ src/core/ext/transport/chttp2/transport/writing.c
+ src/core/lib/channel/channel_args.c
+ src/core/lib/channel/channel_stack.c
+ src/core/lib/channel/channel_stack_builder.c
+ src/core/lib/channel/compress_filter.c
+ src/core/lib/channel/connected_channel.c
+ src/core/lib/channel/deadline_filter.c
+ src/core/lib/channel/handshaker.c
+ src/core/lib/channel/http_client_filter.c
+ src/core/lib/channel/http_server_filter.c
+ src/core/lib/channel/message_size_filter.c
+ src/core/lib/compression/compression.c
+ src/core/lib/compression/message_compress.c
+ src/core/lib/debug/trace.c
+ src/core/lib/http/format_request.c
+ src/core/lib/http/httpcli.c
+ src/core/lib/http/parser.c
+ src/core/lib/iomgr/closure.c
+ src/core/lib/iomgr/combiner.c
+ src/core/lib/iomgr/endpoint.c
+ src/core/lib/iomgr/endpoint_pair_posix.c
+ src/core/lib/iomgr/endpoint_pair_uv.c
+ src/core/lib/iomgr/endpoint_pair_windows.c
+ src/core/lib/iomgr/error.c
+ src/core/lib/iomgr/ev_epoll_linux.c
+ src/core/lib/iomgr/ev_poll_posix.c
+ src/core/lib/iomgr/ev_posix.c
+ src/core/lib/iomgr/exec_ctx.c
+ src/core/lib/iomgr/executor.c
+ src/core/lib/iomgr/iocp_windows.c
+ src/core/lib/iomgr/iomgr.c
+ src/core/lib/iomgr/iomgr_posix.c
+ src/core/lib/iomgr/iomgr_uv.c
+ src/core/lib/iomgr/iomgr_windows.c
+ src/core/lib/iomgr/load_file.c
+ src/core/lib/iomgr/network_status_tracker.c
+ src/core/lib/iomgr/polling_entity.c
+ src/core/lib/iomgr/pollset_set_uv.c
+ src/core/lib/iomgr/pollset_set_windows.c
+ src/core/lib/iomgr/pollset_uv.c
+ src/core/lib/iomgr/pollset_windows.c
+ src/core/lib/iomgr/resolve_address_posix.c
+ src/core/lib/iomgr/resolve_address_uv.c
+ src/core/lib/iomgr/resolve_address_windows.c
+ src/core/lib/iomgr/resource_quota.c
+ src/core/lib/iomgr/sockaddr_utils.c
+ src/core/lib/iomgr/socket_mutator.c
+ src/core/lib/iomgr/socket_utils_common_posix.c
+ src/core/lib/iomgr/socket_utils_linux.c
+ src/core/lib/iomgr/socket_utils_posix.c
+ src/core/lib/iomgr/socket_utils_uv.c
+ src/core/lib/iomgr/socket_utils_windows.c
+ src/core/lib/iomgr/socket_windows.c
+ src/core/lib/iomgr/tcp_client_posix.c
+ src/core/lib/iomgr/tcp_client_uv.c
+ src/core/lib/iomgr/tcp_client_windows.c
+ src/core/lib/iomgr/tcp_posix.c
+ src/core/lib/iomgr/tcp_server_posix.c
+ src/core/lib/iomgr/tcp_server_uv.c
+ src/core/lib/iomgr/tcp_server_windows.c
+ src/core/lib/iomgr/tcp_uv.c
+ src/core/lib/iomgr/tcp_windows.c
+ src/core/lib/iomgr/time_averaged_stats.c
+ src/core/lib/iomgr/timer_generic.c
+ src/core/lib/iomgr/timer_heap.c
+ src/core/lib/iomgr/timer_uv.c
+ src/core/lib/iomgr/udp_server.c
+ src/core/lib/iomgr/unix_sockets_posix.c
+ src/core/lib/iomgr/unix_sockets_posix_noop.c
+ src/core/lib/iomgr/wakeup_fd_cv.c
+ src/core/lib/iomgr/wakeup_fd_eventfd.c
+ src/core/lib/iomgr/wakeup_fd_nospecial.c
+ src/core/lib/iomgr/wakeup_fd_pipe.c
+ src/core/lib/iomgr/wakeup_fd_posix.c
+ src/core/lib/iomgr/workqueue_uv.c
+ src/core/lib/iomgr/workqueue_windows.c
+ src/core/lib/json/json.c
+ src/core/lib/json/json_reader.c
+ src/core/lib/json/json_string.c
+ src/core/lib/json/json_writer.c
+ src/core/lib/slice/percent_encoding.c
+ src/core/lib/slice/slice.c
+ src/core/lib/slice/slice_buffer.c
+ src/core/lib/slice/slice_string_helpers.c
+ src/core/lib/surface/alarm.c
+ src/core/lib/surface/api_trace.c
+ src/core/lib/surface/byte_buffer.c
+ src/core/lib/surface/byte_buffer_reader.c
+ src/core/lib/surface/call.c
+ src/core/lib/surface/call_details.c
+ src/core/lib/surface/call_log_batch.c
+ src/core/lib/surface/channel.c
+ src/core/lib/surface/channel_init.c
+ src/core/lib/surface/channel_ping.c
+ src/core/lib/surface/channel_stack_type.c
+ src/core/lib/surface/completion_queue.c
+ src/core/lib/surface/event_string.c
+ src/core/lib/surface/lame_client.c
+ src/core/lib/surface/metadata_array.c
+ src/core/lib/surface/server.c
+ src/core/lib/surface/validate_metadata.c
+ src/core/lib/surface/version.c
+ src/core/lib/transport/byte_stream.c
+ src/core/lib/transport/connectivity_state.c
+ src/core/lib/transport/mdstr_hash_table.c
+ src/core/lib/transport/metadata.c
+ src/core/lib/transport/metadata_batch.c
+ src/core/lib/transport/pid_controller.c
+ src/core/lib/transport/service_config.c
+ src/core/lib/transport/static_metadata.c
+ src/core/lib/transport/timeout_encoding.c
+ src/core/lib/transport/transport.c
+ src/core/lib/transport/transport_op_string.c
+ src/core/ext/transport/chttp2/alpn/alpn.c
+ src/core/ext/client_channel/channel_connectivity.c
+ src/core/ext/client_channel/client_channel.c
+ src/core/ext/client_channel/client_channel_factory.c
+ src/core/ext/client_channel/client_channel_plugin.c
+ src/core/ext/client_channel/connector.c
+ src/core/ext/client_channel/default_initial_connect_string.c
+ src/core/ext/client_channel/http_connect_handshaker.c
+ src/core/ext/client_channel/initial_connect_string.c
+ src/core/ext/client_channel/lb_policy.c
+ src/core/ext/client_channel/lb_policy_factory.c
+ src/core/ext/client_channel/lb_policy_registry.c
+ src/core/ext/client_channel/parse_address.c
+ src/core/ext/client_channel/resolver.c
+ src/core/ext/client_channel/resolver_factory.c
+ src/core/ext/client_channel/resolver_registry.c
+ src/core/ext/client_channel/subchannel.c
+ src/core/ext/client_channel/subchannel_index.c
+ src/core/ext/client_channel/uri_parser.c
+ src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
+ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
+ src/core/ext/transport/chttp2/server/chttp2_server.c
+ src/core/ext/census/base_resources.c
+ src/core/ext/census/context.c
+ src/core/ext/census/gen/census.pb.c
+ src/core/ext/census/gen/trace_context.pb.c
+ src/core/ext/census/grpc_context.c
+ src/core/ext/census/grpc_filter.c
+ src/core/ext/census/grpc_plugin.c
+ src/core/ext/census/initialize.c
+ src/core/ext/census/mlog.c
+ src/core/ext/census/operation.c
+ src/core/ext/census/placeholders.c
+ src/core/ext/census/resource.c
+ src/core/ext/census/trace_context.c
+ src/core/ext/census/tracing.c
+ third_party/nanopb/pb_common.c
+ third_party/nanopb/pb_decode.c
+ third_party/nanopb/pb_encode.c
)
target_include_directories(grpc++_cronet
@@ -1362,6 +1542,16 @@ 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/byte_buffer.h
+ include/grpc/byte_buffer_reader.h
+ include/grpc/compression.h
+ include/grpc/grpc.h
+ include/grpc/grpc_posix.h
+ include/grpc/grpc_security_constants.h
+ include/grpc/slice.h
+ include/grpc/slice_buffer.h
+ include/grpc/status.h
+ include/grpc/census.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
diff --git a/Makefile b/Makefile
index b38c3881e1..73fc743230 100644
--- a/Makefile
+++ b/Makefile
@@ -2775,9 +2775,9 @@ LIBGRPC_SRC = \
src/core/lib/security/credentials/plugin/plugin_credentials.c \
src/core/lib/security/credentials/ssl/ssl_credentials.c \
src/core/lib/security/transport/client_auth_filter.c \
- src/core/lib/security/transport/handshake.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
+ src/core/lib/security/transport/security_handshaker.c \
src/core/lib/security/transport/server_auth_filter.c \
src/core/lib/security/transport/tsi_error.c \
src/core/lib/security/util/b64.c \
@@ -2786,6 +2786,7 @@ LIBGRPC_SRC = \
src/core/lib/tsi/fake_transport_security.c \
src/core/lib/tsi/ssl_transport_security.c \
src/core/lib/tsi/transport_security.c \
+ src/core/ext/transport/chttp2/server/chttp2_server.c \
src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \
src/core/ext/client_channel/channel_connectivity.c \
src/core/ext/client_channel/client_channel.c \
@@ -2805,6 +2806,7 @@ LIBGRPC_SRC = \
src/core/ext/client_channel/subchannel.c \
src/core/ext/client_channel/subchannel_index.c \
src/core/ext/client_channel/uri_parser.c \
+ src/core/ext/transport/chttp2/client/chttp2_connector.c \
src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
src/core/ext/transport/chttp2/client/insecure/channel_create.c \
@@ -3093,9 +3095,9 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/security/credentials/plugin/plugin_credentials.c \
src/core/lib/security/credentials/ssl/ssl_credentials.c \
src/core/lib/security/transport/client_auth_filter.c \
- src/core/lib/security/transport/handshake.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
+ src/core/lib/security/transport/security_handshaker.c \
src/core/lib/security/transport/server_auth_filter.c \
src/core/lib/security/transport/tsi_error.c \
src/core/lib/security/util/b64.c \
@@ -3104,6 +3106,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/tsi/fake_transport_security.c \
src/core/lib/tsi/ssl_transport_security.c \
src/core/lib/tsi/transport_security.c \
+ src/core/ext/transport/chttp2/client/chttp2_connector.c \
src/core/plugin_registry/grpc_cronet_plugin_registry.c \
PUBLIC_HEADERS_C += \
@@ -3562,8 +3565,10 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/transport/chttp2/transport/varint.c \
src/core/ext/transport/chttp2/transport/writing.c \
src/core/ext/transport/chttp2/alpn/alpn.c \
+ src/core/ext/transport/chttp2/server/chttp2_server.c \
src/core/ext/transport/chttp2/client/insecure/channel_create.c \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
+ src/core/ext/transport/chttp2/client/chttp2_connector.c \
src/core/ext/client_channel/channel_connectivity.c \
src/core/ext/client_channel/client_channel.c \
src/core/ext/client_channel/client_channel_factory.c \
@@ -3979,6 +3984,181 @@ LIBGRPC++_CRONET_SRC = \
src/cpp/util/string_ref.cc \
src/cpp/util/time_cc.cc \
src/cpp/codegen/codegen_init.cc \
+ src/core/ext/transport/chttp2/client/insecure/channel_create.c \
+ src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
+ src/core/ext/transport/chttp2/client/chttp2_connector.c \
+ src/core/ext/transport/chttp2/transport/bin_decoder.c \
+ src/core/ext/transport/chttp2/transport/bin_encoder.c \
+ src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
+ src/core/ext/transport/chttp2/transport/chttp2_transport.c \
+ src/core/ext/transport/chttp2/transport/frame_data.c \
+ src/core/ext/transport/chttp2/transport/frame_goaway.c \
+ src/core/ext/transport/chttp2/transport/frame_ping.c \
+ src/core/ext/transport/chttp2/transport/frame_rst_stream.c \
+ src/core/ext/transport/chttp2/transport/frame_settings.c \
+ src/core/ext/transport/chttp2/transport/frame_window_update.c \
+ src/core/ext/transport/chttp2/transport/hpack_encoder.c \
+ src/core/ext/transport/chttp2/transport/hpack_parser.c \
+ src/core/ext/transport/chttp2/transport/hpack_table.c \
+ src/core/ext/transport/chttp2/transport/huffsyms.c \
+ src/core/ext/transport/chttp2/transport/incoming_metadata.c \
+ src/core/ext/transport/chttp2/transport/parsing.c \
+ src/core/ext/transport/chttp2/transport/status_conversion.c \
+ src/core/ext/transport/chttp2/transport/stream_lists.c \
+ src/core/ext/transport/chttp2/transport/stream_map.c \
+ src/core/ext/transport/chttp2/transport/varint.c \
+ src/core/ext/transport/chttp2/transport/writing.c \
+ src/core/lib/channel/channel_args.c \
+ src/core/lib/channel/channel_stack.c \
+ src/core/lib/channel/channel_stack_builder.c \
+ src/core/lib/channel/compress_filter.c \
+ src/core/lib/channel/connected_channel.c \
+ src/core/lib/channel/deadline_filter.c \
+ src/core/lib/channel/handshaker.c \
+ src/core/lib/channel/http_client_filter.c \
+ src/core/lib/channel/http_server_filter.c \
+ src/core/lib/channel/message_size_filter.c \
+ src/core/lib/compression/compression.c \
+ src/core/lib/compression/message_compress.c \
+ src/core/lib/debug/trace.c \
+ src/core/lib/http/format_request.c \
+ src/core/lib/http/httpcli.c \
+ src/core/lib/http/parser.c \
+ src/core/lib/iomgr/closure.c \
+ src/core/lib/iomgr/combiner.c \
+ src/core/lib/iomgr/endpoint.c \
+ src/core/lib/iomgr/endpoint_pair_posix.c \
+ src/core/lib/iomgr/endpoint_pair_uv.c \
+ src/core/lib/iomgr/endpoint_pair_windows.c \
+ src/core/lib/iomgr/error.c \
+ src/core/lib/iomgr/ev_epoll_linux.c \
+ src/core/lib/iomgr/ev_poll_posix.c \
+ src/core/lib/iomgr/ev_posix.c \
+ src/core/lib/iomgr/exec_ctx.c \
+ src/core/lib/iomgr/executor.c \
+ src/core/lib/iomgr/iocp_windows.c \
+ src/core/lib/iomgr/iomgr.c \
+ src/core/lib/iomgr/iomgr_posix.c \
+ src/core/lib/iomgr/iomgr_uv.c \
+ src/core/lib/iomgr/iomgr_windows.c \
+ src/core/lib/iomgr/load_file.c \
+ src/core/lib/iomgr/network_status_tracker.c \
+ src/core/lib/iomgr/polling_entity.c \
+ src/core/lib/iomgr/pollset_set_uv.c \
+ src/core/lib/iomgr/pollset_set_windows.c \
+ src/core/lib/iomgr/pollset_uv.c \
+ src/core/lib/iomgr/pollset_windows.c \
+ src/core/lib/iomgr/resolve_address_posix.c \
+ src/core/lib/iomgr/resolve_address_uv.c \
+ src/core/lib/iomgr/resolve_address_windows.c \
+ src/core/lib/iomgr/resource_quota.c \
+ src/core/lib/iomgr/sockaddr_utils.c \
+ src/core/lib/iomgr/socket_mutator.c \
+ src/core/lib/iomgr/socket_utils_common_posix.c \
+ src/core/lib/iomgr/socket_utils_linux.c \
+ src/core/lib/iomgr/socket_utils_posix.c \
+ src/core/lib/iomgr/socket_utils_uv.c \
+ src/core/lib/iomgr/socket_utils_windows.c \
+ src/core/lib/iomgr/socket_windows.c \
+ src/core/lib/iomgr/tcp_client_posix.c \
+ src/core/lib/iomgr/tcp_client_uv.c \
+ src/core/lib/iomgr/tcp_client_windows.c \
+ src/core/lib/iomgr/tcp_posix.c \
+ src/core/lib/iomgr/tcp_server_posix.c \
+ src/core/lib/iomgr/tcp_server_uv.c \
+ src/core/lib/iomgr/tcp_server_windows.c \
+ src/core/lib/iomgr/tcp_uv.c \
+ src/core/lib/iomgr/tcp_windows.c \
+ src/core/lib/iomgr/time_averaged_stats.c \
+ src/core/lib/iomgr/timer_generic.c \
+ src/core/lib/iomgr/timer_heap.c \
+ src/core/lib/iomgr/timer_uv.c \
+ src/core/lib/iomgr/udp_server.c \
+ src/core/lib/iomgr/unix_sockets_posix.c \
+ src/core/lib/iomgr/unix_sockets_posix_noop.c \
+ src/core/lib/iomgr/wakeup_fd_cv.c \
+ src/core/lib/iomgr/wakeup_fd_eventfd.c \
+ src/core/lib/iomgr/wakeup_fd_nospecial.c \
+ src/core/lib/iomgr/wakeup_fd_pipe.c \
+ src/core/lib/iomgr/wakeup_fd_posix.c \
+ src/core/lib/iomgr/workqueue_uv.c \
+ src/core/lib/iomgr/workqueue_windows.c \
+ src/core/lib/json/json.c \
+ src/core/lib/json/json_reader.c \
+ src/core/lib/json/json_string.c \
+ src/core/lib/json/json_writer.c \
+ src/core/lib/slice/percent_encoding.c \
+ src/core/lib/slice/slice.c \
+ src/core/lib/slice/slice_buffer.c \
+ src/core/lib/slice/slice_string_helpers.c \
+ src/core/lib/surface/alarm.c \
+ src/core/lib/surface/api_trace.c \
+ src/core/lib/surface/byte_buffer.c \
+ src/core/lib/surface/byte_buffer_reader.c \
+ src/core/lib/surface/call.c \
+ src/core/lib/surface/call_details.c \
+ src/core/lib/surface/call_log_batch.c \
+ src/core/lib/surface/channel.c \
+ src/core/lib/surface/channel_init.c \
+ src/core/lib/surface/channel_ping.c \
+ src/core/lib/surface/channel_stack_type.c \
+ src/core/lib/surface/completion_queue.c \
+ src/core/lib/surface/event_string.c \
+ src/core/lib/surface/lame_client.c \
+ src/core/lib/surface/metadata_array.c \
+ src/core/lib/surface/server.c \
+ src/core/lib/surface/validate_metadata.c \
+ src/core/lib/surface/version.c \
+ src/core/lib/transport/byte_stream.c \
+ src/core/lib/transport/connectivity_state.c \
+ src/core/lib/transport/mdstr_hash_table.c \
+ src/core/lib/transport/metadata.c \
+ src/core/lib/transport/metadata_batch.c \
+ src/core/lib/transport/pid_controller.c \
+ src/core/lib/transport/service_config.c \
+ src/core/lib/transport/static_metadata.c \
+ src/core/lib/transport/timeout_encoding.c \
+ src/core/lib/transport/transport.c \
+ src/core/lib/transport/transport_op_string.c \
+ src/core/ext/transport/chttp2/alpn/alpn.c \
+ src/core/ext/client_channel/channel_connectivity.c \
+ src/core/ext/client_channel/client_channel.c \
+ src/core/ext/client_channel/client_channel_factory.c \
+ src/core/ext/client_channel/client_channel_plugin.c \
+ src/core/ext/client_channel/connector.c \
+ src/core/ext/client_channel/default_initial_connect_string.c \
+ src/core/ext/client_channel/http_connect_handshaker.c \
+ src/core/ext/client_channel/initial_connect_string.c \
+ src/core/ext/client_channel/lb_policy.c \
+ src/core/ext/client_channel/lb_policy_factory.c \
+ src/core/ext/client_channel/lb_policy_registry.c \
+ src/core/ext/client_channel/parse_address.c \
+ src/core/ext/client_channel/resolver.c \
+ src/core/ext/client_channel/resolver_factory.c \
+ src/core/ext/client_channel/resolver_registry.c \
+ src/core/ext/client_channel/subchannel.c \
+ src/core/ext/client_channel/subchannel_index.c \
+ src/core/ext/client_channel/uri_parser.c \
+ src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
+ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
+ src/core/ext/transport/chttp2/server/chttp2_server.c \
+ src/core/ext/census/base_resources.c \
+ src/core/ext/census/context.c \
+ src/core/ext/census/gen/census.pb.c \
+ src/core/ext/census/gen/trace_context.pb.c \
+ src/core/ext/census/grpc_context.c \
+ src/core/ext/census/grpc_filter.c \
+ src/core/ext/census/grpc_plugin.c \
+ src/core/ext/census/initialize.c \
+ src/core/ext/census/mlog.c \
+ src/core/ext/census/operation.c \
+ src/core/ext/census/placeholders.c \
+ src/core/ext/census/resource.c \
+ src/core/ext/census/trace_context.c \
+ src/core/ext/census/tracing.c \
+ third_party/nanopb/pb_common.c \
+ third_party/nanopb/pb_decode.c \
+ third_party/nanopb/pb_encode.c \
PUBLIC_HEADERS_CXX += \
include/grpc++/alarm.h \
@@ -4068,6 +4248,16 @@ 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/byte_buffer.h \
+ include/grpc/byte_buffer_reader.h \
+ include/grpc/compression.h \
+ include/grpc/grpc.h \
+ include/grpc/grpc_posix.h \
+ include/grpc/grpc_security_constants.h \
+ include/grpc/slice.h \
+ include/grpc/slice_buffer.h \
+ include/grpc/status.h \
+ include/grpc/census.h \
LIBGRPC++_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_CRONET_SRC))))
@@ -16577,9 +16767,9 @@ src/core/lib/security/credentials/oauth2/oauth2_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/credentials/plugin/plugin_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/credentials/ssl/ssl_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/transport/client_auth_filter.c: $(OPENSSL_DEP)
-src/core/lib/security/transport/handshake.c: $(OPENSSL_DEP)
src/core/lib/security/transport/secure_endpoint.c: $(OPENSSL_DEP)
src/core/lib/security/transport/security_connector.c: $(OPENSSL_DEP)
+src/core/lib/security/transport/security_handshaker.c: $(OPENSSL_DEP)
src/core/lib/security/transport/server_auth_filter.c: $(OPENSSL_DEP)
src/core/lib/security/transport/tsi_error.c: $(OPENSSL_DEP)
src/core/lib/security/util/b64.c: $(OPENSSL_DEP)
diff --git a/binding.gyp b/binding.gyp
index 28d7c6b9a5..516cbdce5d 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -716,9 +716,9 @@
'src/core/lib/security/credentials/plugin/plugin_credentials.c',
'src/core/lib/security/credentials/ssl/ssl_credentials.c',
'src/core/lib/security/transport/client_auth_filter.c',
- 'src/core/lib/security/transport/handshake.c',
'src/core/lib/security/transport/secure_endpoint.c',
'src/core/lib/security/transport/security_connector.c',
+ 'src/core/lib/security/transport/security_handshaker.c',
'src/core/lib/security/transport/server_auth_filter.c',
'src/core/lib/security/transport/tsi_error.c',
'src/core/lib/security/util/b64.c',
@@ -727,6 +727,7 @@
'src/core/lib/tsi/fake_transport_security.c',
'src/core/lib/tsi/ssl_transport_security.c',
'src/core/lib/tsi/transport_security.c',
+ 'src/core/ext/transport/chttp2/server/chttp2_server.c',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.c',
'src/core/ext/client_channel/channel_connectivity.c',
'src/core/ext/client_channel/client_channel.c',
@@ -746,6 +747,7 @@
'src/core/ext/client_channel/subchannel.c',
'src/core/ext/client_channel/subchannel_index.c',
'src/core/ext/client_channel/uri_parser.c',
+ 'src/core/ext/transport/chttp2/client/chttp2_connector.c',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
diff --git a/build.yaml b/build.yaml
index 1404c89dc2..a5fbaa3a4e 100644
--- a/build.yaml
+++ b/build.yaml
@@ -495,9 +495,9 @@ filegroups:
- src/core/lib/security/credentials/plugin/plugin_credentials.h
- src/core/lib/security/credentials/ssl/ssl_credentials.h
- src/core/lib/security/transport/auth_filters.h
- - src/core/lib/security/transport/handshake.h
- src/core/lib/security/transport/secure_endpoint.h
- src/core/lib/security/transport/security_connector.h
+ - src/core/lib/security/transport/security_handshaker.h
- src/core/lib/security/transport/tsi_error.h
- src/core/lib/security/util/b64.h
- src/core/lib/security/util/json_util.h
@@ -518,9 +518,9 @@ filegroups:
- src/core/lib/security/credentials/plugin/plugin_credentials.c
- src/core/lib/security/credentials/ssl/ssl_credentials.c
- src/core/lib/security/transport/client_auth_filter.c
- - src/core/lib/security/transport/handshake.c
- src/core/lib/security/transport/secure_endpoint.c
- src/core/lib/security/transport/security_connector.c
+ - src/core/lib/security/transport/security_handshaker.c
- src/core/lib/security/transport/server_auth_filter.c
- src/core/lib/security/transport/tsi_error.c
- src/core/lib/security/util/b64.c
@@ -621,11 +621,20 @@ filegroups:
- src/core/ext/transport/chttp2/alpn/alpn.c
deps:
- gpr
+- name: grpc_transport_chttp2_client_connector
+ headers:
+ - src/core/ext/transport/chttp2/client/chttp2_connector.h
+ src:
+ - src/core/ext/transport/chttp2/client/chttp2_connector.c
+ uses:
+ - grpc_transport_chttp2
+ - grpc_base
- name: grpc_transport_chttp2_client_insecure
src:
- src/core/ext/transport/chttp2/client/insecure/channel_create.c
- src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
uses:
+ - grpc_transport_chttp2_client_connector
- grpc_transport_chttp2
- grpc_base
- grpc_client_channel
@@ -637,6 +646,15 @@ filegroups:
- grpc_base
- grpc_client_channel
- grpc_secure
+ - grpc_transport_chttp2_client_connector
+- name: grpc_transport_chttp2_server
+ headers:
+ - src/core/ext/transport/chttp2/server/chttp2_server.h
+ src:
+ - src/core/ext/transport/chttp2/server/chttp2_server.c
+ uses:
+ - grpc_transport_chttp2
+ - grpc_base
- name: grpc_transport_chttp2_server_insecure
src:
- src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
@@ -644,6 +662,7 @@ filegroups:
uses:
- grpc_transport_chttp2
- grpc_base
+ - grpc_transport_chttp2_server
- name: grpc_transport_chttp2_server_secure
src:
- src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
@@ -651,6 +670,7 @@ filegroups:
- grpc_transport_chttp2
- grpc_base
- grpc_secure
+ - grpc_transport_chttp2_server
- name: grpc_transport_cronet_client_secure
public_headers:
- include/grpc/grpc_cronet.h
@@ -1039,6 +1059,9 @@ libs:
- grpc++_base
- grpc++_codegen_base
- grpc++_codegen_base_src
+ - grpc_transport_chttp2_client_insecure
+ - grpc_transport_chttp2_server_insecure
+ - census
platforms:
- linux
secure: true
diff --git a/config.m4 b/config.m4
index 7f65b7c0d8..4b86e25581 100644
--- a/config.m4
+++ b/config.m4
@@ -232,9 +232,9 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/security/credentials/plugin/plugin_credentials.c \
src/core/lib/security/credentials/ssl/ssl_credentials.c \
src/core/lib/security/transport/client_auth_filter.c \
- src/core/lib/security/transport/handshake.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
+ src/core/lib/security/transport/security_handshaker.c \
src/core/lib/security/transport/server_auth_filter.c \
src/core/lib/security/transport/tsi_error.c \
src/core/lib/security/util/b64.c \
@@ -243,6 +243,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/tsi/fake_transport_security.c \
src/core/lib/tsi/ssl_transport_security.c \
src/core/lib/tsi/transport_security.c \
+ src/core/ext/transport/chttp2/server/chttp2_server.c \
src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \
src/core/ext/client_channel/channel_connectivity.c \
src/core/ext/client_channel/client_channel.c \
@@ -262,6 +263,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/client_channel/subchannel.c \
src/core/ext/client_channel/subchannel_index.c \
src/core/ext/client_channel/uri_parser.c \
+ src/core/ext/transport/chttp2/client/chttp2_connector.c \
src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
src/core/ext/transport/chttp2/client/insecure/channel_create.c \
@@ -609,8 +611,10 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/resolver/dns/native)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/resolver/sockaddr)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/alpn)
+ PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/client)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/client/insecure)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/client/secure)
+ PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server/insecure)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server/secure)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/transport)
diff --git a/doc/connection-backoff.md b/doc/connection-backoff.md
index 251a60f384..0e83d9b97f 100644
--- a/doc/connection-backoff.md
+++ b/doc/connection-backoff.md
@@ -7,9 +7,10 @@ requests) and instead do some form of exponential backoff.
We have several parameters:
1. INITIAL_BACKOFF (how long to wait after the first failure before retrying)
- 2. MULTIPLIER (factor with which to multiply backoff after a failed retry)
- 3. MAX_BACKOFF (upper bound on backoff)
- 4. MIN_CONNECT_TIMEOUT (minimum time we're willing to give a connection to
+ 1. MULTIPLIER (factor with which to multiply backoff after a failed retry)
+ 1. JITTER (by how much to randomize backoffs).
+ 1. MAX_BACKOFF (upper bound on backoff)
+ 1. MIN_CONNECT_TIMEOUT (minimum time we're willing to give a connection to
complete)
## Proposed Backoff Algorithm
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index c4ec01da93..04f7211d21 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -376,9 +376,9 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/transport/auth_filters.h',
- 'src/core/lib/security/transport/handshake.h',
'src/core/lib/security/transport/secure_endpoint.h',
'src/core/lib/security/transport/security_connector.h',
+ 'src/core/lib/security/transport/security_handshaker.h',
'src/core/lib/security/transport/tsi_error.h',
'src/core/lib/security/util/b64.h',
'src/core/lib/security/util/json_util.h',
@@ -387,6 +387,7 @@ Pod::Spec.new do |s|
'src/core/lib/tsi/ssl_types.h',
'src/core/lib/tsi/transport_security.h',
'src/core/lib/tsi/transport_security_interface.h',
+ 'src/core/ext/transport/chttp2/server/chttp2_server.h',
'src/core/ext/client_channel/client_channel.h',
'src/core/ext/client_channel/client_channel_factory.h',
'src/core/ext/client_channel/connector.h',
@@ -402,6 +403,7 @@ Pod::Spec.new do |s|
'src/core/ext/client_channel/subchannel.h',
'src/core/ext/client_channel/subchannel_index.h',
'src/core/ext/client_channel/uri_parser.h',
+ 'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/lb_policy/grpclb/grpclb.h',
'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
@@ -574,9 +576,9 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.c',
'src/core/lib/security/credentials/ssl/ssl_credentials.c',
'src/core/lib/security/transport/client_auth_filter.c',
- 'src/core/lib/security/transport/handshake.c',
'src/core/lib/security/transport/secure_endpoint.c',
'src/core/lib/security/transport/security_connector.c',
+ 'src/core/lib/security/transport/security_handshaker.c',
'src/core/lib/security/transport/server_auth_filter.c',
'src/core/lib/security/transport/tsi_error.c',
'src/core/lib/security/util/b64.c',
@@ -585,6 +587,7 @@ Pod::Spec.new do |s|
'src/core/lib/tsi/fake_transport_security.c',
'src/core/lib/tsi/ssl_transport_security.c',
'src/core/lib/tsi/transport_security.c',
+ 'src/core/ext/transport/chttp2/server/chttp2_server.c',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.c',
'src/core/ext/client_channel/channel_connectivity.c',
'src/core/ext/client_channel/client_channel.c',
@@ -604,6 +607,7 @@ Pod::Spec.new do |s|
'src/core/ext/client_channel/subchannel.c',
'src/core/ext/client_channel/subchannel_index.c',
'src/core/ext/client_channel/uri_parser.c',
+ 'src/core/ext/transport/chttp2/client/chttp2_connector.c',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
@@ -779,9 +783,9 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/transport/auth_filters.h',
- 'src/core/lib/security/transport/handshake.h',
'src/core/lib/security/transport/secure_endpoint.h',
'src/core/lib/security/transport/security_connector.h',
+ 'src/core/lib/security/transport/security_handshaker.h',
'src/core/lib/security/transport/tsi_error.h',
'src/core/lib/security/util/b64.h',
'src/core/lib/security/util/json_util.h',
@@ -790,6 +794,7 @@ Pod::Spec.new do |s|
'src/core/lib/tsi/ssl_types.h',
'src/core/lib/tsi/transport_security.h',
'src/core/lib/tsi/transport_security_interface.h',
+ 'src/core/ext/transport/chttp2/server/chttp2_server.h',
'src/core/ext/client_channel/client_channel.h',
'src/core/ext/client_channel/client_channel_factory.h',
'src/core/ext/client_channel/connector.h',
@@ -805,6 +810,7 @@ Pod::Spec.new do |s|
'src/core/ext/client_channel/subchannel.h',
'src/core/ext/client_channel/subchannel_index.h',
'src/core/ext/client_channel/uri_parser.h',
+ 'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/lb_policy/grpclb/grpclb.h',
'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index cce6f2cfcc..6019b97f67 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -295,9 +295,9 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h )
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h )
s.files += %w( src/core/lib/security/transport/auth_filters.h )
- s.files += %w( src/core/lib/security/transport/handshake.h )
s.files += %w( src/core/lib/security/transport/secure_endpoint.h )
s.files += %w( src/core/lib/security/transport/security_connector.h )
+ s.files += %w( src/core/lib/security/transport/security_handshaker.h )
s.files += %w( src/core/lib/security/transport/tsi_error.h )
s.files += %w( src/core/lib/security/util/b64.h )
s.files += %w( src/core/lib/security/util/json_util.h )
@@ -306,6 +306,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/tsi/ssl_types.h )
s.files += %w( src/core/lib/tsi/transport_security.h )
s.files += %w( src/core/lib/tsi/transport_security_interface.h )
+ s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.h )
s.files += %w( src/core/ext/client_channel/client_channel.h )
s.files += %w( src/core/ext/client_channel/client_channel_factory.h )
s.files += %w( src/core/ext/client_channel/connector.h )
@@ -321,6 +322,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/client_channel/subchannel.h )
s.files += %w( src/core/ext/client_channel/subchannel_index.h )
s.files += %w( src/core/ext/client_channel/uri_parser.h )
+ s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.h )
s.files += %w( src/core/ext/lb_policy/grpclb/grpclb.h )
s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.h )
s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
@@ -493,9 +495,9 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.c )
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.c )
s.files += %w( src/core/lib/security/transport/client_auth_filter.c )
- s.files += %w( src/core/lib/security/transport/handshake.c )
s.files += %w( src/core/lib/security/transport/secure_endpoint.c )
s.files += %w( src/core/lib/security/transport/security_connector.c )
+ s.files += %w( src/core/lib/security/transport/security_handshaker.c )
s.files += %w( src/core/lib/security/transport/server_auth_filter.c )
s.files += %w( src/core/lib/security/transport/tsi_error.c )
s.files += %w( src/core/lib/security/util/b64.c )
@@ -504,6 +506,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/tsi/fake_transport_security.c )
s.files += %w( src/core/lib/tsi/ssl_transport_security.c )
s.files += %w( src/core/lib/tsi/transport_security.c )
+ s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.c )
s.files += %w( src/core/ext/transport/chttp2/client/secure/secure_channel_create.c )
s.files += %w( src/core/ext/client_channel/channel_connectivity.c )
s.files += %w( src/core/ext/client_channel/client_channel.c )
@@ -523,6 +526,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/client_channel/subchannel.c )
s.files += %w( src/core/ext/client_channel/subchannel_index.c )
s.files += %w( src/core/ext/client_channel/uri_parser.c )
+ s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.c )
s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2.c )
s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.c )
diff --git a/package.xml b/package.xml
index 2822ac624d..61668815a6 100644
--- a/package.xml
+++ b/package.xml
@@ -303,9 +303,9 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/security/transport/handshake.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_connector.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/b64.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/json_util.h" role="src" />
@@ -314,6 +314,7 @@
<file baseinstalldir="/" name="src/core/lib/tsi/ssl_types.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/tsi/transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/tsi/transport_security_interface.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/chttp2_server.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_channel/client_channel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_channel/client_channel_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_channel/connector.h" role="src" />
@@ -329,6 +330,7 @@
<file baseinstalldir="/" name="src/core/ext/client_channel/subchannel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_channel/subchannel_index.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_channel/uri_parser.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
@@ -501,9 +503,9 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/client_auth_filter.c" role="src" />
- <file baseinstalldir="/" name="src/core/lib/security/transport/handshake.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_connector.c" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/server_auth_filter.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/b64.c" role="src" />
@@ -512,6 +514,7 @@
<file baseinstalldir="/" name="src/core/lib/tsi/fake_transport_security.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/tsi/ssl_transport_security.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/tsi/transport_security.c" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/chttp2_server.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/secure/secure_channel_create.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_channel/channel_connectivity.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_channel/client_channel.c" role="src" />
@@ -531,6 +534,7 @@
<file baseinstalldir="/" name="src/core/ext/client_channel/subchannel.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_channel/subchannel_index.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_channel/uri_parser.c" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.c" role="src" />
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index febaf135b6..b0a60092ab 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -760,6 +760,32 @@ PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config)
PythonGrpcGenerator::~PythonGrpcGenerator() {}
+static bool GenerateGrpc(GeneratorContext* context, PrivateGenerator& generator,
+ grpc::string file_name, bool generate_in_pb2_grpc) {
+ bool success;
+ std::unique_ptr<ZeroCopyOutputStream> output;
+ std::unique_ptr<CodedOutputStream> coded_output;
+ grpc::string grpc_code;
+
+ if (generate_in_pb2_grpc) {
+ output.reset(context->Open(file_name));
+ generator.generate_in_pb2_grpc = true;
+ } else {
+ output.reset(context->OpenForInsert(file_name, "module_scope"));
+ generator.generate_in_pb2_grpc = false;
+ }
+
+ coded_output.reset(new CodedOutputStream(output.get()));
+ tie(success, grpc_code) = generator.GetGrpcServices();
+
+ if (success) {
+ coded_output->WriteRaw(grpc_code.data(), grpc_code.size());
+ return true;
+ } else {
+ return false;
+ }
+}
+
bool PythonGrpcGenerator::Generate(const FileDescriptor* file,
const grpc::string& parameter,
GeneratorContext* context,
@@ -780,28 +806,15 @@ bool PythonGrpcGenerator::Generate(const FileDescriptor* file,
}
PrivateGenerator generator(config_, file);
-
- std::unique_ptr<ZeroCopyOutputStream> pb2_output(
- context->OpenForAppend(pb2_file_name));
- std::unique_ptr<ZeroCopyOutputStream> grpc_output(
- context->Open(pb2_grpc_file_name));
- CodedOutputStream pb2_coded_out(pb2_output.get());
- CodedOutputStream grpc_coded_out(grpc_output.get());
- bool success = false;
- grpc::string pb2_code;
- grpc::string grpc_code;
- generator.generate_in_pb2_grpc = false;
- tie(success, pb2_code) = generator.GetGrpcServices();
- if (success) {
- generator.generate_in_pb2_grpc = true;
- tie(success, grpc_code) = generator.GetGrpcServices();
- if (success) {
- pb2_coded_out.WriteRaw(pb2_code.data(), pb2_code.size());
- grpc_coded_out.WriteRaw(grpc_code.data(), grpc_code.size());
- return true;
- }
+ if (parameter == "grpc_2_0") {
+ return GenerateGrpc(context, generator, pb2_grpc_file_name, true);
+ } else if (parameter == "") {
+ return GenerateGrpc(context, generator, pb2_grpc_file_name, true) &&
+ GenerateGrpc(context, generator, pb2_file_name, false);
+ } else {
+ *error = "Invalid parameter '" + parameter + "'.";
+ return false;
}
- return false;
}
} // namespace grpc_python_generator
diff --git a/src/core/ext/client_channel/http_connect_handshaker.c b/src/core/ext/client_channel/http_connect_handshaker.c
index 82042897b2..572af52dfd 100644
--- a/src/core/ext/client_channel/http_connect_handshaker.c
+++ b/src/core/ext/client_channel/http_connect_handshaker.c
@@ -41,9 +41,9 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/http/format_request.h"
#include "src/core/lib/http/parser.h"
-#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/support/env.h"
typedef struct http_connect_handshaker {
@@ -53,27 +53,38 @@ typedef struct http_connect_handshaker {
char* proxy_server;
char* server_name;
+ gpr_refcount refcount;
+ gpr_mu mu;
+
+ bool shutdown;
+ // Endpoint and read buffer to destroy after a shutdown.
+ grpc_endpoint* endpoint_to_destroy;
+ grpc_slice_buffer* read_buffer_to_destroy;
+
// State saved while performing the handshake.
- grpc_endpoint* endpoint;
- grpc_channel_args* args;
- grpc_handshaker_done_cb cb;
- void* user_data;
+ grpc_handshaker_args* args;
+ grpc_closure* on_handshake_done;
// Objects for processing the HTTP CONNECT request and response.
grpc_slice_buffer write_buffer;
- grpc_slice_buffer* read_buffer; // Ownership passes through this object.
grpc_closure request_done_closure;
grpc_closure response_read_closure;
grpc_http_parser http_parser;
grpc_http_response http_response;
- grpc_timer timeout_timer;
-
- gpr_refcount refcount;
} http_connect_handshaker;
// Unref and clean up handshaker.
-static void http_connect_handshaker_unref(http_connect_handshaker* handshaker) {
+static void http_connect_handshaker_unref(grpc_exec_ctx* exec_ctx,
+ http_connect_handshaker* handshaker) {
if (gpr_unref(&handshaker->refcount)) {
+ gpr_mu_destroy(&handshaker->mu);
+ if (handshaker->endpoint_to_destroy != NULL) {
+ grpc_endpoint_destroy(exec_ctx, handshaker->endpoint_to_destroy);
+ }
+ if (handshaker->read_buffer_to_destroy != NULL) {
+ grpc_slice_buffer_destroy(handshaker->read_buffer_to_destroy);
+ gpr_free(handshaker->read_buffer_to_destroy);
+ }
gpr_free(handshaker->proxy_server);
gpr_free(handshaker->server_name);
grpc_slice_buffer_destroy(&handshaker->write_buffer);
@@ -83,28 +94,64 @@ static void http_connect_handshaker_unref(http_connect_handshaker* handshaker) {
}
}
-// Callback invoked when deadline is exceeded.
-static void on_timeout(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
- http_connect_handshaker* handshaker = arg;
- if (error == GRPC_ERROR_NONE) { // Timer fired, rather than being cancelled.
- grpc_endpoint_shutdown(exec_ctx, handshaker->endpoint);
+// Set args fields to NULL, saving the endpoint and read buffer for
+// later destruction.
+static void cleanup_args_for_failure_locked(
+ http_connect_handshaker* handshaker) {
+ handshaker->endpoint_to_destroy = handshaker->args->endpoint;
+ handshaker->args->endpoint = NULL;
+ handshaker->read_buffer_to_destroy = handshaker->args->read_buffer;
+ handshaker->args->read_buffer = NULL;
+ grpc_channel_args_destroy(handshaker->args->args);
+ handshaker->args->args = NULL;
+}
+
+// If the handshake failed or we're shutting down, clean up and invoke the
+// callback with the error.
+static void handshake_failed_locked(grpc_exec_ctx* exec_ctx,
+ http_connect_handshaker* handshaker,
+ grpc_error* error) {
+ if (error == GRPC_ERROR_NONE) {
+ // If we were shut down after an endpoint operation succeeded but
+ // before the endpoint callback was invoked, we need to generate our
+ // own error.
+ error = GRPC_ERROR_CREATE("Handshaker shutdown");
}
- http_connect_handshaker_unref(handshaker);
+ if (!handshaker->shutdown) {
+ // TODO(ctiller): It is currently necessary to shutdown endpoints
+ // before destroying them, even if we know that there are no
+ // pending read/write callbacks. This should be fixed, at which
+ // point this can be removed.
+ grpc_endpoint_shutdown(exec_ctx, handshaker->args->endpoint);
+ // Not shutting down, so the handshake failed. Clean up before
+ // invoking the callback.
+ cleanup_args_for_failure_locked(handshaker);
+ // Set shutdown to true so that subsequent calls to
+ // http_connect_handshaker_shutdown() do nothing.
+ handshaker->shutdown = true;
+ }
+ // Invoke callback.
+ grpc_exec_ctx_sched(exec_ctx, handshaker->on_handshake_done, error, NULL);
}
// Callback invoked when finished writing HTTP CONNECT request.
static void on_write_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
http_connect_handshaker* handshaker = arg;
- if (error != GRPC_ERROR_NONE) {
- // If the write failed, invoke the callback immediately with the error.
- handshaker->cb(exec_ctx, handshaker->endpoint, handshaker->args,
- handshaker->read_buffer, handshaker->user_data,
- GRPC_ERROR_REF(error));
+ gpr_mu_lock(&handshaker->mu);
+ if (error != GRPC_ERROR_NONE || handshaker->shutdown) {
+ // If the write failed or we're shutting down, clean up and invoke the
+ // callback with the error.
+ handshake_failed_locked(exec_ctx, handshaker, GRPC_ERROR_REF(error));
+ gpr_mu_unlock(&handshaker->mu);
+ http_connect_handshaker_unref(exec_ctx, handshaker);
} else {
// Otherwise, read the response.
- grpc_endpoint_read(exec_ctx, handshaker->endpoint, handshaker->read_buffer,
+ // The read callback inherits our ref to the handshaker.
+ grpc_endpoint_read(exec_ctx, handshaker->args->endpoint,
+ handshaker->args->read_buffer,
&handshaker->response_read_closure);
+ gpr_mu_unlock(&handshaker->mu);
}
}
@@ -112,36 +159,40 @@ static void on_write_done(grpc_exec_ctx* exec_ctx, void* arg,
static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
http_connect_handshaker* handshaker = arg;
- if (error != GRPC_ERROR_NONE) {
- GRPC_ERROR_REF(error); // Take ref to pass to the handshake-done callback.
+ gpr_mu_lock(&handshaker->mu);
+ if (error != GRPC_ERROR_NONE || handshaker->shutdown) {
+ // If the read failed or we're shutting down, clean up and invoke the
+ // callback with the error.
+ handshake_failed_locked(exec_ctx, handshaker, GRPC_ERROR_REF(error));
goto done;
}
// Add buffer to parser.
- for (size_t i = 0; i < handshaker->read_buffer->count; ++i) {
- if (GRPC_SLICE_LENGTH(handshaker->read_buffer->slices[i]) > 0) {
+ for (size_t i = 0; i < handshaker->args->read_buffer->count; ++i) {
+ if (GRPC_SLICE_LENGTH(handshaker->args->read_buffer->slices[i]) > 0) {
size_t body_start_offset = 0;
error = grpc_http_parser_parse(&handshaker->http_parser,
- handshaker->read_buffer->slices[i],
+ handshaker->args->read_buffer->slices[i],
&body_start_offset);
- if (error != GRPC_ERROR_NONE) goto done;
+ if (error != GRPC_ERROR_NONE) {
+ handshake_failed_locked(exec_ctx, handshaker, error);
+ goto done;
+ }
if (handshaker->http_parser.state == GRPC_HTTP_BODY) {
- // We've gotten back a successul response, so stop the timeout timer.
- grpc_timer_cancel(exec_ctx, &handshaker->timeout_timer);
// Remove the data we've already read from the read buffer,
// leaving only the leftover bytes (if any).
grpc_slice_buffer tmp_buffer;
grpc_slice_buffer_init(&tmp_buffer);
if (body_start_offset <
- GRPC_SLICE_LENGTH(handshaker->read_buffer->slices[i])) {
+ GRPC_SLICE_LENGTH(handshaker->args->read_buffer->slices[i])) {
grpc_slice_buffer_add(
&tmp_buffer,
- grpc_slice_split_tail(&handshaker->read_buffer->slices[i],
+ grpc_slice_split_tail(&handshaker->args->read_buffer->slices[i],
body_start_offset));
}
grpc_slice_buffer_addn(&tmp_buffer,
- &handshaker->read_buffer->slices[i + 1],
- handshaker->read_buffer->count - i - 1);
- grpc_slice_buffer_swap(handshaker->read_buffer, &tmp_buffer);
+ &handshaker->args->read_buffer->slices[i + 1],
+ handshaker->args->read_buffer->count - i - 1);
+ grpc_slice_buffer_swap(handshaker->args->read_buffer, &tmp_buffer);
grpc_slice_buffer_destroy(&tmp_buffer);
break;
}
@@ -159,9 +210,11 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
// complete (e.g., handling chunked transfer encoding or looking
// at the Content-Length: header).
if (handshaker->http_parser.state != GRPC_HTTP_BODY) {
- grpc_slice_buffer_reset_and_unref(handshaker->read_buffer);
- grpc_endpoint_read(exec_ctx, handshaker->endpoint, handshaker->read_buffer,
+ grpc_slice_buffer_reset_and_unref(handshaker->args->read_buffer);
+ grpc_endpoint_read(exec_ctx, handshaker->args->endpoint,
+ handshaker->args->read_buffer,
&handshaker->response_read_closure);
+ gpr_mu_unlock(&handshaker->mu);
return;
}
// Make sure we got a 2xx response.
@@ -172,11 +225,17 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
handshaker->http_response.status);
error = GRPC_ERROR_CREATE(msg);
gpr_free(msg);
+ handshake_failed_locked(exec_ctx, handshaker, error);
+ goto done;
}
+ // Success. Invoke handshake-done callback.
+ grpc_exec_ctx_sched(exec_ctx, handshaker->on_handshake_done, error, NULL);
done:
- // Invoke handshake-done callback.
- handshaker->cb(exec_ctx, handshaker->endpoint, handshaker->args,
- handshaker->read_buffer, handshaker->user_data, error);
+ // Set shutdown to true so that subsequent calls to
+ // http_connect_handshaker_shutdown() do nothing.
+ handshaker->shutdown = true;
+ gpr_mu_unlock(&handshaker->mu);
+ http_connect_handshaker_unref(exec_ctx, handshaker);
}
//
@@ -186,25 +245,30 @@ done:
static void http_connect_handshaker_destroy(grpc_exec_ctx* exec_ctx,
grpc_handshaker* handshaker_in) {
http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
- http_connect_handshaker_unref(handshaker);
+ http_connect_handshaker_unref(exec_ctx, handshaker);
}
static void http_connect_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
- grpc_handshaker* handshaker) {}
+ grpc_handshaker* handshaker_in) {
+ http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
+ gpr_mu_lock(&handshaker->mu);
+ if (!handshaker->shutdown) {
+ handshaker->shutdown = true;
+ grpc_endpoint_shutdown(exec_ctx, handshaker->args->endpoint);
+ cleanup_args_for_failure_locked(handshaker);
+ }
+ gpr_mu_unlock(&handshaker->mu);
+}
static void http_connect_handshaker_do_handshake(
grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker_in,
- grpc_endpoint* endpoint, grpc_channel_args* args,
- grpc_slice_buffer* read_buffer, gpr_timespec deadline,
- grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb,
- void* user_data) {
+ grpc_tcp_server_acceptor* acceptor, grpc_closure* on_handshake_done,
+ grpc_handshaker_args* args) {
http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
+ gpr_mu_lock(&handshaker->mu);
// Save state in the handshaker object.
- handshaker->endpoint = endpoint;
handshaker->args = args;
- handshaker->cb = cb;
- handshaker->user_data = user_data;
- handshaker->read_buffer = read_buffer;
+ handshaker->on_handshake_done = on_handshake_done;
// Send HTTP CONNECT request.
gpr_log(GPR_INFO, "Connecting to server %s via HTTP proxy %s",
handshaker->server_name, handshaker->proxy_server);
@@ -216,16 +280,14 @@ static void http_connect_handshaker_do_handshake(
request.handshaker = &grpc_httpcli_plaintext;
grpc_slice request_slice = grpc_httpcli_format_connect_request(&request);
grpc_slice_buffer_add(&handshaker->write_buffer, request_slice);
- grpc_endpoint_write(exec_ctx, endpoint, &handshaker->write_buffer,
- &handshaker->request_done_closure);
- // Set timeout timer. The timer gets a reference to the handshaker.
+ // Take a new ref to be held by the write callback.
gpr_ref(&handshaker->refcount);
- grpc_timer_init(exec_ctx, &handshaker->timeout_timer,
- gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
- on_timeout, handshaker, gpr_now(GPR_CLOCK_MONOTONIC));
+ grpc_endpoint_write(exec_ctx, args->endpoint, &handshaker->write_buffer,
+ &handshaker->request_done_closure);
+ gpr_mu_unlock(&handshaker->mu);
}
-static const struct grpc_handshaker_vtable http_connect_handshaker_vtable = {
+static const grpc_handshaker_vtable http_connect_handshaker_vtable = {
http_connect_handshaker_destroy, http_connect_handshaker_shutdown,
http_connect_handshaker_do_handshake};
@@ -233,10 +295,11 @@ grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server,
const char* server_name) {
GPR_ASSERT(proxy_server != NULL);
GPR_ASSERT(server_name != NULL);
- http_connect_handshaker* handshaker =
- gpr_malloc(sizeof(http_connect_handshaker));
+ http_connect_handshaker* handshaker = gpr_malloc(sizeof(*handshaker));
memset(handshaker, 0, sizeof(*handshaker));
grpc_handshaker_init(&http_connect_handshaker_vtable, &handshaker->base);
+ gpr_mu_init(&handshaker->mu);
+ gpr_ref_init(&handshaker->refcount, 1);
handshaker->proxy_server = gpr_strdup(proxy_server);
handshaker->server_name = gpr_strdup(server_name);
grpc_slice_buffer_init(&handshaker->write_buffer);
@@ -246,7 +309,6 @@ grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server,
handshaker);
grpc_http_parser_init(&handshaker->http_parser, GRPC_HTTP_RESPONSE,
&handshaker->http_response);
- gpr_ref_init(&handshaker->refcount, 1);
return &handshaker->base;
}
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index a148b2a0e1..08632079d6 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -119,9 +119,9 @@ struct grpc_subchannel {
gpr_mu mu;
/** have we seen a disconnection? */
- int disconnected;
+ bool disconnected;
/** are we connecting */
- int connecting;
+ bool connecting;
/** connectivity state tracking */
grpc_connectivity_state_tracker state_tracker;
@@ -132,7 +132,9 @@ struct grpc_subchannel {
/** backoff state */
gpr_backoff backoff_state;
/** do we have an active alarm? */
- int have_alarm;
+ bool have_alarm;
+ /** have we started the backoff loop */
+ bool backoff_begun;
/** our alarm */
grpc_timer alarm;
};
@@ -264,7 +266,7 @@ static void disconnect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
grpc_subchannel_index_unregister(exec_ctx, c->key, c);
gpr_mu_lock(&c->mu);
GPR_ASSERT(!c->disconnected);
- c->disconnected = 1;
+ c->disconnected = true;
grpc_connector_shutdown(exec_ctx, c->connector);
con = GET_CONNECTED_SUBCHANNEL(c, no_barrier);
if (con != NULL) {
@@ -334,16 +336,18 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
int initial_backoff_ms =
GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000;
int max_backoff_ms = GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS * 1000;
+ int min_backoff_ms = GRPC_SUBCHANNEL_MIN_CONNECT_TIMEOUT_SECONDS * 1000;
bool fixed_reconnect_backoff = false;
if (c->args) {
for (size_t i = 0; i < c->args->num_args; i++) {
if (0 == strcmp(c->args->args[i].key,
- "grpc.testing.fixed_reconnect_backoff")) {
+ "grpc.testing.fixed_reconnect_backoff_ms")) {
GPR_ASSERT(c->args->args[i].type == GRPC_ARG_INTEGER);
fixed_reconnect_backoff = true;
- initial_backoff_ms = max_backoff_ms = grpc_channel_arg_get_integer(
- &c->args->args[i],
- (grpc_integer_options){initial_backoff_ms, 100, INT_MAX});
+ initial_backoff_ms = min_backoff_ms = max_backoff_ms =
+ grpc_channel_arg_get_integer(
+ &c->args->args[i],
+ (grpc_integer_options){initial_backoff_ms, 100, INT_MAX});
} else if (0 == strcmp(c->args->args[i].key,
GRPC_ARG_MAX_RECONNECT_BACKOFF_MS)) {
fixed_reconnect_backoff = false;
@@ -360,17 +364,18 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
}
}
gpr_backoff_init(
- &c->backoff_state,
+ &c->backoff_state, initial_backoff_ms,
fixed_reconnect_backoff ? 1.0
: GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER,
fixed_reconnect_backoff ? 0.0 : GRPC_SUBCHANNEL_RECONNECT_JITTER,
- initial_backoff_ms, max_backoff_ms);
+ min_backoff_ms, max_backoff_ms);
gpr_mu_init(&c->mu);
return grpc_subchannel_index_register(exec_ctx, key, c);
}
-static void continue_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
+static void continue_connect_locked(grpc_exec_ctx *exec_ctx,
+ grpc_subchannel *c) {
grpc_connect_in_args args;
args.interested_parties = c->pollset_set;
@@ -386,12 +391,6 @@ static void continue_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
&c->connected);
}
-static void start_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
- c->next_attempt =
- gpr_backoff_begin(&c->backoff_state, gpr_now(GPR_CLOCK_MONOTONIC));
- continue_connect(exec_ctx, c);
-}
-
grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel *c,
grpc_error **error) {
grpc_connectivity_state state;
@@ -418,6 +417,73 @@ static void on_external_state_watcher_done(grpc_exec_ctx *exec_ctx, void *arg,
follow_up->cb(exec_ctx, follow_up->cb_arg, error);
}
+static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+ grpc_subchannel *c = arg;
+ gpr_mu_lock(&c->mu);
+ c->have_alarm = false;
+ if (c->disconnected) {
+ error = GRPC_ERROR_CREATE_REFERENCING("Disconnected", &error, 1);
+ } else {
+ GRPC_ERROR_REF(error);
+ }
+ if (error == GRPC_ERROR_NONE) {
+ gpr_log(GPR_INFO, "Failed to connect to channel, retrying");
+ c->next_attempt =
+ gpr_backoff_step(&c->backoff_state, gpr_now(GPR_CLOCK_MONOTONIC));
+ continue_connect_locked(exec_ctx, c);
+ gpr_mu_unlock(&c->mu);
+ } else {
+ gpr_mu_unlock(&c->mu);
+ GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
+ }
+ GRPC_ERROR_UNREF(error);
+}
+
+static void maybe_start_connecting_locked(grpc_exec_ctx *exec_ctx,
+ grpc_subchannel *c) {
+ if (c->disconnected) {
+ /* Don't try to connect if we're already disconnected */
+ return;
+ }
+
+ if (c->connecting) {
+ /* Already connecting: don't restart */
+ return;
+ }
+
+ if (GET_CONNECTED_SUBCHANNEL(c, no_barrier) != NULL) {
+ /* Already connected: don't restart */
+ return;
+ }
+
+ if (!grpc_connectivity_state_has_watchers(&c->state_tracker)) {
+ /* Nobody is interested in connecting: so don't just yet */
+ return;
+ }
+
+ c->connecting = true;
+ GRPC_SUBCHANNEL_WEAK_REF(c, "connecting");
+
+ gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
+ if (!c->backoff_begun) {
+ c->backoff_begun = true;
+ c->next_attempt = gpr_backoff_begin(&c->backoff_state, now);
+ continue_connect_locked(exec_ctx, c);
+ } else {
+ GPR_ASSERT(!c->have_alarm);
+ c->have_alarm = true;
+ gpr_timespec time_til_next = gpr_time_sub(c->next_attempt, now);
+ if (gpr_time_cmp(time_til_next, gpr_time_0(time_til_next.clock_type)) <=
+ 0) {
+ gpr_log(GPR_INFO, "Retry immediately");
+ } else {
+ gpr_log(GPR_INFO, "Retry in %" PRId64 ".%09d seconds",
+ time_til_next.tv_sec, time_til_next.tv_nsec);
+ }
+ grpc_timer_init(exec_ctx, &c->alarm, c->next_attempt, on_alarm, c, now);
+ }
+}
+
void grpc_subchannel_notify_on_state_change(
grpc_exec_ctx *exec_ctx, grpc_subchannel *c,
grpc_pollset_set *interested_parties, grpc_connectivity_state *state,
@@ -449,13 +515,9 @@ void grpc_subchannel_notify_on_state_change(
w->next = &c->root_external_state_watcher;
w->prev = w->next->prev;
w->next->prev = w->prev->next = w;
- if (grpc_connectivity_state_notify_on_state_change(
- exec_ctx, &c->state_tracker, state, &w->closure)) {
- c->connecting = 1;
- /* released by connection */
- GRPC_SUBCHANNEL_WEAK_REF(c, "connecting");
- start_connect(exec_ctx, c);
- }
+ grpc_connectivity_state_notify_on_state_change(exec_ctx, &c->state_tracker,
+ state, &w->closure);
+ maybe_start_connecting_locked(exec_ctx, c);
gpr_mu_unlock(&c->mu);
}
}
@@ -575,12 +637,9 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
Re-evaluate if we really need this. */
gpr_atm_full_barrier();
GPR_ASSERT(gpr_atm_rel_cas(&c->connected_subchannel, 0, (gpr_atm)con));
- c->connecting = 0;
/* setup subchannel watching connected subchannel for changes; subchannel
- ref
- for connecting is donated
- to the state watcher */
+ ref for connecting is donated to the state watcher */
GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
grpc_connected_subchannel_notify_on_state_change(
@@ -592,28 +651,6 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
GRPC_ERROR_NONE, "connected");
}
-static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
- grpc_subchannel *c = arg;
- gpr_mu_lock(&c->mu);
- c->have_alarm = 0;
- if (c->disconnected) {
- error = GRPC_ERROR_CREATE_REFERENCING("Disconnected", &error, 1);
- } else {
- GRPC_ERROR_REF(error);
- }
- if (error == GRPC_ERROR_NONE) {
- gpr_log(GPR_INFO, "Failed to connect to channel, retrying");
- c->next_attempt =
- gpr_backoff_step(&c->backoff_state, gpr_now(GPR_CLOCK_MONOTONIC));
- continue_connect(exec_ctx, c);
- gpr_mu_unlock(&c->mu);
- } else {
- gpr_mu_unlock(&c->mu);
- GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
- }
- GRPC_ERROR_UNREF(error);
-}
-
static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
grpc_subchannel *c = arg;
@@ -621,35 +658,28 @@ static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg,
GRPC_SUBCHANNEL_WEAK_REF(c, "connected");
gpr_mu_lock(&c->mu);
+ c->connecting = false;
if (c->connecting_result.transport != NULL) {
publish_transport_locked(exec_ctx, c);
} else if (c->disconnected) {
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
} else {
- gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
- GPR_ASSERT(!c->have_alarm);
- c->have_alarm = 1;
grpc_connectivity_state_set(
exec_ctx, &c->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
grpc_error_set_int(
GRPC_ERROR_CREATE_REFERENCING("Connect Failed", &error, 1),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
"connect_failed");
- gpr_timespec time_til_next = gpr_time_sub(c->next_attempt, now);
+
const char *errmsg = grpc_error_string(error);
gpr_log(GPR_INFO, "Connect failed: %s", errmsg);
- if (gpr_time_cmp(time_til_next, gpr_time_0(time_til_next.clock_type)) <=
- 0) {
- gpr_log(GPR_INFO, "Retry immediately");
- } else {
- gpr_log(GPR_INFO, "Retry in %" PRId64 ".%09d seconds",
- time_til_next.tv_sec, time_til_next.tv_nsec);
- }
- grpc_timer_init(exec_ctx, &c->alarm, c->next_attempt, on_alarm, c, now);
grpc_error_free_string(errmsg);
+
+ maybe_start_connecting_locked(exec_ctx, c);
+ GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
}
gpr_mu_unlock(&c->mu);
- GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
+ GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connected");
grpc_channel_args_destroy(delete_channel_args);
}
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index 4262d2b9a4..df0db61c22 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -123,10 +123,11 @@
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/transport/static_metadata.h"
-#define BACKOFF_MULTIPLIER 1.6
-#define BACKOFF_JITTER 0.2
-#define BACKOFF_MIN_SECONDS 10
-#define BACKOFF_MAX_SECONDS 60
+#define GRPC_GRPCLB_MIN_CONNECT_TIMEOUT_SECONDS 20
+#define GRPC_GRPCLB_INITIAL_CONNECT_BACKOFF_SECONDS 1
+#define GRPC_GRPCLB_RECONNECT_BACKOFF_MULTIPLIER 1.6
+#define GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS 120
+#define GRPC_GRPCLB_RECONNECT_JITTER 0.2
int grpc_lb_glb_trace = 0;
@@ -1107,9 +1108,12 @@ static void lb_call_init_locked(glb_lb_policy *glb_policy) {
grpc_closure_init(&glb_policy->lb_on_response_received,
lb_on_response_received, glb_policy);
- gpr_backoff_init(&glb_policy->lb_call_backoff_state, BACKOFF_MULTIPLIER,
- BACKOFF_JITTER, BACKOFF_MIN_SECONDS * 1000,
- BACKOFF_MAX_SECONDS * 1000);
+ gpr_backoff_init(&glb_policy->lb_call_backoff_state,
+ GRPC_GRPCLB_INITIAL_CONNECT_BACKOFF_SECONDS,
+ GRPC_GRPCLB_RECONNECT_BACKOFF_MULTIPLIER,
+ GRPC_GRPCLB_RECONNECT_JITTER,
+ GRPC_GRPCLB_MIN_CONNECT_TIMEOUT_SECONDS * 1000,
+ GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
}
static void lb_call_destroy_locked(glb_lb_policy *glb_policy) {
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 665439f360..15476f5792 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -46,10 +46,11 @@
#include "src/core/lib/support/backoff.h"
#include "src/core/lib/support/string.h"
-#define BACKOFF_MULTIPLIER 1.6
-#define BACKOFF_JITTER 0.2
-#define BACKOFF_MIN_SECONDS 1
-#define BACKOFF_MAX_SECONDS 120
+#define GRPC_DNS_MIN_CONNECT_TIMEOUT_SECONDS 1
+#define GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS 1
+#define GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER 1.6
+#define GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS 120
+#define GRPC_DNS_RECONNECT_JITTER 0.2
typedef struct {
/** base class: must be first */
@@ -269,8 +270,11 @@ static grpc_resolver *dns_create(grpc_resolver_args *args,
server_name_arg.value.string = (char *)path;
r->channel_args =
grpc_channel_args_copy_and_add(args->args, &server_name_arg, 1);
- gpr_backoff_init(&r->backoff_state, BACKOFF_MULTIPLIER, BACKOFF_JITTER,
- BACKOFF_MIN_SECONDS * 1000, BACKOFF_MAX_SECONDS * 1000);
+ gpr_backoff_init(&r->backoff_state, GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS,
+ GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER,
+ GRPC_DNS_RECONNECT_JITTER,
+ GRPC_DNS_MIN_CONNECT_TIMEOUT_SECONDS * 1000,
+ GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
return &r->base;
}
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.c b/src/core/ext/transport/chttp2/client/chttp2_connector.c
new file mode 100644
index 0000000000..213395c20f
--- /dev/null
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.c
@@ -0,0 +1,261 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
+
+#include <grpc/grpc.h>
+
+#include <string.h>
+
+#include <grpc/slice_buffer.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/ext/client_channel/connector.h"
+#include "src/core/ext/client_channel/http_connect_handshaker.h"
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/iomgr/tcp_client.h"
+#include "src/core/lib/security/transport/security_connector.h"
+
+typedef struct {
+ grpc_connector base;
+
+ gpr_mu mu;
+ gpr_refcount refs;
+
+ bool shutdown;
+
+ char *server_name;
+ grpc_chttp2_create_handshakers_func create_handshakers;
+ void *create_handshakers_user_data;
+
+ grpc_closure *notify;
+ grpc_connect_in_args args;
+ grpc_connect_out_args *result;
+ grpc_closure initial_string_sent;
+ grpc_slice_buffer initial_string_buffer;
+
+ grpc_endpoint *endpoint; // Non-NULL until handshaking starts.
+
+ grpc_closure connected;
+
+ grpc_handshake_manager *handshake_mgr;
+} chttp2_connector;
+
+static void chttp2_connector_ref(grpc_connector *con) {
+ chttp2_connector *c = (chttp2_connector *)con;
+ gpr_ref(&c->refs);
+}
+
+static void chttp2_connector_unref(grpc_exec_ctx *exec_ctx,
+ grpc_connector *con) {
+ chttp2_connector *c = (chttp2_connector *)con;
+ if (gpr_unref(&c->refs)) {
+ /* c->initial_string_buffer does not need to be destroyed */
+ gpr_mu_destroy(&c->mu);
+ // If handshaking is not yet in progress, destroy the endpoint.
+ // Otherwise, the handshaker will do this for us.
+ if (c->endpoint != NULL) grpc_endpoint_destroy(exec_ctx, c->endpoint);
+ gpr_free(c->server_name);
+ gpr_free(c);
+ }
+}
+
+static void chttp2_connector_shutdown(grpc_exec_ctx *exec_ctx,
+ grpc_connector *con) {
+ chttp2_connector *c = (chttp2_connector *)con;
+ gpr_mu_lock(&c->mu);
+ c->shutdown = true;
+ if (c->handshake_mgr != NULL) {
+ grpc_handshake_manager_shutdown(exec_ctx, c->handshake_mgr);
+ }
+ // If handshaking is not yet in progress, shutdown the endpoint.
+ // Otherwise, the handshaker will do this for us.
+ if (c->endpoint != NULL) grpc_endpoint_shutdown(exec_ctx, c->endpoint);
+ gpr_mu_unlock(&c->mu);
+}
+
+static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ grpc_handshaker_args *args = arg;
+ chttp2_connector *c = args->user_data;
+ gpr_mu_lock(&c->mu);
+ if (error != GRPC_ERROR_NONE || c->shutdown) {
+ if (error == GRPC_ERROR_NONE) {
+ error = GRPC_ERROR_CREATE("connector shutdown");
+ // We were shut down after handshaking completed successfully, so
+ // destroy the endpoint here.
+ // TODO(ctiller): It is currently necessary to shutdown endpoints
+ // before destroying them, even if we know that there are no
+ // pending read/write callbacks. This should be fixed, at which
+ // point this can be removed.
+ grpc_endpoint_shutdown(exec_ctx, args->endpoint);
+ grpc_endpoint_destroy(exec_ctx, args->endpoint);
+ grpc_channel_args_destroy(args->args);
+ grpc_slice_buffer_destroy(args->read_buffer);
+ gpr_free(args->read_buffer);
+ } else {
+ error = GRPC_ERROR_REF(error);
+ }
+ memset(c->result, 0, sizeof(*c->result));
+ } else {
+ c->result->transport =
+ grpc_create_chttp2_transport(exec_ctx, args->args, args->endpoint, 1);
+ GPR_ASSERT(c->result->transport);
+ grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport,
+ args->read_buffer);
+ c->result->channel_args = args->args;
+ }
+ grpc_closure *notify = c->notify;
+ c->notify = NULL;
+ grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
+ grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr);
+ c->handshake_mgr = NULL;
+ gpr_mu_unlock(&c->mu);
+ chttp2_connector_unref(exec_ctx, (grpc_connector *)c);
+}
+
+static void start_handshake_locked(grpc_exec_ctx *exec_ctx,
+ chttp2_connector *c) {
+ c->handshake_mgr = grpc_handshake_manager_create();
+ char *proxy_name = grpc_get_http_proxy_server();
+ if (proxy_name != NULL) {
+ grpc_handshake_manager_add(
+ c->handshake_mgr,
+ grpc_http_connect_handshaker_create(proxy_name, c->server_name));
+ gpr_free(proxy_name);
+ }
+ if (c->create_handshakers != NULL) {
+ c->create_handshakers(exec_ctx, c->create_handshakers_user_data,
+ c->handshake_mgr);
+ }
+ grpc_handshake_manager_do_handshake(
+ exec_ctx, c->handshake_mgr, c->endpoint, c->args.channel_args,
+ c->args.deadline, NULL /* acceptor */, on_handshake_done, c);
+ c->endpoint = NULL; // Endpoint handed off to handshake manager.
+}
+
+static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ chttp2_connector *c = arg;
+ gpr_mu_lock(&c->mu);
+ if (error != GRPC_ERROR_NONE || c->shutdown) {
+ if (error == GRPC_ERROR_NONE) {
+ error = GRPC_ERROR_CREATE("connector shutdown");
+ } else {
+ error = GRPC_ERROR_REF(error);
+ }
+ memset(c->result, 0, sizeof(*c->result));
+ grpc_closure *notify = c->notify;
+ c->notify = NULL;
+ grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
+ gpr_mu_unlock(&c->mu);
+ chttp2_connector_unref(exec_ctx, arg);
+ } else {
+ start_handshake_locked(exec_ctx, c);
+ gpr_mu_unlock(&c->mu);
+ }
+}
+
+static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+ chttp2_connector *c = arg;
+ gpr_mu_lock(&c->mu);
+ if (error != GRPC_ERROR_NONE || c->shutdown) {
+ if (error == GRPC_ERROR_NONE) {
+ error = GRPC_ERROR_CREATE("connector shutdown");
+ } else {
+ error = GRPC_ERROR_REF(error);
+ }
+ memset(c->result, 0, sizeof(*c->result));
+ grpc_closure *notify = c->notify;
+ c->notify = NULL;
+ grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
+ gpr_mu_unlock(&c->mu);
+ chttp2_connector_unref(exec_ctx, arg);
+ } else {
+ GPR_ASSERT(c->endpoint != NULL);
+ if (!GRPC_SLICE_IS_EMPTY(c->args.initial_connect_string)) {
+ grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent,
+ c);
+ grpc_slice_buffer_init(&c->initial_string_buffer);
+ grpc_slice_buffer_add(&c->initial_string_buffer,
+ c->args.initial_connect_string);
+ grpc_endpoint_write(exec_ctx, c->endpoint, &c->initial_string_buffer,
+ &c->initial_string_sent);
+ } else {
+ start_handshake_locked(exec_ctx, c);
+ }
+ gpr_mu_unlock(&c->mu);
+ }
+}
+
+static void chttp2_connector_connect(grpc_exec_ctx *exec_ctx,
+ grpc_connector *con,
+ const grpc_connect_in_args *args,
+ grpc_connect_out_args *result,
+ grpc_closure *notify) {
+ chttp2_connector *c = (chttp2_connector *)con;
+ gpr_mu_lock(&c->mu);
+ GPR_ASSERT(c->notify == NULL);
+ c->notify = notify;
+ c->args = *args;
+ c->result = result;
+ GPR_ASSERT(c->endpoint == NULL);
+ chttp2_connector_ref(con); // Ref taken for callback.
+ grpc_closure_init(&c->connected, connected, c);
+ grpc_tcp_client_connect(exec_ctx, &c->connected, &c->endpoint,
+ args->interested_parties, args->channel_args,
+ args->addr, args->deadline);
+ gpr_mu_unlock(&c->mu);
+}
+
+static const grpc_connector_vtable chttp2_connector_vtable = {
+ chttp2_connector_ref, chttp2_connector_unref, chttp2_connector_shutdown,
+ chttp2_connector_connect};
+
+grpc_connector *grpc_chttp2_connector_create(
+ grpc_exec_ctx *exec_ctx, const char *server_name,
+ grpc_chttp2_create_handshakers_func create_handshakers,
+ void *create_handshakers_user_data) {
+ chttp2_connector *c = gpr_malloc(sizeof(*c));
+ memset(c, 0, sizeof(*c));
+ c->base.vtable = &chttp2_connector_vtable;
+ gpr_mu_init(&c->mu);
+ gpr_ref_init(&c->refs, 1);
+ c->server_name = gpr_strdup(server_name);
+ c->create_handshakers = create_handshakers;
+ c->create_handshakers_user_data = create_handshakers_user_data;
+ return &c->base;
+}
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.h b/src/core/ext/transport/chttp2/client/chttp2_connector.h
new file mode 100644
index 0000000000..6c34ce1af1
--- /dev/null
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H
+
+#include "src/core/ext/client_channel/connector.h"
+#include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+
+typedef void (*grpc_chttp2_create_handshakers_func)(
+ grpc_exec_ctx* exec_ctx, void* user_data,
+ grpc_handshake_manager* handshake_mgr);
+
+/// If \a create_handshakers is non-NULL, it will be called with
+/// \a create_handshakers_user_data to add handshakers.
+grpc_connector* grpc_chttp2_connector_create(
+ grpc_exec_ctx* exec_ctx, const char* server_name,
+ grpc_chttp2_create_handshakers_func create_handshakers,
+ void* create_handshakers_user_data);
+
+#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H */
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 8e03fd82c1..29f3759d00 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -33,138 +33,17 @@
#include <grpc/grpc.h>
-#include <stdlib.h>
#include <string.h>
-#include <grpc/slice.h>
-#include <grpc/slice_buffer.h>
#include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/http_connect_handshaker.h"
#include "src/core/ext/client_channel/resolver_registry.h"
-#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/compress_filter.h"
-#include "src/core/lib/channel/handshaker.h"
-#include "src/core/lib/channel/http_client_filter.h"
-#include "src/core/lib/iomgr/tcp_client.h"
+#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/channel.h"
-//
-// connector
-//
-
-typedef struct {
- grpc_connector base;
- gpr_refcount refs;
-
- grpc_closure *notify;
- grpc_connect_in_args args;
- grpc_connect_out_args *result;
- grpc_closure initial_string_sent;
- grpc_slice_buffer initial_string_buffer;
-
- grpc_endpoint *tcp;
-
- grpc_closure connected;
-
- grpc_handshake_manager *handshake_mgr;
-} connector;
-
-static void connector_ref(grpc_connector *con) {
- connector *c = (connector *)con;
- gpr_ref(&c->refs);
-}
-
-static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) {
- connector *c = (connector *)con;
- if (gpr_unref(&c->refs)) {
- /* c->initial_string_buffer does not need to be destroyed */
- grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr);
- gpr_free(c);
- }
-}
-
-static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error) {
- connector_unref(exec_ctx, arg);
-}
-
-static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
- grpc_channel_args *args,
- grpc_slice_buffer *read_buffer, void *user_data,
- grpc_error *error) {
- connector *c = user_data;
- if (error != GRPC_ERROR_NONE) {
- grpc_channel_args_destroy(args);
- gpr_free(read_buffer);
- } else {
- c->result->transport =
- grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1);
- GPR_ASSERT(c->result->transport);
- grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport,
- read_buffer);
- c->result->channel_args = args;
- }
- grpc_closure *notify = c->notify;
- c->notify = NULL;
- grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
-}
-
-static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
- connector *c = arg;
- grpc_endpoint *tcp = c->tcp;
- if (tcp != NULL) {
- if (!GRPC_SLICE_IS_EMPTY(c->args.initial_connect_string)) {
- grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent,
- c);
- grpc_slice_buffer_init(&c->initial_string_buffer);
- grpc_slice_buffer_add(&c->initial_string_buffer,
- c->args.initial_connect_string);
- connector_ref(arg);
- grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer,
- &c->initial_string_sent);
- } else {
- grpc_handshake_manager_do_handshake(
- exec_ctx, c->handshake_mgr, tcp, c->args.channel_args,
- c->args.deadline, NULL /* acceptor */, on_handshake_done, c);
- }
- } else {
- memset(c->result, 0, sizeof(*c->result));
- grpc_closure *notify = c->notify;
- c->notify = NULL;
- grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL);
- }
-}
-
-static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) {}
-
-static void connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *con,
- const grpc_connect_in_args *args,
- grpc_connect_out_args *result,
- grpc_closure *notify) {
- connector *c = (connector *)con;
- GPR_ASSERT(c->notify == NULL);
- GPR_ASSERT(notify->cb);
- c->notify = notify;
- c->args = *args;
- c->result = result;
- c->tcp = NULL;
- grpc_closure_init(&c->connected, connected, c);
- grpc_tcp_client_connect(exec_ctx, &c->connected, &c->tcp,
- args->interested_parties, args->channel_args,
- args->addr, args->deadline);
-}
-
-static const grpc_connector_vtable connector_vtable = {
- connector_ref, connector_unref, connector_shutdown, connector_connect};
-
-//
-// client_channel_factory
-//
-
static void client_channel_factory_ref(
grpc_client_channel_factory *cc_factory) {}
@@ -174,20 +53,11 @@ static void client_channel_factory_unref(
static grpc_subchannel *client_channel_factory_create_subchannel(
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
const grpc_subchannel_args *args) {
- connector *c = gpr_malloc(sizeof(*c));
- memset(c, 0, sizeof(*c));
- c->base.vtable = &connector_vtable;
- gpr_ref_init(&c->refs, 1);
- c->handshake_mgr = grpc_handshake_manager_create();
- char *proxy_name = grpc_get_http_proxy_server();
- if (proxy_name != NULL) {
- grpc_handshake_manager_add(
- c->handshake_mgr,
- grpc_http_connect_handshaker_create(proxy_name, args->server_name));
- gpr_free(proxy_name);
- }
- grpc_subchannel *s = grpc_subchannel_create(exec_ctx, &c->base, args);
- grpc_connector_unref(exec_ctx, &c->base);
+ grpc_connector *connector = grpc_chttp2_connector_create(
+ exec_ctx, args->server_name, NULL /* create_handshakers */,
+ NULL /* user_data */);
+ grpc_subchannel *s = grpc_subchannel_create(exec_ctx, connector, args);
+ grpc_connector_unref(exec_ctx, connector);
return s;
}
@@ -198,16 +68,14 @@ static grpc_channel *client_channel_factory_create_channel(
grpc_channel *channel =
grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
grpc_resolver *resolver = grpc_resolver_create(target, args);
- if (!resolver) {
+ if (resolver == NULL) {
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
"client_channel_factory_create_channel");
return NULL;
}
-
grpc_client_channel_finish_initialization(
exec_ctx, grpc_channel_get_channel_stack(channel), resolver, cc_factory);
GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create_channel");
-
return channel;
}
@@ -230,16 +98,13 @@ grpc_channel *grpc_insecure_channel_create(const char *target,
GRPC_API_TRACE(
"grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3,
(target, args, reserved));
- GPR_ASSERT(!reserved);
-
+ GPR_ASSERT(reserved == NULL);
grpc_client_channel_factory *factory =
(grpc_client_channel_factory *)&client_channel_factory;
grpc_channel *channel = client_channel_factory_create_channel(
&exec_ctx, factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, args);
-
grpc_client_channel_factory_unref(&exec_ctx, factory);
grpc_exec_ctx_finish(&exec_ctx);
-
return channel != NULL ? channel : grpc_lame_client_channel_create(
target, GRPC_STATUS_INTERNAL,
"Failed to create client channel");
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 04c88a2d36..35e1e1f716 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -33,196 +33,19 @@
#include <grpc/grpc.h>
-#include <stdlib.h>
#include <string.h>
-#include <grpc/slice.h>
-#include <grpc/slice_buffer.h>
#include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/http_connect_handshaker.h"
#include "src/core/ext/client_channel/resolver_registry.h"
-#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/handshaker.h"
-#include "src/core/lib/iomgr/tcp_client.h"
-#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/security/transport/auth_filters.h"
+#include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/channel.h"
-#include "src/core/lib/tsi/transport_security_interface.h"
-
-//
-// connector
-//
-
-typedef struct {
- grpc_connector base;
- gpr_refcount refs;
-
- grpc_channel_security_connector *security_connector;
-
- grpc_closure *notify;
- grpc_connect_in_args args;
- grpc_connect_out_args *result;
- grpc_closure initial_string_sent;
- grpc_slice_buffer initial_string_buffer;
-
- gpr_mu mu;
- grpc_endpoint *connecting_endpoint;
- grpc_endpoint *newly_connecting_endpoint;
-
- grpc_closure connected_closure;
-
- grpc_handshake_manager *handshake_mgr;
-
- // TODO(roth): Remove once we eliminate on_secure_handshake_done().
- grpc_channel_args *tmp_args;
-} connector;
-
-static void connector_ref(grpc_connector *con) {
- connector *c = (connector *)con;
- gpr_ref(&c->refs);
-}
-
-static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) {
- connector *c = (connector *)con;
- if (gpr_unref(&c->refs)) {
- /* c->initial_string_buffer does not need to be destroyed */
- grpc_channel_args_destroy(c->tmp_args);
- grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr);
- gpr_free(c);
- }
-}
-
-static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_security_status status,
- grpc_endpoint *secure_endpoint,
- grpc_auth_context *auth_context) {
- connector *c = arg;
- gpr_mu_lock(&c->mu);
- grpc_error *error = GRPC_ERROR_NONE;
- if (c->connecting_endpoint == NULL) {
- memset(c->result, 0, sizeof(*c->result));
- gpr_mu_unlock(&c->mu);
- } else if (status != GRPC_SECURITY_OK) {
- error = grpc_error_set_int(GRPC_ERROR_CREATE("Secure handshake failed"),
- GRPC_ERROR_INT_SECURITY_STATUS, status);
- memset(c->result, 0, sizeof(*c->result));
- c->connecting_endpoint = NULL;
- gpr_mu_unlock(&c->mu);
- } else {
- grpc_arg auth_context_arg;
- c->connecting_endpoint = NULL;
- gpr_mu_unlock(&c->mu);
- c->result->transport = grpc_create_chttp2_transport(
- exec_ctx, c->args.channel_args, secure_endpoint, 1);
- grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL);
- auth_context_arg = grpc_auth_context_to_arg(auth_context);
- c->result->channel_args =
- grpc_channel_args_copy_and_add(c->tmp_args, &auth_context_arg, 1);
- }
- grpc_closure *notify = c->notify;
- c->notify = NULL;
- grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
-}
-
-static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
- grpc_channel_args *args,
- grpc_slice_buffer *read_buffer, void *user_data,
- grpc_error *error) {
- connector *c = user_data;
- c->tmp_args = args;
- if (error != GRPC_ERROR_NONE) {
- gpr_free(read_buffer);
- grpc_closure *notify = c->notify;
- c->notify = NULL;
- grpc_exec_ctx_sched(exec_ctx, notify, error, NULL);
- } else {
- // TODO(roth, jboeuf): Convert security connector handshaking to use new
- // handshake API, and then move the code from on_secure_handshake_done()
- // into this function.
- grpc_channel_security_connector_do_handshake(
- exec_ctx, c->security_connector, endpoint, read_buffer,
- c->args.deadline, on_secure_handshake_done, c);
- }
-}
-
-static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error) {
- connector *c = arg;
- grpc_handshake_manager_do_handshake(
- exec_ctx, c->handshake_mgr, c->connecting_endpoint, c->args.channel_args,
- c->args.deadline, NULL /* acceptor */, on_handshake_done, c);
-}
-
-static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
- connector *c = arg;
- grpc_endpoint *tcp = c->newly_connecting_endpoint;
- if (tcp != NULL) {
- gpr_mu_lock(&c->mu);
- GPR_ASSERT(c->connecting_endpoint == NULL);
- c->connecting_endpoint = tcp;
- gpr_mu_unlock(&c->mu);
- if (!GRPC_SLICE_IS_EMPTY(c->args.initial_connect_string)) {
- grpc_closure_init(&c->initial_string_sent, on_initial_connect_string_sent,
- c);
- grpc_slice_buffer_init(&c->initial_string_buffer);
- grpc_slice_buffer_add(&c->initial_string_buffer,
- c->args.initial_connect_string);
- grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer,
- &c->initial_string_sent);
- } else {
- grpc_handshake_manager_do_handshake(
- exec_ctx, c->handshake_mgr, tcp, c->args.channel_args,
- c->args.deadline, NULL /* acceptor */, on_handshake_done, c);
- }
- } else {
- memset(c->result, 0, sizeof(*c->result));
- grpc_closure *notify = c->notify;
- c->notify = NULL;
- grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL);
- }
-}
-
-static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) {
- connector *c = (connector *)con;
- grpc_endpoint *ep;
- gpr_mu_lock(&c->mu);
- ep = c->connecting_endpoint;
- c->connecting_endpoint = NULL;
- gpr_mu_unlock(&c->mu);
- if (ep) {
- grpc_endpoint_shutdown(exec_ctx, ep);
- }
-}
-
-static void connector_connect(grpc_exec_ctx *exec_ctx, grpc_connector *con,
- const grpc_connect_in_args *args,
- grpc_connect_out_args *result,
- grpc_closure *notify) {
- connector *c = (connector *)con;
- GPR_ASSERT(c->notify == NULL);
- c->notify = notify;
- c->args = *args;
- c->result = result;
- gpr_mu_lock(&c->mu);
- GPR_ASSERT(c->connecting_endpoint == NULL);
- gpr_mu_unlock(&c->mu);
- grpc_closure_init(&c->connected_closure, connected, c);
- grpc_tcp_client_connect(
- exec_ctx, &c->connected_closure, &c->newly_connecting_endpoint,
- args->interested_parties, args->channel_args, args->addr, args->deadline);
-}
-
-static const grpc_connector_vtable connector_vtable = {
- connector_ref, connector_unref, connector_shutdown, connector_connect};
-
-//
-// client_channel_factory
-//
typedef struct {
grpc_client_channel_factory base;
@@ -246,26 +69,21 @@ static void client_channel_factory_unref(
}
}
+static void create_handshakers(grpc_exec_ctx *exec_ctx,
+ void *security_connector,
+ grpc_handshake_manager *handshake_mgr) {
+ grpc_channel_security_connector_create_handshakers(
+ exec_ctx, security_connector, handshake_mgr);
+}
+
static grpc_subchannel *client_channel_factory_create_subchannel(
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
const grpc_subchannel_args *args) {
client_channel_factory *f = (client_channel_factory *)cc_factory;
- connector *c = gpr_malloc(sizeof(*c));
- memset(c, 0, sizeof(*c));
- c->base.vtable = &connector_vtable;
- c->security_connector = f->security_connector;
- c->handshake_mgr = grpc_handshake_manager_create();
- char *proxy_name = grpc_get_http_proxy_server();
- if (proxy_name != NULL) {
- grpc_handshake_manager_add(
- c->handshake_mgr,
- grpc_http_connect_handshaker_create(proxy_name, args->server_name));
- gpr_free(proxy_name);
- }
- gpr_mu_init(&c->mu);
- gpr_ref_init(&c->refs, 1);
- grpc_subchannel *s = grpc_subchannel_create(exec_ctx, &c->base, args);
- grpc_connector_unref(exec_ctx, &c->base);
+ grpc_connector *connector = grpc_chttp2_connector_create(
+ exec_ctx, args->server_name, create_handshakers, f->security_connector);
+ grpc_subchannel *s = grpc_subchannel_create(exec_ctx, connector, args);
+ grpc_connector_unref(exec_ctx, connector);
return s;
}
@@ -277,15 +95,14 @@ static grpc_channel *client_channel_factory_create_channel(
grpc_channel *channel =
grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
grpc_resolver *resolver = grpc_resolver_create(target, args);
- if (resolver != NULL) {
- grpc_client_channel_finish_initialization(
- exec_ctx, grpc_channel_get_channel_stack(channel), resolver, &f->base);
- GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create");
- } else {
+ if (resolver == NULL) {
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
"client_channel_factory_create_channel");
- channel = NULL;
+ return NULL;
}
+ grpc_client_channel_finish_initialization(
+ exec_ctx, grpc_channel_get_channel_stack(channel), resolver, &f->base);
+ GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create_channel");
return channel;
}
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.c b/src/core/ext/transport/chttp2/server/chttp2_server.c
new file mode 100644
index 0000000000..7795606e73
--- /dev/null
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.c
@@ -0,0 +1,356 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/ext/transport/chttp2/server/chttp2_server.h"
+
+#include <grpc/grpc.h>
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/channel/http_server_filter.h"
+#include "src/core/lib/iomgr/endpoint.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/iomgr/tcp_server.h"
+#include "src/core/lib/surface/api_trace.h"
+#include "src/core/lib/surface/server.h"
+
+void grpc_chttp2_server_handshaker_factory_create_handshakers(
+ grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_server_handshaker_factory *handshaker_factory,
+ grpc_handshake_manager *handshake_mgr) {
+ if (handshaker_factory != NULL) {
+ handshaker_factory->vtable->create_handshakers(
+ exec_ctx, handshaker_factory, handshake_mgr);
+ }
+}
+
+void grpc_chttp2_server_handshaker_factory_destroy(
+ grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_server_handshaker_factory *handshaker_factory) {
+ if (handshaker_factory != NULL) {
+ handshaker_factory->vtable->destroy(exec_ctx, handshaker_factory);
+ }
+}
+
+
+typedef struct pending_handshake_manager_node {
+ grpc_handshake_manager *handshake_mgr;
+ struct pending_handshake_manager_node *next;
+} pending_handshake_manager_node;
+
+typedef struct {
+ grpc_server *server;
+ grpc_tcp_server *tcp_server;
+ grpc_channel_args *args;
+ grpc_chttp2_server_handshaker_factory *handshaker_factory;
+ gpr_mu mu;
+ bool shutdown;
+ grpc_closure tcp_server_shutdown_complete;
+ grpc_closure *server_destroy_listener_done;
+ pending_handshake_manager_node *pending_handshake_mgrs;
+} server_state;
+
+typedef struct {
+ server_state *server_state;
+ grpc_pollset *accepting_pollset;
+ grpc_tcp_server_acceptor *acceptor;
+ grpc_handshake_manager *handshake_mgr;
+} server_connection_state;
+
+static void pending_handshake_manager_add_locked(
+ server_state *state, grpc_handshake_manager *handshake_mgr) {
+ pending_handshake_manager_node *node = gpr_malloc(sizeof(*node));
+ node->handshake_mgr = handshake_mgr;
+ node->next = state->pending_handshake_mgrs;
+ state->pending_handshake_mgrs = node;
+}
+
+static void pending_handshake_manager_remove_locked(
+ server_state *state, grpc_handshake_manager *handshake_mgr) {
+ pending_handshake_manager_node **prev_node = &state->pending_handshake_mgrs;
+ for (pending_handshake_manager_node *node = state->pending_handshake_mgrs;
+ node != NULL; node = node->next) {
+ if (node->handshake_mgr == handshake_mgr) {
+ *prev_node = node->next;
+ gpr_free(node);
+ break;
+ }
+ prev_node = &node->next;
+ }
+}
+
+static void pending_handshake_manager_shutdown_locked(grpc_exec_ctx *exec_ctx,
+ server_state *state) {
+ pending_handshake_manager_node *prev_node = NULL;
+ for (pending_handshake_manager_node *node = state->pending_handshake_mgrs;
+ node != NULL; node = node->next) {
+ grpc_handshake_manager_shutdown(exec_ctx, node->handshake_mgr);
+ gpr_free(prev_node);
+ prev_node = node;
+ }
+ gpr_free(prev_node);
+ state->pending_handshake_mgrs = NULL;
+}
+
+static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ grpc_handshaker_args *args = arg;
+ server_connection_state *connection_state = args->user_data;
+ gpr_mu_lock(&connection_state->server_state->mu);
+ if (error != GRPC_ERROR_NONE || connection_state->server_state->shutdown) {
+ const char *error_str = grpc_error_string(error);
+ gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
+ grpc_error_free_string(error_str);
+ if (error == GRPC_ERROR_NONE) {
+ // We were shut down after handshaking completed successfully, so
+ // destroy the endpoint here.
+ // TODO(ctiller): It is currently necessary to shutdown endpoints
+ // before destroying them, even if we know that there are no
+ // pending read/write callbacks. This should be fixed, at which
+ // point this can be removed.
+ grpc_endpoint_shutdown(exec_ctx, args->endpoint);
+ grpc_endpoint_destroy(exec_ctx, args->endpoint);
+ grpc_channel_args_destroy(args->args);
+ grpc_slice_buffer_destroy(args->read_buffer);
+ gpr_free(args->read_buffer);
+ }
+ } else {
+ grpc_transport *transport =
+ grpc_create_chttp2_transport(exec_ctx, args->args, args->endpoint, 0);
+ grpc_server_setup_transport(
+ exec_ctx, connection_state->server_state->server, transport,
+ connection_state->accepting_pollset, args->args);
+ grpc_chttp2_transport_start_reading(exec_ctx, transport, args->read_buffer);
+ grpc_channel_args_destroy(args->args);
+ }
+ pending_handshake_manager_remove_locked(connection_state->server_state,
+ connection_state->handshake_mgr);
+ gpr_mu_unlock(&connection_state->server_state->mu);
+ grpc_handshake_manager_destroy(exec_ctx, connection_state->handshake_mgr);
+ grpc_tcp_server_unref(exec_ctx, connection_state->server_state->tcp_server);
+ gpr_free(connection_state);
+}
+
+static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp,
+ grpc_pollset *accepting_pollset,
+ grpc_tcp_server_acceptor *acceptor) {
+ server_state *state = arg;
+ gpr_mu_lock(&state->mu);
+ if (state->shutdown) {
+ gpr_mu_unlock(&state->mu);
+ grpc_endpoint_destroy(exec_ctx, tcp);
+ return;
+ }
+ grpc_handshake_manager *handshake_mgr = grpc_handshake_manager_create();
+ pending_handshake_manager_add_locked(state, handshake_mgr);
+ gpr_mu_unlock(&state->mu);
+ grpc_tcp_server_ref(state->tcp_server);
+ server_connection_state *connection_state =
+ gpr_malloc(sizeof(*connection_state));
+ connection_state->server_state = state;
+ connection_state->accepting_pollset = accepting_pollset;
+ connection_state->acceptor = acceptor;
+ connection_state->handshake_mgr = handshake_mgr;
+ grpc_chttp2_server_handshaker_factory_create_handshakers(
+ exec_ctx, state->handshaker_factory, connection_state->handshake_mgr);
+ // TODO(roth): We should really get this timeout value from channel
+ // args instead of hard-coding it.
+ const gpr_timespec deadline = gpr_time_add(
+ gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN));
+ grpc_handshake_manager_do_handshake(
+ exec_ctx, connection_state->handshake_mgr, tcp, state->args, deadline,
+ acceptor, on_handshake_done, connection_state);
+}
+
+/* Server callback: start listening on our ports */
+static void server_start_listener(grpc_exec_ctx *exec_ctx, grpc_server *server,
+ void *arg, grpc_pollset **pollsets,
+ size_t pollset_count) {
+ server_state *state = arg;
+ gpr_mu_lock(&state->mu);
+ state->shutdown = false;
+ gpr_mu_unlock(&state->mu);
+ grpc_tcp_server_start(exec_ctx, state->tcp_server, pollsets, pollset_count,
+ on_accept, state);
+}
+
+static void tcp_server_shutdown_complete(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ server_state *state = arg;
+ /* ensure all threads have unlocked */
+ gpr_mu_lock(&state->mu);
+ grpc_closure *destroy_done = state->server_destroy_listener_done;
+ GPR_ASSERT(state->shutdown);
+ pending_handshake_manager_shutdown_locked(exec_ctx, state);
+ gpr_mu_unlock(&state->mu);
+ // Flush queued work before destroying handshaker factory, since that
+ // may do a synchronous unref.
+ grpc_exec_ctx_flush(exec_ctx);
+ grpc_chttp2_server_handshaker_factory_destroy(exec_ctx,
+ state->handshaker_factory);
+ if (destroy_done != NULL) {
+ destroy_done->cb(exec_ctx, destroy_done->cb_arg, GRPC_ERROR_REF(error));
+ grpc_exec_ctx_flush(exec_ctx);
+ }
+ grpc_channel_args_destroy(state->args);
+ gpr_mu_destroy(&state->mu);
+ gpr_free(state);
+}
+
+/* Server callback: destroy the tcp listener (so we don't generate further
+ callbacks) */
+static void server_destroy_listener(grpc_exec_ctx *exec_ctx,
+ grpc_server *server, void *arg,
+ grpc_closure *destroy_done) {
+ server_state *state = arg;
+ gpr_mu_lock(&state->mu);
+ state->shutdown = true;
+ state->server_destroy_listener_done = destroy_done;
+ grpc_tcp_server *tcp_server = state->tcp_server;
+ gpr_mu_unlock(&state->mu);
+ grpc_tcp_server_shutdown_listeners(exec_ctx, tcp_server);
+ grpc_tcp_server_unref(exec_ctx, tcp_server);
+}
+
+grpc_error *grpc_chttp2_server_add_port(
+ grpc_exec_ctx *exec_ctx, grpc_server *server, const char *addr,
+ grpc_channel_args *args,
+ grpc_chttp2_server_handshaker_factory *handshaker_factory, int *port_num) {
+ grpc_resolved_addresses *resolved = NULL;
+ grpc_tcp_server *tcp_server = NULL;
+ size_t i;
+ size_t count = 0;
+ int port_temp;
+ grpc_error *err = GRPC_ERROR_NONE;
+ server_state *state = NULL;
+ grpc_error **errors = NULL;
+
+ *port_num = -1;
+
+ /* resolve address */
+ err = grpc_blocking_resolve_address(addr, "https", &resolved);
+ if (err != GRPC_ERROR_NONE) {
+ goto error;
+ }
+ state = gpr_malloc(sizeof(*state));
+ memset(state, 0, sizeof(*state));
+ grpc_closure_init(&state->tcp_server_shutdown_complete,
+ tcp_server_shutdown_complete, state);
+ err =
+ grpc_tcp_server_create(exec_ctx, &state->tcp_server_shutdown_complete,
+ args, &tcp_server);
+ if (err != GRPC_ERROR_NONE) {
+ goto error;
+ }
+
+ state->server = server;
+ state->tcp_server = tcp_server;
+ state->args = args;
+ state->handshaker_factory = handshaker_factory;
+ state->shutdown = true;
+ gpr_mu_init(&state->mu);
+
+ const size_t naddrs = resolved->naddrs;
+ errors = gpr_malloc(sizeof(*errors) * naddrs);
+ for (i = 0; i < naddrs; i++) {
+ errors[i] =
+ grpc_tcp_server_add_port(tcp_server, &resolved->addrs[i], &port_temp);
+ if (errors[i] == GRPC_ERROR_NONE) {
+ if (*port_num == -1) {
+ *port_num = port_temp;
+ } else {
+ GPR_ASSERT(*port_num == port_temp);
+ }
+ count++;
+ }
+ }
+ if (count == 0) {
+ char *msg;
+ gpr_asprintf(&msg, "No address added out of total %" PRIuPTR " resolved",
+ naddrs);
+ err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, naddrs);
+ gpr_free(msg);
+ goto error;
+ } else if (count != naddrs) {
+ char *msg;
+ gpr_asprintf(&msg, "Only %" PRIuPTR
+ " addresses added out of total %" PRIuPTR " resolved",
+ count, naddrs);
+ err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, naddrs);
+ gpr_free(msg);
+
+ const char *warning_message = grpc_error_string(err);
+ gpr_log(GPR_INFO, "WARNING: %s", warning_message);
+ grpc_error_free_string(warning_message);
+ /* we managed to bind some addresses: continue */
+ }
+ grpc_resolved_addresses_destroy(resolved);
+
+ /* Register with the server only upon success */
+ grpc_server_add_listener(exec_ctx, server, state, server_start_listener,
+ server_destroy_listener);
+ goto done;
+
+/* Error path: cleanup and return */
+error:
+ GPR_ASSERT(err != GRPC_ERROR_NONE);
+ if (resolved) {
+ grpc_resolved_addresses_destroy(resolved);
+ }
+ if (tcp_server) {
+ grpc_tcp_server_unref(exec_ctx, tcp_server);
+ } else {
+ grpc_channel_args_destroy(args);
+ grpc_chttp2_server_handshaker_factory_destroy(exec_ctx, handshaker_factory);
+ gpr_free(state);
+ }
+ *port_num = 0;
+
+done:
+ if (errors != NULL) {
+ for (i = 0; i < naddrs; i++) {
+ GRPC_ERROR_UNREF(errors[i]);
+ }
+ gpr_free(errors);
+ }
+ return err;
+}
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.h b/src/core/ext/transport/chttp2/server/chttp2_server.h
new file mode 100644
index 0000000000..b1ff04bcbb
--- /dev/null
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.h
@@ -0,0 +1,79 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H
+
+#include <grpc/impl/codegen/grpc_types.h>
+
+#include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+
+/// A server handshaker factory is used to create handshakers for server
+/// connections.
+typedef struct grpc_chttp2_server_handshaker_factory
+ grpc_chttp2_server_handshaker_factory;
+
+typedef struct {
+ void (*create_handshakers)(
+ grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_server_handshaker_factory *handshaker_factory,
+ grpc_handshake_manager *handshake_mgr);
+ void (*destroy)(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_server_handshaker_factory *handshaker_factory);
+} grpc_chttp2_server_handshaker_factory_vtable;
+
+struct grpc_chttp2_server_handshaker_factory {
+ const grpc_chttp2_server_handshaker_factory_vtable *vtable;
+};
+
+void grpc_chttp2_server_handshaker_factory_create_handshakers(
+ grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_server_handshaker_factory *handshaker_factory,
+ grpc_handshake_manager *handshake_mgr);
+
+void grpc_chttp2_server_handshaker_factory_destroy(
+ grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_server_handshaker_factory *handshaker_factory);
+
+/// Adds a port to \a server. Sets \a port_num to the port number.
+/// If \a handshaker_factory is not NULL, it will be used to create
+/// handshakers for the port.
+/// Takes ownership of \a args and \a handshaker_factory.
+grpc_error *grpc_chttp2_server_add_port(
+ grpc_exec_ctx *exec_ctx, grpc_server *server, const char *addr,
+ grpc_channel_args *args,
+ grpc_chttp2_server_handshaker_factory *handshaker_factory,
+ int *port_num);
+
+#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H */
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
index c18d618f96..366312bd72 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
@@ -33,180 +33,28 @@
#include <grpc/grpc.h>
-#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/useful.h>
-#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/ext/transport/chttp2/server/chttp2_server.h"
#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/handshaker.h"
-#include "src/core/lib/channel/http_server_filter.h"
-#include "src/core/lib/iomgr/resolve_address.h"
-#include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/server.h"
-typedef struct server_connect_state {
- grpc_server *server;
- grpc_pollset *accepting_pollset;
- grpc_tcp_server_acceptor *acceptor;
- grpc_handshake_manager *handshake_mgr;
-} server_connect_state;
-
-static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
- grpc_channel_args *args,
- grpc_slice_buffer *read_buffer, void *user_data,
- grpc_error *error) {
- server_connect_state *state = user_data;
- if (error != GRPC_ERROR_NONE) {
- const char *error_str = grpc_error_string(error);
- gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
- grpc_error_free_string(error_str);
- GRPC_ERROR_UNREF(error);
- grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr);
- gpr_free(read_buffer);
- } else {
- // Beware that the call to grpc_create_chttp2_transport() has to happen
- // before grpc_tcp_server_destroy(). This is fine here, but similar code
- // asynchronously doing a handshake instead of calling
- // grpc_tcp_server_start() (as in server_secure_chttp2.c) needs to add
- // synchronization to avoid this case.
- grpc_transport *transport =
- grpc_create_chttp2_transport(exec_ctx, args, endpoint, 0);
- grpc_server_setup_transport(exec_ctx, state->server, transport,
- state->accepting_pollset,
- grpc_server_get_channel_args(state->server));
- grpc_chttp2_transport_start_reading(exec_ctx, transport, read_buffer);
- }
- // Clean up.
- grpc_channel_args_destroy(args);
- grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr);
- gpr_free(state);
-}
-
-static void on_accept(grpc_exec_ctx *exec_ctx, void *server, grpc_endpoint *tcp,
- grpc_pollset *accepting_pollset,
- grpc_tcp_server_acceptor *acceptor) {
- server_connect_state *state = gpr_malloc(sizeof(server_connect_state));
- state->server = server;
- state->accepting_pollset = accepting_pollset;
- state->acceptor = acceptor;
- state->handshake_mgr = grpc_handshake_manager_create();
- // TODO(roth): We should really get this timeout value from channel
- // args instead of hard-coding it.
- const gpr_timespec deadline = gpr_time_add(
- gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN));
- grpc_handshake_manager_do_handshake(
- exec_ctx, state->handshake_mgr, tcp, grpc_server_get_channel_args(server),
- deadline, acceptor, on_handshake_done, state);
-}
-
-/* Server callback: start listening on our ports */
-static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp,
- grpc_pollset **pollsets, size_t pollset_count) {
- grpc_tcp_server *tcp = tcpp;
- grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, on_accept,
- server);
-}
-
-/* Server callback: destroy the tcp listener (so we don't generate further
- callbacks) */
-static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp,
- grpc_closure *destroy_done) {
- grpc_tcp_server *tcp = tcpp;
- grpc_tcp_server_shutdown_listeners(exec_ctx, tcp);
- grpc_tcp_server_unref(exec_ctx, tcp);
- grpc_exec_ctx_sched(exec_ctx, destroy_done, GRPC_ERROR_NONE, NULL);
-}
-
int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
- grpc_resolved_addresses *resolved = NULL;
- grpc_tcp_server *tcp = NULL;
- size_t i;
- size_t count = 0;
- int port_num = -1;
- int port_temp;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- grpc_error *err = GRPC_ERROR_NONE;
-
+ int port_num = 0;
GRPC_API_TRACE("grpc_server_add_insecure_http2_port(server=%p, addr=%s)", 2,
(server, addr));
-
- grpc_error **errors = NULL;
- err = grpc_blocking_resolve_address(addr, "https", &resolved);
- if (err != GRPC_ERROR_NONE) {
- goto error;
- }
-
- err = grpc_tcp_server_create(&exec_ctx, NULL,
- grpc_server_get_channel_args(server), &tcp);
+ grpc_error* err = grpc_chttp2_server_add_port(
+ &exec_ctx, server, addr,
+ grpc_channel_args_copy(grpc_server_get_channel_args(server)),
+ NULL /* handshaker_factory */, &port_num);
if (err != GRPC_ERROR_NONE) {
- goto error;
- }
-
- const size_t naddrs = resolved->naddrs;
- errors = gpr_malloc(sizeof(*errors) * naddrs);
- for (i = 0; i < naddrs; i++) {
- errors[i] = grpc_tcp_server_add_port(tcp, &resolved->addrs[i], &port_temp);
- if (errors[i] == GRPC_ERROR_NONE) {
- if (port_num == -1) {
- port_num = port_temp;
- } else {
- GPR_ASSERT(port_num == port_temp);
- }
- count++;
- }
+ const char *msg = grpc_error_string(err);
+ gpr_log(GPR_ERROR, "%s", msg);
+ grpc_error_free_string(msg);
+ GRPC_ERROR_UNREF(err);
}
- if (count == 0) {
- char *msg;
- gpr_asprintf(&msg, "No address added out of total %" PRIuPTR " resolved",
- naddrs);
- err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, naddrs);
- gpr_free(msg);
- goto error;
- } else if (count != naddrs) {
- char *msg;
- gpr_asprintf(&msg, "Only %" PRIuPTR
- " addresses added out of total %" PRIuPTR " resolved",
- count, naddrs);
- err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, naddrs);
- gpr_free(msg);
-
- const char *warning_message = grpc_error_string(err);
- gpr_log(GPR_INFO, "WARNING: %s", warning_message);
- grpc_error_free_string(warning_message);
- /* we managed to bind some addresses: continue */
- }
- grpc_resolved_addresses_destroy(resolved);
-
- /* Register with the server only upon success */
- grpc_server_add_listener(&exec_ctx, server, tcp, start, destroy);
- goto done;
-
-/* Error path: cleanup and return */
-error:
- GPR_ASSERT(err != GRPC_ERROR_NONE);
- if (resolved) {
- grpc_resolved_addresses_destroy(resolved);
- }
- if (tcp) {
- grpc_tcp_server_unref(&exec_ctx, tcp);
- }
- port_num = 0;
-
- const char *msg = grpc_error_string(err);
- gpr_log(GPR_ERROR, "%s", msg);
- grpc_error_free_string(msg);
- GRPC_ERROR_UNREF(err);
-
-done:
grpc_exec_ctx_finish(&exec_ctx);
- if (errors != NULL) {
- for (i = 0; i < naddrs; i++) {
- GRPC_ERROR_UNREF(errors[i]);
- }
- }
- gpr_free(errors);
return port_num;
}
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
index 942638ad7f..5f41728132 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
@@ -38,218 +38,63 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include <grpc/support/sync.h>
-#include <grpc/support/useful.h>
+
+#include "src/core/ext/transport/chttp2/server/chttp2_server.h"
+
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
-#include "src/core/lib/channel/http_server_filter.h"
-#include "src/core/lib/iomgr/endpoint.h"
-#include "src/core/lib/iomgr/resolve_address.h"
-#include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/security/transport/auth_filters.h"
-#include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/server.h"
-typedef struct server_secure_state {
- grpc_server *server;
- grpc_tcp_server *tcp;
- grpc_server_security_connector *sc;
- grpc_server_credentials *creds;
- bool is_shutdown;
- gpr_mu mu;
- grpc_closure tcp_server_shutdown_complete;
- grpc_closure *server_destroy_listener_done;
-} server_secure_state;
-
-typedef struct server_secure_connect {
- server_secure_state *server_state;
- grpc_pollset *accepting_pollset;
- grpc_tcp_server_acceptor *acceptor;
- grpc_handshake_manager *handshake_mgr;
- // TODO(roth): Remove the following two fields when we eliminate
- // grpc_server_security_connector_do_handshake().
- gpr_timespec deadline;
- grpc_channel_args *args;
-} server_secure_connect;
-
-static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
- grpc_security_status status,
- grpc_endpoint *secure_endpoint,
- grpc_auth_context *auth_context) {
- server_secure_connect *connection_state = statep;
- if (status == GRPC_SECURITY_OK) {
- if (secure_endpoint) {
- gpr_mu_lock(&connection_state->server_state->mu);
- if (!connection_state->server_state->is_shutdown) {
- grpc_transport *transport = grpc_create_chttp2_transport(
- exec_ctx, grpc_server_get_channel_args(
- connection_state->server_state->server),
- secure_endpoint, 0);
- grpc_arg args_to_add[2];
- args_to_add[0] = grpc_server_credentials_to_arg(
- connection_state->server_state->creds);
- args_to_add[1] = grpc_auth_context_to_arg(auth_context);
- grpc_channel_args *args_copy = grpc_channel_args_copy_and_add(
- connection_state->args, args_to_add, GPR_ARRAY_SIZE(args_to_add));
- grpc_server_setup_transport(
- exec_ctx, connection_state->server_state->server, transport,
- connection_state->accepting_pollset, args_copy);
- grpc_channel_args_destroy(args_copy);
- grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL);
- } else {
- /* We need to consume this here, because the server may already have
- * gone away. */
- grpc_endpoint_destroy(exec_ctx, secure_endpoint);
- }
- gpr_mu_unlock(&connection_state->server_state->mu);
- }
- } else {
- gpr_log(GPR_ERROR, "Secure transport failed with error %d", status);
- }
- grpc_channel_args_destroy(connection_state->args);
- grpc_tcp_server_unref(exec_ctx, connection_state->server_state->tcp);
- gpr_free(connection_state);
-}
-
-static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
- grpc_channel_args *args,
- grpc_slice_buffer *read_buffer, void *user_data,
- grpc_error *error) {
- server_secure_connect *connection_state = user_data;
- if (error != GRPC_ERROR_NONE) {
- const char *error_str = grpc_error_string(error);
- gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
- grpc_error_free_string(error_str);
- GRPC_ERROR_UNREF(error);
- grpc_channel_args_destroy(args);
- gpr_free(read_buffer);
- grpc_handshake_manager_shutdown(exec_ctx, connection_state->handshake_mgr);
- grpc_handshake_manager_destroy(exec_ctx, connection_state->handshake_mgr);
- grpc_tcp_server_unref(exec_ctx, connection_state->server_state->tcp);
- gpr_free(connection_state);
- return;
- }
- grpc_handshake_manager_destroy(exec_ctx, connection_state->handshake_mgr);
- connection_state->handshake_mgr = NULL;
- // TODO(roth, jboeuf): Convert security connector handshaking to use new
- // handshake API, and then move the code from on_secure_handshake_done()
- // into this function.
- connection_state->args = args;
- grpc_server_security_connector_do_handshake(
- exec_ctx, connection_state->server_state->sc, connection_state->acceptor,
- endpoint, read_buffer, connection_state->deadline,
- on_secure_handshake_done, connection_state);
-}
-
-static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp,
- grpc_pollset *accepting_pollset,
- grpc_tcp_server_acceptor *acceptor) {
- server_secure_state *server_state = statep;
- server_secure_connect *connection_state = NULL;
- gpr_mu_lock(&server_state->mu);
- if (server_state->is_shutdown) {
- gpr_mu_unlock(&server_state->mu);
- grpc_endpoint_destroy(exec_ctx, tcp);
- return;
- }
- gpr_mu_unlock(&server_state->mu);
- grpc_tcp_server_ref(server_state->tcp);
- connection_state = gpr_malloc(sizeof(*connection_state));
- connection_state->server_state = server_state;
- connection_state->accepting_pollset = accepting_pollset;
- connection_state->acceptor = acceptor;
- connection_state->handshake_mgr = grpc_handshake_manager_create();
- // TODO(roth): We should really get this timeout value from channel
- // args instead of hard-coding it.
- connection_state->deadline = gpr_time_add(
- gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN));
- grpc_handshake_manager_do_handshake(
- exec_ctx, connection_state->handshake_mgr, tcp,
- grpc_server_get_channel_args(connection_state->server_state->server),
- connection_state->deadline, acceptor, on_handshake_done,
- connection_state);
+typedef struct {
+ grpc_chttp2_server_handshaker_factory base;
+ grpc_server_security_connector *security_connector;
+} server_security_handshaker_factory;
+
+static void server_security_handshaker_factory_create_handshakers(
+ grpc_exec_ctx *exec_ctx, grpc_chttp2_server_handshaker_factory *hf,
+ grpc_handshake_manager *handshake_mgr) {
+ server_security_handshaker_factory *handshaker_factory =
+ (server_security_handshaker_factory *)hf;
+ grpc_server_security_connector_create_handshakers(
+ exec_ctx, handshaker_factory->security_connector, handshake_mgr);
}
-/* Server callback: start listening on our ports */
-static void server_start_listener(grpc_exec_ctx *exec_ctx, grpc_server *server,
- void *statep, grpc_pollset **pollsets,
- size_t pollset_count) {
- server_secure_state *server_state = statep;
- gpr_mu_lock(&server_state->mu);
- server_state->is_shutdown = false;
- gpr_mu_unlock(&server_state->mu);
- grpc_tcp_server_start(exec_ctx, server_state->tcp, pollsets, pollset_count,
- on_accept, server_state);
+static void server_security_handshaker_factory_destroy(
+ grpc_exec_ctx* exec_ctx, grpc_chttp2_server_handshaker_factory *hf) {
+ server_security_handshaker_factory *handshaker_factory =
+ (server_security_handshaker_factory *)hf;
+ GRPC_SECURITY_CONNECTOR_UNREF(&handshaker_factory->security_connector->base,
+ "server");
+ gpr_free(hf);
}
-static void tcp_server_shutdown_complete(grpc_exec_ctx *exec_ctx, void *statep,
- grpc_error *error) {
- server_secure_state *server_state = statep;
- /* ensure all threads have unlocked */
- gpr_mu_lock(&server_state->mu);
- grpc_closure *destroy_done = server_state->server_destroy_listener_done;
- GPR_ASSERT(server_state->is_shutdown);
- gpr_mu_unlock(&server_state->mu);
- /* clean up */
- grpc_server_security_connector_shutdown(exec_ctx, server_state->sc);
-
- /* Flush queued work before a synchronous unref. */
- grpc_exec_ctx_flush(exec_ctx);
- GRPC_SECURITY_CONNECTOR_UNREF(&server_state->sc->base, "server");
- grpc_server_credentials_unref(server_state->creds);
-
- if (destroy_done != NULL) {
- destroy_done->cb(exec_ctx, destroy_done->cb_arg, GRPC_ERROR_REF(error));
- grpc_exec_ctx_flush(exec_ctx);
- }
- gpr_free(server_state);
-}
-
-static void server_destroy_listener(grpc_exec_ctx *exec_ctx,
- grpc_server *server, void *statep,
- grpc_closure *callback) {
- server_secure_state *server_state = statep;
- grpc_tcp_server *tcp;
- gpr_mu_lock(&server_state->mu);
- server_state->is_shutdown = true;
- server_state->server_destroy_listener_done = callback;
- tcp = server_state->tcp;
- gpr_mu_unlock(&server_state->mu);
- grpc_tcp_server_shutdown_listeners(exec_ctx, tcp);
- grpc_tcp_server_unref(exec_ctx, server_state->tcp);
-}
+static const grpc_chttp2_server_handshaker_factory_vtable
+ server_security_handshaker_factory_vtable = {
+ server_security_handshaker_factory_create_handshakers,
+ server_security_handshaker_factory_destroy};
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
grpc_server_credentials *creds) {
- grpc_resolved_addresses *resolved = NULL;
- grpc_tcp_server *tcp = NULL;
- server_secure_state *server_state = NULL;
- size_t i;
- size_t count = 0;
- int port_num = -1;
- int port_temp;
- grpc_security_status status = GRPC_SECURITY_ERROR;
- grpc_server_security_connector *sc = NULL;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_error *err = GRPC_ERROR_NONE;
- grpc_error **errors = NULL;
-
+ grpc_server_security_connector *sc = NULL;
+ int port_num = 0;
GRPC_API_TRACE(
"grpc_server_add_secure_http2_port("
"server=%p, addr=%s, creds=%p)",
3, (server, addr, creds));
-
- /* create security context */
+ // Create security context.
if (creds == NULL) {
err = GRPC_ERROR_CREATE(
"No credentials specified for secure server port (creds==NULL)");
- goto error;
+ goto done;
}
- status = grpc_server_credentials_create_security_connector(creds, &sc);
+ grpc_security_status status =
+ grpc_server_credentials_create_security_connector(creds, &sc);
if (status != GRPC_SECURITY_OK) {
char *msg;
gpr_asprintf(&msg,
@@ -258,107 +103,28 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
err = grpc_error_set_int(GRPC_ERROR_CREATE(msg),
GRPC_ERROR_INT_SECURITY_STATUS, status);
gpr_free(msg);
- goto error;
+ goto done;
}
- sc->channel_args = grpc_server_get_channel_args(server);
-
- /* resolve address */
- err = grpc_blocking_resolve_address(addr, "https", &resolved);
- if (err != GRPC_ERROR_NONE) {
- goto error;
- }
- server_state = gpr_malloc(sizeof(*server_state));
- memset(server_state, 0, sizeof(*server_state));
- grpc_closure_init(&server_state->tcp_server_shutdown_complete,
- tcp_server_shutdown_complete, server_state);
- err = grpc_tcp_server_create(&exec_ctx,
- &server_state->tcp_server_shutdown_complete,
- grpc_server_get_channel_args(server), &tcp);
+ // Create handshaker factory.
+ server_security_handshaker_factory* handshaker_factory =
+ gpr_malloc(sizeof(*handshaker_factory));
+ memset(handshaker_factory, 0, sizeof(*handshaker_factory));
+ handshaker_factory->base.vtable = &server_security_handshaker_factory_vtable;
+ handshaker_factory->security_connector = sc;
+ // Create channel args.
+ grpc_arg channel_arg = grpc_server_credentials_to_arg(creds);
+ grpc_channel_args *args = grpc_channel_args_copy_and_add(
+ grpc_server_get_channel_args(server), &channel_arg, 1);
+ // Add server port.
+ err = grpc_chttp2_server_add_port(&exec_ctx, server, addr, args,
+ &handshaker_factory->base, &port_num);
+done:
+ grpc_exec_ctx_finish(&exec_ctx);
if (err != GRPC_ERROR_NONE) {
- goto error;
+ const char *msg = grpc_error_string(err);
+ gpr_log(GPR_ERROR, "%s", msg);
+ grpc_error_free_string(msg);
+ GRPC_ERROR_UNREF(err);
}
-
- server_state->server = server;
- server_state->tcp = tcp;
- server_state->sc = sc;
- server_state->creds = grpc_server_credentials_ref(creds);
- server_state->is_shutdown = true;
- gpr_mu_init(&server_state->mu);
-
- errors = gpr_malloc(sizeof(*errors) * resolved->naddrs);
- for (i = 0; i < resolved->naddrs; i++) {
- errors[i] = grpc_tcp_server_add_port(tcp, &resolved->addrs[i], &port_temp);
- if (errors[i] == GRPC_ERROR_NONE) {
- if (port_num == -1) {
- port_num = port_temp;
- } else {
- GPR_ASSERT(port_num == port_temp);
- }
- count++;
- }
- }
- if (count == 0) {
- char *msg;
- gpr_asprintf(&msg, "No address added out of total %" PRIuPTR " resolved",
- resolved->naddrs);
- err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, resolved->naddrs);
- gpr_free(msg);
- goto error;
- } else if (count != resolved->naddrs) {
- char *msg;
- gpr_asprintf(&msg, "Only %" PRIuPTR
- " addresses added out of total %" PRIuPTR " resolved",
- count, resolved->naddrs);
- err = GRPC_ERROR_CREATE_REFERENCING(msg, errors, resolved->naddrs);
- gpr_free(msg);
-
- const char *warning_message = grpc_error_string(err);
- gpr_log(GPR_INFO, "WARNING: %s", warning_message);
- grpc_error_free_string(warning_message);
- /* we managed to bind some addresses: continue */
- } else {
- for (i = 0; i < resolved->naddrs; i++) {
- GRPC_ERROR_UNREF(errors[i]);
- }
- }
- gpr_free(errors);
- errors = NULL;
- grpc_resolved_addresses_destroy(resolved);
-
- /* Register with the server only upon success */
- grpc_server_add_listener(&exec_ctx, server, server_state,
- server_start_listener, server_destroy_listener);
-
- grpc_exec_ctx_finish(&exec_ctx);
return port_num;
-
-/* Error path: cleanup and return */
-error:
- GPR_ASSERT(err != GRPC_ERROR_NONE);
- if (errors != NULL) {
- for (i = 0; i < resolved->naddrs; i++) {
- GRPC_ERROR_UNREF(errors[i]);
- }
- gpr_free(errors);
- }
- if (resolved) {
- grpc_resolved_addresses_destroy(resolved);
- }
- if (tcp) {
- grpc_tcp_server_unref(&exec_ctx, tcp);
- } else {
- if (sc) {
- grpc_exec_ctx_flush(&exec_ctx);
- GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server");
- }
- if (server_state) {
- gpr_free(server_state);
- }
- }
- grpc_exec_ctx_finish(&exec_ctx);
- const char *msg = grpc_error_string(err);
- GRPC_ERROR_UNREF(err);
- gpr_log(GPR_ERROR, "%s", msg);
- grpc_error_free_string(msg);
- return 0;
}
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 4e3c7ff681..3e7c078d3c 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -111,9 +111,6 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
void *byte_stream,
grpc_error *error_ignored);
-static void fail_pending_writes(grpc_exec_ctx *exec_ctx,
- grpc_chttp2_transport *t, grpc_chttp2_stream *s,
- grpc_error *error);
static void benign_reclaimer(grpc_exec_ctx *exec_ctx, void *t,
grpc_error *error);
@@ -428,6 +425,7 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
/* flush writable stream list to avoid dangling references */
grpc_chttp2_stream *s;
while (grpc_chttp2_list_pop_writable_stream(t, &s)) {
+ grpc_chttp2_leave_writing_lists(exec_ctx, t, s);
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:close");
}
end_all_the_calls(exec_ctx, t, GRPC_ERROR_REF(error));
@@ -523,6 +521,10 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
}
}
+ if (s->fail_pending_writes_on_writes_finished_error != NULL) {
+ GRPC_ERROR_UNREF(s->fail_pending_writes_on_writes_finished_error);
+ }
+
GPR_ASSERT(s->send_initial_metadata_finished == NULL);
GPR_ASSERT(s->fetching_send_message == NULL);
GPR_ASSERT(s->send_trailing_metadata_finished == NULL);
@@ -704,8 +706,6 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp,
}
}
- grpc_chttp2_end_write(exec_ctx, t, GRPC_ERROR_REF(error));
-
switch (t->write_state) {
case GRPC_CHTTP2_WRITE_STATE_IDLE:
GPR_UNREACHABLE_CODE(break);
@@ -734,6 +734,8 @@ static void write_action_end_locked(grpc_exec_ctx *exec_ctx, void *tp,
break;
}
+ grpc_chttp2_end_write(exec_ctx, t, GRPC_ERROR_REF(error));
+
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "writing");
GPR_TIMER_END("terminate_writing_with_lock", 0);
}
@@ -1404,6 +1406,7 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
}
}
if (grpc_chttp2_list_remove_writable_stream(t, s)) {
+ grpc_chttp2_leave_writing_lists(exec_ctx, t, s);
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:remove_stream");
}
@@ -1534,9 +1537,41 @@ static grpc_error *removal_error(grpc_error *extra_error, grpc_chttp2_stream *s,
return error;
}
-static void fail_pending_writes(grpc_exec_ctx *exec_ctx,
- grpc_chttp2_transport *t, grpc_chttp2_stream *s,
- grpc_error *error) {
+void grpc_chttp2_leave_writing_lists(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_transport *t,
+ grpc_chttp2_stream *s) {
+ if (s->need_fail_pending_writes_on_writes_finished) {
+ grpc_error *error = s->fail_pending_writes_on_writes_finished_error;
+ s->fail_pending_writes_on_writes_finished_error = NULL;
+ s->need_fail_pending_writes_on_writes_finished = false;
+ grpc_chttp2_fail_pending_writes(exec_ctx, t, s, error);
+ }
+}
+
+void grpc_chttp2_fail_pending_writes(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_transport *t,
+ grpc_chttp2_stream *s, grpc_error *error) {
+ if (s->need_fail_pending_writes_on_writes_finished ||
+ (t->write_state != GRPC_CHTTP2_WRITE_STATE_IDLE &&
+ (s->included[GRPC_CHTTP2_LIST_WRITABLE] ||
+ s->included[GRPC_CHTTP2_LIST_WRITING]))) {
+ /* If a write is in progress, and it involves this stream, wait for the
+ * write to complete before cancelling things out. If we don't do this, then
+ * our combiner lock might think that some operation on its queue might be
+ * covering a completion even though there is none, in which case we might
+ * offload to another thread, which isn't guarateed to exist */
+ if (error != GRPC_ERROR_NONE) {
+ if (s->fail_pending_writes_on_writes_finished_error == GRPC_ERROR_NONE) {
+ s->fail_pending_writes_on_writes_finished_error = GRPC_ERROR_CREATE(
+ "Post-poned fail writes due to in-progress write");
+ }
+ s->fail_pending_writes_on_writes_finished_error = grpc_error_add_child(
+ s->fail_pending_writes_on_writes_finished_error, error);
+ }
+ s->need_fail_pending_writes_on_writes_finished = true;
+ return; /* early out */
+ }
+
error =
removal_error(error, s, "Pending writes failed due to stream closure");
s->send_initial_metadata = NULL;
@@ -1590,7 +1625,7 @@ void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx,
if (close_writes && !s->write_closed) {
s->write_closed_error = GRPC_ERROR_REF(error);
s->write_closed = true;
- fail_pending_writes(exec_ctx, t, s, GRPC_ERROR_REF(error));
+ grpc_chttp2_fail_pending_writes(exec_ctx, t, s, GRPC_ERROR_REF(error));
grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s);
}
if (s->read_closed && s->write_closed) {
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index b74233d992..6cba1e7fd2 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -409,6 +409,9 @@ struct grpc_chttp2_stream {
grpc_error *read_closed_error;
/** the error that resulted in this stream being write-closed */
grpc_error *write_closed_error;
+ /** should any writes be cleared once this stream becomes non-writable */
+ bool need_fail_pending_writes_on_writes_finished;
+ grpc_error *fail_pending_writes_on_writes_finished_error;
grpc_published_metadata_method published_metadata[2];
bool final_metadata_requested;
@@ -689,4 +692,11 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
+void grpc_chttp2_leave_writing_lists(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_transport *t,
+ grpc_chttp2_stream *s);
+void grpc_chttp2_fail_pending_writes(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_transport *t,
+ grpc_chttp2_stream *s, grpc_error *error);
+
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INTERNAL_H */
diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index 139e7387c4..769b229a0d 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -208,6 +208,7 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:already_writing");
}
} else {
+ grpc_chttp2_leave_writing_lists(exec_ctx, t, s);
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:no_write");
}
}
@@ -252,6 +253,7 @@ void grpc_chttp2_end_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_mark_stream_closed(exec_ctx, t, s, !t->is_client, 1,
GRPC_ERROR_REF(error));
}
+ grpc_chttp2_leave_writing_lists(exec_ctx, t, s);
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:end");
}
grpc_slice_buffer_reset_and_unref(&t->outbuf);
diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c
index a45a39981c..90626dc2d1 100644
--- a/src/core/lib/channel/handshaker.c
+++ b/src/core/lib/channel/handshaker.c
@@ -38,67 +38,66 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/iomgr/timer.h"
//
// grpc_handshaker
//
-void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable,
+void grpc_handshaker_init(const grpc_handshaker_vtable* vtable,
grpc_handshaker* handshaker) {
handshaker->vtable = vtable;
}
-void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx,
- grpc_handshaker* handshaker) {
+static void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx,
+ grpc_handshaker* handshaker) {
handshaker->vtable->destroy(exec_ctx, handshaker);
}
-void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
- grpc_handshaker* handshaker) {
+static void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
+ grpc_handshaker* handshaker) {
handshaker->vtable->shutdown(exec_ctx, handshaker);
}
-void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx,
- grpc_handshaker* handshaker,
- grpc_endpoint* endpoint,
- grpc_channel_args* args,
- grpc_slice_buffer* read_buffer,
- gpr_timespec deadline,
- grpc_tcp_server_acceptor* acceptor,
- grpc_handshaker_done_cb cb, void* user_data) {
- handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args,
- read_buffer, deadline, acceptor, cb,
- user_data);
+static void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx,
+ grpc_handshaker* handshaker,
+ grpc_tcp_server_acceptor* acceptor,
+ grpc_closure* on_handshake_done,
+ grpc_handshaker_args* args) {
+ handshaker->vtable->do_handshake(exec_ctx, handshaker, acceptor,
+ on_handshake_done, args);
}
//
// grpc_handshake_manager
//
-// State used while chaining handshakers.
-struct grpc_handshaker_state {
- // The index of the handshaker to invoke next.
- size_t index;
- // The deadline for all handshakers.
- gpr_timespec deadline;
- // The acceptor to call the handshakers with.
- grpc_tcp_server_acceptor* acceptor;
- // The final callback and user_data to invoke after the last handshaker.
- grpc_handshaker_done_cb final_cb;
- void* final_user_data;
-};
-
struct grpc_handshake_manager {
+ gpr_mu mu;
+ gpr_refcount refs;
+ bool shutdown;
// An array of handshakers added via grpc_handshake_manager_add().
size_t count;
grpc_handshaker** handshakers;
- // State used while chaining handshakers.
- struct grpc_handshaker_state* state;
+ // The index of the handshaker to invoke next and closure to invoke it.
+ size_t index;
+ grpc_closure call_next_handshaker;
+ // The acceptor to call the handshakers with.
+ grpc_tcp_server_acceptor* acceptor;
+ // Deadline timer across all handshakers.
+ grpc_timer deadline_timer;
+ // The final callback and user_data to invoke after the last handshaker.
+ grpc_closure on_handshake_done;
+ void* user_data;
+ // Handshaker args.
+ grpc_handshaker_args args;
};
grpc_handshake_manager* grpc_handshake_manager_create() {
grpc_handshake_manager* mgr = gpr_malloc(sizeof(grpc_handshake_manager));
memset(mgr, 0, sizeof(*mgr));
+ gpr_mu_init(&mgr->mu);
+ gpr_ref_init(&mgr->refs, 1);
return mgr;
}
@@ -106,6 +105,7 @@ static bool is_power_of_2(size_t n) { return (n & (n - 1)) == 0; }
void grpc_handshake_manager_add(grpc_handshake_manager* mgr,
grpc_handshaker* handshaker) {
+ gpr_mu_lock(&mgr->mu);
// To avoid allocating memory for each handshaker we add, we double
// the number of elements every time we need more.
size_t realloc_count = 0;
@@ -119,85 +119,116 @@ void grpc_handshake_manager_add(grpc_handshake_manager* mgr,
gpr_realloc(mgr->handshakers, realloc_count * sizeof(grpc_handshaker*));
}
mgr->handshakers[mgr->count++] = handshaker;
+ gpr_mu_unlock(&mgr->mu);
+}
+
+static void grpc_handshake_manager_unref(grpc_exec_ctx* exec_ctx,
+ grpc_handshake_manager* mgr) {
+ if (gpr_unref(&mgr->refs)) {
+ for (size_t i = 0; i < mgr->count; ++i) {
+ grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]);
+ }
+ gpr_free(mgr->handshakers);
+ gpr_mu_destroy(&mgr->mu);
+ gpr_free(mgr);
+ }
}
void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx,
grpc_handshake_manager* mgr) {
- for (size_t i = 0; i < mgr->count; ++i) {
- grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]);
- }
- gpr_free(mgr->handshakers);
- gpr_free(mgr);
+ grpc_handshake_manager_unref(exec_ctx, mgr);
}
void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx,
grpc_handshake_manager* mgr) {
- for (size_t i = 0; i < mgr->count; ++i) {
- grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[i]);
+ gpr_mu_lock(&mgr->mu);
+ // Shutdown the handshaker that's currently in progress, if any.
+ if (!mgr->shutdown && mgr->index > 0) {
+ mgr->shutdown = true;
+ grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[mgr->index - 1]);
}
- if (mgr->state != NULL) {
- gpr_free(mgr->state);
- mgr->state = NULL;
+ gpr_mu_unlock(&mgr->mu);
+}
+
+// Helper function to call either the next handshaker or the
+// on_handshake_done callback.
+// Returns true if we've scheduled the on_handshake_done callback.
+static bool call_next_handshaker_locked(grpc_exec_ctx* exec_ctx,
+ grpc_handshake_manager* mgr,
+ grpc_error* error) {
+ GPR_ASSERT(mgr->index <= mgr->count);
+ // If we got an error or we've been shut down or we've finished the last
+ // handshaker, invoke the on_handshake_done callback. Otherwise, call the
+ // next handshaker.
+ if (error != GRPC_ERROR_NONE || mgr->shutdown || mgr->index == mgr->count) {
+ // Cancel deadline timer, since we're invoking the on_handshake_done
+ // callback now.
+ grpc_timer_cancel(exec_ctx, &mgr->deadline_timer);
+ grpc_exec_ctx_sched(exec_ctx, &mgr->on_handshake_done, error, NULL);
+ mgr->shutdown = true;
+ } else {
+ grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->index],
+ mgr->acceptor, &mgr->call_next_handshaker,
+ &mgr->args);
}
+ ++mgr->index;
+ return mgr->shutdown;
}
// A function used as the handshaker-done callback when chaining
// handshakers together.
-static void call_next_handshaker(grpc_exec_ctx* exec_ctx,
- grpc_endpoint* endpoint,
- grpc_channel_args* args,
- grpc_slice_buffer* read_buffer,
- void* user_data, grpc_error* error) {
- grpc_handshake_manager* mgr = user_data;
- GPR_ASSERT(mgr->state != NULL);
- GPR_ASSERT(mgr->state->index < mgr->count);
- // If we got an error, skip all remaining handshakers and invoke the
- // caller-supplied callback immediately.
- if (error != GRPC_ERROR_NONE) {
- mgr->state->final_cb(exec_ctx, endpoint, args, read_buffer,
- mgr->state->final_user_data, error);
- return;
+static void call_next_handshaker(grpc_exec_ctx* exec_ctx, void* arg,
+ grpc_error* error) {
+ grpc_handshake_manager* mgr = arg;
+ gpr_mu_lock(&mgr->mu);
+ bool done = call_next_handshaker_locked(exec_ctx, mgr, GRPC_ERROR_REF(error));
+ gpr_mu_unlock(&mgr->mu);
+ // If we're invoked the final callback, we won't be coming back
+ // to this function, so we can release our reference to the
+ // handshake manager.
+ if (done) {
+ grpc_handshake_manager_unref(exec_ctx, mgr);
}
- grpc_handshaker_done_cb cb = call_next_handshaker;
- // If this is the last handshaker, use the caller-supplied callback
- // and user_data instead of chaining back to this function again.
- if (mgr->state->index == mgr->count - 1) {
- cb = mgr->state->final_cb;
- user_data = mgr->state->final_user_data;
- }
- // Invoke handshaker.
- grpc_handshaker_do_handshake(
- exec_ctx, mgr->handshakers[mgr->state->index], endpoint, args,
- read_buffer, mgr->state->deadline, mgr->state->acceptor, cb, user_data);
- ++mgr->state->index;
- // If this is the last handshaker, clean up state.
- if (mgr->state->index == mgr->count) {
- gpr_free(mgr->state);
- mgr->state = NULL;
+}
+
+// Callback invoked when deadline is exceeded.
+static void on_timeout(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
+ grpc_handshake_manager* mgr = arg;
+ if (error == GRPC_ERROR_NONE) { // Timer fired, rather than being cancelled.
+ grpc_handshake_manager_shutdown(exec_ctx, mgr);
}
+ grpc_handshake_manager_unref(exec_ctx, mgr);
}
void grpc_handshake_manager_do_handshake(
grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr,
- grpc_endpoint* endpoint, const grpc_channel_args* args,
+ grpc_endpoint* endpoint, const grpc_channel_args* channel_args,
gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor,
- grpc_handshaker_done_cb cb, void* user_data) {
- grpc_channel_args* args_copy = grpc_channel_args_copy(args);
- grpc_slice_buffer* read_buffer = gpr_malloc(sizeof(*read_buffer));
- grpc_slice_buffer_init(read_buffer);
- if (mgr->count == 0) {
- // No handshakers registered, so we just immediately call the done
- // callback with the passed-in endpoint.
- cb(exec_ctx, endpoint, args_copy, read_buffer, user_data, GRPC_ERROR_NONE);
- } else {
- GPR_ASSERT(mgr->state == NULL);
- mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state));
- memset(mgr->state, 0, sizeof(*mgr->state));
- mgr->state->deadline = deadline;
- mgr->state->acceptor = acceptor;
- mgr->state->final_cb = cb;
- mgr->state->final_user_data = user_data;
- call_next_handshaker(exec_ctx, endpoint, args_copy, read_buffer, mgr,
- GRPC_ERROR_NONE);
+ grpc_iomgr_cb_func on_handshake_done, void* user_data) {
+ gpr_mu_lock(&mgr->mu);
+ GPR_ASSERT(mgr->index == 0);
+ GPR_ASSERT(!mgr->shutdown);
+ // Construct handshaker args. These will be passed through all
+ // handshakers and eventually be freed by the on_handshake_done callback.
+ mgr->args.endpoint = endpoint;
+ mgr->args.args = grpc_channel_args_copy(channel_args);
+ mgr->args.user_data = user_data;
+ mgr->args.read_buffer = gpr_malloc(sizeof(*mgr->args.read_buffer));
+ grpc_slice_buffer_init(mgr->args.read_buffer);
+ // Initialize state needed for calling handshakers.
+ mgr->acceptor = acceptor;
+ grpc_closure_init(&mgr->call_next_handshaker, call_next_handshaker, mgr);
+ grpc_closure_init(&mgr->on_handshake_done, on_handshake_done, &mgr->args);
+ // Start deadline timer, which owns a ref.
+ gpr_ref(&mgr->refs);
+ grpc_timer_init(exec_ctx, &mgr->deadline_timer,
+ gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
+ on_timeout, mgr, gpr_now(GPR_CLOCK_MONOTONIC));
+ // Start first handshaker, which also owns a ref.
+ gpr_ref(&mgr->refs);
+ bool done = call_next_handshaker_locked(exec_ctx, mgr, GRPC_ERROR_NONE);
+ gpr_mu_unlock(&mgr->mu);
+ if (done) {
+ grpc_handshake_manager_unref(exec_ctx, mgr);
}
}
diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h
index f8a36c6473..ebbc1ff7f3 100644
--- a/src/core/lib/channel/handshaker.h
+++ b/src/core/lib/channel/handshaker.h
@@ -54,15 +54,30 @@
typedef struct grpc_handshaker grpc_handshaker;
-/// Callback type invoked when a handshaker is done.
-/// Takes ownership of \a args and \a read_buffer.
-typedef void (*grpc_handshaker_done_cb)(grpc_exec_ctx* exec_ctx,
- grpc_endpoint* endpoint,
- grpc_channel_args* args,
- grpc_slice_buffer* read_buffer,
- void* user_data, grpc_error* error);
-
-struct grpc_handshaker_vtable {
+/// Arguments passed through handshakers and to the on_handshake_done callback.
+///
+/// For handshakers, all members are input/output parameters; for
+/// example, a handshaker may read from or write to \a endpoint and
+/// then later replace it with a wrapped endpoint. Similarly, a
+/// handshaker may modify \a args.
+///
+/// A handshaker takes ownership of the members while a handshake is in
+/// progress. Upon failure or shutdown of an in-progress handshaker,
+/// the handshaker is responsible for destroying the members and setting
+/// them to NULL before invoking the on_handshake_done callback.
+///
+/// For the on_handshake_done callback, all members are input arguments,
+/// which the callback takes ownership of.
+typedef struct {
+ grpc_endpoint* endpoint;
+ grpc_channel_args* args;
+ grpc_slice_buffer* read_buffer;
+ // User data passed through the handshake manager. Not used by
+ // individual handshakers.
+ void* user_data;
+} grpc_handshaker_args;
+
+typedef struct {
/// Destroys the handshaker.
void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker);
@@ -70,44 +85,26 @@ struct grpc_handshaker_vtable {
/// aborted in the middle).
void (*shutdown)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker);
- /// Performs handshaking. When finished, calls \a cb with \a user_data.
- /// Takes ownership of \a args.
- /// Takes ownership of \a read_buffer, which contains leftover bytes read
- /// from the endpoint by the previous handshaker.
+ /// Performs handshaking, modifying \a args as needed (e.g., to
+ /// replace \a endpoint with a wrapped endpoint).
+ /// When finished, invokes \a on_handshake_done.
/// \a acceptor will be NULL for client-side handshakers.
void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker,
- grpc_endpoint* endpoint, grpc_channel_args* args,
- grpc_slice_buffer* read_buffer, gpr_timespec deadline,
grpc_tcp_server_acceptor* acceptor,
- grpc_handshaker_done_cb cb, void* user_data);
-};
+ grpc_closure* on_handshake_done,
+ grpc_handshaker_args* args);
+} grpc_handshaker_vtable;
/// Base struct. To subclass, make this the first member of the
/// implementation struct.
struct grpc_handshaker {
- const struct grpc_handshaker_vtable* vtable;
+ const grpc_handshaker_vtable* vtable;
};
/// Called by concrete implementations to initialize the base struct.
-void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable,
+void grpc_handshaker_init(const grpc_handshaker_vtable* vtable,
grpc_handshaker* handshaker);
-/// Convenient wrappers for invoking methods via the vtable.
-/// These probably do not need to be called from anywhere but
-/// grpc_handshake_manager.
-void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx,
- grpc_handshaker* handshaker);
-void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
- grpc_handshaker* handshaker);
-void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx,
- grpc_handshaker* handshaker,
- grpc_endpoint* endpoint,
- grpc_channel_args* args,
- grpc_slice_buffer* read_buffer,
- gpr_timespec deadline,
- grpc_tcp_server_acceptor* acceptor,
- grpc_handshaker_done_cb cb, void* user_data);
-
///
/// grpc_handshake_manager
///
@@ -134,15 +131,21 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx,
grpc_handshake_manager* mgr);
/// Invokes handshakers in the order they were added.
-/// Does NOT take ownership of \a args. Instead, makes a copy before
+/// Takes ownership of \a endpoint, and then passes that ownership to
+/// the \a on_handshake_done callback.
+/// Does NOT take ownership of \a channel_args. Instead, makes a copy before
/// invoking the first handshaker.
/// \a acceptor will be NULL for client-side handshakers.
-/// Invokes \a cb with \a user_data after either a handshaker fails or
-/// all handshakers have completed successfully.
+///
+/// When done, invokes \a on_handshake_done with a grpc_handshaker_args
+/// object as its argument. If the callback is invoked with error !=
+/// GRPC_ERROR_NONE, then handshaking failed and the handshaker has done
+/// the necessary clean-up. Otherwise, the callback takes ownership of
+/// the arguments.
void grpc_handshake_manager_do_handshake(
grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr,
- grpc_endpoint* endpoint, const grpc_channel_args* args,
+ grpc_endpoint* endpoint, const grpc_channel_args* channel_args,
gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor,
- grpc_handshaker_done_cb cb, void* user_data);
+ grpc_iomgr_cb_func on_handshake_done, void* user_data);
#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index dbe0d25211..fd8b46afcb 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -245,12 +245,15 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
message, and the payload is below the size threshold, and all the data
for this request is immediately available. */
grpc_mdelem *method = GRPC_MDELEM_METHOD_POST;
- calld->send_message_blocked = false;
if ((op->send_initial_metadata_flags &
GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) &&
op->send_message != NULL &&
op->send_message->length < channeld->max_payload_size_for_get) {
method = GRPC_MDELEM_METHOD_GET;
+ /* The following write to calld->send_message_blocked isn't racy with
+ reads in hc_start_transport_op (which deals with SEND_MESSAGE ops) because
+ being here means ops->send_message is not NULL, which is primarily
+ guarding the read there. */
calld->send_message_blocked = true;
} else if (op->send_initial_metadata_flags &
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) {
@@ -331,8 +334,7 @@ static void hc_start_transport_op(grpc_exec_ctx *exec_ctx,
call_data *calld = elem->call_data;
if (op->send_message != NULL && calld->send_message_blocked) {
/* Don't forward the op. send_message contains slices that aren't ready
- yet. The call will be forwarded by the op_complete of slice read call.
- */
+ yet. The call will be forwarded by the op_complete of slice read call. */
} else {
grpc_call_next_op(exec_ctx, elem, op);
}
@@ -347,6 +349,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
calld->on_done_recv_trailing_metadata = NULL;
calld->on_complete = NULL;
calld->payload_bytes = NULL;
+ calld->send_message_blocked = false;
grpc_slice_buffer_init(&calld->slices);
grpc_closure_init(&calld->hc_on_recv_initial_metadata,
hc_on_recv_initial_metadata, elem);
diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c
index 24d264c32a..0ab34d00e4 100644
--- a/src/core/lib/http/httpcli_security_connector.c
+++ b/src/core/lib/http/httpcli_security_connector.c
@@ -38,7 +38,9 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include "src/core/lib/security/transport/handshake.h"
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/tsi/ssl_transport_security.h"
@@ -58,52 +60,42 @@ static void httpcli_ssl_destroy(grpc_security_connector *sc) {
gpr_free(sc);
}
-static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
- grpc_channel_security_connector *sc,
- grpc_endpoint *nonsecure_endpoint,
- grpc_slice_buffer *read_buffer,
- gpr_timespec deadline,
- grpc_security_handshake_done_cb cb,
- void *user_data) {
+static void httpcli_ssl_create_handshakers(
+ grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
+ grpc_handshake_manager *handshake_mgr) {
grpc_httpcli_ssl_channel_security_connector *c =
(grpc_httpcli_ssl_channel_security_connector *)sc;
- tsi_result result = TSI_OK;
- tsi_handshaker *handshaker;
- if (c->handshaker_factory == NULL) {
- gpr_free(read_buffer);
- cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
- return;
- }
- result = tsi_ssl_handshaker_factory_create_handshaker(
- c->handshaker_factory, c->secure_peer_name, &handshaker);
- if (result != TSI_OK) {
- gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
- tsi_result_to_string(result));
- gpr_free(read_buffer);
- cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
- } else {
- grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
- nonsecure_endpoint, read_buffer, deadline, cb,
- user_data);
+ tsi_handshaker *handshaker = NULL;
+ if (c->handshaker_factory != NULL) {
+ tsi_result result = tsi_ssl_handshaker_factory_create_handshaker(
+ c->handshaker_factory, c->secure_peer_name, &handshaker);
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
+ tsi_result_to_string(result));
+ }
}
+ grpc_security_create_handshakers(exec_ctx, handshaker, &sc->base,
+ handshake_mgr);
}
static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, tsi_peer peer,
- grpc_security_peer_check_cb cb,
- void *user_data) {
+ grpc_auth_context **auth_context,
+ grpc_closure *on_peer_checked) {
grpc_httpcli_ssl_channel_security_connector *c =
(grpc_httpcli_ssl_channel_security_connector *)sc;
- grpc_security_status status = GRPC_SECURITY_OK;
+ grpc_error *error = GRPC_ERROR_NONE;
/* Check the peer name. */
if (c->secure_peer_name != NULL &&
!tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) {
- gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate",
- c->secure_peer_name);
- status = GRPC_SECURITY_ERROR;
+ char *msg;
+ gpr_asprintf(&msg, "Peer name %s is not in peer certificate",
+ c->secure_peer_name);
+ error = GRPC_ERROR_CREATE(msg);
+ gpr_free(msg);
}
- cb(exec_ctx, user_data, status, NULL);
+ grpc_exec_ctx_sched(exec_ctx, on_peer_checked, error, NULL);
tsi_peer_destruct(&peer);
}
@@ -140,7 +132,7 @@ static grpc_security_status httpcli_ssl_channel_security_connector_create(
*sc = NULL;
return GRPC_SECURITY_ERROR;
}
- c->base.do_handshake = httpcli_ssl_do_handshake;
+ c->base.create_handshakers = httpcli_ssl_create_handshakers;
*sc = &c->base;
return GRPC_SECURITY_OK;
}
@@ -150,19 +142,25 @@ static grpc_security_status httpcli_ssl_channel_security_connector_create(
typedef struct {
void (*func)(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *endpoint);
void *arg;
+ grpc_handshake_manager *handshake_mgr;
} on_done_closure;
-static void on_secure_transport_setup_done(grpc_exec_ctx *exec_ctx, void *rp,
- grpc_security_status status,
- grpc_endpoint *secure_endpoint,
- grpc_auth_context *auth_context) {
- on_done_closure *c = rp;
- if (status != GRPC_SECURITY_OK) {
- gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status);
+static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ grpc_handshaker_args *args = arg;
+ on_done_closure *c = args->user_data;
+ if (error != GRPC_ERROR_NONE) {
+ const char *msg = grpc_error_string(error);
+ gpr_log(GPR_ERROR, "Secure transport setup failed: %s", msg);
+ grpc_error_free_string(msg);
c->func(exec_ctx, c->arg, NULL);
} else {
- c->func(exec_ctx, c->arg, secure_endpoint);
+ grpc_channel_args_destroy(args->args);
+ grpc_slice_buffer_destroy(args->read_buffer);
+ gpr_free(args->read_buffer);
+ c->func(exec_ctx, c->arg, args->endpoint);
}
+ grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr);
gpr_free(c);
}
@@ -183,11 +181,15 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
}
c->func = on_done;
c->arg = arg;
+ c->handshake_mgr = grpc_handshake_manager_create();
GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
pem_root_certs, pem_root_certs_size, host, &sc) ==
GRPC_SECURITY_OK);
- grpc_channel_security_connector_do_handshake(
- exec_ctx, sc, tcp, NULL, deadline, on_secure_transport_setup_done, c);
+ grpc_channel_security_connector_create_handshakers(exec_ctx, sc,
+ c->handshake_mgr);
+ grpc_handshake_manager_do_handshake(
+ exec_ctx, c->handshake_mgr, tcp, NULL /* channel_args */, deadline,
+ NULL /* acceptor */, on_handshake_done, c /* user_data */);
GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli");
}
diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c
index 60ee14eb23..cfc67020ae 100644
--- a/src/core/lib/iomgr/combiner.c
+++ b/src/core/lib/iomgr/combiner.c
@@ -90,6 +90,12 @@ static bool is_covered_by_poller(grpc_combiner *lock) {
gpr_atm_acq_load(&lock->elements_covered_by_poller) > 0;
}
+#define IS_COVERED_BY_POLLER_FMT "(final=%d elems=%" PRIdPTR ")->%d"
+#define IS_COVERED_BY_POLLER_ARGS(lock) \
+ (lock)->final_list_covered_by_poller, \
+ gpr_atm_acq_load(&(lock)->elements_covered_by_poller), \
+ is_covered_by_poller((lock))
+
grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue) {
grpc_combiner *lock = gpr_malloc(sizeof(*lock));
lock->next_combiner_on_this_exec_ctx = NULL;
@@ -197,9 +203,10 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
GRPC_COMBINER_TRACE(
gpr_log(GPR_DEBUG,
"C:%p grpc_combiner_continue_exec_ctx workqueue=%p "
- "is_covered_by_poller=%d exec_ctx_ready_to_finish=%d "
+ "is_covered_by_poller=" IS_COVERED_BY_POLLER_FMT
+ " exec_ctx_ready_to_finish=%d "
"time_to_execute_final_list=%d",
- lock, lock->optional_workqueue, is_covered_by_poller(lock),
+ lock, lock->optional_workqueue, IS_COVERED_BY_POLLER_ARGS(lock),
grpc_exec_ctx_ready_to_finish(exec_ctx),
lock->time_to_execute_final_list));
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index 91041a7c28..07fbfd849e 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -72,6 +72,11 @@ static int grpc_polling_trace = 0; /* Disabled by default */
static int grpc_wakeup_signal = -1;
static bool is_grpc_wakeup_signal_initialized = false;
+/* TODO: sreek: Right now, this wakes up all pollers. In future we should make
+ * sure to wake up one polling thread (which can wake up other threads if
+ * needed) */
+static grpc_wakeup_fd global_wakeup_fd;
+
/* Implements the function defined in grpc_posix.h. This function might be
* called before even calling grpc_init() to set either a different signal to
* use. If signum == -1, then the use of signals is disabled */
@@ -437,9 +442,8 @@ static void polling_island_add_wakeup_fd_locked(polling_island *pi,
gpr_asprintf(&err_msg,
"epoll_ctl (epoll_fd: %d) add wakeup fd: %d failed with "
"error: %d (%s)",
- pi->epoll_fd,
- GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), errno,
- strerror(errno));
+ pi->epoll_fd, GRPC_WAKEUP_FD_GET_READ_FD(&global_wakeup_fd),
+ errno, strerror(errno));
append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc);
gpr_free(err_msg);
}
@@ -541,7 +545,7 @@ static polling_island *polling_island_create(grpc_exec_ctx *exec_ctx,
goto done;
}
- polling_island_add_wakeup_fd_locked(pi, &grpc_global_wakeup_fd, error);
+ polling_island_add_wakeup_fd_locked(pi, &global_wakeup_fd, error);
polling_island_add_wakeup_fd_locked(pi, &pi->workqueue_wakeup_fd, error);
if (initial_fd != NULL) {
@@ -843,11 +847,6 @@ static void polling_island_global_shutdown() {
* alarm 'epoch'). This wakeup_fd gives us something to alert on when such a
* case occurs. */
-/* TODO: sreek: Right now, this wakes up all pollers. In future we should make
- * sure to wake up one polling thread (which can wake up other threads if
- * needed) */
-grpc_wakeup_fd grpc_global_wakeup_fd;
-
static grpc_fd *fd_freelist = NULL;
static gpr_mu fd_freelist_mu;
@@ -1163,11 +1162,11 @@ static grpc_error *pollset_global_init(void) {
gpr_tls_init(&g_current_thread_pollset);
gpr_tls_init(&g_current_thread_worker);
poller_kick_init();
- return grpc_wakeup_fd_init(&grpc_global_wakeup_fd);
+ return grpc_wakeup_fd_init(&global_wakeup_fd);
}
static void pollset_global_shutdown(void) {
- grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd);
+ grpc_wakeup_fd_destroy(&global_wakeup_fd);
gpr_tls_destroy(&g_current_thread_pollset);
gpr_tls_destroy(&g_current_thread_worker);
}
@@ -1274,7 +1273,7 @@ static grpc_error *pollset_kick(grpc_pollset *p,
}
static grpc_error *kick_poller(void) {
- return grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd);
+ return grpc_wakeup_fd_wakeup(&global_wakeup_fd);
}
static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
@@ -1501,13 +1500,11 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
for (int i = 0; i < ep_rv; ++i) {
void *data_ptr = ep_ev[i].data.ptr;
- if (data_ptr == &grpc_global_wakeup_fd) {
- append_error(error,
- grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd),
+ if (data_ptr == &global_wakeup_fd) {
+ append_error(error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
err_desc);
} else if (data_ptr == &pi->workqueue_wakeup_fd) {
- append_error(error,
- grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd),
+ append_error(error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
err_desc);
maybe_do_workqueue_work(exec_ctx, pi);
} else if (data_ptr == &polling_island_wakeup_fd) {
diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c
index 8f5d9d43fb..21b28e5554 100644
--- a/src/core/lib/iomgr/ev_poll_posix.c
+++ b/src/core/lib/iomgr/ev_poll_posix.c
@@ -120,6 +120,8 @@ struct grpc_fd {
grpc_pollset *read_notifier_pollset;
};
+static grpc_wakeup_fd global_wakeup_fd;
+
/* Begin polling on an fd.
Registers that the given pollset is interested in this fd - so that if read
or writability interest changes, the pollset can be kicked to pick up that
@@ -769,17 +771,17 @@ static grpc_error *pollset_kick(grpc_pollset *p,
static grpc_error *pollset_global_init(void) {
gpr_tls_init(&g_current_thread_poller);
gpr_tls_init(&g_current_thread_worker);
- return grpc_wakeup_fd_init(&grpc_global_wakeup_fd);
+ return grpc_wakeup_fd_init(&global_wakeup_fd);
}
static void pollset_global_shutdown(void) {
- grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd);
+ grpc_wakeup_fd_destroy(&global_wakeup_fd);
gpr_tls_destroy(&g_current_thread_poller);
gpr_tls_destroy(&g_current_thread_worker);
}
static grpc_error *kick_poller(void) {
- return grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd);
+ return grpc_wakeup_fd_wakeup(&global_wakeup_fd);
}
/* main interface */
@@ -947,7 +949,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
fd_count = 0;
pfd_count = 2;
- pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd);
+ pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&global_wakeup_fd);
pfds[0].events = POLLIN;
pfds[0].revents = 0;
pfds[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker.wakeup_fd->fd);
@@ -1001,8 +1003,8 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
}
} else {
if (pfds[0].revents & POLLIN_CHECK) {
- work_combine_error(
- &error, grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd));
+ work_combine_error(&error,
+ grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd));
}
if (pfds[1].revents & POLLIN_CHECK) {
work_combine_error(
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index 2fdef06838..cb5832539d 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -183,6 +183,5 @@ void grpc_pollset_set_del_fd(grpc_exec_ctx *exec_ctx,
/* override to allow tests to hook poll() usage */
typedef int (*grpc_poll_function_type)(struct pollfd *, nfds_t, int);
extern grpc_poll_function_type grpc_poll_function;
-extern grpc_wakeup_fd grpc_global_wakeup_fd;
#endif /* GRPC_CORE_LIB_IOMGR_EV_POSIX_H */
diff --git a/src/core/lib/iomgr/iomgr.c b/src/core/lib/iomgr/iomgr.c
index 4fd83e0b22..3470b5ac81 100644
--- a/src/core/lib/iomgr/iomgr.c
+++ b/src/core/lib/iomgr/iomgr.c
@@ -108,6 +108,7 @@ void grpc_iomgr_shutdown(void) {
NULL)) {
gpr_mu_unlock(&g_mu);
grpc_exec_ctx_flush(&exec_ctx);
+ grpc_iomgr_platform_flush();
gpr_mu_lock(&g_mu);
continue;
}
diff --git a/src/core/lib/iomgr/resource_quota.c b/src/core/lib/iomgr/resource_quota.c
index 051a30baa3..213d29600c 100644
--- a/src/core/lib/iomgr/resource_quota.c
+++ b/src/core/lib/iomgr/resource_quota.c
@@ -104,6 +104,9 @@ struct grpc_resource_user {
/* Reclaimers: index 0 is the benign reclaimer, 1 is the destructive reclaimer
*/
grpc_closure *reclaimers[2];
+ /* Reclaimers just posted: once we're in the combiner lock, we'll move them
+ to the array above */
+ grpc_closure *new_reclaimers[2];
/* Trampoline closures to finish reclamation and re-enter the quota combiner
lock */
grpc_closure post_reclaimer_closure[2];
@@ -141,6 +144,12 @@ struct grpc_resource_quota {
/* Closure around rq_reclamation_done */
grpc_closure rq_reclamation_done_closure;
+ /* This is only really usable for debugging: it's always a stale pointer, but
+ a stale pointer that might just be fresh enough to guide us to where the
+ reclamation system is stuck */
+ grpc_closure *debug_only_last_initiated_reclaimer;
+ grpc_resource_user *debug_only_last_reclaimer_resource_user;
+
/* Roots of all resource user lists */
grpc_resource_user *roots[GRPC_RULIST_COUNT];
@@ -222,6 +231,7 @@ static void rulist_remove(grpc_resource_user *resource_user, grpc_rulist list) {
resource_user->links[list].prev;
resource_user->links[list].prev->links[list].next =
resource_user->links[list].next;
+ resource_user->links[list].next = resource_user->links[list].prev = NULL;
}
/*******************************************************************************
@@ -337,6 +347,9 @@ static bool rq_reclaim(grpc_exec_ctx *exec_ctx,
resource_quota->reclaiming = true;
grpc_resource_quota_internal_ref(resource_quota);
grpc_closure *c = resource_user->reclaimers[destructive];
+ GPR_ASSERT(c);
+ resource_quota->debug_only_last_reclaimer_resource_user = resource_user;
+ resource_quota->debug_only_last_initiated_reclaimer = c;
resource_user->reclaimers[destructive] = NULL;
grpc_closure_run(exec_ctx, c, GRPC_ERROR_NONE);
return true;
@@ -418,9 +431,25 @@ static void ru_add_to_free_pool(grpc_exec_ctx *exec_ctx, void *ru,
rulist_add_tail(resource_user, GRPC_RULIST_NON_EMPTY_FREE_POOL);
}
+static bool ru_post_reclaimer(grpc_exec_ctx *exec_ctx,
+ grpc_resource_user *resource_user,
+ bool destructive) {
+ grpc_closure *closure = resource_user->new_reclaimers[destructive];
+ GPR_ASSERT(closure != NULL);
+ resource_user->new_reclaimers[destructive] = NULL;
+ GPR_ASSERT(resource_user->reclaimers[destructive] == NULL);
+ if (gpr_atm_acq_load(&resource_user->shutdown) > 0) {
+ grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_CANCELLED, NULL);
+ return false;
+ }
+ resource_user->reclaimers[destructive] = closure;
+ return true;
+}
+
static void ru_post_benign_reclaimer(grpc_exec_ctx *exec_ctx, void *ru,
grpc_error *error) {
grpc_resource_user *resource_user = ru;
+ if (!ru_post_reclaimer(exec_ctx, resource_user, false)) return;
if (!rulist_empty(resource_user->resource_quota,
GRPC_RULIST_AWAITING_ALLOCATION) &&
rulist_empty(resource_user->resource_quota,
@@ -435,6 +464,7 @@ static void ru_post_benign_reclaimer(grpc_exec_ctx *exec_ctx, void *ru,
static void ru_post_destructive_reclaimer(grpc_exec_ctx *exec_ctx, void *ru,
grpc_error *error) {
grpc_resource_user *resource_user = ru;
+ if (!ru_post_reclaimer(exec_ctx, resource_user, true)) return;
if (!rulist_empty(resource_user->resource_quota,
GRPC_RULIST_AWAITING_ALLOCATION) &&
rulist_empty(resource_user->resource_quota,
@@ -456,6 +486,8 @@ static void ru_shutdown(grpc_exec_ctx *exec_ctx, void *ru, grpc_error *error) {
GRPC_ERROR_CANCELLED, NULL);
resource_user->reclaimers[0] = NULL;
resource_user->reclaimers[1] = NULL;
+ rulist_remove(resource_user, GRPC_RULIST_RECLAIMER_BENIGN);
+ rulist_remove(resource_user, GRPC_RULIST_RECLAIMER_DESTRUCTIVE);
}
static void ru_destroy(grpc_exec_ctx *exec_ctx, void *ru, grpc_error *error) {
@@ -649,6 +681,8 @@ grpc_resource_user *grpc_resource_user_create(
resource_user->added_to_free_pool = false;
resource_user->reclaimers[0] = NULL;
resource_user->reclaimers[1] = NULL;
+ resource_user->new_reclaimers[0] = NULL;
+ resource_user->new_reclaimers[1] = NULL;
for (int i = 0; i < GRPC_RULIST_COUNT; i++) {
resource_user->links[i].next = resource_user->links[i].prev = NULL;
}
@@ -748,12 +782,8 @@ void grpc_resource_user_post_reclaimer(grpc_exec_ctx *exec_ctx,
grpc_resource_user *resource_user,
bool destructive,
grpc_closure *closure) {
- GPR_ASSERT(resource_user->reclaimers[destructive] == NULL);
- if (gpr_atm_acq_load(&resource_user->shutdown) > 0) {
- grpc_exec_ctx_sched(exec_ctx, closure, GRPC_ERROR_CANCELLED, NULL);
- return;
- }
- resource_user->reclaimers[destructive] = closure;
+ GPR_ASSERT(resource_user->new_reclaimers[destructive] == NULL);
+ resource_user->new_reclaimers[destructive] = closure;
grpc_combiner_execute(exec_ctx, resource_user->resource_quota->combiner,
&resource_user->post_reclaimer_closure[destructive],
GRPC_ERROR_NONE, false);
diff --git a/src/core/lib/iomgr/socket_windows.c b/src/core/lib/iomgr/socket_windows.c
index 35f23300dc..54911e0e31 100644
--- a/src/core/lib/iomgr/socket_windows.c
+++ b/src/core/lib/iomgr/socket_windows.c
@@ -76,6 +76,14 @@ void grpc_winsocket_shutdown(grpc_winsocket *winsocket) {
LPFN_DISCONNECTEX DisconnectEx;
DWORD ioctl_num_bytes;
+ gpr_mu_lock(&winsocket->state_mu);
+ if (winsocket->shutdown_called) {
+ gpr_mu_unlock(&winsocket->state_mu);
+ return;
+ }
+ winsocket->shutdown_called = true;
+ gpr_mu_unlock(&winsocket->state_mu);
+
status = WSAIoctl(winsocket->socket, SIO_GET_EXTENSION_FUNCTION_POINTER,
&guid, sizeof(guid), &DisconnectEx, sizeof(DisconnectEx),
&ioctl_num_bytes, NULL, NULL);
diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h
index 490d0e0a06..a3875ce16c 100644
--- a/src/core/lib/iomgr/socket_windows.h
+++ b/src/core/lib/iomgr/socket_windows.h
@@ -87,6 +87,7 @@ typedef struct grpc_winsocket {
grpc_winsocket_callback_info read_info;
gpr_mu state_mu;
+ bool shutdown_called;
/* You can't add the same socket twice to the same IO Completion Port.
This prevents that. */
diff --git a/src/core/lib/iomgr/tcp_client_windows.c b/src/core/lib/iomgr/tcp_client_windows.c
index 4d1e809872..1127588ebc 100644
--- a/src/core/lib/iomgr/tcp_client_windows.c
+++ b/src/core/lib/iomgr/tcp_client_windows.c
@@ -107,18 +107,22 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
gpr_mu_lock(&ac->mu);
- if (error == GRPC_ERROR_NONE && socket != NULL) {
- DWORD transfered_bytes = 0;
- DWORD flags;
- BOOL wsa_success =
- WSAGetOverlappedResult(socket->socket, &socket->write_info.overlapped,
- &transfered_bytes, FALSE, &flags);
- GPR_ASSERT(transfered_bytes == 0);
- if (!wsa_success) {
- error = GRPC_WSA_ERROR(WSAGetLastError(), "ConnectEx");
+ if (error == GRPC_ERROR_NONE) {
+ if (socket != NULL) {
+ DWORD transfered_bytes = 0;
+ DWORD flags;
+ BOOL wsa_success =
+ WSAGetOverlappedResult(socket->socket, &socket->write_info.overlapped,
+ &transfered_bytes, FALSE, &flags);
+ GPR_ASSERT(transfered_bytes == 0);
+ if (!wsa_success) {
+ error = GRPC_WSA_ERROR(WSAGetLastError(), "ConnectEx");
+ } else {
+ *ep = grpc_tcp_create(socket, ac->resource_quota, ac->addr_name);
+ socket = NULL;
+ }
} else {
- *ep = grpc_tcp_create(socket, ac->resource_quota, ac->addr_name);
- socket = NULL;
+ error = GRPC_ERROR_CREATE("socket is null");
}
}
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index ae54c70d2d..b8a391c059 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -73,6 +73,7 @@ struct grpc_tcp_listener {
/* The cached AcceptEx for that port. */
LPFN_ACCEPTEX AcceptEx;
int shutting_down;
+ int outstanding_calls;
/* closure for socket notification of accept being ready */
grpc_closure on_accept;
/* linked list */
@@ -140,10 +141,9 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
return GRPC_ERROR_NONE;
}
-static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
- if (s->shutdown_complete != NULL) {
- grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL);
- }
+static void destroy_server(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ grpc_tcp_server *s = arg;
/* Now that the accepts have been aborted, we can destroy the sockets.
The IOCP won't get notified on these, so we can flag them as already
@@ -159,6 +159,16 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
gpr_free(s);
}
+static void finish_shutdown_locked(grpc_exec_ctx *exec_ctx,
+ grpc_tcp_server *s) {
+ if (s->shutdown_complete != NULL) {
+ grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL);
+ }
+
+ grpc_exec_ctx_sched(exec_ctx, grpc_closure_create(destroy_server, s),
+ GRPC_ERROR_NONE, NULL);
+}
+
grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
gpr_ref_non_zero(&s->refs);
return s;
@@ -180,17 +190,14 @@ static void tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
/* First, shutdown all fd's. This will queue abortion calls for all
of the pending accepts due to the normal operation mechanism. */
if (s->active_ports == 0) {
- immediately_done = 1;
- }
- for (sp = s->head; sp; sp = sp->next) {
- sp->shutting_down = 1;
- grpc_winsocket_shutdown(sp->socket);
+ finish_shutdown_locked(exec_ctx, s);
+ } else {
+ for (sp = s->head; sp; sp = sp->next) {
+ sp->shutting_down = 1;
+ grpc_winsocket_shutdown(sp->socket);
+ }
}
gpr_mu_unlock(&s->mu);
-
- if (immediately_done) {
- finish_shutdown(exec_ctx, s);
- }
}
void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
@@ -251,31 +258,30 @@ failure:
return error;
}
-static void decrement_active_ports_and_notify(grpc_exec_ctx *exec_ctx,
- grpc_tcp_listener *sp) {
+static void decrement_active_ports_and_notify_locked(grpc_exec_ctx *exec_ctx,
+ grpc_tcp_listener *sp) {
int notify = 0;
sp->shutting_down = 0;
- gpr_mu_lock(&sp->server->mu);
GPR_ASSERT(sp->server->active_ports > 0);
if (0 == --sp->server->active_ports) {
- notify = 1;
- }
- gpr_mu_unlock(&sp->server->mu);
- if (notify) {
- finish_shutdown(exec_ctx, sp->server);
+ finish_shutdown_locked(exec_ctx, sp->server);
}
}
/* In order to do an async accept, we need to create a socket first which
will be the one assigned to the new incoming connection. */
-static grpc_error *start_accept(grpc_exec_ctx *exec_ctx,
- grpc_tcp_listener *port) {
+static grpc_error *start_accept_locked(grpc_exec_ctx *exec_ctx,
+ grpc_tcp_listener *port) {
SOCKET sock = INVALID_SOCKET;
BOOL success;
DWORD addrlen = sizeof(struct sockaddr_in6) + 16;
DWORD bytes_received = 0;
grpc_error *error = GRPC_ERROR_NONE;
+ if (port->shutting_down) {
+ return GRPC_ERROR_NONE;
+ }
+
sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0,
WSA_FLAG_OVERLAPPED);
if (sock == INVALID_SOCKET) {
@@ -305,20 +311,11 @@ static grpc_error *start_accept(grpc_exec_ctx *exec_ctx,
immediately process an accept that happened in the meantime. */
port->new_socket = sock;
grpc_socket_notify_on_read(exec_ctx, port->socket, &port->on_accept);
+ port->outstanding_calls++;
return error;
failure:
GPR_ASSERT(error != GRPC_ERROR_NONE);
- if (port->shutting_down) {
- /* We are abandoning the listener port, take that into account to prevent
- occasional hangs on shutdown. The hang happens when sp->shutting_down
- change is not seen by on_accept and we proceed to trying new accept,
- but we fail there because the listening port has been closed in the
- meantime. */
- decrement_active_ports_and_notify(exec_ctx, port);
- GRPC_ERROR_UNREF(error);
- return GRPC_ERROR_NONE;
- }
if (sock != INVALID_SOCKET) closesocket(sock);
return error;
}
@@ -338,6 +335,8 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
BOOL wsa_success;
int err;
+ gpr_mu_lock(&sp->server->mu);
+
peer_name.len = sizeof(struct sockaddr_storage);
/* The general mechanism for shutting down is to queue abortion calls. While
@@ -347,6 +346,7 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
const char *msg = grpc_error_string(error);
gpr_log(GPR_INFO, "Skipping on_accept due to error: %s", msg);
grpc_error_free_string(msg);
+ gpr_mu_unlock(&sp->server->mu);
return;
}
@@ -356,17 +356,12 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
wsa_success = WSAGetOverlappedResult(sock, &info->overlapped,
&transfered_bytes, FALSE, &flags);
if (!wsa_success) {
- if (sp->shutting_down) {
- /* During the shutdown case, we ARE expecting an error. So that's well,
- and we can wake up the shutdown thread. */
- decrement_active_ports_and_notify(exec_ctx, sp);
- return;
- } else {
+ if (!sp->shutting_down) {
char *utf8_message = gpr_format_message(WSAGetLastError());
gpr_log(GPR_ERROR, "on_accept error: %s", utf8_message);
gpr_free(utf8_message);
- closesocket(sock);
}
+ closesocket(sock);
} else {
if (!sp->shutting_down) {
peer_name_string = NULL;
@@ -408,7 +403,12 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
the former socked we created has now either been destroy or assigned
to the new connection. We need to create a new one for the next
connection. */
- GPR_ASSERT(GRPC_LOG_IF_ERROR("start_accept", start_accept(exec_ctx, sp)));
+ GPR_ASSERT(
+ GRPC_LOG_IF_ERROR("start_accept", start_accept_locked(exec_ctx, sp)));
+ if (0 == --sp->outstanding_calls) {
+ decrement_active_ports_and_notify_locked(exec_ctx, sp);
+ }
+ gpr_mu_unlock(&sp->server->mu);
}
static grpc_error *add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
@@ -456,6 +456,7 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
sp->server = s;
sp->socket = grpc_winsocket_create(sock, "listener");
sp->shutting_down = 0;
+ sp->outstanding_calls = 0;
sp->AcceptEx = AcceptEx;
sp->new_socket = INVALID_SOCKET;
sp->port = port;
@@ -553,7 +554,8 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
s->on_accept_cb = on_accept_cb;
s->on_accept_cb_arg = on_accept_cb_arg;
for (sp = s->head; sp; sp = sp->next) {
- GPR_ASSERT(GRPC_LOG_IF_ERROR("start_accept", start_accept(exec_ctx, sp)));
+ GPR_ASSERT(
+ GRPC_LOG_IF_ERROR("start_accept", start_accept_locked(exec_ctx, sp)));
s->active_ports++;
}
gpr_mu_unlock(&s->mu);
diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c
index fd0c7a0f9d..3c24ea9afa 100644
--- a/src/core/lib/iomgr/udp_server.c
+++ b/src/core/lib/iomgr/udp_server.c
@@ -388,7 +388,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s,
/* Try listening on IPv6 first. */
addr = &wild6;
// TODO(rjshade): Test and propagate the returned grpc_error*:
- grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd);
+ GRPC_ERROR_UNREF(grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP,
+ &dsmode, &fd));
allocated_port1 = add_socket_to_server(s, fd, addr, read_cb, orphan_cb);
if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
goto done;
@@ -402,7 +403,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s,
}
// TODO(rjshade): Test and propagate the returned grpc_error*:
- grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd);
+ GRPC_ERROR_UNREF(grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP,
+ &dsmode, &fd));
if (fd < 0) {
gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno));
}
diff --git a/src/core/lib/security/transport/handshake.c b/src/core/lib/security/transport/handshake.c
deleted file mode 100644
index 9623797610..0000000000
--- a/src/core/lib/security/transport/handshake.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/core/lib/security/transport/handshake.h"
-
-#include <stdbool.h>
-#include <string.h>
-
-#include <grpc/slice_buffer.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include "src/core/lib/iomgr/timer.h"
-#include "src/core/lib/security/context/security_context.h"
-#include "src/core/lib/security/transport/secure_endpoint.h"
-#include "src/core/lib/security/transport/tsi_error.h"
-
-#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
-
-typedef struct {
- grpc_security_connector *connector;
- tsi_handshaker *handshaker;
- bool is_client_side;
- unsigned char *handshake_buffer;
- size_t handshake_buffer_size;
- grpc_endpoint *wrapped_endpoint;
- grpc_endpoint *secure_endpoint;
- grpc_slice_buffer left_overs;
- grpc_slice_buffer incoming;
- grpc_slice_buffer outgoing;
- grpc_security_handshake_done_cb cb;
- void *user_data;
- grpc_closure on_handshake_data_sent_to_peer;
- grpc_closure on_handshake_data_received_from_peer;
- grpc_auth_context *auth_context;
- grpc_timer timer;
- gpr_refcount refs;
-} grpc_security_handshake;
-
-static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
- void *setup,
- grpc_error *error);
-
-static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *setup,
- grpc_error *error);
-
-static void security_connector_remove_handshake(grpc_security_handshake *h) {
- GPR_ASSERT(!h->is_client_side);
- grpc_security_connector_handshake_list *node;
- grpc_security_connector_handshake_list *tmp;
- grpc_server_security_connector *sc =
- (grpc_server_security_connector *)h->connector;
- gpr_mu_lock(&sc->mu);
- node = sc->handshaking_handshakes;
- if (node && node->handshake == h) {
- sc->handshaking_handshakes = node->next;
- gpr_free(node);
- gpr_mu_unlock(&sc->mu);
- return;
- }
- while (node) {
- if (node->next->handshake == h) {
- tmp = node->next;
- node->next = node->next->next;
- gpr_free(tmp);
- gpr_mu_unlock(&sc->mu);
- return;
- }
- node = node->next;
- }
- gpr_mu_unlock(&sc->mu);
-}
-
-static void unref_handshake(grpc_security_handshake *h) {
- if (gpr_unref(&h->refs)) {
- if (h->handshaker != NULL) tsi_handshaker_destroy(h->handshaker);
- if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer);
- grpc_slice_buffer_destroy(&h->left_overs);
- grpc_slice_buffer_destroy(&h->outgoing);
- grpc_slice_buffer_destroy(&h->incoming);
- GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake");
- GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake");
- gpr_free(h);
- }
-}
-
-static void security_handshake_done(grpc_exec_ctx *exec_ctx,
- grpc_security_handshake *h,
- grpc_error *error) {
- grpc_timer_cancel(exec_ctx, &h->timer);
- if (!h->is_client_side) {
- security_connector_remove_handshake(h);
- }
- if (error == GRPC_ERROR_NONE) {
- h->cb(exec_ctx, h->user_data, GRPC_SECURITY_OK, h->secure_endpoint,
- h->auth_context);
- } else {
- const char *msg = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "Security handshake failed: %s", msg);
- grpc_error_free_string(msg);
-
- if (h->secure_endpoint != NULL) {
- grpc_endpoint_shutdown(exec_ctx, h->secure_endpoint);
- grpc_endpoint_destroy(exec_ctx, h->secure_endpoint);
- } else {
- grpc_endpoint_destroy(exec_ctx, h->wrapped_endpoint);
- }
- h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, NULL, NULL);
- }
- unref_handshake(h);
- GRPC_ERROR_UNREF(error);
-}
-
-static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *user_data,
- grpc_security_status status,
- grpc_auth_context *auth_context) {
- grpc_security_handshake *h = user_data;
- tsi_frame_protector *protector;
- tsi_result result;
- if (status != GRPC_SECURITY_OK) {
- security_handshake_done(
- exec_ctx, h,
- grpc_error_set_int(GRPC_ERROR_CREATE("Error checking peer."),
- GRPC_ERROR_INT_SECURITY_STATUS, status));
- return;
- }
- h->auth_context = GRPC_AUTH_CONTEXT_REF(auth_context, "handshake");
- result =
- tsi_handshaker_create_frame_protector(h->handshaker, NULL, &protector);
- if (result != TSI_OK) {
- security_handshake_done(
- exec_ctx, h,
- grpc_set_tsi_error_result(
- GRPC_ERROR_CREATE("Frame protector creation failed"), result));
- return;
- }
- h->secure_endpoint =
- grpc_secure_endpoint_create(protector, h->wrapped_endpoint,
- h->left_overs.slices, h->left_overs.count);
- h->left_overs.count = 0;
- h->left_overs.length = 0;
- security_handshake_done(exec_ctx, h, GRPC_ERROR_NONE);
- return;
-}
-
-static void check_peer(grpc_exec_ctx *exec_ctx, grpc_security_handshake *h) {
- tsi_peer peer;
- tsi_result result = tsi_handshaker_extract_peer(h->handshaker, &peer);
-
- if (result != TSI_OK) {
- security_handshake_done(
- exec_ctx, h, grpc_set_tsi_error_result(
- GRPC_ERROR_CREATE("Peer extraction failed"), result));
- return;
- }
- grpc_security_connector_check_peer(exec_ctx, h->connector, peer,
- on_peer_checked, h);
-}
-
-static void send_handshake_bytes_to_peer(grpc_exec_ctx *exec_ctx,
- grpc_security_handshake *h) {
- size_t offset = 0;
- tsi_result result = TSI_OK;
- grpc_slice to_send;
-
- do {
- size_t to_send_size = h->handshake_buffer_size - offset;
- result = tsi_handshaker_get_bytes_to_send_to_peer(
- h->handshaker, h->handshake_buffer + offset, &to_send_size);
- offset += to_send_size;
- if (result == TSI_INCOMPLETE_DATA) {
- h->handshake_buffer_size *= 2;
- h->handshake_buffer =
- gpr_realloc(h->handshake_buffer, h->handshake_buffer_size);
- }
- } while (result == TSI_INCOMPLETE_DATA);
-
- if (result != TSI_OK) {
- security_handshake_done(exec_ctx, h,
- grpc_set_tsi_error_result(
- GRPC_ERROR_CREATE("Handshake failed"), result));
- return;
- }
-
- to_send =
- grpc_slice_from_copied_buffer((const char *)h->handshake_buffer, offset);
- grpc_slice_buffer_reset_and_unref(&h->outgoing);
- grpc_slice_buffer_add(&h->outgoing, to_send);
- /* TODO(klempner,jboeuf): This should probably use the client setup
- deadline */
- grpc_endpoint_write(exec_ctx, h->wrapped_endpoint, &h->outgoing,
- &h->on_handshake_data_sent_to_peer);
-}
-
-static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
- void *handshake,
- grpc_error *error) {
- grpc_security_handshake *h = handshake;
- size_t consumed_slice_size = 0;
- tsi_result result = TSI_OK;
- size_t i;
- size_t num_left_overs;
- int has_left_overs_in_current_slice = 0;
-
- if (error != GRPC_ERROR_NONE) {
- security_handshake_done(
- exec_ctx, h,
- GRPC_ERROR_CREATE_REFERENCING("Handshake read failed", &error, 1));
- return;
- }
-
- for (i = 0; i < h->incoming.count; i++) {
- consumed_slice_size = GRPC_SLICE_LENGTH(h->incoming.slices[i]);
- result = tsi_handshaker_process_bytes_from_peer(
- h->handshaker, GRPC_SLICE_START_PTR(h->incoming.slices[i]),
- &consumed_slice_size);
- if (!tsi_handshaker_is_in_progress(h->handshaker)) break;
- }
-
- if (tsi_handshaker_is_in_progress(h->handshaker)) {
- /* We may need more data. */
- if (result == TSI_INCOMPLETE_DATA) {
- grpc_endpoint_read(exec_ctx, h->wrapped_endpoint, &h->incoming,
- &h->on_handshake_data_received_from_peer);
- return;
- } else {
- send_handshake_bytes_to_peer(exec_ctx, h);
- return;
- }
- }
-
- if (result != TSI_OK) {
- security_handshake_done(exec_ctx, h,
- grpc_set_tsi_error_result(
- GRPC_ERROR_CREATE("Handshake failed"), result));
- return;
- }
-
- /* Handshake is done and successful this point. */
- has_left_overs_in_current_slice =
- (consumed_slice_size < GRPC_SLICE_LENGTH(h->incoming.slices[i]));
- num_left_overs =
- (has_left_overs_in_current_slice ? 1 : 0) + h->incoming.count - i - 1;
- if (num_left_overs == 0) {
- check_peer(exec_ctx, h);
- return;
- }
-
- /* Put the leftovers in our buffer (ownership transfered). */
- if (has_left_overs_in_current_slice) {
- grpc_slice_buffer_add(
- &h->left_overs,
- grpc_slice_split_tail(&h->incoming.slices[i], consumed_slice_size));
- grpc_slice_unref(
- h->incoming.slices[i]); /* split_tail above increments refcount. */
- }
- grpc_slice_buffer_addn(
- &h->left_overs, &h->incoming.slices[i + 1],
- num_left_overs - (size_t)has_left_overs_in_current_slice);
- check_peer(exec_ctx, h);
-}
-
-/* If handshake is NULL, the handshake is done. */
-static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx,
- void *handshake, grpc_error *error) {
- grpc_security_handshake *h = handshake;
-
- /* Make sure that write is OK. */
- if (error != GRPC_ERROR_NONE) {
- if (handshake != NULL)
- security_handshake_done(
- exec_ctx, h,
- GRPC_ERROR_CREATE_REFERENCING("Handshake write failed", &error, 1));
- return;
- }
-
- /* We may be done. */
- if (tsi_handshaker_is_in_progress(h->handshaker)) {
- /* TODO(klempner,jboeuf): This should probably use the client setup
- deadline */
- grpc_endpoint_read(exec_ctx, h->wrapped_endpoint, &h->incoming,
- &h->on_handshake_data_received_from_peer);
- } else {
- check_peer(exec_ctx, h);
- }
-}
-
-static void on_timeout(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
- grpc_security_handshake *h = arg;
- if (error == GRPC_ERROR_NONE) {
- grpc_endpoint_shutdown(exec_ctx, h->wrapped_endpoint);
- }
- unref_handshake(h);
-}
-
-void grpc_do_security_handshake(
- grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker,
- grpc_security_connector *connector, bool is_client_side,
- grpc_endpoint *nonsecure_endpoint, grpc_slice_buffer *read_buffer,
- gpr_timespec deadline, grpc_security_handshake_done_cb cb,
- void *user_data) {
- grpc_security_connector_handshake_list *handshake_node;
- grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake));
- memset(h, 0, sizeof(grpc_security_handshake));
- h->handshaker = handshaker;
- h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake");
- h->is_client_side = is_client_side;
- h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
- h->handshake_buffer = gpr_malloc(h->handshake_buffer_size);
- h->wrapped_endpoint = nonsecure_endpoint;
- h->user_data = user_data;
- h->cb = cb;
- gpr_ref_init(&h->refs, 2); /* timer and handshake proper each get a ref */
- grpc_closure_init(&h->on_handshake_data_sent_to_peer,
- on_handshake_data_sent_to_peer, h);
- grpc_closure_init(&h->on_handshake_data_received_from_peer,
- on_handshake_data_received_from_peer, h);
- grpc_slice_buffer_init(&h->left_overs);
- grpc_slice_buffer_init(&h->outgoing);
- grpc_slice_buffer_init(&h->incoming);
- if (read_buffer != NULL) {
- grpc_slice_buffer_move_into(read_buffer, &h->incoming);
- gpr_free(read_buffer);
- }
- if (!is_client_side) {
- grpc_server_security_connector *server_connector =
- (grpc_server_security_connector *)connector;
- handshake_node = gpr_malloc(sizeof(grpc_security_connector_handshake_list));
- handshake_node->handshake = h;
- gpr_mu_lock(&server_connector->mu);
- handshake_node->next = server_connector->handshaking_handshakes;
- server_connector->handshaking_handshakes = handshake_node;
- gpr_mu_unlock(&server_connector->mu);
- }
- send_handshake_bytes_to_peer(exec_ctx, h);
- grpc_timer_init(exec_ctx, &h->timer,
- gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
- on_timeout, h, gpr_now(GPR_CLOCK_MONOTONIC));
-}
-
-void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx,
- void *handshake) {
- grpc_security_handshake *h = handshake;
- grpc_endpoint_shutdown(exec_ctx, h->wrapped_endpoint);
-}
diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c
index 0fbd63a7e1..a2e0c7c7c7 100644
--- a/src/core/lib/security/transport/security_connector.c
+++ b/src/core/lib/security/transport/security_connector.c
@@ -46,8 +46,8 @@
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/security/transport/handshake.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
+#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/lib/support/env.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/tsi/fake_transport_security.h"
@@ -111,58 +111,34 @@ const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
return NULL;
}
-void grpc_server_security_connector_shutdown(
- grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector) {
- grpc_security_connector_handshake_list *tmp;
- gpr_mu_lock(&connector->mu);
- while (connector->handshaking_handshakes) {
- tmp = connector->handshaking_handshakes;
- grpc_security_handshake_shutdown(
- exec_ctx, connector->handshaking_handshakes->handshake);
- connector->handshaking_handshakes = tmp->next;
- gpr_free(tmp);
+void grpc_channel_security_connector_create_handshakers(
+ grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector,
+ grpc_handshake_manager *handshake_mgr) {
+ if (connector != NULL) {
+ connector->create_handshakers(exec_ctx, connector, handshake_mgr);
}
- gpr_mu_unlock(&connector->mu);
}
-void grpc_channel_security_connector_do_handshake(
- grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
- grpc_endpoint *nonsecure_endpoint, grpc_slice_buffer *read_buffer,
- gpr_timespec deadline, grpc_security_handshake_done_cb cb,
- void *user_data) {
- if (sc == NULL || nonsecure_endpoint == NULL) {
- gpr_free(read_buffer);
- cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
- } else {
- sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, read_buffer, deadline,
- cb, user_data);
- }
-}
-
-void grpc_server_security_connector_do_handshake(
- grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
- grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
- grpc_slice_buffer *read_buffer, gpr_timespec deadline,
- grpc_security_handshake_done_cb cb, void *user_data) {
- if (sc == NULL || nonsecure_endpoint == NULL) {
- gpr_free(read_buffer);
- cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
- } else {
- sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, read_buffer,
- deadline, cb, user_data);
+void grpc_server_security_connector_create_handshakers(
+ grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector,
+ grpc_handshake_manager *handshake_mgr) {
+ if (connector != NULL) {
+ connector->create_handshakers(exec_ctx, connector, handshake_mgr);
}
}
void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc,
tsi_peer peer,
- grpc_security_peer_check_cb cb,
- void *user_data) {
+ grpc_auth_context **auth_context,
+ grpc_closure *on_peer_checked) {
if (sc == NULL) {
- cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL);
+ grpc_exec_ctx_sched(
+ exec_ctx, on_peer_checked,
+ GRPC_ERROR_CREATE("cannot check peer -- no security connector"), NULL);
tsi_peer_destruct(&peer);
} else {
- sc->vtable->check_peer(exec_ctx, sc, peer, cb, user_data);
+ sc->vtable->check_peer(exec_ctx, sc, peer, auth_context, on_peer_checked);
}
}
@@ -262,45 +238,41 @@ static void fake_channel_destroy(grpc_security_connector *sc) {
gpr_free(sc);
}
-static void fake_server_destroy(grpc_security_connector *sc) {
- grpc_server_security_connector *c = (grpc_server_security_connector *)sc;
- gpr_mu_destroy(&c->mu);
- gpr_free(sc);
-}
+static void fake_server_destroy(grpc_security_connector *sc) { gpr_free(sc); }
static void fake_check_peer(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, tsi_peer peer,
- grpc_security_peer_check_cb cb, void *user_data) {
+ grpc_auth_context **auth_context,
+ grpc_closure *on_peer_checked) {
const char *prop_name;
- grpc_security_status status = GRPC_SECURITY_OK;
- grpc_auth_context *auth_context = NULL;
+ grpc_error *error = GRPC_ERROR_NONE;
+ *auth_context = NULL;
if (peer.property_count != 1) {
- gpr_log(GPR_ERROR, "Fake peers should only have 1 property.");
- status = GRPC_SECURITY_ERROR;
+ error = GRPC_ERROR_CREATE("Fake peers should only have 1 property.");
goto end;
}
prop_name = peer.properties[0].name;
if (prop_name == NULL ||
strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) {
- gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.",
- prop_name == NULL ? "<EMPTY>" : prop_name);
- status = GRPC_SECURITY_ERROR;
+ char *msg;
+ gpr_asprintf(&msg, "Unexpected property in fake peer: %s.",
+ prop_name == NULL ? "<EMPTY>" : prop_name);
+ error = GRPC_ERROR_CREATE(msg);
+ gpr_free(msg);
goto end;
}
if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE,
peer.properties[0].value.length)) {
- gpr_log(GPR_ERROR, "Invalid value for cert type property.");
- status = GRPC_SECURITY_ERROR;
+ error = GRPC_ERROR_CREATE("Invalid value for cert type property.");
goto end;
}
- auth_context = grpc_auth_context_create(NULL);
+ *auth_context = grpc_auth_context_create(NULL);
grpc_auth_context_add_cstring_property(
- auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
+ *auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_FAKE_TRANSPORT_SECURITY_TYPE);
end:
- cb(exec_ctx, user_data, status, auth_context);
- grpc_auth_context_unref(auth_context);
+ grpc_exec_ctx_sched(exec_ctx, on_peer_checked, error, NULL);
tsi_peer_destruct(&peer);
}
@@ -313,26 +285,20 @@ static void fake_channel_check_call_host(grpc_exec_ctx *exec_ctx,
cb(exec_ctx, user_data, GRPC_SECURITY_OK);
}
-static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx,
- grpc_channel_security_connector *sc,
- grpc_endpoint *nonsecure_endpoint,
- grpc_slice_buffer *read_buffer,
- gpr_timespec deadline,
- grpc_security_handshake_done_cb cb,
- void *user_data) {
- grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), &sc->base,
- true, nonsecure_endpoint, read_buffer, deadline,
- cb, user_data);
+static void fake_channel_create_handshakers(
+ grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
+ grpc_handshake_manager *handshake_mgr) {
+ grpc_security_create_handshakers(
+ exec_ctx, tsi_create_fake_handshaker(true /* is_client */), &sc->base,
+ handshake_mgr);
}
-static void fake_server_do_handshake(
+static void fake_server_create_handshakers(
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
- grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
- grpc_slice_buffer *read_buffer, gpr_timespec deadline,
- grpc_security_handshake_done_cb cb, void *user_data) {
- grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base,
- false, nonsecure_endpoint, read_buffer, deadline,
- cb, user_data);
+ grpc_handshake_manager *handshake_mgr) {
+ grpc_security_create_handshakers(
+ exec_ctx, tsi_create_fake_handshaker(false /* is_client */), &sc->base,
+ handshake_mgr);
}
static grpc_security_connector_vtable fake_channel_vtable = {
@@ -350,7 +316,7 @@ grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
c->base.vtable = &fake_channel_vtable;
c->request_metadata_creds = grpc_call_credentials_ref(request_metadata_creds);
c->check_call_host = fake_channel_check_call_host;
- c->do_handshake = fake_channel_do_handshake;
+ c->create_handshakers = fake_channel_create_handshakers;
return c;
}
@@ -362,8 +328,7 @@ grpc_server_security_connector *grpc_fake_server_security_connector_create(
gpr_ref_init(&c->base.refcount, 1);
c->base.vtable = &fake_server_vtable;
c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
- c->do_handshake = fake_server_do_handshake;
- gpr_mu_init(&c->mu);
+ c->create_handshakers = fake_server_create_handshakers;
return c;
}
@@ -396,11 +361,9 @@ static void ssl_channel_destroy(grpc_security_connector *sc) {
static void ssl_server_destroy(grpc_security_connector *sc) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)sc;
-
if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
- gpr_mu_destroy(&c->base.mu);
gpr_free(sc);
}
@@ -419,49 +382,33 @@ static grpc_security_status ssl_create_handshaker(
return GRPC_SECURITY_OK;
}
-static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
- grpc_channel_security_connector *sc,
- grpc_endpoint *nonsecure_endpoint,
- grpc_slice_buffer *read_buffer,
- gpr_timespec deadline,
- grpc_security_handshake_done_cb cb,
- void *user_data) {
+static void ssl_channel_create_handshakers(
+ grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
+ grpc_handshake_manager *handshake_mgr) {
grpc_ssl_channel_security_connector *c =
(grpc_ssl_channel_security_connector *)sc;
- tsi_handshaker *handshaker;
- grpc_security_status status = ssl_create_handshaker(
- c->handshaker_factory, true,
- c->overridden_target_name != NULL ? c->overridden_target_name
- : c->target_name,
- &handshaker);
- if (status != GRPC_SECURITY_OK) {
- gpr_free(read_buffer);
- cb(exec_ctx, user_data, status, NULL, NULL);
- } else {
- grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
- nonsecure_endpoint, read_buffer, deadline, cb,
- user_data);
- }
-}
-
-static void ssl_server_do_handshake(
+ // Instantiate TSI handshaker.
+ tsi_handshaker *tsi_hs = NULL;
+ ssl_create_handshaker(c->handshaker_factory, true /* is_client */,
+ c->overridden_target_name != NULL
+ ? c->overridden_target_name
+ : c->target_name,
+ &tsi_hs);
+ // Create handshakers.
+ grpc_security_create_handshakers(exec_ctx, tsi_hs, &sc->base, handshake_mgr);
+}
+
+static void ssl_server_create_handshakers(
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
- grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
- grpc_slice_buffer *read_buffer, gpr_timespec deadline,
- grpc_security_handshake_done_cb cb, void *user_data) {
+ grpc_handshake_manager *handshake_mgr) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)sc;
- tsi_handshaker *handshaker;
- grpc_security_status status =
- ssl_create_handshaker(c->handshaker_factory, false, NULL, &handshaker);
- if (status != GRPC_SECURITY_OK) {
- gpr_free(read_buffer);
- cb(exec_ctx, user_data, status, NULL, NULL);
- } else {
- grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, false,
- nonsecure_endpoint, read_buffer, deadline, cb,
- user_data);
- }
+ // Instantiate TSI handshaker.
+ tsi_handshaker *tsi_hs = NULL;
+ ssl_create_handshaker(c->handshaker_factory, false /* is_client */,
+ NULL /* peer_name */, &tsi_hs);
+ // Create handshakers.
+ grpc_security_create_handshakers(exec_ctx, tsi_hs, &sc->base, handshake_mgr);
}
static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) {
@@ -518,57 +465,53 @@ grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer) {
return ctx;
}
-static grpc_security_status ssl_check_peer(grpc_security_connector *sc,
- const char *peer_name,
- const tsi_peer *peer,
- grpc_auth_context **auth_context) {
+static grpc_error *ssl_check_peer(grpc_security_connector *sc,
+ const char *peer_name, const tsi_peer *peer,
+ grpc_auth_context **auth_context) {
/* Check the ALPN. */
const tsi_peer_property *p =
tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
if (p == NULL) {
- gpr_log(GPR_ERROR, "Missing selected ALPN property.");
- return GRPC_SECURITY_ERROR;
+ return GRPC_ERROR_CREATE(
+ "Cannot check peer: missing selected ALPN property.");
}
if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) {
- gpr_log(GPR_ERROR, "Invalid ALPN value.");
- return GRPC_SECURITY_ERROR;
+ return GRPC_ERROR_CREATE("Cannot check peer: invalid ALPN value.");
}
/* Check the peer name if specified. */
if (peer_name != NULL && !ssl_host_matches_name(peer, peer_name)) {
- gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name);
- return GRPC_SECURITY_ERROR;
+ char *msg;
+ gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name);
+ grpc_error *error = GRPC_ERROR_CREATE(msg);
+ gpr_free(msg);
+ return error;
}
*auth_context = tsi_ssl_peer_to_auth_context(peer);
- return GRPC_SECURITY_OK;
+ return GRPC_ERROR_NONE;
}
static void ssl_channel_check_peer(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, tsi_peer peer,
- grpc_security_peer_check_cb cb,
- void *user_data) {
+ grpc_auth_context **auth_context,
+ grpc_closure *on_peer_checked) {
grpc_ssl_channel_security_connector *c =
(grpc_ssl_channel_security_connector *)sc;
- grpc_security_status status;
- grpc_auth_context *auth_context = NULL;
- status = ssl_check_peer(sc, c->overridden_target_name != NULL
- ? c->overridden_target_name
- : c->target_name,
- &peer, &auth_context);
- cb(exec_ctx, user_data, status, auth_context);
- grpc_auth_context_unref(auth_context);
+ grpc_error *error = ssl_check_peer(sc, c->overridden_target_name != NULL
+ ? c->overridden_target_name
+ : c->target_name,
+ &peer, auth_context);
+ grpc_exec_ctx_sched(exec_ctx, on_peer_checked, error, NULL);
tsi_peer_destruct(&peer);
}
static void ssl_server_check_peer(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, tsi_peer peer,
- grpc_security_peer_check_cb cb,
- void *user_data) {
- grpc_auth_context *auth_context = NULL;
- grpc_security_status status = ssl_check_peer(sc, NULL, &peer, &auth_context);
+ grpc_auth_context **auth_context,
+ grpc_closure *on_peer_checked) {
+ grpc_error *error = ssl_check_peer(sc, NULL, &peer, auth_context);
tsi_peer_destruct(&peer);
- cb(exec_ctx, user_data, status, auth_context);
- grpc_auth_context_unref(auth_context);
+ grpc_exec_ctx_sched(exec_ctx, on_peer_checked, error, NULL);
}
static void add_shallow_auth_property_to_peer(tsi_peer *peer,
@@ -765,7 +708,7 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
c->base.request_metadata_creds =
grpc_call_credentials_ref(request_metadata_creds);
c->base.check_call_host = ssl_channel_check_call_host;
- c->base.do_handshake = ssl_channel_do_handshake;
+ c->base.create_handshakers = ssl_channel_create_handshakers;
gpr_split_host_port(target_name, &c->target_name, &port);
gpr_free(port);
if (overridden_target_name != NULL) {
@@ -840,8 +783,7 @@ grpc_security_status grpc_ssl_server_security_connector_create(
*sc = NULL;
goto error;
}
- gpr_mu_init(&c->base.mu);
- c->base.do_handshake = ssl_server_do_handshake;
+ c->base.create_handshakers = ssl_server_create_handshakers;
*sc = &c->base;
gpr_free((void *)alpn_protocol_strings);
gpr_free(alpn_protocol_string_lengths);
diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h
index dc02692b01..696db0e02e 100644
--- a/src/core/lib/security/transport/security_connector.h
+++ b/src/core/lib/security/transport/security_connector.h
@@ -35,6 +35,8 @@
#define GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H
#include <grpc/grpc_security.h>
+
+#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/lib/tsi/transport_security_interface.h"
@@ -57,21 +59,11 @@ typedef struct grpc_security_connector grpc_security_connector;
#define GRPC_SECURITY_CONNECTOR_ARG "grpc.security_connector"
-typedef void (*grpc_security_peer_check_cb)(grpc_exec_ctx *exec_ctx,
- void *user_data,
- grpc_security_status status,
- grpc_auth_context *auth_context);
-
-/* Ownership of the secure_endpoint is transfered. */
-typedef void (*grpc_security_handshake_done_cb)(
- grpc_exec_ctx *exec_ctx, void *user_data, grpc_security_status status,
- grpc_endpoint *secure_endpoint, grpc_auth_context *auth_context);
-
typedef struct {
void (*destroy)(grpc_security_connector *sc);
void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
- tsi_peer peer, grpc_security_peer_check_cb cb,
- void *user_data);
+ tsi_peer peer, grpc_auth_context **auth_context,
+ grpc_closure *on_peer_checked);
} grpc_security_connector_vtable;
typedef struct grpc_security_connector_handshake_list {
@@ -106,12 +98,12 @@ void grpc_security_connector_unref(grpc_security_connector *policy);
#endif
/* Check the peer. Callee takes ownership of the peer object.
- The callback will include the resulting auth_context. */
+ Sets *auth_context and invokes on_peer_checked when done. */
void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc,
tsi_peer peer,
- grpc_security_peer_check_cb cb,
- void *user_data);
+ grpc_auth_context **auth_context,
+ grpc_closure *on_peer_checked);
/* Util to encapsulate the connector in a channel arg. */
grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc);
@@ -141,11 +133,9 @@ struct grpc_channel_security_connector {
grpc_channel_security_connector *sc, const char *host,
grpc_auth_context *auth_context,
grpc_security_call_host_check_cb cb, void *user_data);
- void (*do_handshake)(grpc_exec_ctx *exec_ctx,
- grpc_channel_security_connector *sc,
- grpc_endpoint *nonsecure_endpoint,
- grpc_slice_buffer *read_buffer, gpr_timespec deadline,
- grpc_security_handshake_done_cb cb, void *user_data);
+ void (*create_handshakers)(grpc_exec_ctx *exec_ctx,
+ grpc_channel_security_connector *sc,
+ grpc_handshake_manager *handshake_mgr);
};
/* Checks that the host that will be set for a call is acceptable. */
@@ -154,11 +144,10 @@ void grpc_channel_security_connector_check_call_host(
const char *host, grpc_auth_context *auth_context,
grpc_security_call_host_check_cb cb, void *user_data);
-/* Handshake. */
-void grpc_channel_security_connector_do_handshake(
+/* Registers handshakers with \a handshake_mgr. */
+void grpc_channel_security_connector_create_handshakers(
grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector,
- grpc_endpoint *nonsecure_endpoint, grpc_slice_buffer *read_buffer,
- gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data);
+ grpc_handshake_manager *handshake_mgr);
/* --- server_security_connector object. ---
@@ -169,25 +158,14 @@ typedef struct grpc_server_security_connector grpc_server_security_connector;
struct grpc_server_security_connector {
grpc_security_connector base;
- gpr_mu mu;
- grpc_security_connector_handshake_list *handshaking_handshakes;
- const grpc_channel_args *channel_args;
- void (*do_handshake)(grpc_exec_ctx *exec_ctx,
- grpc_server_security_connector *sc,
- grpc_tcp_server_acceptor *acceptor,
- grpc_endpoint *nonsecure_endpoint,
- grpc_slice_buffer *read_buffer, gpr_timespec deadline,
- grpc_security_handshake_done_cb cb, void *user_data);
+ void (*create_handshakers)(grpc_exec_ctx *exec_ctx,
+ grpc_server_security_connector *sc,
+ grpc_handshake_manager *handshake_mgr);
};
-void grpc_server_security_connector_do_handshake(
+void grpc_server_security_connector_create_handshakers(
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
- grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
- grpc_slice_buffer *read_buffer, gpr_timespec deadline,
- grpc_security_handshake_done_cb cb, void *user_data);
-
-void grpc_server_security_connector_shutdown(
- grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector);
+ grpc_handshake_manager *handshake_mgr);
/* --- Creation security connectors. --- */
diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.c
new file mode 100644
index 0000000000..fc01bec2f2
--- /dev/null
+++ b/src/core/lib/security/transport/security_handshaker.c
@@ -0,0 +1,450 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/lib/security/transport/security_handshaker.h"
+
+#include <stdbool.h>
+#include <string.h>
+
+#include <grpc/slice_buffer.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/security/context/security_context.h"
+#include "src/core/lib/security/transport/secure_endpoint.h"
+#include "src/core/lib/security/transport/tsi_error.h"
+
+#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
+
+typedef struct {
+ grpc_handshaker base;
+
+ // State set at creation time.
+ tsi_handshaker *handshaker;
+ grpc_security_connector *connector;
+
+ gpr_mu mu;
+ gpr_refcount refs;
+
+ bool shutdown;
+ // Endpoint and read buffer to destroy after a shutdown.
+ grpc_endpoint *endpoint_to_destroy;
+ grpc_slice_buffer *read_buffer_to_destroy;
+
+ // State saved while performing the handshake.
+ grpc_handshaker_args *args;
+ grpc_closure *on_handshake_done;
+
+ unsigned char *handshake_buffer;
+ size_t handshake_buffer_size;
+ grpc_slice_buffer left_overs;
+ grpc_slice_buffer outgoing;
+ grpc_closure on_handshake_data_sent_to_peer;
+ grpc_closure on_handshake_data_received_from_peer;
+ grpc_closure on_peer_checked;
+ grpc_auth_context *auth_context;
+} security_handshaker;
+
+static void security_handshaker_unref(grpc_exec_ctx *exec_ctx,
+ security_handshaker *h) {
+ if (gpr_unref(&h->refs)) {
+ gpr_mu_destroy(&h->mu);
+ tsi_handshaker_destroy(h->handshaker);
+ if (h->endpoint_to_destroy != NULL) {
+ grpc_endpoint_destroy(exec_ctx, h->endpoint_to_destroy);
+ }
+ if (h->read_buffer_to_destroy != NULL) {
+ grpc_slice_buffer_destroy(h->read_buffer_to_destroy);
+ gpr_free(h->read_buffer_to_destroy);
+ }
+ gpr_free(h->handshake_buffer);
+ grpc_slice_buffer_destroy(&h->left_overs);
+ grpc_slice_buffer_destroy(&h->outgoing);
+ GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake");
+ GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake");
+ gpr_free(h);
+ }
+}
+
+// Set args fields to NULL, saving the endpoint and read buffer for
+// later destruction.
+static void cleanup_args_for_failure_locked(security_handshaker *h) {
+ h->endpoint_to_destroy = h->args->endpoint;
+ h->args->endpoint = NULL;
+ h->read_buffer_to_destroy = h->args->read_buffer;
+ h->args->read_buffer = NULL;
+ grpc_channel_args_destroy(h->args->args);
+ h->args->args = NULL;
+}
+
+// If the handshake failed or we're shutting down, clean up and invoke the
+// callback with the error.
+static void security_handshake_failed_locked(grpc_exec_ctx *exec_ctx,
+ security_handshaker *h,
+ grpc_error *error) {
+ if (error == GRPC_ERROR_NONE) {
+ // If we were shut down after the handshake succeeded but before an
+ // endpoint callback was invoked, we need to generate our own error.
+ error = GRPC_ERROR_CREATE("Handshaker shutdown");
+ }
+ const char *msg = grpc_error_string(error);
+ gpr_log(GPR_DEBUG, "Security handshake failed: %s", msg);
+ grpc_error_free_string(msg);
+ if (!h->shutdown) {
+ // TODO(ctiller): It is currently necessary to shutdown endpoints
+ // before destroying them, even if we know that there are no
+ // pending read/write callbacks. This should be fixed, at which
+ // point this can be removed.
+ grpc_endpoint_shutdown(exec_ctx, h->args->endpoint);
+ // Not shutting down, so the write failed. Clean up before
+ // invoking the callback.
+ cleanup_args_for_failure_locked(h);
+ }
+ // Invoke callback.
+ grpc_exec_ctx_sched(exec_ctx, h->on_handshake_done, error, NULL);
+}
+
+static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ security_handshaker *h = arg;
+ gpr_mu_lock(&h->mu);
+ if (error != GRPC_ERROR_NONE || h->shutdown) {
+ security_handshake_failed_locked(exec_ctx, h, GRPC_ERROR_REF(error));
+ goto done;
+ }
+ // Get frame protector.
+ tsi_frame_protector *protector;
+ tsi_result result =
+ tsi_handshaker_create_frame_protector(h->handshaker, NULL, &protector);
+ if (result != TSI_OK) {
+ error = grpc_set_tsi_error_result(
+ GRPC_ERROR_CREATE("Frame protector creation failed"), result);
+ security_handshake_failed_locked(exec_ctx, h, error);
+ goto done;
+ }
+ // Success.
+ // Create secure endpoint.
+ h->args->endpoint = grpc_secure_endpoint_create(
+ protector, h->args->endpoint, h->left_overs.slices, h->left_overs.count);
+ h->left_overs.count = 0;
+ h->left_overs.length = 0;
+ // Clear out the read buffer before it gets passed to the transport,
+ // since any excess bytes were already copied to h->left_overs.
+ grpc_slice_buffer_reset_and_unref(h->args->read_buffer);
+ // Add auth context to channel args.
+ grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context);
+ grpc_channel_args *tmp_args = h->args->args;
+ h->args->args =
+ grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1);
+ grpc_channel_args_destroy(tmp_args);
+ // Invoke callback.
+ grpc_exec_ctx_sched(exec_ctx, h->on_handshake_done, GRPC_ERROR_NONE, NULL);
+ // Set shutdown to true so that subsequent calls to
+ // security_handshaker_shutdown() do nothing.
+ h->shutdown = true;
+done:
+ gpr_mu_unlock(&h->mu);
+ security_handshaker_unref(exec_ctx, h);
+}
+
+static grpc_error *check_peer_locked(grpc_exec_ctx *exec_ctx,
+ security_handshaker *h) {
+ tsi_peer peer;
+ tsi_result result = tsi_handshaker_extract_peer(h->handshaker, &peer);
+ if (result != TSI_OK) {
+ return grpc_set_tsi_error_result(
+ GRPC_ERROR_CREATE("Peer extraction failed"), result);
+ }
+ grpc_security_connector_check_peer(exec_ctx, h->connector, peer,
+ &h->auth_context, &h->on_peer_checked);
+ return GRPC_ERROR_NONE;
+}
+
+static grpc_error *send_handshake_bytes_to_peer_locked(grpc_exec_ctx *exec_ctx,
+ security_handshaker *h) {
+ // Get data to send.
+ tsi_result result = TSI_OK;
+ size_t offset = 0;
+ do {
+ size_t to_send_size = h->handshake_buffer_size - offset;
+ result = tsi_handshaker_get_bytes_to_send_to_peer(
+ h->handshaker, h->handshake_buffer + offset, &to_send_size);
+ offset += to_send_size;
+ if (result == TSI_INCOMPLETE_DATA) {
+ h->handshake_buffer_size *= 2;
+ h->handshake_buffer =
+ gpr_realloc(h->handshake_buffer, h->handshake_buffer_size);
+ }
+ } while (result == TSI_INCOMPLETE_DATA);
+ if (result != TSI_OK) {
+ return grpc_set_tsi_error_result(GRPC_ERROR_CREATE("Handshake failed"),
+ result);
+ }
+ // Send data.
+ grpc_slice to_send =
+ grpc_slice_from_copied_buffer((const char *)h->handshake_buffer, offset);
+ grpc_slice_buffer_reset_and_unref(&h->outgoing);
+ grpc_slice_buffer_add(&h->outgoing, to_send);
+ grpc_endpoint_write(exec_ctx, h->args->endpoint, &h->outgoing,
+ &h->on_handshake_data_sent_to_peer);
+ return GRPC_ERROR_NONE;
+}
+
+static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
+ void *arg, grpc_error *error) {
+ security_handshaker *h = arg;
+ gpr_mu_lock(&h->mu);
+ if (error != GRPC_ERROR_NONE || h->shutdown) {
+ security_handshake_failed_locked(
+ exec_ctx, h,
+ GRPC_ERROR_CREATE_REFERENCING("Handshake read failed", &error, 1));
+ gpr_mu_unlock(&h->mu);
+ security_handshaker_unref(exec_ctx, h);
+ return;
+ }
+ // Process received data.
+ tsi_result result = TSI_OK;
+ size_t consumed_slice_size = 0;
+ size_t i;
+ for (i = 0; i < h->args->read_buffer->count; i++) {
+ consumed_slice_size = GRPC_SLICE_LENGTH(h->args->read_buffer->slices[i]);
+ result = tsi_handshaker_process_bytes_from_peer(
+ h->handshaker, GRPC_SLICE_START_PTR(h->args->read_buffer->slices[i]),
+ &consumed_slice_size);
+ if (!tsi_handshaker_is_in_progress(h->handshaker)) break;
+ }
+ if (tsi_handshaker_is_in_progress(h->handshaker)) {
+ /* We may need more data. */
+ if (result == TSI_INCOMPLETE_DATA) {
+ grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer,
+ &h->on_handshake_data_received_from_peer);
+ goto done;
+ } else {
+ error = send_handshake_bytes_to_peer_locked(exec_ctx, h);
+ if (error != GRPC_ERROR_NONE) {
+ security_handshake_failed_locked(exec_ctx, h, error);
+ gpr_mu_unlock(&h->mu);
+ security_handshaker_unref(exec_ctx, h);
+ return;
+ }
+ goto done;
+ }
+ }
+ if (result != TSI_OK) {
+ security_handshake_failed_locked(
+ exec_ctx, h, grpc_set_tsi_error_result(
+ GRPC_ERROR_CREATE("Handshake failed"), result));
+ gpr_mu_unlock(&h->mu);
+ security_handshaker_unref(exec_ctx, h);
+ return;
+ }
+ /* Handshake is done and successful this point. */
+ bool has_left_overs_in_current_slice =
+ (consumed_slice_size <
+ GRPC_SLICE_LENGTH(h->args->read_buffer->slices[i]));
+ size_t num_left_overs = (has_left_overs_in_current_slice ? 1 : 0) +
+ h->args->read_buffer->count - i - 1;
+ if (num_left_overs > 0) {
+ /* Put the leftovers in our buffer (ownership transfered). */
+ if (has_left_overs_in_current_slice) {
+ grpc_slice_buffer_add(
+ &h->left_overs,
+ grpc_slice_split_tail(&h->args->read_buffer->slices[i],
+ consumed_slice_size));
+ /* split_tail above increments refcount. */
+ grpc_slice_unref(h->args->read_buffer->slices[i]);
+ }
+ grpc_slice_buffer_addn(
+ &h->left_overs, &h->args->read_buffer->slices[i + 1],
+ num_left_overs - (size_t)has_left_overs_in_current_slice);
+ }
+ // Check peer.
+ error = check_peer_locked(exec_ctx, h);
+ if (error != GRPC_ERROR_NONE) {
+ security_handshake_failed_locked(exec_ctx, h, error);
+ gpr_mu_unlock(&h->mu);
+ security_handshaker_unref(exec_ctx, h);
+ return;
+ }
+done:
+ gpr_mu_unlock(&h->mu);
+}
+
+static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ security_handshaker *h = arg;
+ gpr_mu_lock(&h->mu);
+ if (error != GRPC_ERROR_NONE || h->shutdown) {
+ security_handshake_failed_locked(
+ exec_ctx, h,
+ GRPC_ERROR_CREATE_REFERENCING("Handshake write failed", &error, 1));
+ gpr_mu_unlock(&h->mu);
+ security_handshaker_unref(exec_ctx, h);
+ return;
+ }
+ /* We may be done. */
+ if (tsi_handshaker_is_in_progress(h->handshaker)) {
+ grpc_endpoint_read(exec_ctx, h->args->endpoint, h->args->read_buffer,
+ &h->on_handshake_data_received_from_peer);
+ } else {
+ error = check_peer_locked(exec_ctx, h);
+ if (error != GRPC_ERROR_NONE) {
+ security_handshake_failed_locked(exec_ctx, h, error);
+ gpr_mu_unlock(&h->mu);
+ security_handshaker_unref(exec_ctx, h);
+ return;
+ }
+ }
+ gpr_mu_unlock(&h->mu);
+}
+
+//
+// public handshaker API
+//
+
+static void security_handshaker_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_handshaker *handshaker) {
+ security_handshaker *h = (security_handshaker *)handshaker;
+ security_handshaker_unref(exec_ctx, h);
+}
+
+static void security_handshaker_shutdown(grpc_exec_ctx *exec_ctx,
+ grpc_handshaker *handshaker) {
+ security_handshaker *h = (security_handshaker *)handshaker;
+ gpr_mu_lock(&h->mu);
+ if (!h->shutdown) {
+ h->shutdown = true;
+ grpc_endpoint_shutdown(exec_ctx, h->args->endpoint);
+ cleanup_args_for_failure_locked(h);
+ }
+ gpr_mu_unlock(&h->mu);
+}
+
+static void security_handshaker_do_handshake(grpc_exec_ctx *exec_ctx,
+ grpc_handshaker *handshaker,
+ grpc_tcp_server_acceptor *acceptor,
+ grpc_closure *on_handshake_done,
+ grpc_handshaker_args *args) {
+ security_handshaker *h = (security_handshaker *)handshaker;
+ gpr_mu_lock(&h->mu);
+ h->args = args;
+ h->on_handshake_done = on_handshake_done;
+ gpr_ref(&h->refs);
+ grpc_error *error = send_handshake_bytes_to_peer_locked(exec_ctx, h);
+ if (error != GRPC_ERROR_NONE) {
+ security_handshake_failed_locked(exec_ctx, h, error);
+ gpr_mu_unlock(&h->mu);
+ security_handshaker_unref(exec_ctx, h);
+ return;
+ }
+ gpr_mu_unlock(&h->mu);
+}
+
+static const grpc_handshaker_vtable security_handshaker_vtable = {
+ security_handshaker_destroy, security_handshaker_shutdown,
+ security_handshaker_do_handshake};
+
+static grpc_handshaker *security_handshaker_create(
+ grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker,
+ grpc_security_connector *connector) {
+ security_handshaker *h = gpr_malloc(sizeof(security_handshaker));
+ memset(h, 0, sizeof(security_handshaker));
+ grpc_handshaker_init(&security_handshaker_vtable, &h->base);
+ h->handshaker = handshaker;
+ h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake");
+ gpr_mu_init(&h->mu);
+ gpr_ref_init(&h->refs, 1);
+ h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
+ h->handshake_buffer = gpr_malloc(h->handshake_buffer_size);
+ grpc_closure_init(&h->on_handshake_data_sent_to_peer,
+ on_handshake_data_sent_to_peer, h);
+ grpc_closure_init(&h->on_handshake_data_received_from_peer,
+ on_handshake_data_received_from_peer, h);
+ grpc_closure_init(&h->on_peer_checked, on_peer_checked, h);
+ grpc_slice_buffer_init(&h->left_overs);
+ grpc_slice_buffer_init(&h->outgoing);
+ return &h->base;
+}
+
+//
+// fail_handshaker
+//
+
+static void fail_handshaker_destroy(grpc_exec_ctx *exec_ctx,
+ grpc_handshaker *handshaker) {
+ gpr_free(handshaker);
+}
+
+static void fail_handshaker_shutdown(grpc_exec_ctx *exec_ctx,
+ grpc_handshaker *handshaker) {}
+
+static void fail_handshaker_do_handshake(grpc_exec_ctx *exec_ctx,
+ grpc_handshaker *handshaker,
+ grpc_tcp_server_acceptor *acceptor,
+ grpc_closure *on_handshake_done,
+ grpc_handshaker_args *args) {
+ grpc_exec_ctx_sched(exec_ctx, on_handshake_done,
+ GRPC_ERROR_CREATE("Failed to create security handshaker"),
+ NULL);
+}
+
+static const grpc_handshaker_vtable fail_handshaker_vtable = {
+ fail_handshaker_destroy, fail_handshaker_shutdown,
+ fail_handshaker_do_handshake};
+
+static grpc_handshaker *fail_handshaker_create() {
+ grpc_handshaker *h = gpr_malloc(sizeof(*h));
+ grpc_handshaker_init(&fail_handshaker_vtable, h);
+ return h;
+}
+
+//
+// exported functions
+//
+
+void grpc_security_create_handshakers(grpc_exec_ctx *exec_ctx,
+ tsi_handshaker *handshaker,
+ grpc_security_connector *connector,
+ grpc_handshake_manager *handshake_mgr) {
+ // If no TSI handshaker was created, add a handshaker that always fails.
+ // Otherwise, add a real security handshaker.
+ if (handshaker == NULL) {
+ grpc_handshake_manager_add(handshake_mgr, fail_handshaker_create());
+ } else {
+ grpc_handshake_manager_add(
+ handshake_mgr,
+ security_handshaker_create(exec_ctx, handshaker, connector));
+ }
+}
diff --git a/src/core/lib/security/transport/handshake.h b/src/core/lib/security/transport/security_handshaker.h
index f894540515..f71f43a359 100644
--- a/src/core/lib/security/transport/handshake.h
+++ b/src/core/lib/security/transport/security_handshaker.h
@@ -31,20 +31,17 @@
*
*/
-#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_HANDSHAKE_H
-#define GRPC_CORE_LIB_SECURITY_TRANSPORT_HANDSHAKE_H
+#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_HANDSHAKER_H
+#define GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_HANDSHAKER_H
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/security/transport/security_connector.h"
-/* Calls the callback upon completion. Takes owership of handshaker and
- * read_buffer. */
-void grpc_do_security_handshake(
- grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker,
- grpc_security_connector *connector, bool is_client_side,
- grpc_endpoint *nonsecure_endpoint, grpc_slice_buffer *read_buffer,
- gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data);
+/// Creates any necessary security handshakers and adds them to
+/// \a handshake_mgr.
+void grpc_security_create_handshakers(grpc_exec_ctx *exec_ctx,
+ tsi_handshaker *handshaker,
+ grpc_security_connector *connector,
+ grpc_handshake_manager *handshake_mgr);
-void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake);
-
-#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_HANDSHAKE_H */
+#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_HANDSHAKER_H */
diff --git a/src/core/lib/support/backoff.c b/src/core/lib/support/backoff.c
index e89ef47220..0612472712 100644
--- a/src/core/lib/support/backoff.c
+++ b/src/core/lib/support/backoff.c
@@ -35,8 +35,10 @@
#include <grpc/support/useful.h>
-void gpr_backoff_init(gpr_backoff *backoff, double multiplier, double jitter,
+void gpr_backoff_init(gpr_backoff *backoff, int64_t initial_connect_timeout,
+ double multiplier, double jitter,
int64_t min_timeout_millis, int64_t max_timeout_millis) {
+ backoff->initial_connect_timeout = initial_connect_timeout;
backoff->multiplier = multiplier;
backoff->jitter = jitter;
backoff->min_timeout_millis = min_timeout_millis;
@@ -45,9 +47,10 @@ void gpr_backoff_init(gpr_backoff *backoff, double multiplier, double jitter,
}
gpr_timespec gpr_backoff_begin(gpr_backoff *backoff, gpr_timespec now) {
- backoff->current_timeout_millis = backoff->min_timeout_millis;
- return gpr_time_add(
- now, gpr_time_from_millis(backoff->current_timeout_millis, GPR_TIMESPAN));
+ backoff->current_timeout_millis = backoff->initial_connect_timeout;
+ const int64_t first_timeout =
+ GPR_MAX(backoff->current_timeout_millis, backoff->min_timeout_millis);
+ return gpr_time_add(now, gpr_time_from_millis(first_timeout, GPR_TIMESPAN));
}
/* Generate a random number between 0 and 1. */
@@ -57,20 +60,28 @@ static double generate_uniform_random_number(uint32_t *rng_state) {
}
gpr_timespec gpr_backoff_step(gpr_backoff *backoff, gpr_timespec now) {
- double new_timeout_millis =
+ const double new_timeout_millis =
backoff->multiplier * (double)backoff->current_timeout_millis;
- double jitter_range = backoff->jitter * new_timeout_millis;
- double jitter =
+ backoff->current_timeout_millis =
+ GPR_MIN((int64_t)new_timeout_millis, backoff->max_timeout_millis);
+
+ const double jitter_range_width = backoff->jitter * new_timeout_millis;
+ const double jitter =
(2 * generate_uniform_random_number(&backoff->rng_state) - 1) *
- jitter_range;
+ jitter_range_width;
+
backoff->current_timeout_millis =
- GPR_CLAMP((int64_t)(new_timeout_millis + jitter),
- backoff->min_timeout_millis, backoff->max_timeout_millis);
- return gpr_time_add(
+ (int64_t)((double)(backoff->current_timeout_millis) + jitter);
+
+ const gpr_timespec current_deadline = gpr_time_add(
now, gpr_time_from_millis(backoff->current_timeout_millis, GPR_TIMESPAN));
+
+ const gpr_timespec min_deadline = gpr_time_add(
+ now, gpr_time_from_millis(backoff->min_timeout_millis, GPR_TIMESPAN));
+
+ return gpr_time_max(current_deadline, min_deadline);
}
void gpr_backoff_reset(gpr_backoff *backoff) {
- // forces step() to return a timeout of min_timeout_millis
- backoff->current_timeout_millis = 0;
+ backoff->current_timeout_millis = backoff->initial_connect_timeout;
}
diff --git a/src/core/lib/support/backoff.h b/src/core/lib/support/backoff.h
index 6d40c15546..5e9b740824 100644
--- a/src/core/lib/support/backoff.h
+++ b/src/core/lib/support/backoff.h
@@ -37,7 +37,9 @@
#include <grpc/support/time.h>
typedef struct {
- /// const: multiplier between retry attempts
+ /// const: how long to wait after the first failure before retrying
+ int64_t initial_connect_timeout;
+ /// const: factor with which to multiply backoff after a failed retry
double multiplier;
/// const: amount to randomize backoffs
double jitter;
@@ -54,7 +56,8 @@ typedef struct {
} gpr_backoff;
/// Initialize backoff machinery - does not need to be destroyed
-void gpr_backoff_init(gpr_backoff *backoff, double multiplier, double jitter,
+void gpr_backoff_init(gpr_backoff *backoff, int64_t initial_connect_timeout,
+ double multiplier, double jitter,
int64_t min_timeout_millis, int64_t max_timeout_millis);
/// Begin retry loop: returns a timespec for the NEXT retry
diff --git a/src/core/lib/support/subprocess_posix.c b/src/core/lib/support/subprocess_posix.c
index 4f4de9298e..4247a1c12b 100644
--- a/src/core/lib/support/subprocess_posix.c
+++ b/src/core/lib/support/subprocess_posix.c
@@ -40,6 +40,7 @@
#include <assert.h>
#include <errno.h>
#include <signal.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -52,7 +53,7 @@
struct gpr_subprocess {
int pid;
- int joined;
+ bool joined;
};
const char *gpr_subprocess_binary_extension() { return ""; }
@@ -97,9 +98,11 @@ retry:
if (errno == EINTR) {
goto retry;
}
- gpr_log(GPR_ERROR, "waitpid failed: %s", strerror(errno));
+ gpr_log(GPR_ERROR, "waitpid failed for pid %d: %s", p->pid,
+ strerror(errno));
return -1;
}
+ p->joined = true;
return status;
}
diff --git a/src/core/lib/transport/connectivity_state.c b/src/core/lib/transport/connectivity_state.c
index 89072879d9..4f49d7cf7d 100644
--- a/src/core/lib/transport/connectivity_state.c
+++ b/src/core/lib/transport/connectivity_state.c
@@ -100,7 +100,12 @@ grpc_connectivity_state grpc_connectivity_state_check(
return tracker->current_state;
}
-int grpc_connectivity_state_notify_on_state_change(
+bool grpc_connectivity_state_has_watchers(
+ grpc_connectivity_state_tracker *connectivity_state) {
+ return connectivity_state->watchers != NULL;
+}
+
+bool grpc_connectivity_state_notify_on_state_change(
grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker,
grpc_connectivity_state *current, grpc_closure *notify) {
if (grpc_connectivity_state_trace) {
@@ -119,7 +124,7 @@ int grpc_connectivity_state_notify_on_state_change(
grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_CANCELLED, NULL);
tracker->watchers = w->next;
gpr_free(w);
- return 0;
+ return false;
}
while (w != NULL) {
grpc_connectivity_state_watcher *rm_candidate = w->next;
@@ -127,11 +132,11 @@ int grpc_connectivity_state_notify_on_state_change(
grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_CANCELLED, NULL);
w->next = w->next->next;
gpr_free(rm_candidate);
- return 0;
+ return false;
}
w = w->next;
}
- return 0;
+ return false;
} else {
if (tracker->current_state != *current) {
*current = tracker->current_state;
diff --git a/src/core/lib/transport/connectivity_state.h b/src/core/lib/transport/connectivity_state.h
index 7a2fa52c10..769c675b79 100644
--- a/src/core/lib/transport/connectivity_state.h
+++ b/src/core/lib/transport/connectivity_state.h
@@ -75,13 +75,16 @@ void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx,
grpc_error *associated_error,
const char *reason);
+bool grpc_connectivity_state_has_watchers(
+ grpc_connectivity_state_tracker *tracker);
+
grpc_connectivity_state grpc_connectivity_state_check(
grpc_connectivity_state_tracker *tracker, grpc_error **current_error);
/** Return 1 if the channel should start connecting, 0 otherwise.
If current==NULL cancel notify if it is already queued (success==0 in that
case) */
-int grpc_connectivity_state_notify_on_state_change(
+bool grpc_connectivity_state_notify_on_state_change(
grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker,
grpc_connectivity_state *current, grpc_closure *notify);
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
index a44aaf1fdd..99e8c1a3da 100644
--- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
@@ -87,7 +87,6 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
- <None Include="Grpc.Auth.nuspec" />
<None Include="Grpc.Auth.project.json" />
<None Include="packages.config" />
</ItemGroup>
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.nuspec b/src/csharp/Grpc.Auth/Grpc.Auth.nuspec
deleted file mode 100644
index a1f5668e2e..0000000000
--- a/src/csharp/Grpc.Auth/Grpc.Auth.nuspec
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<package>
- <metadata>
- <id>Grpc.Auth</id>
- <title>gRPC C# Auth</title>
- <summary>Auth library for C# implementation of gRPC - an RPC library and framework</summary>
- <description>Auth library for C# implementation of gRPC - an RPC library and framework. See project site for more info.</description>
- <version>$version$</version>
- <authors>Google Inc.</authors>
- <owners>grpc-packages</owners>
- <licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
- <projectUrl>https://github.com/grpc/grpc</projectUrl>
- <requireLicenseAcceptance>false</requireLicenseAcceptance>
- <releaseNotes>Release $version$ of gRPC C#</releaseNotes>
- <copyright>Copyright 2015, Google Inc.</copyright>
- <tags>gRPC RPC Protocol HTTP/2 Auth OAuth2</tags>
- <dependencies>
- <dependency id="Google.Apis.Auth" version="1.15.0" />
- <dependency id="Grpc.Core" version="$version$" />
- </dependencies>
- </metadata>
- <files>
- <file src="bin/ReleaseSigned/Grpc.Auth.dll" target="lib/net45" />
- <file src="bin/ReleaseSigned/Grpc.Auth.pdb" target="lib/net45" />
- <file src="bin/ReleaseSigned/Grpc.Auth.xml" target="lib/net45" />
- <file src="**\*.cs" target="src" />
- </files>
-</package>
diff --git a/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs b/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs
index 99a2d47e6e..3c3b9f7745 100644
--- a/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs
+++ b/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs
@@ -67,6 +67,9 @@ namespace Grpc.Core.Tests
var credentials = new FakeCallCredentials();
Assert.AreSame(credentials, options.WithCredentials(credentials).Credentials);
+ var flags = CallFlags.WaitForReady | CallFlags.CacheableRequest;
+ Assert.AreEqual(flags, options.WithFlags(flags).Flags);
+
// Check that the original instance is unchanged.
Assert.IsNull(options.Headers);
Assert.IsNull(options.Deadline);
@@ -74,6 +77,7 @@ namespace Grpc.Core.Tests
Assert.IsNull(options.WriteOptions);
Assert.IsNull(options.PropagationToken);
Assert.IsNull(options.Credentials);
+ Assert.AreEqual(default(CallFlags), options.Flags);
}
[Test]
@@ -94,5 +98,16 @@ namespace Grpc.Core.Tests
Assert.AreEqual(token, new CallOptions(propagationToken: propagationToken2).Normalize().CancellationToken);
Assert.Throws(typeof(ArgumentException), () => new CallOptions(cancellationToken: token, propagationToken: propagationToken2).Normalize());
}
+
+ [Test]
+ public void WaitForReady()
+ {
+ var callOptions = new CallOptions();
+ Assert.IsFalse(callOptions.IsWaitForReady);
+
+ Assert.AreEqual(CallFlags.WaitForReady, callOptions.WithWaitForReady().Flags);
+ Assert.IsTrue(callOptions.WithWaitForReady().IsWaitForReady);
+ Assert.IsFalse(callOptions.WithWaitForReady(true).WithWaitForReady(false).IsWaitForReady);
+ }
}
}
diff --git a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs
index 909112a47c..fe067fe8b0 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs
@@ -115,27 +115,27 @@ namespace Grpc.Core.Internal.Tests
return "PEER";
}
- public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
+ public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
UnaryResponseClientHandler = callback;
}
- public void StartUnary(BatchContextSafeHandle ctx, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
+ public void StartUnary(BatchContextSafeHandle ctx, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
throw new NotImplementedException();
}
- public void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray)
+ public void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
UnaryResponseClientHandler = callback;
}
- public void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
+ public void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
ReceivedStatusOnClientHandler = callback;
}
- public void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray)
+ public void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
ReceivedStatusOnClientHandler = callback;
}
diff --git a/src/csharp/Grpc.Core.Tests/SanityTest.cs b/src/csharp/Grpc.Core.Tests/SanityTest.cs
index f1eb13dffc..1c28277df5 100644
--- a/src/csharp/Grpc.Core.Tests/SanityTest.cs
+++ b/src/csharp/Grpc.Core.Tests/SanityTest.cs
@@ -115,7 +115,8 @@ namespace Grpc.Core.Tests
var otherAssemblies = new[] {
"Grpc.Examples.Tests",
"Grpc.HealthCheck.Tests",
- "Grpc.IntegrationTesting"
+ "Grpc.IntegrationTesting",
+ "Grpc.Reflection.Tests",
};
foreach (var assemblyName in otherAssemblies)
{
diff --git a/src/csharp/Grpc.Core/CallOptions.cs b/src/csharp/Grpc.Core/CallOptions.cs
index 35548cfc96..ce43dae171 100644
--- a/src/csharp/Grpc.Core/CallOptions.cs
+++ b/src/csharp/Grpc.Core/CallOptions.cs
@@ -50,6 +50,7 @@ namespace Grpc.Core
WriteOptions writeOptions;
ContextPropagationToken propagationToken;
CallCredentials credentials;
+ CallFlags flags;
/// <summary>
/// Creates a new instance of <c>CallOptions</c> struct.
@@ -69,6 +70,7 @@ namespace Grpc.Core
this.writeOptions = writeOptions;
this.propagationToken = propagationToken;
this.credentials = credentials;
+ this.flags = default(CallFlags);
}
/// <summary>
@@ -126,6 +128,24 @@ namespace Grpc.Core
}
/// <summary>
+ /// If <c>true</c> and and channel is in <c>ChannelState.TransientFailure</c>, the call will attempt waiting for the channel to recover
+ /// instead of failing immediately (which is the default "FailFast" semantics).
+ /// Note: experimental API that can change or be removed without any prior notice.
+ /// </summary>
+ public bool IsWaitForReady
+ {
+ get { return (this.flags & CallFlags.WaitForReady) == CallFlags.WaitForReady; }
+ }
+
+ /// <summary>
+ /// Flags to use for this call.
+ /// </summary>
+ internal CallFlags Flags
+ {
+ get { return this.flags; }
+ }
+
+ /// <summary>
/// Returns new instance of <see cref="CallOptions"/> with
/// <c>Headers</c> set to the value provided. Values of all other fields are preserved.
/// </summary>
@@ -198,6 +218,32 @@ namespace Grpc.Core
}
/// <summary>
+ /// Returns new instance of <see cref="CallOptions"/> with "WaitForReady" semantics enabled/disabled.
+ /// <see cref="IsWaitForReady"/>.
+ /// Note: experimental API that can change or be removed without any prior notice.
+ /// </summary>
+ public CallOptions WithWaitForReady(bool waitForReady = true)
+ {
+ if (waitForReady)
+ {
+ return WithFlags(this.flags | CallFlags.WaitForReady);
+ }
+ return WithFlags(this.flags & ~CallFlags.WaitForReady);
+ }
+
+ /// <summary>
+ /// Returns new instance of <see cref="CallOptions"/> with
+ /// <c>Flags</c> set to the value provided. Values of all other fields are preserved.
+ /// </summary>
+ /// <param name="flags">The call flags.</param>
+ internal CallOptions WithFlags(CallFlags flags)
+ {
+ var newOptions = this;
+ newOptions.flags = flags;
+ return newOptions;
+ }
+
+ /// <summary>
/// Returns a new instance of <see cref="CallOptions"/> with
/// all previously unset values set to their defaults and deadline and cancellation
/// token propagated when appropriate.
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index b9715183d0..5bfb978ca6 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -140,9 +140,9 @@
<Compile Include="Logging\LogLevelFilterLogger.cs" />
<Compile Include="Internal\RequestCallContextSafeHandle.cs" />
<Compile Include="Utils\TaskUtils.cs" />
+ <Compile Include="Internal\CallFlags.cs" />
</ItemGroup>
<ItemGroup>
- <None Include="Grpc.Core.nuspec" />
<None Include="Grpc.Core.project.json" />
<None Include="packages.config" />
</ItemGroup>
@@ -154,4 +154,4 @@
<Link>roots.pem</Link>
</EmbeddedResource>
</ItemGroup>
-</Project>
+</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Core/Grpc.Core.nuspec b/src/csharp/Grpc.Core/Grpc.Core.nuspec
deleted file mode 100644
index b2a0160147..0000000000
--- a/src/csharp/Grpc.Core/Grpc.Core.nuspec
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<package>
- <metadata>
- <id>Grpc.Core</id>
- <title>gRPC C# Core</title>
- <summary>Core C# implementation of gRPC - an RPC library and framework</summary>
- <description>Core C# implementation of gRPC - an RPC library and framework. See project site for more info.</description>
- <version>$version$</version>
- <authors>Google Inc.</authors>
- <owners>grpc-packages</owners>
- <licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
- <projectUrl>https://github.com/grpc/grpc</projectUrl>
- <requireLicenseAcceptance>false</requireLicenseAcceptance>
- <releaseNotes>Release $version$ of gRPC C#</releaseNotes>
- <copyright>Copyright 2015, Google Inc.</copyright>
- <tags>gRPC RPC Protocol HTTP/2</tags>
- <dependencies>
- <dependency id="System.Interactive.Async" version="3.1.1" />
- </dependencies>
- </metadata>
- <files>
- <file src="bin/ReleaseSigned/Grpc.Core.dll" target="lib/net45" />
- <file src="bin/ReleaseSigned/Grpc.Core.pdb" target="lib/net45" />
- <file src="bin/ReleaseSigned/Grpc.Core.xml" target="lib/net45" />
- <file src="**\*.cs" target="src" />
- <file src="Grpc.Core.targets" target="\build\net45\Grpc.Core.targets" />
- <!-- without backslashes in the the source path, nuget won't copy the files -->
- <file src="..\nativelibs\windows_x86\grpc_csharp_ext.dll" target="/runtimes/win/native/grpc_csharp_ext.x86.dll" />
- <file src="..\nativelibs\windows_x64\grpc_csharp_ext.dll" target="/runtimes/win/native/grpc_csharp_ext.x64.dll" />
- <file src="..\nativelibs\linux_x86\libgrpc_csharp_ext.so" target="/runtimes/linux/native/libgrpc_csharp_ext.x86.so" />
- <file src="..\nativelibs\linux_x64\libgrpc_csharp_ext.so" target="/runtimes/linux/native/libgrpc_csharp_ext.x64.so" />
- <file src="..\nativelibs\macosx_x86\libgrpc_csharp_ext.dylib" target="/runtimes/osx/native/libgrpc_csharp_ext.x86.dylib" />
- <file src="..\nativelibs\macosx_x64\libgrpc_csharp_ext.dylib" target="/runtimes/osx/native/libgrpc_csharp_ext.x64.dylib" />
- </files>
-</package>
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index da45c4829d..1f738a3b6f 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -106,7 +106,7 @@ namespace Grpc.Core.Internal
using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
using (var ctx = BatchContextSafeHandle.Create())
{
- call.StartUnary(ctx, payload, metadataArray, GetWriteFlagsForCall());
+ call.StartUnary(ctx, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags);
var ev = cq.Pluck(ctx.Handle);
@@ -150,7 +150,7 @@ namespace Grpc.Core.Internal
unaryResponseTcs = new TaskCompletionSource<TResponse>();
using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
{
- call.StartUnary(HandleUnaryResponse, payload, metadataArray, GetWriteFlagsForCall());
+ call.StartUnary(HandleUnaryResponse, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags);
}
return unaryResponseTcs.Task;
}
@@ -174,7 +174,7 @@ namespace Grpc.Core.Internal
unaryResponseTcs = new TaskCompletionSource<TResponse>();
using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
{
- call.StartClientStreaming(HandleUnaryResponse, metadataArray);
+ call.StartClientStreaming(HandleUnaryResponse, metadataArray, details.Options.Flags);
}
return unaryResponseTcs.Task;
@@ -200,7 +200,7 @@ namespace Grpc.Core.Internal
streamingResponseCallFinishedTcs = new TaskCompletionSource<object>();
using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
{
- call.StartServerStreaming(HandleFinished, payload, metadataArray, GetWriteFlagsForCall());
+ call.StartServerStreaming(HandleFinished, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags);
}
call.StartReceiveInitialMetadata(HandleReceivedResponseHeaders);
}
@@ -222,7 +222,7 @@ namespace Grpc.Core.Internal
streamingResponseCallFinishedTcs = new TaskCompletionSource<object>();
using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
{
- call.StartDuplexStreaming(HandleFinished, metadataArray);
+ call.StartDuplexStreaming(HandleFinished, metadataArray, details.Options.Flags);
}
call.StartReceiveInitialMetadata(HandleReceivedResponseHeaders);
}
diff --git a/src/csharp/Grpc.Core/Internal/CallFlags.cs b/src/csharp/Grpc.Core/Internal/CallFlags.cs
new file mode 100644
index 0000000000..454fa9b1f4
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/CallFlags.cs
@@ -0,0 +1,60 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// Flags to enable special call behaviors (client-side only).
+ /// </summary>
+ [Flags]
+ internal enum CallFlags
+ {
+ /// <summary>
+ /// The call is idempotent (retrying the call doesn't change the outcome of the operation).
+ /// </summary>
+ IdempotentRequest = 0x10,
+
+ /// <summary>
+ /// If channel is in <c>ChannelState.TransientFailure</c>, attempt waiting for the channel to recover
+ /// instead of failing the call immediately.
+ /// </summary>
+ WaitForReady = 0x20,
+
+ /// <summary>
+ /// The call is cacheable. gRPC is free to use GET verb */
+ /// </summary>
+ CacheableRequest = 0x40
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index f817a61bce..6bfcc7fa74 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -63,50 +63,50 @@ namespace Grpc.Core.Internal
Native.grpcsharp_call_set_credentials(this, credentials).CheckOk();
}
- public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
+ public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
- Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
+ Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, metadataArray, callFlags)
.CheckOk();
}
}
- public void StartUnary(BatchContextSafeHandle ctx, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
+ public void StartUnary(BatchContextSafeHandle ctx, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
- Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
+ Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, metadataArray, callFlags)
.CheckOk();
}
- public void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray)
+ public void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
- Native.grpcsharp_call_start_client_streaming(this, ctx, metadataArray).CheckOk();
+ Native.grpcsharp_call_start_client_streaming(this, ctx, metadataArray, callFlags).CheckOk();
}
}
- public void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
+ public void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
- Native.grpcsharp_call_start_server_streaming(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags).CheckOk();
+ Native.grpcsharp_call_start_server_streaming(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, metadataArray, callFlags).CheckOk();
}
}
- public void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray)
+ public void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
- Native.grpcsharp_call_start_duplex_streaming(this, ctx, metadataArray).CheckOk();
+ Native.grpcsharp_call_start_duplex_streaming(this, ctx, metadataArray, callFlags).CheckOk();
}
}
diff --git a/src/csharp/Grpc.Core/Internal/INativeCall.cs b/src/csharp/Grpc.Core/Internal/INativeCall.cs
index cd3719cb50..94fbb08feb 100644
--- a/src/csharp/Grpc.Core/Internal/INativeCall.cs
+++ b/src/csharp/Grpc.Core/Internal/INativeCall.cs
@@ -31,6 +31,7 @@
#endregion
using System;
+using Grpc.Core;
namespace Grpc.Core.Internal
{
@@ -54,19 +55,19 @@ namespace Grpc.Core.Internal
{
void Cancel();
- void CancelWithStatus(Grpc.Core.Status status);
+ void CancelWithStatus(Status status);
string GetPeer();
- void StartUnary(UnaryResponseClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, Grpc.Core.WriteFlags writeFlags);
+ void StartUnary(UnaryResponseClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
- void StartUnary(BatchContextSafeHandle ctx, byte[] payload, MetadataArraySafeHandle metadataArray, Grpc.Core.WriteFlags writeFlags);
+ void StartUnary(BatchContextSafeHandle ctx, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
- void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray);
+ void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
- void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, Grpc.Core.WriteFlags writeFlags);
+ void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
- void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray);
+ void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
void StartReceiveMessage(ReceivedMessageHandler callback);
@@ -74,11 +75,11 @@ namespace Grpc.Core.Internal
void StartSendInitialMetadata(SendCompletionHandler callback, MetadataArraySafeHandle metadataArray);
- void StartSendMessage(SendCompletionHandler callback, byte[] payload, Grpc.Core.WriteFlags writeFlags, bool sendEmptyInitialMetadata);
+ void StartSendMessage(SendCompletionHandler callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
void StartSendCloseFromClient(SendCompletionHandler callback);
- void StartSendStatusFromServer(SendCompletionHandler callback, Grpc.Core.Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, byte[] optionalPayload, Grpc.Core.WriteFlags writeFlags);
+ void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, byte[] optionalPayload, WriteFlags writeFlags);
void StartServerSide(ReceivedCloseOnServerHandler callback);
}
diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
index 40ba7e30cb..ce38e37093 100644
--- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
@@ -325,14 +325,14 @@ namespace Grpc.Core.Internal
public delegate CallError grpcsharp_call_cancel_delegate(CallSafeHandle call);
public delegate CallError grpcsharp_call_cancel_with_status_delegate(CallSafeHandle call, StatusCode status, string description);
public delegate CallError grpcsharp_call_start_unary_delegate(CallSafeHandle call,
- BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
+ BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags);
public delegate CallError grpcsharp_call_start_client_streaming_delegate(CallSafeHandle call,
- BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
+ BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags);
public delegate CallError grpcsharp_call_start_server_streaming_delegate(CallSafeHandle call,
- BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen,
- MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
+ BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags,
+ MetadataArraySafeHandle metadataArray, CallFlags metadataFlags);
public delegate CallError grpcsharp_call_start_duplex_streaming_delegate(CallSafeHandle call,
- BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
+ BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags);
public delegate CallError grpcsharp_call_send_message_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
public delegate CallError grpcsharp_call_send_close_from_client_delegate(CallSafeHandle call,
diff --git a/src/csharp/Grpc.Dotnet.sln b/src/csharp/Grpc.Dotnet.sln
index 98b3cd54ab..824c6822f7 100644
--- a/src/csharp/Grpc.Dotnet.sln
+++ b/src/csharp/Grpc.Dotnet.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.25123.0
+VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Core", "Grpc.Core\Grpc.Core.xproj", "{DC9908B6-F291-4FC8-A46D-2EA2551790EC}"
EndProject
@@ -31,6 +31,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.IntegrationTesting.Ser
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.IntegrationTesting.StressClient", "Grpc.IntegrationTesting.StressClient\Grpc.IntegrationTesting.StressClient.xproj", "{0EBC910B-8867-4D3E-8686-91F34183D839}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Reflection", "Grpc.Reflection\Grpc.Reflection.xproj", "{2B372155-80BA-4CF9-82D6-4B938E8EC3A0}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Grpc.Reflection.Tests", "Grpc.Reflection.Tests\Grpc.Reflection.Tests.xproj", "{FE90181D-A4B3-4A5C-8490-F07561E18E3B}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -93,6 +97,14 @@ Global
{0EBC910B-8867-4D3E-8686-91F34183D839}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0EBC910B-8867-4D3E-8686-91F34183D839}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0EBC910B-8867-4D3E-8686-91F34183D839}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2B372155-80BA-4CF9-82D6-4B938E8EC3A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2B372155-80BA-4CF9-82D6-4B938E8EC3A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2B372155-80BA-4CF9-82D6-4B938E8EC3A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2B372155-80BA-4CF9-82D6-4B938E8EC3A0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FE90181D-A4B3-4A5C-8490-F07561E18E3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE90181D-A4B3-4A5C-8490-F07561E18E3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FE90181D-A4B3-4A5C-8490-F07561E18E3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FE90181D-A4B3-4A5C-8490-F07561E18E3B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/csharp/Grpc.Examples/Math.cs b/src/csharp/Grpc.Examples/Math.cs
index fae4fd3c26..e5b76f8305 100644
--- a/src/csharp/Grpc.Examples/Math.cs
+++ b/src/csharp/Grpc.Examples/Math.cs
@@ -1,5 +1,5 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: math.proto
+// source: math/math.proto
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -9,11 +9,11 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Math {
- /// <summary>Holder for reflection information generated from math.proto</summary>
+ /// <summary>Holder for reflection information generated from math/math.proto</summary>
public static partial class MathReflection {
#region Descriptor
- /// <summary>File descriptor for math.proto</summary>
+ /// <summary>File descriptor for math/math.proto</summary>
public static pbr::FileDescriptor Descriptor {
get { return descriptor; }
}
@@ -22,15 +22,15 @@ namespace Math {
static MathReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
- "CgptYXRoLnByb3RvEgRtYXRoIiwKB0RpdkFyZ3MSEAoIZGl2aWRlbmQYASAB",
- "KAMSDwoHZGl2aXNvchgCIAEoAyIvCghEaXZSZXBseRIQCghxdW90aWVudBgB",
- "IAEoAxIRCglyZW1haW5kZXIYAiABKAMiGAoHRmliQXJncxINCgVsaW1pdBgB",
- "IAEoAyISCgNOdW0SCwoDbnVtGAEgASgDIhkKCEZpYlJlcGx5Eg0KBWNvdW50",
- "GAEgASgDMqQBCgRNYXRoEiYKA0RpdhINLm1hdGguRGl2QXJncxoOLm1hdGgu",
- "RGl2UmVwbHkiABIuCgdEaXZNYW55Eg0ubWF0aC5EaXZBcmdzGg4ubWF0aC5E",
- "aXZSZXBseSIAKAEwARIjCgNGaWISDS5tYXRoLkZpYkFyZ3MaCS5tYXRoLk51",
- "bSIAMAESHwoDU3VtEgkubWF0aC5OdW0aCS5tYXRoLk51bSIAKAFiBnByb3Rv",
- "Mw=="));
+ "Cg9tYXRoL21hdGgucHJvdG8SBG1hdGgiLAoHRGl2QXJncxIQCghkaXZpZGVu",
+ "ZBgBIAEoAxIPCgdkaXZpc29yGAIgASgDIi8KCERpdlJlcGx5EhAKCHF1b3Rp",
+ "ZW50GAEgASgDEhEKCXJlbWFpbmRlchgCIAEoAyIYCgdGaWJBcmdzEg0KBWxp",
+ "bWl0GAEgASgDIhIKA051bRILCgNudW0YASABKAMiGQoIRmliUmVwbHkSDQoF",
+ "Y291bnQYASABKAMypAEKBE1hdGgSJgoDRGl2Eg0ubWF0aC5EaXZBcmdzGg4u",
+ "bWF0aC5EaXZSZXBseSIAEi4KB0Rpdk1hbnkSDS5tYXRoLkRpdkFyZ3MaDi5t",
+ "YXRoLkRpdlJlcGx5IgAoATABEiMKA0ZpYhINLm1hdGguRmliQXJncxoJLm1h",
+ "dGguTnVtIgAwARIfCgNTdW0SCS5tYXRoLk51bRoJLm1hdGguTnVtIgAoAWIG",
+ "cHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index 21727d57c6..8b431c7218 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -1,5 +1,5 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: math.proto
+// source: math/math.proto
// Original file comments:
// Copyright 2015, Google Inc.
// All rights reserved.
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
index c8b6d478b7..7418768316 100644
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
+++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -62,13 +62,12 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
- <None Include="Grpc.HealthCheck.nuspec" />
<None Include="Grpc.HealthCheck.project.json" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
- <Project>{ccc4440e-49f7-4790-b0af-feabb0837ae7}</Project>
+ <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
<Name>Grpc.Core</Name>
</ProjectReference>
</ItemGroup>
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
deleted file mode 100644
index f2e36ba2be..0000000000
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<package>
- <metadata>
- <id>Grpc.HealthCheck</id>
- <title>gRPC C# Healthchecking</title>
- <summary>Implementation of gRPC health service</summary>
- <description>Example implementation of grpc.health.v1 service that can be used for health-checking.</description>
- <version>$version$</version>
- <authors>Google Inc.</authors>
- <owners>grpc-packages</owners>
- <licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
- <projectUrl>https://github.com/grpc/grpc</projectUrl>
- <requireLicenseAcceptance>false</requireLicenseAcceptance>
- <copyright>Copyright 2015, Google Inc.</copyright>
- <tags>gRPC health check</tags>
- <dependencies>
- <dependency id="Google.Protobuf" version="$ProtobufVersion$" />
- <dependency id="Grpc.Core" version="$version$" />
- <dependency id="System.Interactive.Async" version="3.1.1" />
- </dependencies>
- </metadata>
- <files>
- <file src="bin/ReleaseSigned/Grpc.HealthCheck.dll" target="lib/net45" />
- <file src="bin/ReleaseSigned/Grpc.HealthCheck.pdb" target="lib/net45" />
- <file src="bin/ReleaseSigned/Grpc.HealthCheck.xml" target="lib/net45" />
- <file src="**\*.cs" target="src" />
- </files>
-</package>
diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs
index b8e2e2274c..b9880d9636 100644
--- a/src/csharp/Grpc.HealthCheck/Health.cs
+++ b/src/csharp/Grpc.HealthCheck/Health.cs
@@ -1,5 +1,5 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: health.proto
+// source: grpc/health/v1/health.proto
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@@ -9,11 +9,11 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Grpc.Health.V1 {
- /// <summary>Holder for reflection information generated from health.proto</summary>
+ /// <summary>Holder for reflection information generated from grpc/health/v1/health.proto</summary>
public static partial class HealthReflection {
#region Descriptor
- /// <summary>File descriptor for health.proto</summary>
+ /// <summary>File descriptor for grpc/health/v1/health.proto</summary>
public static pbr::FileDescriptor Descriptor {
get { return descriptor; }
}
@@ -22,14 +22,14 @@ namespace Grpc.Health.V1 {
static HealthReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
- "CgxoZWFsdGgucHJvdG8SDmdycGMuaGVhbHRoLnYxIiUKEkhlYWx0aENoZWNr",
- "UmVxdWVzdBIPCgdzZXJ2aWNlGAEgASgJIpQBChNIZWFsdGhDaGVja1Jlc3Bv",
- "bnNlEkEKBnN0YXR1cxgBIAEoDjIxLmdycGMuaGVhbHRoLnYxLkhlYWx0aENo",
- "ZWNrUmVzcG9uc2UuU2VydmluZ1N0YXR1cyI6Cg1TZXJ2aW5nU3RhdHVzEgsK",
- "B1VOS05PV04QABILCgdTRVJWSU5HEAESDwoLTk9UX1NFUlZJTkcQAjJaCgZI",
- "ZWFsdGgSUAoFQ2hlY2sSIi5ncnBjLmhlYWx0aC52MS5IZWFsdGhDaGVja1Jl",
- "cXVlc3QaIy5ncnBjLmhlYWx0aC52MS5IZWFsdGhDaGVja1Jlc3BvbnNlQhGq",
- "Ag5HcnBjLkhlYWx0aC5WMWIGcHJvdG8z"));
+ "ChtncnBjL2hlYWx0aC92MS9oZWFsdGgucHJvdG8SDmdycGMuaGVhbHRoLnYx",
+ "IiUKEkhlYWx0aENoZWNrUmVxdWVzdBIPCgdzZXJ2aWNlGAEgASgJIpQBChNI",
+ "ZWFsdGhDaGVja1Jlc3BvbnNlEkEKBnN0YXR1cxgBIAEoDjIxLmdycGMuaGVh",
+ "bHRoLnYxLkhlYWx0aENoZWNrUmVzcG9uc2UuU2VydmluZ1N0YXR1cyI6Cg1T",
+ "ZXJ2aW5nU3RhdHVzEgsKB1VOS05PV04QABILCgdTRVJWSU5HEAESDwoLTk9U",
+ "X1NFUlZJTkcQAjJaCgZIZWFsdGgSUAoFQ2hlY2sSIi5ncnBjLmhlYWx0aC52",
+ "MS5IZWFsdGhDaGVja1JlcXVlc3QaIy5ncnBjLmhlYWx0aC52MS5IZWFsdGhD",
+ "aGVja1Jlc3BvbnNlQhGqAg5HcnBjLkhlYWx0aC5WMWIGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 03381f0b88..ad5cf11b75 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -1,5 +1,5 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: health.proto
+// source: grpc/health/v1/health.proto
// Original file comments:
// Copyright 2015, Google Inc.
// All rights reserved.
diff --git a/src/csharp/Grpc.Reflection.Tests/.gitignore b/src/csharp/Grpc.Reflection.Tests/.gitignore
new file mode 100644
index 0000000000..1746e3269e
--- /dev/null
+++ b/src/csharp/Grpc.Reflection.Tests/.gitignore
@@ -0,0 +1,2 @@
+bin
+obj
diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj
new file mode 100644
index 0000000000..cebcf59ce8
--- /dev/null
+++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{B88F91D6-436D-4C78-8B99-47800FA8DE03}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Grpc.Reflection.Tests</RootNamespace>
+ <AssemblyName>Grpc.Reflection.Tests</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ <Reference Include="nunit.framework">
+ <HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="nunitlite">
+ <HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
+ </Reference>
+ <Reference Include="Google.Protobuf">
+ <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Interactive.Async">
+ <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Grpc.Core\Version.cs">
+ <Link>Version.cs</Link>
+ </Compile>
+ <Compile Include="SymbolRegistryTest.cs" />
+ <Compile Include="ReflectionClientServerTest.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="NUnitMain.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
+ <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
+ <Name>Grpc.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Grpc.Reflection\Grpc.Reflection.csproj">
+ <Project>{4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}</Project>
+ <Name>Grpc.Reflection</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Grpc.Reflection.Tests.project.json" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.project.json b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.project.json
new file mode 100644
index 0000000000..c2f5bcb163
--- /dev/null
+++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.project.json
@@ -0,0 +1,8 @@
+{
+ "frameworks": {
+ "net45": { }
+ },
+ "runtimes": {
+ "win": { }
+ }
+}
diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.xproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.xproj
new file mode 100644
index 0000000000..4a3100853d
--- /dev/null
+++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.xproj
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>fe90181d-a4b3-4a5c-8490-f07561e18e3b</ProjectGuid>
+ <RootNamespace>Grpc.Reflection.Tests</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs
new file mode 100644
index 0000000000..a60d7b03eb
--- /dev/null
+++ b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs
@@ -0,0 +1,59 @@
+#region Copyright notice and license
+
+// Copyright 2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Reflection;
+using Grpc.Core;
+using Grpc.Core.Logging;
+using NUnit.Common;
+using NUnitLite;
+
+namespace Grpc.Reflection.Tests
+{
+ /// <summary>
+ /// Provides entry point for NUnitLite
+ /// </summary>
+ public class NUnitMain
+ {
+ public static int Main(string[] args)
+ {
+ // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
+ GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
+#if NETCOREAPP1_0
+ return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
+#else
+ return new AutoRun().Execute(args);
+#endif
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Reflection.Tests/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Reflection.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..d29054a4d1
--- /dev/null
+++ b/src/csharp/Grpc.Reflection.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,44 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle("Grpc.Reflection.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
diff --git a/src/csharp/Grpc.Reflection.Tests/ReflectionClientServerTest.cs b/src/csharp/Grpc.Reflection.Tests/ReflectionClientServerTest.cs
new file mode 100644
index 0000000000..1d0845e276
--- /dev/null
+++ b/src/csharp/Grpc.Reflection.Tests/ReflectionClientServerTest.cs
@@ -0,0 +1,154 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Grpc.Core;
+using Grpc.Reflection;
+using Grpc.Reflection.V1Alpha;
+using NUnit.Framework;
+
+namespace Grpc.Reflection.Tests
+{
+ /// <summary>
+ /// Reflection client talks to reflection server.
+ /// </summary>
+ public class ReflectionClientServerTest
+ {
+ const string Host = "localhost";
+ Server server;
+ Channel channel;
+ ServerReflection.ServerReflectionClient client;
+ ReflectionServiceImpl serviceImpl;
+
+ [TestFixtureSetUp]
+ public void Init()
+ {
+ serviceImpl = new ReflectionServiceImpl(ServerReflection.Descriptor);
+
+ server = new Server
+ {
+ Services = { ServerReflection.BindService(serviceImpl) },
+ Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } }
+ };
+ server.Start();
+ channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure);
+
+ client = new ServerReflection.ServerReflectionClient(channel);
+ }
+
+ [TestFixtureTearDown]
+ public void Cleanup()
+ {
+ channel.ShutdownAsync().Wait();
+ server.ShutdownAsync().Wait();
+ }
+
+ [Test]
+ public async Task FileByFilename_NotFound()
+ {
+ var response = await SingleRequestAsync(new ServerReflectionRequest
+ {
+ FileByFilename = "somepackage/nonexistent.proto"
+ });
+ Assert.AreEqual((int)StatusCode.NotFound, response.ErrorResponse.ErrorCode);
+ }
+
+ [Test]
+ public async Task FileByFilename()
+ {
+ var response = await SingleRequestAsync(new ServerReflectionRequest
+ {
+ FileByFilename = "grpc/reflection/v1alpha/reflection.proto"
+ });
+ Assert.AreEqual(1, response.FileDescriptorResponse.FileDescriptorProto.Count);
+ Assert.AreEqual(ReflectionReflection.Descriptor.SerializedData, response.FileDescriptorResponse.FileDescriptorProto[0]);
+ }
+
+ [Test]
+ public async Task FileContainingSymbol()
+ {
+ var response = await SingleRequestAsync(new ServerReflectionRequest
+ {
+ FileContainingSymbol = "grpc.reflection.v1alpha.ServerReflection"
+ });
+ Assert.AreEqual(1, response.FileDescriptorResponse.FileDescriptorProto.Count);
+ Assert.AreEqual(ReflectionReflection.Descriptor.SerializedData, response.FileDescriptorResponse.FileDescriptorProto[0]);
+ }
+
+ [Test]
+ public async Task FileContainingSymbol_NotFound()
+ {
+ var response = await SingleRequestAsync(new ServerReflectionRequest
+ {
+ FileContainingSymbol = "somepackage.Nonexistent"
+ });
+ Assert.AreEqual((int)StatusCode.NotFound, response.ErrorResponse.ErrorCode);
+ }
+
+ [Test]
+ public async Task ListServices()
+ {
+ var response = await SingleRequestAsync(new ServerReflectionRequest
+ {
+ ListServices = ""
+ });
+ Assert.AreEqual(1, response.ListServicesResponse.Service.Count);
+ Assert.AreEqual(ServerReflection.Descriptor.FullName, response.ListServicesResponse.Service[0].Name);
+ }
+
+ [Test]
+ public async Task FileContainingExtension()
+ {
+ var response = await SingleRequestAsync(new ServerReflectionRequest
+ {
+ FileContainingExtension = new ExtensionRequest()
+ });
+ Assert.AreEqual((int)StatusCode.Unimplemented, response.ErrorResponse.ErrorCode);
+ }
+
+ private async Task<ServerReflectionResponse> SingleRequestAsync(ServerReflectionRequest request)
+ {
+ var call = client.ServerReflectionInfo();
+ await call.RequestStream.WriteAsync(request);
+ Assert.IsTrue(await call.ResponseStream.MoveNext());
+
+ var response = call.ResponseStream.Current;
+ await call.RequestStream.CompleteAsync();
+ Assert.IsFalse(await call.ResponseStream.MoveNext());
+ return response;
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Reflection.Tests/SymbolRegistryTest.cs b/src/csharp/Grpc.Reflection.Tests/SymbolRegistryTest.cs
new file mode 100644
index 0000000000..68ee6dc10d
--- /dev/null
+++ b/src/csharp/Grpc.Reflection.Tests/SymbolRegistryTest.cs
@@ -0,0 +1,63 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using Grpc.Reflection;
+using Grpc.Reflection.V1Alpha;
+using NUnit.Framework;
+
+
+namespace Grpc.Reflection.Tests
+{
+ /// <summary>
+ /// Tests for ReflectionServiceImpl
+ /// </summary>
+ public class SymbolRegistryTest
+ {
+ SymbolRegistry registry = SymbolRegistry.FromFiles(new[] { ReflectionReflection.Descriptor, Google.Protobuf.WellKnownTypes.Duration.Descriptor.File });
+
+ [Test]
+ public void FileByName()
+ {
+ Assert.AreSame(Google.Protobuf.WellKnownTypes.Duration.Descriptor.File, registry.FileByName("google/protobuf/duration.proto"));
+ Assert.IsNull(registry.FileByName("somepackage/nonexistent.proto"));
+ }
+
+ [Test]
+ public void FileContainingSymbol()
+ {
+ Assert.AreSame(Google.Protobuf.WellKnownTypes.Duration.Descriptor.File, registry.FileContainingSymbol("google.protobuf.Duration"));
+ Assert.AreSame(ReflectionReflection.Descriptor, registry.FileContainingSymbol("grpc.reflection.v1alpha.ServerReflection.ServerReflectionInfo")); // method
+ Assert.AreSame(ReflectionReflection.Descriptor, registry.FileContainingSymbol("grpc.reflection.v1alpha.ServerReflection")); // service
+ Assert.AreSame(ReflectionReflection.Descriptor, registry.FileContainingSymbol("grpc.reflection.v1alpha.ServerReflectionRequest")); // message
+ Assert.IsNull(registry.FileContainingSymbol("somepackage.Nonexistent"));
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Reflection.Tests/packages.config b/src/csharp/Grpc.Reflection.Tests/packages.config
new file mode 100644
index 0000000000..0fed4dbd41
--- /dev/null
+++ b/src/csharp/Grpc.Reflection.Tests/packages.config
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
+ <package id="NUnit" version="3.2.0" targetFramework="net45" />
+ <package id="NUnitLite" version="3.2.0" targetFramework="net45" />
+ <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/src/csharp/Grpc.Reflection.Tests/project.json b/src/csharp/Grpc.Reflection.Tests/project.json
new file mode 100644
index 0000000000..61d3b7e47b
--- /dev/null
+++ b/src/csharp/Grpc.Reflection.Tests/project.json
@@ -0,0 +1,65 @@
+{
+ "buildOptions": {
+ "emitEntryPoint": true
+ },
+ "configurations": {
+ "Debug": {
+ "buildOptions": {
+ "define": [ "SIGNED" ],
+ "keyFile": "../keys/Grpc.snk",
+ "xmlDoc": true,
+ "compile": {
+ "includeFiles": [ "../Grpc.Core/Version.cs" ]
+ },
+ "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",
+ "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
+ "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib"
+ }
+ }
+ }
+ },
+ "Release": {
+ "buildOptions": {
+ "define": [ "SIGNED" ],
+ "keyFile": "../keys/Grpc.snk",
+ "xmlDoc": true,
+ "compile": {
+ "includeFiles": [ "../Grpc.Core/Version.cs" ]
+ },
+ "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",
+ "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
+ "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib"
+ }
+ }
+ }
+ }
+ },
+
+ "dependencies": {
+ "Grpc.Reflection": {
+ "target": "project"
+ },
+ "NUnit": "3.2.0",
+ "NUnitLite": "3.2.0-*"
+ },
+ "frameworks": {
+ "net45": { },
+ "netcoreapp1.0": {
+ "imports": [
+ "portable-net45"
+ ],
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0"
+ }
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Reflection/.gitignore b/src/csharp/Grpc.Reflection/.gitignore
new file mode 100644
index 0000000000..1746e3269e
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/.gitignore
@@ -0,0 +1,2 @@
+bin
+obj
diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj
new file mode 100644
index 0000000000..ea65998ce3
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Grpc.Reflection</RootNamespace>
+ <AssemblyName>Grpc.Reflection</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <DocumentationFile>bin\$(Configuration)\Grpc.Reflection.Xml</DocumentationFile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ <Reference Include="Google.Protobuf">
+ <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Interactive.Async">
+ <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Grpc.Core\Version.cs">
+ <Link>Version.cs</Link>
+ </Compile>
+ <Compile Include="SymbolRegistry.cs" />
+ <Compile Include="ReflectionServiceImpl.cs" />
+ <Compile Include="Reflection.cs" />
+ <Compile Include="ReflectionGrpc.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Grpc.Reflection.project.json" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
+ <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
+ <Name>Grpc.Core</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.project.json b/src/csharp/Grpc.Reflection/Grpc.Reflection.project.json
new file mode 100644
index 0000000000..c2f5bcb163
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.project.json
@@ -0,0 +1,8 @@
+{
+ "frameworks": {
+ "net45": { }
+ },
+ "runtimes": {
+ "win": { }
+ }
+}
diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.xproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.xproj
new file mode 100644
index 0000000000..833d98b121
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.xproj
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>2b372155-80ba-4cf9-82d6-4b938e8ec3a0</ProjectGuid>
+ <RootNamespace>Grpc.Reflection</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Reflection/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Reflection/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..3104ecdd54
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/Properties/AssemblyInfo.cs
@@ -0,0 +1,44 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle("Grpc.Reflection")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
diff --git a/src/csharp/Grpc.Reflection/Reflection.cs b/src/csharp/Grpc.Reflection/Reflection.cs
new file mode 100644
index 0000000000..06c5d08030
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/Reflection.cs
@@ -0,0 +1,1556 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: grpc/reflection/v1alpha/reflection.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Reflection.V1Alpha {
+
+ /// <summary>Holder for reflection information generated from grpc/reflection/v1alpha/reflection.proto</summary>
+ public static partial class ReflectionReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for grpc/reflection/v1alpha/reflection.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static ReflectionReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "CihncnBjL3JlZmxlY3Rpb24vdjFhbHBoYS9yZWZsZWN0aW9uLnByb3RvEhdn",
+ "cnBjLnJlZmxlY3Rpb24udjFhbHBoYSKKAgoXU2VydmVyUmVmbGVjdGlvblJl",
+ "cXVlc3QSDAoEaG9zdBgBIAEoCRIaChBmaWxlX2J5X2ZpbGVuYW1lGAMgASgJ",
+ "SAASIAoWZmlsZV9jb250YWluaW5nX3N5bWJvbBgEIAEoCUgAEk4KGWZpbGVf",
+ "Y29udGFpbmluZ19leHRlbnNpb24YBSABKAsyKS5ncnBjLnJlZmxlY3Rpb24u",
+ "djFhbHBoYS5FeHRlbnNpb25SZXF1ZXN0SAASJwodYWxsX2V4dGVuc2lvbl9u",
+ "dW1iZXJzX29mX3R5cGUYBiABKAlIABIXCg1saXN0X3NlcnZpY2VzGAcgASgJ",
+ "SABCEQoPbWVzc2FnZV9yZXF1ZXN0IkUKEEV4dGVuc2lvblJlcXVlc3QSFwoP",
+ "Y29udGFpbmluZ190eXBlGAEgASgJEhgKEGV4dGVuc2lvbl9udW1iZXIYAiAB",
+ "KAUi0QMKGFNlcnZlclJlZmxlY3Rpb25SZXNwb25zZRISCgp2YWxpZF9ob3N0",
+ "GAEgASgJEkoKEG9yaWdpbmFsX3JlcXVlc3QYAiABKAsyMC5ncnBjLnJlZmxl",
+ "Y3Rpb24udjFhbHBoYS5TZXJ2ZXJSZWZsZWN0aW9uUmVxdWVzdBJTChhmaWxl",
+ "X2Rlc2NyaXB0b3JfcmVzcG9uc2UYBCABKAsyLy5ncnBjLnJlZmxlY3Rpb24u",
+ "djFhbHBoYS5GaWxlRGVzY3JpcHRvclJlc3BvbnNlSAASWgoeYWxsX2V4dGVu",
+ "c2lvbl9udW1iZXJzX3Jlc3BvbnNlGAUgASgLMjAuZ3JwYy5yZWZsZWN0aW9u",
+ "LnYxYWxwaGEuRXh0ZW5zaW9uTnVtYmVyUmVzcG9uc2VIABJOChZsaXN0X3Nl",
+ "cnZpY2VzX3Jlc3BvbnNlGAYgASgLMiwuZ3JwYy5yZWZsZWN0aW9uLnYxYWxw",
+ "aGEuTGlzdFNlcnZpY2VSZXNwb25zZUgAEkAKDmVycm9yX3Jlc3BvbnNlGAcg",
+ "ASgLMiYuZ3JwYy5yZWZsZWN0aW9uLnYxYWxwaGEuRXJyb3JSZXNwb25zZUgA",
+ "QhIKEG1lc3NhZ2VfcmVzcG9uc2UiNwoWRmlsZURlc2NyaXB0b3JSZXNwb25z",
+ "ZRIdChVmaWxlX2Rlc2NyaXB0b3JfcHJvdG8YASADKAwiSwoXRXh0ZW5zaW9u",
+ "TnVtYmVyUmVzcG9uc2USFgoOYmFzZV90eXBlX25hbWUYASABKAkSGAoQZXh0",
+ "ZW5zaW9uX251bWJlchgCIAMoBSJQChNMaXN0U2VydmljZVJlc3BvbnNlEjkK",
+ "B3NlcnZpY2UYASADKAsyKC5ncnBjLnJlZmxlY3Rpb24udjFhbHBoYS5TZXJ2",
+ "aWNlUmVzcG9uc2UiHwoPU2VydmljZVJlc3BvbnNlEgwKBG5hbWUYASABKAki",
+ "OgoNRXJyb3JSZXNwb25zZRISCgplcnJvcl9jb2RlGAEgASgFEhUKDWVycm9y",
+ "X21lc3NhZ2UYAiABKAkykwEKEFNlcnZlclJlZmxlY3Rpb24SfwoUU2VydmVy",
+ "UmVmbGVjdGlvbkluZm8SMC5ncnBjLnJlZmxlY3Rpb24udjFhbHBoYS5TZXJ2",
+ "ZXJSZWZsZWN0aW9uUmVxdWVzdBoxLmdycGMucmVmbGVjdGlvbi52MWFscGhh",
+ "LlNlcnZlclJlZmxlY3Rpb25SZXNwb25zZSgBMAFiBnByb3RvMw=="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Reflection.V1Alpha.ServerReflectionRequest), global::Grpc.Reflection.V1Alpha.ServerReflectionRequest.Parser, new[]{ "Host", "FileByFilename", "FileContainingSymbol", "FileContainingExtension", "AllExtensionNumbersOfType", "ListServices" }, new[]{ "MessageRequest" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Reflection.V1Alpha.ExtensionRequest), global::Grpc.Reflection.V1Alpha.ExtensionRequest.Parser, new[]{ "ContainingType", "ExtensionNumber" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Reflection.V1Alpha.ServerReflectionResponse), global::Grpc.Reflection.V1Alpha.ServerReflectionResponse.Parser, new[]{ "ValidHost", "OriginalRequest", "FileDescriptorResponse", "AllExtensionNumbersResponse", "ListServicesResponse", "ErrorResponse" }, new[]{ "MessageResponse" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Reflection.V1Alpha.FileDescriptorResponse), global::Grpc.Reflection.V1Alpha.FileDescriptorResponse.Parser, new[]{ "FileDescriptorProto" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Reflection.V1Alpha.ExtensionNumberResponse), global::Grpc.Reflection.V1Alpha.ExtensionNumberResponse.Parser, new[]{ "BaseTypeName", "ExtensionNumber" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Reflection.V1Alpha.ListServiceResponse), global::Grpc.Reflection.V1Alpha.ListServiceResponse.Parser, new[]{ "Service" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Reflection.V1Alpha.ServiceResponse), global::Grpc.Reflection.V1Alpha.ServiceResponse.Parser, new[]{ "Name" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Reflection.V1Alpha.ErrorResponse), global::Grpc.Reflection.V1Alpha.ErrorResponse.Parser, new[]{ "ErrorCode", "ErrorMessage" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ /// <summary>
+ /// The message sent by the client when calling ServerReflectionInfo method.
+ /// </summary>
+ public sealed partial class ServerReflectionRequest : pb::IMessage<ServerReflectionRequest> {
+ private static readonly pb::MessageParser<ServerReflectionRequest> _parser = new pb::MessageParser<ServerReflectionRequest>(() => new ServerReflectionRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ServerReflectionRequest> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Reflection.V1Alpha.ReflectionReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ServerReflectionRequest() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ServerReflectionRequest(ServerReflectionRequest other) : this() {
+ host_ = other.host_;
+ switch (other.MessageRequestCase) {
+ case MessageRequestOneofCase.FileByFilename:
+ FileByFilename = other.FileByFilename;
+ break;
+ case MessageRequestOneofCase.FileContainingSymbol:
+ FileContainingSymbol = other.FileContainingSymbol;
+ break;
+ case MessageRequestOneofCase.FileContainingExtension:
+ FileContainingExtension = other.FileContainingExtension.Clone();
+ break;
+ case MessageRequestOneofCase.AllExtensionNumbersOfType:
+ AllExtensionNumbersOfType = other.AllExtensionNumbersOfType;
+ break;
+ case MessageRequestOneofCase.ListServices:
+ ListServices = other.ListServices;
+ break;
+ }
+
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ServerReflectionRequest Clone() {
+ return new ServerReflectionRequest(this);
+ }
+
+ /// <summary>Field number for the "host" field.</summary>
+ public const int HostFieldNumber = 1;
+ private string host_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Host {
+ get { return host_; }
+ set {
+ host_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "file_by_filename" field.</summary>
+ public const int FileByFilenameFieldNumber = 3;
+ /// <summary>
+ /// Find a proto file by the file name.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string FileByFilename {
+ get { return messageRequestCase_ == MessageRequestOneofCase.FileByFilename ? (string) messageRequest_ : ""; }
+ set {
+ messageRequest_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ messageRequestCase_ = MessageRequestOneofCase.FileByFilename;
+ }
+ }
+
+ /// <summary>Field number for the "file_containing_symbol" field.</summary>
+ public const int FileContainingSymbolFieldNumber = 4;
+ /// <summary>
+ /// Find the proto file that declares the given fully-qualified symbol name.
+ /// This field should be a fully-qualified symbol name
+ /// (e.g. &lt;package>.&lt;service>[.&lt;method>] or &lt;package>.&lt;type>).
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string FileContainingSymbol {
+ get { return messageRequestCase_ == MessageRequestOneofCase.FileContainingSymbol ? (string) messageRequest_ : ""; }
+ set {
+ messageRequest_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ messageRequestCase_ = MessageRequestOneofCase.FileContainingSymbol;
+ }
+ }
+
+ /// <summary>Field number for the "file_containing_extension" field.</summary>
+ public const int FileContainingExtensionFieldNumber = 5;
+ /// <summary>
+ /// Find the proto file which defines an extension extending the given
+ /// message type with the given field number.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Grpc.Reflection.V1Alpha.ExtensionRequest FileContainingExtension {
+ get { return messageRequestCase_ == MessageRequestOneofCase.FileContainingExtension ? (global::Grpc.Reflection.V1Alpha.ExtensionRequest) messageRequest_ : null; }
+ set {
+ messageRequest_ = value;
+ messageRequestCase_ = value == null ? MessageRequestOneofCase.None : MessageRequestOneofCase.FileContainingExtension;
+ }
+ }
+
+ /// <summary>Field number for the "all_extension_numbers_of_type" field.</summary>
+ public const int AllExtensionNumbersOfTypeFieldNumber = 6;
+ /// <summary>
+ /// Finds the tag numbers used by all known extensions of the given message
+ /// type, and appends them to ExtensionNumberResponse in an undefined order.
+ /// Its corresponding method is best-effort: it's not guaranteed that the
+ /// reflection service will implement this method, and it's not guaranteed
+ /// that this method will provide all extensions. Returns
+ /// StatusCode::UNIMPLEMENTED if it's not implemented.
+ /// This field should be a fully-qualified type name. The format is
+ /// &lt;package>.&lt;type>
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string AllExtensionNumbersOfType {
+ get { return messageRequestCase_ == MessageRequestOneofCase.AllExtensionNumbersOfType ? (string) messageRequest_ : ""; }
+ set {
+ messageRequest_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ messageRequestCase_ = MessageRequestOneofCase.AllExtensionNumbersOfType;
+ }
+ }
+
+ /// <summary>Field number for the "list_services" field.</summary>
+ public const int ListServicesFieldNumber = 7;
+ /// <summary>
+ /// List the full names of registered services. The content will not be
+ /// checked.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string ListServices {
+ get { return messageRequestCase_ == MessageRequestOneofCase.ListServices ? (string) messageRequest_ : ""; }
+ set {
+ messageRequest_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ messageRequestCase_ = MessageRequestOneofCase.ListServices;
+ }
+ }
+
+ private object messageRequest_;
+ /// <summary>Enum of possible cases for the "message_request" oneof.</summary>
+ public enum MessageRequestOneofCase {
+ None = 0,
+ FileByFilename = 3,
+ FileContainingSymbol = 4,
+ FileContainingExtension = 5,
+ AllExtensionNumbersOfType = 6,
+ ListServices = 7,
+ }
+ private MessageRequestOneofCase messageRequestCase_ = MessageRequestOneofCase.None;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public MessageRequestOneofCase MessageRequestCase {
+ get { return messageRequestCase_; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void ClearMessageRequest() {
+ messageRequestCase_ = MessageRequestOneofCase.None;
+ messageRequest_ = null;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ServerReflectionRequest);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ServerReflectionRequest other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Host != other.Host) return false;
+ if (FileByFilename != other.FileByFilename) return false;
+ if (FileContainingSymbol != other.FileContainingSymbol) return false;
+ if (!object.Equals(FileContainingExtension, other.FileContainingExtension)) return false;
+ if (AllExtensionNumbersOfType != other.AllExtensionNumbersOfType) return false;
+ if (ListServices != other.ListServices) return false;
+ if (MessageRequestCase != other.MessageRequestCase) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Host.Length != 0) hash ^= Host.GetHashCode();
+ if (messageRequestCase_ == MessageRequestOneofCase.FileByFilename) hash ^= FileByFilename.GetHashCode();
+ if (messageRequestCase_ == MessageRequestOneofCase.FileContainingSymbol) hash ^= FileContainingSymbol.GetHashCode();
+ if (messageRequestCase_ == MessageRequestOneofCase.FileContainingExtension) hash ^= FileContainingExtension.GetHashCode();
+ if (messageRequestCase_ == MessageRequestOneofCase.AllExtensionNumbersOfType) hash ^= AllExtensionNumbersOfType.GetHashCode();
+ if (messageRequestCase_ == MessageRequestOneofCase.ListServices) hash ^= ListServices.GetHashCode();
+ hash ^= (int) messageRequestCase_;
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Host.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Host);
+ }
+ if (messageRequestCase_ == MessageRequestOneofCase.FileByFilename) {
+ output.WriteRawTag(26);
+ output.WriteString(FileByFilename);
+ }
+ if (messageRequestCase_ == MessageRequestOneofCase.FileContainingSymbol) {
+ output.WriteRawTag(34);
+ output.WriteString(FileContainingSymbol);
+ }
+ if (messageRequestCase_ == MessageRequestOneofCase.FileContainingExtension) {
+ output.WriteRawTag(42);
+ output.WriteMessage(FileContainingExtension);
+ }
+ if (messageRequestCase_ == MessageRequestOneofCase.AllExtensionNumbersOfType) {
+ output.WriteRawTag(50);
+ output.WriteString(AllExtensionNumbersOfType);
+ }
+ if (messageRequestCase_ == MessageRequestOneofCase.ListServices) {
+ output.WriteRawTag(58);
+ output.WriteString(ListServices);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Host.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Host);
+ }
+ if (messageRequestCase_ == MessageRequestOneofCase.FileByFilename) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(FileByFilename);
+ }
+ if (messageRequestCase_ == MessageRequestOneofCase.FileContainingSymbol) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(FileContainingSymbol);
+ }
+ if (messageRequestCase_ == MessageRequestOneofCase.FileContainingExtension) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(FileContainingExtension);
+ }
+ if (messageRequestCase_ == MessageRequestOneofCase.AllExtensionNumbersOfType) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(AllExtensionNumbersOfType);
+ }
+ if (messageRequestCase_ == MessageRequestOneofCase.ListServices) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(ListServices);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ServerReflectionRequest other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Host.Length != 0) {
+ Host = other.Host;
+ }
+ switch (other.MessageRequestCase) {
+ case MessageRequestOneofCase.FileByFilename:
+ FileByFilename = other.FileByFilename;
+ break;
+ case MessageRequestOneofCase.FileContainingSymbol:
+ FileContainingSymbol = other.FileContainingSymbol;
+ break;
+ case MessageRequestOneofCase.FileContainingExtension:
+ FileContainingExtension = other.FileContainingExtension;
+ break;
+ case MessageRequestOneofCase.AllExtensionNumbersOfType:
+ AllExtensionNumbersOfType = other.AllExtensionNumbersOfType;
+ break;
+ case MessageRequestOneofCase.ListServices:
+ ListServices = other.ListServices;
+ break;
+ }
+
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Host = input.ReadString();
+ break;
+ }
+ case 26: {
+ FileByFilename = input.ReadString();
+ break;
+ }
+ case 34: {
+ FileContainingSymbol = input.ReadString();
+ break;
+ }
+ case 42: {
+ global::Grpc.Reflection.V1Alpha.ExtensionRequest subBuilder = new global::Grpc.Reflection.V1Alpha.ExtensionRequest();
+ if (messageRequestCase_ == MessageRequestOneofCase.FileContainingExtension) {
+ subBuilder.MergeFrom(FileContainingExtension);
+ }
+ input.ReadMessage(subBuilder);
+ FileContainingExtension = subBuilder;
+ break;
+ }
+ case 50: {
+ AllExtensionNumbersOfType = input.ReadString();
+ break;
+ }
+ case 58: {
+ ListServices = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// The type name and extension number sent by the client when requesting
+ /// file_containing_extension.
+ /// </summary>
+ public sealed partial class ExtensionRequest : pb::IMessage<ExtensionRequest> {
+ private static readonly pb::MessageParser<ExtensionRequest> _parser = new pb::MessageParser<ExtensionRequest>(() => new ExtensionRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ExtensionRequest> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Reflection.V1Alpha.ReflectionReflection.Descriptor.MessageTypes[1]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ExtensionRequest() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ExtensionRequest(ExtensionRequest other) : this() {
+ containingType_ = other.containingType_;
+ extensionNumber_ = other.extensionNumber_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ExtensionRequest Clone() {
+ return new ExtensionRequest(this);
+ }
+
+ /// <summary>Field number for the "containing_type" field.</summary>
+ public const int ContainingTypeFieldNumber = 1;
+ private string containingType_ = "";
+ /// <summary>
+ /// Fully-qualified type name. The format should be &lt;package>.&lt;type>
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string ContainingType {
+ get { return containingType_; }
+ set {
+ containingType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "extension_number" field.</summary>
+ public const int ExtensionNumberFieldNumber = 2;
+ private int extensionNumber_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int ExtensionNumber {
+ get { return extensionNumber_; }
+ set {
+ extensionNumber_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ExtensionRequest);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ExtensionRequest other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (ContainingType != other.ContainingType) return false;
+ if (ExtensionNumber != other.ExtensionNumber) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (ContainingType.Length != 0) hash ^= ContainingType.GetHashCode();
+ if (ExtensionNumber != 0) hash ^= ExtensionNumber.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (ContainingType.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(ContainingType);
+ }
+ if (ExtensionNumber != 0) {
+ output.WriteRawTag(16);
+ output.WriteInt32(ExtensionNumber);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (ContainingType.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(ContainingType);
+ }
+ if (ExtensionNumber != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(ExtensionNumber);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ExtensionRequest other) {
+ if (other == null) {
+ return;
+ }
+ if (other.ContainingType.Length != 0) {
+ ContainingType = other.ContainingType;
+ }
+ if (other.ExtensionNumber != 0) {
+ ExtensionNumber = other.ExtensionNumber;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ ContainingType = input.ReadString();
+ break;
+ }
+ case 16: {
+ ExtensionNumber = input.ReadInt32();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// The message sent by the server to answer ServerReflectionInfo method.
+ /// </summary>
+ public sealed partial class ServerReflectionResponse : pb::IMessage<ServerReflectionResponse> {
+ private static readonly pb::MessageParser<ServerReflectionResponse> _parser = new pb::MessageParser<ServerReflectionResponse>(() => new ServerReflectionResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ServerReflectionResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Reflection.V1Alpha.ReflectionReflection.Descriptor.MessageTypes[2]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ServerReflectionResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ServerReflectionResponse(ServerReflectionResponse other) : this() {
+ validHost_ = other.validHost_;
+ OriginalRequest = other.originalRequest_ != null ? other.OriginalRequest.Clone() : null;
+ switch (other.MessageResponseCase) {
+ case MessageResponseOneofCase.FileDescriptorResponse:
+ FileDescriptorResponse = other.FileDescriptorResponse.Clone();
+ break;
+ case MessageResponseOneofCase.AllExtensionNumbersResponse:
+ AllExtensionNumbersResponse = other.AllExtensionNumbersResponse.Clone();
+ break;
+ case MessageResponseOneofCase.ListServicesResponse:
+ ListServicesResponse = other.ListServicesResponse.Clone();
+ break;
+ case MessageResponseOneofCase.ErrorResponse:
+ ErrorResponse = other.ErrorResponse.Clone();
+ break;
+ }
+
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ServerReflectionResponse Clone() {
+ return new ServerReflectionResponse(this);
+ }
+
+ /// <summary>Field number for the "valid_host" field.</summary>
+ public const int ValidHostFieldNumber = 1;
+ private string validHost_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string ValidHost {
+ get { return validHost_; }
+ set {
+ validHost_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "original_request" field.</summary>
+ public const int OriginalRequestFieldNumber = 2;
+ private global::Grpc.Reflection.V1Alpha.ServerReflectionRequest originalRequest_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Grpc.Reflection.V1Alpha.ServerReflectionRequest OriginalRequest {
+ get { return originalRequest_; }
+ set {
+ originalRequest_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "file_descriptor_response" field.</summary>
+ public const int FileDescriptorResponseFieldNumber = 4;
+ /// <summary>
+ /// This message is used to answer file_by_filename, file_containing_symbol,
+ /// file_containing_extension requests with transitive dependencies. As
+ /// the repeated label is not allowed in oneof fields, we use a
+ /// FileDescriptorResponse message to encapsulate the repeated fields.
+ /// The reflection service is allowed to avoid sending FileDescriptorProtos
+ /// that were previously sent in response to earlier requests in the stream.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Grpc.Reflection.V1Alpha.FileDescriptorResponse FileDescriptorResponse {
+ get { return messageResponseCase_ == MessageResponseOneofCase.FileDescriptorResponse ? (global::Grpc.Reflection.V1Alpha.FileDescriptorResponse) messageResponse_ : null; }
+ set {
+ messageResponse_ = value;
+ messageResponseCase_ = value == null ? MessageResponseOneofCase.None : MessageResponseOneofCase.FileDescriptorResponse;
+ }
+ }
+
+ /// <summary>Field number for the "all_extension_numbers_response" field.</summary>
+ public const int AllExtensionNumbersResponseFieldNumber = 5;
+ /// <summary>
+ /// This message is used to answer all_extension_numbers_of_type requst.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Grpc.Reflection.V1Alpha.ExtensionNumberResponse AllExtensionNumbersResponse {
+ get { return messageResponseCase_ == MessageResponseOneofCase.AllExtensionNumbersResponse ? (global::Grpc.Reflection.V1Alpha.ExtensionNumberResponse) messageResponse_ : null; }
+ set {
+ messageResponse_ = value;
+ messageResponseCase_ = value == null ? MessageResponseOneofCase.None : MessageResponseOneofCase.AllExtensionNumbersResponse;
+ }
+ }
+
+ /// <summary>Field number for the "list_services_response" field.</summary>
+ public const int ListServicesResponseFieldNumber = 6;
+ /// <summary>
+ /// This message is used to answer list_services request.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Grpc.Reflection.V1Alpha.ListServiceResponse ListServicesResponse {
+ get { return messageResponseCase_ == MessageResponseOneofCase.ListServicesResponse ? (global::Grpc.Reflection.V1Alpha.ListServiceResponse) messageResponse_ : null; }
+ set {
+ messageResponse_ = value;
+ messageResponseCase_ = value == null ? MessageResponseOneofCase.None : MessageResponseOneofCase.ListServicesResponse;
+ }
+ }
+
+ /// <summary>Field number for the "error_response" field.</summary>
+ public const int ErrorResponseFieldNumber = 7;
+ /// <summary>
+ /// This message is used when an error occurs.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Grpc.Reflection.V1Alpha.ErrorResponse ErrorResponse {
+ get { return messageResponseCase_ == MessageResponseOneofCase.ErrorResponse ? (global::Grpc.Reflection.V1Alpha.ErrorResponse) messageResponse_ : null; }
+ set {
+ messageResponse_ = value;
+ messageResponseCase_ = value == null ? MessageResponseOneofCase.None : MessageResponseOneofCase.ErrorResponse;
+ }
+ }
+
+ private object messageResponse_;
+ /// <summary>Enum of possible cases for the "message_response" oneof.</summary>
+ public enum MessageResponseOneofCase {
+ None = 0,
+ FileDescriptorResponse = 4,
+ AllExtensionNumbersResponse = 5,
+ ListServicesResponse = 6,
+ ErrorResponse = 7,
+ }
+ private MessageResponseOneofCase messageResponseCase_ = MessageResponseOneofCase.None;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public MessageResponseOneofCase MessageResponseCase {
+ get { return messageResponseCase_; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void ClearMessageResponse() {
+ messageResponseCase_ = MessageResponseOneofCase.None;
+ messageResponse_ = null;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ServerReflectionResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ServerReflectionResponse other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (ValidHost != other.ValidHost) return false;
+ if (!object.Equals(OriginalRequest, other.OriginalRequest)) return false;
+ if (!object.Equals(FileDescriptorResponse, other.FileDescriptorResponse)) return false;
+ if (!object.Equals(AllExtensionNumbersResponse, other.AllExtensionNumbersResponse)) return false;
+ if (!object.Equals(ListServicesResponse, other.ListServicesResponse)) return false;
+ if (!object.Equals(ErrorResponse, other.ErrorResponse)) return false;
+ if (MessageResponseCase != other.MessageResponseCase) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (ValidHost.Length != 0) hash ^= ValidHost.GetHashCode();
+ if (originalRequest_ != null) hash ^= OriginalRequest.GetHashCode();
+ if (messageResponseCase_ == MessageResponseOneofCase.FileDescriptorResponse) hash ^= FileDescriptorResponse.GetHashCode();
+ if (messageResponseCase_ == MessageResponseOneofCase.AllExtensionNumbersResponse) hash ^= AllExtensionNumbersResponse.GetHashCode();
+ if (messageResponseCase_ == MessageResponseOneofCase.ListServicesResponse) hash ^= ListServicesResponse.GetHashCode();
+ if (messageResponseCase_ == MessageResponseOneofCase.ErrorResponse) hash ^= ErrorResponse.GetHashCode();
+ hash ^= (int) messageResponseCase_;
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (ValidHost.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(ValidHost);
+ }
+ if (originalRequest_ != null) {
+ output.WriteRawTag(18);
+ output.WriteMessage(OriginalRequest);
+ }
+ if (messageResponseCase_ == MessageResponseOneofCase.FileDescriptorResponse) {
+ output.WriteRawTag(34);
+ output.WriteMessage(FileDescriptorResponse);
+ }
+ if (messageResponseCase_ == MessageResponseOneofCase.AllExtensionNumbersResponse) {
+ output.WriteRawTag(42);
+ output.WriteMessage(AllExtensionNumbersResponse);
+ }
+ if (messageResponseCase_ == MessageResponseOneofCase.ListServicesResponse) {
+ output.WriteRawTag(50);
+ output.WriteMessage(ListServicesResponse);
+ }
+ if (messageResponseCase_ == MessageResponseOneofCase.ErrorResponse) {
+ output.WriteRawTag(58);
+ output.WriteMessage(ErrorResponse);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (ValidHost.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(ValidHost);
+ }
+ if (originalRequest_ != null) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(OriginalRequest);
+ }
+ if (messageResponseCase_ == MessageResponseOneofCase.FileDescriptorResponse) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(FileDescriptorResponse);
+ }
+ if (messageResponseCase_ == MessageResponseOneofCase.AllExtensionNumbersResponse) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(AllExtensionNumbersResponse);
+ }
+ if (messageResponseCase_ == MessageResponseOneofCase.ListServicesResponse) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(ListServicesResponse);
+ }
+ if (messageResponseCase_ == MessageResponseOneofCase.ErrorResponse) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(ErrorResponse);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ServerReflectionResponse other) {
+ if (other == null) {
+ return;
+ }
+ if (other.ValidHost.Length != 0) {
+ ValidHost = other.ValidHost;
+ }
+ if (other.originalRequest_ != null) {
+ if (originalRequest_ == null) {
+ originalRequest_ = new global::Grpc.Reflection.V1Alpha.ServerReflectionRequest();
+ }
+ OriginalRequest.MergeFrom(other.OriginalRequest);
+ }
+ switch (other.MessageResponseCase) {
+ case MessageResponseOneofCase.FileDescriptorResponse:
+ FileDescriptorResponse = other.FileDescriptorResponse;
+ break;
+ case MessageResponseOneofCase.AllExtensionNumbersResponse:
+ AllExtensionNumbersResponse = other.AllExtensionNumbersResponse;
+ break;
+ case MessageResponseOneofCase.ListServicesResponse:
+ ListServicesResponse = other.ListServicesResponse;
+ break;
+ case MessageResponseOneofCase.ErrorResponse:
+ ErrorResponse = other.ErrorResponse;
+ break;
+ }
+
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ ValidHost = input.ReadString();
+ break;
+ }
+ case 18: {
+ if (originalRequest_ == null) {
+ originalRequest_ = new global::Grpc.Reflection.V1Alpha.ServerReflectionRequest();
+ }
+ input.ReadMessage(originalRequest_);
+ break;
+ }
+ case 34: {
+ global::Grpc.Reflection.V1Alpha.FileDescriptorResponse subBuilder = new global::Grpc.Reflection.V1Alpha.FileDescriptorResponse();
+ if (messageResponseCase_ == MessageResponseOneofCase.FileDescriptorResponse) {
+ subBuilder.MergeFrom(FileDescriptorResponse);
+ }
+ input.ReadMessage(subBuilder);
+ FileDescriptorResponse = subBuilder;
+ break;
+ }
+ case 42: {
+ global::Grpc.Reflection.V1Alpha.ExtensionNumberResponse subBuilder = new global::Grpc.Reflection.V1Alpha.ExtensionNumberResponse();
+ if (messageResponseCase_ == MessageResponseOneofCase.AllExtensionNumbersResponse) {
+ subBuilder.MergeFrom(AllExtensionNumbersResponse);
+ }
+ input.ReadMessage(subBuilder);
+ AllExtensionNumbersResponse = subBuilder;
+ break;
+ }
+ case 50: {
+ global::Grpc.Reflection.V1Alpha.ListServiceResponse subBuilder = new global::Grpc.Reflection.V1Alpha.ListServiceResponse();
+ if (messageResponseCase_ == MessageResponseOneofCase.ListServicesResponse) {
+ subBuilder.MergeFrom(ListServicesResponse);
+ }
+ input.ReadMessage(subBuilder);
+ ListServicesResponse = subBuilder;
+ break;
+ }
+ case 58: {
+ global::Grpc.Reflection.V1Alpha.ErrorResponse subBuilder = new global::Grpc.Reflection.V1Alpha.ErrorResponse();
+ if (messageResponseCase_ == MessageResponseOneofCase.ErrorResponse) {
+ subBuilder.MergeFrom(ErrorResponse);
+ }
+ input.ReadMessage(subBuilder);
+ ErrorResponse = subBuilder;
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// Serialized FileDescriptorProto messages sent by the server answering
+ /// a file_by_filename, file_containing_symbol, or file_containing_extension
+ /// request.
+ /// </summary>
+ public sealed partial class FileDescriptorResponse : pb::IMessage<FileDescriptorResponse> {
+ private static readonly pb::MessageParser<FileDescriptorResponse> _parser = new pb::MessageParser<FileDescriptorResponse>(() => new FileDescriptorResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<FileDescriptorResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Reflection.V1Alpha.ReflectionReflection.Descriptor.MessageTypes[3]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public FileDescriptorResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public FileDescriptorResponse(FileDescriptorResponse other) : this() {
+ fileDescriptorProto_ = other.fileDescriptorProto_.Clone();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public FileDescriptorResponse Clone() {
+ return new FileDescriptorResponse(this);
+ }
+
+ /// <summary>Field number for the "file_descriptor_proto" field.</summary>
+ public const int FileDescriptorProtoFieldNumber = 1;
+ private static readonly pb::FieldCodec<pb::ByteString> _repeated_fileDescriptorProto_codec
+ = pb::FieldCodec.ForBytes(10);
+ private readonly pbc::RepeatedField<pb::ByteString> fileDescriptorProto_ = new pbc::RepeatedField<pb::ByteString>();
+ /// <summary>
+ /// Serialized FileDescriptorProto messages. We avoid taking a dependency on
+ /// descriptor.proto, which uses proto2 only features, by making them opaque
+ /// bytes instead.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<pb::ByteString> FileDescriptorProto {
+ get { return fileDescriptorProto_; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as FileDescriptorResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(FileDescriptorResponse other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if(!fileDescriptorProto_.Equals(other.fileDescriptorProto_)) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ hash ^= fileDescriptorProto_.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ fileDescriptorProto_.WriteTo(output, _repeated_fileDescriptorProto_codec);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ size += fileDescriptorProto_.CalculateSize(_repeated_fileDescriptorProto_codec);
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(FileDescriptorResponse other) {
+ if (other == null) {
+ return;
+ }
+ fileDescriptorProto_.Add(other.fileDescriptorProto_);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ fileDescriptorProto_.AddEntriesFrom(input, _repeated_fileDescriptorProto_codec);
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// A list of extension numbers sent by the server answering
+ /// all_extension_numbers_of_type request.
+ /// </summary>
+ public sealed partial class ExtensionNumberResponse : pb::IMessage<ExtensionNumberResponse> {
+ private static readonly pb::MessageParser<ExtensionNumberResponse> _parser = new pb::MessageParser<ExtensionNumberResponse>(() => new ExtensionNumberResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ExtensionNumberResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Reflection.V1Alpha.ReflectionReflection.Descriptor.MessageTypes[4]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ExtensionNumberResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ExtensionNumberResponse(ExtensionNumberResponse other) : this() {
+ baseTypeName_ = other.baseTypeName_;
+ extensionNumber_ = other.extensionNumber_.Clone();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ExtensionNumberResponse Clone() {
+ return new ExtensionNumberResponse(this);
+ }
+
+ /// <summary>Field number for the "base_type_name" field.</summary>
+ public const int BaseTypeNameFieldNumber = 1;
+ private string baseTypeName_ = "";
+ /// <summary>
+ /// Full name of the base type, including the package name. The format
+ /// is &lt;package>.&lt;type>
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string BaseTypeName {
+ get { return baseTypeName_; }
+ set {
+ baseTypeName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "extension_number" field.</summary>
+ public const int ExtensionNumberFieldNumber = 2;
+ private static readonly pb::FieldCodec<int> _repeated_extensionNumber_codec
+ = pb::FieldCodec.ForInt32(18);
+ private readonly pbc::RepeatedField<int> extensionNumber_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<int> ExtensionNumber {
+ get { return extensionNumber_; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ExtensionNumberResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ExtensionNumberResponse other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (BaseTypeName != other.BaseTypeName) return false;
+ if(!extensionNumber_.Equals(other.extensionNumber_)) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (BaseTypeName.Length != 0) hash ^= BaseTypeName.GetHashCode();
+ hash ^= extensionNumber_.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (BaseTypeName.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(BaseTypeName);
+ }
+ extensionNumber_.WriteTo(output, _repeated_extensionNumber_codec);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (BaseTypeName.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(BaseTypeName);
+ }
+ size += extensionNumber_.CalculateSize(_repeated_extensionNumber_codec);
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ExtensionNumberResponse other) {
+ if (other == null) {
+ return;
+ }
+ if (other.BaseTypeName.Length != 0) {
+ BaseTypeName = other.BaseTypeName;
+ }
+ extensionNumber_.Add(other.extensionNumber_);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ BaseTypeName = input.ReadString();
+ break;
+ }
+ case 18:
+ case 16: {
+ extensionNumber_.AddEntriesFrom(input, _repeated_extensionNumber_codec);
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// A list of ServiceResponse sent by the server answering list_services request.
+ /// </summary>
+ public sealed partial class ListServiceResponse : pb::IMessage<ListServiceResponse> {
+ private static readonly pb::MessageParser<ListServiceResponse> _parser = new pb::MessageParser<ListServiceResponse>(() => new ListServiceResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ListServiceResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Reflection.V1Alpha.ReflectionReflection.Descriptor.MessageTypes[5]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ListServiceResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ListServiceResponse(ListServiceResponse other) : this() {
+ service_ = other.service_.Clone();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ListServiceResponse Clone() {
+ return new ListServiceResponse(this);
+ }
+
+ /// <summary>Field number for the "service" field.</summary>
+ public const int ServiceFieldNumber = 1;
+ private static readonly pb::FieldCodec<global::Grpc.Reflection.V1Alpha.ServiceResponse> _repeated_service_codec
+ = pb::FieldCodec.ForMessage(10, global::Grpc.Reflection.V1Alpha.ServiceResponse.Parser);
+ private readonly pbc::RepeatedField<global::Grpc.Reflection.V1Alpha.ServiceResponse> service_ = new pbc::RepeatedField<global::Grpc.Reflection.V1Alpha.ServiceResponse>();
+ /// <summary>
+ /// The information of each service may be expanded in the future, so we use
+ /// ServiceResponse message to encapsulate it.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<global::Grpc.Reflection.V1Alpha.ServiceResponse> Service {
+ get { return service_; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ListServiceResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ListServiceResponse other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if(!service_.Equals(other.service_)) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ hash ^= service_.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ service_.WriteTo(output, _repeated_service_codec);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ size += service_.CalculateSize(_repeated_service_codec);
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ListServiceResponse other) {
+ if (other == null) {
+ return;
+ }
+ service_.Add(other.service_);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ service_.AddEntriesFrom(input, _repeated_service_codec);
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// The information of a single service used by ListServiceResponse to answer
+ /// list_services request.
+ /// </summary>
+ public sealed partial class ServiceResponse : pb::IMessage<ServiceResponse> {
+ private static readonly pb::MessageParser<ServiceResponse> _parser = new pb::MessageParser<ServiceResponse>(() => new ServiceResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ServiceResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Reflection.V1Alpha.ReflectionReflection.Descriptor.MessageTypes[6]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ServiceResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ServiceResponse(ServiceResponse other) : this() {
+ name_ = other.name_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ServiceResponse Clone() {
+ return new ServiceResponse(this);
+ }
+
+ /// <summary>Field number for the "name" field.</summary>
+ public const int NameFieldNumber = 1;
+ private string name_ = "";
+ /// <summary>
+ /// Full name of a registered service, including its package name. The format
+ /// is &lt;package>.&lt;service>
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Name {
+ get { return name_; }
+ set {
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ServiceResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ServiceResponse other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Name != other.Name) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Name.Length != 0) hash ^= Name.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Name.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Name);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Name.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ServiceResponse other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Name.Length != 0) {
+ Name = other.Name;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Name = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// The error code and error message sent by the server when an error occurs.
+ /// </summary>
+ public sealed partial class ErrorResponse : pb::IMessage<ErrorResponse> {
+ private static readonly pb::MessageParser<ErrorResponse> _parser = new pb::MessageParser<ErrorResponse>(() => new ErrorResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ErrorResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Reflection.V1Alpha.ReflectionReflection.Descriptor.MessageTypes[7]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ErrorResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ErrorResponse(ErrorResponse other) : this() {
+ errorCode_ = other.errorCode_;
+ errorMessage_ = other.errorMessage_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ErrorResponse Clone() {
+ return new ErrorResponse(this);
+ }
+
+ /// <summary>Field number for the "error_code" field.</summary>
+ public const int ErrorCodeFieldNumber = 1;
+ private int errorCode_;
+ /// <summary>
+ /// This field uses the error codes defined in grpc::StatusCode.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int ErrorCode {
+ get { return errorCode_; }
+ set {
+ errorCode_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "error_message" field.</summary>
+ public const int ErrorMessageFieldNumber = 2;
+ private string errorMessage_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string ErrorMessage {
+ get { return errorMessage_; }
+ set {
+ errorMessage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ErrorResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ErrorResponse other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (ErrorCode != other.ErrorCode) return false;
+ if (ErrorMessage != other.ErrorMessage) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (ErrorCode != 0) hash ^= ErrorCode.GetHashCode();
+ if (ErrorMessage.Length != 0) hash ^= ErrorMessage.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (ErrorCode != 0) {
+ output.WriteRawTag(8);
+ output.WriteInt32(ErrorCode);
+ }
+ if (ErrorMessage.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteString(ErrorMessage);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (ErrorCode != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(ErrorCode);
+ }
+ if (ErrorMessage.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(ErrorMessage);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ErrorResponse other) {
+ if (other == null) {
+ return;
+ }
+ if (other.ErrorCode != 0) {
+ ErrorCode = other.ErrorCode;
+ }
+ if (other.ErrorMessage.Length != 0) {
+ ErrorMessage = other.ErrorMessage;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 8: {
+ ErrorCode = input.ReadInt32();
+ break;
+ }
+ case 18: {
+ ErrorMessage = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
new file mode 100644
index 0000000000..1b6f96ce7c
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
@@ -0,0 +1,132 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: grpc/reflection/v1alpha/reflection.proto
+// Original file comments:
+// Copyright 2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Service exported by server reflection
+//
+#region Designer generated code
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+
+namespace Grpc.Reflection.V1Alpha {
+ public static partial class ServerReflection
+ {
+ static readonly string __ServiceName = "grpc.reflection.v1alpha.ServerReflection";
+
+ static readonly Marshaller<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest> __Marshaller_ServerReflectionRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Reflection.V1Alpha.ServerReflectionRequest.Parser.ParseFrom);
+ static readonly Marshaller<global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> __Marshaller_ServerReflectionResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Reflection.V1Alpha.ServerReflectionResponse.Parser.ParseFrom);
+
+ static readonly Method<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> __Method_ServerReflectionInfo = new Method<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse>(
+ MethodType.DuplexStreaming,
+ __ServiceName,
+ "ServerReflectionInfo",
+ __Marshaller_ServerReflectionRequest,
+ __Marshaller_ServerReflectionResponse);
+
+ /// <summary>Service descriptor</summary>
+ public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+ {
+ get { return global::Grpc.Reflection.V1Alpha.ReflectionReflection.Descriptor.Services[0]; }
+ }
+
+ /// <summary>Base class for server-side implementations of ServerReflection</summary>
+ public abstract partial class ServerReflectionBase
+ {
+ /// <summary>
+ /// The reflection service is structured as a bidirectional stream, ensuring
+ /// all related requests go to a single server.
+ /// </summary>
+ public virtual global::System.Threading.Tasks.Task ServerReflectionInfo(IAsyncStreamReader<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest> requestStream, IServerStreamWriter<global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> responseStream, ServerCallContext context)
+ {
+ throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+ }
+
+ }
+
+ /// <summary>Client for ServerReflection</summary>
+ public partial class ServerReflectionClient : ClientBase<ServerReflectionClient>
+ {
+ /// <summary>Creates a new client for ServerReflection</summary>
+ /// <param name="channel">The channel to use to make remote calls.</param>
+ public ServerReflectionClient(Channel channel) : base(channel)
+ {
+ }
+ /// <summary>Creates a new client for ServerReflection that uses a custom <c>CallInvoker</c>.</summary>
+ /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+ public ServerReflectionClient(CallInvoker callInvoker) : base(callInvoker)
+ {
+ }
+ /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected ServerReflectionClient() : base()
+ {
+ }
+ /// <summary>Protected constructor to allow creation of configured clients.</summary>
+ /// <param name="configuration">The client configuration.</param>
+ protected ServerReflectionClient(ClientBaseConfiguration configuration) : base(configuration)
+ {
+ }
+
+ /// <summary>
+ /// The reflection service is structured as a bidirectional stream, ensuring
+ /// all related requests go to a single server.
+ /// </summary>
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return ServerReflectionInfo(new CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// The reflection service is structured as a bidirectional stream, ensuring
+ /// all related requests go to a single server.
+ /// </summary>
+ public virtual AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(CallOptions options)
+ {
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_ServerReflectionInfo, null, options);
+ }
+ /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
+ protected override ServerReflectionClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new ServerReflectionClient(configuration);
+ }
+ }
+
+ /// <summary>Creates service definition that can be registered with a server</summary>
+ public static ServerServiceDefinition BindService(ServerReflectionBase serviceImpl)
+ {
+ return ServerServiceDefinition.CreateBuilder()
+ .AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo).Build();
+ }
+
+ }
+}
+#endregion
diff --git a/src/csharp/Grpc.Reflection/ReflectionServiceImpl.cs b/src/csharp/Grpc.Reflection/ReflectionServiceImpl.cs
new file mode 100644
index 0000000000..105c4c963b
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/ReflectionServiceImpl.cs
@@ -0,0 +1,173 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Grpc.Core;
+using Grpc.Core.Utils;
+using Grpc.Reflection.V1Alpha;
+using Google.Protobuf.Reflection;
+
+namespace Grpc.Reflection
+{
+ /// <summary>
+ /// Implementation of server reflection service.
+ /// </summary>
+ public class ReflectionServiceImpl : Grpc.Reflection.V1Alpha.ServerReflection.ServerReflectionBase
+ {
+ readonly List<string> services;
+ readonly SymbolRegistry symbolRegistry;
+
+ /// <summary>
+ /// Creates a new instance of <c>ReflectionServiceIml</c>.
+ /// </summary>
+ public ReflectionServiceImpl(IEnumerable<string> services, SymbolRegistry symbolRegistry)
+ {
+ this.services = new List<string>(services);
+ this.symbolRegistry = symbolRegistry;
+ }
+
+ /// <summary>
+ /// Creates a new instance of <c>ReflectionServiceIml</c>.
+ /// </summary>
+ public ReflectionServiceImpl(IEnumerable<ServiceDescriptor> serviceDescriptors)
+ {
+ this.services = new List<string>(serviceDescriptors.Select((serviceDescriptor) => serviceDescriptor.FullName));
+ this.symbolRegistry = SymbolRegistry.FromFiles(serviceDescriptors.Select((serviceDescriptor) => serviceDescriptor.File));
+ }
+
+ /// <summary>
+ /// Creates a new instance of <c>ReflectionServiceIml</c>.
+ /// </summary>
+ public ReflectionServiceImpl(params ServiceDescriptor[] serviceDescriptors) : this((IEnumerable<ServiceDescriptor>) serviceDescriptors)
+ {
+ }
+
+ public override async Task ServerReflectionInfo(IAsyncStreamReader<ServerReflectionRequest> requestStream, IServerStreamWriter<ServerReflectionResponse> responseStream, ServerCallContext context)
+ {
+ while (await requestStream.MoveNext())
+ {
+ var response = ProcessRequest(requestStream.Current);
+ await responseStream.WriteAsync(response);
+ }
+ }
+
+ ServerReflectionResponse ProcessRequest(ServerReflectionRequest request)
+ {
+ switch (request.MessageRequestCase)
+ {
+ case ServerReflectionRequest.MessageRequestOneofCase.FileByFilename:
+ return FileByFilename(request.FileByFilename);
+ case ServerReflectionRequest.MessageRequestOneofCase.FileContainingSymbol:
+ return FileContainingSymbol(request.FileContainingSymbol);
+ case ServerReflectionRequest.MessageRequestOneofCase.ListServices:
+ return ListServices();
+ case ServerReflectionRequest.MessageRequestOneofCase.AllExtensionNumbersOfType:
+ case ServerReflectionRequest.MessageRequestOneofCase.FileContainingExtension:
+ default:
+ return CreateErrorResponse(StatusCode.Unimplemented, "Request type not supported by C# reflection service.");
+ }
+ }
+
+ ServerReflectionResponse FileByFilename(string filename)
+ {
+ FileDescriptor file = symbolRegistry.FileByName(filename);
+ if (file == null)
+ {
+ return CreateErrorResponse(StatusCode.NotFound, "File not found.");
+ }
+
+ var transitiveDependencies = new HashSet<FileDescriptor>();
+ CollectTransitiveDependencies(file, transitiveDependencies);
+
+ return new ServerReflectionResponse
+ {
+ FileDescriptorResponse = new FileDescriptorResponse { FileDescriptorProto = { transitiveDependencies.Select((d) => d.SerializedData) } }
+ };
+ }
+
+ ServerReflectionResponse FileContainingSymbol(string symbol)
+ {
+ FileDescriptor file = symbolRegistry.FileContainingSymbol(symbol);
+ if (file == null)
+ {
+ return CreateErrorResponse(StatusCode.NotFound, "Symbol not found.");
+ }
+
+ var transitiveDependencies = new HashSet<FileDescriptor>();
+ CollectTransitiveDependencies(file, transitiveDependencies);
+
+ return new ServerReflectionResponse
+ {
+ FileDescriptorResponse = new FileDescriptorResponse { FileDescriptorProto = { transitiveDependencies.Select((d) => d.SerializedData) } }
+ };
+ }
+
+ ServerReflectionResponse ListServices()
+ {
+ var serviceResponses = new ListServiceResponse();
+ foreach (string serviceName in services)
+ {
+ serviceResponses.Service.Add(new ServiceResponse { Name = serviceName });
+ }
+
+ return new ServerReflectionResponse
+ {
+ ListServicesResponse = serviceResponses
+ };
+ }
+
+ ServerReflectionResponse CreateErrorResponse(StatusCode status, string message)
+ {
+ return new ServerReflectionResponse
+ {
+ ErrorResponse = new ErrorResponse { ErrorCode = (int) status, ErrorMessage = message }
+ };
+ }
+
+ void CollectTransitiveDependencies(FileDescriptor descriptor, HashSet<FileDescriptor> pool)
+ {
+ pool.Add(descriptor);
+ foreach (var dependency in descriptor.Dependencies)
+ {
+ if (pool.Add(dependency))
+ {
+ // descriptors cannot have circular dependencies
+ CollectTransitiveDependencies(dependency, pool);
+ }
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Reflection/Settings.StyleCop b/src/csharp/Grpc.Reflection/Settings.StyleCop
new file mode 100644
index 0000000000..2942add962
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/Settings.StyleCop
@@ -0,0 +1,10 @@
+<StyleCopSettings Version="105">
+ <SourceFileList>
+ <SourceFile>Health.cs</SourceFile>
+ <Settings>
+ <GlobalSettings>
+ <BooleanProperty Name="RulesEnabledByDefault">False</BooleanProperty>
+ </GlobalSettings>
+ </Settings>
+ </SourceFileList>
+</StyleCopSettings>
diff --git a/src/csharp/Grpc.Reflection/SymbolRegistry.cs b/src/csharp/Grpc.Reflection/SymbolRegistry.cs
new file mode 100644
index 0000000000..b7104ab2f9
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/SymbolRegistry.cs
@@ -0,0 +1,160 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using System.Collections.Generic;
+using Grpc.Core.Utils;
+using Google.Protobuf.Reflection;
+
+namespace Grpc.Reflection
+{
+ /// <summary>Registry of protobuf symbols</summary>
+ public class SymbolRegistry
+ {
+ private readonly Dictionary<string, FileDescriptor> filesByName;
+ private readonly Dictionary<string, FileDescriptor> filesBySymbol;
+
+ private SymbolRegistry(Dictionary<string, FileDescriptor> filesByName, Dictionary<string, FileDescriptor> filesBySymbol)
+ {
+ this.filesByName = new Dictionary<string, FileDescriptor>(filesByName);
+ this.filesBySymbol = new Dictionary<string, FileDescriptor>(filesBySymbol);
+ }
+
+ /// <summary>
+ /// Creates a symbol registry from the specified set of file descriptors.
+ /// </summary>
+ /// <param name="fileDescriptors">The set of files to include in the registry. Must not contain null values.</param>
+ /// <returns>A symbol registry for the given files.</returns>
+ public static SymbolRegistry FromFiles(IEnumerable<FileDescriptor> fileDescriptors)
+ {
+ GrpcPreconditions.CheckNotNull(fileDescriptors);
+ var builder = new Builder();
+ foreach (var file in fileDescriptors)
+ {
+ builder.AddFile(file);
+ }
+ return builder.Build();
+ }
+
+ /// <summary>
+ /// Gets file descriptor for given file name (including package path). Returns <c>null</c> if not found.
+ /// </summary>
+ public FileDescriptor FileByName(string filename)
+ {
+ FileDescriptor file;
+ filesByName.TryGetValue(filename, out file);
+ return file;
+ }
+
+ /// <summary>
+ /// Gets file descriptor that contains definition of given symbol full name (including package path). Returns <c>null</c> if not found.
+ /// </summary>
+ public FileDescriptor FileContainingSymbol(string symbol)
+ {
+ FileDescriptor file;
+ filesBySymbol.TryGetValue(symbol, out file);
+ return file;
+ }
+
+ /// <summary>
+ /// Builder class which isn't exposed, but acts as a convenient alternative to passing round two dictionaries in recursive calls.
+ /// </summary>
+ private class Builder
+ {
+ private readonly Dictionary<string, FileDescriptor> filesByName;
+ private readonly Dictionary<string, FileDescriptor> filesBySymbol;
+
+
+ internal Builder()
+ {
+ filesByName = new Dictionary<string, FileDescriptor>();
+ filesBySymbol = new Dictionary<string, FileDescriptor>();
+ }
+
+ internal void AddFile(FileDescriptor fileDescriptor)
+ {
+ if (filesByName.ContainsKey(fileDescriptor.Name))
+ {
+ return;
+ }
+ filesByName.Add(fileDescriptor.Name, fileDescriptor);
+
+ foreach (var dependency in fileDescriptor.Dependencies)
+ {
+ AddFile(dependency);
+ }
+ foreach (var enumeration in fileDescriptor.EnumTypes)
+ {
+ AddEnum(enumeration);
+ }
+ foreach (var message in fileDescriptor.MessageTypes)
+ {
+ AddMessage(message);
+ }
+ foreach (var service in fileDescriptor.Services)
+ {
+ AddService(service);
+ }
+ }
+
+ private void AddEnum(EnumDescriptor enumDescriptor)
+ {
+ filesBySymbol[enumDescriptor.FullName] = enumDescriptor.File;
+ }
+
+ private void AddMessage(MessageDescriptor messageDescriptor)
+ {
+ foreach (var nestedEnum in messageDescriptor.EnumTypes)
+ {
+ AddEnum(nestedEnum);
+ }
+ foreach (var nestedType in messageDescriptor.NestedTypes)
+ {
+ AddMessage(nestedType);
+ }
+ filesBySymbol[messageDescriptor.FullName] = messageDescriptor.File;
+ }
+
+ private void AddService(ServiceDescriptor serviceDescriptor)
+ {
+ foreach (var method in serviceDescriptor.Methods)
+ {
+ filesBySymbol[method.FullName] = method.File;
+ }
+ filesBySymbol[serviceDescriptor.FullName] = serviceDescriptor.File;
+ }
+
+ internal SymbolRegistry Build()
+ {
+ return new SymbolRegistry(filesByName, filesBySymbol);
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Reflection/packages.config b/src/csharp/Grpc.Reflection/packages.config
new file mode 100644
index 0000000000..5ab40b7a8c
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/packages.config
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
+ <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/src/csharp/Grpc.Reflection/project.json b/src/csharp/Grpc.Reflection/project.json
new file mode 100644
index 0000000000..2fe617cc7a
--- /dev/null
+++ b/src/csharp/Grpc.Reflection/project.json
@@ -0,0 +1,40 @@
+{
+ "version": "1.1.0-dev",
+ "title": "gRPC C# Reflection",
+ "authors": [ "Google Inc." ],
+ "copyright": "Copyright 2016, Google Inc.",
+ "packOptions": {
+ "summary": "Implementation of gRPC reflection service",
+ "description": "Provides information about services running on a gRPC C# server.",
+ "owners": [ "grpc-packages" ],
+ "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
+ "projectUrl": "https://github.com/grpc/grpc",
+ "requireLicenseAcceptance": false,
+ "tags": [ "gRPC reflection" ]
+ },
+ "buildOptions": {
+ "define": [ "SIGNED" ],
+ "keyFile": "../keys/Grpc.snk",
+ "xmlDoc": true,
+ "compile": {
+ "includeFiles": [ "../Grpc.Core/Version.cs" ]
+ }
+ },
+ "dependencies": {
+ "Grpc.Core": "1.1.0-dev",
+ "Google.Protobuf": "3.0.0"
+ },
+ "frameworks": {
+ "net45": {
+ "frameworkAssemblies": {
+ "System.Runtime": "",
+ "System.IO": ""
+ }
+ },
+ "netstandard1.5": {
+ "dependencies": {
+ "NETStandard.Library": "1.6.0"
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln
index 9be36c0caa..2e6a8fd435 100644
--- a/src/csharp/Grpc.sln
+++ b/src/csharp/Grpc.sln
@@ -36,6 +36,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Qps
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.StressClient", "Grpc.IntegrationTesting.StressClient\Grpc.IntegrationTesting.StressClient.csproj", "{ADEBA147-80AE-4710-82E9-5B7F93690266}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Reflection", "Grpc.Reflection\Grpc.Reflection.csproj", "{4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Reflection.Tests", "Grpc.Reflection.Tests\Grpc.Reflection.Tests.csproj", "{B88F91D6-436D-4C78-8B99-47800FA8DE03}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -55,6 +59,12 @@ Global
{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Release|Any CPU.Build.0 = Release|Any CPU
{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU
+ {4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {4F18CF52-B3DB-4A77-97C5-7F7F4B6C1715}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU
{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -103,6 +113,12 @@ Global
{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.Release|Any CPU.Build.0 = Release|Any CPU
{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.ReleaseSigned|Any CPU.ActiveCfg = Release|Any CPU
{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.ReleaseSigned|Any CPU.Build.0 = Release|Any CPU
+ {B88F91D6-436D-4C78-8B99-47800FA8DE03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B88F91D6-436D-4C78-8B99-47800FA8DE03}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B88F91D6-436D-4C78-8B99-47800FA8DE03}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B88F91D6-436D-4C78-8B99-47800FA8DE03}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B88F91D6-436D-4C78-8B99-47800FA8DE03}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {B88F91D6-436D-4C78-8B99-47800FA8DE03}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU
{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|Any CPU.ActiveCfg = Release|Any CPU
diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat
deleted file mode 100644
index c0036df13f..0000000000
--- a/src/csharp/build_packages.bat
+++ /dev/null
@@ -1,91 +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 Builds gRPC NuGet packages
-
-@rem This way of building nuget packages is now obsolete. C# nuget packages
-@rem with CoreCLR support are now being built using the dotnet cli
-@rem in build_packages_dotnetcli.sh
-
-@rem Current package versions
-set VERSION=1.1.0-dev
-set PROTOBUF_VERSION=3.0.0
-
-@rem Adjust the location of nuget.exe
-set NUGET=C:\nuget\nuget.exe
-
-@rem Collect the artifacts built by the previous build step if running on Jenkins
-@rem TODO(jtattermusch): is there a better way to do this?
-xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=windows\artifacts\* nativelibs\windows_x86\
-xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=windows\artifacts\* nativelibs\windows_x64\
-xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=linux\artifacts\* nativelibs\linux_x86\
-xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=linux\artifacts\* nativelibs\linux_x64\
-xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=macos\artifacts\* nativelibs\macosx_x86\
-xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=macos\artifacts\* nativelibs\macosx_x64\
-
-@rem Collect protoc artifacts built by the previous build step
-xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x86\
-xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x64\
-xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x86\
-xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x64\
-xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x86\
-xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x64\
-
-@rem Fetch all dependencies
-%NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error
-
-setlocal
-
-@call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
-
-@rem We won't use the native libraries from this step, but without this Grpc.sln will fail.
-msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:Configuration=Release /p:PlatformToolset=v120 || goto :error
-
-msbuild Grpc.sln /p:Configuration=ReleaseSigned || goto :error
-
-endlocal
-
-%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
-%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
-%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
-%NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
-%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
-
-@rem copy resulting nuget packages to artifacts directory
-xcopy /Y /I *.nupkg ..\..\artifacts\
-
-@rem create a zipfile with the artifacts as well
-powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('..\..\artifacts', 'csharp_nugets_obsolete.zip');"
-xcopy /Y /I csharp_nugets_obsolete.zip ..\..\artifacts\
-
-goto :EOF
-
-:error
-echo Failed!
-exit /b %errorlevel%
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index b0e358fdff..9e8c045a1f 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -28,7 +28,7 @@
@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@rem Current package versions
-set VERSION=1.0.1
+set VERSION=1.1.0-dev
set PROTOBUF_VERSION=3.0.0
@rem Adjust the location of nuget.exe
@@ -61,9 +61,10 @@ xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* pr
%DOTNET% pack --configuration Release Grpc.Core\project.json --output ..\..\artifacts || goto :error
%DOTNET% pack --configuration Release Grpc.Auth\project.json --output ..\..\artifacts || goto :error
%DOTNET% pack --configuration Release Grpc.HealthCheck\project.json --output ..\..\artifacts || goto :error
+%DOTNET% pack --configuration Release Grpc.Reflection\project.json --output ..\..\artifacts || goto :error
-%NUGET% pack Grpc.nuspec -Version "1.0.1" -OutputDirectory ..\..\artifacts || goto :error
-%NUGET% pack Grpc.Tools.nuspec -Version "1.0.1" -OutputDirectory ..\..\artifacts
+%NUGET% pack Grpc.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts || goto :error
+%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts
@rem copy resulting nuget packages to artifacts directory
xcopy /Y /I *.nupkg ..\..\artifacts\ || goto :error
diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh
index 3c127f320b..52cf2f9ddc 100755
--- a/src/csharp/build_packages_dotnetcli.sh
+++ b/src/csharp/build_packages_dotnetcli.sh
@@ -63,6 +63,7 @@ dotnet restore .
dotnet pack --configuration Release Grpc.Core/project.json --output ../../artifacts
dotnet pack --configuration Release Grpc.Auth/project.json --output ../../artifacts
dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts
+dotnet pack --configuration Release Grpc.Reflection/project.json --output ../../artifacts
nuget pack Grpc.nuspec -Version "1.1.0-dev" -OutputDirectory ../../artifacts
nuget pack Grpc.Tools.nuspec -Version "1.1.0-dev" -OutputDirectory ../../artifacts
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 37d04eb100..946f5872c0 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -521,8 +521,8 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_destroy(grpc_call *call) {
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_start_unary(grpc_call *call, grpcsharp_batch_context *ctx,
- const char *send_buffer, size_t send_buffer_len,
- grpc_metadata_array *initial_metadata, uint32_t write_flags) {
+ const char *send_buffer, size_t send_buffer_len, uint32_t write_flags,
+ grpc_metadata_array *initial_metadata, uint32_t initial_metadata_flags) {
/* TODO: don't use magic number */
grpc_op ops[6];
memset(ops, 0, sizeof(ops));
@@ -532,7 +532,7 @@ grpcsharp_call_start_unary(grpc_call *call, grpcsharp_batch_context *ctx,
ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
ops[0].data.send_initial_metadata.metadata =
ctx->send_initial_metadata.metadata;
- ops[0].flags = 0;
+ ops[0].flags = initial_metadata_flags;
ops[0].reserved = NULL;
ops[1].op = GRPC_OP_SEND_MESSAGE;
@@ -575,7 +575,8 @@ grpcsharp_call_start_unary(grpc_call *call, grpcsharp_batch_context *ctx,
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_start_client_streaming(grpc_call *call,
grpcsharp_batch_context *ctx,
- grpc_metadata_array *initial_metadata) {
+ grpc_metadata_array *initial_metadata,
+ uint32_t initial_metadata_flags) {
/* TODO: don't use magic number */
grpc_op ops[4];
memset(ops, 0, sizeof(ops));
@@ -585,7 +586,7 @@ grpcsharp_call_start_client_streaming(grpc_call *call,
ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
ops[0].data.send_initial_metadata.metadata =
ctx->send_initial_metadata.metadata;
- ops[0].flags = 0;
+ ops[0].flags = initial_metadata_flags;
ops[0].reserved = NULL;
ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
@@ -617,7 +618,8 @@ grpcsharp_call_start_client_streaming(grpc_call *call,
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_server_streaming(
grpc_call *call, grpcsharp_batch_context *ctx, const char *send_buffer,
- size_t send_buffer_len, grpc_metadata_array *initial_metadata, uint32_t write_flags) {
+ size_t send_buffer_len, uint32_t write_flags,
+ grpc_metadata_array *initial_metadata, uint32_t initial_metadata_flags) {
/* TODO: don't use magic number */
grpc_op ops[4];
memset(ops, 0, sizeof(ops));
@@ -627,7 +629,7 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_server_streaming(
ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
ops[0].data.send_initial_metadata.metadata =
ctx->send_initial_metadata.metadata;
- ops[0].flags = 0;
+ ops[0].flags = initial_metadata_flags;
ops[0].reserved = NULL;
ops[1].op = GRPC_OP_SEND_MESSAGE;
@@ -660,7 +662,8 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_server_streaming(
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_start_duplex_streaming(grpc_call *call,
grpcsharp_batch_context *ctx,
- grpc_metadata_array *initial_metadata) {
+ grpc_metadata_array *initial_metadata,
+ uint32_t initial_metadata_flags) {
/* TODO: don't use magic number */
grpc_op ops[2];
memset(ops, 0, sizeof(ops));
@@ -670,7 +673,7 @@ grpcsharp_call_start_duplex_streaming(grpc_call *call,
ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
ops[0].data.send_initial_metadata.metadata =
ctx->send_initial_metadata.metadata;
- ops[0].flags = 0;
+ ops[0].flags = initial_metadata_flags;
ops[0].reserved = NULL;
ops[1].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
diff --git a/src/csharp/generate_proto_csharp.sh b/src/csharp/generate_proto_csharp.sh
index 79488e02a5..ea5d678cba 100755
--- a/src/csharp/generate_proto_csharp.sh
+++ b/src/csharp/generate_proto_csharp.sh
@@ -36,13 +36,20 @@ PROTOC=bins/opt/protobuf/protoc
PLUGIN=protoc-gen-grpc=bins/opt/grpc_csharp_plugin
EXAMPLES_DIR=src/csharp/Grpc.Examples
HEALTHCHECK_DIR=src/csharp/Grpc.HealthCheck
+REFLECTION_DIR=src/csharp/Grpc.Reflection
TESTING_DIR=src/csharp/Grpc.IntegrationTesting
$PROTOC --plugin=$PLUGIN --csharp_out=$EXAMPLES_DIR --grpc_out=$EXAMPLES_DIR \
- -I src/proto/math src/proto/math/math.proto
+ -I src/proto src/proto/math/math.proto
$PROTOC --plugin=$PLUGIN --csharp_out=$HEALTHCHECK_DIR --grpc_out=$HEALTHCHECK_DIR \
- -I src/proto/grpc/health/v1 src/proto/grpc/health/v1/health.proto
+ -I src/proto src/proto/grpc/health/v1/health.proto
+
+$PROTOC --plugin=$PLUGIN --csharp_out=$REFLECTION_DIR --grpc_out=$REFLECTION_DIR \
+ -I src/proto src/proto/grpc/reflection/v1alpha/reflection.proto
+# TODO(jtattermusch): following .proto files are a bit broken and import paths
+# don't match the package names. Setting -I to the correct value src/proto
+# breaks the code generation.
$PROTOC --plugin=$PLUGIN --csharp_out=$TESTING_DIR --grpc_out=$TESTING_DIR \
-I . src/proto/grpc/testing/{control,empty,messages,metrics,payloads,services,stats,test}.proto
diff --git a/src/csharp/tests.json b/src/csharp/tests.json
index 7e7aee1093..4ce6769eee 100644
--- a/src/csharp/tests.json
+++ b/src/csharp/tests.json
@@ -48,5 +48,9 @@
"Grpc.IntegrationTesting.MetadataCredentialsTest",
"Grpc.IntegrationTesting.RunnerClientServerTest",
"Grpc.IntegrationTesting.SslCredentialsTest"
+ ],
+ "Grpc.Reflection.Tests": [
+ "Grpc.Reflection.Tests.ReflectionClientServerTest",
+ "Grpc.Reflection.Tests.SymbolRegistryTest"
]
} \ No newline at end of file
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
index 17478fab12..5785b976f2 100644
--- a/src/objective-c/tests/Podfile
+++ b/src/objective-c/tests/Podfile
@@ -84,9 +84,9 @@ post_install do |installer|
end
# CocoaPods creates duplicated library targets of gRPC-Core when the test targets include
- # non-default subspecs of gRPC-Core. All of these library targets start with prefix 'gRPC-Core.'
+ # non-default subspecs of gRPC-Core. All of these library targets start with prefix 'gRPC-Core'
# and require the same error suppresion.
- if target.name == 'gRPC-Core' or target.name.start_with?('gRPC-Core.')
+ if target.name.start_with?('gRPC-Core')
target.build_configurations.each do |config|
# TODO(zyc): Remove this setting after the issue is resolved
# GPR_UNREACHABLE_CODE causes "Control may reach end of non-void
diff --git a/src/php/tests/unit_tests/ChannelTest.php b/src/php/tests/unit_tests/ChannelTest.php
index 4b35b1a28c..fa33d38911 100644
--- a/src/php/tests/unit_tests/ChannelTest.php
+++ b/src/php/tests/unit_tests/ChannelTest.php
@@ -99,7 +99,7 @@ class ChannelTest extends PHPUnit_Framework_TestCase
$this->channel = new Grpc\Channel('localhost:0',
['credentials' => Grpc\ChannelCredentials::createInsecure()]);
$time = new Grpc\Timeval(1000);
- $state = $this->channel->watchConnectivityState(123, $time);
+ $state = $this->channel->watchConnectivityState(1, $time);
$this->assertTrue($state);
unset($time);
}
diff --git a/src/php/tests/unit_tests/ServerTest.php b/src/php/tests/unit_tests/ServerTest.php
index f2346ab113..5f40202f18 100644
--- a/src/php/tests/unit_tests/ServerTest.php
+++ b/src/php/tests/unit_tests/ServerTest.php
@@ -67,9 +67,9 @@ class ServerTest extends PHPUnit_Framework_TestCase
public function testRequestCall()
{
$this->server = new Grpc\Server();
- $port = $this->server->addHttp2Port('0.0.0.0:8888');
+ $port = $this->server->addHttp2Port('0.0.0.0:0');
$this->server->start();
- $channel = new Grpc\Channel('localhost:8888',
+ $channel = new Grpc\Channel('localhost:' . $port,
['credentials' => Grpc\ChannelCredentials::createInsecure()]);
$deadline = Grpc\Timeval::infFuture();
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index 4e4062bafc..6087276d51 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -905,6 +905,21 @@ class Server(six.with_metaclass(abc.ABCMeta)):
raise NotImplementedError()
@abc.abstractmethod
+ def add_shutdown_handler(self, shutdown_handler):
+ """Adds a handler to be called on server shutdown.
+
+ Shutdown handlers are run on server stop() or in the event that a running
+ server is destroyed unexpectedly. The handlers are run in series before
+ the stop grace period.
+
+ Args:
+ shutdown_handler: A function taking a single arg, a time in seconds
+ within which the handler should complete. None indicates the handler can
+ run for any duration.
+ """
+ raise NotImplementedError()
+
+ @abc.abstractmethod
def start(self):
"""Starts this Server's service of RPCs.
@@ -914,7 +929,7 @@ class Server(six.with_metaclass(abc.ABCMeta)):
raise NotImplementedError()
@abc.abstractmethod
- def stop(self, grace):
+ def stop(self, grace, shutdown_handler_grace=None):
"""Stops this Server's service of RPCs.
All calls to this method immediately stop service of new RPCs. When existing
@@ -937,6 +952,8 @@ class Server(six.with_metaclass(abc.ABCMeta)):
aborted by this Server's stopping. If None, all RPCs will be aborted
immediately and this method will block until this Server is completely
stopped.
+ shutdown_handler_grace: A duration of time in seconds or None. This
+ value is passed to all shutdown handlers.
Returns:
A threading.Event that will be set when this Server has completely
@@ -1231,7 +1248,8 @@ def secure_channel(target, credentials, options=None):
credentials._credentials)
-def server(thread_pool, handlers=None, options=None):
+def server(thread_pool, handlers=None, options=None, exit_grace=None,
+ exit_shutdown_handler_grace=None):
"""Creates a Server with which RPCs can be serviced.
Args:
@@ -1244,13 +1262,19 @@ def server(thread_pool, handlers=None, options=None):
returned Server is started.
options: A sequence of string-value pairs according to which to configure
the created server.
+ exit_grace: The grace period to use when terminating
+ running servers at interpreter exit. None indicates unspecified.
+ exit_shutdown_handler_grace: The shutdown handler grace to use when
+ terminating running servers at interpreter exit. None indicates
+ unspecified.
Returns:
A Server with which RPCs can be serviced.
"""
from grpc import _server
return _server.Server(thread_pool, () if handlers is None else handlers,
- () if options is None else options)
+ () if options is None else options, exit_grace,
+ exit_shutdown_handler_grace)
################################### __all__ #################################
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index 5223712dfa..d83a2e6ded 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -60,7 +60,8 @@ _CANCELLED = 'cancelled'
_EMPTY_FLAGS = 0
_EMPTY_METADATA = cygrpc.Metadata(())
-_UNEXPECTED_EXIT_SERVER_GRACE = 1.0
+_DEFAULT_EXIT_GRACE = 1.0
+_DEFAULT_EXIT_SHUTDOWN_HANDLER_GRACE = 5.0
def _serialized_request(request_event):
@@ -595,14 +596,18 @@ class _ServerStage(enum.Enum):
class _ServerState(object):
- def __init__(self, completion_queue, server, generic_handlers, thread_pool):
+ def __init__(self, completion_queue, server, generic_handlers, thread_pool,
+ exit_grace, exit_shutdown_handler_grace):
self.lock = threading.Lock()
self.completion_queue = completion_queue
self.server = server
self.generic_handlers = list(generic_handlers)
self.thread_pool = thread_pool
+ self.exit_grace = exit_grace
+ self.exit_shutdown_handler_grace = exit_shutdown_handler_grace
self.stage = _ServerStage.STOPPED
self.shutdown_events = None
+ self.shutdown_handlers = []
# TODO(https://github.com/grpc/grpc/issues/6597): eliminate these fields.
self.rpc_states = set()
@@ -672,41 +677,45 @@ def _serve(state):
return
-def _stop(state, grace):
- with state.lock:
- if state.stage is _ServerStage.STOPPED:
- shutdown_event = threading.Event()
- shutdown_event.set()
- return shutdown_event
- else:
- if state.stage is _ServerStage.STARTED:
- state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG)
+def _stop(state, grace, shutdown_handler_grace):
+ shutdown_event = threading.Event()
+
+ def cancel_all_calls_after_grace():
+ with state.lock:
+ if state.stage is _ServerStage.STOPPED:
+ shutdown_event.set()
+ return
+ elif state.stage is _ServerStage.STARTED:
+ do_shutdown = True
state.stage = _ServerStage.GRACE
state.shutdown_events = []
- state.due.add(_SHUTDOWN_TAG)
- shutdown_event = threading.Event()
+ else:
+ do_shutdown = False
state.shutdown_events.append(shutdown_event)
- if grace is None:
+
+ if do_shutdown:
+ # Run Shutdown Handlers without the lock
+ for handler in state.shutdown_handlers:
+ handler(shutdown_handler_grace)
+ with state.lock:
+ state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG)
+ state.stage = _ServerStage.GRACE
+ state.due.add(_SHUTDOWN_TAG)
+
+ if not shutdown_event.wait(timeout=grace):
+ with state.lock:
state.server.cancel_all_calls()
# TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
for rpc_state in state.rpc_states:
with rpc_state.condition:
rpc_state.client = _CANCELLED
rpc_state.condition.notify_all()
- else:
- def cancel_all_calls_after_grace():
- shutdown_event.wait(timeout=grace)
- with state.lock:
- state.server.cancel_all_calls()
- # TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
- for rpc_state in state.rpc_states:
- with rpc_state.condition:
- rpc_state.client = _CANCELLED
- rpc_state.condition.notify_all()
- thread = threading.Thread(target=cancel_all_calls_after_grace)
- thread.start()
- return shutdown_event
- shutdown_event.wait()
+
+ if grace is None:
+ cancel_all_calls_after_grace()
+ else:
+ threading.Thread(target=cancel_all_calls_after_grace).start()
+
return shutdown_event
@@ -716,12 +725,12 @@ def _start(state):
raise ValueError('Cannot start already-started server!')
state.server.start()
state.stage = _ServerStage.STARTED
- _request_call(state)
+ _request_call(state)
def cleanup_server(timeout):
if timeout is None:
- _stop(state, _UNEXPECTED_EXIT_SERVER_GRACE).wait()
+ _stop(state, state.exit_grace, state.exit_shutdown_handler_grace).wait()
else:
- _stop(state, timeout).wait()
+ _stop(state, timeout, 0).wait()
thread = _common.CleanupThread(
cleanup_server, target=_serve, args=(state,))
@@ -729,12 +738,16 @@ def _start(state):
class Server(grpc.Server):
- def __init__(self, thread_pool, generic_handlers, options):
+ def __init__(self, thread_pool, generic_handlers, options, exit_grace,
+ exit_shutdown_handler_grace):
completion_queue = cygrpc.CompletionQueue()
server = cygrpc.Server(_common.channel_args(options))
server.register_completion_queue(completion_queue)
self._state = _ServerState(
- completion_queue, server, generic_handlers, thread_pool)
+ completion_queue, server, generic_handlers, thread_pool,
+ _DEFAULT_EXIT_GRACE if exit_grace is None else exit_grace,
+ _DEFAULT_EXIT_SHUTDOWN_HANDLER_GRACE if exit_shutdown_handler_grace
+ is None else exit_shutdown_handler_grace)
def add_generic_rpc_handlers(self, generic_rpc_handlers):
_add_generic_handlers(self._state, generic_rpc_handlers)
@@ -745,11 +758,14 @@ class Server(grpc.Server):
def add_secure_port(self, address, server_credentials):
return _add_secure_port(self._state, _common.encode(address), server_credentials)
+ def add_shutdown_handler(self, handler):
+ self._state.shutdown_handlers.append(handler)
+
def start(self):
_start(self._state)
- def stop(self, grace):
- return _stop(self._state, grace)
+ def stop(self, grace, shutdown_handler_grace=None):
+ return _stop(self._state, grace, shutdown_handler_grace)
def __del__(self):
- _stop(self._state, None)
+ _stop(self._state, None, None)
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index bfd706a78b..d43f93b94f 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -226,9 +226,9 @@ CORE_SOURCE_FILES = [
'src/core/lib/security/credentials/plugin/plugin_credentials.c',
'src/core/lib/security/credentials/ssl/ssl_credentials.c',
'src/core/lib/security/transport/client_auth_filter.c',
- 'src/core/lib/security/transport/handshake.c',
'src/core/lib/security/transport/secure_endpoint.c',
'src/core/lib/security/transport/security_connector.c',
+ 'src/core/lib/security/transport/security_handshaker.c',
'src/core/lib/security/transport/server_auth_filter.c',
'src/core/lib/security/transport/tsi_error.c',
'src/core/lib/security/util/b64.c',
@@ -237,6 +237,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/tsi/fake_transport_security.c',
'src/core/lib/tsi/ssl_transport_security.c',
'src/core/lib/tsi/transport_security.c',
+ 'src/core/ext/transport/chttp2/server/chttp2_server.c',
'src/core/ext/transport/chttp2/client/secure/secure_channel_create.c',
'src/core/ext/client_channel/channel_connectivity.c',
'src/core/ext/client_channel/client_channel.c',
@@ -256,6 +257,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/client_channel/subchannel.c',
'src/core/ext/client_channel/subchannel_index.c',
'src/core/ext/client_channel/uri_parser.c',
+ 'src/core/ext/transport/chttp2/client/chttp2_connector.c',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
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 089366a8c7..64fd97256e 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
@@ -167,7 +167,7 @@ class SameSeparateTest(unittest.TestCase, SeparateTestMixin):
'',
'--proto_path={}'.format(self.proto_directory),
'--python_out={}'.format(self.python_out_directory),
- '--grpc_python_out={}'.format(self.grpc_python_out_directory),
+ '--grpc_python_out=grpc_2_0:{}'.format(self.grpc_python_out_directory),
same_proto_file,
])
if protoc_result != 0:
@@ -241,7 +241,7 @@ class SplitCommonTest(unittest.TestCase, CommonTestMixin):
'',
'--proto_path={}'.format(self.proto_directory),
'--python_out={}'.format(self.python_out_directory),
- '--grpc_python_out={}'.format(self.python_out_directory),
+ '--grpc_python_out={}'.format(self.grpc_python_out_directory),
services_proto_file,
messages_proto_file,
])
@@ -285,7 +285,7 @@ class SplitSeparateTest(unittest.TestCase, SeparateTestMixin):
'',
'--proto_path={}'.format(self.proto_directory),
'--python_out={}'.format(self.python_out_directory),
- '--grpc_python_out={}'.format(self.grpc_python_out_directory),
+ '--grpc_python_out=grpc_2_0:{}'.format(self.grpc_python_out_directory),
services_proto_file,
messages_proto_file,
])
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index dd4a0257f5..04a2e44178 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -27,6 +27,7 @@
"unit._cython.cygrpc_test.TypeSmokeTest",
"unit._empty_message_test.EmptyMessageTest",
"unit._exit_test.ExitTest",
+ "unit._exit_test.ShutdownHandlerTest",
"unit._metadata_code_details_test.MetadataCodeDetailsTest",
"unit._metadata_test.MetadataTest",
"unit._rpc_test.RPCTest",
diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py
index 5a4a32887c..342f5fcc10 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_test.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_test.py
@@ -43,6 +43,8 @@ import threading
import time
import unittest
+import grpc
+from grpc.framework.foundation import logging_pool
from tests.unit import _exit_scenarios
SCENARIO_FILE = os.path.abspath(os.path.join(
@@ -52,7 +54,7 @@ BASE_COMMAND = [INTERPRETER, SCENARIO_FILE]
BASE_SIGTERM_COMMAND = BASE_COMMAND + ['--wait_for_interrupt']
INIT_TIME = 1.0
-
+SHUTDOWN_GRACE = 5.0
processes = []
process_lock = threading.Lock()
@@ -182,5 +184,24 @@ class ExitTest(unittest.TestCase):
interrupt_and_wait(process)
+class _ShutDownHandler(object):
+
+ def __init__(self):
+ self.seen_handler_grace = None
+
+ def shutdown_handler(self, handler_grace):
+ self.seen_handler_grace = handler_grace
+
+
+class ShutdownHandlerTest(unittest.TestCase):
+
+ def test_shutdown_handler(self):
+ server = grpc.server(logging_pool.pool(1))
+ handler = _ShutDownHandler()
+ server.add_shutdown_handler(handler.shutdown_handler)
+ server.start()
+ server.stop(0, shutdown_handler_grace=SHUTDOWN_GRACE).wait()
+ self.assertEqual(SHUTDOWN_GRACE, handler.seen_handler_grace)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/templates/src/csharp/Grpc.Reflection.Tests/project.json.template b/templates/src/csharp/Grpc.Reflection.Tests/project.json.template
new file mode 100644
index 0000000000..2869609138
--- /dev/null
+++ b/templates/src/csharp/Grpc.Reflection.Tests/project.json.template
@@ -0,0 +1,26 @@
+%YAML 1.2
+--- |
+ {
+ <%include file="../build_options.include" args="executable=True"/>
+ "dependencies": {
+ "Grpc.Reflection": {
+ "target": "project"
+ },
+ "NUnit": "3.2.0",
+ "NUnitLite": "3.2.0-*"
+ },
+ "frameworks": {
+ "net45": { },
+ "netcoreapp1.0": {
+ "imports": [
+ "portable-net45"
+ ],
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0"
+ }
+ }
+ }
+ }
+ }
diff --git a/templates/src/csharp/Grpc.Reflection/project.json.template b/templates/src/csharp/Grpc.Reflection/project.json.template
new file mode 100644
index 0000000000..8a33e1ccc9
--- /dev/null
+++ b/templates/src/csharp/Grpc.Reflection/project.json.template
@@ -0,0 +1,42 @@
+%YAML 1.2
+--- |
+ {
+ "version": "${settings.csharp_version}",
+ "title": "gRPC C# Reflection",
+ "authors": [ "Google Inc." ],
+ "copyright": "Copyright 2016, Google Inc.",
+ "packOptions": {
+ "summary": "Implementation of gRPC reflection service",
+ "description": "Provides information about services running on a gRPC C# server.",
+ "owners": [ "grpc-packages" ],
+ "licenseUrl": "https://github.com/grpc/grpc/blob/master/LICENSE",
+ "projectUrl": "https://github.com/grpc/grpc",
+ "requireLicenseAcceptance": false,
+ "tags": [ "gRPC reflection" ]
+ },
+ "buildOptions": {
+ "define": [ "SIGNED" ],
+ "keyFile": "../keys/Grpc.snk",
+ "xmlDoc": true,
+ "compile": {
+ "includeFiles": [ "../Grpc.Core/Version.cs" ]
+ }
+ },
+ "dependencies": {
+ "Grpc.Core": "${settings.csharp_version}",
+ "Google.Protobuf": "3.0.0"
+ },
+ "frameworks": {
+ "net45": {
+ "frameworkAssemblies": {
+ "System.Runtime": "",
+ "System.IO": ""
+ }
+ },
+ "netstandard1.5": {
+ "dependencies": {
+ "NETStandard.Library": "1.6.0"
+ }
+ }
+ }
+ }
diff --git a/templates/src/csharp/build_packages.bat.template b/templates/src/csharp/build_packages_dotnetcli.bat.template
index 87c4b5ae27..562b7704ab 100644..100755
--- a/templates/src/csharp/build_packages.bat.template
+++ b/templates/src/csharp/build_packages_dotnetcli.bat.template
@@ -29,18 +29,17 @@
@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 Builds gRPC NuGet packages
-
- @rem This way of building nuget packages is now obsolete. C# nuget packages
- @rem with CoreCLR support are now being built using the dotnet cli
- @rem in build_packages_dotnetcli.sh
-
@rem Current package versions
set VERSION=${settings.csharp_version}
set PROTOBUF_VERSION=3.0.0
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe
+ set DOTNET=C:\dotnet\dotnet.exe
+
+ set -ex
+
+ mkdir -p ..\..\artifacts${"\\"}
@rem Collect the artifacts built by the previous build step if running on Jenkins
@rem TODO(jtattermusch): is there a better way to do this?
@@ -59,32 +58,22 @@
xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x86${"\\"}
xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x64${"\\"}
- @rem Fetch all dependencies
- %%NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error
-
- setlocal
-
- @call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
-
- @rem We won't use the native libraries from this step, but without this Grpc.sln will fail.
- msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:Configuration=Release /p:PlatformToolset=v120 || goto :error
-
- msbuild Grpc.sln /p:Configuration=ReleaseSigned || goto :error
+ %%DOTNET% restore . || goto :error
- endlocal
+ %%DOTNET% pack --configuration Release Grpc.Core\project.json --output ..\..\artifacts || goto :error
+ %%DOTNET% pack --configuration Release Grpc.Auth\project.json --output ..\..\artifacts || goto :error
+ %%DOTNET% pack --configuration Release Grpc.HealthCheck\project.json --output ..\..\artifacts || goto :error
+ %%DOTNET% pack --configuration Release Grpc.Reflection\project.json --output ..\..\artifacts || goto :error
- %%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
- %%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
- %%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
- %%NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
- %%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
+ %%NUGET% pack Grpc.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts || goto :error
+ %%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts
@rem copy resulting nuget packages to artifacts directory
- xcopy /Y /I *.nupkg ..\..\artifacts${"\\"}
+ xcopy /Y /I *.nupkg ..\..\artifacts\ || goto :error
@rem create a zipfile with the artifacts as well
- powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('..\..\artifacts', 'csharp_nugets_obsolete.zip');"
- xcopy /Y /I csharp_nugets_obsolete.zip ..\..\artifacts${"\\"}
+ powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('..\..\artifacts', 'csharp_nugets_windows_dotnetcli.zip');"
+ xcopy /Y /I csharp_nugets_windows_dotnetcli.zip ..\..\artifacts\ || goto :error
goto :EOF
diff --git a/templates/src/csharp/build_packages_dotnetcli.sh.template b/templates/src/csharp/build_packages_dotnetcli.sh.template
index 99b049a5a1..91c6fb6928 100755
--- a/templates/src/csharp/build_packages_dotnetcli.sh.template
+++ b/templates/src/csharp/build_packages_dotnetcli.sh.template
@@ -65,6 +65,7 @@
dotnet pack --configuration Release Grpc.Core/project.json --output ../../artifacts
dotnet pack --configuration Release Grpc.Auth/project.json --output ../../artifacts
dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts
+ dotnet pack --configuration Release Grpc.Reflection/project.json --output ../../artifacts
nuget pack Grpc.nuspec -Version "${settings.csharp_version}" -OutputDirectory ../../artifacts
nuget pack Grpc.Tools.nuspec -Version "${settings.csharp_version}" -OutputDirectory ../../artifacts
diff --git a/templates/tools/dockerfile/test/sanity/Dockerfile.template b/templates/tools/dockerfile/test/sanity/Dockerfile.template
index 12309b64d1..0168353933 100644
--- a/templates/tools/dockerfile/test/sanity/Dockerfile.template
+++ b/templates/tools/dockerfile/test/sanity/Dockerfile.template
@@ -48,9 +48,12 @@
#======================================
# More sanity test dependencies (bazel)
RUN apt-get install -y openjdk-8-jdk
- # TOOD(jtattermusch): pin the bazel version
- RUN git clone https://github.com/bazelbuild/bazel.git /bazel
- RUN cd /bazel && ./compile.sh
+ # Check out Bazel version 0.4.1 since this version allows running
+ # ./compile.sh without a local protoc dependency
+ # TODO(mattkwong): install dependencies to support latest Bazel version if newer
+ # version is needed
+ RUN git clone https://github.com/bazelbuild/bazel.git /bazel && \
+ cd /bazel && git checkout tags/0.4.1 && ./compile.sh
RUN ln -s /bazel/output/bazel /bin/
#===================
diff --git a/test/core/client_channel/lb_policies_test.c b/test/core/client_channel/lb_policies_test.c
index 95595d7c51..6e4058fc21 100644
--- a/test/core/client_channel/lb_policies_test.c
+++ b/test/core/client_channel/lb_policies_test.c
@@ -64,9 +64,11 @@ typedef struct servers_fixture {
} servers_fixture;
typedef struct request_sequences {
- size_t n;
- int *connections;
- int *connectivity_states;
+ size_t n; /* number of iterations */
+ int *connections; /* indexed by the interation number, value is the index of
+ the server it connected to or -1 if none */
+ int *connectivity_states; /* indexed by the interation number, value is the
+ client connectivity state */
} request_sequences;
typedef void (*verifier_fn)(const servers_fixture *, grpc_channel *,
@@ -481,7 +483,7 @@ void run_spec(const test_spec *spec) {
gpr_asprintf(&client_hostport, "ipv4:%s", servers_hostports_str);
arg_array[0].type = GRPC_ARG_INTEGER;
- arg_array[0].key = "grpc.testing.fixed_reconnect_backoff";
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
arg_array[0].value.integer = RETRY_TIMEOUT;
arg_array[1].type = GRPC_ARG_STRING;
arg_array[1].key = GRPC_ARG_LB_POLICY_NAME;
@@ -519,7 +521,7 @@ static grpc_channel *create_client(const servers_fixture *f) {
gpr_asprintf(&client_hostport, "ipv4:%s", servers_hostports_str);
arg_array[0].type = GRPC_ARG_INTEGER;
- arg_array[0].key = "grpc.testing.fixed_reconnect_backoff";
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
arg_array[0].value.integer = RETRY_TIMEOUT;
arg_array[1].type = GRPC_ARG_STRING;
arg_array[1].key = GRPC_ARG_LB_POLICY_NAME;
@@ -780,15 +782,17 @@ static void verify_total_carnage_round_robin(const servers_fixture *f,
}
}
- /* no server is ever available. The persistent state is TRANSIENT_FAILURE */
+ /* no server is ever available. The persistent state is TRANSIENT_FAILURE. May
+ * also be CONNECTING if, under load, this check took too long to run and some
+ * subchannel already transitioned to retrying. */
for (size_t i = 0; i < sequences->n; i++) {
const grpc_connectivity_state actual = sequences->connectivity_states[i];
- const grpc_connectivity_state expected = GRPC_CHANNEL_TRANSIENT_FAILURE;
- if (actual != expected) {
+ if (actual != GRPC_CHANNEL_TRANSIENT_FAILURE &&
+ actual != GRPC_CHANNEL_CONNECTING) {
gpr_log(GPR_ERROR,
- "CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' "
- "at iteration #%d",
- grpc_connectivity_state_name(expected),
+ "CONNECTIVITY STATUS SEQUENCE FAILURE: expected "
+ "GRPC_CHANNEL_TRANSIENT_FAILURE or GRPC_CHANNEL_CONNECTING, got "
+ "'%s' at iteration #%d",
grpc_connectivity_state_name(actual), (int)i);
abort();
}
@@ -825,8 +829,7 @@ static void verify_partial_carnage_round_robin(
}
/* We can assert that the first client channel state should be READY, when all
- * servers were available; and that the last one should be TRANSIENT_FAILURE,
- * after all servers are gone. */
+ * servers were available */
grpc_connectivity_state actual = sequences->connectivity_states[0];
grpc_connectivity_state expected = GRPC_CHANNEL_READY;
if (actual != expected) {
@@ -838,17 +841,21 @@ static void verify_partial_carnage_round_robin(
abort();
}
+ /* ... and that the last one should be TRANSIENT_FAILURE, after all servers
+ * are gone. May also be CONNECTING if, under load, this check took too long
+ * to run and the subchannel already transitioned to retrying. */
actual = sequences->connectivity_states[num_iters - 1];
- expected = GRPC_CHANNEL_TRANSIENT_FAILURE;
- if (actual != expected) {
- gpr_log(GPR_ERROR,
- "CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' "
- "at iteration #%d",
- grpc_connectivity_state_name(expected),
- grpc_connectivity_state_name(actual), (int)num_iters - 1);
- abort();
+ for (i = 0; i < sequences->n; i++) {
+ if (actual != GRPC_CHANNEL_TRANSIENT_FAILURE &&
+ actual != GRPC_CHANNEL_CONNECTING) {
+ gpr_log(GPR_ERROR,
+ "CONNECTIVITY STATUS SEQUENCE FAILURE: expected "
+ "GRPC_CHANNEL_TRANSIENT_FAILURE or GRPC_CHANNEL_CONNECTING, got "
+ "'%s' at iteration #%d",
+ grpc_connectivity_state_name(actual), (int)i);
+ abort();
+ }
}
-
gpr_free(expected_connection_sequence);
}
@@ -873,68 +880,21 @@ static void verify_rebirth_round_robin(const servers_fixture *f,
grpc_channel *client,
const request_sequences *sequences,
const size_t num_iters) {
- int *expected_connection_sequence;
- size_t i, j, unique_seq_last_idx, unique_seq_first_idx;
- const size_t expected_seq_length = f->num_servers;
- int *seen_elements;
-
dump_array("actual_connection_sequence", sequences->connections, num_iters);
- /* verify conn. seq. expectation */
- /* get the first unique run of length "num_servers". */
- expected_connection_sequence = gpr_malloc(sizeof(int) * expected_seq_length);
- seen_elements = gpr_malloc(sizeof(int) * expected_seq_length);
-
- unique_seq_last_idx = ~(size_t)0;
-
- memset(seen_elements, 0, sizeof(int) * expected_seq_length);
- for (i = 0; i < num_iters; i++) {
- if (sequences->connections[i] < 0 ||
- seen_elements[sequences->connections[i]] != 0) {
- /* if anything breaks the uniqueness of the run, back to square zero */
- memset(seen_elements, 0, sizeof(int) * expected_seq_length);
- continue;
- }
- seen_elements[sequences->connections[i]] = 1;
- for (j = 0; j < expected_seq_length; j++) {
- if (seen_elements[j] == 0) break;
- }
- if (j == expected_seq_length) { /* seen all the elements */
- unique_seq_last_idx = i;
- break;
- }
- }
- /* make sure we found a valid run */
- dump_array("seen_elements", seen_elements, expected_seq_length);
- for (j = 0; j < expected_seq_length; j++) {
- GPR_ASSERT(seen_elements[j] != 0);
- }
-
- GPR_ASSERT(unique_seq_last_idx != ~(size_t)0);
-
- unique_seq_first_idx = (unique_seq_last_idx - expected_seq_length + 1);
- memcpy(expected_connection_sequence,
- sequences->connections + unique_seq_first_idx,
- sizeof(int) * expected_seq_length);
-
/* first iteration succeeds */
GPR_ASSERT(sequences->connections[0] != -1);
/* then we fail for a while... */
GPR_ASSERT(sequences->connections[1] == -1);
- /* ... but should be up at "unique_seq_first_idx" */
- GPR_ASSERT(sequences->connections[unique_seq_first_idx] != -1);
-
- for (j = 0, i = unique_seq_first_idx; i < num_iters; i++) {
- const int actual = sequences->connections[i];
- const int expected =
- expected_connection_sequence[j++ % expected_seq_length];
- if (actual != expected) {
- print_failed_expectations(expected_connection_sequence,
- sequences->connections, expected_seq_length,
- num_iters);
- abort();
+ /* ... but should be up eventually */
+ size_t first_iter_back_up = ~0ul;
+ for (size_t i = 2; i < sequences->n; ++i) {
+ if (sequences->connections[i] != -1) {
+ first_iter_back_up = i;
+ break;
}
}
+ GPR_ASSERT(first_iter_back_up != ~0ul);
/* We can assert that the first client channel state should be READY, when all
* servers were available; same thing for the last one. In the middle
@@ -962,7 +922,7 @@ static void verify_rebirth_round_robin(const servers_fixture *f,
}
bool found_failure_status = false;
- for (i = 1; i < sequences->n - 1; i++) {
+ for (size_t i = 1; i < sequences->n - 1; i++) {
if (sequences->connectivity_states[i] == GRPC_CHANNEL_TRANSIENT_FAILURE) {
found_failure_status = true;
break;
@@ -974,14 +934,11 @@ static void verify_rebirth_round_robin(const servers_fixture *f,
"CONNECTIVITY STATUS SEQUENCE FAILURE: "
"GRPC_CHANNEL_TRANSIENT_FAILURE status not found. Got the following "
"instead:");
- for (i = 0; i < num_iters; i++) {
+ for (size_t i = 0; i < num_iters; i++) {
gpr_log(GPR_ERROR, "[%d]: %s", (int)i,
grpc_connectivity_state_name(sequences->connectivity_states[i]));
}
}
-
- gpr_free(expected_connection_sequence);
- gpr_free(seen_elements);
}
int main(int argc, char **argv) {
diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c
index 0a45f76395..11af7bee1e 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.c
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c
@@ -144,6 +144,8 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char **argv) {
size_t i;
+ g_fixture_slowdown_factor = 2.0;
+
grpc_test_init(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c
index a8c7b2be5a..cd68b390bb 100644
--- a/test/core/end2end/goaway_server_test.c
+++ b/test/core/end2end/goaway_server_test.c
@@ -126,8 +126,16 @@ int main(int argc, char **argv) {
char *addr;
+ grpc_channel_args client_args;
+ grpc_arg arg_array[1];
+ arg_array[0].type = GRPC_ARG_INTEGER;
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
+ arg_array[0].value.integer = 1000;
+ client_args.args = arg_array;
+ client_args.num_args = 1;
+
/* create a channel that picks first amongst the servers */
- grpc_channel *chan = grpc_insecure_channel_create("test", NULL, NULL);
+ grpc_channel *chan = grpc_insecure_channel_create("test", &client_args, NULL);
/* and an initial call to them */
grpc_call *call1 = grpc_channel_create_call(
chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", "127.0.0.1",
diff --git a/test/core/end2end/tests/connectivity.c b/test/core/end2end/tests/connectivity.c
index 260297ebd4..42475c7331 100644
--- a/test/core/end2end/tests/connectivity.c
+++ b/test/core/end2end/tests/connectivity.c
@@ -68,7 +68,15 @@ static void test_connectivity(grpc_end2end_test_config config) {
gpr_thd_options thdopt = gpr_thd_options_default();
gpr_thd_id thdid;
- config.init_client(&f, NULL);
+ grpc_channel_args client_args;
+ grpc_arg arg_array[1];
+ arg_array[0].type = GRPC_ARG_INTEGER;
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
+ arg_array[0].value.integer = 1000;
+ client_args.args = arg_array;
+ client_args.num_args = 1;
+
+ config.init_client(&f, &client_args);
ce.channel = f.client;
ce.cq = f.cq;
diff --git a/test/core/end2end/tests/filter_latency.c b/test/core/end2end/tests/filter_latency.c
index 37ce3b1222..ea63d45420 100644
--- a/test/core/end2end/tests/filter_latency.c
+++ b/test/core/end2end/tests/filter_latency.c
@@ -226,18 +226,6 @@ static void test_request(grpc_end2end_test_config config) {
grpc_call_destroy(s);
grpc_call_destroy(c);
- const gpr_timespec end_time = gpr_now(GPR_CLOCK_MONOTONIC);
- const gpr_timespec max_latency = gpr_time_sub(end_time, start_time);
-
- gpr_mu_lock(&g_mu);
- GPR_ASSERT(gpr_time_cmp(max_latency, g_client_latency) >= 0);
- GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_client_latency) < 0);
- GPR_ASSERT(gpr_time_cmp(max_latency, g_server_latency) >= 0);
- GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_server_latency) < 0);
- // Server latency should always be smaller than client latency.
- GPR_ASSERT(gpr_time_cmp(g_server_latency, g_client_latency) < 0);
- gpr_mu_unlock(&g_mu);
-
cq_verifier_destroy(cqv);
grpc_byte_buffer_destroy(request_payload);
@@ -245,6 +233,24 @@ static void test_request(grpc_end2end_test_config config) {
end_test(&f);
config.tear_down_data(&f);
+
+ const gpr_timespec end_time = gpr_now(GPR_CLOCK_MONOTONIC);
+ const gpr_timespec max_latency = gpr_time_sub(end_time, start_time);
+
+ // Perform checks after test tear-down
+ // Guards against the case that there's outstanding channel-related work on a
+ // call prior to verification
+ gpr_mu_lock(&g_mu);
+ GPR_ASSERT(gpr_time_cmp(max_latency, g_client_latency) >= 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_client_latency) <= 0);
+ GPR_ASSERT(gpr_time_cmp(max_latency, g_server_latency) >= 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_server_latency) <= 0);
+ // Server latency should always be smaller than client latency, however since
+ // we only calculate latency at destruction time, and that might mean that we
+ // need to wait for outstanding channel-related work, this isn't verifiable
+ // right now (the server MAY hold on to the call for longer than the client).
+ // GPR_ASSERT(gpr_time_cmp(g_server_latency, g_client_latency) < 0);
+ gpr_mu_unlock(&g_mu);
}
/*******************************************************************************
diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c
index db2e5c83de..4a88c5f2a8 100644
--- a/test/core/end2end/tests/payload.c
+++ b/test/core/end2end/tests/payload.c
@@ -126,7 +126,7 @@ static void request_response_with_payload(grpc_end2end_test_config config,
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_byte_buffer *response_payload =
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
- gpr_timespec deadline = five_seconds_time();
+ gpr_timespec deadline = n_seconds_time(60);
cq_verifier *cqv = cq_verifier_create(f.cq);
grpc_op ops[6];
grpc_op *op;
diff --git a/test/core/end2end/tests/resource_quota_server.c b/test/core/end2end/tests/resource_quota_server.c
index 7ec33e97a3..c919faea89 100644
--- a/test/core/end2end/tests/resource_quota_server.c
+++ b/test/core/end2end/tests/resource_quota_server.c
@@ -234,7 +234,7 @@ void resource_quota_server(grpc_end2end_test_config config) {
while (pending_client_calls + pending_server_recv_calls +
pending_server_end_calls >
0) {
- grpc_event ev = grpc_completion_queue_next(f.cq, n_seconds_time(10), NULL);
+ grpc_event ev = grpc_completion_queue_next(f.cq, n_seconds_time(60), NULL);
GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
int ev_tag = (int)(intptr_t)ev.tag;
diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c
index ec40c8f22d..414a03d98b 100644
--- a/test/core/end2end/tests/simple_delayed_request.c
+++ b/test/core/end2end/tests/simple_delayed_request.c
@@ -200,21 +200,36 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
static void test_simple_delayed_request_short(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f;
+ grpc_channel_args client_args;
+ grpc_arg arg_array[1];
+ arg_array[0].type = GRPC_ARG_INTEGER;
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
+ arg_array[0].value.integer = 1000;
+ client_args.args = arg_array;
+ client_args.num_args = 1;
gpr_log(GPR_INFO, "%s/%s", "test_simple_delayed_request_short", config.name);
f = config.create_fixture(NULL, NULL);
- simple_delayed_request_body(config, &f, NULL, NULL, 100000);
+
+ simple_delayed_request_body(config, &f, &client_args, NULL, 100000);
end_test(&f);
config.tear_down_data(&f);
}
static void test_simple_delayed_request_long(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f;
+ grpc_channel_args client_args;
+ grpc_arg arg_array[1];
+ arg_array[0].type = GRPC_ARG_INTEGER;
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
+ arg_array[0].value.integer = 1000;
+ client_args.args = arg_array;
+ client_args.num_args = 1;
gpr_log(GPR_INFO, "%s/%s", "test_simple_delayed_request_long", config.name);
f = config.create_fixture(NULL, NULL);
/* This timeout should be longer than a single retry */
- simple_delayed_request_body(config, &f, NULL, NULL, 1500000);
+ simple_delayed_request_body(config, &f, &client_args, NULL, 1500000);
end_test(&f);
config.tear_down_data(&f);
}
diff --git a/test/core/handshake/client_ssl.c b/test/core/handshake/client_ssl.c
index 44efe4dbac..24281e0b41 100644
--- a/test/core/handshake/client_ssl.c
+++ b/test/core/handshake/client_ssl.c
@@ -211,7 +211,7 @@ static bool client_ssl_test(char *server_alpn_preferred) {
// and port picking.
int port = -1;
int server_socket = -1;
- int socket_retries = 10;
+ int socket_retries = 30;
while (server_socket == -1 && socket_retries-- > 0) {
port = grpc_pick_unused_port_or_die();
server_socket = create_socket(port);
diff --git a/test/core/security/ssl_server_fuzzer.c b/test/core/security/ssl_server_fuzzer.c
index 04969765f5..ca629a6eba 100644
--- a/test/core/security/ssl_server_fuzzer.c
+++ b/test/core/security/ssl_server_fuzzer.c
@@ -58,17 +58,14 @@ struct handshake_state {
bool done_callback_called;
};
-static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
- grpc_security_status status,
- grpc_endpoint *secure_endpoint,
- grpc_auth_context *auth_context) {
- struct handshake_state *state = (struct handshake_state *)statep;
+static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ grpc_handshaker_args *args = arg;
+ struct handshake_state *state = args->user_data;
GPR_ASSERT(state->done_callback_called == false);
state->done_callback_called = true;
// The fuzzer should not pass the handshake.
- GPR_ASSERT(status != GRPC_SECURITY_OK);
- GPR_ASSERT(secure_endpoint == NULL);
- GPR_ASSERT(auth_context == NULL);
+ GPR_ASSERT(error != GRPC_ERROR_NONE);
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
@@ -108,15 +105,17 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_security_status status =
grpc_server_credentials_create_security_connector(creds, &sc);
GPR_ASSERT(status == GRPC_SECURITY_OK);
- sc->channel_args = NULL;
gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_seconds(1, GPR_TIMESPAN));
struct handshake_state state;
state.done_callback_called = false;
- grpc_server_security_connector_do_handshake(&exec_ctx, sc, NULL,
- mock_endpoint, NULL, deadline,
- on_secure_handshake_done, &state);
+ grpc_handshake_manager *handshake_mgr = grpc_handshake_manager_create();
+ grpc_server_security_connector_create_handshakers(&exec_ctx, sc,
+ handshake_mgr);
+ grpc_handshake_manager_do_handshake(
+ &exec_ctx, handshake_mgr, mock_endpoint, NULL /* channel_args */,
+ deadline, NULL /* acceptor */, on_handshake_done, &state);
grpc_exec_ctx_flush(&exec_ctx);
// If the given string happens to be part of the correct client hello, the
@@ -129,6 +128,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
GPR_ASSERT(state.done_callback_called);
+ grpc_handshake_manager_destroy(&exec_ctx, handshake_mgr);
GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "test");
grpc_server_credentials_release(creds);
grpc_slice_unref(cert_slice);
diff --git a/test/core/support/backoff_test.c b/test/core/support/backoff_test.c
index 13cba7d750..ad6e5a98f2 100644
--- a/test/core/support/backoff_test.c
+++ b/test/core/support/backoff_test.c
@@ -39,61 +39,110 @@
static void test_constant_backoff(void) {
gpr_backoff backoff;
- gpr_backoff_init(&backoff, 1.0, 0.0, 1000, 1000);
+ gpr_backoff_init(&backoff, 200 /* initial timeout */, 1.0 /* multiplier */,
+ 0.0 /* jitter */, 100 /* min timeout */,
+ 1000 /* max timeout */);
gpr_timespec now = gpr_time_0(GPR_TIMESPAN);
gpr_timespec next = gpr_backoff_begin(&backoff, now);
- GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 1000);
+ GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 200);
for (int i = 0; i < 10000; i++) {
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 1000);
+ GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 200);
now = next;
}
}
-static void test_no_jitter_backoff(void) {
+static void test_min_connect(void) {
gpr_backoff backoff;
- gpr_backoff_init(&backoff, 2.0, 0.0, 1, 513);
+ gpr_backoff_init(&backoff, 100 /* initial timeout */, 1.0 /* multiplier */,
+ 0.0 /* jitter */, 200 /* min timeout */,
+ 1000 /* max timeout */);
gpr_timespec now = gpr_time_0(GPR_TIMESPAN);
gpr_timespec next = gpr_backoff_begin(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1, GPR_TIMESPAN), next) == 0);
- now = next;
- next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(3, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 200);
+}
+
+static void test_no_jitter_backoff(void) {
+ gpr_backoff backoff;
+ gpr_backoff_init(&backoff, 2 /* initial timeout */, 2.0 /* multiplier */,
+ 0.0 /* jitter */, 1 /* min timeout */,
+ 513 /* max timeout */);
+ // x_1 = 2
+ // x_n = 2**i + x_{i-1} ( = 2**(n+1) - 2 )
+ gpr_timespec now = gpr_time_0(GPR_TIMESPAN);
+ gpr_timespec next = gpr_backoff_begin(&backoff, now);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(7, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(6, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(15, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(14, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(31, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(30, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(63, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(62, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(127, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(126, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(255, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(254, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(511, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(510, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1023, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1022, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1536, GPR_TIMESPAN), next) == 0);
+ // Hit the maximum timeout. From this point onwards, retries will increase
+ // only by max timeout.
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1535, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2049, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2048, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2562, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2561, GPR_TIMESPAN), next) == 0);
+}
+
+static void test_jitter_backoff(void) {
+ const int64_t initial_timeout = 500;
+ const double jitter = 0.1;
+ gpr_backoff backoff;
+ gpr_backoff_init(&backoff, initial_timeout, 1.0 /* multiplier */, jitter,
+ 100 /* min timeout */, 1000 /* max timeout */);
+
+ backoff.rng_state = 0; // force consistent PRNG
+
+ gpr_timespec now = gpr_time_0(GPR_TIMESPAN);
+ gpr_timespec next = gpr_backoff_begin(&backoff, now);
+ GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 500);
+
+ int64_t expected_next_lower_bound =
+ (int64_t)((double)initial_timeout * (1 - jitter));
+ int64_t expected_next_upper_bound =
+ (int64_t)((double)initial_timeout * (1 + jitter));
+
+ for (int i = 0; i < 10000; i++) {
+ next = gpr_backoff_step(&backoff, now);
+
+ // next-now must be within (jitter*100)% of the previous timeout.
+ const int64_t timeout_millis = gpr_time_to_millis(gpr_time_sub(next, now));
+ GPR_ASSERT(timeout_millis >= expected_next_lower_bound);
+ GPR_ASSERT(timeout_millis <= expected_next_upper_bound);
+
+ expected_next_lower_bound =
+ (int64_t)((double)timeout_millis * (1 - jitter));
+ expected_next_upper_bound =
+ (int64_t)((double)timeout_millis * (1 + jitter));
+ now = next;
+ }
}
int main(int argc, char **argv) {
@@ -101,7 +150,9 @@ int main(int argc, char **argv) {
gpr_time_init();
test_constant_backoff();
+ test_min_connect();
test_no_jitter_backoff();
+ test_jitter_backoff();
return 0;
}
diff --git a/test/core/surface/server_chttp2_test.c b/test/core/surface/server_chttp2_test.c
index 6310b6f00b..6c178abdad 100644
--- a/test/core/surface/server_chttp2_test.c
+++ b/test/core/surface/server_chttp2_test.c
@@ -44,8 +44,11 @@
#include "test/core/util/test_config.h"
void test_unparsable_target(void) {
- int port = grpc_server_add_insecure_http2_port(NULL, "[");
+ grpc_channel_args args = {0, NULL};
+ grpc_server *server = grpc_server_create(&args, NULL);
+ int port = grpc_server_add_insecure_http2_port(server, "[");
GPR_ASSERT(port == 0);
+ grpc_server_destroy(server);
}
void test_add_same_port_twice() {
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index 1cb4a8c05f..4a42e4c702 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -127,9 +127,9 @@ static bool is_port_available(int *port, bool is_tcp) {
on each supported family. */
bool got_socket = false;
for (int is_ipv6 = 1; is_ipv6 >= 0; is_ipv6--) {
- const int fd = socket(is_ipv6 ? AF_INET6 : AF_INET,
- is_tcp ? SOCK_STREAM : SOCK_DGRAM,
- is_tcp ? IPPROTO_TCP : 0);
+ const int fd =
+ socket(is_ipv6 ? AF_INET6 : AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM,
+ is_tcp ? IPPROTO_TCP : 0);
if (fd >= 0) {
got_socket = true;
} else {
@@ -147,9 +147,9 @@ static bool is_port_available(int *port, bool is_tcp) {
/* Try binding to port */
grpc_resolved_address addr;
if (is_ipv6) {
- grpc_sockaddr_make_wildcard6(*port, &addr); /* [::]:port */
+ grpc_sockaddr_make_wildcard6(*port, &addr); /* [::]:port */
} else {
- grpc_sockaddr_make_wildcard4(*port, &addr); /* 0.0.0.0:port */
+ grpc_sockaddr_make_wildcard4(*port, &addr); /* 0.0.0.0:port */
}
if (bind(fd, (struct sockaddr *)addr.addr, (socklen_t)addr.len) < 0) {
gpr_log(GPR_DEBUG, "bind(port=%d) failed: %s", *port, strerror(errno));
@@ -158,8 +158,8 @@ static bool is_port_available(int *port, bool is_tcp) {
}
/* Get the bound port number */
- if (getsockname(fd, (struct sockaddr *)addr.addr,
- (socklen_t *)&addr.len) < 0) {
+ if (getsockname(fd, (struct sockaddr *)addr.addr, (socklen_t *)&addr.len) <
+ 0) {
gpr_log(GPR_ERROR, "getsockname() failed: %s", strerror(errno));
close(fd);
return false;
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index 479aeda898..d86ed94637 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -33,14 +33,20 @@
#include "test/core/util/test_config.h"
-#include <grpc/support/log.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/support/env.h"
#include "src/core/lib/support/string.h"
double g_fixture_slowdown_factor = 1.0;
+double g_poller_slowdown_factor = 1.0;
#if GPR_GETPID_IN_UNISTD_H
#include <unistd.h>
@@ -274,9 +280,16 @@ static void install_crash_handler() {}
void grpc_test_init(int argc, char **argv) {
install_crash_handler();
- gpr_log(GPR_DEBUG, "test slowdown: machine=%f build=%f total=%f",
+ { /* poll-cv poll strategy runs much more slowly than anything else */
+ char *s = gpr_getenv("GRPC_POLL_STRATEGY");
+ if (s != NULL && 0 == strcmp(s, "poll-cv")) {
+ g_poller_slowdown_factor = 5.0;
+ }
+ gpr_free(s);
+ }
+ gpr_log(GPR_DEBUG, "test slowdown: machine=%f build=%f poll=%f total=%f",
(double)GRPC_TEST_SLOWDOWN_MACHINE_FACTOR,
- (double)GRPC_TEST_SLOWDOWN_BUILD_FACTOR,
+ (double)GRPC_TEST_SLOWDOWN_BUILD_FACTOR, g_poller_slowdown_factor,
(double)GRPC_TEST_SLOWDOWN_FACTOR);
/* seed rng with pid, so we don't end up with the same random numbers as a
concurrently running test binary */
diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h
index 76686f1c51..c13fe86a64 100644
--- a/test/core/util/test_config.h
+++ b/test/core/util/test_config.h
@@ -49,10 +49,11 @@ extern "C" {
#endif
extern double g_fixture_slowdown_factor;
+extern double g_poller_slowdown_factor;
#define GRPC_TEST_SLOWDOWN_FACTOR \
(GRPC_TEST_SLOWDOWN_BUILD_FACTOR * GRPC_TEST_SLOWDOWN_MACHINE_FACTOR * \
- g_fixture_slowdown_factor)
+ g_fixture_slowdown_factor * g_poller_slowdown_factor)
#define GRPC_TIMEOUT_SECONDS_TO_DEADLINE(x) \
gpr_time_add( \
diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc
index 57a53ca11e..fcdcaba6a2 100644
--- a/test/cpp/grpclb/grpclb_test.cc
+++ b/test/cpp/grpclb/grpclb_test.cc
@@ -523,9 +523,8 @@ static void perform_request(client_fixture *cf) {
CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
cq_verify(cqv);
+ gpr_log(GPR_INFO, "Client after sending msg %d / 4", i + 1);
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, PAYLOAD));
- GPR_ASSERT(grpc_channel_check_connectivity_state(
- cf->client, 0 /* try to connect */) == GRPC_CHANNEL_READY);
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(response_payload_recv);
@@ -546,16 +545,17 @@ static void perform_request(client_fixture *cf) {
cq_verify(cqv);
peer = grpc_call_get_peer(c);
gpr_log(GPR_INFO, "Client DONE WITH SERVER %s ", peer);
- gpr_free(peer);
grpc_call_destroy(c);
- cq_verify_empty_timeout(cqv, 1);
+ cq_verify_empty_timeout(cqv, 1 /* seconds */);
cq_verifier_destroy(cqv);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
gpr_free(details);
+ gpr_log(GPR_INFO, "Client call (peer %s) DESTROYED.", peer);
+ gpr_free(peer);
}
static void setup_client(const char *server_hostport, client_fixture *cf) {
@@ -699,39 +699,42 @@ static test_fixture test_update(int lb_server_update_delay_ms) {
TEST(GrpclbTest, Updates) {
grpc::test_fixture tf_result;
- // Clients take a bit over one second to complete a call (the last part of the
+ // Clients take at least one second to complete a call (the last part of the
// call sleeps for 1 second while verifying the client's completion queue is
- // empty). Therefore:
+ // empty), more if the system is under load. Therefore:
//
// If the LB server waits 800ms before sending an update, it will arrive
- // before the first client request is done, skipping the second server from
- // batch 1 altogether: the 2nd client request will go to the 1st server of
- // batch 2 (ie, the third one out of the four total servers).
+ // before the first client request finishes, skipping the second server from
+ // batch 1. All subsequent picks will come from the second half of the
+ // backends, those coming in the LB update.
tf_result = grpc::test_update(800);
GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced == 1);
GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced == 0);
- GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced == 2);
- GPR_ASSERT(tf_result.lb_backends[3].num_calls_serviced == 1);
+ GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced +
+ tf_result.lb_backends[3].num_calls_serviced >
+ 0);
+ int num_serviced_calls = 0;
+ for (int i = 0; i < 4; i++) {
+ num_serviced_calls += tf_result.lb_backends[i].num_calls_serviced;
+ }
+ GPR_ASSERT(num_serviced_calls == 4);
- // If the LB server waits 1500ms, the update arrives after having picked the
- // 2nd server from batch 1 but before the next pick for the first server of
- // batch 2. All server are used.
- tf_result = grpc::test_update(1500);
- GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced == 1);
- GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced == 1);
- GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced == 1);
- GPR_ASSERT(tf_result.lb_backends[3].num_calls_serviced == 1);
-
- // If the LB server waits > 2000ms, the update arrives after the first two
- // request are done and the third pick is performed, which returns, in RR
- // fashion, the 1st server of the 1st update. Therefore, the second server of
- // batch 1 is hit at least one, whereas the first server of batch 2 is never
- // hit.
+ // If the LB server waits 2500ms, the update arrives after two calls and three
+ // picks. The third pick will be the 1st server of the 1st update (RR policy
+ // going around). The fourth and final pick will come from the second LB
+ // update. In any case, the total number of serviced calls must again be equal
+ // to four across all the backends.
tf_result = grpc::test_update(2500);
GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced >= 1);
- GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced > 0);
- GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced > 0);
- GPR_ASSERT(tf_result.lb_backends[3].num_calls_serviced == 0);
+ GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced == 1);
+ GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced +
+ tf_result.lb_backends[3].num_calls_serviced >
+ 0);
+ num_serviced_calls = 0;
+ for (int i = 0; i < 4; i++) {
+ num_serviced_calls += tf_result.lb_backends[i].num_calls_serviced;
+ }
+ GPR_ASSERT(num_serviced_calls == 4);
}
TEST(GrpclbTest, InvalidAddressInServerlist) {}
diff --git a/test/cpp/microbenchmarks/bm_fullstack.cc b/test/cpp/microbenchmarks/bm_fullstack.cc
index 10984b7e91..6c0bf80488 100644
--- a/test/cpp/microbenchmarks/bm_fullstack.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack.cc
@@ -71,6 +71,8 @@ static class InitializeStuff {
rq_ = grpc_resource_quota_create("bm");
}
+ ~InitializeStuff() { init_lib_.shutdown(); }
+
grpc_resource_quota* rq() { return rq_; }
private:
@@ -126,7 +128,16 @@ class TCP : public FullstackFixture {
class UDS : public FullstackFixture {
public:
- UDS(Service* service) : FullstackFixture(service, "unix:bm_fullstack") {}
+ UDS(Service* service) : FullstackFixture(service, MakeAddress()) {}
+
+ private:
+ static grpc::string MakeAddress() {
+ int port = grpc_pick_unused_port_or_die(); // just for a unique id - not a
+ // real port
+ std::stringstream addr;
+ addr << "unix:/tmp/bm_fullstack." << port;
+ return addr.str();
+ }
};
class EndpointPairFixture {
@@ -221,7 +232,7 @@ class InProcessCHTTP2 : public EndpointPairFixture {
* CONTEXT MUTATORS
*/
-static const int kPregenerateKeyCount = 10000000;
+static const int kPregenerateKeyCount = 100000;
template <class F>
auto MakeVector(size_t length, F f) -> std::vector<decltype(f())> {
diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py
index e4d9e7ac58..4aa58d2737 100755
--- a/test/cpp/qps/gen_build_yaml.py
+++ b/test/cpp/qps/gen_build_yaml.py
@@ -43,28 +43,38 @@ sys.path.append(run_tests_root)
import performance.scenario_config as scenario_config
-def _scenario_json_string(scenario_json):
+configs_from_yaml = yaml.load(open(os.path.join(os.path.dirname(sys.argv[0]), '../../../build.yaml')))['configs'].keys()
+
+def mutate_scenario(scenario_json, is_tsan):
# tweak parameters to get fast test times
+ scenario_json = dict(scenario_json)
scenario_json['warmup_seconds'] = 0
scenario_json['benchmark_seconds'] = 1
- scenarios_json = {'scenarios': [scenario_config.remove_nonproto_fields(scenario_json)]}
+ outstanding_rpcs_divisor = 1
+ if is_tsan and (
+ scenario_json['client_config']['client_type'] == 'SYNC_CLIENT' or
+ scenario_json['server_config']['server_type'] == 'SYNC_SERVER'):
+ outstanding_rpcs_divisor = 10
+ scenario_json['client_config']['outstanding_rpcs_per_channel'] = max(1,
+ int(scenario_json['client_config']['outstanding_rpcs_per_channel'] / outstanding_rpcs_divisor))
+ return scenario_json
+
+def _scenario_json_string(scenario_json, is_tsan):
+ scenarios_json = {'scenarios': [scenario_config.remove_nonproto_fields(mutate_scenario(scenario_json, is_tsan))]}
return json.dumps(scenarios_json)
-def threads_of_type(scenario_json, path):
- d = scenario_json
- for el in path.split('/'):
- if el not in d:
- return 0
- d = d[el]
- return d
+def threads_required(scenario_json, where, is_tsan):
+ scenario_json = mutate_scenario(scenario_json, is_tsan)
+ if scenario_json['%s_config' % where]['%s_type' % where] == 'ASYNC_%s' % where.upper():
+ return scenario_json['%s_config' % where].get('async_%s_threads' % where, 0)
+ return scenario_json['client_config']['outstanding_rpcs_per_channel'] * scenario_json['client_config']['client_channels']
-def guess_cpu(scenario_json):
- client = threads_of_type(scenario_json, 'client_config/async_client_threads')
- server = threads_of_type(scenario_json, 'server_config/async_server_threads')
+def guess_cpu(scenario_json, is_tsan):
+ client = threads_required(scenario_json, 'client', is_tsan)
+ server = threads_required(scenario_json, 'server', is_tsan)
# make an arbitrary guess if set to auto-detect
# about the size of the jenkins instances we have for unit tests
- if client == 0: client = 8
- if server == 0: server = 8
+ if client == 0 or server == 0: return 'capacity'
return (scenario_json['num_clients'] * client +
scenario_json['num_servers'] * server)
@@ -73,15 +83,32 @@ print yaml.dump({
{
'name': 'json_run_localhost',
'shortname': 'json_run_localhost:%s' % scenario_json['name'],
- 'args': ['--scenarios_json', _scenario_json_string(scenario_json)],
+ 'args': ['--scenarios_json', _scenario_json_string(scenario_json, False)],
+ 'ci_platforms': ['linux'],
+ 'platforms': ['linux'],
+ 'flaky': False,
+ 'language': 'c++',
+ 'boringssl': True,
+ 'defaults': 'boringssl',
+ 'cpu_cost': guess_cpu(scenario_json, False),
+ 'exclude_configs': ['tsan'],
+ 'timeout_seconds': 6*60
+ }
+ for scenario_json in scenario_config.CXXLanguage().scenarios()
+ if 'scalable' in scenario_json.get('CATEGORIES', [])
+ ] + [
+ {
+ 'name': 'json_run_localhost',
+ 'shortname': 'json_run_localhost:%s' % scenario_json['name'],
+ 'args': ['--scenarios_json', _scenario_json_string(scenario_json, True)],
'ci_platforms': ['linux'],
'platforms': ['linux'],
'flaky': False,
'language': 'c++',
'boringssl': True,
'defaults': 'boringssl',
- 'cpu_cost': guess_cpu(scenario_json),
- 'exclude_configs': [],
+ 'cpu_cost': guess_cpu(scenario_json, True),
+ 'exclude_configs': sorted(c for c in configs_from_yaml if c != 'tsan'),
'timeout_seconds': 6*60
}
for scenario_json in scenario_config.CXXLanguage().scenarios()
diff --git a/test/cpp/qps/json_run_localhost.cc b/test/cpp/qps/json_run_localhost.cc
index 74e40fbf1a..b7b2553f12 100644
--- a/test/cpp/qps/json_run_localhost.cc
+++ b/test/cpp/qps/json_run_localhost.cc
@@ -31,7 +31,11 @@
*
*/
+#include <signal.h>
+#include <string.h>
+
#include <memory>
+#include <mutex>
#include <sstream>
#include <string>
@@ -43,6 +47,11 @@
using grpc::SubProcess;
+constexpr auto kNumWorkers = 2;
+
+static SubProcess* g_driver;
+static SubProcess* g_workers[kNumWorkers];
+
template <class T>
std::string as_string(const T& val) {
std::ostringstream out;
@@ -50,9 +59,38 @@ std::string as_string(const T& val) {
return out.str();
}
+static void sighandler(int sig) {
+ const int errno_saved = errno;
+ if (g_driver != NULL) g_driver->Interrupt();
+ for (int i = 0; i < kNumWorkers; ++i) {
+ if (g_workers[i]) g_workers[i]->Interrupt();
+ }
+ errno = errno_saved;
+}
+
+static void register_sighandler() {
+ struct sigaction act;
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = sighandler;
+
+ sigaction(SIGINT, &act, NULL);
+ sigaction(SIGTERM, &act, NULL);
+}
+
+static void LogStatus(int status, const char* label) {
+ if (WIFEXITED(status)) {
+ gpr_log(GPR_INFO, "%s: subprocess exited with status %d", label,
+ WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status)) {
+ gpr_log(GPR_INFO, "%s: subprocess terminated with signal %d", label,
+ WTERMSIG(status));
+ } else {
+ gpr_log(GPR_INFO, "%s: unknown subprocess status: %d", label, status);
+ }
+}
+
int main(int argc, char** argv) {
- typedef std::unique_ptr<SubProcess> SubProcessPtr;
- std::vector<SubProcessPtr> jobs;
+ register_sighandler();
std::string my_bin = argv[0];
std::string bin_dir = my_bin.substr(0, my_bin.rfind('/'));
@@ -60,11 +98,11 @@ int main(int argc, char** argv) {
std::ostringstream env;
bool first = true;
- for (int i = 0; i < 2; i++) {
- auto port = grpc_pick_unused_port_or_die();
+ for (int i = 0; i < kNumWorkers; i++) {
+ const auto port = grpc_pick_unused_port_or_die();
std::vector<std::string> args = {bin_dir + "/qps_worker", "-driver_port",
as_string(port)};
- jobs.emplace_back(new SubProcess(args));
+ g_workers[i] = new SubProcess(args);
if (!first) env << ",";
env << "localhost:" << port;
first = false;
@@ -75,12 +113,27 @@ int main(int argc, char** argv) {
for (int i = 1; i < argc; i++) {
args.push_back(argv[i]);
}
- GPR_ASSERT(SubProcess(args).Join() == 0);
- for (auto it = jobs.begin(); it != jobs.end(); ++it) {
- (*it)->Interrupt();
+ g_driver = new SubProcess(args);
+ const int driver_join_status = g_driver->Join();
+ if (driver_join_status != 0) {
+ LogStatus(driver_join_status, "driver");
}
- for (auto it = jobs.begin(); it != jobs.end(); ++it) {
- (*it)->Join();
+ for (int i = 0; i < kNumWorkers; ++i) {
+ if (g_workers[i]) g_workers[i]->Interrupt();
}
+
+ for (int i = 0; i < kNumWorkers; ++i) {
+ if (g_workers[i]) {
+ const int worker_status = g_workers[i]->Join();
+ if (worker_status != 0) {
+ LogStatus(worker_status, "worker");
+ }
+ }
+ }
+
+ delete g_driver;
+ g_driver = NULL;
+ for (int i = 0; i < kNumWorkers; ++i) delete g_workers[i];
+ GPR_ASSERT(driver_join_status == 0);
}
diff --git a/tools/README.md b/tools/README.md
index d142d4aee2..d051846c33 100644
--- a/tools/README.md
+++ b/tools/README.md
@@ -11,6 +11,8 @@ gce: Scripts to help setup testing infrastructure on GCE.
gcp: Helper scripts for interacting with various services on GCP (like Google
container engine, BigQuery etc)
+internal_ci: Support for running tests on an internal CI platform.
+
jenkins: Support for running tests on Jenkins.
run_tests: Scripts to run gRPC tests in parallel.
diff --git a/tools/dockerfile/push_testing_images.sh b/tools/dockerfile/push_testing_images.sh
new file mode 100755
index 0000000000..f1ee8d59dd
--- /dev/null
+++ b/tools/dockerfile/push_testing_images.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Builds selected testing docker images and pushes them to dockerhub.
+# Useful for testing environments where it's impractical (or impossible)
+# to rely on docker images being cached locally after they've been built
+# for the first time (which might be costly especially for some images).
+# NOTE: gRPC docker images intended to be used by end users are NOT
+# pushed using this script (they're built automatically by dockerhub).
+# This script is only for "internal" images we use when testing gRPC.
+
+set -ex
+
+cd $(dirname $0)/../..
+git_root=$(pwd)
+cd -
+
+DOCKERHUB_ORGANIZATION=grpctesting
+
+for DOCKERFILE_DIR in tools/dockerfile/test/fuzzer
+do
+ # Generate image name based on Dockerfile checksum. That works well as long
+ # as can count on dockerfiles being written in a way that changing the logical
+ # contents of the docker image always changes the SHA (e.g. using "ADD file"
+ # cmd in the dockerfile in not ok as contents of the added file will not be
+ # reflected in the SHA).
+ DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
+
+ # skip the image if it already exists in the repo
+ curl --silent -f -lSL https://registry.hub.docker.com/v2/repositories/${DOCKERHUB_ORGANIZATION}/${DOCKER_IMAGE_NAME}/tags/latest > /dev/null \
+ && continue
+
+ docker build -t ${DOCKERHUB_ORGANIZATION}/${DOCKER_IMAGE_NAME} ${DOCKERFILE_DIR}
+
+ # "docker login" needs to be run in advance
+ docker push ${DOCKERHUB_ORGANIZATION}/${DOCKER_IMAGE_NAME}
+done
diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile
index f4b4831a64..6b19ac845b 100644
--- a/tools/dockerfile/test/sanity/Dockerfile
+++ b/tools/dockerfile/test/sanity/Dockerfile
@@ -93,9 +93,11 @@ RUN pip install simplejson mako
#======================================
# More sanity test dependencies (bazel)
RUN apt-get install -y openjdk-8-jdk
-# TOOD(jtattermusch): pin the bazel version
-RUN git clone https://github.com/bazelbuild/bazel.git /bazel
-RUN cd /bazel && ./compile.sh
+# Check out Bazel version 0.4.1 since this version allows running
+# ./compile.sh without a local protoc dependency
+# TODO(mattkwong): install dependencies to support latest Bazel version if newer
+# version is needed
+RUN git clone https://github.com/bazelbuild/bazel.git /bazel && cd /bazel && git checkout tags/0.4.1 && ./compile.sh
RUN ln -s /bazel/output/bazel /bin/
#===================
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index a629bdc542..6572bd4ddf 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -919,9 +919,9 @@ src/core/lib/security/credentials/oauth2/oauth2_credentials.h \
src/core/lib/security/credentials/plugin/plugin_credentials.h \
src/core/lib/security/credentials/ssl/ssl_credentials.h \
src/core/lib/security/transport/auth_filters.h \
-src/core/lib/security/transport/handshake.h \
src/core/lib/security/transport/secure_endpoint.h \
src/core/lib/security/transport/security_connector.h \
+src/core/lib/security/transport/security_handshaker.h \
src/core/lib/security/transport/tsi_error.h \
src/core/lib/security/util/b64.h \
src/core/lib/security/util/json_util.h \
@@ -930,6 +930,7 @@ src/core/lib/tsi/ssl_transport_security.h \
src/core/lib/tsi/ssl_types.h \
src/core/lib/tsi/transport_security.h \
src/core/lib/tsi/transport_security_interface.h \
+src/core/ext/transport/chttp2/server/chttp2_server.h \
src/core/ext/client_channel/client_channel.h \
src/core/ext/client_channel/client_channel_factory.h \
src/core/ext/client_channel/connector.h \
@@ -945,6 +946,7 @@ src/core/ext/client_channel/resolver_registry.h \
src/core/ext/client_channel/subchannel.h \
src/core/ext/client_channel/subchannel_index.h \
src/core/ext/client_channel/uri_parser.h \
+src/core/ext/transport/chttp2/client/chttp2_connector.h \
src/core/ext/lb_policy/grpclb/grpclb.h \
src/core/ext/lb_policy/grpclb/load_balancer_api.h \
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h \
@@ -1117,9 +1119,9 @@ src/core/lib/security/credentials/oauth2/oauth2_credentials.c \
src/core/lib/security/credentials/plugin/plugin_credentials.c \
src/core/lib/security/credentials/ssl/ssl_credentials.c \
src/core/lib/security/transport/client_auth_filter.c \
-src/core/lib/security/transport/handshake.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
+src/core/lib/security/transport/security_handshaker.c \
src/core/lib/security/transport/server_auth_filter.c \
src/core/lib/security/transport/tsi_error.c \
src/core/lib/security/util/b64.c \
@@ -1128,6 +1130,7 @@ src/core/lib/surface/init_secure.c \
src/core/lib/tsi/fake_transport_security.c \
src/core/lib/tsi/ssl_transport_security.c \
src/core/lib/tsi/transport_security.c \
+src/core/ext/transport/chttp2/server/chttp2_server.c \
src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \
src/core/ext/client_channel/channel_connectivity.c \
src/core/ext/client_channel/client_channel.c \
@@ -1147,6 +1150,7 @@ src/core/ext/client_channel/resolver_registry.c \
src/core/ext/client_channel/subchannel.c \
src/core/ext/client_channel/subchannel_index.c \
src/core/ext/client_channel/uri_parser.c \
+src/core/ext/transport/chttp2/client/chttp2_connector.c \
src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
src/core/ext/transport/chttp2/client/insecure/channel_create.c \
diff --git a/tools/internal_ci/README.md b/tools/internal_ci/README.md
new file mode 100644
index 0000000000..8bed6ca782
--- /dev/null
+++ b/tools/internal_ci/README.md
@@ -0,0 +1,6 @@
+#Internal continuous integration
+
+gRPC's externally facing testing is managed by Jenkins CI (see `tools/jenkins`
+directory). Nevertheless, some of the tests are better suited for being run
+on internal infrastructure and using an internal CI system. Configuration for
+such tests is under this directory.
diff --git a/tools/internal_ci/linux/grpc_master.cfg b/tools/internal_ci/linux/grpc_master.cfg
new file mode 100644
index 0000000000..1f81660078
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_master.cfg
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Config file for the internal CI (in protobuf text format)
+
+# Location of the continuous shell script in repository.
+build_file: "grpc/tools/internal_ci/linux/run_tests.sh"
diff --git a/tools/internal_ci/linux/run_tests.sh b/tools/internal_ci/linux/run_tests.sh
new file mode 100755
index 0000000000..be477c1271
--- /dev/null
+++ b/tools/internal_ci/linux/run_tests.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set -ex
+
+# change to grpc repo root
+cd $(dirname $0)/../../..
+
+# TODO(jtattermusch): get rid of the system inspection eventually
+nproc || true
+lsb_release -dc || true
+gcc --version || true
+clang --version || true
+docker --version || true
+
+git submodule update --init
+
+tools/run_tests/run_tests.py -l c --build_only
diff --git a/tools/jenkins/README.md b/tools/jenkins/README.md
index 8e06b68466..02f63f0f4a 100644
--- a/tools/jenkins/README.md
+++ b/tools/jenkins/README.md
@@ -1 +1,6 @@
+# Jenkins CI scripts
+
Scripts invoked by Jenkins (our CI platform) to run gRPC test suites.
+We run a comprehensive set of tests (unit, integration, interop,
+performance, portability..) on each pull request and also periodically on
+`master` and release branches.
diff --git a/tools/run_tests/dockerize/build_and_run_docker.sh b/tools/run_tests/dockerize/build_and_run_docker.sh
index 1ef34b2f96..f52f16ebd6 100755
--- a/tools/run_tests/dockerize/build_and_run_docker.sh
+++ b/tools/run_tests/dockerize/build_and_run_docker.sh
@@ -41,13 +41,20 @@ cd -
# DOCKERFILE_DIR - Directory in which Dockerfile file is located.
# DOCKER_RUN_SCRIPT - Script to run under docker (relative to grpc repo root)
# OUTPUT_DIR - Directory that will be copied from inside docker after finishing.
+# DOCKERHUB_ORGANIZATION - If set, pull a prebuilt image from given dockerhub org.
# $@ - Extra args to pass to docker run
# Use image name based on Dockerfile location checksum
DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
-# Make sure docker image has been built. Should be instantaneous if so.
-docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR
+if [ "$DOCKERHUB_ORGANIZATION" != "" ]
+then
+ DOCKER_IMAGE_NAME=$DOCKERHUB_ORGANIZATION/$DOCKER_IMAGE_NAME
+ docker pull $DOCKER_IMAGE_NAME
+else
+ # Make sure docker image has been built. Should be instantaneous if so.
+ docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR
+fi
# Choose random name for docker container
CONTAINER_NAME="build_and_run_docker_$(uuidgen)"
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index b84eb3b5d7..2acc7971f6 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -49,12 +49,22 @@ measure_cpu_costs = False
_DEFAULT_MAX_JOBS = 16 * multiprocessing.cpu_count()
_MAX_RESULT_SIZE = 8192
+
+# NOTE: If you change this, please make sure to test reviewing the
+# github PR with http://reviewable.io, which is known to add UTF-8
+# characters to the PR description, which leak into the environment here
+# and cause failures.
+def strip_non_ascii_chars(s):
+ return ''.join(c for c in s if ord(c) < 128)
+
+
def sanitized_environment(env):
sanitized = {}
for key, value in env.items():
- sanitized[str(key).encode()] = str(value).encode()
+ sanitized[strip_non_ascii_chars(key)] = strip_non_ascii_chars(value)
return sanitized
+
def platform_string():
if platform.system() == 'Windows':
return 'windows'
diff --git a/tools/run_tests/package_targets.py b/tools/run_tests/package_targets.py
index 2802957ff1..673affeac0 100644
--- a/tools/run_tests/package_targets.py
+++ b/tools/run_tests/package_targets.py
@@ -71,50 +71,28 @@ def create_jobspec(name, cmdline, environ=None, cwd=None, shell=False,
class CSharpPackage:
"""Builds C# nuget packages."""
- def __init__(self, linux=False, use_dotnet_cli=True):
+ def __init__(self, linux=False):
self.linux = linux
- self.use_dotnet_cli = use_dotnet_cli
-
self.labels = ['package', 'csharp']
-
- if use_dotnet_cli:
- if linux:
- self.name = 'csharp_package_dotnetcli_linux'
- self.labels += ['linux']
- else:
- self.name = 'csharp_package_dotnetcli_windows'
- self.labels += ['windows']
+ if linux:
+ self.name = 'csharp_package_dotnetcli_linux'
+ self.labels += ['linux']
else:
- # official packages built with dotnet cli rather than nuget pack
- self.name = 'csharp_package_obsolete'
- self.labels += ['obsolete']
-
+ self.name = 'csharp_package_dotnetcli_windows'
+ self.labels += ['windows']
def pre_build_jobspecs(self):
- # The older, obsolete build uses nuget only instead of dotnet cli
- if 'obsolete' in self.labels:
- return [create_jobspec('prebuild_%s' % self.name,
- ['tools\\run_tests\\pre_build_csharp.bat'],
- shell=True,
- flake_retries=5,
- timeout_retries=2)]
- else:
- return []
+ return []
def build_jobspec(self):
- if self.use_dotnet_cli and self.linux:
+ if self.linux:
return create_docker_jobspec(
self.name,
'tools/dockerfile/test/csharp_coreclr_x64',
'src/csharp/build_packages_dotnetcli.sh')
- elif self.use_dotnet_cli:
- return create_jobspec(self.name,
- ['build_packages_dotnetcli.bat'],
- cwd='src\\csharp',
- shell=True)
else:
return create_jobspec(self.name,
- ['build_packages.bat'],
+ ['build_packages_dotnetcli.bat'],
cwd='src\\csharp',
shell=True)
@@ -194,7 +172,6 @@ def targets():
"""Gets list of supported targets"""
return [CSharpPackage(),
CSharpPackage(linux=True),
- CSharpPackage(use_dotnet_cli=False),
NodePackage(),
RubyPackage(),
PythonPackage(),
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 6a01bc23c4..83cfc429f9 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -64,11 +64,10 @@ _SKIP_SERVER_COMPRESSION = ['server_compressed_unary',
_SKIP_COMPRESSION = _SKIP_CLIENT_COMPRESSION + _SKIP_SERVER_COMPRESSION
-_SKIP_ADVANCED_GO = ['custom_metadata',
- 'unimplemented_method',
- 'unimplemented_service']
-
-_SKIP_ADVANCED = _SKIP_ADVANCED_GO + ['status_code_and_message']
+_SKIP_ADVANCED = ['status_code_and_message',
+ 'custom_metadata',
+ 'unimplemented_method',
+ 'unimplemented_service']
_TEST_TIMEOUT = 3*60
@@ -209,10 +208,10 @@ class GoLanguage:
return {}
def unimplemented_test_cases(self):
- return _SKIP_ADVANCED_GO + _SKIP_COMPRESSION
+ return _SKIP_COMPRESSION
def unimplemented_test_cases_server(self):
- return _SKIP_ADVANCED_GO + _SKIP_COMPRESSION
+ return _SKIP_COMPRESSION
def __str__(self):
return 'go'
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index fe8ad5f6ad..1544ff369d 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -231,6 +231,9 @@ class CLanguage(object):
'GRPC_POLL_STRATEGY': polling_strategy,
'GRPC_VERBOSITY': 'DEBUG'}
shortname_ext = '' if polling_strategy=='all' else ' GRPC_POLL_STRATEGY=%s' % polling_strategy
+ timeout_scaling = 1
+ if polling_strategy == 'poll-cv':
+ timeout_scaling *= 5
if self.config.build_config in target['exclude_configs']:
continue
if self.args.iomgr_platform in target.get('exclude_iomgrs', []):
@@ -242,6 +245,9 @@ class CLanguage(object):
target['name'])
else:
binary = 'bins/%s/%s' % (self.config.build_config, target['name'])
+ cpu_cost = target['cpu_cost']
+ if cpu_cost == 'capacity':
+ cpu_cost = multiprocessing.cpu_count()
if os.path.isfile(binary):
if 'gtest' in target and target['gtest']:
# here we parse the output of --gtest_list_tests to build up a
@@ -265,7 +271,8 @@ class CLanguage(object):
cmdline = [binary] + ['--gtest_filter=%s' % test]
out.append(self.config.job_spec(cmdline,
shortname='%s --gtest_filter=%s %s' % (binary, test, shortname_ext),
- cpu_cost=target['cpu_cost'],
+ cpu_cost=cpu_cost,
+ timeout_seconds=_DEFAULT_TIMEOUT_SECONDS * timeout_scaling,
environ=env))
else:
cmdline = [binary] + target['args']
@@ -274,9 +281,9 @@ class CLanguage(object):
pipes.quote(arg)
for arg in cmdline) +
shortname_ext,
- cpu_cost=target['cpu_cost'],
+ cpu_cost=cpu_cost,
flaky=target.get('flaky', False),
- timeout_seconds=target.get('timeout_seconds', _DEFAULT_TIMEOUT_SECONDS),
+ timeout_seconds=target.get('timeout_seconds', _DEFAULT_TIMEOUT_SECONDS) * timeout_scaling,
environ=env))
elif self.args.regex == '.*' or self.platform == 'windows':
print('\nWARNING: binary not found, skipping', binary)
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index d176765b33..b1114deb05 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -5141,11 +5141,14 @@
},
{
"deps": [
+ "census",
"gpr",
"grpc++_base",
"grpc++_codegen_base",
"grpc++_codegen_base_src",
- "grpc_cronet"
+ "grpc_cronet",
+ "grpc_transport_chttp2_client_insecure",
+ "grpc_transport_chttp2_server_insecure"
],
"headers": [],
"is_filegroup": false,
@@ -7216,9 +7219,9 @@
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/transport/auth_filters.h",
- "src/core/lib/security/transport/handshake.h",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/security_connector.h",
+ "src/core/lib/security/transport/security_handshaker.h",
"src/core/lib/security/transport/tsi_error.h",
"src/core/lib/security/util/b64.h",
"src/core/lib/security/util/json_util.h"
@@ -7257,12 +7260,12 @@
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/transport/auth_filters.h",
"src/core/lib/security/transport/client_auth_filter.c",
- "src/core/lib/security/transport/handshake.c",
- "src/core/lib/security/transport/handshake.h",
"src/core/lib/security/transport/secure_endpoint.c",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/security_connector.c",
"src/core/lib/security/transport/security_connector.h",
+ "src/core/lib/security/transport/security_handshaker.c",
+ "src/core/lib/security/transport/security_handshaker.h",
"src/core/lib/security/transport/server_auth_filter.c",
"src/core/lib/security/transport/tsi_error.c",
"src/core/lib/security/transport/tsi_error.h",
@@ -7429,9 +7432,29 @@
"deps": [
"gpr",
"grpc_base",
- "grpc_client_channel",
"grpc_transport_chttp2"
],
+ "headers": [
+ "src/core/ext/transport/chttp2/client/chttp2_connector.h"
+ ],
+ "is_filegroup": true,
+ "language": "c",
+ "name": "grpc_transport_chttp2_client_connector",
+ "src": [
+ "src/core/ext/transport/chttp2/client/chttp2_connector.c",
+ "src/core/ext/transport/chttp2/client/chttp2_connector.h"
+ ],
+ "third_party": false,
+ "type": "filegroup"
+ },
+ {
+ "deps": [
+ "gpr",
+ "grpc_base",
+ "grpc_client_channel",
+ "grpc_transport_chttp2",
+ "grpc_transport_chttp2_client_connector"
+ ],
"headers": [],
"is_filegroup": true,
"language": "c",
@@ -7449,7 +7472,8 @@
"grpc_base",
"grpc_client_channel",
"grpc_secure",
- "grpc_transport_chttp2"
+ "grpc_transport_chttp2",
+ "grpc_transport_chttp2_client_connector"
],
"headers": [],
"is_filegroup": true,
@@ -7467,6 +7491,26 @@
"grpc_base",
"grpc_transport_chttp2"
],
+ "headers": [
+ "src/core/ext/transport/chttp2/server/chttp2_server.h"
+ ],
+ "is_filegroup": true,
+ "language": "c",
+ "name": "grpc_transport_chttp2_server",
+ "src": [
+ "src/core/ext/transport/chttp2/server/chttp2_server.c",
+ "src/core/ext/transport/chttp2/server/chttp2_server.h"
+ ],
+ "third_party": false,
+ "type": "filegroup"
+ },
+ {
+ "deps": [
+ "gpr",
+ "grpc_base",
+ "grpc_transport_chttp2",
+ "grpc_transport_chttp2_server"
+ ],
"headers": [],
"is_filegroup": true,
"language": "c",
@@ -7483,7 +7527,8 @@
"gpr",
"grpc_base",
"grpc_secure",
- "grpc_transport_chttp2"
+ "grpc_transport_chttp2",
+ "grpc_transport_chttp2_server"
],
"headers": [],
"is_filegroup": true,
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 7df7b18e3a..c4bfd0a9a7 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -36756,7 +36756,7 @@
{
"args": [
"--scenarios_json",
- "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
],
"boringssl": true,
"ci_platforms": [
@@ -36764,7 +36764,9 @@
],
"cpu_cost": 2,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -36777,15 +36779,17 @@
{
"args": [
"--scenarios_json",
- "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
],
"boringssl": true,
"ci_platforms": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -36798,15 +36802,17 @@
{
"args": [
"--scenarios_json",
- "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
],
"boringssl": true,
"ci_platforms": [
"linux"
],
- "cpu_cost": 1,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -36819,15 +36825,17 @@
{
"args": [
"--scenarios_json",
- "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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\": \"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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -36840,15 +36848,17 @@
{
"args": [
"--scenarios_json",
- "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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\": \"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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -36861,7 +36871,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, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"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": [
@@ -36869,7 +36879,9 @@
],
"cpu_cost": 2,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -36882,15 +36894,17 @@
{
"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, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 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}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": 1024,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -36903,15 +36917,17 @@
{
"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, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 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}}, \"num_clients\": 0}]}"
+ "{\"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, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": 1024,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -36924,7 +36940,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, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"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": [
@@ -36932,7 +36948,9 @@
],
"cpu_cost": 2,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -36945,15 +36963,17 @@
{
"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, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -36966,15 +36986,17 @@
{
"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, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"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, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -36987,7 +37009,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, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"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": [
@@ -36995,7 +37017,9 @@
],
"cpu_cost": 2,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37008,15 +37032,17 @@
{
"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, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 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}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": 1024,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37029,15 +37055,17 @@
{
"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, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 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}}, \"num_clients\": 0}]}"
+ "{\"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, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": 1024,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37050,7 +37078,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, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"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": [
@@ -37058,7 +37086,9 @@
],
"cpu_cost": 2,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37071,15 +37101,17 @@
{
"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, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37092,15 +37124,17 @@
{
"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, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"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, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37113,7 +37147,7 @@
{
"args": [
"--scenarios_json",
- "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
],
"boringssl": true,
"ci_platforms": [
@@ -37121,7 +37155,9 @@
],
"cpu_cost": 2,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37134,15 +37170,17 @@
{
"args": [
"--scenarios_json",
- "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
],
"boringssl": true,
"ci_platforms": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37155,15 +37193,17 @@
{
"args": [
"--scenarios_json",
- "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
],
"boringssl": true,
"ci_platforms": [
"linux"
],
- "cpu_cost": 1,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37176,15 +37216,17 @@
{
"args": [
"--scenarios_json",
- "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37197,15 +37239,17 @@
{
"args": [
"--scenarios_json",
- "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37218,7 +37262,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, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 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": [
@@ -37226,7 +37270,9 @@
],
"cpu_cost": 2,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37239,15 +37285,17 @@
{
"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, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 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}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": 1024,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37260,15 +37308,17 @@
{
"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, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 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}}, \"num_clients\": 0}]}"
+ "{\"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, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": 1024,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37281,7 +37331,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, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 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": [
@@ -37289,7 +37339,9 @@
],
"cpu_cost": 2,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37302,15 +37354,17 @@
{
"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, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37323,15 +37377,17 @@
{
"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, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"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, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37344,7 +37400,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, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 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": [
@@ -37352,7 +37408,9 @@
],
"cpu_cost": 2,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37365,15 +37423,17 @@
{
"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, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 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}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": 1024,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37386,15 +37446,17 @@
{
"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, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 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}}, \"num_clients\": 0}]}"
+ "{\"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, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": 1024,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37407,7 +37469,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, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 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": [
@@ -37415,7 +37477,9 @@
],
"cpu_cost": 2,
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37428,15 +37492,17 @@
{
"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, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
@@ -37449,15 +37515,1309 @@
{
"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, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+ "{\"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, \"core_limit\": 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": [
"linux"
],
- "cpu_cost": 8,
+ "cpu_cost": "capacity",
"defaults": "boringssl",
- "exclude_configs": [],
+ "exclude_configs": [
+ "tsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure_500kib_resource_quota",
+ "timeout_seconds": 360
+ },
+ {
+ "args": [
+ "--scenarios_json",
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+ ],
+ "boringssl": true,
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 2,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "args": [
+ "--scenarios_json",
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+ ],
+ "boringssl": true,
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "args": [
+ "--scenarios_json",
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+ ],
+ "boringssl": true,
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "args": [
+ "--scenarios_json",
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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\": \"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": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "args": [
+ "--scenarios_json",
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 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\": \"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": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 2,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 64,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 64,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_500kib_resource_quota",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 2,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_500kib_resource_quota",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 2,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 64,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 64,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_secure_500kib_resource_quota",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 2,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_secure_500kib_resource_quota",
+ "timeout_seconds": 360
+ },
+ {
+ "args": [
+ "--scenarios_json",
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+ ],
+ "boringssl": true,
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 2,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_generic_async_streaming_ping_pong_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "args": [
+ "--scenarios_json",
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+ ],
+ "boringssl": true,
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "args": [
+ "--scenarios_json",
+ "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+ ],
+ "boringssl": true,
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "args": [
+ "--scenarios_json",
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_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\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+ ],
+ "boringssl": true,
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "args": [
+ "--scenarios_json",
+ "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_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\": 10, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
+ ],
+ "boringssl": true,
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 2,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 64,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 64,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_500kib_resource_quota",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 2,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_unary_ping_pong_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_500kib_resource_quota",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 2,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 64,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 64,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_insecure_500kib_resource_quota",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": 2,
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_streaming_ping_pong_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
+ "flaky": false,
+ "language": "c++",
+ "name": "json_run_localhost",
+ "platforms": [
+ "linux"
+ ],
+ "shortname": "json_run_localhost:cpp_protobuf_async_streaming_qps_unconstrained_insecure",
+ "timeout_seconds": 360
+ },
+ {
+ "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, \"core_limit\": 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": [
+ "linux"
+ ],
+ "cpu_cost": "capacity",
+ "defaults": "boringssl",
+ "exclude_configs": [
+ "asan",
+ "asan-noleaks",
+ "asan-trace-cmp",
+ "basicprof",
+ "dbg",
+ "easan",
+ "edbg",
+ "etsan",
+ "gcov",
+ "helgrind",
+ "memcheck",
+ "msan",
+ "mutrace",
+ "opt",
+ "stapprof",
+ "ubsan"
+ ],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 81b43f7a87..558b5b0c66 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -428,9 +428,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\credentials\plugin\plugin_credentials.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\credentials\ssl\ssl_credentials.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\auth_filters.h" />
- <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\handshake.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\secure_endpoint.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\security_connector.h" />
+ <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\security_handshaker.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\util\b64.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\util\json_util.h" />
@@ -439,6 +439,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\ssl_types.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\transport_security.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\transport_security_interface.h" />
+ <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_factory.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\connector.h" />
@@ -454,6 +455,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\subchannel_index.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.h" />
+ <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.h" />
@@ -780,12 +782,12 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\client_auth_filter.c">
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\handshake.c">
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\secure_endpoint.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\security_connector.c">
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\security_handshaker.c">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\server_auth_filter.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.c">
@@ -802,6 +804,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\tsi\transport_security.c">
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.c">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\secure\secure_channel_create.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\channel_connectivity.c">
@@ -840,6 +844,8 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.c">
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.c">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\insecure\server_chttp2.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\insecure\server_chttp2_posix.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 2f4a659aaa..a40a1b5f1c 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -457,15 +457,15 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\client_auth_filter.c">
<Filter>src\core\lib\security\transport</Filter>
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\handshake.c">
- <Filter>src\core\lib\security\transport</Filter>
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\secure_endpoint.c">
<Filter>src\core\lib\security\transport</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\security_connector.c">
<Filter>src\core\lib\security\transport</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\security_handshaker.c">
+ <Filter>src\core\lib\security\transport</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\lib\security\transport\server_auth_filter.c">
<Filter>src\core\lib\security\transport</Filter>
</ClCompile>
@@ -490,6 +490,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\lib\tsi\transport_security.c">
<Filter>src\core\lib\tsi</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.c">
+ <Filter>src\core\ext\transport\chttp2\server</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\secure\secure_channel_create.c">
<Filter>src\core\ext\transport\chttp2\client\secure</Filter>
</ClCompile>
@@ -547,6 +550,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.c">
<Filter>src\core\ext\client_channel</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.c">
+ <Filter>src\core\ext\transport\chttp2\client</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\insecure\server_chttp2.c">
<Filter>src\core\ext\transport\chttp2\server\insecure</Filter>
</ClCompile>
@@ -1121,15 +1127,15 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\auth_filters.h">
<Filter>src\core\lib\security\transport</Filter>
</ClInclude>
- <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\handshake.h">
- <Filter>src\core\lib\security\transport</Filter>
- </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\secure_endpoint.h">
<Filter>src\core\lib\security\transport</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\security_connector.h">
<Filter>src\core\lib\security\transport</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\security_handshaker.h">
+ <Filter>src\core\lib\security\transport</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\lib\security\transport\tsi_error.h">
<Filter>src\core\lib\security\transport</Filter>
</ClInclude>
@@ -1154,6 +1160,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\lib\tsi\transport_security_interface.h">
<Filter>src\core\lib\tsi</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.h">
+ <Filter>src\core\ext\transport\chttp2\server</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.h">
<Filter>src\core\ext\client_channel</Filter>
</ClInclude>
@@ -1199,6 +1208,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\uri_parser.h">
<Filter>src\core\ext\client_channel</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.h">
+ <Filter>src\core\ext\transport\chttp2\client</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\grpclb.h">
<Filter>src\core\ext\lb_policy\grpclb</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index c96d48db58..661192101c 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -405,6 +405,8 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\stream_map.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\varint.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.h" />
+ <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.h" />
+ <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel_factory.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\connector.h" />
@@ -718,10 +720,14 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.c">
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.c">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create_posix.c">
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.c">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\channel_connectivity.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 4b75288b2b..466116e604 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -415,12 +415,18 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.c">
<Filter>src\core\ext\transport\chttp2\alpn</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.c">
+ <Filter>src\core\ext\transport\chttp2\server</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create.c">
<Filter>src\core\ext\transport\chttp2\client\insecure</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create_posix.c">
<Filter>src\core\ext\transport\chttp2\client\insecure</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.c">
+ <Filter>src\core\ext\transport\chttp2\client</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_channel\channel_connectivity.c">
<Filter>src\core\ext\client_channel</Filter>
</ClCompile>
@@ -995,6 +1001,12 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\alpn\alpn.h">
<Filter>src\core\ext\transport\chttp2\alpn</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\chttp2_server.h">
+ <Filter>src\core\ext\transport\chttp2\server</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\chttp2_connector.h">
+ <Filter>src\core\ext\transport\chttp2\client</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_channel\client_channel.h">
<Filter>src\core\ext\client_channel</Filter>
</ClInclude>