Merge pull request #14450 from markdroth/c++_service_config

Convert slice hash table and service config code to C++
reviewable/pr10684/r30^2
Mark D. Roth 7 years ago committed by GitHub
commit 02a8d09cae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      BUILD
  2. 81
      CMakeLists.txt
  3. 102
      Makefile
  4. 30
      build.yaml
  5. 4
      config.m4
  6. 4
      config.w32
  7. 3
      gRPC-C++.podspec
  8. 10
      gRPC-Core.podspec
  9. 7
      grpc.gemspec
  10. 10
      grpc.gyp
  11. 7
      package.xml
  12. 157
      src/core/ext/filters/client_channel/client_channel.cc
  13. 55
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
  14. 103
      src/core/ext/filters/client_channel/method_params.cc
  15. 63
      src/core/ext/filters/client_channel/method_params.h
  16. 8
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  17. 89
      src/core/ext/filters/message_size/message_size_filter.cc
  18. 39
      src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
  19. 1
      src/core/lib/gprpp/orphanable.h
  20. 2
      src/core/lib/gprpp/ref_counted.h
  21. 1
      src/core/lib/gprpp/ref_counted_ptr.h
  22. 4
      src/core/lib/security/security_connector/security_connector.cc
  23. 61
      src/core/lib/security/transport/lb_targets_info.cc
  24. 75
      src/core/lib/security/transport/target_authority_table.cc
  25. 22
      src/core/lib/security/transport/target_authority_table.h
  26. 147
      src/core/lib/slice/slice_hash_table.cc
  27. 221
      src/core/lib/slice/slice_hash_table.h
  28. 194
      src/core/lib/transport/service_config.cc
  29. 256
      src/core/lib/transport/service_config.h
  30. 4
      src/python/grpcio/grpc_core_dependencies.py
  31. 3
      test/core/slice/BUILD
  32. 248
      test/core/slice/slice_hash_table_test.cc
  33. 7
      tools/doxygen/Doxyfile.core.internal
  34. 44
      tools/run_tests/generated/sources_and_headers.json
  35. 48
      tools/run_tests/generated/tests.json

10
BUILD

