diff options
author | Yash Tibrewal <yashkt@google.com> | 2018-10-25 19:50:10 -0700 |
---|---|---|
committer | Yash Tibrewal <yashkt@google.com> | 2018-10-25 19:50:10 -0700 |
commit | 3896dabb85bd4f7314fbe9f850c4af4294157019 (patch) | |
tree | 73155467b35d4b969b2360656cbc718ca3d79e2d | |
parent | a094b7b3127ffcb607e11486a64fc905e92a2565 (diff) | |
parent | 111f47437638ce0c00144199b08272b35a99acd7 (diff) |
Merge branch 'master' into interceptors
161 files changed, 7314 insertions, 3376 deletions
diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000000..bc31c54e94 --- /dev/null +++ b/.bazelrc @@ -0,0 +1,3 @@ +# load bazelrc from the legacy location +# as recommended in https://github.com/bazelbuild/bazel/issues/6319 +import %workspace%/tools/bazel.rc diff --git a/.clang_complete b/.clang_complete index aa77554f4e..1448b01342 100644 --- a/.clang_complete +++ b/.clang_complete @@ -14,4 +14,5 @@ -Ithird_party/cares -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googlemock/include +-Ithird_party/nanopb @@ -131,7 +131,6 @@ GRPCXX_SRCS = [ "src/cpp/server/create_default_thread_pool.cc", "src/cpp/server/dynamic_thread_pool.cc", "src/cpp/server/health/default_health_check_service.cc", - "src/cpp/server/health/health.pb.c", "src/cpp/server/health/health_check_service.cc", "src/cpp/server/health/health_check_service_server_builder_option.cc", "src/cpp/server/server_builder.cc", @@ -151,7 +150,6 @@ GRPCXX_HDRS = [ "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/health/default_health_check_service.h", - "src/cpp/server/health/health.pb.h", "src/cpp/server/thread_pool_interface.h", "src/cpp/thread_manager/thread_manager.h", ] @@ -1040,6 +1038,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/client_channel_factory.cc", "src/core/ext/filters/client_channel/client_channel_plugin.cc", "src/core/ext/filters/client_channel/connector.cc", + "src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_proxy.cc", "src/core/ext/filters/client_channel/lb_policy.cc", @@ -1062,6 +1061,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/client_channel_channelz.h", "src/core/ext/filters/client_channel/client_channel_factory.h", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", @@ -1089,6 +1089,7 @@ grpc_cc_library( "orphanable", "ref_counted", "ref_counted_ptr", + "health_proto", ], ) @@ -1201,6 +1202,20 @@ grpc_cc_library( ) grpc_cc_library( + name = "health_proto", + srcs = [ + "src/core/ext/filters/client_channel/health/health.pb.c", + ], + hdrs = [ + "src/core/ext/filters/client_channel/health/health.pb.h", + ], + external_deps = [ + "nanopb", + ], + language = "c++", +) + +grpc_cc_library( name = "grpclb_proto", srcs = [ "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", @@ -1566,11 +1581,14 @@ grpc_cc_library( "src/core/lib/security/credentials/oauth2/oauth2_credentials.cc", "src/core/lib/security/credentials/plugin/plugin_credentials.cc", "src/core/lib/security/credentials/ssl/ssl_credentials.cc", - "src/core/lib/security/security_connector/alts_security_connector.cc", + "src/core/lib/security/security_connector/alts/alts_security_connector.cc", + "src/core/lib/security/security_connector/fake/fake_security_connector.cc", "src/core/lib/security/security_connector/load_system_roots_fallback.cc", "src/core/lib/security/security_connector/load_system_roots_linux.cc", - "src/core/lib/security/security_connector/local_security_connector.cc", + "src/core/lib/security/security_connector/local/local_security_connector.cc", "src/core/lib/security/security_connector/security_connector.cc", + "src/core/lib/security/security_connector/ssl_utils.cc", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.cc", "src/core/lib/security/transport/client_auth_filter.cc", "src/core/lib/security/transport/secure_endpoint.cc", "src/core/lib/security/transport/security_handshaker.cc", @@ -1597,11 +1615,14 @@ grpc_cc_library( "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/security_connector/alts_security_connector.h", + "src/core/lib/security/security_connector/alts/alts_security_connector.h", + "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", "src/core/lib/security/security_connector/load_system_roots_linux.h", - "src/core/lib/security/security_connector/local_security_connector.h", + "src/core/lib/security/security_connector/local/local_security_connector.h", "src/core/lib/security/security_connector/security_connector.h", + "src/core/lib/security/security_connector/ssl_utils.h", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", "src/core/lib/security/transport/auth_filters.h", "src/core/lib/security/transport/secure_endpoint.h", "src/core/lib/security/transport/security_handshaker.h", @@ -1987,6 +2008,7 @@ grpc_cc_library( deps = [ "grpc", "grpc++_codegen_base", + "health_proto", ], ) @@ -1999,6 +2021,7 @@ grpc_cc_library( deps = [ "grpc++_codegen_base", "grpc_unsecure", + "health_proto", ], ) @@ -2205,7 +2228,6 @@ grpc_cc_library( grpc_cc_library( name = "grpc_opencensus_plugin", srcs = [ - "src/core/ext/filters/census/grpc_context.cc", "src/cpp/ext/filters/census/channel_filter.cc", "src/cpp/ext/filters/census/client_filter.cc", "src/cpp/ext/filters/census/context.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index cd7ca1fd01..faa1e7d1d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -488,7 +488,6 @@ add_dependencies(buildtests_c h2_sockpair_1byte_nosec_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c h2_uds_nosec_test) endif() -add_dependencies(buildtests_c inproc_nosec_test) add_dependencies(buildtests_c alts_credentials_fuzzer_one_entry) add_dependencies(buildtests_c api_fuzzer_one_entry) add_dependencies(buildtests_c client_fuzzer_one_entry) @@ -1171,11 +1170,14 @@ add_library(grpc src/core/lib/security/credentials/oauth2/oauth2_credentials.cc src/core/lib/security/credentials/plugin/plugin_credentials.cc src/core/lib/security/credentials/ssl/ssl_credentials.cc - src/core/lib/security/security_connector/alts_security_connector.cc + src/core/lib/security/security_connector/alts/alts_security_connector.cc + src/core/lib/security/security_connector/fake/fake_security_connector.cc src/core/lib/security/security_connector/load_system_roots_fallback.cc src/core/lib/security/security_connector/load_system_roots_linux.cc - src/core/lib/security/security_connector/local_security_connector.cc + src/core/lib/security/security_connector/local/local_security_connector.cc src/core/lib/security/security_connector/security_connector.cc + src/core/lib/security/security_connector/ssl/ssl_security_connector.cc + src/core/lib/security/security_connector/ssl_utils.cc src/core/lib/security/transport/client_auth_filter.cc src/core/lib/security/transport/secure_endpoint.cc src/core/lib/security/transport/security_handshaker.cc @@ -1230,6 +1232,7 @@ add_library(grpc src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -1246,6 +1249,7 @@ add_library(grpc src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/client_channel/uri_parser.cc src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/client_channel/health/health.pb.c src/core/tsi/alts_transport_security.cc src/core/tsi/fake_transport_security.cc src/core/tsi/local_transport_security.cc @@ -1580,6 +1584,7 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -1596,6 +1601,10 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/client_channel/uri_parser.cc src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/core/lib/http/httpcli_security_connector.cc src/core/lib/security/context/security_context.cc src/core/lib/security/credentials/alts/alts_credentials.cc @@ -1613,11 +1622,14 @@ add_library(grpc_cronet src/core/lib/security/credentials/oauth2/oauth2_credentials.cc src/core/lib/security/credentials/plugin/plugin_credentials.cc src/core/lib/security/credentials/ssl/ssl_credentials.cc - src/core/lib/security/security_connector/alts_security_connector.cc + src/core/lib/security/security_connector/alts/alts_security_connector.cc + src/core/lib/security/security_connector/fake/fake_security_connector.cc src/core/lib/security/security_connector/load_system_roots_fallback.cc src/core/lib/security/security_connector/load_system_roots_linux.cc - src/core/lib/security/security_connector/local_security_connector.cc + src/core/lib/security/security_connector/local/local_security_connector.cc src/core/lib/security/security_connector/security_connector.cc + src/core/lib/security/security_connector/ssl/ssl_security_connector.cc + src/core/lib/security/security_connector/ssl_utils.cc src/core/lib/security/transport/client_auth_filter.cc src/core/lib/security/transport/secure_endpoint.cc src/core/lib/security/transport/security_handshaker.cc @@ -1657,9 +1669,6 @@ add_library(grpc_cronet src/core/tsi/alts/handshaker/altscontext.pb.c src/core/tsi/alts/handshaker/handshaker.pb.c src/core/tsi/alts/handshaker/transport_security_common.pb.c - third_party/nanopb/pb_common.c - third_party/nanopb/pb_decode.c - third_party/nanopb/pb_encode.c src/core/tsi/transport_security.cc src/core/ext/transport/chttp2/client/insecure/channel_create.cc src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc @@ -1947,6 +1956,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -1963,6 +1973,10 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/client_channel/uri_parser.cc src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/core/ext/transport/chttp2/transport/bin_decoder.cc src/core/ext/transport/chttp2/transport/bin_encoder.cc src/core/ext/transport/chttp2/transport/chttp2_plugin.cc @@ -2261,6 +2275,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -2277,6 +2292,10 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/client_channel/uri_parser.cc src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/core/ext/transport/chttp2/transport/bin_decoder.cc src/core/ext/transport/chttp2/transport/bin_encoder.cc src/core/ext/transport/chttp2/transport/chttp2_plugin.cc @@ -2588,6 +2607,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -2604,6 +2624,10 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/client_channel/uri_parser.cc src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/core/ext/transport/inproc/inproc_plugin.cc src/core/ext/transport/inproc/inproc_transport.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -2622,9 +2646,6 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc - third_party/nanopb/pb_common.c - third_party/nanopb/pb_decode.c - third_party/nanopb/pb_encode.c src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c @@ -2858,7 +2879,6 @@ add_library(grpc++ src/cpp/server/create_default_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc src/cpp/server/health/default_health_check_service.cc - src/cpp/server/health/health.pb.c src/cpp/server/health/health_check_service.cc src/cpp/server/health/health_check_service_server_builder_option.cc src/cpp/server/server_builder.cc @@ -2871,6 +2891,10 @@ add_library(grpc++ src/cpp/util/status.cc src/cpp/util/string_ref.cc src/cpp/util/time_cc.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/cpp/codegen/call_wrapper.cc src/cpp/codegen/codegen_init.cc ) @@ -3223,7 +3247,6 @@ add_library(grpc++_cronet src/cpp/server/create_default_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc src/cpp/server/health/default_health_check_service.cc - src/cpp/server/health/health.pb.c src/cpp/server/health/health_check_service.cc src/cpp/server/health/health_check_service_server_builder_option.cc src/cpp/server/server_builder.cc @@ -3236,6 +3259,10 @@ add_library(grpc++_cronet src/cpp/util/status.cc src/cpp/util/string_ref.cc src/cpp/util/time_cc.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/cpp/codegen/call_wrapper.cc src/cpp/codegen/codegen_init.cc src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -3427,6 +3454,7 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -4358,7 +4386,6 @@ add_library(grpc++_unsecure src/cpp/server/create_default_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc src/cpp/server/health/default_health_check_service.cc - src/cpp/server/health/health.pb.c src/cpp/server/health/health_check_service.cc src/cpp/server/health/health_check_service_server_builder_option.cc src/cpp/server/server_builder.cc @@ -4371,6 +4398,10 @@ add_library(grpc++_unsecure src/cpp/util/status.cc src/cpp/util/string_ref.cc src/cpp/util/time_cc.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/cpp/codegen/call_wrapper.cc src/cpp/codegen/codegen_init.cc ) @@ -17661,42 +17692,6 @@ endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) -add_executable(inproc_nosec_test - test/core/end2end/fixtures/inproc.cc -) - - -target_include_directories(inproc_nosec_test - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} -) - -target_link_libraries(inproc_nosec_test - ${_gRPC_ALLTARGETS_LIBRARIES} - end2end_nosec_tests - grpc_test_util_unsecure - grpc_unsecure - gpr_test_util - gpr -) - - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(inproc_nosec_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(inproc_nosec_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() - -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - add_executable(resolver_component_test_unsecure test/cpp/naming/resolver_component_test.cc third_party/googletest/googletest/src/gtest-all.cc @@ -1344,7 +1344,6 @@ h2_sockpair_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test h2_sockpair+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test h2_sockpair_1byte_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test h2_uds_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds_nosec_test -inproc_nosec_test: $(BINDIR)/$(CONFIG)/inproc_nosec_test resolver_component_test_unsecure: $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure resolver_component_test: $(BINDIR)/$(CONFIG)/resolver_component_test resolver_component_tests_runner_invoker_unsecure: $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure @@ -1603,7 +1602,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test \ $(BINDIR)/$(CONFIG)/h2_uds_nosec_test \ - $(BINDIR)/$(CONFIG)/inproc_nosec_test \ $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry \ $(BINDIR)/$(CONFIG)/api_fuzzer_one_entry \ $(BINDIR)/$(CONFIG)/client_fuzzer_one_entry \ @@ -3643,11 +3641,14 @@ LIBGRPC_SRC = \ src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ - src/core/lib/security/security_connector/alts_security_connector.cc \ + src/core/lib/security/security_connector/alts/alts_security_connector.cc \ + src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ src/core/lib/security/security_connector/load_system_roots_linux.cc \ - src/core/lib/security/security_connector/local_security_connector.cc \ + src/core/lib/security/security_connector/local/local_security_connector.cc \ src/core/lib/security/security_connector/security_connector.cc \ + src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ + src/core/lib/security/security_connector/ssl_utils.cc \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ src/core/lib/security/transport/security_handshaker.cc \ @@ -3702,6 +3703,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -3718,6 +3720,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/alts_transport_security.cc \ src/core/tsi/fake_transport_security.cc \ src/core/tsi/local_transport_security.cc \ @@ -4046,6 +4049,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4062,6 +4066,10 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/core/lib/http/httpcli_security_connector.cc \ src/core/lib/security/context/security_context.cc \ src/core/lib/security/credentials/alts/alts_credentials.cc \ @@ -4079,11 +4087,14 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ - src/core/lib/security/security_connector/alts_security_connector.cc \ + src/core/lib/security/security_connector/alts/alts_security_connector.cc \ + src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ src/core/lib/security/security_connector/load_system_roots_linux.cc \ - src/core/lib/security/security_connector/local_security_connector.cc \ + src/core/lib/security/security_connector/local/local_security_connector.cc \ src/core/lib/security/security_connector/security_connector.cc \ + src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ + src/core/lib/security/security_connector/ssl_utils.cc \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ src/core/lib/security/transport/security_handshaker.cc \ @@ -4123,9 +4134,6 @@ LIBGRPC_CRONET_SRC = \ src/core/tsi/alts/handshaker/altscontext.pb.c \ src/core/tsi/alts/handshaker/handshaker.pb.c \ src/core/tsi/alts/handshaker/transport_security_common.pb.c \ - third_party/nanopb/pb_common.c \ - third_party/nanopb/pb_decode.c \ - third_party/nanopb/pb_encode.c \ src/core/tsi/transport_security.cc \ src/core/ext/transport/chttp2/client/insecure/channel_create.cc \ src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \ @@ -4406,6 +4414,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4422,6 +4431,10 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/core/ext/transport/chttp2/transport/bin_decoder.cc \ src/core/ext/transport/chttp2/transport/bin_encoder.cc \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ @@ -4706,6 +4719,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4722,6 +4736,10 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/core/ext/transport/chttp2/transport/bin_decoder.cc \ src/core/ext/transport/chttp2/transport/bin_encoder.cc \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ @@ -5006,6 +5024,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -5022,6 +5041,10 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/core/ext/transport/inproc/inproc_plugin.cc \ src/core/ext/transport/inproc/inproc_transport.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \ @@ -5040,9 +5063,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \ - third_party/nanopb/pb_common.c \ - third_party/nanopb/pb_decode.c \ - third_party/nanopb/pb_encode.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \ @@ -5241,7 +5261,6 @@ LIBGRPC++_SRC = \ src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/health/default_health_check_service.cc \ - src/cpp/server/health/health.pb.c \ src/cpp/server/health/health_check_service.cc \ src/cpp/server/health/health_check_service_server_builder_option.cc \ src/cpp/server/server_builder.cc \ @@ -5254,6 +5273,10 @@ LIBGRPC++_SRC = \ src/cpp/util/status.cc \ src/cpp/util/string_ref.cc \ src/cpp/util/time_cc.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/cpp/codegen/call_wrapper.cc \ src/cpp/codegen/codegen_init.cc \ @@ -5616,7 +5639,6 @@ LIBGRPC++_CRONET_SRC = \ src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/health/default_health_check_service.cc \ - src/cpp/server/health/health.pb.c \ src/cpp/server/health/health_check_service.cc \ src/cpp/server/health/health_check_service_server_builder_option.cc \ src/cpp/server/server_builder.cc \ @@ -5629,6 +5651,10 @@ LIBGRPC++_CRONET_SRC = \ src/cpp/util/status.cc \ src/cpp/util/string_ref.cc \ src/cpp/util/time_cc.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/cpp/codegen/call_wrapper.cc \ src/cpp/codegen/codegen_init.cc \ src/core/ext/transport/chttp2/client/insecure/channel_create.cc \ @@ -5820,6 +5846,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -6718,7 +6745,6 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/health/default_health_check_service.cc \ - src/cpp/server/health/health.pb.c \ src/cpp/server/health/health_check_service.cc \ src/cpp/server/health/health_check_service_server_builder_option.cc \ src/cpp/server/server_builder.cc \ @@ -6731,6 +6757,10 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/util/status.cc \ src/cpp/util/string_ref.cc \ src/cpp/util/time_cc.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/cpp/codegen/call_wrapper.cc \ src/cpp/codegen/codegen_init.cc \ @@ -24066,26 +24096,6 @@ ifneq ($(NO_DEPS),true) endif -INPROC_NOSEC_TEST_SRC = \ - test/core/end2end/fixtures/inproc.cc \ - -INPROC_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INPROC_NOSEC_TEST_SRC)))) - - -$(BINDIR)/$(CONFIG)/inproc_nosec_test: $(INPROC_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INPROC_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/inproc_nosec_test - -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/inproc.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_inproc_nosec_test: $(INPROC_NOSEC_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(INPROC_NOSEC_TEST_OBJS:.o=.dep) -endif - - RESOLVER_COMPONENT_TEST_UNSECURE_SRC = \ test/cpp/naming/resolver_component_test.cc \ @@ -24916,11 +24926,14 @@ src/core/lib/security/credentials/local/local_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/oauth2/oauth2_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/plugin/plugin_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/ssl/ssl_credentials.cc: $(OPENSSL_DEP) -src/core/lib/security/security_connector/alts_security_connector.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/alts/alts_security_connector.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/fake/fake_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/load_system_roots_fallback.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/load_system_roots_linux.cc: $(OPENSSL_DEP) -src/core/lib/security/security_connector/local_security_connector.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/local/local_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/security_connector.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/ssl/ssl_security_connector.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/ssl_utils.cc: $(OPENSSL_DEP) src/core/lib/security/transport/client_auth_filter.cc: $(OPENSSL_DEP) src/core/lib/security/transport/secure_endpoint.cc: $(OPENSSL_DEP) src/core/lib/security/transport/security_handshaker.cc: $(OPENSSL_DEP) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 4096720569..03bed3593d 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -169,12 +169,12 @@ def grpc_deps(): if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): native.http_archive( name = "com_github_bazelbuild_bazeltoolchains", - strip_prefix = "bazel-toolchains-cdea5b8675914d0a354d89f108de5d28e54e0edc", + strip_prefix = "bazel-toolchains-280edaa6f93623074513d2b426068de42e62ea4d", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/cdea5b8675914d0a354d89f108de5d28e54e0edc.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/cdea5b8675914d0a354d89f108de5d28e54e0edc.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/280edaa6f93623074513d2b426068de42e62ea4d.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/280edaa6f93623074513d2b426068de42e62ea4d.tar.gz", ], - sha256 = "cefb6ccf86ca592baaa029bcef04148593c0efe8f734542f10293ea58f170715", + sha256 = "50c9df51f80cdf9ff8f2bc27620c155526b9ba67be95e8a686f32ff8898a06e2", ) if "io_opencensus_cpp" not in native.existing_rules(): diff --git a/build.yaml b/build.yaml index 1ebc996f9f..5480b83cc3 100644 --- a/build.yaml +++ b/build.yaml @@ -572,6 +572,7 @@ filegroups: - src/core/ext/filters/client_channel/client_channel_channelz.h - src/core/ext/filters/client_channel/client_channel_factory.h - src/core/ext/filters/client_channel/connector.h + - src/core/ext/filters/client_channel/health/health_check_client.h - src/core/ext/filters/client_channel/http_connect_handshaker.h - src/core/ext/filters/client_channel/http_proxy.h - src/core/ext/filters/client_channel/lb_policy.h @@ -596,6 +597,7 @@ filegroups: - src/core/ext/filters/client_channel/client_channel_factory.cc - src/core/ext/filters/client_channel/client_channel_plugin.cc - src/core/ext/filters/client_channel/connector.cc + - src/core/ext/filters/client_channel/health/health_check_client.cc - src/core/ext/filters/client_channel/http_connect_handshaker.cc - src/core/ext/filters/client_channel/http_proxy.cc - src/core/ext/filters/client_channel/lb_policy.cc @@ -615,6 +617,7 @@ filegroups: uses: - grpc_base - grpc_deadline_filter + - health_proto - name: grpc_codegen public_headers: - include/grpc/impl/codegen/byte_buffer.h @@ -824,11 +827,14 @@ filegroups: - 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/security_connector/alts_security_connector.h + - src/core/lib/security/security_connector/alts/alts_security_connector.h + - src/core/lib/security/security_connector/fake/fake_security_connector.h - src/core/lib/security/security_connector/load_system_roots.h - src/core/lib/security/security_connector/load_system_roots_linux.h - - src/core/lib/security/security_connector/local_security_connector.h + - src/core/lib/security/security_connector/local/local_security_connector.h - src/core/lib/security/security_connector/security_connector.h + - src/core/lib/security/security_connector/ssl/ssl_security_connector.h + - src/core/lib/security/security_connector/ssl_utils.h - src/core/lib/security/transport/auth_filters.h - src/core/lib/security/transport/secure_endpoint.h - src/core/lib/security/transport/security_handshaker.h @@ -853,11 +859,14 @@ filegroups: - src/core/lib/security/credentials/oauth2/oauth2_credentials.cc - src/core/lib/security/credentials/plugin/plugin_credentials.cc - src/core/lib/security/credentials/ssl/ssl_credentials.cc - - src/core/lib/security/security_connector/alts_security_connector.cc + - src/core/lib/security/security_connector/alts/alts_security_connector.cc + - src/core/lib/security/security_connector/fake/fake_security_connector.cc - src/core/lib/security/security_connector/load_system_roots_fallback.cc - src/core/lib/security/security_connector/load_system_roots_linux.cc - - src/core/lib/security/security_connector/local_security_connector.cc + - src/core/lib/security/security_connector/local/local_security_connector.cc - src/core/lib/security/security_connector/security_connector.cc + - src/core/lib/security/security_connector/ssl/ssl_security_connector.cc + - src/core/lib/security/security_connector/ssl_utils.cc - src/core/lib/security/transport/client_auth_filter.cc - src/core/lib/security/transport/secure_endpoint.cc - src/core/lib/security/transport/security_handshaker.cc @@ -1107,6 +1116,13 @@ filegroups: - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c uses: - nanopb +- name: health_proto + headers: + - src/core/ext/filters/client_channel/health/health.pb.h + src: + - src/core/ext/filters/client_channel/health/health.pb.c + uses: + - nanopb - name: nanopb src: - third_party/nanopb/pb_common.c @@ -1358,7 +1374,6 @@ filegroups: - src/cpp/common/channel_filter.h - src/cpp/server/dynamic_thread_pool.h - src/cpp/server/health/default_health_check_service.h - - src/cpp/server/health/health.pb.h - src/cpp/server/thread_pool_interface.h - src/cpp/thread_manager/thread_manager.h src: @@ -1382,7 +1397,6 @@ filegroups: - src/cpp/server/create_default_thread_pool.cc - src/cpp/server/dynamic_thread_pool.cc - src/cpp/server/health/default_health_check_service.cc - - src/cpp/server/health/health.pb.c - src/cpp/server/health/health_check_service.cc - src/cpp/server/health/health_check_service_server_builder_option.cc - src/cpp/server/server_builder.cc @@ -1401,6 +1415,7 @@ filegroups: - grpc_transport_inproc_headers - grpc++_codegen_base - nanopb_headers + - health_proto - name: grpc++_config_proto language: c++ public_headers: @@ -280,11 +280,14 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ - src/core/lib/security/security_connector/alts_security_connector.cc \ + src/core/lib/security/security_connector/alts/alts_security_connector.cc \ + src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ src/core/lib/security/security_connector/load_system_roots_linux.cc \ - src/core/lib/security/security_connector/local_security_connector.cc \ + src/core/lib/security/security_connector/local/local_security_connector.cc \ src/core/lib/security/security_connector/security_connector.cc \ + src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ + src/core/lib/security/security_connector/ssl_utils.cc \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ src/core/lib/security/transport/security_handshaker.cc \ @@ -339,6 +342,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -355,6 +359,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/alts_transport_security.cc \ src/core/tsi/fake_transport_security.cc \ src/core/tsi/local_transport_security.cc \ @@ -667,6 +672,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/census) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/health) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf) @@ -718,6 +724,10 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/plugin) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/ssl) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/alts) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/fake) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/local) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/ssl) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/transport) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/util) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/slice) diff --git a/config.w32 b/config.w32 index a1bada1c61..da1279ccbc 100644 --- a/config.w32 +++ b/config.w32 @@ -255,11 +255,14 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\security\\credentials\\oauth2\\oauth2_credentials.cc " + "src\\core\\lib\\security\\credentials\\plugin\\plugin_credentials.cc " + "src\\core\\lib\\security\\credentials\\ssl\\ssl_credentials.cc " + - "src\\core\\lib\\security\\security_connector\\alts_security_connector.cc " + + "src\\core\\lib\\security\\security_connector\\alts\\alts_security_connector.cc " + + "src\\core\\lib\\security\\security_connector\\fake\\fake_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\load_system_roots_fallback.cc " + "src\\core\\lib\\security\\security_connector\\load_system_roots_linux.cc " + - "src\\core\\lib\\security\\security_connector\\local_security_connector.cc " + + "src\\core\\lib\\security\\security_connector\\local\\local_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\security_connector.cc " + + "src\\core\\lib\\security\\security_connector\\ssl\\ssl_security_connector.cc " + + "src\\core\\lib\\security\\security_connector\\ssl_utils.cc " + "src\\core\\lib\\security\\transport\\client_auth_filter.cc " + "src\\core\\lib\\security\\transport\\secure_endpoint.cc " + "src\\core\\lib\\security\\transport\\security_handshaker.cc " + @@ -314,6 +317,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\client_channel_factory.cc " + "src\\core\\ext\\filters\\client_channel\\client_channel_plugin.cc " + "src\\core\\ext\\filters\\client_channel\\connector.cc " + + "src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " + "src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " + "src\\core\\ext\\filters\\client_channel\\http_proxy.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy.cc " + @@ -330,6 +334,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " + "src\\core\\ext\\filters\\client_channel\\uri_parser.cc " + "src\\core\\ext\\filters\\deadline\\deadline_filter.cc " + + "src\\core\\ext\\filters\\client_channel\\health\\health.pb.c " + "src\\core\\tsi\\alts_transport_security.cc " + "src\\core\\tsi\\fake_transport_security.cc " + "src\\core\\tsi\\local_transport_security.cc " + @@ -672,6 +677,7 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\census"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\health"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto"); @@ -734,6 +740,10 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\plugin"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\ssl"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\alts"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\fake"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\local"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\ssl"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\transport"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\util"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\slice"); diff --git a/doc/combiner-explainer.md b/doc/core/combiner-explainer.md index 9e9d077273..9e9d077273 100644 --- a/doc/combiner-explainer.md +++ b/doc/core/combiner-explainer.md diff --git a/doc/epoll-polling-engine.md b/doc/core/epoll-polling-engine.md index 1f5d855743..1f5d855743 100644 --- a/doc/epoll-polling-engine.md +++ b/doc/core/epoll-polling-engine.md diff --git a/doc/images/new_epoll_impl.png b/doc/core/images/new_epoll_impl.png Binary files differindex 9ca1f49cbd..9ca1f49cbd 100644 --- a/doc/images/new_epoll_impl.png +++ b/doc/core/images/new_epoll_impl.png diff --git a/doc/images/old_epoll_impl.png b/doc/core/images/old_epoll_impl.png Binary files differindex 7ac3df8367..7ac3df8367 100644 --- a/doc/images/old_epoll_impl.png +++ b/doc/core/images/old_epoll_impl.png diff --git a/doc/environment_variables.md b/doc/environment_variables.md index b472f7e126..1eb850e976 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -52,6 +52,7 @@ some configuration as environment variables that can be set. traces epoll-fd creation/close calls for epollex polling engine - glb - traces the grpclb load balancer - handshaker - traces handshaking state + - health_check_client - traces health checking client code - http - traces state in the http2 transport engine - http2_stream_state - traces all http2 stream state mutations. - http1 - traces HTTP/1.x operations performed by gRPC diff --git a/examples/python/helloworld/greeter_client_with_options.py b/examples/python/helloworld/greeter_client_with_options.py new file mode 100644 index 0000000000..7eda8c9066 --- /dev/null +++ b/examples/python/helloworld/greeter_client_with_options.py @@ -0,0 +1,44 @@ +# Copyright 2018 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""The Python implementation of the GRPC helloworld.Greeter client with channel options and call timeout parameters.""" + +from __future__ import print_function + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + + +def run(): + # NOTE(gRPC Python Team): .close() is possible on a channel and should be + # used in circumstances in which the with statement does not fit the needs + # of the code. + # + # For more channel options, please see https://grpc.io/grpc/core/group__grpc__arg__keys.html + with grpc.insecure_channel( + target='localhost:50051', + options=[('grpc.lb_policy_name', 'pick_first'), + ('grpc.enable_retries', 0), ('grpc.keepalive_timeout_ms', + 10000)]) as channel: + stub = helloworld_pb2_grpc.GreeterStub(channel) + # Timeout in seconds. + # Please refer gRPC Python documents for more detail. https://grpc.io/grpc/python/grpc.html + response = stub.SayHello( + helloworld_pb2.HelloRequest(name='you'), timeout=10) + print("Greeter client received: " + response.message) + + +if __name__ == '__main__': + run() diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index e8b98cf84b..89503d65bf 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -176,7 +176,6 @@ Pod::Spec.new do |s| 'src/cpp/common/channel_filter.h', 'src/cpp/server/dynamic_thread_pool.h', 'src/cpp/server/health/default_health_check_service.h', - 'src/cpp/server/health/health.pb.h', 'src/cpp/server/thread_pool_interface.h', 'src/cpp/thread_manager/thread_manager.h', 'src/cpp/client/insecure_credentials.cc', @@ -207,7 +206,6 @@ Pod::Spec.new do |s| 'src/cpp/server/create_default_thread_pool.cc', 'src/cpp/server/dynamic_thread_pool.cc', 'src/cpp/server/health/default_health_check_service.cc', - 'src/cpp/server/health/health.pb.c', 'src/cpp/server/health/health_check_service.cc', 'src/cpp/server/health/health_check_service_server_builder_option.cc', 'src/cpp/server/server_builder.cc', @@ -288,11 +286,14 @@ Pod::Spec.new do |s| '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/security_connector/alts_security_connector.h', + 'src/core/lib/security/security_connector/alts/alts_security_connector.h', + 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', 'src/core/lib/security/security_connector/load_system_roots_linux.h', - 'src/core/lib/security/security_connector/local_security_connector.h', + 'src/core/lib/security/security_connector/local/local_security_connector.h', 'src/core/lib/security/security_connector/security_connector.h', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', + 'src/core/lib/security/security_connector/ssl_utils.h', 'src/core/lib/security/transport/auth_filters.h', 'src/core/lib/security/transport/secure_endpoint.h', 'src/core/lib/security/transport/security_handshaker.h', @@ -333,6 +334,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', @@ -350,6 +352,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/subchannel_index.h', 'src/core/ext/filters/client_channel/uri_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', + 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/alts_transport_security.h', 'src/core/tsi/fake_transport_security.h', 'src/core/tsi/local_transport_security.h', @@ -524,7 +527,6 @@ Pod::Spec.new do |s| 'src/cpp/common/channel_filter.h', 'src/cpp/server/dynamic_thread_pool.h', 'src/cpp/server/health/default_health_check_service.h', - 'src/cpp/server/health/health.pb.h', 'src/cpp/server/thread_pool_interface.h', 'src/cpp/thread_manager/thread_manager.h', 'src/core/lib/gpr/alloc.h', @@ -688,7 +690,8 @@ Pod::Spec.new do |s| 'src/core/lib/transport/transport.h', 'src/core/lib/transport/transport_impl.h', 'src/core/lib/debug/trace.h', - 'src/core/ext/transport/inproc/inproc_transport.h' + 'src/core/ext/transport/inproc/inproc_transport.h', + 'src/core/ext/filters/client_channel/health/health.pb.h' end s.subspec 'Protobuf' do |ss| diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 8d63f67c34..bbd5d7e961 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -291,11 +291,14 @@ Pod::Spec.new do |s| '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/security_connector/alts_security_connector.h', + 'src/core/lib/security/security_connector/alts/alts_security_connector.h', + 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', 'src/core/lib/security/security_connector/load_system_roots_linux.h', - 'src/core/lib/security/security_connector/local_security_connector.h', + 'src/core/lib/security/security_connector/local/local_security_connector.h', 'src/core/lib/security/security_connector/security_connector.h', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', + 'src/core/lib/security/security_connector/ssl_utils.h', 'src/core/lib/security/transport/auth_filters.h', 'src/core/lib/security/transport/secure_endpoint.h', 'src/core/lib/security/transport/security_handshaker.h', @@ -336,6 +339,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', @@ -353,6 +357,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/subchannel_index.h', 'src/core/ext/filters/client_channel/uri_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', + 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/alts_transport_security.h', 'src/core/tsi/fake_transport_security.h', 'src/core/tsi/local_transport_security.h', @@ -715,11 +720,14 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', - 'src/core/lib/security/security_connector/alts_security_connector.cc', + 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', + 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', 'src/core/lib/security/security_connector/load_system_roots_linux.cc', - 'src/core/lib/security/security_connector/local_security_connector.cc', + 'src/core/lib/security/security_connector/local/local_security_connector.cc', 'src/core/lib/security/security_connector/security_connector.cc', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', + 'src/core/lib/security/security_connector/ssl_utils.cc', 'src/core/lib/security/transport/client_auth_filter.cc', 'src/core/lib/security/transport/secure_endpoint.cc', 'src/core/lib/security/transport/security_handshaker.cc', @@ -771,6 +779,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -787,6 +796,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/alts_transport_security.cc', 'src/core/tsi/fake_transport_security.cc', 'src/core/tsi/local_transport_security.cc', @@ -900,11 +910,14 @@ Pod::Spec.new do |s| '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/security_connector/alts_security_connector.h', + 'src/core/lib/security/security_connector/alts/alts_security_connector.h', + 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', 'src/core/lib/security/security_connector/load_system_roots_linux.h', - 'src/core/lib/security/security_connector/local_security_connector.h', + 'src/core/lib/security/security_connector/local/local_security_connector.h', 'src/core/lib/security/security_connector/security_connector.h', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', + 'src/core/lib/security/security_connector/ssl_utils.h', 'src/core/lib/security/transport/auth_filters.h', 'src/core/lib/security/transport/secure_endpoint.h', 'src/core/lib/security/transport/security_handshaker.h', @@ -945,6 +958,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', @@ -962,6 +976,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/subchannel_index.h', 'src/core/ext/filters/client_channel/uri_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', + 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/alts_transport_security.h', 'src/core/tsi/fake_transport_security.h', 'src/core/tsi/local_transport_security.h', @@ -1207,6 +1222,9 @@ Pod::Spec.new do |s| 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'test/core/end2end/data/ssl_test_data.h', 'test/core/security/oauth2_utils.h', 'test/core/end2end/cq_verifier.h', @@ -1228,6 +1246,10 @@ Pod::Spec.new do |s| 'test/core/util/tracer_util.h', 'test/core/util/trickle_endpoint.h', 'test/core/util/cmdline.h', + 'third_party/nanopb/pb.h', + 'third_party/nanopb/pb_common.h', + 'third_party/nanopb/pb_decode.h', + 'third_party/nanopb/pb_encode.h', 'test/core/end2end/end2end_tests.cc', 'test/core/end2end/end2end_test_utils.cc', 'test/core/end2end/tests/authority_not_supported.cc', diff --git a/grpc.gemspec b/grpc.gemspec index 533bb90b75..a3924d0d93 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -223,11 +223,14 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.h ) 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/security_connector/alts_security_connector.h ) + s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.h ) + s.files += %w( src/core/lib/security/security_connector/fake/fake_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/load_system_roots.h ) s.files += %w( src/core/lib/security/security_connector/load_system_roots_linux.h ) - s.files += %w( src/core/lib/security/security_connector/local_security_connector.h ) + s.files += %w( src/core/lib/security/security_connector/local/local_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/security_connector.h ) + s.files += %w( src/core/lib/security/security_connector/ssl/ssl_security_connector.h ) + s.files += %w( src/core/lib/security/security_connector/ssl_utils.h ) s.files += %w( src/core/lib/security/transport/auth_filters.h ) s.files += %w( src/core/lib/security/transport/secure_endpoint.h ) s.files += %w( src/core/lib/security/transport/security_handshaker.h ) @@ -272,6 +275,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/client_channel_channelz.h ) s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h ) s.files += %w( src/core/ext/filters/client_channel/connector.h ) + s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.h ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.h ) @@ -289,6 +293,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h ) s.files += %w( src/core/ext/filters/client_channel/uri_parser.h ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.h ) + s.files += %w( src/core/ext/filters/client_channel/health/health.pb.h ) s.files += %w( src/core/tsi/alts_transport_security.h ) s.files += %w( src/core/tsi/fake_transport_security.h ) s.files += %w( src/core/tsi/local_transport_security.h ) @@ -651,11 +656,14 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.cc ) s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.cc ) s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.cc ) - s.files += %w( src/core/lib/security/security_connector/alts_security_connector.cc ) + s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.cc ) + s.files += %w( src/core/lib/security/security_connector/fake/fake_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/load_system_roots_fallback.cc ) s.files += %w( src/core/lib/security/security_connector/load_system_roots_linux.cc ) - s.files += %w( src/core/lib/security/security_connector/local_security_connector.cc ) + s.files += %w( src/core/lib/security/security_connector/local/local_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/security_connector.cc ) + s.files += %w( src/core/lib/security/security_connector/ssl/ssl_security_connector.cc ) + s.files += %w( src/core/lib/security/security_connector/ssl_utils.cc ) s.files += %w( src/core/lib/security/transport/client_auth_filter.cc ) s.files += %w( src/core/lib/security/transport/secure_endpoint.cc ) s.files += %w( src/core/lib/security/transport/security_handshaker.cc ) @@ -710,6 +718,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.cc ) s.files += %w( src/core/ext/filters/client_channel/client_channel_plugin.cc ) s.files += %w( src/core/ext/filters/client_channel/connector.cc ) + s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc ) @@ -726,6 +735,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc ) s.files += %w( src/core/ext/filters/client_channel/uri_parser.cc ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc ) + s.files += %w( src/core/ext/filters/client_channel/health/health.pb.c ) s.files += %w( src/core/tsi/alts_transport_security.cc ) s.files += %w( src/core/tsi/fake_transport_security.cc ) s.files += %w( src/core/tsi/local_transport_security.cc ) @@ -472,11 +472,14 @@ 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', - 'src/core/lib/security/security_connector/alts_security_connector.cc', + 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', + 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', 'src/core/lib/security/security_connector/load_system_roots_linux.cc', - 'src/core/lib/security/security_connector/local_security_connector.cc', + 'src/core/lib/security/security_connector/local/local_security_connector.cc', 'src/core/lib/security/security_connector/security_connector.cc', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', + 'src/core/lib/security/security_connector/ssl_utils.cc', 'src/core/lib/security/transport/client_auth_filter.cc', 'src/core/lib/security/transport/secure_endpoint.cc', 'src/core/lib/security/transport/security_handshaker.cc', @@ -531,6 +534,7 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -547,6 +551,7 @@ 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/alts_transport_security.cc', 'src/core/tsi/fake_transport_security.cc', 'src/core/tsi/local_transport_security.cc', @@ -789,6 +794,7 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -805,6 +811,10 @@ 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'src/core/ext/transport/chttp2/transport/bin_decoder.cc', 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', @@ -1023,6 +1033,7 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -1039,6 +1050,10 @@ 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'src/core/ext/transport/chttp2/transport/bin_decoder.cc', 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', @@ -1269,6 +1284,7 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -1285,6 +1301,10 @@ 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'src/core/ext/transport/inproc/inproc_plugin.cc', 'src/core/ext/transport/inproc/inproc_transport.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc', @@ -1303,9 +1323,6 @@ 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc', - 'third_party/nanopb/pb_common.c', - 'third_party/nanopb/pb_decode.c', - 'third_party/nanopb/pb_encode.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', @@ -1387,7 +1404,6 @@ 'src/cpp/server/create_default_thread_pool.cc', 'src/cpp/server/dynamic_thread_pool.cc', 'src/cpp/server/health/default_health_check_service.cc', - 'src/cpp/server/health/health.pb.c', 'src/cpp/server/health/health_check_service.cc', 'src/cpp/server/health/health_check_service_server_builder_option.cc', 'src/cpp/server/server_builder.cc', @@ -1400,6 +1416,10 @@ 'src/cpp/util/status.cc', 'src/cpp/util/string_ref.cc', 'src/cpp/util/time_cc.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'src/cpp/codegen/call_wrapper.cc', 'src/cpp/codegen/codegen_init.cc', ], @@ -1537,7 +1557,6 @@ 'src/cpp/server/create_default_thread_pool.cc', 'src/cpp/server/dynamic_thread_pool.cc', 'src/cpp/server/health/default_health_check_service.cc', - 'src/cpp/server/health/health.pb.c', 'src/cpp/server/health/health_check_service.cc', 'src/cpp/server/health/health_check_service_server_builder_option.cc', 'src/cpp/server/server_builder.cc', @@ -1550,6 +1569,10 @@ 'src/cpp/util/status.cc', 'src/cpp/util/string_ref.cc', 'src/cpp/util/time_cc.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'src/cpp/codegen/call_wrapper.cc', 'src/cpp/codegen/codegen_init.cc', ], diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 3ce88a8264..17a43fab0f 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -347,6 +347,9 @@ typedef struct { /** If set to non zero, surfaces the user agent string to the server. User agent is surfaced by default. */ #define GRPC_ARG_SURFACE_USER_AGENT "grpc.surface_user_agent" +/** If set, inhibits health checking (which may be enabled via the + * service config.) */ +#define GRPC_ARG_INHIBIT_HEALTH_CHECKING "grpc.inhibit_health_checking" /** \} */ /** Result of a grpc call. If the caller satisfies the prerequisites of a diff --git a/include/grpcpp/impl/codegen/call.h b/include/grpcpp/impl/codegen/call.h index c6894003b6..0a6dad9cd8 100644 --- a/include/grpcpp/impl/codegen/call.h +++ b/include/grpcpp/impl/codegen/call.h @@ -1189,7 +1189,6 @@ class CallOpSet : public CallOpSetInterface, } bool FinalizeResult(void** tag, bool* status) override { - gpr_log(GPR_ERROR, "finalizing result"); if (done_intercepting_) { // We have already finished intercepting and filling in the results. This // round trip from the core needed to be made because interceptors were diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index 3f586b2394..eba9ec6edc 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -32,16 +32,16 @@ namespace grpc { namespace internal { /// An exception-safe way of invoking a user-specified callback function -template <class Func, class Arg> -void CatchingCallback(Func&& func, Arg&& arg) { +template <class Func, class... Args> +void CatchingCallback(Func&& func, Args&&... args) { #if GRPC_ALLOW_EXCEPTIONS try { - func(arg); + func(std::forward<Args>(args)...); } catch (...) { // nothing to return or change here, just don't crash the library } #else // GRPC_ALLOW_EXCEPTIONS - func(arg); + func(std::forward<Args>(args)...); #endif // GRPC_ALLOW_EXCEPTIONS } diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index fc1ed3278a..0aa68208d2 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -122,8 +122,8 @@ class CompletionQueue : private GrpcLibraryCodegen { /// Read from the queue, blocking until an event is available or the queue is /// shutting down. /// - /// \param tag[out] Updated to point to the read event's tag. - /// \param ok[out] true if read a successful event, false otherwise. + /// \param tag [out] Updated to point to the read event's tag. + /// \param ok [out] true if read a successful event, false otherwise. /// /// Note that each tag sent to the completion queue (through RPC operations /// or alarms) will be delivered out of the completion queue by a call to @@ -178,10 +178,10 @@ class CompletionQueue : private GrpcLibraryCodegen { /// within the \a deadline). A \a tag points to an arbitrary location usually /// employed to uniquely identify an event. /// - /// \param tag[out] Upon sucess, updated to point to the event's tag. - /// \param ok[out] Upon sucess, true if a successful event, false otherwise + /// \param tag [out] Upon sucess, updated to point to the event's tag. + /// \param ok [out] Upon sucess, true if a successful event, false otherwise /// See documentation for CompletionQueue::Next for explanation of ok - /// \param deadline[in] How long to block in wait for an event. + /// \param deadline [in] How long to block in wait for an event. /// /// \return The type of event read. template <typename T> @@ -197,10 +197,11 @@ class CompletionQueue : private GrpcLibraryCodegen { /// within the \a deadline). A \a tag points to an arbitrary location usually /// employed to uniquely identify an event. /// - /// \param F[in] Function to execute before calling AsyncNext on this queue. - /// \param tag[out] Upon sucess, updated to point to the event's tag. - /// \param ok[out] Upon sucess, true if read a regular event, false otherwise. - /// \param deadline[in] How long to block in wait for an event. + /// \param f [in] Function to execute before calling AsyncNext on this queue. + /// \param tag [out] Upon sucess, updated to point to the event's tag. + /// \param ok [out] Upon sucess, true if read a regular event, false + /// otherwise. + /// \param deadline [in] How long to block in wait for an event. /// /// \return The type of event read. template <typename T, typename F> @@ -379,7 +380,7 @@ class ServerCompletionQueue : public CompletionQueue { ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {} private: - /// \param is_frequently_polled Informs the GRPC library about whether the + /// \param polling_type Informs the GRPC library about whether the /// server completion queue would be actively polled (by calling Next() or /// AsyncNext()). By default all server completion queues are assumed to be /// frequently polled. diff --git a/include/grpcpp/impl/codegen/config_protobuf.h b/include/grpcpp/impl/codegen/config_protobuf.h index 94e593d1ef..8c2e9e6792 100644 --- a/include/grpcpp/impl/codegen/config_protobuf.h +++ b/include/grpcpp/impl/codegen/config_protobuf.h @@ -66,6 +66,12 @@ #define GRPC_CUSTOM_CODEDINPUTSTREAM ::google::protobuf::io::CodedInputStream #endif +#ifndef GRPC_CUSTOM_JSONUTIL +#include <google/protobuf/util/json_util.h> +#define GRPC_CUSTOM_JSONUTIL ::google::protobuf::util +#define GRPC_CUSTOM_UTIL_STATUS ::google::protobuf::util::Status +#endif + namespace grpc { namespace protobuf { @@ -83,6 +89,12 @@ typedef GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor; typedef GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE SimpleDescriptorDatabase; typedef GRPC_CUSTOM_SOURCELOCATION SourceLocation; +namespace util { +typedef GRPC_CUSTOM_UTIL_STATUS Status; +} // namespace util + +namespace json = GRPC_CUSTOM_JSONUTIL; + namespace io { typedef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM ZeroCopyOutputStream; typedef GRPC_CUSTOM_ZEROCOPYINPUTSTREAM ZeroCopyInputStream; diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index b2693e287b..5a3249b904 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -107,7 +107,7 @@ class ServerContext { /// Return a \a gpr_timespec representation of the server call's deadline. gpr_timespec raw_deadline() const { return deadline_; } - /// Add the (\a meta_key, \a meta_value) pair to the initial metadata + /// Add the (\a key, \a value) pair to the initial metadata /// associated with a server call. These are made available at the client side /// by the \a grpc::ClientContext::GetServerInitialMetadata() method. /// @@ -115,13 +115,13 @@ class ServerContext { /// to the client (which can happen explicitly, or implicitly when sending a /// a response message or status to the client). /// - /// \param meta_key The metadata key. If \a meta_value is binary data, it must + /// \param key The metadata key. If \a value is binary data, it must /// end in "-bin". - /// \param meta_value The metadata value. If its value is binary, the key name + /// \param value The metadata value. If its value is binary, the key name /// must end in "-bin". void AddInitialMetadata(const grpc::string& key, const grpc::string& value); - /// Add the (\a meta_key, \a meta_value) pair to the initial metadata + /// Add the (\a key, \a value) pair to the initial metadata /// associated with a server call. These are made available at the client /// side by the \a grpc::ClientContext::GetServerTrailingMetadata() method. /// @@ -129,9 +129,9 @@ class ServerContext { /// metadata to the client (which happens when the call is finished and a /// status is sent to the client). /// - /// \param meta_key The metadata key. If \a meta_value is binary data, + /// \param key The metadata key. If \a value is binary data, /// it must end in "-bin". - /// \param meta_value The metadata value. If its value is binary, the key name + /// \param value The metadata value. If its value is binary, the key name /// must end in "-bin". void AddTrailingMetadata(const grpc::string& key, const grpc::string& value); @@ -177,9 +177,9 @@ class ServerContext { return compression_level_; } - /// Set \a algorithm to be the compression algorithm used for the server call. + /// Set \a level to be the compression level used for the server call. /// - /// \param algorithm The compression algorithm used for the server call. + /// \param level The compression level used for the server call. void set_compression_level(grpc_compression_level level) { compression_level_set_ = true; compression_level_ = level; diff --git a/package.xml b/package.xml index 0d40707786..c90cee8fe9 100644 --- a/package.xml +++ b/package.xml @@ -228,11 +228,14 @@ <file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.h" role="src" /> <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/security_connector/alts_security_connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts/alts_security_connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/fake/fake_security_connector.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/load_system_roots.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/load_system_roots_linux.h" role="src" /> - <file baseinstalldir="/" name="src/core/lib/security/security_connector/local_security_connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/local/local_security_connector.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/ssl/ssl_security_connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/ssl_utils.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.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_handshaker.h" role="src" /> @@ -277,6 +280,7 @@ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_channelz.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.h" role="src" /> @@ -294,6 +298,7 @@ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health.pb.h" role="src" /> <file baseinstalldir="/" name="src/core/tsi/alts_transport_security.h" role="src" /> <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.h" role="src" /> <file baseinstalldir="/" name="src/core/tsi/local_transport_security.h" role="src" /> @@ -656,11 +661,14 @@ <file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.cc" role="src" /> - <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts_security_connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts/alts_security_connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/fake/fake_security_connector.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/load_system_roots_fallback.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/load_system_roots_linux.cc" role="src" /> - <file baseinstalldir="/" name="src/core/lib/security/security_connector/local_security_connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/local/local_security_connector.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/ssl/ssl_security_connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/ssl_utils.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/client_auth_filter.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.cc" role="src" /> @@ -715,6 +723,7 @@ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_plugin.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.cc" role="src" /> @@ -731,6 +740,7 @@ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.cc" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health.pb.c" role="src" /> <file baseinstalldir="/" name="src/core/tsi/alts_transport_security.cc" role="src" /> <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.cc" role="src" /> <file baseinstalldir="/" name="src/core/tsi/local_transport_security.cc" role="src" /> diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index bad1ef668c..8e5426081c 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -128,7 +128,8 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) { if (subchannel_ == nullptr) { state = GRPC_CHANNEL_SHUTDOWN; } else { - state = grpc_subchannel_check_connectivity(subchannel_, nullptr); + state = grpc_subchannel_check_connectivity( + subchannel_, nullptr, true /* inhibit_health_checking */); } json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); diff --git a/src/cpp/server/health/health.pb.c b/src/core/ext/filters/client_channel/health/health.pb.c index 5c214c7160..5499c549cc 100644 --- a/src/cpp/server/health/health.pb.c +++ b/src/core/ext/filters/client_channel/health/health.pb.c @@ -1,7 +1,7 @@ /* Automatically generated nanopb constant definitions */ /* Generated by nanopb-0.3.7-dev */ -#include "src/cpp/server/health/health.pb.h" +#include "src/core/ext/filters/client_channel/health/health.pb.h" /* @@protoc_insertion_point(includes) */ #if PB_PROTO_HEADER_VERSION != 30 #error Regenerate this file with the current version of nanopb generator. diff --git a/src/cpp/server/health/health.pb.h b/src/core/ext/filters/client_channel/health/health.pb.h index 9d54ccd618..9d54ccd618 100644 --- a/src/cpp/server/health/health.pb.h +++ b/src/core/ext/filters/client_channel/health/health.pb.h diff --git a/src/core/ext/filters/client_channel/health/health_check_client.cc b/src/core/ext/filters/client_channel/health/health_check_client.cc new file mode 100644 index 0000000000..a3c782d8c9 --- /dev/null +++ b/src/core/ext/filters/client_channel/health/health_check_client.cc @@ -0,0 +1,647 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/support/port_platform.h> + +#include <stdint.h> +#include <stdio.h> + +#include "src/core/ext/filters/client_channel/health/health_check_client.h" + +#include "pb_decode.h" +#include "pb_encode.h" +#include "src/core/ext/filters/client_channel/health/health.pb.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/transport/error_utils.h" +#include "src/core/lib/transport/status_metadata.h" + +#define HEALTH_CHECK_INITIAL_CONNECT_BACKOFF_SECONDS 1 +#define HEALTH_CHECK_RECONNECT_BACKOFF_MULTIPLIER 1.6 +#define HEALTH_CHECK_RECONNECT_MAX_BACKOFF_SECONDS 120 +#define HEALTH_CHECK_RECONNECT_JITTER 0.2 + +grpc_core::TraceFlag grpc_health_check_client_trace(false, + "health_check_client"); + +namespace grpc_core { + +// +// HealthCheckClient +// + +HealthCheckClient::HealthCheckClient( + const char* service_name, + RefCountedPtr<ConnectedSubchannel> connected_subchannel, + grpc_pollset_set* interested_parties, + grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode> channelz_node) + : InternallyRefCountedWithTracing<HealthCheckClient>( + &grpc_health_check_client_trace), + service_name_(service_name), + connected_subchannel_(std::move(connected_subchannel)), + interested_parties_(interested_parties), + channelz_node_(std::move(channelz_node)), + retry_backoff_( + BackOff::Options() + .set_initial_backoff( + HEALTH_CHECK_INITIAL_CONNECT_BACKOFF_SECONDS * 1000) + .set_multiplier(HEALTH_CHECK_RECONNECT_BACKOFF_MULTIPLIER) + .set_jitter(HEALTH_CHECK_RECONNECT_JITTER) + .set_max_backoff(HEALTH_CHECK_RECONNECT_MAX_BACKOFF_SECONDS * + 1000)) { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "created HealthCheckClient %p", this); + } + GRPC_CLOSURE_INIT(&retry_timer_callback_, OnRetryTimer, this, + grpc_schedule_on_exec_ctx); + gpr_mu_init(&mu_); + StartCall(); +} + +HealthCheckClient::~HealthCheckClient() { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "destroying HealthCheckClient %p", this); + } + GRPC_ERROR_UNREF(error_); + gpr_mu_destroy(&mu_); +} + +void HealthCheckClient::NotifyOnHealthChange(grpc_connectivity_state* state, + grpc_closure* closure) { + MutexLock lock(&mu_); + GPR_ASSERT(notify_state_ == nullptr); + if (*state != state_) { + *state = state_; + GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_REF(error_)); + return; + } + notify_state_ = state; + on_health_changed_ = closure; +} + +void HealthCheckClient::SetHealthStatus(grpc_connectivity_state state, + grpc_error* error) { + MutexLock lock(&mu_); + SetHealthStatusLocked(state, error); +} + +void HealthCheckClient::SetHealthStatusLocked(grpc_connectivity_state state, + grpc_error* error) { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: setting state=%d error=%s", this, + state, grpc_error_string(error)); + } + if (notify_state_ != nullptr && *notify_state_ != state) { + *notify_state_ = state; + notify_state_ = nullptr; + GRPC_CLOSURE_SCHED(on_health_changed_, GRPC_ERROR_REF(error)); + on_health_changed_ = nullptr; + } + state_ = state; + GRPC_ERROR_UNREF(error_); + error_ = error; +} + +void HealthCheckClient::Orphan() { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: shutting down", this); + } + { + MutexLock lock(&mu_); + if (on_health_changed_ != nullptr) { + *notify_state_ = GRPC_CHANNEL_SHUTDOWN; + notify_state_ = nullptr; + GRPC_CLOSURE_SCHED(on_health_changed_, GRPC_ERROR_NONE); + on_health_changed_ = nullptr; + } + shutting_down_ = true; + call_state_.reset(); + if (retry_timer_callback_pending_) { + grpc_timer_cancel(&retry_timer_); + } + } + Unref(DEBUG_LOCATION, "orphan"); +} + +void HealthCheckClient::StartCall() { + MutexLock lock(&mu_); + StartCallLocked(); +} + +void HealthCheckClient::StartCallLocked() { + if (shutting_down_) return; + GPR_ASSERT(call_state_ == nullptr); + SetHealthStatusLocked(GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE); + call_state_ = MakeOrphanable<CallState>(Ref(), interested_parties_); + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: created CallState %p", this, + call_state_.get()); + } + call_state_->StartCall(); +} + +void HealthCheckClient::StartRetryTimer() { + MutexLock lock(&mu_); + SetHealthStatusLocked( + GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "health check call failed; will retry after backoff")); + grpc_millis next_try = retry_backoff_.NextAttemptTime(); + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: health check call lost...", this); + grpc_millis timeout = next_try - ExecCtx::Get()->Now(); + if (timeout > 0) { + gpr_log(GPR_INFO, + "HealthCheckClient %p: ... will retry in %" PRId64 "ms.", this, + timeout); + } else { + gpr_log(GPR_INFO, "HealthCheckClient %p: ... retrying immediately.", + this); + } + } + // Ref for callback, tracked manually. + Ref(DEBUG_LOCATION, "health_retry_timer").release(); + retry_timer_callback_pending_ = true; + grpc_timer_init(&retry_timer_, next_try, &retry_timer_callback_); +} + +void HealthCheckClient::OnRetryTimer(void* arg, grpc_error* error) { + HealthCheckClient* self = static_cast<HealthCheckClient*>(arg); + { + MutexLock lock(&self->mu_); + self->retry_timer_callback_pending_ = false; + if (!self->shutting_down_ && error == GRPC_ERROR_NONE && + self->call_state_ == nullptr) { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: restarting health check call", + self); + } + self->StartCallLocked(); + } + } + self->Unref(DEBUG_LOCATION, "health_retry_timer"); +} + +// +// protobuf helpers +// + +namespace { + +void EncodeRequest(const char* service_name, + ManualConstructor<SliceBufferByteStream>* send_message) { + grpc_health_v1_HealthCheckRequest request_struct; + request_struct.has_service = true; + snprintf(request_struct.service, sizeof(request_struct.service), "%s", + service_name); + pb_ostream_t ostream; + memset(&ostream, 0, sizeof(ostream)); + pb_encode(&ostream, grpc_health_v1_HealthCheckRequest_fields, + &request_struct); + grpc_slice request_slice = GRPC_SLICE_MALLOC(ostream.bytes_written); + ostream = pb_ostream_from_buffer(GRPC_SLICE_START_PTR(request_slice), + GRPC_SLICE_LENGTH(request_slice)); + GPR_ASSERT(pb_encode(&ostream, grpc_health_v1_HealthCheckRequest_fields, + &request_struct) != 0); + grpc_slice_buffer slice_buffer; + grpc_slice_buffer_init(&slice_buffer); + grpc_slice_buffer_add(&slice_buffer, request_slice); + send_message->Init(&slice_buffer, 0); + grpc_slice_buffer_destroy_internal(&slice_buffer); +} + +// Returns true if healthy. +// If there was an error parsing the response, sets *error and returns false. +bool DecodeResponse(grpc_slice_buffer* slice_buffer, grpc_error** error) { + // If message is empty, assume unhealthy. + if (slice_buffer->length == 0) { + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("health check response was empty"); + return false; + } + // Concatenate the slices to form a single string. + UniquePtr<uint8_t> recv_message_deleter; + uint8_t* recv_message; + if (slice_buffer->count == 1) { + recv_message = GRPC_SLICE_START_PTR(slice_buffer->slices[0]); + } else { + recv_message = static_cast<uint8_t*>(gpr_malloc(slice_buffer->length)); + recv_message_deleter.reset(recv_message); + size_t offset = 0; + for (size_t i = 0; i < slice_buffer->count; ++i) { + memcpy(recv_message + offset, + GRPC_SLICE_START_PTR(slice_buffer->slices[i]), + GRPC_SLICE_LENGTH(slice_buffer->slices[i])); + offset += GRPC_SLICE_LENGTH(slice_buffer->slices[i]); + } + } + // Deserialize message. + grpc_health_v1_HealthCheckResponse response_struct; + pb_istream_t istream = + pb_istream_from_buffer(recv_message, slice_buffer->length); + if (!pb_decode(&istream, grpc_health_v1_HealthCheckResponse_fields, + &response_struct)) { + // Can't parse message; assume unhealthy. + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "cannot parse health check response"); + return false; + } + if (!response_struct.has_status) { + // Field not present; assume unhealthy. + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "status field not present in health check response"); + return false; + } + return response_struct.status == + grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING; +} + +} // namespace + +// +// HealthCheckClient::CallState +// + +HealthCheckClient::CallState::CallState( + RefCountedPtr<HealthCheckClient> health_check_client, + grpc_pollset_set* interested_parties) + : InternallyRefCountedWithTracing<CallState>( + &grpc_health_check_client_trace), + health_check_client_(std::move(health_check_client)), + pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)), + arena_(gpr_arena_create(health_check_client_->connected_subchannel_ + ->GetInitialCallSizeEstimate(0))) { + memset(&call_combiner_, 0, sizeof(call_combiner_)); + grpc_call_combiner_init(&call_combiner_); + memset(context_, 0, sizeof(context_)); + gpr_atm_rel_store(&seen_response_, static_cast<gpr_atm>(0)); +} + +HealthCheckClient::CallState::~CallState() { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: destroying CallState %p", + health_check_client_.get(), this); + } + if (call_ != nullptr) GRPC_SUBCHANNEL_CALL_UNREF(call_, "call_ended"); + // Unset the call combiner cancellation closure. This has the + // effect of scheduling the previously set cancellation closure, if + // any, so that it can release any internal references it may be + // holding to the call stack. Also flush the closures on exec_ctx so that + // filters that schedule cancel notification closures on exec_ctx do not + // need to take a ref of the call stack to guarantee closure liveness. + grpc_call_combiner_set_notify_on_cancel(&call_combiner_, nullptr); + grpc_core::ExecCtx::Get()->Flush(); + grpc_call_combiner_destroy(&call_combiner_); + gpr_arena_destroy(arena_); +} + +void HealthCheckClient::CallState::Orphan() { + grpc_call_combiner_cancel(&call_combiner_, GRPC_ERROR_CANCELLED); + Cancel(); +} + +void HealthCheckClient::CallState::StartCall() { + ConnectedSubchannel::CallArgs args = { + &pollent_, + GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH, + gpr_now(GPR_CLOCK_MONOTONIC), // start_time + GRPC_MILLIS_INF_FUTURE, // deadline + arena_, + context_, + &call_combiner_, + 0, // parent_data_size + }; + grpc_error* error = + health_check_client_->connected_subchannel_->CreateCall(args, &call_); + if (error != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, + "HealthCheckClient %p CallState %p: error creating health " + "checking call on subchannel (%s); will retry", + health_check_client_.get(), this, grpc_error_string(error)); + GRPC_ERROR_UNREF(error); + // Schedule instead of running directly, since we must not be + // holding health_check_client_->mu_ when CallEnded() is called. + Ref(DEBUG_LOCATION, "call_end_closure").release(); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT(&batch_.handler_private.closure, CallEndedRetry, this, + grpc_schedule_on_exec_ctx), + GRPC_ERROR_NONE); + return; + } + // Initialize payload and batch. + memset(&batch_, 0, sizeof(batch_)); + batch_.payload = &payload_; + // on_complete callback takes ref, handled manually. + Ref(DEBUG_LOCATION, "on_complete").release(); + batch_.on_complete = GRPC_CLOSURE_INIT(&on_complete_, OnComplete, this, + grpc_schedule_on_exec_ctx); + // Add send_initial_metadata op. + grpc_metadata_batch_init(&send_initial_metadata_); + error = grpc_metadata_batch_add_head( + &send_initial_metadata_, &path_metadata_storage_, + grpc_mdelem_from_slices( + GRPC_MDSTR_PATH, + GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH)); + GPR_ASSERT(error == GRPC_ERROR_NONE); + payload_.send_initial_metadata.send_initial_metadata = + &send_initial_metadata_; + payload_.send_initial_metadata.send_initial_metadata_flags = 0; + payload_.send_initial_metadata.peer_string = nullptr; + batch_.send_initial_metadata = true; + // Add send_message op. + EncodeRequest(health_check_client_->service_name_, &send_message_); + payload_.send_message.send_message.reset(send_message_.get()); + batch_.send_message = true; + // Add send_trailing_metadata op. + grpc_metadata_batch_init(&send_trailing_metadata_); + payload_.send_trailing_metadata.send_trailing_metadata = + &send_trailing_metadata_; + batch_.send_trailing_metadata = true; + // Add recv_initial_metadata op. + grpc_metadata_batch_init(&recv_initial_metadata_); + payload_.recv_initial_metadata.recv_initial_metadata = + &recv_initial_metadata_; + payload_.recv_initial_metadata.recv_flags = nullptr; + payload_.recv_initial_metadata.trailing_metadata_available = nullptr; + payload_.recv_initial_metadata.peer_string = nullptr; + // recv_initial_metadata_ready callback takes ref, handled manually. + Ref(DEBUG_LOCATION, "recv_initial_metadata_ready").release(); + payload_.recv_initial_metadata.recv_initial_metadata_ready = + GRPC_CLOSURE_INIT(&recv_initial_metadata_ready_, RecvInitialMetadataReady, + this, grpc_schedule_on_exec_ctx); + batch_.recv_initial_metadata = true; + // Add recv_message op. + payload_.recv_message.recv_message = &recv_message_; + // recv_message callback takes ref, handled manually. + Ref(DEBUG_LOCATION, "recv_message_ready").release(); + payload_.recv_message.recv_message_ready = GRPC_CLOSURE_INIT( + &recv_message_ready_, RecvMessageReady, this, grpc_schedule_on_exec_ctx); + batch_.recv_message = true; + // Start batch. + StartBatch(&batch_); + // Initialize recv_trailing_metadata batch. + memset(&recv_trailing_metadata_batch_, 0, + sizeof(recv_trailing_metadata_batch_)); + recv_trailing_metadata_batch_.payload = &payload_; + // Add recv_trailing_metadata op. + grpc_metadata_batch_init(&recv_trailing_metadata_); + payload_.recv_trailing_metadata.recv_trailing_metadata = + &recv_trailing_metadata_; + payload_.recv_trailing_metadata.collect_stats = &collect_stats_; + // This callback signals the end of the call, so it relies on the + // initial ref instead of taking a new ref. When it's invoked, the + // initial ref is released. + payload_.recv_trailing_metadata.recv_trailing_metadata_ready = + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, + RecvTrailingMetadataReady, this, + grpc_schedule_on_exec_ctx); + recv_trailing_metadata_batch_.recv_trailing_metadata = true; + // Start recv_trailing_metadata batch. + StartBatch(&recv_trailing_metadata_batch_); +} + +void HealthCheckClient::CallState::StartBatchInCallCombiner(void* arg, + grpc_error* error) { + grpc_transport_stream_op_batch* batch = + static_cast<grpc_transport_stream_op_batch*>(arg); + grpc_subchannel_call* call = + static_cast<grpc_subchannel_call*>(batch->handler_private.extra_arg); + grpc_subchannel_call_process_op(call, batch); +} + +void HealthCheckClient::CallState::StartBatch( + grpc_transport_stream_op_batch* batch) { + batch->handler_private.extra_arg = call_; + GRPC_CLOSURE_INIT(&batch->handler_private.closure, StartBatchInCallCombiner, + batch, grpc_schedule_on_exec_ctx); + GRPC_CALL_COMBINER_START(&call_combiner_, &batch->handler_private.closure, + GRPC_ERROR_NONE, "start_subchannel_batch"); +} + +void HealthCheckClient::CallState::OnCancelComplete(void* arg, + grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "health_cancel"); + self->Unref(DEBUG_LOCATION, "cancel"); +} + +void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + auto* batch = grpc_make_transport_stream_op( + GRPC_CLOSURE_CREATE(OnCancelComplete, self, grpc_schedule_on_exec_ctx)); + batch->cancel_stream = true; + batch->payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED; + grpc_subchannel_call_process_op(self->call_, batch); +} + +void HealthCheckClient::CallState::Cancel() { + if (call_ != nullptr) { + Ref(DEBUG_LOCATION, "cancel").release(); + GRPC_CALL_COMBINER_START( + &call_combiner_, + GRPC_CLOSURE_CREATE(StartCancel, this, grpc_schedule_on_exec_ctx), + GRPC_ERROR_NONE, "health_cancel"); + } +} + +void HealthCheckClient::CallState::OnComplete(void* arg, grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "on_complete"); + grpc_metadata_batch_destroy(&self->send_initial_metadata_); + grpc_metadata_batch_destroy(&self->send_trailing_metadata_); + self->Unref(DEBUG_LOCATION, "on_complete"); +} + +void HealthCheckClient::CallState::RecvInitialMetadataReady(void* arg, + grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "recv_initial_metadata_ready"); + grpc_metadata_batch_destroy(&self->recv_initial_metadata_); + self->Unref(DEBUG_LOCATION, "recv_initial_metadata_ready"); +} + +void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) { + recv_message_.reset(); + if (error != GRPC_ERROR_NONE) { + GRPC_ERROR_UNREF(error); + Cancel(); + grpc_slice_buffer_destroy_internal(&recv_message_buffer_); + Unref(DEBUG_LOCATION, "recv_message_ready"); + return; + } + const bool healthy = DecodeResponse(&recv_message_buffer_, &error); + const grpc_connectivity_state state = + healthy ? GRPC_CHANNEL_READY : GRPC_CHANNEL_TRANSIENT_FAILURE; + if (error == GRPC_ERROR_NONE && !healthy) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("backend unhealthy"); + } + health_check_client_->SetHealthStatus(state, error); + gpr_atm_rel_store(&seen_response_, static_cast<gpr_atm>(1)); + grpc_slice_buffer_destroy_internal(&recv_message_buffer_); + // Start another recv_message batch. + // This re-uses the ref we're holding. + // Note: Can't just reuse batch_ here, since we don't know that all + // callbacks from the original batch have completed yet. + memset(&recv_message_batch_, 0, sizeof(recv_message_batch_)); + recv_message_batch_.payload = &payload_; + payload_.recv_message.recv_message = &recv_message_; + payload_.recv_message.recv_message_ready = GRPC_CLOSURE_INIT( + &recv_message_ready_, RecvMessageReady, this, grpc_schedule_on_exec_ctx); + recv_message_batch_.recv_message = true; + StartBatch(&recv_message_batch_); +} + +grpc_error* HealthCheckClient::CallState::PullSliceFromRecvMessage() { + grpc_slice slice; + grpc_error* error = recv_message_->Pull(&slice); + if (error == GRPC_ERROR_NONE) { + grpc_slice_buffer_add(&recv_message_buffer_, slice); + } + return error; +} + +void HealthCheckClient::CallState::ContinueReadingRecvMessage() { + while (recv_message_->Next(SIZE_MAX, &recv_message_ready_)) { + grpc_error* error = PullSliceFromRecvMessage(); + if (error != GRPC_ERROR_NONE) { + DoneReadingRecvMessage(error); + return; + } + if (recv_message_buffer_.length == recv_message_->length()) { + DoneReadingRecvMessage(GRPC_ERROR_NONE); + break; + } + } +} + +void HealthCheckClient::CallState::OnByteStreamNext(void* arg, + grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + if (error != GRPC_ERROR_NONE) { + self->DoneReadingRecvMessage(GRPC_ERROR_REF(error)); + return; + } + error = self->PullSliceFromRecvMessage(); + if (error != GRPC_ERROR_NONE) { + self->DoneReadingRecvMessage(error); + return; + } + if (self->recv_message_buffer_.length == self->recv_message_->length()) { + self->DoneReadingRecvMessage(GRPC_ERROR_NONE); + } else { + self->ContinueReadingRecvMessage(); + } +} + +void HealthCheckClient::CallState::RecvMessageReady(void* arg, + grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "recv_message_ready"); + if (self->recv_message_ == nullptr) { + self->Unref(DEBUG_LOCATION, "recv_message_ready"); + return; + } + grpc_slice_buffer_init(&self->recv_message_buffer_); + GRPC_CLOSURE_INIT(&self->recv_message_ready_, OnByteStreamNext, self, + grpc_schedule_on_exec_ctx); + self->ContinueReadingRecvMessage(); + // Ref will continue to be held until we finish draining the byte stream. +} + +void HealthCheckClient::CallState::RecvTrailingMetadataReady( + void* arg, grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + GRPC_CALL_COMBINER_STOP(&self->call_combiner_, + "recv_trailing_metadata_ready"); + // Get call status. + grpc_status_code status = GRPC_STATUS_UNKNOWN; + if (error != GRPC_ERROR_NONE) { + grpc_error_get_status(error, GRPC_MILLIS_INF_FUTURE, &status, + nullptr /* slice */, nullptr /* http_error */, + nullptr /* error_string */); + } else if (self->recv_trailing_metadata_.idx.named.grpc_status != nullptr) { + status = grpc_get_status_code_from_metadata( + self->recv_trailing_metadata_.idx.named.grpc_status->md); + } + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, + "HealthCheckClient %p CallState %p: health watch failed with " + "status %d", + self->health_check_client_.get(), self, status); + } + // Clean up. + grpc_metadata_batch_destroy(&self->recv_trailing_metadata_); + // For status UNIMPLEMENTED, give up and assume always healthy. + bool retry = true; + if (status == GRPC_STATUS_UNIMPLEMENTED) { + static const char kErrorMessage[] = + "health checking Watch method returned UNIMPLEMENTED; " + "disabling health checks but assuming server is healthy"; + gpr_log(GPR_ERROR, kErrorMessage); + if (self->health_check_client_->channelz_node_ != nullptr) { + self->health_check_client_->channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Error, + grpc_slice_from_static_string(kErrorMessage)); + } + self->health_check_client_->SetHealthStatus(GRPC_CHANNEL_READY, + GRPC_ERROR_NONE); + retry = false; + } + self->CallEnded(retry); +} + +void HealthCheckClient::CallState::CallEndedRetry(void* arg, + grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + self->CallEnded(true /* retry */); + self->Unref(DEBUG_LOCATION, "call_end_closure"); +} + +void HealthCheckClient::CallState::CallEnded(bool retry) { + // If this CallState is still in use, this call ended because of a failure, + // so we need to stop using it and optionally create a new one. + // Otherwise, we have deliberately ended this call, and no further action + // is required. + if (this == health_check_client_->call_state_.get()) { + health_check_client_->call_state_.reset(); + if (retry) { + GPR_ASSERT(!health_check_client_->shutting_down_); + if (static_cast<bool>(gpr_atm_acq_load(&seen_response_))) { + // If the call fails after we've gotten a successful response, reset + // the backoff and restart the call immediately. + health_check_client_->retry_backoff_.Reset(); + health_check_client_->StartCall(); + } else { + // If the call failed without receiving any messages, retry later. + health_check_client_->StartRetryTimer(); + } + } + } + Unref(DEBUG_LOCATION, "call_ended"); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/health/health_check_client.h b/src/core/ext/filters/client_channel/health/health_check_client.h new file mode 100644 index 0000000000..7f77348f18 --- /dev/null +++ b/src/core/ext/filters/client_channel/health/health_check_client.h @@ -0,0 +1,173 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_CLIENT_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_CLIENT_H + +#include <grpc/support/port_platform.h> + +#include <grpc/grpc.h> +#include <grpc/support/atm.h> +#include <grpc/support/sync.h> + +#include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/gpr/arena.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/call_combiner.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/transport/byte_stream.h" +#include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/transport/transport.h" + +namespace grpc_core { + +class HealthCheckClient + : public InternallyRefCountedWithTracing<HealthCheckClient> { + public: + HealthCheckClient(const char* service_name, + RefCountedPtr<ConnectedSubchannel> connected_subchannel, + grpc_pollset_set* interested_parties, + RefCountedPtr<channelz::SubchannelNode> channelz_node); + + ~HealthCheckClient(); + + // When the health state changes from *state, sets *state to the new + // value and schedules closure. + // Only one closure can be outstanding at a time. + void NotifyOnHealthChange(grpc_connectivity_state* state, + grpc_closure* closure); + + void Orphan() override; + + private: + // Contains a call to the backend and all the data related to the call. + class CallState : public InternallyRefCountedWithTracing<CallState> { + public: + CallState(RefCountedPtr<HealthCheckClient> health_check_client, + grpc_pollset_set* interested_parties_); + ~CallState(); + + void Orphan() override; + + void StartCall(); + + private: + void Cancel(); + + void StartBatch(grpc_transport_stream_op_batch* batch); + static void StartBatchInCallCombiner(void* arg, grpc_error* error); + + static void CallEndedRetry(void* arg, grpc_error* error); + void CallEnded(bool retry); + + static void OnComplete(void* arg, grpc_error* error); + static void RecvInitialMetadataReady(void* arg, grpc_error* error); + static void RecvMessageReady(void* arg, grpc_error* error); + static void RecvTrailingMetadataReady(void* arg, grpc_error* error); + static void StartCancel(void* arg, grpc_error* error); + static void OnCancelComplete(void* arg, grpc_error* error); + + static void OnByteStreamNext(void* arg, grpc_error* error); + void ContinueReadingRecvMessage(); + grpc_error* PullSliceFromRecvMessage(); + void DoneReadingRecvMessage(grpc_error* error); + + RefCountedPtr<HealthCheckClient> health_check_client_; + grpc_polling_entity pollent_; + + gpr_arena* arena_; + grpc_call_combiner call_combiner_; + grpc_call_context_element context_[GRPC_CONTEXT_COUNT]; + + // The streaming call to the backend. Always non-NULL. + grpc_subchannel_call* call_; + + grpc_transport_stream_op_batch_payload payload_; + grpc_transport_stream_op_batch batch_; + grpc_transport_stream_op_batch recv_message_batch_; + grpc_transport_stream_op_batch recv_trailing_metadata_batch_; + + grpc_closure on_complete_; + + // send_initial_metadata + grpc_metadata_batch send_initial_metadata_; + grpc_linked_mdelem path_metadata_storage_; + + // send_message + ManualConstructor<SliceBufferByteStream> send_message_; + + // send_trailing_metadata + grpc_metadata_batch send_trailing_metadata_; + + // recv_initial_metadata + grpc_metadata_batch recv_initial_metadata_; + grpc_closure recv_initial_metadata_ready_; + + // recv_message + OrphanablePtr<ByteStream> recv_message_; + grpc_closure recv_message_ready_; + grpc_slice_buffer recv_message_buffer_; + gpr_atm seen_response_; + + // recv_trailing_metadata + grpc_metadata_batch recv_trailing_metadata_; + grpc_transport_stream_stats collect_stats_; + grpc_closure recv_trailing_metadata_ready_; + }; + + void StartCall(); + void StartCallLocked(); // Requires holding mu_. + + void StartRetryTimer(); + static void OnRetryTimer(void* arg, grpc_error* error); + + void SetHealthStatus(grpc_connectivity_state state, grpc_error* error); + void SetHealthStatusLocked(grpc_connectivity_state state, + grpc_error* error); // Requires holding mu_. + + const char* service_name_; // Do not own. + RefCountedPtr<ConnectedSubchannel> connected_subchannel_; + grpc_pollset_set* interested_parties_; // Do not own. + RefCountedPtr<channelz::SubchannelNode> channelz_node_; + + gpr_mu mu_; + grpc_connectivity_state state_ = GRPC_CHANNEL_CONNECTING; + grpc_error* error_ = GRPC_ERROR_NONE; + grpc_connectivity_state* notify_state_ = nullptr; + grpc_closure* on_health_changed_ = nullptr; + bool shutting_down_ = false; + + // The data associated with the current health check call. It holds a ref + // to this HealthCheckClient object. + OrphanablePtr<CallState> call_state_; + + // Call retry state. + BackOff retry_backoff_; + grpc_timer retry_timer_; + grpc_closure retry_timer_callback_; + bool retry_timer_callback_pending_ = false; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_CLIENT_H */ diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 5511df7a27..17e0d26875 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1699,7 +1699,7 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { // Replace the LB addresses in the channel args that we pass down to // the subchannel. static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES}; - const grpc_arg args_to_add[] = { + grpc_arg args_to_add[3] = { grpc_lb_addresses_create_channel_arg(addresses), // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. @@ -1708,9 +1708,15 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), is_backend_from_grpclb_load_balancer), }; + size_t num_args_to_add = 2; + if (is_backend_from_grpclb_load_balancer) { + args_to_add[2] = grpc_channel_arg_integer_create( + const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); + ++num_args_to_add; + } grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, - GPR_ARRAY_SIZE(args_to_add)); + num_args_to_add); grpc_lb_addresses_destroy(addresses); return args; } diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index f4dca146f7..eb494486b9 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -359,9 +359,14 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) { "Pick First %p received update with %" PRIuPTR " addresses", this, addresses->num_addresses); } + grpc_arg new_arg = grpc_channel_arg_integer_create( + const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(&args, &new_arg, 1); auto subchannel_list = MakeOrphanable<PickFirstSubchannelList>( this, &grpc_lb_pick_first_trace, addresses, combiner(), - client_channel_factory(), args); + client_channel_factory(), *new_args); + grpc_channel_args_destroy(new_args); if (subchannel_list->num_subchannels() == 0) { // Empty update or no valid subchannels. Unsubscribe from all current // subchannels and put the channel in TRANSIENT_FAILURE. diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index e0e0e1e638..4ec9e935ed 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -102,8 +102,8 @@ class SubchannelData { // ProcessConnectivityChangeLocked()). grpc_connectivity_state CheckConnectivityStateLocked(grpc_error** error) { GPR_ASSERT(!connectivity_notification_pending_); - pending_connectivity_state_unsafe_ = - grpc_subchannel_check_connectivity(subchannel(), error); + pending_connectivity_state_unsafe_ = grpc_subchannel_check_connectivity( + subchannel(), error, subchannel_list_->inhibit_health_checking()); UpdateConnectedSubchannelLocked(); return pending_connectivity_state_unsafe_; } @@ -216,6 +216,7 @@ class SubchannelList // Accessors. LoadBalancingPolicy* policy() const { return policy_; } TraceFlag* tracer() const { return tracer_; } + bool inhibit_health_checking() const { return inhibit_health_checking_; } // Resets connection backoff of all subchannels. // TODO(roth): We will probably need to rethink this as part of moving @@ -254,6 +255,8 @@ class SubchannelList TraceFlag* tracer_; + bool inhibit_health_checking_; + grpc_combiner* combiner_; // The list of subchannels. @@ -340,7 +343,8 @@ void SubchannelData<SubchannelListType, subchannel_list()->Ref(DEBUG_LOCATION, "connectivity_watch").release(); grpc_subchannel_notify_on_state_change( subchannel_, subchannel_list_->policy()->interested_parties(), - &pending_connectivity_state_unsafe_, &connectivity_changed_closure_); + &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, + subchannel_list_->inhibit_health_checking()); } template <typename SubchannelListType, typename SubchannelDataType> @@ -359,7 +363,8 @@ void SubchannelData<SubchannelListType, GPR_ASSERT(connectivity_notification_pending_); grpc_subchannel_notify_on_state_change( subchannel_, subchannel_list_->policy()->interested_parties(), - &pending_connectivity_state_unsafe_, &connectivity_changed_closure_); + &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, + subchannel_list_->inhibit_health_checking()); } template <typename SubchannelListType, typename SubchannelDataType> @@ -390,8 +395,9 @@ void SubchannelData<SubchannelListType, SubchannelDataType>:: subchannel_, reason); } GPR_ASSERT(connectivity_notification_pending_); - grpc_subchannel_notify_on_state_change(subchannel_, nullptr, nullptr, - &connectivity_changed_closure_); + grpc_subchannel_notify_on_state_change( + subchannel_, nullptr, nullptr, &connectivity_changed_closure_, + subchannel_list_->inhibit_health_checking()); } template <typename SubchannelListType, typename SubchannelDataType> @@ -499,8 +505,13 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList( subchannels_.reserve(addresses->num_addresses); // We need to remove the LB addresses in order to be able to compare the // subchannel keys of subchannels from a different batch of addresses. + // We also remove the inhibit-health-checking arg, since we are + // handling that here. + inhibit_health_checking_ = grpc_channel_arg_get_bool( + grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false); static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS, - GRPC_ARG_LB_ADDRESSES}; + GRPC_ARG_LB_ADDRESSES, + GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. grpc_subchannel_args sc_args; for (size_t i = 0; i < addresses->num_addresses; i++) { diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index a0a40eb2b3..e4c6efe862 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -30,6 +30,7 @@ #include <grpc/support/string_util.h> #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/health/health_check_client.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" @@ -41,6 +42,7 @@ #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/iomgr/timer.h" @@ -50,6 +52,7 @@ #include "src/core/lib/surface/channel_init.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/error_utils.h" +#include "src/core/lib/transport/service_config.h" #include "src/core/lib/transport/status_metadata.h" #define INTERNAL_REF_BITS 16 @@ -66,6 +69,10 @@ struct state_watcher { grpc_closure closure; grpc_subchannel* subchannel; grpc_connectivity_state connectivity_state; + grpc_connectivity_state last_connectivity_state; + grpc_core::OrphanablePtr<grpc_core::HealthCheckClient> health_check_client; + grpc_closure health_check_closure; + grpc_connectivity_state health_state; }; } // namespace @@ -78,6 +85,12 @@ typedef struct external_state_watcher { struct external_state_watcher* prev; } external_state_watcher; +namespace grpc_core { + +class ConnectedSubchannelStateWatcher; + +} // namespace grpc_core + struct grpc_subchannel { grpc_connector* connector; @@ -109,19 +122,24 @@ struct grpc_subchannel { being setup */ grpc_pollset_set* pollset_set; + grpc_core::UniquePtr<char> health_check_service_name; + /** mutex protecting remaining elements */ gpr_mu mu; - /** active connection, or null; of type grpc_core::ConnectedSubchannel - */ + /** active connection, or null */ grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel> connected_subchannel; + grpc_core::OrphanablePtr<grpc_core::ConnectedSubchannelStateWatcher> + connected_subchannel_watcher; /** have we seen a disconnection? */ bool disconnected; /** are we connecting */ bool connecting; + /** connectivity state tracking */ grpc_connectivity_state_tracker state_tracker; + grpc_connectivity_state_tracker state_and_health_tracker; external_state_watcher root_external_state_watcher; @@ -153,6 +171,171 @@ struct grpc_subchannel_call { grpc_millis deadline; }; +static void maybe_start_connecting_locked(grpc_subchannel* c); + +static const char* subchannel_connectivity_state_change_string( + grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "Subchannel state change to IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "Subchannel state change to CONNECTING"; + case GRPC_CHANNEL_READY: + return "Subchannel state change to READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "Subchannel state change to TRANSIENT_FAILURE"; + case GRPC_CHANNEL_SHUTDOWN: + return "Subchannel state change to SHUTDOWN"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +static void set_subchannel_connectivity_state_locked( + grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error, + const char* reason) { + if (c->channelz_subchannel != nullptr) { + c->channelz_subchannel->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + subchannel_connectivity_state_change_string(state))); + } + grpc_connectivity_state_set(&c->state_tracker, state, error, reason); +} + +namespace grpc_core { + +class ConnectedSubchannelStateWatcher + : public InternallyRefCounted<ConnectedSubchannelStateWatcher> { + public: + // Must be instantiated while holding c->mu. + explicit ConnectedSubchannelStateWatcher(grpc_subchannel* c) + : subchannel_(c) { + // Steal subchannel ref for connecting. + GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "state_watcher"); + GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "connecting"); + // Start watching for connectivity state changes. + // Callback uses initial ref to this. + GRPC_CLOSURE_INIT(&on_connectivity_changed_, OnConnectivityChanged, this, + grpc_schedule_on_exec_ctx); + c->connected_subchannel->NotifyOnStateChange(c->pollset_set, + &pending_connectivity_state_, + &on_connectivity_changed_); + // Start health check if needed. + grpc_connectivity_state health_state = GRPC_CHANNEL_READY; + if (c->health_check_service_name != nullptr) { + health_check_client_ = grpc_core::MakeOrphanable<HealthCheckClient>( + c->health_check_service_name.get(), c->connected_subchannel, + c->pollset_set, c->channelz_subchannel); + GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this, + grpc_schedule_on_exec_ctx); + Ref().release(); // Ref for health callback tracked manually. + health_check_client_->NotifyOnHealthChange(&health_state_, + &on_health_changed_); + health_state = GRPC_CHANNEL_CONNECTING; + } + // Report initial state. + set_subchannel_connectivity_state_locked( + c, GRPC_CHANNEL_READY, GRPC_ERROR_NONE, "subchannel_connected"); + grpc_connectivity_state_set(&c->state_and_health_tracker, health_state, + GRPC_ERROR_NONE, "subchannel_connected"); + } + + ~ConnectedSubchannelStateWatcher() { + GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "state_watcher"); + } + + void Orphan() override { health_check_client_.reset(); } + + private: + static void OnConnectivityChanged(void* arg, grpc_error* error) { + auto* self = static_cast<ConnectedSubchannelStateWatcher*>(arg); + grpc_subchannel* c = self->subchannel_; + { + MutexLock lock(&c->mu); + switch (self->pending_connectivity_state_) { + case GRPC_CHANNEL_TRANSIENT_FAILURE: + case GRPC_CHANNEL_SHUTDOWN: { + if (!c->disconnected && c->connected_subchannel != nullptr) { + if (grpc_trace_stream_refcount.enabled()) { + gpr_log(GPR_INFO, + "Connected subchannel %p of subchannel %p has gone into " + "%s. Attempting to reconnect.", + c->connected_subchannel.get(), c, + grpc_connectivity_state_name( + self->pending_connectivity_state_)); + } + c->connected_subchannel.reset(); + c->connected_subchannel_watcher.reset(); + self->last_connectivity_state_ = GRPC_CHANNEL_TRANSIENT_FAILURE; + set_subchannel_connectivity_state_locked( + c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + "reflect_child"); + grpc_connectivity_state_set(&c->state_and_health_tracker, + GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_REF(error), "reflect_child"); + c->backoff_begun = false; + c->backoff->Reset(); + maybe_start_connecting_locked(c); + } else { + self->last_connectivity_state_ = GRPC_CHANNEL_SHUTDOWN; + } + self->health_check_client_.reset(); + break; + } + default: { + // In principle, this should never happen. We should not get + // a callback for READY, because that was the state we started + // this watch from. And a connected subchannel should never go + // from READY to CONNECTING or IDLE. + self->last_connectivity_state_ = self->pending_connectivity_state_; + set_subchannel_connectivity_state_locked( + c, self->pending_connectivity_state_, GRPC_ERROR_REF(error), + "reflect_child"); + if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) { + grpc_connectivity_state_set(&c->state_and_health_tracker, + self->pending_connectivity_state_, + GRPC_ERROR_REF(error), "reflect_child"); + } + c->connected_subchannel->NotifyOnStateChange( + nullptr, &self->pending_connectivity_state_, + &self->on_connectivity_changed_); + self = nullptr; // So we don't unref below. + } + } + } + // Don't unref until we've released the lock, because this might + // cause the subchannel (which contains the lock) to be destroyed. + if (self != nullptr) self->Unref(); + } + + static void OnHealthChanged(void* arg, grpc_error* error) { + auto* self = static_cast<ConnectedSubchannelStateWatcher*>(arg); + if (self->health_state_ == GRPC_CHANNEL_SHUTDOWN) { + self->Unref(); + return; + } + grpc_subchannel* c = self->subchannel_; + MutexLock lock(&c->mu); + if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) { + grpc_connectivity_state_set(&c->state_and_health_tracker, + self->health_state_, GRPC_ERROR_REF(error), + "health_changed"); + } + self->health_check_client_->NotifyOnHealthChange(&self->health_state_, + &self->on_health_changed_); + } + + grpc_subchannel* subchannel_; + grpc_closure on_connectivity_changed_; + grpc_connectivity_state pending_connectivity_state_ = GRPC_CHANNEL_READY; + grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_READY; + grpc_core::OrphanablePtr<grpc_core::HealthCheckClient> health_check_client_; + grpc_closure on_health_changed_; + grpc_connectivity_state health_state_ = GRPC_CHANNEL_CONNECTING; +}; + +} // namespace grpc_core + #define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ (grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ sizeof(grpc_subchannel_call))) @@ -198,8 +381,10 @@ static void subchannel_destroy(void* arg, grpc_error* error) { c->channelz_subchannel.reset(); } gpr_free((void*)c->filters); + c->health_check_service_name.reset(); grpc_channel_args_destroy(c->args); grpc_connectivity_state_destroy(&c->state_tracker); + grpc_connectivity_state_destroy(&c->state_and_health_tracker); grpc_connector_unref(c->connector); grpc_pollset_set_destroy(c->pollset_set); grpc_subchannel_key_destroy(c->key); @@ -262,6 +447,7 @@ static void disconnect(grpc_subchannel* c) { grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Subchannel disconnected")); c->connected_subchannel.reset(); + c->connected_subchannel_watcher.reset(); gpr_mu_unlock(&c->mu); } @@ -337,6 +523,31 @@ static void parse_args_for_backoff_values( .set_max_backoff(max_backoff_ms); } +namespace grpc_core { +namespace { + +struct HealthCheckParams { + UniquePtr<char> service_name; + + static void Parse(const grpc_json* field, HealthCheckParams* params) { + if (strcmp(field->key, "healthCheckConfig") == 0) { + if (field->type != GRPC_JSON_OBJECT) return; + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) return; + if (strcmp(sub_field->key, "serviceName") == 0) { + if (params->service_name != nullptr) return; // Duplicate. + if (sub_field->type != GRPC_JSON_STRING) return; + params->service_name.reset(gpr_strdup(sub_field->value)); + } + } + } + } +}; + +} // namespace +} // namespace grpc_core + grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, const grpc_subchannel_args* args) { grpc_subchannel_key* key = grpc_subchannel_key_create(args); @@ -387,12 +598,28 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, grpc_schedule_on_exec_ctx); grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE, "subchannel"); + grpc_connectivity_state_init(&c->state_and_health_tracker, GRPC_CHANNEL_IDLE, + "subchannel"); grpc_core::BackOff::Options backoff_options; parse_args_for_backoff_values(args->args, &backoff_options, &c->min_connect_timeout_ms); c->backoff.Init(backoff_options); gpr_mu_init(&c->mu); + // Check whether we should enable health checking. + const char* service_config_json = grpc_channel_arg_get_string( + grpc_channel_args_find(c->args, GRPC_ARG_SERVICE_CONFIG)); + if (service_config_json != nullptr) { + grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config = + grpc_core::ServiceConfig::Create(service_config_json); + if (service_config != nullptr) { + grpc_core::HealthCheckParams params; + service_config->ParseGlobalParams(grpc_core::HealthCheckParams::Parse, + ¶ms); + c->health_check_service_name = std::move(params.service_name); + } + } + const grpc_arg* arg = grpc_channel_args_find(c->args, GRPC_ARG_ENABLE_CHANNELZ); bool channelz_enabled = @@ -428,35 +655,6 @@ intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel) { } } -static const char* subchannel_connectivity_state_change_string( - grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "Subchannel state change to IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "Subchannel state change to CONNECTING"; - case GRPC_CHANNEL_READY: - return "Subchannel state change to READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "Subchannel state change to TRANSIENT_FAILURE"; - case GRPC_CHANNEL_SHUTDOWN: - return "Subchannel state change to SHUTDOWN"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -static void set_subchannel_connectivity_state_locked( - grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error, - const char* reason) { - if (c->channelz_subchannel != nullptr) { - c->channelz_subchannel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - subchannel_connectivity_state_change_string(state))); - } - grpc_connectivity_state_set(&c->state_tracker, state, error, reason); -} - static void continue_connect_locked(grpc_subchannel* c) { grpc_connect_in_args args; args.interested_parties = c->pollset_set; @@ -467,15 +665,19 @@ static void continue_connect_locked(grpc_subchannel* c) { args.channel_args = c->args; set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, "connecting"); + grpc_connectivity_state_set(&c->state_and_health_tracker, + GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + "connecting"); grpc_connector_connect(c->connector, &args, &c->connecting_result, &c->on_connected); } -grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel* c, - grpc_error** error) { - grpc_connectivity_state state; +grpc_connectivity_state grpc_subchannel_check_connectivity( + grpc_subchannel* c, grpc_error** error, bool inhibit_health_checks) { gpr_mu_lock(&c->mu); - state = grpc_connectivity_state_get(&c->state_tracker, error); + grpc_connectivity_state_tracker* tracker = + inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; + grpc_connectivity_state state = grpc_connectivity_state_get(tracker, error); gpr_mu_unlock(&c->mu); return state; } @@ -533,7 +735,8 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) { /* Already connected: don't restart */ return; } - if (!grpc_connectivity_state_has_watchers(&c->state_tracker)) { + if (!grpc_connectivity_state_has_watchers(&c->state_tracker) && + !grpc_connectivity_state_has_watchers(&c->state_and_health_tracker)) { /* Nobody is interested in connecting: so don't just yet */ return; } @@ -560,16 +763,18 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) { void grpc_subchannel_notify_on_state_change( grpc_subchannel* c, grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, grpc_closure* notify) { + grpc_connectivity_state* state, grpc_closure* notify, + bool inhibit_health_checks) { + grpc_connectivity_state_tracker* tracker = + inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; external_state_watcher* w; - if (state == nullptr) { gpr_mu_lock(&c->mu); for (w = c->root_external_state_watcher.next; w != &c->root_external_state_watcher; w = w->next) { if (w->notify == notify) { - grpc_connectivity_state_notify_on_state_change(&c->state_tracker, - nullptr, &w->closure); + grpc_connectivity_state_notify_on_state_change(tracker, nullptr, + &w->closure); } } gpr_mu_unlock(&c->mu); @@ -588,62 +793,12 @@ 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; - grpc_connectivity_state_notify_on_state_change(&c->state_tracker, state, - &w->closure); + grpc_connectivity_state_notify_on_state_change(tracker, state, &w->closure); maybe_start_connecting_locked(c); gpr_mu_unlock(&c->mu); } } -static void on_connected_subchannel_connectivity_changed(void* p, - grpc_error* error) { - state_watcher* connected_subchannel_watcher = static_cast<state_watcher*>(p); - grpc_subchannel* c = connected_subchannel_watcher->subchannel; - gpr_mu* mu = &c->mu; - - gpr_mu_lock(mu); - - switch (connected_subchannel_watcher->connectivity_state) { - case GRPC_CHANNEL_TRANSIENT_FAILURE: - case GRPC_CHANNEL_SHUTDOWN: { - if (!c->disconnected && c->connected_subchannel != nullptr) { - if (grpc_trace_stream_refcount.enabled()) { - gpr_log(GPR_INFO, - "Connected subchannel %p of subchannel %p has gone into %s. " - "Attempting to reconnect.", - c->connected_subchannel.get(), c, - grpc_connectivity_state_name( - connected_subchannel_watcher->connectivity_state)); - } - c->connected_subchannel.reset(); - set_subchannel_connectivity_state_locked( - c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - "reflect_child"); - c->backoff_begun = false; - c->backoff->Reset(); - maybe_start_connecting_locked(c); - } else { - connected_subchannel_watcher->connectivity_state = - GRPC_CHANNEL_SHUTDOWN; - } - break; - } - default: { - set_subchannel_connectivity_state_locked( - c, connected_subchannel_watcher->connectivity_state, - GRPC_ERROR_REF(error), "reflect_child"); - GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); - c->connected_subchannel->NotifyOnStateChange( - nullptr, &connected_subchannel_watcher->connectivity_state, - &connected_subchannel_watcher->closure); - connected_subchannel_watcher = nullptr; - } - } - gpr_mu_unlock(mu); - GRPC_SUBCHANNEL_WEAK_UNREF(c, "state_watcher"); - gpr_free(connected_subchannel_watcher); -} - static bool publish_transport_locked(grpc_subchannel* c) { /* construct channel stack */ grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); @@ -670,17 +825,7 @@ static bool publish_transport_locked(grpc_subchannel* c) { intptr_t socket_uuid = c->connecting_result.socket_uuid; memset(&c->connecting_result, 0, sizeof(c->connecting_result)); - /* initialize state watcher */ - state_watcher* connected_subchannel_watcher = static_cast<state_watcher*>( - gpr_zalloc(sizeof(*connected_subchannel_watcher))); - connected_subchannel_watcher->subchannel = c; - connected_subchannel_watcher->connectivity_state = GRPC_CHANNEL_READY; - GRPC_CLOSURE_INIT(&connected_subchannel_watcher->closure, - on_connected_subchannel_connectivity_changed, - connected_subchannel_watcher, grpc_schedule_on_exec_ctx); - if (c->disconnected) { - gpr_free(connected_subchannel_watcher); grpc_channel_stack_destroy(stk); gpr_free(stk); return false; @@ -692,17 +837,10 @@ static bool publish_transport_locked(grpc_subchannel* c) { gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", c->connected_subchannel.get(), c); - /* setup subchannel watching connected subchannel for changes; subchannel - ref for connecting is donated to the state watcher */ - GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); - GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); - c->connected_subchannel->NotifyOnStateChange( - c->pollset_set, &connected_subchannel_watcher->connectivity_state, - &connected_subchannel_watcher->closure); - - /* signal completion */ - set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_READY, - GRPC_ERROR_NONE, "connected"); + // Instantiate state watcher. Will clean itself up. + c->connected_subchannel_watcher = + grpc_core::MakeOrphanable<grpc_core::ConnectedSubchannelStateWatcher>(c); + return true; } @@ -725,6 +863,12 @@ static void on_subchannel_connected(void* arg, grpc_error* error) { "Connect Failed", &error, 1), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), "connect_failed"); + grpc_connectivity_state_set( + &c->state_and_health_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE, + grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Connect Failed", &error, 1), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), + "connect_failed"); const char* errmsg = grpc_error_string(error); gpr_log(GPR_INFO, "Connect failed: %s", errmsg); @@ -956,15 +1100,8 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate, grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, grpc_subchannel_call** call) { - size_t allocation_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); - if (args.parent_data_size > 0) { - allocation_size += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + - args.parent_data_size; - } else { - allocation_size += channel_stack_->call_stack_size; - } + const size_t allocation_size = + GetInitialCallSizeEstimate(args.parent_data_size); *call = static_cast<grpc_subchannel_call*>( gpr_arena_alloc(args.arena, allocation_size)); grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); @@ -994,4 +1131,18 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, return GRPC_ERROR_NONE; } +size_t ConnectedSubchannel::GetInitialCallSizeEstimate( + size_t parent_data_size) const { + size_t allocation_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); + if (parent_data_size > 0) { + allocation_size += + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + + parent_data_size; + } else { + allocation_size += channel_stack_->call_stack_size; + } + return allocation_size; +} + } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index c53b13e37e..ec3b4d86e4 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -103,6 +103,8 @@ class ConnectedSubchannel : public RefCountedWithTracing<ConnectedSubchannel> { } intptr_t socket_uuid() { return socket_uuid_; } + size_t GetInitialCallSizeEstimate(size_t parent_data_size) const; + private: grpc_channel_stack* channel_stack_; // ref counted pointer to the channelz node in this connected subchannel's @@ -143,13 +145,14 @@ void* grpc_connected_subchannel_call_get_parent_data( /** poll the current connectivity state of a channel */ grpc_connectivity_state grpc_subchannel_check_connectivity( - grpc_subchannel* channel, grpc_error** error); + grpc_subchannel* channel, grpc_error** error, bool inhibit_health_checking); /** Calls notify when the connectivity state of a channel becomes different from *state. Updates *state with the new state of the channel. */ void grpc_subchannel_notify_on_state_change( grpc_subchannel* channel, grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, grpc_closure* notify); + grpc_connectivity_state* state, grpc_closure* notify, + bool inhibit_health_checks); /** retrieve the grpc_core::ConnectedSubchannel - or nullptr if not connected * (which may happen before it initially connects or during transient failures) diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 5229304fa4..60a32022f5 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -163,9 +163,8 @@ static void start_handshake_locked(chttp2_connector* c) { c->args.interested_parties, c->handshake_mgr); grpc_endpoint_add_to_pollset_set(c->endpoint, c->args.interested_parties); grpc_handshake_manager_do_handshake( - c->handshake_mgr, c->args.interested_parties, c->endpoint, - c->args.channel_args, c->args.deadline, nullptr /* acceptor */, - on_handshake_done, c); + c->handshake_mgr, c->endpoint, c->args.channel_args, c->args.deadline, + nullptr /* acceptor */, on_handshake_done, c); c->endpoint = nullptr; // Endpoint handed off to handshake manager. } @@ -213,9 +212,17 @@ static void chttp2_connector_connect(grpc_connector* con, GRPC_CLOSURE_INIT(&c->connected, connected, c, grpc_schedule_on_exec_ctx); GPR_ASSERT(!c->connecting); c->connecting = true; - grpc_tcp_client_connect(&c->connected, &c->endpoint, args->interested_parties, - args->channel_args, &addr, args->deadline); + grpc_closure* closure = &c->connected; + grpc_endpoint** ep = &c->endpoint; gpr_mu_unlock(&c->mu); + // In some implementations, the closure can be flushed before + // grpc_tcp_client_connect and since the closure requires access to c->mu, + // this can result in a deadlock. Refer + // https://github.com/grpc/grpc/issues/16427 + // grpc_tcp_client_connect would fill c->endpoint with proper contents and we + // make sure that we would still exist at that point by taking a ref. + grpc_tcp_client_connect(closure, ep, args->interested_parties, + args->channel_args, &addr, args->deadline); } static const grpc_connector_vtable chttp2_connector_vtable = { diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 6ed88dfb5e..bdb2339e40 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -39,6 +39,7 @@ #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/api_trace.h" @@ -114,9 +115,16 @@ static void on_handshake_done(void* arg, grpc_error* error) { server_connection_state* connection_state = static_cast<server_connection_state*>(args->user_data); gpr_mu_lock(&connection_state->svr_state->mu); + grpc_resource_user* resource_user = grpc_server_get_default_resource_user( + connection_state->svr_state->server); if (error != GRPC_ERROR_NONE || connection_state->svr_state->shutdown) { const char* error_str = grpc_error_string(error); gpr_log(GPR_DEBUG, "Handshaking failed: %s", error_str); + grpc_resource_user* resource_user = grpc_server_get_default_resource_user( + connection_state->svr_state->server); + if (resource_user != nullptr) { + grpc_resource_user_free(resource_user, GRPC_RESOURCE_QUOTA_CHANNEL_SIZE); + } if (error == GRPC_ERROR_NONE && args->endpoint != nullptr) { // We were shut down after handshaking completed successfully, so // destroy the endpoint here. @@ -134,13 +142,14 @@ static void on_handshake_done(void* arg, grpc_error* error) { // If the handshaking succeeded but there is no endpoint, then the // handshaker may have handed off the connection to some external // code, so we can just clean up here without creating a transport. + // TODO(juanlishen): Do we need to free the memory to resource user? if (args->endpoint != nullptr) { - grpc_transport* transport = - grpc_create_chttp2_transport(args->args, args->endpoint, false); + grpc_transport* transport = grpc_create_chttp2_transport( + args->args, args->endpoint, false, resource_user); grpc_server_setup_transport( connection_state->svr_state->server, transport, connection_state->accepting_pollset, args->args, - grpc_chttp2_transport_get_socket_uuid(transport)); + grpc_chttp2_transport_get_socket_uuid(transport), resource_user); // Use notify_on_receive_settings callback to enforce the // handshake deadline. connection_state->transport = @@ -183,6 +192,20 @@ static void on_accept(void* arg, grpc_endpoint* tcp, gpr_free(acceptor); return; } + grpc_resource_user* resource_user = + grpc_server_get_default_resource_user(state->server); + if (resource_user != nullptr && + !grpc_resource_user_safe_alloc(resource_user, + GRPC_RESOURCE_QUOTA_CHANNEL_SIZE)) { + gpr_log( + GPR_ERROR, + "Memory quota exhausted, rejecting the connection, no handshaking."); + gpr_mu_unlock(&state->mu); + grpc_endpoint_shutdown(tcp, GRPC_ERROR_NONE); + grpc_endpoint_destroy(tcp); + gpr_free(acceptor); + return; + } grpc_handshake_manager* handshake_mgr = grpc_handshake_manager_create(); grpc_handshake_manager_pending_list_add(&state->pending_handshake_mgrs, handshake_mgr); @@ -208,10 +231,10 @@ static void on_accept(void* arg, grpc_endpoint* tcp, grpc_core::ExecCtx::Get()->Now() + grpc_channel_arg_get_integer(timeout_arg, {120 * GPR_MS_PER_SEC, 1, INT_MAX}); - grpc_handshake_manager_do_handshake( - connection_state->handshake_mgr, nullptr /* interested_parties */, tcp, - state->args, connection_state->deadline, acceptor, on_handshake_done, - connection_state); + grpc_handshake_manager_do_handshake(connection_state->handshake_mgr, tcp, + state->args, connection_state->deadline, + acceptor, on_handshake_done, + connection_state); } /* Server callback: start listening on our ports */ diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 8a481bb7d5..04874a9494 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -478,7 +478,8 @@ static void init_keepalive_pings_if_enabled(grpc_chttp2_transport* t) { static void init_transport(grpc_chttp2_transport* t, const grpc_channel_args* channel_args, - grpc_endpoint* ep, bool is_client) { + grpc_endpoint* ep, bool is_client, + grpc_resource_user* resource_user) { GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) == GRPC_CHTTP2_CLIENT_CONNECT_STRLEN); @@ -491,6 +492,7 @@ static void init_transport(grpc_chttp2_transport* t, t->endpoint_reading = 1; t->next_stream_id = is_client ? 1 : 2; t->is_client = is_client; + t->resource_user = resource_user; t->deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0; t->is_first_frame = true; grpc_connectivity_state_init( @@ -778,6 +780,10 @@ static void destroy_stream_locked(void* sp, grpc_error* error) { s->flow_control.Destroy(); + if (t->resource_user != nullptr) { + grpc_resource_user_free(t->resource_user, GRPC_RESOURCE_QUOTA_CALL_SIZE); + } + GRPC_CHTTP2_UNREF_TRANSPORT(t, "stream"); GRPC_CLOSURE_SCHED(s->destroy_stream_arg, GRPC_ERROR_NONE); @@ -816,7 +822,21 @@ grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t, if (t->channel_callback.accept_stream == nullptr) { return nullptr; } - grpc_chttp2_stream* accepting; + // Don't accept the stream if memory quota doesn't allow. Note that we should + // simply refuse the stream here instead of canceling the stream after it's + // accepted since the latter will create the call which costs much memory. + if (t->resource_user != nullptr && + !grpc_resource_user_safe_alloc(t->resource_user, + GRPC_RESOURCE_QUOTA_CALL_SIZE)) { + gpr_log(GPR_ERROR, "Memory exhausted, rejecting the stream."); + grpc_slice_buffer_add( + &t->qbuf, + grpc_chttp2_rst_stream_create( + id, static_cast<uint32_t>(GRPC_HTTP2_REFUSED_STREAM), nullptr)); + grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM); + return nullptr; + } + grpc_chttp2_stream* accepting = nullptr; GPR_ASSERT(t->accepting_stream == nullptr); t->accepting_stream = &accepting; t->channel_callback.accept_stream(t->channel_callback.accept_stream_user_data, @@ -3185,10 +3205,11 @@ intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport) { } grpc_transport* grpc_create_chttp2_transport( - const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client) { + const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, + grpc_resource_user* resource_user) { grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>( gpr_zalloc(sizeof(grpc_chttp2_transport))); - init_transport(t, channel_args, ep, is_client); + init_transport(t, channel_args, ep, is_client, resource_user); return &t->base; } diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h index e5872fee43..b3fe1c082e 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h @@ -32,7 +32,8 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_chttp2_refcount; extern bool g_flow_control_enabled; grpc_transport* grpc_create_chttp2_transport( - const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client); + const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, + grpc_resource_user* resource_user = nullptr); intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport); diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc index 4bdd4309a4..a0a7534594 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc @@ -32,7 +32,7 @@ grpc_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code, grpc_transport_one_way_stats* stats) { static const size_t frame_size = 13; grpc_slice slice = GRPC_SLICE_MALLOC(frame_size); - stats->framing_bytes += frame_size; + if (stats != nullptr) stats->framing_bytes += frame_size; uint8_t* p = GRPC_SLICE_START_PTR(slice); // Frame size. diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index ff26dd9255..202017641b 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -285,6 +285,8 @@ struct grpc_chttp2_transport { grpc_endpoint* ep; char* peer_string; + grpc_resource_user* resource_user; + grpc_combiner* combiner; grpc_closure* notify_on_receive_settings; diff --git a/src/core/lib/channel/channel_stack_builder.cc b/src/core/lib/channel/channel_stack_builder.cc index df5a783631..8b3008f221 100644 --- a/src/core/lib/channel/channel_stack_builder.cc +++ b/src/core/lib/channel/channel_stack_builder.cc @@ -40,6 +40,7 @@ struct grpc_channel_stack_builder { // various set/get-able parameters grpc_channel_args* args; grpc_transport* transport; + grpc_resource_user* resource_user; char* target; const char* name; }; @@ -157,6 +158,11 @@ void grpc_channel_stack_builder_set_channel_arguments( builder->args = grpc_channel_args_copy(args); } +const grpc_channel_args* grpc_channel_stack_builder_get_channel_arguments( + grpc_channel_stack_builder* builder) { + return builder->args; +} + void grpc_channel_stack_builder_set_transport( grpc_channel_stack_builder* builder, grpc_transport* transport) { GPR_ASSERT(builder->transport == nullptr); @@ -168,9 +174,15 @@ grpc_transport* grpc_channel_stack_builder_get_transport( return builder->transport; } -const grpc_channel_args* grpc_channel_stack_builder_get_channel_arguments( +void grpc_channel_stack_builder_set_resource_user( + grpc_channel_stack_builder* builder, grpc_resource_user* resource_user) { + GPR_ASSERT(builder->resource_user == nullptr); + builder->resource_user = resource_user; +} + +grpc_resource_user* grpc_channel_stack_builder_get_resource_user( grpc_channel_stack_builder* builder) { - return builder->args; + return builder->resource_user; } bool grpc_channel_stack_builder_append_filter( diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h index 9196de9378..89c30e0c5e 100644 --- a/src/core/lib/channel/channel_stack_builder.h +++ b/src/core/lib/channel/channel_stack_builder.h @@ -54,6 +54,14 @@ void grpc_channel_stack_builder_set_transport( grpc_transport* grpc_channel_stack_builder_get_transport( grpc_channel_stack_builder* builder); +/// Attach \a resource_user to the builder (does not take ownership) +void grpc_channel_stack_builder_set_resource_user( + grpc_channel_stack_builder* builder, grpc_resource_user* resource_user); + +/// Fetch attached resource user +grpc_resource_user* grpc_channel_stack_builder_get_resource_user( + grpc_channel_stack_builder* builder); + /// Set channel arguments: copies args void grpc_channel_stack_builder_set_channel_arguments( grpc_channel_stack_builder* builder, const grpc_channel_args* args); diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index e90a9e1f7f..1fe2fad3e1 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -79,12 +79,13 @@ void ChannelzRegistry::MaybePerformCompactionLocked() { } } -int ChannelzRegistry::FindByUuidLocked(intptr_t target_uuid) { - size_t left = 0; - size_t right = entities_.size() - 1; +int ChannelzRegistry::FindByUuidLocked(intptr_t target_uuid, + bool direct_hit_needed) { + int left = 0; + int right = int(entities_.size() - 1); while (left <= right) { - size_t true_middle = left + (right - left) / 2; - size_t first_non_null = true_middle; + int true_middle = left + (right - left) / 2; + int first_non_null = true_middle; while (first_non_null < right && entities_[first_non_null] == nullptr) { first_non_null++; } @@ -102,14 +103,14 @@ int ChannelzRegistry::FindByUuidLocked(intptr_t target_uuid) { right = true_middle - 1; } } - return -1; + return direct_hit_needed ? -1 : left; } void ChannelzRegistry::InternalUnregister(intptr_t uuid) { GPR_ASSERT(uuid >= 1); MutexLock lock(&mu_); GPR_ASSERT(uuid <= uuid_generator_); - int idx = FindByUuidLocked(uuid); + int idx = FindByUuidLocked(uuid, true); GPR_ASSERT(idx >= 0); entities_[idx] = nullptr; num_empty_slots_++; @@ -121,7 +122,7 @@ BaseNode* ChannelzRegistry::InternalGet(intptr_t uuid) { if (uuid < 1 || uuid > uuid_generator_) { return nullptr; } - int idx = FindByUuidLocked(uuid); + int idx = FindByUuidLocked(uuid, true); return idx < 0 ? nullptr : entities_[idx]; } @@ -131,16 +132,13 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; InlinedVector<BaseNode*, 10> top_level_channels; - // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is - // reserved). However, we want to support requests coming in with - // start_channel_id=0, which signifies "give me everything." Hence this - // funky looking line below. - size_t start_idx = start_channel_id == 0 ? 0 : start_channel_id - 1; bool reached_pagination_limit = false; + int start_idx = GPR_MAX(FindByUuidLocked(start_channel_id, false), 0); for (size_t i = start_idx; i < entities_.size(); ++i) { if (entities_[i] != nullptr && entities_[i]->type() == - grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel) { + grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel && + entities_[i]->uuid() >= start_channel_id) { // check if we are over pagination limit to determine if we need to set // the "end" element. If we don't go through this block, we know that // when the loop terminates, we have <= to kPaginationLimit. @@ -176,15 +174,13 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) { grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; InlinedVector<BaseNode*, 10> servers; - // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is - // reserved). However, we want to support requests coming in with - // start_server_id=0, which signifies "give me everything." - size_t start_idx = start_server_id == 0 ? 0 : start_server_id - 1; bool reached_pagination_limit = false; + int start_idx = GPR_MAX(FindByUuidLocked(start_server_id, false), 0); for (size_t i = start_idx; i < entities_.size(); ++i) { if (entities_[i] != nullptr && entities_[i]->type() == - grpc_core::channelz::BaseNode::EntityType::kServer) { + grpc_core::channelz::BaseNode::EntityType::kServer && + entities_[i]->uuid() >= start_server_id) { // check if we are over pagination limit to determine if we need to set // the "end" element. If we don't go through this block, we know that // when the loop terminates, we have <= to kPaginationLimit. diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h index ea6ab6c8e5..326f0201c7 100644 --- a/src/core/lib/channel/channelz_registry.h +++ b/src/core/lib/channel/channelz_registry.h @@ -92,7 +92,9 @@ class ChannelzRegistry { void MaybePerformCompactionLocked(); // Performs binary search on entities_ to find the index with that uuid. - int FindByUuidLocked(intptr_t uuid); + // If direct_hit_needed, then will return -1 in case of absence. + // Else, will return idx of the first uuid higher than the target. + int FindByUuidLocked(intptr_t uuid, bool direct_hit_needed); // protects members gpr_mu mu_; diff --git a/src/core/lib/channel/handshaker.cc b/src/core/lib/channel/handshaker.cc index ad3250b7e9..e516b56b74 100644 --- a/src/core/lib/channel/handshaker.cc +++ b/src/core/lib/channel/handshaker.cc @@ -292,17 +292,18 @@ static void on_timeout(void* arg, grpc_error* error) { grpc_handshake_manager_unref(mgr); } -void grpc_handshake_manager_do_handshake( - grpc_handshake_manager* mgr, grpc_pollset_set* interested_parties, - grpc_endpoint* endpoint, const grpc_channel_args* channel_args, - grpc_millis deadline, grpc_tcp_server_acceptor* acceptor, - grpc_iomgr_cb_func on_handshake_done, void* user_data) { +void grpc_handshake_manager_do_handshake(grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, + const grpc_channel_args* channel_args, + grpc_millis deadline, + grpc_tcp_server_acceptor* acceptor, + 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.interested_parties = interested_parties; mgr->args.endpoint = endpoint; mgr->args.args = grpc_channel_args_copy(channel_args); mgr->args.user_data = user_data; diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index be7fd127e4..a65990fceb 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -56,7 +56,6 @@ typedef struct grpc_handshaker grpc_handshaker; /// For the on_handshake_done callback, all members are input arguments, /// which the callback takes ownership of. typedef struct { - grpc_pollset_set* interested_parties; grpc_endpoint* endpoint; grpc_channel_args* args; grpc_slice_buffer* read_buffer; @@ -132,8 +131,6 @@ void grpc_handshake_manager_shutdown(grpc_handshake_manager* mgr, grpc_error* why); /// Invokes handshakers in the order they were added. -/// \a interested_parties may be non-nullptr to provide a pollset_set that -/// may be used during handshaking. Ownership is not taken. /// 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 @@ -145,11 +142,13 @@ void grpc_handshake_manager_shutdown(grpc_handshake_manager* mgr, /// 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_handshake_manager* mgr, grpc_pollset_set* interested_parties, - grpc_endpoint* endpoint, const grpc_channel_args* channel_args, - grpc_millis deadline, grpc_tcp_server_acceptor* acceptor, - grpc_iomgr_cb_func on_handshake_done, void* user_data); +void grpc_handshake_manager_do_handshake(grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, + const grpc_channel_args* channel_args, + grpc_millis deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_iomgr_cb_func on_handshake_done, + void* user_data); /// Add \a mgr to the server side list of all pending handshake managers, the /// list starts with \a *head. diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 5a5e0b72d5..1c798d368b 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "src/core/lib/security/transport/security_handshaker.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/tsi/ssl_transport_security.h" @@ -194,9 +195,8 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, grpc_handshakers_add(HANDSHAKER_CLIENT, &args, nullptr /* interested_parties */, c->handshake_mgr); grpc_handshake_manager_do_handshake( - c->handshake_mgr, nullptr /* interested_parties */, tcp, - nullptr /* channel_args */, deadline, nullptr /* acceptor */, - on_handshake_done, c /* user_data */); + c->handshake_mgr, tcp, nullptr /* channel_args */, deadline, + nullptr /* acceptor */, on_handshake_done, c /* user_data */); GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); } diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc index b6fc7579f7..7e4b3c9b2f 100644 --- a/src/core/lib/iomgr/resource_quota.cc +++ b/src/core/lib/iomgr/resource_quota.cc @@ -90,7 +90,8 @@ struct grpc_resource_user { grpc_closure_list on_allocated; /* True if we are currently trying to allocate from the quota, false if not */ bool allocating; - /* How many bytes of allocations are outstanding */ + /* The amount of memory (in bytes) that has been requested from this user + * asynchronously but hasn't been granted yet. */ int64_t outstanding_allocations; /* True if we are currently trying to add ourselves to the non-free quota list, false otherwise */ @@ -135,6 +136,9 @@ struct grpc_resource_quota { int64_t size; /* Amount of free memory in the resource quota */ int64_t free_pool; + /* Used size of memory in the resource quota. Updated as soon as the resource + * users start to allocate or free the memory. */ + gpr_atm used; gpr_atm last_size; @@ -371,6 +375,7 @@ static bool rq_reclaim_from_per_user_free_pool( while ((resource_user = rulist_pop_head(resource_quota, GRPC_RULIST_NON_EMPTY_FREE_POOL))) { gpr_mu_lock(&resource_user->mu); + resource_user->added_to_free_pool = false; if (resource_user->free_pool > 0) { int64_t amt = resource_user->free_pool; resource_user->free_pool = 0; @@ -386,6 +391,13 @@ static bool rq_reclaim_from_per_user_free_pool( gpr_mu_unlock(&resource_user->mu); return true; } else { + if (grpc_resource_quota_trace.enabled()) { + gpr_log(GPR_INFO, + "RQ %s %s: failed to reclaim_from_per_user_free_pool; " + "free_pool = %" PRId64 "; rq_free_pool = %" PRId64, + resource_quota->name, resource_user->name, + resource_user->free_pool, resource_quota->free_pool); + } gpr_mu_unlock(&resource_user->mu); } } @@ -622,6 +634,7 @@ grpc_resource_quota* grpc_resource_quota_create(const char* name) { resource_quota->combiner = grpc_combiner_create(); resource_quota->free_pool = INT64_MAX; resource_quota->size = INT64_MAX; + resource_quota->used = 0; gpr_atm_no_barrier_store(&resource_quota->last_size, GPR_ATM_MAX); gpr_mu_init(&resource_quota->thread_count_mu); resource_quota->max_threads = INT_MAX; @@ -712,7 +725,7 @@ size_t grpc_resource_quota_peek_size(grpc_resource_quota* resource_quota) { */ grpc_resource_quota* grpc_resource_quota_from_channel_args( - const grpc_channel_args* channel_args) { + const grpc_channel_args* channel_args, bool create) { for (size_t i = 0; i < channel_args->num_args; i++) { if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) { if (channel_args->args[i].type == GRPC_ARG_POINTER) { @@ -724,7 +737,7 @@ grpc_resource_quota* grpc_resource_quota_from_channel_args( } } } - return grpc_resource_quota_create(nullptr); + return create ? grpc_resource_quota_create(nullptr) : nullptr; } static void* rq_copy(void* rq) { @@ -863,33 +876,68 @@ void grpc_resource_user_free_threads(grpc_resource_user* resource_user, gpr_mu_unlock(&resource_user->resource_quota->thread_count_mu); } -void grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size, - grpc_closure* optional_on_done) { - gpr_mu_lock(&resource_user->mu); +static void resource_user_alloc_locked(grpc_resource_user* resource_user, + size_t size, + grpc_closure* optional_on_done) { ru_ref_by(resource_user, static_cast<gpr_atm>(size)); resource_user->free_pool -= static_cast<int64_t>(size); - resource_user->outstanding_allocations += static_cast<int64_t>(size); if (grpc_resource_quota_trace.enabled()) { gpr_log(GPR_INFO, "RQ %s %s: alloc %" PRIdPTR "; free_pool -> %" PRId64, resource_user->resource_quota->name, resource_user->name, size, resource_user->free_pool); } if (resource_user->free_pool < 0) { - grpc_closure_list_append(&resource_user->on_allocated, optional_on_done, - GRPC_ERROR_NONE); + if (optional_on_done != nullptr) { + resource_user->outstanding_allocations += static_cast<int64_t>(size); + grpc_closure_list_append(&resource_user->on_allocated, optional_on_done, + GRPC_ERROR_NONE); + } if (!resource_user->allocating) { resource_user->allocating = true; GRPC_CLOSURE_SCHED(&resource_user->allocate_closure, GRPC_ERROR_NONE); } } else { - resource_user->outstanding_allocations -= static_cast<int64_t>(size); GRPC_CLOSURE_SCHED(optional_on_done, GRPC_ERROR_NONE); } +} + +bool grpc_resource_user_safe_alloc(grpc_resource_user* resource_user, + size_t size) { + if (gpr_atm_no_barrier_load(&resource_user->shutdown)) return false; + gpr_mu_lock(&resource_user->mu); + grpc_resource_quota* resource_quota = resource_user->resource_quota; + bool cas_success; + do { + gpr_atm used = gpr_atm_no_barrier_load(&resource_quota->used); + gpr_atm new_used = used + size; + if (static_cast<size_t>(new_used) > + grpc_resource_quota_peek_size(resource_quota)) { + gpr_mu_unlock(&resource_user->mu); + return false; + } + cas_success = gpr_atm_full_cas(&resource_quota->used, used, new_used); + } while (!cas_success); + resource_user_alloc_locked(resource_user, size, nullptr); + gpr_mu_unlock(&resource_user->mu); + return true; +} + +void grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size, + grpc_closure* optional_on_done) { + // TODO(juanlishen): Maybe return immediately if shutting down. Deferring this + // because some tests become flaky after the change. + gpr_mu_lock(&resource_user->mu); + grpc_resource_quota* resource_quota = resource_user->resource_quota; + gpr_atm_no_barrier_fetch_add(&resource_quota->used, size); + resource_user_alloc_locked(resource_user, size, optional_on_done); gpr_mu_unlock(&resource_user->mu); } void grpc_resource_user_free(grpc_resource_user* resource_user, size_t size) { gpr_mu_lock(&resource_user->mu); + grpc_resource_quota* resource_quota = resource_user->resource_quota; + gpr_atm prior = gpr_atm_no_barrier_fetch_add(&resource_quota->used, -size); + GPR_ASSERT(prior >= static_cast<long>(size)); bool was_zero_or_negative = resource_user->free_pool <= 0; resource_user->free_pool += static_cast<int64_t>(size); if (grpc_resource_quota_trace.enabled()) { @@ -940,6 +988,12 @@ void grpc_resource_user_slice_allocator_init( void grpc_resource_user_alloc_slices( grpc_resource_user_slice_allocator* slice_allocator, size_t length, size_t count, grpc_slice_buffer* dest) { + if (gpr_atm_no_barrier_load(&slice_allocator->resource_user->shutdown)) { + GRPC_CLOSURE_SCHED( + &slice_allocator->on_allocated, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resource user shutdown")); + return; + } slice_allocator->length = length; slice_allocator->count = count; slice_allocator->dest = dest; diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h index 7b0ed7417a..1c79b52e3f 100644 --- a/src/core/lib/iomgr/resource_quota.h +++ b/src/core/lib/iomgr/resource_quota.h @@ -65,11 +65,16 @@ extern grpc_core::TraceFlag grpc_resource_quota_trace; +// TODO(juanlishen): This is a hack. We need to do real accounting instead of +// hard coding. +constexpr size_t GRPC_RESOURCE_QUOTA_CALL_SIZE = 15 * 1024; +constexpr size_t GRPC_RESOURCE_QUOTA_CHANNEL_SIZE = 50 * 1024; + grpc_resource_quota* grpc_resource_quota_ref_internal( grpc_resource_quota* resource_quota); void grpc_resource_quota_unref_internal(grpc_resource_quota* resource_quota); grpc_resource_quota* grpc_resource_quota_from_channel_args( - const grpc_channel_args* channel_args); + const grpc_channel_args* channel_args, bool create = true); /* Return a number indicating current memory pressure: 0.0 ==> no memory usage @@ -109,11 +114,21 @@ bool grpc_resource_user_allocate_threads(grpc_resource_user* resource_user, void grpc_resource_user_free_threads(grpc_resource_user* resource_user, int thread_count); -/* Allocate from the resource user (and its quota). - If optional_on_done is NULL, then allocate immediately. This may push the - quota over-limit, at which point reclamation will kick in. - If optional_on_done is non-NULL, it will be scheduled when the allocation has - been granted by the quota. */ +/* Allocates from the resource user 'size' worth of memory if this won't exceed + * the resource quota's total size. Returns whether the allocation is done + * successfully. If allocated successfully, the memory should be freed by the + * caller eventually. */ +bool grpc_resource_user_safe_alloc(grpc_resource_user* resource_user, + size_t size); +/* Allocates from the resource user 'size' worth of memory. + * If optional_on_done is NULL, then allocate immediately. This may push the + * quota over-limit, at which point reclamation will kick in. The caller is + * always responsible to free the memory eventually. + * If optional_on_done is non-NULL, it will be scheduled without error when the + * allocation has been granted by the quota, and the caller is responsible to + * free the memory eventually. Or it may be scheduled with an error, in which + * case the caller fails to allocate the memory and shouldn't free the memory. + */ void grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size, grpc_closure* optional_on_done); /* Release memory back to the quota */ diff --git a/src/core/lib/iomgr/tcp_client_custom.cc b/src/core/lib/iomgr/tcp_client_custom.cc index 9389861d07..73344b18d8 100644 --- a/src/core/lib/iomgr/tcp_client_custom.cc +++ b/src/core/lib/iomgr/tcp_client_custom.cc @@ -81,9 +81,8 @@ static void on_alarm(void* acp, grpc_error* error) { } } -static void custom_connect_callback(grpc_custom_socket* socket, - grpc_error* error) { - grpc_core::ExecCtx exec_ctx; +static void custom_connect_callback_internal(grpc_custom_socket* socket, + grpc_error* error) { grpc_custom_tcp_connect* connect = socket->connector; int done; grpc_closure* closure = connect->closure; @@ -100,6 +99,18 @@ static void custom_connect_callback(grpc_custom_socket* socket, GRPC_CLOSURE_SCHED(closure, error); } +static void custom_connect_callback(grpc_custom_socket* socket, + grpc_error* error) { + if (grpc_core::ExecCtx::Get() == nullptr) { + /* If we are being run on a thread which does not have an exec_ctx created + * yet, we should create one. */ + grpc_core::ExecCtx exec_ctx; + custom_connect_callback_internal(socket, error); + } else { + custom_connect_callback_internal(socket, error); + } +} + static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep, grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args, diff --git a/src/core/lib/security/credentials/alts/alts_credentials.cc b/src/core/lib/security/credentials/alts/alts_credentials.cc index fa05d901bf..1fbef4ae0c 100644 --- a/src/core/lib/security/credentials/alts/alts_credentials.cc +++ b/src/core/lib/security/credentials/alts/alts_credentials.cc @@ -28,7 +28,7 @@ #include <grpc/support/string_util.h> #include "src/core/lib/security/credentials/alts/check_gcp_environment.h" -#include "src/core/lib/security/security_connector/alts_security_connector.h" +#include "src/core/lib/security/security_connector/alts/alts_security_connector.h" #define GRPC_CREDENTIALS_TYPE_ALTS "Alts" #define GRPC_ALTS_HANDSHAKER_SERVICE_URL "metadata.google.internal:8080" diff --git a/src/core/lib/security/credentials/fake/fake_credentials.cc b/src/core/lib/security/credentials/fake/fake_credentials.cc index 858ab6b41b..d3e0e8c816 100644 --- a/src/core/lib/security/credentials/fake/fake_credentials.cc +++ b/src/core/lib/security/credentials/fake/fake_credentials.cc @@ -29,6 +29,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/security/security_connector/fake/fake_security_connector.h" /* -- Fake transport security credentials. -- */ diff --git a/src/core/lib/security/credentials/local/local_credentials.cc b/src/core/lib/security/credentials/local/local_credentials.cc index 9a2f646ba5..3ccfa2b908 100644 --- a/src/core/lib/security/credentials/local/local_credentials.cc +++ b/src/core/lib/security/credentials/local/local_credentials.cc @@ -25,7 +25,7 @@ #include <grpc/support/log.h> #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/security/security_connector/local_security_connector.h" +#include "src/core/lib/security/security_connector/local/local_security_connector.h" #define GRPC_CREDENTIALS_TYPE_LOCAL "Local" diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.h b/src/core/lib/security/credentials/ssl/ssl_credentials.h index 712d34c733..0fba413876 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.h +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.h @@ -22,6 +22,8 @@ #include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl/ssl_security_connector.h" + typedef struct { grpc_channel_credentials base; grpc_ssl_config config; diff --git a/src/core/lib/security/security_connector/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc index d38c0ff044..dd71c8bc60 100644 --- a/src/core/lib/security/security_connector/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc @@ -18,7 +18,7 @@ #include <grpc/support/port_platform.h> -#include "src/core/lib/security/security_connector/alts_security_connector.h" +#include "src/core/lib/security/security_connector/alts/alts_security_connector.h" #include <stdbool.h> #include <string.h> @@ -33,6 +33,7 @@ #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/transport.h" #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" +#include "src/core/tsi/transport_security.h" typedef struct { grpc_channel_security_connector base; diff --git a/src/core/lib/security/security_connector/alts_security_connector.h b/src/core/lib/security/security_connector/alts/alts_security_connector.h index e7e4cffe2a..d2e057a76a 100644 --- a/src/core/lib/security/security_connector/alts_security_connector.h +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.h @@ -16,8 +16,8 @@ * */ -#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_SECURITY_CONNECTOR_H -#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_SECURITY_CONNECTOR_H +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_ALTS_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_ALTS_SECURITY_CONNECTOR_H #include <grpc/support/port_platform.h> @@ -65,5 +65,5 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer( } // namespace internal } // namespace grpc_core -#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_SECURITY_CONNECTOR_H \ +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_ALTS_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.cc b/src/core/lib/security/security_connector/fake/fake_security_connector.cc new file mode 100644 index 0000000000..5c0c89b88f --- /dev/null +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc @@ -0,0 +1,310 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/support/port_platform.h> + +#include "src/core/lib/security/security_connector/fake/fake_security_connector.h" + +#include <stdbool.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> + +#include "src/core/ext/transport/chttp2/alpn/alpn.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/security/context/security_context.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/credentials/fake/fake_credentials.h" +#include "src/core/lib/security/transport/security_handshaker.h" +#include "src/core/lib/security/transport/target_authority_table.h" +#include "src/core/tsi/fake_transport_security.h" + +typedef struct { + grpc_channel_security_connector base; + char* target; + char* expected_targets; + bool is_lb_channel; + char* target_name_override; +} grpc_fake_channel_security_connector; + +static void fake_channel_destroy(grpc_security_connector* sc) { + grpc_fake_channel_security_connector* c = + reinterpret_cast<grpc_fake_channel_security_connector*>(sc); + grpc_call_credentials_unref(c->base.request_metadata_creds); + gpr_free(c->target); + gpr_free(c->expected_targets); + gpr_free(c->target_name_override); + gpr_free(c); +} + +static void fake_server_destroy(grpc_security_connector* sc) { gpr_free(sc); } + +static bool fake_check_target(const char* target_type, const char* target, + const char* set_str) { + GPR_ASSERT(target_type != nullptr); + GPR_ASSERT(target != nullptr); + char** set = nullptr; + size_t set_size = 0; + gpr_string_split(set_str, ",", &set, &set_size); + bool found = false; + for (size_t i = 0; i < set_size; ++i) { + if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true; + } + for (size_t i = 0; i < set_size; ++i) { + gpr_free(set[i]); + } + gpr_free(set); + return found; +} + +static void fake_secure_name_check(const char* target, + const char* expected_targets, + bool is_lb_channel) { + if (expected_targets == nullptr) return; + char** lbs_and_backends = nullptr; + size_t lbs_and_backends_size = 0; + bool success = false; + gpr_string_split(expected_targets, ";", &lbs_and_backends, + &lbs_and_backends_size); + if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) { + gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'", + expected_targets); + goto done; + } + if (is_lb_channel) { + if (lbs_and_backends_size != 2) { + gpr_log(GPR_ERROR, + "Invalid expected targets arg value: '%s'. Expectations for LB " + "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...", + expected_targets); + goto done; + } + if (!fake_check_target("LB", target, lbs_and_backends[1])) { + gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'", + target, lbs_and_backends[1]); + goto done; + } + success = true; + } else { + if (!fake_check_target("Backend", target, lbs_and_backends[0])) { + gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'", + target, lbs_and_backends[0]); + goto done; + } + success = true; + } +done: + for (size_t i = 0; i < lbs_and_backends_size; ++i) { + gpr_free(lbs_and_backends[i]); + } + gpr_free(lbs_and_backends); + if (!success) abort(); +} + +static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_auth_context** auth_context, + grpc_closure* on_peer_checked) { + const char* prop_name; + grpc_error* error = GRPC_ERROR_NONE; + *auth_context = nullptr; + if (peer.property_count != 1) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Fake peers should only have 1 property."); + goto end; + } + prop_name = peer.properties[0].name; + if (prop_name == nullptr || + strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) { + char* msg; + gpr_asprintf(&msg, "Unexpected property in fake peer: %s.", + prop_name == nullptr ? "<EMPTY>" : prop_name); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + goto end; + } + if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE, + peer.properties[0].value.length)) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Invalid value for cert type property."); + goto end; + } + *auth_context = grpc_auth_context_create(nullptr); + grpc_auth_context_add_cstring_property( + *auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + GRPC_FAKE_TRANSPORT_SECURITY_TYPE); +end: + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); +} + +static void fake_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_auth_context** auth_context, + grpc_closure* on_peer_checked) { + fake_check_peer(sc, peer, auth_context, on_peer_checked); + grpc_fake_channel_security_connector* c = + reinterpret_cast<grpc_fake_channel_security_connector*>(sc); + fake_secure_name_check(c->target, c->expected_targets, c->is_lb_channel); +} + +static void fake_server_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_auth_context** auth_context, + grpc_closure* on_peer_checked) { + fake_check_peer(sc, peer, auth_context, on_peer_checked); +} + +static int fake_channel_cmp(grpc_security_connector* sc1, + grpc_security_connector* sc2) { + grpc_fake_channel_security_connector* c1 = + reinterpret_cast<grpc_fake_channel_security_connector*>(sc1); + grpc_fake_channel_security_connector* c2 = + reinterpret_cast<grpc_fake_channel_security_connector*>(sc2); + int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); + if (c != 0) return c; + c = strcmp(c1->target, c2->target); + if (c != 0) return c; + if (c1->expected_targets == nullptr || c2->expected_targets == nullptr) { + c = GPR_ICMP(c1->expected_targets, c2->expected_targets); + } else { + c = strcmp(c1->expected_targets, c2->expected_targets); + } + if (c != 0) return c; + return GPR_ICMP(c1->is_lb_channel, c2->is_lb_channel); +} + +static int fake_server_cmp(grpc_security_connector* sc1, + grpc_security_connector* sc2) { + return grpc_server_security_connector_cmp( + reinterpret_cast<grpc_server_security_connector*>(sc1), + reinterpret_cast<grpc_server_security_connector*>(sc2)); +} + +static bool fake_channel_check_call_host(grpc_channel_security_connector* sc, + const char* host, + grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) { + grpc_fake_channel_security_connector* c = + reinterpret_cast<grpc_fake_channel_security_connector*>(sc); + char* authority_hostname = nullptr; + char* authority_ignored_port = nullptr; + char* target_hostname = nullptr; + char* target_ignored_port = nullptr; + gpr_split_host_port(host, &authority_hostname, &authority_ignored_port); + gpr_split_host_port(c->target, &target_hostname, &target_ignored_port); + if (c->target_name_override != nullptr) { + char* fake_security_target_name_override_hostname = nullptr; + char* fake_security_target_name_override_ignored_port = nullptr; + gpr_split_host_port(c->target_name_override, + &fake_security_target_name_override_hostname, + &fake_security_target_name_override_ignored_port); + if (strcmp(authority_hostname, + fake_security_target_name_override_hostname) != 0) { + gpr_log(GPR_ERROR, + "Authority (host) '%s' != Fake Security Target override '%s'", + host, fake_security_target_name_override_hostname); + abort(); + } + gpr_free(fake_security_target_name_override_hostname); + gpr_free(fake_security_target_name_override_ignored_port); + } else if (strcmp(authority_hostname, target_hostname) != 0) { + gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", + authority_hostname, target_hostname); + abort(); + } + gpr_free(authority_hostname); + gpr_free(authority_ignored_port); + gpr_free(target_hostname); + gpr_free(target_ignored_port); + return true; +} + +static void fake_channel_cancel_check_call_host( + grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, + grpc_error* error) { + GRPC_ERROR_UNREF(error); +} + +static void fake_channel_add_handshakers( + grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) { + grpc_handshake_manager_add( + handshake_mgr, + grpc_security_handshaker_create( + tsi_create_fake_handshaker(true /* is_client */), &sc->base)); +} + +static void fake_server_add_handshakers(grpc_server_security_connector* sc, + grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) { + grpc_handshake_manager_add( + handshake_mgr, + grpc_security_handshaker_create( + tsi_create_fake_handshaker(false /* is_client */), &sc->base)); +} + +static grpc_security_connector_vtable fake_channel_vtable = { + fake_channel_destroy, fake_channel_check_peer, fake_channel_cmp}; + +static grpc_security_connector_vtable fake_server_vtable = { + fake_server_destroy, fake_server_check_peer, fake_server_cmp}; + +grpc_channel_security_connector* grpc_fake_channel_security_connector_create( + grpc_channel_credentials* channel_creds, + grpc_call_credentials* request_metadata_creds, const char* target, + const grpc_channel_args* args) { + grpc_fake_channel_security_connector* c = + static_cast<grpc_fake_channel_security_connector*>( + gpr_zalloc(sizeof(*c))); + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; + c->base.base.vtable = &fake_channel_vtable; + c->base.channel_creds = channel_creds; + c->base.request_metadata_creds = + grpc_call_credentials_ref(request_metadata_creds); + c->base.check_call_host = fake_channel_check_call_host; + c->base.cancel_check_call_host = fake_channel_cancel_check_call_host; + c->base.add_handshakers = fake_channel_add_handshakers; + c->target = gpr_strdup(target); + const char* expected_targets = grpc_fake_transport_get_expected_targets(args); + c->expected_targets = gpr_strdup(expected_targets); + c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr; + const grpc_arg* target_name_override_arg = + grpc_channel_args_find(args, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); + if (target_name_override_arg != nullptr) { + c->target_name_override = + gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg)); + } + return &c->base; +} + +grpc_server_security_connector* grpc_fake_server_security_connector_create( + grpc_server_credentials* server_creds) { + grpc_server_security_connector* c = + static_cast<grpc_server_security_connector*>( + gpr_zalloc(sizeof(grpc_server_security_connector))); + gpr_ref_init(&c->base.refcount, 1); + c->base.vtable = &fake_server_vtable; + c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; + c->server_creds = server_creds; + c->add_handshakers = fake_server_add_handshakers; + return c; +} diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.h b/src/core/lib/security/security_connector/fake/fake_security_connector.h new file mode 100644 index 0000000000..fdfe048c6e --- /dev/null +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_FAKE_FAKE_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_FAKE_FAKE_SECURITY_CONNECTOR_H + +#include <grpc/support/port_platform.h> + +#include <grpc/grpc_security.h> + +#include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/security/security_connector/security_connector.h" + +#define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security" + +/* Creates a fake connector that emulates real channel security. */ +grpc_channel_security_connector* grpc_fake_channel_security_connector_create( + grpc_channel_credentials* channel_creds, + grpc_call_credentials* request_metadata_creds, const char* target, + const grpc_channel_args* args); + +/* Creates a fake connector that emulates real server security. */ +grpc_server_security_connector* grpc_fake_server_security_connector_create( + grpc_server_credentials* server_creds); + +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_FAKE_FAKE_SECURITY_CONNECTOR_H \ + */ diff --git a/src/core/lib/security/security_connector/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc index 911013ae58..008a98df28 100644 --- a/src/core/lib/security/security_connector/local_security_connector.cc +++ b/src/core/lib/security/security_connector/local/local_security_connector.cc @@ -18,7 +18,7 @@ #include <grpc/support/port_platform.h> -#include "src/core/lib/security/security_connector/local_security_connector.h" +#include "src/core/lib/security/security_connector/local/local_security_connector.h" #include <stdbool.h> #include <string.h> diff --git a/src/core/lib/security/security_connector/local_security_connector.h b/src/core/lib/security/security_connector/local/local_security_connector.h index a970a74788..5369a2127a 100644 --- a/src/core/lib/security/security_connector/local_security_connector.h +++ b/src/core/lib/security/security_connector/local/local_security_connector.h @@ -16,8 +16,8 @@ * */ -#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H -#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_LOCAL_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_LOCAL_SECURITY_CONNECTOR_H #include <grpc/support/port_platform.h> @@ -54,5 +54,5 @@ grpc_security_status grpc_local_channel_security_connector_create( grpc_security_status grpc_local_server_security_connector_create( grpc_server_credentials* server_creds, grpc_server_security_connector** sc); -#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H \ +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_LOCAL_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 7028ae8d16..02cecb0eb1 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -20,8 +20,6 @@ #include "src/core/lib/security/security_connector/security_connector.h" -#include <stdbool.h> - #include <grpc/slice_buffer.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> @@ -36,88 +34,12 @@ #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/credentials/fake/fake_credentials.h" -#include "src/core/lib/security/credentials/ssl/ssl_credentials.h" #include "src/core/lib/security/security_connector/load_system_roots.h" -#include "src/core/lib/security/transport/secure_endpoint.h" #include "src/core/lib/security/transport/security_handshaker.h" -#include "src/core/lib/security/transport/target_authority_table.h" -#include "src/core/tsi/fake_transport_security.h" -#include "src/core/tsi/ssl_transport_security.h" grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount( false, "security_connector_refcount"); -/* -- Constants. -- */ - -#ifndef INSTALL_PREFIX -static const char* installed_roots_path = "/usr/share/grpc/roots.pem"; -#else -static const char* installed_roots_path = - INSTALL_PREFIX "/share/grpc/roots.pem"; -#endif - -/** Environment variable used as a flag to enable/disable loading system root - certificates from the OS trust store. */ -#ifndef GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR -#define GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_NOT_USE_SYSTEM_SSL_ROOTS" -#endif - -#ifndef TSI_OPENSSL_ALPN_SUPPORT -#define TSI_OPENSSL_ALPN_SUPPORT 1 -#endif - -/* -- Overridden default roots. -- */ - -static grpc_ssl_roots_override_callback ssl_roots_override_cb = nullptr; - -void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) { - ssl_roots_override_cb = cb; -} - -/* -- Cipher suites. -- */ - -/* Defines the cipher suites that we accept by default. All these cipher suites - are compliant with HTTP2. */ -#define GRPC_SSL_CIPHER_SUITES \ - "ECDHE-ECDSA-AES128-GCM-SHA256:" \ - "ECDHE-ECDSA-AES256-GCM-SHA384:" \ - "ECDHE-RSA-AES128-GCM-SHA256:" \ - "ECDHE-RSA-AES256-GCM-SHA384" - -static gpr_once cipher_suites_once = GPR_ONCE_INIT; -static const char* cipher_suites = nullptr; - -static void init_cipher_suites(void) { - char* overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES"); - cipher_suites = overridden != nullptr ? overridden : GRPC_SSL_CIPHER_SUITES; -} - -static const char* ssl_cipher_suites(void) { - gpr_once_init(&cipher_suites_once, init_cipher_suites); - return cipher_suites; -} - -/* -- Common methods. -- */ - -/* Returns the first property with that name. */ -const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* peer, - const char* name) { - size_t i; - if (peer == nullptr) return nullptr; - for (i = 0; i < peer->property_count; i++) { - const tsi_peer_property* property = &peer->properties[i]; - if (name == nullptr && property->name == nullptr) { - return property; - } - if (name != nullptr && property->name != nullptr && - strcmp(property->name, name) == 0) { - return property; - } - } - return nullptr; -} - void grpc_channel_security_connector_add_handshakers( grpc_channel_security_connector* connector, grpc_pollset_set* interested_parties, @@ -288,965 +210,3 @@ grpc_security_connector* grpc_security_connector_find_in_args( } return nullptr; } - -static tsi_client_certificate_request_type -get_tsi_client_certificate_request_type( - grpc_ssl_client_certificate_request_type grpc_request_type) { - switch (grpc_request_type) { - case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE: - return TSI_DONT_REQUEST_CLIENT_CERTIFICATE; - - case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY; - - case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: - return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY; - - case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY; - - case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: - return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; - - default: - return TSI_DONT_REQUEST_CLIENT_CERTIFICATE; - } -} - -/* -- Fake implementation. -- */ - -typedef struct { - grpc_channel_security_connector base; - char* target; - char* expected_targets; - bool is_lb_channel; - char* target_name_override; -} grpc_fake_channel_security_connector; - -static void fake_channel_destroy(grpc_security_connector* sc) { - grpc_fake_channel_security_connector* c = - reinterpret_cast<grpc_fake_channel_security_connector*>(sc); - grpc_call_credentials_unref(c->base.request_metadata_creds); - gpr_free(c->target); - gpr_free(c->expected_targets); - gpr_free(c->target_name_override); - gpr_free(c); -} - -static void fake_server_destroy(grpc_security_connector* sc) { gpr_free(sc); } - -static bool fake_check_target(const char* target_type, const char* target, - const char* set_str) { - GPR_ASSERT(target_type != nullptr); - GPR_ASSERT(target != nullptr); - char** set = nullptr; - size_t set_size = 0; - gpr_string_split(set_str, ",", &set, &set_size); - bool found = false; - for (size_t i = 0; i < set_size; ++i) { - if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true; - } - for (size_t i = 0; i < set_size; ++i) { - gpr_free(set[i]); - } - gpr_free(set); - return found; -} - -static void fake_secure_name_check(const char* target, - const char* expected_targets, - bool is_lb_channel) { - if (expected_targets == nullptr) return; - char** lbs_and_backends = nullptr; - size_t lbs_and_backends_size = 0; - bool success = false; - gpr_string_split(expected_targets, ";", &lbs_and_backends, - &lbs_and_backends_size); - if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) { - gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'", - expected_targets); - goto done; - } - if (is_lb_channel) { - if (lbs_and_backends_size != 2) { - gpr_log(GPR_ERROR, - "Invalid expected targets arg value: '%s'. Expectations for LB " - "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...", - expected_targets); - goto done; - } - if (!fake_check_target("LB", target, lbs_and_backends[1])) { - gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'", - target, lbs_and_backends[1]); - goto done; - } - success = true; - } else { - if (!fake_check_target("Backend", target, lbs_and_backends[0])) { - gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'", - target, lbs_and_backends[0]); - goto done; - } - success = true; - } -done: - for (size_t i = 0; i < lbs_and_backends_size; ++i) { - gpr_free(lbs_and_backends[i]); - } - gpr_free(lbs_and_backends); - if (!success) abort(); -} - -static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - const char* prop_name; - grpc_error* error = GRPC_ERROR_NONE; - *auth_context = nullptr; - if (peer.property_count != 1) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Fake peers should only have 1 property."); - goto end; - } - prop_name = peer.properties[0].name; - if (prop_name == nullptr || - strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) { - char* msg; - gpr_asprintf(&msg, "Unexpected property in fake peer: %s.", - prop_name == nullptr ? "<EMPTY>" : prop_name); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); - goto end; - } - if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE, - peer.properties[0].value.length)) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Invalid value for cert type property."); - goto end; - } - *auth_context = grpc_auth_context_create(nullptr); - grpc_auth_context_add_cstring_property( - *auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, - GRPC_FAKE_TRANSPORT_SECURITY_TYPE); -end: - GRPC_CLOSURE_SCHED(on_peer_checked, error); - tsi_peer_destruct(&peer); -} - -static void fake_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - fake_check_peer(sc, peer, auth_context, on_peer_checked); - grpc_fake_channel_security_connector* c = - reinterpret_cast<grpc_fake_channel_security_connector*>(sc); - fake_secure_name_check(c->target, c->expected_targets, c->is_lb_channel); -} - -static void fake_server_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - fake_check_peer(sc, peer, auth_context, on_peer_checked); -} - -static int fake_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_fake_channel_security_connector* c1 = - reinterpret_cast<grpc_fake_channel_security_connector*>(sc1); - grpc_fake_channel_security_connector* c2 = - reinterpret_cast<grpc_fake_channel_security_connector*>(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - c = strcmp(c1->target, c2->target); - if (c != 0) return c; - if (c1->expected_targets == nullptr || c2->expected_targets == nullptr) { - c = GPR_ICMP(c1->expected_targets, c2->expected_targets); - } else { - c = strcmp(c1->expected_targets, c2->expected_targets); - } - if (c != 0) return c; - return GPR_ICMP(c1->is_lb_channel, c2->is_lb_channel); -} - -static int fake_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - return grpc_server_security_connector_cmp( - reinterpret_cast<grpc_server_security_connector*>(sc1), - reinterpret_cast<grpc_server_security_connector*>(sc2)); -} - -static bool fake_channel_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_fake_channel_security_connector* c = - reinterpret_cast<grpc_fake_channel_security_connector*>(sc); - char* authority_hostname = nullptr; - char* authority_ignored_port = nullptr; - char* target_hostname = nullptr; - char* target_ignored_port = nullptr; - gpr_split_host_port(host, &authority_hostname, &authority_ignored_port); - gpr_split_host_port(c->target, &target_hostname, &target_ignored_port); - if (c->target_name_override != nullptr) { - char* fake_security_target_name_override_hostname = nullptr; - char* fake_security_target_name_override_ignored_port = nullptr; - gpr_split_host_port(c->target_name_override, - &fake_security_target_name_override_hostname, - &fake_security_target_name_override_ignored_port); - if (strcmp(authority_hostname, - fake_security_target_name_override_hostname) != 0) { - gpr_log(GPR_ERROR, - "Authority (host) '%s' != Fake Security Target override '%s'", - host, fake_security_target_name_override_hostname); - abort(); - } - gpr_free(fake_security_target_name_override_hostname); - gpr_free(fake_security_target_name_override_ignored_port); - } else if (strcmp(authority_hostname, target_hostname) != 0) { - gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", - authority_hostname, target_hostname); - abort(); - } - gpr_free(authority_hostname); - gpr_free(authority_ignored_port); - gpr_free(target_hostname); - gpr_free(target_ignored_port); - return true; -} - -static void fake_channel_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -static void fake_channel_add_handshakers( - grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(true /* is_client */), &sc->base)); -} - -static void fake_server_add_handshakers(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(false /* is_client */), &sc->base)); -} - -static grpc_security_connector_vtable fake_channel_vtable = { - fake_channel_destroy, fake_channel_check_peer, fake_channel_cmp}; - -static grpc_security_connector_vtable fake_server_vtable = { - fake_server_destroy, fake_server_check_peer, fake_server_cmp}; - -grpc_channel_security_connector* grpc_fake_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target, - const grpc_channel_args* args) { - grpc_fake_channel_security_connector* c = - static_cast<grpc_fake_channel_security_connector*>( - gpr_zalloc(sizeof(*c))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->base.base.vtable = &fake_channel_vtable; - c->base.channel_creds = channel_creds; - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = fake_channel_check_call_host; - c->base.cancel_check_call_host = fake_channel_cancel_check_call_host; - c->base.add_handshakers = fake_channel_add_handshakers; - c->target = gpr_strdup(target); - const char* expected_targets = grpc_fake_transport_get_expected_targets(args); - c->expected_targets = gpr_strdup(expected_targets); - c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr; - const grpc_arg* target_name_override_arg = - grpc_channel_args_find(args, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); - if (target_name_override_arg != nullptr) { - c->target_name_override = - gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg)); - } - return &c->base; -} - -grpc_server_security_connector* grpc_fake_server_security_connector_create( - grpc_server_credentials* server_creds) { - grpc_server_security_connector* c = - static_cast<grpc_server_security_connector*>( - gpr_zalloc(sizeof(grpc_server_security_connector))); - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &fake_server_vtable; - c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->server_creds = server_creds; - c->add_handshakers = fake_server_add_handshakers; - return c; -} - -/* --- Ssl implementation. --- */ - -grpc_ssl_session_cache* grpc_ssl_session_cache_create_lru(size_t capacity) { - tsi_ssl_session_cache* cache = tsi_ssl_session_cache_create_lru(capacity); - return reinterpret_cast<grpc_ssl_session_cache*>(cache); -} - -void grpc_ssl_session_cache_destroy(grpc_ssl_session_cache* cache) { - tsi_ssl_session_cache* tsi_cache = - reinterpret_cast<tsi_ssl_session_cache*>(cache); - tsi_ssl_session_cache_unref(tsi_cache); -} - -static void* grpc_ssl_session_cache_arg_copy(void* p) { - tsi_ssl_session_cache* tsi_cache = - reinterpret_cast<tsi_ssl_session_cache*>(p); - // destroy call below will unref the pointer. - tsi_ssl_session_cache_ref(tsi_cache); - return p; -} - -static void grpc_ssl_session_cache_arg_destroy(void* p) { - tsi_ssl_session_cache* tsi_cache = - reinterpret_cast<tsi_ssl_session_cache*>(p); - tsi_ssl_session_cache_unref(tsi_cache); -} - -static int grpc_ssl_session_cache_arg_cmp(void* p, void* q) { - return GPR_ICMP(p, q); -} - -grpc_arg grpc_ssl_session_cache_create_channel_arg( - grpc_ssl_session_cache* cache) { - static const grpc_arg_pointer_vtable vtable = { - grpc_ssl_session_cache_arg_copy, - grpc_ssl_session_cache_arg_destroy, - grpc_ssl_session_cache_arg_cmp, - }; - return grpc_channel_arg_pointer_create( - const_cast<char*>(GRPC_SSL_SESSION_CACHE_ARG), cache, &vtable); -} - -typedef struct { - grpc_channel_security_connector base; - tsi_ssl_client_handshaker_factory* client_handshaker_factory; - char* target_name; - char* overridden_target_name; - const verify_peer_options* verify_options; -} grpc_ssl_channel_security_connector; - -typedef struct { - grpc_server_security_connector base; - tsi_ssl_server_handshaker_factory* server_handshaker_factory; -} grpc_ssl_server_security_connector; - -static bool server_connector_has_cert_config_fetcher( - grpc_ssl_server_security_connector* c) { - GPR_ASSERT(c != nullptr); - grpc_ssl_server_credentials* server_creds = - reinterpret_cast<grpc_ssl_server_credentials*>(c->base.server_creds); - GPR_ASSERT(server_creds != nullptr); - return server_creds->certificate_config_fetcher.cb != nullptr; -} - -static void ssl_channel_destroy(grpc_security_connector* sc) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); - grpc_channel_credentials_unref(c->base.channel_creds); - grpc_call_credentials_unref(c->base.request_metadata_creds); - tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory); - c->client_handshaker_factory = nullptr; - if (c->target_name != nullptr) gpr_free(c->target_name); - if (c->overridden_target_name != nullptr) gpr_free(c->overridden_target_name); - gpr_free(sc); -} - -static void ssl_server_destroy(grpc_security_connector* sc) { - grpc_ssl_server_security_connector* c = - reinterpret_cast<grpc_ssl_server_security_connector*>(sc); - grpc_server_credentials_unref(c->base.server_creds); - tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory); - c->server_handshaker_factory = nullptr; - gpr_free(sc); -} - -static void ssl_channel_add_handshakers(grpc_channel_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); - // Instantiate TSI handshaker. - tsi_handshaker* tsi_hs = nullptr; - tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( - c->client_handshaker_factory, - c->overridden_target_name != nullptr ? c->overridden_target_name - : c->target_name, - &tsi_hs); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); - return; - } - // Create handshakers. - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); -} - -static const char** fill_alpn_protocol_strings(size_t* num_alpn_protocols) { - GPR_ASSERT(num_alpn_protocols != nullptr); - *num_alpn_protocols = grpc_chttp2_num_alpn_versions(); - const char** alpn_protocol_strings = static_cast<const char**>( - gpr_malloc(sizeof(const char*) * (*num_alpn_protocols))); - for (size_t i = 0; i < *num_alpn_protocols; i++) { - alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i); - } - return alpn_protocol_strings; -} - -/* Attempts to replace the server_handshaker_factory with a new factory using - * the provided grpc_ssl_server_certificate_config. Should new factory creation - * fail, the existing factory will not be replaced. Returns true on success (new - * factory created). */ -static bool try_replace_server_handshaker_factory( - grpc_ssl_server_security_connector* sc, - const grpc_ssl_server_certificate_config* config) { - if (config == nullptr) { - gpr_log(GPR_ERROR, - "Server certificate config callback returned invalid (NULL) " - "config."); - return false; - } - gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config); - - size_t num_alpn_protocols = 0; - const char** alpn_protocol_strings = - fill_alpn_protocol_strings(&num_alpn_protocols); - tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( - config->pem_key_cert_pairs, config->num_key_cert_pairs); - tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; - grpc_ssl_server_credentials* server_creds = - reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds); - tsi_result result = tsi_create_ssl_server_handshaker_factory_ex( - cert_pairs, config->num_key_cert_pairs, config->pem_root_certs, - get_tsi_client_certificate_request_type( - server_creds->config.client_certificate_request), - ssl_cipher_suites(), alpn_protocol_strings, - static_cast<uint16_t>(num_alpn_protocols), &new_handshaker_factory); - gpr_free(cert_pairs); - gpr_free((void*)alpn_protocol_strings); - - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - return false; - } - tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory); - sc->server_handshaker_factory = new_handshaker_factory; - return true; -} - -/* Attempts to fetch the server certificate config if a callback is available. - * Current certificate config will continue to be used if the callback returns - * an error. Returns true if new credentials were sucessfully loaded. */ -static bool try_fetch_ssl_server_credentials( - grpc_ssl_server_security_connector* sc) { - grpc_ssl_server_certificate_config* certificate_config = nullptr; - bool status; - - GPR_ASSERT(sc != nullptr); - if (!server_connector_has_cert_config_fetcher(sc)) return false; - - grpc_ssl_server_credentials* server_creds = - reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds); - grpc_ssl_certificate_config_reload_status cb_result = - server_creds->certificate_config_fetcher.cb( - server_creds->certificate_config_fetcher.user_data, - &certificate_config); - if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { - gpr_log(GPR_DEBUG, "No change in SSL server credentials."); - status = false; - } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) { - status = try_replace_server_handshaker_factory(sc, certificate_config); - } else { - // Log error, continue using previously-loaded credentials. - gpr_log(GPR_ERROR, - "Failed fetching new server credentials, continuing to " - "use previously-loaded credentials."); - status = false; - } - - if (certificate_config != nullptr) { - grpc_ssl_server_certificate_config_destroy(certificate_config); - } - return status; -} - -static void ssl_server_add_handshakers(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_ssl_server_security_connector* c = - reinterpret_cast<grpc_ssl_server_security_connector*>(sc); - // Instantiate TSI handshaker. - try_fetch_ssl_server_credentials(c); - tsi_handshaker* tsi_hs = nullptr; - tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( - c->server_handshaker_factory, &tsi_hs); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); - return; - } - // Create handshakers. - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); -} - -int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) { - char* allocated_name = nullptr; - int r; - - char* ignored_port; - gpr_split_host_port(peer_name, &allocated_name, &ignored_port); - gpr_free(ignored_port); - peer_name = allocated_name; - if (!peer_name) return 0; - - // IPv6 zone-id should not be included in comparisons. - char* const zone_id = strchr(allocated_name, '%'); - if (zone_id != nullptr) *zone_id = '\0'; - - r = tsi_ssl_peer_matches_name(peer, peer_name); - gpr_free(allocated_name); - return r; -} - -grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) { - size_t i; - grpc_auth_context* ctx = nullptr; - const char* peer_identity_property_name = nullptr; - - /* The caller has checked the certificate type property. */ - GPR_ASSERT(peer->property_count >= 1); - ctx = grpc_auth_context_create(nullptr); - grpc_auth_context_add_cstring_property( - ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, - GRPC_SSL_TRANSPORT_SECURITY_TYPE); - for (i = 0; i < peer->property_count; i++) { - const tsi_peer_property* prop = &peer->properties[i]; - if (prop->name == nullptr) continue; - if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) { - /* If there is no subject alt name, have the CN as the identity. */ - if (peer_identity_property_name == nullptr) { - peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME; - } - grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME, - prop->value.data, prop->value.length); - } else if (strcmp(prop->name, - TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { - peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME; - grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME, - prop->value.data, prop->value.length); - } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) { - grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME, - prop->value.data, prop->value.length); - } else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) { - grpc_auth_context_add_property(ctx, GRPC_SSL_SESSION_REUSED_PROPERTY, - prop->value.data, prop->value.length); - } - } - if (peer_identity_property_name != nullptr) { - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - ctx, peer_identity_property_name) == 1); - } - return ctx; -} - -static grpc_error* ssl_check_peer(grpc_security_connector* sc, - const char* peer_name, const tsi_peer* peer, - grpc_auth_context** auth_context) { -#if TSI_OPENSSL_ALPN_SUPPORT - /* Check the ALPN if ALPN is supported. */ - const tsi_peer_property* p = - tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); - if (p == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: missing selected ALPN property."); - } - if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: invalid ALPN value."); - } -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ - /* Check the peer name if specified. */ - if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { - char* msg; - gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name); - grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); - return error; - } - *auth_context = grpc_ssl_peer_to_auth_context(peer); - return GRPC_ERROR_NONE; -} - -static void ssl_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); - const char* target_name = c->overridden_target_name != nullptr - ? c->overridden_target_name - : c->target_name; - grpc_error* error = ssl_check_peer(sc, target_name, &peer, auth_context); - if (error == GRPC_ERROR_NONE && - c->verify_options->verify_peer_callback != nullptr) { - const tsi_peer_property* p = - tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); - if (p == nullptr) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: missing pem cert property."); - } else { - char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1)); - memcpy(peer_pem, p->value.data, p->value.length); - peer_pem[p->value.length] = '\0'; - int callback_status = c->verify_options->verify_peer_callback( - target_name, peer_pem, - c->verify_options->verify_peer_callback_userdata); - gpr_free(peer_pem); - if (callback_status) { - char* msg; - gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", - callback_status); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); - } - } - } - GRPC_CLOSURE_SCHED(on_peer_checked, error); - tsi_peer_destruct(&peer); -} - -static void ssl_server_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_error* error = ssl_check_peer(sc, nullptr, &peer, auth_context); - tsi_peer_destruct(&peer); - GRPC_CLOSURE_SCHED(on_peer_checked, error); -} - -static int ssl_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_ssl_channel_security_connector* c1 = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc1); - grpc_ssl_channel_security_connector* c2 = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - c = strcmp(c1->target_name, c2->target_name); - if (c != 0) return c; - return (c1->overridden_target_name == nullptr || - c2->overridden_target_name == nullptr) - ? GPR_ICMP(c1->overridden_target_name, c2->overridden_target_name) - : strcmp(c1->overridden_target_name, c2->overridden_target_name); -} - -static int ssl_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - return grpc_server_security_connector_cmp( - reinterpret_cast<grpc_server_security_connector*>(sc1), - reinterpret_cast<grpc_server_security_connector*>(sc2)); -} - -static void add_shallow_auth_property_to_peer(tsi_peer* peer, - const grpc_auth_property* prop, - const char* tsi_prop_name) { - tsi_peer_property* tsi_prop = &peer->properties[peer->property_count++]; - tsi_prop->name = const_cast<char*>(tsi_prop_name); - tsi_prop->value.data = prop->value; - tsi_prop->value.length = prop->value_length; -} - -tsi_peer grpc_shallow_peer_from_ssl_auth_context( - const grpc_auth_context* auth_context) { - size_t max_num_props = 0; - grpc_auth_property_iterator it; - const grpc_auth_property* prop; - tsi_peer peer; - memset(&peer, 0, sizeof(peer)); - - it = grpc_auth_context_property_iterator(auth_context); - while (grpc_auth_property_iterator_next(&it) != nullptr) max_num_props++; - - if (max_num_props > 0) { - peer.properties = static_cast<tsi_peer_property*>( - gpr_malloc(max_num_props * sizeof(tsi_peer_property))); - it = grpc_auth_context_property_iterator(auth_context); - while ((prop = grpc_auth_property_iterator_next(&it)) != nullptr) { - if (strcmp(prop->name, GRPC_X509_SAN_PROPERTY_NAME) == 0) { - add_shallow_auth_property_to_peer( - &peer, prop, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY); - } else if (strcmp(prop->name, GRPC_X509_CN_PROPERTY_NAME) == 0) { - add_shallow_auth_property_to_peer( - &peer, prop, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); - } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) { - add_shallow_auth_property_to_peer(&peer, prop, - TSI_X509_PEM_CERT_PROPERTY); - } - } - } - return peer; -} - -void grpc_shallow_peer_destruct(tsi_peer* peer) { - if (peer->properties != nullptr) gpr_free(peer->properties); -} - -static bool ssl_channel_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); - grpc_security_status status = GRPC_SECURITY_ERROR; - tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); - if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; - /* If the target name was overridden, then the original target_name was - 'checked' transitively during the previous peer check at the end of the - handshake. */ - if (c->overridden_target_name != nullptr && - strcmp(host, c->target_name) == 0) { - status = GRPC_SECURITY_OK; - } - if (status != GRPC_SECURITY_OK) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "call host does not match SSL server name"); - } - grpc_shallow_peer_destruct(&peer); - return true; -} - -static void ssl_channel_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -static grpc_security_connector_vtable ssl_channel_vtable = { - ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp}; - -static grpc_security_connector_vtable ssl_server_vtable = { - ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp}; - -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_ssl_config* config, const char* target_name, - const char* overridden_target_name, - tsi_ssl_session_cache* ssl_session_cache, - grpc_channel_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_ssl_channel_security_connector* c; - char* port; - bool has_key_cert_pair; - tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); - options.alpn_protocols = - fill_alpn_protocol_strings(&options.num_alpn_protocols); - - if (config == nullptr || target_name == nullptr) { - gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); - goto error; - } - if (config->pem_root_certs == nullptr) { - // Use default root certificates. - options.pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); - options.root_store = grpc_core::DefaultSslRootStore::GetRootStore(); - if (options.pem_root_certs == nullptr) { - gpr_log(GPR_ERROR, "Could not get default pem root certs."); - goto error; - } - } else { - options.pem_root_certs = config->pem_root_certs; - } - c = static_cast<grpc_ssl_channel_security_connector*>( - gpr_zalloc(sizeof(grpc_ssl_channel_security_connector))); - - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &ssl_channel_vtable; - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = ssl_channel_check_call_host; - c->base.cancel_check_call_host = ssl_channel_cancel_check_call_host; - c->base.add_handshakers = ssl_channel_add_handshakers; - gpr_split_host_port(target_name, &c->target_name, &port); - gpr_free(port); - if (overridden_target_name != nullptr) { - c->overridden_target_name = gpr_strdup(overridden_target_name); - } - c->verify_options = &config->verify_options; - - has_key_cert_pair = config->pem_key_cert_pair != nullptr && - config->pem_key_cert_pair->private_key != nullptr && - config->pem_key_cert_pair->cert_chain != nullptr; - if (has_key_cert_pair) { - options.pem_key_cert_pair = config->pem_key_cert_pair; - } - options.cipher_suites = ssl_cipher_suites(); - options.session_cache = ssl_session_cache; - result = tsi_create_ssl_client_handshaker_factory_with_options( - &options, &c->client_handshaker_factory); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - ssl_channel_destroy(&c->base.base); - *sc = nullptr; - goto error; - } - *sc = &c->base; - gpr_free((void*)options.alpn_protocols); - return GRPC_SECURITY_OK; - -error: - gpr_free((void*)options.alpn_protocols); - return GRPC_SECURITY_ERROR; -} - -static grpc_ssl_server_security_connector* -grpc_ssl_server_security_connector_initialize( - grpc_server_credentials* server_creds) { - grpc_ssl_server_security_connector* c = - static_cast<grpc_ssl_server_security_connector*>( - gpr_zalloc(sizeof(grpc_ssl_server_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.base.vtable = &ssl_server_vtable; - c->base.add_handshakers = ssl_server_add_handshakers; - c->base.server_creds = grpc_server_credentials_ref(server_creds); - return c; -} - -grpc_security_status grpc_ssl_server_security_connector_create( - grpc_server_credentials* gsc, grpc_server_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_ssl_server_credentials* server_credentials = - reinterpret_cast<grpc_ssl_server_credentials*>(gsc); - grpc_security_status retval = GRPC_SECURITY_OK; - - GPR_ASSERT(server_credentials != nullptr); - GPR_ASSERT(sc != nullptr); - - grpc_ssl_server_security_connector* c = - grpc_ssl_server_security_connector_initialize(gsc); - if (server_connector_has_cert_config_fetcher(c)) { - // Load initial credentials from certificate_config_fetcher: - if (!try_fetch_ssl_server_credentials(c)) { - gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher."); - retval = GRPC_SECURITY_ERROR; - } - } else { - size_t num_alpn_protocols = 0; - const char** alpn_protocol_strings = - fill_alpn_protocol_strings(&num_alpn_protocols); - result = tsi_create_ssl_server_handshaker_factory_ex( - server_credentials->config.pem_key_cert_pairs, - server_credentials->config.num_key_cert_pairs, - server_credentials->config.pem_root_certs, - get_tsi_client_certificate_request_type( - server_credentials->config.client_certificate_request), - ssl_cipher_suites(), alpn_protocol_strings, - static_cast<uint16_t>(num_alpn_protocols), - &c->server_handshaker_factory); - gpr_free((void*)alpn_protocol_strings); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - retval = GRPC_SECURITY_ERROR; - } - } - - if (retval == GRPC_SECURITY_OK) { - *sc = &c->base; - } else { - if (c != nullptr) ssl_server_destroy(&c->base.base); - if (sc != nullptr) *sc = nullptr; - } - return retval; -} - -namespace grpc_core { - -tsi_ssl_root_certs_store* DefaultSslRootStore::default_root_store_; -grpc_slice DefaultSslRootStore::default_pem_root_certs_; - -const tsi_ssl_root_certs_store* DefaultSslRootStore::GetRootStore() { - InitRootStore(); - return default_root_store_; -} - -const char* DefaultSslRootStore::GetPemRootCerts() { - InitRootStore(); - return GRPC_SLICE_IS_EMPTY(default_pem_root_certs_) - ? nullptr - : reinterpret_cast<const char*> - GRPC_SLICE_START_PTR(default_pem_root_certs_); -} - -grpc_slice DefaultSslRootStore::ComputePemRootCerts() { - grpc_slice result = grpc_empty_slice(); - char* not_use_system_roots_env_value = - gpr_getenv(GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR); - const bool not_use_system_roots = gpr_is_true(not_use_system_roots_env_value); - gpr_free(not_use_system_roots_env_value); - // First try to load the roots from the environment. - char* default_root_certs_path = - gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); - if (default_root_certs_path != nullptr) { - GRPC_LOG_IF_ERROR("load_file", - grpc_load_file(default_root_certs_path, 1, &result)); - gpr_free(default_root_certs_path); - } - // Try overridden roots if needed. - grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL; - if (GRPC_SLICE_IS_EMPTY(result) && ssl_roots_override_cb != nullptr) { - char* pem_root_certs = nullptr; - ovrd_res = ssl_roots_override_cb(&pem_root_certs); - if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) { - GPR_ASSERT(pem_root_certs != nullptr); - result = grpc_slice_from_copied_buffer( - pem_root_certs, - strlen(pem_root_certs) + 1); // nullptr terminator. - } - gpr_free(pem_root_certs); - } - // Try loading roots from OS trust store if flag is enabled. - if (GRPC_SLICE_IS_EMPTY(result) && !not_use_system_roots) { - result = LoadSystemRootCerts(); - } - // Fallback to roots manually shipped with gRPC. - if (GRPC_SLICE_IS_EMPTY(result) && - ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) { - GRPC_LOG_IF_ERROR("load_file", - grpc_load_file(installed_roots_path, 1, &result)); - } - return result; -} - -void DefaultSslRootStore::InitRootStore() { - static gpr_once once = GPR_ONCE_INIT; - gpr_once_init(&once, DefaultSslRootStore::InitRootStoreOnce); -} - -void DefaultSslRootStore::InitRootStoreOnce() { - default_pem_root_certs_ = ComputePemRootCerts(); - if (!GRPC_SLICE_IS_EMPTY(default_pem_root_certs_)) { - default_root_store_ = - tsi_ssl_root_certs_store_create(reinterpret_cast<const char*>( - GRPC_SLICE_START_PTR(default_pem_root_certs_))); - } -} - -} // namespace grpc_core diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index d8df3cd72f..4c921a8793 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -38,11 +38,6 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount; typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status; -/* --- URL schemes. --- */ - -#define GRPC_SSL_URL_SCHEME "https" -#define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security" - /* --- security_connector object. --- A security connector object represents away to configure the underlying @@ -179,112 +174,4 @@ void grpc_server_security_connector_add_handshakers( grpc_server_security_connector* sc, grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr); -/* --- Creation security connectors. --- */ - -/* For TESTING ONLY! - Creates a fake connector that emulates real channel security. */ -grpc_channel_security_connector* grpc_fake_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target, - const grpc_channel_args* args); - -/* For TESTING ONLY! - Creates a fake connector that emulates real server security. */ -grpc_server_security_connector* grpc_fake_server_security_connector_create( - grpc_server_credentials* server_creds); - -/* Config for ssl clients. */ - -typedef struct { - tsi_ssl_pem_key_cert_pair* pem_key_cert_pair; - char* pem_root_certs; - verify_peer_options verify_options; -} grpc_ssl_config; - -/* Creates an SSL channel_security_connector. - - request_metadata_creds is the credentials object which metadata - will be sent with each request. This parameter can be NULL. - - config is the SSL config to be used for the SSL channel establishment. - - is_client should be 0 for a server or a non-0 value for a client. - - secure_peer_name is the secure peer name that should be checked in - grpc_channel_security_connector_check_peer. This parameter may be NULL in - which case the peer name will not be checked. Note that if this parameter - is not NULL, then, pem_root_certs should not be NULL either. - - sc is a pointer on the connector to be created. - This function returns GRPC_SECURITY_OK in case of success or a - specific error code otherwise. -*/ -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_ssl_config* config, const char* target_name, - const char* overridden_target_name, - tsi_ssl_session_cache* ssl_session_cache, - grpc_channel_security_connector** sc); - -/* Config for ssl servers. */ -typedef struct { - tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs; - size_t num_key_cert_pairs; - char* pem_root_certs; - grpc_ssl_client_certificate_request_type client_certificate_request; -} grpc_ssl_server_config; - -/* Creates an SSL server_security_connector. - - config is the SSL config to be used for the SSL channel establishment. - - sc is a pointer on the connector to be created. - This function returns GRPC_SECURITY_OK in case of success or a - specific error code otherwise. -*/ -grpc_security_status grpc_ssl_server_security_connector_create( - grpc_server_credentials* server_credentials, - grpc_server_security_connector** sc); - -/* Util. */ -const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* peer, - const char* name); - -/* Exposed for testing only. */ -grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer); -tsi_peer grpc_shallow_peer_from_ssl_auth_context( - const grpc_auth_context* auth_context); -void grpc_shallow_peer_destruct(tsi_peer* peer); -int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name); - -/* --- Default SSL Root Store. --- */ -namespace grpc_core { - -// The class implements default SSL root store. -class DefaultSslRootStore { - public: - // Gets the default SSL root store. Returns nullptr if not found. - static const tsi_ssl_root_certs_store* GetRootStore(); - - // Gets the default PEM root certificate. - static const char* GetPemRootCerts(); - - protected: - // Returns default PEM root certificates in nullptr terminated grpc_slice. - // This function is protected instead of private, so that it can be tested. - static grpc_slice ComputePemRootCerts(); - - private: - // Construct me not! - DefaultSslRootStore(); - - // Initialization of default SSL root store. - static void InitRootStore(); - - // One-time initialization of default SSL root store. - static void InitRootStoreOnce(); - - // SSL root store in tsi_ssl_root_certs_store object. - static tsi_ssl_root_certs_store* default_root_store_; - - // Default PEM root certificates. - static grpc_slice default_pem_root_certs_; -}; - -} // namespace grpc_core - #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SECURITY_CONNECTOR_H */ diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc new file mode 100644 index 0000000000..20a9533dd1 --- /dev/null +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -0,0 +1,474 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/support/port_platform.h> + +#include "src/core/lib/security/security_connector/ssl/ssl_security_connector.h" + +#include <stdbool.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> + +#include "src/core/ext/transport/chttp2/alpn/alpn.h" +#include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/security/context/security_context.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/credentials/ssl/ssl_credentials.h" +#include "src/core/lib/security/security_connector/load_system_roots.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" +#include "src/core/lib/security/transport/security_handshaker.h" +#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/tsi/transport_security.h" + +typedef struct { + grpc_channel_security_connector base; + tsi_ssl_client_handshaker_factory* client_handshaker_factory; + char* target_name; + char* overridden_target_name; + const verify_peer_options* verify_options; +} grpc_ssl_channel_security_connector; + +typedef struct { + grpc_server_security_connector base; + tsi_ssl_server_handshaker_factory* server_handshaker_factory; +} grpc_ssl_server_security_connector; + +static bool server_connector_has_cert_config_fetcher( + grpc_ssl_server_security_connector* c) { + GPR_ASSERT(c != nullptr); + grpc_ssl_server_credentials* server_creds = + reinterpret_cast<grpc_ssl_server_credentials*>(c->base.server_creds); + GPR_ASSERT(server_creds != nullptr); + return server_creds->certificate_config_fetcher.cb != nullptr; +} + +static void ssl_channel_destroy(grpc_security_connector* sc) { + grpc_ssl_channel_security_connector* c = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); + grpc_channel_credentials_unref(c->base.channel_creds); + grpc_call_credentials_unref(c->base.request_metadata_creds); + tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory); + c->client_handshaker_factory = nullptr; + if (c->target_name != nullptr) gpr_free(c->target_name); + if (c->overridden_target_name != nullptr) gpr_free(c->overridden_target_name); + gpr_free(sc); +} + +static void ssl_server_destroy(grpc_security_connector* sc) { + grpc_ssl_server_security_connector* c = + reinterpret_cast<grpc_ssl_server_security_connector*>(sc); + grpc_server_credentials_unref(c->base.server_creds); + tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory); + c->server_handshaker_factory = nullptr; + gpr_free(sc); +} + +static void ssl_channel_add_handshakers(grpc_channel_security_connector* sc, + grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) { + grpc_ssl_channel_security_connector* c = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); + // Instantiate TSI handshaker. + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( + c->client_handshaker_factory, + c->overridden_target_name != nullptr ? c->overridden_target_name + : c->target_name, + &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + grpc_handshake_manager_add( + handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); +} + +/* Attempts to replace the server_handshaker_factory with a new factory using + * the provided grpc_ssl_server_certificate_config. Should new factory creation + * fail, the existing factory will not be replaced. Returns true on success (new + * factory created). */ +static bool try_replace_server_handshaker_factory( + grpc_ssl_server_security_connector* sc, + const grpc_ssl_server_certificate_config* config) { + if (config == nullptr) { + gpr_log(GPR_ERROR, + "Server certificate config callback returned invalid (NULL) " + "config."); + return false; + } + gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config); + + size_t num_alpn_protocols = 0; + const char** alpn_protocol_strings = + grpc_fill_alpn_protocol_strings(&num_alpn_protocols); + tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( + config->pem_key_cert_pairs, config->num_key_cert_pairs); + tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; + grpc_ssl_server_credentials* server_creds = + reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds); + tsi_result result = tsi_create_ssl_server_handshaker_factory_ex( + cert_pairs, config->num_key_cert_pairs, config->pem_root_certs, + grpc_get_tsi_client_certificate_request_type( + server_creds->config.client_certificate_request), + grpc_get_ssl_cipher_suites(), alpn_protocol_strings, + static_cast<uint16_t>(num_alpn_protocols), &new_handshaker_factory); + gpr_free(cert_pairs); + gpr_free((void*)alpn_protocol_strings); + + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return false; + } + tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory); + sc->server_handshaker_factory = new_handshaker_factory; + return true; +} + +/* Attempts to fetch the server certificate config if a callback is available. + * Current certificate config will continue to be used if the callback returns + * an error. Returns true if new credentials were sucessfully loaded. */ +static bool try_fetch_ssl_server_credentials( + grpc_ssl_server_security_connector* sc) { + grpc_ssl_server_certificate_config* certificate_config = nullptr; + bool status; + + GPR_ASSERT(sc != nullptr); + if (!server_connector_has_cert_config_fetcher(sc)) return false; + + grpc_ssl_server_credentials* server_creds = + reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds); + grpc_ssl_certificate_config_reload_status cb_result = + server_creds->certificate_config_fetcher.cb( + server_creds->certificate_config_fetcher.user_data, + &certificate_config); + if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { + gpr_log(GPR_DEBUG, "No change in SSL server credentials."); + status = false; + } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) { + status = try_replace_server_handshaker_factory(sc, certificate_config); + } else { + // Log error, continue using previously-loaded credentials. + gpr_log(GPR_ERROR, + "Failed fetching new server credentials, continuing to " + "use previously-loaded credentials."); + status = false; + } + + if (certificate_config != nullptr) { + grpc_ssl_server_certificate_config_destroy(certificate_config); + } + return status; +} + +static void ssl_server_add_handshakers(grpc_server_security_connector* sc, + grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) { + grpc_ssl_server_security_connector* c = + reinterpret_cast<grpc_ssl_server_security_connector*>(sc); + // Instantiate TSI handshaker. + try_fetch_ssl_server_credentials(c); + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( + c->server_handshaker_factory, &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + grpc_handshake_manager_add( + handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); +} + +static grpc_error* ssl_check_peer(grpc_security_connector* sc, + const char* peer_name, const tsi_peer* peer, + grpc_auth_context** auth_context) { +#if TSI_OPENSSL_ALPN_SUPPORT + /* Check the ALPN if ALPN is supported. */ + const tsi_peer_property* p = + tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); + if (p == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing selected ALPN property."); + } + if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: invalid ALPN value."); + } +#endif /* TSI_OPENSSL_ALPN_SUPPORT */ + /* Check the peer name if specified. */ + if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { + char* msg; + gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name); + grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + return error; + } + *auth_context = grpc_ssl_peer_to_auth_context(peer); + return GRPC_ERROR_NONE; +} + +static void ssl_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_auth_context** auth_context, + grpc_closure* on_peer_checked) { + grpc_ssl_channel_security_connector* c = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); + const char* target_name = c->overridden_target_name != nullptr + ? c->overridden_target_name + : c->target_name; + grpc_error* error = ssl_check_peer(sc, target_name, &peer, auth_context); + if (error == GRPC_ERROR_NONE && + c->verify_options->verify_peer_callback != nullptr) { + const tsi_peer_property* p = + tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); + if (p == nullptr) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing pem cert property."); + } else { + char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1)); + memcpy(peer_pem, p->value.data, p->value.length); + peer_pem[p->value.length] = '\0'; + int callback_status = c->verify_options->verify_peer_callback( + target_name, peer_pem, + c->verify_options->verify_peer_callback_userdata); + gpr_free(peer_pem); + if (callback_status) { + char* msg; + gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", + callback_status); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + } + } + } + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); +} + +static void ssl_server_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_auth_context** auth_context, + grpc_closure* on_peer_checked) { + grpc_error* error = ssl_check_peer(sc, nullptr, &peer, auth_context); + tsi_peer_destruct(&peer); + GRPC_CLOSURE_SCHED(on_peer_checked, error); +} + +static int ssl_channel_cmp(grpc_security_connector* sc1, + grpc_security_connector* sc2) { + grpc_ssl_channel_security_connector* c1 = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc1); + grpc_ssl_channel_security_connector* c2 = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc2); + int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); + if (c != 0) return c; + c = strcmp(c1->target_name, c2->target_name); + if (c != 0) return c; + return (c1->overridden_target_name == nullptr || + c2->overridden_target_name == nullptr) + ? GPR_ICMP(c1->overridden_target_name, c2->overridden_target_name) + : strcmp(c1->overridden_target_name, c2->overridden_target_name); +} + +static int ssl_server_cmp(grpc_security_connector* sc1, + grpc_security_connector* sc2) { + return grpc_server_security_connector_cmp( + reinterpret_cast<grpc_server_security_connector*>(sc1), + reinterpret_cast<grpc_server_security_connector*>(sc2)); +} + +static bool ssl_channel_check_call_host(grpc_channel_security_connector* sc, + const char* host, + grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) { + grpc_ssl_channel_security_connector* c = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); + grpc_security_status status = GRPC_SECURITY_ERROR; + tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); + if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; + /* If the target name was overridden, then the original target_name was + 'checked' transitively during the previous peer check at the end of the + handshake. */ + if (c->overridden_target_name != nullptr && + strcmp(host, c->target_name) == 0) { + status = GRPC_SECURITY_OK; + } + if (status != GRPC_SECURITY_OK) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "call host does not match SSL server name"); + } + grpc_shallow_peer_destruct(&peer); + return true; +} + +static void ssl_channel_cancel_check_call_host( + grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, + grpc_error* error) { + GRPC_ERROR_UNREF(error); +} + +static grpc_security_connector_vtable ssl_channel_vtable = { + ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp}; + +static grpc_security_connector_vtable ssl_server_vtable = { + ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp}; + +grpc_security_status grpc_ssl_channel_security_connector_create( + grpc_channel_credentials* channel_creds, + grpc_call_credentials* request_metadata_creds, + const grpc_ssl_config* config, const char* target_name, + const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache, + grpc_channel_security_connector** sc) { + tsi_result result = TSI_OK; + grpc_ssl_channel_security_connector* c; + char* port; + bool has_key_cert_pair; + tsi_ssl_client_handshaker_options options; + memset(&options, 0, sizeof(options)); + options.alpn_protocols = + grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); + + if (config == nullptr || target_name == nullptr) { + gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); + goto error; + } + if (config->pem_root_certs == nullptr) { + // Use default root certificates. + options.pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); + options.root_store = grpc_core::DefaultSslRootStore::GetRootStore(); + if (options.pem_root_certs == nullptr) { + gpr_log(GPR_ERROR, "Could not get default pem root certs."); + goto error; + } + } else { + options.pem_root_certs = config->pem_root_certs; + } + c = static_cast<grpc_ssl_channel_security_connector*>( + gpr_zalloc(sizeof(grpc_ssl_channel_security_connector))); + + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.vtable = &ssl_channel_vtable; + c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; + c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); + c->base.request_metadata_creds = + grpc_call_credentials_ref(request_metadata_creds); + c->base.check_call_host = ssl_channel_check_call_host; + c->base.cancel_check_call_host = ssl_channel_cancel_check_call_host; + c->base.add_handshakers = ssl_channel_add_handshakers; + gpr_split_host_port(target_name, &c->target_name, &port); + gpr_free(port); + if (overridden_target_name != nullptr) { + c->overridden_target_name = gpr_strdup(overridden_target_name); + } + c->verify_options = &config->verify_options; + + has_key_cert_pair = config->pem_key_cert_pair != nullptr && + config->pem_key_cert_pair->private_key != nullptr && + config->pem_key_cert_pair->cert_chain != nullptr; + if (has_key_cert_pair) { + options.pem_key_cert_pair = config->pem_key_cert_pair; + } + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.session_cache = ssl_session_cache; + result = tsi_create_ssl_client_handshaker_factory_with_options( + &options, &c->client_handshaker_factory); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + ssl_channel_destroy(&c->base.base); + *sc = nullptr; + goto error; + } + *sc = &c->base; + gpr_free((void*)options.alpn_protocols); + return GRPC_SECURITY_OK; + +error: + gpr_free((void*)options.alpn_protocols); + return GRPC_SECURITY_ERROR; +} + +static grpc_ssl_server_security_connector* +grpc_ssl_server_security_connector_initialize( + grpc_server_credentials* server_creds) { + grpc_ssl_server_security_connector* c = + static_cast<grpc_ssl_server_security_connector*>( + gpr_zalloc(sizeof(grpc_ssl_server_security_connector))); + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; + c->base.base.vtable = &ssl_server_vtable; + c->base.add_handshakers = ssl_server_add_handshakers; + c->base.server_creds = grpc_server_credentials_ref(server_creds); + return c; +} + +grpc_security_status grpc_ssl_server_security_connector_create( + grpc_server_credentials* gsc, grpc_server_security_connector** sc) { + tsi_result result = TSI_OK; + grpc_ssl_server_credentials* server_credentials = + reinterpret_cast<grpc_ssl_server_credentials*>(gsc); + grpc_security_status retval = GRPC_SECURITY_OK; + + GPR_ASSERT(server_credentials != nullptr); + GPR_ASSERT(sc != nullptr); + + grpc_ssl_server_security_connector* c = + grpc_ssl_server_security_connector_initialize(gsc); + if (server_connector_has_cert_config_fetcher(c)) { + // Load initial credentials from certificate_config_fetcher: + if (!try_fetch_ssl_server_credentials(c)) { + gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher."); + retval = GRPC_SECURITY_ERROR; + } + } else { + size_t num_alpn_protocols = 0; + const char** alpn_protocol_strings = + grpc_fill_alpn_protocol_strings(&num_alpn_protocols); + result = tsi_create_ssl_server_handshaker_factory_ex( + server_credentials->config.pem_key_cert_pairs, + server_credentials->config.num_key_cert_pairs, + server_credentials->config.pem_root_certs, + grpc_get_tsi_client_certificate_request_type( + server_credentials->config.client_certificate_request), + grpc_get_ssl_cipher_suites(), alpn_protocol_strings, + static_cast<uint16_t>(num_alpn_protocols), + &c->server_handshaker_factory); + gpr_free((void*)alpn_protocol_strings); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + retval = GRPC_SECURITY_ERROR; + } + } + + if (retval == GRPC_SECURITY_OK) { + *sc = &c->base; + } else { + if (c != nullptr) ssl_server_destroy(&c->base.base); + if (sc != nullptr) *sc = nullptr; + } + return retval; +} diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.h b/src/core/lib/security/security_connector/ssl/ssl_security_connector.h new file mode 100644 index 0000000000..9b80590606 --- /dev/null +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.h @@ -0,0 +1,77 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_SSL_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_SSL_SECURITY_CONNECTOR_H + +#include <grpc/support/port_platform.h> + +#include <grpc/grpc_security.h> + +#include "src/core/lib/security/security_connector/security_connector.h" + +#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/tsi/transport_security_interface.h" + +typedef struct { + tsi_ssl_pem_key_cert_pair* pem_key_cert_pair; + char* pem_root_certs; + verify_peer_options verify_options; +} grpc_ssl_config; + +/* Creates an SSL channel_security_connector. + - request_metadata_creds is the credentials object which metadata + will be sent with each request. This parameter can be NULL. + - config is the SSL config to be used for the SSL channel establishment. + - is_client should be 0 for a server or a non-0 value for a client. + - secure_peer_name is the secure peer name that should be checked in + grpc_channel_security_connector_check_peer. This parameter may be NULL in + which case the peer name will not be checked. Note that if this parameter + is not NULL, then, pem_root_certs should not be NULL either. + - sc is a pointer on the connector to be created. + This function returns GRPC_SECURITY_OK in case of success or a + specific error code otherwise. +*/ +grpc_security_status grpc_ssl_channel_security_connector_create( + grpc_channel_credentials* channel_creds, + grpc_call_credentials* request_metadata_creds, + const grpc_ssl_config* config, const char* target_name, + const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache, + grpc_channel_security_connector** sc); + +/* Config for ssl servers. */ +typedef struct { + tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs; + size_t num_key_cert_pairs; + char* pem_root_certs; + grpc_ssl_client_certificate_request_type client_certificate_request; +} grpc_ssl_server_config; + +/* Creates an SSL server_security_connector. + - config is the SSL config to be used for the SSL channel establishment. + - sc is a pointer on the connector to be created. + This function returns GRPC_SECURITY_OK in case of success or a + specific error code otherwise. +*/ +grpc_security_status grpc_ssl_server_security_connector_create( + grpc_server_credentials* server_credentials, + grpc_server_security_connector** sc); + +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_SSL_SECURITY_CONNECTOR_H \ + */ diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc new file mode 100644 index 0000000000..fbf41cfbc7 --- /dev/null +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -0,0 +1,345 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/support/port_platform.h> + +#include "src/core/lib/security/security_connector/ssl_utils.h" + +#include <grpc/slice_buffer.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> + +#include "src/core/ext/transport/chttp2/alpn/alpn.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/load_file.h" +#include "src/core/lib/security/context/security_context.h" +#include "src/core/lib/security/security_connector/load_system_roots.h" +#include "src/core/tsi/ssl_transport_security.h" + +/* -- Constants. -- */ + +#ifndef INSTALL_PREFIX +static const char* installed_roots_path = "/usr/share/grpc/roots.pem"; +#else +static const char* installed_roots_path = + INSTALL_PREFIX "/share/grpc/roots.pem"; +#endif + +/** Environment variable used as a flag to enable/disable loading system root + certificates from the OS trust store. */ +#ifndef GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR +#define GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_NOT_USE_SYSTEM_SSL_ROOTS" +#endif + +#ifndef TSI_OPENSSL_ALPN_SUPPORT +#define TSI_OPENSSL_ALPN_SUPPORT 1 +#endif + +/* -- Overridden default roots. -- */ + +static grpc_ssl_roots_override_callback ssl_roots_override_cb = nullptr; + +void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) { + ssl_roots_override_cb = cb; +} + +/* -- Cipher suites. -- */ + +/* Defines the cipher suites that we accept by default. All these cipher suites + are compliant with HTTP2. */ +#define GRPC_SSL_CIPHER_SUITES \ + "ECDHE-ECDSA-AES128-GCM-SHA256:" \ + "ECDHE-ECDSA-AES256-GCM-SHA384:" \ + "ECDHE-RSA-AES128-GCM-SHA256:" \ + "ECDHE-RSA-AES256-GCM-SHA384" + +static gpr_once cipher_suites_once = GPR_ONCE_INIT; +static const char* cipher_suites = nullptr; + +static void init_cipher_suites(void) { + char* overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES"); + cipher_suites = overridden != nullptr ? overridden : GRPC_SSL_CIPHER_SUITES; +} + +/* --- Util --- */ + +const char* grpc_get_ssl_cipher_suites(void) { + gpr_once_init(&cipher_suites_once, init_cipher_suites); + return cipher_suites; +} + +tsi_client_certificate_request_type +grpc_get_tsi_client_certificate_request_type( + grpc_ssl_client_certificate_request_type grpc_request_type) { + switch (grpc_request_type) { + case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE: + return TSI_DONT_REQUEST_CLIENT_CERTIFICATE; + + case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY; + + case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: + return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY; + + case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY; + + case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: + return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; + + default: + return TSI_DONT_REQUEST_CLIENT_CERTIFICATE; + } +} + +const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols) { + GPR_ASSERT(num_alpn_protocols != nullptr); + *num_alpn_protocols = grpc_chttp2_num_alpn_versions(); + const char** alpn_protocol_strings = static_cast<const char**>( + gpr_malloc(sizeof(const char*) * (*num_alpn_protocols))); + for (size_t i = 0; i < *num_alpn_protocols; i++) { + alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i); + } + return alpn_protocol_strings; +} + +int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) { + char* allocated_name = nullptr; + int r; + + char* ignored_port; + gpr_split_host_port(peer_name, &allocated_name, &ignored_port); + gpr_free(ignored_port); + peer_name = allocated_name; + if (!peer_name) return 0; + + // IPv6 zone-id should not be included in comparisons. + char* const zone_id = strchr(allocated_name, '%'); + if (zone_id != nullptr) *zone_id = '\0'; + + r = tsi_ssl_peer_matches_name(peer, peer_name); + gpr_free(allocated_name); + return r; +} + +grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) { + size_t i; + grpc_auth_context* ctx = nullptr; + const char* peer_identity_property_name = nullptr; + + /* The caller has checked the certificate type property. */ + GPR_ASSERT(peer->property_count >= 1); + ctx = grpc_auth_context_create(nullptr); + grpc_auth_context_add_cstring_property( + ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + GRPC_SSL_TRANSPORT_SECURITY_TYPE); + for (i = 0; i < peer->property_count; i++) { + const tsi_peer_property* prop = &peer->properties[i]; + if (prop->name == nullptr) continue; + if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) { + /* If there is no subject alt name, have the CN as the identity. */ + if (peer_identity_property_name == nullptr) { + peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME; + } + grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME, + prop->value.data, prop->value.length); + } else if (strcmp(prop->name, + TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { + peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME; + grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME, + prop->value.data, prop->value.length); + } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) { + grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME, + prop->value.data, prop->value.length); + } else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) { + grpc_auth_context_add_property(ctx, GRPC_SSL_SESSION_REUSED_PROPERTY, + prop->value.data, prop->value.length); + } + } + if (peer_identity_property_name != nullptr) { + GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( + ctx, peer_identity_property_name) == 1); + } + return ctx; +} + +static void add_shallow_auth_property_to_peer(tsi_peer* peer, + const grpc_auth_property* prop, + const char* tsi_prop_name) { + tsi_peer_property* tsi_prop = &peer->properties[peer->property_count++]; + tsi_prop->name = const_cast<char*>(tsi_prop_name); + tsi_prop->value.data = prop->value; + tsi_prop->value.length = prop->value_length; +} + +tsi_peer grpc_shallow_peer_from_ssl_auth_context( + const grpc_auth_context* auth_context) { + size_t max_num_props = 0; + grpc_auth_property_iterator it; + const grpc_auth_property* prop; + tsi_peer peer; + memset(&peer, 0, sizeof(peer)); + + it = grpc_auth_context_property_iterator(auth_context); + while (grpc_auth_property_iterator_next(&it) != nullptr) max_num_props++; + + if (max_num_props > 0) { + peer.properties = static_cast<tsi_peer_property*>( + gpr_malloc(max_num_props * sizeof(tsi_peer_property))); + it = grpc_auth_context_property_iterator(auth_context); + while ((prop = grpc_auth_property_iterator_next(&it)) != nullptr) { + if (strcmp(prop->name, GRPC_X509_SAN_PROPERTY_NAME) == 0) { + add_shallow_auth_property_to_peer( + &peer, prop, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY); + } else if (strcmp(prop->name, GRPC_X509_CN_PROPERTY_NAME) == 0) { + add_shallow_auth_property_to_peer( + &peer, prop, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); + } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) { + add_shallow_auth_property_to_peer(&peer, prop, + TSI_X509_PEM_CERT_PROPERTY); + } + } + } + return peer; +} + +void grpc_shallow_peer_destruct(tsi_peer* peer) { + if (peer->properties != nullptr) gpr_free(peer->properties); +} + +/* --- Ssl cache implementation. --- */ + +grpc_ssl_session_cache* grpc_ssl_session_cache_create_lru(size_t capacity) { + tsi_ssl_session_cache* cache = tsi_ssl_session_cache_create_lru(capacity); + return reinterpret_cast<grpc_ssl_session_cache*>(cache); +} + +void grpc_ssl_session_cache_destroy(grpc_ssl_session_cache* cache) { + tsi_ssl_session_cache* tsi_cache = + reinterpret_cast<tsi_ssl_session_cache*>(cache); + tsi_ssl_session_cache_unref(tsi_cache); +} + +static void* grpc_ssl_session_cache_arg_copy(void* p) { + tsi_ssl_session_cache* tsi_cache = + reinterpret_cast<tsi_ssl_session_cache*>(p); + // destroy call below will unref the pointer. + tsi_ssl_session_cache_ref(tsi_cache); + return p; +} + +static void grpc_ssl_session_cache_arg_destroy(void* p) { + tsi_ssl_session_cache* tsi_cache = + reinterpret_cast<tsi_ssl_session_cache*>(p); + tsi_ssl_session_cache_unref(tsi_cache); +} + +static int grpc_ssl_session_cache_arg_cmp(void* p, void* q) { + return GPR_ICMP(p, q); +} + +grpc_arg grpc_ssl_session_cache_create_channel_arg( + grpc_ssl_session_cache* cache) { + static const grpc_arg_pointer_vtable vtable = { + grpc_ssl_session_cache_arg_copy, + grpc_ssl_session_cache_arg_destroy, + grpc_ssl_session_cache_arg_cmp, + }; + return grpc_channel_arg_pointer_create( + const_cast<char*>(GRPC_SSL_SESSION_CACHE_ARG), cache, &vtable); +} + +/* --- Default SSL root store implementation. --- */ + +namespace grpc_core { + +tsi_ssl_root_certs_store* DefaultSslRootStore::default_root_store_; +grpc_slice DefaultSslRootStore::default_pem_root_certs_; + +const tsi_ssl_root_certs_store* DefaultSslRootStore::GetRootStore() { + InitRootStore(); + return default_root_store_; +} + +const char* DefaultSslRootStore::GetPemRootCerts() { + InitRootStore(); + return GRPC_SLICE_IS_EMPTY(default_pem_root_certs_) + ? nullptr + : reinterpret_cast<const char*> + GRPC_SLICE_START_PTR(default_pem_root_certs_); +} + +grpc_slice DefaultSslRootStore::ComputePemRootCerts() { + grpc_slice result = grpc_empty_slice(); + char* not_use_system_roots_env_value = + gpr_getenv(GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR); + const bool not_use_system_roots = gpr_is_true(not_use_system_roots_env_value); + gpr_free(not_use_system_roots_env_value); + // First try to load the roots from the environment. + char* default_root_certs_path = + gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); + if (default_root_certs_path != nullptr) { + GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(default_root_certs_path, 1, &result)); + gpr_free(default_root_certs_path); + } + // Try overridden roots if needed. + grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL; + if (GRPC_SLICE_IS_EMPTY(result) && ssl_roots_override_cb != nullptr) { + char* pem_root_certs = nullptr; + ovrd_res = ssl_roots_override_cb(&pem_root_certs); + if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) { + GPR_ASSERT(pem_root_certs != nullptr); + result = grpc_slice_from_copied_buffer( + pem_root_certs, + strlen(pem_root_certs) + 1); // nullptr terminator. + } + gpr_free(pem_root_certs); + } + // Try loading roots from OS trust store if flag is enabled. + if (GRPC_SLICE_IS_EMPTY(result) && !not_use_system_roots) { + result = LoadSystemRootCerts(); + } + // Fallback to roots manually shipped with gRPC. + if (GRPC_SLICE_IS_EMPTY(result) && + ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) { + GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(installed_roots_path, 1, &result)); + } + return result; +} + +void DefaultSslRootStore::InitRootStore() { + static gpr_once once = GPR_ONCE_INIT; + gpr_once_init(&once, DefaultSslRootStore::InitRootStoreOnce); +} + +void DefaultSslRootStore::InitRootStoreOnce() { + default_pem_root_certs_ = ComputePemRootCerts(); + if (!GRPC_SLICE_IS_EMPTY(default_pem_root_certs_)) { + default_root_store_ = + tsi_ssl_root_certs_store_create(reinterpret_cast<const char*>( + GRPC_SLICE_START_PTR(default_pem_root_certs_))); + } +} + +} // namespace grpc_core diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h new file mode 100644 index 0000000000..6f6d473311 --- /dev/null +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -0,0 +1,93 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_UTILS_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_UTILS_H + +#include <grpc/support/port_platform.h> + +#include <stdbool.h> + +#include <grpc/grpc_security.h> +#include <grpc/slice_buffer.h> + +#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/tsi/transport_security_interface.h" + +/* --- Util. --- */ + +/* --- URL schemes. --- */ +#define GRPC_SSL_URL_SCHEME "https" + +/* Return HTTP2-compliant cipher suites that gRPC accepts by default. */ +const char* grpc_get_ssl_cipher_suites(void); + +/* Map from grpc_ssl_client_certificate_request_type to + * tsi_client_certificate_request_type. */ +tsi_client_certificate_request_type +grpc_get_tsi_client_certificate_request_type( + grpc_ssl_client_certificate_request_type grpc_request_type); + +/* Return an array of strings containing alpn protocols. */ +const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols); + +/* Exposed for testing only. */ +grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer); +tsi_peer grpc_shallow_peer_from_ssl_auth_context( + const grpc_auth_context* auth_context); +void grpc_shallow_peer_destruct(tsi_peer* peer); +int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name); + +/* --- Default SSL Root Store. --- */ +namespace grpc_core { + +// The class implements default SSL root store. +class DefaultSslRootStore { + public: + // Gets the default SSL root store. Returns nullptr if not found. + static const tsi_ssl_root_certs_store* GetRootStore(); + + // Gets the default PEM root certificate. + static const char* GetPemRootCerts(); + + protected: + // Returns default PEM root certificates in nullptr terminated grpc_slice. + // This function is protected instead of private, so that it can be tested. + static grpc_slice ComputePemRootCerts(); + + private: + // Construct me not! + DefaultSslRootStore(); + + // Initialization of default SSL root store. + static void InitRootStore(); + + // One-time initialization of default SSL root store. + static void InitRootStoreOnce(); + + // SSL root store in tsi_ssl_root_certs_store object. + static tsi_ssl_root_certs_store* default_root_store_; + + // Default PEM root certificates. + static grpc_slice default_pem_root_certs_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_UTILS_H \ + */ diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 0f125e7c26..e34eacc8d7 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -32,6 +32,7 @@ #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/security_connector.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/surface/call.h" diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index d7095c24d4..123be79c88 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -39,6 +39,7 @@ #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" @@ -63,6 +64,7 @@ struct grpc_channel { grpc_compression_options compression_options; gpr_atm call_size_estimate; + grpc_resource_user* resource_user; gpr_mu registered_call_mu; registered_call* registered_calls; @@ -82,6 +84,8 @@ grpc_channel* grpc_channel_create_with_builder( char* target = gpr_strdup(grpc_channel_stack_builder_get_target(builder)); grpc_channel_args* args = grpc_channel_args_copy( grpc_channel_stack_builder_get_channel_arguments(builder)); + grpc_resource_user* resource_user = + grpc_channel_stack_builder_get_resource_user(builder); grpc_channel* channel; if (channel_stack_type == GRPC_SERVER_CHANNEL) { GRPC_STATS_INC_SERVER_CHANNELS_CREATED(); @@ -101,6 +105,7 @@ grpc_channel* grpc_channel_create_with_builder( } channel->target = target; + channel->resource_user = resource_user; channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type); bool channelz_enabled = GRPC_ENABLE_CHANNELZ_DEFAULT; size_t channel_tracer_max_memory = 0; // default to off @@ -217,7 +222,8 @@ grpc_core::channelz::ChannelNode* grpc_channel_get_channelz_node( grpc_channel* grpc_channel_create(const char* target, const grpc_channel_args* input_args, grpc_channel_stack_type channel_stack_type, - grpc_transport* optional_transport) { + grpc_transport* optional_transport, + grpc_resource_user* resource_user) { grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); const grpc_core::UniquePtr<char> default_authority = get_default_authority(input_args); @@ -227,11 +233,17 @@ grpc_channel* grpc_channel_create(const char* target, grpc_channel_args_destroy(args); grpc_channel_stack_builder_set_target(builder, target); grpc_channel_stack_builder_set_transport(builder, optional_transport); + grpc_channel_stack_builder_set_resource_user(builder, resource_user); if (!grpc_channel_init_create_stack(builder, channel_stack_type)) { grpc_channel_stack_builder_destroy(builder); + if (resource_user != nullptr) { + grpc_resource_user_free(resource_user, GRPC_RESOURCE_QUOTA_CHANNEL_SIZE); + } return nullptr; } - return grpc_channel_create_with_builder(builder, channel_stack_type); + grpc_channel* channel = + grpc_channel_create_with_builder(builder, channel_stack_type); + return channel; } size_t grpc_channel_get_call_size_estimate(grpc_channel* channel) { @@ -441,6 +453,10 @@ static void destroy_channel(void* arg, grpc_error* error) { GRPC_MDELEM_UNREF(rc->authority); gpr_free(rc); } + if (channel->resource_user != nullptr) { + grpc_resource_user_free(channel->resource_user, + GRPC_RESOURCE_QUOTA_CHANNEL_SIZE); + } gpr_mu_destroy(&channel->registered_call_mu); gpr_free(channel->target); gpr_free(channel); diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index 4ac76b8a29..ab00b8e94f 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -29,7 +29,8 @@ grpc_channel* grpc_channel_create(const char* target, const grpc_channel_args* args, grpc_channel_stack_type channel_stack_type, - grpc_transport* optional_transport); + grpc_transport* optional_transport, + grpc_resource_user* resource_user = nullptr); grpc_channel* grpc_channel_create_with_builder( grpc_channel_stack_builder* builder, diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 35ab2c3bce..72391ca697 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -189,6 +189,8 @@ typedef struct { struct grpc_server { grpc_channel_args* channel_args; + grpc_resource_user* default_resource_user; + grpc_completion_queue** cqs; grpc_pollset** pollsets; size_t cq_count; @@ -1024,6 +1026,15 @@ grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) { grpc_slice_from_static_string("Server created")); } + if (args != nullptr) { + grpc_resource_quota* resource_quota = + grpc_resource_quota_from_channel_args(args, false /* create */); + if (resource_quota != nullptr) { + server->default_resource_user = + grpc_resource_user_create(resource_quota, "default"); + } + } + return server; } @@ -1122,7 +1133,8 @@ void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets, void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, grpc_pollset* accepting_pollset, const grpc_channel_args* args, - intptr_t socket_uuid) { + intptr_t socket_uuid, + grpc_resource_user* resource_user) { size_t num_registered_methods; size_t alloc; registered_method* rm; @@ -1135,7 +1147,8 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, uint32_t max_probes = 0; grpc_transport_op* op = nullptr; - channel = grpc_channel_create(nullptr, args, GRPC_SERVER_CHANNEL, transport); + channel = grpc_channel_create(nullptr, args, GRPC_SERVER_CHANNEL, transport, + resource_user); chand = static_cast<channel_data*>( grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0) ->channel_data); @@ -1330,6 +1343,13 @@ void grpc_server_shutdown_and_notify(grpc_server* server, channel_broadcaster_shutdown(&broadcaster, true /* send_goaway */, GRPC_ERROR_NONE); + + if (server->default_resource_user != nullptr) { + grpc_resource_quota_unref( + grpc_resource_user_quota(server->default_resource_user)); + grpc_resource_user_shutdown(server->default_resource_user); + grpc_resource_user_unref(server->default_resource_user); + } } void grpc_server_cancel_all_calls(grpc_server* server) { @@ -1546,6 +1566,10 @@ const grpc_channel_args* grpc_server_get_channel_args(grpc_server* server) { return server->channel_args; } +grpc_resource_user* grpc_server_get_default_resource_user(grpc_server* server) { + return server->default_resource_user; +} + int grpc_server_has_open_connections(grpc_server* server) { int r; gpr_mu_lock(&server->mu_global); diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 33c205417e..27038fdb7a 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -47,7 +47,8 @@ void grpc_server_add_listener(grpc_server* server, void* listener, void grpc_server_setup_transport(grpc_server* server, grpc_transport* transport, grpc_pollset* accepting_pollset, const grpc_channel_args* args, - intptr_t socket_uuid); + intptr_t socket_uuid, + grpc_resource_user* resource_user = nullptr); /* fills in the uuids of all sockets used for connections on this server */ void grpc_server_populate_server_sockets( @@ -63,6 +64,8 @@ grpc_core::channelz::ServerNode* grpc_server_get_channelz_node( const grpc_channel_args* grpc_server_get_channel_args(grpc_server* server); +grpc_resource_user* grpc_server_get_default_resource_user(grpc_server* server); + int grpc_server_has_open_connections(grpc_server* server); /* Do not call this before grpc_server_start. Returns the pollsets and the diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index cdcb9a11d2..4ebe73f82a 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -63,51 +63,53 @@ static uint8_t g_bytes[] = { 115, 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 47, 103, 114, 112, 99, 46, 108, 98, 46, 118, 49, 46, 76, 111, 97, 100, 66, 97, 108, 97, 110, 99, 101, 114, 47, 66, 97, 108, 97, 110, 99, 101, 76, 111, - 97, 100, 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116, - 114, 101, 97, 109, 47, 103, 122, 105, 112, 71, 69, 84, 80, 79, 83, - 84, 47, 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 104, 116, - 116, 112, 104, 116, 116, 112, 115, 50, 48, 48, 50, 48, 52, 50, 48, - 54, 51, 48, 52, 52, 48, 48, 52, 48, 52, 53, 48, 48, 97, 99, - 99, 101, 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 103, 122, 105, - 112, 44, 32, 100, 101, 102, 108, 97, 116, 101, 97, 99, 99, 101, 112, - 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 97, 99, 99, 101, 112, - 116, 45, 114, 97, 110, 103, 101, 115, 97, 99, 99, 101, 112, 116, 97, - 99, 99, 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, - 108, 108, 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, - 108, 108, 111, 119, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, - 111, 110, 99, 97, 99, 104, 101, 45, 99, 111, 110, 116, 114, 111, 108, - 99, 111, 110, 116, 101, 110, 116, 45, 100, 105, 115, 112, 111, 115, 105, - 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, - 103, 117, 97, 103, 101, 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, - 110, 103, 116, 104, 99, 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, - 97, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, - 110, 103, 101, 99, 111, 111, 107, 105, 101, 100, 97, 116, 101, 101, 116, - 97, 103, 101, 120, 112, 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, - 102, 114, 111, 109, 105, 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, - 109, 111, 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, - 102, 45, 110, 111, 110, 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, - 114, 97, 110, 103, 101, 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, - 105, 101, 100, 45, 115, 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, - 111, 100, 105, 102, 105, 101, 100, 108, 105, 110, 107, 108, 111, 99, 97, - 116, 105, 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, 100, - 115, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116, 105, - 99, 97, 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 111, - 114, 105, 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114, 101, - 102, 101, 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116, - 114, 121, 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115, - 101, 116, 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99, 116, - 45, 116, 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, 117, - 114, 105, 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, 110, - 99, 111, 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119, 119, - 119, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 48, - 105, 100, 101, 110, 116, 105, 116, 121, 116, 114, 97, 105, 108, 101, 114, - 115, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103, 114, - 112, 99, 103, 114, 112, 99, 80, 85, 84, 108, 98, 45, 99, 111, 115, - 116, 45, 98, 105, 110, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, - 101, 102, 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, - 103, 122, 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, - 112, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, - 116, 101, 44, 103, 122, 105, 112}; + 97, 100, 47, 103, 114, 112, 99, 46, 104, 101, 97, 108, 116, 104, 46, + 118, 49, 46, 72, 101, 97, 108, 116, 104, 47, 87, 97, 116, 99, 104, + 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116, 114, 101, + 97, 109, 47, 103, 122, 105, 112, 71, 69, 84, 80, 79, 83, 84, 47, + 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 104, 116, 116, 112, + 104, 116, 116, 112, 115, 50, 48, 48, 50, 48, 52, 50, 48, 54, 51, + 48, 52, 52, 48, 48, 52, 48, 52, 53, 48, 48, 97, 99, 99, 101, + 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 103, 122, 105, 112, 44, + 32, 100, 101, 102, 108, 97, 116, 101, 97, 99, 99, 101, 112, 116, 45, + 108, 97, 110, 103, 117, 97, 103, 101, 97, 99, 99, 101, 112, 116, 45, + 114, 97, 110, 103, 101, 115, 97, 99, 99, 101, 112, 116, 97, 99, 99, + 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108, + 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108, + 111, 119, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, + 99, 97, 99, 104, 101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111, + 110, 116, 101, 110, 116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105, + 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117, + 97, 103, 101, 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, + 116, 104, 99, 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116, + 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103, + 101, 99, 111, 111, 107, 105, 101, 100, 97, 116, 101, 101, 116, 97, 103, + 101, 120, 112, 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, 102, 114, + 111, 109, 105, 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111, + 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, 102, 45, + 110, 111, 110, 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, 114, 97, + 110, 103, 101, 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, 105, 101, + 100, 45, 115, 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, 111, 100, + 105, 102, 105, 101, 100, 108, 105, 110, 107, 108, 111, 99, 97, 116, 105, + 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, 100, 115, 112, + 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, + 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 111, 114, 105, + 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114, 101, 102, 101, + 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116, 114, 121, + 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115, 101, 116, + 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99, 116, 45, 116, + 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, 117, 114, 105, + 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, 110, 99, 111, + 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119, 119, 119, 45, + 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 48, 105, 100, + 101, 110, 116, 105, 116, 121, 116, 114, 97, 105, 108, 101, 114, 115, 97, + 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103, 114, 112, 99, + 103, 114, 112, 99, 80, 85, 84, 108, 98, 45, 99, 111, 115, 116, 45, + 98, 105, 110, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, + 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122, + 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112, 105, + 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, + 44, 103, 122, 105, 112}; static void static_ref(void* unused) {} static void static_unref(void* unused) {} @@ -224,6 +226,7 @@ grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = { {&grpc_static_metadata_vtable, &static_sub_refcnt}, {&grpc_static_metadata_vtable, &static_sub_refcnt}, {&grpc_static_metadata_vtable, &static_sub_refcnt}, + {&grpc_static_metadata_vtable, &static_sub_refcnt}, }; const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { @@ -262,76 +265,77 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { {&grpc_static_metadata_refcounts[32], {{g_bytes + 385, 30}}}, {&grpc_static_metadata_refcounts[33], {{g_bytes + 415, 31}}}, {&grpc_static_metadata_refcounts[34], {{g_bytes + 446, 36}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 493, 11}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 3}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 507, 4}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 511, 1}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 512, 11}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 523, 4}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 527, 5}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 532, 3}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 535, 3}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 538, 3}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 541, 3}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 544, 3}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 547, 3}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 550, 3}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 553, 14}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 567, 13}}}, - {&grpc_static_metadata_refcounts[53], {{g_bytes + 580, 15}}}, - {&grpc_static_metadata_refcounts[54], {{g_bytes + 595, 13}}}, - {&grpc_static_metadata_refcounts[55], {{g_bytes + 608, 6}}}, - {&grpc_static_metadata_refcounts[56], {{g_bytes + 614, 27}}}, - {&grpc_static_metadata_refcounts[57], {{g_bytes + 641, 3}}}, - {&grpc_static_metadata_refcounts[58], {{g_bytes + 644, 5}}}, - {&grpc_static_metadata_refcounts[59], {{g_bytes + 649, 13}}}, - {&grpc_static_metadata_refcounts[60], {{g_bytes + 662, 13}}}, - {&grpc_static_metadata_refcounts[61], {{g_bytes + 675, 19}}}, - {&grpc_static_metadata_refcounts[62], {{g_bytes + 694, 16}}}, - {&grpc_static_metadata_refcounts[63], {{g_bytes + 710, 14}}}, - {&grpc_static_metadata_refcounts[64], {{g_bytes + 724, 16}}}, - {&grpc_static_metadata_refcounts[65], {{g_bytes + 740, 13}}}, - {&grpc_static_metadata_refcounts[66], {{g_bytes + 753, 6}}}, - {&grpc_static_metadata_refcounts[67], {{g_bytes + 759, 4}}}, - {&grpc_static_metadata_refcounts[68], {{g_bytes + 763, 4}}}, - {&grpc_static_metadata_refcounts[69], {{g_bytes + 767, 6}}}, - {&grpc_static_metadata_refcounts[70], {{g_bytes + 773, 7}}}, - {&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 4}}}, - {&grpc_static_metadata_refcounts[72], {{g_bytes + 784, 8}}}, - {&grpc_static_metadata_refcounts[73], {{g_bytes + 792, 17}}}, - {&grpc_static_metadata_refcounts[74], {{g_bytes + 809, 13}}}, - {&grpc_static_metadata_refcounts[75], {{g_bytes + 822, 8}}}, - {&grpc_static_metadata_refcounts[76], {{g_bytes + 830, 19}}}, - {&grpc_static_metadata_refcounts[77], {{g_bytes + 849, 13}}}, - {&grpc_static_metadata_refcounts[78], {{g_bytes + 862, 4}}}, - {&grpc_static_metadata_refcounts[79], {{g_bytes + 866, 8}}}, - {&grpc_static_metadata_refcounts[80], {{g_bytes + 874, 12}}}, - {&grpc_static_metadata_refcounts[81], {{g_bytes + 886, 18}}}, - {&grpc_static_metadata_refcounts[82], {{g_bytes + 904, 19}}}, - {&grpc_static_metadata_refcounts[83], {{g_bytes + 923, 5}}}, - {&grpc_static_metadata_refcounts[84], {{g_bytes + 928, 7}}}, - {&grpc_static_metadata_refcounts[85], {{g_bytes + 935, 7}}}, - {&grpc_static_metadata_refcounts[86], {{g_bytes + 942, 11}}}, - {&grpc_static_metadata_refcounts[87], {{g_bytes + 953, 6}}}, - {&grpc_static_metadata_refcounts[88], {{g_bytes + 959, 10}}}, - {&grpc_static_metadata_refcounts[89], {{g_bytes + 969, 25}}}, - {&grpc_static_metadata_refcounts[90], {{g_bytes + 994, 17}}}, - {&grpc_static_metadata_refcounts[91], {{g_bytes + 1011, 4}}}, - {&grpc_static_metadata_refcounts[92], {{g_bytes + 1015, 3}}}, - {&grpc_static_metadata_refcounts[93], {{g_bytes + 1018, 16}}}, - {&grpc_static_metadata_refcounts[94], {{g_bytes + 1034, 1}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1043, 8}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1051, 16}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1067, 4}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1071, 3}}}, - {&grpc_static_metadata_refcounts[100], {{g_bytes + 1074, 11}}}, - {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}, + {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 28}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}, + {&grpc_static_metadata_refcounts[38], {{g_bytes + 521, 11}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 532, 3}}}, + {&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}}, + {&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}}, + {&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}}, + {&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}}, + {&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}}, + {&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}}, + {&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}}, + {&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}}, + {&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}}, + {&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}}, + {&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}}, + {&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}}, + {&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}}, + {&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}}, + {&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}}, + {&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}}, + {&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}}, + {&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}}, + {&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}}, + {&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}}, + {&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}}, + {&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}}, + {&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}}, + {&grpc_static_metadata_refcounts[63], {{g_bytes + 722, 16}}}, + {&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}}, + {&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}}, + {&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}}, + {&grpc_static_metadata_refcounts[67], {{g_bytes + 781, 6}}}, + {&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}}, + {&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}}, + {&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}}, + {&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}}, + {&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}}, + {&grpc_static_metadata_refcounts[73], {{g_bytes + 812, 8}}}, + {&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}}, + {&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}}, + {&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}}, + {&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}}, + {&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}}, + {&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}}, + {&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}}, + {&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}}, + {&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}}, + {&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}}, + {&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}}, + {&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}}, + {&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}}, + {&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}}, + {&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}}, + {&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}}, + {&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}}, + {&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}}, + {&grpc_static_metadata_refcounts[92], {{g_bytes + 1039, 4}}}, + {&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}}, + {&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}}, + {&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}, + {&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}}, + {&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}}, + {&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}}, + {&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}}, + {&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}}, + {&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}}, + {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}, + {&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}}, + {&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}}, }; uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { @@ -341,17 +345,17 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4}; static const int8_t elems_r[] = { - 15, 9, -8, 0, 2, -44, -78, 17, 0, 6, -8, 0, 0, 0, 6, - -5, -10, 0, 0, -2, -3, -4, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -63, 0, -46, -68, -69, -53, 0, 31, 30, - 29, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 18, - 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, - 2, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, -5, 0}; + 16, 11, -8, 0, 3, -42, -81, -43, 0, 6, -8, 0, 0, 0, -7, + -3, -10, 0, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -63, 0, -47, -68, -69, -70, 0, 33, + 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 20, + 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, + 4, 4, 4, 3, 10, 9, 0, 0, 0, 0, 0, 0, -3, 0}; static uint32_t elems_phash(uint32_t i) { - i -= 40; - uint32_t x = i % 103; - uint32_t y = i / 103; + i -= 41; + uint32_t x = i % 104; + uint32_t y = i / 104; uint32_t h = x; if (y < GPR_ARRAY_SIZE(elems_r)) { uint32_t delta = (uint32_t)elems_r[y]; @@ -361,29 +365,29 @@ static uint32_t elems_phash(uint32_t i) { } static const uint16_t elem_keys[] = { - 254, 255, 256, 257, 258, 259, 260, 1085, 1086, 143, 144, 1709, - 462, 463, 1604, 40, 41, 761, 1716, 980, 981, 1611, 621, 1499, - 760, 2024, 2129, 2234, 5384, 5699, 5804, 6014, 6119, 6224, 1732, 6329, - 6434, 6539, 6644, 6749, 6854, 6959, 7064, 7169, 7274, 7379, 7484, 7589, - 5909, 5594, 7694, 7799, 7904, 8009, 8114, 8219, 8324, 8429, 8534, 8639, - 8744, 8849, 8954, 9059, 9164, 9269, 9374, 1145, 518, 9479, 204, 9584, - 9689, 1151, 1152, 1153, 1154, 1775, 9794, 1040, 1670, 10529, 0, 0, - 1782, 829, 0, 0, 0, 0, 344, 1567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0}; + 257, 258, 259, 260, 261, 262, 263, 1096, 1097, 1513, 1725, 145, + 146, 467, 468, 1619, 41, 42, 1733, 990, 991, 767, 768, 1627, + 627, 837, 2043, 2149, 2255, 5541, 5859, 5965, 6071, 6177, 1749, 6283, + 6389, 6495, 6601, 6707, 6813, 6919, 7025, 7131, 7237, 7343, 7449, 7555, + 7661, 5753, 7767, 7873, 7979, 8085, 8191, 8297, 8403, 8509, 8615, 8721, + 8827, 8933, 9039, 9145, 9251, 9357, 9463, 1156, 9569, 523, 9675, 9781, + 206, 1162, 1163, 1164, 1165, 1792, 1582, 1050, 9887, 9993, 1686, 10735, + 1799, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; static const uint8_t elem_idxs[] = { - 7, 8, 9, 10, 11, 12, 13, 77, 79, 1, 2, 71, 5, 6, 25, 3, - 4, 63, 84, 66, 65, 73, 67, 30, 62, 57, 37, 74, 14, 17, 18, 20, - 21, 22, 15, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35, 36, 38, - 19, 16, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 76, 69, 56, 70, 58, 59, 78, 80, 81, 82, 83, 60, 64, - 72, 75, 255, 255, 85, 61, 255, 255, 255, 255, 0, 68}; + 7, 8, 9, 10, 11, 12, 13, 77, 79, 30, 71, 1, 2, 5, 6, 25, + 3, 4, 84, 66, 65, 62, 63, 73, 67, 61, 57, 37, 74, 14, 17, 18, + 19, 20, 15, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35, + 36, 16, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 76, 55, 69, 56, 58, 70, 78, 80, 81, 82, 83, 68, 64, + 59, 60, 72, 75, 85, 255, 255, 255, 255, 255, 0}; grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) { if (a == -1 || b == -1) return GRPC_MDNULL; - uint32_t k = (uint32_t)(a * 105 + b); + uint32_t k = (uint32_t)(a * 106 + b); uint32_t h = elems_phash(k); return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 @@ -396,175 +400,175 @@ grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { {{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 3}}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 532, 3}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 507, 4}}}}, + {&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}}}, {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 511, 1}}}}, + {&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}}}, {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 512, 11}}}}, + {&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 523, 4}}}}, + {&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 527, 5}}}}, + {&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 532, 3}}}}, + {&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 535, 3}}}}, + {&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 538, 3}}}}, + {&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 541, 3}}}}, + {&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 544, 3}}}}, + {&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 547, 3}}}}, + {&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 550, 3}}}}, - {{&grpc_static_metadata_refcounts[51], {{g_bytes + 553, 14}}}, + {&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}}}, + {{&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 567, 13}}}}, - {{&grpc_static_metadata_refcounts[53], {{g_bytes + 580, 15}}}, + {&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}}}, + {{&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[54], {{g_bytes + 595, 13}}}, + {{&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[55], {{g_bytes + 608, 6}}}, + {{&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[56], {{g_bytes + 614, 27}}}, + {{&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[57], {{g_bytes + 641, 3}}}, + {{&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[58], {{g_bytes + 644, 5}}}, + {{&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[59], {{g_bytes + 649, 13}}}, + {{&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[60], {{g_bytes + 662, 13}}}, + {{&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[61], {{g_bytes + 675, 19}}}, + {{&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[62], {{g_bytes + 694, 16}}}, + {{&grpc_static_metadata_refcounts[63], {{g_bytes + 722, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[63], {{g_bytes + 710, 14}}}, + {{&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[64], {{g_bytes + 724, 16}}}, + {{&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[65], {{g_bytes + 740, 13}}}, + {{&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[66], {{g_bytes + 753, 6}}}, + {{&grpc_static_metadata_refcounts[67], {{g_bytes + 781, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[67], {{g_bytes + 759, 4}}}, + {{&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[68], {{g_bytes + 763, 4}}}, + {{&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[69], {{g_bytes + 767, 6}}}, + {{&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[70], {{g_bytes + 773, 7}}}, + {{&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 4}}}, + {{&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[72], {{g_bytes + 784, 8}}}, + {{&grpc_static_metadata_refcounts[73], {{g_bytes + 812, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[73], {{g_bytes + 792, 17}}}, + {{&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[74], {{g_bytes + 809, 13}}}, + {{&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[75], {{g_bytes + 822, 8}}}, + {{&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[76], {{g_bytes + 830, 19}}}, + {{&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[77], {{g_bytes + 849, 13}}}, + {{&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[78], {{g_bytes + 862, 4}}}, + {{&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[79], {{g_bytes + 866, 8}}}, + {{&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[80], {{g_bytes + 874, 12}}}, + {{&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[81], {{g_bytes + 886, 18}}}, + {{&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[82], {{g_bytes + 904, 19}}}, + {{&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[83], {{g_bytes + 923, 5}}}, + {{&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[84], {{g_bytes + 928, 7}}}, + {{&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[85], {{g_bytes + 935, 7}}}, + {{&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[86], {{g_bytes + 942, 11}}}, + {{&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[87], {{g_bytes + 953, 6}}}, + {{&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[88], {{g_bytes + 959, 10}}}, + {{&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[89], {{g_bytes + 969, 25}}}, + {{&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[90], {{g_bytes + 994, 17}}}, + {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1011, 4}}}, + {{&grpc_static_metadata_refcounts[92], {{g_bytes + 1039, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[92], {{g_bytes + 1015, 3}}}, + {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1018, 16}}}, + {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[94], {{g_bytes + 1034, 1}}}}, + {&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}}}, {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}}, {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}}, {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}}, {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1043, 8}}}}, + {&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}}}, {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1051, 16}}}}, + {&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1067, 4}}}}, + {&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1071, 3}}}}, + {&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, {{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[100], {{g_bytes + 1074, 11}}}, + {{&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}}, + {&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, + {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}}, + {&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}}, + {&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, + {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}}, }; const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78, 79, 80, 81, 82}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 5e57ea5741..2bb9f72838 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -31,7 +31,7 @@ #include "src/core/lib/transport/metadata.h" -#define GRPC_STATIC_MDSTR_COUNT 105 +#define GRPC_STATIC_MDSTR_COUNT 106 extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* ":path" */ #define GRPC_MDSTR_PATH (grpc_static_slice_table[0]) @@ -107,147 +107,150 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */ #define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \ (grpc_static_slice_table[34]) +/* "/grpc.health.v1.Health/Watch" */ +#define GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH \ + (grpc_static_slice_table[35]) /* "deflate" */ -#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[35]) +#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[36]) /* "gzip" */ -#define GRPC_MDSTR_GZIP (grpc_static_slice_table[36]) +#define GRPC_MDSTR_GZIP (grpc_static_slice_table[37]) /* "stream/gzip" */ -#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[37]) +#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[38]) /* "GET" */ -#define GRPC_MDSTR_GET (grpc_static_slice_table[38]) +#define GRPC_MDSTR_GET (grpc_static_slice_table[39]) /* "POST" */ -#define GRPC_MDSTR_POST (grpc_static_slice_table[39]) +#define GRPC_MDSTR_POST (grpc_static_slice_table[40]) /* "/" */ -#define GRPC_MDSTR_SLASH (grpc_static_slice_table[40]) +#define GRPC_MDSTR_SLASH (grpc_static_slice_table[41]) /* "/index.html" */ -#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[41]) +#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[42]) /* "http" */ -#define GRPC_MDSTR_HTTP (grpc_static_slice_table[42]) +#define GRPC_MDSTR_HTTP (grpc_static_slice_table[43]) /* "https" */ -#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[43]) +#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[44]) /* "200" */ -#define GRPC_MDSTR_200 (grpc_static_slice_table[44]) +#define GRPC_MDSTR_200 (grpc_static_slice_table[45]) /* "204" */ -#define GRPC_MDSTR_204 (grpc_static_slice_table[45]) +#define GRPC_MDSTR_204 (grpc_static_slice_table[46]) /* "206" */ -#define GRPC_MDSTR_206 (grpc_static_slice_table[46]) +#define GRPC_MDSTR_206 (grpc_static_slice_table[47]) /* "304" */ -#define GRPC_MDSTR_304 (grpc_static_slice_table[47]) +#define GRPC_MDSTR_304 (grpc_static_slice_table[48]) /* "400" */ -#define GRPC_MDSTR_400 (grpc_static_slice_table[48]) +#define GRPC_MDSTR_400 (grpc_static_slice_table[49]) /* "404" */ -#define GRPC_MDSTR_404 (grpc_static_slice_table[49]) +#define GRPC_MDSTR_404 (grpc_static_slice_table[50]) /* "500" */ -#define GRPC_MDSTR_500 (grpc_static_slice_table[50]) +#define GRPC_MDSTR_500 (grpc_static_slice_table[51]) /* "accept-charset" */ -#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[51]) +#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[52]) /* "gzip, deflate" */ -#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[52]) +#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[53]) /* "accept-language" */ -#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[53]) +#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[54]) /* "accept-ranges" */ -#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[54]) +#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[55]) /* "accept" */ -#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[55]) +#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[56]) /* "access-control-allow-origin" */ -#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[56]) +#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[57]) /* "age" */ -#define GRPC_MDSTR_AGE (grpc_static_slice_table[57]) +#define GRPC_MDSTR_AGE (grpc_static_slice_table[58]) /* "allow" */ -#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[58]) +#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[59]) /* "authorization" */ -#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[59]) +#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[60]) /* "cache-control" */ -#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[60]) +#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[61]) /* "content-disposition" */ -#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[61]) +#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[62]) /* "content-language" */ -#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[62]) +#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[63]) /* "content-length" */ -#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[63]) +#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[64]) /* "content-location" */ -#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[64]) +#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[65]) /* "content-range" */ -#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[65]) +#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[66]) /* "cookie" */ -#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[66]) +#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[67]) /* "date" */ -#define GRPC_MDSTR_DATE (grpc_static_slice_table[67]) +#define GRPC_MDSTR_DATE (grpc_static_slice_table[68]) /* "etag" */ -#define GRPC_MDSTR_ETAG (grpc_static_slice_table[68]) +#define GRPC_MDSTR_ETAG (grpc_static_slice_table[69]) /* "expect" */ -#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[69]) +#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[70]) /* "expires" */ -#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[70]) +#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[71]) /* "from" */ -#define GRPC_MDSTR_FROM (grpc_static_slice_table[71]) +#define GRPC_MDSTR_FROM (grpc_static_slice_table[72]) /* "if-match" */ -#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[72]) +#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[73]) /* "if-modified-since" */ -#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[73]) +#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[74]) /* "if-none-match" */ -#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[74]) +#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[75]) /* "if-range" */ -#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[75]) +#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[76]) /* "if-unmodified-since" */ -#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[76]) +#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[77]) /* "last-modified" */ -#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[77]) +#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[78]) /* "link" */ -#define GRPC_MDSTR_LINK (grpc_static_slice_table[78]) +#define GRPC_MDSTR_LINK (grpc_static_slice_table[79]) /* "location" */ -#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[79]) +#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[80]) /* "max-forwards" */ -#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[80]) +#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[81]) /* "proxy-authenticate" */ -#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[81]) +#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[82]) /* "proxy-authorization" */ -#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[82]) +#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[83]) /* "range" */ -#define GRPC_MDSTR_RANGE (grpc_static_slice_table[83]) +#define GRPC_MDSTR_RANGE (grpc_static_slice_table[84]) /* "referer" */ -#define GRPC_MDSTR_REFERER (grpc_static_slice_table[84]) +#define GRPC_MDSTR_REFERER (grpc_static_slice_table[85]) /* "refresh" */ -#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[85]) +#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[86]) /* "retry-after" */ -#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[86]) +#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[87]) /* "server" */ -#define GRPC_MDSTR_SERVER (grpc_static_slice_table[87]) +#define GRPC_MDSTR_SERVER (grpc_static_slice_table[88]) /* "set-cookie" */ -#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[88]) +#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[89]) /* "strict-transport-security" */ -#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[89]) +#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[90]) /* "transfer-encoding" */ -#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[90]) +#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[91]) /* "vary" */ -#define GRPC_MDSTR_VARY (grpc_static_slice_table[91]) +#define GRPC_MDSTR_VARY (grpc_static_slice_table[92]) /* "via" */ -#define GRPC_MDSTR_VIA (grpc_static_slice_table[92]) +#define GRPC_MDSTR_VIA (grpc_static_slice_table[93]) /* "www-authenticate" */ -#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[93]) +#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[94]) /* "0" */ -#define GRPC_MDSTR_0 (grpc_static_slice_table[94]) +#define GRPC_MDSTR_0 (grpc_static_slice_table[95]) /* "identity" */ -#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[95]) +#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[96]) /* "trailers" */ -#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[96]) +#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[97]) /* "application/grpc" */ -#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[97]) +#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[98]) /* "grpc" */ -#define GRPC_MDSTR_GRPC (grpc_static_slice_table[98]) +#define GRPC_MDSTR_GRPC (grpc_static_slice_table[99]) /* "PUT" */ -#define GRPC_MDSTR_PUT (grpc_static_slice_table[99]) +#define GRPC_MDSTR_PUT (grpc_static_slice_table[100]) /* "lb-cost-bin" */ -#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[100]) +#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[101]) /* "identity,deflate" */ -#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[101]) +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[102]) /* "identity,gzip" */ -#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[102]) +#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[103]) /* "deflate,gzip" */ -#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[103]) +#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[104]) /* "identity,deflate,gzip" */ #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (grpc_static_slice_table[104]) + (grpc_static_slice_table[105]) extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable; extern grpc_slice_refcount diff --git a/src/core/tsi/transport_security.cc b/src/core/tsi/transport_security.cc index 99b3229e88..ca861b52de 100644 --- a/src/core/tsi/transport_security.cc +++ b/src/core/tsi/transport_security.cc @@ -338,3 +338,20 @@ tsi_result tsi_construct_peer(size_t property_count, tsi_peer* peer) { } return TSI_OK; } + +const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* peer, + const char* name) { + size_t i; + if (peer == nullptr) return nullptr; + for (i = 0; i < peer->property_count; i++) { + const tsi_peer_property* property = &peer->properties[i]; + if (name == nullptr && property->name == nullptr) { + return property; + } + if (name != nullptr && property->name != nullptr && + strcmp(property->name, name) == 0) { + return property; + } + } + return nullptr; +} diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h index 1923a702e5..482d300a05 100644 --- a/src/core/tsi/transport_security.h +++ b/src/core/tsi/transport_security.h @@ -122,7 +122,8 @@ tsi_result tsi_construct_allocated_string_peer_property( const char* name, size_t value_length, tsi_peer_property* property); tsi_result tsi_construct_string_peer_property_from_cstring( const char* name, const char* value, tsi_peer_property* property); - +const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* peer, + const char* name); /* Utils. */ char* tsi_strdup(const char* src); /* Sadly, no strdup in C89. */ diff --git a/src/cpp/common/completion_queue_cc.cc b/src/cpp/common/completion_queue_cc.cc index 5dfcfa2984..6893201e2e 100644 --- a/src/cpp/common/completion_queue_cc.cc +++ b/src/cpp/common/completion_queue_cc.cc @@ -64,7 +64,6 @@ CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal( *ok = ev.success != 0; *tag = cq_tag; if (cq_tag->FinalizeResult(tag, ok)) { - gpr_log(GPR_ERROR, "alright got tag %p", *tag); return GOT_EVENT; } break; diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index 79ed9102e5..428893f277 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -20,9 +20,6 @@ #include "src/cpp/server/channelz/channelz_service.h" -#include <google/protobuf/text_format.h> -#include <google/protobuf/util/json_util.h> - #include <grpc/grpc.h> #include <grpc/support/alloc.h> @@ -33,13 +30,14 @@ Status ChannelzService::GetTopChannels( channelz::v1::GetTopChannelsResponse* response) { char* json_str = grpc_channelz_get_top_channels(request->start_channel_id()); if (json_str == nullptr) { - return Status(INTERNAL, "grpc_channelz_get_top_channels returned null"); + return Status(StatusCode::INTERNAL, + "grpc_channelz_get_top_channels returned null"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } @@ -49,13 +47,14 @@ Status ChannelzService::GetServers( channelz::v1::GetServersResponse* response) { char* json_str = grpc_channelz_get_servers(request->start_server_id()); if (json_str == nullptr) { - return Status(INTERNAL, "grpc_channelz_get_servers returned null"); + return Status(StatusCode::INTERNAL, + "grpc_channelz_get_servers returned null"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } @@ -66,13 +65,14 @@ Status ChannelzService::GetServerSockets( char* json_str = grpc_channelz_get_server_sockets(request->server_id(), request->start_socket_id()); if (json_str == nullptr) { - return Status(INTERNAL, "grpc_channelz_get_server_sockets returned null"); + return Status(StatusCode::INTERNAL, + "grpc_channelz_get_server_sockets returned null"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } @@ -82,13 +82,13 @@ Status ChannelzService::GetChannel( channelz::v1::GetChannelResponse* response) { char* json_str = grpc_channelz_get_channel(request->channel_id()); if (json_str == nullptr) { - return Status(NOT_FOUND, "No object found for that ChannelId"); + return Status(StatusCode::NOT_FOUND, "No object found for that ChannelId"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } @@ -98,13 +98,14 @@ Status ChannelzService::GetSubchannel( channelz::v1::GetSubchannelResponse* response) { char* json_str = grpc_channelz_get_subchannel(request->subchannel_id()); if (json_str == nullptr) { - return Status(NOT_FOUND, "No object found for that SubchannelId"); + return Status(StatusCode::NOT_FOUND, + "No object found for that SubchannelId"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } @@ -114,13 +115,13 @@ Status ChannelzService::GetSocket(ServerContext* unused, channelz::v1::GetSocketResponse* response) { char* json_str = grpc_channelz_get_socket(request->socket_id()); if (json_str == nullptr) { - return Status(NOT_FOUND, "No object found for that SocketId"); + return Status(StatusCode::NOT_FOUND, "No object found for that SocketId"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index 0c03fdf17a..c951c69d51 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -26,8 +26,8 @@ #include "pb_decode.h" #include "pb_encode.h" +#include "src/core/ext/filters/client_channel/health/health.pb.h" #include "src/cpp/server/health/default_health_check_service.h" -#include "src/cpp/server/health/health.pb.h" namespace grpc { @@ -78,12 +78,12 @@ void DefaultHealthCheckService::RegisterCallHandler( void DefaultHealthCheckService::UnregisterCallHandler( const grpc::string& service_name, - std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler) { + const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler) { std::unique_lock<std::mutex> lock(mu_); auto it = services_map_.find(service_name); if (it == services_map_.end()) return; ServiceData& service_data = it->second; - service_data.RemoveCallHandler(std::move(handler)); + service_data.RemoveCallHandler(handler); if (service_data.Unused()) { services_map_.erase(it); } @@ -115,7 +115,7 @@ void DefaultHealthCheckService::ServiceData::AddCallHandler( } void DefaultHealthCheckService::ServiceData::RemoveCallHandler( - std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler) { + const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler) { call_handlers_.erase(handler); } @@ -184,16 +184,13 @@ bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( std::vector<Slice> slices; if (!request.Dump(&slices).ok()) return false; uint8_t* request_bytes = nullptr; - bool request_bytes_owned = false; size_t request_size = 0; grpc_health_v1_HealthCheckRequest request_struct; - if (slices.empty()) { - request_struct.has_service = false; - } else if (slices.size() == 1) { + request_struct.has_service = false; + if (slices.size() == 1) { request_bytes = const_cast<uint8_t*>(slices[0].begin()); request_size = slices[0].size(); - } else { - request_bytes_owned = true; + } else if (slices.size() > 1) { request_bytes = static_cast<uint8_t*>(gpr_malloc(request.Length())); uint8_t* copy_to = request_bytes; for (size_t i = 0; i < slices.size(); i++) { @@ -201,15 +198,13 @@ bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( copy_to += slices[i].size(); } } - if (request_bytes != nullptr) { - pb_istream_t istream = pb_istream_from_buffer(request_bytes, request_size); - bool decode_status = pb_decode( - &istream, grpc_health_v1_HealthCheckRequest_fields, &request_struct); - if (request_bytes_owned) { - gpr_free(request_bytes); - } - if (!decode_status) return false; + pb_istream_t istream = pb_istream_from_buffer(request_bytes, request_size); + bool decode_status = pb_decode( + &istream, grpc_health_v1_HealthCheckRequest_fields, &request_struct); + if (slices.size() > 1) { + gpr_free(request_bytes); } + if (!decode_status) return false; *service_name = request_struct.has_service ? request_struct.service : ""; return true; } @@ -318,6 +313,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: gpr_log(GPR_DEBUG, "[HCS %p] Health check call finished for handler %p", service_, this); } + self.reset(); // To appease clang-tidy. } // @@ -442,7 +438,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: SendFinish(std::shared_ptr<CallHandler> self, const Status& status) { if (finish_called_) return; std::unique_lock<std::mutex> cq_lock(service_->cq_shutdown_mu_); - if (!service_->shutdown_) return; + if (service_->shutdown_) return; SendFinishLocked(std::move(self), status); } @@ -464,6 +460,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: "handler: %p).", service_, service_name_.c_str(), this); } + self.reset(); // To appease clang-tidy. } // TODO(roth): This method currently assumes that there will be only one @@ -473,9 +470,10 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: OnDoneNotified(std::shared_ptr<CallHandler> self, bool ok) { GPR_ASSERT(ok); gpr_log(GPR_DEBUG, - "[HCS %p] Healt watch call is notified done (handler: %p, " + "[HCS %p] Health watch call is notified done (handler: %p, " "is_cancelled: %d).", service_, this, static_cast<int>(ctx_.IsCancelled())); + database_->UnregisterCallHandler(service_name_, self); SendFinish(std::move(self), Status::CANCELLED); } diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index 3bab76b6b0..450bd543f5 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -252,7 +252,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface { void AddCallHandler( std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler); void RemoveCallHandler( - std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler); + const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler); bool Unused() const { return call_handlers_.empty() && status_ == NOT_FOUND; } @@ -269,7 +269,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface { void UnregisterCallHandler( const grpc::string& service_name, - std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler); + const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler); mutable std::mutex mu_; std::map<grpc::string, ServiceData> services_map_; // Guarded by mu_. diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index 44ee0846b6..995e787785 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -40,8 +40,10 @@ namespace grpc { class ServerContext::CompletionOp final : public internal::CallOpSetInterface { public: // initial refs: one in the server context, one in the cq - CompletionOp() - : has_tag_(false), + // must ref the call before calling constructor and after deleting this + CompletionOp(internal::Call* call) + : call_(*call), + has_tag_(false), tag_(nullptr), refs_(2), finalized_(false), @@ -55,6 +57,21 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { } void FillOps(internal::Call* call) override; + + // This should always be arena allocated in the call, so override delete. + // But this class is not trivially destructible, so must actually call delete + // before allowing the arena to be freed + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(CompletionOp)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + bool FinalizeResult(void** tag, bool* status) override; bool CheckCancelled(CompletionQueue* cq) { @@ -92,7 +109,9 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { std::unique_lock<std::mutex> lock(mu_); if (--refs_ == 0) { lock.unlock(); + grpc_call* call = call_.call(); delete this; + grpc_call_unref(call); } return; } @@ -108,6 +127,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { return finalized_ ? (cancelled_ != 0) : false; } + internal::Call call_; bool has_tag_; void* tag_; std::mutex mu_; @@ -115,7 +135,6 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { bool finalized_; int cancelled_; bool done_intercepting_; - internal::Call call_; internal::InterceptorBatchMethodsImpl interceptor_methods_; }; @@ -123,7 +142,9 @@ void ServerContext::CompletionOp::Unref() { std::unique_lock<std::mutex> lock(mu_); if (--refs_ == 0) { lock.unlock(); + grpc_call* call = call_.call(); delete this; + grpc_call_unref(call); } } @@ -133,7 +154,6 @@ void ServerContext::CompletionOp::FillOps(internal::Call* call) { ops.data.recv_close_on_server.cancelled = &cancelled_; ops.flags = 0; ops.reserved = nullptr; - call_ = *call; interceptor_methods_.SetCall(&call_); interceptor_methods_.SetReverse(); interceptor_methods_.SetCallOpSetInterface(this); @@ -153,7 +173,9 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { } if (--refs_ == 0) { lock.unlock(); + grpc_call* call = call_.call(); delete this; + grpc_call_unref(call); } return ret; } @@ -175,7 +197,9 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { lock.lock(); if (--refs_ == 0) { lock.unlock(); + grpc_call* call = call_.call(); delete this; + grpc_call_unref(call); } return ret; } @@ -226,7 +250,10 @@ void ServerContext::BeginCompletionOp(internal::Call* call) { if (rpc_info_) { rpc_info_->Ref(); } - completion_op_ = new CompletionOp(); + grpc_call_ref(call->call()); + completion_op_ = + new (grpc_call_arena_alloc(call->call(), sizeof(CompletionOp))) + CompletionOp(call); if (has_notify_when_done_tag_) { completion_op_->set_tag(async_notify_when_done_tag_); } diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 0bd3951a19..cb48b9f62c 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -254,11 +254,14 @@ CORE_SOURCE_FILES = [ 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', - 'src/core/lib/security/security_connector/alts_security_connector.cc', + 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', + 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', 'src/core/lib/security/security_connector/load_system_roots_linux.cc', - 'src/core/lib/security/security_connector/local_security_connector.cc', + 'src/core/lib/security/security_connector/local/local_security_connector.cc', 'src/core/lib/security/security_connector/security_connector.cc', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', + 'src/core/lib/security/security_connector/ssl_utils.cc', 'src/core/lib/security/transport/client_auth_filter.cc', 'src/core/lib/security/transport/secure_endpoint.cc', 'src/core/lib/security/transport/security_handshaker.cc', @@ -313,6 +316,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -329,6 +333,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/alts_transport_security.cc', 'src/core/tsi/fake_transport_security.cc', 'src/core/tsi/local_transport_security.cc', diff --git a/templates/tools/dockerfile/apt_get_python_27.include b/templates/tools/dockerfile/apt_get_python_27.include new file mode 100644 index 0000000000..4ee37ef11f --- /dev/null +++ b/templates/tools/dockerfile/apt_get_python_27.include @@ -0,0 +1,3 @@ +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 diff --git a/templates/tools/dockerfile/debian_testing_repo.include b/templates/tools/dockerfile/debian_testing_repo.include new file mode 100644 index 0000000000..1a5248e226 --- /dev/null +++ b/templates/tools/dockerfile/debian_testing_repo.include @@ -0,0 +1,3 @@ +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local diff --git a/templates/tools/dockerfile/java_build_interop.sh.include b/templates/tools/dockerfile/java_build_interop.sh.include index 895b86ace0..16d5fb65cf 100755 --- a/templates/tools/dockerfile/java_build_interop.sh.include +++ b/templates/tools/dockerfile/java_build_interop.sh.include @@ -25,3 +25,11 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true + +# enable extra java logging +mkdir -p /var/local/grpc_java_logging +echo "handlers = java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level = ALL +.level = FINE +io.grpc.netty.NettyClientHandler = ALL +io.grpc.netty.NettyServerHandler = ALL" > /var/local/grpc_java_logging/logconf.txt diff --git a/templates/tools/dockerfile/python_stretch.include b/templates/tools/dockerfile/python_stretch.include new file mode 100644 index 0000000000..45bafe5184 --- /dev/null +++ b/templates/tools/dockerfile/python_stretch.include @@ -0,0 +1,9 @@ +FROM debian:stretch + +<%include file="./apt_get_basic.include"/> +<%include file="./gcp_api_libraries.include"/> +<%include file="./apt_get_python_27.include"/> +<%include file="./debian_testing_repo.include"/> +<%include file="./run_tests_addons.include"/> +# Define the default command. +CMD ["bash"] diff --git a/templates/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile.template new file mode 100644 index 0000000000..a1c9d9f84d --- /dev/null +++ b/templates/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile.template @@ -0,0 +1,17 @@ +%YAML 1.2 +--- | + # Copyright 2018 The gRPC Authors + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + <%include file="../../python_stretch.include"/> diff --git a/templates/tools/dockerfile/test/python_pyenv_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_3.5_x64/Dockerfile.template index 1e013b742c..93b655ea0d 100644 --- a/templates/tools/dockerfile/test/python_pyenv_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/python_stretch_3.5_x64/Dockerfile.template @@ -1,6 +1,6 @@ %YAML 1.2 --- | - # Copyright 2016 gRPC authors. + # Copyright 2018 The gRPC Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,17 +13,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - - FROM debian:stretch - - <%include file="../../apt_get_basic.include"/> - <%include file="../../gcp_api_libraries.include"/> - <%include file="../../python_deps.include"/> - <%include file="../../apt_get_pyenv.include"/> - # Install pip and virtualenv for Python 3.5 - RUN curl https://bootstrap.pypa.io/get-pip.py | python3.5 - RUN python3.5 -m pip install virtualenv - <%include file="../../run_tests_addons.include"/> - # Define the default command. - CMD ["bash"] + <%include file="../../python_stretch.include"/> + + RUN apt-get update && apt-get install -y python3.5 python3-all-dev + RUN curl https://bootstrap.pypa.io/get-pip.py | python3.5 diff --git a/templates/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile.template new file mode 100644 index 0000000000..a5dcf196f2 --- /dev/null +++ b/templates/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile.template @@ -0,0 +1,20 @@ +%YAML 1.2 +--- | + # Copyright 2018 The gRPC Authors + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + <%include file="../../python_stretch.include"/> + + RUN apt-get update && apt-get -t testing install -y python3.6 python3-all-dev + RUN curl https://bootstrap.pypa.io/get-pip.py | python3.6 diff --git a/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template new file mode 100644 index 0000000000..ff342db493 --- /dev/null +++ b/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template @@ -0,0 +1,20 @@ +%YAML 1.2 +--- | + # Copyright 2018 The gRPC Authors + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + <%include file="../../python_stretch.include"/> + + RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev + RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 diff --git a/templates/tools/run_tests/generated/lb_interop_test_scenarios.json.template b/templates/tools/run_tests/generated/lb_interop_test_scenarios.json.template new file mode 100644 index 0000000000..18d71a7c84 --- /dev/null +++ b/templates/tools/run_tests/generated/lb_interop_test_scenarios.json.template @@ -0,0 +1,6 @@ +%YAML 1.2 +--- | + <%! + import json + %> + ${json.dumps(lb_interop_test_scenarios, indent=4, sort_keys=True)} diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index 5ead12e870..5f27320512 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -85,6 +85,19 @@ void ValidateJsonArraySize(grpc_json* json, const char* key, EXPECT_EQ(count, expected_size); } +std::vector<intptr_t> GetUuidListFromArray(grpc_json* arr) { + EXPECT_EQ(arr->type, GRPC_JSON_ARRAY); + std::vector<intptr_t> uuids; + for (grpc_json* child = arr->child; child != nullptr; child = child->next) { + grpc_json* it = GetJsonChild(child, "ref"); + EXPECT_NE(it, nullptr); + it = GetJsonChild(it, "channelId"); + EXPECT_NE(it, nullptr); + uuids.push_back(atoi(it->value)); + } + return uuids; +} + void ValidateGetTopChannels(size_t expected_channels) { char* json_str = ChannelzRegistry::GetTopChannels(0); grpc::testing::ValidateGetTopChannelsResponseProtoJsonTranslation(json_str); @@ -226,19 +239,7 @@ void ChannelzSleep(int64_t sleep_us) { } // anonymous namespace -class ChannelzChannelTest : public ::testing::TestWithParam<size_t> { - protected: - // ensure we always have a fresh registry for tests. - void SetUp() override { - ChannelzRegistry::Shutdown(); - ChannelzRegistry::Init(); - } - - void TearDown() override { - ChannelzRegistry::Shutdown(); - ChannelzRegistry::Init(); - } -}; +class ChannelzChannelTest : public ::testing::TestWithParam<size_t> {}; TEST_P(ChannelzChannelTest, BasicChannel) { grpc_core::ExecCtx exec_ctx; @@ -307,25 +308,39 @@ TEST_P(ChannelzChannelTest, LastCallStartedMillis) { EXPECT_NE(millis1, millis4); } -TEST(ChannelzGetTopChannelsTest, BasicGetTopChannelsTest) { +class ChannelzRegistryBasedTest : public ::testing::TestWithParam<size_t> { + protected: + // ensure we always have a fresh registry for tests. + void SetUp() override { + ChannelzRegistry::Shutdown(); + ChannelzRegistry::Init(); + } + + void TearDown() override { + ChannelzRegistry::Shutdown(); + ChannelzRegistry::Init(); + } +}; + +TEST_F(ChannelzRegistryBasedTest, BasicGetTopChannelsTest) { grpc_core::ExecCtx exec_ctx; ChannelFixture channel; ValidateGetTopChannels(1); } -TEST(ChannelzGetTopChannelsTest, NoChannelsTest) { +TEST_F(ChannelzRegistryBasedTest, NoChannelsTest) { grpc_core::ExecCtx exec_ctx; ValidateGetTopChannels(0); } -TEST(ChannelzGetTopChannelsTest, ManyChannelsTest) { +TEST_F(ChannelzRegistryBasedTest, ManyChannelsTest) { grpc_core::ExecCtx exec_ctx; ChannelFixture channels[10]; (void)channels; // suppress unused variable error ValidateGetTopChannels(10); } -TEST(ChannelzGetTopChannelsTest, GetTopChannelsPagination) { +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsPagination) { grpc_core::ExecCtx exec_ctx; // this is over the pagination limit. ChannelFixture channels[150]; @@ -351,7 +366,116 @@ TEST(ChannelzGetTopChannelsTest, GetTopChannelsPagination) { gpr_free(json_str); } -TEST(ChannelzGetTopChannelsTest, InternalChannelTest) { +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsUuidCheck) { + const intptr_t kNumChannels = 50; + grpc_core::ExecCtx exec_ctx; + ChannelFixture channels[kNumChannels]; + (void)channels; // suppress unused variable error + char* json_str = ChannelzRegistry::GetTopChannels(0); + grpc_json* parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", kNumChannels); + grpc_json* json_channels = GetJsonChild(parsed_json, "channel"); + std::vector<intptr_t> uuids = GetUuidListFromArray(json_channels); + for (int i = 0; i < kNumChannels; ++i) { + EXPECT_EQ(i + 1, uuids[i]); + } + grpc_json_destroy(parsed_json); + gpr_free(json_str); +} + +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsMiddleUuidCheck) { + const intptr_t kNumChannels = 50; + const intptr_t kMidQuery = 40; + grpc_core::ExecCtx exec_ctx; + ChannelFixture channels[kNumChannels]; + (void)channels; // suppress unused variable error + // only query for the end of the channels + char* json_str = ChannelzRegistry::GetTopChannels(kMidQuery); + grpc_json* parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", kNumChannels - kMidQuery + 1); + grpc_json* json_channels = GetJsonChild(parsed_json, "channel"); + std::vector<intptr_t> uuids = GetUuidListFromArray(json_channels); + for (size_t i = 0; i < uuids.size(); ++i) { + EXPECT_EQ(static_cast<intptr_t>(kMidQuery + i), uuids[i]); + } + grpc_json_destroy(parsed_json); + gpr_free(json_str); +} + +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsNoHitUuid) { + grpc_core::ExecCtx exec_ctx; + ChannelFixture pre_channels[40]; // will take uuid[1, 40] + (void)pre_channels; // suppress unused variable error + ServerFixture servers[10]; // will take uuid[41, 50] + (void)servers; // suppress unused variable error + ChannelFixture channels[10]; // will take uuid[51, 60] + (void)channels; // suppress unused variable error + // query in the middle of the server channels + char* json_str = ChannelzRegistry::GetTopChannels(45); + grpc_json* parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", 10); + grpc_json* json_channels = GetJsonChild(parsed_json, "channel"); + std::vector<intptr_t> uuids = GetUuidListFromArray(json_channels); + for (size_t i = 0; i < uuids.size(); ++i) { + EXPECT_EQ(static_cast<intptr_t>(51 + i), uuids[i]); + } + grpc_json_destroy(parsed_json); + gpr_free(json_str); +} + +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsMoreGaps) { + grpc_core::ExecCtx exec_ctx; + ChannelFixture channel_with_uuid1; + { ServerFixture channel_with_uuid2; } + ChannelFixture channel_with_uuid3; + { ServerFixture server_with_uuid4; } + ChannelFixture channel_with_uuid5; + // Current state of list: [1, NULL, 3, NULL, 5] + char* json_str = ChannelzRegistry::GetTopChannels(2); + grpc_json* parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", 2); + grpc_json* json_channels = GetJsonChild(parsed_json, "channel"); + std::vector<intptr_t> uuids = GetUuidListFromArray(json_channels); + EXPECT_EQ(static_cast<intptr_t>(3), uuids[0]); + EXPECT_EQ(static_cast<intptr_t>(5), uuids[1]); + grpc_json_destroy(parsed_json); + gpr_free(json_str); + json_str = ChannelzRegistry::GetTopChannels(4); + parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", 1); + json_channels = GetJsonChild(parsed_json, "channel"); + uuids = GetUuidListFromArray(json_channels); + EXPECT_EQ(static_cast<intptr_t>(5), uuids[0]); + grpc_json_destroy(parsed_json); + gpr_free(json_str); +} + +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsUuidAfterCompaction) { + const intptr_t kLoopIterations = 50; + grpc_core::ExecCtx exec_ctx; + std::vector<UniquePtr<ChannelFixture>> even_channels; + { + // these will delete and unregister themselves after this block. + std::vector<UniquePtr<ChannelFixture>> odd_channels; + for (int i = 0; i < kLoopIterations; i++) { + odd_channels.push_back(MakeUnique<ChannelFixture>()); + even_channels.push_back(MakeUnique<ChannelFixture>()); + } + } + char* json_str = ChannelzRegistry::GetTopChannels(0); + grpc_json* parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", kLoopIterations); + grpc_json* json_channels = GetJsonChild(parsed_json, "channel"); + std::vector<intptr_t> uuids = GetUuidListFromArray(json_channels); + for (int i = 0; i < kLoopIterations; ++i) { + // only the even uuids will still be present. + EXPECT_EQ((i + 1) * 2, uuids[i]); + } + grpc_json_destroy(parsed_json); + gpr_free(json_str); +} + +TEST_F(ChannelzRegistryBasedTest, InternalChannelTest) { grpc_core::ExecCtx exec_ctx; ChannelFixture channels[10]; (void)channels; // suppress unused variable error @@ -369,9 +493,7 @@ TEST(ChannelzGetTopChannelsTest, InternalChannelTest) { grpc_channel_destroy(internal_channel); } -class ChannelzServerTest : public ::testing::TestWithParam<size_t> {}; - -TEST_P(ChannelzServerTest, BasicServerAPIFunctionality) { +TEST(ChannelzServerTest, BasicServerAPIFunctionality) { grpc_core::ExecCtx exec_ctx; ServerFixture server(10); ServerNode* channelz_server = grpc_server_get_channelz_node(server.server()); @@ -388,18 +510,18 @@ TEST_P(ChannelzServerTest, BasicServerAPIFunctionality) { ValidateServer(channelz_server, {3, 3, 3}); } -TEST(ChannelzGetServersTest, BasicGetServersTest) { +TEST_F(ChannelzRegistryBasedTest, BasicGetServersTest) { grpc_core::ExecCtx exec_ctx; ServerFixture server; ValidateGetServers(1); } -TEST(ChannelzGetServersTest, NoServersTest) { +TEST_F(ChannelzRegistryBasedTest, NoServersTest) { grpc_core::ExecCtx exec_ctx; ValidateGetServers(0); } -TEST(ChannelzGetServersTest, ManyServersTest) { +TEST_F(ChannelzRegistryBasedTest, ManyServersTest) { grpc_core::ExecCtx exec_ctx; ServerFixture servers[10]; (void)servers; // suppress unused variable error @@ -409,9 +531,6 @@ TEST(ChannelzGetServersTest, ManyServersTest) { INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest, ::testing::Values(0, 8, 64, 1024, 1024 * 1024)); -INSTANTIATE_TEST_CASE_P(ChannelzServerTestSweep, ChannelzServerTest, - ::testing::Values(0, 8, 64, 1024, 1024 * 1024)); - } // namespace testing } // namespace channelz } // namespace grpc_core diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index 37999a98d1..398e8a2d9a 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -18,7 +18,7 @@ licenses(["notice"]) # Apache v2 grpc_package(name = "test/core/end2end") -load(":generate_tests.bzl", "grpc_end2end_tests") +load(":generate_tests.bzl", "grpc_end2end_tests", "grpc_end2end_nosec_tests") grpc_cc_library( name = "cq_verifier", @@ -46,7 +46,6 @@ grpc_cc_library( visibility = ["//test:__subpackages__"], ) - grpc_cc_library( name = "http_proxy", srcs = ["fixtures/http_proxy_fixture.cc"], @@ -128,7 +127,7 @@ grpc_cc_test( srcs = ["inproc_callback_test.cc"], language = "C++", deps = [ - ':end2end_tests', + ":end2end_tests", "//:gpr", "//:grpc", "//test/core/util:gpr_test_util", @@ -177,6 +176,8 @@ grpc_cc_test( grpc_end2end_tests() +grpc_end2end_nosec_tests() + grpc_cc_test( name = "h2_ssl_session_reuse_test", srcs = ["h2_ssl_session_reuse_test.cc"], @@ -185,11 +186,11 @@ grpc_cc_test( ], language = "C++", deps = [ - ':end2end_tests', - '//:gpr', - '//:grpc', - '//:tsi', - '//test/core/util:gpr_test_util', - '//test/core/util:grpc_test_util', + ":end2end_tests", + "//:gpr", + "//:grpc", + "//:tsi", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary index 569e744a6b..a79fe5ad95 100644 --- a/test/core/end2end/fuzzers/hpack.dictionary +++ b/test/core/end2end/fuzzers/hpack.dictionary @@ -34,6 +34,7 @@ "\x1Egrpc.max_request_message_bytes" "\x1Fgrpc.max_response_message_bytes" "$/grpc.lb.v1.LoadBalancer/BalanceLoad" +"\x1C/grpc.health.v1.Health/Watch" "\x07deflate" "\x04gzip" "\x0Bstream/gzip" diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 39b9ba4a19..601d3bac38 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -41,7 +41,7 @@ local_fixture_options = default_secure_fixture_options._replace( fd_unsecure_fixture_options = default_unsecure_fixture_options._replace( dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv'], client_channel=False) -inproc_fixture_options = default_unsecure_fixture_options._replace( +inproc_fixture_options = default_secure_fixture_options._replace( dns_resolver=False, fullstack=False, name_resolution=False, supports_compression=False, is_inproc=True, is_http2=False, supports_write_buffering=False, client_channel=False) diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 6d9ffcfb91..81956db841 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -92,6 +92,7 @@ END2END_FIXTURES = { _platforms = ["linux", "mac", "posix"], ), "inproc": _fixture_options( + secure = True, fullstack = False, dns_resolver = False, name_resolution = False, @@ -102,6 +103,55 @@ END2END_FIXTURES = { ), } +# maps fixture name to whether it requires the security library +END2END_NOSEC_FIXTURES = { + "h2_compress": _fixture_options(secure = False), + "h2_census": _fixture_options(secure = False), + # TODO(juanlishen): This is disabled for now, but should be considered to re-enable once we have + # decided how the load reporting service should be enabled. + #'h2_load_reporting': _fixture_options(), + "h2_fakesec": _fixture_options(), + "h2_fd": _fixture_options( + dns_resolver = False, + fullstack = False, + client_channel = False, + secure = False, + _platforms = ["linux", "mac", "posix"], + ), + "h2_full": _fixture_options(secure = False), + "h2_full+pipe": _fixture_options(secure = False, _platforms = ["linux"]), + "h2_full+trace": _fixture_options(secure = False, tracing = True), + "h2_full+workarounds": _fixture_options(secure = False), + "h2_http_proxy": _fixture_options(secure = False, supports_proxy_auth = True), + "h2_proxy": _fixture_options(secure = False, includes_proxy = True), + "h2_sockpair_1byte": _fixture_options( + fullstack = False, + dns_resolver = False, + client_channel = False, + secure = False, + ), + "h2_sockpair": _fixture_options( + fullstack = False, + dns_resolver = False, + client_channel = False, + secure = False, + ), + "h2_sockpair+trace": _fixture_options( + fullstack = False, + dns_resolver = False, + tracing = True, + secure = False, + client_channel = False, + ), + "h2_ssl": _fixture_options(secure = False), + "h2_ssl_proxy": _fixture_options(includes_proxy = True, secure = False), + "h2_uds": _fixture_options( + dns_resolver = False, + _platforms = ["linux", "mac", "posix"], + secure = False, + ), +} + def _test_options( needs_fullstack = False, needs_dns = False, @@ -357,3 +407,57 @@ def grpc_end2end_tests(): poller, ], ) + +def grpc_end2end_nosec_tests(): + grpc_cc_library( + name = "end2end_nosec_tests", + srcs = ["end2end_nosec_tests.cc", "end2end_test_utils.cc"] + [ + "tests/%s.cc" % t + for t in sorted(END2END_TESTS.keys()) + if not END2END_TESTS[t].secure + ], + hdrs = [ + "tests/cancel_test_helpers.h", + "end2end_tests.h", + ], + language = "C++", + deps = [ + ":cq_verifier", + ":ssl_test_data", + ":http_proxy", + ":proxy", + ], + ) + + for f, fopt in END2END_NOSEC_FIXTURES.items(): + if fopt.secure: + continue + grpc_cc_binary( + name = "%s_nosec_test" % f, + srcs = ["fixtures/%s.cc" % f], + language = "C++", + deps = [ + ":end2end_nosec_tests", + "//test/core/util:grpc_test_util_unsecure", + "//:grpc_unsecure", + "//test/core/util:gpr_test_util", + "//:gpr", + ], + ) + for t, topt in END2END_TESTS.items(): + #print(_compatible(fopt, topt), f, t, fopt, topt) + if not _compatible(fopt, topt): + continue + if topt.secure: + continue + for poller in POLLERS: + native.sh_test( + name = "%s_nosec_test@%s@poller=%s" % (f, t, poller), + data = [":%s_nosec_test" % f], + srcs = ["end2end_test.sh"], + args = [ + "$(location %s_nosec_test)" % f, + t, + poller, + ], + ) diff --git a/test/core/iomgr/tcp_client_uv_test.cc b/test/core/iomgr/tcp_client_uv_test.cc index ffcc7937c7..27f894e3f3 100644 --- a/test/core/iomgr/tcp_client_uv_test.cc +++ b/test/core/iomgr/tcp_client_uv_test.cc @@ -129,6 +129,7 @@ void test_succeeds(void) { uv_close((uv_handle_t*)svr_handle, close_cb); gpr_mu_unlock(g_mu); + grpc_core::ExecCtx::Get()->Flush(); } void test_fails(void) { @@ -178,6 +179,7 @@ void test_fails(void) { } gpr_mu_unlock(g_mu); + grpc_core::ExecCtx::Get()->Flush(); } static void destroy_pollset(void* p, grpc_error* error) { @@ -186,21 +188,22 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_core::ExecCtx exec_ctx; grpc_test_init(argc, argv); grpc_init(); - g_pollset = static_cast<grpc_pollset*>(gpr_malloc(grpc_pollset_size())); - grpc_pollset_init(g_pollset, &g_mu); - - test_succeeds(); - gpr_log(GPR_ERROR, "End of first test"); - test_fails(); - GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, g_pollset, - grpc_schedule_on_exec_ctx); - grpc_pollset_shutdown(g_pollset, &destroyed); - + { + grpc_core::ExecCtx exec_ctx; + g_pollset = static_cast<grpc_pollset*>(gpr_malloc(grpc_pollset_size())); + grpc_pollset_init(g_pollset, &g_mu); + + test_succeeds(); + gpr_log(GPR_ERROR, "End of first test"); + test_fails(); + GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, g_pollset, + grpc_schedule_on_exec_ctx); + grpc_pollset_shutdown(g_pollset, &destroyed); + gpr_free(g_pollset); + } grpc_shutdown(); - gpr_free(g_pollset); return 0; } diff --git a/test/core/iomgr/tcp_server_uv_test.cc b/test/core/iomgr/tcp_server_uv_test.cc index 35d62b51b7..e99fa79bfd 100644 --- a/test/core/iomgr/tcp_server_uv_test.cc +++ b/test/core/iomgr/tcp_server_uv_test.cc @@ -119,6 +119,7 @@ static void test_no_op(void) { grpc_tcp_server* s; GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(NULL, NULL, &s)); grpc_tcp_server_unref(s); + grpc_core::ExecCtx::Get()->Flush(); } static void test_no_op_with_start(void) { @@ -128,6 +129,7 @@ static void test_no_op_with_start(void) { LOG_TEST("test_no_op_with_start"); grpc_tcp_server_start(s, NULL, 0, on_connect, NULL); grpc_tcp_server_unref(s); + grpc_core::ExecCtx::Get()->Flush(); } static void test_no_op_with_port(void) { @@ -147,6 +149,7 @@ static void test_no_op_with_port(void) { port > 0); grpc_tcp_server_unref(s); + grpc_core::ExecCtx::Get()->Flush(); } static void test_no_op_with_port_and_start(void) { @@ -168,6 +171,7 @@ static void test_no_op_with_port_and_start(void) { grpc_tcp_server_start(s, NULL, 0, on_connect, NULL); grpc_tcp_server_unref(s); + grpc_core::ExecCtx::Get()->Flush(); } static void connect_cb(uv_connect_t* req, int status) { @@ -273,7 +277,7 @@ static void test_connect(unsigned n) { GPR_ASSERT(weak_ref.server != NULL); grpc_tcp_server_unref(s); - + grpc_core::ExecCtx::Get()->Flush(); /* Weak ref lost. */ GPR_ASSERT(weak_ref.server == NULL); } @@ -284,25 +288,27 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_core::ExecCtx exec_ctx; grpc_test_init(argc, argv); grpc_init(); - g_pollset = static_cast<grpc_pollset*>(gpr_malloc(grpc_pollset_size())); - grpc_pollset_init(g_pollset, &g_mu); - - test_no_op(); - test_no_op_with_start(); - test_no_op_with_port(); - test_no_op_with_port_and_start(); - test_connect(1); - test_connect(10); - - GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, g_pollset, - grpc_schedule_on_exec_ctx); - grpc_pollset_shutdown(g_pollset, &destroyed); - + { + grpc_core::ExecCtx exec_ctx; + g_pollset = static_cast<grpc_pollset*>(gpr_malloc(grpc_pollset_size())); + grpc_pollset_init(g_pollset, &g_mu); + + test_no_op(); + test_no_op_with_start(); + test_no_op_with_port(); + test_no_op_with_port_and_start(); + test_connect(1); + test_connect(10); + + GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, g_pollset, + grpc_schedule_on_exec_ctx); + grpc_pollset_shutdown(g_pollset, &destroyed); + + gpr_free(g_pollset); + } grpc_shutdown(); - gpr_free(g_pollset); return 0; } diff --git a/test/core/security/alts_security_connector_test.cc b/test/core/security/alts_security_connector_test.cc index 103a493526..9378236338 100644 --- a/test/core/security/alts_security_connector_test.cc +++ b/test/core/security/alts_security_connector_test.cc @@ -24,7 +24,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include "src/core/lib/security/security_connector/alts_security_connector.h" +#include "src/core/lib/security/security_connector/alts/alts_security_connector.h" #include "src/core/lib/transport/transport.h" #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" #include "src/core/tsi/transport_security.h" diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index 9dd37b975b..fef0ea71f7 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -29,6 +29,7 @@ #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/security_connector/security_connector.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security.h" diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc index 1e04691ce2..d2bbb7c1c2 100644 --- a/test/core/security/ssl_server_fuzzer.cc +++ b/test/core/security/ssl_server_fuzzer.cc @@ -93,9 +93,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_handshake_manager* handshake_mgr = grpc_handshake_manager_create(); grpc_server_security_connector_add_handshakers(sc, nullptr, handshake_mgr); grpc_handshake_manager_do_handshake( - handshake_mgr, nullptr /* interested_parties */, mock_endpoint, - nullptr /* channel_args */, deadline, nullptr /* acceptor */, - on_handshake_done, &state); + handshake_mgr, mock_endpoint, nullptr /* channel_args */, deadline, + nullptr /* acceptor */, on_handshake_done, &state); grpc_core::ExecCtx::Get()->Flush(); // If the given string happens to be part of the correct client hello, the diff --git a/test/core/tsi/fake_transport_security_test.cc b/test/core/tsi/fake_transport_security_test.cc index 5e6671965d..587d8f5dda 100644 --- a/test/core/tsi/fake_transport_security_test.cc +++ b/test/core/tsi/fake_transport_security_test.cc @@ -22,6 +22,7 @@ #include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/tsi/fake_transport_security.h" +#include "src/core/tsi/transport_security.h" #include "test/core/tsi/transport_security_test_lib.h" #include "test/core/util/test_config.h" diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt index 2268adc169..63898ea3b1 100644 --- a/test/core/util/ubsan_suppressions.txt +++ b/test/core/util/ubsan_suppressions.txt @@ -15,3 +15,17 @@ enum:message_compress_test enum:transport_security_test enum:algorithm_test alignment:transport_security_test +# TODO(jtattermusch): address issues and remove the supressions +nonnull-attribute:gsec_aes_gcm_aead_crypter_decrypt_iovec +nonnull-attribute:gsec_test_random_encrypt_decrypt +nonnull-attribute:gsec_test_multiple_random_encrypt_decrypt +nonnull-attribute:gsec_test_copy +nonnull-attribute:gsec_test_encrypt_decrypt_test_vector +alignment:absl::little_endian::Store64 +alignment:absl::little_endian::Load64 +float-divide-by-zero:grpc::testing::postprocess_scenario_result +enum:grpc_op_string +nonnull-attribute:grpc_lb_addresses_copy +signed-integer-overflow:chrono +enum:grpc_http2_error_to_grpc_status +enum:grpc_chttp2_cancel_stream
\ No newline at end of file diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index a9d68ab058..77c25c1416 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -31,6 +31,7 @@ #include <grpcpp/channel.h> #include <grpcpp/client_context.h> #include <grpcpp/create_channel.h> +#include <grpcpp/health_check_service_interface.h> #include <grpcpp/server.h> #include <grpcpp/server_builder.h> @@ -287,6 +288,10 @@ class ClientLbEnd2endTest : public ::testing::Test { server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); if (join) thread_->join(); } + + void SetServingStatus(const grpc::string& service, bool serving) { + server_->GetHealthCheckService()->SetServingStatus(service, serving); + } }; void ResetCounters() { @@ -318,6 +323,17 @@ class ClientLbEnd2endTest : public ::testing::Test { return true; } + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + bool SeenAllServers() { for (const auto& server : servers_) { if (server->service_.request_count() == 0) return false; @@ -357,11 +373,7 @@ TEST_F(ClientLbEnd2endTest, PickFirst) { StartServers(kNumServers); auto channel = BuildChannel(""); // test that pick first is the default. auto stub = BuildStub(channel); - std::vector<int> ports; - for (size_t i = 0; i < servers_.size(); ++i) { - ports.emplace_back(servers_[i]->port_); - } - SetNextResolution(ports); + SetNextResolution(GetServersPorts()); for (size_t i = 0; i < servers_.size(); ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); } @@ -584,10 +596,7 @@ TEST_P(ClientLbEnd2endWithParamTest, PickFirstManyUpdates) { StartServers(kNumServers); auto channel = BuildChannel("pick_first"); auto stub = BuildStub(channel); - std::vector<int> ports; - for (size_t i = 0; i < servers_.size(); ++i) { - ports.emplace_back(servers_[i]->port_); - } + std::vector<int> ports = GetServersPorts(); for (size_t i = 0; i < 1000; ++i) { std::shuffle(ports.begin(), ports.end(), std::mt19937(std::random_device()())); @@ -717,11 +726,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobin) { StartServers(kNumServers); auto channel = BuildChannel("round_robin"); auto stub = BuildStub(channel); - std::vector<int> ports; - for (const auto& server : servers_) { - ports.emplace_back(server->port_); - } - SetNextResolution(ports); + SetNextResolution(GetServersPorts()); // Wait until all backends are ready. do { CheckRpcSendOk(stub, DEBUG_LOCATION); @@ -883,10 +888,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinManyUpdates) { StartServers(kNumServers); auto channel = BuildChannel("round_robin"); auto stub = BuildStub(channel); - std::vector<int> ports; - for (size_t i = 0; i < servers_.size(); ++i) { - ports.emplace_back(servers_[i]->port_); - } + std::vector<int> ports = GetServersPorts(); for (size_t i = 0; i < 1000; ++i) { std::shuffle(ports.begin(), ports.end(), std::mt19937(std::random_device()())); @@ -996,6 +998,125 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { WaitForServer(stub, 0, DEBUG_LOCATION); } +// If health checking is required by client but health checking service +// is not running on the server, the channel should be treated as healthy. +TEST_F(ClientLbEnd2endTest, + RoundRobinServersHealthCheckingUnimplementedTreatedAsHealthy) { + StartServers(1); // Single server + ChannelArguments args; + args.SetServiceConfigJSON( + "{\"healthCheckConfig\": " + "{\"serviceName\": \"health_check_service_name\"}}"); + auto channel = BuildChannel("round_robin", args); + auto stub = BuildStub(channel); + SetNextResolution({servers_[0]->port_}); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + CheckRpcSendOk(stub, DEBUG_LOCATION); +} + +TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthChecking) { + EnableDefaultHealthCheckService(true); + // Start servers. + const int kNumServers = 3; + StartServers(kNumServers); + ChannelArguments args; + args.SetServiceConfigJSON( + "{\"healthCheckConfig\": " + "{\"serviceName\": \"health_check_service_name\"}}"); + auto channel = BuildChannel("round_robin", args); + auto stub = BuildStub(channel); + SetNextResolution(GetServersPorts()); + // Channel should not become READY, because health checks should be failing. + gpr_log(GPR_INFO, + "*** initial state: unknown health check service name for " + "all servers"); + EXPECT_FALSE(WaitForChannelReady(channel.get(), 1)); + // Now set one of the servers to be healthy. + // The channel should become healthy and all requests should go to + // the healthy server. + gpr_log(GPR_INFO, "*** server 0 healthy"); + servers_[0]->SetServingStatus("health_check_service_name", true); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + for (int i = 0; i < 10; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + EXPECT_EQ(10, servers_[0]->service_.request_count()); + EXPECT_EQ(0, servers_[1]->service_.request_count()); + EXPECT_EQ(0, servers_[2]->service_.request_count()); + // Now set a second server to be healthy. + gpr_log(GPR_INFO, "*** server 2 healthy"); + servers_[2]->SetServingStatus("health_check_service_name", true); + WaitForServer(stub, 2, DEBUG_LOCATION); + for (int i = 0; i < 10; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + EXPECT_EQ(5, servers_[0]->service_.request_count()); + EXPECT_EQ(0, servers_[1]->service_.request_count()); + EXPECT_EQ(5, servers_[2]->service_.request_count()); + // Now set the remaining server to be healthy. + gpr_log(GPR_INFO, "*** server 1 healthy"); + servers_[1]->SetServingStatus("health_check_service_name", true); + WaitForServer(stub, 1, DEBUG_LOCATION); + for (int i = 0; i < 9; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + EXPECT_EQ(3, servers_[0]->service_.request_count()); + EXPECT_EQ(3, servers_[1]->service_.request_count()); + EXPECT_EQ(3, servers_[2]->service_.request_count()); + // Now set one server to be unhealthy again. Then wait until the + // unhealthiness has hit the client. We know that the client will see + // this when we send kNumServers requests and one of the remaining servers + // sees two of the requests. + gpr_log(GPR_INFO, "*** server 0 unhealthy"); + servers_[0]->SetServingStatus("health_check_service_name", false); + do { + ResetCounters(); + for (int i = 0; i < kNumServers; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + } while (servers_[1]->service_.request_count() != 2 && + servers_[2]->service_.request_count() != 2); + // Now set the remaining two servers to be unhealthy. Make sure the + // channel leaves READY state and that RPCs fail. + gpr_log(GPR_INFO, "*** all servers unhealthy"); + servers_[1]->SetServingStatus("health_check_service_name", false); + servers_[2]->SetServingStatus("health_check_service_name", false); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + CheckRpcSendFailure(stub); + // Clean up. + EnableDefaultHealthCheckService(false); +} + +TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { + EnableDefaultHealthCheckService(true); + // Start server. + const int kNumServers = 1; + StartServers(kNumServers); + // Create a channel with health-checking enabled. + ChannelArguments args; + args.SetServiceConfigJSON( + "{\"healthCheckConfig\": " + "{\"serviceName\": \"health_check_service_name\"}}"); + auto channel1 = BuildChannel("round_robin", args); + auto stub1 = BuildStub(channel1); + std::vector<int> ports = GetServersPorts(); + SetNextResolution(ports); + // Create a channel with health checking enabled but inhibited. + args.SetInt(GRPC_ARG_INHIBIT_HEALTH_CHECKING, 1); + auto channel2 = BuildChannel("round_robin", args); + auto stub2 = BuildStub(channel2); + SetNextResolution(ports); + // First channel should not become READY, because health checks should be + // failing. + EXPECT_FALSE(WaitForChannelReady(channel1.get(), 1)); + CheckRpcSendFailure(stub1); + // Second channel should be READY. + EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); + CheckRpcSendOk(stub2, DEBUG_LOCATION); + // Clean up. + EnableDefaultHealthCheckService(false); +} + } // namespace } // namespace testing } // namespace grpc diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index 4f21551ff4..0f81305405 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -142,3 +142,24 @@ grpc_cc_binary( "//test/cpp/util:test_config", ], ) + +grpc_cc_test( + name = "interop_test", + srcs = ["interop_test.cc"], + data = [ + ":interop_client", + ":interop_server", + ], + external_deps = [ + "gflags", + ], + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", + "//test/cpp/util:test_util", + ], +) diff --git a/test/cpp/naming/utils/dns_server.py b/test/cpp/naming/utils/dns_server.py index 1e8e2e3287..bf11d14c30 100755 --- a/test/cpp/naming/utils/dns_server.py +++ b/test/cpp/naming/utils/dns_server.py @@ -93,6 +93,10 @@ def start_local_dns_server(args): _push_record(record_full_name, dns.Record_SRV(p, w, port, target_full_name, ttl=r_ttl)) if r_type == 'TXT': _maybe_split_up_txt_data(record_full_name, r_data, r_ttl) + # Add an optional IPv4 record is specified + if args.add_a_record: + extra_host, extra_host_ipv4 = args.add_a_record.split(':') + _push_record(extra_host, dns.Record_A(extra_host_ipv4, ttl=0)) # Server health check record _push_record(_SERVER_HEALTH_CHECK_RECORD_NAME, dns.Record_A(_SERVER_HEALTH_CHECK_RECORD_DATA, ttl=0)) soa_record = dns.Record_SOA(mname = common_zone_name) @@ -122,7 +126,7 @@ def flush_stdout_loop(): num_timeouts_so_far = 0 sleep_time = 1 # Prevent zombies. Tests that use this server are short-lived. - max_timeouts = 60 * 2 + max_timeouts = 60 * 10 while num_timeouts_so_far < max_timeouts: sys.stdout.flush() time.sleep(sleep_time) @@ -136,7 +140,14 @@ def main(): help='Port for DNS server to listen on for TCP and UDP.') argp.add_argument('-r', '--records_config_path', default=None, type=str, help=('Directory of resolver_test_record_groups.yaml file. ' - 'Defauls to path needed when the test is invoked as part of run_tests.py.')) + 'Defaults to path needed when the test is invoked as part ' + 'of run_tests.py.')) + argp.add_argument('--add_a_record', default=None, type=str, + help=('Add an A record via the command line. Useful for when we ' + 'need to serve a one-off A record that is under a ' + 'different domain then the rest the records configured in ' + '--records_config_path (which all need to be under the ' + 'same domain). Format: <name>:<ipv4 address>')) args = argp.parse_args() signal.signal(signal.SIGTERM, _quit_on_signal) signal.signal(signal.SIGINT, _quit_on_signal) diff --git a/test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py b/test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py new file mode 100755 index 0000000000..97171e21da --- /dev/null +++ b/test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python2.7 +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import argparse +import subprocess +import os +import tempfile +import sys +import time +import signal +import yaml + +argp = argparse.ArgumentParser(description='Runs a DNS server for LB interop tests') +argp.add_argument('-l', '--grpclb_ips', default=None, type=str, + help='Comma-separated list of IP addresses of balancers') +argp.add_argument('-f', '--fallback_ips', default=None, type=str, + help='Comma-separated list of IP addresses of fallback servers') +argp.add_argument('-c', '--cause_no_error_no_data_for_balancer_a_record', + default=False, action='store_const', const=True, + help=('Used for testing the case in which the grpclb ' + 'balancer A record lookup results in a DNS NOERROR response ' + 'but with no ANSWER section i.e. no addresses')) +args = argp.parse_args() + +balancer_records = [] +grpclb_ips = args.grpclb_ips.split(',') +if grpclb_ips[0]: + for ip in grpclb_ips: + balancer_records.append({ + 'TTL': '2100', + 'data': ip, + 'type': 'A', + }) +fallback_records = [] +fallback_ips = args.fallback_ips.split(',') +if fallback_ips[0]: + for ip in fallback_ips: + fallback_records.append({ + 'TTL': '2100', + 'data': ip, + 'type': 'A', + }) +records_config_yaml = { + 'resolver_tests_common_zone_name': + 'test.google.fr.', + 'resolver_component_tests': [{ + 'records': { + '_grpclb._tcp.server': [ + { + 'TTL': '2100', + 'data': '0 0 12000 balancer', + 'type': 'SRV' + }, + ], + 'balancer': + balancer_records, + 'server': + fallback_records, + } + }] +} +if args.cause_no_error_no_data_for_balancer_a_record: + balancer_records = records_config_yaml[ + 'resolver_component_tests'][0]['records']['balancer'] + assert not balancer_records + # Insert a TXT record at the balancer.test.google.fr. domain. + # This TXT record won't actually be resolved or used by gRPC clients; + # inserting this record is just a way get the balancer.test.google.fr. + # A record queries to return NOERROR DNS responses that also have no + # ANSWER section, in order to simulate this failure case. + balancer_records.append({ + 'TTL': '2100', + 'data': 'arbitrary string that wont actually be resolved', + 'type': 'TXT', + }) +# Generate the actual DNS server records config file +records_config_path = tempfile.mktemp() +with open(records_config_path, 'w') as records_config_generated: + records_config_generated.write(yaml.dump(records_config_yaml)) + +with open(records_config_path, 'r') as records_config_generated: + sys.stderr.write('===== DNS server records config: =====\n') + sys.stderr.write(records_config_generated.read()) + sys.stderr.write('======================================\n') + +# Run the DNS server +# Note that we need to add the extra +# A record for metadata.google.internal in order for compute engine +# OAuth creds and ALTS creds to work. +# TODO(apolcyn): should metadata.google.internal always resolve +# to 169.254.169.254? +subprocess.check_output([ + '/var/local/git/grpc/test/cpp/naming/utils/dns_server.py', '--port=53', + '--records_config_path', records_config_path, + '--add_a_record=metadata.google.internal:169.254.169.254', +]) diff --git a/test/cpp/naming/utils/tcp_connect.py b/test/cpp/naming/utils/tcp_connect.py index 5773c7cae8..f3ad5891fd 100755 --- a/test/cpp/naming/utils/tcp_connect.py +++ b/test/cpp/naming/utils/tcp_connect.py @@ -31,7 +31,8 @@ def main(): argp.add_argument('-t', '--timeout', default=1, type=int, help='Force process exit after this number of seconds.') args = argp.parse_args() - socket.create_connection([args.server_host, args.server_port]) + socket.create_connection([args.server_host, args.server_port], + timeout=args.timeout) if __name__ == '__main__': main() diff --git a/test/cpp/util/config_grpc_cli.h b/test/cpp/util/config_grpc_cli.h index 1df7b36e2e..358884196d 100644 --- a/test/cpp/util/config_grpc_cli.h +++ b/test/cpp/util/config_grpc_cli.h @@ -40,11 +40,6 @@ #define GRPC_CUSTOM_TEXTFORMAT ::google::protobuf::TextFormat #endif -#ifndef GRPC_CUSTOM_JSONUTIL -#include <google/protobuf/util/json_util.h> -#define GRPC_CUSTOM_JSONUTIL ::google::protobuf::util -#endif - #ifndef GRPC_CUSTOM_DISKSOURCETREE #include <google/protobuf/compiler/importer.h> #define GRPC_CUSTOM_DISKSOURCETREE ::google::protobuf::compiler::DiskSourceTree @@ -63,8 +58,6 @@ typedef GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE MergedDescriptorDatabase; typedef GRPC_CUSTOM_TEXTFORMAT TextFormat; -namespace json = GRPC_CUSTOM_JSONUTIL; - namespace compiler { typedef GRPC_CUSTOM_DISKSOURCETREE DiskSourceTree; typedef GRPC_CUSTOM_IMPORTER Importer; diff --git a/tools/bazel.rc b/tools/bazel.rc index 39f8071535..088c9da63c 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -1,51 +1,54 @@ +# bazelrc file +# bazel >= 0.18 looks for %workspace%/.bazelrc (which redirects here) +# Older bazel versions look for %workspace%/tools/bazel.rc (this file) +# See https://github.com/bazelbuild/bazel/issues/6319 + build --client_env=CC=clang -build --copt -DGRPC_BAZEL_BUILD +build --copt=-DGRPC_BAZEL_BUILD -build:opt --copt -Wframe-larger-than=16384 +build:opt --copt=-Wframe-larger-than=16384 build:asan --strip=never -build:asan --copt -fsanitize-coverage=edge -build:asan --copt -fsanitize=address -build:asan --copt -O0 -build:asan --copt -fno-omit-frame-pointer -build:asan --copt -DGPR_NO_DIRECT_SYSCALLS -build:asan --linkopt -fsanitize=address +build:asan --copt=-fsanitize=address +build:asan --copt=-O0 +build:asan --copt=-fno-omit-frame-pointer +build:asan --copt=-DGPR_NO_DIRECT_SYSCALLS +build:asan --linkopt=-fsanitize=address build:asan --action_env=ASAN_OPTIONS=detect_leaks=1:color=always build:asan --action_env=LSAN_OPTIONS=suppressions=test/core/util/lsan_suppressions.txt:report_objects=1 build:msan --strip=never -build:msan --copt -fsanitize-coverage=edge -build:msan --copt -fsanitize=memory -build:msan --copt -O0 -build:msan --copt -fsanitize-memory-track-origins -build:msan --copt -fsanitize-memory-use-after-dtor -build:msan --copt -fno-omit-frame-pointer -build:msan --copt -fPIE -build:msan --copt -DGPR_NO_DIRECT_SYSCALLS -build:msan --linkopt -fsanitize=memory -build:msan --linkopt -fPIE +build:msan --copt=-fsanitize-coverage=edge +build:msan --copt=-fsanitize=memory +build:msan --copt=-O0 +build:msan --copt=-fsanitize-memory-track-origins +build:msan --copt=-fsanitize-memory-use-after-dtor +build:msan --copt=-fno-omit-frame-pointer +build:msan --copt=-fPIE +build:msan --copt=-DGPR_NO_DIRECT_SYSCALLS +build:msan --linkopt=-fsanitize=memory +build:msan --linkopt=-fPIE build:msan --action_env=MSAN_OPTIONS=poison_in_dtor=1 build:tsan --strip=never -build:tsan --copt -fsanitize=thread -build:tsan --copt -fno-omit-frame-pointer -build:tsan --copt -DGPR_NO_DIRECT_SYSCALLS -build:tsan --copt -DGRPC_TSAN -build:tsan --linkopt -fsanitize=thread +build:tsan --copt=-fsanitize=thread +build:tsan --copt=-fno-omit-frame-pointer +build:tsan --copt=-DGPR_NO_DIRECT_SYSCALLS +build:tsan --copt=-DGRPC_TSAN +build:tsan --linkopt=-fsanitize=thread build:tsan --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1 build:ubsan --strip=never -build:ubsan --copt -fsanitize-coverage=edge -build:ubsan --copt -fsanitize=undefined -build:ubsan --copt -fno-omit-frame-pointer -build:ubsan --copt -DGRPC_UBSAN -build:ubsan --copt -DNDEBUG -build:ubsan --copt -fno-sanitize=function,vptr -build:ubsan --linkopt -fsanitize=undefined +build:ubsan --copt=-fsanitize=undefined +build:ubsan --copt=-fno-omit-frame-pointer +build:ubsan --copt=-DGRPC_UBSAN +build:ubsan --copt=-DNDEBUG +build:ubsan --copt=-fno-sanitize=function,vptr +build:ubsan --linkopt=-fsanitize=undefined build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1:suppressions=test/core/util/ubsan_suppressions.txt build:basicprof --strip=never -build:basicprof --copt -DNDEBUG -build:basicprof --copt -O2 -build:basicprof --copt -DGRPC_BASIC_PROFILER -build:basicprof --copt -DGRPC_TIMERS_RDTSC +build:basicprof --copt=-DNDEBUG +build:basicprof --copt=-O2 +build:basicprof --copt=-DGRPC_BASIC_PROFILER +build:basicprof --copt=-DGRPC_TIMERS_RDTSC diff --git a/tools/buildgen/generate_build_additions.sh b/tools/buildgen/generate_build_additions.sh index 693c02fdb2..5a1f4a598a 100755 --- a/tools/buildgen/generate_build_additions.sh +++ b/tools/buildgen/generate_build_additions.sh @@ -25,7 +25,8 @@ gen_build_yaml_dirs=" \ test/core/bad_ssl \ test/core/end2end \ test/cpp/naming \ - test/cpp/qps" + test/cpp/qps \ + tools/run_tests/lb_interop_tests" gen_build_files="" for gen_build_yaml in $gen_build_yaml_dirs do diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index f705a9bd41..adfd4a24f9 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -63,6 +63,7 @@ CONFIG = [ 'grpc.max_response_message_bytes', # well known method names '/grpc.lb.v1.LoadBalancer/BalanceLoad', + '/grpc.health.v1.Health/Watch', # compression algorithm names 'deflate', 'gzip', diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py index 77f602ad1f..787bef1778 100755 --- a/tools/distrib/check_copyright.py +++ b/tools/distrib/check_copyright.py @@ -75,6 +75,8 @@ _EXEMPT = frozenset(( 'examples/python/multiplex/route_guide_pb2_grpc.py', 'examples/python/route_guide/route_guide_pb2.py', 'examples/python/route_guide/route_guide_pb2_grpc.py', + 'src/core/ext/filters/client_channel/health/health.pb.h', + 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h', @@ -87,8 +89,6 @@ _EXEMPT = frozenset(( 'src/core/tsi/alts/handshaker/handshaker.pb.c', 'src/core/tsi/alts/handshaker/transport_security_common.pb.h', 'src/core/tsi/alts/handshaker/transport_security_common.pb.c', - 'src/cpp/server/health/health.pb.h', - 'src/cpp/server/health/health.pb.c', # An older file originally from outside gRPC. 'src/php/tests/bootstrap.php', diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py index 56f48af56a..b8d530cce0 100755 --- a/tools/distrib/check_include_guards.py +++ b/tools/distrib/check_include_guards.py @@ -156,6 +156,7 @@ argp.add_argument('--precommit', default=False, action='store_true') args = argp.parse_args() KNOWN_BAD = set([ + 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h', diff --git a/tools/distrib/check_nanopb_output.sh b/tools/distrib/check_nanopb_output.sh index 1c2ef9b768..018cbb7b66 100755 --- a/tools/distrib/check_nanopb_output.sh +++ b/tools/distrib/check_nanopb_output.sh @@ -71,7 +71,7 @@ fi # # checks for health.proto # -readonly HEALTH_GRPC_OUTPUT_PATH='src/cpp/server/health' +readonly HEALTH_GRPC_OUTPUT_PATH='src/core/ext/filters/client_channel/health' # nanopb-compile the proto to a temp location ./tools/codegen/core/gen_nano_proto.sh \ src/proto/grpc/health/v1/health.proto \ @@ -79,7 +79,7 @@ readonly HEALTH_GRPC_OUTPUT_PATH='src/cpp/server/health' "$HEALTH_GRPC_OUTPUT_PATH" # compare outputs to checked compiled code for NANOPB_OUTPUT_FILE in $NANOPB_HEALTH_TMP_OUTPUT/*.pb.*; do - if ! diff "$NANOPB_OUTPUT_FILE" "src/cpp/server/health/$(basename $NANOPB_OUTPUT_FILE)"; then + if ! diff "$NANOPB_OUTPUT_FILE" "${HEALTH_GRPC_OUTPUT_PATH}/$(basename $NANOPB_OUTPUT_FILE)"; then echo "Outputs differ: $NANOPB_HEALTH_TMP_OUTPUT vs $HEALTH_GRPC_OUTPUT_PATH" exit 2 fi diff --git a/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh index 2f31bea69b..fd549fb9e5 100755 --- a/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh @@ -31,7 +31,7 @@ cd /var/local/git/grpc make install-certs # build C++ interop client & server -make interop_client interop_server +make interop_client interop_server -j2 # build C++ http2 client make http2_client diff --git a/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh index b651ac5b88..0e36c193c9 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh @@ -26,3 +26,11 @@ cd /var/local/git/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true +# enable extra java logging +mkdir -p /var/local/grpc_java_logging +echo "handlers = java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level = ALL +.level = FINE +io.grpc.netty.NettyClientHandler = ALL +io.grpc.netty.NettyServerHandler = ALL" > /var/local/grpc_java_logging/logconf.txt + diff --git a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh index 521111acaa..4c5ba4b7a3 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh @@ -25,4 +25,12 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true + +# enable extra java logging +mkdir -p /var/local/grpc_java_logging +echo "handlers = java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level = ALL +.level = FINE +io.grpc.netty.NettyClientHandler = ALL +io.grpc.netty.NettyServerHandler = ALL" > /var/local/grpc_java_logging/logconf.txt diff --git a/tools/dockerfile/interoptest/lb_interop_fake_servers/Dockerfile b/tools/dockerfile/interoptest/lb_interop_fake_servers/Dockerfile new file mode 100644 index 0000000000..22963f7f83 --- /dev/null +++ b/tools/dockerfile/interoptest/lb_interop_fake_servers/Dockerfile @@ -0,0 +1,34 @@ +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM golang:1.10 + +RUN apt-get update && apt-get install -y \ + dnsutils \ + git \ + vim \ + curl \ + python-pip \ + python-yaml \ + make && apt-get clean + +RUN ln -s /usr/local/go/bin/go /usr/local/bin + +# Install Python packages from PyPI +RUN pip install --upgrade pip==10.0.1 +RUN pip install virtualenv +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/interoptest/lb_interop_fake_servers/build_interop.sh b/tools/dockerfile/interoptest/lb_interop_fake_servers/build_interop.sh new file mode 100644 index 0000000000..1846d51753 --- /dev/null +++ b/tools/dockerfile/interoptest/lb_interop_fake_servers/build_interop.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Gets a built Go interop server, fake balancer server, and python +# DNS server into a base image. +set -e + +# Clone just the grpc-go source code without any dependencies. +# We are cloning from a local git repo that contains the right revision +# to test instead of using "go get" to download from Github directly. +git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc + +# Get all gRPC Go dependencies +(cd src/google.golang.org/grpc && make deps && make testdeps) + +# Build the interop server and fake balancer +(cd src/google.golang.org/grpc/interop/server && go install) +(cd src/google.golang.org/grpc/interop/fake_grpclb && go install) + +# Clone the grpc/grpc repo to get the python DNS server. +# Hack: we don't need to init submodules for the scripts we need. +mkdir -p /var/local/git/grpc +git clone /var/local/jenkins/grpc /var/local/git/grpc diff --git a/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile b/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile new file mode 100644 index 0000000000..a7a8174db4 --- /dev/null +++ b/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile @@ -0,0 +1,69 @@ +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM debian:stretch + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + dnsutils \ + gcc \ + gcc-multilib \ + git \ + golang \ + gyp \ + lcov \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +#================ +# Build profiling +RUN apt-get update && apt-get install -y time && apt-get clean + +# Google Cloud platform API libraries +RUN apt-get update && apt-get install -y python-pip && apt-get clean +RUN pip install --upgrade google-api-python-client oauth2client + +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 + +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local + + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] + diff --git a/tools/dockerfile/test/python_pyenv_x64/Dockerfile b/tools/dockerfile/test/python_stretch_3.5_x64/Dockerfile index d94ccc8c74..0e97e77e2f 100644 --- a/tools/dockerfile/test/python_pyenv_x64/Dockerfile +++ b/tools/dockerfile/test/python_stretch_3.5_x64/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2016 gRPC authors. +# Copyright 2018 The gRPC Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ # limitations under the License. FROM debian:stretch - + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ @@ -53,51 +53,20 @@ RUN apt-get update && apt-get install -y time && apt-get clean RUN apt-get update && apt-get install -y python-pip && apt-get clean RUN pip install --upgrade google-api-python-client oauth2client -#==================== -# Python dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - python-all-dev \ - python3-all-dev \ - python-pip - -# Install Python packages from PyPI -RUN pip install --upgrade pip==10.0.1 -RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 - -# Install dependencies for pyenv -RUN apt-get update && apt-get install -y \ - libbz2-dev \ - libncurses5-dev \ - libncursesw5-dev \ - libreadline-dev \ - libsqlite3-dev \ - libssl-dev \ - llvm \ - mercurial \ - zlib1g-dev && apt-get clean - -# Install Pyenv and dev Python versions 3.{5,6,7} -RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash -ENV PATH /root/.pyenv/bin:$PATH -RUN eval "$(pyenv init -)" -RUN eval "$(pyenv virtualenv-init -)" -RUN pyenv update -RUN pyenv install 3.5-dev -RUN pyenv install 3.6-dev -RUN pyenv install 3.7-dev -RUN pyenv install pypy-5.3.1 -RUN pyenv local 3.5-dev 3.6-dev 3.7-dev pypy-5.3.1 +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 -# Install pip and virtualenv for Python 3.5 -RUN curl https://bootstrap.pypa.io/get-pip.py | python3.5 -RUN python3.5 -m pip install virtualenv +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local RUN mkdir /var/local/jenkins # Define the default command. CMD ["bash"] + + +RUN apt-get update && apt-get install -y python3.5 python3-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python3.5 diff --git a/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile b/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile new file mode 100644 index 0000000000..9b16b2d3a1 --- /dev/null +++ b/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile @@ -0,0 +1,72 @@ +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM debian:stretch + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + dnsutils \ + gcc \ + gcc-multilib \ + git \ + golang \ + gyp \ + lcov \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +#================ +# Build profiling +RUN apt-get update && apt-get install -y time && apt-get clean + +# Google Cloud platform API libraries +RUN apt-get update && apt-get install -y python-pip && apt-get clean +RUN pip install --upgrade google-api-python-client oauth2client + +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 + +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local + + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] + + +RUN apt-get update && apt-get -t testing install -y python3.6 python3-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python3.6 diff --git a/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile new file mode 100644 index 0000000000..add1cc509d --- /dev/null +++ b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile @@ -0,0 +1,72 @@ +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM debian:stretch + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + dnsutils \ + gcc \ + gcc-multilib \ + git \ + golang \ + gyp \ + lcov \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +#================ +# Build profiling +RUN apt-get update && apt-get install -y time && apt-get clean + +# Google Cloud platform API libraries +RUN apt-get update && apt-get install -y python-pip && apt-get clean +RUN pip install --upgrade google-api-python-client oauth2client + +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 + +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local + + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] + + +RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index aa6870fe22..5b73fd897a 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -764,7 +764,6 @@ INPUT = doc/PROTOCOL-HTTP2.md \ doc/PROTOCOL-WEB.md \ doc/binary-logging.md \ doc/c-style-guide.md \ -doc/combiner-explainer.md \ doc/command_line_tool.md \ doc/compression.md \ doc/compression_cookbook.md \ @@ -775,7 +774,6 @@ doc/cpp-style-guide.md \ doc/cpp/pending_api_cleanups.md \ doc/cpp/perf_notes.md \ doc/environment_variables.md \ -doc/epoll-polling-engine.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index dc803575c4..69135d24fc 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -764,7 +764,6 @@ INPUT = doc/PROTOCOL-HTTP2.md \ doc/PROTOCOL-WEB.md \ doc/binary-logging.md \ doc/c-style-guide.md \ -doc/combiner-explainer.md \ doc/command_line_tool.md \ doc/compression.md \ doc/compression_cookbook.md \ @@ -775,7 +774,6 @@ doc/cpp-style-guide.md \ doc/cpp/pending_api_cleanups.md \ doc/cpp/perf_notes.md \ doc/environment_variables.md \ -doc/epoll-polling-engine.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ @@ -1017,6 +1015,8 @@ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ include/grpcpp/support/time.h \ +src/core/ext/filters/client_channel/health/health.pb.c \ +src/core/ext/filters/client_channel/health/health.pb.h \ src/core/ext/transport/inproc/inproc_transport.h \ src/core/lib/avl/avl.h \ src/core/lib/backoff/backoff.h \ @@ -1214,8 +1214,6 @@ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.h \ src/cpp/server/health/default_health_check_service.cc \ src/cpp/server/health/default_health_check_service.h \ -src/cpp/server/health/health.pb.c \ -src/cpp/server/health/health.pb.h \ src/cpp/server/health/health_check_service.cc \ src/cpp/server/health/health_check_service_server_builder_option.cc \ src/cpp/server/insecure_server_credentials.cc \ @@ -1234,8 +1232,11 @@ src/cpp/util/status.cc \ src/cpp/util/string_ref.cc \ src/cpp/util/time_cc.cc \ third_party/nanopb/pb.h \ +third_party/nanopb/pb_common.c \ third_party/nanopb/pb_common.h \ +third_party/nanopb/pb_decode.c \ third_party/nanopb/pb_decode.h \ +third_party/nanopb/pb_encode.c \ third_party/nanopb/pb_encode.h # This tag can be used to specify the character encoding of the source files diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 973975ae28..b78fb607ad 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -764,13 +764,14 @@ INPUT = doc/PROTOCOL-HTTP2.md \ doc/PROTOCOL-WEB.md \ doc/binary-logging.md \ doc/c-style-guide.md \ -doc/combiner-explainer.md \ doc/command_line_tool.md \ doc/compression.md \ doc/compression_cookbook.md \ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ +doc/core/combiner-explainer.md \ +doc/core/epoll-polling-engine.md \ doc/core/grpc-client-server-polling-engine-usage.md \ doc/core/grpc-cq.md \ doc/core/grpc-error.md \ @@ -780,7 +781,6 @@ doc/core/pending_api_cleanups.md \ doc/core/transport_explainer.md \ doc/cpp-style-guide.md \ doc/environment_variables.md \ -doc/epoll-polling-engine.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 204ef493ba..437253c01b 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -764,13 +764,14 @@ INPUT = doc/PROTOCOL-HTTP2.md \ doc/PROTOCOL-WEB.md \ doc/binary-logging.md \ doc/c-style-guide.md \ -doc/combiner-explainer.md \ doc/command_line_tool.md \ doc/compression.md \ doc/compression_cookbook.md \ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ +doc/core/combiner-explainer.md \ +doc/core/epoll-polling-engine.md \ doc/core/grpc-client-server-polling-engine-usage.md \ doc/core/grpc-cq.md \ doc/core/grpc-error.md \ @@ -780,7 +781,6 @@ doc/core/pending_api_cleanups.md \ doc/core/transport_explainer.md \ doc/cpp-style-guide.md \ doc/environment_variables.md \ -doc/epoll-polling-engine.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ @@ -885,6 +885,10 @@ src/core/ext/filters/client_channel/client_channel_factory.h \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.h \ +src/core/ext/filters/client_channel/health/health.pb.c \ +src/core/ext/filters/client_channel/health/health.pb.h \ +src/core/ext/filters/client_channel/health/health_check_client.cc \ +src/core/ext/filters/client_channel/health/health_check_client.h \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.h \ src/core/ext/filters/client_channel/http_proxy.cc \ @@ -1369,16 +1373,22 @@ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.h \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.h \ -src/core/lib/security/security_connector/alts_security_connector.cc \ -src/core/lib/security/security_connector/alts_security_connector.h \ +src/core/lib/security/security_connector/alts/alts_security_connector.cc \ +src/core/lib/security/security_connector/alts/alts_security_connector.h \ +src/core/lib/security/security_connector/fake/fake_security_connector.cc \ +src/core/lib/security/security_connector/fake/fake_security_connector.h \ src/core/lib/security/security_connector/load_system_roots.h \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ src/core/lib/security/security_connector/load_system_roots_linux.cc \ src/core/lib/security/security_connector/load_system_roots_linux.h \ -src/core/lib/security/security_connector/local_security_connector.cc \ -src/core/lib/security/security_connector/local_security_connector.h \ +src/core/lib/security/security_connector/local/local_security_connector.cc \ +src/core/lib/security/security_connector/local/local_security_connector.h \ src/core/lib/security/security_connector/security_connector.cc \ src/core/lib/security/security_connector/security_connector.h \ +src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ +src/core/lib/security/security_connector/ssl/ssl_security_connector.h \ +src/core/lib/security/security_connector/ssl_utils.cc \ +src/core/lib/security/security_connector/ssl_utils.h \ src/core/lib/security/transport/auth_filters.h \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ diff --git a/tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc b/tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc new file mode 100644 index 0000000000..a8e350be58 --- /dev/null +++ b/tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc @@ -0,0 +1,33 @@ +#!/bin/bash +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Source this rc script to prepare the environment for interop builds +# This rc script must be used in the root directory of gRPC + +export LANG=en_US.UTF-8 + +# Download Docker images from DockerHub +export DOCKERHUB_ORGANIZATION=grpctesting + +git submodule update --init + +# Set up gRPC-Go and gRPC-Java to test +git clone --recursive https://github.com/grpc/grpc-go ./../grpc-go +git clone --recursive https://github.com/grpc/grpc-java ./../grpc-java + +# TODO(apolcyn): move to kokoro image? +virtualenv env +source env/bin/activate +pip install twisted diff --git a/tools/internal_ci/linux/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/grpc_asan_on_foundry.sh index dfef004a60..24fbdf74c2 100755 --- a/tools/internal_ci/linux/grpc_asan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_asan_on_foundry.sh @@ -14,7 +14,5 @@ # limitations under the License. export UPLOAD_TEST_RESULTS=true -EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600 --cache_test_results=no" -EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=asan --cache_test_results=no diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index bb2a85138c..768e15b380 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -38,28 +38,8 @@ export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instan # TODO(adelez): implement size for test targets and change test_timeout back "${KOKORO_GFILE_DIR}/bazel_wrapper.py" \ - --host_jvm_args=-Dbazel.DigestFunction=SHA256 \ - test --jobs="200" \ - --test_output=errors \ - --verbose_failures=true \ - --keep_going \ - --remote_accept_cached=true \ - --spawn_strategy=remote \ - --remote_local_fallback=false \ - --remote_timeout=3600 \ - --strategy=Javac=remote \ - --strategy=Closure=remote \ - --genrule_strategy=remote \ - --experimental_strict_action_env=true \ - --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain \ - --define GRPC_PORT_ISOLATED_RUNTIME=1 \ - --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \ - --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default \ - --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ - --platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --test_env=GRPC_VERBOSITY=debug \ - --remote_instance_name=projects/grpc-testing/instances/default_instance \ + --bazelrc=tools/remote_build/kokoro.bazelrc \ + test \ $@ \ -- //test/... || FAILED="true" diff --git a/tools/internal_ci/linux/grpc_interop_matrix.cfg b/tools/internal_ci/linux/grpc_interop_matrix.cfg index 696a55c0df..e13c26e8ba 100644 --- a/tools/internal_ci/linux/grpc_interop_matrix.cfg +++ b/tools/internal_ci/linux/grpc_interop_matrix.cfg @@ -16,7 +16,6 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/linux/grpc_interop_matrix.sh" -# grpc_interop tests can take 1 hours to complete. timeout_mins: 300 action { define_artifacts { @@ -24,3 +23,8 @@ action { regex: "github/grpc/reports/**" } } + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "--language=all --release=all --allow_flakes --report_file=sponge_log.xml --bq_result_table interop_results" +} diff --git a/tools/internal_ci/linux/grpc_interop_matrix.sh b/tools/internal_ci/linux/grpc_interop_matrix.sh index 4c24c43488..a5220ea087 100755 --- a/tools/internal_ci/linux/grpc_interop_matrix.sh +++ b/tools/internal_ci/linux/grpc_interop_matrix.sh @@ -22,4 +22,4 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc -tools/interop_matrix/run_interop_matrix_tests.py --language=all --release=all --allow_flakes --report_file=sponge_log.xml --bq_result_table interop_results $@ +tools/interop_matrix/run_interop_matrix_tests.py $RUN_TESTS_FLAGS diff --git a/tools/internal_ci/linux/grpc_run_grpclb_interop_tests.sh b/tools/internal_ci/linux/grpc_run_grpclb_interop_tests.sh new file mode 100755 index 0000000000..806b5c947e --- /dev/null +++ b/tools/internal_ci/linux/grpc_run_grpclb_interop_tests.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -ex + +export LANG=en_US.UTF-8 + +# Enter the gRPC repo root +cd $(dirname $0)/../../.. + +source tools/internal_ci/helper_scripts/prepare_build_linux_rc +source tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc + +tools/run_tests/run_grpclb_interop_tests.py -l all --scenarios_file=tools/run_tests/generated/lb_interop_test_scenarios.json diff --git a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh index 366b5cbe34..7686794784 100644 --- a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh @@ -14,6 +14,4 @@ # limitations under the License. export UPLOAD_TEST_RESULTS=true -EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=thread --linkopt=-fsanitize=thread --test_timeout=3600 --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1 --cache_test_results=no" -EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=tsan --cache_test_results=no diff --git a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh index e0ae9103c4..4350cb1ba5 100644 --- a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh @@ -13,66 +13,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -ex - -# A temporary solution to give Kokoro credentials. -# The file name 4321_grpc-testing-service needs to match auth_credential in -# the build config. -# TODO: Use keystore. -mkdir -p ${KOKORO_KEYSTORE_DIR} -cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service - -temp_dir=$(mktemp -d) -ln -f "${KOKORO_GFILE_DIR}/bazel-latest-release" ${temp_dir}/bazel -chmod 755 "${KOKORO_GFILE_DIR}/bazel-latest-release" -export PATH="${temp_dir}:${PATH}" -# This should show ${temp_dir}/bazel -which bazel -chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py" - -# change to grpc repo root -cd $(dirname $0)/../../.. - -source tools/internal_ci/helper_scripts/prepare_build_linux_rc - -export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instance" - -"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \ - --host_jvm_args=-Dbazel.DigestFunction=SHA256 \ - test --jobs="200" \ - --test_timeout="3600,3600,3600,3600" \ - --test_output=errors \ - --verbose_failures=true \ - --keep_going \ - --remote_accept_cached=true \ - --spawn_strategy=remote \ - --remote_local_fallback=false \ - --remote_timeout=3600 \ - --strategy=Javac=remote \ - --strategy=Closure=remote \ - --genrule_strategy=remote \ - --experimental_strict_action_env=true \ - --define GRPC_PORT_ISOLATED_RUNTIME=1 \ - --copt=-gmlt \ - --strip=never \ - --copt=-fsanitize=undefined \ - --linkopt=-fsanitize=undefined \ - --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.15.0/ubsan:toolchain \ - --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \ - --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default \ - --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ - --platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --cache_test_results=no \ - --test_env=GRPC_VERBOSITY=debug \ - --remote_instance_name=projects/grpc-testing/instances/default_instance \ - -- //test/... || FAILED="true" - -# Sleep to let ResultStore finish writing results before querying -sleep 60 -python ./tools/run_tests/python_utils/upload_rbe_results.py - -if [ "$FAILED" != "" ] -then - exit 1 -fi +export UPLOAD_TEST_RESULTS=true +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=ubsan --cache_test_results=no diff --git a/tools/internal_ci/linux/grpclb_in_dns_interop.cfg b/tools/internal_ci/linux/grpclb_in_dns_interop.cfg new file mode 100644 index 0000000000..6cd5f2e21a --- /dev/null +++ b/tools/internal_ci/linux/grpclb_in_dns_interop.cfg @@ -0,0 +1,25 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# 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/grpc_run_grpclb_interop_tests.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/sponge_log.xml" + regex: "github/grpc/reports/**" + } +} diff --git a/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh index 39c991f291..84b65a3eb1 100644 --- a/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh @@ -13,7 +13,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600" -EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=asan diff --git a/tools/internal_ci/linux/pull_request/grpc_interop_matrix_adhoc.cfg b/tools/internal_ci/linux/pull_request/grpc_interop_matrix_adhoc.cfg new file mode 100644 index 0000000000..6726384f18 --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_interop_matrix_adhoc.cfg @@ -0,0 +1,30 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# 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/grpc_interop_matrix.sh" +timeout_mins: 300 +action { + define_artifacts { + regex: "**/sponge_log.xml" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "--language=all --release=all --allow_flakes --report_file=sponge_log.xml" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh index 3dee115300..4a9687f7e2 100644 --- a/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh @@ -13,6 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=thread --linkopt=-fsanitize=thread --test_timeout=3600 --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1" -EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=tsan diff --git a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh index 8547fa4d93..fb69d73635 100644 --- a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh @@ -13,61 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -ex - -# A temporary solution to give Kokoro credentials. -# The file name 4321_grpc-testing-service needs to match auth_credential in -# the build config. -# TODO: Use keystore. -mkdir -p ${KOKORO_KEYSTORE_DIR} -cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service - -temp_dir=$(mktemp -d) -ln -f "${KOKORO_GFILE_DIR}/bazel-latest-release" ${temp_dir}/bazel -chmod 755 "${KOKORO_GFILE_DIR}/bazel-latest-release" -export PATH="${temp_dir}:${PATH}" -# This should show ${temp_dir}/bazel -which bazel -chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py" - -# change to grpc repo root -cd $(dirname $0)/../../../.. - -source tools/internal_ci/helper_scripts/prepare_build_linux_rc - -export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instance" - -"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \ - --host_jvm_args=-Dbazel.DigestFunction=SHA256 \ - test --jobs="200" \ - --test_timeout="3600,3600,3600,3600" \ - --test_output=errors \ - --verbose_failures=true \ - --keep_going \ - --remote_accept_cached=true \ - --spawn_strategy=remote \ - --remote_local_fallback=false \ - --remote_timeout=3600 \ - --strategy=Javac=remote \ - --strategy=Closure=remote \ - --genrule_strategy=remote \ - --experimental_strict_action_env=true \ - --define GRPC_PORT_ISOLATED_RUNTIME=1 \ - --copt=-gmlt \ - --strip=never \ - --copt=-fsanitize=undefined \ - --linkopt=-fsanitize=undefined \ - --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.15.0/ubsan:toolchain \ - --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \ - --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default \ - --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ - --platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --test_env=GRPC_VERBOSITY=debug \ - --remote_instance_name=projects/grpc-testing/instances/default_instance \ - -- //test/... || FAILED="true" - -if [ "$FAILED" != "" ] -then - exit 1 -fi +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=ubsan diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 15b53d1716..c4935e8eee 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Dictionaries used for client matrix testing. +# Defines languages, runtimes and releases for backward compatibility testing def get_github_repo(lang): @@ -53,8 +53,7 @@ LANG_RUNTIME_MATRIX = { 'csharp': ['csharp', 'csharpcoreclr'], } -# Dictionary of releases per language. For each language, we need to provide -# a release tag pointing to the latest build of the branch. +# Dictionary of known releases for given language. LANG_RELEASE_MATRIX = { 'cxx': [ { @@ -102,6 +101,9 @@ LANG_RELEASE_MATRIX = { { 'v1.15.0': None }, + { + 'v1.16.0': None + }, ], 'go': [ { @@ -138,7 +140,19 @@ LANG_RELEASE_MATRIX = { 'v1.11.3': None }, { - 'v1.12.0': None + 'v1.12.2': None + }, + { + 'v1.13.0': None + }, + { + 'v1.14.0': None + }, + { + 'v1.15.0': None + }, + { + 'v1.16.0': None }, ], 'java': [ @@ -237,6 +251,9 @@ LANG_RELEASE_MATRIX = { { 'v1.15.0': None }, + { + 'v1.16.0': None + }, ], 'node': [ { @@ -328,6 +345,9 @@ LANG_RELEASE_MATRIX = { { 'v1.15.0': None }, + { + 'v1.16.0': None + }, ], 'php': [ { @@ -375,6 +395,9 @@ LANG_RELEASE_MATRIX = { { 'v1.15.0': None }, + { + 'v1.16.0': None + }, ], 'csharp': [ { @@ -427,6 +450,9 @@ LANG_RELEASE_MATRIX = { { 'v1.15.0': None }, + { + 'v1.16.0': None + }, ], } diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 6cd6f43167..6cf2a9b036 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -26,7 +26,7 @@ import subprocess import sys import uuid -# Langauage Runtime Matrix +# Language Runtime Matrix import client_matrix python_util_dir = os.path.abspath( @@ -37,6 +37,9 @@ import jobset import report_utils import upload_test_results +_TEST_TIMEOUT_SECONDS = 60 +_PULL_IMAGE_TIMEOUT_SECONDS = 15 * 60 +_MAX_PARALLEL_DOWNLOADS = 6 _LANGUAGES = client_matrix.LANG_RUNTIME_MATRIX.keys() # All gRPC release tags, flattened, deduped and sorted. _RELEASES = sorted( @@ -45,7 +48,6 @@ _RELEASES = sorted( client_matrix.get_release_tag_name(info) for lang in client_matrix.LANG_RELEASE_MATRIX.values() for info in lang))) -_TEST_TIMEOUT = 60 argp = argparse.ArgumentParser(description='Run interop tests.') argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int) @@ -56,7 +58,7 @@ argp.add_argument( argp.add_argument( '--release', default='all', - choices=['all', 'master'] + _RELEASES, + choices=['all'] + _RELEASES, help='Release tags to test. When testing all ' 'releases defined in client_matrix.py, use "all".') argp.add_argument( @@ -92,136 +94,154 @@ argp.add_argument( nargs='?', help='The gateway to backend services.') -args = argp.parse_args() - -print(str(args)) - -def find_all_images_for_lang(lang): +def _get_test_images_for_lang(lang, release_arg, image_path_prefix): """Find docker images for a language across releases and runtimes. Returns dictionary of list of (<tag>, <image-full-path>) keyed by runtime. """ - # Find all defined releases. - if args.release == 'all': - releases = ['master'] + client_matrix.get_release_tags(lang) + if release_arg == 'all': + # Use all defined releases for given language + releases = client_matrix.get_release_tags(lang) else: # Look for a particular release. - if args.release not in ['master' - ] + client_matrix.get_release_tags(lang): + if release_arg not in client_matrix.get_release_tags(lang): jobset.message( 'SKIPPED', - '%s for %s is not defined' % (args.release, lang), + 'release %s for %s is not defined' % (release_arg, lang), do_newline=True) return {} - releases = [args.release] + releases = [release_arg] - # TODO(jtattermusch): why do we need to query the existing images/tags? - # From LANG_RUNTIME_MATRIX and LANG_RELEASE_MATRIX it should be obvious - # which tags we want to test - and it should be an error if they are - # missing. # Images tuples keyed by runtime. images = {} for runtime in client_matrix.LANG_RUNTIME_MATRIX[lang]: - image_path = '%s/grpc_interop_%s' % (args.gcr_path, runtime) - output = subprocess.check_output([ - 'gcloud', 'beta', 'container', 'images', 'list-tags', - '--format=json', image_path - ]) - docker_image_list = json.loads(output) - # All images should have a single tag or no tag. - # TODO(adelez): Remove tagless images. - tags = [i['tags'][0] for i in docker_image_list if i['tags']] - jobset.message( - 'START', - 'Found images for %s: %s' % (image_path, tags), - do_newline=True) - skipped = len(docker_image_list) - len(tags) - jobset.message( - 'SKIPPED', - 'Skipped images (no-tag/unknown-tag): %d' % skipped, - do_newline=True) - # Filter tags based on the releases. - images[runtime] = [(tag, '%s:%s' % (image_path, tag)) - for tag in tags - if tag in releases] + image_path = '%s/grpc_interop_%s' % (image_path_prefix, runtime) + images[runtime] = [ + (tag, '%s:%s' % (image_path, tag)) for tag in releases + ] return images -# caches test cases (list of JobSpec) loaded from file. Keyed by lang and runtime. -def find_test_cases(lang, runtime, release, suite_name): - """Returns the list of test cases from testcase files per lang/release.""" +def _read_test_cases_file(lang, runtime, release): + """Read test cases from a bash-like file and return a list of commands""" testcase_dir = os.path.join(os.path.dirname(__file__), 'testcases') filename_prefix = lang if lang == 'csharp': + # TODO(jtattermusch): remove this odd specialcase filename_prefix = runtime # Check to see if we need to use a particular version of test cases. lang_version = '%s_%s' % (filename_prefix, release) if lang_version in client_matrix.TESTCASES_VERSION_MATRIX: - testcases = os.path.join( + testcase_file = os.path.join( testcase_dir, client_matrix.TESTCASES_VERSION_MATRIX[lang_version]) else: - testcases = os.path.join(testcase_dir, '%s__master' % filename_prefix) + # TODO(jtattermusch): remove the double-underscore, it is pointless + testcase_file = os.path.join(testcase_dir, + '%s__master' % filename_prefix) + + lines = [] + with open(testcase_file) as f: + for line in f.readlines(): + line = re.sub('\\#.*$', '', line) # remove hash comments + line = line.strip() + if line and not line.startswith('echo'): + # Each non-empty line is a treated as a test case command + lines.append(line) + return lines + + +def _cleanup_docker_image(image): + jobset.message('START', 'Cleanup docker image %s' % image, do_newline=True) + dockerjob.remove_image(image, skip_nonexistent=True) + + +args = argp.parse_args() + + +# caches test cases (list of JobSpec) loaded from file. Keyed by lang and runtime. +def _generate_test_case_jobspecs(lang, runtime, release, suite_name): + """Returns the list of test cases from testcase files per lang/release.""" + testcase_lines = _read_test_cases_file(lang, runtime, release) job_spec_list = [] - try: - with open(testcases) as f: - # Only line start with 'docker run' are test cases. - for line in f.readlines(): - if line.startswith('docker run'): - m = re.search('--test_case=(.*)"', line) - shortname = m.group(1) if m else 'unknown_test' - m = re.search( - '--server_host_override=(.*).sandbox.googleapis.com', - line) - server = m.group(1) if m else 'unknown_server' - - # If server_host arg is not None, replace the original - # server_host with the one provided or append to the end of - # the command if server_host does not appear originally. - if args.server_host: - if line.find('--server_host=') > -1: - line = re.sub('--server_host=[^ ]*', - '--server_host=%s' % args.server_host, - line) - else: - line = '%s --server_host=%s"' % (line[:-1], - args.server_host) - print(line) - - spec = jobset.JobSpec( - cmdline=line, - shortname='%s:%s:%s:%s' % (suite_name, lang, server, - shortname), - timeout_seconds=_TEST_TIMEOUT, - shell=True, - flake_retries=5 if args.allow_flakes else 0) - job_spec_list.append(spec) - jobset.message( - 'START', - 'Loaded %s tests from %s' % (len(job_spec_list), testcases), - do_newline=True) - except IOError as err: - jobset.message('FAILED', err, do_newline=True) + for line in testcase_lines: + # TODO(jtattermusch): revisit the logic for updating test case commands + # what it currently being done seems fragile. + m = re.search('--test_case=(.*)"', line) + shortname = m.group(1) if m else 'unknown_test' + m = re.search('--server_host_override=(.*).sandbox.googleapis.com', + line) + server = m.group(1) if m else 'unknown_server' + + # If server_host arg is not None, replace the original + # server_host with the one provided or append to the end of + # the command if server_host does not appear originally. + if args.server_host: + if line.find('--server_host=') > -1: + line = re.sub('--server_host=[^ ]*', + '--server_host=%s' % args.server_host, line) + else: + line = '%s --server_host=%s"' % (line[:-1], args.server_host) + + spec = jobset.JobSpec( + cmdline=line, + shortname='%s:%s:%s:%s' % (suite_name, lang, server, shortname), + timeout_seconds=_TEST_TIMEOUT_SECONDS, + shell=True, + flake_retries=5 if args.allow_flakes else 0) + job_spec_list.append(spec) return job_spec_list -_xml_report_tree = report_utils.new_junit_xml_tree() +def _pull_images_for_lang(lang, images): + """Pull all images for given lang from container registry.""" + jobset.message( + 'START', 'Downloading images for language "%s"' % lang, do_newline=True) + download_specs = [] + for release, image in images: + # Pull the image and warm it up. + # First time we use an image with "docker run", it takes time to unpack + # the image and later this delay would fail our test cases. + cmdline = [ + 'time gcloud docker -- pull %s && time docker run --rm=true %s /bin/true' + % (image, image) + ] + spec = jobset.JobSpec( + cmdline=cmdline, + shortname='pull_image_%s' % (image), + timeout_seconds=_PULL_IMAGE_TIMEOUT_SECONDS, + shell=True) + download_specs.append(spec) + # too many image downloads at once tend to get stuck + max_pull_jobs = min(args.jobs, _MAX_PARALLEL_DOWNLOADS) + num_failures, resultset = jobset.run( + download_specs, newline_on_success=True, maxjobs=max_pull_jobs) + if num_failures: + jobset.message( + 'FAILED', 'Failed to download some images', do_newline=True) + return False + else: + jobset.message( + 'SUCCESS', 'All images downloaded successfully.', do_newline=True) + return True -def run_tests_for_lang(lang, runtime, images): +def _run_tests_for_lang(lang, runtime, images, xml_report_tree): """Find and run all test cases for a language. images is a list of (<release-tag>, <image-full-path>) tuple. """ + if not _pull_images_for_lang(lang, images): + jobset.message( + 'FAILED', 'Image download failed. Exiting.', do_newline=True) + return 1 + total_num_failures = 0 - for image_tuple in images: - release, image = image_tuple - jobset.message('START', 'Testing %s' % image, do_newline=True) - # Download the docker image before running each test case. - subprocess.check_call(['gcloud', 'docker', '--', 'pull', image]) + for release, image in images: suite_name = '%s__%s_%s' % (lang, runtime, release) - job_spec_list = find_test_cases(lang, runtime, release, suite_name) + job_spec_list = _generate_test_case_jobspecs(lang, runtime, release, + suite_name) if not job_spec_list: jobset.message( @@ -242,28 +262,24 @@ def run_tests_for_lang(lang, runtime, images): else: jobset.message('SUCCESS', 'All tests passed', do_newline=True) - report_utils.append_junit_xml_results(_xml_report_tree, resultset, + report_utils.append_junit_xml_results(xml_report_tree, resultset, 'grpc_interop_matrix', suite_name, str(uuid.uuid4())) if not args.keep: - cleanup(image) + _cleanup_docker_image(image) return total_num_failures -def cleanup(image): - jobset.message('START', 'Cleanup docker image %s' % image, do_newline=True) - dockerjob.remove_image(image, skip_nonexistent=True) - - languages = args.language if args.language != ['all'] else _LANGUAGES total_num_failures = 0 +_xml_report_tree = report_utils.new_junit_xml_tree() for lang in languages: - docker_images = find_all_images_for_lang(lang) + docker_images = _get_test_images_for_lang(lang, args.release, args.gcr_path) for runtime in sorted(docker_images.keys()): - total_num_failures += run_tests_for_lang(lang, runtime, - docker_images[runtime]) + total_num_failures += _run_tests_for_lang( + lang, runtime, docker_images[runtime], _xml_report_tree) report_utils.create_xml_report_file(_xml_report_tree, args.report_file) diff --git a/tools/remote_build/README.md b/tools/remote_build/README.md new file mode 100644 index 0000000000..7492de75a5 --- /dev/null +++ b/tools/remote_build/README.md @@ -0,0 +1,30 @@ +# Running Remote Builds with bazel + +This allows you to spawn gRPC C/C++ remote build and tests from your workstation with +configuration that's very similar to what's used by our CI Kokoro. + +Note that this will only work for gRPC team members (it requires access to the +remote build and execution cluster), others will need to rely on local test runs +and tests run by Kokoro CI. + + +## Prerequisites + +- See [Installing Bazel](https://docs.bazel.build/versions/master/install.html) for instructions how to install bazel on your system. + +- Setup application default credentials for running remote builds by following [RBE Credentials Setup](https://cloud.google.com/remote-build-execution/docs/getting-started#set_credentials) + + +## Running remote build manually from dev workstation + +Run from repository root: +``` +# manual run of bazel tests remotely on Foundry +bazel --bazelrc=tools/remote_build/manual.bazelrc test -c opt //test/... +``` + +Sanitizer runs (asan, msan, tsan, ubsan): +``` +# manual run of bazel tests remotely on Foundry with given sanitizer +bazel --bazelrc=tools/remote_build/manual.bazelrc test --config=asan //test/... +``` diff --git a/tools/remote_build/kokoro.bazelrc b/tools/remote_build/kokoro.bazelrc new file mode 100644 index 0000000000..0aacddf663 --- /dev/null +++ b/tools/remote_build/kokoro.bazelrc @@ -0,0 +1,23 @@ +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# bazelrc file for running gRPC tests on Kokoro using Foundry + +import %workspace%/tools/remote_build/rbe_common.bazelrc + +build --jobs=200 +build --test_output=errors +build --keep_going +build --remote_accept_cached=true +build --remote_local_fallback=true diff --git a/tools/remote_build/manual.bazelrc b/tools/remote_build/manual.bazelrc new file mode 100644 index 0000000000..d67bafedf3 --- /dev/null +++ b/tools/remote_build/manual.bazelrc @@ -0,0 +1,42 @@ +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# bazelrc file for running gRPC tests with Foundry (remote build execution) +# manually from developer's workstation + +import %workspace%/tools/remote_build/rbe_common.bazelrc + +build --remote_cache=remotebuildexecution.googleapis.com +build --remote_executor=remotebuildexecution.googleapis.com +build --tls_enabled=true + +# Enable authentication. This will pick up application default credentials by +# default. You can use --auth_credentials=some_file.json to use a service +# account credential instead. +# How to setup credentials: +# See https://cloud.google.com/remote-build-execution/docs/getting-started#set_credentials +build --auth_enabled=true + +# Set flags for uploading to BES in order to view results in the Bazel Build +# Results UI. +build --bes_backend="buildeventservice.googleapis.com" +build --bes_timeout=60s +build --bes_results_url="https://source.cloud.google.com/results/invocations/" +build --project_id=grpc-testing + +build --jobs=100 + +# TODO(jtattermusch): this should be part of the common config +# but currently sanitizers use different test_timeout values +build --test_timeout=300,450,1200,3600 diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc new file mode 100644 index 0000000000..cdf492a2cc --- /dev/null +++ b/tools/remote_build/rbe_common.bazelrc @@ -0,0 +1,88 @@ +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# bazelrc with Foundry setting common to both manual run and runs started by Kokoro +# see https://github.com/bazelbuild/bazel-toolchains/tree/master/bazelrc +# for examples and more documentation + +startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 + +build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain +build --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default +# Use custom execution platforms defined in third_party/toolchains +build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 +build --host_platform=//third_party/toolchains:rbe_ubuntu1604 +build --platforms=//third_party/toolchains:rbe_ubuntu1604 + +build --spawn_strategy=remote +build --strategy=Javac=remote +build --strategy=Closure=remote +build --genrule_strategy=remote +build --remote_timeout=3600 + +build --remote_instance_name=projects/grpc-testing/instances/default_instance + +build --verbose_failures=true + +build --experimental_strict_action_env=true +build --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 + +# don't use port server +build --define GRPC_PORT_ISOLATED_RUNTIME=1 +# without verbose gRPC logs the test outputs are not very useful +test --test_env=GRPC_VERBOSITY=debug + +# address sanitizer: most settings are already in %workspace%/.bazelrc +# we only need a few additional ones that are Foundry specific +build:asan --copt=-gmlt +# TODO(jtattermusch): use more reasonable test timeout +build:asan --test_timeout=3600 +build:asan --test_tag_filters=-qps_json_driver,-json_run_localhost +# TODO: revisit these from bazel.rc: +#build:asan --copt=-O0 +#build:asan --copt=-fno-omit-frame-pointer +#build:asan --copt=-DGPR_NO_DIRECT_SYSCALLS +#build:asan --action_env=ASAN_OPTIONS=detect_leaks=1:color=always +#build:asan --action_env=LSAN_OPTIONS=suppressions=test/core/util/lsan_suppressions.txt:report_objects=1 + +# TODO(jtattermusch): align msan settings from tools/bazel.rc +# and grpc_msan_on_foundry.sh + +# thread sanitizer: most settings are already in %workspace%/.bazelrc +# we only need a few additional ones that are Foundry specific +build:tsan --copt=-gmlt +# TODO(jtattermusch): use more reasonable test timeout +build:tsan --test_timeout=3600 +build:tsan --test_tag_filters=-qps_json_driver,-json_run_localhost +# TODO: revisit these from bazel.rc: +#build:tsan --copt=-fno-omit-frame-pointer +#build:tsan --copt=-DGPR_NO_DIRECT_SYSCALLS +#build:tsan --copt=-DGRPC_TSAN + +# undefined behavior sanitizer: most settings are already in %workspace%/.bazelrc +# we only need a few additional ones that are Foundry specific +build:ubsan --copt=-gmlt +# TODO(jtattermusch): use more reasonable test timeout +build:ubsan --test_timeout=3600 +# TODO: revisit these from bazel.rc: +#build:ubsan --copt=-fno-omit-frame-pointer +#build:ubsan --copt=-DGRPC_UBSAN +#build:ubsan --copt=-DNDEBUG +#build:ubsan --copt=-fno-sanitize=function,vptr +# TODO: revisit this from grpc_ubsan_on_foundry.sh: +#--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.15.0/ubsan:toolchain +# TODO(jtattermusch): remove this once Foundry adds the env to the docker image. +# ubsan needs symbolizer to work properly, otherwise the suppression file doesn't work +# and we get test failures. +build:ubsan --action_env=UBSAN_SYMBOLIZER_PATH=/usr/local/bin/llvm-symbolizer diff --git a/tools/run_tests/generated/lb_interop_test_scenarios.json b/tools/run_tests/generated/lb_interop_test_scenarios.json new file mode 100644 index 0000000000..4f956c568a --- /dev/null +++ b/tools/run_tests/generated/lb_interop_test_scenarios.json @@ -0,0 +1,1167 @@ + +[ + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "no_balancer_because_lb_a_record_returns_nx_domain_insecure", + "skip_langs": [], + "transport_sec": "insecure" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "alts" + } + ], + "name": "no_balancer_because_lb_a_record_returns_nx_domain_alts", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "no_balancer_because_lb_a_record_returns_nx_domain_tls", + "skip_langs": [], + "transport_sec": "tls" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "no_balancer_because_lb_a_record_returns_nx_domain_google_default_credentials", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": true, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "no_balancer_because_lb_a_record_returns_no_data_insecure", + "skip_langs": [], + "transport_sec": "insecure" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": true, + "fallback_configs": [ + { + "transport_sec": "alts" + } + ], + "name": "no_balancer_because_lb_a_record_returns_no_data_alts", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": true, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "no_balancer_because_lb_a_record_returns_no_data_tls", + "skip_langs": [], + "transport_sec": "tls" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": true, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "no_balancer_because_lb_a_record_returns_no_data_google_default_credentials", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_insecure_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_alts_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_tls_short_stream_True", + "skip_langs": [ + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_google_default_credentials_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_insecure_short_stream_False", + "skip_langs": [], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_alts_short_stream_False", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_tls_short_stream_False", + "skip_langs": [ + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_google_default_credentials_short_stream_False", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_alts_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_tls_short_stream_True", + "skip_langs": [ + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_google_default_credentials_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_alts_short_stream_False", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_tls_short_stream_False", + "skip_langs": [ + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_google_default_credentials_short_stream_False", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_insecure_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_alts_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_tls_short_stream_True", + "skip_langs": [ + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_google_default_credentials_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_insecure_short_stream_False", + "skip_langs": [], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_alts_short_stream_False", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_tls_short_stream_False", + "skip_langs": [ + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_google_default_credentials_short_stream_False", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_falls_back_because_no_backends_insecure_short_stream_True", + "skip_langs": [ + "go", + "java", + "java" + ], + "transport_sec": "insecure" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "alts" + } + ], + "name": "client_falls_back_because_no_backends_alts_short_stream_True", + "skip_langs": [ + "go", + "java", + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_no_backends_tls_short_stream_True", + "skip_langs": [ + "go", + "java", + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_no_backends_google_default_credentials_short_stream_True", + "skip_langs": [ + "go", + "java", + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_falls_back_because_no_backends_insecure_short_stream_False", + "skip_langs": [ + "go", + "java" + ], + "transport_sec": "insecure" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "alts" + } + ], + "name": "client_falls_back_because_no_backends_alts_short_stream_False", + "skip_langs": [ + "go", + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_no_backends_tls_short_stream_False", + "skip_langs": [ + "go", + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_no_backends_google_default_credentials_short_stream_False", + "skip_langs": [ + "go", + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "alts" + } + ], + "name": "client_falls_back_because_balancer_connection_broken_alts", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_balancer_connection_broken_tls", + "skip_langs": [ + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_balancer_connection_broken_google_default_credentials", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "insecure" + }, + { + "short_stream": true, + "transport_sec": "insecure" + }, + { + "short_stream": true, + "transport_sec": "insecure" + }, + { + "short_stream": true, + "transport_sec": "insecure" + }, + { + "short_stream": true, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_insecure_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_alts_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "tls" + }, + { + "short_stream": true, + "transport_sec": "tls" + }, + { + "short_stream": true, + "transport_sec": "tls" + }, + { + "short_stream": true, + "transport_sec": "tls" + }, + { + "short_stream": true, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_tls_short_stream_True", + "skip_langs": [ + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_google_default_credentials_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + }, + { + "short_stream": false, + "transport_sec": "insecure" + }, + { + "short_stream": false, + "transport_sec": "insecure" + }, + { + "short_stream": false, + "transport_sec": "insecure" + }, + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_insecure_short_stream_False", + "skip_langs": [], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_alts_short_stream_False", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "tls" + }, + { + "short_stream": false, + "transport_sec": "tls" + }, + { + "short_stream": false, + "transport_sec": "tls" + }, + { + "short_stream": false, + "transport_sec": "tls" + }, + { + "short_stream": false, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_tls_short_stream_False", + "skip_langs": [ + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_google_default_credentials_short_stream_False", + "skip_langs": [], + "transport_sec": "google_default_credentials" + } +] diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a2240d28ce..ab5a9db8ef 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -6579,24 +6579,6 @@ }, { "deps": [ - "end2end_nosec_tests", - "gpr", - "gpr_test_util", - "grpc_test_util_unsecure", - "grpc_unsecure" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "inproc_nosec_test", - "src": [ - "test/core/end2end/fixtures/inproc.cc" - ], - "third_party": false, - "type": "target" - }, - { - "deps": [ "gpr", "gpr_test_util", "grpc++_test_config", @@ -10006,7 +9988,8 @@ "deps": [ "gpr", "grpc_base", - "grpc_deadline_filter" + "grpc_deadline_filter", + "health_proto" ], "headers": [ "src/core/ext/filters/client_channel/backup_poller.h", @@ -10014,6 +9997,7 @@ "src/core/ext/filters/client_channel/client_channel_channelz.h", "src/core/ext/filters/client_channel/client_channel_factory.h", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", @@ -10047,6 +10031,8 @@ "src/core/ext/filters/client_channel/client_channel_plugin.cc", "src/core/ext/filters/client_channel/connector.cc", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/health/health_check_client.cc", + "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.cc", @@ -10481,11 +10467,14 @@ "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/security_connector/alts_security_connector.h", + "src/core/lib/security/security_connector/alts/alts_security_connector.h", + "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", "src/core/lib/security/security_connector/load_system_roots_linux.h", - "src/core/lib/security/security_connector/local_security_connector.h", + "src/core/lib/security/security_connector/local/local_security_connector.h", "src/core/lib/security/security_connector/security_connector.h", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", + "src/core/lib/security/security_connector/ssl_utils.h", "src/core/lib/security/transport/auth_filters.h", "src/core/lib/security/transport/secure_endpoint.h", "src/core/lib/security/transport/security_handshaker.h", @@ -10531,16 +10520,22 @@ "src/core/lib/security/credentials/plugin/plugin_credentials.h", "src/core/lib/security/credentials/ssl/ssl_credentials.cc", "src/core/lib/security/credentials/ssl/ssl_credentials.h", - "src/core/lib/security/security_connector/alts_security_connector.cc", - "src/core/lib/security/security_connector/alts_security_connector.h", + "src/core/lib/security/security_connector/alts/alts_security_connector.cc", + "src/core/lib/security/security_connector/alts/alts_security_connector.h", + "src/core/lib/security/security_connector/fake/fake_security_connector.cc", + "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", "src/core/lib/security/security_connector/load_system_roots_fallback.cc", "src/core/lib/security/security_connector/load_system_roots_linux.cc", "src/core/lib/security/security_connector/load_system_roots_linux.h", - "src/core/lib/security/security_connector/local_security_connector.cc", - "src/core/lib/security/security_connector/local_security_connector.h", + "src/core/lib/security/security_connector/local/local_security_connector.cc", + "src/core/lib/security/security_connector/local/local_security_connector.h", "src/core/lib/security/security_connector/security_connector.cc", "src/core/lib/security/security_connector/security_connector.h", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.cc", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", + "src/core/lib/security/security_connector/ssl_utils.cc", + "src/core/lib/security/security_connector/ssl_utils.h", "src/core/lib/security/transport/auth_filters.h", "src/core/lib/security/transport/client_auth_filter.cc", "src/core/lib/security/transport/secure_endpoint.cc", @@ -11019,6 +11014,23 @@ }, { "deps": [ + "nanopb" + ], + "headers": [ + "src/core/ext/filters/client_channel/health/health.pb.h" + ], + "is_filegroup": true, + "language": "c", + "name": "health_proto", + "src": [ + "src/core/ext/filters/client_channel/health/health.pb.c", + "src/core/ext/filters/client_channel/health/health.pb.h" + ], + "third_party": false, + "type": "filegroup" + }, + { + "deps": [ "nanopb_headers" ], "headers": [], @@ -11318,6 +11330,7 @@ "grpc++_codegen_base", "grpc_base_headers", "grpc_transport_inproc_headers", + "health_proto", "nanopb_headers" ], "headers": [ @@ -11418,7 +11431,6 @@ "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/health/default_health_check_service.h", - "src/cpp/server/health/health.pb.h", "src/cpp/server/thread_pool_interface.h", "src/cpp/thread_manager/thread_manager.h" ], @@ -11543,8 +11555,6 @@ "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/health/default_health_check_service.cc", "src/cpp/server/health/default_health_check_service.h", - "src/cpp/server/health/health.pb.c", - "src/cpp/server/health/health.pb.h", "src/cpp/server/health/health_check_service.cc", "src/cpp/server/health/health_check_service_server_builder_option.cc", "src/cpp/server/server_builder.cc", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 4099204694..1052666634 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -56290,949 +56290,6 @@ }, { "args": [ - "authority_not_supported" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "binary_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_accept" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_client_done" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_invoke" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_round_trip" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_before_invoke" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_in_a_vacuum" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_with_status" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "channelz" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "empty_batch" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "filter_call_init_fails" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "filter_causes_close" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "filter_latency" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "filter_status_code" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "high_initial_seqno" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "hpack_size" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "idempotent_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "invoke_large_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "large_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "max_message_length" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "negative_deadline" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "no_error_on_hotpath" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "no_logging" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "no_op" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "ping_pong_streaming" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "registered_call" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "request_with_flags" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "request_with_payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "resource_quota_server" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "server_finishes_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "shutdown_finishes_calls" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "shutdown_finishes_tags" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "simple_cacheable_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "simple_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "simple_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "streaming_error_response" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "trailing_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "workaround_cronet_compression" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ "--scenarios_json", "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_1channel_100rpcs_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], diff --git a/tools/run_tests/lb_interop_tests/gen_build_yaml.py b/tools/run_tests/lb_interop_tests/gen_build_yaml.py new file mode 100755 index 0000000000..b7d655b75b --- /dev/null +++ b/tools/run_tests/lb_interop_tests/gen_build_yaml.py @@ -0,0 +1,347 @@ +#!/usr/bin/env python2.7 +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Generates the appropriate JSON data for LB interop test scenarios.""" + +import json +import os +import yaml + +all_scenarios = [] + +# TODO(https://github.com/grpc/grpc-go/issues/2347): enable +# client_falls_back_because_no_backends_* scenarios for Java/Go. + +# TODO(https://github.com/grpc/grpc-java/issues/4887): enable +# *short_stream* scenarios for Java. + +# TODO(https://github.com/grpc/grpc-java/issues/4912): enable +# Java TLS tests involving TLS to the balancer. + + +def server_sec(transport_sec): + if transport_sec == 'google_default_credentials': + return 'alts', 'alts', 'tls' + return transport_sec, transport_sec, transport_sec + + +def generate_no_balancer_because_lb_a_record_returns_nx_domain(): + all_configs = [] + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + config = { + 'name': + 'no_balancer_because_lb_a_record_returns_nx_domain_%s' % + transport_sec, + 'skip_langs': [], + 'transport_sec': + transport_sec, + 'balancer_configs': [], + 'backend_configs': [], + 'fallback_configs': [{ + 'transport_sec': fallback_sec, + }], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_no_balancer_because_lb_a_record_returns_nx_domain() + + +def generate_no_balancer_because_lb_a_record_returns_no_data(): + all_configs = [] + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + config = { + 'name': + 'no_balancer_because_lb_a_record_returns_no_data_%s' % + transport_sec, + 'skip_langs': [], + 'transport_sec': + transport_sec, + 'balancer_configs': [], + 'backend_configs': [], + 'fallback_configs': [{ + 'transport_sec': fallback_sec, + }], + 'cause_no_error_no_data_for_balancer_a_record': + True, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_no_balancer_because_lb_a_record_returns_no_data() + + +def generate_client_referred_to_backend(): + all_configs = [] + for balancer_short_stream in [True, False]: + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = [] + if transport_sec == 'tls': + skip_langs += ['java'] + if balancer_short_stream: + skip_langs += ['java'] + config = { + 'name': + 'client_referred_to_backend_%s_short_stream_%s' % + (transport_sec, balancer_short_stream), + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [{ + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }], + 'backend_configs': [{ + 'transport_sec': backend_sec, + }], + 'fallback_configs': [], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_referred_to_backend() + + +def generate_client_referred_to_backend_fallback_broken(): + all_configs = [] + for balancer_short_stream in [True, False]: + for transport_sec in ['alts', 'tls', 'google_default_credentials']: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = [] + if transport_sec == 'tls': + skip_langs += ['java'] + if balancer_short_stream: + skip_langs += ['java'] + config = { + 'name': + 'client_referred_to_backend_fallback_broken_%s_short_stream_%s' + % (transport_sec, balancer_short_stream), + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [{ + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }], + 'backend_configs': [{ + 'transport_sec': backend_sec, + }], + 'fallback_configs': [{ + 'transport_sec': 'insecure', + }], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_referred_to_backend_fallback_broken() + + +def generate_client_referred_to_backend_multiple_backends(): + all_configs = [] + for balancer_short_stream in [True, False]: + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = [] + if transport_sec == 'tls': + skip_langs += ['java'] + if balancer_short_stream: + skip_langs += ['java'] + config = { + 'name': + 'client_referred_to_backend_multiple_backends_%s_short_stream_%s' + % (transport_sec, balancer_short_stream), + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [{ + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }], + 'backend_configs': [{ + 'transport_sec': backend_sec, + }, { + 'transport_sec': backend_sec, + }, { + 'transport_sec': backend_sec, + }, { + 'transport_sec': backend_sec, + }, { + 'transport_sec': backend_sec, + }], + 'fallback_configs': [], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_referred_to_backend_multiple_backends() + + +def generate_client_falls_back_because_no_backends(): + all_configs = [] + for balancer_short_stream in [True, False]: + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = ['go', 'java'] + if transport_sec == 'tls': + skip_langs += ['java'] + if balancer_short_stream: + skip_langs += ['java'] + config = { + 'name': + 'client_falls_back_because_no_backends_%s_short_stream_%s' % + (transport_sec, balancer_short_stream), + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [{ + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }], + 'backend_configs': [], + 'fallback_configs': [{ + 'transport_sec': fallback_sec, + }], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_falls_back_because_no_backends() + + +def generate_client_falls_back_because_balancer_connection_broken(): + all_configs = [] + for transport_sec in ['alts', 'tls', 'google_default_credentials']: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = [] + if transport_sec == 'tls': + skip_langs = ['java'] + config = { + 'name': + 'client_falls_back_because_balancer_connection_broken_%s' % + transport_sec, + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [{ + 'transport_sec': 'insecure', + 'short_stream': False, + }], + 'backend_configs': [], + 'fallback_configs': [{ + 'transport_sec': fallback_sec, + }], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_falls_back_because_balancer_connection_broken() + + +def generate_client_referred_to_backend_multiple_balancers(): + all_configs = [] + for balancer_short_stream in [True, False]: + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = [] + if transport_sec == 'tls': + skip_langs += ['java'] + if balancer_short_stream: + skip_langs += ['java'] + config = { + 'name': + 'client_referred_to_backend_multiple_balancers_%s_short_stream_%s' + % (transport_sec, balancer_short_stream), + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [ + { + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }, + { + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }, + { + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }, + { + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }, + { + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }, + ], + 'backend_configs': [ + { + 'transport_sec': backend_sec, + }, + ], + 'fallback_configs': [], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_referred_to_backend_multiple_balancers() + +print(yaml.dump({ + 'lb_interop_test_scenarios': all_scenarios, +})) diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh index 9e6e72d97b..ab6bffdc34 100755 --- a/tools/run_tests/performance/build_performance.sh +++ b/tools/run_tests/performance/build_performance.sh @@ -25,10 +25,16 @@ CONFIG=${CONFIG:-opt} # TODO(jtattermusch): C++ worker and driver are not buildable on Windows yet if [ "$OSTYPE" != "msys" ] then - # TODO(jtattermusch): not embedding OpenSSL breaks the C# build because - # grpc_csharp_ext needs OpenSSL embedded and some intermediate files from - # this build will be reused. - make CONFIG="${CONFIG}" EMBED_OPENSSL=true EMBED_ZLIB=true qps_worker qps_json_driver -j8 + # build C++ with cmake as building with "make" disables boringssl assembly + # optimizations that can have huge impact on secure channel throughput. + mkdir -p cmake/build + cd cmake/build + cmake -DgRPC_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release ../.. + make qps_worker qps_json_driver -j8 + cd ../.. + # unbreak subsequent make builds by restoring zconf.h (previously renamed by cmake build) + # See https://github.com/grpc/grpc/issues/11581 + (cd third_party/zlib; git checkout zconf.h) fi PHP_ALREADY_BUILT="" diff --git a/tools/run_tests/performance/run_qps_driver.sh b/tools/run_tests/performance/run_qps_driver.sh index 2d9e310dec..47a03db026 100755 --- a/tools/run_tests/performance/run_qps_driver.sh +++ b/tools/run_tests/performance/run_qps_driver.sh @@ -17,7 +17,7 @@ set -ex cd "$(dirname "$0")/../../.." -bins/opt/qps_json_driver "$@" +cmake/build/qps_json_driver "$@" if [ "$BQ_RESULT_TABLE" != "" ] then diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index 2e78bd07fb..481918c52e 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -231,7 +231,7 @@ class CXXLanguage: self.safename = 'cxx' def worker_cmdline(self): - return ['bins/opt/qps_worker'] + return ['cmake/build/qps_worker'] def worker_port_offset(self): return 0 @@ -250,7 +250,7 @@ class CXXLanguage: channels=1, num_clients=1, secure=False, - categories=[SMOKETEST] + [INPROC] + [SCALABLE]) + categories=[INPROC] + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_streaming_from_client_1channel_1MB', @@ -280,12 +280,12 @@ class CXXLanguage: secure=False, async_server_threads=16, server_threads_per_cq=1, - categories=[SMOKETEST] + [SCALABLE]) + categories=[SCALABLE]) for secure in [True, False]: secstr = 'secure' if secure else 'insecure' - smoketest_categories = ([SMOKETEST] - if secure else [INPROC]) + [SCALABLE] + smoketest_categories = ([SMOKETEST] if secure else []) + inproc_categories = ([INPROC] if not secure else []) yield _ping_pong_scenario( 'cpp_generic_async_streaming_ping_pong_%s' % secstr, @@ -295,7 +295,8 @@ class CXXLanguage: use_generic_payload=True, async_server_threads=1, secure=secure, - categories=smoketest_categories) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) yield _ping_pong_scenario( 'cpp_generic_async_streaming_qps_unconstrained_%s' % secstr, @@ -306,7 +307,8 @@ class CXXLanguage: use_generic_payload=True, secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) for mps in geometric_progression(1, 20, 10): yield _ping_pong_scenario( @@ -320,7 +322,8 @@ class CXXLanguage: secure=secure, messages_per_stream=mps, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) for mps in geometric_progression(1, 200, math.sqrt(10)): yield _ping_pong_scenario( @@ -347,7 +350,7 @@ class CXXLanguage: use_generic_payload=True, secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE], + categories=inproc_categories + [SCALABLE], channels=1, outstanding=100) @@ -363,7 +366,7 @@ class CXXLanguage: use_generic_payload=True, secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_generic_async_streaming_qps_unconstrained_1cq_%s' % secstr, @@ -375,7 +378,8 @@ class CXXLanguage: secure=secure, client_threads_per_cq=1000000, server_threads_per_cq=1000000, - categories=smoketest_categories + [SCALABLE]) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) yield _ping_pong_scenario( 'cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_%s' @@ -388,7 +392,7 @@ class CXXLanguage: secure=secure, client_threads_per_cq=2, server_threads_per_cq=2, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_streaming_qps_unconstrained_1cq_%s' % @@ -400,7 +404,7 @@ class CXXLanguage: secure=secure, client_threads_per_cq=1000000, server_threads_per_cq=1000000, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_%s' @@ -412,7 +416,7 @@ class CXXLanguage: secure=secure, client_threads_per_cq=2, server_threads_per_cq=2, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_unary_qps_unconstrained_1cq_%s' % secstr, @@ -423,7 +427,8 @@ class CXXLanguage: secure=secure, client_threads_per_cq=1000000, server_threads_per_cq=1000000, - categories=smoketest_categories + [SCALABLE]) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_%s' % @@ -435,7 +440,7 @@ class CXXLanguage: secure=secure, client_threads_per_cq=2, server_threads_per_cq=2, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_generic_async_streaming_qps_one_server_core_%s' % secstr, @@ -457,7 +462,8 @@ class CXXLanguage: unconstrained_client='async', secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE], + categories=smoketest_categories + inproc_categories + + [SCALABLE], excluded_poll_engines=['poll-cv']) yield _ping_pong_scenario( @@ -472,7 +478,7 @@ class CXXLanguage: resp_size=8 * 1024 * 1024, secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_%s' @@ -483,7 +489,8 @@ class CXXLanguage: unconstrained_client='async', secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE], + categories=smoketest_categories + inproc_categories + + [SCALABLE], excluded_poll_engines=['poll-cv']) yield _ping_pong_scenario( @@ -495,7 +502,8 @@ class CXXLanguage: resp_size=1024 * 1024, secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) for rpc_type in [ 'unary', 'streaming', 'streaming_from_client', @@ -538,7 +546,7 @@ class CXXLanguage: minimal_stack=not secure, server_threads_per_cq=3, client_threads_per_cq=3, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) # TODO(vjpai): Re-enable this test. It has a lot of timeouts # and hasn't yet been conclusively identified as a test failure @@ -565,7 +573,7 @@ class CXXLanguage: secure=secure, messages_per_stream=mps, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) for mps in geometric_progression(1, 200, math.sqrt(10)): yield _ping_pong_scenario( diff --git a/tools/run_tests/python_utils/dockerjob.py b/tools/run_tests/python_utils/dockerjob.py index 2d22dc13a0..5260f7b44b 100755 --- a/tools/run_tests/python_utils/dockerjob.py +++ b/tools/run_tests/python_utils/dockerjob.py @@ -20,6 +20,7 @@ import time import uuid import os import subprocess +import json import jobset @@ -54,6 +55,25 @@ def docker_mapped_port(cid, port, timeout_seconds=15): cid)) +def docker_ip_address(cid, timeout_seconds=15): + """Get port mapped to internal given internal port for given container.""" + started = time.time() + while time.time() - started < timeout_seconds: + cmd = 'docker inspect %s' % cid + try: + output = subprocess.check_output(cmd, stderr=_DEVNULL, shell=True) + json_info = json.loads(output) + assert len(json_info) == 1 + out = json_info[0]['NetworkSettings']['IPAddress'] + if not out: + continue + return out + except subprocess.CalledProcessError as e: + pass + raise Exception( + 'Non-retryable error: Failed to get ip address of container %s.' % cid) + + def wait_for_healthy(cid, shortname, timeout_seconds): """Wait timeout_seconds for the container to become healthy""" started = time.time() @@ -74,10 +94,10 @@ def wait_for_healthy(cid, shortname, timeout_seconds): (shortname, cid)) -def finish_jobs(jobs): +def finish_jobs(jobs, suppress_failure=True): """Kills given docker containers and waits for corresponding jobs to finish""" for job in jobs: - job.kill(suppress_failure=True) + job.kill(suppress_failure=suppress_failure) while any(job.is_running() for job in jobs): time.sleep(1) @@ -120,6 +140,9 @@ class DockerJob: def mapped_port(self, port): return docker_mapped_port(self._container_name, port) + def ip_address(self): + return docker_ip_address(self._container_name) + def wait_for_healthy(self, timeout_seconds): wait_for_healthy(self._container_name, self._spec.shortname, timeout_seconds) diff --git a/tools/run_tests/run_grpclb_interop_tests.py b/tools/run_tests/run_grpclb_interop_tests.py new file mode 100755 index 0000000000..3bfbcecf06 --- /dev/null +++ b/tools/run_tests/run_grpclb_interop_tests.py @@ -0,0 +1,609 @@ +#!/usr/bin/env python +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Run interop (cross-language) tests in parallel.""" + +from __future__ import print_function + +import argparse +import atexit +import itertools +import json +import multiprocessing +import os +import re +import subprocess +import sys +import tempfile +import time +import uuid +import six +import traceback + +import python_utils.dockerjob as dockerjob +import python_utils.jobset as jobset +import python_utils.report_utils as report_utils + +# Docker doesn't clean up after itself, so we do it on exit. +atexit.register(lambda: subprocess.call(['stty', 'echo'])) + +ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..')) +os.chdir(ROOT) + +_FALLBACK_SERVER_PORT = 443 +_BALANCER_SERVER_PORT = 12000 +_BACKEND_SERVER_PORT = 8080 + +_TEST_TIMEOUT = 30 + +_FAKE_SERVERS_SAFENAME = 'fake_servers' + +# Use a name that's verified by the test certs +_SERVICE_NAME = 'server.test.google.fr' + + +class CXXLanguage: + + def __init__(self): + self.client_cwd = '/var/local/git/grpc' + self.safename = 'cxx' + + def client_cmd(self, args): + return ['bins/opt/interop_client'] + args + + def global_env(self): + # 1) Set c-ares as the resolver, to + # enable grpclb. + # 2) Turn on verbose logging. + # 3) Set the ROOTS_PATH env variable + # to the test CA in order for + # GoogleDefaultCredentials to be + # able to use the test CA. + return { + 'GRPC_DNS_RESOLVER': + 'ares', + 'GRPC_VERBOSITY': + 'DEBUG', + 'GRPC_TRACE': + 'client_channel,glb', + 'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH': + '/var/local/git/grpc/src/core/tsi/test_creds/ca.pem', + } + + def __str__(self): + return 'c++' + + +class JavaLanguage: + + def __init__(self): + self.client_cwd = '/var/local/git/grpc-java' + self.safename = str(self) + + def client_cmd(self, args): + # Take necessary steps to import our test CA into + # the set of test CA's that the Java runtime of the + # docker container will pick up, so that + # Java GoogleDefaultCreds can use it. + pem_to_der_cmd = ('openssl x509 -outform der ' + '-in /external_mount/src/core/tsi/test_creds/ca.pem ' + '-out /tmp/test_ca.der') + keystore_import_cmd = ( + 'keytool -import ' + '-keystore /usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts ' + '-file /tmp/test_ca.der ' + '-deststorepass changeit ' + '-noprompt') + return [ + 'bash', '-c', ('{pem_to_der_cmd} && ' + '{keystore_import_cmd} && ' + './run-test-client.sh {java_client_args}').format( + pem_to_der_cmd=pem_to_der_cmd, + keystore_import_cmd=keystore_import_cmd, + java_client_args=' '.join(args)) + ] + + def global_env(self): + # 1) Enable grpclb + # 2) Enable verbose logging + return { + 'JAVA_OPTS': + ('-Dio.grpc.internal.DnsNameResolverProvider.enable_grpclb=true ' + '-Djava.util.logging.config.file=/var/local/grpc_java_logging/logconf.txt' + ) + } + + def __str__(self): + return 'java' + + +class GoLanguage: + + def __init__(self): + self.client_cwd = '/go/src/google.golang.org/grpc/interop/client' + self.safename = str(self) + + def client_cmd(self, args): + # Copy the test CA file into the path that + # the Go runtime in the docker container will use, so + # that Go's GoogleDefaultCredentials can use it. + # See https://golang.org/src/crypto/x509/root_linux.go. + return [ + 'bash', '-c', ('cp /external_mount/src/core/tsi/test_creds/ca.pem ' + '/etc/ssl/certs/ca-certificates.crt && ' + '/go/bin/client {go_client_args}' + ).format(go_client_args=' '.join(args)) + ] + + def global_env(self): + return { + 'GRPC_GO_LOG_VERBOSITY_LEVEL': '3', + 'GRPC_GO_LOG_SEVERITY_LEVEL': 'INFO' + } + + def __str__(self): + return 'go' + + +_LANGUAGES = { + 'c++': CXXLanguage(), + 'go': GoLanguage(), + 'java': JavaLanguage(), +} + + +def docker_run_cmdline(cmdline, image, docker_args, cwd, environ=None): + """Wraps given cmdline array to create 'docker run' cmdline from it.""" + # turn environ into -e docker args + docker_cmdline = 'docker run -i --rm=true'.split() + if environ: + for k, v in environ.items(): + docker_cmdline += ['-e', '%s=%s' % (k, v)] + return docker_cmdline + ['-w', cwd] + docker_args + [image] + cmdline + + +def _job_kill_handler(job): + assert job._spec.container_name + dockerjob.docker_kill(job._spec.container_name) + + +def transport_security_to_args(transport_security): + args = [] + if transport_security == 'tls': + args += ['--use_tls=true'] + elif transport_security == 'alts': + args += ['--use_tls=false', '--use_alts=true'] + elif transport_security == 'insecure': + args += ['--use_tls=false'] + elif transport_security == 'google_default_credentials': + args += ['--custom_credentials_type=google_default_credentials'] + else: + print('Invalid transport security option.') + sys.exit(1) + return args + + +def lb_client_interop_jobspec(language, + dns_server_ip, + docker_image, + transport_security='tls'): + """Runs a gRPC client under test in a docker container""" + interop_only_options = [ + '--server_host=%s' % _SERVICE_NAME, + '--server_port=%d' % _FALLBACK_SERVER_PORT + ] + transport_security_to_args(transport_security) + # Don't set the server host override in any client; + # Go and Java default to no override. + # We're using a DNS server so there's no need. + if language.safename == 'c++': + interop_only_options += ['--server_host_override=""'] + # Don't set --use_test_ca; we're configuring + # clients to use test CA's via alternate means. + interop_only_options += ['--use_test_ca=false'] + client_args = language.client_cmd(interop_only_options) + container_name = dockerjob.random_name( + 'lb_interop_client_%s' % language.safename) + docker_cmdline = docker_run_cmdline( + client_args, + environ=language.global_env(), + image=docker_image, + cwd=language.client_cwd, + docker_args=[ + '--dns=%s' % dns_server_ip, + '--net=host', + '--name=%s' % container_name, + '-v', + '{grpc_grpc_root_dir}:/external_mount:ro'.format( + grpc_grpc_root_dir=ROOT), + ]) + jobset.message( + 'IDLE', + 'docker_cmdline:\b|%s|' % ' '.join(docker_cmdline), + do_newline=True) + test_job = jobset.JobSpec( + cmdline=docker_cmdline, + shortname=('lb_interop_client:%s' % language), + timeout_seconds=_TEST_TIMEOUT, + kill_handler=_job_kill_handler) + test_job.container_name = container_name + return test_job + + +def fallback_server_jobspec(transport_security, shortname): + """Create jobspec for running a fallback server""" + cmdline = [ + 'bin/server', + '--port=%d' % _FALLBACK_SERVER_PORT, + ] + transport_security_to_args(transport_security) + return grpc_server_in_docker_jobspec( + server_cmdline=cmdline, shortname=shortname) + + +def backend_server_jobspec(transport_security, shortname): + """Create jobspec for running a backend server""" + cmdline = [ + 'bin/server', + '--port=%d' % _BACKEND_SERVER_PORT, + ] + transport_security_to_args(transport_security) + return grpc_server_in_docker_jobspec( + server_cmdline=cmdline, shortname=shortname) + + +def grpclb_jobspec(transport_security, short_stream, backend_addrs, shortname): + """Create jobspec for running a balancer server""" + cmdline = [ + 'bin/fake_grpclb', + '--backend_addrs=%s' % ','.join(backend_addrs), + '--port=%d' % _BALANCER_SERVER_PORT, + '--short_stream=%s' % short_stream, + '--service_name=%s' % _SERVICE_NAME, + ] + transport_security_to_args(transport_security) + return grpc_server_in_docker_jobspec( + server_cmdline=cmdline, shortname=shortname) + + +def grpc_server_in_docker_jobspec(server_cmdline, shortname): + container_name = dockerjob.random_name(shortname) + environ = { + 'GRPC_GO_LOG_VERBOSITY_LEVEL': '3', + 'GRPC_GO_LOG_SEVERITY_LEVEL': 'INFO ', + } + docker_cmdline = docker_run_cmdline( + server_cmdline, + cwd='/go', + image=docker_images.get(_FAKE_SERVERS_SAFENAME), + environ=environ, + docker_args=['--name=%s' % container_name]) + jobset.message( + 'IDLE', + 'docker_cmdline:\b|%s|' % ' '.join(docker_cmdline), + do_newline=True) + server_job = jobset.JobSpec( + cmdline=docker_cmdline, shortname=shortname, timeout_seconds=30 * 60) + server_job.container_name = container_name + return server_job + + +def dns_server_in_docker_jobspec(grpclb_ips, fallback_ips, shortname, + cause_no_error_no_data_for_balancer_a_record): + container_name = dockerjob.random_name(shortname) + run_dns_server_cmdline = [ + 'python', + 'test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py', + '--grpclb_ips=%s' % ','.join(grpclb_ips), + '--fallback_ips=%s' % ','.join(fallback_ips), + ] + if cause_no_error_no_data_for_balancer_a_record: + run_dns_server_cmdline.append( + '--cause_no_error_no_data_for_balancer_a_record') + docker_cmdline = docker_run_cmdline( + run_dns_server_cmdline, + cwd='/var/local/git/grpc', + image=docker_images.get(_FAKE_SERVERS_SAFENAME), + docker_args=['--name=%s' % container_name]) + jobset.message( + 'IDLE', + 'docker_cmdline:\b|%s|' % ' '.join(docker_cmdline), + do_newline=True) + server_job = jobset.JobSpec( + cmdline=docker_cmdline, shortname=shortname, timeout_seconds=30 * 60) + server_job.container_name = container_name + return server_job + + +def build_interop_image_jobspec(lang_safename, basename_prefix='grpc_interop'): + """Creates jobspec for building interop docker image for a language""" + tag = '%s_%s:%s' % (basename_prefix, lang_safename, uuid.uuid4()) + env = { + 'INTEROP_IMAGE': tag, + 'BASE_NAME': '%s_%s' % (basename_prefix, lang_safename), + } + build_job = jobset.JobSpec( + cmdline=['tools/run_tests/dockerize/build_interop_image.sh'], + environ=env, + shortname='build_docker_%s' % lang_safename, + timeout_seconds=30 * 60) + build_job.tag = tag + return build_job + + +argp = argparse.ArgumentParser(description='Run interop tests.') +argp.add_argument( + '-l', + '--language', + choices=['all'] + sorted(_LANGUAGES), + nargs='+', + default=['all'], + help='Clients to run.') +argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int) +argp.add_argument( + '-s', + '--scenarios_file', + default=None, + type=str, + help='File containing test scenarios as JSON configs.') +argp.add_argument( + '-n', + '--scenario_name', + default=None, + type=str, + help=( + 'Useful for manual runs: specify the name of ' + 'the scenario to run from scenarios_file. Run all scenarios if unset.')) +argp.add_argument( + '--cxx_image_tag', + default=None, + type=str, + help=('Setting this skips the clients docker image ' + 'build step and runs the client from the named ' + 'image. Only supports running a one client language.')) +argp.add_argument( + '--go_image_tag', + default=None, + type=str, + help=('Setting this skips the clients docker image build ' + 'step and runs the client from the named image. Only ' + 'supports running a one client language.')) +argp.add_argument( + '--java_image_tag', + default=None, + type=str, + help=('Setting this skips the clients docker image build ' + 'step and runs the client from the named image. Only ' + 'supports running a one client language.')) +argp.add_argument( + '--servers_image_tag', + default=None, + type=str, + help=('Setting this skips the fake servers docker image ' + 'build step and runs the servers from the named image.')) +argp.add_argument( + '--no_skips', + default=False, + type=bool, + nargs='?', + const=True, + help=('Useful for manual runs. Setting this overrides test ' + '"skips" configured in test scenarios.')) +argp.add_argument( + '--verbose', + default=False, + type=bool, + nargs='?', + const=True, + help='Increase logging.') +args = argp.parse_args() + +docker_images = {} + +build_jobs = [] +if len(args.language) and args.language[0] == 'all': + languages = _LANGUAGES.keys() +else: + languages = args.language +for lang_name in languages: + l = _LANGUAGES[lang_name] + # First check if a pre-built image was supplied, and avoid + # rebuilding the particular docker image if so. + if lang_name == 'c++' and args.cxx_image_tag: + docker_images[str(l.safename)] = args.cxx_image_tag + elif lang_name == 'go' and args.go_image_tag: + docker_images[str(l.safename)] = args.go_image_tag + elif lang_name == 'java' and args.java_image_tag: + docker_images[str(l.safename)] = args.java_image_tag + else: + # Build the test client in docker and save the fully + # built image. + job = build_interop_image_jobspec(l.safename) + build_jobs.append(job) + docker_images[str(l.safename)] = job.tag + +# First check if a pre-built image was supplied. +if args.servers_image_tag: + docker_images[_FAKE_SERVERS_SAFENAME] = args.servers_image_tag +else: + # Build the test servers in docker and save the fully + # built image. + job = build_interop_image_jobspec( + _FAKE_SERVERS_SAFENAME, basename_prefix='lb_interop') + build_jobs.append(job) + docker_images[_FAKE_SERVERS_SAFENAME] = job.tag + +if build_jobs: + jobset.message('START', 'Building interop docker images.', do_newline=True) + print('Jobs to run: \n%s\n' % '\n'.join(str(j) for j in build_jobs)) + num_failures, _ = jobset.run( + build_jobs, newline_on_success=True, maxjobs=args.jobs) + if num_failures == 0: + jobset.message( + 'SUCCESS', 'All docker images built successfully.', do_newline=True) + else: + jobset.message( + 'FAILED', 'Failed to build interop docker images.', do_newline=True) + sys.exit(1) + + +def wait_until_dns_server_is_up(dns_server_ip): + """Probes the DNS server until it's running and safe for tests.""" + for i in range(0, 30): + print('Health check: attempt to connect to DNS server over TCP.') + tcp_connect_subprocess = subprocess.Popen([ + os.path.join(os.getcwd(), 'test/cpp/naming/utils/tcp_connect.py'), + '--server_host', dns_server_ip, '--server_port', + str(53), '--timeout', + str(1) + ]) + tcp_connect_subprocess.communicate() + if tcp_connect_subprocess.returncode == 0: + print(('Health check: attempt to make an A-record ' + 'query to DNS server.')) + dns_resolver_subprocess = subprocess.Popen( + [ + os.path.join(os.getcwd(), + 'test/cpp/naming/utils/dns_resolver.py'), + '--qname', ('health-check-local-dns-server-is-alive.' + 'resolver-tests.grpctestingexp'), + '--server_host', dns_server_ip, '--server_port', + str(53) + ], + stdout=subprocess.PIPE) + dns_resolver_stdout, _ = dns_resolver_subprocess.communicate() + if dns_resolver_subprocess.returncode == 0: + if '123.123.123.123' in dns_resolver_stdout: + print(('DNS server is up! ' + 'Successfully reached it over UDP and TCP.')) + return + time.sleep(0.1) + raise Exception(('Failed to reach DNS server over TCP and/or UDP. ' + 'Exitting without running tests.')) + + +def shortname(shortname_prefix, shortname, index): + return '%s_%s_%d' % (shortname_prefix, shortname, index) + + +def run_one_scenario(scenario_config): + jobset.message('START', 'Run scenario: %s' % scenario_config['name']) + server_jobs = {} + server_addresses = {} + suppress_server_logs = True + try: + backend_addrs = [] + fallback_ips = [] + grpclb_ips = [] + shortname_prefix = scenario_config['name'] + # Start backends + for i in xrange(len(scenario_config['backend_configs'])): + backend_config = scenario_config['backend_configs'][i] + backend_shortname = shortname(shortname_prefix, 'backend_server', i) + backend_spec = backend_server_jobspec( + backend_config['transport_sec'], backend_shortname) + backend_job = dockerjob.DockerJob(backend_spec) + server_jobs[backend_shortname] = backend_job + backend_addrs.append('%s:%d' % (backend_job.ip_address(), + _BACKEND_SERVER_PORT)) + # Start fallbacks + for i in xrange(len(scenario_config['fallback_configs'])): + fallback_config = scenario_config['fallback_configs'][i] + fallback_shortname = shortname(shortname_prefix, 'fallback_server', + i) + fallback_spec = fallback_server_jobspec( + fallback_config['transport_sec'], fallback_shortname) + fallback_job = dockerjob.DockerJob(fallback_spec) + server_jobs[fallback_shortname] = fallback_job + fallback_ips.append(fallback_job.ip_address()) + # Start balancers + for i in xrange(len(scenario_config['balancer_configs'])): + balancer_config = scenario_config['balancer_configs'][i] + grpclb_shortname = shortname(shortname_prefix, 'grpclb_server', i) + grpclb_spec = grpclb_jobspec(balancer_config['transport_sec'], + balancer_config['short_stream'], + backend_addrs, grpclb_shortname) + grpclb_job = dockerjob.DockerJob(grpclb_spec) + server_jobs[grpclb_shortname] = grpclb_job + grpclb_ips.append(grpclb_job.ip_address()) + # Start DNS server + dns_server_shortname = shortname(shortname_prefix, 'dns_server', 0) + dns_server_spec = dns_server_in_docker_jobspec( + grpclb_ips, fallback_ips, dns_server_shortname, + scenario_config['cause_no_error_no_data_for_balancer_a_record']) + dns_server_job = dockerjob.DockerJob(dns_server_spec) + server_jobs[dns_server_shortname] = dns_server_job + # Get the IP address of the docker container running the DNS server. + # The DNS server is running on port 53 of that IP address. Note we will + # point the DNS resolvers of grpc clients under test to our controlled + # DNS server by effectively modifying the /etc/resolve.conf "nameserver" + # lists of their docker containers. + dns_server_ip = dns_server_job.ip_address() + wait_until_dns_server_is_up(dns_server_ip) + # Run clients + jobs = [] + for lang_name in languages: + # Skip languages that are known to not currently + # work for this test. + if not args.no_skips and lang_name in scenario_config.get( + 'skip_langs', []): + jobset.message('IDLE', + 'Skipping scenario: %s for language: %s\n' % + (scenario_config['name'], lang_name)) + continue + lang = _LANGUAGES[lang_name] + test_job = lb_client_interop_jobspec( + lang, + dns_server_ip, + docker_image=docker_images.get(lang.safename), + transport_security=scenario_config['transport_sec']) + jobs.append(test_job) + jobset.message('IDLE', 'Jobs to run: \n%s\n' % '\n'.join( + str(job) for job in jobs)) + num_failures, resultset = jobset.run( + jobs, newline_on_success=True, maxjobs=args.jobs) + report_utils.render_junit_xml_report(resultset, 'sponge_log.xml') + if num_failures: + suppress_server_logs = False + jobset.message( + 'FAILED', + 'Scenario: %s. Some tests failed' % scenario_config['name'], + do_newline=True) + else: + jobset.message( + 'SUCCESS', + 'Scenario: %s. All tests passed' % scenario_config['name'], + do_newline=True) + return num_failures + finally: + # Check if servers are still running. + for server, job in server_jobs.items(): + if not job.is_running(): + print('Server "%s" has exited prematurely.' % server) + suppress_failure = suppress_server_logs and not args.verbose + dockerjob.finish_jobs( + [j for j in six.itervalues(server_jobs)], + suppress_failure=suppress_failure) + + +num_failures = 0 +with open(args.scenarios_file, 'r') as scenarios_input: + all_scenarios = json.loads(scenarios_input.read()) + for scenario in all_scenarios: + if args.scenario_name: + if args.scenario_name != scenario['name']: + jobset.message('IDLE', + 'Skipping scenario: %s' % scenario['name']) + continue + num_failures += run_one_scenario(scenario) +if num_failures == 0: + sys.exit(0) +else: + sys.exit(1) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 1d639edb82..5722a88182 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -688,6 +688,10 @@ def write_cmdlog_maybe(cmdlog, filename): if cmdlog: with open(filename, 'w') as logfile: logfile.write('#!/bin/bash\n') + logfile.write('# DO NOT MODIFY\n') + logfile.write( + '# This file is generated by run_interop_tests.py/create_testcases.sh\n' + ) logfile.writelines("%s\n" % line for line in cmdlog) print('Command log written to file %s' % filename) diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py index a746d531a1..c6e67eaf56 100755 --- a/tools/run_tests/run_performance_tests.py +++ b/tools/run_tests/run_performance_tests.py @@ -41,6 +41,11 @@ os.chdir(_ROOT) _REMOTE_HOST_USERNAME = 'jenkins' +_SCENARIO_TIMEOUT = 3 * 60 +_WORKER_TIMEOUT = 3 * 60 +_NETPERF_TIMEOUT = 60 +_QUIT_WORKER_TIMEOUT = 2 * 60 + class QpsWorkerJob: """Encapsulates a qps worker server job.""" @@ -85,7 +90,7 @@ def create_qpsworker_job(language, cmdline = perf_cmd + ['-o', '%s-perf.data' % perf_file_base_name ] + cmdline - worker_timeout = 3 * 60 + worker_timeout = _WORKER_TIMEOUT if remote_host: user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host) ssh_cmd = ['ssh'] @@ -131,7 +136,7 @@ def create_scenario_jobspec(scenario_json, return jobset.JobSpec( cmdline=[cmd], shortname='qps_json_driver.%s' % scenario_json['name'], - timeout_seconds=12 * 60, + timeout_seconds=_SCENARIO_TIMEOUT, shell=True, verbose_success=True) @@ -139,7 +144,7 @@ def create_scenario_jobspec(scenario_json, def create_quit_jobspec(workers, remote_host=None): """Runs quit using QPS driver.""" # setting QPS_WORKERS env variable here makes sure it works with SSH too. - cmd = 'QPS_WORKERS="%s" bins/opt/qps_json_driver --quit' % ','.join( + cmd = 'QPS_WORKERS="%s" cmake/build/qps_json_driver --quit' % ','.join( w.host_and_port for w in workers) if remote_host: user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host) @@ -149,7 +154,7 @@ def create_quit_jobspec(workers, remote_host=None): return jobset.JobSpec( cmdline=[cmd], shortname='qps_json_driver.quit', - timeout_seconds=3 * 60, + timeout_seconds=_QUIT_WORKER_TIMEOUT, shell=True, verbose_success=True) @@ -181,7 +186,7 @@ def create_netperf_jobspec(server_host='localhost', return jobset.JobSpec( cmdline=[cmd], shortname='netperf', - timeout_seconds=60, + timeout_seconds=_NETPERF_TIMEOUT, shell=True, verbose_success=True) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 48c40ad724..44151f49fb 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -759,8 +759,10 @@ class PythonLanguage(object): self.python_manager_name(), _docker_arch_suffix(self.args.arch)) def python_manager_name(self): - if self.args.compiler in ['python3.5', 'python3.6']: - return 'pyenv' + if self.args.compiler in [ + 'python2.7', 'python3.5', 'python3.6', 'python3.7' + ]: + return 'stretch_' + self.args.compiler[len('python'):] elif self.args.compiler == 'python_alpine': return 'alpine' else: @@ -1515,7 +1517,7 @@ else: lang_list = args.language # We don't support code coverage on some languages if 'gcov' in args.config: - for bad in ['grpc-node', 'objc', 'sanity']: + for bad in ['csharp', 'grpc-node', 'objc', 'sanity']: if bad in lang_list: lang_list.remove(bad) diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py index 8afd826453..2a5dcda5be 100755 --- a/tools/run_tests/sanity/core_banned_functions.py +++ b/tools/run_tests/sanity/core_banned_functions.py @@ -24,7 +24,8 @@ os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..')) # map of banned function signature to whitelist BANNED_EXCEPT = { 'grpc_resource_quota_ref(': ['src/core/lib/iomgr/resource_quota.cc'], - 'grpc_resource_quota_unref(': ['src/core/lib/iomgr/resource_quota.cc'], + 'grpc_resource_quota_unref(': + ['src/core/lib/iomgr/resource_quota.cc', 'src/core/lib/surface/server.cc'], 'grpc_slice_buffer_destroy(': ['src/core/lib/slice/slice_buffer.cc'], 'grpc_slice_buffer_reset_and_unref(': ['src/core/lib/slice/slice_buffer.cc'], |