Merge remote-tracking branch 'upstream/master' into no_backup_poller

Also, fix a segfault issue on g_event_engine when using a custom iomgr.
pull/19454/head
Guantao Liu 6 years ago
commit da56330cd6
  1. 9
      BUILD
  2. 9
      BUILD.gn
  3. 164
      CMakeLists.txt
  4. 116
      Makefile
  5. 2
      WORKSPACE
  6. 6
      bazel/generate_cc.bzl
  7. 6
      bazel/python_rules.bzl
  8. 36
      build.yaml
  9. 2
      config.m4
  10. 2
      config.w32
  11. 2
      doc/statuscodes.md
  12. 65
      examples/python/auth/BUILD.bazel
  13. 112
      examples/python/auth/README.md
  14. 31
      examples/python/auth/_credentials.py
  15. 19
      examples/python/auth/credentials/localhost.crt
  16. 27
      examples/python/auth/credentials/localhost.key
  17. 20
      examples/python/auth/credentials/root.crt
  18. 105
      examples/python/auth/customized_auth_client.py
  19. 110
      examples/python/auth/customized_auth_server.py
  20. 56
      examples/python/auth/test/_auth_example_test.py
  21. 7
      gRPC-C++.podspec
  22. 8
      gRPC-Core.podspec
  23. 1
      grpc.def
  24. 5
      grpc.gemspec
  25. 2
      grpc.gyp
  26. 25
      include/grpc/grpc_security.h
  27. 24
      include/grpcpp/completion_queue_impl.h
  28. 1
      include/grpcpp/impl/codegen/server_interface.h
  29. 1
      include/grpcpp/server_impl.h
  30. 5
      package.xml
  31. 25
      src/core/ext/filters/client_channel/client_channel_channelz.cc
  32. 17
      src/core/ext/filters/client_channel/client_channel_channelz.h
  33. 19
      src/core/ext/filters/client_channel/http_proxy.cc
  34. 1
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  35. 1
      src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
  36. 55
      src/core/ext/filters/client_channel/parse_address.cc
  37. 4
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  38. 480
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
  39. 95
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
  40. 1
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
  41. 1
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
  42. 4
      src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
  43. 1
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
  44. 1
      src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
  45. 27
      src/core/ext/filters/client_channel/subchannel.cc
  46. 8
      src/core/ext/filters/client_channel/subchannel.h
  47. 1
      src/core/ext/transport/chttp2/server/chttp2_server.cc
  48. 8
      src/core/ext/transport/chttp2/transport/frame_data.cc
  49. 27
      src/core/ext/transport/chttp2/transport/hpack_encoder.cc
  50. 96
      src/core/ext/transport/chttp2/transport/hpack_parser.cc
  51. 1
      src/core/ext/transport/cronet/transport/cronet_transport.cc
  52. 15
      src/core/lib/channel/channelz.cc
  53. 98
      src/core/lib/gpr/host_port.cc
  54. 9
      src/core/lib/gpr/string.cc
  55. 1
      src/core/lib/gpr/string.h
  56. 105
      src/core/lib/gprpp/host_port.cc
  57. 38
      src/core/lib/gprpp/host_port.h
  58. 143
      src/core/lib/gprpp/string_view.h
  59. 11
      src/core/lib/gprpp/thd.h
  60. 26
      src/core/lib/gprpp/thd_posix.cc
  61. 10
      src/core/lib/gprpp/thd_windows.cc
  62. 4
      src/core/lib/http/httpcli_security_connector.cc
  63. 3
      src/core/lib/iomgr/ev_posix.cc
  64. 5
      src/core/lib/iomgr/executor.cc
  65. 10
      src/core/lib/iomgr/iomgr_posix_cfstream.cc
  66. 1
      src/core/lib/iomgr/iomgr_uv.cc
  67. 35
      src/core/lib/iomgr/resolve_address_custom.cc
  68. 18
      src/core/lib/iomgr/resolve_address_posix.cc
  69. 14
      src/core/lib/iomgr/resolve_address_windows.cc
  70. 8
      src/core/lib/iomgr/sockaddr_utils.cc
  71. 1
      src/core/lib/iomgr/socket_utils_common_posix.cc
  72. 13
      src/core/lib/iomgr/tcp_client_cfstream.cc
  73. 4
      src/core/lib/security/credentials/credentials.h
  74. 8
      src/core/lib/security/credentials/jwt/json_token.cc
  75. 2
      src/core/lib/security/credentials/jwt/json_token.h
  76. 260
      src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
  77. 16
      src/core/lib/security/credentials/oauth2/oauth2_credentials.h
  78. 5
      src/core/lib/security/security_connector/alts/alts_security_connector.cc
  79. 46
      src/core/lib/security/security_connector/fake/fake_security_connector.cc
  80. 5
      src/core/lib/security/security_connector/local/local_security_connector.cc
  81. 2
      src/core/lib/security/security_connector/security_connector.cc
  82. 2
      src/core/lib/security/security_connector/security_connector.h
  83. 38
      src/core/lib/security/security_connector/ssl/ssl_security_connector.cc
  84. 57
      src/core/lib/security/security_connector/ssl_utils.cc
  85. 19
      src/core/lib/security/security_connector/ssl_utils.h
  86. 36
      src/core/lib/security/security_connector/tls/spiffe_security_connector.cc
  87. 7
      src/core/lib/security/security_connector/tls/spiffe_security_connector.h
  88. 3
      src/core/lib/security/transport/client_auth_filter.cc
  89. 24
      src/core/lib/security/util/json_util.cc
  90. 4
      src/core/lib/security/util/json_util.h
  91. 6
      src/core/lib/transport/metadata.h
  92. 172
      src/core/lib/transport/static_metadata.cc
  93. 1
      src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
  94. 78
      src/core/tsi/ssl_transport_security.cc
  95. 3
      src/core/tsi/ssl_transport_security.h
  96. 10
      src/csharp/Grpc.Core/Common.csproj.include
  97. 9
      src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj
  98. 9
      src/csharp/Grpc.Tools/Grpc.Tools.csproj
  99. 3
      src/csharp/Grpc/Grpc.csproj
  100. 5
      src/objective-c/GRPCClient/GRPCCall.m
  101. Some files were not shown because too many files have changed in this diff Show More

