diff --git a/.gitignore b/.gitignore index a8c58277c34..4a400b4e3b4 100644 --- a/.gitignore +++ b/.gitignore @@ -146,3 +146,6 @@ bm_*.json # Clion artifacts cmake-build-debug/ + +# Benchmark outputs +BenchmarkDotNet.Artifacts/ \ No newline at end of file diff --git a/BUILD b/BUILD index 0f741648e1c..2fa3028111a 100644 --- a/BUILD +++ b/BUILD @@ -223,6 +223,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", @@ -559,7 +560,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", @@ -586,6 +586,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", @@ -595,7 +596,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", @@ -612,14 +612,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", @@ -628,6 +630,7 @@ grpc_cc_library( public_hdrs = GPR_PUBLIC_HDRS, deps = [ "gpr_codegen", + "grpc_codegen", ], ) @@ -783,6 +786,7 @@ grpc_cc_library( "src/core/lib/iomgr/ev_windows.cc", "src/core/lib/iomgr/exec_ctx.cc", "src/core/lib/iomgr/executor.cc", + "src/core/lib/iomgr/executor/mpmcqueue.cc", "src/core/lib/iomgr/fork_posix.cc", "src/core/lib/iomgr/fork_windows.cc", "src/core/lib/iomgr/gethostname_fallback.cc", @@ -940,6 +944,7 @@ grpc_cc_library( "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/gevent_util.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", diff --git a/BUILD.gn b/BUILD.gn index e5396f51426..6b6a0f5c392 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -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", @@ -524,6 +525,8 @@ config("grpc_config") { "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.cc", "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/executor/mpmcqueue.cc", + "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/fork_posix.cc", "src/core/lib/iomgr/fork_windows.cc", "src/core/lib/iomgr/gethostname.h", @@ -1028,6 +1031,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 +1175,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 +1196,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 +1206,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", @@ -1226,6 +1231,7 @@ config("grpc_config") { "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index bacaac86953..f9b51f1715a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.5.1) set(PACKAGE_NAME "grpc") set(PACKAGE_VERSION "1.23.0-dev") @@ -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) @@ -378,6 +379,7 @@ add_dependencies(buildtests_c memory_usage_test) endif() add_dependencies(buildtests_c message_compress_test) add_dependencies(buildtests_c minimal_stack_is_minimal_test) +add_dependencies(buildtests_c mpmcqueue_test) add_dependencies(buildtests_c multiple_server_queues_test) add_dependencies(buildtests_c murmur_hash_test) add_dependencies(buildtests_c no_server_test) @@ -713,6 +715,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 +864,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 +890,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 @@ -1028,6 +1031,7 @@ add_library(grpc src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -1363,6 +1367,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 @@ -1463,6 +1470,7 @@ add_library(grpc_cronet src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -1761,6 +1769,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 @@ -1880,6 +1891,7 @@ add_library(grpc_test_util src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -2090,6 +2102,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 @@ -2210,6 +2225,7 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -2420,6 +2436,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 @@ -2516,6 +2535,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -2773,6 +2793,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 +3183,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 @@ -3542,6 +3566,7 @@ add_library(grpc++_cronet src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -3728,6 +3753,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 +3809,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 +4809,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 +5798,6 @@ endif() endif (gRPC_BUILD_CSHARP_EXT) if (gRPC_BUILD_TESTS) -add_library(upb - third_party/upb/generated_for_cmake/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 $ $ - 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 $<$:${_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 +6852,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 +6870,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 +6879,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 $<$:${_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 $<$:${_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 $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) endif() endif (gRPC_BUILD_TESTS) @@ -7506,7 +7518,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 ) @@ -9357,6 +9369,40 @@ target_link_libraries(minimal_stack_is_minimal_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(mpmcqueue_test + test/core/iomgr/mpmcqueue_test.cc +) + + +target_include_directories(mpmcqueue_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(mpmcqueue_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(mpmcqueue_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(mpmcqueue_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(multiple_server_queues_test test/core/end2end/multiple_server_queues_test.cc ) @@ -16639,6 +16685,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) diff --git a/Makefile b/Makefile index 48afd395f0e..2955182ad8f 100644 --- a/Makefile +++ b/Makefile @@ -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 @@ -1092,6 +1094,7 @@ memory_usage_server: $(BINDIR)/$(CONFIG)/memory_usage_server memory_usage_test: $(BINDIR)/$(CONFIG)/memory_usage_test message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test minimal_stack_is_minimal_test: $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test +mpmcqueue_test: $(BINDIR)/$(CONFIG)/mpmcqueue_test multiple_server_queues_test: $(BINDIR)/$(CONFIG)/multiple_server_queues_test murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test @@ -1278,6 +1281,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 +1450,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 \ @@ -1515,6 +1520,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/memory_usage_test \ $(BINDIR)/$(CONFIG)/message_compress_test \ $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test \ + $(BINDIR)/$(CONFIG)/mpmcqueue_test \ $(BINDIR)/$(CONFIG)/multiple_server_queues_test \ $(BINDIR)/$(CONFIG)/murmur_hash_test \ $(BINDIR)/$(CONFIG)/no_server_test \ @@ -1744,6 +1750,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 +1914,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 +1991,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" @@ -2109,6 +2119,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/message_compress_test || ( echo test message_compress_test failed ; exit 1 ) $(E) "[RUN] Testing minimal_stack_is_minimal_test" $(Q) $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test || ( echo test minimal_stack_is_minimal_test failed ; exit 1 ) + $(E) "[RUN] Testing mpmcqueue_test" + $(Q) $(BINDIR)/$(CONFIG)/mpmcqueue_test || ( echo test mpmcqueue_test failed ; exit 1 ) $(E) "[RUN] Testing multiple_server_queues_test" $(Q) $(BINDIR)/$(CONFIG)/multiple_server_queues_test || ( echo test multiple_server_queues_test failed ; exit 1 ) $(E) "[RUN] Testing murmur_hash_test" @@ -2433,6 +2445,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 +3393,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 +3419,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 \ @@ -3525,6 +3539,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -3954,6 +3969,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -4364,6 +4380,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -4681,6 +4698,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -4961,6 +4979,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -5534,6 +5553,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 \ @@ -5960,6 +5980,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -6163,6 +6184,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 +7133,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 +9661,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 +10273,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 +10293,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) @@ -12120,6 +12175,38 @@ endif endif +MPMCQUEUE_TEST_SRC = \ + test/core/iomgr/mpmcqueue_test.cc \ + +MPMCQUEUE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MPMCQUEUE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/mpmcqueue_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/mpmcqueue_test: $(MPMCQUEUE_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) $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/mpmcqueue_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/mpmcqueue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_mpmcqueue_test: $(MPMCQUEUE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(MPMCQUEUE_TEST_OBJS:.o=.dep) +endif +endif + + MULTIPLE_SERVER_QUEUES_TEST_SRC = \ test/core/end2end/multiple_server_queues_test.cc \ @@ -19666,6 +19753,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 \ diff --git a/WORKSPACE b/WORKSPACE index 11b30e2a68d..5dead436fdc 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -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", ) diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index b7edcda702f..87e8b9d3292 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -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, diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 27d19eee518..2507fd5f242 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -66,11 +66,6 @@ def grpc_deps(): actual = "@com_github_google_googletest//:gtest", ) - native.bind( - name = "gmock", - actual = "@com_github_google_googletest//:gmock", - ) - native.bind( name = "benchmark", actual = "@com_github_google_benchmark//:benchmark", @@ -144,10 +139,9 @@ def grpc_deps(): if "com_github_google_googletest" not in native.existing_rules(): http_archive( name = "com_github_google_googletest", - build_file = "@com_github_grpc_grpc//third_party:gtest.BUILD", - sha256 = "175a22300b3450e27e5f2e6f95cc9abca74617cbc21a1e0ed19bdfbd22ea0305", - strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780", - url = "https://github.com/google/googletest/archive/ec44c6c1675c25b9827aacd08c02433cccde7780.tar.gz", + sha256 = "d0d447b4feeedca837a0d46a289d4223089b32ac2f84545fa4982755cc8919be", + strip_prefix = "googletest-2fe3bd994b3189899d93f1d5a881e725e046fdc2", + url = "https://github.com/google/googletest/archive/2fe3bd994b3189899d93f1d5a881e725e046fdc2.tar.gz", ) if "com_github_gflags_gflags" not in native.existing_rules(): diff --git a/bazel/python_rules.bzl b/bazel/python_rules.bzl index 17004f3474d..d4ff77094cc 100644 --- a/bazel/python_rules.bzl +++ b/bazel/python_rules.bzl @@ -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, diff --git a/build.yaml b/build.yaml index ebd484fbcd9..68754a5698a 100644 --- a/build.yaml +++ b/build.yaml @@ -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 @@ -280,6 +280,7 @@ filegroups: - src/core/lib/iomgr/ev_windows.cc - src/core/lib/iomgr/exec_ctx.cc - src/core/lib/iomgr/executor.cc + - src/core/lib/iomgr/executor/mpmcqueue.cc - src/core/lib/iomgr/fork_posix.cc - src/core/lib/iomgr/fork_windows.cc - src/core/lib/iomgr/gethostname_fallback.cc @@ -444,6 +445,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 @@ -466,6 +468,7 @@ filegroups: - src/core/lib/iomgr/ev_posix.h - src/core/lib/iomgr/exec_ctx.h - src/core/lib/iomgr/executor.h + - src/core/lib/iomgr/executor/mpmcqueue.h - src/core/lib/iomgr/gethostname.h - src/core/lib/iomgr/grpc_if_nametoindex.h - src/core/lib/iomgr/internal_errqueue.h @@ -1366,6 +1369,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 +2403,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 +2412,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 +2642,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 @@ -3266,6 +3283,16 @@ targets: - grpc - gpr uses_polling: false +- name: mpmcqueue_test + build: test + language: c + src: + - test/core/iomgr/mpmcqueue_test.cc + deps: + - grpc_test_util + - grpc + - gpr + uses_polling: false - name: multiple_server_queues_test build: test language: c @@ -5760,6 +5787,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++ diff --git a/config.m4 b/config.m4 index bb30be56910..1791a3ca27b 100644 --- a/config.m4 +++ b/config.m4 @@ -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 \ @@ -127,6 +127,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -726,6 +727,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/gprpp) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/http) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr/executor) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/json) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/profiling) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/context) diff --git a/config.w32 b/config.w32 index c9faa8d9ac8..ddb5a39bc6c 100644 --- a/config.w32 +++ b/config.w32 @@ -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 " + @@ -102,6 +102,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\ev_windows.cc " + "src\\core\\lib\\iomgr\\exec_ctx.cc " + "src\\core\\lib\\iomgr\\executor.cc " + + "src\\core\\lib\\iomgr\\executor\\mpmcqueue.cc " + "src\\core\\lib\\iomgr\\fork_posix.cc " + "src\\core\\lib\\iomgr\\fork_windows.cc " + "src\\core\\lib\\iomgr\\gethostname_fallback.cc " + @@ -739,6 +740,7 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\gprpp"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\http"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr\\executor"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\json"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\profiling"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security"); diff --git a/doc/statuscodes.md b/doc/statuscodes.md index 61e0d820b48..a5c395d0ceb 100644 --- a/doc/statuscodes.md +++ b/doc/statuscodes.md @@ -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. diff --git a/examples/cpp/helloworld/CMakeLists.txt b/examples/cpp/helloworld/CMakeLists.txt index d0f705f6d99..146ee814261 100644 --- a/examples/cpp/helloworld/CMakeLists.txt +++ b/examples/cpp/helloworld/CMakeLists.txt @@ -17,7 +17,7 @@ # See cmake_externalproject/CMakeLists.txt for all-in-one cmake build # that automatically builds all the dependencies before building helloworld. -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.5.1) project(HelloWorld C CXX) diff --git a/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt b/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt index 9fbdf071a8d..0d8470a8d68 100644 --- a/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt +++ b/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt @@ -20,7 +20,7 @@ # including the "helloworld" project itself. # See https://blog.kitware.com/cmake-superbuilds-git-submodules/ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.5.1) # Project project(HelloWorld-SuperBuild C CXX) diff --git a/examples/python/auth/BUILD.bazel b/examples/python/auth/BUILD.bazel new file mode 100644 index 00000000000..7bb4203f93f --- /dev/null +++ b/examples/python/auth/BUILD.bazel @@ -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", + ], +) diff --git a/examples/python/auth/README.md b/examples/python/auth/README.md new file mode 100644 index 00000000000..2fd044b8a30 --- /dev/null +++ b/examples/python/auth/README.md @@ -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) +``` diff --git a/examples/python/auth/_credentials.py b/examples/python/auth/_credentials.py new file mode 100644 index 00000000000..732587b7c5b --- /dev/null +++ b/examples/python/auth/_credentials.py @@ -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') diff --git a/examples/python/auth/credentials/localhost.crt b/examples/python/auth/credentials/localhost.crt new file mode 100644 index 00000000000..fc54fd492e1 --- /dev/null +++ b/examples/python/auth/credentials/localhost.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----- diff --git a/examples/python/auth/credentials/localhost.key b/examples/python/auth/credentials/localhost.key new file mode 100644 index 00000000000..72e24632828 --- /dev/null +++ b/examples/python/auth/credentials/localhost.key @@ -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----- diff --git a/examples/python/auth/credentials/root.crt b/examples/python/auth/credentials/root.crt new file mode 100644 index 00000000000..0fa644d3e59 --- /dev/null +++ b/examples/python/auth/credentials/root.crt @@ -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----- diff --git a/examples/python/auth/customized_auth_client.py b/examples/python/auth/customized_auth_client.py new file mode 100644 index 00000000000..0236c07adb1 --- /dev/null +++ b/examples/python/auth/customized_auth_client.py @@ -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() diff --git a/examples/python/auth/customized_auth_server.py b/examples/python/auth/customized_auth_server.py new file mode 100644 index 00000000000..1debc6c3c5f --- /dev/null +++ b/examples/python/auth/customized_auth_server.py @@ -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() diff --git a/examples/python/auth/test/_auth_example_test.py b/examples/python/auth/test/_auth_example_test.py new file mode 100644 index 00000000000..e2214267212 --- /dev/null +++ b/examples/python/auth/test/_auth_example_test.py @@ -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) diff --git a/examples/python/compression/BUILD.bazel b/examples/python/compression/BUILD.bazel new file mode 100644 index 00000000000..b95d7cccc77 --- /dev/null +++ b/examples/python/compression/BUILD.bazel @@ -0,0 +1,44 @@ +# 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. + +py_binary( + name = "server", + srcs = ["server.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//examples:py_helloworld", + ], + srcs_version = "PY2AND3", +) + +py_binary( + name = "client", + srcs = ["client.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//examples:py_helloworld", + ], + srcs_version = "PY2AND3", +) + +py_test( + name = "test/compression_example_test", + srcs = ["test/compression_example_test.py"], + srcs_version = "PY2AND3", + data = [ + ":client", + ":server", + ], + size = "small", +) diff --git a/examples/python/compression/README.md b/examples/python/compression/README.md new file mode 100644 index 00000000000..c719bba07f8 --- /dev/null +++ b/examples/python/compression/README.md @@ -0,0 +1,58 @@ +## Compression with gRPC Python + +gRPC offers lossless compression options in order to decrease the number of bits +transferred over the wire. Three levels of compression are available: + + - `grpc.Compression.NoCompression` - No compression is applied to the payload. (default) + - `grpc.Compression.Deflate` - The "Deflate" algorithm is applied to the payload. + - `grpc.Compression.Gzip` - The Gzip algorithm is applied to the payload. + +The default option on both clients and servers is `grpc.Compression.NoCompression`. + +See [the gRPC Compression Spec](https://github.com/grpc/grpc/blob/master/doc/compression.md) +for more information. + +### Client Side Compression + +Compression may be set at two levels on the client side. + +#### At the channel level + +```python +with grpc.insecure_channel('foo.bar:1234', compression=grpc.Compression.Gzip) as channel: + use_channel(channel) +``` + +#### At the call level + +Setting the compression method at the call level will override any settings on +the channel level. + +```python +stub = helloworld_pb2_grpc.GreeterStub(channel) +response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'), + compression=grpc.Compression.Deflate) +``` + + +### Server Side Compression + +Additionally, compression may be set at two levels on the server side. + +#### On the entire server + +```python +server = grpc.server(futures.ThreadPoolExecutor(), + compression=grpc.Compression.Gzip) +``` + +#### For an individual RPC + +```python +def SayHello(self, request, context): + context.set_response_compression(grpc.Compression.NoCompression) + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) +``` + +Setting the compression method for an individual RPC will override any setting +supplied at server creation time. diff --git a/examples/python/compression/client.py b/examples/python/compression/client.py new file mode 100644 index 00000000000..444f14c1f68 --- /dev/null +++ b/examples/python/compression/client.py @@ -0,0 +1,76 @@ +# 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. +"""An example of compression on the client side with gRPC.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import argparse +import logging +import grpc + +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc + +_DESCRIPTION = 'A client capable of compression.' +_COMPRESSION_OPTIONS = { + "none": grpc.Compression.NoCompression, + "deflate": grpc.Compression.Deflate, + "gzip": grpc.Compression.Gzip, +} + +_LOGGER = logging.getLogger(__name__) + + +def run_client(channel_compression, call_compression, target): + with grpc.insecure_channel( + target, compression=channel_compression) as channel: + stub = helloworld_pb2_grpc.GreeterStub(channel) + response = stub.SayHello( + helloworld_pb2.HelloRequest(name='you'), + compression=call_compression, + wait_for_ready=True) + print("Response: {}".format(response)) + + +def main(): + parser = argparse.ArgumentParser(description=_DESCRIPTION) + parser.add_argument( + '--channel_compression', + default='none', + nargs='?', + choices=_COMPRESSION_OPTIONS.keys(), + help='The compression method to use for the channel.') + parser.add_argument( + '--call_compression', + default='none', + nargs='?', + choices=_COMPRESSION_OPTIONS.keys(), + help='The compression method to use for an individual call.') + parser.add_argument( + '--server', + default='localhost:50051', + type=str, + nargs='?', + help='The host-port pair at which to reach the server.') + args = parser.parse_args() + channel_compression = _COMPRESSION_OPTIONS[args.channel_compression] + call_compression = _COMPRESSION_OPTIONS[args.call_compression] + run_client(channel_compression, call_compression, args.server) + + +if __name__ == "__main__": + logging.basicConfig() + main() diff --git a/examples/python/compression/server.py b/examples/python/compression/server.py new file mode 100644 index 00000000000..bc13e60cb5b --- /dev/null +++ b/examples/python/compression/server.py @@ -0,0 +1,109 @@ +# 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. +"""An example of compression on the server side with gRPC.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from concurrent import futures +import argparse +import logging +import threading +import time +import grpc + +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc + +_DESCRIPTION = 'A server capable of compression.' +_COMPRESSION_OPTIONS = { + "none": grpc.Compression.NoCompression, + "deflate": grpc.Compression.Deflate, + "gzip": grpc.Compression.Gzip, +} +_LOGGER = logging.getLogger(__name__) + +_SERVER_HOST = 'localhost' +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +class Greeter(helloworld_pb2_grpc.GreeterServicer): + + def __init__(self, no_compress_every_n): + super(Greeter, self).__init__() + self._no_compress_every_n = 0 + self._request_counter = 0 + self._counter_lock = threading.RLock() + + def _should_suppress_compression(self): + suppress_compression = False + with self._counter_lock: + if self._no_compress_every_n and self._request_counter % self._no_compress_every_n == 0: + suppress_compression = True + self._request_counter += 1 + return suppress_compression + + def SayHello(self, request, context): + if self._should_suppress_compression(): + context.set_response_compression(grpc.Compression.NoCompression) + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def run_server(server_compression, no_compress_every_n, port): + server = grpc.server( + futures.ThreadPoolExecutor(), + compression=server_compression, + options=(('grpc.so_reuseport', 1),)) + helloworld_pb2_grpc.add_GreeterServicer_to_server( + Greeter(no_compress_every_n), server) + address = '{}:{}'.format(_SERVER_HOST, port) + server.add_insecure_port(address) + server.start() + print("Server listening at '{}'".format(address)) + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop(None) + + +def main(): + parser = argparse.ArgumentParser(description=_DESCRIPTION) + parser.add_argument( + '--server_compression', + default='none', + nargs='?', + choices=_COMPRESSION_OPTIONS.keys(), + help='The default compression method for the server.') + parser.add_argument( + '--no_compress_every_n', + type=int, + default=0, + nargs='?', + help='If set, every nth reply will be uncompressed.') + parser.add_argument( + '--port', + type=int, + default=50051, + nargs='?', + help='The port on which the server will listen.') + args = parser.parse_args() + run_server(_COMPRESSION_OPTIONS[args.server_compression], + args.no_compress_every_n, args.port) + + +if __name__ == "__main__": + logging.basicConfig() + main() diff --git a/examples/python/compression/test/compression_example_test.py b/examples/python/compression/test/compression_example_test.py new file mode 100644 index 00000000000..7d25379683f --- /dev/null +++ b/examples/python/compression/test/compression_example_test.py @@ -0,0 +1,62 @@ +# 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 compression example.""" + +import contextlib +import os +import socket +import subprocess +import unittest + +_BINARY_DIR = os.path.realpath( + os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) +_SERVER_PATH = os.path.join(_BINARY_DIR, 'server') +_CLIENT_PATH = os.path.join(_BINARY_DIR, 'client') + + +@contextlib.contextmanager +def _get_port(): + sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 0: + raise RuntimeError("Failed to set SO_REUSEPORT.") + sock.bind(('', 0)) + try: + yield sock.getsockname()[1] + finally: + sock.close() + + +class CompressionExampleTest(unittest.TestCase): + + def test_compression_example(self): + with _get_port() as test_port: + server_process = subprocess.Popen((_SERVER_PATH, '--port', + str(test_port), + '--server_compression', 'gzip')) + try: + server_target = 'localhost:{}'.format(test_port) + client_process = subprocess.Popen( + (_CLIENT_PATH, '--server', server_target, + '--channel_compression', 'gzip')) + client_return_code = client_process.wait() + self.assertEqual(0, client_return_code) + self.assertIsNone(server_process.poll()) + finally: + server_process.kill() + server_process.wait() + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index a05eb9edda0..b1e5951a8b0 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -87,7 +87,7 @@ def _reserve_port(): """Find and reserve a port for all subprocesses to use.""" sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) != 1: + if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 0: raise RuntimeError("Failed to set SO_REUSEPORT.") sock.bind(('', 0)) try: diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index f0a4418b20c..14492edd0e6 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -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', @@ -466,6 +468,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', + 'src/core/lib/iomgr/executor/mpmcqueue.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', @@ -591,7 +594,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 +614,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 +651,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', @@ -670,6 +674,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', + 'src/core/lib/iomgr/executor/mpmcqueue.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 2e34e8d7573..340c7b4b66b 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -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', @@ -436,6 +437,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', + 'src/core/lib/iomgr/executor/mpmcqueue.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', @@ -589,6 +591,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -884,7 +887,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 +907,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 +1070,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', @@ -1089,6 +1093,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', + 'src/core/lib/iomgr/executor/mpmcqueue.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', diff --git a/grpc.def b/grpc.def index 32289dffeb7..f451775dba6 100644 --- a/grpc.def +++ b/grpc.def @@ -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 diff --git a/grpc.gemspec b/grpc.gemspec index 11469a3ec5c..0249e0a1fcd 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -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 ) @@ -370,6 +371,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/ev_posix.h ) s.files += %w( src/core/lib/iomgr/exec_ctx.h ) s.files += %w( src/core/lib/iomgr/executor.h ) + s.files += %w( src/core/lib/iomgr/executor/mpmcqueue.h ) s.files += %w( src/core/lib/iomgr/gethostname.h ) s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex.h ) s.files += %w( src/core/lib/iomgr/internal_errqueue.h ) @@ -523,6 +525,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/ev_windows.cc ) s.files += %w( src/core/lib/iomgr/exec_ctx.cc ) s.files += %w( src/core/lib/iomgr/executor.cc ) + s.files += %w( src/core/lib/iomgr/executor/mpmcqueue.cc ) s.files += %w( src/core/lib/iomgr/fork_posix.cc ) s.files += %w( src/core/lib/iomgr/fork_windows.cc ) s.files += %w( src/core/lib/iomgr/gethostname_fallback.cc ) diff --git a/grpc.gyp b/grpc.gyp index 0dc1c662f7a..673a797fbcf 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -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', @@ -309,6 +309,7 @@ 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -685,6 +686,7 @@ 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -935,6 +937,7 @@ 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -1161,6 +1164,7 @@ 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 139c0c37a1f..8e4f26a2854 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -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 diff --git a/include/grpcpp/completion_queue_impl.h b/include/grpcpp/completion_queue_impl.h new file mode 100644 index 00000000000..b6fb2b4f990 --- /dev/null +++ b/include/grpcpp/completion_queue_impl.h @@ -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 + +#endif // GRPCPP_COMPLETION_QUEUE_IMPL_H diff --git a/include/grpcpp/generic/generic_stub_impl.h b/include/grpcpp/generic/generic_stub_impl.h index 90414611cbd..fdbc0d0a272 100644 --- a/include/grpcpp/generic/generic_stub_impl.h +++ b/include/grpcpp/generic/generic_stub_impl.h @@ -21,6 +21,7 @@ #include +#include #include #include #include diff --git a/include/grpcpp/impl/codegen/async_generic_service.h b/include/grpcpp/impl/codegen/async_generic_service.h index 46d09121a7b..d8e6f49b2f3 100644 --- a/include/grpcpp/impl/codegen/async_generic_service.h +++ b/include/grpcpp/impl/codegen/async_generic_service.h @@ -33,7 +33,7 @@ typedef ServerAsyncResponseWriter GenericServerAsyncResponseWriter; typedef ServerAsyncReader GenericServerAsyncReader; typedef ServerAsyncWriter GenericServerAsyncWriter; -class GenericServerContext final : public ServerContext { +class GenericServerContext final : public ::grpc_impl::ServerContext { public: const grpc::string& method() const { return method_; } const grpc::string& host() const { return host_; } @@ -99,7 +99,7 @@ class ServerGenericBidiReactor virtual void OnStarted(GenericServerContext* context) {} private: - void OnStarted(ServerContext* ctx) final { + void OnStarted(::grpc_impl::ServerContext* ctx) final { OnStarted(static_cast(ctx)); } }; diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index f95772650a2..417dceb587f 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -181,8 +181,8 @@ class ClientAsyncReaderFactory { static ClientAsyncReader* Create(ChannelInterface* channel, CompletionQueue* cq, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const W& request, - bool start, void* tag) { + ::grpc_impl::ClientContext* context, + const W& request, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( call.call(), sizeof(ClientAsyncReader))) @@ -260,8 +260,9 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface { private: friend class internal::ClientAsyncReaderFactory; template - ClientAsyncReader(::grpc::internal::Call call, ClientContext* context, - const W& request, bool start, void* tag) + ClientAsyncReader(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, const W& request, + bool start, void* tag) : context_(context), call_(call), started_(start) { // TODO(ctiller): don't assert GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok()); @@ -280,7 +281,7 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface { call_.PerformOps(&init_ops_); } - ClientContext* context_; + ::grpc_impl::ClientContext* context_; ::grpc::internal::Call call_; bool started_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, @@ -329,8 +330,8 @@ class ClientAsyncWriterFactory { static ClientAsyncWriter* Create(ChannelInterface* channel, CompletionQueue* cq, const ::grpc::internal::RpcMethod& method, - ClientContext* context, R* response, - bool start, void* tag) { + ::grpc_impl::ClientContext* context, + R* response, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( call.call(), sizeof(ClientAsyncWriter))) @@ -426,8 +427,9 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { private: friend class internal::ClientAsyncWriterFactory; template - ClientAsyncWriter(::grpc::internal::Call call, ClientContext* context, - R* response, bool start, void* tag) + ClientAsyncWriter(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, R* response, + bool start, void* tag) : context_(context), call_(call), started_(start) { finish_ops_.RecvMessage(response); finish_ops_.AllowNoMessage(); @@ -449,7 +451,7 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { } } - ClientContext* context_; + ::grpc_impl::ClientContext* context_; ::grpc::internal::Call call_; bool started_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> @@ -493,8 +495,8 @@ class ClientAsyncReaderWriterFactory { /// used to send to the server when starting the call. static ClientAsyncReaderWriter* Create( ChannelInterface* channel, CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, ClientContext* context, - bool start, void* tag) { + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( @@ -599,8 +601,9 @@ class ClientAsyncReaderWriter final private: friend class internal::ClientAsyncReaderWriterFactory; - ClientAsyncReaderWriter(::grpc::internal::Call call, ClientContext* context, - bool start, void* tag) + ClientAsyncReaderWriter(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, bool start, + void* tag) : context_(context), call_(call), started_(start) { if (start) { StartCallInternal(tag); @@ -620,7 +623,7 @@ class ClientAsyncReaderWriter final } } - ClientContext* context_; + ::grpc_impl::ClientContext* context_; ::grpc::internal::Call call_; bool started_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> @@ -696,7 +699,7 @@ class ServerAsyncReaderInterface template class ServerAsyncReader final : public ServerAsyncReaderInterface { public: - explicit ServerAsyncReader(ServerContext* ctx) + explicit ServerAsyncReader(::grpc_impl::ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. @@ -782,7 +785,7 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface { void BindCall(::grpc::internal::Call* call) override { call_ = *call; } ::grpc::internal::Call call_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> meta_ops_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; @@ -843,7 +846,7 @@ class ServerAsyncWriterInterface template class ServerAsyncWriter final : public ServerAsyncWriterInterface { public: - explicit ServerAsyncWriter(ServerContext* ctx) + explicit ServerAsyncWriter(::grpc_impl::ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. @@ -940,7 +943,7 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface { } ::grpc::internal::Call call_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> meta_ops_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, @@ -1009,7 +1012,7 @@ template class ServerAsyncReaderWriter final : public ServerAsyncReaderWriterInterface { public: - explicit ServerAsyncReaderWriter(ServerContext* ctx) + explicit ServerAsyncReaderWriter(::grpc_impl::ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. @@ -1114,7 +1117,7 @@ class ServerAsyncReaderWriter final } ::grpc::internal::Call call_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> meta_ops_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; diff --git a/include/grpcpp/impl/codegen/async_unary_call.h b/include/grpcpp/impl/codegen/async_unary_call.h index 4b97cf29018..5da6a649f14 100644 --- a/include/grpcpp/impl/codegen/async_unary_call.h +++ b/include/grpcpp/impl/codegen/async_unary_call.h @@ -22,8 +22,8 @@ #include #include #include -#include -#include +#include +#include #include #include @@ -80,9 +80,9 @@ class ClientAsyncResponseReaderFactory { /// used to send to the server when starting the call. template static ClientAsyncResponseReader* Create( - ChannelInterface* channel, CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, ClientContext* context, - const W& request, bool start) { + ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, const W& request, bool start) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( call.call(), sizeof(ClientAsyncResponseReader))) @@ -156,13 +156,14 @@ class ClientAsyncResponseReader final private: friend class internal::ClientAsyncResponseReaderFactory; - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; ::grpc::internal::Call call_; bool started_; bool initial_metadata_read_ = false; template - ClientAsyncResponseReader(::grpc::internal::Call call, ClientContext* context, + ClientAsyncResponseReader(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, const W& request, bool start) : context_(context), call_(call), started_(start) { // Bind the metadata at time of StartCallInternal but set up the rest here @@ -199,7 +200,7 @@ template class ServerAsyncResponseWriter final : public internal::ServerAsyncStreamingInterface { public: - explicit ServerAsyncResponseWriter(ServerContext* ctx) + explicit ServerAsyncResponseWriter(::grpc_impl::ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. @@ -289,7 +290,7 @@ class ServerAsyncResponseWriter final void BindCall(::grpc::internal::Call* call) override { call_ = *call; } ::grpc::internal::Call call_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> meta_buf_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index c3ae6c4e3d2..d0958bbb251 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -697,7 +697,7 @@ class CallOpRecvInitialMetadata { public: CallOpRecvInitialMetadata() : metadata_map_(nullptr) {} - void RecvInitialMetadata(ClientContext* context) { + void RecvInitialMetadata(::grpc_impl::ClientContext* context) { context->initial_metadata_received_ = true; metadata_map_ = &context->recv_initial_metadata_; } @@ -746,7 +746,7 @@ class CallOpClientRecvStatus { CallOpClientRecvStatus() : recv_status_(nullptr), debug_error_string_(nullptr) {} - void ClientRecvStatus(ClientContext* context, Status* status) { + void ClientRecvStatus(::grpc_impl::ClientContext* context, Status* status) { client_context_ = context; metadata_map_ = &client_context_->trailing_metadata_; recv_status_ = status; @@ -807,7 +807,7 @@ class CallOpClientRecvStatus { private: bool hijacked_ = false; - ClientContext* client_context_; + ::grpc_impl::ClientContext* client_context_; MetadataMap* metadata_map_; Status* recv_status_; const char* debug_error_string_; diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 86d06b72c91..9441a48b051 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -44,8 +44,8 @@ class RpcMethod; /// TODO(vjpai): Combine as much as possible with the blocking unary call code template void CallbackUnaryCall(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, const InputMessage* request, - OutputMessage* result, + ::grpc_impl::ClientContext* context, + const InputMessage* request, OutputMessage* result, std::function on_completion) { CallbackUnaryCallImpl x( channel, method, context, request, result, on_completion); @@ -55,8 +55,8 @@ template class CallbackUnaryCallImpl { public: CallbackUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, const InputMessage* request, - OutputMessage* result, + ::grpc_impl::ClientContext* context, + const InputMessage* request, OutputMessage* result, std::function on_completion) { CompletionQueue* cq = channel->CallbackCQ(); GPR_CODEGEN_ASSERT(cq != nullptr); @@ -550,7 +550,7 @@ class ClientCallbackReaderWriterImpl friend class ClientCallbackReaderWriterFactory; ClientCallbackReaderWriterImpl( - Call call, ClientContext* context, + Call call, ::grpc_impl::ClientContext* context, ::grpc::experimental::ClientBidiReactor* reactor) : context_(context), call_(call), @@ -559,7 +559,7 @@ class ClientCallbackReaderWriterImpl this->BindReactor(reactor); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientBidiReactor* const reactor_; @@ -594,7 +594,7 @@ class ClientCallbackReaderWriterFactory { public: static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, + ::grpc_impl::ClientContext* context, ::grpc::experimental::ClientBidiReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); @@ -692,7 +692,7 @@ class ClientCallbackReaderImpl template ClientCallbackReaderImpl( - Call call, ClientContext* context, Request* request, + Call call, ::grpc_impl::ClientContext* context, Request* request, ::grpc::experimental::ClientReadReactor* reactor) : context_(context), call_(call), reactor_(reactor) { this->BindReactor(reactor); @@ -701,7 +701,7 @@ class ClientCallbackReaderImpl start_ops_.ClientSendClose(); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientReadReactor* const reactor_; @@ -729,7 +729,7 @@ class ClientCallbackReaderFactory { template static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const Request* request, + ::grpc_impl::ClientContext* context, const Request* request, ::grpc::experimental::ClientReadReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); @@ -866,7 +866,7 @@ class ClientCallbackWriterImpl template ClientCallbackWriterImpl( - Call call, ClientContext* context, Response* response, + Call call, ::grpc_impl::ClientContext* context, Response* response, ::grpc::experimental::ClientWriteReactor* reactor) : context_(context), call_(call), @@ -877,7 +877,7 @@ class ClientCallbackWriterImpl finish_ops_.AllowNoMessage(); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientWriteReactor* const reactor_; @@ -909,7 +909,7 @@ class ClientCallbackWriterFactory { template static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, Response* response, + ::grpc_impl::ClientContext* context, Response* response, ::grpc::experimental::ClientWriteReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); @@ -976,8 +976,8 @@ class ClientCallbackUnaryImpl final friend class ClientCallbackUnaryFactory; template - ClientCallbackUnaryImpl(Call call, ClientContext* context, Request* request, - Response* response, + ClientCallbackUnaryImpl(Call call, ::grpc_impl::ClientContext* context, + Request* request, Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) : context_(context), call_(call), reactor_(reactor) { this->BindReactor(reactor); @@ -988,7 +988,7 @@ class ClientCallbackUnaryImpl final finish_ops_.AllowNoMessage(); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientUnaryReactor* const reactor_; @@ -1011,8 +1011,8 @@ class ClientCallbackUnaryFactory { template static void Create(ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const Request* request, - Response* response, + ::grpc_impl::ClientContext* context, + const Request* request, Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); diff --git a/include/grpcpp/impl/codegen/intercepted_channel.h b/include/grpcpp/impl/codegen/intercepted_channel.h index cd0fcc06753..bcdd89db741 100644 --- a/include/grpcpp/impl/codegen/intercepted_channel.h +++ b/include/grpcpp/impl/codegen/intercepted_channel.h @@ -49,7 +49,7 @@ class InterceptedChannel : public ChannelInterface { InterceptedChannel(ChannelInterface* channel, size_t pos) : channel_(channel), interceptor_pos_(pos) {} - Call CreateCall(const RpcMethod& method, ClientContext* context, + Call CreateCall(const RpcMethod& method, ::grpc_impl::ClientContext* context, ::grpc_impl::CompletionQueue* cq) override { return channel_->CreateCallInternal(method, context, cq, interceptor_pos_); } diff --git a/include/grpcpp/impl/codegen/method_handler_impl.h b/include/grpcpp/impl/codegen/method_handler_impl.h index dee1cb56ad1..1903f898ba8 100644 --- a/include/grpcpp/impl/codegen/method_handler_impl.h +++ b/include/grpcpp/impl/codegen/method_handler_impl.h @@ -52,10 +52,11 @@ Status CatchingFunctionHandler(Callable&& handler) { template class RpcMethodHandler : public MethodHandler { public: - RpcMethodHandler(std::function - func, - ServiceType* service) + RpcMethodHandler( + std::function + func, + ServiceType* service) : func_(func), service_(service) {} void RunHandler(const HandlerParameter& param) final { @@ -103,8 +104,8 @@ class RpcMethodHandler : public MethodHandler { private: /// Application provided rpc handler function. - std::function + std::function func_; // The class the above handler function lives in. ServiceType* service_; @@ -115,7 +116,7 @@ template class ClientStreamingHandler : public MethodHandler { public: ClientStreamingHandler( - std::function*, ResponseType*)> func, ServiceType* service) @@ -147,8 +148,8 @@ class ClientStreamingHandler : public MethodHandler { } private: - std::function*, - ResponseType*)> + std::function*, ResponseType*)> func_; ServiceType* service_; }; @@ -158,8 +159,8 @@ template class ServerStreamingHandler : public MethodHandler { public: ServerStreamingHandler( - std::function*)> + std::function*)> func, ServiceType* service) : func_(func), service_(service) {} @@ -207,8 +208,8 @@ class ServerStreamingHandler : public MethodHandler { } private: - std::function*)> + std::function*)> func_; ServiceType* service_; }; @@ -224,7 +225,7 @@ template class TemplatedBidiStreamingHandler : public MethodHandler { public: TemplatedBidiStreamingHandler( - std::function func) + std::function func) : func_(func), write_needed_(WriteNeeded) {} void RunHandler(const HandlerParameter& param) final { @@ -256,7 +257,7 @@ class TemplatedBidiStreamingHandler : public MethodHandler { } private: - std::function func_; + std::function func_; const bool write_needed_; }; @@ -266,7 +267,7 @@ class BidiStreamingHandler ServerReaderWriter, false> { public: BidiStreamingHandler( - std::function*)> func, ServiceType* service) @@ -281,7 +282,7 @@ class StreamedUnaryHandler ServerUnaryStreamer, true> { public: explicit StreamedUnaryHandler( - std::function*)> func) : TemplatedBidiStreamingHandler< @@ -294,7 +295,7 @@ class SplitServerStreamingHandler ServerSplitStreamer, false> { public: explicit SplitServerStreamingHandler( - std::function*)> func) : TemplatedBidiStreamingHandler< @@ -307,7 +308,7 @@ template class ErrorMethodHandler : public MethodHandler { public: template - static void FillOps(ServerContext* context, T* ops) { + static void FillOps(::grpc_impl::ServerContext* context, T* ops) { Status status(code, ""); if (!context->sent_initial_metadata_) { ops->SendInitialMetadata(&context->initial_metadata_, diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index 9600e5f053d..a375d3c0b4c 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include namespace grpc_impl { @@ -34,7 +34,6 @@ class Channel; class CompletionQueue; class ServerCompletionQueue; class ServerCredentials; -class ServerContext; } // namespace grpc_impl namespace grpc { diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index 0d3fdfcb8dc..9d030a13a71 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -21,10 +21,10 @@ #include #include -#include +#include #include #include -#include +#include #include #include @@ -163,7 +163,8 @@ class ClientReaderFactory { template static ClientReader* Create(ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const W& request) { + ::grpc_impl::ClientContext* context, + const W& request) { return new ClientReader(channel, method, context, request); } }; @@ -230,8 +231,8 @@ class ClientReader final : public ClientReaderInterface { private: friend class internal::ClientReaderFactory; - ClientContext* context_; - CompletionQueue cq_; + ::grpc_impl::ClientContext* context_; + ::grpc_impl::CompletionQueue cq_; ::grpc::internal::Call call_; /// Block to create a stream and write the initial metadata and \a request @@ -240,7 +241,7 @@ class ClientReader final : public ClientReaderInterface { template ClientReader(::grpc::ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const W& request) + ::grpc_impl::ClientContext* context, const W& request) : context_(context), cq_(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, @@ -281,7 +282,8 @@ class ClientWriterFactory { template static ClientWriter* Create(::grpc::ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, R* response) { + ::grpc_impl::ClientContext* context, + R* response) { return new ClientWriter(channel, method, context, response); } }; @@ -374,7 +376,7 @@ class ClientWriter : public ClientWriterInterface { template ClientWriter(ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, R* response) + ::grpc_impl::ClientContext* context, R* response) : context_(context), cq_(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, @@ -393,12 +395,12 @@ class ClientWriter : public ClientWriterInterface { } } - ClientContext* context_; + ::grpc_impl::ClientContext* context_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, ::grpc::internal::CallOpGenericRecvMessage, ::grpc::internal::CallOpClientRecvStatus> finish_ops_; - CompletionQueue cq_; + ::grpc_impl::CompletionQueue cq_; ::grpc::internal::Call call_; }; @@ -431,7 +433,8 @@ class ClientReaderWriterFactory { public: static ClientReaderWriter* Create( ::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, ClientContext* context) { + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context) { return new ClientReaderWriter(channel, method, context); } }; @@ -539,8 +542,8 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { private: friend class internal::ClientReaderWriterFactory; - ClientContext* context_; - CompletionQueue cq_; + ::grpc_impl::ClientContext* context_; + ::grpc_impl::CompletionQueue cq_; ::grpc::internal::Call call_; /// Block to create a stream and write the initial metadata and \a request @@ -548,7 +551,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { /// used to send to the server when starting the call. ClientReaderWriter(::grpc::ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context) + ::grpc_impl::ClientContext* context) : context_(context), cq_(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, @@ -607,12 +610,12 @@ class ServerReader final : public ServerReaderInterface { private: internal::Call* const call_; - ServerContext* const ctx_; + ::grpc_impl::ServerContext* const ctx_; template friend class internal::ClientStreamingHandler; - ServerReader(internal::Call* call, ServerContext* ctx) + ServerReader(internal::Call* call, ::grpc_impl::ServerContext* ctx) : call_(call), ctx_(ctx) {} }; @@ -681,12 +684,12 @@ class ServerWriter final : public ServerWriterInterface { private: internal::Call* const call_; - ServerContext* const ctx_; + ::grpc_impl::ServerContext* const ctx_; template friend class internal::ServerStreamingHandler; - ServerWriter(internal::Call* call, ServerContext* ctx) + ServerWriter(internal::Call* call, ::grpc_impl::ServerContext* ctx) : call_(call), ctx_(ctx) {} }; @@ -701,7 +704,7 @@ namespace internal { template class ServerReaderWriterBody final { public: - ServerReaderWriterBody(Call* call, ServerContext* ctx) + ServerReaderWriterBody(Call* call, ::grpc_impl::ServerContext* ctx) : call_(call), ctx_(ctx) {} void SendInitialMetadata() { @@ -759,7 +762,7 @@ class ServerReaderWriterBody final { private: Call* const call_; - ServerContext* const ctx_; + ::grpc_impl::ServerContext* const ctx_; }; } // namespace internal @@ -797,7 +800,7 @@ class ServerReaderWriter final : public ServerReaderWriterInterface { friend class internal::TemplatedBidiStreamingHandler, false>; - ServerReaderWriter(internal::Call* call, ServerContext* ctx) + ServerReaderWriter(internal::Call* call, ::grpc_impl::ServerContext* ctx) : body_(call, ctx) {} }; @@ -865,7 +868,7 @@ class ServerUnaryStreamer final friend class internal::TemplatedBidiStreamingHandler< ServerUnaryStreamer, true>; - ServerUnaryStreamer(internal::Call* call, ServerContext* ctx) + ServerUnaryStreamer(internal::Call* call, ::grpc_impl::ServerContext* ctx) : body_(call, ctx), read_done_(false), write_done_(false) {} }; @@ -925,7 +928,7 @@ class ServerSplitStreamer final friend class internal::TemplatedBidiStreamingHandler< ServerSplitStreamer, false>; - ServerSplitStreamer(internal::Call* call, ServerContext* ctx) + ServerSplitStreamer(internal::Call* call, ::grpc_impl::ServerContext* ctx) : body_(call, ctx), read_done_(false) {} }; diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 84a88f2dd7b..349995c8c1c 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -21,11 +21,11 @@ #include +#include #include namespace grpc_impl { -class ChannelArguments; class ServerBuilder; class ServerInitializer; } // namespace grpc_impl @@ -57,7 +57,7 @@ class ServerBuilderPlugin { /// UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(), /// before the Server instance is created. - virtual void UpdateChannelArguments(grpc_impl::ChannelArguments* args) {} + virtual void UpdateChannelArguments(ChannelArguments* args) {} virtual bool has_sync_methods() const { return false; } virtual bool has_async_methods() const { return false; } diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index e924275d592..b124d3d37be 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -28,6 +28,7 @@ typedef ::grpc_impl::CallCredentials CallCredentials; typedef ::grpc_impl::SslCredentialsOptions SslCredentialsOptions; typedef ::grpc_impl::SecureCallCredentials SecureCallCredentials; typedef ::grpc_impl::SecureChannelCredentials SecureChannelCredentials; +typedef ::grpc_impl::MetadataCredentialsPlugin MetadataCredentialsPlugin; static inline std::shared_ptr GoogleDefaultCredentials() { diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index 29ba2075c29..34920a55bbe 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -24,11 +24,11 @@ #include #include -#include +#include #include #include #include -#include +#include #include #include @@ -41,16 +41,16 @@ class CallCredentials; class SecureCallCredentials; class SecureChannelCredentials; -std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, - const grpc::ChannelArguments& args); + const ChannelArguments& args); namespace experimental { -std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( +std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, - const grpc::ChannelArguments& args, + const ChannelArguments& args, std::vector< std::unique_ptr> interceptor_creators); @@ -75,27 +75,27 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( + friend std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, - const grpc::ChannelArguments& args); + const ChannelArguments& args); - friend std::shared_ptr<::grpc::Channel> + friend std::shared_ptr grpc_impl::experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, - const grpc::ChannelArguments& args, + const ChannelArguments& args, std::vector> interceptor_creators); - virtual std::shared_ptr<::grpc::Channel> CreateChannelImpl( - const grpc::string& target, const grpc::ChannelArguments& args) = 0; + virtual std::shared_ptr CreateChannelImpl( + const grpc::string& target, const ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is // implemented as a virtual function so that it does not break API. - virtual std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( - const grpc::string& target, const grpc::ChannelArguments& args, + virtual std::shared_ptr CreateChannelWithInterceptors( + const grpc::string& target, const ChannelArguments& args, std::vector> interceptor_creators) { diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h index 7f85e807d07..9c69adc9147 100644 --- a/include/grpcpp/server_builder_impl.h +++ b/include/grpcpp/server_builder_impl.h @@ -112,6 +112,10 @@ class ServerBuilder { /// /// It can be invoked multiple times. /// + /// If port is not provided in the \a addr (e.g., "1.2.3.4:" or "1.2.3.4"), + /// the default port (i.e., https) is used. To request an ephemeral port, + /// \a addr must include 0 as the port number (e.g., "1.2.3.4:0"). + /// /// \param addr_uri The address to try to bind to the server in URI form. If /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, /// please use IPv6 any, i.e., [::]:, which also accepts IPv4 diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index b75012e5da8..52988b50288 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -27,16 +27,17 @@ #include #include -#include -#include +#include +#include #include #include #include +#include #include #include #include #include -#include +#include #include #include @@ -80,7 +81,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { public: virtual ~GlobalCallbacks() {} /// Called before server is created. - virtual void UpdateArguments(grpc::ChannelArguments* args) {} + virtual void UpdateArguments(ChannelArguments* args) {} /// Called before application callback for each synchronous server request virtual void PreSynchronousRequest(grpc_impl::ServerContext* context) = 0; /// Called after application callback for each synchronous server request @@ -108,8 +109,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { } /// Establish a channel for in-process communication - std::shared_ptr<::grpc::Channel> InProcessChannel( - const grpc::ChannelArguments& args); + std::shared_ptr InProcessChannel(const ChannelArguments& args); /// NOTE: class experimental_type is not part of the public API of this class. /// TODO(yashykt): Integrate into public API when this is no longer @@ -120,8 +120,8 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// Establish a channel for in-process communication with client /// interceptors - std::shared_ptr<::grpc::Channel> InProcessChannelWithInterceptors( - const grpc::ChannelArguments& args, + std::shared_ptr InProcessChannelWithInterceptors( + const ChannelArguments& args, std::vector> interceptor_creators); @@ -182,19 +182,18 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// /// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on /// server completion queues passed via sync_server_cqs param. - Server( - int max_message_size, grpc::ChannelArguments* args, - std::shared_ptr>> - sync_server_cqs, - int min_pollers, int max_pollers, int sync_cq_timeout_msec, - std::vector< - std::shared_ptr> - acceptors, - grpc_resource_quota* server_rq = nullptr, - std::vector> - interceptor_creators = std::vector>()); + Server(int max_message_size, ChannelArguments* args, + std::shared_ptr>> + sync_server_cqs, + int min_pollers, int max_pollers, int sync_cq_timeout_msec, + std::vector< + std::shared_ptr> + acceptors, + grpc_resource_quota* server_rq = nullptr, + std::vector> + interceptor_creators = std::vector>()); /// Start the server. /// @@ -202,7 +201,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// caller is required to keep all completion queues live until the server is /// destroyed. /// \param num_cqs How many completion queues does \a cqs hold. - void Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) override; + void Start(ServerCompletionQueue** cqs, size_t num_cqs) override; grpc_server* server() override { return server_; } @@ -283,7 +282,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { return max_receive_message_size_; } - grpc::CompletionQueue* CallbackCQ() override; + CompletionQueue* CallbackCQ() override; grpc_impl::ServerInitializer* initializer(); @@ -304,7 +303,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// The following completion queues are ONLY used in case of Sync API /// i.e. if the server has any services with sync methods. The server uses /// these completion queues to poll for new RPCs - std::shared_ptr>> + std::shared_ptr>> sync_server_cqs_; /// List of \a ThreadManager instances (one for each cq in @@ -374,7 +373,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { // It is _not owned_ by the server; ownership belongs with its internal // shutdown callback tag (invoked when the CQ is fully shutdown). // It is protected by mu_ - grpc::CompletionQueue* callback_cq_ = nullptr; + CompletionQueue* callback_cq_ = nullptr; }; } // namespace grpc_impl diff --git a/package.xml b/package.xml index 616e1ece20e..4467a11aae4 100644 --- a/package.xml +++ b/package.xml @@ -90,7 +90,6 @@ - @@ -111,6 +110,7 @@ + @@ -127,7 +127,6 @@ - @@ -154,6 +153,7 @@ + @@ -353,6 +353,7 @@ + @@ -375,6 +376,7 @@ + @@ -528,6 +530,7 @@ + diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 23e3bd50eff..358efe9fd79 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -142,14 +142,17 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, "grpcpp/impl/codegen/async_stream.h", "grpcpp/impl/codegen/async_unary_call.h", "grpcpp/impl/codegen/client_callback.h", + "grpcpp/impl/codegen/client_context.h", "grpcpp/impl/codegen/method_handler_impl.h", "grpcpp/impl/codegen/proto_utils.h", "grpcpp/impl/codegen/rpc_method.h", "grpcpp/impl/codegen/server_callback.h", + "grpcpp/impl/codegen/server_context.h", "grpcpp/impl/codegen/service_type.h", "grpcpp/impl/codegen/status.h", "grpcpp/impl/codegen/stub_options.h", - "grpcpp/impl/codegen/sync_stream.h"}; + "grpcpp/impl/codegen/sync_stream.h", + }; std::vector headers(headers_strs, array_end(headers_strs)); PrintIncludes(printer.get(), headers, params.use_system_headers, params.grpc_search_path); diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc index 9e51a83415e..2e2d8d607de 100644 --- a/src/core/ext/filters/client_channel/backup_poller.cc +++ b/src/core/ext/filters/client_channel/backup_poller.cc @@ -24,10 +24,12 @@ #include #include #include + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/surface/channel.h" @@ -153,7 +155,7 @@ static void g_poller_init_locked() { void grpc_client_channel_start_backup_polling( grpc_pollset_set* interested_parties) { - if (g_poll_interval_ms == 0) { + if (g_poll_interval_ms == 0 || grpc_iomgr_run_in_background()) { return; } gpr_mu_lock(&g_poller_mu); @@ -171,7 +173,7 @@ void grpc_client_channel_start_backup_polling( void grpc_client_channel_stop_backup_polling( grpc_pollset_set* interested_parties) { - if (g_poll_interval_ms == 0) { + if (g_poll_interval_ms == 0 || grpc_iomgr_run_in_background()) { return; } grpc_pollset_set_del_pollset(interested_parties, g_poller->pollset); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index e068d11dc41..a489685df40 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -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(gpr_strdup(subchannel_->GetTargetAddress()))), + target_(UniquePtr(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); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 9f11e928998..80a6fd230c8 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -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 connectivity_state_{GRPC_CHANNEL_IDLE}; + Atomic child_socket_uuid_{0}; UniquePtr target_; CallCountingHelper call_counter_; ChannelTrace trace_; diff --git a/src/core/ext/filters/client_channel/http_proxy.cc b/src/core/ext/filters/client_channel/http_proxy.cc index 8951a2920c4..9e60a553ceb 100644 --- a/src/core/ext/filters/client_channel/http_proxy.cc +++ b/src/core/ext/filters/client_channel/http_proxy.cc @@ -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 server_host; + grpc_core::UniquePtr 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; } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 2f3516066da..71e8e248770 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -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" diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index e5c27fe67a4..ca9ea9e31cc 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -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" diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index c5e1ed811bc..fbfbb4445f3 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -33,8 +33,8 @@ #include #include -#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 @@ -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 host; + grpc_core::UniquePtr 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(sizeof(grpc_sockaddr_in)); grpc_sockaddr_in* in = reinterpret_cast(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(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 host; + grpc_core::UniquePtr 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(addr->addr); in6->sin6_family = GRPC_AF_INET6; // Handle the RFC6874 syntax for IPv6 zone identifiers. - char* host_end = static_cast(gpr_memrchr(host, '%', strlen(host))); + char* host_end = + static_cast(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(host_end - host); + size_t host_without_scope_len = static_cast(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(port_num)); success = true; done: - gpr_free(host); - gpr_free(port); return success; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 32a339af359..43b28bc9650 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -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; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index 7d5215938e3..addae23dc3e 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -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(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(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,160 @@ 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(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 transferred_bytes = 0; + DWORD flags; + BOOL wsa_success = + WSAGetOverlappedResult(grpc_winsocket_wrapped_socket(winsocket_), + &winsocket_->write_info.overlapped, + &transferred_bytes, FALSE, &flags); + GPR_ASSERT(transferred_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("Connect error code:|%d|, msg:|%s|. fd:|%s|", - wsa_last_error, msg, GetName()); + 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); - // c-ares expects a posix-style connect API - out = -1; + 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("fd:%s bind error code:%d msg:|%s|", GetName(), + wsa_last_error, msg); + gpr_free(msg); + 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,26 +610,27 @@ 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)); } } } if (error == GRPC_ERROR_NONE) { - read_buf_ = grpc_slice_sub_no_ref(read_buf_, 0, - winsocket_->read_info.bytes_transfered); + read_buf_ = grpc_slice_sub_no_ref( + read_buf_, 0, winsocket_->read_info.bytes_transferred); read_buf_has_data_ = true; } else { grpc_slice_unref_internal(read_buf_); 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 +641,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); + write_buf_, 0, winsocket_->write_info.bytes_transferred); + GRPC_CARES_TRACE_LOG("fd:|%s| OnIocpWriteableInner. bytes transferred:%d", + GetName(), winsocket_->write_info.bytes_transferred); } else { grpc_slice_unref_internal(write_buf_); write_buf_ = grpc_empty_slice(); @@ -386,9 +682,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 +763,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(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(s, map->combiner_); + New(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(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(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(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) { diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index ad0f1460121..0c1a8ba828f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -35,8 +35,8 @@ #include #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 host; + grpc_core::UniquePtr 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* addrs, char** host, - char** port, char** hostport) { - gpr_split_host_port(name, host, port); + grpc_core::UniquePtr* addrs, + grpc_core::UniquePtr* host, grpc_core::UniquePtr* port, + grpc_core::UniquePtr* 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(); (*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* addrs) { - char* host = nullptr; - char* port = nullptr; - char* hostport = nullptr; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + grpc_core::UniquePtr 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* host, + grpc_core::UniquePtr* 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 host; + grpc_core::UniquePtr 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* addrs, char** host, - char** port) { - gpr_split_host_port(name, host, port); + grpc_core::UniquePtr* addrs, + grpc_core::UniquePtr* host, grpc_core::UniquePtr* 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(); - 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* 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 host; + grpc_core::UniquePtr 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( diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index f85feb674dd..d9e3293deb6 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -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() { diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 06cd5722ce3..1749cf77201 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -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" diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index 5ab75d02793..1abe9ad3e44 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -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; } diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index 7f613ee21bc..ff728a3dc43 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -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" diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc index 1465b0c644e..517b9297af4 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -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" diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index dd16eded826..b6ab47fb09d 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -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_subchannel, - intptr_t socket_uuid) + RefCountedPtr 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( - 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(stk, args_, channelz_node_, socket_uuid)); + New(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(this); // Report initial state. diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 2f05792b872..64d679af6c5 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -85,8 +85,7 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface { ConnectedSubchannel( grpc_channel_stack* channel_stack, const grpc_channel_args* args, - RefCountedPtr channelz_subchannel, - intptr_t socket_uuid); + RefCountedPtr 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_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(); diff --git a/src/core/ext/filters/http/client/http_client_filter.cc b/src/core/ext/filters/http/client/http_client_filter.cc index 4ef6c1f610e..d014460b34e 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -558,7 +558,7 @@ static grpc_slice user_agent_from_args(const grpc_channel_args* args, tmp = gpr_strvec_flatten(&v, nullptr); gpr_strvec_destroy(&v); - result = grpc_slice_intern(grpc_slice_from_static_string(tmp)); + result = grpc_slice_intern(grpc_slice_from_static_string_internal(tmp)); gpr_free(tmp); return result; diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc index 85b30bc13ca..4bd666ecfee 100644 --- a/src/core/ext/filters/http/client_authority_filter.cc +++ b/src/core/ext/filters/http/client_authority_filter.cc @@ -101,8 +101,8 @@ grpc_error* init_channel_elem(grpc_channel_element* elem, return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "GRPC_ARG_DEFAULT_AUTHORITY channel arg. must be a string"); } - chand->default_authority = - grpc_slice_intern(grpc_slice_from_static_string(default_authority_str)); + chand->default_authority = grpc_slice_intern( + grpc_slice_from_static_string_internal(default_authority_str)); chand->default_authority_mdelem = grpc_mdelem_create( GRPC_MDSTR_AUTHORITY, chand->default_authority, nullptr); GPR_ASSERT(!args->is_last); diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 8285ee76445..dc60ec2487b 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -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" diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index 74c305b820f..c50d7e48d41 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -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(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( + 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; diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 359ad275bbb..666d28975a8 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -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(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_MDELEM_DATA(md)) + ->StaticIndex()) < GRPC_CHTTP2_LAST_STATIC_ENTRY) { + emit_indexed(c, static_cast(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(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_MDELEM_DATA(l->md)) + ->StaticIndex()) < GRPC_CHTTP2_LAST_STATIC_ENTRY) { + emit_indexed(c, static_cast(static_index + 1), &st); } else { hpack_enc(c, l->md, &st); } diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc index 7d5c39e5144..efbd997e994 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -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 +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"); } @@ -670,7 +674,7 @@ static grpc_slice take_string(grpc_chttp2_hpack_parser* p, str->copied = true; str->data.referenced = grpc_empty_slice(); } else if (intern) { - s = grpc_slice_intern(grpc_slice_from_static_buffer( + s = grpc_slice_intern(grpc_slice_from_static_buffer_internal( str->data.copied.str, str->data.copied.length)); } else { s = grpc_slice_from_copied_buffer(str->data.copied.str, @@ -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(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( + 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(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( + 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( + 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( + 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( + 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); } @@ -1496,14 +1488,14 @@ static grpc_error* parse_key_string(grpc_chttp2_hpack_parser* p, static bool is_binary_literal_header(grpc_chttp2_hpack_parser* p) { /* We know that either argument here is a reference counter slice. - * 1. If a result of grpc_slice_from_static_buffer, the refcount is set to - * NoopRefcount. + * 1. If a result of grpc_slice_from_static_buffer_internal, the refcount is + * set to kNoopRefcount. * 2. If it's p->key.data.referenced, then p->key.copied was set to false, * which occurs in begin_parse_string() - where the refcount is set to * p->current_slice_refcount, which is not null. */ return grpc_is_refcounted_slice_binary_header( - p->key.copied ? grpc_slice_from_static_buffer(p->key.data.copied.str, - p->key.data.copied.length) + p->key.copied ? grpc_slice_from_static_buffer_internal( + p->key.data.copied.str, p->key.data.copied.length) : p->key.data.referenced); } diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc index f9e97cc5566..9d1ac4b370f 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc @@ -29,6 +29,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/validate_metadata.h" #include "src/core/lib/transport/static_metadata.h" @@ -182,9 +183,10 @@ void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl* tbl) { memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries); for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { tbl->static_ents[i - 1] = grpc_mdelem_from_slices( - grpc_slice_intern(grpc_slice_from_static_string(static_table[i].key)), grpc_slice_intern( - grpc_slice_from_static_string(static_table[i].value))); + grpc_slice_from_static_string_internal(static_table[i].key)), + grpc_slice_intern( + grpc_slice_from_static_string_internal(static_table[i].value))); } } diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 3ddda268cfb..a5f6571c510 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -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" diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 8da89851a69..8cb9ac4a2fd 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -1203,7 +1203,7 @@ void inproc_transports_create(grpc_transport** server_transport, */ void grpc_inproc_transport_init(void) { grpc_core::ExecCtx exec_ctx; - g_empty_slice = grpc_slice_from_static_buffer(nullptr, 0); + g_empty_slice = grpc_slice_from_static_buffer_internal(nullptr, 0); grpc_slice key_tmp = grpc_slice_from_static_string(":path"); g_fake_path_key = grpc_slice_intern(key_tmp); diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 4b130372e46..184ba17889d 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -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 host; + UniquePtr 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); diff --git a/src/core/lib/gpr/host_port.cc b/src/core/lib/gpr/host_port.cc deleted file mode 100644 index a34e01cb516..00000000000 --- a/src/core/lib/gpr/host_port.cc +++ /dev/null @@ -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 - -#include "src/core/lib/gpr/host_port.h" - -#include - -#include -#include -#include - -#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') { - /* ] */ - port_start = nullptr; - } else if (rbracket[1] == ':') { - /* ]: */ - port_start = rbracket + 2; - } else { - /* ] */ - return 0; - } - host_start = name + 1; - host_len = static_cast(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(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(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; -} diff --git a/src/core/lib/gpr/string.cc b/src/core/lib/gpr/string.cc index a39f56ef926..14436ec1bf9 100644 --- a/src/core/lib/gpr/string.cc +++ b/src/core/lib/gpr/string.cc @@ -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 = diff --git a/src/core/lib/gpr/string.h b/src/core/lib/gpr/string.h index bf59db7abfe..fcccf5e6764 100644 --- a/src/core/lib/gpr/string.h +++ b/src/core/lib/gpr/string.h @@ -115,6 +115,7 @@ char* gpr_strvec_flatten(gpr_strvec* strs, size_t* total_length); /** Case insensitive string comparison... return <0 if lower(a)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); diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc new file mode 100644 index 00000000000..13b63eb902b --- /dev/null +++ b/src/core/lib/gprpp/host_port.cc @@ -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 + +#include "src/core/lib/gprpp/host_port.h" + +#include + +#include +#include +#include + +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/string_view.h" + +namespace grpc_core { +int JoinHostPort(UniquePtr* 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) { + /* ] */ + port->clear(); + } else if (name[rbracket + 1] == ':') { + /* ]: */ + *port = name.substr(rbracket + 2, name.size() - rbracket - 2); + } else { + /* ] */ + 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* host, + UniquePtr* 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 diff --git a/src/core/lib/gpr/host_port.h b/src/core/lib/gprpp/host_port.h similarity index 51% rename from src/core/lib/gpr/host_port.h rename to src/core/lib/gprpp/host_port.h index 0bf0960f824..9a0b492b98f 100644 --- a/src/core/lib/gpr/host_port.h +++ b/src/core/lib/gprpp/host_port.h @@ -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 +#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* 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. -#endif /* GRPC_CORE_LIB_GPR_HOST_PORT_H */ + 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* host, + UniquePtr* port); + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_GPRPP_HOST_PORT_H */ diff --git a/src/core/lib/gprpp/string_view.h b/src/core/lib/gprpp/string_view.h new file mode 100644 index 00000000000..05a81066d48 --- /dev/null +++ b/src/core/lib/gprpp/string_view.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 + +#include +#include +#include + +#include +#include +#include +#include + +#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::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(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(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 dup() const { + char* str = static_cast(gpr_malloc(size_ + 1)); + if (size_ > 0) memcpy(str, ptr_, size_); + str[size_] = '\0'; + return grpc_core::UniquePtr(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 */ diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index cae707061e0..0af33faa119 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.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 diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 28932081538..99197cbbfa9 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -31,6 +31,7 @@ #include #include #include +#include #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(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* { diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index bbb48a58cd6..5014444dcfd 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -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; diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 762cbe41bcf..8196019f098 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/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; diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index ebec9dc704a..eb44c9a2c90 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -447,13 +447,17 @@ grpc_error* grpc_error_set_int(grpc_error* src, grpc_error_ints which, typedef struct { grpc_status_code code; const char* msg; + size_t len; } special_error_status_map; -static const special_error_status_map error_status_map[] = { - {GRPC_STATUS_OK, ""}, // GRPC_ERROR_NONE - {GRPC_STATUS_INVALID_ARGUMENT, ""}, // GRPC_ERROR_RESERVED_1 - {GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"}, // GRPC_ERROR_OOM - {GRPC_STATUS_INVALID_ARGUMENT, ""}, // GRPC_ERROR_RESERVED_2 - {GRPC_STATUS_CANCELLED, "Cancelled"}, // GRPC_ERROR_CANCELLED + +const special_error_status_map error_status_map[] = { + {GRPC_STATUS_OK, "", 0}, // GRPC_ERROR_NONE + {GRPC_STATUS_INVALID_ARGUMENT, "", 0}, // GRPC_ERROR_RESERVED_1 + {GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory", + strlen("Out of memory")}, // GRPC_ERROR_OOM + {GRPC_STATUS_INVALID_ARGUMENT, "", 0}, // GRPC_ERROR_RESERVED_2 + {GRPC_STATUS_CANCELLED, "Cancelled", + strlen("Cancelled")}, // GRPC_ERROR_CANCELLED }; bool grpc_error_get_int(grpc_error* err, grpc_error_ints which, intptr_t* p) { @@ -483,8 +487,12 @@ bool grpc_error_get_str(grpc_error* err, grpc_error_strs which, grpc_slice* str) { if (grpc_error_is_special(err)) { if (which != GRPC_ERROR_STR_GRPC_MESSAGE) return false; - *str = grpc_slice_from_static_string( - error_status_map[reinterpret_cast(err)].msg); + const special_error_status_map& msg = + error_status_map[reinterpret_cast(err)]; + str->refcount = &grpc_core::kNoopRefcount; + str->data.refcounted.bytes = + reinterpret_cast(const_cast(msg.msg)); + str->data.refcounted.length = msg.len; return true; } uint8_t slot = err->strs[which]; diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 92f81c2efb8..d78ac2dac2d 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -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) { diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index 8adc0902bd1..721542544cd 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -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); diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc new file mode 100644 index 00000000000..ea2a6868d2f --- /dev/null +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -0,0 +1,114 @@ +/* + * + * 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. + * + */ + +#include + +#include "src/core/lib/iomgr/executor/mpmcqueue.h" + +namespace grpc_core { + +DebugOnlyTraceFlag grpc_thread_pool_trace(false, "thread_pool"); + +inline void* InfLenFIFOQueue::PopFront() { + // Caller should already check queue is not empty and has already held the + // mutex. This function will only do the job of removal. + void* result = queue_head_->content; + Node* head_to_remove = queue_head_; + queue_head_ = queue_head_->next; + + count_.Store(count_.Load(MemoryOrder::RELAXED) - 1, MemoryOrder::RELAXED); + + if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { + gpr_timespec wait_time = + gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), head_to_remove->insert_time); + + // Updates Stats info + stats_.num_completed++; + stats_.total_queue_time = gpr_time_add(stats_.total_queue_time, wait_time); + stats_.max_queue_time = gpr_time_max( + gpr_convert_clock_type(stats_.max_queue_time, GPR_TIMESPAN), wait_time); + + if (count_.Load(MemoryOrder::RELAXED) == 0) { + stats_.busy_queue_time = + gpr_time_add(stats_.busy_queue_time, + gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), busy_time)); + } + + gpr_log(GPR_INFO, + "[InfLenFIFOQueue PopFront] num_completed: %" PRIu64 + " total_queue_time: %f max_queue_time: %f busy_queue_time: %f", + stats_.num_completed, + gpr_timespec_to_micros(stats_.total_queue_time), + gpr_timespec_to_micros(stats_.max_queue_time), + gpr_timespec_to_micros(stats_.busy_queue_time)); + } + + Delete(head_to_remove); + // Singal waiting thread + if (count_.Load(MemoryOrder::RELAXED) > 0 && num_waiters_ > 0) { + wait_nonempty_.Signal(); + } + + return result; +} + +InfLenFIFOQueue::~InfLenFIFOQueue() { + GPR_ASSERT(count_.Load(MemoryOrder::RELAXED) == 0); + GPR_ASSERT(num_waiters_ == 0); +} + +void InfLenFIFOQueue::Put(void* elem) { + MutexLock l(&mu_); + + Node* new_node = New(elem); + if (count_.Load(MemoryOrder::RELAXED) == 0) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { + busy_time = gpr_now(GPR_CLOCK_MONOTONIC); + } + queue_head_ = queue_tail_ = new_node; + } else { + queue_tail_->next = new_node; + queue_tail_ = queue_tail_->next; + } + count_.Store(count_.Load(MemoryOrder::RELAXED) + 1, MemoryOrder::RELAXED); + // Updates Stats info + if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { + stats_.num_started++; + gpr_log(GPR_INFO, "[InfLenFIFOQueue Put] num_started: %" PRIu64, + stats_.num_started); + } + + if (num_waiters_ > 0) { + wait_nonempty_.Signal(); + } +} + +void* InfLenFIFOQueue::Get() { + MutexLock l(&mu_); + if (count_.Load(MemoryOrder::RELAXED) == 0) { + num_waiters_++; + do { + wait_nonempty_.Wait(&mu_); + } while (count_.Load(MemoryOrder::RELAXED) == 0); + num_waiters_--; + } + GPR_DEBUG_ASSERT(count_.Load(MemoryOrder::RELAXED) > 0); + return PopFront(); +} + +} // namespace grpc_core diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h new file mode 100644 index 00000000000..8ece95699c7 --- /dev/null +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -0,0 +1,128 @@ +/* + * + * 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_IOMGR_EXECUTOR_MPMCQUEUE_H +#define GRPC_CORE_LIB_IOMGR_EXECUTOR_MPMCQUEUE_H + +#include + +#include "src/core/lib/debug/stats.h" +#include "src/core/lib/gprpp/abstract.h" +#include "src/core/lib/gprpp/atomic.h" +#include "src/core/lib/gprpp/sync.h" + +namespace grpc_core { + +extern DebugOnlyTraceFlag grpc_thread_pool_trace; + +// Abstract base class of a Multiple-Producer-Multiple-Consumer(MPMC) queue +// interface +class MPMCQueueInterface { + public: + virtual ~MPMCQueueInterface() {} + + // Puts elem into queue immediately at the end of queue. + // This might cause to block on full queue depending on implementation. + virtual void Put(void* elem) GRPC_ABSTRACT; + + // Removes the oldest element from the queue and return it. + // This might cause to block on empty queue depending on implementation. + virtual void* Get() GRPC_ABSTRACT; + + // Returns number of elements in the queue currently + virtual int count() const GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS +}; + +class InfLenFIFOQueue : public MPMCQueueInterface { + public: + // Creates a new MPMC Queue. The queue created will have infinite length. + InfLenFIFOQueue() {} + + // Releases all resources held by the queue. The queue must be empty, and no + // one waits on conditional variables. + ~InfLenFIFOQueue(); + + // Puts elem into queue immediately at the end of queue. Since the queue has + // infinite length, this routine will never block and should never fail. + void Put(void* elem); + + // Removes the oldest element from the queue and returns it. + // This routine will cause the thread to block if queue is currently empty. + void* Get(); + + // Returns number of elements in queue currently. + // There might be concurrently add/remove on queue, so count might change + // quickly. + int count() const { return count_.Load(MemoryOrder::RELAXED); } + + private: + // For Internal Use Only. + // Removes the oldest element from the queue and returns it. This routine + // will NOT check whether queue is empty, and it will NOT acquire mutex. + // Caller should do the check and acquire mutex before callling. + void* PopFront(); + + struct Node { + Node* next; // Linking + void* content; // Points to actual element + gpr_timespec insert_time; // Time for stats + + Node(void* c) : content(c) { + next = nullptr; + insert_time = gpr_now(GPR_CLOCK_MONOTONIC); + } + }; + + // Stats of queue. This will only be collect when debug trace mode is on. + // All printed stats info will have time measurement in microsecond. + struct Stats { + uint64_t num_started; // Number of elements have been added to queue + uint64_t num_completed; // Number of elements have been removed from + // the queue + gpr_timespec total_queue_time; // Total waiting time that all the + // removed elements have spent in queue + gpr_timespec max_queue_time; // Max waiting time among all removed + // elements + gpr_timespec busy_queue_time; // Accumulated amount of time that queue + // was not empty + + Stats() { + num_started = 0; + num_completed = 0; + total_queue_time = gpr_time_0(GPR_TIMESPAN); + max_queue_time = gpr_time_0(GPR_TIMESPAN); + busy_queue_time = gpr_time_0(GPR_TIMESPAN); + } + }; + + Mutex mu_; // Protecting lock + CondVar wait_nonempty_; // Wait on empty queue on get + int num_waiters_ = 0; // Number of waiters + + Node* queue_head_ = nullptr; // Head of the queue, remove position + Node* queue_tail_ = nullptr; // End of queue, insert position + Atomic count_{0}; // Number of elements in queue + Stats stats_; // Stats info + gpr_timespec busy_time; // Start time of busy queue +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_MPMCQUEUE_H */ diff --git a/src/core/lib/iomgr/iocp_windows.cc b/src/core/lib/iomgr/iocp_windows.cc index ad325fe2156..29a05ee3099 100644 --- a/src/core/lib/iomgr/iocp_windows.cc +++ b/src/core/lib/iomgr/iocp_windows.cc @@ -90,12 +90,12 @@ grpc_iocp_work_status grpc_iocp_work(grpc_millis deadline) { abort(); } if (socket->shutdown_called) { - info->bytes_transfered = 0; + info->bytes_transferred = 0; info->wsa_error = WSA_OPERATION_ABORTED; } else { success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes, FALSE, &flags); - info->bytes_transfered = bytes; + info->bytes_transferred = bytes; info->wsa_error = success ? 0 : WSAGetLastError(); } GPR_ASSERT(overlapped == &info->overlapped); diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc index cf4d05318ea..72b2ae5eb00 100644 --- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -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); @@ -90,4 +100,8 @@ void grpc_set_default_iomgr_platform() { grpc_set_iomgr_platform_vtable(&vtable); } +bool grpc_iomgr_run_in_background() { + return grpc_event_engine_run_in_background(); +} + #endif /* GRPC_CFSTREAM_IOMGR */ diff --git a/src/core/lib/iomgr/iomgr_uv.cc b/src/core/lib/iomgr/iomgr_uv.cc index 4a984446dba..a617239678e 100644 --- a/src/core/lib/iomgr/iomgr_uv.cc +++ b/src/core/lib/iomgr/iomgr_uv.cc @@ -37,4 +37,7 @@ void grpc_set_default_iomgr_platform() { grpc_custom_iomgr_init(&grpc_uv_socket_vtable, &uv_resolver_vtable, &uv_timer_vtable, &uv_pollset_vtable); } + +bool grpc_iomgr_run_in_background() { return false; } + #endif diff --git a/src/core/lib/iomgr/resolve_address_custom.cc b/src/core/lib/iomgr/resolve_address_custom.cc index 9cf7817f66e..64c33cdc0d4 100644 --- a/src/core/lib/iomgr/resolve_address_custom.cc +++ b/src/core/lib/iomgr/resolve_address_custom.cc @@ -24,9 +24,9 @@ #include #include -#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* host, + grpc_core::UniquePtr* 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 host; + grpc_core::UniquePtr 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 host; + grpc_core::UniquePtr 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); diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc index e6dd8f1ceab..e02dc19bb27 100644 --- a/src/core/lib/iomgr/resolve_address_posix.cc +++ b/src/core/lib/iomgr/resolve_address_posix.cc @@ -33,9 +33,9 @@ #include #include -#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 host; + grpc_core::UniquePtr 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); } diff --git a/src/core/lib/iomgr/resolve_address_windows.cc b/src/core/lib/iomgr/resolve_address_windows.cc index 64351c38a8f..a06d5cefbcb 100644 --- a/src/core/lib/iomgr/resolve_address_windows.cc +++ b/src/core/lib/iomgr/resolve_address_windows.cc @@ -35,8 +35,8 @@ #include #include -#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 host; + grpc_core::UniquePtr 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); } diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc index 0839bdfef2d..baadf1da99e 100644 --- a/src/core/lib/iomgr/sockaddr_utils.cc +++ b/src/core/lib/iomgr/sockaddr_utils.cc @@ -28,8 +28,8 @@ #include #include -#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 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); } diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index 2101651b33f..47d9f51b095 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -46,7 +46,6 @@ #include #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" diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 5fed6909e6f..78f79453c6c 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -59,7 +59,7 @@ typedef struct grpc_winsocket_callback_info { to hold a mutex for a long amount of time. */ int has_pending_iocp; /* The results of the overlapped operation. */ - DWORD bytes_transfered; + DWORD bytes_transferred; int wsa_error; } grpc_winsocket_callback_info; diff --git a/src/core/lib/iomgr/tcp_client_cfstream.cc b/src/core/lib/iomgr/tcp_client_cfstream.cc index 4b21322d746..fcad5edd222 100644 --- a/src/core/lib/iomgr/tcp_client_cfstream.cc +++ b/src/core/lib/iomgr/tcp_client_cfstream.cc @@ -34,7 +34,7 @@ #include #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 host_string; + grpc_core::UniquePtr 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); } diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 889272f6299..819c5284256 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -435,12 +435,17 @@ static void tcp_do_read(grpc_tcp* tcp) { GPR_TIMER_SCOPE("tcp_do_read", 0); struct msghdr msg; struct iovec iov[MAX_READ_IOVEC]; - char cmsgbuf[24 /*CMSG_SPACE(sizeof(int))*/]; ssize_t read_bytes; size_t total_read_bytes = 0; - size_t iov_len = std::min(MAX_READ_IOVEC, tcp->incoming_buffer->count); +#ifdef GRPC_LINUX_ERRQUEUE + constexpr size_t cmsg_alloc_space = + CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + CMSG_SPACE(sizeof(int)); +#else + constexpr size_t cmsg_alloc_space = 24 /* CMSG_SPACE(sizeof(int)) */; +#endif /* GRPC_LINUX_ERRQUEUE */ + char cmsgbuf[cmsg_alloc_space]; for (size_t i = 0; i < iov_len; i++) { iov[i].iov_base = GRPC_SLICE_START_PTR(tcp->incoming_buffer->slices[i]); iov[i].iov_len = GRPC_SLICE_LENGTH(tcp->incoming_buffer->slices[i]); @@ -524,6 +529,7 @@ static void tcp_do_read(grpc_tcp* tcp) { if (cmsg->cmsg_level == SOL_TCP && cmsg->cmsg_type == TCP_CM_INQ && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { tcp->inq = *reinterpret_cast(CMSG_DATA(cmsg)); + break; } } } diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index ae6b2b68e62..32d0bb36ea7 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -196,17 +196,17 @@ static void on_read(void* tcpp, grpc_error* error) { gpr_free(utf8_message); grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); } else { - if (info->bytes_transfered != 0 && !tcp->shutting_down) { - GPR_ASSERT((size_t)info->bytes_transfered <= tcp->read_slices->length); - if (static_cast(info->bytes_transfered) != + if (info->bytes_transferred != 0 && !tcp->shutting_down) { + GPR_ASSERT((size_t)info->bytes_transferred <= tcp->read_slices->length); + if (static_cast(info->bytes_transferred) != tcp->read_slices->length) { grpc_slice_buffer_trim_end( tcp->read_slices, tcp->read_slices->length - - static_cast(info->bytes_transfered), + static_cast(info->bytes_transferred), &tcp->last_read_buffer); } - GPR_ASSERT((size_t)info->bytes_transfered == tcp->read_slices->length); + GPR_ASSERT((size_t)info->bytes_transferred == tcp->read_slices->length); if (grpc_tcp_trace.enabled()) { size_t i; @@ -288,7 +288,7 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, /* Did we get data immediately ? Yay. */ if (info->wsa_error != WSAEWOULDBLOCK) { - info->bytes_transfered = bytes_read; + info->bytes_transferred = bytes_read; GRPC_CLOSURE_SCHED(&tcp->on_read, GRPC_ERROR_NONE); return; } @@ -333,7 +333,7 @@ static void on_write(void* tcpp, grpc_error* error) { if (info->wsa_error != 0) { error = GRPC_WSA_ERROR(info->wsa_error, "WSASend"); } else { - GPR_ASSERT(info->bytes_transfered == tcp->write_slices->length); + GPR_ASSERT(info->bytes_transferred == tcp->write_slices->length); } } diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h index a9d581280d1..907cf2b02f6 100644 --- a/src/core/lib/security/credentials/credentials.h +++ b/src/core/lib/security/credentials/credentials.h @@ -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&" \ diff --git a/src/core/lib/security/credentials/jwt/json_token.cc b/src/core/lib/security/credentials/jwt/json_token.cc index 113e2b83754..12b7c5368da 100644 --- a/src/core/lib/security/credentials/jwt/json_token.cc +++ b/src/core/lib/security/credentials/jwt/json_token.cc @@ -18,6 +18,7 @@ #include +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/credentials/jwt/json_token.h" #include @@ -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; } diff --git a/src/core/lib/security/credentials/jwt/json_token.h b/src/core/lib/security/credentials/jwt/json_token.h index 3ed990140d3..20390f3096a 100644 --- a/src/core/lib/security/credentials/jwt/json_token.h +++ b/src/core/lib/security/credentials/jwt/json_token.h @@ -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. --- */ diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index b001868b3d3..06fa8bbdb4b 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -22,14 +22,23 @@ #include -#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 +#include +#include #include #include #include +#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("Metadata-Flavor"), + const_cast("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("Content-Type"), + const_cast("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("Content-Type"), + const_cast("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(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(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 resource_; + grpc_core::UniquePtr audience_; + grpc_core::UniquePtr scope_; + grpc_core::UniquePtr requested_token_type_; + grpc_core::UniquePtr subject_token_path_; + grpc_core::UniquePtr subject_token_type_; + grpc_core::UniquePtr actor_token_path_; + grpc_core::UniquePtr 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 error_list; + UniquePtr 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( + sts_url, options) + .release(); +} + // // Oauth2 Access Token credentials. // diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h index 510a78b484a..c9b2d1decac 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h @@ -21,8 +21,15 @@ #include +#include #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 */ diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc index 38b1f856d52..79908601130 100644 --- a/src/core/lib/security/security_connector/alts/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc @@ -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"); } diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.cc b/src/core/lib/security/security_connector/fake/fake_security_connector.cc index c55fd34d0e2..940c2ac5ee5 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.cc +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc @@ -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; } diff --git a/src/core/lib/security/security_connector/local/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc index c1a101d4ab8..5b777009d34 100644 --- a/src/core/lib/security/security_connector/local/local_security_connector.cc +++ b/src/core/lib/security/security_connector/local/local_security_connector.cc @@ -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"); } diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 47c0ad5aa3d..2c7c982e719 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -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" diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index f71ee54402d..e5ced44638b 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.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; diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index f920dc6046d..97c04cafce4 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -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* 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(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 target_name_; + grpc_core::UniquePtr overridden_target_name_; const verify_peer_options* verify_options_; }; diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index cb0d5437988..ebb4a3f9ee8 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -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_ssl_peer_to_auth_context( diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index 1765a344c2a..bf8c1de3aae 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -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_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 { diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc index ebf9c905079..5853de4fc13 100644 --- a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc @@ -28,7 +28,7 @@ #include #include -#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* 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( diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.h b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h index 56972153e07..5ea00ee85b6 100644 --- a/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h @@ -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 target_name_; + grpc_core::UniquePtr overridden_target_name_; tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr; grpc_tls_server_authorization_check_arg* check_arg_; }; diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 1062fc2f4fa..33343d276eb 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -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 */ } } diff --git a/src/core/lib/security/util/json_util.cc b/src/core/lib/security/util/json_util.cc index fe9f5fe3d35..8a1db636139 100644 --- a/src/core/lib/security/util/json_util.cc +++ b/src/core/lib/security/util/json_util.cc @@ -18,6 +18,7 @@ #include +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/util/json_util.h" #include @@ -26,17 +27,27 @@ #include 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; diff --git a/src/core/lib/security/util/json_util.h b/src/core/lib/security/util/json_util.h index 89deffcc081..44d9eccd545 100644 --- a/src/core/lib/security/util/json_util.h +++ b/src/core/lib/security/util/json_util.h @@ -23,6 +23,7 @@ #include +#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. diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index eebf66bb882..57862518feb 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -66,32 +66,13 @@ void grpc_slice_unref(grpc_slice slice) { } } +namespace grpc_core { + /* grpc_slice_from_static_string support structure - a refcount that does nothing */ -static grpc_slice_refcount NoopRefcount = - grpc_slice_refcount(grpc_slice_refcount::Type::NOP); - -size_t grpc_slice_memory_usage(grpc_slice s) { - if (s.refcount == nullptr || s.refcount == &NoopRefcount) { - return 0; - } else { - return s.data.refcounted.length; - } -} - -grpc_slice grpc_slice_from_static_buffer(const void* s, size_t len) { - grpc_slice slice; - slice.refcount = &NoopRefcount; - slice.data.refcounted.bytes = (uint8_t*)s; - slice.data.refcounted.length = len; - return slice; -} - -grpc_slice grpc_slice_from_static_string(const char* s) { - return grpc_slice_from_static_buffer(s, strlen(s)); -} - -namespace grpc_core { +grpc_slice_refcount kNoopRefcount(grpc_slice_refcount::Type::NOP); +static_assert(std::is_trivially_destructible::value, + "kNoopRefcount must be trivially destructible."); /* grpc_slice_new support structures - we create a refcount object extended with the user provided data pointer & destroy function */ @@ -122,6 +103,22 @@ class NewSliceRefcount { } // namespace grpc_core +size_t grpc_slice_memory_usage(grpc_slice s) { + if (s.refcount == nullptr || s.refcount == &grpc_core::kNoopRefcount) { + return 0; + } else { + return s.data.refcounted.length; + } +} + +grpc_slice grpc_slice_from_static_buffer(const void* s, size_t len) { + return grpc_slice_from_static_buffer_internal(s, len); +} + +grpc_slice grpc_slice_from_static_string(const char* s) { + return grpc_slice_from_static_buffer_internal(s, strlen(s)); +} + grpc_slice grpc_slice_new_with_user_data(void* p, size_t len, void (*destroy)(void*), void* user_data) { @@ -375,10 +372,10 @@ grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice* source, size_t split, switch (ref_whom) { case GRPC_SLICE_REF_TAIL: tail.refcount = source->refcount->sub_refcount(); - source->refcount = &NoopRefcount; + source->refcount = &grpc_core::kNoopRefcount; break; case GRPC_SLICE_REF_HEAD: - tail.refcount = &NoopRefcount; + tail.refcount = &grpc_core::kNoopRefcount; source->refcount = source->refcount->sub_refcount(); break; case GRPC_SLICE_REF_BOTH: diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index c6943fe6563..54badeb9ab9 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -171,6 +171,8 @@ struct grpc_slice_refcount { namespace grpc_core { +extern grpc_slice_refcount kNoopRefcount; + struct InternedSliceRefcount { static void Destroy(void* arg) { auto* rc = static_cast(arg); @@ -312,4 +314,17 @@ grpc_slice grpc_slice_from_moved_string(grpc_core::UniquePtr p); // 0. All other slices will return the size of the allocated chars. size_t grpc_slice_memory_usage(grpc_slice s); +inline grpc_slice grpc_slice_from_static_buffer_internal(const void* s, + size_t len) { + grpc_slice slice; + slice.refcount = &grpc_core::kNoopRefcount; + slice.data.refcounted.bytes = (uint8_t*)s; + slice.data.refcounted.length = len; + return slice; +} + +inline grpc_slice grpc_slice_from_static_string_internal(const char* s) { + return grpc_slice_from_static_buffer_internal(s, strlen(s)); +} + #endif /* GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H */ diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc index eb4e8c3a282..5be98c9f04f 100644 --- a/src/core/lib/transport/error_utils.cc +++ b/src/core/lib/transport/error_utils.cc @@ -22,6 +22,7 @@ #include #include "src/core/lib/iomgr/error_internal.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/status_conversion.h" static grpc_error* recursively_find_error_with_field(grpc_error* error, @@ -52,7 +53,15 @@ void grpc_error_get_status(grpc_error* error, grpc_millis deadline, if (GPR_LIKELY(error == GRPC_ERROR_NONE)) { if (code != nullptr) *code = GRPC_STATUS_OK; if (slice != nullptr) { - grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, slice); + // Normally, we call grpc_error_get_str( + // error, GRPC_ERROR_STR_GRPC_MESSAGE, slice). + // We can fastpath since we know that: + // 1) Error is null + // 2) which == GRPC_ERROR_STR_GRPC_MESSAGE + // 3) The resulting slice is statically known. + // 4) Said resulting slice is of length 0 (""). + // This means 3 movs, instead of 10s of instructions and a strlen. + *slice = grpc_slice_from_static_string_internal(""); } if (http_error != nullptr) { *http_error = GRPC_HTTP2_NO_ERROR; diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 3cef031031d..4621433bf01 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -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 { @@ -348,10 +350,11 @@ inline void grpc_mdelem_unref(grpc_mdelem gmd) { free an interned md at any time: it's unsafe from this point on to access it so we read the hash now. */ uint32_t hash = md->hash(); - if (GPR_UNLIKELY(md->Unref())) { #ifndef NDEBUG + if (GPR_UNLIKELY(md->Unref(file, line))) { grpc_mdelem_on_final_unref(storage, md, hash, file, line); #else + if (GPR_UNLIKELY(md->Unref())) { grpc_mdelem_on_final_unref(storage, md, hash); #endif } diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index bbf1736b595..5887e3515fb 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -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}; diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index 1b7e58d3ce0..0d28303e7dd 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -30,7 +30,6 @@ #include #include -#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" diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 25ae2cee285..d3c8982c847 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -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 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; } } diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index 769949e4aad..0203141e56e 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -21,6 +21,7 @@ #include +#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. --- diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h index 3b201afb5a7..4abd4c3dda9 100644 --- a/src/cpp/client/create_channel_internal.h +++ b/src/cpp/client/create_channel_internal.h @@ -21,6 +21,7 @@ #include +#include #include #include diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index dcbb56dccda..0556fa0e50f 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -15,13 +15,11 @@ * limitations under the License. * */ - #include #include #include #include -#include #include #include #include "src/cpp/client/create_channel_internal.h" @@ -31,16 +29,16 @@ namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: - std::shared_ptr<::grpc::Channel> CreateChannelImpl( - const grpc::string& target, const grpc::ChannelArguments& args) override { + std::shared_ptr CreateChannelImpl( + const grpc::string& target, const ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, std::vector>()); } - std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( - const grpc::string& target, const grpc::ChannelArguments& args, + std::shared_ptr CreateChannelWithInterceptors( + const grpc::string& target, const ChannelArguments& args, std::vector> interceptor_creators) override { diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 197112d4bb7..d73b3e035c8 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -36,17 +36,17 @@ SecureChannelCredentials::SecureChannelCredentials( g_gli_initializer.summon(); } -std::shared_ptr SecureChannelCredentials::CreateChannelImpl( - const grpc::string& target, const grpc::ChannelArguments& args) { +std::shared_ptr SecureChannelCredentials::CreateChannelImpl( + const grpc::string& target, const ChannelArguments& args) { return CreateChannelWithInterceptors( target, args, std::vector>()); } -std::shared_ptr +std::shared_ptr SecureChannelCredentials::CreateChannelWithInterceptors( - const grpc::string& target, const grpc::ChannelArguments& args, + const grpc::string& target, const ChannelArguments& args, std::vector< std::unique_ptr> interceptor_creators) { @@ -209,7 +209,7 @@ std::shared_ptr CompositeCallCredentials( return nullptr; } -std::shared_ptr MetadataCredentialsFromPlugin( +std::shared_ptr MetadataCredentialsFromPlugin( std::unique_ptr plugin) { grpc::GrpcLibraryCodegen init; // To call grpc_init(). const char* type = plugin->GetType(); diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index c4eef6c746d..dd379ca657d 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -39,14 +39,14 @@ class SecureChannelCredentials final : public ChannelCredentials { } grpc_channel_credentials* GetRawCreds() { return c_creds_; } - std::shared_ptr<::grpc::Channel> CreateChannelImpl( - const grpc::string& target, const grpc::ChannelArguments& args) override; + std::shared_ptr CreateChannelImpl( + const grpc::string& target, const ChannelArguments& args) override; SecureChannelCredentials* AsSecureCredentials() override { return this; } private: - std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( - const grpc::string& target, const grpc::ChannelArguments& args, + std::shared_ptr CreateChannelWithInterceptors( + const grpc::string& target, const ChannelArguments& args, std::vector> interceptor_creators) override; diff --git a/src/csharp/Grpc.Core.Api/AuthProperty.cs b/src/csharp/Grpc.Core.Api/AuthProperty.cs index 0907edba84d..c208cee0267 100644 --- a/src/csharp/Grpc.Core.Api/AuthProperty.cs +++ b/src/csharp/Grpc.Core.Api/AuthProperty.cs @@ -17,8 +17,6 @@ #endregion using System; -using System.Collections.Generic; -using System.Linq; using System.Text; using Grpc.Core.Utils; @@ -33,13 +31,12 @@ namespace Grpc.Core static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8; string name; byte[] valueBytes; - Lazy value; + string lazyValue; private AuthProperty(string name, byte[] valueBytes) { this.name = GrpcPreconditions.CheckNotNull(name); this.valueBytes = GrpcPreconditions.CheckNotNull(valueBytes); - this.value = new Lazy(() => EncodingUTF8.GetString(this.valueBytes)); } /// @@ -60,7 +57,7 @@ namespace Grpc.Core { get { - return value.Value; + return lazyValue ?? (lazyValue = EncodingUTF8.GetString(this.valueBytes)); } } diff --git a/src/csharp/Grpc.Core/Common.csproj.include b/src/csharp/Grpc.Core/Common.csproj.include index 3b1bec2d55f..19e7240f443 100755 --- a/src/csharp/Grpc.Core/Common.csproj.include +++ b/src/csharp/Grpc.Core/Common.csproj.include @@ -19,10 +19,8 @@ true - - - /usr/lib/mono/4.5-api - /usr/local/lib/mono/4.5-api - /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api - + + + + diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs index b33cb631e26..77e4ccd356d 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -38,7 +38,7 @@ namespace Grpc.Core private readonly Metadata responseTrailers; private Status status; private readonly IServerResponseStream serverResponseStream; - private readonly Lazy authContext; + private AuthContext lazyAuthContext; /// /// Creates a new instance of ServerCallContext. @@ -57,8 +57,6 @@ namespace Grpc.Core this.responseTrailers = new Metadata(); this.status = Status.DefaultSuccess; this.serverResponseStream = serverResponseStream; - // TODO(jtattermusch): avoid unnecessary allocation of factory function and the lazy object - this.authContext = new Lazy(GetAuthContextEager); } protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) @@ -97,7 +95,7 @@ namespace Grpc.Core set => serverResponseStream.WriteOptions = value; } - protected override AuthContext AuthContextCore => authContext.Value; + protected override AuthContext AuthContextCore => lazyAuthContext ?? (lazyAuthContext = GetAuthContextEager()); private AuthContext GetAuthContextEager() { diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs index 26d182ae53b..8705f52666f 100644 --- a/src/csharp/Grpc.Core/Server.cs +++ b/src/csharp/Grpc.Core/Server.cs @@ -334,7 +334,7 @@ namespace Grpc.Core /// /// Selects corresponding handler for given call and handles the call. /// - private async Task HandleCallAsync(ServerRpcNew newRpc, CompletionQueueSafeHandle cq, Action continuation) + private async Task HandleCallAsync(ServerRpcNew newRpc, CompletionQueueSafeHandle cq, Action continuation) { try { @@ -351,7 +351,7 @@ namespace Grpc.Core } finally { - continuation(); + continuation(this, cq); } } @@ -374,7 +374,7 @@ namespace Grpc.Core // Don't await, the continuations will run on gRPC thread pool once triggered // by cq.Next(). #pragma warning disable 4014 - HandleCallAsync(newRpc, cq, () => AllowOneRpc(cq)); + HandleCallAsync(newRpc, cq, (server, state) => server.AllowOneRpc(state)); #pragma warning restore 4014 } } diff --git a/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs b/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs new file mode 100644 index 00000000000..c6bdf471b8a --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs @@ -0,0 +1,66 @@ +#region Copyright notice and license + +// 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. + +#endregion + +using System; +using System.Threading; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using Grpc.Core; + +namespace Grpc.Microbenchmarks +{ + + // common base-type for tests that need to run with some level of concurrency; + // note there's nothing *special* about this type - it is just to save some + // boilerplate + + [ClrJob, CoreJob] // test .NET Core and .NET Framework + [MemoryDiagnoser] // allocations + public abstract class CommonThreadedBase + { + protected virtual bool NeedsEnvironment => true; + + [Params(1, 2, 4, 8, 12)] + public int ThreadCount { get; set; } + + protected GrpcEnvironment Environment { get; private set; } + + [GlobalSetup] + public virtual void Setup() + { + ThreadPool.GetMinThreads(out var workers, out var iocp); + if (workers <= ThreadCount) ThreadPool.SetMinThreads(ThreadCount + 1, iocp); + if (NeedsEnvironment) Environment = GrpcEnvironment.AddRef(); + } + + [GlobalCleanup] + public virtual void Cleanup() + { + if (Environment != null) + { + Environment = null; + GrpcEnvironment.ReleaseAsync().Wait(); + } + } + + protected void RunConcurrent(Action operation) + { + Parallel.For(0, ThreadCount, _ => operation()); + } + } +} diff --git a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs index bb57a6968fa..e4cd7eeb1f6 100644 --- a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs @@ -1,4 +1,4 @@ -#region Copyright notice and license +#region Copyright notice and license // Copyright 2015 gRPC authors. // @@ -17,62 +17,38 @@ #endregion using System; -using System.Runtime.InteropServices; -using System.Threading; -using Grpc.Core; +using BenchmarkDotNet.Attributes; using Grpc.Core.Internal; -using System.Collections.Generic; -using System.Diagnostics; namespace Grpc.Microbenchmarks { - public class CompletionRegistryBenchmark + public class CompletionRegistryBenchmark : CommonThreadedBase { - GrpcEnvironment environment; + [Params(false, true)] + public bool UseSharedRegistry { get; set; } - public void Init() + const int Iterations = 1000000; // High number to make the overhead of RunConcurrent negligible. + [Benchmark(OperationsPerInvoke = Iterations)] + public void RegisterExtract() { - environment = GrpcEnvironment.AddRef(); + RunConcurrent(() => { + CompletionRegistry sharedRegistry = UseSharedRegistry ? new CompletionRegistry(Environment, () => BatchContextSafeHandle.Create(), () => RequestCallContextSafeHandle.Create()) : null; + RunBody(sharedRegistry); + }); } - public void Cleanup() + private void RunBody(CompletionRegistry optionalSharedRegistry) { - GrpcEnvironment.ReleaseAsync().Wait(); - } - - public void Run(int threadCount, int iterations, bool useSharedRegistry) - { - Console.WriteLine(string.Format("CompletionRegistryBenchmark: threads={0}, iterations={1}, useSharedRegistry={2}", threadCount, iterations, useSharedRegistry)); - CompletionRegistry sharedRegistry = useSharedRegistry ? new CompletionRegistry(environment, () => BatchContextSafeHandle.Create(), () => RequestCallContextSafeHandle.Create()) : null; - var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, sharedRegistry)); - threadedBenchmark.Run(); - // TODO: parametrize by number of pending completions - } - - private void ThreadBody(int iterations, CompletionRegistry optionalSharedRegistry) - { - var completionRegistry = optionalSharedRegistry ?? new CompletionRegistry(environment, () => throw new NotImplementedException(), () => throw new NotImplementedException()); + var completionRegistry = optionalSharedRegistry ?? new CompletionRegistry(Environment, () => throw new NotImplementedException(), () => throw new NotImplementedException()); var ctx = BatchContextSafeHandle.Create(); - - var stopwatch = Stopwatch.StartNew(); - for (int i = 0; i < iterations; i++) + + for (int i = 0; i < Iterations; i++) { completionRegistry.Register(ctx.Handle, ctx); var callback = completionRegistry.Extract(ctx.Handle); // NOTE: we are not calling the callback to avoid disposing ctx. } - stopwatch.Stop(); - Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds); - ctx.Recycle(); } - - private class NopCompletionCallback : IOpCompletionCallback - { - public void OnComplete(bool success) - { - - } - } } } diff --git a/src/csharp/Grpc.Microbenchmarks/GCStats.cs b/src/csharp/Grpc.Microbenchmarks/GCStats.cs deleted file mode 100644 index ca7051ec4e5..00000000000 --- a/src/csharp/Grpc.Microbenchmarks/GCStats.cs +++ /dev/null @@ -1,69 +0,0 @@ -#region Copyright notice and license - -// 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. - -#endregion - -using System; -using Grpc.Core; -using Grpc.Core.Internal; - -namespace Grpc.Microbenchmarks -{ - internal class GCStats - { - readonly object myLock = new object(); - GCStatsSnapshot lastSnapshot; - - public GCStats() - { - lastSnapshot = new GCStatsSnapshot(GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2)); - } - - public GCStatsSnapshot GetSnapshot(bool reset = false) - { - lock (myLock) - { - var newSnapshot = new GCStatsSnapshot(GC.CollectionCount(0) - lastSnapshot.Gen0, - GC.CollectionCount(1) - lastSnapshot.Gen1, - GC.CollectionCount(2) - lastSnapshot.Gen2); - if (reset) - { - lastSnapshot = newSnapshot; - } - return newSnapshot; - } - } - } - - public class GCStatsSnapshot - { - public GCStatsSnapshot(int gen0, int gen1, int gen2) - { - this.Gen0 = gen0; - this.Gen1 = gen1; - this.Gen2 = gen2; - } - - public int Gen0 { get; } - public int Gen1 { get; } - public int Gen2 { get; } - - public override string ToString() - { - return string.Format("[GCCollectionCount: gen0 {0}, gen1 {1}, gen2 {2}]", Gen0, Gen1, Gen2); - } - } -} diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index e0fcdecd9ac..f775e4c85fb 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -3,9 +3,10 @@ - net45;netcoreapp2.1 + net461;netcoreapp2.1 Exe true + true @@ -13,10 +14,10 @@ - + - + @@ -24,5 +25,4 @@ - diff --git a/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs index 787b5508fba..de4e635580f 100644 --- a/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs @@ -1,4 +1,4 @@ -#region Copyright notice and license +#region Copyright notice and license // Copyright 2015 gRPC authors. // @@ -16,49 +16,39 @@ #endregion -using System; using System.Runtime.InteropServices; -using System.Threading; -using Grpc.Core; +using BenchmarkDotNet.Attributes; using Grpc.Core.Internal; -using System.Collections.Generic; -using System.Diagnostics; namespace Grpc.Microbenchmarks { - public class PInvokeByteArrayBenchmark + public class PInvokeByteArrayBenchmark : CommonThreadedBase { static readonly NativeMethods Native = NativeMethods.Get(); - public void Init() + protected override bool NeedsEnvironment => false; + + + [Params(0)] + public int PayloadSize { get; set; } + + const int Iterations = 1000000; // High number to make the overhead of RunConcurrent negligible. + [Benchmark(OperationsPerInvoke = Iterations)] + public void AllocFree() { + RunConcurrent(RunBody); } - public void Cleanup() + private void RunBody() { - } - - public void Run(int threadCount, int iterations, int payloadSize) - { - Console.WriteLine(string.Format("PInvokeByteArrayBenchmark: threads={0}, iterations={1}, payloadSize={2}", threadCount, iterations, payloadSize)); - var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, payloadSize)); - threadedBenchmark.Run(); - } - - private void ThreadBody(int iterations, int payloadSize) - { - var payload = new byte[payloadSize]; - - var stopwatch = Stopwatch.StartNew(); - for (int i = 0; i < iterations; i++) + var payload = new byte[PayloadSize]; + for (int i = 0; i < Iterations; i++) { var gcHandle = GCHandle.Alloc(payload, GCHandleType.Pinned); var payloadPtr = gcHandle.AddrOfPinnedObject(); Native.grpcsharp_test_nop(payloadPtr); gcHandle.Free(); } - stopwatch.Stop(); - Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds); } } } diff --git a/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs new file mode 100644 index 00000000000..3949040aac0 --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs @@ -0,0 +1,102 @@ +#region Copyright notice and license + +// 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. + +#endregion + +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using Grpc.Core; + +namespace Grpc.Microbenchmarks +{ + // this test creates a real server and client, measuring the inherent inbuilt + // platform overheads; the marshallers **DO NOT ALLOCATE**, so any allocations + // are from the framework, not the messages themselves + + // important: allocs are not reliable on .NET Core until .NET Core 3, since + // this test involves multiple threads + + [ClrJob, CoreJob] // test .NET Core and .NET Framework + [MemoryDiagnoser] // allocations + public class PingBenchmark + { + private static readonly Task CompletedString = Task.FromResult(""); + private static readonly byte[] EmptyBlob = new byte[0]; + private static readonly Marshaller EmptyMarshaller = new Marshaller(_ => EmptyBlob, _ => ""); + private static readonly Method PingMethod = new Method(MethodType.Unary, nameof(PingBenchmark), "Ping", EmptyMarshaller, EmptyMarshaller); + + + [Benchmark] + public async ValueTask PingAsync() + { + using (var result = client.PingAsync("", new CallOptions())) + { + return await result.ResponseAsync; + } + } + + [Benchmark] + public string Ping() + { + return client.Ping("", new CallOptions()); + } + + private Task ServerMethod(string request, ServerCallContext context) + { + return CompletedString; + } + + Server server; + Channel channel; + PingClient client; + + [GlobalSetup] + public async Task Setup() + { + // create server + server = new Server { + Ports = { new ServerPort("localhost", 10042, ServerCredentials.Insecure) }, + Services = { ServerServiceDefinition.CreateBuilder().AddMethod(PingMethod, ServerMethod).Build() }, + }; + server.Start(); + + // create client + channel = new Channel("localhost", 10042, ChannelCredentials.Insecure); + await channel.ConnectAsync(); + client = new PingClient(new DefaultCallInvoker(channel)); + } + + [GlobalCleanup] + public async Task Cleanup() + { + await channel.ShutdownAsync(); + await server.ShutdownAsync(); + } + + class PingClient : LiteClientBase + { + public PingClient(CallInvoker callInvoker) : base(callInvoker) { } + public AsyncUnaryCall PingAsync(string request, CallOptions options) + { + return CallInvoker.AsyncUnaryCall(PingMethod, null, options, request); + } + public string Ping(string request, CallOptions options) + { + return CallInvoker.BlockingUnaryCall(PingMethod, null, options, request); + } + } + } +} diff --git a/src/csharp/Grpc.Microbenchmarks/Program.cs b/src/csharp/Grpc.Microbenchmarks/Program.cs index a64c2979abe..71e549f76ff 100644 --- a/src/csharp/Grpc.Microbenchmarks/Program.cs +++ b/src/csharp/Grpc.Microbenchmarks/Program.cs @@ -1,4 +1,4 @@ -#region Copyright notice and license +#region Copyright notice and license // Copyright 2015 gRPC authors. // @@ -16,95 +16,18 @@ #endregion -using System; -using Grpc.Core; -using Grpc.Core.Internal; -using Grpc.Core.Logging; -using CommandLine; -using CommandLine.Text; +using BenchmarkDotNet.Running; namespace Grpc.Microbenchmarks { class Program { - public enum MicrobenchmarkType - { - CompletionRegistry, - PInvokeByteArray, - SendMessage - } - - private class BenchmarkOptions - { - [Option("benchmark", Required = true, HelpText = "Benchmark to run")] - public MicrobenchmarkType Benchmark { get; set; } - } - + // typical usage: dotnet run -c Release -f netcoreapp2.1 + // (this will profile both .net core and .net framework; for some reason + // if you start from "-f net461", it goes horribly wrong) public static void Main(string[] args) { - GrpcEnvironment.SetLogger(new ConsoleLogger()); - var parserResult = Parser.Default.ParseArguments(args) - .WithNotParsed(errors => { - Console.WriteLine("Supported benchmarks:"); - foreach (var enumValue in Enum.GetValues(typeof(MicrobenchmarkType))) - { - Console.WriteLine(" " + enumValue); - } - Environment.Exit(1); - }) - .WithParsed(options => - { - switch (options.Benchmark) - { - case MicrobenchmarkType.CompletionRegistry: - RunCompletionRegistryBenchmark(); - break; - case MicrobenchmarkType.PInvokeByteArray: - RunPInvokeByteArrayBenchmark(); - break; - case MicrobenchmarkType.SendMessage: - RunSendMessageBenchmark(); - break; - default: - throw new ArgumentException("Unsupported benchmark."); - } - }); - } - - static void RunCompletionRegistryBenchmark() - { - var benchmark = new CompletionRegistryBenchmark(); - benchmark.Init(); - foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12}) - { - foreach (bool useSharedRegistry in new bool[] {false, true}) - { - benchmark.Run(threadCount, 4 * 1000 * 1000, useSharedRegistry); - } - } - benchmark.Cleanup(); - } - - static void RunPInvokeByteArrayBenchmark() - { - var benchmark = new PInvokeByteArrayBenchmark(); - benchmark.Init(); - foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12}) - { - benchmark.Run(threadCount, 4 * 1000 * 1000, 0); - } - benchmark.Cleanup(); - } - - static void RunSendMessageBenchmark() - { - var benchmark = new SendMessageBenchmark(); - benchmark.Init(); - foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12}) - { - benchmark.Run(threadCount, 4 * 1000 * 1000, 0); - } - benchmark.Cleanup(); + BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); } } } diff --git a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs index 390c062298d..d9554db00db 100644 --- a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs @@ -1,4 +1,4 @@ -#region Copyright notice and license +#region Copyright notice and license // Copyright 2015 gRPC authors. // @@ -17,59 +17,48 @@ #endregion using System; -using System.Threading; +using BenchmarkDotNet.Attributes; using Grpc.Core; using Grpc.Core.Internal; -using System.Collections.Generic; -using System.Diagnostics; namespace Grpc.Microbenchmarks { - public class SendMessageBenchmark + public class SendMessageBenchmark : CommonThreadedBase { static readonly NativeMethods Native = NativeMethods.Get(); - GrpcEnvironment environment; - - public void Init() + public override void Setup() { Native.grpcsharp_test_override_method("grpcsharp_call_start_batch", "nop"); - environment = GrpcEnvironment.AddRef(); + base.Setup(); } - public void Cleanup() + [Params(0)] + public int PayloadSize { get; set; } + + const int Iterations = 1000000; // High number to make the overhead of RunConcurrent negligible. + [Benchmark(OperationsPerInvoke = Iterations)] + public void SendMessage() { - GrpcEnvironment.ReleaseAsync().Wait(); - // TODO(jtattermusch): track GC stats + RunConcurrent(RunBody); } - public void Run(int threadCount, int iterations, int payloadSize) + private void RunBody() { - Console.WriteLine(string.Format("SendMessageBenchmark: threads={0}, iterations={1}, payloadSize={2}", threadCount, iterations, payloadSize)); - var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, payloadSize)); - threadedBenchmark.Run(); - } - - private void ThreadBody(int iterations, int payloadSize) - { - var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => throw new NotImplementedException()); + var completionRegistry = new CompletionRegistry(Environment, () => Environment.BatchContextPool.Lease(), () => throw new NotImplementedException()); var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry); var call = CreateFakeCall(cq); var sendCompletionCallback = new NopSendCompletionCallback(); - var payload = new byte[payloadSize]; + var payload = new byte[PayloadSize]; var writeFlags = default(WriteFlags); - var stopwatch = Stopwatch.StartNew(); - for (int i = 0; i < iterations; i++) + for (int i = 0; i < Iterations; i++) { call.StartSendMessage(sendCompletionCallback, payload, writeFlags, false); var callback = completionRegistry.Extract(completionRegistry.LastRegisteredKey); callback.OnComplete(true); } - stopwatch.Stop(); - Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds); - cq.Dispose(); } diff --git a/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs deleted file mode 100644 index 95b9aaaf3f9..00000000000 --- a/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs +++ /dev/null @@ -1,65 +0,0 @@ -#region Copyright notice and license - -// 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. - -#endregion - -using System; -using System.Threading; -using Grpc.Core; -using Grpc.Core.Internal; -using System.Collections.Generic; -using System.Diagnostics; - -namespace Grpc.Microbenchmarks -{ - public class ThreadedBenchmark - { - List runners; - - public ThreadedBenchmark(IEnumerable runners) - { - this.runners = new List(runners); - } - - public ThreadedBenchmark(int threadCount, Action threadBody) - { - this.runners = new List(); - for (int i = 0; i < threadCount; i++) - { - this.runners.Add(new ThreadStart(() => threadBody())); - } - } - - public void Run() - { - Console.WriteLine("Running threads."); - var gcStats = new GCStats(); - var threads = new List(); - for (int i = 0; i < runners.Count; i++) - { - var thread = new Thread(runners[i]); - thread.Start(); - threads.Add(thread); - } - - foreach (var thread in threads) - { - thread.Join(); - } - Console.WriteLine("All threads finished (GC Stats Delta: " + gcStats.GetSnapshot() + ")"); - } - } -} diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs new file mode 100644 index 00000000000..70bbae6f400 --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs @@ -0,0 +1,70 @@ +#region Copyright notice and license + +// 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. + +#endregion + +using System; +using System.Collections.Generic; +using System.Text; +using BenchmarkDotNet.Attributes; +using Grpc.Core.Internal; + +namespace Grpc.Microbenchmarks +{ + [ClrJob, CoreJob] // test .NET Core and .NET Framework + [MemoryDiagnoser] // allocations + public class Utf8Decode + { + [Params(0, 1, 4, 128, 1024)] + public int PayloadSize + { + get { return payloadSize; } + set + { + payloadSize = value; + payload = Invent(value); + } + } + + private int payloadSize; + private byte[] payload; + + static byte[] Invent(int length) + { + var rand = new Random(Seed: length); + var chars = new char[length]; + for(int i = 0; i < chars.Length; i++) + { + chars[i] = (char)rand.Next(32, 300); + } + return Encoding.UTF8.GetBytes(chars); + } + + const int Iterations = 1000; + [Benchmark(OperationsPerInvoke = Iterations)] + public unsafe void Decode() + { + fixed (byte* ptr = payload) + { + var iPtr = new IntPtr(ptr); + for (int i = 0; i < Iterations; i++) + { + MarshalUtils.PtrToStringUTF8(iPtr, payload.Length); + } + } + } + } +} diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs new file mode 100644 index 00000000000..3eddb33788a --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs @@ -0,0 +1,126 @@ +#region Copyright notice and license + +// 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. + +#endregion + +using System; +using System.Collections.Generic; +using BenchmarkDotNet.Attributes; +using Grpc.Core; +using Grpc.Core.Internal; + +namespace Grpc.Microbenchmarks +{ + [ClrJob, CoreJob] // test .NET Core and .NET Framework + [MemoryDiagnoser] // allocations + public class Utf8Encode : ISendStatusFromServerCompletionCallback + { + [Params(0, 1, 4, 128, 1024)] + public int PayloadSize + { + get { return payloadSize; } + set + { + payloadSize = value; + status = new Status(StatusCode.OK, Invent(value)); + } + } + + private int payloadSize; + private Status status; + + static string Invent(int length) + { + var rand = new Random(Seed: length); + var chars = new char[length]; + for(int i = 0; i < chars.Length; i++) + { + chars[i] = (char)rand.Next(32, 300); + } + return new string(chars); + } + + private GrpcEnvironment environment; + private CompletionRegistry completionRegistry; + [GlobalSetup] + public void Setup() + { + var native = NativeMethods.Get(); + + // nop the native-call via reflection + NativeMethods.Delegates.grpcsharp_call_send_status_from_server_delegate nop = (CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags) => { + completionRegistry.Extract(ctx.Handle).OnComplete(true); // drain the dictionary as we go + return CallError.OK; + }; + native.GetType().GetField(nameof(native.grpcsharp_call_send_status_from_server)).SetValue(native, nop); + + environment = GrpcEnvironment.AddRef(); + metadata = MetadataArraySafeHandle.Create(Metadata.Empty); + completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => throw new NotImplementedException()); + var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry); + call = CreateFakeCall(cq); + } + + private static CallSafeHandle CreateFakeCall(CompletionQueueSafeHandle cq) + { + var call = CallSafeHandle.CreateFake(new IntPtr(0xdead), cq); + bool success = false; + while (!success) + { + // avoid calling destroy on a nonexistent grpc_call pointer + call.DangerousAddRef(ref success); + } + return call; + } + + [GlobalCleanup] + public void Cleanup() + { + try + { + metadata?.Dispose(); + metadata = null; + call?.Dispose(); + call = null; + + if (environment != null) + { + environment = null; + // cleanup seems... unreliable on CLR + // GrpcEnvironment.ReleaseAsync().Wait(1000); + } + } + catch (Exception ex) + { + Console.Error.WriteLine(ex.Message); + } + } + private CallSafeHandle call; + private MetadataArraySafeHandle metadata; + + const int Iterations = 1000; + [Benchmark(OperationsPerInvoke = Iterations)] + public unsafe void SendStatus() + { + for (int i = 0; i < Iterations; i++) + { + call.StartSendStatusFromServer(this, status, metadata, false, null, WriteFlags.NoCompress); + } + } + + void ISendStatusFromServerCompletionCallback.OnSendStatusFromServerCompletion(bool success) { } + } +} diff --git a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj index 7ad2ce21694..bc32e375860 100644 --- a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj +++ b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj @@ -7,13 +7,10 @@ - - + /usr/lib/mono/4.5-api /usr/local/lib/mono/4.5-api /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index d09d97d1397..e73f7b7deae 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -7,13 +7,10 @@ net45;netstandard1.3 - - + /usr/lib/mono/4.5-api /usr/local/lib/mono/4.5-api /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj index b71cd93ff9a..4cf52cc39f7 100644 --- a/src/csharp/Grpc/Grpc.csproj +++ b/src/csharp/Grpc/Grpc.csproj @@ -21,6 +21,7 @@ - + + diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index e9b5645d012..939078def22 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -101,7 +101,7 @@ Pod::Spec.new do |s| s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.7.0' + s.dependency '!ProtoCompiler', '3.8.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index 58d74be4d4e..d8ce4d8e89d 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler' - v = '3.7.0' + v = '3.8.0' s.version = v s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e97ed6e3a9e..b5dfade0c39 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -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:)]; } } diff --git a/src/objective-c/manual_tests/main.m b/src/objective-c/manual_tests/main.m index 451b50cc0e2..2797c6f17f2 100644 --- a/src/objective-c/manual_tests/main.m +++ b/src/objective-c/manual_tests/main.m @@ -21,8 +21,6 @@ int main(int argc, char* argv[]) { @autoreleasepool { - // enable CFStream API - setenv("grpc_cfstream", "1", 1); return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } diff --git a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm index a24734024dc..ad426014a5b 100644 --- a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm @@ -37,9 +37,9 @@ #include #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/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -51,19 +51,18 @@ #import "../ConfigureCronet.h" -typedef struct fullstack_secure_fixture_data { - char *localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args *client_args, grpc_channel_args *server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_secure_fixture_data *ffd = - (fullstack_secure_fixture_data *)gpr_malloc(sizeof(fullstack_secure_fixture_data)); + fullstack_secure_fixture_data *ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port); + grpc_core::JoinHostPort(&ffd->localaddr, "127.0.0.1", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(NULL); @@ -83,7 +82,8 @@ static void cronet_init_client_secure_fullstack(grpc_end2end_test_fixture *f, grpc_channel_args *client_args, stream_engine *cronetEngine) { fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; - f->client = grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); + f->client = + grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr.get(), client_args, NULL); GPR_ASSERT(f->client != NULL); } @@ -96,15 +96,14 @@ static void chttp2_init_server_secure_fullstack(grpc_end2end_test_fixture *f, } f->server = grpc_server_create(server_args, NULL); grpc_server_register_completion_queue(f->server, f->cq, NULL); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); } static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void cronet_init_client_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f, diff --git a/src/objective-c/tests/CronetTests/CronetUnitTests.mm b/src/objective-c/tests/CronetTests/CronetUnitTests.mm index 2473cf612be..4e2e70f1512 100644 --- a/src/objective-c/tests/CronetTests/CronetUnitTests.mm +++ b/src/objective-c/tests/CronetTests/CronetUnitTests.mm @@ -33,9 +33,9 @@ #import "src/core/lib/channel/channel_args.h" #import "src/core/lib/gpr/env.h" -#import "src/core/lib/gpr/host_port.h" #import "src/core/lib/gpr/string.h" #import "src/core/lib/gpr/tmpfile.h" +#import "src/core/lib/gprpp/host_port.h" #import "test/core/end2end/data/ssl_test_data.h" #import "test/core/util/test_config.h" @@ -133,11 +133,11 @@ unsigned int parse_h2_length(const char *field) { {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); - char *addr; - gpr_join_host_port(&addr, "127.0.0.1", port); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "127.0.0.1", port); grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL); stream_engine *cronetEngine = [Cronet getGlobalEngine]; - grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, NULL, NULL); + grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr.get(), NULL, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; @@ -264,11 +264,11 @@ unsigned int parse_h2_length(const char *field) { {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); - char *addr; - gpr_join_host_port(&addr, "127.0.0.1", port); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "127.0.0.1", port); grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL); stream_engine *cronetEngine = [Cronet getGlobalEngine]; - grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, args, NULL); + grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr.get(), args, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; diff --git a/src/proto/grpc/testing/messages.proto b/src/proto/grpc/testing/messages.proto index 7b1b7286dce..3b966ae1b25 100644 --- a/src/proto/grpc/testing/messages.proto +++ b/src/proto/grpc/testing/messages.proto @@ -77,6 +77,9 @@ message SimpleRequest { // Whether the server should expect this request to be compressed. BoolValue expect_compressed = 8; + + // Whether SimpleResponse should include server_id. + bool fill_server_id = 9; } // Unary response, as configured by the request. @@ -88,6 +91,10 @@ message SimpleResponse { string username = 2; // OAuth scope. string oauth_scope = 3; + + // Server ID. This must be unique among different server instances, + // but the same across all RPC's made to a particular server instance. + string server_id = 4; } // Client-streaming request. diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi index 59b3891d9fa..30fdf6a7600 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi @@ -44,12 +44,12 @@ cdef extern from "src/core/lib/iomgr/resolve_address_custom.h": pass struct grpc_custom_resolver_vtable: - grpc_error* (*resolve)(char* host, char* port, grpc_resolved_addresses** res) except * - void (*resolve_async)(grpc_custom_resolver* resolver, char* host, char* port) except * + grpc_error* (*resolve)(char* host, char* port, grpc_resolved_addresses** res); + void (*resolve_async)(grpc_custom_resolver* resolver, char* host, char* port); void grpc_custom_resolve_callback(grpc_custom_resolver* resolver, grpc_resolved_addresses* result, - grpc_error* error) + grpc_error* error); cdef extern from "src/core/lib/iomgr/tcp_custom.h": struct grpc_custom_socket: @@ -67,25 +67,25 @@ cdef extern from "src/core/lib/iomgr/tcp_custom.h": ctypedef void (*grpc_custom_close_callback)(grpc_custom_socket* socket) struct grpc_socket_vtable: - grpc_error* (*init)(grpc_custom_socket* socket, int domain) except * + grpc_error* (*init)(grpc_custom_socket* socket, int domain); void (*connect)(grpc_custom_socket* socket, const grpc_sockaddr* addr, - size_t len, grpc_custom_connect_callback cb) except * - void (*destroy)(grpc_custom_socket* socket) except * - void (*shutdown)(grpc_custom_socket* socket) except * - void (*close)(grpc_custom_socket* socket, grpc_custom_close_callback cb) except * + size_t len, grpc_custom_connect_callback cb); + void (*destroy)(grpc_custom_socket* socket); + void (*shutdown)(grpc_custom_socket* socket); + void (*close)(grpc_custom_socket* socket, grpc_custom_close_callback cb); void (*write)(grpc_custom_socket* socket, grpc_slice_buffer* slices, - grpc_custom_write_callback cb) except * + grpc_custom_write_callback cb); void (*read)(grpc_custom_socket* socket, char* buffer, size_t length, - grpc_custom_read_callback cb) except * + grpc_custom_read_callback cb); grpc_error* (*getpeername)(grpc_custom_socket* socket, - const grpc_sockaddr* addr, int* len) except * + const grpc_sockaddr* addr, int* len); grpc_error* (*getsockname)(grpc_custom_socket* socket, - const grpc_sockaddr* addr, int* len) except * + const grpc_sockaddr* addr, int* len); grpc_error* (*bind)(grpc_custom_socket* socket, const grpc_sockaddr* addr, - size_t len, int flags) except * - grpc_error* (*listen)(grpc_custom_socket* socket) except * + size_t len, int flags); + grpc_error* (*listen)(grpc_custom_socket* socket); void (*accept)(grpc_custom_socket* socket, grpc_custom_socket* client, - grpc_custom_accept_callback cb) except * + grpc_custom_accept_callback cb); cdef extern from "src/core/lib/iomgr/timer_custom.h": struct grpc_custom_timer: @@ -94,17 +94,17 @@ cdef extern from "src/core/lib/iomgr/timer_custom.h": # We don't care about the rest of the fields struct grpc_custom_timer_vtable: - void (*start)(grpc_custom_timer* t) except * - void (*stop)(grpc_custom_timer* t) except * + void (*start)(grpc_custom_timer* t); + void (*stop)(grpc_custom_timer* t); - void grpc_custom_timer_callback(grpc_custom_timer* t, grpc_error* error) + void grpc_custom_timer_callback(grpc_custom_timer* t, grpc_error* error); cdef extern from "src/core/lib/iomgr/pollset_custom.h": struct grpc_custom_poller_vtable: - void (*init)() except * - void (*poll)(size_t timeout_ms) except * - void (*kick)() except * - void (*shutdown)() except * + void (*init)() + void (*poll)(size_t timeout_ms) + void (*kick)() + void (*shutdown)() cdef extern from "src/core/lib/iomgr/iomgr_custom.h": void grpc_custom_iomgr_init(grpc_socket_vtable* socket, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi index f82fca2cce7..a1618d04d0e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi @@ -56,7 +56,7 @@ cdef sockaddr_is_ipv4(const grpc_sockaddr* address, size_t length): c_addr.len = length return grpc_sockaddr_get_uri_scheme(&c_addr) == b'ipv4' -cdef grpc_resolved_addresses* tuples_to_resolvaddr(tups) except *: +cdef grpc_resolved_addresses* tuples_to_resolvaddr(tups): cdef grpc_resolved_addresses* addresses tups_set = set((tup[4][0], tup[4][1]) for tup in tups) addresses = malloc(sizeof(grpc_resolved_addresses)) @@ -84,7 +84,7 @@ cdef class SocketWrapper: self.c_buffer = NULL self.len = 0 -cdef grpc_error* socket_init(grpc_custom_socket* socket, int domain) except * with gil: +cdef grpc_error* socket_init(grpc_custom_socket* socket, int domain) with gil: sw = SocketWrapper() sw.c_socket = socket sw.sockopts = [] @@ -112,7 +112,7 @@ def socket_connect_async(socket_wrapper, addr_tuple): cdef void socket_connect(grpc_custom_socket* socket, const grpc_sockaddr* addr, size_t addr_len, - grpc_custom_connect_callback cb) except * with gil: + grpc_custom_connect_callback cb) with gil: py_socket = None socket_wrapper = socket.impl socket_wrapper.connect_cb = cb @@ -125,10 +125,10 @@ cdef void socket_connect(grpc_custom_socket* socket, const grpc_sockaddr* addr, socket_wrapper.socket = py_socket _spawn_greenlet(socket_connect_async, socket_wrapper, addr_tuple) -cdef void socket_destroy(grpc_custom_socket* socket) except * with gil: +cdef void socket_destroy(grpc_custom_socket* socket) with gil: cpython.Py_DECREF(socket.impl) -cdef void socket_shutdown(grpc_custom_socket* socket) except * with gil: +cdef void socket_shutdown(grpc_custom_socket* socket) with gil: try: (socket.impl).socket.shutdown(gevent_socket.SHUT_RDWR) except IOError as io_error: @@ -136,7 +136,7 @@ cdef void socket_shutdown(grpc_custom_socket* socket) except * with gil: raise io_error cdef void socket_close(grpc_custom_socket* socket, - grpc_custom_close_callback cb) except * with gil: + grpc_custom_close_callback cb) with gil: socket_wrapper = (socket.impl) if socket_wrapper.socket is not None: socket_wrapper.socket.close() @@ -176,7 +176,7 @@ def socket_write_async(socket_wrapper, write_bytes): socket_write_async_cython(socket_wrapper, write_bytes) cdef void socket_write(grpc_custom_socket* socket, grpc_slice_buffer* buffer, - grpc_custom_write_callback cb) except * with gil: + grpc_custom_write_callback cb) with gil: cdef char* start sw = socket.impl sw.write_cb = cb @@ -204,7 +204,7 @@ def socket_read_async(socket_wrapper): socket_read_async_cython(socket_wrapper) cdef void socket_read(grpc_custom_socket* socket, char* buffer, - size_t length, grpc_custom_read_callback cb) except * with gil: + size_t length, grpc_custom_read_callback cb) with gil: sw = socket.impl sw.read_cb = cb sw.c_buffer = buffer @@ -213,7 +213,7 @@ cdef void socket_read(grpc_custom_socket* socket, char* buffer, cdef grpc_error* socket_getpeername(grpc_custom_socket* socket, const grpc_sockaddr* addr, - int* length) except * with gil: + int* length) with gil: cdef char* src_buf peer = (socket.impl).socket.getpeername() @@ -226,7 +226,7 @@ cdef grpc_error* socket_getpeername(grpc_custom_socket* socket, cdef grpc_error* socket_getsockname(grpc_custom_socket* socket, const grpc_sockaddr* addr, - int* length) except * with gil: + int* length) with gil: cdef char* src_buf cdef grpc_resolved_address c_addr if (socket.impl).socket is None: @@ -245,7 +245,7 @@ def applysockopts(s): cdef grpc_error* socket_bind(grpc_custom_socket* socket, const grpc_sockaddr* addr, - size_t len, int flags) except * with gil: + size_t len, int flags) with gil: addr_tuple = sockaddr_to_tuple(addr, len) try: try: @@ -262,7 +262,7 @@ cdef grpc_error* socket_bind(grpc_custom_socket* socket, else: return grpc_error_none() -cdef grpc_error* socket_listen(grpc_custom_socket* socket) except * with gil: +cdef grpc_error* socket_listen(grpc_custom_socket* socket) with gil: (socket.impl).socket.listen(50) return grpc_error_none() @@ -292,7 +292,7 @@ def socket_accept_async(s): accept_callback_cython(s) cdef void socket_accept(grpc_custom_socket* socket, grpc_custom_socket* client, - grpc_custom_accept_callback cb) except * with gil: + grpc_custom_accept_callback cb) with gil: sw = socket.impl sw.accepting_socket = client sw.accept_cb = cb @@ -322,7 +322,7 @@ cdef socket_resolve_async_cython(ResolveWrapper resolve_wrapper): def socket_resolve_async_python(resolve_wrapper): socket_resolve_async_cython(resolve_wrapper) -cdef void socket_resolve_async(grpc_custom_resolver* r, char* host, char* port) except * with gil: +cdef void socket_resolve_async(grpc_custom_resolver* r, char* host, char* port) with gil: rw = ResolveWrapper() rw.c_resolver = r rw.c_host = host @@ -330,7 +330,7 @@ cdef void socket_resolve_async(grpc_custom_resolver* r, char* host, char* port) _spawn_greenlet(socket_resolve_async_python, rw) cdef grpc_error* socket_resolve(char* host, char* port, - grpc_resolved_addresses** res) except * with gil: + grpc_resolved_addresses** res) with gil: try: result = gevent_socket.getaddrinfo(host, port) res[0] = tuples_to_resolvaddr(result) @@ -360,13 +360,13 @@ cdef class TimerWrapper: self.event.set() self.timer.stop() -cdef void timer_start(grpc_custom_timer* t) except * with gil: +cdef void timer_start(grpc_custom_timer* t) with gil: timer = TimerWrapper(t.timeout_ms / 1000.0) timer.c_timer = t t.timer = timer timer.start() -cdef void timer_stop(grpc_custom_timer* t) except * with gil: +cdef void timer_stop(grpc_custom_timer* t) with gil: time_wrapper = t.timer time_wrapper.stop() @@ -374,16 +374,16 @@ cdef void timer_stop(grpc_custom_timer* t) except * with gil: ### pollset implementation ### ############################### -cdef void init_loop() except * with gil: +cdef void init_loop() with gil: pass -cdef void destroy_loop() except * with gil: +cdef void destroy_loop() with gil: g_pool.join() -cdef void kick_loop() except * with gil: +cdef void kick_loop() with gil: g_event.set() -cdef void run_loop(size_t timeout_ms) except * with gil: +cdef void run_loop(size_t timeout_ms) with gil: timeout = timeout_ms / 1000.0 if timeout_ms > 0: g_event.wait(timeout) diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 2619ccf9740..72e19f02081 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -27,7 +27,6 @@ CORE_SOURCE_FILES = [ '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', @@ -54,6 +53,7 @@ CORE_SOURCE_FILES = [ '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', @@ -101,6 +101,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', diff --git a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py index c6b72c327b1..006a3deecb4 100644 --- a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py +++ b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py @@ -24,9 +24,12 @@ import sys # Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 def sys_path_to_site_dir_hack(): """Add valid sys.path item to site directory to parse the .pth files.""" + items = [] for item in sys.path: if os.path.exists(item): # The only difference between sys.path and site-directory is # whether the .pth file will be parsed or not. A site-directory # will always exist in sys.path, but not another way around. - site.addsitedir(item) + items.append(item) + for item in items: + site.addsitedir(item) diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index b1165a6d6eb..fa275c75419 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -134,6 +134,7 @@ grpc_service_account_jwt_access_credentials_create_type grpc_service_account_jwt grpc_google_refresh_token_credentials_create_type grpc_google_refresh_token_credentials_create_import; grpc_access_token_credentials_create_type grpc_access_token_credentials_create_import; grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_import; +grpc_sts_credentials_create_type grpc_sts_credentials_create_import; grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import; grpc_secure_channel_create_type grpc_secure_channel_create_import; grpc_server_credentials_release_type grpc_server_credentials_release_import; @@ -404,6 +405,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_google_refresh_token_credentials_create_import = (grpc_google_refresh_token_credentials_create_type) GetProcAddress(library, "grpc_google_refresh_token_credentials_create"); grpc_access_token_credentials_create_import = (grpc_access_token_credentials_create_type) GetProcAddress(library, "grpc_access_token_credentials_create"); grpc_google_iam_credentials_create_import = (grpc_google_iam_credentials_create_type) GetProcAddress(library, "grpc_google_iam_credentials_create"); + grpc_sts_credentials_create_import = (grpc_sts_credentials_create_type) GetProcAddress(library, "grpc_sts_credentials_create"); grpc_metadata_credentials_create_from_plugin_import = (grpc_metadata_credentials_create_from_plugin_type) GetProcAddress(library, "grpc_metadata_credentials_create_from_plugin"); grpc_secure_channel_create_import = (grpc_secure_channel_create_type) GetProcAddress(library, "grpc_secure_channel_create"); grpc_server_credentials_release_import = (grpc_server_credentials_release_type) GetProcAddress(library, "grpc_server_credentials_release"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 5809194f1ae..1389c301728 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -377,6 +377,9 @@ extern grpc_access_token_credentials_create_type grpc_access_token_credentials_c typedef grpc_call_credentials*(*grpc_google_iam_credentials_create_type)(const char* authorization_token, const char* authority_selector, void* reserved); extern grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_import; #define grpc_google_iam_credentials_create grpc_google_iam_credentials_create_import +typedef grpc_call_credentials*(*grpc_sts_credentials_create_type)(const grpc_sts_credentials_options* options, void* reserved); +extern grpc_sts_credentials_create_type grpc_sts_credentials_create_import; +#define grpc_sts_credentials_create grpc_sts_credentials_create_import typedef grpc_call_credentials*(*grpc_metadata_credentials_create_from_plugin_type)(grpc_metadata_credentials_plugin plugin, void* reserved); extern grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import; #define grpc_metadata_credentials_create_from_plugin grpc_metadata_credentials_create_from_plugin_import diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 43bc063aee5..87088abfc53 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -69,7 +69,7 @@ return 'endif()\n' %> - cmake_minimum_required(VERSION 2.8) + cmake_minimum_required(VERSION 3.5.1) set(PACKAGE_NAME "grpc") set(PACKAGE_VERSION "${settings.cpp_version}") @@ -325,7 +325,7 @@ % for lib in libs: % if lib.build in ["all", "protoc", "tool", "test", "private"] and not lib.boringssl: % if not lib.get('build_system', []) or 'cmake' in lib.get('build_system', []): - % if not lib.name in ['ares', 'benchmark', 'z']: # we build these using CMake instead + % if not lib.name in ['ares', 'benchmark', 'upb', 'z']: # we build these using CMake instead % if lib.build in ["test", "private"]: if (gRPC_BUILD_TESTS) ${cc_library(lib)} @@ -467,6 +467,13 @@ ) endif (_gRPC_PLATFORM_ANDROID) % endif + % if lib.name in ["grpc", "grpc_cronet", "grpc_test_util", \ + "grpc_test_util_unsecure", "grpc_unsecure", \ + "grpc++_cronet"]: + if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(${lib.name} "-framework CoreFoundation") + endif() + %endif % if len(lib.get('public_headers', [])) > 0: foreach(_hdr diff --git a/templates/Makefile.template b/templates/Makefile.template index fb0dd1d87b3..a46a27061ab 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -220,6 +220,7 @@ CXXFLAGS += -std=c++11 ifeq ($(SYSTEM),Darwin) CXXFLAGS += -stdlib=libc++ + LDFLAGS += -framework CoreFoundation endif % for arg in ['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'COREFLAGS', 'LDFLAGS', 'DEFINES']: % if defaults.get('global', []).get(arg, None) is not None: diff --git a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template index 741f9b7e54d..b2335ac8a9e 100644 --- a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template +++ b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template @@ -103,7 +103,7 @@ s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.7.0' + s.dependency '!ProtoCompiler', '3.8.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template index 34ea645cfa0..dee59335280 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM google/dart:2.0 + FROM google/dart:2.3 # Upgrade Dart to version 2. RUN apt-get update && apt-get upgrade -y dart diff --git a/test/core/bad_ssl/bad_ssl_test.cc b/test/core/bad_ssl/bad_ssl_test.cc index 8dd55f64944..deae9072613 100644 --- a/test/core/bad_ssl/bad_ssl_test.cc +++ b/test/core/bad_ssl/bad_ssl_test.cc @@ -25,8 +25,9 @@ #include #include -#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/memory.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" @@ -144,7 +145,9 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/bad_ssl_%s_server%s", root, test, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); @@ -153,7 +156,6 @@ int main(int argc, char** argv) { run_test(args[2], i); grpc_shutdown(); } - gpr_free(args[2]); gpr_subprocess_interrupt(svr); status = gpr_subprocess_join(svr); diff --git a/test/core/client_channel/parse_address_with_named_scope_id_test.cc b/test/core/client_channel/parse_address_with_named_scope_id_test.cc index bfafa745178..071fb88b734 100644 --- a/test/core/client_channel/parse_address_with_named_scope_id_test.cc +++ b/test/core/client_channel/parse_address_with_named_scope_id_test.cc @@ -30,7 +30,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/socket_utils.h" #include "test/core/util/test_config.h" @@ -60,20 +61,20 @@ static void test_grpc_parse_ipv6_parity_with_getaddrinfo( struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) { grpc_uri* uri = grpc_uri_parse(uri_text, 0); - char* host = nullptr; - char* port = nullptr; - gpr_split_host_port(uri->path, &host, &port); + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + grpc_core::SplitHostPort(uri->path, &host, &port); struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST; struct addrinfo* result; - int res = getaddrinfo(host, port, &hints, &result); + int res = getaddrinfo(host.get(), port.get(), &hints, &result); if (res != 0) { gpr_log(GPR_ERROR, - "getaddrinfo failed to resolve host:%s port:%s. Error: %d.", host, - port, res); + "getaddrinfo failed to resolve host:%s port:%s. Error: %d.", + host.get(), port.get(), res); abort(); } size_t num_addrs_from_getaddrinfo = 0; @@ -86,8 +87,6 @@ struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) { *reinterpret_cast(result->ai_addr); // Cleanup freeaddrinfo(result); - gpr_free(host); - gpr_free(port); grpc_uri_destroy(uri); return out; } diff --git a/test/core/client_channel/resolvers/BUILD b/test/core/client_channel/resolvers/BUILD index 3dbee5c9e6d..e5882069cd4 100644 --- a/test/core/client_channel/resolvers/BUILD +++ b/test/core/client_channel/resolvers/BUILD @@ -19,9 +19,26 @@ grpc_package(name = "test/core/client_channel_resolvers") licenses(["notice"]) # Apache v2 grpc_cc_test( - name = "dns_resolver_connectivity_test", + name = "dns_resolver_connectivity_using_ares_resolver_test", srcs = ["dns_resolver_connectivity_test.cc"], language = "C++", + args = [ + "--resolver=ares", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "dns_resolver_connectivity_using_native_resolver_test", + srcs = ["dns_resolver_connectivity_test.cc"], + language = "C++", + args = [ + "--resolver=native", + ], deps = [ "//:gpr", "//:grpc", diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index 7b3a4589f5b..683d02079c3 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -101,12 +101,16 @@ static grpc_ares_request* test_dns_lookup_ares_locked( addresses, check_grpclb, service_config_json, query_timeout_ms, combiner); ++g_resolution_count; static grpc_millis last_resolution_time = 0; + grpc_millis now = + grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); + gpr_log(GPR_DEBUG, + "last_resolution_time:%" PRId64 " now:%" PRId64 + " min_time_between:%d", + last_resolution_time, now, kMinResolutionPeriodForCheckMs); if (last_resolution_time == 0) { last_resolution_time = grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); } else { - grpc_millis now = - grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); GPR_ASSERT(now - last_resolution_time >= kMinResolutionPeriodForCheckMs); last_resolution_time = now; } @@ -212,11 +216,14 @@ struct OnResolutionCallbackArg { // Set to true by the last callback in the resolution chain. static bool g_all_callbacks_invoked; -static void on_second_resolution(OnResolutionCallbackArg* cb_arg) { - gpr_log(GPR_INFO, "2nd: g_resolution_count: %d", g_resolution_count); - // The resolution callback was not invoked until new data was - // available, which was delayed until after the cooldown period. - GPR_ASSERT(g_resolution_count == 2); +// It's interesting to run a few rounds of this test because as +// we run more rounds, the base starting time +// (i.e. ExecCtx g_start_time) gets further and further away +// from "Now()". Thus the more rounds ran, the more highlighted the +// difference is between absolute and relative times values. +static void on_fourth_resolution(OnResolutionCallbackArg* cb_arg) { + gpr_log(GPR_INFO, "4th: g_resolution_count: %d", g_resolution_count); + GPR_ASSERT(g_resolution_count == 4); cb_arg->resolver.reset(); gpr_atm_rel_store(&g_iomgr_args.done_atm, 1); gpr_mu_lock(g_iomgr_args.mu); @@ -227,6 +234,30 @@ static void on_second_resolution(OnResolutionCallbackArg* cb_arg) { g_all_callbacks_invoked = true; } +static void on_third_resolution(OnResolutionCallbackArg* cb_arg) { + gpr_log(GPR_INFO, "3rd: g_resolution_count: %d", g_resolution_count); + GPR_ASSERT(g_resolution_count == 3); + cb_arg->result_handler->SetCallback(on_fourth_resolution, cb_arg); + cb_arg->resolver->RequestReresolutionLocked(); + gpr_mu_lock(g_iomgr_args.mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(g_iomgr_args.pollset, nullptr)); + gpr_mu_unlock(g_iomgr_args.mu); +} + +static void on_second_resolution(OnResolutionCallbackArg* cb_arg) { + gpr_log(GPR_INFO, "2nd: g_resolution_count: %d", g_resolution_count); + // The resolution callback was not invoked until new data was + // available, which was delayed until after the cooldown period. + GPR_ASSERT(g_resolution_count == 2); + cb_arg->result_handler->SetCallback(on_third_resolution, cb_arg); + cb_arg->resolver->RequestReresolutionLocked(); + gpr_mu_lock(g_iomgr_args.mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(g_iomgr_args.pollset, nullptr)); + gpr_mu_unlock(g_iomgr_args.mu); +} + static void on_first_resolution(OnResolutionCallbackArg* cb_arg) { gpr_log(GPR_INFO, "1st: g_resolution_count: %d", g_resolution_count); // There's one initial system-level resolution and one invocation of a @@ -243,9 +274,7 @@ static void on_first_resolution(OnResolutionCallbackArg* cb_arg) { static void start_test_under_combiner(void* arg, grpc_error* error) { OnResolutionCallbackArg* res_cb_arg = static_cast(arg); - res_cb_arg->result_handler = grpc_core::New(); - grpc_core::ResolverFactory* factory = grpc_core::ResolverRegistry::LookupResolverFactory("dns"); grpc_uri* uri = grpc_uri_parse(res_cb_arg->uri_str, 0); @@ -300,7 +329,6 @@ int main(int argc, char** argv) { grpc_set_resolver_impl(&test_resolver); test_cooldown(); - { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index 2d74b6b77b3..db480463b68 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -29,8 +29,8 @@ #include #include -#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/memory.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -71,7 +71,7 @@ #define SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD (size_t)200 struct rpc_state { - char* target; + grpc_core::UniquePtr target; grpc_completion_queue* cq; grpc_channel* channel; grpc_call* call; @@ -165,8 +165,9 @@ static void start_rpc(int target_port, grpc_status_code expected_status, state.cq = grpc_completion_queue_create_for_next(nullptr); cqv = cq_verifier_create(state.cq); - gpr_join_host_port(&state.target, "127.0.0.1", target_port); - state.channel = grpc_insecure_channel_create(state.target, nullptr, nullptr); + grpc_core::JoinHostPort(&state.target, "127.0.0.1", target_port); + state.channel = + grpc_insecure_channel_create(state.target.get(), nullptr, nullptr); grpc_slice host = grpc_slice_from_static_string("localhost"); state.call = grpc_channel_create_call( state.channel, nullptr, GRPC_PROPAGATE_DEFAULTS, state.cq, @@ -230,7 +231,7 @@ static void cleanup_rpc() { } while (ev.type != GRPC_QUEUE_SHUTDOWN); grpc_completion_queue_destroy(state.cq); grpc_channel_destroy(state.channel); - gpr_free(state.target); + state.target.reset(); } typedef struct { diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc index 446e7b045a1..3bb6d2e23b6 100644 --- a/test/core/end2end/connection_refused_test.cc +++ b/test/core/end2end/connection_refused_test.cc @@ -24,7 +24,7 @@ #include #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/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" @@ -77,10 +77,10 @@ static void run_test(bool wait_for_ready, bool use_service_config) { /* create a call, channel to a port which will refuse connection */ int port = grpc_pick_unused_port_or_die(); - char* addr; - gpr_join_host_port(&addr, "127.0.0.1", port); - gpr_log(GPR_INFO, "server: %s", addr); - chan = grpc_insecure_channel_create(addr, args, nullptr); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "127.0.0.1", port); + gpr_log(GPR_INFO, "server: %s", addr.get()); + chan = grpc_insecure_channel_create(addr.get(), args, nullptr); grpc_slice host = grpc_slice_from_static_string("nonexistant"); gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2); call = @@ -88,8 +88,6 @@ static void run_test(bool wait_for_ready, bool use_service_config) { grpc_slice_from_static_string("/service/method"), &host, deadline, nullptr); - gpr_free(addr); - memset(ops, 0, sizeof(ops)); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc index 330af8fce07..cb49e0030b4 100644 --- a/test/core/end2end/dualstack_socket_test.cc +++ b/test/core/end2end/dualstack_socket_test.cc @@ -28,8 +28,8 @@ #include #include -#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/error.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -70,8 +70,6 @@ static void log_resolved_addrs(const char* label, const char* hostname) { void test_connect(const char* server_host, const char* client_host, int port, int expect_ok) { - char* client_hostport; - char* server_hostport; grpc_channel* client; grpc_server* server; grpc_completion_queue* cq; @@ -99,7 +97,8 @@ void test_connect(const char* server_host, const char* client_host, int port, picked_port = 1; } - gpr_join_host_port(&server_hostport, server_host, port); + grpc_core::UniquePtr server_hostport; + grpc_core::JoinHostPort(&server_hostport, server_host, port); grpc_metadata_array_init(&initial_metadata_recv); grpc_metadata_array_init(&trailing_metadata_recv); @@ -111,7 +110,7 @@ void test_connect(const char* server_host, const char* client_host, int port, server = grpc_server_create(nullptr, nullptr); grpc_server_register_completion_queue(server, cq, nullptr); GPR_ASSERT((got_port = grpc_server_add_insecure_http2_port( - server, server_hostport)) > 0); + server, server_hostport.get())) > 0); if (port == 0) { port = got_port; } else { @@ -121,6 +120,7 @@ void test_connect(const char* server_host, const char* client_host, int port, cqv = cq_verifier_create(cq); /* Create client. */ + grpc_core::UniquePtr client_hostport; if (client_host[0] == 'i') { /* for ipv4:/ipv6: addresses, concatenate the port to each of the parts */ size_t i; @@ -139,8 +139,8 @@ void test_connect(const char* server_host, const char* client_host, int port, gpr_asprintf(&hosts_with_port[i], "%s:%d", uri_part_str, port); gpr_free(uri_part_str); } - client_hostport = gpr_strjoin_sep((const char**)hosts_with_port, - uri_parts.count, ",", nullptr); + client_hostport.reset(gpr_strjoin_sep((const char**)hosts_with_port, + uri_parts.count, ",", nullptr)); for (i = 0; i < uri_parts.count; i++) { gpr_free(hosts_with_port[i]); } @@ -148,18 +148,17 @@ void test_connect(const char* server_host, const char* client_host, int port, grpc_slice_buffer_destroy(&uri_parts); grpc_slice_unref(uri_slice); } else { - gpr_join_host_port(&client_hostport, client_host, port); + grpc_core::JoinHostPort(&client_hostport, client_host, port); } - client = grpc_insecure_channel_create(client_hostport, nullptr, nullptr); + client = + grpc_insecure_channel_create(client_hostport.get(), nullptr, nullptr); gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)", - server_hostport, client_hostport, expect_ok ? "success" : "failure"); + server_hostport.get(), client_hostport.get(), + expect_ok ? "success" : "failure"); log_resolved_addrs("server resolved addr", server_host); log_resolved_addrs("client resolved addr", client_host); - gpr_free(client_hostport); - gpr_free(server_hostport); - if (expect_ok) { /* Normal deadline, shouldn't be reached. */ deadline = grpc_timeout_milliseconds_to_deadline(60000); diff --git a/test/core/end2end/fixtures/h2_census.cc b/test/core/end2end/fixtures/h2_census.cc index 60442ddcc77..72cb96138e1 100644 --- a/test/core/end2end/fixtures/h2_census.cc +++ b/test/core/end2end/fixtures/h2_census.cc @@ -29,25 +29,23 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -71,7 +69,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, grpc_arg arg = make_census_enable_arg(); client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); { grpc_core::ExecCtx exec_ctx; @@ -94,15 +92,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, grpc_channel_args_destroy(server_args); } grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc index 01e5ae1b7b5..dd0c1fe0201 100644 --- a/test/core/end2end/fixtures/h2_compress.cc +++ b/test/core/end2end/fixtures/h2_compress.cc @@ -30,28 +30,29 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/compression/compression_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_compression_fixture_data { - char* localaddr; - grpc_channel_args* client_args_compression; - grpc_channel_args* server_args_compression; -} fullstack_compression_fixture_data; +struct fullstack_compression_fixture_data { + ~fullstack_compression_fixture_data() { + grpc_channel_args_destroy(client_args_compression); + grpc_channel_args_destroy(server_args_compression); + } + grpc_core::UniquePtr localaddr; + grpc_channel_args* client_args_compression = nullptr; + grpc_channel_args* server_args_compression = nullptr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_compression( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_compression_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_compression_fixture_data))); - memset(ffd, 0, sizeof(fullstack_compression_fixture_data)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::New(); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); memset(&f, 0, sizeof(f)); f.fixture_data = ffd; @@ -73,7 +74,7 @@ void chttp2_init_client_fullstack_compression(grpc_end2end_test_fixture* f, grpc_channel_args_set_channel_default_compression_algorithm( client_args, GRPC_COMPRESS_GZIP); f->client = grpc_insecure_channel_create( - ffd->localaddr, ffd->client_args_compression, nullptr); + ffd->localaddr.get(), ffd->client_args_compression, nullptr); } void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture* f, @@ -92,7 +93,8 @@ void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(ffd->server_args_compression, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } @@ -100,10 +102,7 @@ void chttp2_tear_down_fullstack_compression(grpc_end2end_test_fixture* f) { grpc_core::ExecCtx exec_ctx; fullstack_compression_fixture_data* ffd = static_cast(f->fixture_data); - grpc_channel_args_destroy(ffd->client_args_compression); - grpc_channel_args_destroy(ffd->server_args_compression); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_fakesec.cc b/test/core/end2end/fixtures/h2_fakesec.cc index ad83aab39f4..1375549ed6c 100644 --- a/test/core/end2end/fixtures/h2_fakesec.cc +++ b/test/core/end2end/fixtures/h2_fakesec.cc @@ -25,26 +25,24 @@ #include #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/security/credentials/fake/fake_credentials.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); - + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -66,8 +64,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -82,7 +80,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -91,8 +89,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_fake_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_full+pipe.cc b/test/core/end2end/fixtures/h2_full+pipe.cc index 6d559c4e516..ac4913674f0 100644 --- a/test/core/end2end/fixtures/h2_full+pipe.cc +++ b/test/core/end2end/fixtures/h2_full+pipe.cc @@ -33,26 +33,25 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -66,7 +65,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -79,15 +78,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index b8dbe261183..04de2a20182 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -34,25 +34,24 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -66,7 +65,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -79,15 +78,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full+workarounds.cc b/test/core/end2end/fixtures/h2_full+workarounds.cc index cb0f7d275b3..8cfba4587e0 100644 --- a/test/core/end2end/fixtures/h2_full+workarounds.cc +++ b/test/core/end2end/fixtures/h2_full+workarounds.cc @@ -30,7 +30,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -39,24 +39,20 @@ static char* workarounds_arg[GRPC_MAX_WORKAROUND_ID] = { const_cast(GRPC_ARG_WORKAROUND_CRONET_COMPRESSION)}; -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); - + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - return f; } @@ -65,7 +61,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -88,7 +84,8 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args_new, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); grpc_channel_args_destroy(server_args_new); } @@ -96,8 +93,7 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full.cc b/test/core/end2end/fixtures/h2_full.cc index c0d21288c7e..a3f2f25db5f 100644 --- a/test/core/end2end/fixtures/h2_full.cc +++ b/test/core/end2end/fixtures/h2_full.cc @@ -28,25 +28,24 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -60,7 +59,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -73,15 +72,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_http_proxy.cc b/test/core/end2end/fixtures/h2_http_proxy.cc index 9b6a81494e1..18ba0e7f847 100644 --- a/test/core/end2end/fixtures/h2_http_proxy.cc +++ b/test/core/end2end/fixtures/h2_http_proxy.cc @@ -30,26 +30,26 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/fixtures/http_proxy_fixture.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* server_addr; - grpc_end2end_http_proxy* proxy; -} fullstack_fixture_data; +struct fullstack_fixture_data { + ~fullstack_fixture_data() { grpc_end2end_http_proxy_destroy(proxy); } + grpc_core::UniquePtr server_addr; + grpc_end2end_http_proxy* proxy = nullptr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; memset(&f, 0, sizeof(f)); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); const int server_port = grpc_pick_unused_port_or_die(); - gpr_join_host_port(&ffd->server_addr, "localhost", server_port); + grpc_core::JoinHostPort(&ffd->server_addr, "localhost", server_port); /* Passing client_args to proxy_create for the case of checking for proxy auth */ @@ -81,8 +81,8 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, } gpr_setenv("http_proxy", proxy_uri); gpr_free(proxy_uri); - f->client = - grpc_insecure_channel_create(ffd->server_addr, client_args, nullptr); + f->client = grpc_insecure_channel_create(ffd->server_addr.get(), client_args, + nullptr); GPR_ASSERT(f->client); } @@ -95,16 +95,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->server_addr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->server_addr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->server_addr); - grpc_end2end_http_proxy_destroy(ffd->proxy); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_local_ipv4.cc b/test/core/end2end/fixtures/h2_local_ipv4.cc index f6996bf6be3..e27844be2df 100644 --- a/test/core/end2end/fixtures/h2_local_ipv4.cc +++ b/test/core/end2end/fixtures/h2_local_ipv4.cc @@ -20,7 +20,7 @@ #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/end2end/end2end_tests.h" #include "test/core/end2end/fixtures/local_util.h" #include "test/core/util/port.h" @@ -31,7 +31,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv4( grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); int port = grpc_pick_unused_port_or_die(); - gpr_join_host_port( + grpc_core::JoinHostPort( &static_cast(f.fixture_data) ->localaddr, "127.0.0.1", port); diff --git a/test/core/end2end/fixtures/h2_local_ipv6.cc b/test/core/end2end/fixtures/h2_local_ipv6.cc index e360727ca82..91acaa347f6 100644 --- a/test/core/end2end/fixtures/h2_local_ipv6.cc +++ b/test/core/end2end/fixtures/h2_local_ipv6.cc @@ -20,7 +20,7 @@ #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/end2end/end2end_tests.h" #include "test/core/end2end/fixtures/local_util.h" #include "test/core/util/port.h" @@ -31,7 +31,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv6( grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); int port = grpc_pick_unused_port_or_die(); - gpr_join_host_port( + grpc_core::JoinHostPort( &static_cast(f.fixture_data) ->localaddr, "[::1]", port); diff --git a/test/core/end2end/fixtures/h2_local_uds.cc b/test/core/end2end/fixtures/h2_local_uds.cc index f1bce213dc2..6c748896760 100644 --- a/test/core/end2end/fixtures/h2_local_uds.cc +++ b/test/core/end2end/fixtures/h2_local_uds.cc @@ -30,10 +30,10 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_uds( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); - gpr_asprintf( - &static_cast(f.fixture_data) - ->localaddr, - "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++); + char* out = nullptr; + gpr_asprintf(&out, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++); + static_cast(f.fixture_data) + ->localaddr.reset(out); return f; } diff --git a/test/core/end2end/fixtures/h2_oauth2.cc b/test/core/end2end/fixtures/h2_oauth2.cc index 113a6b11732..513fded4b62 100644 --- a/test/core/end2end/fixtures/h2_oauth2.cc +++ b/test/core/end2end/fixtures/h2_oauth2.cc @@ -25,7 +25,7 @@ #include #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/iomgr.h" #include "src/core/lib/security/credentials/credentials.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -36,9 +36,9 @@ static const char oauth2_md[] = "Bearer aaslkfjs424535asdf"; static const char* client_identity_property_name = "smurf_name"; static const char* client_identity = "Brainy Smurf"; -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static const grpc_metadata* find_metadata(const grpc_metadata* md, size_t md_count, const char* key, @@ -95,16 +95,12 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); - + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - return f; } @@ -113,8 +109,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -129,7 +125,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -138,8 +134,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_proxy.cc b/test/core/end2end/fixtures/h2_proxy.cc index e334396ea7c..f0ada89d14d 100644 --- a/test/core/end2end/fixtures/h2_proxy.cc +++ b/test/core/end2end/fixtures/h2_proxy.cc @@ -28,7 +28,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/fixtures/proxy.h" diff --git a/test/core/end2end/fixtures/h2_spiffe.cc b/test/core/end2end/fixtures/h2_spiffe.cc index cdf091bac10..4352ef640cd 100644 --- a/test/core/end2end/fixtures/h2_spiffe.cc +++ b/test/core/end2end/fixtures/h2_spiffe.cc @@ -28,9 +28,9 @@ #include #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/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/security/credentials/credentials.h" @@ -42,10 +42,15 @@ typedef grpc_core::InlinedVector ThreadList; -typedef struct fullstack_secure_fixture_data { - char* localaddr; +struct fullstack_secure_fixture_data { + ~fullstack_secure_fixture_data() { + for (size_t ind = 0; ind < thd_list.size(); ind++) { + thd_list[ind].Join(); + } + } + grpc_core::UniquePtr localaddr; ThreadList thd_list; -} fullstack_secure_fixture_data; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { @@ -54,7 +59,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( fullstack_secure_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); @@ -74,8 +79,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -90,7 +95,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -99,10 +104,6 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - for (size_t ind = 0; ind < ffd->thd_list.size(); ind++) { - ffd->thd_list[ind].Join(); - } - gpr_free(ffd->localaddr); grpc_core::Delete(ffd); } diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc index 3fc9bc7f329..cb55bb72061 100644 --- a/test/core/end2end/fixtures/h2_ssl.cc +++ b/test/core/end2end/fixtures/h2_ssl.cc @@ -25,29 +25,28 @@ #include #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/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -69,8 +68,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -85,7 +84,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -94,8 +93,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_simple_ssl_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc index 1d54a431364..2a9591845b9 100644 --- a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc +++ b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc @@ -25,19 +25,19 @@ #include #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/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_secure_fixture_data { - char* localaddr; - bool server_credential_reloaded; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; + bool server_credential_reloaded = false; +}; static grpc_ssl_certificate_config_reload_status ssl_server_certificate_config_callback( @@ -64,10 +64,9 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -89,8 +88,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -106,7 +105,7 @@ static void chttp2_init_server_secure_fullstack( ffd->server_credential_reloaded = false; f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -115,8 +114,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_simple_ssl_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc index d5f695b1575..b16ffa1b8b8 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.cc +++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc @@ -25,7 +25,6 @@ #include #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/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" diff --git a/test/core/end2end/fixtures/h2_uds.cc b/test/core/end2end/fixtures/h2_uds.cc index f251bbd28c5..2b6c73d39c7 100644 --- a/test/core/end2end/fixtures/h2_uds.cc +++ b/test/core/end2end/fixtures/h2_uds.cc @@ -31,7 +31,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index 6b5513f160e..da2381aa0a0 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -31,8 +31,8 @@ #include #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/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/closure.h" @@ -53,8 +53,7 @@ struct grpc_end2end_http_proxy { grpc_end2end_http_proxy() - : proxy_name(nullptr), - server(nullptr), + : server(nullptr), channel_args(nullptr), mu(nullptr), pollset(nullptr), @@ -62,7 +61,7 @@ struct grpc_end2end_http_proxy { gpr_ref_init(&users, 1); combiner = grpc_combiner_create(); } - char* proxy_name; + grpc_core::UniquePtr proxy_name; grpc_core::Thread thd; grpc_tcp_server* server; grpc_channel_args* channel_args; @@ -532,8 +531,8 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create( grpc_end2end_http_proxy* proxy = grpc_core::New(); // Construct proxy address. const int proxy_port = grpc_pick_unused_port_or_die(); - gpr_join_host_port(&proxy->proxy_name, "localhost", proxy_port); - gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name); + grpc_core::JoinHostPort(&proxy->proxy_name, "localhost", proxy_port); + gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name.get()); // Create TCP server. proxy->channel_args = grpc_channel_args_copy(args); grpc_error* error = @@ -573,7 +572,6 @@ void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) { proxy->thd.Join(); grpc_tcp_server_shutdown_listeners(proxy->server); grpc_tcp_server_unref(proxy->server); - gpr_free(proxy->proxy_name); grpc_channel_args_destroy(proxy->channel_args); grpc_pollset_shutdown(proxy->pollset, GRPC_CLOSURE_CREATE(destroy_pollset, proxy->pollset, @@ -584,5 +582,5 @@ void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) { const char* grpc_end2end_http_proxy_get_proxy_name( grpc_end2end_http_proxy* proxy) { - return proxy->proxy_name; + return proxy->proxy_name.get(); } diff --git a/test/core/end2end/fixtures/inproc.cc b/test/core/end2end/fixtures/inproc.cc index dadf3ef455d..70cc6b05479 100644 --- a/test/core/end2end/fixtures/inproc.cc +++ b/test/core/end2end/fixtures/inproc.cc @@ -28,7 +28,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/inproc/inproc_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" diff --git a/test/core/end2end/fixtures/local_util.cc b/test/core/end2end/fixtures/local_util.cc index 5f0b0300ac0..767f3a28ef8 100644 --- a/test/core/end2end/fixtures/local_util.cc +++ b/test/core/end2end/fixtures/local_util.cc @@ -27,7 +27,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/surface/server.h" @@ -37,8 +36,7 @@ grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack() { grpc_end2end_test_fixture f; grpc_end2end_local_fullstack_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(grpc_end2end_local_fullstack_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -52,8 +50,8 @@ void grpc_end2end_local_chttp2_init_client_fullstack( grpc_channel_credentials* creds = grpc_local_credentials_create(type); grpc_end2end_local_fullstack_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -99,8 +97,8 @@ void grpc_end2end_local_chttp2_init_server_fullstack( nullptr}; grpc_server_credentials_set_auth_metadata_processor(creds, processor); } - GPR_ASSERT( - grpc_server_add_secure_http2_port(f->server, ffd->localaddr, creds)); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), + creds)); grpc_server_credentials_release(creds); grpc_server_start(f->server); } @@ -109,6 +107,5 @@ void grpc_end2end_local_chttp2_tear_down_fullstack( grpc_end2end_test_fixture* f) { grpc_end2end_local_fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } diff --git a/test/core/end2end/fixtures/local_util.h b/test/core/end2end/fixtures/local_util.h index f133b4d977e..df204d2fab2 100644 --- a/test/core/end2end/fixtures/local_util.h +++ b/test/core/end2end/fixtures/local_util.h @@ -22,9 +22,9 @@ #include "src/core/lib/surface/channel.h" -typedef struct grpc_end2end_local_fullstack_fixture_data { - char* localaddr; -} grpc_end2end_local_fullstack_fixture_data; +struct grpc_end2end_local_fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; /* Utility functions shared by h2_local tests. */ grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack(); diff --git a/test/core/end2end/fixtures/proxy.cc b/test/core/end2end/fixtures/proxy.cc index 869b6e846d3..4ae7450b0df 100644 --- a/test/core/end2end/fixtures/proxy.cc +++ b/test/core/end2end/fixtures/proxy.cc @@ -24,16 +24,15 @@ #include #include -#include "src/core/lib/gpr/host_port.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/gprpp/thd.h" #include "test/core/util/port.h" struct grpc_end2end_proxy { grpc_end2end_proxy() - : proxy_port(nullptr), - server_port(nullptr), - cq(nullptr), + : cq(nullptr), server(nullptr), client(nullptr), shutdown(false), @@ -42,8 +41,8 @@ struct grpc_end2end_proxy { memset(&new_call_metadata, 0, sizeof(new_call_metadata)); } grpc_core::Thread thd; - char* proxy_port; - char* server_port; + grpc_core::UniquePtr proxy_port; + grpc_core::UniquePtr server_port; grpc_completion_queue* cq; grpc_server* server; grpc_channel* client; @@ -92,15 +91,15 @@ grpc_end2end_proxy* grpc_end2end_proxy_create(const grpc_end2end_proxy_def* def, grpc_end2end_proxy* proxy = grpc_core::New(); - gpr_join_host_port(&proxy->proxy_port, "localhost", proxy_port); - gpr_join_host_port(&proxy->server_port, "localhost", server_port); + grpc_core::JoinHostPort(&proxy->proxy_port, "localhost", proxy_port); + grpc_core::JoinHostPort(&proxy->server_port, "localhost", server_port); - gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port, - proxy->server_port); + gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port.get(), + proxy->server_port.get()); proxy->cq = grpc_completion_queue_create_for_next(nullptr); - proxy->server = def->create_server(proxy->proxy_port, server_args); - proxy->client = def->create_client(proxy->server_port, client_args); + proxy->server = def->create_server(proxy->proxy_port.get(), server_args); + proxy->client = def->create_client(proxy->server_port.get(), client_args); grpc_server_register_completion_queue(proxy->server, proxy->cq, nullptr); grpc_server_start(proxy->server); @@ -131,8 +130,6 @@ void grpc_end2end_proxy_destroy(grpc_end2end_proxy* proxy) { grpc_server_shutdown_and_notify(proxy->server, proxy->cq, new_closure(shutdown_complete, proxy)); proxy->thd.Join(); - gpr_free(proxy->proxy_port); - gpr_free(proxy->server_port); grpc_server_destroy(proxy->server); grpc_channel_destroy(proxy->client); grpc_completion_queue_destroy(proxy->cq); @@ -441,9 +438,9 @@ static void thread_main(void* arg) { } const char* grpc_end2end_proxy_get_client_target(grpc_end2end_proxy* proxy) { - return proxy->proxy_port; + return proxy->proxy_port.get(); } const char* grpc_end2end_proxy_get_server_port(grpc_end2end_proxy* proxy) { - return proxy->server_port; + return proxy->server_port.get(); } diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index e9285778a2d..34a9ef760b5 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -25,9 +25,9 @@ #include #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/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" @@ -40,20 +40,19 @@ namespace grpc { namespace testing { -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -73,8 +72,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -89,7 +88,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -98,8 +97,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static int fail_server_auth_check(grpc_channel_args* server_args) { diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc index b2d0a5e1133..6ffc138820e 100644 --- a/test/core/end2end/h2_ssl_session_reuse_test.cc +++ b/test/core/end2end/h2_ssl_session_reuse_test.cc @@ -25,9 +25,9 @@ #include #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/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" @@ -215,19 +215,18 @@ void drain_cq(grpc_completion_queue* cq) { TEST(H2SessionReuseTest, SingleReuse) { int port = grpc_pick_unused_port_or_die(); - char* server_addr; - gpr_join_host_port(&server_addr, "localhost", port); + grpc_core::UniquePtr server_addr; + grpc_core::JoinHostPort(&server_addr, "localhost", port); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_ssl_session_cache* cache = grpc_ssl_session_cache_create_lru(16); - grpc_server* server = server_create(cq, server_addr); + grpc_server* server = server_create(cq, server_addr.get()); - do_round_trip(cq, server, server_addr, cache, false); - do_round_trip(cq, server, server_addr, cache, true); - do_round_trip(cq, server, server_addr, cache, true); + do_round_trip(cq, server, server_addr.get(), cache, false); + do_round_trip(cq, server, server_addr.get(), cache, true); + do_round_trip(cq, server, server_addr.get(), cache, true); - gpr_free(server_addr); grpc_ssl_session_cache_destroy(cache); GPR_ASSERT(grpc_completion_queue_next( diff --git a/test/core/end2end/invalid_call_argument_test.cc b/test/core/end2end/invalid_call_argument_test.cc index bd28d192984..5f920fad638 100644 --- a/test/core/end2end/invalid_call_argument_test.cc +++ b/test/core/end2end/invalid_call_argument_test.cc @@ -25,7 +25,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -54,7 +55,6 @@ static struct test_state g_state; static void prepare_test(int is_client) { int port = grpc_pick_unused_port_or_die(); - char* server_hostport; grpc_op* op; g_state.is_client = is_client; grpc_metadata_array_init(&g_state.initial_metadata_recv); @@ -77,14 +77,13 @@ static void prepare_test(int is_client) { } else { g_state.server = grpc_server_create(nullptr, nullptr); grpc_server_register_completion_queue(g_state.server, g_state.cq, nullptr); - gpr_join_host_port(&server_hostport, "0.0.0.0", port); - grpc_server_add_insecure_http2_port(g_state.server, server_hostport); + grpc_core::UniquePtr server_hostport; + grpc_core::JoinHostPort(&server_hostport, "0.0.0.0", port); + grpc_server_add_insecure_http2_port(g_state.server, server_hostport.get()); grpc_server_start(g_state.server); - gpr_free(server_hostport); - gpr_join_host_port(&server_hostport, "localhost", port); + grpc_core::JoinHostPort(&server_hostport, "localhost", port); g_state.chan = - grpc_insecure_channel_create(server_hostport, nullptr, nullptr); - gpr_free(server_hostport); + grpc_insecure_channel_create(server_hostport.get(), nullptr, nullptr); grpc_slice host = grpc_slice_from_static_string("bar"); g_state.call = grpc_channel_create_call( g_state.chan, nullptr, GRPC_PROPAGATE_DEFAULTS, g_state.cq, diff --git a/test/core/fling/fling_stream_test.cc b/test/core/fling/fling_stream_test.cc index 32bc9896414..474b4fbbc3b 100644 --- a/test/core/fling/fling_stream_test.cc +++ b/test/core/fling/fling_stream_test.cc @@ -22,8 +22,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -46,23 +46,24 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/fling_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/fling_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - gpr_join_host_port(&args[2], "127.0.0.1", port); + grpc_core::JoinHostPort(&joined, "127.0.0.1", port); + args[2] = joined.get(); args[3] = const_cast("--scenario=ping-pong-stream"); args[4] = const_cast("--no-secure"); args[5] = nullptr; cli = gpr_subprocess_create(6, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/fling/fling_test.cc b/test/core/fling/fling_test.cc index 3587a4acaae..3667d48f010 100644 --- a/test/core/fling/fling_test.cc +++ b/test/core/fling/fling_test.cc @@ -22,8 +22,9 @@ #include #include -#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/memory.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -46,23 +47,24 @@ int main(int argc, const char** argv) { gpr_asprintf(&args[0], "%s/fling_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/fling_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - gpr_join_host_port(&args[2], "127.0.0.1", port); + grpc_core::JoinHostPort(&joined, "127.0.0.1", port); + args[2] = joined.get(); args[3] = const_cast("--scenario=ping-pong-request"); args[4] = const_cast("--no-secure"); args[5] = nullptr; cli = gpr_subprocess_create(6, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/fling/server.cc b/test/core/fling/server.cc index cf7e2465d9e..241ac71bc7d 100644 --- a/test/core/fling/server.cc +++ b/test/core/fling/server.cc @@ -33,7 +33,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/profiling/timers.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/cmdline.h" @@ -172,7 +172,7 @@ static void sigint_handler(int x) { _exit(0); } int main(int argc, char** argv) { grpc_event ev; call_state* s; - char* addr_buf = nullptr; + grpc_core::UniquePtr addr_buf; gpr_cmdline* cl; grpc_completion_queue* shutdown_cq; int shutdown_started = 0; @@ -199,8 +199,8 @@ int main(int argc, char** argv) { gpr_cmdline_destroy(cl); if (addr == nullptr) { - gpr_join_host_port(&addr_buf, "::", grpc_pick_unused_port_or_die()); - addr = addr_buf; + grpc_core::JoinHostPort(&addr_buf, "::", grpc_pick_unused_port_or_die()); + addr = addr_buf.get(); } gpr_log(GPR_INFO, "creating server on: %s", addr); @@ -220,8 +220,8 @@ int main(int argc, char** argv) { grpc_server_register_completion_queue(server, cq, nullptr); grpc_server_start(server); - gpr_free(addr_buf); - addr = addr_buf = nullptr; + addr = nullptr; + addr_buf.reset(); grpc_call_details_init(&call_details); diff --git a/test/core/gpr/BUILD b/test/core/gpr/BUILD index 434d55e0451..c2b2576ff03 100644 --- a/test/core/gpr/BUILD +++ b/test/core/gpr/BUILD @@ -58,16 +58,6 @@ grpc_cc_test( ], ) -grpc_cc_test( - name = "host_port_test", - srcs = ["host_port_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//test/core/util:grpc_test_util", - ], -) - grpc_cc_test( name = "log_test", srcs = ["log_test.cc"], diff --git a/test/core/gpr/host_port_test.cc b/test/core/gpr/host_port_test.cc deleted file mode 100644 index b01bbf4b695..00000000000 --- a/test/core/gpr/host_port_test.cc +++ /dev/null @@ -1,59 +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 - -#include -#include - -#include "src/core/lib/gpr/host_port.h" -#include "test/core/util/test_config.h" - -static void join_host_port_expect(const char* host, int port, - const char* expected) { - char* buf; - int len; - len = gpr_join_host_port(&buf, host, port); - GPR_ASSERT(len >= 0); - GPR_ASSERT(strlen(expected) == (size_t)len); - GPR_ASSERT(strcmp(expected, buf) == 0); - gpr_free(buf); -} - -static void test_join_host_port(void) { - join_host_port_expect("foo", 101, "foo:101"); - join_host_port_expect("", 102, ":102"); - join_host_port_expect("1::2", 103, "[1::2]:103"); - join_host_port_expect("[::1]", 104, "[::1]:104"); -} - -/* Garbage in, garbage out. */ -static void test_join_host_port_garbage(void) { - join_host_port_expect("[foo]", 105, "[foo]:105"); - join_host_port_expect("[::", 106, "[:::106"); - join_host_port_expect("::]", 107, "[::]]:107"); -} - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - - test_join_host_port(); - test_join_host_port_garbage(); - - return 0; -} diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index cd3232addfd..5cee96a3ad2 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -64,6 +64,16 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "host_port_test", + srcs = ["host_port_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "grpc_core_map_test", srcs = ["map_test.cc"], @@ -156,6 +166,19 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "string_view_test", + srcs = ["string_view_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr_base", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "thd_test", srcs = ["thd_test.cc"], diff --git a/test/core/gprpp/host_port_test.cc b/test/core/gprpp/host_port_test.cc new file mode 100644 index 00000000000..3b392da66e8 --- /dev/null +++ b/test/core/gprpp/host_port_test.cc @@ -0,0 +1,94 @@ +/* + * + * 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 + +#include +#include + +#include "src/core/lib/gprpp/host_port.h" +#include "test/core/util/test_config.h" + +static void join_host_port_expect(const char* host, int port, + const char* expected) { + grpc_core::UniquePtr buf; + int len; + len = grpc_core::JoinHostPort(&buf, host, port); + GPR_ASSERT(len >= 0); + GPR_ASSERT(strlen(expected) == static_cast(len)); + GPR_ASSERT(strcmp(expected, buf.get()) == 0); +} + +static void test_join_host_port(void) { + join_host_port_expect("foo", 101, "foo:101"); + join_host_port_expect("", 102, ":102"); + join_host_port_expect("1::2", 103, "[1::2]:103"); + join_host_port_expect("[::1]", 104, "[::1]:104"); +} + +/* Garbage in, garbage out. */ +static void test_join_host_port_garbage(void) { + join_host_port_expect("[foo]", 105, "[foo]:105"); + join_host_port_expect("[::", 106, "[:::106"); + join_host_port_expect("::]", 107, "[::]]:107"); +} + +static void split_host_port_expect(const char* name, const char* host, + const char* port, bool ret) { + grpc_core::UniquePtr actual_host; + grpc_core::UniquePtr actual_port; + const bool actual_ret = + grpc_core::SplitHostPort(name, &actual_host, &actual_port); + GPR_ASSERT(actual_ret == ret); + if (host == nullptr) { + GPR_ASSERT(actual_host == nullptr); + } else { + GPR_ASSERT(strcmp(host, actual_host.get()) == 0); + } + if (port == nullptr) { + GPR_ASSERT(actual_port == nullptr); + } else { + GPR_ASSERT(strcmp(port, actual_port.get()) == 0); + } +} + +static void test_split_host_port() { + split_host_port_expect("", "", nullptr, true); + split_host_port_expect("[a:b]", "a:b", nullptr, true); + split_host_port_expect("1.2.3.4", "1.2.3.4", nullptr, true); + split_host_port_expect("a:b:c::", "a:b:c::", nullptr, true); + split_host_port_expect("[a:b]:30", "a:b", "30", true); + split_host_port_expect("1.2.3.4:30", "1.2.3.4", "30", true); + split_host_port_expect(":30", "", "30", true); +} + +static void test_split_host_port_invalid() { + split_host_port_expect("[a:b", nullptr, nullptr, false); + split_host_port_expect("[a:b]30", nullptr, nullptr, false); +} + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + + test_join_host_port(); + test_join_host_port_garbage(); + test_split_host_port(); + test_split_host_port_invalid(); + + return 0; +} diff --git a/test/core/gprpp/string_view_test.cc b/test/core/gprpp/string_view_test.cc new file mode 100644 index 00000000000..1c8adb1db14 --- /dev/null +++ b/test/core/gprpp/string_view_test.cc @@ -0,0 +1,163 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/gprpp/string_view.h" + +#include +#include "src/core/lib/gprpp/memory.h" +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace testing { + +TEST(StringViewTest, Empty) { + grpc_core::StringView empty; + EXPECT_TRUE(empty.empty()); + EXPECT_EQ(empty.size(), 0lu); + + grpc_core::StringView empty_buf(""); + EXPECT_TRUE(empty_buf.empty()); + EXPECT_EQ(empty_buf.size(), 0lu); + + grpc_core::StringView empty_trimmed("foo", 0); + EXPECT_TRUE(empty_trimmed.empty()); + EXPECT_EQ(empty_trimmed.size(), 0lu); + + grpc_core::StringView empty_slice(grpc_empty_slice()); + EXPECT_TRUE(empty_slice.empty()); + EXPECT_EQ(empty_slice.size(), 0lu); +} + +TEST(StringViewTest, Size) { + constexpr char kStr[] = "foo"; + grpc_core::StringView str1(kStr); + EXPECT_EQ(str1.size(), strlen(kStr)); + grpc_core::StringView str2(kStr, 2); + EXPECT_EQ(str2.size(), 2lu); +} + +TEST(StringViewTest, Data) { + constexpr char kStr[] = "foo-bar"; + grpc_core::StringView str(kStr); + EXPECT_EQ(str.size(), strlen(kStr)); + for (size_t i = 0; i < strlen(kStr); ++i) { + EXPECT_EQ(str[i], kStr[i]); + } +} + +TEST(StringViewTest, Slice) { + constexpr char kStr[] = "foo"; + grpc_core::StringView slice(grpc_slice_from_static_string(kStr)); + EXPECT_EQ(slice.size(), strlen(kStr)); +} + +TEST(StringViewTest, Dup) { + constexpr char kStr[] = "foo"; + grpc_core::StringView slice(grpc_slice_from_static_string(kStr)); + grpc_core::UniquePtr dup = slice.dup(); + EXPECT_EQ(0, strcmp(kStr, dup.get())); + EXPECT_EQ(slice.size(), strlen(kStr)); +} + +TEST(StringViewTest, Eq) { + constexpr char kStr1[] = "foo"; + constexpr char kStr2[] = "bar"; + grpc_core::StringView str1(kStr1); + EXPECT_EQ(kStr1, str1); + EXPECT_EQ(str1, kStr1); + grpc_core::StringView slice1(grpc_slice_from_static_string(kStr1)); + EXPECT_EQ(slice1, str1); + EXPECT_EQ(str1, slice1); + EXPECT_NE(slice1, kStr2); + EXPECT_NE(kStr2, slice1); + grpc_core::StringView slice2(grpc_slice_from_static_string(kStr2)); + EXPECT_NE(slice2, str1); + EXPECT_NE(str1, slice2); +} + +TEST(StringViewTest, Cmp) { + constexpr char kStr1[] = "abc"; + constexpr char kStr2[] = "abd"; + constexpr char kStr3[] = "abcd"; + grpc_core::StringView str1(kStr1); + grpc_core::StringView str2(kStr2); + grpc_core::StringView str3(kStr3); + EXPECT_EQ(str1.cmp(str1), 0); + EXPECT_LT(str1.cmp(str2), 0); + EXPECT_LT(str1.cmp(str3), 0); + EXPECT_EQ(str2.cmp(str2), 0); + EXPECT_GT(str2.cmp(str1), 0); + EXPECT_GT(str2.cmp(str3), 0); + EXPECT_EQ(str3.cmp(str3), 0); + EXPECT_GT(str3.cmp(str1), 0); + EXPECT_LT(str3.cmp(str2), 0); +} + +TEST(StringViewTest, RemovePrefix) { + constexpr char kStr[] = "abcd"; + grpc_core::StringView str(kStr); + str.remove_prefix(1); + EXPECT_EQ("bcd", str); + str.remove_prefix(2); + EXPECT_EQ("d", str); + str.remove_prefix(1); + EXPECT_EQ("", str); +} + +TEST(StringViewTest, RemoveSuffix) { + constexpr char kStr[] = "abcd"; + grpc_core::StringView str(kStr); + str.remove_suffix(1); + EXPECT_EQ("abc", str); + str.remove_suffix(2); + EXPECT_EQ("a", str); + str.remove_suffix(1); + EXPECT_EQ("", str); +} + +TEST(StringViewTest, Substring) { + constexpr char kStr[] = "abcd"; + grpc_core::StringView str(kStr); + EXPECT_EQ("bcd", str.substr(1)); + EXPECT_EQ("bc", str.substr(1, 2)); +} + +TEST(StringViewTest, Find) { + // Passing StringView::npos directly to GTEST macros result in link errors. + // Store the value in a local variable and use it in the test. + const size_t npos = grpc_core::StringView::npos; + constexpr char kStr[] = "abacad"; + grpc_core::StringView str(kStr); + EXPECT_EQ(0ul, str.find('a')); + EXPECT_EQ(2ul, str.find('a', 1)); + EXPECT_EQ(4ul, str.find('a', 3)); + EXPECT_EQ(1ul, str.find('b')); + EXPECT_EQ(npos, str.find('b', 2)); + EXPECT_EQ(npos, str.find('z')); +} + +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 1aefa0ab224..af67d5de25e 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -130,6 +130,17 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "mpmcqueue_test", + srcs = ["mpmcqueue_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "resolve_address_using_ares_resolver_posix_test", srcs = ["resolve_address_posix_test.cc"], diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc new file mode 100644 index 00000000000..a301832f608 --- /dev/null +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -0,0 +1,178 @@ +/* + * + * 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. + * + */ + +#include "src/core/lib/iomgr/executor/mpmcqueue.h" + +#include + +#include "src/core/lib/gprpp/thd.h" +#include "test/core/util/test_config.h" + +#define TEST_NUM_ITEMS 10000 + +// Testing items for queue +struct WorkItem { + int index; + bool done; + + WorkItem(int i) : index(i) { done = false; } +}; + +// Thread to "produce" items and put items into queue +// It will also check that all items has been marked done and clean up all +// produced items on destructing. +class ProducerThread { + public: + ProducerThread(grpc_core::InfLenFIFOQueue* queue, int start_index, + int num_items) + : start_index_(start_index), num_items_(num_items), queue_(queue) { + items_ = nullptr; + thd_ = grpc_core::Thread( + "mpmcq_test_producer_thd", + [](void* th) { static_cast(th)->Run(); }, this); + } + ~ProducerThread() { + for (int i = 0; i < num_items_; ++i) { + GPR_ASSERT(items_[i]->done); + grpc_core::Delete(items_[i]); + } + gpr_free(items_); + } + + void Start() { thd_.Start(); } + void Join() { thd_.Join(); } + + private: + void Run() { + items_ = + static_cast(gpr_zalloc(num_items_ * sizeof(WorkItem*))); + for (int i = 0; i < num_items_; ++i) { + items_[i] = grpc_core::New(start_index_ + i); + queue_->Put(items_[i]); + } + } + + int start_index_; + int num_items_; + grpc_core::InfLenFIFOQueue* queue_; + grpc_core::Thread thd_; + WorkItem** items_; +}; + +// Thread to pull out items from queue +class ConsumerThread { + public: + ConsumerThread(grpc_core::InfLenFIFOQueue* queue) : queue_(queue) { + thd_ = grpc_core::Thread( + "mpmcq_test_consumer_thd", + [](void* th) { static_cast(th)->Run(); }, this); + } + ~ConsumerThread() {} + + void Start() { thd_.Start(); } + void Join() { thd_.Join(); } + + private: + void Run() { + // count number of Get() called in this thread + int count = 0; + + WorkItem* item; + while ((item = static_cast(queue_->Get())) != nullptr) { + count++; + GPR_ASSERT(!item->done); + item->done = true; + } + + gpr_log(GPR_DEBUG, "ConsumerThread: %d times of Get() called.", count); + } + grpc_core::InfLenFIFOQueue* queue_; + grpc_core::Thread thd_; +}; + +static void test_FIFO(void) { + gpr_log(GPR_INFO, "test_FIFO"); + grpc_core::InfLenFIFOQueue large_queue; + for (int i = 0; i < TEST_NUM_ITEMS; ++i) { + large_queue.Put(static_cast(grpc_core::New(i))); + } + GPR_ASSERT(large_queue.count() == TEST_NUM_ITEMS); + for (int i = 0; i < TEST_NUM_ITEMS; ++i) { + WorkItem* item = static_cast(large_queue.Get()); + GPR_ASSERT(i == item->index); + grpc_core::Delete(item); + } +} + +static void test_many_thread(void) { + gpr_log(GPR_INFO, "test_many_thread"); + const int num_producer_threads = 10; + const int num_consumer_threads = 20; + grpc_core::InfLenFIFOQueue queue; + ProducerThread** producer_threads = static_cast( + gpr_zalloc(num_producer_threads * sizeof(ProducerThread*))); + ConsumerThread** consumer_threads = static_cast( + gpr_zalloc(num_consumer_threads * sizeof(ConsumerThread*))); + + gpr_log(GPR_DEBUG, "Fork ProducerThreads..."); + for (int i = 0; i < num_producer_threads; ++i) { + producer_threads[i] = grpc_core::New( + &queue, i * TEST_NUM_ITEMS, TEST_NUM_ITEMS); + producer_threads[i]->Start(); + } + gpr_log(GPR_DEBUG, "ProducerThreads Started."); + gpr_log(GPR_DEBUG, "Fork ConsumerThreads..."); + for (int i = 0; i < num_consumer_threads; ++i) { + consumer_threads[i] = grpc_core::New(&queue); + consumer_threads[i]->Start(); + } + gpr_log(GPR_DEBUG, "ConsumerThreads Started."); + gpr_log(GPR_DEBUG, "Waiting ProducerThreads to finish..."); + for (int i = 0; i < num_producer_threads; ++i) { + producer_threads[i]->Join(); + } + gpr_log(GPR_DEBUG, "All ProducerThreads Terminated."); + gpr_log(GPR_DEBUG, "Terminating ConsumerThreads..."); + for (int i = 0; i < num_consumer_threads; ++i) { + queue.Put(nullptr); + } + for (int i = 0; i < num_consumer_threads; ++i) { + consumer_threads[i]->Join(); + } + gpr_log(GPR_DEBUG, "All ConsumerThreads Terminated."); + gpr_log(GPR_DEBUG, "Checking WorkItems and Cleaning Up..."); + for (int i = 0; i < num_producer_threads; ++i) { + // Destructor of ProducerThread will do the check of WorkItems + grpc_core::Delete(producer_threads[i]); + } + gpr_free(producer_threads); + for (int i = 0; i < num_consumer_threads; ++i) { + grpc_core::Delete(consumer_threads[i]); + } + gpr_free(consumer_threads); + gpr_log(GPR_DEBUG, "Done."); +} + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + grpc_init(); + test_FIFO(); + test_many_thread(); + grpc_shutdown(); + return 0; +} diff --git a/test/core/memory_usage/memory_usage_test.cc b/test/core/memory_usage/memory_usage_test.cc index 5c35b4e1d36..5df8af5658b 100644 --- a/test/core/memory_usage/memory_usage_test.cc +++ b/test/core/memory_usage/memory_usage_test.cc @@ -22,8 +22,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -46,22 +46,23 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/memory_usage_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/memory_usage_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - gpr_join_host_port(&args[2], "127.0.0.1", port); + grpc_core::JoinHostPort(&joined, "127.0.0.1", port); + args[2] = joined.get(); args[3] = const_cast("--warmup=1000"); args[4] = const_cast("--benchmark=9000"); cli = gpr_subprocess_create(5, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 6fb14fa31a0..ecdf17925ec 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -33,7 +33,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/cmdline.h" #include "test/core/util/memory_counters.h" @@ -149,7 +149,7 @@ static void sigint_handler(int x) { _exit(0); } int main(int argc, char** argv) { grpc_memory_counters_init(); grpc_event ev; - char* addr_buf = nullptr; + grpc_core::UniquePtr addr_buf; gpr_cmdline* cl; grpc_completion_queue* shutdown_cq; int shutdown_started = 0; @@ -174,8 +174,8 @@ int main(int argc, char** argv) { gpr_cmdline_destroy(cl); if (addr == nullptr) { - gpr_join_host_port(&addr_buf, "::", grpc_pick_unused_port_or_die()); - addr = addr_buf; + grpc_core::JoinHostPort(&addr_buf, "::", grpc_pick_unused_port_or_die()); + addr = addr_buf.get(); } gpr_log(GPR_INFO, "creating server on: %s", addr); @@ -202,8 +202,8 @@ int main(int argc, char** argv) { struct grpc_memory_counters after_server_create = grpc_memory_counters_snapshot(); - gpr_free(addr_buf); - addr = addr_buf = nullptr; + addr = nullptr; + addr_buf.reset(); // initialize call instances for (int i = 0; i < static_cast(sizeof(calls) / sizeof(fling_call)); diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index 141346bca94..cbce595c354 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -24,8 +24,8 @@ #include #include +#include #include - #include #include #include @@ -34,13 +34,16 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/http/httpcli.h" +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/credentials/composite/composite_credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/lib/security/credentials/google_default/google_default_credentials.h" #include "src/core/lib/security/credentials/jwt/jwt_credentials.h" #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h" #include "src/core/lib/security/transport/auth_filters.h" +#include "src/core/lib/uri/uri_parser.h" #include "test/core/util/test_config.h" using grpc_core::internal::grpc_flush_cached_google_default_credentials; @@ -99,15 +102,27 @@ static const char valid_oauth2_json_response[] = " \"expires_in\":3599, " " \"token_type\":\"Bearer\"}"; +static const char valid_sts_json_response[] = + "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\"," + " \"expires_in\":3599, " + " \"issued_token_type\":\"urn:ietf:params:oauth:token-type:access_token\", " + " \"token_type\":\"Bearer\"}"; + static const char test_scope[] = "perm1 perm2"; static const char test_signed_jwt[] = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImY0OTRkN2M1YWU2MGRmOTcyNmM4YW" "U0MDcyZTViYTdmZDkwODg2YzcifQ"; +static const char test_signed_jwt_token_type[] = + "urn:ietf:params:oauth:token-type:id_token"; +static const char test_signed_jwt_path_prefix[] = "test_sign_jwt"; static const char test_service_url[] = "https://foo.com/foo.v1"; static const char other_test_service_url[] = "https://bar.com/bar.v1"; +static const char test_sts_endpoint_url[] = + "https://foo.com:5555/v1/token-exchange"; + static const char test_method[] = "ThisIsNotAMethod"; /* -- Global state flags. -- */ @@ -657,11 +672,11 @@ static int refresh_token_httpcli_post_success( return 1; } -static int refresh_token_httpcli_post_failure( - const grpc_httpcli_request* request, const char* body, size_t body_size, - grpc_millis deadline, grpc_closure* on_done, - grpc_httpcli_response* response) { - validate_refresh_token_http_request(request, body, body_size); +static int token_httpcli_post_failure(const grpc_httpcli_request* request, + const char* body, size_t body_size, + grpc_millis deadline, + grpc_closure* on_done, + grpc_httpcli_response* response) { *response = http_response(403, "Not Authorized."); GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); return 1; @@ -676,7 +691,7 @@ static void test_refresh_token_creds_success(void) { grpc_call_credentials* creds = grpc_google_refresh_token_credentials_create( test_refresh_token_str, nullptr); - /* First request: http get should be called. */ + /* First request: http put should be called. */ request_metadata_state* state = make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd)); grpc_httpcli_set_override(httpcli_get_should_not_be_called, @@ -707,12 +722,281 @@ static void test_refresh_token_creds_failure(void) { grpc_call_credentials* creds = grpc_google_refresh_token_credentials_create( test_refresh_token_str, nullptr); grpc_httpcli_set_override(httpcli_get_should_not_be_called, - refresh_token_httpcli_post_failure); + token_httpcli_post_failure); run_request_metadata_test(creds, auth_md_ctx, state); creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } +static void test_valid_sts_creds_options(void) { + grpc_sts_credentials_options valid_options = { + test_sts_endpoint_url, // sts_endpoint_url + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + test_signed_jwt_path_prefix, // subject_token_path + test_signed_jwt_token_type, // subject_token_type + nullptr, // actor_token_path + nullptr // actor_token_type + }; + grpc_uri* sts_url; + grpc_error* error = + grpc_core::ValidateStsCredentialsOptions(&valid_options, &sts_url); + GPR_ASSERT(error == GRPC_ERROR_NONE); + GPR_ASSERT(sts_url != nullptr); + grpc_core::StringView host; + grpc_core::StringView port; + GPR_ASSERT(grpc_core::SplitHostPort(sts_url->authority, &host, &port)); + GPR_ASSERT(host.cmp("foo.com") == 0); + GPR_ASSERT(port.cmp("5555") == 0); + grpc_uri_destroy(sts_url); +} + +static void test_invalid_sts_creds_options(void) { + grpc_sts_credentials_options invalid_options = { + test_sts_endpoint_url, // sts_endpoint_url + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + nullptr, // subject_token_path (Required) + test_signed_jwt_token_type, // subject_token_type + nullptr, // actor_token_path + nullptr // actor_token_type + }; + grpc_uri* url_should_be_null; + grpc_error* error = grpc_core::ValidateStsCredentialsOptions( + &invalid_options, &url_should_be_null); + GPR_ASSERT(error != GRPC_ERROR_NONE); + GRPC_ERROR_UNREF(error); + GPR_ASSERT(url_should_be_null == nullptr); + + invalid_options = { + test_sts_endpoint_url, // sts_endpoint_url + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + test_signed_jwt_path_prefix, // subject_token_path + nullptr, // subject_token_type (Required) + nullptr, // actor_token_path + nullptr // actor_token_type + }; + error = grpc_core::ValidateStsCredentialsOptions(&invalid_options, + &url_should_be_null); + GPR_ASSERT(error != GRPC_ERROR_NONE); + GRPC_ERROR_UNREF(error); + GPR_ASSERT(url_should_be_null == nullptr); + + invalid_options = { + nullptr, // sts_endpoint_url (Required) + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + test_signed_jwt_path_prefix, // subject_token_path + test_signed_jwt_token_type, // subject_token_type (Required) + nullptr, // actor_token_path + nullptr // actor_token_type + }; + error = grpc_core::ValidateStsCredentialsOptions(&invalid_options, + &url_should_be_null); + GPR_ASSERT(error != GRPC_ERROR_NONE); + GRPC_ERROR_UNREF(error); + GPR_ASSERT(url_should_be_null == nullptr); + + invalid_options = { + "not_a_valid_uri", // sts_endpoint_url + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + test_signed_jwt_path_prefix, // subject_token_path + test_signed_jwt_token_type, // subject_token_type (Required) + nullptr, // actor_token_path + nullptr // actor_token_type + }; + error = grpc_core::ValidateStsCredentialsOptions(&invalid_options, + &url_should_be_null); + GPR_ASSERT(error != GRPC_ERROR_NONE); + GRPC_ERROR_UNREF(error); + GPR_ASSERT(url_should_be_null == nullptr); + + invalid_options = { + "ftp://ftp.is.not.a.valid.scheme/bar", // sts_endpoint_url + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + test_signed_jwt_path_prefix, // subject_token_path + test_signed_jwt_token_type, // subject_token_type (Required) + nullptr, // actor_token_path + nullptr // actor_token_type + }; + error = grpc_core::ValidateStsCredentialsOptions(&invalid_options, + &url_should_be_null); + GPR_ASSERT(error != GRPC_ERROR_NONE); + GRPC_ERROR_UNREF(error); + GPR_ASSERT(url_should_be_null == nullptr); +} + +static void validate_sts_token_http_request(const grpc_httpcli_request* request, + const char* body, + size_t body_size) { + // Check that the body is constructed properly. + GPR_ASSERT(body != nullptr); + GPR_ASSERT(body_size != 0); + GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl); + char* get_url_equivalent; + gpr_asprintf(&get_url_equivalent, "%s?%s", test_sts_endpoint_url, body); + grpc_uri* url = grpc_uri_parse(get_url_equivalent, false); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "resource"), "resource") == 0); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "audience"), "audience") == 0); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "scope"), "scope") == 0); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "requested_token_type"), + "requested_token_type") == 0); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "subject_token"), + test_signed_jwt) == 0); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "subject_token_type"), + test_signed_jwt_token_type) == 0); + GPR_ASSERT(grpc_uri_get_query_arg(url, "actor_token") == nullptr); + GPR_ASSERT(grpc_uri_get_query_arg(url, "actor_token_type") == nullptr); + grpc_uri_destroy(url); + gpr_free(get_url_equivalent); + + // Check the rest of the request. + GPR_ASSERT(strcmp(request->host, "foo.com:5555") == 0); + GPR_ASSERT(strcmp(request->http.path, "/v1/token-exchange") == 0); + GPR_ASSERT(request->http.hdr_count == 1); + GPR_ASSERT(strcmp(request->http.hdrs[0].key, "Content-Type") == 0); + GPR_ASSERT(strcmp(request->http.hdrs[0].value, + "application/x-www-form-urlencoded") == 0); +} + +static int sts_token_httpcli_post_success(const grpc_httpcli_request* request, + const char* body, size_t body_size, + grpc_millis deadline, + grpc_closure* on_done, + grpc_httpcli_response* response) { + validate_sts_token_http_request(request, body, body_size); + *response = http_response(200, valid_sts_json_response); + GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + return 1; +} + +static char* write_tmp_jwt_file(void) { + char* path; + FILE* tmp = gpr_tmpfile(test_signed_jwt_path_prefix, &path); + GPR_ASSERT(path != nullptr); + GPR_ASSERT(tmp != nullptr); + size_t jwt_length = strlen(test_signed_jwt); + GPR_ASSERT(fwrite(test_signed_jwt, 1, jwt_length, tmp) == jwt_length); + fclose(tmp); + return path; +} + +static void test_sts_creds_success(void) { + grpc_core::ExecCtx exec_ctx; + expected_md emd[] = { + {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}}; + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, + nullptr, nullptr}; + char* test_signed_jwt_path = write_tmp_jwt_file(); + grpc_sts_credentials_options valid_options = { + test_sts_endpoint_url, // sts_endpoint_url + "resource", // resource + "audience", // audience + "scope", // scope + "requested_token_type", // requested_token_type + test_signed_jwt_path, // subject_token_path + test_signed_jwt_token_type, // subject_token_type + nullptr, // actor_token_path + nullptr // actor_token_type + }; + grpc_call_credentials* creds = + grpc_sts_credentials_create(&valid_options, nullptr); + + /* First request: http put should be called. */ + request_metadata_state* state = + make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd)); + grpc_httpcli_set_override(httpcli_get_should_not_be_called, + sts_token_httpcli_post_success); + run_request_metadata_test(creds, auth_md_ctx, state); + grpc_core::ExecCtx::Get()->Flush(); + + /* Second request: the cached token should be served directly. */ + state = + make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd)); + grpc_httpcli_set_override(httpcli_get_should_not_be_called, + httpcli_post_should_not_be_called); + run_request_metadata_test(creds, auth_md_ctx, state); + grpc_core::ExecCtx::Get()->Flush(); + + creds->Unref(); + grpc_httpcli_set_override(nullptr, nullptr); + gpr_free(test_signed_jwt_path); +} + +static void test_sts_creds_load_token_failure(void) { + grpc_core::ExecCtx exec_ctx; + request_metadata_state* state = make_request_metadata_state( + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Error occurred when fetching oauth2 token."), + nullptr, 0); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, + nullptr, nullptr}; + char* test_signed_jwt_path = write_tmp_jwt_file(); + grpc_sts_credentials_options options = { + test_sts_endpoint_url, // sts_endpoint_url + "resource", // resource + "audience", // audience + "scope", // scope + "requested_token_type", // requested_token_type + "invalid_path", // subject_token_path + test_signed_jwt_token_type, // subject_token_type + nullptr, // actor_token_path + nullptr // actor_token_type + }; + grpc_call_credentials* creds = grpc_sts_credentials_create(&options, nullptr); + grpc_httpcli_set_override(httpcli_get_should_not_be_called, + httpcli_post_should_not_be_called); + run_request_metadata_test(creds, auth_md_ctx, state); + creds->Unref(); + grpc_httpcli_set_override(nullptr, nullptr); + gpr_free(test_signed_jwt_path); +} + +static void test_sts_creds_http_failure(void) { + grpc_core::ExecCtx exec_ctx; + request_metadata_state* state = make_request_metadata_state( + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Error occurred when fetching oauth2 token."), + nullptr, 0); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, + nullptr, nullptr}; + char* test_signed_jwt_path = write_tmp_jwt_file(); + grpc_sts_credentials_options valid_options = { + test_sts_endpoint_url, // sts_endpoint_url + "resource", // resource + "audience", // audience + "scope", // scope + "requested_token_type", // requested_token_type + test_signed_jwt_path, // subject_token_path + test_signed_jwt_token_type, // subject_token_type + nullptr, // actor_token_path + nullptr // actor_token_type + }; + grpc_call_credentials* creds = + grpc_sts_credentials_create(&valid_options, nullptr); + grpc_httpcli_set_override(httpcli_get_should_not_be_called, + token_httpcli_post_failure); + run_request_metadata_test(creds, auth_md_ctx, state); + creds->Unref(); + grpc_httpcli_set_override(nullptr, nullptr); + gpr_free(test_signed_jwt_path); +} + static void validate_jwt_encode_and_sign_params( const grpc_auth_json_key* json_key, const char* scope, gpr_timespec token_lifetime) { @@ -1288,6 +1572,11 @@ int main(int argc, char** argv) { test_compute_engine_creds_failure(); test_refresh_token_creds_success(); test_refresh_token_creds_failure(); + test_valid_sts_creds_options(); + test_invalid_sts_creds_options(); + test_sts_creds_success(); + test_sts_creds_load_token_failure(); + test_sts_creds_http_failure(); test_jwt_creds_lifetime(); test_jwt_creds_success(); test_jwt_creds_signing_failure(); diff --git a/test/core/security/fetch_oauth2.cc b/test/core/security/fetch_oauth2.cc index 82efe682be0..d404368b8b9 100644 --- a/test/core/security/fetch_oauth2.cc +++ b/test/core/security/fetch_oauth2.cc @@ -26,33 +26,82 @@ #include #include +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/util/json_util.h" #include "test/core/security/oauth2_utils.h" #include "test/core/util/cmdline.h" +static grpc_sts_credentials_options sts_options_from_json(grpc_json* json) { + grpc_sts_credentials_options options; + memset(&options, 0, sizeof(options)); + grpc_error* error = GRPC_ERROR_NONE; + options.sts_endpoint_url = + grpc_json_get_string_property(json, "sts_endpoint_url", &error); + GRPC_LOG_IF_ERROR("STS credentials parsing", error); + options.resource = grpc_json_get_string_property(json, "resource", nullptr); + options.audience = grpc_json_get_string_property(json, "audience", nullptr); + options.scope = grpc_json_get_string_property(json, "scope", nullptr); + options.requested_token_type = + grpc_json_get_string_property(json, "requested_token_type", nullptr); + options.subject_token_path = + grpc_json_get_string_property(json, "subject_token_path", &error); + GRPC_LOG_IF_ERROR("STS credentials parsing", error); + options.subject_token_type = + grpc_json_get_string_property(json, "subject_token_type", &error); + GRPC_LOG_IF_ERROR("STS credentials parsing", error); + options.actor_token_path = + grpc_json_get_string_property(json, "actor_token_path", nullptr); + options.actor_token_type = + grpc_json_get_string_property(json, "actor_token_type", nullptr); + return options; +} + +static grpc_call_credentials* create_sts_creds(const char* json_file_path) { + grpc_slice sts_options_slice; + GPR_ASSERT(GRPC_LOG_IF_ERROR( + "load_file", grpc_load_file(json_file_path, 1, &sts_options_slice))); + grpc_json* json = grpc_json_parse_string( + reinterpret_cast(GRPC_SLICE_START_PTR(sts_options_slice))); + if (json == nullptr) { + gpr_log(GPR_ERROR, "Invalid json"); + return nullptr; + } + grpc_sts_credentials_options options = sts_options_from_json(json); + grpc_call_credentials* result = + grpc_sts_credentials_create(&options, nullptr); + grpc_json_destroy(json); + gpr_slice_unref(sts_options_slice); + return result; +} + static grpc_call_credentials* create_refresh_token_creds( const char* json_refresh_token_file_path) { grpc_slice refresh_token; GPR_ASSERT(GRPC_LOG_IF_ERROR( "load_file", grpc_load_file(json_refresh_token_file_path, 1, &refresh_token))); - return grpc_google_refresh_token_credentials_create( + grpc_call_credentials* result = grpc_google_refresh_token_credentials_create( reinterpret_cast GRPC_SLICE_START_PTR(refresh_token), nullptr); + gpr_slice_unref(refresh_token); + return result; } int main(int argc, char** argv) { grpc_call_credentials* creds = nullptr; - char* json_key_file_path = nullptr; + const char* json_sts_options_file_path = nullptr; const char* json_refresh_token_file_path = nullptr; char* token = nullptr; int use_gce = 0; - char* scope = nullptr; gpr_cmdline* cl = gpr_cmdline_create("fetch_oauth2"); gpr_cmdline_add_string(cl, "json_refresh_token", "File path of the json refresh token.", &json_refresh_token_file_path); + gpr_cmdline_add_string(cl, "json_sts_options", + "File path of the json sts options.", + &json_sts_options_file_path); gpr_cmdline_add_flag( cl, "gce", "Get a token from the GCE metadata server (only works in GCE).", @@ -61,18 +110,20 @@ int main(int argc, char** argv) { grpc_init(); - if (json_key_file_path != nullptr && + if (json_sts_options_file_path != nullptr && json_refresh_token_file_path != nullptr) { - gpr_log(GPR_ERROR, - "--json_key and --json_refresh_token are mutually exclusive."); + gpr_log( + GPR_ERROR, + "--json_sts_options and --json_refresh_token are mutually exclusive."); exit(1); } if (use_gce) { - if (json_key_file_path != nullptr || scope != nullptr) { + if (json_sts_options_file_path != nullptr || + json_refresh_token_file_path != nullptr) { gpr_log(GPR_INFO, - "Ignoring json key and scope to get a token from the GCE " - "metadata server."); + "Ignoring json refresh token or sts options to get a token from " + "the GCE metadata server."); } creds = grpc_google_compute_engine_credentials_create(nullptr); if (creds == nullptr) { @@ -88,8 +139,19 @@ int main(int argc, char** argv) { json_refresh_token_file_path); exit(1); } + } else if (json_sts_options_file_path != nullptr) { + creds = create_sts_creds(json_sts_options_file_path); + if (creds == nullptr) { + gpr_log(GPR_ERROR, + "Could not create sts creds. %s does probably not contain a " + "valid json for sts options.", + json_sts_options_file_path); + exit(1); + } } else { - gpr_log(GPR_ERROR, "Missing --gce or --json_refresh_token option."); + gpr_log( + GPR_ERROR, + "Missing --gce, --json_sts_options, or --json_refresh_token option."); exit(1); } GPR_ASSERT(creds != nullptr); diff --git a/test/core/security/jwt_verifier_test.cc b/test/core/security/jwt_verifier_test.cc index 70155cdd065..21a7aa47b9d 100644 --- a/test/core/security/jwt_verifier_test.cc +++ b/test/core/security/jwt_verifier_test.cc @@ -128,9 +128,9 @@ static const char good_openid_config[] = " \"issuer\": \"https://accounts.google.com\"," " \"authorization_endpoint\": " "\"https://accounts.google.com/o/oauth2/v2/auth\"," - " \"token_endpoint\": \"https://www.googleapis.com/oauth2/v4/token\"," + " \"token_endpoint\": \"https://oauth2.googleapis.com/token\"," " \"userinfo_endpoint\": \"https://www.googleapis.com/oauth2/v3/userinfo\"," - " \"revocation_endpoint\": \"https://accounts.google.com/o/oauth2/revoke\"," + " \"revocation_endpoint\": \"https://oauth2.googleapis.com/revoke\"," " \"jwks_uri\": \"https://www.googleapis.com/oauth2/v3/certs\"" "}"; diff --git a/test/core/security/oauth2_utils.cc b/test/core/security/oauth2_utils.cc index c9e205ab743..b24e7c180e1 100644 --- a/test/core/security/oauth2_utils.cc +++ b/test/core/security/oauth2_utils.cc @@ -63,14 +63,17 @@ static void on_oauth2_response(void* arg, grpc_error* error) { gpr_mu_unlock(request->mu); } -static void do_nothing(void* unused, grpc_error* error) {} +static void destroy_after_shutdown(void* pollset, grpc_error* error) { + grpc_pollset_destroy(reinterpret_cast(pollset)); + gpr_free(pollset); +} char* grpc_test_fetch_oauth2_token_with_credentials( grpc_call_credentials* creds) { oauth2_request request; memset(&request, 0, sizeof(request)); grpc_core::ExecCtx exec_ctx; - grpc_closure do_nothing_closure; + grpc_closure destroy_after_shutdown_closure; grpc_auth_metadata_context null_ctx = {"", "", nullptr, nullptr}; grpc_pollset* pollset = @@ -79,8 +82,8 @@ char* grpc_test_fetch_oauth2_token_with_credentials( request.pops = grpc_polling_entity_create_from_pollset(pollset); request.is_done = false; - GRPC_CLOSURE_INIT(&do_nothing_closure, do_nothing, nullptr, - grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&destroy_after_shutdown_closure, destroy_after_shutdown, + pollset, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&request.closure, on_oauth2_response, &request, grpc_schedule_on_exec_ctx); @@ -107,8 +110,6 @@ char* grpc_test_fetch_oauth2_token_with_credentials( gpr_mu_unlock(request.mu); grpc_pollset_shutdown(grpc_polling_entity_pollset(&request.pops), - &do_nothing_closure); - - gpr_free(grpc_polling_entity_pollset(&request.pops)); + &destroy_after_shutdown_closure); return request.token; } diff --git a/test/core/surface/num_external_connectivity_watchers_test.cc b/test/core/surface/num_external_connectivity_watchers_test.cc index 454cbd5747e..2c9b0d9aaed 100644 --- a/test/core/surface/num_external_connectivity_watchers_test.cc +++ b/test/core/surface/num_external_connectivity_watchers_test.cc @@ -22,7 +22,8 @@ #include #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/gprpp/memory.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -66,13 +67,11 @@ static void channel_idle_poll_for_timeout(grpc_channel* channel, static void run_timeouts_test(const test_fixture* fixture) { gpr_log(GPR_INFO, "TEST: %s", fixture->name); - char* addr; - + grpc_core::UniquePtr addr; grpc_init(); + grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); - gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); - - grpc_channel* channel = fixture->create_channel(addr); + grpc_channel* channel = fixture->create_channel(addr.get()); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); /* start 1 watcher and then let it time out */ @@ -111,7 +110,6 @@ static void run_timeouts_test(const test_fixture* fixture) { grpc_completion_queue_destroy(cq); grpc_shutdown(); - gpr_free(addr); } /* An edge scenario; sets channel state to explicitly, and outside @@ -120,13 +118,11 @@ static void run_channel_shutdown_before_timeout_test( const test_fixture* fixture) { gpr_log(GPR_INFO, "TEST: %s", fixture->name); - char* addr; - + grpc_core::UniquePtr addr; grpc_init(); + grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); - gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); - - grpc_channel* channel = fixture->create_channel(addr); + grpc_channel* channel = fixture->create_channel(addr.get()); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); /* start 1 watcher and then shut down the channel before the timer goes off */ @@ -154,7 +150,6 @@ static void run_channel_shutdown_before_timeout_test( grpc_completion_queue_destroy(cq); grpc_shutdown(); - gpr_free(addr); } static grpc_channel* insecure_test_create_channel(const char* addr) { diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 3aaa1e709ee..e537e482936 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -171,6 +171,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_google_refresh_token_credentials_create); printf("%lx", (unsigned long) grpc_access_token_credentials_create); printf("%lx", (unsigned long) grpc_google_iam_credentials_create); + printf("%lx", (unsigned long) grpc_sts_credentials_create); printf("%lx", (unsigned long) grpc_metadata_credentials_create_from_plugin); printf("%lx", (unsigned long) grpc_secure_channel_create); printf("%lx", (unsigned long) grpc_server_credentials_release); diff --git a/test/core/surface/sequential_connectivity_test.cc b/test/core/surface/sequential_connectivity_test.cc index 3f9a7baf98b..46c4a24f5ed 100644 --- a/test/core/surface/sequential_connectivity_test.cc +++ b/test/core/surface/sequential_connectivity_test.cc @@ -22,7 +22,7 @@ #include #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/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -56,11 +56,11 @@ static void run_test(const test_fixture* fixture) { grpc_init(); - char* addr; - gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); grpc_server* server = grpc_server_create(nullptr, nullptr); - fixture->add_server_port(server, addr); + fixture->add_server_port(server, addr.get()); grpc_completion_queue* server_cq = grpc_completion_queue_create_for_next(nullptr); grpc_server_register_completion_queue(server, server_cq, nullptr); @@ -73,7 +73,7 @@ static void run_test(const test_fixture* fixture) { grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_channel* channels[NUM_CONNECTIONS]; for (size_t i = 0; i < NUM_CONNECTIONS; i++) { - channels[i] = fixture->create_channel(addr); + channels[i] = fixture->create_channel(addr.get()); gpr_timespec connect_deadline = grpc_timeout_seconds_to_deadline(30); grpc_connectivity_state state; @@ -116,7 +116,6 @@ static void run_test(const test_fixture* fixture) { grpc_completion_queue_destroy(cq); grpc_shutdown(); - gpr_free(addr); } static void insecure_test_add_port(grpc_server* server, const char* addr) { diff --git a/test/core/surface/server_chttp2_test.cc b/test/core/surface/server_chttp2_test.cc index ffb7f14f987..a88362e13b0 100644 --- a/test/core/surface/server_chttp2_test.cc +++ b/test/core/surface/server_chttp2_test.cc @@ -22,7 +22,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/tsi/fake_transport_security.h" @@ -47,17 +47,17 @@ void test_add_same_port_twice() { grpc_channel_args args = {1, &a}; int port = grpc_pick_unused_port_or_die(); - char* addr = nullptr; + grpc_core::UniquePtr addr; grpc_completion_queue* cq = grpc_completion_queue_create_for_pluck(nullptr); grpc_server* server = grpc_server_create(&args, nullptr); grpc_server_credentials* fake_creds = grpc_fake_transport_security_server_credentials_create(); - gpr_join_host_port(&addr, "localhost", port); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds)); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds) == 0); + grpc_core::JoinHostPort(&addr, "localhost", port); + GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr.get(), fake_creds)); + GPR_ASSERT( + grpc_server_add_secure_http2_port(server, addr.get(), fake_creds) == 0); grpc_server_credentials_release(fake_creds); - gpr_free(addr); grpc_server_shutdown_and_notify(server, cq, nullptr); grpc_completion_queue_pluck(cq, nullptr, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr); diff --git a/test/core/surface/server_test.cc b/test/core/surface/server_test.cc index 2fc166546b0..185a6757743 100644 --- a/test/core/surface/server_test.cc +++ b/test/core/surface/server_test.cc @@ -22,7 +22,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "test/core/util/port.h" @@ -106,18 +106,19 @@ void test_bind_server_twice(void) { void test_bind_server_to_addr(const char* host, bool secure) { int port = grpc_pick_unused_port_or_die(); - char* addr; - gpr_join_host_port(&addr, host, port); - gpr_log(GPR_INFO, "Test bind to %s", addr); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, host, port); + gpr_log(GPR_INFO, "Test bind to %s", addr.get()); grpc_server* server = grpc_server_create(nullptr, nullptr); if (secure) { grpc_server_credentials* fake_creds = grpc_fake_transport_security_server_credentials_create(); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds)); + GPR_ASSERT( + grpc_server_add_secure_http2_port(server, addr.get(), fake_creds)); grpc_server_credentials_release(fake_creds); } else { - GPR_ASSERT(grpc_server_add_insecure_http2_port(server, addr)); + GPR_ASSERT(grpc_server_add_insecure_http2_port(server, addr.get())); } grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_server_register_completion_queue(server, cq, nullptr); @@ -126,7 +127,6 @@ void test_bind_server_to_addr(const char* host, bool secure) { grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_MONOTONIC), nullptr); grpc_server_destroy(server); grpc_completion_queue_destroy(cq); - gpr_free(addr); } static int external_dns_works(const char* host) { diff --git a/test/core/util/reconnect_server.cc b/test/core/util/reconnect_server.cc index 144ad64f095..03c088db772 100644 --- a/test/core/util/reconnect_server.cc +++ b/test/core/util/reconnect_server.cc @@ -25,7 +25,6 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/tcp_server.h" diff --git a/test/core/util/test_tcp_server.cc b/test/core/util/test_tcp_server.cc index 170584df2b9..d7803e53555 100644 --- a/test/core/util/test_tcp_server.cc +++ b/test/core/util/test_tcp_server.cc @@ -28,7 +28,6 @@ #include #include -#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/tcp_server.h" diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 64ab123123b..035955023b8 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -31,10 +31,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/test/cpp/codegen/proto_utils_test.cc b/test/cpp/codegen/proto_utils_test.cc index 801660eef67..e9dcea0fd9c 100644 --- a/test/cpp/codegen/proto_utils_test.cc +++ b/test/cpp/codegen/proto_utils_test.cc @@ -49,7 +49,18 @@ class GrpcByteBufferPeer { ByteBuffer* bb_; }; -class ProtoUtilsTest : public ::testing::Test {}; +class ProtoUtilsTest : public ::testing::Test { + protected: + static void SetUpTestCase() { + // Ensure the ProtoBufferWriter internals are initialized. + grpc::internal::GrpcLibraryInitializer init; + init.summon(); + grpc::GrpcLibraryCodegen lib; + grpc_init(); + } + + static void TearDownTestCase() { grpc_shutdown(); } +}; // Regression test for a memory corruption bug where a series of // ProtoBufferWriter Next()/Backup() invocations could result in a dangling @@ -136,36 +147,46 @@ void BufferWriterTest(int block_size, int total_size, int backup_size) { grpc_byte_buffer_reader_destroy(&reader); } -TEST(WriterTest, TinyBlockTinyBackup) { +class WriterTest : public ::testing::Test { + protected: + static void SetUpTestCase() { + grpc::internal::GrpcLibraryInitializer init; + init.summon(); + grpc::GrpcLibraryCodegen lib; + // Ensure the ProtoBufferWriter internals are initialized. + grpc_init(); + } + + static void TearDownTestCase() { grpc_shutdown(); } +}; + +TEST_F(WriterTest, TinyBlockTinyBackup) { for (int i = 2; i < static_cast GRPC_SLICE_INLINED_SIZE; i++) { BufferWriterTest(i, 256, 1); } } -TEST(WriterTest, SmallBlockTinyBackup) { BufferWriterTest(64, 256, 1); } +TEST_F(WriterTest, SmallBlockTinyBackup) { BufferWriterTest(64, 256, 1); } -TEST(WriterTest, SmallBlockNoBackup) { BufferWriterTest(64, 256, 0); } +TEST_F(WriterTest, SmallBlockNoBackup) { BufferWriterTest(64, 256, 0); } -TEST(WriterTest, SmallBlockFullBackup) { BufferWriterTest(64, 256, 64); } +TEST_F(WriterTest, SmallBlockFullBackup) { BufferWriterTest(64, 256, 64); } -TEST(WriterTest, LargeBlockTinyBackup) { BufferWriterTest(4096, 8192, 1); } +TEST_F(WriterTest, LargeBlockTinyBackup) { BufferWriterTest(4096, 8192, 1); } -TEST(WriterTest, LargeBlockNoBackup) { BufferWriterTest(4096, 8192, 0); } +TEST_F(WriterTest, LargeBlockNoBackup) { BufferWriterTest(4096, 8192, 0); } -TEST(WriterTest, LargeBlockFullBackup) { BufferWriterTest(4096, 8192, 4096); } +TEST_F(WriterTest, LargeBlockFullBackup) { BufferWriterTest(4096, 8192, 4096); } -TEST(WriterTest, LargeBlockLargeBackup) { BufferWriterTest(4096, 8192, 4095); } +TEST_F(WriterTest, LargeBlockLargeBackup) { + BufferWriterTest(4096, 8192, 4095); +} } // namespace } // namespace internal } // namespace grpc int main(int argc, char** argv) { - // Ensure the ProtoBufferWriter internals are initialized. - grpc::internal::GrpcLibraryInitializer init; - init.summon(); - grpc::GrpcLibraryCodegen lib; - ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc index 12fd9784f47..7fbed5ba3ea 100644 --- a/test/cpp/common/channel_arguments_test.cc +++ b/test/cpp/common/channel_arguments_test.cc @@ -84,6 +84,10 @@ class ChannelArgumentsTest : public ::testing::Test { channel_args.SetChannelArgs(args); } + static void SetUpTestCase() { grpc_init(); } + + static void TearDownTestCase() { grpc_shutdown(); } + grpc::string GetDefaultUserAgentPrefix() { std::ostringstream user_agent_prefix; user_agent_prefix << "grpc-c++/" << Version(); @@ -252,8 +256,6 @@ TEST_F(ChannelArgumentsTest, SetUserAgentPrefix) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index d229cc33034..ab0ef0c46ba 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -369,7 +369,6 @@ grpc_cc_test( name = "mock_test", srcs = ["mock_test.cc"], external_deps = [ - "gmock", "gtest", ], deps = [ @@ -406,7 +405,6 @@ grpc_cc_test( name = "client_lb_end2end_test", srcs = ["client_lb_end2end_test.cc"], external_deps = [ - "gmock", "gtest", ], deps = [ @@ -427,7 +425,6 @@ grpc_cc_test( name = "service_config_end2end_test", srcs = ["service_config_end2end_test.cc"], external_deps = [ - "gmock", "gtest", ], deps = [ @@ -447,7 +444,6 @@ grpc_cc_test( name = "grpclb_end2end_test", srcs = ["grpclb_end2end_test.cc"], external_deps = [ - "gmock", "gtest", ], deps = [ @@ -469,7 +465,6 @@ grpc_cc_test( name = "xds_end2end_test", srcs = ["xds_end2end_test.cc"], external_deps = [ - "gmock", "gtest", ], deps = [ @@ -594,7 +589,6 @@ grpc_cc_test( srcs = ["server_load_reporting_end2end_test.cc"], external_deps = [ "gtest", - "gmock", ], deps = [ "//:grpcpp_server_load_reporting", diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index f6d4a48b6f0..d499f136ef6 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -141,6 +141,12 @@ class ClientLbEnd2endTest : public ::testing::Test { creds_(new SecureChannelCredentials( grpc_fake_transport_security_credentials_create())) {} + static void SetUpTestCase() { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + } + void SetUp() override { grpc_init(); response_generator_ = @@ -1481,9 +1487,6 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesEnabled) { } // namespace grpc int main(int argc, char** argv) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); ::testing::InitGoogleTest(&argc, argv); grpc::testing::TestEnvironment env(argc, argv); const auto result = RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index a4c981a3eb1..e96825c33eb 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -121,6 +121,12 @@ class FilterEnd2endTest : public ::testing::Test { protected: FilterEnd2endTest() : server_host_("localhost") {} + static void SetUpTestCase() { + gpr_log(GPR_ERROR, "In SetUpTestCase"); + grpc::RegisterChannelFilter( + "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); + } + void SetUp() override { int port = grpc_pick_unused_port_or_die(); server_address_ << server_host_ << ":" << port; @@ -321,11 +327,6 @@ TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { EXPECT_EQ(1, GetConnectionCounterValue()); } -void RegisterFilter() { - grpc::RegisterChannelFilter( - "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); -} - } // namespace } // namespace testing } // namespace grpc @@ -333,6 +334,5 @@ void RegisterFilter() { int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); - grpc::testing::RegisterFilter(); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 70c443412aa..e3b79c810cd 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -374,6 +374,15 @@ class GrpclbEnd2endTest : public ::testing::Test { client_load_reporting_interval_seconds_( client_load_reporting_interval_seconds) {} + static void SetUpTestCase() { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + grpc_init(); + } + + static void TearDownTestCase() { grpc_shutdown(); } + void SetUp() override { response_generator_ = grpc_core::MakeRefCounted(); @@ -1003,7 +1012,7 @@ TEST_F(SingleBalancerTest, SecureNamingDeathTest) { ::testing::FLAGS_gtest_death_test_style = "threadsafe"; // Make sure that we blow up (via abort() from the security connector) when // the name from the balancer doesn't match expectations. - ASSERT_DEATH( + ASSERT_DEATH_IF_SUPPORTED( { ResetStub(0, kApplicationTargetName_ + ";lb"); SetNextResolution({AddressData{balancers_[0]->port_, true, "woops"}}); @@ -1990,13 +1999,8 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) { } // namespace grpc int main(int argc, char** argv) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); - grpc_init(); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); const auto result = RUN_ALL_TESTS(); - grpc_shutdown(); return result; } diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc index 8bf4a7c22ff..a00a45ecbb7 100644 --- a/test/cpp/end2end/service_config_end2end_test.cc +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -119,6 +119,12 @@ class ServiceConfigEnd2endTest : public ::testing::Test { creds_(new SecureChannelCredentials( grpc_fake_transport_security_credentials_create())) {} + static void SetUpTestCase() { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + } + void SetUp() override { grpc_init(); response_generator_ = @@ -611,9 +617,6 @@ TEST_F(ServiceConfigEnd2endTest, } // namespace grpc int main(int argc, char** argv) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); ::testing::InitGoogleTest(&argc, argv); grpc::testing::TestEnvironment env(argc, argv); const auto result = RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index eac6f32a538..5e7717e4e06 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -370,6 +370,15 @@ class XdsEnd2endTest : public ::testing::Test { client_load_reporting_interval_seconds_( client_load_reporting_interval_seconds) {} + static void SetUpTestCase() { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + grpc_init(); + } + + static void TearDownTestCase() { grpc_shutdown(); } + void SetUp() override { response_generator_ = grpc_core::MakeRefCounted(); @@ -788,7 +797,7 @@ TEST_F(SingleBalancerTest, SecureNamingDeathTest) { ::testing::FLAGS_gtest_death_test_style = "threadsafe"; // Make sure that we blow up (via abort() from the security connector) when // the name from the balancer doesn't match expectations. - ASSERT_DEATH( + ASSERT_DEATH_IF_SUPPORTED( { ResetStub(0, kApplicationTargetName_ + ";lb"); SetNextResolution({}, @@ -1401,13 +1410,8 @@ class SingleBalancerWithClientLoadReportingTest : public XdsEnd2endTest { } // namespace grpc int main(int argc, char** argv) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); - grpc_init(); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); const auto result = RUN_ALL_TESTS(); - grpc_shutdown(); return result; } diff --git a/test/cpp/ext/filters/census/BUILD b/test/cpp/ext/filters/census/BUILD index 78b27e2063c..452a84b2a7a 100644 --- a/test/cpp/ext/filters/census/BUILD +++ b/test/cpp/ext/filters/census/BUILD @@ -26,7 +26,6 @@ grpc_cc_test( ], external_deps = [ "gtest", - "gmock", "opencensus-stats-test", ], language = "C++", diff --git a/test/cpp/grpclb/grpclb_api_test.cc b/test/cpp/grpclb/grpclb_api_test.cc index ecba9f9ca3c..0ace512c278 100644 --- a/test/cpp/grpclb/grpclb_api_test.cc +++ b/test/cpp/grpclb/grpclb_api_test.cc @@ -31,7 +31,12 @@ namespace { using grpc::lb::v1::LoadBalanceRequest; using grpc::lb::v1::LoadBalanceResponse; -class GrpclbTest : public ::testing::Test {}; +class GrpclbTest : public ::testing::Test { + protected: + static void SetUpTestCase() { grpc_init(); } + + static void TearDownTestCase() { grpc_shutdown(); } +}; grpc::string Ip4ToPackedString(const char* ip_str) { struct in_addr ip4; @@ -128,8 +133,6 @@ TEST_F(GrpclbTest, ParseResponseServerList) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index ccfd2bb0c45..47653b25ef9 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -222,6 +222,8 @@ int main(int argc, char** argv) { &grpc::testing::InteropClient::DoTimeoutOnSleepingServer, &client); actions["empty_stream"] = std::bind(&grpc::testing::InteropClient::DoEmptyStream, &client); + actions["pick_first_unary"] = + std::bind(&grpc::testing::InteropClient::DoPickFirstUnary, &client); if (FLAGS_use_tls) { actions["compute_engine_creds"] = std::bind(&grpc::testing::InteropClient::DoComputeEngineCreds, &client, diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc index 92f07387d75..a7279eb0092 100644 --- a/test/cpp/interop/client_helper.cc +++ b/test/cpp/interop/client_helper.cc @@ -105,6 +105,13 @@ std::shared_ptr CreateChannelForTestCase( creds = FLAGS_custom_credentials_type == "google_default_credentials" ? nullptr : AccessTokenCredentials(GetOauth2AccessToken()); + } else if (test_case == "pick_first_unary") { + ChannelArguments channel_args; + // allow the LB policy to be configured with service config + channel_args.SetInt(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION, 0); + return CreateTestChannel(host_port, FLAGS_custom_credentials_type, + FLAGS_server_host_override, !FLAGS_use_test_ca, + creds, channel_args); } if (FLAGS_custom_credentials_type.empty()) { transport_security security_type = diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 649abf8a938..f474903331f 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -948,6 +948,32 @@ bool InteropClient::DoCacheableUnary() { return true; } +bool InteropClient::DoPickFirstUnary() { + const int rpcCount = 100; + SimpleRequest request; + SimpleResponse response; + std::string server_id; + request.set_fill_server_id(true); + for (int i = 0; i < rpcCount; i++) { + ClientContext context; + Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); + if (!AssertStatusOk(s, context.debug_error_string())) { + return false; + } + if (i == 0) { + server_id = response.server_id(); + continue; + } + if (response.server_id() != server_id) { + gpr_log(GPR_ERROR, "#%d rpc hits server_id %s, expect server_id %s", i, + response.server_id().c_str(), server_id.c_str()); + return false; + } + } + gpr_log(GPR_DEBUG, "pick first unary successfully finished"); + return true; +} + bool InteropClient::DoCustomMetadata() { const grpc::string kEchoInitialMetadataKey("x-grpc-test-echo-initial"); const grpc::string kInitialMetadataValue("test_initial_metadata_value"); diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index 22df688468b..483d9becac2 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -69,6 +69,8 @@ class InteropClient { bool DoUnimplementedMethod(); bool DoUnimplementedService(); bool DoCacheableUnary(); + // all requests are sent to one server despite multiple servers are resolved + bool DoPickFirstUnary(); // The following interop test are not yet part of the interop spec, and are // not implemented cross-language. They are considered experimental for now, diff --git a/test/cpp/interop/interop_test.cc b/test/cpp/interop/interop_test.cc index 8e45b877212..e0bacb3cfd6 100644 --- a/test/cpp/interop/interop_test.cc +++ b/test/cpp/interop/interop_test.cc @@ -32,7 +32,6 @@ #include "test/core/util/port.h" #include "test/cpp/util/test_config.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_utils_posix.h" diff --git a/test/cpp/naming/BUILD b/test/cpp/naming/BUILD index 7db435a3fd4..b91c0b83c9b 100644 --- a/test/cpp/naming/BUILD +++ b/test/cpp/naming/BUILD @@ -37,7 +37,7 @@ grpc_py_binary( grpc_cc_test( name = "cancel_ares_query_test", srcs = ["cancel_ares_query_test.cc"], - external_deps = ["gmock"], + external_deps = ["gtest"], deps = [ ":dns_test_util", "//:gpr", diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index affc75bc634..a3d9936606d 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -40,8 +40,8 @@ #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/gprpp/host_port.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" @@ -64,30 +64,28 @@ struct TestAddress { }; grpc_resolved_address TestAddressToGrpcResolvedAddress(TestAddress test_addr) { - char* host; - char* port; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; grpc_resolved_address resolved_addr; - gpr_split_host_port(test_addr.dest_addr.c_str(), &host, &port); + grpc_core::SplitHostPort(test_addr.dest_addr.c_str(), &host, &port); if (test_addr.family == AF_INET) { sockaddr_in in_dest; memset(&in_dest, 0, sizeof(sockaddr_in)); - in_dest.sin_port = htons(atoi(port)); + in_dest.sin_port = htons(atoi(port.get())); in_dest.sin_family = AF_INET; - GPR_ASSERT(inet_pton(AF_INET, host, &in_dest.sin_addr) == 1); + GPR_ASSERT(inet_pton(AF_INET, host.get(), &in_dest.sin_addr) == 1); memcpy(&resolved_addr.addr, &in_dest, sizeof(sockaddr_in)); resolved_addr.len = sizeof(sockaddr_in); } else { GPR_ASSERT(test_addr.family == AF_INET6); sockaddr_in6 in6_dest; memset(&in6_dest, 0, sizeof(sockaddr_in6)); - in6_dest.sin6_port = htons(atoi(port)); + in6_dest.sin6_port = htons(atoi(port.get())); in6_dest.sin6_family = AF_INET6; - GPR_ASSERT(inet_pton(AF_INET6, host, &in6_dest.sin6_addr) == 1); + GPR_ASSERT(inet_pton(AF_INET6, host.get(), &in6_dest.sin6_addr) == 1); memcpy(&resolved_addr.addr, &in6_dest, sizeof(sockaddr_in6)); resolved_addr.len = sizeof(sockaddr_in6); } - gpr_free(host); - gpr_free(port); return resolved_addr; } diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index 667011ae291..ab9deb7bcbc 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -33,7 +33,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/stats.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/thd.h" @@ -177,7 +176,32 @@ void TestCancelActiveDNSQuery(ArgsStruct* args) { ArgsFinish(args); } -TEST(CancelDuringAresQuery, TestCancelActiveDNSQuery) { +class CancelDuringAresQuery : public ::testing::Test { + protected: + static void SetUpTestCase() { + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); + // Sanity check the time that it takes to run the test + // including the teardown time (the teardown + // part of the test involves cancelling the DNS query, + // which is the main point of interest for this test). + overall_deadline = grpc_timeout_seconds_to_deadline(4); + grpc_init(); + } + + static void TearDownTestCase() { + grpc_shutdown(); + if (gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), overall_deadline) > 0) { + gpr_log(GPR_ERROR, "Test took too long"); + abort(); + } + } + + private: + static gpr_timespec overall_deadline; +}; +gpr_timespec CancelDuringAresQuery::overall_deadline; + +TEST_F(CancelDuringAresQuery, TestCancelActiveDNSQuery) { grpc_core::ExecCtx exec_ctx; ArgsStruct args; ArgsInit(&args); @@ -216,7 +240,7 @@ void MaybePollArbitraryPollsetTwice() {} #endif -TEST(CancelDuringAresQuery, TestFdsAreDeletedFromPollsetSet) { +TEST_F(CancelDuringAresQuery, TestFdsAreDeletedFromPollsetSet) { grpc_core::ExecCtx exec_ctx; ArgsStruct args; ArgsInit(&args); @@ -352,18 +376,18 @@ void TestCancelDuringActiveQuery( EndTest(client, cq); } -TEST(CancelDuringAresQuery, - TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) { +TEST_F(CancelDuringAresQuery, + TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) { TestCancelDuringActiveQuery(NONE /* don't set query timeouts */); } -TEST( +TEST_F( CancelDuringAresQuery, TestHitDeadlineAndDestroyChannelDuringAresResolutionWithQueryTimeoutIsGraceful) { TestCancelDuringActiveQuery(SHORT /* set short query timeout */); } -TEST( +TEST_F( CancelDuringAresQuery, TestHitDeadlineAndDestroyChannelDuringAresResolutionWithZeroQueryTimeoutIsGraceful) { TestCancelDuringActiveQuery(ZERO /* disable query timeouts */); @@ -374,18 +398,6 @@ TEST( int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); - GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); - // Sanity check the time that it takes to run the test - // including the teardown time (the teardown - // part of the test involves cancelling the DNS query, - // which is the main point of interest for this test). - gpr_timespec overall_deadline = grpc_timeout_seconds_to_deadline(4); - grpc_init(); auto result = RUN_ALL_TESTS(); - grpc_shutdown(); - if (gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), overall_deadline) > 0) { - gpr_log(GPR_ERROR, "Test took too long"); - abort(); - } return result; } diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl index bcc62f62871..2ce61d05446 100755 --- a/test/cpp/naming/generate_resolver_component_tests.bzl +++ b/test/cpp/naming/generate_resolver_component_tests.bzl @@ -23,7 +23,7 @@ def generate_resolver_component_tests(): "address_sorting_test.cc", ], external_deps = [ - "gmock", + "gtest", ], deps = [ "//test/cpp/util:test_util%s" % unsecure_build_config_suffix, @@ -43,7 +43,7 @@ def generate_resolver_component_tests(): "resolver_component_test.cc", ], external_deps = [ - "gmock", + "gtest", ], deps = [ ":dns_test_util", diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 6cea8143907..67ed307d2d7 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -46,8 +46,8 @@ #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/gprpp/host_port.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/executor.h" @@ -506,10 +506,10 @@ int g_fake_non_responsive_dns_server_port = -1; void InjectBrokenNameServerList(ares_channel channel) { struct ares_addr_port_node dns_server_addrs[2]; memset(dns_server_addrs, 0, sizeof(dns_server_addrs)); - char* unused_host; - char* local_dns_server_port; - GPR_ASSERT(gpr_split_host_port(FLAGS_local_dns_server_address.c_str(), - &unused_host, &local_dns_server_port)); + grpc_core::UniquePtr unused_host; + grpc_core::UniquePtr local_dns_server_port; + GPR_ASSERT(grpc_core::SplitHostPort(FLAGS_local_dns_server_address.c_str(), + &unused_host, &local_dns_server_port)); gpr_log(GPR_DEBUG, "Injecting broken nameserver list. Bad server address:|[::1]:%d|. " "Good server address:%s", @@ -528,12 +528,10 @@ void InjectBrokenNameServerList(ares_channel channel) { dns_server_addrs[1].family = AF_INET; ((char*)&dns_server_addrs[1].addr.addr4)[0] = 0x7f; ((char*)&dns_server_addrs[1].addr.addr4)[3] = 0x1; - dns_server_addrs[1].tcp_port = atoi(local_dns_server_port); - dns_server_addrs[1].udp_port = atoi(local_dns_server_port); + dns_server_addrs[1].tcp_port = atoi(local_dns_server_port.get()); + dns_server_addrs[1].udp_port = atoi(local_dns_server_port.get()); dns_server_addrs[1].next = nullptr; GPR_ASSERT(ares_set_servers_ports(channel, dns_server_addrs) == ARES_SUCCESS); - gpr_free(local_dns_server_port); - gpr_free(unused_host); } void StartResolvingLocked(void* arg, grpc_error* unused) { diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 668d9abf5ca..5fc14ddbabd 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -33,7 +33,6 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/client.h" diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 7d4d5d99446..cfc3c8e9a06 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -31,7 +31,7 @@ #include #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/worker_service.grpc.pb.h" #include "test/core/util/port.h" @@ -52,15 +52,10 @@ using std::vector; namespace grpc { namespace testing { static std::string get_host(const std::string& worker) { - char* host; - char* port; - - gpr_split_host_port(worker.c_str(), &host, &port); - const string s(host); - - gpr_free(host); - gpr_free(port); - return s; + grpc_core::StringView host; + grpc_core::StringView port; + grpc_core::SplitHostPort(worker.c_str(), &host, &port); + return std::string(host.data(), host.size()); } static deque get_workers(const string& env_name) { @@ -324,11 +319,10 @@ std::unique_ptr RunScenario( client_config.add_server_targets(cli_target); } else { std::string host; - char* cli_target; + grpc_core::UniquePtr cli_target; host = get_host(workers[i]); - gpr_join_host_port(&cli_target, host.c_str(), init_status.port()); - client_config.add_server_targets(cli_target); - gpr_free(cli_target); + grpc_core::JoinHostPort(&cli_target, host.c_str(), init_status.port()); + client_config.add_server_targets(cli_target.get()); } } diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc index 23fe72316a1..bdf94d86c10 100644 --- a/test/cpp/qps/qps_worker.cc +++ b/test/cpp/qps/qps_worker.cc @@ -34,7 +34,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/proto/grpc/testing/worker_service.grpc.pb.h" #include "test/core/util/grpc_profiler.h" #include "test/core/util/histogram.h" @@ -279,12 +279,11 @@ QpsWorker::QpsWorker(int driver_port, int server_port, std::unique_ptr builder = CreateQpsServerBuilder(); if (driver_port >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", driver_port); + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", driver_port); builder->AddListeningPort( - server_address, + server_address.get(), GetCredentialsProvider()->GetServerCredentials(credential_type)); - gpr_free(server_address); } builder->RegisterService(impl_.get()); diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h index 89b0e3af4b2..2b82abce202 100644 --- a/test/cpp/qps/server.h +++ b/test/cpp/qps/server.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index a5f8347c269..e9978212f95 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -34,7 +34,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/completion_queue.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/core/util/test_config.h" @@ -80,11 +80,10 @@ class AsyncQpsServerTest final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", port_num); - builder->AddListeningPort(server_address, + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", port_num); + builder->AddListeningPort(server_address.get(), Server::CreateServerCredentials(config)); - gpr_free(server_address); } register_service(builder.get(), &async_service_); diff --git a/test/cpp/qps/server_callback.cc b/test/cpp/qps/server_callback.cc index 4a346dd0178..1829905cb49 100644 --- a/test/cpp/qps/server_callback.cc +++ b/test/cpp/qps/server_callback.cc @@ -21,7 +21,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/qps_server_builder.h" #include "test/cpp/qps/server.h" @@ -103,11 +103,10 @@ class CallbackServer final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", port_num); - builder->AddListeningPort(server_address, + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", port_num); + builder->AddListeningPort(server_address.get(), Server::CreateServerCredentials(config)); - gpr_free(server_address); } ApplyConfigToBuilder(config, builder.get()); diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc index 2e63f5ec867..7b76e9c206a 100644 --- a/test/cpp/qps/server_sync.cc +++ b/test/cpp/qps/server_sync.cc @@ -25,7 +25,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/qps_server_builder.h" #include "test/cpp/qps/server.h" @@ -160,11 +160,10 @@ class SynchronousServer final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", port_num); - builder->AddListeningPort(server_address, + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", port_num); + builder->AddListeningPort(server_address.get(), Server::CreateServerCredentials(config)); - gpr_free(server_address); } ApplyConfigToBuilder(config, builder.get()); diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD index db5c93263ad..633b6d8c0d9 100644 --- a/test/cpp/server/load_reporter/BUILD +++ b/test/cpp/server/load_reporter/BUILD @@ -35,7 +35,6 @@ grpc_cc_test( srcs = ["load_reporter_test.cc"], external_deps = [ "gtest", - "gmock", "opencensus-stats-test", ], deps = [ diff --git a/test/cpp/server/server_builder_test.cc b/test/cpp/server/server_builder_test.cc index 5c22dda16f0..e07ae8dbc66 100644 --- a/test/cpp/server/server_builder_test.cc +++ b/test/cpp/server/server_builder_test.cc @@ -44,13 +44,19 @@ const grpc::string& GetPort() { return g_port; } -TEST(ServerBuilderTest, NoOp) { ServerBuilder b; } +class ServerBuilderTest : public ::testing::Test { + protected: + static void SetUpTestCase() { grpc_init(); } -TEST(ServerBuilderTest, CreateServerNoPorts) { + static void TearDownTestCase() { grpc_shutdown(); } +}; +TEST_F(ServerBuilderTest, NoOp) { ServerBuilder b; } + +TEST_F(ServerBuilderTest, CreateServerNoPorts) { ServerBuilder().RegisterService(&g_service).BuildAndStart()->Shutdown(); } -TEST(ServerBuilderTest, CreateServerOnePort) { +TEST_F(ServerBuilderTest, CreateServerOnePort) { ServerBuilder() .RegisterService(&g_service) .AddListeningPort(GetPort(), InsecureServerCredentials()) @@ -58,7 +64,7 @@ TEST(ServerBuilderTest, CreateServerOnePort) { ->Shutdown(); } -TEST(ServerBuilderTest, CreateServerRepeatedPort) { +TEST_F(ServerBuilderTest, CreateServerRepeatedPort) { ServerBuilder() .RegisterService(&g_service) .AddListeningPort(GetPort(), InsecureServerCredentials()) @@ -67,7 +73,7 @@ TEST(ServerBuilderTest, CreateServerRepeatedPort) { ->Shutdown(); } -TEST(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) { +TEST_F(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) { EXPECT_EQ(ServerBuilder() .RegisterService(&g_service) .AddListeningPort(GetPort(), InsecureServerCredentials()) @@ -82,8 +88,6 @@ TEST(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } diff --git a/test/cpp/server/server_builder_with_socket_mutator_test.cc b/test/cpp/server/server_builder_with_socket_mutator_test.cc index 5c7dd696c9f..15e5c073a04 100644 --- a/test/cpp/server/server_builder_with_socket_mutator_test.cc +++ b/test/cpp/server/server_builder_with_socket_mutator_test.cc @@ -86,7 +86,14 @@ class MockSocketMutatorServerBuilderOption : public grpc::ServerBuilderOption { MockSocketMutator* mock_socket_mutator_; }; -TEST(ServerBuilderWithSocketMutatorTest, CreateServerWithSocketMutator) { +class ServerBuilderWithSocketMutatorTest : public ::testing::Test { + protected: + static void SetUpTestCase() { grpc_init(); } + + static void TearDownTestCase() { grpc_shutdown(); } +}; + +TEST_F(ServerBuilderWithSocketMutatorTest, CreateServerWithSocketMutator) { auto address = "localhost:" + std::to_string(grpc_pick_unused_port_or_die()); auto mock_socket_mutator = new MockSocketMutator(); std::unique_ptr mock_socket_mutator_builder_option( @@ -109,8 +116,6 @@ TEST(ServerBuilderWithSocketMutatorTest, CreateServerWithSocketMutator) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } diff --git a/test/cpp/util/byte_buffer_test.cc b/test/cpp/util/byte_buffer_test.cc index 9bffbf7ac1c..fdae56a90c2 100644 --- a/test/cpp/util/byte_buffer_test.cc +++ b/test/cpp/util/byte_buffer_test.cc @@ -36,7 +36,12 @@ namespace { const char* kContent1 = "hello xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char* kContent2 = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy world"; -class ByteBufferTest : public ::testing::Test {}; +class ByteBufferTest : public ::testing::Test { + protected: + static void SetUpTestCase() { grpc_init(); } + + static void TearDownTestCase() { grpc_shutdown(); } +}; TEST_F(ByteBufferTest, CopyCtor) { ByteBuffer buffer1; @@ -121,8 +126,6 @@ TEST_F(ByteBufferTest, SerializationMakesCopy) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index 42564a31ec8..2aacbc9bdf3 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -21,8 +21,10 @@ #include +#include #include #include +#include namespace grpc_impl { @@ -37,31 +39,31 @@ typedef enum { INSECURE = 0, TLS, ALTS } transport_security; } // namespace testing -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, testing::transport_security security_type); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& cred_type, const grpc::string& override_hostname, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& credential_type, const std::shared_ptr& creds); diff --git a/test/cpp/util/slice_test.cc b/test/cpp/util/slice_test.cc index dc1910038f0..f8561c48a14 100644 --- a/test/cpp/util/slice_test.cc +++ b/test/cpp/util/slice_test.cc @@ -33,6 +33,10 @@ const char* kContent = "hello xxxxxxxxxxxxxxxxxxxx world"; class SliceTest : public ::testing::Test { protected: + static void SetUpTestCase() { grpc_init(); } + + static void TearDownTestCase() { grpc_shutdown(); } + void CheckSliceSize(const Slice& s, const grpc::string& content) { EXPECT_EQ(content.size(), s.size()); } @@ -132,8 +136,6 @@ TEST_F(SliceTest, Cslice) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } diff --git a/third_party/googletest b/third_party/googletest index ec44c6c1675..2fe3bd994b3 160000 --- a/third_party/googletest +++ b/third_party/googletest @@ -1 +1 @@ -Subproject commit ec44c6c1675c25b9827aacd08c02433cccde7780 +Subproject commit 2fe3bd994b3189899d93f1d5a881e725e046fdc2 diff --git a/third_party/gtest.BUILD b/third_party/gtest.BUILD deleted file mode 100644 index f38bfd8d457..00000000000 --- a/third_party/gtest.BUILD +++ /dev/null @@ -1,42 +0,0 @@ -cc_library( - name = "gtest", - srcs = [ - "googletest/src/gtest-all.cc", - ], - hdrs = glob([ - "googletest/include/**/*.h", - "googletest/src/*.cc", - "googletest/src/*.h", - ]), - includes = [ - "googletest", - "googletest/include", - ], - linkstatic = 1, - visibility = [ - "//visibility:public", - ], -) - -cc_library( - name = "gmock", - srcs = [ - "googlemock/src/gmock-all.cc" - ], - hdrs = glob([ - "googlemock/include/**/*.h", - "googlemock/src/*.cc", - "googlemock/src/*.h" - ]), - includes = [ - "googlemock", - "googlemock/include", - ], - deps = [ - ":gtest", - ], - linkstatic = 1, - visibility = [ - "//visibility:public", - ], -) diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index b534d8dab7e..a149e001d75 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -550,9 +550,9 @@ print >> C, '}' print >> C print >> C, 'grpc_core::StaticMetadata grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {' -for a, b in all_elems: - print >> C, 'grpc_core::StaticMetadata(%s,%s),' % (slice_def(str_idx(a)), - slice_def(str_idx(b))) +for idx, (a, b) in enumerate(all_elems): + print >> C, 'grpc_core::StaticMetadata(%s,%s, %d),' % ( + slice_def(str_idx(a)), slice_def(str_idx(b)), idx) print >> C, '};' print >> H, 'typedef enum {' diff --git a/tools/distrib/check_protobuf_pod_version.sh b/tools/distrib/check_protobuf_pod_version.sh new file mode 100755 index 00000000000..174931a0d18 --- /dev/null +++ b/tools/distrib/check_protobuf_pod_version.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# 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. + +set -ex + +cd `dirname $0`/../.. + +# get the version of protobuf in /third_party/protobuf +pushd third_party/protobuf + +version1=$(git describe --tags | cut -f 1 -d'-') +v1=${version1:1} + +popd + +# get the version of protobuf in /src/objective-c/!ProtoCompiler.podspec +v2=$(cat src/objective-c/\!ProtoCompiler.podspec | egrep "v = " | cut -f 2 -d"'") + +# get the version of protobuf in /src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +v3=$(cat src/objective-c/\!ProtoCompiler-gRPCPlugin.podspec | egrep 'dependency.*!ProtoCompiler' | cut -f 4 -d"'") + +# compare and emit error +ret=0 +if [ $v1 != $v2 ]; then + echo 'Protobuf version in src/objective-c/!ProtoCompiler.podspec does not match protobuf version in third_party/protobuf.' + ret=1 +fi + +if [ $v1 != $v3 ]; then + echo 'Protobuf version in src/objective-c/!ProtoCompiler-gRPCPlugin.podspec does not match protobuf version in third_party/protobuf.' + ret=1 +fi + +exit $ret diff --git a/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile index 897354891c1..43d8a60daea 100644 --- a/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM google/dart:2.0 +FROM google/dart:2.3 # Upgrade Dart to version 2. RUN apt-get update && apt-get upgrade -y dart diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 183ab0dff53..501be844410 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -930,6 +930,7 @@ include/grpcpp/channel.h \ 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 \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index e2d753e02eb..79cc89e13e8 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -931,6 +931,7 @@ include/grpcpp/channel.h \ 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 \ @@ -1076,7 +1077,6 @@ src/core/lib/debug/trace.h \ 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 \ @@ -1098,6 +1098,7 @@ 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/host_port.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ @@ -1107,6 +1108,7 @@ src/core/lib/gprpp/orphanable.h \ 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 \ @@ -1131,6 +1133,7 @@ src/core/lib/iomgr/ev_poll_posix.h \ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ src/core/lib/iomgr/executor.h \ +src/core/lib/iomgr/executor/mpmcqueue.h \ src/core/lib/iomgr/gethostname.h \ src/core/lib/iomgr/grpc_if_nametoindex.h \ src/core/lib/iomgr/internal_errqueue.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 7768bca30f5..273c56e0242 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1125,8 +1125,6 @@ src/core/lib/gpr/env.h \ 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 \ @@ -1175,6 +1173,8 @@ src/core/lib/gprpp/global_config_custom.h \ 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/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ @@ -1184,6 +1184,7 @@ src/core/lib/gprpp/orphanable.h \ 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/gprpp/thd_posix.cc \ @@ -1233,6 +1234,8 @@ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/exec_ctx.h \ src/core/lib/iomgr/executor.cc \ src/core/lib/iomgr/executor.h \ +src/core/lib/iomgr/executor/mpmcqueue.cc \ +src/core/lib/iomgr/executor/mpmcqueue.h \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname.h \ diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 05c495f5633..d6d0612b4e4 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -284,9 +284,9 @@ LANG_RELEASE_MATRIX = { ('v1.16.0', ReleaseInfo(testcases_file='php__v1.0.1')), ('v1.17.1', ReleaseInfo(testcases_file='php__v1.0.1')), ('v1.18.0', ReleaseInfo()), + # v1.19 and v1.20 were deliberately omitted here because of an issue. + # See https://github.com/grpc/grpc/issues/18264 ('v1.21.4', ReleaseInfo()), - # TODO:https://github.com/grpc/grpc/issues/18264 - # Error in above issues needs to be resolved. ]), 'csharp': OrderedDict([ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 2a8ed7367f4..a5fbd71d780 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -392,7 +392,23 @@ "headers": [], "is_filegroup": false, "language": "c", - "name": "dns_resolver_cooldown_test", + "name": "dns_resolver_cooldown_using_ares_resolver_test", + "src": [ + "test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "dns_resolver_cooldown_using_native_resolver_test", "src": [ "test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc" ], @@ -683,7 +699,7 @@ "language": "c", "name": "gpr_host_port_test", "src": [ - "test/core/gpr/host_port_test.cc" + "test/core/gprpp/host_port_test.cc" ], "third_party": false, "type": "target" @@ -1626,6 +1642,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "mpmcqueue_test", + "src": [ + "test/core/iomgr/mpmcqueue_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -5058,6 +5090,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "string_view_test", + "src": [ + "test/core/gprpp/string_view_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -8189,7 +8239,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", @@ -8216,6 +8265,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", @@ -8249,7 +8299,6 @@ "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", @@ -8270,6 +8319,7 @@ "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", @@ -8302,7 +8352,6 @@ "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", @@ -8323,6 +8372,7 @@ "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", @@ -8458,6 +8508,7 @@ "src/core/lib/iomgr/ev_windows.cc", "src/core/lib/iomgr/exec_ctx.cc", "src/core/lib/iomgr/executor.cc", + "src/core/lib/iomgr/executor/mpmcqueue.cc", "src/core/lib/iomgr/fork_posix.cc", "src/core/lib/iomgr/fork_windows.cc", "src/core/lib/iomgr/gethostname_fallback.cc", @@ -8623,6 +8674,7 @@ "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", @@ -8645,6 +8697,7 @@ "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", @@ -8780,6 +8833,7 @@ "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", @@ -8802,6 +8856,7 @@ "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", @@ -10381,6 +10436,7 @@ "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", @@ -10508,6 +10564,7 @@ "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", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 625d3bd295f..2ac529238d5 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -484,7 +484,9 @@ "uses_polling": true }, { - "args": [], + "args": [ + "--resolver=ares" + ], "benchmark": false, "ci_platforms": [ "linux", @@ -498,7 +500,33 @@ "flaky": false, "gtest": false, "language": "c", - "name": "dns_resolver_cooldown_test", + "name": "dns_resolver_cooldown_using_ares_resolver_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, + { + "args": [ + "--resolver=native" + ], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "dns_resolver_cooldown_using_native_resolver_test", "platforms": [ "linux", "mac", @@ -1959,6 +1987,30 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "mpmcqueue_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, @@ -5730,6 +5782,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "string_view_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index 593db878173..5ebd395835a 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -35,7 +35,7 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules" a83394157ad97f4dadbc8ed81f56ad5b3a72e542 third_party/envoy-api (heads/master) 28f50e0fed19872e0fd50dd23ce2ee8cd759338e third_party/gflags (v2.2.0-5-g30dbc81) 80ed4d0bbf65d57cc267dfc63bd2584557f11f9b third_party/googleapis (common-protos-1_3_1-915-g80ed4d0bb) - ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0) + 2fe3bd994b3189899d93f1d5a881e725e046fdc2 third_party/googletest (release-1.8.1) 6599cac0965be8e5a835ab7a5684bbef033d5ad0 third_party/libcxx (heads/release_60) 9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60) 09745575a923640154bcf307fba8aedff47f240a third_party/protobuf (v3.7.0-rc.2-247-g09745575) diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py index ce9ff0dae21..a9c986b3ac2 100755 --- a/tools/run_tests/sanity/core_banned_functions.py +++ b/tools/run_tests/sanity/core_banned_functions.py @@ -23,6 +23,7 @@ os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..')) # map of banned function signature to whitelist BANNED_EXCEPT = { + 'grpc_slice_from_static_buffer(': ['src/core/lib/slice/slice.cc'], 'grpc_resource_quota_ref(': ['src/core/lib/iomgr/resource_quota.cc'], 'grpc_resource_quota_unref(': ['src/core/lib/iomgr/resource_quota.cc', 'src/core/lib/surface/server.cc'], diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index 1913edd4257..1c5dc5d4312 100644 --- a/tools/run_tests/sanity/sanity_tests.yaml +++ b/tools/run_tests/sanity/sanity_tests.yaml @@ -23,5 +23,6 @@ - script: tools/distrib/pylint_code.sh - script: tools/distrib/yapf_code.sh - script: tools/distrib/python/check_grpcio_tools.py -- script: tools/distrib/check_shadow_boringssl_symbol_list.sh cpu_cost: 1000 +- script: tools/distrib/check_shadow_boringssl_symbol_list.sh +- script: tools/distrib/check_protobuf_pod_version.sh