@ -779,7 +779,6 @@ grpc_cc_library(
"src/core/lib/slice/percent_encoding.cc",
"src/core/lib/slice/slice.cc",
"src/core/lib/slice/slice_buffer.cc",
"src/core/lib/slice/slice_hash_table.cc",
"src/core/lib/slice/slice_intern.cc",
"src/core/lib/slice/slice_string_helpers.cc",
"src/core/lib/surface/api_trace.cc",
@ -945,6 +944,9 @@ grpc_cc_library(
"gpr_base",
"grpc_codegen",
"grpc_trace",
"ref_counted",
"ref_counted_ptr",
"inlined_vector",
],
)
@ -999,6 +1001,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/lb_policy.cc",
"src/core/ext/filters/client_channel/lb_policy_factory.cc",
"src/core/ext/filters/client_channel/lb_policy_registry.cc",
"src/core/ext/filters/client_channel/method_params.cc",
"src/core/ext/filters/client_channel/parse_address.cc",
"src/core/ext/filters/client_channel/proxy_mapper.cc",
"src/core/ext/filters/client_channel/proxy_mapper_registry.cc",
@ -1019,6 +1022,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/lb_policy.h",
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
"src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.h",
"src/core/ext/filters/client_channel/proxy_mapper_registry.h",
@ -1328,10 +1332,10 @@ grpc_cc_library(
"src/core/lib/security/credentials/ssl/ssl_credentials.cc",
"src/core/lib/security/security_connector/security_connector.cc",
"src/core/lib/security/transport/client_auth_filter.cc",
"src/core/lib/security/transport/lb_targets_info.cc",
"src/core/lib/security/transport/secure_endpoint.cc",
"src/core/lib/security/transport/security_handshaker.cc",
"src/core/lib/security/transport/server_auth_filter.cc",
"src/core/lib/security/transport/target_authority_table.cc",
"src/core/lib/security/transport/tsi_error.cc",
"src/core/lib/security/util/json_util.cc",
"src/core/lib/surface/init_secure.cc",
@ -1351,9 +1355,9 @@ grpc_cc_library(
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/security_connector/security_connector.h",
"src/core/lib/security/transport/auth_filters.h",
"src/core/lib/security/transport/lb_targets_info.h",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/security_handshaker.h",
"src/core/lib/security/transport/target_authority_table.h",
"src/core/lib/security/transport/tsi_error.h",
"src/core/lib/security/util/json_util.h",
],

@ -344,7 +344,6 @@ add_dependencies(buildtests_c sequential_connectivity_test)
add_dependencies(buildtests_c server_chttp2_test)
add_dependencies(buildtests_c server_test)
add_dependencies(buildtests_c slice_buffer_test)
add_dependencies(buildtests_c slice_hash_table_test)
add_dependencies(buildtests_c slice_string_helpers_test)
add_dependencies(buildtests_c slice_test)
add_dependencies(buildtests_c sockaddr_resolver_test)
@ -594,6 +593,7 @@ add_dependencies(buildtests_cxx server_crash_test_client)
add_dependencies(buildtests_cxx server_early_return_test)
add_dependencies(buildtests_cxx server_request_call_test)
add_dependencies(buildtests_cxx shutdown_test)
add_dependencies(buildtests_cxx slice_hash_table_test)
add_dependencies(buildtests_cxx stats_test)
add_dependencies(buildtests_cxx status_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@ -881,7 +881,6 @@ add_library(grpc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@ -961,10 +960,10 @@ add_library(grpc
src/core/lib/security/credentials/ssl/ssl_credentials.cc
src/core/lib/security/security_connector/security_connector.cc
src/core/lib/security/transport/client_auth_filter.cc
src/core/lib/security/transport/lb_targets_info.cc
src/core/lib/security/transport/secure_endpoint.cc
src/core/lib/security/transport/security_handshaker.cc
src/core/lib/security/transport/server_auth_filter.cc
src/core/lib/security/transport/target_authority_table.cc
src/core/lib/security/transport/tsi_error.cc
src/core/lib/security/util/json_util.cc
src/core/lib/surface/init_secure.cc
@ -987,6 +986,7 @@ add_library(grpc
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
@ -1221,7 +1221,6 @@ add_library(grpc_cronet
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@ -1298,6 +1297,7 @@ add_library(grpc_cronet
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
@ -1325,10 +1325,10 @@ add_library(grpc_cronet
src/core/lib/security/credentials/ssl/ssl_credentials.cc
src/core/lib/security/security_connector/security_connector.cc
src/core/lib/security/transport/client_auth_filter.cc
src/core/lib/security/transport/lb_targets_info.cc
src/core/lib/security/transport/secure_endpoint.cc
src/core/lib/security/transport/security_handshaker.cc
src/core/lib/security/transport/server_auth_filter.cc
src/core/lib/security/transport/target_authority_table.cc
src/core/lib/security/transport/tsi_error.cc
src/core/lib/security/util/json_util.cc
src/core/lib/surface/init_secure.cc
@ -1547,7 +1547,6 @@ add_library(grpc_test_util
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@ -1593,6 +1592,7 @@ add_library(grpc_test_util
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
@ -1834,7 +1834,6 @@ add_library(grpc_test_util_unsecure
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@ -1880,6 +1879,7 @@ add_library(grpc_test_util_unsecure
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
@ -2101,7 +2101,6 @@ add_library(grpc_unsecure
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@ -2180,6 +2179,7 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
@ -2900,7 +2900,6 @@ add_library(grpc++_cronet
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@ -2951,6 +2950,7 @@ add_library(grpc++_cronet
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
@ -7880,33 +7880,6 @@ target_link_libraries(slice_buffer_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(slice_hash_table_test
test/core/slice/slice_hash_table_test.cc
)
target_include_directories(slice_hash_table_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}
)
target_link_libraries(slice_hash_table_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr_test_util
gpr
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(slice_string_helpers_test
test/core/slice/slice_string_helpers_test.cc
)
@ -12104,6 +12077,42 @@ target_link_libraries(shutdown_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(slice_hash_table_test
test/core/slice/slice_hash_table_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(slice_hash_table_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 third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(slice_hash_table_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr_test_util
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(stats_test
test/core/debug/stats_test.cc
third_party/googletest/googletest/src/gtest-all.cc

@ -1067,7 +1067,6 @@ server_chttp2_test: $(BINDIR)/$(CONFIG)/server_chttp2_test
server_fuzzer: $(BINDIR)/$(CONFIG)/server_fuzzer
server_test: $(BINDIR)/$(CONFIG)/server_test
slice_buffer_test: $(BINDIR)/$(CONFIG)/slice_buffer_test
slice_hash_table_test: $(BINDIR)/$(CONFIG)/slice_hash_table_test
slice_string_helpers_test: $(BINDIR)/$(CONFIG)/slice_string_helpers_test
slice_test: $(BINDIR)/$(CONFIG)/slice_test
sockaddr_resolver_test: $(BINDIR)/$(CONFIG)/sockaddr_resolver_test
@ -1181,6 +1180,7 @@ server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
server_early_return_test: $(BINDIR)/$(CONFIG)/server_early_return_test
server_request_call_test: $(BINDIR)/$(CONFIG)/server_request_call_test
shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test
slice_hash_table_test: $(BINDIR)/$(CONFIG)/slice_hash_table_test
stats_test: $(BINDIR)/$(CONFIG)/stats_test
status_test: $(BINDIR)/$(CONFIG)/status_test
streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test
@ -1469,7 +1469,6 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/server_chttp2_test \
$(BINDIR)/$(CONFIG)/server_test \
$(BINDIR)/$(CONFIG)/slice_buffer_test \
$(BINDIR)/$(CONFIG)/slice_hash_table_test \
$(BINDIR)/$(CONFIG)/slice_string_helpers_test \
$(BINDIR)/$(CONFIG)/slice_test \
$(BINDIR)/$(CONFIG)/sockaddr_resolver_test \
@ -1639,6 +1638,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_early_return_test \
$(BINDIR)/$(CONFIG)/server_request_call_test \
$(BINDIR)/$(CONFIG)/shutdown_test \
$(BINDIR)/$(CONFIG)/slice_hash_table_test \
$(BINDIR)/$(CONFIG)/stats_test \
$(BINDIR)/$(CONFIG)/status_test \
$(BINDIR)/$(CONFIG)/streaming_throughput_test \
@ -1783,6 +1783,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_early_return_test \
$(BINDIR)/$(CONFIG)/server_request_call_test \
$(BINDIR)/$(CONFIG)/shutdown_test \
$(BINDIR)/$(CONFIG)/slice_hash_table_test \
$(BINDIR)/$(CONFIG)/stats_test \
$(BINDIR)/$(CONFIG)/status_test \
$(BINDIR)/$(CONFIG)/streaming_throughput_test \
@ -1994,8 +1995,6 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/server_test || ( echo test server_test failed ; exit 1 )
$(E) "[RUN] Testing slice_buffer_test"
$(Q) $(BINDIR)/$(CONFIG)/slice_buffer_test || ( echo test slice_buffer_test failed ; exit 1 )
$(E) "[RUN] Testing slice_hash_table_test"
$(Q) $(BINDIR)/$(CONFIG)/slice_hash_table_test || ( echo test slice_hash_table_test failed ; exit 1 )
$(E) "[RUN] Testing slice_string_helpers_test"
$(Q) $(BINDIR)/$(CONFIG)/slice_string_helpers_test || ( echo test slice_string_helpers_test failed ; exit 1 )
$(E) "[RUN] Testing slice_test"
@ -2208,6 +2207,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/server_request_call_test || ( echo test server_request_call_test failed ; exit 1 )
$(E) "[RUN] Testing shutdown_test"
$(Q) $(BINDIR)/$(CONFIG)/shutdown_test || ( echo test shutdown_test failed ; exit 1 )
$(E) "[RUN] Testing slice_hash_table_test"
$(Q) $(BINDIR)/$(CONFIG)/slice_hash_table_test || ( echo test slice_hash_table_test failed ; exit 1 )
$(E) "[RUN] Testing stats_test"
$(Q) $(BINDIR)/$(CONFIG)/stats_test || ( echo test stats_test failed ; exit 1 )
$(E) "[RUN] Testing status_test"
@ -3115,7 +3116,6 @@ LIBGRPC_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@ -3195,10 +3195,10 @@ LIBGRPC_SRC = \
src/core/lib/security/credentials/ssl/ssl_credentials.cc \
src/core/lib/security/security_connector/security_connector.cc \
src/core/lib/security/transport/client_auth_filter.cc \
src/core/lib/security/transport/lb_targets_info.cc \
src/core/lib/security/transport/secure_endpoint.cc \
src/core/lib/security/transport/security_handshaker.cc \
src/core/lib/security/transport/server_auth_filter.cc \
src/core/lib/security/transport/target_authority_table.cc \
src/core/lib/security/transport/tsi_error.cc \
src/core/lib/security/util/json_util.cc \
src/core/lib/surface/init_secure.cc \
@ -3221,6 +3221,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
@ -3457,7 +3458,6 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@ -3534,6 +3534,7 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
@ -3561,10 +3562,10 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/security/credentials/ssl/ssl_credentials.cc \
src/core/lib/security/security_connector/security_connector.cc \
src/core/lib/security/transport/client_auth_filter.cc \
src/core/lib/security/transport/lb_targets_info.cc \
src/core/lib/security/transport/secure_endpoint.cc \
src/core/lib/security/transport/security_handshaker.cc \
src/core/lib/security/transport/server_auth_filter.cc \
src/core/lib/security/transport/target_authority_table.cc \
src/core/lib/security/transport/tsi_error.cc \
src/core/lib/security/util/json_util.cc \
src/core/lib/surface/init_secure.cc \
@ -3784,7 +3785,6 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@ -3830,6 +3830,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
@ -4064,7 +4065,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@ -4110,6 +4110,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
@ -4311,7 +4312,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@ -4390,6 +4390,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
@ -5111,7 +5112,6 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@ -5162,6 +5162,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
@ -13306,38 +13307,6 @@ endif
endif
SLICE_HASH_TABLE_TEST_SRC = \
test/core/slice/slice_hash_table_test.cc \
SLICE_HASH_TABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SLICE_HASH_TABLE_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/slice_hash_table_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_hash_table_test
endif
$(OBJDIR)/$(CONFIG)/test/core/slice/slice_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
endif
endif
SLICE_STRING_HELPERS_TEST_SRC = \
test/core/slice/slice_string_helpers_test.cc \
@ -17910,6 +17879,49 @@ endif
endif
SLICE_HASH_TABLE_TEST_SRC = \
test/core/slice/slice_hash_table_test.cc \
SLICE_HASH_TABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SLICE_HASH_TABLE_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/slice_hash_table_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
$(BINDIR)/$(CONFIG)/slice_hash_table_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(PROTOBUF_DEP) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_hash_table_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/core/slice/slice_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
endif
endif
STATS_TEST_SRC = \
test/core/debug/stats_test.cc \
@ -22221,10 +22233,10 @@ 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/security_connector.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/client_auth_filter.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/lb_targets_info.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/secure_endpoint.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/security_handshaker.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/server_auth_filter.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/target_authority_table.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/tsi_error.cc: $(OPENSSL_DEP)
src/core/lib/security/util/json_util.cc: $(OPENSSL_DEP)
src/core/lib/surface/init_secure.cc: $(OPENSSL_DEP)

@ -250,7 +250,6 @@ filegroups:
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_hash_table.cc
- src/core/lib/slice/slice_intern.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/lib/surface/api_trace.cc
@ -447,6 +446,7 @@ filegroups:
- src/core/ext/filters/client_channel/lb_policy.h
- src/core/ext/filters/client_channel/lb_policy_factory.h
- src/core/ext/filters/client_channel/lb_policy_registry.h
- src/core/ext/filters/client_channel/method_params.h
- src/core/ext/filters/client_channel/parse_address.h
- src/core/ext/filters/client_channel/proxy_mapper.h
- src/core/ext/filters/client_channel/proxy_mapper_registry.h
@ -469,6 +469,7 @@ filegroups:
- src/core/ext/filters/client_channel/lb_policy.cc
- src/core/ext/filters/client_channel/lb_policy_factory.cc
- src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
- src/core/ext/filters/client_channel/parse_address.cc
- src/core/ext/filters/client_channel/proxy_mapper.cc
- src/core/ext/filters/client_channel/proxy_mapper_registry.cc
@ -650,9 +651,9 @@ filegroups:
- src/core/lib/security/credentials/ssl/ssl_credentials.h
- src/core/lib/security/security_connector/security_connector.h
- src/core/lib/security/transport/auth_filters.h
- src/core/lib/security/transport/lb_targets_info.h
- src/core/lib/security/transport/secure_endpoint.h
- src/core/lib/security/transport/security_handshaker.h
- src/core/lib/security/transport/target_authority_table.h
- src/core/lib/security/transport/tsi_error.h
- src/core/lib/security/util/json_util.h
src:
@ -673,10 +674,10 @@ filegroups:
- src/core/lib/security/credentials/ssl/ssl_credentials.cc
- src/core/lib/security/security_connector/security_connector.cc
- src/core/lib/security/transport/client_auth_filter.cc
- src/core/lib/security/transport/lb_targets_info.cc
- src/core/lib/security/transport/secure_endpoint.cc
- src/core/lib/security/transport/security_handshaker.cc
- src/core/lib/security/transport/server_auth_filter.cc
- src/core/lib/security/transport/target_authority_table.cc
- src/core/lib/security/transport/tsi_error.cc
- src/core/lib/security/util/json_util.cc
- src/core/lib/surface/init_secure.cc
@ -3147,17 +3148,6 @@ targets:
- gpr_test_util
- gpr
uses_polling: false
- name: slice_hash_table_test
build: test
language: c
src:
- test/core/slice/slice_hash_table_test.cc
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
uses_polling: false
- name: slice_string_helpers_test
build: test
language: c
@ -4827,6 +4817,18 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: slice_hash_table_test
gtest: true
build: test
language: c++
src:
- test/core/slice/slice_hash_table_test.cc
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
uses_polling: false
- name: stats_test
gtest: true
build: test

@ -180,7 +180,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@ -260,10 +259,10 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/security/credentials/ssl/ssl_credentials.cc \
src/core/lib/security/security_connector/security_connector.cc \
src/core/lib/security/transport/client_auth_filter.cc \
src/core/lib/security/transport/lb_targets_info.cc \
src/core/lib/security/transport/secure_endpoint.cc \
src/core/lib/security/transport/security_handshaker.cc \
src/core/lib/security/transport/server_auth_filter.cc \
src/core/lib/security/transport/target_authority_table.cc \
src/core/lib/security/transport/tsi_error.cc \
src/core/lib/security/util/json_util.cc \
src/core/lib/surface/init_secure.cc \
@ -286,6 +285,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \

@ -157,7 +157,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\slice\\percent_encoding.cc " +
"src\\core\\lib\\slice\\slice.cc " +
"src\\core\\lib\\slice\\slice_buffer.cc " +
"src\\core\\lib\\slice\\slice_hash_table.cc " +
"src\\core\\lib\\slice\\slice_intern.cc " +
"src\\core\\lib\\slice\\slice_string_helpers.cc " +
"src\\core\\lib\\surface\\api_trace.cc " +
@ -237,10 +236,10 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\security\\credentials\\ssl\\ssl_credentials.cc " +
"src\\core\\lib\\security\\security_connector\\security_connector.cc " +
"src\\core\\lib\\security\\transport\\client_auth_filter.cc " +
"src\\core\\lib\\security\\transport\\lb_targets_info.cc " +
"src\\core\\lib\\security\\transport\\secure_endpoint.cc " +
"src\\core\\lib\\security\\transport\\security_handshaker.cc " +
"src\\core\\lib\\security\\transport\\server_auth_filter.cc " +
"src\\core\\lib\\security\\transport\\target_authority_table.cc " +
"src\\core\\lib\\security\\transport\\tsi_error.cc " +
"src\\core\\lib\\security\\util\\json_util.cc " +
"src\\core\\lib\\surface\\init_secure.cc " +
@ -263,6 +262,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\lb_policy.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy_factory.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " +
"src\\core\\ext\\filters\\client_channel\\method_params.cc " +
"src\\core\\ext\\filters\\client_channel\\parse_address.cc " +
"src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " +
"src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " +

@ -273,9 +273,9 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/lb_targets_info.h',
'src/core/lib/security/transport/secure_endpoint.h',
'src/core/lib/security/transport/security_handshaker.h',
'src/core/lib/security/transport/target_authority_table.h',
'src/core/lib/security/transport/tsi_error.h',
'src/core/lib/security/util/json_util.h',
'src/core/tsi/alts_transport_security.h',
@ -296,6 +296,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',

@ -285,9 +285,9 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/lb_targets_info.h',
'src/core/lib/security/transport/secure_endpoint.h',
'src/core/lib/security/transport/security_handshaker.h',
'src/core/lib/security/transport/target_authority_table.h',
'src/core/lib/security/transport/tsi_error.h',
'src/core/lib/security/util/json_util.h',
'src/core/tsi/alts_transport_security.h',
@ -308,6 +308,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
@ -563,7 +564,6 @@ Pod::Spec.new do |s|
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@ -643,10 +643,10 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
'src/core/lib/security/security_connector/security_connector.cc',
'src/core/lib/security/transport/client_auth_filter.cc',
'src/core/lib/security/transport/lb_targets_info.cc',
'src/core/lib/security/transport/secure_endpoint.cc',
'src/core/lib/security/transport/security_handshaker.cc',
'src/core/lib/security/transport/server_auth_filter.cc',
'src/core/lib/security/transport/target_authority_table.cc',
'src/core/lib/security/transport/tsi_error.cc',
'src/core/lib/security/util/json_util.cc',
'src/core/lib/surface/init_secure.cc',
@ -669,6 +669,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
@ -773,9 +774,9 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/lb_targets_info.h',
'src/core/lib/security/transport/secure_endpoint.h',
'src/core/lib/security/transport/security_handshaker.h',
'src/core/lib/security/transport/target_authority_table.h',
'src/core/lib/security/transport/tsi_error.h',
'src/core/lib/security/util/json_util.h',
'src/core/tsi/alts_transport_security.h',
@ -796,6 +797,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',

@ -211,9 +211,9 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h )
s.files += %w( src/core/lib/security/security_connector/security_connector.h )
s.files += %w( src/core/lib/security/transport/auth_filters.h )
s.files += %w( src/core/lib/security/transport/lb_targets_info.h )
s.files += %w( src/core/lib/security/transport/secure_endpoint.h )
s.files += %w( src/core/lib/security/transport/security_handshaker.h )
s.files += %w( src/core/lib/security/transport/target_authority_table.h )
s.files += %w( src/core/lib/security/transport/tsi_error.h )
s.files += %w( src/core/lib/security/util/json_util.h )
s.files += %w( src/core/tsi/alts_transport_security.h )
@ -234,6 +234,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.h )
s.files += %w( src/core/ext/filters/client_channel/method_params.h )
s.files += %w( src/core/ext/filters/client_channel/parse_address.h )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h )
@ -493,7 +494,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/slice/percent_encoding.cc )
s.files += %w( src/core/lib/slice/slice.cc )
s.files += %w( src/core/lib/slice/slice_buffer.cc )
s.files += %w( src/core/lib/slice/slice_hash_table.cc )
s.files += %w( src/core/lib/slice/slice_intern.cc )
s.files += %w( src/core/lib/slice/slice_string_helpers.cc )
s.files += %w( src/core/lib/surface/api_trace.cc )
@ -573,10 +573,10 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.cc )
s.files += %w( src/core/lib/security/security_connector/security_connector.cc )
s.files += %w( src/core/lib/security/transport/client_auth_filter.cc )
s.files += %w( src/core/lib/security/transport/lb_targets_info.cc )
s.files += %w( src/core/lib/security/transport/secure_endpoint.cc )
s.files += %w( src/core/lib/security/transport/security_handshaker.cc )
s.files += %w( src/core/lib/security/transport/server_auth_filter.cc )
s.files += %w( src/core/lib/security/transport/target_authority_table.cc )
s.files += %w( src/core/lib/security/transport/tsi_error.cc )
s.files += %w( src/core/lib/security/util/json_util.cc )
s.files += %w( src/core/lib/surface/init_secure.cc )
@ -599,6 +599,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.cc )
s.files += %w( src/core/ext/filters/client_channel/method_params.cc )
s.files += %w( src/core/ext/filters/client_channel/parse_address.cc )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.cc )

@ -321,7 +321,6 @@
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@ -401,10 +400,10 @@
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
'src/core/lib/security/security_connector/security_connector.cc',
'src/core/lib/security/transport/client_auth_filter.cc',
'src/core/lib/security/transport/lb_targets_info.cc',
'src/core/lib/security/transport/secure_endpoint.cc',
'src/core/lib/security/transport/security_handshaker.cc',
'src/core/lib/security/transport/server_auth_filter.cc',
'src/core/lib/security/transport/target_authority_table.cc',
'src/core/lib/security/transport/tsi_error.cc',
'src/core/lib/security/util/json_util.cc',
'src/core/lib/surface/init_secure.cc',
@ -427,6 +426,7 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
@ -618,7 +618,6 @@
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@ -664,6 +663,7 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
@ -833,7 +833,6 @@
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@ -879,6 +878,7 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
@ -1027,7 +1027,6 @@
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@ -1106,6 +1105,7 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',

@ -218,9 +218,9 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/lb_targets_info.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" />
<file baseinstalldir="/" name="src/core/lib/security/transport/target_authority_table.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/json_util.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts_transport_security.h" role="src" />
@ -241,6 +241,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/method_params.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/parse_address.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper_registry.h" role="src" />
@ -500,7 +501,6 @@
<file baseinstalldir="/" name="src/core/lib/slice/percent_encoding.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_buffer.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_hash_table.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_intern.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_string_helpers.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/api_trace.cc" role="src" />
@ -580,10 +580,10 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.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/lb_targets_info.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" />
<file baseinstalldir="/" name="src/core/lib/security/transport/server_auth_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/target_authority_table.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/json_util.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/init_secure.cc" role="src" />
@ -606,6 +606,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/method_params.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/parse_address.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper_registry.cc" role="src" />

@ -33,6 +33,7 @@
#include "src/core/ext/filters/client_channel/backup_poller.h"
#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/method_params.h"
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/filters/client_channel/retry_throttle.h"
@ -53,114 +54,21 @@
#include "src/core/lib/transport/service_config.h"
#include "src/core/lib/transport/static_metadata.h"
using grpc_core::internal::ClientChannelMethodParams;
/* Client channel implementation */
grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel");
/*************************************************************************
* METHOD-CONFIG TABLE
* CHANNEL-WIDE FUNCTIONS
*/
typedef enum {
/* zero so it can be default initialized */
WAIT_FOR_READY_UNSET = 0,
WAIT_FOR_READY_FALSE,
WAIT_FOR_READY_TRUE
} wait_for_ready_value;
typedef struct {
gpr_refcount refs;
grpc_millis timeout;
wait_for_ready_value wait_for_ready;
} method_parameters;
static method_parameters* method_parameters_ref(
method_parameters* method_params) {
gpr_ref(&method_params->refs);
return method_params;
}
static void method_parameters_unref(method_parameters* method_params) {
if (gpr_unref(&method_params->refs)) {
gpr_free(method_params);
}
}
// Wrappers to pass to grpc_service_config_create_method_config_table().
static void* method_parameters_ref_wrapper(void* value) {
return method_parameters_ref(static_cast<method_parameters*>(value));
}
static void method_parameters_unref_wrapper(void* value) {
method_parameters_unref(static_cast<method_parameters*>(value));
}
static bool parse_wait_for_ready(grpc_json* field,
wait_for_ready_value* wait_for_ready) {
if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
return false;
}
*wait_for_ready = field->type == GRPC_JSON_TRUE ? WAIT_FOR_READY_TRUE
: WAIT_FOR_READY_FALSE;
return true;
}
static bool parse_timeout(grpc_json* field, grpc_millis* timeout) {
if (field->type != GRPC_JSON_STRING) return false;
size_t len = strlen(field->value);
if (field->value[len - 1] != 's') return false;
char* buf = gpr_strdup(field->value);
buf[len - 1] = '\0'; // Remove trailing 's'.
char* decimal_point = strchr(buf, '.');
int nanos = 0;
if (decimal_point != nullptr) {
*decimal_point = '\0';
nanos = gpr_parse_nonnegative_int(decimal_point + 1);
if (nanos == -1) {
gpr_free(buf);
return false;
}
int num_digits = static_cast<int>(strlen(decimal_point + 1));
if (num_digits > 9) { // We don't accept greater precision than nanos.
gpr_free(buf);
return false;
}
for (int i = 0; i < (9 - num_digits); ++i) {
nanos *= 10;
}
}
int seconds = decimal_point == buf ? 0 : gpr_parse_nonnegative_int(buf);
gpr_free(buf);
if (seconds == -1) return false;
*timeout = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
return true;
}
static void* method_parameters_create_from_json(const grpc_json* json) {
wait_for_ready_value wait_for_ready = WAIT_FOR_READY_UNSET;
grpc_millis timeout = 0;
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
if (field->key == nullptr) continue;
if (strcmp(field->key, "waitForReady") == 0) {
if (wait_for_ready != WAIT_FOR_READY_UNSET) return nullptr; // Duplicate.
if (!parse_wait_for_ready(field, &wait_for_ready)) return nullptr;
} else if (strcmp(field->key, "timeout") == 0) {
if (timeout > 0) return nullptr; // Duplicate.
if (!parse_timeout(field, &timeout)) return nullptr;
}
}
method_parameters* value =
static_cast<method_parameters*>(gpr_malloc(sizeof(method_parameters)));
gpr_ref_init(&value->refs, 1);
value->timeout = timeout;
value->wait_for_ready = wait_for_ready;
return value;
}
struct external_connectivity_watcher;
/*************************************************************************
* CHANNEL-WIDE FUNCTIONS
*/
typedef grpc_core::SliceHashTable<
grpc_core::RefCountedPtr<ClientChannelMethodParams>>
MethodParamsTable;
typedef struct client_channel_channel_data {
/** resolver for this channel */
@ -179,7 +87,7 @@ typedef struct client_channel_channel_data {
/** retry throttle data */
grpc_server_retry_throttle_data* retry_throttle_data;
/** maps method names to method_parameters structs */
grpc_slice_hash_table* method_params_table;
grpc_core::RefCountedPtr<MethodParamsTable> method_params_table;
/** incoming resolver result - set by resolver.next() */
grpc_channel_args* resolver_result;
/** a list of closures that are all waiting for resolver result to come in */
@ -306,9 +214,8 @@ typedef struct {
grpc_server_retry_throttle_data* retry_throttle_data;
} service_config_parsing_state;
static void parse_retry_throttle_params(const grpc_json* field, void* arg) {
service_config_parsing_state* parsing_state =
static_cast<service_config_parsing_state*>(arg);
static void parse_retry_throttle_params(
const grpc_json* field, service_config_parsing_state* parsing_state) {
if (strcmp(field->key, "retryThrottling") == 0) {
if (parsing_state->retry_throttle_data != nullptr) return; // Duplicate.
if (field->type != GRPC_JSON_OBJECT) return;
@ -396,7 +303,7 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
grpc_core::OrphanablePtr<grpc_core::LoadBalancingPolicy> new_lb_policy;
char* service_config_json = nullptr;
grpc_server_retry_throttle_data* retry_throttle_data = nullptr;
grpc_slice_hash_table* method_params_table = nullptr;
grpc_core::RefCountedPtr<MethodParamsTable> method_params_table;
if (chand->resolver_result != nullptr) {
if (chand->resolver != nullptr) {
// Find LB policy name.
@ -475,8 +382,8 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
service_config_json =
gpr_strdup(grpc_channel_arg_get_string(channel_arg));
if (service_config_json != nullptr) {
grpc_service_config* service_config =
grpc_service_config_create(service_config_json);
grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config =
grpc_core::ServiceConfig::Create(service_config_json);
if (service_config != nullptr) {
channel_arg = grpc_channel_args_find(chand->resolver_result,
GRPC_ARG_SERVER_URI);
@ -488,14 +395,12 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
memset(&parsing_state, 0, sizeof(parsing_state));
parsing_state.server_name =
uri->path[0] == '/' ? uri->path + 1 : uri->path;
grpc_service_config_parse_global_params(
service_config, parse_retry_throttle_params, &parsing_state);
service_config->ParseGlobalParams(parse_retry_throttle_params,
&parsing_state);
grpc_uri_destroy(uri);
retry_throttle_data = parsing_state.retry_throttle_data;
method_params_table = grpc_service_config_create_method_config_table(
service_config, method_parameters_create_from_json,
method_parameters_ref_wrapper, method_parameters_unref_wrapper);
grpc_service_config_destroy(service_config);
method_params_table = service_config->CreateMethodConfigTable(
ClientChannelMethodParams::CreateFromJson);
}
}
// Before we clean up, save a copy of lb_policy_name, since it might
@ -534,10 +439,7 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
}
chand->retry_throttle_data = retry_throttle_data;
// Swap out the method params table.
if (chand->method_params_table != nullptr) {
grpc_slice_hash_table_unref(chand->method_params_table);
}
chand->method_params_table = method_params_table;
chand->method_params_table = std::move(method_params_table);
// If we have a new LB policy or are shutting down (in which case
// new_lb_policy will be NULL), swap out the LB policy, unreffing the old one
// and removing its fds from chand->interested_parties. Note that we do NOT do
@ -794,7 +696,7 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) {
grpc_server_retry_throttle_data_unref(chand->retry_throttle_data);
}
if (chand->method_params_table != nullptr) {
grpc_slice_hash_table_unref(chand->method_params_table);
chand->method_params_table.reset();
}
grpc_client_channel_stop_backup_polling(chand->interested_parties);
grpc_connectivity_state_destroy(&chand->state_tracker);
@ -841,7 +743,7 @@ typedef struct client_channel_call_data {
grpc_call_combiner* call_combiner;
grpc_server_retry_throttle_data* retry_throttle_data;
method_parameters* method_params;
grpc_core::RefCountedPtr<ClientChannelMethodParams> method_params;
grpc_subchannel_call* subchannel_call;
grpc_error* error;
@ -970,17 +872,16 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) {
grpc_server_retry_throttle_data_ref(chand->retry_throttle_data);
}
if (chand->method_params_table != nullptr) {
calld->method_params = static_cast<method_parameters*>(
grpc_method_config_table_get(chand->method_params_table, calld->path));
calld->method_params = grpc_core::ServiceConfig::MethodConfigTableLookup(
*chand->method_params_table, calld->path);
if (calld->method_params != nullptr) {
method_parameters_ref(calld->method_params);
// If the deadline from the service config is shorter than the one
// from the client API, reset the deadline timer.
if (chand->deadline_checking_enabled &&
calld->method_params->timeout != 0) {
calld->method_params->timeout() != 0) {
const grpc_millis per_method_deadline =
grpc_timespec_to_millis_round_up(calld->call_start_time) +
calld->method_params->timeout;
calld->method_params->timeout();
if (per_method_deadline < calld->deadline) {
calld->deadline = per_method_deadline;
grpc_deadline_state_reset(elem, calld->deadline);
@ -1109,9 +1010,11 @@ static bool pick_callback_start_locked(grpc_call_element* elem) {
GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET;
const bool wait_for_ready_set_from_service_config =
calld->method_params != nullptr &&
calld->method_params->wait_for_ready != WAIT_FOR_READY_UNSET;
calld->method_params->wait_for_ready() !=
ClientChannelMethodParams::WAIT_FOR_READY_UNSET;
if (!wait_for_ready_set_from_api && wait_for_ready_set_from_service_config) {
if (calld->method_params->wait_for_ready == WAIT_FOR_READY_TRUE) {
if (calld->method_params->wait_for_ready() ==
ClientChannelMethodParams::WAIT_FOR_READY_TRUE) {
initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY;
} else {
initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY;
@ -1441,9 +1344,7 @@ static void cc_destroy_call_elem(grpc_call_element* elem,
grpc_deadline_state_destroy(elem);
}
grpc_slice_unref_internal(calld->path);
if (calld->method_params != nullptr) {
method_parameters_unref(calld->method_params);
}
calld->method_params.reset();
GRPC_ERROR_UNREF(calld->error);
if (calld->subchannel_call != nullptr) {
grpc_subchannel_call_set_cleanup_closure(calld->subchannel_call,

@ -30,47 +30,41 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
#include "src/core/lib/security/transport/target_authority_table.h"
#include "src/core/lib/slice/slice_internal.h"
static void destroy_balancer_name(void* balancer_name) {
gpr_free(balancer_name);
}
static grpc_slice_hash_table_entry targets_info_entry_create(
const char* address, const char* balancer_name) {
grpc_slice_hash_table_entry entry;
entry.key = grpc_slice_from_copied_string(address);
entry.value = gpr_strdup(balancer_name);
return entry;
}
namespace grpc_core {
namespace {
static int balancer_name_cmp_fn(void* a, void* b) {
const char* a_str = static_cast<const char*>(a);
const char* b_str = static_cast<const char*>(b);
return strcmp(a_str, b_str);
int BalancerNameCmp(const grpc_core::UniquePtr<char>& a,
const grpc_core::UniquePtr<char>& b) {
return strcmp(a.get(), b.get());
}
static grpc_slice_hash_table* build_targets_info_table(
RefCountedPtr<TargetAuthorityTable> CreateTargetAuthorityTable(
grpc_lb_addresses* addresses) {
grpc_slice_hash_table_entry* targets_info_entries =
static_cast<grpc_slice_hash_table_entry*>(
gpr_zalloc(sizeof(*targets_info_entries) * addresses->num_addresses));
TargetAuthorityTable::Entry* target_authority_entries =
static_cast<TargetAuthorityTable::Entry*>(gpr_zalloc(
sizeof(*target_authority_entries) * addresses->num_addresses));
for (size_t i = 0; i < addresses->num_addresses; ++i) {
char* addr_str;
GPR_ASSERT(grpc_sockaddr_to_string(
&addr_str, &addresses->addresses[i].address, true) > 0);
targets_info_entries[i] = targets_info_entry_create(
addr_str, addresses->addresses[i].balancer_name);
target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str);
target_authority_entries[i].value.reset(
gpr_strdup(addresses->addresses[i].balancer_name));
gpr_free(addr_str);
}
grpc_slice_hash_table* targets_info = grpc_slice_hash_table_create(
addresses->num_addresses, targets_info_entries, destroy_balancer_name,
balancer_name_cmp_fn);
gpr_free(targets_info_entries);
return targets_info;
RefCountedPtr<TargetAuthorityTable> target_authority_table =
TargetAuthorityTable::Create(addresses->num_addresses,
target_authority_entries, BalancerNameCmp);
gpr_free(target_authority_entries);
return target_authority_table;
}
} // namespace
} // namespace grpc_core
grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
grpc_channel_args* args) {
const char* args_to_remove[1];
@ -83,9 +77,11 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
grpc_lb_addresses* addresses =
static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
grpc_slice_hash_table* targets_info = build_targets_info_table(addresses);
grpc_core::RefCountedPtr<grpc_core::TargetAuthorityTable>
target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses);
args_to_add[num_args_to_add++] =
grpc_lb_targets_info_create_channel_arg(targets_info);
grpc_core::CreateTargetAuthorityTableChannelArg(
target_authority_table.get());
// Substitute the channel credentials with a version without call
// credentials: the load balancer is not necessarily trusted to handle
// bearer token credentials.
@ -105,7 +101,6 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
args, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add);
// Clean up.
grpc_channel_args_destroy(args);
grpc_slice_hash_table_unref(targets_info);
if (creds_sans_call_creds != nullptr) {
grpc_channel_credentials_unref(creds_sans_call_creds);
}

@ -0,0 +1,103 @@
/*
*
* 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 <stdio.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/method_params.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/memory.h"
namespace grpc_core {
namespace internal {
namespace {
bool ParseWaitForReady(
grpc_json* field, ClientChannelMethodParams::WaitForReady* wait_for_ready) {
if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
return false;
}
*wait_for_ready = field->type == GRPC_JSON_TRUE
? ClientChannelMethodParams::WAIT_FOR_READY_TRUE
: ClientChannelMethodParams::WAIT_FOR_READY_FALSE;
return true;
}
// Parses a JSON field of the form generated for a google.proto.Duration
// proto message.
bool ParseDuration(grpc_json* field, grpc_millis* duration) {
if (field->type != GRPC_JSON_STRING) return false;
size_t len = strlen(field->value);
if (field->value[len - 1] != 's') return false;
UniquePtr<char> buf(gpr_strdup(field->value));
*(buf.get() + len - 1) = '\0'; // Remove trailing 's'.
char* decimal_point = strchr(buf.get(), '.');
int nanos = 0;
if (decimal_point != nullptr) {
*decimal_point = '\0';
nanos = gpr_parse_nonnegative_int(decimal_point + 1);
if (nanos == -1) {
return false;
}
int num_digits = (int)strlen(decimal_point + 1);
if (num_digits > 9) { // We don't accept greater precision than nanos.
return false;
}
for (int i = 0; i < (9 - num_digits); ++i) {
nanos *= 10;
}
}
int seconds =
decimal_point == buf.get() ? 0 : gpr_parse_nonnegative_int(buf.get());
if (seconds == -1) return false;
*duration = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
return true;
}
} // namespace
RefCountedPtr<ClientChannelMethodParams>
ClientChannelMethodParams::CreateFromJson(const grpc_json* json) {
RefCountedPtr<ClientChannelMethodParams> method_params =
MakeRefCounted<ClientChannelMethodParams>();
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
if (field->key == nullptr) continue;
if (strcmp(field->key, "waitForReady") == 0) {
if (method_params->wait_for_ready_ != WAIT_FOR_READY_UNSET) {
return nullptr; // Duplicate.
}
if (!ParseWaitForReady(field, &method_params->wait_for_ready_)) {
return nullptr;
}
} else if (strcmp(field->key, "timeout") == 0) {
if (method_params->timeout_ > 0) return nullptr; // Duplicate.
if (!ParseDuration(field, &method_params->timeout_)) return nullptr;
}
}
return method_params;
}
} // namespace internal
} // namespace grpc_core

@ -0,0 +1,63 @@
/*
*
* 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_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/exec_ctx.h" // for grpc_millis
#include "src/core/lib/json/json.h"
namespace grpc_core {
namespace internal {
class ClientChannelMethodParams : public RefCounted<ClientChannelMethodParams> {
public:
enum WaitForReady {
WAIT_FOR_READY_UNSET = 0,
WAIT_FOR_READY_FALSE,
WAIT_FOR_READY_TRUE
};
/// Creates a method_parameters object from \a json.
/// Intended for use with ServiceConfig::CreateMethodConfigTable().
static RefCountedPtr<ClientChannelMethodParams> CreateFromJson(
const grpc_json* json);
grpc_millis timeout() const { return timeout_; }
WaitForReady wait_for_ready() const { return wait_for_ready_; }
private:
// So New() can call our private ctor.
template <typename T, typename... Args>
friend T* grpc_core::New(Args&&... args);
ClientChannelMethodParams() {}
virtual ~ClientChannelMethodParams() {}
grpc_millis timeout_ = 0;
WaitForReady wait_for_ready_ = WAIT_FOR_READY_UNSET;
};
} // namespace internal
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H */

@ -295,7 +295,7 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
size_t num_args_to_add = 0;
new_args[num_args_to_add++] =
grpc_lb_addresses_create_channel_arg(r->lb_addresses_);
grpc_service_config* service_config = nullptr;
grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config;
char* service_config_string = nullptr;
if (r->service_config_json_ != nullptr) {
service_config_string = ChooseServiceConfig(r->service_config_json_);
@ -306,10 +306,11 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
args_to_remove[num_args_to_remove++] = GRPC_ARG_SERVICE_CONFIG;
new_args[num_args_to_add++] = grpc_channel_arg_string_create(
(char*)GRPC_ARG_SERVICE_CONFIG, service_config_string);
service_config = grpc_service_config_create(service_config_string);
service_config =
grpc_core::ServiceConfig::Create(service_config_string);
if (service_config != nullptr) {
const char* lb_policy_name =
grpc_service_config_get_lb_policy_name(service_config);
service_config->GetLoadBalancingPolicyName();
if (lb_policy_name != nullptr) {
args_to_remove[num_args_to_remove++] = GRPC_ARG_LB_POLICY_NAME;
new_args[num_args_to_add++] = grpc_channel_arg_string_create(
@ -322,7 +323,6 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
result = grpc_channel_args_copy_and_add_and_remove(
r->channel_args_, args_to_remove, num_args_to_remove, new_args,
num_args_to_add);
if (service_config != nullptr) grpc_service_config_destroy(service_config);
gpr_free(service_config_string);
grpc_lb_addresses_destroy(r->lb_addresses_);
// Reset backoff state so that we start from the beginning when the

@ -29,6 +29,8 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/service_config.h"
@ -37,27 +39,29 @@ typedef struct {
int max_recv_size;
} message_size_limits;
typedef struct {
gpr_refcount refs;
message_size_limits limits;
} refcounted_message_size_limits;
namespace grpc_core {
namespace {
static void* refcounted_message_size_limits_ref(void* value) {
refcounted_message_size_limits* limits =
static_cast<refcounted_message_size_limits*>(value);
gpr_ref(&limits->refs);
return value;
}
class MessageSizeLimits : public RefCounted<MessageSizeLimits> {
public:
static RefCountedPtr<MessageSizeLimits> CreateFromJson(const grpc_json* json);
static void refcounted_message_size_limits_unref(void* value) {
refcounted_message_size_limits* limits =
static_cast<refcounted_message_size_limits*>(value);
if (gpr_unref(&limits->refs)) {
gpr_free(value);
const message_size_limits& limits() const { return limits_; }
private:
// So New() can call our private ctor.
template <typename T, typename... Args>
friend T* grpc_core::New(Args&&... args);
MessageSizeLimits(int max_send_size, int max_recv_size) {
limits_.max_send_size = max_send_size;
limits_.max_recv_size = max_recv_size;
}
}
static void* refcounted_message_size_limits_create_from_json(
message_size_limits limits_;
};
RefCountedPtr<MessageSizeLimits> MessageSizeLimits::CreateFromJson(
const grpc_json* json) {
int max_request_message_bytes = -1;
int max_response_message_bytes = -1;
@ -79,16 +83,15 @@ static void* refcounted_message_size_limits_create_from_json(
if (max_response_message_bytes == -1) return nullptr;
}
}
refcounted_message_size_limits* value =
static_cast<refcounted_message_size_limits*>(
gpr_malloc(sizeof(refcounted_message_size_limits)));
gpr_ref_init(&value->refs, 1);
value->limits.max_send_size = max_request_message_bytes;
value->limits.max_recv_size = max_response_message_bytes;
return value;
return MakeRefCounted<MessageSizeLimits>(max_request_message_bytes,
max_response_message_bytes);
}
} // namespace
} // namespace grpc_core
namespace {
struct call_data {
grpc_call_combiner* call_combiner;
message_size_limits limits;
@ -105,8 +108,11 @@ struct call_data {
struct channel_data {
message_size_limits limits;
// Maps path names to refcounted_message_size_limits structs.
grpc_slice_hash_table* method_limit_table;
grpc_core::RefCountedPtr<grpc_core::SliceHashTable<
grpc_core::RefCountedPtr<grpc_core::MessageSizeLimits>>>
method_limit_table;
};
} // namespace
// Callback invoked when we receive a message. Here we check the max
@ -185,20 +191,19 @@ static grpc_error* init_call_elem(grpc_call_element* elem,
// size to the receive limit.
calld->limits = chand->limits;
if (chand->method_limit_table != nullptr) {
refcounted_message_size_limits* limits =
static_cast<refcounted_message_size_limits*>(
grpc_method_config_table_get(chand->method_limit_table,
args->path));
grpc_core::RefCountedPtr<grpc_core::MessageSizeLimits> limits =
grpc_core::ServiceConfig::MethodConfigTableLookup(
*chand->method_limit_table, args->path);
if (limits != nullptr) {
if (limits->limits.max_send_size >= 0 &&
(limits->limits.max_send_size < calld->limits.max_send_size ||
if (limits->limits().max_send_size >= 0 &&
(limits->limits().max_send_size < calld->limits.max_send_size ||
calld->limits.max_send_size < 0)) {
calld->limits.max_send_size = limits->limits.max_send_size;
calld->limits.max_send_size = limits->limits().max_send_size;
}
if (limits->limits.max_recv_size >= 0 &&
(limits->limits.max_recv_size < calld->limits.max_recv_size ||
if (limits->limits().max_recv_size >= 0 &&
(limits->limits().max_recv_size < calld->limits.max_recv_size ||
calld->limits.max_recv_size < 0)) {
calld->limits.max_recv_size = limits->limits.max_recv_size;
calld->limits.max_recv_size = limits->limits().max_recv_size;
}
}
}
@ -253,15 +258,11 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG);
const char* service_config_str = grpc_channel_arg_get_string(channel_arg);
if (service_config_str != nullptr) {
grpc_service_config* service_config =
grpc_service_config_create(service_config_str);
grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config =
grpc_core::ServiceConfig::Create(service_config_str);
if (service_config != nullptr) {
chand->method_limit_table =
grpc_service_config_create_method_config_table(
service_config, refcounted_message_size_limits_create_from_json,
refcounted_message_size_limits_ref,
refcounted_message_size_limits_unref);
grpc_service_config_destroy(service_config);
chand->method_limit_table = service_config->CreateMethodConfigTable(
grpc_core::MessageSizeLimits::CreateFromJson);
}
}
return GRPC_ERROR_NONE;
@ -270,7 +271,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
// Destructor for channel_data.
static void destroy_channel_elem(grpc_channel_element* elem) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
grpc_slice_hash_table_unref(chand->method_limit_table);
chand->method_limit_table.reset();
}
const grpc_channel_filter grpc_message_size_filter = {

@ -30,10 +30,11 @@
#include "src/core/ext/filters/client_channel/uri_parser.h"
#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_connector/security_connector.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
#include "src/core/lib/security/transport/target_authority_table.h"
#include "src/core/lib/slice/slice_hash_table.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
@ -73,11 +74,11 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args(
const char* server_uri_path;
server_uri_path =
server_uri->path[0] == '/' ? server_uri->path + 1 : server_uri->path;
const grpc_slice_hash_table* targets_info =
grpc_lb_targets_info_find_in_args(args->args);
char* target_name_to_check = nullptr;
if (targets_info != nullptr) { // LB channel
// Find the balancer name for the target.
const grpc_core::TargetAuthorityTable* target_authority_table =
grpc_core::FindTargetAuthorityTableInArgs(args->args);
grpc_core::UniquePtr<char> authority;
if (target_authority_table != nullptr) {
// Find the authority for the target.
const char* target_uri_str =
grpc_get_subchannel_address_uri_arg(args->args);
grpc_uri* target_uri =
@ -86,37 +87,33 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args(
if (target_uri->path[0] != '\0') { // "path" may be empty
const grpc_slice key = grpc_slice_from_static_string(
target_uri->path[0] == '/' ? target_uri->path + 1 : target_uri->path);
const char* value = static_cast<const char*>(
grpc_slice_hash_table_get(targets_info, key));
if (value != nullptr) target_name_to_check = gpr_strdup(value);
const grpc_core::UniquePtr<char>* value =
target_authority_table->Get(key);
if (value != nullptr) authority.reset(gpr_strdup(value->get()));
grpc_slice_unref_internal(key);
}
if (target_name_to_check == nullptr) {
// If the target name to check hasn't already been set, fall back to using
// SERVER_URI
target_name_to_check = gpr_strdup(server_uri_path);
}
grpc_uri_destroy(target_uri);
} else { // regular channel: the secure name is the original server URI.
target_name_to_check = gpr_strdup(server_uri_path);
}
// If the authority hasn't already been set (either because no target
// authority table was present or because the target was not present
// in the table), fall back to using the original server URI.
if (authority == nullptr) {
authority.reset(gpr_strdup(server_uri_path));
}
grpc_uri_destroy(server_uri);
GPR_ASSERT(target_name_to_check != nullptr);
grpc_channel_security_connector* subchannel_security_connector = nullptr;
// Create the security connector using the credentials and target name.
grpc_channel_args* new_args_from_connector = nullptr;
const grpc_security_status security_status =
grpc_channel_credentials_create_security_connector(
channel_credentials, target_name_to_check, args->args,
channel_credentials, authority.get(), args->args,
&subchannel_security_connector, &new_args_from_connector);
if (security_status != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR,
"Failed to create secure subchannel for secure name '%s'",
target_name_to_check);
gpr_free(target_name_to_check);
authority.get());
return nullptr;
}
gpr_free(target_name_to_check);
grpc_arg new_security_connector_arg =
grpc_security_connector_to_arg(&subchannel_security_connector->base);

@ -24,6 +24,7 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <cinttypes>
#include <memory>
#include "src/core/lib/debug/trace.h"

@ -24,6 +24,8 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <cinttypes>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/abstract.h"
#include "src/core/lib/gprpp/debug_location.h"

@ -33,6 +33,7 @@ template <typename T>
class RefCountedPtr {
public:
RefCountedPtr() {}
RefCountedPtr(std::nullptr_t) {}
// If value is non-null, we take ownership of a ref to it.
explicit RefCountedPtr(T* value) { value_ = value; }

@ -39,9 +39,9 @@
#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/transport/lb_targets_info.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"
#include "src/core/tsi/transport_security_adapter.h"
@ -514,7 +514,7 @@ grpc_channel_security_connector* grpc_fake_channel_security_connector_create(
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_lb_targets_info_find_in_args(args) != nullptr);
c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr;
return &c->base;
}

@ -1,61 +0,0 @@
/*
*
* Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
/* Channel arg key for the mapping of LB server addresses to their names for
* secure naming purposes. */
#define GRPC_ARG_LB_SECURE_NAMING_MAP "grpc.lb_secure_naming_map"
static void* targets_info_copy(void* p) {
return grpc_slice_hash_table_ref(static_cast<grpc_slice_hash_table*>(p));
}
static void targets_info_destroy(void* p) {
grpc_slice_hash_table_unref(static_cast<grpc_slice_hash_table*>(p));
}
static int targets_info_cmp(void* a, void* b) {
return grpc_slice_hash_table_cmp(
static_cast<const grpc_slice_hash_table*>(a),
static_cast<const grpc_slice_hash_table*>(b));
}
static const grpc_arg_pointer_vtable server_to_balancer_names_vtable = {
targets_info_copy, targets_info_destroy, targets_info_cmp};
grpc_arg grpc_lb_targets_info_create_channel_arg(
grpc_slice_hash_table* targets_info) {
return grpc_channel_arg_pointer_create((char*)GRPC_ARG_LB_SECURE_NAMING_MAP,
targets_info,
&server_to_balancer_names_vtable);
}
grpc_slice_hash_table* grpc_lb_targets_info_find_in_args(
const grpc_channel_args* args) {
const grpc_arg* targets_info_arg =
grpc_channel_args_find(args, GRPC_ARG_LB_SECURE_NAMING_MAP);
if (targets_info_arg != nullptr) {
GPR_ASSERT(targets_info_arg->type == GRPC_ARG_POINTER);
return static_cast<grpc_slice_hash_table*>(
targets_info_arg->value.pointer.p);
}
return nullptr;
}

@ -0,0 +1,75 @@
/*
*
* Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/security/transport/target_authority_table.h"
// Channel arg key for the mapping of target addresses to their authorities.
#define GRPC_ARG_TARGET_AUTHORITY_TABLE "grpc.target_authority_table"
namespace grpc_core {
namespace {
void* target_authority_table_copy(void* p) {
TargetAuthorityTable* table = static_cast<TargetAuthorityTable*>(p);
// TODO(roth): When channel_args are converted to C++, pass the
// RefCountedPtr<> directly instead of managing the ref manually.
table->Ref().release();
return p;
}
void target_authority_table_destroy(void* p) {
TargetAuthorityTable* table = static_cast<TargetAuthorityTable*>(p);
table->Unref();
}
int target_authority_table_cmp(void* a, void* b) {
return TargetAuthorityTable::Cmp(
*static_cast<const TargetAuthorityTable*>(a),
*static_cast<const TargetAuthorityTable*>(b));
}
const grpc_arg_pointer_vtable target_authority_table_arg_vtable = {
target_authority_table_copy, target_authority_table_destroy,
target_authority_table_cmp};
} // namespace
grpc_arg CreateTargetAuthorityTableChannelArg(TargetAuthorityTable* table) {
return grpc_channel_arg_pointer_create((char*)GRPC_ARG_TARGET_AUTHORITY_TABLE,
table,
&target_authority_table_arg_vtable);
}
TargetAuthorityTable* FindTargetAuthorityTableInArgs(
const grpc_channel_args* args) {
const grpc_arg* arg =
grpc_channel_args_find(args, GRPC_ARG_TARGET_AUTHORITY_TABLE);
if (arg != nullptr) {
if (arg->type == GRPC_ARG_POINTER) {
return static_cast<TargetAuthorityTable*>(arg->value.pointer.p);
} else {
gpr_log(GPR_ERROR, "value of " GRPC_ARG_TARGET_AUTHORITY_TABLE
" channel arg was not pointer type; ignoring");
}
}
return nullptr;
}
} // namespace grpc_core

@ -16,19 +16,25 @@
*
*/
#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H
#define GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H
#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_TARGET_AUTHORITY_TABLE_H
#define GRPC_CORE_LIB_SECURITY_TRANSPORT_TARGET_AUTHORITY_TABLE_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/slice/slice_hash_table.h"
/** Return a channel argument containing \a targets_info. */
grpc_arg grpc_lb_targets_info_create_channel_arg(
grpc_slice_hash_table* targets_info);
namespace grpc_core {
/** Return the instance of targets info in \a args or NULL */
grpc_slice_hash_table* grpc_lb_targets_info_find_in_args(
/// A hash table mapping target addresses to authorities.
typedef SliceHashTable<UniquePtr<char>> TargetAuthorityTable;
/// Returns a channel argument containing \a table.
grpc_arg CreateTargetAuthorityTableChannelArg(TargetAuthorityTable* table);
/// Returns the target authority table from \a args or nullptr.
TargetAuthorityTable* FindTargetAuthorityTableInArgs(
const grpc_channel_args* args);
#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H */
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_TARGET_AUTHORITY_TABLE_H */

@ -1,147 +0,0 @@
//
// Copyright 2016 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/slice/slice_hash_table.h"
#include <stdbool.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
struct grpc_slice_hash_table {
gpr_refcount refs;
void (*destroy_value)(void* value);
int (*value_cmp)(void* a, void* b);
size_t size;
size_t max_num_probes;
grpc_slice_hash_table_entry* entries;
};
static bool is_empty(grpc_slice_hash_table_entry* entry) {
return entry->value == nullptr;
}
static void grpc_slice_hash_table_add(grpc_slice_hash_table* table,
grpc_slice key, void* value) {
GPR_ASSERT(value != nullptr);
const size_t hash = grpc_slice_hash(key);
for (size_t offset = 0; offset < table->size; ++offset) {
const size_t idx = (hash + offset) % table->size;
if (is_empty(&table->entries[idx])) {
table->entries[idx].key = key;
table->entries[idx].value = value;
// Keep track of the maximum number of probes needed, since this
// provides an upper bound for lookups.
if (offset > table->max_num_probes) table->max_num_probes = offset;
return;
}
}
GPR_ASSERT(false); // Table should never be full.
}
grpc_slice_hash_table* grpc_slice_hash_table_create(
size_t num_entries, grpc_slice_hash_table_entry* entries,
void (*destroy_value)(void* value), int (*value_cmp)(void* a, void* b)) {
grpc_slice_hash_table* table =
static_cast<grpc_slice_hash_table*>(gpr_zalloc(sizeof(*table)));
gpr_ref_init(&table->refs, 1);
table->destroy_value = destroy_value;
table->value_cmp = value_cmp;
// Keep load factor low to improve performance of lookups.
table->size = num_entries * 2;
const size_t entry_size = sizeof(grpc_slice_hash_table_entry) * table->size;
table->entries =
static_cast<grpc_slice_hash_table_entry*>(gpr_zalloc(entry_size));
for (size_t i = 0; i < num_entries; ++i) {
grpc_slice_hash_table_entry* entry = &entries[i];
grpc_slice_hash_table_add(table, entry->key, entry->value);
}
return table;
}
grpc_slice_hash_table* grpc_slice_hash_table_ref(grpc_slice_hash_table* table) {
if (table != nullptr) gpr_ref(&table->refs);
return table;
}
void grpc_slice_hash_table_unref(grpc_slice_hash_table* table) {
if (table != nullptr && gpr_unref(&table->refs)) {
for (size_t i = 0; i < table->size; ++i) {
grpc_slice_hash_table_entry* entry = &table->entries[i];
if (!is_empty(entry)) {
grpc_slice_unref_internal(entry->key);
table->destroy_value(entry->value);
}
}
gpr_free(table->entries);
gpr_free(table);
}
}
void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table,
const grpc_slice key) {
const size_t hash = grpc_slice_hash(key);
// We cap the number of probes at the max number recorded when
// populating the table.
for (size_t offset = 0; offset <= table->max_num_probes; ++offset) {
const size_t idx = (hash + offset) % table->size;
if (is_empty(&table->entries[idx])) break;
if (grpc_slice_eq(table->entries[idx].key, key)) {
return table->entries[idx].value;
}
}
return nullptr; // Not found.
}
static int pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); }
int grpc_slice_hash_table_cmp(const grpc_slice_hash_table* a,
const grpc_slice_hash_table* b) {
int (*const value_cmp_fn_a)(void* a, void* b) =
a->value_cmp != nullptr ? a->value_cmp : pointer_cmp;
int (*const value_cmp_fn_b)(void* a, void* b) =
b->value_cmp != nullptr ? b->value_cmp : pointer_cmp;
// Compare value_fns
const int value_fns_cmp =
GPR_ICMP((void*)value_cmp_fn_a, (void*)value_cmp_fn_b);
if (value_fns_cmp != 0) return value_fns_cmp;
// Compare sizes
if (a->size < b->size) return -1;
if (a->size > b->size) return 1;
// Compare rows.
for (size_t i = 0; i < a->size; ++i) {
if (is_empty(&a->entries[i])) {
if (!is_empty(&b->entries[i])) {
return -1; // a empty but b non-empty
}
continue; // both empty, no need to check key or value
} else if (is_empty(&b->entries[i])) {
return 1; // a non-empty but b empty
}
// neither entry is empty
const int key_cmp = grpc_slice_cmp(a->entries[i].key, b->entries[i].key);
if (key_cmp != 0) return key_cmp;
const int value_cmp =
value_cmp_fn_a(a->entries[i].value, b->entries[i].value);
if (value_cmp != 0) return value_cmp;
}
return 0;
}

@ -19,52 +19,183 @@
#include <grpc/support/port_platform.h>
#include "src/core/lib/transport/metadata.h"
#include <string.h>
/** Hash table implementation.
*
* This implementation uses open addressing
* (https://en.wikipedia.org/wiki/Open_addressing) with linear
* probing (https://en.wikipedia.org/wiki/Linear_probing).
*
* The keys are \a grpc_slice objects. The values are arbitrary pointers
* with a common destroy function.
*
* Hash tables are intentionally immutable, to avoid the need for locking.
*/
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/slice/slice_internal.h"
/// Hash table implementation.
///
/// This implementation uses open addressing
/// (https://en.wikipedia.org/wiki/Open_addressing) with linear
/// probing (https://en.wikipedia.org/wiki/Linear_probing).
///
/// The keys are \a grpc_slice objects. The values can be any type.
///
/// Hash tables are intentionally immutable, to avoid the need for locking.
namespace grpc_core {
template <typename T>
class SliceHashTable : public RefCounted<SliceHashTable<T>> {
public:
struct Entry {
grpc_slice key;
T value;
bool is_set;
};
// Function for comparing values.
// TODO(roth): Eliminate this and the Cmp() method from this API once
// grpc_channel_args is redesigned to require that keys are unique.
typedef int (*ValueCmp)(const T&, const T&);
/// Creates a new hash table containing \a entries, which is an array
/// of length \a num_entries. Takes ownership of all keys and values in \a
/// entries. If not null, \a value_cmp will be used to compare values in
/// the context of \a Cmp(). If null, raw pointer (\a GPR_ICMP) comparison
/// will be used.
static RefCountedPtr<SliceHashTable> Create(size_t num_entries,
Entry* entries,
ValueCmp value_cmp);
/// Returns the value from the table associated with \a key.
/// Returns null if \a key is not found.
const T* Get(const grpc_slice& key) const;
/// Compares \a a vs. \a b.
/// A table is considered "smaller" (resp. "greater") if:
/// - GPR_ICMP(a->value_cmp, b->value_cmp) < 1 (resp. > 1),
/// - else, it contains fewer (resp. more) entries,
/// - else, if strcmp(a_key, b_key) < 1 (resp. > 1),
/// - else, if value_cmp(a_value, b_value) < 1 (resp. > 1).
static int Cmp(const SliceHashTable& a, const SliceHashTable& b);
private:
// So New() can call our private ctor.
template <typename T2, typename... Args>
friend T2* New(Args&&... args);
SliceHashTable(size_t num_entries, Entry* entries, ValueCmp value_cmp);
virtual ~SliceHashTable();
void Add(grpc_slice key, T& value);
// Default value comparison function, if none specified by caller.
static int DefaultValueCmp(const T& a, const T& b) { return GPR_ICMP(a, b); }
const ValueCmp value_cmp_;
const size_t size_;
size_t max_num_probes_;
Entry* entries_;
};
//
// implementation -- no user-serviceable parts below
//
template <typename T>
RefCountedPtr<SliceHashTable<T>> SliceHashTable<T>::Create(size_t num_entries,
Entry* entries,
ValueCmp value_cmp) {
return MakeRefCounted<SliceHashTable<T>>(num_entries, entries, value_cmp);
}
template <typename T>
SliceHashTable<T>::SliceHashTable(size_t num_entries, Entry* entries,
ValueCmp value_cmp)
: value_cmp_(value_cmp),
// Keep load factor low to improve performance of lookups.
size_(num_entries * 2),
max_num_probes_(0) {
entries_ = static_cast<Entry*>(gpr_zalloc(sizeof(Entry) * size_));
for (size_t i = 0; i < num_entries; ++i) {
Entry* entry = &entries[i];
Add(entry->key, entry->value);
}
}
template <typename T>
SliceHashTable<T>::~SliceHashTable() {
for (size_t i = 0; i < size_; ++i) {
Entry& entry = entries_[i];
if (entry.is_set) {
grpc_slice_unref_internal(entry.key);
entry.value.~T();
}
}
gpr_free(entries_);
}
template <typename T>
void SliceHashTable<T>::Add(grpc_slice key, T& value) {
const size_t hash = grpc_slice_hash(key);
for (size_t offset = 0; offset < size_; ++offset) {
const size_t idx = (hash + offset) % size_;
if (!entries_[idx].is_set) {
entries_[idx].is_set = true;
entries_[idx].key = key;
entries_[idx].value = std::move(value);
// Keep track of the maximum number of probes needed, since this
// provides an upper bound for lookups.
if (offset > max_num_probes_) max_num_probes_ = offset;
return;
}
}
GPR_ASSERT(false); // Table should never be full.
}
template <typename T>
const T* SliceHashTable<T>::Get(const grpc_slice& key) const {
const size_t hash = grpc_slice_hash(key);
// We cap the number of probes at the max number recorded when
// populating the table.
for (size_t offset = 0; offset <= max_num_probes_; ++offset) {
const size_t idx = (hash + offset) % size_;
if (!entries_[idx].is_set) break;
if (grpc_slice_eq(entries_[idx].key, key)) {
return &entries_[idx].value;
}
}
return nullptr; // Not found.
}
template <typename T>
int SliceHashTable<T>::Cmp(const SliceHashTable& a, const SliceHashTable& b) {
ValueCmp value_cmp_a =
a.value_cmp_ != nullptr ? a.value_cmp_ : DefaultValueCmp;
ValueCmp value_cmp_b =
b.value_cmp_ != nullptr ? b.value_cmp_ : DefaultValueCmp;
// Compare value_fns
const int value_fns_cmp = GPR_ICMP((void*)value_cmp_a, (void*)value_cmp_b);
if (value_fns_cmp != 0) return value_fns_cmp;
// Compare sizes
if (a.size_ < b.size_) return -1;
if (a.size_ > b.size_) return 1;
// Compare rows.
for (size_t i = 0; i < a.size_; ++i) {
if (!a.entries_[i].is_set) {
if (b.entries_[i].is_set) {
return -1; // a empty but b non-empty
}
continue; // both empty, no need to check key or value
} else if (!b.entries_[i].is_set) {
return 1; // a non-empty but b empty
}
// neither entry is empty
const int key_cmp = grpc_slice_cmp(a.entries_[i].key, b.entries_[i].key);
if (key_cmp != 0) return key_cmp;
const int value_cmp = value_cmp_a(a.entries_[i].value, b.entries_[i].value);
if (value_cmp != 0) return value_cmp;
}
return 0;
}
typedef struct grpc_slice_hash_table grpc_slice_hash_table;
typedef struct grpc_slice_hash_table_entry {
grpc_slice key;
void* value; /* Must not be NULL. */
} grpc_slice_hash_table_entry;
/** Creates a new hash table of containing \a entries, which is an array
of length \a num_entries. Takes ownership of all keys and values in \a
entries. Values will be cleaned up via \a destroy_value(). If not NULL, \a
value_cmp will be used to compare values in the context of \a
grpc_slice_hash_table_cmp. If NULL, raw pointer (\a GPR_ICMP) comparison
will be used. */
grpc_slice_hash_table* grpc_slice_hash_table_create(
size_t num_entries, grpc_slice_hash_table_entry* entries,
void (*destroy_value)(void* value), int (*value_cmp)(void* a, void* b));
grpc_slice_hash_table* grpc_slice_hash_table_ref(grpc_slice_hash_table* table);
void grpc_slice_hash_table_unref(grpc_slice_hash_table* table);
/** Returns the value from \a table associated with \a key.
Returns NULL if \a key is not found. */
void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table,
const grpc_slice key);
/** Compares \a a vs. \a b.
* A table is considered "smaller" (resp. "greater") if:
* - GPR_ICMP(a->value_cmp, b->value_cmp) < 1 (resp. > 1),
* - else, it contains fewer (resp. more) entries,
* - else, if strcmp(a_key, b_key) < 1 (resp. > 1),
* - else, if value_cmp(a_value, b_value) < 1 (resp. > 1). */
int grpc_slice_hash_table_cmp(const grpc_slice_hash_table* a,
const grpc_slice_hash_table* b);
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_SLICE_SLICE_HASH_TABLE_H */

@ -31,74 +31,30 @@
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
// The main purpose of the code here is to parse the service config in
// JSON form, which will look like this:
//
// {
// "loadBalancingPolicy": "string", // optional
// "methodConfig": [ // array of one or more method_config objects
// {
// "name": [ // array of one or more name objects
// {
// "service": "string", // required
// "method": "string", // optional
// }
// ],
// // remaining fields are optional.
// // see https://developers.google.com/protocol-buffers/docs/proto3#json
// // for format details.
// "waitForReady": bool,
// "timeout": "duration_string",
// "maxRequestMessageBytes": "int64_string",
// "maxResponseMessageBytes": "int64_string",
// }
// ]
// }
struct grpc_service_config {
char* json_string; // Underlying storage for json_tree.
grpc_json* json_tree;
};
namespace grpc_core {
grpc_service_config* grpc_service_config_create(const char* json_string) {
grpc_service_config* service_config =
static_cast<grpc_service_config*>(gpr_malloc(sizeof(*service_config)));
service_config->json_string = gpr_strdup(json_string);
service_config->json_tree =
grpc_json_parse_string(service_config->json_string);
if (service_config->json_tree == nullptr) {
UniquePtr<ServiceConfig> ServiceConfig::Create(const char* json) {
UniquePtr<char> json_string(gpr_strdup(json));
grpc_json* json_tree = grpc_json_parse_string(json_string.get());
if (json_tree == nullptr) {
gpr_log(GPR_INFO, "failed to parse JSON for service config");
gpr_free(service_config->json_string);
gpr_free(service_config);
return nullptr;
}
return service_config;
return MakeUnique<ServiceConfig>(std::move(json_string), json_tree);
}
void grpc_service_config_destroy(grpc_service_config* service_config) {
grpc_json_destroy(service_config->json_tree);
gpr_free(service_config->json_string);
gpr_free(service_config);
}
ServiceConfig::ServiceConfig(UniquePtr<char> json_string, grpc_json* json_tree)
: json_string_(std::move(json_string)), json_tree_(json_tree) {}
void grpc_service_config_parse_global_params(
const grpc_service_config* service_config,
void (*process_json)(const grpc_json* json, void* arg), void* arg) {
const grpc_json* json = service_config->json_tree;
if (json->type != GRPC_JSON_OBJECT || json->key != nullptr) return;
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
if (field->key == nullptr) return;
if (strcmp(field->key, "methodConfig") == 0) continue;
process_json(field, arg);
}
}
ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); }
const char* grpc_service_config_get_lb_policy_name(
const grpc_service_config* service_config) {
const grpc_json* json = service_config->json_tree;
if (json->type != GRPC_JSON_OBJECT || json->key != nullptr) return nullptr;
const char* ServiceConfig::GetLoadBalancingPolicyName() const {
if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) {
return nullptr;
}
const char* lb_policy_name = nullptr;
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
for (grpc_json* field = json_tree_->child; field != nullptr;
field = field->next) {
if (field->key == nullptr) return nullptr;
if (strcmp(field->key, "loadBalancingPolicy") == 0) {
if (lb_policy_name != nullptr) return nullptr; // Duplicate.
@ -109,8 +65,7 @@ const char* grpc_service_config_get_lb_policy_name(
return lb_policy_name;
}
// Returns the number of names specified in the method config \a json.
static size_t count_names_in_method_config_json(grpc_json* json) {
size_t ServiceConfig::CountNamesInMethodConfig(grpc_json* json) {
size_t num_names = 0;
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
if (field->key != nullptr && strcmp(field->key, "name") == 0) {
@ -124,9 +79,7 @@ static size_t count_names_in_method_config_json(grpc_json* json) {
return num_names;
}
// Returns a path string for the JSON name object specified by \a json.
// Returns NULL on error. Caller takes ownership of result.
static char* parse_json_method_name(grpc_json* json) {
UniquePtr<char> ServiceConfig::ParseJsonMethodName(grpc_json* json) {
if (json->type != GRPC_JSON_OBJECT) return nullptr;
const char* service_name = nullptr;
const char* method_name = nullptr;
@ -147,116 +100,7 @@ static char* parse_json_method_name(grpc_json* json) {
char* path;
gpr_asprintf(&path, "/%s/%s", service_name,
method_name == nullptr ? "*" : method_name);
return path;
return UniquePtr<char>(path);
}
// Parses the method config from \a json. Adds an entry to \a entries for
// each name found, incrementing \a idx for each entry added.
// Returns false on error.
static bool parse_json_method_config(
grpc_json* json, void* (*create_value)(const grpc_json* method_config_json),
void* (*ref_value)(void* value), void (*unref_value)(void* value),
grpc_slice_hash_table_entry* entries, size_t* idx) {
// Construct value.
void* method_config = create_value(json);
if (method_config == nullptr) return false;
// Construct list of paths.
bool success = false;
gpr_strvec paths;
gpr_strvec_init(&paths);
for (grpc_json* child = json->child; child != nullptr; child = child->next) {
if (child->key == nullptr) continue;
if (strcmp(child->key, "name") == 0) {
if (child->type != GRPC_JSON_ARRAY) goto done;
for (grpc_json* name = child->child; name != nullptr; name = name->next) {
char* path = parse_json_method_name(name);
if (path == nullptr) goto done;
gpr_strvec_add(&paths, path);
}
}
}
if (paths.count == 0) goto done; // No names specified.
// Add entry for each path.
for (size_t i = 0; i < paths.count; ++i) {
entries[*idx].key = grpc_slice_from_copied_string(paths.strs[i]);
entries[*idx].value = ref_value(method_config);
++*idx;
}
success = true;
done:
unref_value(method_config);
gpr_strvec_destroy(&paths);
return success;
}
grpc_slice_hash_table* grpc_service_config_create_method_config_table(
const grpc_service_config* service_config,
void* (*create_value)(const grpc_json* method_config_json),
void* (*ref_value)(void* value), void (*unref_value)(void* value)) {
const grpc_json* json = service_config->json_tree;
// Traverse parsed JSON tree.
if (json->type != GRPC_JSON_OBJECT || json->key != nullptr) return nullptr;
size_t num_entries = 0;
grpc_slice_hash_table_entry* entries = nullptr;
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
if (field->key == nullptr) return nullptr;
if (strcmp(field->key, "methodConfig") == 0) {
if (entries != nullptr) return nullptr; // Duplicate.
if (field->type != GRPC_JSON_ARRAY) return nullptr;
// Find number of entries.
for (grpc_json* method = field->child; method != nullptr;
method = method->next) {
size_t count = count_names_in_method_config_json(method);
if (count <= 0) return nullptr;
num_entries += count;
}
// Populate method config table entries.
entries = static_cast<grpc_slice_hash_table_entry*>(
gpr_malloc(num_entries * sizeof(grpc_slice_hash_table_entry)));
size_t idx = 0;
for (grpc_json* method = field->child; method != nullptr;
method = method->next) {
if (!parse_json_method_config(method, create_value, ref_value,
unref_value, entries, &idx)) {
for (size_t i = 0; i < idx; ++i) {
grpc_slice_unref_internal(entries[i].key);
unref_value(entries[i].value);
}
gpr_free(entries);
return nullptr;
}
}
GPR_ASSERT(idx == num_entries);
}
}
// Instantiate method config table.
grpc_slice_hash_table* method_config_table = nullptr;
if (entries != nullptr) {
method_config_table = grpc_slice_hash_table_create(num_entries, entries,
unref_value, nullptr);
gpr_free(entries);
}
return method_config_table;
}
void* grpc_method_config_table_get(const grpc_slice_hash_table* table,
grpc_slice path) {
void* value = grpc_slice_hash_table_get(table, path);
// If we didn't find a match for the path, try looking for a wildcard
// entry (i.e., change "/service/method" to "/service/*").
if (value == nullptr) {
char* path_str = grpc_slice_to_c_string(path);
const char* sep = strrchr(path_str, '/') + 1;
const size_t len = static_cast<size_t>(sep - path_str);
char* buf = static_cast<char*>(gpr_malloc(len + 2)); // '*' and NUL
memcpy(buf, path_str, len);
buf[len] = '*';
buf[len + 1] = '\0';
grpc_slice wildcard_path = grpc_slice_from_copied_string(buf);
gpr_free(buf);
value = grpc_slice_hash_table_get(table, wildcard_path);
grpc_slice_unref_internal(wildcard_path);
gpr_free(path_str);
}
return value;
}
} // namespace grpc_core

@ -20,44 +20,230 @@
#include <grpc/support/port_platform.h>
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gprpp/inlined_vector.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/slice/slice_hash_table.h"
typedef struct grpc_service_config grpc_service_config;
grpc_service_config* grpc_service_config_create(const char* json_string);
void grpc_service_config_destroy(grpc_service_config* service_config);
/// Invokes \a process_json() for each global parameter in the service
/// config. \a arg is passed as the second argument to \a process_json().
void grpc_service_config_parse_global_params(
const grpc_service_config* service_config,
void (*process_json)(const grpc_json* json, void* arg), void* arg);
/// Gets the LB policy name from \a service_config.
/// Returns NULL if no LB policy name was specified.
/// Caller does NOT take ownership.
const char* grpc_service_config_get_lb_policy_name(
const grpc_service_config* service_config);
/// Creates a method config table based on the data in \a json.
/// The table's keys are request paths. The table's value type is
/// returned by \a create_value(), based on data parsed from the JSON tree.
/// \a ref_value() and \a unref_value() are used to ref and unref values.
/// Returns NULL on error.
grpc_slice_hash_table* grpc_service_config_create_method_config_table(
const grpc_service_config* service_config,
void* (*create_value)(const grpc_json* method_config_json),
void* (*ref_value)(void* value), void (*unref_value)(void* value));
/// A helper function for looking up values in the table returned by
/// \a grpc_service_config_create_method_config_table().
/// Gets the method config for the specified \a path, which should be of
/// the form "/service/method".
/// Returns NULL if the method has no config.
/// Caller does NOT own a reference to the result.
void* grpc_method_config_table_get(const grpc_slice_hash_table* table,
grpc_slice path);
// The main purpose of the code here is to parse the service config in
// JSON form, which will look like this:
//
// {
// "loadBalancingPolicy": "string", // optional
// "methodConfig": [ // array of one or more method_config objects
// {
// "name": [ // array of one or more name objects
// {
// "service": "string", // required
// "method": "string", // optional
// }
// ],
// // remaining fields are optional.
// // see
// https://developers.google.com/protocol-buffers/docs/proto3#json
// // for format details.
// "waitForReady": bool,
// "timeout": "duration_string",
// "maxRequestMessageBytes": "int64_string",
// "maxResponseMessageBytes": "int64_string",
// }
// ]
// }
namespace grpc_core {
class ServiceConfig {
public:
/// Creates a new service config from parsing \a json_string.
/// Returns null on parse error.
static UniquePtr<ServiceConfig> Create(const char* json);
~ServiceConfig();
/// Invokes \a process_json() for each global parameter in the service
/// config. \a arg is passed as the second argument to \a process_json().
template <typename T>
using ProcessJson = void (*)(const grpc_json*, T*);
template <typename T>
void ParseGlobalParams(ProcessJson<T> process_json, T* arg) const;
/// Gets the LB policy name from \a service_config.
/// Returns NULL if no LB policy name was specified.
/// Caller does NOT take ownership.
const char* GetLoadBalancingPolicyName() const;
/// Creates a method config table based on the data in \a json.
/// The table's keys are request paths. The table's value type is
/// returned by \a create_value(), based on data parsed from the JSON tree.
/// Returns null on error.
template <typename T>
using CreateValue = RefCountedPtr<T> (*)(const grpc_json* method_config_json);
template <typename T>
RefCountedPtr<SliceHashTable<RefCountedPtr<T>>> CreateMethodConfigTable(
CreateValue<T> create_value);
/// A helper function for looking up values in the table returned by
/// \a CreateMethodConfigTable().
/// Gets the method config for the specified \a path, which should be of
/// the form "/service/method".
/// Returns null if the method has no config.
/// Caller does NOT own a reference to the result.
template <typename T>
static RefCountedPtr<T> MethodConfigTableLookup(
const SliceHashTable<RefCountedPtr<T>>& table, grpc_slice path);
private:
// So New() can call our private ctor.
template <typename T, typename... Args>
friend T* New(Args&&... args);
// Takes ownership of \a json_tree.
ServiceConfig(UniquePtr<char> json_string, grpc_json* json_tree);
// Returns the number of names specified in the method config \a json.
static size_t CountNamesInMethodConfig(grpc_json* json);
// Returns a path string for the JSON name object specified by \a json.
// Returns null on error.
static UniquePtr<char> ParseJsonMethodName(grpc_json* json);
// Parses the method config from \a json. Adds an entry to \a entries for
// each name found, incrementing \a idx for each entry added.
// Returns false on error.
template <typename T>
static bool ParseJsonMethodConfig(
grpc_json* json, CreateValue<T> create_value,
typename SliceHashTable<RefCountedPtr<T>>::Entry* entries, size_t* idx);
UniquePtr<char> json_string_; // Underlying storage for json_tree.
grpc_json* json_tree_;
};
//
// implementation -- no user-serviceable parts below
//
template <typename T>
void ServiceConfig::ParseGlobalParams(ProcessJson<T> process_json,
T* arg) const {
if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) {
return;
}
for (grpc_json* field = json_tree_->child; field != nullptr;
field = field->next) {
if (field->key == nullptr) return;
if (strcmp(field->key, "methodConfig") == 0) continue;
process_json(field, arg);
}
}
template <typename T>
bool ServiceConfig::ParseJsonMethodConfig(
grpc_json* json, CreateValue<T> create_value,
typename SliceHashTable<RefCountedPtr<T>>::Entry* entries, size_t* idx) {
// Construct value.
RefCountedPtr<T> method_config = create_value(json);
if (method_config == nullptr) return false;
// Construct list of paths.
InlinedVector<UniquePtr<char>, 10> paths;
for (grpc_json* child = json->child; child != nullptr; child = child->next) {
if (child->key == nullptr) continue;
if (strcmp(child->key, "name") == 0) {
if (child->type != GRPC_JSON_ARRAY) return false;
for (grpc_json* name = child->child; name != nullptr; name = name->next) {
UniquePtr<char> path = ParseJsonMethodName(name);
if (path == nullptr) return false;
paths.push_back(std::move(path));
}
}
}
if (paths.size() == 0) return false; // No names specified.
// Add entry for each path.
for (size_t i = 0; i < paths.size(); ++i) {
entries[*idx].key = grpc_slice_from_copied_string(paths[i].get());
entries[*idx].value = method_config; // Takes a new ref.
++*idx;
}
// Success.
return true;
}
template <typename T>
RefCountedPtr<SliceHashTable<RefCountedPtr<T>>>
ServiceConfig::CreateMethodConfigTable(CreateValue<T> create_value) {
// Traverse parsed JSON tree.
if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) {
return nullptr;
}
size_t num_entries = 0;
typename SliceHashTable<RefCountedPtr<T>>::Entry* entries = nullptr;
for (grpc_json* field = json_tree_->child; field != nullptr;
field = field->next) {
if (field->key == nullptr) return nullptr;
if (strcmp(field->key, "methodConfig") == 0) {
if (entries != nullptr) return nullptr; // Duplicate.
if (field->type != GRPC_JSON_ARRAY) return nullptr;
// Find number of entries.
for (grpc_json* method = field->child; method != nullptr;
method = method->next) {
size_t count = CountNamesInMethodConfig(method);
if (count <= 0) return nullptr;
num_entries += count;
}
// Populate method config table entries.
entries = static_cast<typename SliceHashTable<RefCountedPtr<T>>::Entry*>(
gpr_zalloc(num_entries *
sizeof(typename SliceHashTable<RefCountedPtr<T>>::Entry)));
size_t idx = 0;
for (grpc_json* method = field->child; method != nullptr;
method = method->next) {
if (!ParseJsonMethodConfig(method, create_value, entries, &idx)) {
for (size_t i = 0; i < idx; ++i) {
grpc_slice_unref_internal(entries[i].key);
entries[i].value.reset();
}
gpr_free(entries);
return nullptr;
}
}
GPR_ASSERT(idx == num_entries);
}
}
// Instantiate method config table.
RefCountedPtr<SliceHashTable<RefCountedPtr<T>>> method_config_table;
if (entries != nullptr) {
method_config_table =
SliceHashTable<RefCountedPtr<T>>::Create(num_entries, entries, nullptr);
gpr_free(entries);
}
return method_config_table;
}
template <typename T>
RefCountedPtr<T> ServiceConfig::MethodConfigTableLookup(
const SliceHashTable<RefCountedPtr<T>>& table, grpc_slice path) {
const RefCountedPtr<T>* value = table.Get(path);
// If we didn't find a match for the path, try looking for a wildcard
// entry (i.e., change "/service/method" to "/service/*").
if (value == nullptr) {
char* path_str = grpc_slice_to_c_string(path);
const char* sep = strrchr(path_str, '/') + 1;
const size_t len = (size_t)(sep - path_str);
char* buf = (char*)gpr_malloc(len + 2); // '*' and NUL
memcpy(buf, path_str, len);
buf[len] = '*';
buf[len + 1] = '\0';
grpc_slice wildcard_path = grpc_slice_from_copied_string(buf);
gpr_free(buf);
value = table.Get(wildcard_path);
grpc_slice_unref_internal(wildcard_path);
gpr_free(path_str);
}
return RefCountedPtr<T>(*value);
}
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H */

@ -156,7 +156,6 @@ CORE_SOURCE_FILES = [
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@ -236,10 +235,10 @@ CORE_SOURCE_FILES = [
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
'src/core/lib/security/security_connector/security_connector.cc',
'src/core/lib/security/transport/client_auth_filter.cc',
'src/core/lib/security/transport/lb_targets_info.cc',
'src/core/lib/security/transport/secure_endpoint.cc',
'src/core/lib/security/transport/security_handshaker.cc',
'src/core/lib/security/transport/server_auth_filter.cc',
'src/core/lib/security/transport/target_authority_table.cc',
'src/core/lib/security/transport/tsi_error.cc',
'src/core/lib/security/util/json_util.cc',
'src/core/lib/surface/init_secure.cc',
@ -262,6 +261,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',

@ -87,6 +87,9 @@ grpc_cc_test(
srcs = ["slice_hash_table_test.cc"],
deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
language = "C++",
external_deps = [
"gtest",
],
)
grpc_cc_test(

@ -20,6 +20,10 @@
#include <string.h>
#include <vector>
#include <gtest/gtest.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
@ -27,56 +31,55 @@
#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/test_config.h"
typedef struct {
const char* key;
const char* value;
} test_entry;
namespace grpc_core {
namespace {
static void populate_entries(const test_entry* input, size_t num_entries,
grpc_slice_hash_table_entry* output) {
for (size_t i = 0; i < num_entries; ++i) {
output[i].key = grpc_slice_from_copied_string(input[i].key);
output[i].value = gpr_strdup(input[i].value);
}
}
typedef SliceHashTable<UniquePtr<char>> TestHashTable;
static void check_values(const test_entry* input, size_t num_entries,
grpc_slice_hash_table* table) {
for (size_t i = 0; i < num_entries; ++i) {
grpc_slice key = grpc_slice_from_static_string(input[i].key);
const char* actual =
static_cast<const char*>(grpc_slice_hash_table_get(table, key));
GPR_ASSERT(actual != nullptr);
GPR_ASSERT(strcmp(actual, input[i].value) == 0);
struct TestEntry {
const char* key;
const char* value;
};
void CheckValues(const std::vector<TestEntry>& input,
const TestHashTable& table) {
for (const TestEntry& expected : input) {
grpc_slice key = grpc_slice_from_static_string(expected.key);
const UniquePtr<char>* actual = table.Get(key);
ASSERT_NE(actual, nullptr);
EXPECT_STREQ(expected.value, actual->get());
grpc_slice_unref(key);
}
}
static void check_non_existent_value(const char* key_string,
grpc_slice_hash_table* table) {
void CheckNonExistentValue(const char* key_string, const TestHashTable& table) {
grpc_slice key = grpc_slice_from_static_string(key_string);
GPR_ASSERT(grpc_slice_hash_table_get(table, key) == nullptr);
ASSERT_EQ(nullptr, table.Get(key));
grpc_slice_unref(key);
}
static void destroy_string(void* value) { gpr_free(value); }
static grpc_slice_hash_table* create_table_from_entries(
const test_entry* test_entries, size_t num_test_entries,
int (*value_cmp_fn)(void*, void*)) {
// Construct table.
grpc_slice_hash_table_entry* entries =
static_cast<grpc_slice_hash_table_entry*>(
gpr_zalloc(sizeof(*entries) * num_test_entries));
populate_entries(test_entries, num_test_entries, entries);
grpc_slice_hash_table* table = grpc_slice_hash_table_create(
num_test_entries, entries, destroy_string, value_cmp_fn);
void PopulateEntries(const std::vector<TestEntry>& input,
TestHashTable::Entry* output) {
for (size_t i = 0; i < input.size(); ++i) {
output[i].key = grpc_slice_from_copied_string(input[i].key);
output[i].value = UniquePtr<char>(gpr_strdup(input[i].value));
}
}
RefCountedPtr<TestHashTable> CreateTableFromEntries(
const std::vector<TestEntry>& test_entries,
TestHashTable::ValueCmp value_cmp) {
TestHashTable::Entry* entries = static_cast<TestHashTable::Entry*>(
gpr_zalloc(sizeof(*entries) * test_entries.size()));
PopulateEntries(test_entries, entries);
RefCountedPtr<TestHashTable> table =
TestHashTable::Create(test_entries.size(), entries, value_cmp);
gpr_free(entries);
return table;
}
static void test_slice_hash_table() {
const test_entry test_entries[] = {
TEST(SliceHashTable, Basic) {
const std::vector<TestEntry> test_entries = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"},
{"key_3", "value_3"}, {"key_4", "value_4"}, {"key_5", "value_5"},
{"key_6", "value_6"}, {"key_7", "value_7"}, {"key_8", "value_8"},
@ -112,129 +115,110 @@ static void test_slice_hash_table() {
{"key_96", "value_96"}, {"key_97", "value_97"}, {"key_98", "value_98"},
{"key_99", "value_99"},
};
const size_t num_entries = GPR_ARRAY_SIZE(test_entries);
grpc_slice_hash_table* table =
create_table_from_entries(test_entries, num_entries, nullptr);
RefCountedPtr<TestHashTable> table =
CreateTableFromEntries(test_entries, nullptr);
// Check contents of table.
check_values(test_entries, num_entries, table);
check_non_existent_value("XX", table);
// Clean up.
grpc_core::ExecCtx exec_ctx;
grpc_slice_hash_table_unref(table);
CheckValues(test_entries, *table);
CheckNonExistentValue("XX", *table);
}
static int value_cmp_fn(void* a, void* b) {
const char* a_str = static_cast<const char*>(a);
const char* b_str = static_cast<const char*>(b);
return strcmp(a_str, b_str);
int StringCmp(const UniquePtr<char>& a, const UniquePtr<char>& b) {
return strcmp(a.get(), b.get());
}
static int pointer_cmp_fn(void* a, void* b) { return GPR_ICMP(a, b); }
int PointerCmp(const UniquePtr<char>& a, const UniquePtr<char>& b) {
return GPR_ICMP(a.get(), b.get());
}
static void test_slice_hash_table_eq() {
const test_entry test_entries_a[] = {
TEST(SliceHashTable, CmpEqual) {
const std::vector<TestEntry> test_entries_a = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
const size_t num_entries_a = GPR_ARRAY_SIZE(test_entries_a);
grpc_slice_hash_table* table_a =
create_table_from_entries(test_entries_a, num_entries_a, value_cmp_fn);
GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_a) == 0);
const test_entry test_entries_b[] = {
RefCountedPtr<TestHashTable> table_a =
CreateTableFromEntries(test_entries_a, StringCmp);
const std::vector<TestEntry> test_entries_b = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
const size_t num_entries_b = GPR_ARRAY_SIZE(test_entries_b);
grpc_slice_hash_table* table_b =
create_table_from_entries(test_entries_b, num_entries_b, value_cmp_fn);
GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_b) == 0);
grpc_core::ExecCtx exec_ctx;
grpc_slice_hash_table_unref(table_a);
grpc_slice_hash_table_unref(table_b);
RefCountedPtr<TestHashTable> table_b =
CreateTableFromEntries(test_entries_b, StringCmp);
// table_a equals itself.
EXPECT_EQ(0, TestHashTable::Cmp(*table_a, *table_a));
// table_a equals table_b.
EXPECT_EQ(0, TestHashTable::Cmp(*table_a, *table_b));
}
static void test_slice_hash_table_not_eq() {
const test_entry test_entries_a[] = {
TEST(SliceHashTable, CmpDifferentSizes) {
// table_a has 3 entries, table_b has only 2.
const std::vector<TestEntry> test_entries_a = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
const size_t num_entries_a = GPR_ARRAY_SIZE(test_entries_a);
grpc_slice_hash_table* table_a =
create_table_from_entries(test_entries_a, num_entries_a, value_cmp_fn);
// Different sizes.
const test_entry test_entries_b_smaller[] = {{"key_0", "value_0"},
{"key_1", "value_1"}};
const size_t num_entries_b_smaller = GPR_ARRAY_SIZE(test_entries_b_smaller);
grpc_slice_hash_table* table_b_smaller = create_table_from_entries(
test_entries_b_smaller, num_entries_b_smaller, value_cmp_fn);
GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_b_smaller) > 0);
const test_entry test_entries_b_larger[] = {{"key_0", "value_0"},
{"key_1", "value_1"},
{"key_2", "value_2"},
{"key_3", "value_3"}};
const size_t num_entries_b_larger = GPR_ARRAY_SIZE(test_entries_b_larger);
grpc_slice_hash_table* table_b_larger = create_table_from_entries(
test_entries_b_larger, num_entries_b_larger, value_cmp_fn);
GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_b_larger) < 0);
RefCountedPtr<TestHashTable> table_a =
CreateTableFromEntries(test_entries_a, StringCmp);
const std::vector<TestEntry> test_entries_b = {{"key_0", "value_0"},
{"key_1", "value_1"}};
RefCountedPtr<TestHashTable> table_b =
CreateTableFromEntries(test_entries_b, StringCmp);
EXPECT_GT(TestHashTable::Cmp(*table_a, *table_b), 0);
EXPECT_LT(TestHashTable::Cmp(*table_b, *table_a), 0);
}
TEST(SliceHashTable, CmpDifferentKey) {
// One key doesn't match and is lexicographically "smaller".
const test_entry test_entries_c[] = {
const std::vector<TestEntry> test_entries_a = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
RefCountedPtr<TestHashTable> table_a =
CreateTableFromEntries(test_entries_a, StringCmp);
const std::vector<TestEntry> test_entries_b = {
{"key_zz", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
const size_t num_entries_c = GPR_ARRAY_SIZE(test_entries_c);
grpc_slice_hash_table* table_c =
create_table_from_entries(test_entries_c, num_entries_c, value_cmp_fn);
GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_c) > 0);
GPR_ASSERT(grpc_slice_hash_table_cmp(table_c, table_a) < 0);
RefCountedPtr<TestHashTable> table_b =
CreateTableFromEntries(test_entries_b, StringCmp);
EXPECT_GT(TestHashTable::Cmp(*table_a, *table_b), 0);
EXPECT_LT(TestHashTable::Cmp(*table_b, *table_a), 0);
}
TEST(SliceHashTable, CmpDifferentValue) {
// One value doesn't match.
const test_entry test_entries_d[] = {
const std::vector<TestEntry> test_entries_a = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
RefCountedPtr<TestHashTable> table_a =
CreateTableFromEntries(test_entries_a, StringCmp);
const std::vector<TestEntry> test_entries_b = {
{"key_0", "value_z"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
const size_t num_entries_d = GPR_ARRAY_SIZE(test_entries_d);
grpc_slice_hash_table* table_d =
create_table_from_entries(test_entries_d, num_entries_d, value_cmp_fn);
GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_d) < 0);
GPR_ASSERT(grpc_slice_hash_table_cmp(table_d, table_a) > 0);
RefCountedPtr<TestHashTable> table_b =
CreateTableFromEntries(test_entries_b, StringCmp);
EXPECT_LT(TestHashTable::Cmp(*table_a, *table_b), 0);
EXPECT_GT(TestHashTable::Cmp(*table_b, *table_a), 0);
}
TEST(SliceHashTable, CmpDifferentCmpFunctions) {
// Same values but different "equals" functions.
const test_entry test_entries_e[] = {
const std::vector<TestEntry> test_entries_a = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
const size_t num_entries_e = GPR_ARRAY_SIZE(test_entries_e);
grpc_slice_hash_table* table_e =
create_table_from_entries(test_entries_e, num_entries_e, value_cmp_fn);
const test_entry test_entries_f[] = {
RefCountedPtr<TestHashTable> table_a =
CreateTableFromEntries(test_entries_a, StringCmp);
const std::vector<TestEntry> test_entries_b = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
const size_t num_entries_f = GPR_ARRAY_SIZE(test_entries_f);
grpc_slice_hash_table* table_f =
create_table_from_entries(test_entries_f, num_entries_f, pointer_cmp_fn);
GPR_ASSERT(grpc_slice_hash_table_cmp(table_e, table_f) != 0);
RefCountedPtr<TestHashTable> table_b =
CreateTableFromEntries(test_entries_b, PointerCmp);
EXPECT_NE(TestHashTable::Cmp(*table_a, *table_b), 0);
}
TEST(SliceHashTable, CmpEmptyKeysDifferentValue) {
// Same (empty) key, different values.
const test_entry test_entries_g[] = {{"", "value_0"}};
const size_t num_entries_g = GPR_ARRAY_SIZE(test_entries_g);
grpc_slice_hash_table* table_g =
create_table_from_entries(test_entries_g, num_entries_g, value_cmp_fn);
const test_entry test_entries_h[] = {{"", "value_1"}};
const size_t num_entries_h = GPR_ARRAY_SIZE(test_entries_h);
grpc_slice_hash_table* table_h =
create_table_from_entries(test_entries_h, num_entries_h, pointer_cmp_fn);
GPR_ASSERT(grpc_slice_hash_table_cmp(table_g, table_h) != 0);
grpc_core::ExecCtx exec_ctx;
grpc_slice_hash_table_unref(table_a);
grpc_slice_hash_table_unref(table_b_larger);
grpc_slice_hash_table_unref(table_b_smaller);
grpc_slice_hash_table_unref(table_c);
grpc_slice_hash_table_unref(table_d);
grpc_slice_hash_table_unref(table_e);
grpc_slice_hash_table_unref(table_f);
grpc_slice_hash_table_unref(table_g);
grpc_slice_hash_table_unref(table_h);
const std::vector<TestEntry> test_entries_a = {{"", "value_0"}};
RefCountedPtr<TestHashTable> table_a =
CreateTableFromEntries(test_entries_a, StringCmp);
const std::vector<TestEntry> test_entries_b = {{"", "value_1"}};
RefCountedPtr<TestHashTable> table_b =
CreateTableFromEntries(test_entries_b, PointerCmp);
EXPECT_NE(TestHashTable::Cmp(*table_a, *table_b), 0);
}
} // namespace
} // namespace grpc_core
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc_test_init(argc, argv);
grpc_core::ExecCtx::GlobalInit();
test_slice_hash_table();
test_slice_hash_table_eq();
test_slice_hash_table_not_eq();
int result = RUN_ALL_TESTS();
grpc_core::ExecCtx::GlobalShutdown();
return 0;
return result;
}

@ -901,6 +901,8 @@ src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_factory.h \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/lb_policy_registry.h \
src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/method_params.h \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/parse_address.h \
src/core/ext/filters/client_channel/proxy_mapper.cc \
@ -1309,13 +1311,13 @@ src/core/lib/security/security_connector/security_connector.cc \
src/core/lib/security/security_connector/security_connector.h \
src/core/lib/security/transport/auth_filters.h \
src/core/lib/security/transport/client_auth_filter.cc \
src/core/lib/security/transport/lb_targets_info.cc \
src/core/lib/security/transport/lb_targets_info.h \
src/core/lib/security/transport/secure_endpoint.cc \
src/core/lib/security/transport/secure_endpoint.h \
src/core/lib/security/transport/security_handshaker.cc \
src/core/lib/security/transport/security_handshaker.h \
src/core/lib/security/transport/server_auth_filter.cc \
src/core/lib/security/transport/target_authority_table.cc \
src/core/lib/security/transport/target_authority_table.h \
src/core/lib/security/transport/tsi_error.cc \
src/core/lib/security/transport/tsi_error.h \
src/core/lib/security/util/json_util.cc \
@ -1326,7 +1328,6 @@ src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/percent_encoding.h \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_hash_table.h \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_internal.h \

@ -1954,23 +1954,6 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c",
"name": "slice_hash_table_test",
"src": [
"test/core/slice/slice_hash_table_test.cc"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
@ -4170,6 +4153,23 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c++",
"name": "slice_hash_table_test",
"src": [
"test/core/slice/slice_hash_table_test.cc"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
@ -8577,7 +8577,6 @@
"src/core/lib/slice/percent_encoding.cc",
"src/core/lib/slice/slice.cc",
"src/core/lib/slice/slice_buffer.cc",
"src/core/lib/slice/slice_hash_table.cc",
"src/core/lib/slice/slice_intern.cc",
"src/core/lib/slice/slice_string_helpers.cc",
"src/core/lib/surface/api_trace.cc",
@ -8921,6 +8920,7 @@
"src/core/ext/filters/client_channel/lb_policy.h",
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
"src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.h",
"src/core/ext/filters/client_channel/proxy_mapper_registry.h",
@ -8956,6 +8956,8 @@
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.cc",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
"src/core/ext/filters/client_channel/method_params.cc",
"src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.cc",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.cc",
@ -9308,9 +9310,9 @@
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/security_connector/security_connector.h",
"src/core/lib/security/transport/auth_filters.h",
"src/core/lib/security/transport/lb_targets_info.h",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/security_handshaker.h",
"src/core/lib/security/transport/target_authority_table.h",
"src/core/lib/security/transport/tsi_error.h",
"src/core/lib/security/util/json_util.h"
],
@ -9350,13 +9352,13 @@
"src/core/lib/security/security_connector/security_connector.h",
"src/core/lib/security/transport/auth_filters.h",
"src/core/lib/security/transport/client_auth_filter.cc",
"src/core/lib/security/transport/lb_targets_info.cc",
"src/core/lib/security/transport/lb_targets_info.h",
"src/core/lib/security/transport/secure_endpoint.cc",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/security_handshaker.cc",
"src/core/lib/security/transport/security_handshaker.h",
"src/core/lib/security/transport/server_auth_filter.cc",
"src/core/lib/security/transport/target_authority_table.cc",
"src/core/lib/security/transport/target_authority_table.h",
"src/core/lib/security/transport/tsi_error.cc",
"src/core/lib/security/transport/tsi_error.h",
"src/core/lib/security/util/json_util.cc",

@ -2259,30 +2259,6 @@
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
"name": "slice_hash_table_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
@ -4455,6 +4431,30 @@
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "slice_hash_table_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save