@ -222,6 +222,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/channel_impl.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
"include/grpcpp/completion_queue_impl.h",
"include/grpcpp/create_channel.h",
"include/grpcpp/create_channel_impl.h",
"include/grpcpp/create_channel_posix.h",
@ -558,7 +559,6 @@ grpc_cc_library(
"src/core/lib/gpr/env_linux.cc",
"src/core/lib/gpr/env_posix.cc",
"src/core/lib/gpr/env_windows.cc",
"src/core/lib/gpr/host_port.cc",
"src/core/lib/gpr/log.cc",
"src/core/lib/gpr/log_android.cc",
"src/core/lib/gpr/log_linux.cc",
@ -585,6 +585,7 @@ grpc_cc_library(
"src/core/lib/gprpp/arena.cc",
"src/core/lib/gprpp/fork.cc",
"src/core/lib/gprpp/global_config_env.cc",
"src/core/lib/gprpp/host_port.cc",
"src/core/lib/gprpp/thd_posix.cc",
"src/core/lib/gprpp/thd_windows.cc",
"src/core/lib/profiling/basic_timers.cc",
@ -594,7 +595,6 @@ grpc_cc_library(
"src/core/lib/gpr/alloc.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
"src/core/lib/gpr/host_port.h",
"src/core/lib/gpr/mpscq.h",
"src/core/lib/gpr/murmur_hash.h",
"src/core/lib/gpr/spinlock.h",
@ -611,14 +611,16 @@ grpc_cc_library(
"src/core/lib/gprpp/arena.h",
"src/core/lib/gprpp/atomic.h",
"src/core/lib/gprpp/fork.h",
"src/core/lib/gprpp/global_config.h",
"src/core/lib/gprpp/global_config_custom.h",
"src/core/lib/gprpp/global_config_env.h",
"src/core/lib/gprpp/global_config_generic.h",
"src/core/lib/gprpp/global_config.h",
"src/core/lib/gprpp/host_port.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/map.h",
"src/core/lib/gprpp/memory.h",
"src/core/lib/gprpp/pair.h",
"src/core/lib/gprpp/string_view.h",
"src/core/lib/gprpp/sync.h",
"src/core/lib/gprpp/thd.h",
"src/core/lib/profiling/timers.h",
@ -627,6 +629,7 @@ grpc_cc_library(
public_hdrs = GPR_PUBLIC_HDRS,
deps = [
"gpr_codegen",
"grpc_codegen",
],
)

@ -141,8 +141,6 @@ config("grpc_config") {
"src/core/lib/gpr/env_linux.cc",
"src/core/lib/gpr/env_posix.cc",
"src/core/lib/gpr/env_windows.cc",
"src/core/lib/gpr/host_port.cc",
"src/core/lib/gpr/host_port.h",
"src/core/lib/gpr/log.cc",
"src/core/lib/gpr/log_android.cc",
"src/core/lib/gpr/log_linux.cc",
@ -189,6 +187,8 @@ config("grpc_config") {
"src/core/lib/gprpp/global_config_env.cc",
"src/core/lib/gprpp/global_config_env.h",
"src/core/lib/gprpp/global_config_generic.h",
"src/core/lib/gprpp/host_port.cc",
"src/core/lib/gprpp/host_port.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/map.h",
"src/core/lib/gprpp/memory.h",
@ -480,6 +480,7 @@ config("grpc_config") {
"src/core/lib/gprpp/orphanable.h",
"src/core/lib/gprpp/ref_counted.h",
"src/core/lib/gprpp/ref_counted_ptr.h",
"src/core/lib/gprpp/string_view.h",
"src/core/lib/http/format_request.cc",
"src/core/lib/http/format_request.h",
"src/core/lib/http/httpcli.cc",
@ -1028,6 +1029,7 @@ config("grpc_config") {
"include/grpcpp/channel_impl.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
"include/grpcpp/completion_queue_impl.h",
"include/grpcpp/create_channel.h",
"include/grpcpp/create_channel_impl.h",
"include/grpcpp/create_channel_posix.h",
@ -1171,7 +1173,6 @@ config("grpc_config") {
"src/core/lib/gpr/alloc.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
"src/core/lib/gpr/host_port.h",
"src/core/lib/gpr/mpscq.h",
"src/core/lib/gpr/murmur_hash.h",
"src/core/lib/gpr/spinlock.h",
@ -1193,6 +1194,7 @@ config("grpc_config") {
"src/core/lib/gprpp/global_config_custom.h",
"src/core/lib/gprpp/global_config_env.h",
"src/core/lib/gprpp/global_config_generic.h",
"src/core/lib/gprpp/host_port.h",
"src/core/lib/gprpp/inlined_vector.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/map.h",
@ -1202,6 +1204,7 @@ config("grpc_config") {
"src/core/lib/gprpp/pair.h",
"src/core/lib/gprpp/ref_counted.h",
"src/core/lib/gprpp/ref_counted_ptr.h",
"src/core/lib/gprpp/string_view.h",
"src/core/lib/gprpp/sync.h",
"src/core/lib/gprpp/thd.h",
"src/core/lib/http/format_request.h",

@ -275,7 +275,8 @@ add_dependencies(buildtests_c compression_test)
add_dependencies(buildtests_c concurrent_connectivity_test)
add_dependencies(buildtests_c connection_refused_test)
add_dependencies(buildtests_c dns_resolver_connectivity_test)
add_dependencies(buildtests_c dns_resolver_cooldown_test)
add_dependencies(buildtests_c dns_resolver_cooldown_using_ares_resolver_test)
add_dependencies(buildtests_c dns_resolver_cooldown_using_native_resolver_test)
add_dependencies(buildtests_c dns_resolver_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c dualstack_socket_test)
@ -713,6 +714,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx streaming_throughput_test)
endif()
add_dependencies(buildtests_cxx stress_test)
add_dependencies(buildtests_cxx string_view_test)
add_dependencies(buildtests_cxx thread_manager_test)
add_dependencies(buildtests_cxx thread_stress_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@ -861,7 +863,6 @@ add_library(gpr
src/core/lib/gpr/env_linux.cc
src/core/lib/gpr/env_posix.cc
src/core/lib/gpr/env_windows.cc
src/core/lib/gpr/host_port.cc
src/core/lib/gpr/log.cc
src/core/lib/gpr/log_android.cc
src/core/lib/gpr/log_linux.cc
@ -888,6 +889,7 @@ add_library(gpr
src/core/lib/gprpp/arena.cc
src/core/lib/gprpp/fork.cc
src/core/lib/gprpp/global_config_env.cc
src/core/lib/gprpp/host_port.cc
src/core/lib/gprpp/thd_posix.cc
src/core/lib/gprpp/thd_windows.cc
src/core/lib/profiling/basic_timers.cc
@ -1363,6 +1365,9 @@ target_link_libraries(grpc
${_gRPC_ALLTARGETS_LIBRARIES}
gpr
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc/impl/codegen/byte_buffer.h
@ -1761,6 +1766,9 @@ target_link_libraries(grpc_cronet
${_gRPC_ALLTARGETS_LIBRARIES}
gpr
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc_cronet "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc/impl/codegen/byte_buffer.h
@ -2090,6 +2098,9 @@ target_link_libraries(grpc_test_util
gpr
grpc
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc_test_util "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc/support/alloc.h
@ -2420,6 +2431,9 @@ target_link_libraries(grpc_test_util_unsecure
gpr
grpc_unsecure
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc_test_util_unsecure "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc/support/alloc.h
@ -2773,6 +2787,9 @@ target_link_libraries(grpc_unsecure
${_gRPC_ALLTARGETS_LIBRARIES}
gpr
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc_unsecure "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc/impl/codegen/byte_buffer.h
@ -3160,6 +3177,7 @@ foreach(_hdr
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/completion_queue_impl.h
include/grpcpp/create_channel.h
include/grpcpp/create_channel_impl.h
include/grpcpp/create_channel_posix.h
@ -3728,6 +3746,9 @@ target_link_libraries(grpc++_cronet
grpc_cronet
grpc
)
if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
target_link_libraries(grpc++_cronet "-framework CoreFoundation")
endif()
foreach(_hdr
include/grpc++/alarm.h
@ -3781,6 +3802,7 @@ foreach(_hdr
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/completion_queue_impl.h
include/grpcpp/create_channel.h
include/grpcpp/create_channel_impl.h
include/grpcpp/create_channel_posix.h
@ -4780,6 +4802,7 @@ foreach(_hdr
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
include/grpcpp/completion_queue_impl.h
include/grpcpp/create_channel.h
include/grpcpp/create_channel_impl.h
include/grpcpp/create_channel_posix.h
@ -5768,58 +5791,6 @@ endif()
endif (gRPC_BUILD_CSHARP_EXT)
if (gRPC_BUILD_TESTS)
add_library(upb
third_party/upb/google/protobuf/descriptor.upb.c
third_party/upb/upb/decode.c
third_party/upb/upb/def.c
third_party/upb/upb/encode.c
third_party/upb/upb/handlers.c
third_party/upb/upb/msg.c
third_party/upb/upb/msgfactory.c
third_party/upb/upb/sink.c
third_party/upb/upb/table.c
third_party/upb/upb/upb.c
)
if(WIN32 AND MSVC)
set_target_properties(upb PROPERTIES COMPILE_PDB_NAME "upb"
COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
if (gRPC_INSTALL)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/upb.pdb
DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL
)
endif()
endif()
target_include_directories(upb
PUBLIC $<INSTALL_INTERFACE:${gRPC_INSTALL_INCLUDEDIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(upb PROPERTIES LINKER_LANGUAGE C)
# only use the flags for C++ source files
target_compile_options(upb PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
target_link_libraries(upb
${_gRPC_SSL_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_library(bad_client_test
test/core/bad_client/bad_client.cc
)
@ -6874,12 +6845,12 @@ target_link_libraries(dns_resolver_connectivity_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(dns_resolver_cooldown_test
add_executable(dns_resolver_cooldown_using_ares_resolver_test
test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
)
target_include_directories(dns_resolver_cooldown_test
target_include_directories(dns_resolver_cooldown_using_ares_resolver_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@ -6892,7 +6863,7 @@ target_include_directories(dns_resolver_cooldown_test
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(dns_resolver_cooldown_test
target_link_libraries(dns_resolver_cooldown_using_ares_resolver_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
@ -6901,8 +6872,42 @@ target_link_libraries(dns_resolver_cooldown_test
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(dns_resolver_cooldown_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(dns_resolver_cooldown_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
set_target_properties(dns_resolver_cooldown_using_ares_resolver_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(dns_resolver_cooldown_using_ares_resolver_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(dns_resolver_cooldown_using_native_resolver_test
test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
)
target_include_directories(dns_resolver_cooldown_using_native_resolver_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(dns_resolver_cooldown_using_native_resolver_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
)
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(dns_resolver_cooldown_using_native_resolver_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(dns_resolver_cooldown_using_native_resolver_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS)
@ -7506,7 +7511,7 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(gpr_host_port_test
test/core/gpr/host_port_test.cc
test/core/gprpp/host_port_test.cc
)
@ -16639,6 +16644,45 @@ target_link_libraries(stress_test
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(string_view_test
test/core/gprpp/string_view_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(string_view_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
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(string_view_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc++
grpc
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)

@ -351,6 +351,7 @@ CFLAGS += -std=c99 -Wsign-conversion -Wconversion $(W_SHADOW) $(W_EXTRA_SEMI)
CXXFLAGS += -std=c++11
ifeq ($(SYSTEM),Darwin)
CXXFLAGS += -stdlib=libc++
LDFLAGS += -framework CoreFoundation
endif
CXXFLAGS += -Wnon-virtual-dtor
CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 -Wno-deprecated-declarations -Ithird_party/nanopb -DPB_FIELD_32BIT
@ -1015,7 +1016,8 @@ compression_test: $(BINDIR)/$(CONFIG)/compression_test
concurrent_connectivity_test: $(BINDIR)/$(CONFIG)/concurrent_connectivity_test
connection_refused_test: $(BINDIR)/$(CONFIG)/connection_refused_test
dns_resolver_connectivity_test: $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test
dns_resolver_cooldown_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test
dns_resolver_cooldown_using_ares_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test
dns_resolver_cooldown_using_native_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test
dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test
dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test
endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test
@ -1278,6 +1280,7 @@ status_metadata_test: $(BINDIR)/$(CONFIG)/status_metadata_test
status_util_test: $(BINDIR)/$(CONFIG)/status_util_test
streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test
stress_test: $(BINDIR)/$(CONFIG)/stress_test
string_view_test: $(BINDIR)/$(CONFIG)/string_view_test
thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test
thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test
time_change_test: $(BINDIR)/$(CONFIG)/time_change_test
@ -1446,7 +1449,8 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/concurrent_connectivity_test \
$(BINDIR)/$(CONFIG)/connection_refused_test \
$(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test \
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test \
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test \
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test \
$(BINDIR)/$(CONFIG)/dns_resolver_test \
$(BINDIR)/$(CONFIG)/dualstack_socket_test \
$(BINDIR)/$(CONFIG)/endpoint_pair_test \
@ -1744,6 +1748,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/status_util_test \
$(BINDIR)/$(CONFIG)/streaming_throughput_test \
$(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/string_view_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \
$(BINDIR)/$(CONFIG)/thread_stress_test \
$(BINDIR)/$(CONFIG)/time_change_test \
@ -1907,6 +1912,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/status_util_test \
$(BINDIR)/$(CONFIG)/streaming_throughput_test \
$(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/string_view_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \
$(BINDIR)/$(CONFIG)/thread_stress_test \
$(BINDIR)/$(CONFIG)/time_change_test \
@ -1983,8 +1989,10 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/connection_refused_test || ( echo test connection_refused_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_connectivity_test"
$(Q) $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test || ( echo test dns_resolver_connectivity_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_cooldown_test"
$(Q) $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test || ( echo test dns_resolver_cooldown_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_cooldown_using_ares_resolver_test"
$(Q) $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test || ( echo test dns_resolver_cooldown_using_ares_resolver_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_cooldown_using_native_resolver_test"
$(Q) $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test || ( echo test dns_resolver_cooldown_using_native_resolver_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_test"
$(Q) $(BINDIR)/$(CONFIG)/dns_resolver_test || ( echo test dns_resolver_test failed ; exit 1 )
$(E) "[RUN] Testing dualstack_socket_test"
@ -2433,6 +2441,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/status_util_test || ( echo test status_util_test failed ; exit 1 )
$(E) "[RUN] Testing streaming_throughput_test"
$(Q) $(BINDIR)/$(CONFIG)/streaming_throughput_test || ( echo test streaming_throughput_test failed ; exit 1 )
$(E) "[RUN] Testing string_view_test"
$(Q) $(BINDIR)/$(CONFIG)/string_view_test || ( echo test string_view_test failed ; exit 1 )
$(E) "[RUN] Testing thread_manager_test"
$(Q) $(BINDIR)/$(CONFIG)/thread_manager_test || ( echo test thread_manager_test failed ; exit 1 )
$(E) "[RUN] Testing thread_stress_test"
@ -3379,7 +3389,6 @@ LIBGPR_SRC = \
src/core/lib/gpr/env_linux.cc \
src/core/lib/gpr/env_posix.cc \
src/core/lib/gpr/env_windows.cc \
src/core/lib/gpr/host_port.cc \
src/core/lib/gpr/log.cc \
src/core/lib/gpr/log_android.cc \
src/core/lib/gpr/log_linux.cc \
@ -3406,6 +3415,7 @@ LIBGPR_SRC = \
src/core/lib/gprpp/arena.cc \
src/core/lib/gprpp/fork.cc \
src/core/lib/gprpp/global_config_env.cc \
src/core/lib/gprpp/host_port.cc \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
src/core/lib/profiling/basic_timers.cc \
@ -5534,6 +5544,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/completion_queue_impl.h \
include/grpcpp/create_channel.h \
include/grpcpp/create_channel_impl.h \
include/grpcpp/create_channel_posix.h \
@ -6163,6 +6174,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/completion_queue_impl.h \
include/grpcpp/create_channel.h \
include/grpcpp/create_channel_impl.h \
include/grpcpp/create_channel_posix.h \
@ -7111,6 +7123,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
include/grpcpp/completion_queue_impl.h \
include/grpcpp/create_channel.h \
include/grpcpp/create_channel_impl.h \
include/grpcpp/create_channel_posix.h \
@ -9638,34 +9651,66 @@ endif
endif
DNS_RESOLVER_COOLDOWN_TEST_SRC = \
DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_SRC = \
test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc \
DNS_RESOLVER_COOLDOWN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DNS_RESOLVER_COOLDOWN_TEST_SRC))))
DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: openssl_dep_error
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test
$(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test
endif
$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_cooldown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS:.o=.dep)
deps_dns_resolver_cooldown_using_ares_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(DNS_RESOLVER_COOLDOWN_TEST_OBJS:.o=.dep)
-include $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS:.o=.dep)
endif
endif
DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_SRC = \
test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc \
DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test
endif
$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_cooldown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_dns_resolver_cooldown_using_native_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS:.o=.dep)
endif
endif
@ -10218,7 +10263,7 @@ endif
GPR_HOST_PORT_TEST_SRC = \
test/core/gpr/host_port_test.cc \
test/core/gprpp/host_port_test.cc \
GPR_HOST_PORT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_HOST_PORT_TEST_SRC))))
ifeq ($(NO_SECURE),true)
@ -10238,7 +10283,7 @@ $(BINDIR)/$(CONFIG)/gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(C
endif
$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
$(OBJDIR)/$(CONFIG)/test/core/gprpp/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
deps_gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS:.o=.dep)
@ -19666,6 +19711,49 @@ $(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(GENDIR)/src/proto/grpc/tes
$(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
STRING_VIEW_TEST_SRC = \
test/core/gprpp/string_view_test.cc \
STRING_VIEW_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STRING_VIEW_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/string_view_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.5.0+.
$(BINDIR)/$(CONFIG)/string_view_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/string_view_test: $(PROTOBUF_DEP) $(STRING_VIEW_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(STRING_VIEW_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/string_view_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/core/gprpp/string_view_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_string_view_test: $(STRING_VIEW_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(STRING_VIEW_TEST_OBJS:.o=.dep)
endif
endif
THREAD_MANAGER_TEST_SRC = \
test/cpp/thread_manager/thread_manager_test.cc \

@ -20,7 +20,7 @@ register_toolchains(
git_repository(
name = "io_bazel_rules_python",
commit = "8b5d0683a7d878b28fffe464779c8a53659fc645",
commit = "fdbb17a4118a1728d19e638a5291b4c4266ea5b8",
remote = "https://github.com/bazelbuild/rules_python.git",
)

@ -41,11 +41,11 @@ def _join_directories(directories):
def generate_cc_impl(ctx):
"""Implementation of the generate_cc rule."""
protos = [f for src in ctx.attr.srcs for f in src.proto.check_deps_sources.to_list()]
protos = [f for src in ctx.attr.srcs for f in src[ProtoInfo].check_deps_sources.to_list()]
includes = [
f
for src in ctx.attr.srcs
for f in src.proto.transitive_imports.to_list()
for f in src[ProtoInfo].transitive_imports.to_list()
]
outs = []
proto_root = get_proto_root(
@ -146,7 +146,7 @@ _generate_cc = rule(
"srcs": attr.label_list(
mandatory = True,
allow_empty = False,
providers = ["proto"],
providers = [ProtoInfo],
),
"plugin": attr.label(
executable = True,

@ -28,12 +28,12 @@ def _get_staged_proto_file(context, source_file):
def _generate_py_impl(context):
protos = []
for src in context.attr.deps:
for file in src.proto.direct_sources:
for file in src[ProtoInfo].direct_sources:
protos.append(_get_staged_proto_file(context, file))
includes = [
file
for src in context.attr.deps
for file in src.proto.transitive_imports.to_list()
for file in src[ProtoInfo].transitive_imports.to_list()
]
proto_root = get_proto_root(context.label.workspace_root)
format_str = (_GENERATED_GRPC_PROTO_FORMAT if context.executable.plugin else _GENERATED_PROTO_FORMAT)
@ -99,7 +99,7 @@ __generate_py = rule(
"deps": attr.label_list(
mandatory = True,
allow_empty = False,
providers = ["proto"],
providers = [ProtoInfo],
),
"plugin": attr.label(
executable = True,

@ -122,7 +122,6 @@ filegroups:
- src/core/lib/gpr/env_linux.cc
- src/core/lib/gpr/env_posix.cc
- src/core/lib/gpr/env_windows.cc
- src/core/lib/gpr/host_port.cc
- src/core/lib/gpr/log.cc
- src/core/lib/gpr/log_android.cc
- src/core/lib/gpr/log_linux.cc
@ -149,6 +148,7 @@ filegroups:
- src/core/lib/gprpp/arena.cc
- src/core/lib/gprpp/fork.cc
- src/core/lib/gprpp/global_config_env.cc
- src/core/lib/gprpp/host_port.cc
- src/core/lib/gprpp/thd_posix.cc
- src/core/lib/gprpp/thd_windows.cc
- src/core/lib/profiling/basic_timers.cc
@ -178,7 +178,6 @@ filegroups:
- src/core/lib/gpr/alloc.h
- src/core/lib/gpr/arena.h
- src/core/lib/gpr/env.h
- src/core/lib/gpr/host_port.h
- src/core/lib/gpr/mpscq.h
- src/core/lib/gpr/murmur_hash.h
- src/core/lib/gpr/spinlock.h
@ -199,6 +198,7 @@ filegroups:
- src/core/lib/gprpp/global_config_custom.h
- src/core/lib/gprpp/global_config_env.h
- src/core/lib/gprpp/global_config_generic.h
- src/core/lib/gprpp/host_port.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/map.h
- src/core/lib/gprpp/memory.h
@ -444,6 +444,7 @@ filegroups:
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/string_view.h
- src/core/lib/http/format_request.h
- src/core/lib/http/httpcli.h
- src/core/lib/http/parser.h
@ -1366,6 +1367,7 @@ filegroups:
- include/grpcpp/channel_impl.h
- include/grpcpp/client_context.h
- include/grpcpp/completion_queue.h
- include/grpcpp/completion_queue_impl.h
- include/grpcpp/create_channel.h
- include/grpcpp/create_channel_impl.h
- include/grpcpp/create_channel_posix.h
@ -2399,7 +2401,7 @@ targets:
- gpr
exclude_iomgrs:
- uv
- name: dns_resolver_cooldown_test
- name: dns_resolver_cooldown_using_ares_resolver_test
build: test
language: c
src:
@ -2408,6 +2410,19 @@ targets:
- grpc_test_util
- grpc
- gpr
args:
- --resolver=ares
- name: dns_resolver_cooldown_using_native_resolver_test
build: test
language: c
src:
- test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
deps:
- grpc_test_util
- grpc
- gpr
args:
- --resolver=native
- name: dns_resolver_test
build: test
language: c
@ -2625,7 +2640,7 @@ targets:
build: test
language: c
src:
- test/core/gpr/host_port_test.cc
- test/core/gprpp/host_port_test.cc
deps:
- gpr
- grpc_test_util_unsecure
@ -5760,6 +5775,19 @@ targets:
- grpc
- gpr
- grpc++_test_config
- name: string_view_test
gtest: true
build: test
language: c++
src:
- test/core/gprpp/string_view_test.cc
deps:
- grpc_test_util
- grpc++
- grpc
- gpr
uses:
- grpc++_test
- name: thread_manager_test
build: test
language: c++

@ -53,7 +53,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gpr/env_linux.cc \
src/core/lib/gpr/env_posix.cc \
src/core/lib/gpr/env_windows.cc \
src/core/lib/gpr/host_port.cc \
src/core/lib/gpr/log.cc \
src/core/lib/gpr/log_android.cc \
src/core/lib/gpr/log_linux.cc \
@ -80,6 +79,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gprpp/arena.cc \
src/core/lib/gprpp/fork.cc \
src/core/lib/gprpp/global_config_env.cc \
src/core/lib/gprpp/host_port.cc \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
src/core/lib/profiling/basic_timers.cc \

@ -28,7 +28,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\gpr\\env_linux.cc " +
"src\\core\\lib\\gpr\\env_posix.cc " +
"src\\core\\lib\\gpr\\env_windows.cc " +
"src\\core\\lib\\gpr\\host_port.cc " +
"src\\core\\lib\\gpr\\log.cc " +
"src\\core\\lib\\gpr\\log_android.cc " +
"src\\core\\lib\\gpr\\log_linux.cc " +
@ -55,6 +54,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\gprpp\\arena.cc " +
"src\\core\\lib\\gprpp\\fork.cc " +
"src\\core\\lib\\gprpp\\global_config_env.cc " +
"src\\core\\lib\\gprpp\\host_port.cc " +
"src\\core\\lib\\gprpp\\thd_posix.cc " +
"src\\core\\lib\\gprpp\\thd_windows.cc " +
"src\\core\\lib\\profiling\\basic_timers.cc " +

@ -71,4 +71,4 @@ The following status codes are never generated by the library:
- OUT_OF_RANGE
- DATA_LOSS
Applications that may wish to [retry](https:github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried.
Applications that may wish to [retry](https://github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried.

@ -0,0 +1,65 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
filegroup(
name = "_credentials_files",
testonly = 1,
srcs = [
"credentials/localhost.key",
"credentials/localhost.crt",
"credentials/root.crt",
],
)
py_library(
name = "_credentials",
testonly = 1,
srcs = ["_credentials.py"],
data = [":_credentials_files"],
)
py_binary(
name = "customized_auth_client",
testonly = 1,
srcs = ["customized_auth_client.py"],
deps = [
":_credentials",
"//src/python/grpcio/grpc:grpcio",
"//examples:py_helloworld",
],
)
py_binary(
name = "customized_auth_server",
testonly = 1,
srcs = ["customized_auth_server.py"],
deps = [
":_credentials",
"//src/python/grpcio/grpc:grpcio",
"//examples:py_helloworld",
],
)
py_test(
name = "_auth_example_test",
srcs = ["test/_auth_example_test.py"],
deps = [
"//src/python/grpcio/grpc:grpcio",
"//examples:py_helloworld",
":customized_auth_client",
":customized_auth_server",
":_credentials",
],
)

@ -0,0 +1,112 @@
# Authentication Extension Example in gRPC Python
## Check Our Guide First
For most common usage of authentication in gRPC Python, please see our
[Authentication](https://grpc.io/docs/guides/auth/) guide's Python section. The
Guide includes following scenarios:
1. Server SSL credential setup
2. Client SSL credential setup
3. Authenticate with Google using a JWT
4. Authenticate with Google using an Oauth2 token
Also, the guide talks about gRPC specific credential types.
### Channel credentials
Channel credentials are attached to a `Channel` object, the most common use case
are SSL credentials.
### Call credentials
Call credentials are attached to a `Call` object (corresponding to an RPC).
Under the hood, the call credentials is a function that takes in information of
the RPC and modify metadata through callback.
## About This Example
This example focuses on extending gRPC authentication mechanism:
1) Customize authentication plugin;
2) Composite client side credentials;
3) Validation through interceptor on server side.
## AuthMetadataPlugin: Manipulate metadata for each call
Unlike TLS/SSL based authentication, the authentication extension in gRPC Python
lives at a much higher level of networking. It relies on the transmission of
metadata (HTTP Header) between client and server, instead of alternating the
transport protocol.
gRPC Python provides a way to intercept an RPC and append authentication related
metadata through
[`AuthMetadataPlugin`](https://grpc.github.io/grpc/python/grpc.html#grpc.AuthMetadataPlugin).
Those in need of a custom authentication method may simply provide a concrete
implementation of the following interface:
```Python
class AuthMetadataPlugin:
"""A specification for custom authentication."""
def __call__(self, context, callback):
"""Implements authentication by passing metadata to a callback.
Implementations of this method must not block.
Args:
context: An AuthMetadataContext providing information on the RPC that
the plugin is being called to authenticate.
callback: An AuthMetadataPluginCallback to be invoked either
synchronously or asynchronously.
"""
```
Then pass the instance of the concrete implementation to
`grpc.metadata_call_credentials` function to be converted into a
`CallCredentials` object. Please NOTE that it is possible to pass a Python
function object directly, but we recommend to inherit from the base class to
ensure implementation correctness.
```Python
def metadata_call_credentials(metadata_plugin, name=None):
"""Construct CallCredentials from an AuthMetadataPlugin.
Args:
metadata_plugin: An AuthMetadataPlugin to use for authentication.
name: An optional name for the plugin.
Returns:
A CallCredentials.
"""
```
The `CallCredentials` object can be passed directly into an RPC like:
```Python
call_credentials = grpc.metadata_call_credentials(my_foo_plugin)
stub.FooRpc(request, credentials=call_credentials)
```
Or you can use `ChannelCredentials` and `CallCredentials` at the same time by
combining them:
```Python
channel_credentials = ...
call_credentials = ...
composite_credentials = grpc.composite_channel_credentials(
channel_credential,
call_credentials)
channel = grpc.secure_channel(server_address, composite_credentials)
```
It is also possible to apply multiple `CallCredentials` to a single RPC:
```Python
call_credentials_foo = ...
call_credentials_bar = ...
call_credentials = grpc.composite_call_credentials(
call_credentials_foo,
call_credentials_bar)
stub.FooRpc(request, credentials=call_credentials)
```

@ -0,0 +1,31 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Loading SSL credentials for gRPC Python authentication example."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
def _load_credential_from_file(filepath):
real_path = os.path.join(os.path.dirname(__file__), filepath)
with open(real_path, 'rb') as f:
return f.read()
SERVER_CERTIFICATE = _load_credential_from_file('credentials/localhost.crt')
SERVER_CERTIFICATE_KEY = _load_credential_from_file('credentials/localhost.key')
ROOT_CERTIFICATE = _load_credential_from_file('credentials/root.crt')

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDFjCCAf4CCQCzrLIhrWa55zANBgkqhkiG9w0BAQsFADBCMQswCQYDVQQGEwJV
UzETMBEGA1UECAwKQ2FsaWZvcm5pYTEPMA0GA1UECgwGR29vZ2xlMQ0wCwYDVQQL
DARnUlBDMCAXDTE5MDYyNDIyMjIzM1oYDzIxMTkwNTMxMjIyMjMzWjBWMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEPMA0GA1UECgwGR29vZ2xlMQ0w
CwYDVQQLDARnUlBDMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCtCW0TjugnIUu8BEVIYvdMP+/2GENQDjZhZ8eKR5C6
toDGbgjsDtt/GxISAg4cg70fIvy0XolnGPZodvfHDM4lJ7yHBOdZD8TXQoE6okR7
HZuLUJ20M0pXgWqtRewKRUjuYsSDXBnzLiZw1dcv9nGpo+Bqa8NonpiGRRpEkshF
D6T9KU9Ts/x+wMQBIra2Gj0UMh79jPhUuxcYAQA0JQGivnOtdwuPiumpnUT8j8h6
tWg5l01EsCZWJecCF85KnGpJEVYPyPqBqGsy0nGS9plGotOWF87+jyUQt+KD63xA
aBmTro86mKDDKEK4JvzjVeMGz2UbVcLPiiZnErTFaiXJAgMBAAEwDQYJKoZIhvcN
AQELBQADggEBAKsDgOPCWp5WCy17vJbRlgfgk05sVNIHZtzrmdswjBmvSg8MUpep
XqcPNUpsljAXsf9UM5IFEMRdilUsFGWvHjBEtNAW8WUK9UV18WRuU//0w1Mp5HAN
xUEKb4BoyZr65vlCnTR+AR5c9FfPvLibhr5qHs2RA8Y3GyLOcGqBWed87jhdQLCc
P1bxB+96le5JeXq0tw215lxonI2/3ZYVK4/ok9gwXrQoWm8YieJqitk/ZQ4S17/4
pynHtDfdxLn23EXeGx+UTxJGfpRmhEZdJ+MN7QGYoomzx5qS5XoYKxRNrDlirJpr
OqXIn8E1it+6d5gOZfuHawcNGhRLplE/pfA=
-----END CERTIFICATE-----

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEArQltE47oJyFLvARFSGL3TD/v9hhDUA42YWfHikeQuraAxm4I
7A7bfxsSEgIOHIO9HyL8tF6JZxj2aHb3xwzOJSe8hwTnWQ/E10KBOqJEex2bi1Cd
tDNKV4FqrUXsCkVI7mLEg1wZ8y4mcNXXL/ZxqaPgamvDaJ6YhkUaRJLIRQ+k/SlP
U7P8fsDEASK2tho9FDIe/Yz4VLsXGAEANCUBor5zrXcLj4rpqZ1E/I/IerVoOZdN
RLAmViXnAhfOSpxqSRFWD8j6gahrMtJxkvaZRqLTlhfO/o8lELfig+t8QGgZk66P
OpigwyhCuCb841XjBs9lG1XCz4omZxK0xWolyQIDAQABAoIBADeq/Kh6JT3RfGf0
h8WN8TlaqHxnueAbcmtL0+oss+cdp7gu1jf7X6o4r0uT1a5ew40s2Fe+wj2kzkE1
ZOlouTlC22gkr7j7Vbxa7PBMG/Pvxoa/XL0IczZLsGImSJXVTG1E4SvRiZeulTdf
1GbdxhtpWV1jZe5Wd4Na3+SHxF5S7m3PrHiZlYdz1ND+8XZs1NlL9+ej72qSFul9
t/QjMWJ9pky/Wad5abnRLRyOsg+BsgnXbkUy2rD89ZxFMLda9pzXo3TPyAlBHonr
mkEsE4eRMWMpjBM79JbeyDdHn/cs/LjAZrzeDf7ugXr2CHQpKaM5O0PsNHezJII9
L5kCfzECgYEA4M/rz1UP1/BJoSqigUlSs0tPAg8a5UlkVsh6Osuq72IPNo8qg/Fw
oV/IiIS+q+obRcFj1Od3PGdTpCJwW5dzd2fXBQGmGdj0HucnCrs13RtBh91JiF5i
y/YYI9KfgOG2ZT9gG68T0gTs6jRrS3Qd83npqjrkJqMOd7s00MK9tUcCgYEAxQq7
T541oCYHSBRIIb0IrR25krZy9caxzCqPDwOcuuhaCqCiaq+ATvOWlSfgecm4eH0K
PCH0xlWxG0auPEwm4pA8+/WR/XJwscPZMuoht1EoKy1his4eKx/s7hHNeO6KOF0V
Y/zqIiuZnEwUoKbn7EqqNFSTT65PJKyGsICJFG8CgYAfaw9yl1myfQNdQb8aQGwN
YJ33FLNWje427qeeZe5KrDKiFloDvI9YDjHRWnPnRL1w/zj7fSm9yFb5HlMDieP6
MQnsyjEzdY2QcA+VwVoiv3dmDHgFVeOKy6bOAtaFxYWfGr9MvygO9t9BT/gawGyb
JVORlc9i0vDnrMMR1dV7awKBgBpTWLtGc/u1mPt0Wj7HtsUKV6TWY32a0l5owTxM
S0BdksogtBJ06DukJ9Y9wawD23WdnyRxlPZ6tHLkeprrwbY7dypioOKvy4a0l+xJ
g7+uRCOgqIuXBkjUtx8HmeAyXp0xMo5tWArAsIFFWOwt4IadYygitJvMuh44PraO
NcJZAoGADEiV0dheXUCVr8DrtSom8DQMj92/G/FIYjXL8OUhh0+F+YlYP0+F8PEU
yYIWEqL/S5tVKYshimUXQa537JcRKsTVJBG/ZKD2kuqgOc72zQy3oplimXeJDCXY
h2eAQ0u8GN6tN9C4t8Kp4a3y6FGsxgu+UTxdnL3YQ+yHAVhtCzo=
-----END RSA PRIVATE KEY-----

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDWTCCAkGgAwIBAgIJAPOConZMwykwMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMQ8wDQYDVQQKDAZHb29nbGUxDTAL
BgNVBAsMBGdSUEMwIBcNMTkwNjI0MjIyMDA3WhgPMjExOTA1MzEyMjIwMDdaMEIx
CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMQ8wDQYDVQQKDAZHb29n
bGUxDTALBgNVBAsMBGdSUEMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQCwqei3TfyLidnQNDJ2lierMYo229K92DuORni7nSjJQ59Jc3dNMsmqGQJjCD8o
6mTlKM/oCbs27Wpx+OxcOLvT95j2kiDGca1fCvaMdguIod09SWiyMpv/hp0trLv7
NJIKHznath6rHYX2Ii3fZ1yCPzyQbEPSAA+GNpoNm1v1ZWmWKke9v7vLlS3inNlW
Mt9jepK7DrtbNZnVDjeItnppBSbVYRMxIyNHkepFbqXx5TpkCvl4M4XQZw9bfSxQ
i3WZ3q+T1Tw//OUdPNc+OfMhu0MA0QoMwikskP0NaIC3dbJZ5Ogx0RcnaB4E+9C6
O/znUEh3WuKVl5HXBF+UwWoFAgMBAAGjUDBOMB0GA1UdDgQWBBRm3JIgzgK4G97J
fbMGatWMZc7V3jAfBgNVHSMEGDAWgBRm3JIgzgK4G97JfbMGatWMZc7V3jAMBgNV
HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCNiV8x41if094ry2srS0YucpiN
3rTPk08FOLsENTMYai524TGXJti1P6ofGr5KXCL0uxTByHE3fEiMMud2TIY5iHQo
Y4mzDTTcb+Q7yKHwYZMlcp6nO8W+NeY5t+S0JPHhb8deKWepcN2UpXBUYQLw7AiE
l96T9Gi+vC9h/XE5IVwHFQXTxf5UYzXtW1nfapvrOONg/ms41dgmrRKIi+knWfiJ
FdHpHX2sfDAoJtnpEISX+nxRGNVTLY64utXWm4yxaZJshvy2s8zWJgRg7rtwAhTT
Np9E9MnihXLEmDI4Co9XlLPJyZFmqImsbmVuKFeQOCiLAoPJaMI2lbi7fiTo
-----END CERTIFICATE-----

@ -0,0 +1,105 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Client of the Python example of customizing authentication mechanism."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import contextlib
import logging
import grpc
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
from examples.python.auth import _credentials
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
_SERVER_ADDR_TEMPLATE = 'localhost:%d'
_SIGNATURE_HEADER_KEY = 'x-signature'
class AuthGateway(grpc.AuthMetadataPlugin):
def __call__(self, context, callback):
"""Implements authentication by passing metadata to a callback.
Implementations of this method must not block.
Args:
context: An AuthMetadataContext providing information on the RPC that
the plugin is being called to authenticate.
callback: An AuthMetadataPluginCallback to be invoked either
synchronously or asynchronously.
"""
# Example AuthMetadataContext object:
# AuthMetadataContext(
# service_url=u'https://localhost:50051/helloworld.Greeter',
# method_name=u'SayHello')
signature = context.method_name[::-1]
callback(((_SIGNATURE_HEADER_KEY, signature),), None)
@contextlib.contextmanager
def create_client_channel(addr):
# Call credential object will be invoked for every single RPC
call_credentials = grpc.metadata_call_credentials(
AuthGateway(), name='auth gateway')
# Channel credential will be valid for the entire channel
channel_credential = grpc.ssl_channel_credentials(
_credentials.ROOT_CERTIFICATE)
# Combining channel credentials and call credentials together
composite_credentials = grpc.composite_channel_credentials(
channel_credential,
call_credentials,
)
channel = grpc.secure_channel(addr, composite_credentials)
yield channel
def send_rpc(channel):
stub = helloworld_pb2_grpc.GreeterStub(channel)
request = helloworld_pb2.HelloRequest(name='you')
try:
response = stub.SayHello(request)
except grpc.RpcError as rpc_error:
_LOGGER.error('Received error: %s', rpc_error)
return rpc_error
else:
_LOGGER.info('Received message: %s', response)
return response
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'--port',
nargs='?',
type=int,
default=50051,
help='the address of server')
args = parser.parse_args()
with create_client_channel(_SERVER_ADDR_TEMPLATE % args.port) as channel:
send_rpc(channel)
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
main()

@ -0,0 +1,110 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Server of the Python example of customizing authentication mechanism."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import contextlib
import logging
import time
from concurrent import futures
import grpc
from examples import helloworld_pb2
from examples import helloworld_pb2_grpc
from examples.python.auth import _credentials
_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
_LISTEN_ADDRESS_TEMPLATE = 'localhost:%d'
_SIGNATURE_HEADER_KEY = 'x-signature'
class SignatureValidationInterceptor(grpc.ServerInterceptor):
def __init__(self):
def abort(ignored_request, context):
context.abort(grpc.StatusCode.UNAUTHENTICATED, 'Invalid signature')
self._abortion = grpc.unary_unary_rpc_method_handler(abort)
def intercept_service(self, continuation, handler_call_details):
# Example HandlerCallDetails object:
# _HandlerCallDetails(
# method=u'/helloworld.Greeter/SayHello',
# invocation_metadata=...)
method_name = handler_call_details.method.split('/')[-1]
expected_metadata = (_SIGNATURE_HEADER_KEY, method_name[::-1])
if expected_metadata in handler_call_details.invocation_metadata:
return continuation(handler_call_details)
else:
return self._abortion
class SimpleGreeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, unused_context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
@contextlib.contextmanager
def run_server(port):
# Bind interceptor to server
server = grpc.server(
futures.ThreadPoolExecutor(),
interceptors=(SignatureValidationInterceptor(),))
helloworld_pb2_grpc.add_GreeterServicer_to_server(SimpleGreeter(), server)
# Loading credentials
server_credentials = grpc.ssl_server_credentials(((
_credentials.SERVER_CERTIFICATE_KEY,
_credentials.SERVER_CERTIFICATE,
),))
# Pass down credentials
port = server.add_secure_port(_LISTEN_ADDRESS_TEMPLATE % port,
server_credentials)
server.start()
try:
yield port
finally:
server.stop(0)
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'--port', nargs='?', type=int, default=50051, help='the listening port')
args = parser.parse_args()
with run_server(args.port) as port:
logging.info('Server is listening at port :%d', port)
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
pass
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
main()

@ -0,0 +1,56 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Test for gRPC Python authentication example."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import unittest
import grpc
from examples.python.auth import _credentials
from examples.python.auth import customized_auth_client
from examples.python.auth import customized_auth_server
_SERVER_ADDR_TEMPLATE = 'localhost:%d'
class AuthExampleTest(unittest.TestCase):
def test_successful_call(self):
with customized_auth_server.run_server(0) as port:
with customized_auth_client.create_client_channel(
_SERVER_ADDR_TEMPLATE % port) as channel:
customized_auth_client.send_rpc(channel)
# No unhandled exception raised, test passed!
def test_no_channel_credential(self):
with customized_auth_server.run_server(0) as port:
with grpc.insecure_channel(_SERVER_ADDR_TEMPLATE % port) as channel:
resp = customized_auth_client.send_rpc(channel)
self.assertEqual(resp.code(), grpc.StatusCode.UNAVAILABLE)
def test_no_call_credential(self):
with customized_auth_server.run_server(0) as port:
channel_credential = grpc.ssl_channel_credentials(
_credentials.ROOT_CERTIFICATE)
with grpc.secure_channel(_SERVER_ADDR_TEMPLATE % port,
channel_credential) as channel:
resp = customized_auth_client.send_rpc(channel)
self.assertEqual(resp.code(), grpc.StatusCode.UNAUTHENTICATED)
if __name__ == '__main__':
unittest.main(verbosity=2)

@ -85,6 +85,7 @@ Pod::Spec.new do |s|
'include/grpcpp/channel_impl.h',
'include/grpcpp/client_context.h',
'include/grpcpp/completion_queue.h',
'include/grpcpp/completion_queue_impl.h',
'include/grpcpp/create_channel.h',
'include/grpcpp/create_channel_impl.h',
'include/grpcpp/create_channel_posix.h',
@ -261,7 +262,6 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
'src/core/lib/gpr/spinlock.h',
@ -282,6 +282,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/global_config_custom.h',
'src/core/lib/gprpp/global_config_env.h',
'src/core/lib/gprpp/global_config_generic.h',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
@ -444,6 +445,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/orphanable.h',
'src/core/lib/gprpp/ref_counted.h',
'src/core/lib/gprpp/ref_counted_ptr.h',
'src/core/lib/gprpp/string_view.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
@ -591,7 +593,6 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
'src/core/lib/gpr/spinlock.h',
@ -612,6 +613,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/global_config_custom.h',
'src/core/lib/gprpp/global_config_env.h',
'src/core/lib/gprpp/global_config_generic.h',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
@ -648,6 +650,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/orphanable.h',
'src/core/lib/gprpp/ref_counted.h',
'src/core/lib/gprpp/ref_counted_ptr.h',
'src/core/lib/gprpp/string_view.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',

@ -191,7 +191,6 @@ Pod::Spec.new do |s|
ss.source_files = 'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
'src/core/lib/gpr/spinlock.h',
@ -212,6 +211,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/global_config_custom.h',
'src/core/lib/gprpp/global_config_env.h',
'src/core/lib/gprpp/global_config_generic.h',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
@ -228,7 +228,6 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/env_linux.cc',
'src/core/lib/gpr/env_posix.cc',
'src/core/lib/gpr/env_windows.cc',
'src/core/lib/gpr/host_port.cc',
'src/core/lib/gpr/log.cc',
'src/core/lib/gpr/log_android.cc',
'src/core/lib/gpr/log_linux.cc',
@ -255,6 +254,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/arena.cc',
'src/core/lib/gprpp/fork.cc',
'src/core/lib/gprpp/global_config_env.cc',
'src/core/lib/gprpp/host_port.cc',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
'src/core/lib/profiling/basic_timers.cc',
@ -414,6 +414,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/orphanable.h',
'src/core/lib/gprpp/ref_counted.h',
'src/core/lib/gprpp/ref_counted_ptr.h',
'src/core/lib/gprpp/string_view.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
@ -884,7 +885,6 @@ Pod::Spec.new do |s|
ss.private_header_files = 'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
'src/core/lib/gpr/spinlock.h',
@ -905,6 +905,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/global_config_custom.h',
'src/core/lib/gprpp/global_config_env.h',
'src/core/lib/gprpp/global_config_generic.h',
'src/core/lib/gprpp/host_port.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/map.h',
'src/core/lib/gprpp/memory.h',
@ -1067,6 +1068,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/orphanable.h',
'src/core/lib/gprpp/ref_counted.h',
'src/core/lib/gprpp/ref_counted_ptr.h',
'src/core/lib/gprpp/string_view.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',

@ -111,6 +111,7 @@ EXPORTS
grpc_google_refresh_token_credentials_create
grpc_access_token_credentials_create
grpc_google_iam_credentials_create
grpc_sts_credentials_create
grpc_metadata_credentials_create_from_plugin
grpc_secure_channel_create
grpc_server_credentials_release

@ -85,7 +85,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/alloc.h )
s.files += %w( src/core/lib/gpr/arena.h )
s.files += %w( src/core/lib/gpr/env.h )
s.files += %w( src/core/lib/gpr/host_port.h )
s.files += %w( src/core/lib/gpr/mpscq.h )
s.files += %w( src/core/lib/gpr/murmur_hash.h )
s.files += %w( src/core/lib/gpr/spinlock.h )
@ -106,6 +105,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/global_config_custom.h )
s.files += %w( src/core/lib/gprpp/global_config_env.h )
s.files += %w( src/core/lib/gprpp/global_config_generic.h )
s.files += %w( src/core/lib/gprpp/host_port.h )
s.files += %w( src/core/lib/gprpp/manual_constructor.h )
s.files += %w( src/core/lib/gprpp/map.h )
s.files += %w( src/core/lib/gprpp/memory.h )
@ -122,7 +122,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/env_linux.cc )
s.files += %w( src/core/lib/gpr/env_posix.cc )
s.files += %w( src/core/lib/gpr/env_windows.cc )
s.files += %w( src/core/lib/gpr/host_port.cc )
s.files += %w( src/core/lib/gpr/log.cc )
s.files += %w( src/core/lib/gpr/log_android.cc )
s.files += %w( src/core/lib/gpr/log_linux.cc )
@ -149,6 +148,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/arena.cc )
s.files += %w( src/core/lib/gprpp/fork.cc )
s.files += %w( src/core/lib/gprpp/global_config_env.cc )
s.files += %w( src/core/lib/gprpp/host_port.cc )
s.files += %w( src/core/lib/gprpp/thd_posix.cc )
s.files += %w( src/core/lib/gprpp/thd_windows.cc )
s.files += %w( src/core/lib/profiling/basic_timers.cc )
@ -348,6 +348,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/orphanable.h )
s.files += %w( src/core/lib/gprpp/ref_counted.h )
s.files += %w( src/core/lib/gprpp/ref_counted_ptr.h )
s.files += %w( src/core/lib/gprpp/string_view.h )
s.files += %w( src/core/lib/http/format_request.h )
s.files += %w( src/core/lib/http/httpcli.h )
s.files += %w( src/core/lib/http/parser.h )

@ -226,7 +226,6 @@
'src/core/lib/gpr/env_linux.cc',
'src/core/lib/gpr/env_posix.cc',
'src/core/lib/gpr/env_windows.cc',
'src/core/lib/gpr/host_port.cc',
'src/core/lib/gpr/log.cc',
'src/core/lib/gpr/log_android.cc',
'src/core/lib/gpr/log_linux.cc',
@ -253,6 +252,7 @@
'src/core/lib/gprpp/arena.cc',
'src/core/lib/gprpp/fork.cc',
'src/core/lib/gprpp/global_config_env.cc',
'src/core/lib/gprpp/host_port.cc',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
'src/core/lib/profiling/basic_timers.cc',

@ -328,6 +328,31 @@ GRPCAPI grpc_call_credentials* grpc_google_iam_credentials_create(
const char* authorization_token, const char* authority_selector,
void* reserved);
/** Options for creating STS Oauth Token Exchange credentials following the IETF
draft https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16.
Optional fields may be set to NULL. It is the responsibility of the caller to
ensure that the subject and actor tokens are refreshed on disk at the
specified paths. This API is used for experimental purposes for now and may
change in the future. */
typedef struct {
const char* sts_endpoint_url; /* Required. */
const char* resource; /* Optional. */
const char* audience; /* Optional. */
const char* scope; /* Optional. */
const char* requested_token_type; /* Optional. */
const char* subject_token_path; /* Required. */
const char* subject_token_type; /* Required. */
const char* actor_token_path; /* Optional. */
const char* actor_token_type; /* Optional. */
} grpc_sts_credentials_options;
/** Creates an STS credentials following the STS Token Exchanged specifed in the
IETF draft https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16.
This API is used for experimental purposes for now and may change in the
future. */
GRPCAPI grpc_call_credentials* grpc_sts_credentials_create(
const grpc_sts_credentials_options* options, void* reserved);
/** Callback function to be called by the metadata credentials plugin
implementation when the metadata is ready.
- user_data is the opaque pointer that was passed in the get_metadata method

@ -0,0 +1,24 @@
/*
*
* Copyright 2019 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 GRPCPP_COMPLETION_QUEUE_IMPL_H
#define GRPCPP_COMPLETION_QUEUE_IMPL_H
#include <grpcpp/impl/codegen/completion_queue_impl.h>
#endif // GRPCPP_COMPLETION_QUEUE_IMPL_H

@ -34,7 +34,6 @@ class Channel;
class CompletionQueue;
class ServerCompletionQueue;
class ServerCredentials;
class ServerContext;
} // namespace grpc_impl
namespace grpc {

@ -28,6 +28,7 @@
#include <grpc/compression.h>
#include <grpc/support/atm.h>
#include <grpcpp/channel_impl.h>
#include <grpcpp/completion_queue_impl.h>
#include <grpcpp/health_check_service_interface.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/client_interceptor.h>

@ -90,7 +90,6 @@
<file baseinstalldir="/" name="src/core/lib/gpr/alloc.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/arena.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/env.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/host_port.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/mpscq.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/murmur_hash.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/spinlock.h" role="src" />
@ -111,6 +110,7 @@
<file baseinstalldir="/" name="src/core/lib/gprpp/global_config_custom.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/global_config_env.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/global_config_generic.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/host_port.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/manual_constructor.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/map.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/memory.h" role="src" />
@ -127,7 +127,6 @@
<file baseinstalldir="/" name="src/core/lib/gpr/env_linux.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/env_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/env_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/host_port.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/log.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/log_android.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/log_linux.cc" role="src" />
@ -154,6 +153,7 @@
<file baseinstalldir="/" name="src/core/lib/gprpp/arena.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/fork.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/global_config_env.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/host_port.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/thd_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/thd_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/basic_timers.cc" role="src" />
@ -353,6 +353,7 @@
<file baseinstalldir="/" name="src/core/lib/gprpp/orphanable.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/ref_counted.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/ref_counted_ptr.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/string_view.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/format_request.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/httpcli.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/parser.h" role="src" />

@ -30,24 +30,25 @@
namespace grpc_core {
namespace channelz {
SubchannelNode::SubchannelNode(Subchannel* subchannel,
SubchannelNode::SubchannelNode(const char* target_address,
size_t channel_tracer_max_nodes)
: BaseNode(EntityType::kSubchannel),
subchannel_(subchannel),
target_(UniquePtr<char>(gpr_strdup(subchannel_->GetTargetAddress()))),
target_(UniquePtr<char>(gpr_strdup(target_address))),
trace_(channel_tracer_max_nodes) {}
SubchannelNode::~SubchannelNode() {}
void SubchannelNode::UpdateConnectivityState(grpc_connectivity_state state) {
connectivity_state_.Store(state, MemoryOrder::RELAXED);
}
void SubchannelNode::SetChildSocketUuid(intptr_t uuid) {
child_socket_uuid_.Store(uuid, MemoryOrder::RELAXED);
}
void SubchannelNode::PopulateConnectivityState(grpc_json* json) {
grpc_connectivity_state state;
if (subchannel_ == nullptr) {
state = GRPC_CHANNEL_SHUTDOWN;
} else {
state = subchannel_->CheckConnectivityState(
nullptr /* health_check_service_name */,
nullptr /* connected_subchannel */);
}
grpc_connectivity_state state =
connectivity_state_.Load(MemoryOrder::RELAXED);
json = grpc_json_create_child(nullptr, json, "state", nullptr,
GRPC_JSON_OBJECT, false);
grpc_json_create_child(nullptr, json, "state",
@ -87,7 +88,7 @@ grpc_json* SubchannelNode::RenderJson() {
call_counter_.PopulateCallCounts(json);
json = top_level_json;
// populate the child socket.
intptr_t socket_uuid = subchannel_->GetChildSocketUuid();
intptr_t socket_uuid = child_socket_uuid_.Load(MemoryOrder::RELAXED);
if (socket_uuid != 0) {
grpc_json* array_parent = grpc_json_create_child(
nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false);

@ -34,13 +34,17 @@ namespace channelz {
class SubchannelNode : public BaseNode {
public:
SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes);
SubchannelNode(const char* target_address, size_t channel_tracer_max_nodes);
~SubchannelNode() override;
void MarkSubchannelDestroyed() {
GPR_ASSERT(subchannel_ != nullptr);
subchannel_ = nullptr;
}
// Sets the subchannel's connectivity state without health checking.
void UpdateConnectivityState(grpc_connectivity_state state);
// Used when the subchannel's child socket uuid changes. This should be set
// when the subchannel's transport is created and set to 0 when the subchannel
// unrefs the transport. A uuid of 0 indicates that the child socket is no
// longer associated with this subchannel.
void SetChildSocketUuid(intptr_t uuid);
grpc_json* RenderJson() override;
@ -61,7 +65,8 @@ class SubchannelNode : public BaseNode {
private:
void PopulateConnectivityState(grpc_json* json);
Subchannel* subchannel_;
Atomic<grpc_connectivity_state> connectivity_state_{GRPC_CHANNEL_IDLE};
Atomic<intptr_t> child_socket_uuid_{0};
UniquePtr<char> target_;
CallCountingHelper call_counter_;
ChannelTrace trace_;

@ -31,8 +31,8 @@
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/slice/b64.h"
#include "src/core/lib/uri/uri_parser.h"
@ -126,17 +126,18 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper,
if (no_proxy_str != nullptr) {
static const char* NO_PROXY_SEPARATOR = ",";
bool use_proxy = true;
char* server_host;
char* server_port;
if (!gpr_split_host_port(uri->path[0] == '/' ? uri->path + 1 : uri->path,
&server_host, &server_port)) {
grpc_core::UniquePtr<char> server_host;
grpc_core::UniquePtr<char> server_port;
if (!grpc_core::SplitHostPort(
uri->path[0] == '/' ? uri->path + 1 : uri->path, &server_host,
&server_port)) {
gpr_log(GPR_INFO,
"unable to split host and port, not checking no_proxy list for "
"host '%s'",
server_uri);
gpr_free(no_proxy_str);
} else {
size_t uri_len = strlen(server_host);
size_t uri_len = strlen(server_host.get());
char** no_proxy_hosts;
size_t num_no_proxy_hosts;
gpr_string_split(no_proxy_str, NO_PROXY_SEPARATOR, &no_proxy_hosts,
@ -145,8 +146,8 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper,
char* no_proxy_entry = no_proxy_hosts[i];
size_t no_proxy_len = strlen(no_proxy_entry);
if (no_proxy_len <= uri_len &&
gpr_stricmp(no_proxy_entry, &server_host[uri_len - no_proxy_len]) ==
0) {
gpr_stricmp(no_proxy_entry,
&(server_host.get()[uri_len - no_proxy_len])) == 0) {
gpr_log(GPR_INFO, "not using proxy for host in no_proxy list '%s'",
server_uri);
use_proxy = false;
@ -157,8 +158,6 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper,
gpr_free(no_proxy_hosts[i]);
}
gpr_free(no_proxy_hosts);
gpr_free(server_host);
gpr_free(server_port);
gpr_free(no_proxy_str);
if (!use_proxy) goto no_use_proxy;
}

@ -84,7 +84,6 @@
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/gprpp/memory.h"

@ -84,7 +84,6 @@
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/gprpp/map.h"

@ -33,8 +33,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/host_port.h"
#ifdef GRPC_POSIX_SOCKET
#include <errno.h>
@ -73,9 +73,9 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
bool log_errors) {
bool success = false;
// Split host and port.
char* host;
char* port;
if (!gpr_split_host_port(hostport, &host, &port)) {
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
if (!grpc_core::SplitHostPort(hostport, &host, &port)) {
if (log_errors) {
gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport);
}
@ -86,8 +86,10 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
addr->len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in));
grpc_sockaddr_in* in = reinterpret_cast<grpc_sockaddr_in*>(addr->addr);
in->sin_family = GRPC_AF_INET;
if (grpc_inet_pton(GRPC_AF_INET, host, &in->sin_addr) == 0) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host);
if (grpc_inet_pton(GRPC_AF_INET, host.get(), &in->sin_addr) == 0) {
if (log_errors) {
gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host.get());
}
goto done;
}
// Parse port.
@ -96,15 +98,14 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
goto done;
}
int port_num;
if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port);
if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 ||
port_num > 65535) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port.get());
goto done;
}
in->sin_port = grpc_htons(static_cast<uint16_t>(port_num));
success = true;
done:
gpr_free(host);
gpr_free(port);
return success;
}
@ -124,9 +125,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
bool log_errors) {
bool success = false;
// Split host and port.
char* host;
char* port;
if (!gpr_split_host_port(hostport, &host, &port)) {
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
if (!grpc_core::SplitHostPort(hostport, &host, &port)) {
if (log_errors) {
gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport);
}
@ -138,11 +139,12 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
grpc_sockaddr_in6* in6 = reinterpret_cast<grpc_sockaddr_in6*>(addr->addr);
in6->sin6_family = GRPC_AF_INET6;
// Handle the RFC6874 syntax for IPv6 zone identifiers.
char* host_end = static_cast<char*>(gpr_memrchr(host, '%', strlen(host)));
char* host_end =
static_cast<char*>(gpr_memrchr(host.get(), '%', strlen(host.get())));
if (host_end != nullptr) {
GPR_ASSERT(host_end >= host);
GPR_ASSERT(host_end >= host.get());
char host_without_scope[GRPC_INET6_ADDRSTRLEN + 1];
size_t host_without_scope_len = static_cast<size_t>(host_end - host);
size_t host_without_scope_len = static_cast<size_t>(host_end - host.get());
uint32_t sin6_scope_id = 0;
if (host_without_scope_len > GRPC_INET6_ADDRSTRLEN) {
if (log_errors) {
@ -154,7 +156,7 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
}
goto done;
}
strncpy(host_without_scope, host, host_without_scope_len);
strncpy(host_without_scope, host.get(), host_without_scope_len);
host_without_scope[host_without_scope_len] = '\0';
if (grpc_inet_pton(GRPC_AF_INET6, host_without_scope, &in6->sin6_addr) ==
0) {
@ -163,9 +165,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
}
goto done;
}
if (gpr_parse_bytes_to_uint32(host_end + 1,
strlen(host) - host_without_scope_len - 1,
&sin6_scope_id) == 0) {
if (gpr_parse_bytes_to_uint32(
host_end + 1, strlen(host.get()) - host_without_scope_len - 1,
&sin6_scope_id) == 0) {
if ((sin6_scope_id = grpc_if_nametoindex(host_end + 1)) == 0) {
gpr_log(GPR_ERROR,
"Invalid interface name: '%s'. "
@ -177,8 +179,10 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
// Handle "sin6_scope_id" being type "u_long". See grpc issue #10027.
in6->sin6_scope_id = sin6_scope_id;
} else {
if (grpc_inet_pton(GRPC_AF_INET6, host, &in6->sin6_addr) == 0) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host);
if (grpc_inet_pton(GRPC_AF_INET6, host.get(), &in6->sin6_addr) == 0) {
if (log_errors) {
gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host.get());
}
goto done;
}
}
@ -188,15 +192,14 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
goto done;
}
int port_num;
if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port);
if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 ||
port_num > 65535) {
if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port.get());
goto done;
}
in6->sin6_port = grpc_htons(static_cast<uint16_t>(port_num));
success = true;
done:
gpr_free(host);
gpr_free(port);
return success;
}

@ -38,7 +38,6 @@
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/combiner.h"
@ -401,7 +400,8 @@ void AresDnsResolver::MaybeStartResolvingLocked() {
// new closure API is done, find a way to track this ref with the timer
// callback as part of the type system.
Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release();
grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution,
grpc_timer_init(&next_resolution_timer_,
ExecCtx::Get()->Now() + ms_until_next_resolution,
&on_next_resolution_);
return;
}

@ -31,6 +31,9 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/iocp_windows.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/sockaddr_windows.h"
#include "src/core/lib/iomgr/socket_windows.h"
#include "src/core/lib/iomgr/tcp_windows.h"
#include "src/core/lib/slice/slice_internal.h"
@ -50,6 +53,32 @@ struct iovec {
namespace grpc_core {
/* c-ares reads and takes action on the error codes of the
* "virtual socket operations" in this file, via the WSAGetLastError
* APIs. If code in this file wants to set a specific WSA error that
* c-ares should read, it must do so by calling SetWSAError() on the
* WSAErrorContext instance passed to it. A WSAErrorContext must only be
* instantiated at the top of the virtual socket function callstack. */
class WSAErrorContext {
public:
explicit WSAErrorContext(){};
~WSAErrorContext() {
if (error_ != 0) {
WSASetLastError(error_);
}
}
/* Disallow copy and assignment operators */
WSAErrorContext(const WSAErrorContext&) = delete;
WSAErrorContext& operator=(const WSAErrorContext&) = delete;
void SetWSAError(int error) { error_ = error; }
private:
int error_ = 0;
};
/* c-ares creates its own sockets and is meant to read them when readable and
* write them when writeable. To fit this socket usage model into the grpc
* windows poller (which gives notifications when attempted reads and writes are
@ -68,11 +97,14 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY,
};
GrpcPolledFdWindows(ares_socket_t as, grpc_combiner* combiner)
GrpcPolledFdWindows(ares_socket_t as, grpc_combiner* combiner,
int address_family, int socket_type)
: read_buf_(grpc_empty_slice()),
write_buf_(grpc_empty_slice()),
write_state_(WRITE_IDLE),
gotten_into_driver_list_(false) {
tcp_write_state_(WRITE_IDLE),
gotten_into_driver_list_(false),
address_family_(address_family),
socket_type_(socket_type) {
gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, as);
winsocket_ = grpc_winsocket_create(as, name_);
combiner_ = GRPC_COMBINER_REF(combiner, name_);
@ -82,6 +114,16 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
GRPC_CLOSURE_INIT(&outer_write_closure_,
&GrpcPolledFdWindows::OnIocpWriteable, this,
grpc_combiner_scheduler(combiner_));
GRPC_CLOSURE_INIT(&on_tcp_connect_locked_,
&GrpcPolledFdWindows::OnTcpConnectLocked, this,
grpc_combiner_scheduler(combiner_));
GRPC_CLOSURE_INIT(&continue_register_for_on_readable_locked_,
&GrpcPolledFdWindows::ContinueRegisterForOnReadableLocked,
this, grpc_combiner_scheduler(combiner_));
GRPC_CLOSURE_INIT(
&continue_register_for_on_writeable_locked_,
&GrpcPolledFdWindows::ContinueRegisterForOnWriteableLocked, this,
grpc_combiner_scheduler(combiner_));
}
~GrpcPolledFdWindows() {
@ -111,6 +153,33 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
grpc_slice_unref_internal(read_buf_);
GPR_ASSERT(!read_buf_has_data_);
read_buf_ = GRPC_SLICE_MALLOC(4192);
if (connect_done_) {
GRPC_CLOSURE_SCHED(&continue_register_for_on_readable_locked_,
GRPC_ERROR_NONE);
} else {
GPR_ASSERT(pending_continue_register_for_on_readable_locked_ == nullptr);
pending_continue_register_for_on_readable_locked_ =
&continue_register_for_on_readable_locked_;
}
}
static void ContinueRegisterForOnReadableLocked(void* arg,
grpc_error* unused_error) {
GrpcPolledFdWindows* grpc_polled_fd =
static_cast<GrpcPolledFdWindows*>(arg);
grpc_polled_fd->InnerContinueRegisterForOnReadableLocked(GRPC_ERROR_NONE);
}
void InnerContinueRegisterForOnReadableLocked(grpc_error* unused_error) {
GRPC_CARES_TRACE_LOG(
"fd:|%s| InnerContinueRegisterForOnReadableLocked "
"wsa_connect_error_:%d",
GetName(), wsa_connect_error_);
GPR_ASSERT(connect_done_);
if (wsa_connect_error_ != 0) {
ScheduleAndNullReadClosure(GRPC_WSA_ERROR(wsa_connect_error_, "connect"));
return;
}
WSABUF buffer;
buffer.buf = (char*)GRPC_SLICE_START_PTR(read_buf_);
buffer.len = GRPC_SLICE_LENGTH(read_buf_);
@ -123,13 +192,14 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
&winsocket_->read_info.overlapped, nullptr)) {
int wsa_last_error = WSAGetLastError();
char* msg = gpr_format_message(wsa_last_error);
grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
GRPC_CARES_TRACE_LOG(
"RegisterForOnReadableLocked: WSARecvFrom error:|%s|. fd:|%s|", msg,
GetName());
"fd:|%s| RegisterForOnReadableLocked WSARecvFrom error code:|%d| "
"msg:|%s|",
GetName(), wsa_last_error, msg);
gpr_free(msg);
if (wsa_last_error != WSA_IO_PENDING) {
ScheduleAndNullReadClosure(error);
ScheduleAndNullReadClosure(
GRPC_WSA_ERROR(wsa_last_error, "WSARecvFrom"));
return;
}
}
@ -137,23 +207,68 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
}
void RegisterForOnWriteableLocked(grpc_closure* write_closure) override {
GRPC_CARES_TRACE_LOG(
"RegisterForOnWriteableLocked. fd:|%s|. Current write state: %d",
GetName(), write_state_);
if (socket_type_ == SOCK_DGRAM) {
GRPC_CARES_TRACE_LOG("fd:|%s| RegisterForOnWriteableLocked called",
GetName());
} else {
GPR_ASSERT(socket_type_ == SOCK_STREAM);
GRPC_CARES_TRACE_LOG(
"fd:|%s| RegisterForOnWriteableLocked called tcp_write_state_: %d",
GetName(), tcp_write_state_);
}
GPR_ASSERT(write_closure_ == nullptr);
write_closure_ = write_closure;
switch (write_state_) {
case WRITE_IDLE:
ScheduleAndNullWriteClosure(GRPC_ERROR_NONE);
break;
case WRITE_REQUESTED:
write_state_ = WRITE_PENDING;
SendWriteBuf(nullptr, &winsocket_->write_info.overlapped);
grpc_socket_notify_on_write(winsocket_, &outer_write_closure_);
break;
case WRITE_PENDING:
case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY:
abort();
if (connect_done_) {
GRPC_CLOSURE_SCHED(&continue_register_for_on_writeable_locked_,
GRPC_ERROR_NONE);
} else {
GPR_ASSERT(pending_continue_register_for_on_writeable_locked_ == nullptr);
pending_continue_register_for_on_writeable_locked_ =
&continue_register_for_on_writeable_locked_;
}
}
static void ContinueRegisterForOnWriteableLocked(void* arg,
grpc_error* unused_error) {
GrpcPolledFdWindows* grpc_polled_fd =
static_cast<GrpcPolledFdWindows*>(arg);
grpc_polled_fd->InnerContinueRegisterForOnWriteableLocked(GRPC_ERROR_NONE);
}
void InnerContinueRegisterForOnWriteableLocked(grpc_error* unused_error) {
GRPC_CARES_TRACE_LOG(
"fd:|%s| InnerContinueRegisterForOnWriteableLocked "
"wsa_connect_error_:%d",
GetName(), wsa_connect_error_);
GPR_ASSERT(connect_done_);
if (wsa_connect_error_ != 0) {
ScheduleAndNullWriteClosure(
GRPC_WSA_ERROR(wsa_connect_error_, "connect"));
return;
}
if (socket_type_ == SOCK_DGRAM) {
ScheduleAndNullWriteClosure(GRPC_ERROR_NONE);
} else {
GPR_ASSERT(socket_type_ == SOCK_STREAM);
int wsa_error_code = 0;
switch (tcp_write_state_) {
case WRITE_IDLE:
ScheduleAndNullWriteClosure(GRPC_ERROR_NONE);
break;
case WRITE_REQUESTED:
tcp_write_state_ = WRITE_PENDING;
if (SendWriteBuf(nullptr, &winsocket_->write_info.overlapped,
&wsa_error_code) != 0) {
ScheduleAndNullWriteClosure(
GRPC_WSA_ERROR(wsa_error_code, "WSASend (overlapped)"));
} else {
grpc_socket_notify_on_write(winsocket_, &outer_write_closure_);
}
break;
case WRITE_PENDING:
case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY:
abort();
}
}
}
@ -171,13 +286,15 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
const char* GetName() override { return name_; }
ares_ssize_t RecvFrom(void* data, ares_socket_t data_len, int flags,
ares_ssize_t RecvFrom(WSAErrorContext* wsa_error_ctx, void* data,
ares_socket_t data_len, int flags,
struct sockaddr* from, ares_socklen_t* from_len) {
GRPC_CARES_TRACE_LOG(
"RecvFrom called on fd:|%s|. Current read buf length:|%d|", GetName(),
GRPC_SLICE_LENGTH(read_buf_));
"fd:|%s| RecvFrom called read_buf_has_data:%d Current read buf "
"length:|%d|",
GetName(), read_buf_has_data_, GRPC_SLICE_LENGTH(read_buf_));
if (!read_buf_has_data_) {
WSASetLastError(WSAEWOULDBLOCK);
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
return -1;
}
ares_ssize_t bytes_read = 0;
@ -215,54 +332,99 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
return out;
}
int SendWriteBuf(LPDWORD bytes_sent_ptr, LPWSAOVERLAPPED overlapped) {
int SendWriteBuf(LPDWORD bytes_sent_ptr, LPWSAOVERLAPPED overlapped,
int* wsa_error_code) {
WSABUF buf;
buf.len = GRPC_SLICE_LENGTH(write_buf_);
buf.buf = (char*)GRPC_SLICE_START_PTR(write_buf_);
DWORD flags = 0;
int out = WSASend(grpc_winsocket_wrapped_socket(winsocket_), &buf, 1,
bytes_sent_ptr, flags, overlapped, nullptr);
*wsa_error_code = WSAGetLastError();
GRPC_CARES_TRACE_LOG(
"WSASend: name:%s. buf len:%d. bytes sent: %d. overlapped %p. return "
"val: %d",
GetName(), buf.len, *bytes_sent_ptr, overlapped, out);
"fd:|%s| SendWriteBuf WSASend buf.len:%d *bytes_sent_ptr:%d "
"overlapped:%p "
"return:%d *wsa_error_code:%d",
GetName(), buf.len, bytes_sent_ptr != nullptr ? *bytes_sent_ptr : 0,
overlapped, out, *wsa_error_code);
return out;
}
ares_ssize_t TrySendWriteBufSyncNonBlocking() {
GPR_ASSERT(write_state_ == WRITE_IDLE);
ares_ssize_t SendV(WSAErrorContext* wsa_error_ctx, const struct iovec* iov,
int iov_count) {
GRPC_CARES_TRACE_LOG(
"fd:|%s| SendV called connect_done_:%d wsa_connect_error_:%d",
GetName(), connect_done_, wsa_connect_error_);
if (!connect_done_) {
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
return -1;
}
if (wsa_connect_error_ != 0) {
wsa_error_ctx->SetWSAError(wsa_connect_error_);
return -1;
}
switch (socket_type_) {
case SOCK_DGRAM:
return SendVUDP(wsa_error_ctx, iov, iov_count);
case SOCK_STREAM:
return SendVTCP(wsa_error_ctx, iov, iov_count);
default:
abort();
}
}
ares_ssize_t SendVUDP(WSAErrorContext* wsa_error_ctx, const struct iovec* iov,
int iov_count) {
// c-ares doesn't handle retryable errors on writes of UDP sockets.
// Therefore, the sendv handler for UDP sockets must only attempt
// to write everything inline.
GRPC_CARES_TRACE_LOG("fd:|%s| SendVUDP called", GetName());
GPR_ASSERT(GRPC_SLICE_LENGTH(write_buf_) == 0);
grpc_slice_unref_internal(write_buf_);
write_buf_ = FlattenIovec(iov, iov_count);
DWORD bytes_sent = 0;
if (SendWriteBuf(&bytes_sent, nullptr) != 0) {
int wsa_last_error = WSAGetLastError();
char* msg = gpr_format_message(wsa_last_error);
int wsa_error_code = 0;
if (SendWriteBuf(&bytes_sent, nullptr, &wsa_error_code) != 0) {
wsa_error_ctx->SetWSAError(wsa_error_code);
char* msg = gpr_format_message(wsa_error_code);
GRPC_CARES_TRACE_LOG(
"TrySendWriteBufSyncNonBlocking: SendWriteBuf error:|%s|. fd:|%s|",
msg, GetName());
"fd:|%s| SendVUDP SendWriteBuf error code:%d msg:|%s|", GetName(),
wsa_error_code, msg);
gpr_free(msg);
if (wsa_last_error == WSA_IO_PENDING) {
WSASetLastError(WSAEWOULDBLOCK);
write_state_ = WRITE_REQUESTED;
}
return -1;
}
write_buf_ = grpc_slice_sub_no_ref(write_buf_, bytes_sent,
GRPC_SLICE_LENGTH(write_buf_));
return bytes_sent;
}
ares_ssize_t SendV(const struct iovec* iov, int iov_count) {
GRPC_CARES_TRACE_LOG("SendV called on fd:|%s|. Current write state: %d",
GetName(), write_state_);
switch (write_state_) {
ares_ssize_t SendVTCP(WSAErrorContext* wsa_error_ctx, const struct iovec* iov,
int iov_count) {
// The "sendv" handler on TCP sockets buffers up write
// requests and returns an artifical WSAEWOULDBLOCK. Writing that buffer out
// in the background, and making further send progress in general, will
// happen as long as c-ares continues to show interest in writeability on
// this fd.
GRPC_CARES_TRACE_LOG("fd:|%s| SendVTCP called tcp_write_state_:%d",
GetName(), tcp_write_state_);
switch (tcp_write_state_) {
case WRITE_IDLE:
tcp_write_state_ = WRITE_REQUESTED;
GPR_ASSERT(GRPC_SLICE_LENGTH(write_buf_) == 0);
grpc_slice_unref_internal(write_buf_);
write_buf_ = FlattenIovec(iov, iov_count);
return TrySendWriteBufSyncNonBlocking();
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
return -1;
case WRITE_REQUESTED:
case WRITE_PENDING:
WSASetLastError(WSAEWOULDBLOCK);
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
return -1;
case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY:
// c-ares is retrying a send on data that we previously returned
// WSAEWOULDBLOCK for, but then subsequently wrote out in the
// background. Right now, we assume that c-ares is retrying the same
// send again. If c-ares still needs to send even more data, we'll get
// to it eventually.
grpc_slice currently_attempted = FlattenIovec(iov, iov_count);
GPR_ASSERT(GRPC_SLICE_LENGTH(currently_attempted) >=
GRPC_SLICE_LENGTH(write_buf_));
@ -272,31 +434,159 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
GRPC_SLICE_START_PTR(write_buf_)[i]);
total_sent++;
}
grpc_slice_unref_internal(write_buf_);
write_buf_ =
grpc_slice_sub_no_ref(currently_attempted, total_sent,
GRPC_SLICE_LENGTH(currently_attempted));
write_state_ = WRITE_IDLE;
total_sent += TrySendWriteBufSyncNonBlocking();
grpc_slice_unref_internal(currently_attempted);
tcp_write_state_ = WRITE_IDLE;
return total_sent;
}
abort();
}
int Connect(const struct sockaddr* target, ares_socklen_t target_len) {
static void OnTcpConnectLocked(void* arg, grpc_error* error) {
GrpcPolledFdWindows* grpc_polled_fd =
static_cast<GrpcPolledFdWindows*>(arg);
grpc_polled_fd->InnerOnTcpConnectLocked(error);
}
void InnerOnTcpConnectLocked(grpc_error* error) {
GRPC_CARES_TRACE_LOG(
"fd:%s InnerOnTcpConnectLocked error:|%s| "
"pending_register_for_readable:%" PRIdPTR
" pending_register_for_writeable:%" PRIdPTR,
GetName(), grpc_error_string(error),
pending_continue_register_for_on_readable_locked_,
pending_continue_register_for_on_writeable_locked_);
GPR_ASSERT(!connect_done_);
connect_done_ = true;
GPR_ASSERT(wsa_connect_error_ == 0);
if (error == GRPC_ERROR_NONE) {
DWORD transfered_bytes = 0;
DWORD flags;
BOOL wsa_success = WSAGetOverlappedResult(
grpc_winsocket_wrapped_socket(winsocket_),
&winsocket_->write_info.overlapped, &transfered_bytes, FALSE, &flags);
GPR_ASSERT(transfered_bytes == 0);
if (!wsa_success) {
wsa_connect_error_ = WSAGetLastError();
char* msg = gpr_format_message(wsa_connect_error_);
GRPC_CARES_TRACE_LOG(
"fd:%s InnerOnTcpConnectLocked WSA overlapped result code:%d "
"msg:|%s|",
GetName(), wsa_connect_error_, msg);
gpr_free(msg);
}
} else {
// Spoof up an error code that will cause any future c-ares operations on
// this fd to abort.
wsa_connect_error_ = WSA_OPERATION_ABORTED;
}
if (pending_continue_register_for_on_readable_locked_ != nullptr) {
GRPC_CLOSURE_SCHED(pending_continue_register_for_on_readable_locked_,
GRPC_ERROR_NONE);
}
if (pending_continue_register_for_on_writeable_locked_ != nullptr) {
GRPC_CLOSURE_SCHED(pending_continue_register_for_on_writeable_locked_,
GRPC_ERROR_NONE);
}
}
int Connect(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target,
ares_socklen_t target_len) {
switch (socket_type_) {
case SOCK_DGRAM:
return ConnectUDP(wsa_error_ctx, target, target_len);
case SOCK_STREAM:
return ConnectTCP(wsa_error_ctx, target, target_len);
default:
abort();
}
}
int ConnectUDP(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target,
ares_socklen_t target_len) {
GRPC_CARES_TRACE_LOG("fd:%s ConnectUDP", GetName());
GPR_ASSERT(!connect_done_);
GPR_ASSERT(wsa_connect_error_ == 0);
SOCKET s = grpc_winsocket_wrapped_socket(winsocket_);
GRPC_CARES_TRACE_LOG("Connect: fd:|%s|", GetName());
int out =
WSAConnect(s, target, target_len, nullptr, nullptr, nullptr, nullptr);
if (out != 0) {
wsa_connect_error_ = WSAGetLastError();
wsa_error_ctx->SetWSAError(wsa_connect_error_);
connect_done_ = true;
char* msg = gpr_format_message(wsa_connect_error_);
GRPC_CARES_TRACE_LOG("fd:%s WSAConnect error code:|%d| msg:|%s|", GetName(),
wsa_connect_error_, msg);
gpr_free(msg);
// c-ares expects a posix-style connect API
return out == 0 ? 0 : -1;
}
int ConnectTCP(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target,
ares_socklen_t target_len) {
GRPC_CARES_TRACE_LOG("fd:%s ConnectTCP", GetName());
LPFN_CONNECTEX ConnectEx;
GUID guid = WSAID_CONNECTEX;
DWORD ioctl_num_bytes;
SOCKET s = grpc_winsocket_wrapped_socket(winsocket_);
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
&ConnectEx, sizeof(ConnectEx), &ioctl_num_bytes, nullptr,
nullptr) != 0) {
int wsa_last_error = WSAGetLastError();
wsa_error_ctx->SetWSAError(wsa_last_error);
char* msg = gpr_format_message(wsa_last_error);
GRPC_CARES_TRACE_LOG(
"fd:%s WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER) error code:%d "
"msg:|%s|",
GetName(), wsa_last_error, msg);
gpr_free(msg);
connect_done_ = true;
wsa_connect_error_ = wsa_last_error;
return -1;
}
grpc_resolved_address wildcard4_addr;
grpc_resolved_address wildcard6_addr;
grpc_sockaddr_make_wildcards(0, &wildcard4_addr, &wildcard6_addr);
grpc_resolved_address* local_address = nullptr;
if (address_family_ == AF_INET) {
local_address = &wildcard4_addr;
} else {
local_address = &wildcard6_addr;
}
if (bind(s, (struct sockaddr*)local_address->addr,
(int)local_address->len) != 0) {
int wsa_last_error = WSAGetLastError();
wsa_error_ctx->SetWSAError(wsa_last_error);
char* msg = gpr_format_message(wsa_last_error);
GRPC_CARES_TRACE_LOG("Connect error code:|%d|, msg:|%s|. fd:|%s|",
wsa_last_error, msg, GetName());
GRPC_CARES_TRACE_LOG("fd:%s bind error code:%d msg:|%s|", GetName(),
wsa_last_error, msg);
gpr_free(msg);
// c-ares expects a posix-style connect API
connect_done_ = true;
wsa_connect_error_ = wsa_last_error;
return -1;
}
int out = 0;
if (ConnectEx(s, target, target_len, nullptr, 0, nullptr,
&winsocket_->write_info.overlapped) == 0) {
out = -1;
int wsa_last_error = WSAGetLastError();
wsa_error_ctx->SetWSAError(wsa_last_error);
char* msg = gpr_format_message(wsa_last_error);
GRPC_CARES_TRACE_LOG("fd:%s ConnectEx error code:%d msg:|%s|", GetName(),
wsa_last_error, msg);
gpr_free(msg);
if (wsa_last_error == WSA_IO_PENDING) {
// c-ares only understands WSAEINPROGRESS and EWOULDBLOCK error codes on
// connect, but an async connect on IOCP socket will give
// WSA_IO_PENDING, so we need to convert.
wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK);
} else {
// By returning a non-retryable error to c-ares at this point,
// we're aborting the possibility of any future operations on this fd.
connect_done_ = true;
wsa_connect_error_ = wsa_last_error;
return -1;
}
}
grpc_socket_notify_on_write(winsocket_, &on_tcp_connect_locked_);
return out;
}
@ -319,12 +609,13 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
* in subsequent c-ares reads. */
if (winsocket_->read_info.wsa_error != WSAEMSGSIZE) {
GRPC_ERROR_UNREF(error);
char* msg = gpr_format_message(winsocket_->read_info.wsa_error);
error = GRPC_WSA_ERROR(winsocket_->read_info.wsa_error,
"OnIocpReadableInner");
GRPC_CARES_TRACE_LOG(
"OnIocpReadableInner. winsocket error:|%s|. fd:|%s|", msg,
GetName());
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
"fd:|%s| OnIocpReadableInner winsocket_->read_info.wsa_error "
"code:|%d| msg:|%s|",
GetName(), winsocket_->read_info.wsa_error,
grpc_error_string(error));
}
}
}
@ -337,8 +628,8 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
read_buf_ = grpc_empty_slice();
}
GRPC_CARES_TRACE_LOG(
"OnIocpReadable finishing. read buf length now:|%d|. :fd:|%s|",
GRPC_SLICE_LENGTH(read_buf_), GetName());
"fd:|%s| OnIocpReadable finishing. read buf length now:|%d|", GetName(),
GRPC_SLICE_LENGTH(read_buf_));
ScheduleAndNullReadClosure(error);
}
@ -349,22 +640,26 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
void OnIocpWriteableInner(grpc_error* error) {
GRPC_CARES_TRACE_LOG("OnIocpWriteableInner. fd:|%s|", GetName());
GPR_ASSERT(socket_type_ == SOCK_STREAM);
if (error == GRPC_ERROR_NONE) {
if (winsocket_->write_info.wsa_error != 0) {
char* msg = gpr_format_message(winsocket_->write_info.wsa_error);
GRPC_CARES_TRACE_LOG(
"OnIocpWriteableInner. winsocket error:|%s|. fd:|%s|", msg,
GetName());
GRPC_ERROR_UNREF(error);
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
error = GRPC_WSA_ERROR(winsocket_->write_info.wsa_error,
"OnIocpWriteableInner");
GRPC_CARES_TRACE_LOG(
"fd:|%s| OnIocpWriteableInner. winsocket_->write_info.wsa_error "
"code:|%d| msg:|%s|",
GetName(), winsocket_->write_info.wsa_error,
grpc_error_string(error));
}
}
GPR_ASSERT(write_state_ == WRITE_PENDING);
GPR_ASSERT(tcp_write_state_ == WRITE_PENDING);
if (error == GRPC_ERROR_NONE) {
write_state_ = WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY;
tcp_write_state_ = WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY;
write_buf_ = grpc_slice_sub_no_ref(
write_buf_, 0, winsocket_->write_info.bytes_transfered);
GRPC_CARES_TRACE_LOG("fd:|%s| OnIocpWriteableInner. bytes transferred:%d",
GetName(), winsocket_->write_info.bytes_transfered);
} else {
grpc_slice_unref_internal(write_buf_);
write_buf_ = grpc_empty_slice();
@ -386,9 +681,22 @@ class GrpcPolledFdWindows : public GrpcPolledFd {
grpc_closure outer_read_closure_;
grpc_closure outer_write_closure_;
grpc_winsocket* winsocket_;
WriteState write_state_;
// tcp_write_state_ is only used on TCP GrpcPolledFds
WriteState tcp_write_state_;
char* name_ = nullptr;
bool gotten_into_driver_list_;
int address_family_;
int socket_type_;
grpc_closure on_tcp_connect_locked_;
bool connect_done_ = false;
int wsa_connect_error_ = 0;
// We don't run register_for_{readable,writeable} logic until
// a socket is connected. In the interim, we queue readable/writeable
// registrations with the following state.
grpc_closure continue_register_for_on_readable_locked_;
grpc_closure continue_register_for_on_writeable_locked_;
grpc_closure* pending_continue_register_for_on_readable_locked_ = nullptr;
grpc_closure* pending_continue_register_for_on_writeable_locked_ = nullptr;
};
struct SockToPolledFdEntry {
@ -454,39 +762,53 @@ class SockToPolledFdMap {
* objects.
*/
static ares_socket_t Socket(int af, int type, int protocol, void* user_data) {
if (type != SOCK_DGRAM && type != SOCK_STREAM) {
GRPC_CARES_TRACE_LOG("Socket called with invalid socket type:%d", type);
return INVALID_SOCKET;
}
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
SOCKET s = WSASocket(af, type, protocol, nullptr, 0,
grpc_get_default_wsa_socket_flags());
if (s == INVALID_SOCKET) {
GRPC_CARES_TRACE_LOG(
"WSASocket failed with params af:%d type:%d protocol:%d", af, type,
protocol);
return s;
}
grpc_tcp_set_non_block(s);
GrpcPolledFdWindows* polled_fd =
New<GrpcPolledFdWindows>(s, map->combiner_);
New<GrpcPolledFdWindows>(s, map->combiner_, af, type);
GRPC_CARES_TRACE_LOG(
"fd:|%s| created with params af:%d type:%d protocol:%d",
polled_fd->GetName(), af, type, protocol);
map->AddNewSocket(s, polled_fd);
return s;
}
static int Connect(ares_socket_t as, const struct sockaddr* target,
ares_socklen_t target_len, void* user_data) {
WSAErrorContext wsa_error_ctx;
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as);
return polled_fd->Connect(target, target_len);
return polled_fd->Connect(&wsa_error_ctx, target, target_len);
}
static ares_ssize_t SendV(ares_socket_t as, const struct iovec* iov,
int iovec_count, void* user_data) {
WSAErrorContext wsa_error_ctx;
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as);
return polled_fd->SendV(iov, iovec_count);
return polled_fd->SendV(&wsa_error_ctx, iov, iovec_count);
}
static ares_ssize_t RecvFrom(ares_socket_t as, void* data, size_t data_len,
int flags, struct sockaddr* from,
ares_socklen_t* from_len, void* user_data) {
WSAErrorContext wsa_error_ctx;
SockToPolledFdMap* map = static_cast<SockToPolledFdMap*>(user_data);
GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as);
return polled_fd->RecvFrom(data, data_len, flags, from, from_len);
return polled_fd->RecvFrom(&wsa_error_ctx, data, data_len, flags, from,
from_len);
}
static int CloseSocket(SOCKET s, void* user_data) {

@ -35,8 +35,8 @@
#include <address_sorting/address_sorting.h>
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/executor.h"
@ -355,9 +355,9 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
grpc_ares_hostbyname_request* hr = nullptr;
ares_channel* channel = nullptr;
/* parse name, splitting it into host and port parts */
char* host;
char* port;
gpr_split_host_port(name, &host, &port);
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
grpc_core::SplitHostPort(name, &host, &port);
if (host == nullptr) {
error = grpc_error_set_str(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"),
@ -370,7 +370,7 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
goto error_cleanup;
}
port = gpr_strdup(default_port);
port.reset(gpr_strdup(default_port));
}
error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties,
query_timeout_ms, combiner, r);
@ -414,20 +414,22 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
}
r->pending_queries = 1;
if (grpc_ares_query_ipv6()) {
hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port),
false /* is_balancer */);
hr = create_hostbyname_request_locked(r, host.get(),
grpc_strhtons(port.get()),
/*is_balancer=*/false);
ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_locked,
hr);
}
hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port),
false /* is_balancer */);
hr =
create_hostbyname_request_locked(r, host.get(), grpc_strhtons(port.get()),
/*is_balancer=*/false);
ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_locked,
hr);
if (check_grpclb) {
/* Query the SRV record */
grpc_ares_request_ref_locked(r);
char* service_name;
gpr_asprintf(&service_name, "_grpclb._tcp.%s", host);
gpr_asprintf(&service_name, "_grpclb._tcp.%s", host.get());
ares_query(*channel, service_name, ns_c_in, ns_t_srv,
on_srv_query_done_locked, r);
gpr_free(service_name);
@ -435,28 +437,25 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
if (r->service_config_json_out != nullptr) {
grpc_ares_request_ref_locked(r);
char* config_name;
gpr_asprintf(&config_name, "_grpc_config.%s", host);
gpr_asprintf(&config_name, "_grpc_config.%s", host.get());
ares_search(*channel, config_name, ns_c_in, ns_t_txt, on_txt_done_locked,
r);
gpr_free(config_name);
}
grpc_ares_ev_driver_start_locked(r->ev_driver);
grpc_ares_request_unref_locked(r);
gpr_free(host);
gpr_free(port);
return;
error_cleanup:
GRPC_CLOSURE_SCHED(r->on_done, error);
gpr_free(host);
gpr_free(port);
}
static bool inner_resolve_as_ip_literal_locked(
const char* name, const char* default_port,
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs, char** host,
char** port, char** hostport) {
gpr_split_host_port(name, host, port);
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
grpc_core::UniquePtr<char>* host, grpc_core::UniquePtr<char>* port,
grpc_core::UniquePtr<char>* hostport) {
grpc_core::SplitHostPort(name, host, port);
if (*host == nullptr) {
gpr_log(GPR_ERROR,
"Failed to parse %s to host:port while attempting to resolve as ip "
@ -472,12 +471,14 @@ static bool inner_resolve_as_ip_literal_locked(
name);
return false;
}
*port = gpr_strdup(default_port);
port->reset(gpr_strdup(default_port));
}
grpc_resolved_address addr;
GPR_ASSERT(gpr_join_host_port(hostport, *host, atoi(*port)));
if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) ||
grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) {
GPR_ASSERT(grpc_core::JoinHostPort(hostport, host->get(), atoi(port->get())));
if (grpc_parse_ipv4_hostport(hostport->get(), &addr,
false /* log errors */) ||
grpc_parse_ipv6_hostport(hostport->get(), &addr,
false /* log errors */)) {
GPR_ASSERT(*addrs == nullptr);
*addrs = grpc_core::MakeUnique<ServerAddressList>();
(*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */);
@ -489,24 +490,22 @@ static bool inner_resolve_as_ip_literal_locked(
static bool resolve_as_ip_literal_locked(
const char* name, const char* default_port,
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs) {
char* host = nullptr;
char* port = nullptr;
char* hostport = nullptr;
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
grpc_core::UniquePtr<char> hostport;
bool out = inner_resolve_as_ip_literal_locked(name, default_port, addrs,
&host, &port, &hostport);
gpr_free(host);
gpr_free(port);
gpr_free(hostport);
return out;
}
static bool target_matches_localhost_inner(const char* name, char** host,
char** port) {
if (!gpr_split_host_port(name, host, port)) {
static bool target_matches_localhost_inner(const char* name,
grpc_core::UniquePtr<char>* host,
grpc_core::UniquePtr<char>* port) {
if (!grpc_core::SplitHostPort(name, host, port)) {
gpr_log(GPR_ERROR, "Unable to split host and port for name: %s", name);
return false;
}
if (gpr_stricmp(*host, "localhost") == 0) {
if (gpr_stricmp(host->get(), "localhost") == 0) {
return true;
} else {
return false;
@ -514,20 +513,17 @@ static bool target_matches_localhost_inner(const char* name, char** host,
}
static bool target_matches_localhost(const char* name) {
char* host = nullptr;
char* port = nullptr;
bool out = target_matches_localhost_inner(name, &host, &port);
gpr_free(host);
gpr_free(port);
return out;
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
return target_matches_localhost_inner(name, &host, &port);
}
#ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY
static bool inner_maybe_resolve_localhost_manually_locked(
const char* name, const char* default_port,
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs, char** host,
char** port) {
gpr_split_host_port(name, host, port);
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
grpc_core::UniquePtr<char>* host, grpc_core::UniquePtr<char>* port) {
grpc_core::SplitHostPort(name, host, port);
if (*host == nullptr) {
gpr_log(GPR_ERROR,
"Failed to parse %s into host:port during manual localhost "
@ -543,12 +539,12 @@ static bool inner_maybe_resolve_localhost_manually_locked(
name);
return false;
}
*port = gpr_strdup(default_port);
port->reset(gpr_strdup(default_port));
}
if (gpr_stricmp(*host, "localhost") == 0) {
if (gpr_stricmp(host->get(), "localhost") == 0) {
GPR_ASSERT(*addrs == nullptr);
*addrs = grpc_core::MakeUnique<grpc_core::ServerAddressList>();
uint16_t numeric_port = grpc_strhtons(*port);
uint16_t numeric_port = grpc_strhtons(port->get());
// Append the ipv6 loopback address.
struct sockaddr_in6 ipv6_loopback_addr;
memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr));
@ -576,13 +572,10 @@ static bool inner_maybe_resolve_localhost_manually_locked(
static bool grpc_ares_maybe_resolve_localhost_manually_locked(
const char* name, const char* default_port,
grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs) {
char* host = nullptr;
char* port = nullptr;
bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port,
addrs, &host, &port);
gpr_free(host);
gpr_free(port);
return out;
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
return inner_maybe_resolve_localhost_manually_locked(name, default_port,
addrs, &host, &port);
}
#else /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */
static bool grpc_ares_maybe_resolve_localhost_manually_locked(

@ -26,7 +26,6 @@
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
bool grpc_ares_query_ipv6() {

@ -26,7 +26,6 @@
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/socket_windows.h"

@ -31,7 +31,6 @@
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/combiner.h"
@ -230,7 +229,8 @@ void NativeDnsResolver::MaybeStartResolvingLocked() {
// new closure API is done, find a way to track this ref with the timer
// callback as part of the type system.
Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release();
grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution,
grpc_timer_init(&next_resolution_timer_,
ExecCtx::Get()->Now() + ms_until_next_resolution,
&on_next_resolution_);
return;
}

@ -32,7 +32,6 @@
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/closure.h"

@ -30,7 +30,6 @@
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/resolve_address.h"

@ -84,13 +84,11 @@ DebugOnlyTraceFlag grpc_trace_subchannel_refcount(false, "subchannel_refcount");
ConnectedSubchannel::ConnectedSubchannel(
grpc_channel_stack* channel_stack, const grpc_channel_args* args,
RefCountedPtr<channelz::SubchannelNode> channelz_subchannel,
intptr_t socket_uuid)
RefCountedPtr<channelz::SubchannelNode> channelz_subchannel)
: ConnectedSubchannelInterface(&grpc_trace_subchannel_refcount),
channel_stack_(channel_stack),
args_(grpc_channel_args_copy(args)),
channelz_subchannel_(std::move(channelz_subchannel)),
socket_uuid_(socket_uuid) {}
channelz_subchannel_(std::move(channelz_subchannel)) {}
ConnectedSubchannel::~ConnectedSubchannel() {
grpc_channel_args_destroy(args_);
@ -344,6 +342,9 @@ class Subchannel::ConnectedSubchannelStateWatcher {
self->pending_connectivity_state_));
}
c->connected_subchannel_.reset();
if (c->channelz_node() != nullptr) {
c->channelz_node()->SetChildSocketUuid(0);
}
c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE);
c->backoff_begun_ = false;
c->backoff_.Reset();
@ -676,7 +677,7 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector,
(size_t)grpc_channel_arg_get_integer(arg, options);
if (channelz_enabled) {
channelz_node_ = MakeRefCounted<channelz::SubchannelNode>(
this, channel_tracer_max_memory);
GetTargetAddress(), channel_tracer_max_memory);
channelz_node_->AddTraceEvent(
channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string("subchannel created"));
@ -688,7 +689,7 @@ Subchannel::~Subchannel() {
channelz_node_->AddTraceEvent(
channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string("Subchannel destroyed"));
channelz_node_->MarkSubchannelDestroyed();
channelz_node_->UpdateConnectivityState(GRPC_CHANNEL_SHUTDOWN);
}
grpc_channel_args_destroy(args_);
grpc_connector_unref(connector_);
@ -778,14 +779,6 @@ Subchannel* Subchannel::RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
}
}
intptr_t Subchannel::GetChildSocketUuid() {
if (connected_subchannel_ != nullptr) {
return connected_subchannel_->socket_uuid();
} else {
return 0;
}
}
const char* Subchannel::GetTargetAddress() {
const grpc_arg* addr_arg =
grpc_channel_args_find(args_, GRPC_ARG_SUBCHANNEL_ADDRESS);
@ -930,6 +923,7 @@ const char* SubchannelConnectivityStateChangeString(
void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state) {
state_ = state;
if (channelz_node_ != nullptr) {
channelz_node_->UpdateConnectivityState(state);
channelz_node_->AddTraceEvent(
channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string(
@ -1078,9 +1072,12 @@ bool Subchannel::PublishTransportLocked() {
}
// Publish.
connected_subchannel_.reset(
New<ConnectedSubchannel>(stk, args_, channelz_node_, socket_uuid));
New<ConnectedSubchannel>(stk, args_, channelz_node_));
gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p",
connected_subchannel_.get(), this);
if (channelz_node_ != nullptr) {
channelz_node_->SetChildSocketUuid(socket_uuid);
}
// Instantiate state watcher. Will clean itself up.
New<ConnectedSubchannelStateWatcher>(this);
// Report initial state.

@ -85,8 +85,7 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface {
ConnectedSubchannel(
grpc_channel_stack* channel_stack, const grpc_channel_args* args,
RefCountedPtr<channelz::SubchannelNode> channelz_subchannel,
intptr_t socket_uuid);
RefCountedPtr<channelz::SubchannelNode> channelz_subchannel);
~ConnectedSubchannel();
void NotifyOnStateChange(grpc_pollset_set* interested_parties,
@ -101,7 +100,6 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface {
channelz::SubchannelNode* channelz_subchannel() const {
return channelz_subchannel_.get();
}
intptr_t socket_uuid() const { return socket_uuid_; }
size_t GetInitialCallSizeEstimate(size_t parent_data_size) const;
@ -111,8 +109,6 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface {
// ref counted pointer to the channelz node in this connected subchannel's
// owning subchannel.
RefCountedPtr<channelz::SubchannelNode> channelz_subchannel_;
// uuid of this subchannel's socket. 0 if this subchannel is not connected.
const intptr_t socket_uuid_;
};
// Implements the interface of RefCounted<>.
@ -200,8 +196,6 @@ class Subchannel {
// returns null.
Subchannel* RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
intptr_t GetChildSocketUuid();
// Gets the string representing the subchannel address.
// Caller doesn't take ownership.
const char* GetTargetAddress();

@ -37,7 +37,6 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/resource_quota.h"

@ -137,10 +137,10 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames(
p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID,
static_cast<intptr_t>(s->id));
gpr_free(msg);
p->error =
grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES,
grpc_dump_slice_to_slice(
*slice, GPR_DUMP_HEX | GPR_DUMP_ASCII));
p->error = grpc_error_set_str(
p->error, GRPC_ERROR_STR_RAW_BYTES,
grpc_slice_from_moved_string(grpc_core::UniquePtr<char>(
grpc_dump_slice(*slice, GPR_DUMP_HEX | GPR_DUMP_ASCII))));
p->error =
grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg);
p->state = GRPC_CHTTP2_DATA_ERROR;

@ -130,8 +130,9 @@ static void begin_frame(framer_state* st) {
space to add at least about_to_add bytes -- finishes the current frame if
needed */
static void ensure_space(framer_state* st, size_t need_bytes) {
if (st->output->length - st->output_length_at_start_of_frame + need_bytes <=
st->max_frame_size) {
if (GPR_LIKELY(st->output->length - st->output_length_at_start_of_frame +
need_bytes <=
st->max_frame_size)) {
return;
}
finish_frame(st, 0, 0);
@ -711,18 +712,28 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c,
}
for (size_t i = 0; i < extra_headers_size; ++i) {
grpc_mdelem md = *extra_headers[i];
uintptr_t static_index = grpc_chttp2_get_static_hpack_table_index(md);
if (static_index) {
emit_indexed(c, static_cast<uint32_t>(static_index), &st);
const bool is_static =
GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC;
uintptr_t static_index;
if (is_static &&
(static_index =
reinterpret_cast<grpc_core::StaticMetadata*>(GRPC_MDELEM_DATA(md))
->StaticIndex()) < GRPC_CHTTP2_LAST_STATIC_ENTRY) {
emit_indexed(c, static_cast<uint32_t>(static_index + 1), &st);
} else {
hpack_enc(c, md, &st);
}
}
grpc_metadata_batch_assert_ok(metadata);
for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) {
uintptr_t static_index = grpc_chttp2_get_static_hpack_table_index(l->md);
if (static_index) {
emit_indexed(c, static_cast<uint32_t>(static_index), &st);
const bool is_static =
GRPC_MDELEM_STORAGE(l->md) == GRPC_MDELEM_STORAGE_STATIC;
uintptr_t static_index;
if (is_static &&
(static_index = reinterpret_cast<grpc_core::StaticMetadata*>(
GRPC_MDELEM_DATA(l->md))
->StaticIndex()) < GRPC_CHTTP2_LAST_STATIC_ENTRY) {
emit_indexed(c, static_cast<uint32_t>(static_index + 1), &st);
} else {
hpack_enc(c, l->md, &st);
}

@ -622,33 +622,37 @@ static const uint8_t inverse_base64[256] = {
255,
};
static void GPR_ATTRIBUTE_NOINLINE on_hdr_log(grpc_mdelem md) {
char* k = grpc_slice_to_c_string(GRPC_MDKEY(md));
char* v = nullptr;
if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) {
v = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX);
} else {
v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
}
gpr_log(
GPR_INFO,
"Decode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d",
k, v, GRPC_MDELEM_IS_INTERNED(md), GRPC_MDELEM_STORAGE(md),
grpc_slice_is_interned(GRPC_MDKEY(md)),
grpc_slice_is_interned(GRPC_MDVALUE(md)));
gpr_free(k);
gpr_free(v);
}
/* emission helpers */
static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md,
int add_to_table) {
template <bool do_add>
static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
char* k = grpc_slice_to_c_string(GRPC_MDKEY(md));
char* v = nullptr;
if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) {
v = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX);
} else {
v = grpc_slice_to_c_string(GRPC_MDVALUE(md));
}
gpr_log(
GPR_INFO,
"Decode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d",
k, v, GRPC_MDELEM_IS_INTERNED(md), GRPC_MDELEM_STORAGE(md),
grpc_slice_is_interned(GRPC_MDKEY(md)),
grpc_slice_is_interned(GRPC_MDVALUE(md)));
gpr_free(k);
gpr_free(v);
on_hdr_log(md);
}
if (add_to_table) {
GPR_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED ||
GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC);
if (do_add) {
GPR_DEBUG_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED ||
GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC);
grpc_error* err = grpc_chttp2_hptbl_add(&p->table, md);
if (err != GRPC_ERROR_NONE) return err;
if (GPR_UNLIKELY(err != GRPC_ERROR_NONE)) return err;
}
if (p->on_header == nullptr) {
if (GPR_UNLIKELY(p->on_header == nullptr)) {
GRPC_MDELEM_UNREF(md);
return GRPC_ERROR_CREATE_FROM_STATIC_STRING("on_header callback not set");
}
@ -765,7 +769,7 @@ static grpc_error* finish_indexed_field(grpc_chttp2_hpack_parser* p,
}
GRPC_MDELEM_REF(md);
GRPC_STATS_INC_HPACK_RECV_INDEXED();
grpc_error* err = on_hdr(p, md, 0);
grpc_error* err = on_hdr<false>(p, md);
if (err != GRPC_ERROR_NONE) return err;
return parse_begin(p, cur, end);
}
@ -798,11 +802,9 @@ static grpc_error* finish_lithdr_incidx(grpc_chttp2_hpack_parser* p,
grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, true)),
1);
grpc_error* err = on_hdr<true>(
p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, true)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}
@ -813,10 +815,8 @@ static grpc_error* finish_lithdr_incidx_v(grpc_chttp2_hpack_parser* p,
const uint8_t* end) {
GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX_V();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, true)),
1);
on_hdr<true>(p, grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, true)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}
@ -865,11 +865,9 @@ static grpc_error* finish_lithdr_notidx(grpc_chttp2_hpack_parser* p,
grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, false)),
0);
grpc_error* err = on_hdr<false>(
p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, false)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}
@ -879,11 +877,9 @@ static grpc_error* finish_lithdr_notidx_v(grpc_chttp2_hpack_parser* p,
const uint8_t* cur,
const uint8_t* end) {
GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX_V();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, false)),
0);
grpc_error* err = on_hdr<false>(
p, grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, false)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}
@ -932,11 +928,9 @@ static grpc_error* finish_lithdr_nvridx(grpc_chttp2_hpack_parser* p,
grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */
GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, false)),
0);
grpc_error* err = on_hdr<false>(
p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value, false)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}
@ -946,11 +940,9 @@ static grpc_error* finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser* p,
const uint8_t* cur,
const uint8_t* end) {
GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX_V();
grpc_error* err =
on_hdr(p,
grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, false)),
0);
grpc_error* err = on_hdr<false>(
p, grpc_mdelem_from_slices(take_string(p, &p->key, true),
take_string(p, &p->value, false)));
if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err);
return parse_begin(p, cur, end);
}

@ -30,7 +30,6 @@
#include "src/core/ext/transport/chttp2/transport/incoming_metadata.h"
#include "src/core/ext/transport/cronet/transport/cronet_transport.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/endpoint.h"

@ -30,9 +30,9 @@
#include "src/core/lib/channel/channelz_registry.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/exec_ctx.h"
@ -406,14 +406,15 @@ void PopulateSocketAddressJson(grpc_json* json, const char* name,
(strcmp(uri->scheme, "ipv6") == 0))) {
const char* host_port = uri->path;
if (*host_port == '/') ++host_port;
char* host = nullptr;
char* port = nullptr;
GPR_ASSERT(gpr_split_host_port(host_port, &host, &port));
UniquePtr<char> host;
UniquePtr<char> port;
GPR_ASSERT(SplitHostPort(host_port, &host, &port));
int port_num = -1;
if (port != nullptr) {
port_num = atoi(port);
port_num = atoi(port.get());
}
char* b64_host = grpc_base64_encode(host, strlen(host), false, false);
char* b64_host =
grpc_base64_encode(host.get(), strlen(host.get()), false, false);
json_iterator = grpc_json_create_child(json_iterator, json, "tcpip_address",
nullptr, GRPC_JSON_OBJECT, false);
json = json_iterator;
@ -422,8 +423,6 @@ void PopulateSocketAddressJson(grpc_json* json, const char* name,
"port", port_num);
json_iterator = grpc_json_create_child(json_iterator, json, "ip_address",
b64_host, GRPC_JSON_STRING, true);
gpr_free(host);
gpr_free(port);
} else if (uri != nullptr && strcmp(uri->scheme, "unix") == 0) {
json_iterator = grpc_json_create_child(json_iterator, json, "uds_address",
nullptr, GRPC_JSON_OBJECT, false);

@ -1,98 +0,0 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include "src/core/lib/gpr/host_port.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/string.h"
int gpr_join_host_port(char** out, const char* host, int port) {
if (host[0] != '[' && strchr(host, ':') != nullptr) {
/* IPv6 literals must be enclosed in brackets. */
return gpr_asprintf(out, "[%s]:%d", host, port);
} else {
/* Ordinary non-bracketed host:port. */
return gpr_asprintf(out, "%s:%d", host, port);
}
}
int gpr_split_host_port(const char* name, char** host, char** port) {
const char* host_start;
size_t host_len;
const char* port_start;
*host = nullptr;
*port = nullptr;
if (name[0] == '[') {
/* Parse a bracketed host, typically an IPv6 literal. */
const char* rbracket = strchr(name, ']');
if (rbracket == nullptr) {
/* Unmatched [ */
return 0;
}
if (rbracket[1] == '\0') {
/* ]<end> */
port_start = nullptr;
} else if (rbracket[1] == ':') {
/* ]:<port?> */
port_start = rbracket + 2;
} else {
/* ]<invalid> */
return 0;
}
host_start = name + 1;
host_len = static_cast<size_t>(rbracket - host_start);
if (memchr(host_start, ':', host_len) == nullptr) {
/* Require all bracketed hosts to contain a colon, because a hostname or
IPv4 address should never use brackets. */
return 0;
}
} else {
const char* colon = strchr(name, ':');
if (colon != nullptr && strchr(colon + 1, ':') == nullptr) {
/* Exactly 1 colon. Split into host:port. */
host_start = name;
host_len = static_cast<size_t>(colon - name);
port_start = colon + 1;
} else {
/* 0 or 2+ colons. Bare hostname or IPv6 litearal. */
host_start = name;
host_len = strlen(name);
port_start = nullptr;
}
}
/* Allocate return values. */
*host = static_cast<char*>(gpr_malloc(host_len + 1));
memcpy(*host, host_start, host_len);
(*host)[host_len] = '\0';
if (port_start != nullptr) {
*port = gpr_strdup(port_start);
}
return 1;
}

@ -289,17 +289,22 @@ char* gpr_strvec_flatten(gpr_strvec* sv, size_t* final_length) {
return gpr_strjoin((const char**)sv->strs, sv->count, final_length);
}
int gpr_stricmp(const char* a, const char* b) {
int gpr_strincmp(const char* a, const char* b, size_t n) {
int ca, cb;
do {
ca = tolower(*a);
cb = tolower(*b);
++a;
++b;
} while (ca == cb && ca && cb);
--n;
} while (ca == cb && ca != 0 && cb != 0 && n != 0);
return ca - cb;
}
int gpr_stricmp(const char* a, const char* b) {
return gpr_strincmp(a, b, SIZE_MAX);
}
static void add_string_to_split(const char* beg, const char* end, char*** strs,
size_t* nstrs, size_t* capstrs) {
char* out =

@ -115,6 +115,7 @@ char* gpr_strvec_flatten(gpr_strvec* strs, size_t* total_length);
/** Case insensitive string comparison... return <0 if lower(a)<lower(b), ==0 if
lower(a)==lower(b), >0 if lower(a)>lower(b) */
int gpr_stricmp(const char* a, const char* b);
int gpr_strincmp(const char* a, const char* b, size_t n);
void* gpr_memrchr(const void* s, int c, size_t n);

@ -0,0 +1,105 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include "src/core/lib/gprpp/host_port.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/string_view.h"
namespace grpc_core {
int JoinHostPort(UniquePtr<char>* out, const char* host, int port) {
char* tmp;
int ret;
if (host[0] != '[' && strchr(host, ':') != nullptr) {
/* IPv6 literals must be enclosed in brackets. */
ret = gpr_asprintf(&tmp, "[%s]:%d", host, port);
} else {
/* Ordinary non-bracketed host:port. */
ret = gpr_asprintf(&tmp, "%s:%d", host, port);
}
out->reset(tmp);
return ret;
}
bool SplitHostPort(StringView name, StringView* host, StringView* port) {
if (name[0] == '[') {
/* Parse a bracketed host, typically an IPv6 literal. */
const size_t rbracket = name.find(']', 1);
if (rbracket == grpc_core::StringView::npos) {
/* Unmatched [ */
return false;
}
if (rbracket == name.size() - 1) {
/* ]<end> */
port->clear();
} else if (name[rbracket + 1] == ':') {
/* ]:<port?> */
*port = name.substr(rbracket + 2, name.size() - rbracket - 2);
} else {
/* ]<invalid> */
return false;
}
*host = name.substr(1, rbracket - 1);
if (host->find(':') == grpc_core::StringView::npos) {
/* Require all bracketed hosts to contain a colon, because a hostname or
IPv4 address should never use brackets. */
host->clear();
return false;
}
} else {
size_t colon = name.find(':');
if (colon != grpc_core::StringView::npos &&
name.find(':', colon + 1) == grpc_core::StringView::npos) {
/* Exactly 1 colon. Split into host:port. */
*host = name.substr(0, colon);
*port = name.substr(colon + 1, name.size() - colon - 1);
} else {
/* 0 or 2+ colons. Bare hostname or IPv6 litearal. */
*host = name;
port->clear();
}
}
return true;
}
bool SplitHostPort(StringView name, UniquePtr<char>* host,
UniquePtr<char>* port) {
GPR_DEBUG_ASSERT(host != nullptr && *host == nullptr);
GPR_DEBUG_ASSERT(port != nullptr && *port == nullptr);
StringView host_view;
StringView port_view;
const bool ret = SplitHostPort(name, &host_view, &port_view);
if (ret) {
// We always set the host, but port is set only when it's non-empty,
// to remain backward compatible with the old split_host_port API.
*host = host_view.dup();
if (!port_view.empty()) {
*port = port_view.dup();
}
}
return ret;
}
} // namespace grpc_core

@ -16,28 +16,44 @@
*
*/
#ifndef GRPC_CORE_LIB_GPR_HOST_PORT_H
#define GRPC_CORE_LIB_GPR_HOST_PORT_H
#ifndef GRPC_CORE_LIB_GPRPP_HOST_PORT_H
#define GRPC_CORE_LIB_GPRPP_HOST_PORT_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/string_view.h"
namespace grpc_core {
/** Given a host and port, creates a newly-allocated string of the form
"host:port" or "[ho:st]:port", depending on whether the host contains colons
like an IPv6 literal. If the host is already bracketed, then additional
brackets will not be added.
Usage is similar to gpr_asprintf: returns the number of bytes written
(excluding the final '\0'), and *out points to a string which must later be
destroyed using gpr_free().
(excluding the final '\0'), and *out points to a string.
In the unlikely event of an error, returns -1 and sets *out to NULL. */
int gpr_join_host_port(char** out, const char* host, int port);
int JoinHostPort(UniquePtr<char>* out, const char* host, int port);
/** Given a name in the form "host:port" or "[ho:st]:port", split into hostname
and port number, into newly allocated strings, which must later be
destroyed using gpr_free().
Return 1 on success, 0 on failure. Guarantees *host and *port == NULL on
failure. */
int gpr_split_host_port(const char* name, char** host, char** port);
and port number.
There are two variants of this method:
1) StringView output: port and host are returned as views on name.
2) char* output: port and host are copied into newly allocated strings.
Prefer variant (1) over (2), because no allocation or copy is performed in
variant (1). Use (2) only when interacting with C API that mandate
null-terminated strings.
Return true on success, false on failure. Guarantees *host and *port are
cleared on failure. */
bool SplitHostPort(StringView name, StringView* host, StringView* port);
bool SplitHostPort(StringView name, UniquePtr<char>* host,
UniquePtr<char>* port);
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_GPR_HOST_PORT_H */
#endif /* GRPC_CORE_LIB_GPRPP_HOST_PORT_H */

@ -0,0 +1,143 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_CORE_LIB_GPRPP_STRING_VIEW_H
#define GRPC_CORE_LIB_GPRPP_STRING_VIEW_H
#include <grpc/support/port_platform.h>
#include <grpc/impl/codegen/slice.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <algorithm>
#include <cstdint>
#include <cstring>
#include <limits>
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/memory.h"
namespace grpc_core {
// Provides a light-weight view over a char array or a slice, similar but not
// identical to absl::string_view.
//
// Any method that has the same name as absl::string_view MUST HAVE identical
// semantics to what absl::string_view provides.
//
// Methods that are not part of absl::string_view API, must be clearly
// annotated.
//
// StringView does not own the buffers that back the view. Callers must ensure
// the buffer stays around while the StringView is accessible.
//
// Pass StringView by value in functions, since it is exactly two pointers in
// size.
//
// The interface used here is not identical to absl::string_view. Notably, we
// need to support slices while we cannot support std::string, and gpr string
// style functions such as strdup() and cmp(). Once we switch to
// absl::string_view this class will inherit from absl::string_view and add the
// gRPC-specific APIs.
class StringView final {
public:
static constexpr size_t npos = std::numeric_limits<size_t>::max();
constexpr StringView(const char* ptr, size_t size) : ptr_(ptr), size_(size) {}
constexpr StringView(const char* ptr)
: StringView(ptr, ptr == nullptr ? 0 : strlen(ptr)) {}
// Not part of absl::string_view API.
StringView(const grpc_slice& slice)
: StringView(reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(slice)),
GRPC_SLICE_LENGTH(slice)) {}
constexpr StringView() : StringView(nullptr, 0) {}
constexpr const char* data() const { return ptr_; }
constexpr size_t size() const { return size_; }
constexpr bool empty() const { return size_ == 0; }
StringView substr(size_t start, size_t size = npos) {
GPR_DEBUG_ASSERT(start + size <= size_);
return StringView(ptr_ + start, std::min(size, size_ - start));
}
constexpr const char& operator[](size_t i) const { return ptr_[i]; }
const char& front() const { return ptr_[0]; }
const char& back() const { return ptr_[size_ - 1]; }
void remove_prefix(size_t n) {
GPR_DEBUG_ASSERT(n <= size_);
ptr_ += n;
size_ -= n;
}
void remove_suffix(size_t n) {
GPR_DEBUG_ASSERT(n <= size_);
size_ -= n;
}
size_t find(char c, size_t pos = 0) const {
if (empty() || pos >= size_) return npos;
const char* result =
static_cast<const char*>(memchr(ptr_ + pos, c, size_ - pos));
return result != nullptr ? result - ptr_ : npos;
}
void clear() {
ptr_ = nullptr;
size_ = 0;
}
// Creates a dup of the string viewed by this class.
// Return value is null-terminated and never nullptr.
//
// Not part of absl::string_view API.
grpc_core::UniquePtr<char> dup() const {
char* str = static_cast<char*>(gpr_malloc(size_ + 1));
if (size_ > 0) memcpy(str, ptr_, size_);
str[size_] = '\0';
return grpc_core::UniquePtr<char>(str);
}
// Not part of absl::string_view API.
int cmp(StringView other) const {
const size_t len = GPR_MIN(size(), other.size());
const int ret = strncmp(data(), other.data(), len);
if (ret != 0) return ret;
if (size() == other.size()) return 0;
if (size() < other.size()) return -1;
return 1;
}
private:
const char* ptr_;
size_t size_;
};
inline bool operator==(StringView lhs, StringView rhs) {
return lhs.size() == rhs.size() &&
strncmp(lhs.data(), rhs.data(), lhs.size()) == 0;
}
inline bool operator!=(StringView lhs, StringView rhs) { return !(lhs == rhs); }
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_GPRPP_STRING_VIEW_H */

@ -49,7 +49,7 @@ class Thread {
public:
class Options {
public:
Options() : joinable_(true), tracked_(true) {}
Options() : joinable_(true), tracked_(true), stack_size_(0) {}
/// Set whether the thread is joinable or detached.
Options& set_joinable(bool joinable) {
joinable_ = joinable;
@ -64,9 +64,18 @@ class Thread {
}
bool tracked() const { return tracked_; }
/// Sets thread stack size (in bytes). Sets to 0 will use the default stack
/// size which is 64KB for Windows threads and 2MB for Posix(x86) threads.
Options& set_stack_size(size_t bytes) {
stack_size_ = bytes;
return *this;
}
size_t stack_size() const { return stack_size_; }
private:
bool joinable_;
bool tracked_;
size_t stack_size_;
};
/// Default constructor only to allow use in structs that lack constructors
/// Does not produce a validly-constructed thread; must later

@ -31,6 +31,7 @@
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/fork.h"
@ -48,6 +49,26 @@ struct thd_arg {
bool tracked;
};
// TODO(yunjiaw): move this to a function-level static, or remove the use of a
// non-constexpr initializer when possible
const size_t page_size = static_cast<size_t>(sysconf(_SC_PAGESIZE));
size_t RoundUpToPageSize(size_t size) {
return (size + page_size - 1) & ~(page_size - 1);
}
// Returns the minimum valid stack size that can be passed to
// pthread_attr_setstacksize.
size_t MinValidStackSize(size_t request_size) {
if (request_size < _SC_THREAD_STACK_MIN) {
request_size = _SC_THREAD_STACK_MIN;
}
// On some systems, pthread_attr_setstacksize() can fail if stacksize is
// not a multiple of the system page size.
return RoundUpToPageSize(request_size);
}
class ThreadInternalsPosix : public internal::ThreadInternalsInterface {
public:
ThreadInternalsPosix(const char* thd_name, void (*thd_body)(void* arg),
@ -79,6 +100,11 @@ class ThreadInternalsPosix : public internal::ThreadInternalsInterface {
0);
}
if (options.stack_size() != 0) {
size_t stack_size = MinValidStackSize(options.stack_size());
GPR_ASSERT(pthread_attr_setstacksize(&attr, stack_size) == 0);
}
*success =
(pthread_create(&pthread_id_, &attr,
[](void* v) -> void* {

@ -75,7 +75,15 @@ class ThreadInternalsWindows
return;
}
}
handle = CreateThread(nullptr, 64 * 1024, thread_body, info_, 0, nullptr);
if (options.stack_size() != 0) {
// Windows will round up the given stack_size value to nearest page.
handle = CreateThread(nullptr, options.stack_size(), thread_body, info_,
0, nullptr);
} else {
handle = CreateThread(nullptr, 64 * 1024, thread_body, info_, 0, nullptr);
}
if (handle == nullptr) {
destroy_thread();
*success = false;

@ -30,6 +30,7 @@
#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/string_view.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
@ -108,7 +109,8 @@ class grpc_httpcli_ssl_channel_security_connector final
return strcmp(secure_peer_name_, other->secure_peer_name_);
}
bool check_call_host(const char* host, grpc_auth_context* auth_context,
bool check_call_host(grpc_core::StringView host,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error) override {
*error = GRPC_ERROR_NONE;

@ -246,7 +246,8 @@ bool grpc_event_engine_can_track_errors(void) {
}
bool grpc_event_engine_run_in_background(void) {
return g_event_engine->run_in_background;
// g_event_engine is nullptr when using a custom iomgr.
return g_event_engine != nullptr && g_event_engine->run_in_background;
}
grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) {

@ -120,7 +120,10 @@ size_t Executor::RunClosures(const char* executor_name,
// thread itself, but this is the point where we could start seeing
// application-level callbacks. No need to create a new ExecCtx, though,
// since there already is one and it is flushed (but not destructed) in this
// function itself.
// function itself. The ApplicationCallbackExecCtx will have its callbacks
// invoked on its destruction, which will be after completing any closures in
// the executor's closure list (which were explicitly scheduled onto the
// executor).
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx(
GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD);

@ -78,9 +78,19 @@ static grpc_iomgr_platform_vtable vtable = {
void grpc_set_default_iomgr_platform() {
char* enable_cfstream = getenv(grpc_cfstream_env_var);
grpc_tcp_client_vtable* client_vtable = &grpc_posix_tcp_client_vtable;
// CFStream is enabled by default on iOS, and disabled by default on other
// platforms. Defaults can be overriden by setting the grpc_cfstream
// environment variable.
#if TARGET_OS_IPHONE
if (enable_cfstream == nullptr || enable_cfstream[0] == '1') {
client_vtable = &grpc_cfstream_client_vtable;
}
#else
if (enable_cfstream != nullptr && enable_cfstream[0] == '1') {
client_vtable = &grpc_cfstream_client_vtable;
}
#endif
grpc_set_tcp_client_impl(client_vtable);
grpc_set_tcp_server_impl(&grpc_posix_tcp_server_vtable);
grpc_set_timer_impl(&grpc_generic_timer_vtable);

@ -39,4 +39,5 @@ void grpc_set_default_iomgr_platform() {
}
bool grpc_iomgr_run_in_background() { return false; }
#endif

@ -24,9 +24,9 @@
#include <grpc/support/string_util.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/iomgr/iomgr_custom.h"
#include "src/core/lib/iomgr/resolve_address_custom.h"
@ -86,11 +86,12 @@ void grpc_custom_resolve_callback(grpc_custom_resolver* r,
}
static grpc_error* try_split_host_port(const char* name,
const char* default_port, char** host,
char** port) {
const char* default_port,
grpc_core::UniquePtr<char>* host,
grpc_core::UniquePtr<char>* port) {
/* parse name, splitting it into host and port parts */
grpc_error* error;
gpr_split_host_port(name, host, port);
SplitHostPort(name, host, port);
if (*host == nullptr) {
char* msg;
gpr_asprintf(&msg, "unparseable host:port: '%s'", name);
@ -107,7 +108,7 @@ static grpc_error* try_split_host_port(const char* name,
gpr_free(msg);
return error;
}
*port = gpr_strdup(default_port);
port->reset(gpr_strdup(default_port));
}
return GRPC_ERROR_NONE;
}
@ -115,28 +116,26 @@ static grpc_error* try_split_host_port(const char* name,
static grpc_error* blocking_resolve_address_impl(
const char* name, const char* default_port,
grpc_resolved_addresses** addresses) {
char* host;
char* port;
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
grpc_error* err;
GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD();
err = try_split_host_port(name, default_port, &host, &port);
if (err != GRPC_ERROR_NONE) {
gpr_free(host);
gpr_free(port);
return err;
}
/* Call getaddrinfo */
grpc_custom_resolver resolver;
resolver.host = host;
resolver.port = port;
resolver.host = host.get();
resolver.port = port.get();
grpc_resolved_addresses* addrs;
grpc_core::ExecCtx* curr = grpc_core::ExecCtx::Get();
grpc_core::ExecCtx::Set(nullptr);
err = resolve_address_vtable->resolve(host, port, &addrs);
err = resolve_address_vtable->resolve(host.get(), port.get(), &addrs);
if (err != GRPC_ERROR_NONE) {
if (retry_named_port_failure(&resolver, &addrs)) {
GRPC_ERROR_UNREF(err);
@ -147,8 +146,6 @@ static grpc_error* blocking_resolve_address_impl(
if (err == GRPC_ERROR_NONE) {
*addresses = addrs;
}
gpr_free(resolver.host);
gpr_free(resolver.port);
return err;
}
@ -157,22 +154,20 @@ static void resolve_address_impl(const char* name, const char* default_port,
grpc_closure* on_done,
grpc_resolved_addresses** addrs) {
grpc_custom_resolver* r = nullptr;
char* host = nullptr;
char* port = nullptr;
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
grpc_error* err;
GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD();
err = try_split_host_port(name, default_port, &host, &port);
if (err != GRPC_ERROR_NONE) {
GRPC_CLOSURE_SCHED(on_done, err);
gpr_free(host);
gpr_free(port);
return;
}
r = (grpc_custom_resolver*)gpr_malloc(sizeof(grpc_custom_resolver));
r->on_done = on_done;
r->addresses = addrs;
r->host = host;
r->port = port;
r->host = host.release();
r->port = port.release();
/* Call getaddrinfo */
resolve_address_vtable->resolve_async(r, r->host, r->port);

@ -33,9 +33,9 @@
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/block_annotate.h"
#include "src/core/lib/iomgr/executor.h"
@ -48,8 +48,6 @@ static grpc_error* posix_blocking_resolve_address(
grpc_core::ExecCtx exec_ctx;
struct addrinfo hints;
struct addrinfo *result = nullptr, *resp;
char* host;
char* port;
int s;
size_t i;
grpc_error* err;
@ -59,8 +57,10 @@ static grpc_error* posix_blocking_resolve_address(
return grpc_resolve_unix_domain_address(name + 5, addresses);
}
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
/* parse name, splitting it into host and port parts */
gpr_split_host_port(name, &host, &port);
grpc_core::SplitHostPort(name, &host, &port);
if (host == nullptr) {
err = grpc_error_set_str(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"),
@ -74,7 +74,7 @@ static grpc_error* posix_blocking_resolve_address(
GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
goto done;
}
port = gpr_strdup(default_port);
port.reset(gpr_strdup(default_port));
}
/* Call getaddrinfo */
@ -84,16 +84,16 @@ static grpc_error* posix_blocking_resolve_address(
hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */
GRPC_SCHEDULING_START_BLOCKING_REGION;
s = getaddrinfo(host, port, &hints, &result);
s = getaddrinfo(host.get(), port.get(), &hints, &result);
GRPC_SCHEDULING_END_BLOCKING_REGION;
if (s != 0) {
/* Retry if well-known service name is recognized */
const char* svc[][2] = {{"http", "80"}, {"https", "443"}};
for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) {
if (strcmp(port, svc[i][0]) == 0) {
if (strcmp(port.get(), svc[i][0]) == 0) {
GRPC_SCHEDULING_START_BLOCKING_REGION;
s = getaddrinfo(host, svc[i][1], &hints, &result);
s = getaddrinfo(host.get(), svc[i][1], &hints, &result);
GRPC_SCHEDULING_END_BLOCKING_REGION;
break;
}
@ -133,8 +133,6 @@ static grpc_error* posix_blocking_resolve_address(
err = GRPC_ERROR_NONE;
done:
gpr_free(host);
gpr_free(port);
if (result) {
freeaddrinfo(result);
}

@ -35,8 +35,8 @@
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/block_annotate.h"
#include "src/core/lib/iomgr/executor.h"
@ -57,14 +57,14 @@ static grpc_error* windows_blocking_resolve_address(
grpc_core::ExecCtx exec_ctx;
struct addrinfo hints;
struct addrinfo *result = NULL, *resp;
char* host;
char* port;
int s;
size_t i;
grpc_error* error = GRPC_ERROR_NONE;
/* parse name, splitting it into host and port parts */
gpr_split_host_port(name, &host, &port);
grpc_core::UniquePtr<char> host;
grpc_core::UniquePtr<char> port;
grpc_core::SplitHostPort(name, &host, &port);
if (host == NULL) {
char* msg;
gpr_asprintf(&msg, "unparseable host:port: '%s'", name);
@ -80,7 +80,7 @@ static grpc_error* windows_blocking_resolve_address(
gpr_free(msg);
goto done;
}
port = gpr_strdup(default_port);
port.reset(gpr_strdup(default_port));
}
/* Call getaddrinfo */
@ -90,7 +90,7 @@ static grpc_error* windows_blocking_resolve_address(
hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */
GRPC_SCHEDULING_START_BLOCKING_REGION;
s = getaddrinfo(host, port, &hints, &result);
s = getaddrinfo(host.get(), port.get(), &hints, &result);
GRPC_SCHEDULING_END_BLOCKING_REGION;
if (s != 0) {
error = GRPC_WSA_ERROR(WSAGetLastError(), "getaddrinfo");
@ -122,8 +122,6 @@ static grpc_error* windows_blocking_resolve_address(
}
done:
gpr_free(host);
gpr_free(port);
if (result) {
freeaddrinfo(result);
}

@ -28,8 +28,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/socket_utils.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
@ -181,15 +181,17 @@ int grpc_sockaddr_to_string(char** out,
}
if (ip != nullptr && grpc_inet_ntop(addr->sa_family, ip, ntop_buf,
sizeof(ntop_buf)) != nullptr) {
grpc_core::UniquePtr<char> tmp_out;
if (sin6_scope_id != 0) {
char* host_with_scope;
/* Enclose sin6_scope_id with the format defined in RFC 6784 section 2. */
gpr_asprintf(&host_with_scope, "%s%%25%" PRIu32, ntop_buf, sin6_scope_id);
ret = gpr_join_host_port(out, host_with_scope, port);
ret = grpc_core::JoinHostPort(&tmp_out, host_with_scope, port);
gpr_free(host_with_scope);
} else {
ret = gpr_join_host_port(out, ntop_buf, port);
ret = grpc_core::JoinHostPort(&tmp_out, ntop_buf, port);
}
*out = tmp_out.release();
} else {
ret = gpr_asprintf(out, "(sockaddr family=%d)", addr->sa_family);
}

@ -46,7 +46,6 @@
#include <grpc/support/sync.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"

@ -34,7 +34,7 @@
#include <netinet/in.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/iomgr/cfstream_handle.h"
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/endpoint_cfstream.h"
@ -143,12 +143,13 @@ static void OnOpen(void* arg, grpc_error* error) {
static void ParseResolvedAddress(const grpc_resolved_address* addr,
CFStringRef* host, int* port) {
char *host_port, *host_string, *port_string;
char* host_port;
grpc_sockaddr_to_string(&host_port, addr, 1);
gpr_split_host_port(host_port, &host_string, &port_string);
*host = CFStringCreateWithCString(NULL, host_string, kCFStringEncodingUTF8);
gpr_free(host_string);
gpr_free(port_string);
grpc_core::UniquePtr<char> host_string;
grpc_core::UniquePtr<char> port_string;
grpc_core::SplitHostPort(host_port, &host_string, &port_string);
*host =
CFStringCreateWithCString(NULL, host_string.get(), kCFStringEncodingUTF8);
gpr_free(host_port);
*port = grpc_sockaddr_get_port(addr);
}

@ -64,8 +64,8 @@ typedef enum {
#define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \
"/computeMetadata/v1/instance/service-accounts/default/token"
#define GRPC_GOOGLE_OAUTH2_SERVICE_HOST "www.googleapis.com"
#define GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH "/oauth2/v3/token"
#define GRPC_GOOGLE_OAUTH2_SERVICE_HOST "oauth2.googleapis.com"
#define GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH "/token"
#define GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX \
"grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" \

@ -18,6 +18,7 @@
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/security/credentials/jwt/json_token.h"
#include <string.h>
@ -69,6 +70,7 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json* json) {
BIO* bio = nullptr;
const char* prop_value;
int success = 0;
grpc_error* error = GRPC_ERROR_NONE;
memset(&result, 0, sizeof(grpc_auth_json_key));
result.type = GRPC_AUTH_JSON_TYPE_INVALID;
@ -77,7 +79,8 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json* json) {
goto end;
}
prop_value = grpc_json_get_string_property(json, "type");
prop_value = grpc_json_get_string_property(json, "type", &error);
GRPC_LOG_IF_ERROR("JSON key parsing", error);
if (prop_value == nullptr ||
strcmp(prop_value, GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT)) {
goto end;
@ -92,7 +95,8 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json* json) {
goto end;
}
prop_value = grpc_json_get_string_property(json, "private_key");
prop_value = grpc_json_get_string_property(json, "private_key", &error);
GRPC_LOG_IF_ERROR("JSON key parsing", error);
if (prop_value == nullptr) {
goto end;
}

@ -30,7 +30,7 @@
/* --- Constants. --- */
#define GRPC_JWT_OAUTH2_AUDIENCE "https://www.googleapis.com/oauth2/v3/token"
#define GRPC_JWT_OAUTH2_AUDIENCE "https://oauth2.googleapis.com/token"
/* --- auth_json_key parsing. --- */

@ -22,14 +22,23 @@
#include <string.h>
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/security/util/json_util.h"
#include "src/core/lib/surface/api_trace.h"
#include <grpc/grpc_security.h>
#include <grpc/impl/codegen/slice.h>
#include <grpc/slice.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/inlined_vector.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/security/util/json_util.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/uri/uri_parser.h"
//
// Auth Refresh Token.
//
@ -45,6 +54,7 @@ grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json(
grpc_auth_refresh_token result;
const char* prop_value;
int success = 0;
grpc_error* error = GRPC_ERROR_NONE;
memset(&result, 0, sizeof(grpc_auth_refresh_token));
result.type = GRPC_AUTH_JSON_TYPE_INVALID;
@ -53,7 +63,8 @@ grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json(
goto end;
}
prop_value = grpc_json_get_string_property(json, "type");
prop_value = grpc_json_get_string_property(json, "type", &error);
GRPC_LOG_IF_ERROR("Parsing refresh token", error);
if (prop_value == nullptr ||
strcmp(prop_value, GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER)) {
goto end;
@ -216,10 +227,12 @@ static void on_oauth2_token_fetcher_http_response(void* user_data,
void grpc_oauth2_token_fetcher_credentials::on_http_response(
grpc_credentials_metadata_request* r, grpc_error* error) {
grpc_mdelem access_token_md = GRPC_MDNULL;
grpc_millis token_lifetime;
grpc_millis token_lifetime = 0;
grpc_credentials_status status =
grpc_oauth2_token_fetcher_credentials_parse_server_response(
&r->response, &access_token_md, &token_lifetime);
error == GRPC_ERROR_NONE
? grpc_oauth2_token_fetcher_credentials_parse_server_response(
&r->response, &access_token_md, &token_lifetime)
: GRPC_CREDENTIALS_ERROR;
// Update cache and grab list of pending requests.
gpr_mu_lock(&mu_);
token_fetch_pending_ = false;
@ -234,14 +247,15 @@ void grpc_oauth2_token_fetcher_credentials::on_http_response(
gpr_mu_unlock(&mu_);
// Invoke callbacks for all pending requests.
while (pending_request != nullptr) {
grpc_error* new_error = GRPC_ERROR_NONE;
if (status == GRPC_CREDENTIALS_OK) {
grpc_credentials_mdelem_array_add(pending_request->md_array,
access_token_md);
} else {
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Error occurred when fetching oauth2 token.", &error, 1);
}
GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, error);
GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, new_error);
grpc_polling_entity_del_from_pollset_set(
pending_request->pollent, grpc_polling_entity_pollset_set(&pollent_));
grpc_oauth2_pending_get_request_metadata* prev = pending_request;
@ -356,7 +370,8 @@ class grpc_compute_engine_token_fetcher_credentials
grpc_polling_entity* pollent,
grpc_iomgr_cb_func response_cb,
grpc_millis deadline) override {
grpc_http_header header = {(char*)"Metadata-Flavor", (char*)"Google"};
grpc_http_header header = {const_cast<char*>("Metadata-Flavor"),
const_cast<char*>("Google")};
grpc_httpcli_request request;
memset(&request, 0, sizeof(grpc_httpcli_request));
request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST;
@ -369,11 +384,14 @@ class grpc_compute_engine_token_fetcher_credentials
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("oauth2_credentials");
grpc_httpcli_get(http_context, pollent, resource_quota, &request, deadline,
GRPC_CLOSURE_CREATE(response_cb, metadata_req,
grpc_schedule_on_exec_ctx),
GRPC_CLOSURE_INIT(&http_get_cb_closure_, response_cb,
metadata_req, grpc_schedule_on_exec_ctx),
&metadata_req->response);
grpc_resource_quota_unref_internal(resource_quota);
}
private:
grpc_closure http_get_cb_closure_;
};
} // namespace
@ -401,8 +419,9 @@ void grpc_google_refresh_token_credentials::fetch_oauth2(
grpc_credentials_metadata_request* metadata_req,
grpc_httpcli_context* httpcli_context, grpc_polling_entity* pollent,
grpc_iomgr_cb_func response_cb, grpc_millis deadline) {
grpc_http_header header = {(char*)"Content-Type",
(char*)"application/x-www-form-urlencoded"};
grpc_http_header header = {
const_cast<char*>("Content-Type"),
const_cast<char*>("application/x-www-form-urlencoded")};
grpc_httpcli_request request;
char* body = nullptr;
gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
@ -419,11 +438,11 @@ void grpc_google_refresh_token_credentials::fetch_oauth2(
extreme memory pressure. */
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("oauth2_credentials_refresh");
grpc_httpcli_post(
httpcli_context, pollent, resource_quota, &request, body, strlen(body),
deadline,
GRPC_CLOSURE_CREATE(response_cb, metadata_req, grpc_schedule_on_exec_ctx),
&metadata_req->response);
grpc_httpcli_post(httpcli_context, pollent, resource_quota, &request, body,
strlen(body), deadline,
GRPC_CLOSURE_INIT(&http_post_cb_closure_, response_cb,
metadata_req, grpc_schedule_on_exec_ctx),
&metadata_req->response);
grpc_resource_quota_unref_internal(resource_quota);
gpr_free(body);
}
@ -472,6 +491,207 @@ grpc_call_credentials* grpc_google_refresh_token_credentials_create(
.release();
}
//
// STS credentials.
//
namespace grpc_core {
namespace {
void MaybeAddToBody(gpr_strvec* body_strvec, const char* field_name,
const char* field) {
if (field == nullptr || strlen(field) == 0) return;
char* new_query;
gpr_asprintf(&new_query, "&%s=%s", field_name, field);
gpr_strvec_add(body_strvec, new_query);
}
grpc_error* LoadTokenFile(const char* path, gpr_slice* token) {
grpc_error* err = grpc_load_file(path, 1, token);
if (err != GRPC_ERROR_NONE) return err;
if (GRPC_SLICE_LENGTH(*token) == 0) {
gpr_log(GPR_ERROR, "Token file %s is empty", path);
err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Token file is empty.");
}
return err;
}
class StsTokenFetcherCredentials
: public grpc_oauth2_token_fetcher_credentials {
public:
StsTokenFetcherCredentials(grpc_uri* sts_url, // Ownership transferred.
const grpc_sts_credentials_options* options)
: sts_url_(sts_url),
resource_(gpr_strdup(options->resource)),
audience_(gpr_strdup(options->audience)),
scope_(gpr_strdup(options->scope)),
requested_token_type_(gpr_strdup(options->requested_token_type)),
subject_token_path_(gpr_strdup(options->subject_token_path)),
subject_token_type_(gpr_strdup(options->subject_token_type)),
actor_token_path_(gpr_strdup(options->actor_token_path)),
actor_token_type_(gpr_strdup(options->actor_token_type)) {}
~StsTokenFetcherCredentials() override { grpc_uri_destroy(sts_url_); }
private:
void fetch_oauth2(grpc_credentials_metadata_request* metadata_req,
grpc_httpcli_context* http_context,
grpc_polling_entity* pollent,
grpc_iomgr_cb_func response_cb,
grpc_millis deadline) override {
char* body = nullptr;
size_t body_length = 0;
grpc_error* err = FillBody(&body, &body_length);
if (err != GRPC_ERROR_NONE) {
response_cb(metadata_req, err);
GRPC_ERROR_UNREF(err);
return;
}
grpc_http_header header = {
const_cast<char*>("Content-Type"),
const_cast<char*>("application/x-www-form-urlencoded")};
grpc_httpcli_request request;
memset(&request, 0, sizeof(grpc_httpcli_request));
request.host = (char*)sts_url_->authority;
request.http.path = (char*)sts_url_->path;
request.http.hdr_count = 1;
request.http.hdrs = &header;
request.handshaker = (strcmp(sts_url_->scheme, "https") == 0)
? &grpc_httpcli_ssl
: &grpc_httpcli_plaintext;
/* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
channel. This would allow us to cancel an authentication query when under
extreme memory pressure. */
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("oauth2_credentials_refresh");
grpc_httpcli_post(
http_context, pollent, resource_quota, &request, body, body_length,
deadline,
GRPC_CLOSURE_INIT(&http_post_cb_closure_, response_cb, metadata_req,
grpc_schedule_on_exec_ctx),
&metadata_req->response);
grpc_resource_quota_unref_internal(resource_quota);
gpr_free(body);
}
grpc_error* FillBody(char** body, size_t* body_length) {
*body = nullptr;
gpr_strvec body_strvec;
gpr_strvec_init(&body_strvec);
grpc_slice subject_token = grpc_empty_slice();
grpc_slice actor_token = grpc_empty_slice();
grpc_error* err = GRPC_ERROR_NONE;
auto cleanup = [&body, &body_length, &body_strvec, &subject_token,
&actor_token, &err]() {
if (err == GRPC_ERROR_NONE) {
*body = gpr_strvec_flatten(&body_strvec, body_length);
} else {
gpr_free(*body);
}
gpr_strvec_destroy(&body_strvec);
grpc_slice_unref_internal(subject_token);
grpc_slice_unref_internal(actor_token);
return err;
};
err = LoadTokenFile(subject_token_path_.get(), &subject_token);
if (err != GRPC_ERROR_NONE) return cleanup();
gpr_asprintf(
body, GRPC_STS_POST_MINIMAL_BODY_FORMAT_STRING,
reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(subject_token)),
subject_token_type_.get());
gpr_strvec_add(&body_strvec, *body);
MaybeAddToBody(&body_strvec, "resource", resource_.get());
MaybeAddToBody(&body_strvec, "audience", audience_.get());
MaybeAddToBody(&body_strvec, "scope", scope_.get());
MaybeAddToBody(&body_strvec, "requested_token_type",
requested_token_type_.get());
if (actor_token_path_ != nullptr) {
err = LoadTokenFile(actor_token_path_.get(), &actor_token);
if (err != GRPC_ERROR_NONE) return cleanup();
MaybeAddToBody(
&body_strvec, "actor_token",
reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(subject_token)));
MaybeAddToBody(&body_strvec, "actor_token_type", actor_token_type_.get());
}
return cleanup();
}
grpc_uri* sts_url_;
grpc_closure http_post_cb_closure_;
grpc_core::UniquePtr<char> resource_;
grpc_core::UniquePtr<char> audience_;
grpc_core::UniquePtr<char> scope_;
grpc_core::UniquePtr<char> requested_token_type_;
grpc_core::UniquePtr<char> subject_token_path_;
grpc_core::UniquePtr<char> subject_token_type_;
grpc_core::UniquePtr<char> actor_token_path_;
grpc_core::UniquePtr<char> actor_token_type_;
};
} // namespace
grpc_error* ValidateStsCredentialsOptions(
const grpc_sts_credentials_options* options, grpc_uri** sts_url_out) {
struct GrpcUriDeleter {
void operator()(grpc_uri* uri) { grpc_uri_destroy(uri); }
};
*sts_url_out = nullptr;
InlinedVector<grpc_error*, 3> error_list;
UniquePtr<grpc_uri, GrpcUriDeleter> sts_url(
options->sts_endpoint_url != nullptr
? grpc_uri_parse(options->sts_endpoint_url, false)
: nullptr);
if (sts_url == nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid or missing STS endpoint URL"));
} else {
if (strcmp(sts_url->scheme, "https") != 0 &&
strcmp(sts_url->scheme, "http") != 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid URI scheme, must be https to http."));
}
}
if (options->subject_token_path == nullptr ||
strlen(options->subject_token_path) == 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"subject_token needs to be specified"));
}
if (options->subject_token_type == nullptr ||
strlen(options->subject_token_type) == 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"subject_token_type needs to be specified"));
}
if (error_list.empty()) {
*sts_url_out = sts_url.release();
return GRPC_ERROR_NONE;
} else {
return GRPC_ERROR_CREATE_FROM_VECTOR("Invalid STS Credentials Options",
&error_list);
}
}
} // namespace grpc_core
grpc_call_credentials* grpc_sts_credentials_create(
const grpc_sts_credentials_options* options, void* reserved) {
GPR_ASSERT(reserved == nullptr);
grpc_uri* sts_url;
grpc_error* error =
grpc_core::ValidateStsCredentialsOptions(options, &sts_url);
if (error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR, "STS Credentials creation failed. Error: %s.",
grpc_error_string(error));
GRPC_ERROR_UNREF(error);
return nullptr;
}
return grpc_core::MakeRefCounted<grpc_core::StsTokenFetcherCredentials>(
sts_url, options)
.release();
}
//
// Oauth2 Access Token credentials.
//

@ -21,8 +21,15 @@
#include <grpc/support/port_platform.h>
#include <grpc/grpc_security.h>
#include "src/core/lib/json/json.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/uri/uri_parser.h"
// Constants.
#define GRPC_STS_POST_MINIMAL_BODY_FORMAT_STRING \
"grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token=%" \
"s&subject_token_type=%s"
// auth_refresh_token parsing.
typedef struct {
@ -115,6 +122,7 @@ class grpc_google_refresh_token_credentials final
private:
grpc_auth_refresh_token refresh_token_;
grpc_closure http_post_cb_closure_;
};
// Access token credentials.
@ -148,4 +156,12 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
const struct grpc_http_response* response, grpc_mdelem* token_md,
grpc_millis* token_lifetime);
namespace grpc_core {
// Exposed for testing only. This function validates the options, ensuring that
// the required fields are set, and outputs the parsed URL of the STS token
// exchanged service.
grpc_error* ValidateStsCredentialsOptions(
const grpc_sts_credentials_options* options, grpc_uri** sts_url);
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H */

@ -108,10 +108,11 @@ class grpc_alts_channel_security_connector final
return strcmp(target_name_, other->target_name_);
}
bool check_call_host(const char* host, grpc_auth_context* auth_context,
bool check_call_host(grpc_core::StringView host,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error) override {
if (host == nullptr || strcmp(host, target_name_) != 0) {
if (host.empty() || host != target_name_) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"ALTS call host does not match target name");
}

@ -31,8 +31,8 @@
#include "src/core/ext/transport/chttp2/alpn/alpn.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
@ -102,39 +102,35 @@ class grpc_fake_channel_security_connector final
tsi_create_fake_handshaker(/*is_client=*/true), this));
}
bool check_call_host(const char* host, grpc_auth_context* auth_context,
bool check_call_host(grpc_core::StringView host,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error) override {
char* authority_hostname = nullptr;
char* authority_ignored_port = nullptr;
char* target_hostname = nullptr;
char* target_ignored_port = nullptr;
gpr_split_host_port(host, &authority_hostname, &authority_ignored_port);
gpr_split_host_port(target_, &target_hostname, &target_ignored_port);
grpc_core::StringView authority_hostname;
grpc_core::StringView authority_ignored_port;
grpc_core::StringView target_hostname;
grpc_core::StringView target_ignored_port;
grpc_core::SplitHostPort(host, &authority_hostname,
&authority_ignored_port);
grpc_core::SplitHostPort(target_, &target_hostname, &target_ignored_port);
if (target_name_override_ != nullptr) {
char* fake_security_target_name_override_hostname = nullptr;
char* fake_security_target_name_override_ignored_port = nullptr;
gpr_split_host_port(target_name_override_,
&fake_security_target_name_override_hostname,
&fake_security_target_name_override_ignored_port);
if (strcmp(authority_hostname,
fake_security_target_name_override_hostname) != 0) {
grpc_core::StringView fake_security_target_name_override_hostname;
grpc_core::StringView fake_security_target_name_override_ignored_port;
grpc_core::SplitHostPort(
target_name_override_, &fake_security_target_name_override_hostname,
&fake_security_target_name_override_ignored_port);
if (authority_hostname != fake_security_target_name_override_hostname) {
gpr_log(GPR_ERROR,
"Authority (host) '%s' != Fake Security Target override '%s'",
host, fake_security_target_name_override_hostname);
host.data(),
fake_security_target_name_override_hostname.data());
abort();
}
gpr_free(fake_security_target_name_override_hostname);
gpr_free(fake_security_target_name_override_ignored_port);
} else if (strcmp(authority_hostname, target_hostname) != 0) {
gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'",
authority_hostname, target_hostname);
} else if (authority_hostname != target_hostname) {
gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", host.data(),
target_);
abort();
}
gpr_free(authority_hostname);
gpr_free(authority_ignored_port);
gpr_free(target_hostname);
gpr_free(target_ignored_port);
return true;
}

@ -156,10 +156,11 @@ class grpc_local_channel_security_connector final
creds->connect_type());
}
bool check_call_host(const char* host, grpc_auth_context* auth_context,
bool check_call_host(grpc_core::StringView host,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error) override {
if (host == nullptr || strcmp(host, target_name_) != 0) {
if (host.empty() || host != target_name_) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"local call host does not match target name");
}

@ -28,8 +28,8 @@
#include "src/core/ext/transport/chttp2/alpn/alpn.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"

@ -98,7 +98,7 @@ class grpc_channel_security_connector : public grpc_security_connector {
/// Returns true if completed synchronously, in which case \a error will
/// be set to indicate the result. Otherwise, \a on_call_host_checked
/// will be invoked when complete.
virtual bool check_call_host(const char* host,
virtual bool check_call_host(grpc_core::StringView host,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error) GRPC_ABSTRACT;

@ -28,8 +28,8 @@
#include "src/core/ext/transport/chttp2/alpn/alpn.h"
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
@ -75,15 +75,14 @@ class grpc_ssl_channel_security_connector final
? nullptr
: gpr_strdup(overridden_target_name)),
verify_options_(&config->verify_options) {
char* port;
gpr_split_host_port(target_name, &target_name_, &port);
gpr_free(port);
grpc_core::StringView host;
grpc_core::StringView port;
grpc_core::SplitHostPort(target_name, &host, &port);
target_name_ = host.dup();
}
~grpc_ssl_channel_security_connector() override {
tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
if (target_name_ != nullptr) gpr_free(target_name_);
if (overridden_target_name_ != nullptr) gpr_free(overridden_target_name_);
}
grpc_security_status InitializeHandshakerFactory(
@ -123,8 +122,8 @@ class grpc_ssl_channel_security_connector final
tsi_handshaker* tsi_hs = nullptr;
tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
client_handshaker_factory_,
overridden_target_name_ != nullptr ? overridden_target_name_
: target_name_,
overridden_target_name_ != nullptr ? overridden_target_name_.get()
: target_name_.get(),
&tsi_hs);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
@ -139,8 +138,8 @@ class grpc_ssl_channel_security_connector final
grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
grpc_closure* on_peer_checked) override {
const char* target_name = overridden_target_name_ != nullptr
? overridden_target_name_
: target_name_;
? overridden_target_name_.get()
: target_name_.get();
grpc_error* error = ssl_check_peer(target_name, &peer, auth_context);
if (error == GRPC_ERROR_NONE &&
verify_options_->verify_peer_callback != nullptr) {
@ -175,17 +174,18 @@ class grpc_ssl_channel_security_connector final
reinterpret_cast<const grpc_ssl_channel_security_connector*>(other_sc);
int c = channel_security_connector_cmp(other);
if (c != 0) return c;
c = strcmp(target_name_, other->target_name_);
c = strcmp(target_name_.get(), other->target_name_.get());
if (c != 0) return c;
return (overridden_target_name_ == nullptr ||
other->overridden_target_name_ == nullptr)
? GPR_ICMP(overridden_target_name_,
other->overridden_target_name_)
: strcmp(overridden_target_name_,
other->overridden_target_name_);
? GPR_ICMP(overridden_target_name_.get(),
other->overridden_target_name_.get())
: strcmp(overridden_target_name_.get(),
other->overridden_target_name_.get());
}
bool check_call_host(const char* host, grpc_auth_context* auth_context,
bool check_call_host(grpc_core::StringView host,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error) override {
grpc_security_status status = GRPC_SECURITY_ERROR;
@ -194,7 +194,7 @@ class grpc_ssl_channel_security_connector final
/* If the target name was overridden, then the original target_name was
'checked' transitively during the previous peer check at the end of the
handshake. */
if (overridden_target_name_ != nullptr && strcmp(host, target_name_) == 0) {
if (overridden_target_name_ != nullptr && host == target_name_.get()) {
status = GRPC_SECURITY_OK;
}
if (status != GRPC_SECURITY_OK) {
@ -212,8 +212,8 @@ class grpc_ssl_channel_security_connector final
private:
tsi_ssl_client_handshaker_factory* client_handshaker_factory_;
char* target_name_;
char* overridden_target_name_;
grpc_core::UniquePtr<char> target_name_;
grpc_core::UniquePtr<char> overridden_target_name_;
const verify_peer_options* verify_options_;
};

@ -27,9 +27,9 @@
#include "src/core/ext/transport/chttp2/alpn/alpn.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/global_config.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/security/context/security_context.h"
@ -136,12 +136,13 @@ grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer) {
return GRPC_ERROR_NONE;
}
grpc_error* grpc_ssl_check_peer_name(const char* peer_name,
grpc_error* grpc_ssl_check_peer_name(grpc_core::StringView peer_name,
const tsi_peer* peer) {
/* Check the peer name if specified. */
if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) {
if (!peer_name.empty() && !grpc_ssl_host_matches_name(peer, peer_name)) {
char* msg;
gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name);
gpr_asprintf(&msg, "Peer name %s is not in peer certificate",
peer_name.data());
grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
return error;
@ -149,15 +150,16 @@ grpc_error* grpc_ssl_check_peer_name(const char* peer_name,
return GRPC_ERROR_NONE;
}
bool grpc_ssl_check_call_host(const char* host, const char* target_name,
const char* overridden_target_name,
bool grpc_ssl_check_call_host(grpc_core::StringView host,
grpc_core::StringView target_name,
grpc_core::StringView overridden_target_name,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error) {
grpc_security_status status = GRPC_SECURITY_ERROR;
tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context);
if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK;
if (overridden_target_name != nullptr && strcmp(host, target_name) == 0) {
if (!overridden_target_name.empty() && host == target_name) {
status = GRPC_SECURITY_OK;
}
if (status != GRPC_SECURITY_OK) {
@ -179,35 +181,28 @@ const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols) {
return alpn_protocol_strings;
}
int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) {
char* allocated_name = nullptr;
int r;
char* ignored_port;
gpr_split_host_port(peer_name, &allocated_name, &ignored_port);
gpr_free(ignored_port);
peer_name = allocated_name;
if (!peer_name) return 0;
int grpc_ssl_host_matches_name(const tsi_peer* peer,
grpc_core::StringView peer_name) {
grpc_core::StringView allocated_name;
grpc_core::StringView ignored_port;
grpc_core::SplitHostPort(peer_name, &allocated_name, &ignored_port);
if (allocated_name.empty()) return 0;
// IPv6 zone-id should not be included in comparisons.
char* const zone_id = strchr(allocated_name, '%');
if (zone_id != nullptr) *zone_id = '\0';
r = tsi_ssl_peer_matches_name(peer, peer_name);
gpr_free(allocated_name);
return r;
const size_t zone_id = allocated_name.find('%');
if (zone_id != grpc_core::StringView::npos) {
allocated_name.remove_suffix(allocated_name.size() - zone_id);
}
return tsi_ssl_peer_matches_name(peer, allocated_name);
}
bool grpc_ssl_cmp_target_name(const char* target_name,
const char* other_target_name,
const char* overridden_target_name,
const char* other_overridden_target_name) {
int c = strcmp(target_name, other_target_name);
int grpc_ssl_cmp_target_name(
grpc_core::StringView target_name, grpc_core::StringView other_target_name,
grpc_core::StringView overridden_target_name,
grpc_core::StringView other_overridden_target_name) {
int c = target_name.cmp(other_target_name);
if (c != 0) return c;
return (overridden_target_name == nullptr ||
other_overridden_target_name == nullptr)
? GPR_ICMP(overridden_target_name, other_overridden_target_name)
: strcmp(overridden_target_name, other_overridden_target_name);
return overridden_target_name.cmp(other_overridden_target_name);
}
grpc_core::RefCountedPtr<grpc_auth_context> grpc_ssl_peer_to_auth_context(

@ -28,6 +28,7 @@
#include "src/core/lib/gprpp/global_config.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/string_view.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/security/security_connector/security_connector.h"
#include "src/core/tsi/ssl_transport_security.h"
@ -46,16 +47,17 @@ GPR_GLOBAL_CONFIG_DECLARE_BOOL(grpc_not_use_system_ssl_roots);
grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer);
/* Check peer name information returned from SSL handshakes. */
grpc_error* grpc_ssl_check_peer_name(const char* peer_name,
grpc_error* grpc_ssl_check_peer_name(grpc_core::StringView peer_name,
const tsi_peer* peer);
/* Compare targer_name information extracted from SSL security connectors. */
bool grpc_ssl_cmp_target_name(const char* target_name,
const char* other_target_name,
const char* overridden_target_name,
const char* other_overridden_target_name);
int grpc_ssl_cmp_target_name(
grpc_core::StringView target_name, grpc_core::StringView other_target_name,
grpc_core::StringView overridden_target_name,
grpc_core::StringView other_overridden_target_name);
/* Check the host that will be set for a call is acceptable.*/
bool grpc_ssl_check_call_host(const char* host, const char* target_name,
const char* overridden_target_name,
bool grpc_ssl_check_call_host(grpc_core::StringView host,
grpc_core::StringView target_name,
grpc_core::StringView overridden_target_name,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error);
@ -89,7 +91,8 @@ grpc_core::RefCountedPtr<grpc_auth_context> grpc_ssl_peer_to_auth_context(
tsi_peer grpc_shallow_peer_from_ssl_auth_context(
const grpc_auth_context* auth_context);
void grpc_shallow_peer_destruct(tsi_peer* peer);
int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name);
int grpc_ssl_host_matches_name(const tsi_peer* peer,
grpc_core::StringView peer_name);
/* --- Default SSL Root Store. --- */
namespace grpc_core {

@ -28,7 +28,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
#include "src/core/lib/security/credentials/tls/spiffe_credentials.h"
#include "src/core/lib/security/security_connector/ssl_utils.h"
@ -105,18 +105,13 @@ SpiffeChannelSecurityConnector::SpiffeChannelSecurityConnector(
? nullptr
: gpr_strdup(overridden_target_name)) {
check_arg_ = ServerAuthorizationCheckArgCreate(this);
char* port;
gpr_split_host_port(target_name, &target_name_, &port);
gpr_free(port);
grpc_core::StringView host;
grpc_core::StringView port;
grpc_core::SplitHostPort(target_name, &host, &port);
target_name_ = host.dup();
}
SpiffeChannelSecurityConnector::~SpiffeChannelSecurityConnector() {
if (target_name_ != nullptr) {
gpr_free(target_name_);
}
if (overridden_target_name_ != nullptr) {
gpr_free(overridden_target_name_);
}
if (client_handshaker_factory_ != nullptr) {
tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
}
@ -130,8 +125,8 @@ void SpiffeChannelSecurityConnector::add_handshakers(
tsi_handshaker* tsi_hs = nullptr;
tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
client_handshaker_factory_,
overridden_target_name_ != nullptr ? overridden_target_name_
: target_name_,
overridden_target_name_ != nullptr ? overridden_target_name_.get()
: target_name_.get(),
&tsi_hs);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
@ -147,8 +142,8 @@ void SpiffeChannelSecurityConnector::check_peer(
grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
grpc_closure* on_peer_checked) {
const char* target_name = overridden_target_name_ != nullptr
? overridden_target_name_
: target_name_;
? overridden_target_name_.get()
: target_name_.get();
grpc_error* error = grpc_ssl_check_alpn(&peer);
if (error != GRPC_ERROR_NONE) {
GRPC_CLOSURE_SCHED(on_peer_checked, error);
@ -203,16 +198,17 @@ int SpiffeChannelSecurityConnector::cmp(
if (c != 0) {
return c;
}
return grpc_ssl_cmp_target_name(target_name_, other->target_name_,
overridden_target_name_,
other->overridden_target_name_);
return grpc_ssl_cmp_target_name(target_name_.get(), other->target_name_.get(),
overridden_target_name_.get(),
other->overridden_target_name_.get());
}
bool SpiffeChannelSecurityConnector::check_call_host(
const char* host, grpc_auth_context* auth_context,
grpc_core::StringView host, grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked, grpc_error** error) {
return grpc_ssl_check_call_host(host, target_name_, overridden_target_name_,
auth_context, on_call_host_checked, error);
return grpc_ssl_check_call_host(host, target_name_.get(),
overridden_target_name_.get(), auth_context,
on_call_host_checked, error);
}
void SpiffeChannelSecurityConnector::cancel_check_call_host(

@ -53,7 +53,8 @@ class SpiffeChannelSecurityConnector final
int cmp(const grpc_security_connector* other_sc) const override;
bool check_call_host(const char* host, grpc_auth_context* auth_context,
bool check_call_host(grpc_core::StringView host,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error) override;
@ -83,8 +84,8 @@ class SpiffeChannelSecurityConnector final
grpc_tls_server_authorization_check_arg* arg);
grpc_closure* on_peer_checked_;
char* target_name_;
char* overridden_target_name_;
grpc_core::UniquePtr<char> target_name_;
grpc_core::UniquePtr<char> overridden_target_name_;
tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr;
grpc_tls_server_authorization_check_arg* check_arg_;
};

@ -346,7 +346,7 @@ static void auth_start_transport_stream_op_batch(
GRPC_CALL_STACK_REF(calld->owning_call, "check_call_host");
GRPC_CLOSURE_INIT(&calld->async_result_closure, on_host_checked, batch,
grpc_schedule_on_exec_ctx);
char* call_host = grpc_slice_to_c_string(calld->host);
grpc_core::StringView call_host(calld->host);
grpc_error* error = GRPC_ERROR_NONE;
if (chand->security_connector->check_call_host(
call_host, chand->auth_context.get(),
@ -360,7 +360,6 @@ static void auth_start_transport_stream_op_batch(
&calld->check_call_host_cancel_closure, cancel_check_call_host,
elem, grpc_schedule_on_exec_ctx));
}
gpr_free(call_host);
return; /* early exit */
}
}

@ -18,6 +18,7 @@
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/security/util/json_util.h"
#include <string.h>
@ -26,17 +27,27 @@
#include <grpc/support/string_util.h>
const char* grpc_json_get_string_property(const grpc_json* json,
const char* prop_name) {
grpc_json* child;
const char* prop_name,
grpc_error** error) {
grpc_json* child = nullptr;
if (error != nullptr) *error = GRPC_ERROR_NONE;
for (child = json->child; child != nullptr; child = child->next) {
if (child->key == nullptr) {
gpr_log(GPR_ERROR, "Invalid (null) JSON key encountered");
if (error != nullptr) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid (null) JSON key encountered");
}
return nullptr;
}
if (strcmp(child->key, prop_name) == 0) break;
}
if (child == nullptr || child->type != GRPC_JSON_STRING) {
gpr_log(GPR_ERROR, "Invalid or missing %s property.", prop_name);
if (error != nullptr) {
char* error_msg;
gpr_asprintf(&error_msg, "Invalid or missing %s property.", prop_name);
*error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
}
return nullptr;
}
return child->value;
@ -45,7 +56,10 @@ const char* grpc_json_get_string_property(const grpc_json* json,
bool grpc_copy_json_string_property(const grpc_json* json,
const char* prop_name,
char** copied_value) {
const char* prop_value = grpc_json_get_string_property(json, prop_name);
grpc_error* error = GRPC_ERROR_NONE;
const char* prop_value =
grpc_json_get_string_property(json, prop_name, &error);
GRPC_LOG_IF_ERROR("Could not copy JSON property", error);
if (prop_value == nullptr) return false;
*copied_value = gpr_strdup(prop_value);
return true;

@ -23,6 +23,7 @@
#include <stdbool.h>
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json.h"
// Constants.
@ -32,7 +33,8 @@
// Gets a child property from a json node.
const char* grpc_json_get_string_property(const grpc_json* json,
const char* prop_name);
const char* prop_name,
grpc_error** error);
// Copies the value of the json child property specified by prop_name.
// Returns false if the property was not found.

@ -186,19 +186,21 @@ struct UserData {
class StaticMetadata {
public:
StaticMetadata(const grpc_slice& key, const grpc_slice& value)
: kv_({key, value}), hash_(0) {}
StaticMetadata(const grpc_slice& key, const grpc_slice& value, uintptr_t idx)
: kv_({key, value}), hash_(0), static_idx_(idx) {}
const grpc_mdelem_data& data() const { return kv_; }
void HashInit();
uint32_t hash() { return hash_; }
uintptr_t StaticIndex() { return static_idx_; }
private:
grpc_mdelem_data kv_;
/* private only data */
uint32_t hash_;
uintptr_t static_idx_;
};
class RefcountedMdBase {

@ -398,262 +398,262 @@ grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b) {
grpc_core::StaticMetadata grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[3], {{10, g_bytes + 19}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 0),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}},
{&grpc_static_metadata_refcounts[40], {{3, g_bytes + 612}}}),
{&grpc_static_metadata_refcounts[40], {{3, g_bytes + 612}}}, 1),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}},
{&grpc_static_metadata_refcounts[41], {{4, g_bytes + 615}}}),
{&grpc_static_metadata_refcounts[41], {{4, g_bytes + 615}}}, 2),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}},
{&grpc_static_metadata_refcounts[42], {{1, g_bytes + 619}}}),
{&grpc_static_metadata_refcounts[42], {{1, g_bytes + 619}}}, 3),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}},
{&grpc_static_metadata_refcounts[43], {{11, g_bytes + 620}}}),
{&grpc_static_metadata_refcounts[43], {{11, g_bytes + 620}}}, 4),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}},
{&grpc_static_metadata_refcounts[44], {{4, g_bytes + 631}}}),
{&grpc_static_metadata_refcounts[44], {{4, g_bytes + 631}}}, 5),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}},
{&grpc_static_metadata_refcounts[45], {{5, g_bytes + 635}}}),
{&grpc_static_metadata_refcounts[45], {{5, g_bytes + 635}}}, 6),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}},
{&grpc_static_metadata_refcounts[46], {{3, g_bytes + 640}}}),
{&grpc_static_metadata_refcounts[46], {{3, g_bytes + 640}}}, 7),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}},
{&grpc_static_metadata_refcounts[47], {{3, g_bytes + 643}}}),
{&grpc_static_metadata_refcounts[47], {{3, g_bytes + 643}}}, 8),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}},
{&grpc_static_metadata_refcounts[48], {{3, g_bytes + 646}}}),
{&grpc_static_metadata_refcounts[48], {{3, g_bytes + 646}}}, 9),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}},
{&grpc_static_metadata_refcounts[49], {{3, g_bytes + 649}}}),
{&grpc_static_metadata_refcounts[49], {{3, g_bytes + 649}}}, 10),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}},
{&grpc_static_metadata_refcounts[50], {{3, g_bytes + 652}}}),
{&grpc_static_metadata_refcounts[50], {{3, g_bytes + 652}}}, 11),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}},
{&grpc_static_metadata_refcounts[51], {{3, g_bytes + 655}}}),
{&grpc_static_metadata_refcounts[51], {{3, g_bytes + 655}}}, 12),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}},
{&grpc_static_metadata_refcounts[52], {{3, g_bytes + 658}}}),
{&grpc_static_metadata_refcounts[52], {{3, g_bytes + 658}}}, 13),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[53], {{14, g_bytes + 661}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 14),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}},
{&grpc_static_metadata_refcounts[54], {{13, g_bytes + 675}}}),
{&grpc_static_metadata_refcounts[54], {{13, g_bytes + 675}}}, 15),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[55], {{15, g_bytes + 688}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 16),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[56], {{13, g_bytes + 703}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 17),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[57], {{6, g_bytes + 716}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 18),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[58], {{27, g_bytes + 722}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 19),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[59], {{3, g_bytes + 749}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 20),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[60], {{5, g_bytes + 752}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 21),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[61], {{13, g_bytes + 757}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 22),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[62], {{13, g_bytes + 770}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 23),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[63], {{19, g_bytes + 783}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 24),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 25),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[64], {{16, g_bytes + 802}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 26),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[65], {{14, g_bytes + 818}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 27),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[66], {{16, g_bytes + 832}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 28),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[67], {{13, g_bytes + 848}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 29),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 30),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[68], {{6, g_bytes + 861}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 31),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[69], {{4, g_bytes + 867}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 32),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[70], {{4, g_bytes + 871}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 33),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[71], {{6, g_bytes + 875}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 34),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[72], {{7, g_bytes + 881}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 35),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[73], {{4, g_bytes + 888}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 36),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[20], {{4, g_bytes + 278}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 37),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[74], {{8, g_bytes + 892}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 38),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[75], {{17, g_bytes + 900}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 39),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[76], {{13, g_bytes + 917}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 40),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[77], {{8, g_bytes + 930}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 41),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[78], {{19, g_bytes + 938}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 42),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[79], {{13, g_bytes + 957}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 43),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[80], {{4, g_bytes + 970}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 44),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[81], {{8, g_bytes + 974}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 45),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[82], {{12, g_bytes + 982}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 46),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[83], {{18, g_bytes + 994}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 47),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[84], {{19, g_bytes + 1012}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 48),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[85], {{5, g_bytes + 1031}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 49),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[86], {{7, g_bytes + 1036}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 50),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[87], {{7, g_bytes + 1043}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 51),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[88], {{11, g_bytes + 1050}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 52),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[89], {{6, g_bytes + 1061}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 53),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[90], {{10, g_bytes + 1067}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 54),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[91], {{25, g_bytes + 1077}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 55),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[92], {{17, g_bytes + 1102}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 56),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[19], {{10, g_bytes + 268}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 57),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[93], {{4, g_bytes + 1119}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 58),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[94], {{3, g_bytes + 1123}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 59),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[95], {{16, g_bytes + 1126}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 60),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}},
{&grpc_static_metadata_refcounts[96], {{1, g_bytes + 1142}}}),
{&grpc_static_metadata_refcounts[96], {{1, g_bytes + 1142}}}, 61),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}},
{&grpc_static_metadata_refcounts[25], {{1, g_bytes + 350}}}),
{&grpc_static_metadata_refcounts[25], {{1, g_bytes + 350}}}, 62),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}},
{&grpc_static_metadata_refcounts[26], {{1, g_bytes + 351}}}),
{&grpc_static_metadata_refcounts[26], {{1, g_bytes + 351}}}, 63),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}},
{&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}),
{&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}, 64),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}},
{&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}),
{&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}, 65),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}},
{&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}),
{&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}, 66),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[5], {{2, g_bytes + 36}}},
{&grpc_static_metadata_refcounts[98], {{8, g_bytes + 1151}}}),
{&grpc_static_metadata_refcounts[98], {{8, g_bytes + 1151}}}, 67),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}},
{&grpc_static_metadata_refcounts[99], {{16, g_bytes + 1159}}}),
{&grpc_static_metadata_refcounts[99], {{16, g_bytes + 1159}}}, 68),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}},
{&grpc_static_metadata_refcounts[100], {{4, g_bytes + 1175}}}),
{&grpc_static_metadata_refcounts[100], {{4, g_bytes + 1175}}}, 69),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}},
{&grpc_static_metadata_refcounts[101], {{3, g_bytes + 1179}}}),
{&grpc_static_metadata_refcounts[101], {{3, g_bytes + 1179}}}, 70),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 71),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}},
{&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}),
{&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}, 72),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}},
{&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}),
{&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}, 73),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[21], {{8, g_bytes + 282}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 74),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[102], {{11, g_bytes + 1182}}},
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}),
{&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 75),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}},
{&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}),
{&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}, 76),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}},
{&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}),
{&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}, 77),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}},
{&grpc_static_metadata_refcounts[103], {{16, g_bytes + 1193}}}),
{&grpc_static_metadata_refcounts[103], {{16, g_bytes + 1193}}}, 78),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}},
{&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}),
{&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}, 79),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}},
{&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}),
{&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}, 80),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}},
{&grpc_static_metadata_refcounts[105], {{12, g_bytes + 1222}}}),
{&grpc_static_metadata_refcounts[105], {{12, g_bytes + 1222}}}, 81),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}},
{&grpc_static_metadata_refcounts[106], {{21, g_bytes + 1234}}}),
{&grpc_static_metadata_refcounts[106], {{21, g_bytes + 1234}}}, 82),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}},
{&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}),
{&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}, 83),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}},
{&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}),
{&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}, 84),
grpc_core::StaticMetadata(
{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}},
{&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}),
{&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}, 85),
};
const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78,
79, 80, 81, 82};

@ -30,7 +30,6 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd_id.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/slice/slice_internal.h"

@ -233,11 +233,10 @@ static void ssl_info_callback(const SSL* ssl, int where, int ret) {
/* Returns 1 if name looks like an IP address, 0 otherwise.
This is a very rough heuristic, and only handles IPv6 in hexadecimal form. */
static int looks_like_ip_address(const char* name) {
size_t i;
static int looks_like_ip_address(grpc_core::StringView name) {
size_t dot_count = 0;
size_t num_size = 0;
for (i = 0; i < strlen(name); i++) {
for (size_t i = 0; i < name.size(); ++i) {
if (name[i] == ':') {
/* IPv6 Address in hexadecimal form, : is not allowed in DNS names. */
return 1;
@ -1506,52 +1505,46 @@ static void tsi_ssl_server_handshaker_factory_destroy(
gpr_free(self);
}
static int does_entry_match_name(const char* entry, size_t entry_length,
const char* name) {
const char* dot;
const char* name_subdomain = nullptr;
size_t name_length = strlen(name);
size_t name_subdomain_length;
if (entry_length == 0) return 0;
static int does_entry_match_name(grpc_core::StringView entry,
grpc_core::StringView name) {
if (entry.empty()) return 0;
/* Take care of '.' terminations. */
if (name[name_length - 1] == '.') {
name_length--;
if (name.back() == '.') {
name.remove_suffix(1);
}
if (entry[entry_length - 1] == '.') {
entry_length--;
if (entry_length == 0) return 0;
if (entry.back() == '.') {
entry.remove_suffix(1);
if (entry.empty()) return 0;
}
if ((name_length == entry_length) &&
strncmp(name, entry, entry_length) == 0) {
if (name == entry) {
return 1; /* Perfect match. */
}
if (entry[0] != '*') return 0;
if (entry.front() != '*') return 0;
/* Wildchar subdomain matching. */
if (entry_length < 3 || entry[1] != '.') { /* At least *.x */
if (entry.size() < 3 || entry[1] != '.') { /* At least *.x */
gpr_log(GPR_ERROR, "Invalid wildchar entry.");
return 0;
}
name_subdomain = strchr(name, '.');
if (name_subdomain == nullptr) return 0;
name_subdomain_length = strlen(name_subdomain);
if (name_subdomain_length < 2) return 0;
name_subdomain++; /* Starts after the dot. */
name_subdomain_length--;
entry += 2; /* Remove *. */
entry_length -= 2;
dot = strchr(name_subdomain, '.');
if ((dot == nullptr) || (dot == &name_subdomain[name_subdomain_length - 1])) {
gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain);
size_t name_subdomain_pos = name.find('.');
if (name_subdomain_pos == grpc_core::StringView::npos) return 0;
if (name_subdomain_pos >= name.size() - 2) return 0;
grpc_core::StringView name_subdomain =
name.substr(name_subdomain_pos + 1); /* Starts after the dot. */
entry.remove_prefix(2); /* Remove *. */
size_t dot = name_subdomain.find('.');
if (dot == grpc_core::StringView::npos || dot == name_subdomain.size() - 1) {
grpc_core::UniquePtr<char> name_subdomain_cstr(name_subdomain.dup());
gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s",
name_subdomain_cstr.get());
return 0;
}
if (name_subdomain[name_subdomain_length - 1] == '.') {
name_subdomain_length--;
if (name_subdomain.back() == '.') {
name_subdomain.remove_suffix(1);
}
return ((entry_length > 0) && (name_subdomain_length == entry_length) &&
strncmp(entry, name_subdomain, entry_length) == 0);
return !entry.empty() && name_subdomain == entry;
}
static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap,
@ -1919,7 +1912,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options(
/* --- tsi_ssl utils. --- */
int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) {
int tsi_ssl_peer_matches_name(const tsi_peer* peer,
grpc_core::StringView name) {
size_t i = 0;
size_t san_count = 0;
const tsi_peer_property* cn_property = nullptr;
@ -1933,13 +1927,10 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) {
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
san_count++;
if (!like_ip && does_entry_match_name(property->value.data,
property->value.length, name)) {
grpc_core::StringView entry(property->value.data, property->value.length);
if (!like_ip && does_entry_match_name(entry, name)) {
return 1;
} else if (like_ip &&
strncmp(name, property->value.data, property->value.length) ==
0 &&
strlen(name) == property->value.length) {
} else if (like_ip && name == entry) {
/* IP Addresses are exact matches only. */
return 1;
}
@ -1951,8 +1942,9 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) {
/* If there's no SAN, try the CN, but only if its not like an IP Address */
if (san_count == 0 && cn_property != nullptr && !like_ip) {
if (does_entry_match_name(cn_property->value.data,
cn_property->value.length, name)) {
if (does_entry_match_name(grpc_core::StringView(cn_property->value.data,
cn_property->value.length),
name)) {
return 1;
}
}

@ -21,6 +21,7 @@
#include <grpc/support/port_platform.h>
#include "src/core/lib/gprpp/string_view.h"
#include "src/core/tsi/transport_security_interface.h"
/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */
@ -306,7 +307,7 @@ void tsi_ssl_server_handshaker_factory_unref(
- handle mixed case.
- handle %encoded chars.
- handle public suffix wildchar more strictly (e.g. *.co.uk) */
int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name);
int tsi_ssl_peer_matches_name(const tsi_peer* peer, grpc_core::StringView name);
/* --- Testing support. ---

@ -19,10 +19,8 @@
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
</PropertyGroup>
<PropertyGroup Condition="'$(OS)' != 'Windows_NT'">
<!-- Workaround for https://github.com/dotnet/sdk/issues/335 -->
<FrameworkPathOverride Condition="Exists('/usr/lib/mono/4.5-api')">/usr/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/usr/local/lib/mono/4.5-api')">/usr/local/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api</FrameworkPathOverride>
</PropertyGroup>
<!-- Needed for the net45 build to work on Unix. See https://github.com/dotnet/designs/pull/33 -->
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0-preview.2" PrivateAssets="All" />
</ItemGroup>
</Project>

@ -7,13 +7,10 @@
<Import Project="..\Grpc.Core\SourceLink.csproj.include" />
<!-- This is copied verbatim from Grpc.Core/Common.csproj.include. Other settings
in that file conflict with the intent of this build, as it cannot be signed,
and may not compile Grpc.Core/Version.cs, as that file references constants
in Grpc.Core.dll.
TODO(kkm): Refactor imports. -->
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' and '$(MSBuildRuntimeType)' == 'Core' ">
<!-- Use Mono reference assemblies in SDK build: https://github.com/dotnet/sdk/issues/335 -->
<!-- Use Mono reference assemblies in SDK build: https://github.com/dotnet/sdk/issues/335.
This is a different approach than used in Grpc.Core/Common.csproj.include because
the workaround used there doesn't seem to be working for Microsoft.Build.* assemblies -->
<FrameworkPathOverride Condition="Exists('/usr/lib/mono/4.5-api')">/usr/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/usr/local/lib/mono/4.5-api')">/usr/local/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api</FrameworkPathOverride>

@ -7,13 +7,10 @@
<TargetFrameworks>net45;netstandard1.3</TargetFrameworks>
</PropertyGroup>
<!-- This is copied verbatim from Grpc.Core/Common.csproj.include. Other settings
in that file conflict with the intent of this build, as it cannot be signed,
and may not compile Grpc.Core/Version.cs, as that file references constants
in Grpc.Core.dll.
TODO(kkm): Refactor imports. -->
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT' and '$(MSBuildRuntimeType)' == 'Core' ">
<!-- Use Mono reference assemblies in SDK build: https://github.com/dotnet/sdk/issues/335 -->
<!-- Use Mono reference assemblies in SDK build: https://github.com/dotnet/sdk/issues/335.
This is a different approach than used in Grpc.Core/Common.csproj.include because
the workaround used there doesn't seem to be working for Microsoft.Build.* assemblies -->
<FrameworkPathOverride Condition="Exists('/usr/lib/mono/4.5-api')">/usr/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/usr/local/lib/mono/4.5-api')">/usr/local/lib/mono/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="Exists('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api</FrameworkPathOverride>

@ -21,6 +21,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" />
<!-- PrivateAssets set to None to ensure the build targets/props are propagated to parent project -->
<ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" PrivateAssets="None" />
</ItemGroup>
</Project>

@ -322,9 +322,6 @@ const char *kCFStreamVarName = "grpc_cfstream";
// Guarantees the code in {} block is invoked only once. See ref at:
// https://developer.apple.com/documentation/objectivec/nsobject/1418639-initialize?language=objc
if (self == [GRPCCall self]) {
// Enable CFStream by default by do not overwrite if the user explicitly disables CFStream with
// environment variable "grpc_cfstream=0"
setenv(kCFStreamVarName, "1", 0);
grpc_init();
callFlags = [NSMutableDictionary dictionary];
}
@ -780,7 +777,7 @@ const char *kCFStreamVarName = "grpc_cfstream";
// Connectivity monitor is not required for CFStream
char *enableCFStream = getenv(kCFStreamVarName);
if (enableCFStream == nil || enableCFStream[0] != '1') {
if (enableCFStream != nil && enableCFStream[0] != '1') {
[GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)];
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save