Merge branch 'master' of github.com:grpc/grpc into compression_implicit_encoding

pull/9531/head
David Garcia Quintas 8 years ago
commit 7317195b8e
  1. 75
      BUILD
  2. 7466
      CMakeLists.txt
  3. 261
      Makefile
  4. 3
      binding.gyp
  5. 120
      build.yaml
  6. 2
      build_config.rb
  7. 14
      cmake/msvc_static_runtime.cmake
  8. 3
      composer.json
  9. 3
      config.m4
  10. 9
      doc/PROTOCOL-WEB.md
  11. 25
      doc/command_line_tool.md
  12. 6
      doc/environment_variables.md
  13. 1
      doc/g_stands_for.md
  14. 2
      examples/csharp/helloworld/generate_protos.bat
  15. 8
      examples/php/composer.json
  16. 10
      examples/php/greeter_client.php
  17. 58
      examples/php/helloworld.pb.php
  18. 168
      examples/php/helloworld.php
  19. 64
      examples/php/helloworld_grpc_pb.php
  20. 209
      examples/php/route_guide/route_guide.pb.php
  21. 789
      examples/php/route_guide/route_guide.php
  22. 120
      examples/php/route_guide/route_guide.proto
  23. 22
      examples/php/route_guide/route_guide_client.php
  24. 116
      examples/php/route_guide/route_guide_grpc_pb.php
  25. 53
      gRPC-Core.podspec
  26. 10
      gRPC-ProtoRPC.podspec
  27. 10
      gRPC-RxLibrary.podspec
  28. 9
      gRPC.podspec
  29. 11
      grpc.gemspec
  30. 9
      include/grpc++/impl/codegen/proto_utils.h
  31. 2
      include/grpc++/server.h
  32. 14
      include/grpc/census.h
  33. 13
      include/grpc/impl/codegen/grpc_types.h
  34. 2
      package.json
  35. 15
      package.xml
  36. 28
      src/compiler/php_generator.cc
  37. 3
      src/compiler/php_generator.h
  38. 15
      src/compiler/php_generator_helpers.h
  39. 20
      src/compiler/php_plugin.cc
  40. 45
      src/core/ext/census/gen/trace_context.pb.c
  41. 48
      src/core/ext/census/gen/trace_context.pb.h
  42. 2
      src/core/ext/census/trace_context.c
  43. 3
      src/core/ext/census/trace_context.h
  44. 61
      src/core/ext/census/trace_label.h
  45. 63
      src/core/ext/census/trace_propagation.h
  46. 45
      src/core/ext/census/trace_status.h
  47. 50
      src/core/ext/census/trace_string.h
  48. 42
      src/core/ext/census/tracing.c
  49. 124
      src/core/ext/census/tracing.h
  50. 42
      src/core/ext/client_channel/client_channel.c
  51. 4
      src/core/ext/client_channel/client_channel.h
  52. 2
      src/core/ext/client_channel/client_channel_plugin.c
  53. 57
      src/core/ext/client_channel/http_proxy.c
  54. 4
      src/core/ext/client_channel/http_proxy.h
  55. 25
      src/core/ext/client_channel/proxy_mapper.c
  56. 36
      src/core/ext/client_channel/proxy_mapper.h
  57. 52
      src/core/ext/client_channel/proxy_mapper_registry.c
  58. 16
      src/core/ext/client_channel/proxy_mapper_registry.h
  59. 20
      src/core/ext/client_channel/subchannel.c
  60. 3
      src/core/ext/client_channel/subchannel.h
  61. 171
      src/core/ext/lb_policy/grpclb/grpclb.c
  62. 77
      src/core/ext/lb_policy/grpclb/grpclb_channel.c
  63. 56
      src/core/ext/lb_policy/grpclb/grpclb_channel.h
  64. 107
      src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c
  65. 7
      src/core/ext/lb_policy/round_robin/round_robin.c
  66. 8
      src/core/ext/transport/chttp2/client/insecure/channel_create.c
  67. 184
      src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
  68. 400
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  69. 22
      src/core/ext/transport/chttp2/transport/frame_ping.c
  70. 4
      src/core/ext/transport/chttp2/transport/frame_ping.h
  71. 9
      src/core/ext/transport/chttp2/transport/frame_rst_stream.c
  72. 7
      src/core/ext/transport/chttp2/transport/frame_settings.c
  73. 11
      src/core/ext/transport/chttp2/transport/frame_window_update.c
  74. 125
      src/core/ext/transport/chttp2/transport/internal.h
  75. 30
      src/core/ext/transport/chttp2/transport/parsing.c
  76. 43
      src/core/ext/transport/chttp2/transport/stream_lists.c
  77. 120
      src/core/ext/transport/chttp2/transport/writing.c
  78. 2
      src/core/ext/transport/cronet/transport/cronet_api_dummy.c
  79. 2
      src/core/ext/transport/cronet/transport/cronet_transport.c
  80. 6
      src/core/lib/channel/connected_channel.c
  81. 5
      src/core/lib/channel/connected_channel.h
  82. 8
      src/core/lib/iomgr/closure.c
  83. 5
      src/core/lib/iomgr/closure.h
  84. 28
      src/core/lib/iomgr/combiner.c
  85. 23
      src/core/lib/iomgr/combiner.h
  86. 34
      src/core/lib/iomgr/resource_quota.c
  87. 6
      src/core/lib/iomgr/resource_quota.h
  88. 38
      src/core/lib/iomgr/sockaddr_utils.c
  89. 4
      src/core/lib/iomgr/sockaddr_utils.h
  90. 27
      src/core/lib/iomgr/tcp_client_windows.c
  91. 331
      src/core/lib/iomgr/tcp_server_posix.c
  92. 42
      src/core/lib/iomgr/udp_server.c
  93. 8
      src/core/lib/iomgr/udp_server.h
  94. 20
      src/core/lib/profiling/basic_timers.c
  95. 47
      src/core/lib/security/credentials/credentials.c
  96. 13
      src/core/lib/security/credentials/credentials.h
  97. 8
      src/core/lib/security/credentials/fake/fake_credentials.c
  98. 15
      src/core/lib/security/credentials/fake/fake_credentials.h
  99. 2
      src/core/lib/security/transport/client_auth_filter.c
  100. 70
      src/core/lib/security/transport/lb_targets_info.c
  101. Some files were not shown because too many files have changed in this diff Show More

75
BUILD

@ -63,7 +63,7 @@ grpc_cc_library(
deps = [
"census",
"grpc_base",
"grpc_lb_policy_grpclb",
"grpc_lb_policy_grpclb_secure",
"grpc_lb_policy_pick_first",
"grpc_lb_policy_round_robin",
"grpc_load_reporting",
@ -140,6 +140,7 @@ grpc_cc_library(
"grpc++_base",
"grpc++_codegen_base",
"grpc++_codegen_base_src",
"grpc++_codegen_proto",
],
)
@ -284,9 +285,15 @@ grpc_cc_library(
"src/core/ext/census/resource.h",
"src/core/ext/census/rpc_metric_id.h",
"src/core/ext/census/trace_context.h",
"src/core/ext/census/trace_label.h",
"src/core/ext/census/trace_propagation.h",
"src/core/ext/census/trace_status.h",
"src/core/ext/census/trace_string.h",
"src/core/ext/census/tracing.h",
],
external_deps = [
"nanopb",
"libssl",
],
language = "c",
public_hdrs = [
@ -526,6 +533,7 @@ grpc_cc_library(
"src/core/lib/transport/metadata.c",
"src/core/lib/transport/metadata_batch.c",
"src/core/lib/transport/pid_controller.c",
"src/core/lib/transport/bdp_estimator.c",
"src/core/lib/transport/service_config.c",
"src/core/lib/transport/static_metadata.c",
"src/core/lib/transport/status_conversion.c",
@ -623,9 +631,9 @@ grpc_cc_library(
"src/core/lib/surface/completion_queue.h",
"src/core/lib/surface/event_string.h",
"src/core/lib/surface/init.h",
"src/core/lib/surface/validate_metadata.h",
"src/core/lib/surface/lame_client.h",
"src/core/lib/surface/server.h",
"src/core/lib/surface/validate_metadata.h",
"src/core/lib/transport/byte_stream.h",
"src/core/lib/transport/connectivity_state.h",
"src/core/lib/transport/error_utils.h",
@ -633,6 +641,7 @@ grpc_cc_library(
"src/core/lib/transport/metadata.h",
"src/core/lib/transport/metadata_batch.h",
"src/core/lib/transport/pid_controller.h",
"src/core/lib/transport/bdp_estimator.h",
"src/core/lib/transport/service_config.h",
"src/core/lib/transport/static_metadata.h",
"src/core/lib/transport/status_conversion.h",
@ -663,7 +672,6 @@ grpc_cc_library(
grpc_cc_library(
name = "grpc_client_channel",
language = "c",
srcs = [
"src/core/ext/client_channel/channel_connectivity.c",
"src/core/ext/client_channel/client_channel.c",
@ -707,6 +715,7 @@ grpc_cc_library(
"src/core/ext/client_channel/subchannel_index.h",
"src/core/ext/client_channel/uri_parser.h",
],
language = "c",
deps = [
"grpc_base",
],
@ -733,11 +742,13 @@ grpc_cc_library(
name = "grpc_lb_policy_grpclb",
srcs = [
"src/core/ext/lb_policy/grpclb/grpclb.c",
"src/core/ext/lb_policy/grpclb/grpclb_channel.c",
"src/core/ext/lb_policy/grpclb/load_balancer_api.c",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
],
hdrs = [
"src/core/ext/lb_policy/grpclb/grpclb.h",
"src/core/ext/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
],
@ -751,6 +762,31 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_lb_policy_grpclb_secure",
srcs = [
"src/core/ext/lb_policy/grpclb/grpclb.c",
"src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c",
"src/core/ext/lb_policy/grpclb/load_balancer_api.c",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
],
hdrs = [
"src/core/ext/lb_policy/grpclb/grpclb.h",
"src/core/ext/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
],
external_deps = [
"nanopb",
],
language = "c",
deps = [
"grpc_base",
"grpc_client_channel",
"grpc_secure",
],
)
grpc_cc_library(
name = "grpc_lb_policy_pick_first",
srcs = [
@ -835,6 +871,7 @@ grpc_cc_library(
"src/core/lib/security/credentials/ssl/ssl_credentials.c",
"src/core/lib/security/transport/client_auth_filter.c",
"src/core/lib/security/transport/secure_endpoint.c",
"src/core/lib/security/transport/lb_targets_info.c",
"src/core/lib/security/transport/security_connector.c",
"src/core/lib/security/transport/security_handshaker.c",
"src/core/lib/security/transport/server_auth_filter.c",
@ -858,6 +895,7 @@ grpc_cc_library(
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/transport/auth_filters.h",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/lb_targets_info.h",
"src/core/lib/security/transport/security_connector.h",
"src/core/lib/security/transport/security_handshaker.h",
"src/core/lib/security/transport/tsi_error.h",
@ -941,22 +979,21 @@ grpc_cc_library(
)
grpc_cc_library(
name = "grpc_transport_chttp2_client_connector",
hdrs = [
"src/core/ext/transport/chttp2/client/chttp2_connector.h",
],
srcs = [
"src/core/ext/transport/chttp2/client/chttp2_connector.c",
],
language = "c",
deps = [
"grpc_transport_chttp2",
"grpc_base",
"grpc_client_channel",
],
name = "grpc_transport_chttp2_client_connector",
srcs = [
"src/core/ext/transport/chttp2/client/chttp2_connector.c",
],
hdrs = [
"src/core/ext/transport/chttp2/client/chttp2_connector.h",
],
language = "c",
deps = [
"grpc_base",
"grpc_client_channel",
"grpc_transport_chttp2",
],
)
grpc_cc_library(
name = "grpc_transport_chttp2_client_insecure",
srcs = [
@ -1038,7 +1075,7 @@ grpc_cc_library(
"src/core/ext/transport/cronet/transport/cronet_transport.c",
],
hdrs = [
"third_party/Cronet/bidirectional_stream_c.h",
"third_party/objective_c/Cronet/bidirectional_stream_c.h",
],
language = "c",
public_hdrs = [
@ -1183,6 +1220,7 @@ grpc_cc_library(
"include/grpc++/impl/codegen/core_codegen_interface.h",
"include/grpc++/impl/codegen/create_auth_context.h",
"include/grpc++/impl/codegen/grpc_library.h",
"include/grpc++/impl/codegen/metadata_map.h",
"include/grpc++/impl/codegen/method_handler_impl.h",
"include/grpc++/impl/codegen/rpc_method.h",
"include/grpc++/impl/codegen/rpc_service_method.h",
@ -1191,6 +1229,7 @@ grpc_cc_library(
"include/grpc++/impl/codegen/server_context.h",
"include/grpc++/impl/codegen/server_interface.h",
"include/grpc++/impl/codegen/service_type.h",
"include/grpc++/impl/codegen/slice.h",
"include/grpc++/impl/codegen/status.h",
"include/grpc++/impl/codegen/status_code_enum.h",
"include/grpc++/impl/codegen/status_helper.h",

File diff suppressed because it is too large Load Diff

@ -111,7 +111,6 @@ LDXX_helgrind = $(DEFAULT_CXX)
CPPFLAGS_helgrind = -O0
LDFLAGS_helgrind = -rdynamic
DEFINES_helgrind = _DEBUG DEBUG
DEFINES_helgrind += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=20
VALID_CONFIG_asan-noleaks = 1
REQUIRE_CUSTOM_LIBRARIES_asan-noleaks = 1
@ -121,7 +120,6 @@ LD_asan-noleaks = clang
LDXX_asan-noleaks = clang++
CPPFLAGS_asan-noleaks = -O0 -fsanitize-coverage=edge -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
LDFLAGS_asan-noleaks = -fsanitize=address
DEFINES_asan-noleaks += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=3
VALID_CONFIG_asan-trace-cmp = 1
REQUIRE_CUSTOM_LIBRARIES_asan-trace-cmp = 1
@ -131,7 +129,6 @@ LD_asan-trace-cmp = clang
LDXX_asan-trace-cmp = clang++
CPPFLAGS_asan-trace-cmp = -O0 -fsanitize-coverage=edge -fsanitize-coverage=trace-cmp -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
LDFLAGS_asan-trace-cmp = -fsanitize=address
DEFINES_asan-trace-cmp += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=3
VALID_CONFIG_dbg = 1
CC_dbg = $(DEFAULT_CC)
@ -166,7 +163,6 @@ LDXX_memcheck = $(DEFAULT_CXX)
CPPFLAGS_memcheck = -O0
LDFLAGS_memcheck = -rdynamic
DEFINES_memcheck = _DEBUG DEBUG
DEFINES_memcheck += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=10
VALID_CONFIG_asan = 1
REQUIRE_CUSTOM_LIBRARIES_asan = 1
@ -176,7 +172,6 @@ LD_asan = clang
LDXX_asan = clang++
CPPFLAGS_asan = -O0 -fsanitize-coverage=edge -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
LDFLAGS_asan = -fsanitize=address
DEFINES_asan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=3
VALID_CONFIG_tsan = 1
REQUIRE_CUSTOM_LIBRARIES_tsan = 1
@ -187,7 +182,6 @@ LDXX_tsan = clang++
CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
LDFLAGS_tsan = -fsanitize=thread
DEFINES_tsan = GRPC_TSAN
DEFINES_tsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=5
VALID_CONFIG_ubsan = 1
REQUIRE_CUSTOM_LIBRARIES_ubsan = 1
@ -198,7 +192,6 @@ LDXX_ubsan = clang++
CPPFLAGS_ubsan = -O0 -fsanitize-coverage=edge -fsanitize=undefined,unsigned-integer-overflow -fno-omit-frame-pointer -Wno-unused-command-line-argument -Wvarargs
LDFLAGS_ubsan = -fsanitize=undefined,unsigned-integer-overflow
DEFINES_ubsan = NDEBUG
DEFINES_ubsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=1.5
VALID_CONFIG_msan = 1
REQUIRE_CUSTOM_LIBRARIES_msan = 1
@ -209,7 +202,6 @@ LDXX_msan = clang++
CPPFLAGS_msan = -O0 -fsanitize-coverage=edge -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
DEFINES_msan = NDEBUG
DEFINES_msan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=4
VALID_CONFIG_mutrace = 1
CC_mutrace = $(DEFAULT_CC)
@ -220,6 +212,14 @@ CPPFLAGS_mutrace = -O3 -fno-omit-frame-pointer
LDFLAGS_mutrace = -rdynamic
DEFINES_mutrace = NDEBUG
VALID_CONFIG_counters = 1
CC_counters = $(DEFAULT_CC)
CXX_counters = $(DEFAULT_CXX)
LD_counters = $(DEFAULT_CC)
LDXX_counters = $(DEFAULT_CXX)
CPPFLAGS_counters = -O2 -DGPR_MU_COUNTERS
DEFINES_counters = NDEBUG
# General settings.
@ -328,7 +328,7 @@ CXXFLAGS += -std=c++11
else
CXXFLAGS += -std=c++0x
endif
CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1
LDFLAGS += -g
CPPFLAGS += $(CPPFLAGS_$(CONFIG))
@ -411,9 +411,9 @@ E = @echo
Q = @
endif
CORE_VERSION = 2.0.0-dev
CPP_VERSION = 1.1.0-dev
CSHARP_VERSION = 1.1.0-dev
CORE_VERSION = 3.0.0-dev
CPP_VERSION = 1.2.0-dev
CSHARP_VERSION = 1.2.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@ -461,7 +461,7 @@ SHARED_EXT_CORE = dll
SHARED_EXT_CPP = dll
SHARED_EXT_CSHARP = dll
SHARED_PREFIX =
SHARED_VERSION_CORE = -2
SHARED_VERSION_CORE = -3
SHARED_VERSION_CPP = -1
SHARED_VERSION_CSHARP = -1
else ifeq ($(SYSTEM),Darwin)
@ -907,6 +907,7 @@ alloc_test: $(BINDIR)/$(CONFIG)/alloc_test
alpn_test: $(BINDIR)/$(CONFIG)/alpn_test
api_fuzzer: $(BINDIR)/$(CONFIG)/api_fuzzer
bad_server_response_test: $(BINDIR)/$(CONFIG)/bad_server_response_test
bdp_estimator_test: $(BINDIR)/$(CONFIG)/bdp_estimator_test
bin_decoder_test: $(BINDIR)/$(CONFIG)/bin_decoder_test
bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test
census_context_test: $(BINDIR)/$(CONFIG)/census_context_test
@ -1005,6 +1006,7 @@ no_server_test: $(BINDIR)/$(CONFIG)/no_server_test
percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer
percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer
percent_encoding_test: $(BINDIR)/$(CONFIG)/percent_encoding_test
pollset_set_test: $(BINDIR)/$(CONFIG)/pollset_set_test
resolve_address_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_posix_test
resolve_address_test: $(BINDIR)/$(CONFIG)/resolve_address_test
resource_quota_test: $(BINDIR)/$(CONFIG)/resource_quota_test
@ -1079,6 +1081,7 @@ metrics_client: $(BINDIR)/$(CONFIG)/metrics_client
mock_test: $(BINDIR)/$(CONFIG)/mock_test
noop-benchmark: $(BINDIR)/$(CONFIG)/noop-benchmark
proto_server_reflection_test: $(BINDIR)/$(CONFIG)/proto_server_reflection_test
proto_utils_test: $(BINDIR)/$(CONFIG)/proto_utils_test
qps_interarrival_test: $(BINDIR)/$(CONFIG)/qps_interarrival_test
qps_json_driver: $(BINDIR)/$(CONFIG)/qps_json_driver
qps_openloop_test: $(BINDIR)/$(CONFIG)/qps_openloop_test
@ -1098,6 +1101,7 @@ streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test
stress_test: $(BINDIR)/$(CONFIG)/stress_test
thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test
thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test
writes_per_rpc_test: $(BINDIR)/$(CONFIG)/writes_per_rpc_test
public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89
boringssl_aes_test: $(BINDIR)/$(CONFIG)/boringssl_aes_test
boringssl_asn1_test: $(BINDIR)/$(CONFIG)/boringssl_asn1_test
@ -1267,6 +1271,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/alloc_test \
$(BINDIR)/$(CONFIG)/alpn_test \
$(BINDIR)/$(CONFIG)/bad_server_response_test \
$(BINDIR)/$(CONFIG)/bdp_estimator_test \
$(BINDIR)/$(CONFIG)/bin_decoder_test \
$(BINDIR)/$(CONFIG)/bin_encoder_test \
$(BINDIR)/$(CONFIG)/census_context_test \
@ -1349,6 +1354,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/murmur_hash_test \
$(BINDIR)/$(CONFIG)/no_server_test \
$(BINDIR)/$(CONFIG)/percent_encoding_test \
$(BINDIR)/$(CONFIG)/pollset_set_test \
$(BINDIR)/$(CONFIG)/resolve_address_posix_test \
$(BINDIR)/$(CONFIG)/resolve_address_test \
$(BINDIR)/$(CONFIG)/resource_quota_test \
@ -1474,6 +1480,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/mock_test \
$(BINDIR)/$(CONFIG)/noop-benchmark \
$(BINDIR)/$(CONFIG)/proto_server_reflection_test \
$(BINDIR)/$(CONFIG)/proto_utils_test \
$(BINDIR)/$(CONFIG)/qps_interarrival_test \
$(BINDIR)/$(CONFIG)/qps_json_driver \
$(BINDIR)/$(CONFIG)/qps_openloop_test \
@ -1493,6 +1500,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \
$(BINDIR)/$(CONFIG)/thread_stress_test \
$(BINDIR)/$(CONFIG)/writes_per_rpc_test \
$(BINDIR)/$(CONFIG)/boringssl_aes_test \
$(BINDIR)/$(CONFIG)/boringssl_asn1_test \
$(BINDIR)/$(CONFIG)/boringssl_base64_test \
@ -1576,6 +1584,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/mock_test \
$(BINDIR)/$(CONFIG)/noop-benchmark \
$(BINDIR)/$(CONFIG)/proto_server_reflection_test \
$(BINDIR)/$(CONFIG)/proto_utils_test \
$(BINDIR)/$(CONFIG)/qps_interarrival_test \
$(BINDIR)/$(CONFIG)/qps_json_driver \
$(BINDIR)/$(CONFIG)/qps_openloop_test \
@ -1595,6 +1604,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \
$(BINDIR)/$(CONFIG)/thread_stress_test \
$(BINDIR)/$(CONFIG)/writes_per_rpc_test \
endif
@ -1614,6 +1624,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/alpn_test || ( echo test alpn_test failed ; exit 1 )
$(E) "[RUN] Testing bad_server_response_test"
$(Q) $(BINDIR)/$(CONFIG)/bad_server_response_test || ( echo test bad_server_response_test failed ; exit 1 )
$(E) "[RUN] Testing bdp_estimator_test"
$(Q) $(BINDIR)/$(CONFIG)/bdp_estimator_test || ( echo test bdp_estimator_test failed ; exit 1 )
$(E) "[RUN] Testing bin_decoder_test"
$(Q) $(BINDIR)/$(CONFIG)/bin_decoder_test || ( echo test bin_decoder_test failed ; exit 1 )
$(E) "[RUN] Testing bin_encoder_test"
@ -1756,6 +1768,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/no_server_test || ( echo test no_server_test failed ; exit 1 )
$(E) "[RUN] Testing percent_encoding_test"
$(Q) $(BINDIR)/$(CONFIG)/percent_encoding_test || ( echo test percent_encoding_test failed ; exit 1 )
$(E) "[RUN] Testing pollset_set_test"
$(Q) $(BINDIR)/$(CONFIG)/pollset_set_test || ( echo test pollset_set_test failed ; exit 1 )
$(E) "[RUN] Testing resolve_address_posix_test"
$(Q) $(BINDIR)/$(CONFIG)/resolve_address_posix_test || ( echo test resolve_address_posix_test failed ; exit 1 )
$(E) "[RUN] Testing resolve_address_test"
@ -1894,8 +1908,6 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 )
$(E) "[RUN] Testing grpclb_test"
$(Q) $(BINDIR)/$(CONFIG)/grpclb_test || ( echo test grpclb_test failed ; exit 1 )
$(E) "[RUN] Testing hybrid_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/hybrid_end2end_test || ( echo test hybrid_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing interop_test"
$(Q) $(BINDIR)/$(CONFIG)/interop_test || ( echo test interop_test failed ; exit 1 )
$(E) "[RUN] Testing mock_test"
@ -1904,6 +1916,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/noop-benchmark || ( echo test noop-benchmark failed ; exit 1 )
$(E) "[RUN] Testing proto_server_reflection_test"
$(Q) $(BINDIR)/$(CONFIG)/proto_server_reflection_test || ( echo test proto_server_reflection_test failed ; exit 1 )
$(E) "[RUN] Testing proto_utils_test"
$(Q) $(BINDIR)/$(CONFIG)/proto_utils_test || ( echo test proto_utils_test failed ; exit 1 )
$(E) "[RUN] Testing qps_openloop_test"
$(Q) $(BINDIR)/$(CONFIG)/qps_openloop_test || ( echo test qps_openloop_test failed ; exit 1 )
$(E) "[RUN] Testing round_robin_end2end_test"
@ -1928,9 +1942,13 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/thread_manager_test || ( echo test thread_manager_test failed ; exit 1 )
$(E) "[RUN] Testing thread_stress_test"
$(Q) $(BINDIR)/$(CONFIG)/thread_stress_test || ( echo test thread_stress_test failed ; exit 1 )
$(E) "[RUN] Testing writes_per_rpc_test"
$(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 )
flaky_test_cxx: buildtests_cxx
$(E) "[RUN] Testing hybrid_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/hybrid_end2end_test || ( echo test hybrid_end2end_test failed ; exit 1 )
test_python: static_c
@ -2342,7 +2360,7 @@ install-shared_c: shared_c strip-shared_c install-pkg-config_c
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgpr.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so.2
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so.3
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgpr.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -2351,7 +2369,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so.2
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so.3
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -2360,7 +2378,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc_cronet.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so.2
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so.3
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_cronet.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)"
@ -2369,7 +2387,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a $(prefix)/lib/libgrpc_unsecure.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so.2
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so.3
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(prefix)/lib/libgrpc_unsecure.so
endif
ifneq ($(SYSTEM),MINGW32)
@ -2386,7 +2404,7 @@ install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c install-pkg-con
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.2
$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.3
$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@ -2395,7 +2413,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_cronet.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.2
$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.3
$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@ -2404,7 +2422,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_reflection.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.2
$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.3
$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@ -2413,7 +2431,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_unsecure.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.2
$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.3
$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so
endif
ifneq ($(SYSTEM),MINGW32)
@ -2430,7 +2448,7 @@ install-shared_csharp: shared_csharp strip-shared_csharp
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a $(prefix)/lib/libgrpc_csharp_ext.a
else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.2
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.3
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so
endif
ifneq ($(SYSTEM),MINGW32)
@ -2594,8 +2612,8 @@ $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OB
ifeq ($(SYSTEM),Darwin)
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS)
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.2 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS)
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.2
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.3 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS)
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.3
$(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so
endif
endif
@ -2737,6 +2755,7 @@ LIBGRPC_SRC = \
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -2787,6 +2806,7 @@ LIBGRPC_SRC = \
src/core/lib/security/credentials/plugin/plugin_credentials.c \
src/core/lib/security/credentials/ssl/ssl_credentials.c \
src/core/lib/security/transport/client_auth_filter.c \
src/core/lib/security/transport/lb_targets_info.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
src/core/lib/security/transport/security_handshaker.c \
@ -2827,6 +2847,7 @@ LIBGRPC_SRC = \
src/core/ext/transport/chttp2/client/insecure/channel_create.c \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
src/core/ext/lb_policy/grpclb/grpclb.c \
src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c \
src/core/ext/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
third_party/nanopb/pb_common.c \
@ -2923,8 +2944,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_
ifeq ($(SYSTEM),Darwin)
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.2
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.3
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
endif
endif
@ -3045,6 +3066,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -3119,6 +3141,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/security/credentials/plugin/plugin_credentials.c \
src/core/lib/security/credentials/ssl/ssl_credentials.c \
src/core/lib/security/transport/client_auth_filter.c \
src/core/lib/security/transport/lb_targets_info.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
src/core/lib/security/transport/security_handshaker.c \
@ -3202,8 +3225,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(L
ifeq ($(SYSTEM),Darwin)
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so.2
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so.3
$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION_CORE).so
endif
endif
@ -3228,6 +3251,7 @@ LIBGRPC_TEST_UTIL_SRC = \
test/core/end2end/fixtures/http_proxy.c \
test/core/end2end/fixtures/proxy.c \
test/core/iomgr/endpoint_tests.c \
test/core/util/debugger_macros.c \
test/core/util/grpc_profiler.c \
test/core/util/memory_counters.c \
test/core/util/mock_endpoint.c \
@ -3343,6 +3367,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -3426,6 +3451,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
test/core/end2end/fixtures/http_proxy.c \
test/core/end2end/fixtures/proxy.c \
test/core/iomgr/endpoint_tests.c \
test/core/util/debugger_macros.c \
test/core/util/grpc_profiler.c \
test/core/util/memory_counters.c \
test/core/util/mock_endpoint.c \
@ -3567,6 +3593,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -3632,6 +3659,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/load_reporting/load_reporting.c \
src/core/ext/load_reporting/load_reporting_filter.c \
src/core/ext/lb_policy/grpclb/grpclb.c \
src/core/ext/lb_policy/grpclb/grpclb_channel.c \
src/core/ext/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
third_party/nanopb/pb_common.c \
@ -3712,8 +3740,8 @@ $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $
ifeq ($(SYSTEM),Darwin)
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
else
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.2
$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.3
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
endif
endif
@ -3896,6 +3924,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/core_codegen_interface.h \
include/grpc++/impl/codegen/create_auth_context.h \
include/grpc++/impl/codegen/grpc_library.h \
include/grpc++/impl/codegen/metadata_map.h \
include/grpc++/impl/codegen/method_handler_impl.h \
include/grpc++/impl/codegen/rpc_method.h \
include/grpc++/impl/codegen/rpc_service_method.h \
@ -3931,6 +3960,8 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h \
include/grpc++/impl/codegen/proto_utils.h \
include/grpc++/impl/codegen/config_protobuf.h \
LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
@ -3978,7 +4009,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC+
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so
endif
@ -4157,6 +4188,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -4268,6 +4300,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/core_codegen_interface.h \
include/grpc++/impl/codegen/create_auth_context.h \
include/grpc++/impl/codegen/grpc_library.h \
include/grpc++/impl/codegen/metadata_map.h \
include/grpc++/impl/codegen/method_handler_impl.h \
include/grpc++/impl/codegen/rpc_method.h \
include/grpc++/impl/codegen/rpc_service_method.h \
@ -4360,7 +4393,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(L
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_cronet
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_cronet.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_cronet
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_cronet.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_CRONET_OBJS) $(LDLIBS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_cronet
$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP).so
endif
@ -4483,7 +4516,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP):
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so
endif
@ -4626,6 +4659,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/core_codegen_interface.h \
include/grpc++/impl/codegen/create_auth_context.h \
include/grpc++/impl/codegen/grpc_library.h \
include/grpc++/impl/codegen/metadata_map.h \
include/grpc++/impl/codegen/method_handler_impl.h \
include/grpc++/impl/codegen/rpc_method.h \
include/grpc++/impl/codegen/rpc_service_method.h \
@ -4807,6 +4841,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/core_codegen_interface.h \
include/grpc++/impl/codegen/create_auth_context.h \
include/grpc++/impl/codegen/grpc_library.h \
include/grpc++/impl/codegen/metadata_map.h \
include/grpc++/impl/codegen/method_handler_impl.h \
include/grpc++/impl/codegen/rpc_method.h \
include/grpc++/impl/codegen/rpc_service_method.h \
@ -4879,7 +4914,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $
ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so
endif
@ -5420,7 +5455,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHA
ifeq ($(SYSTEM),Darwin)
$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
else
$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.2 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
$(Q) $(LD) $(LDFLAGS) $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.3 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(ZLIB_MERGE_LIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP).so
endif
@ -7969,6 +8004,38 @@ endif
endif
BDP_ESTIMATOR_TEST_SRC = \
test/core/transport/bdp_estimator_test.c \
BDP_ESTIMATOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BDP_ESTIMATOR_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bdp_estimator_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/bdp_estimator_test: $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bdp_estimator_test
endif
$(OBJDIR)/$(CONFIG)/test/core/transport/bdp_estimator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_bdp_estimator_test: $(BDP_ESTIMATOR_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BDP_ESTIMATOR_TEST_OBJS:.o=.dep)
endif
endif
BIN_DECODER_TEST_SRC = \
test/core/transport/chttp2/bin_decoder_test.c \
@ -11105,6 +11172,38 @@ endif
endif
POLLSET_SET_TEST_SRC = \
test/core/iomgr/pollset_set_test.c \
POLLSET_SET_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(POLLSET_SET_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/pollset_set_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/pollset_set_test: $(POLLSET_SET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(POLLSET_SET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/pollset_set_test
endif
$(OBJDIR)/$(CONFIG)/test/core/iomgr/pollset_set_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_pollset_set_test: $(POLLSET_SET_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(POLLSET_SET_TEST_OBJS:.o=.dep)
endif
endif
RESOLVE_ADDRESS_POSIX_TEST_SRC = \
test/core/iomgr/resolve_address_posix_test.c \
@ -13863,6 +13962,49 @@ endif
endif
PROTO_UTILS_TEST_SRC = \
test/cpp/codegen/proto_utils_test.cc \
PROTO_UTILS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PROTO_UTILS_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/proto_utils_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
$(BINDIR)/$(CONFIG)/proto_utils_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/proto_utils_test: $(PROTOBUF_DEP) $(PROTO_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(PROTO_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/proto_utils_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/codegen/proto_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a
deps_proto_utils_test: $(PROTO_UTILS_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(PROTO_UTILS_TEST_OBJS:.o=.dep)
endif
endif
QPS_INTERARRIVAL_TEST_SRC = \
test/cpp/qps/qps_interarrival_test.cc \
@ -14729,6 +14871,49 @@ endif
endif
WRITES_PER_RPC_TEST_SRC = \
test/cpp/performance/writes_per_rpc_test.cc \
WRITES_PER_RPC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WRITES_PER_RPC_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/writes_per_rpc_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
$(BINDIR)/$(CONFIG)/writes_per_rpc_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/writes_per_rpc_test: $(PROTOBUF_DEP) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/writes_per_rpc_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/performance/writes_per_rpc_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_writes_per_rpc_test: $(WRITES_PER_RPC_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(WRITES_PER_RPC_TEST_OBJS:.o=.dep)
endif
endif
PUBLIC_HEADERS_MUST_BE_C89_SRC = \
test/core/surface/public_headers_must_be_c89.c \
@ -17570,6 +17755,7 @@ ifneq ($(OPENSSL_DEP),)
# This is to ensure the embedded OpenSSL is built beforehand, properly
# installing headers to their final destination on the drive. We need this
# otherwise parallel compilation will fail if a source is compiled first.
src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c: $(OPENSSL_DEP)
src/core/ext/transport/chttp2/client/secure/secure_channel_create.c: $(OPENSSL_DEP)
src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c: $(OPENSSL_DEP)
src/core/ext/transport/cronet/client/secure/cronet_channel_create.c: $(OPENSSL_DEP)
@ -17591,6 +17777,7 @@ src/core/lib/security/credentials/oauth2/oauth2_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/credentials/plugin/plugin_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/credentials/ssl/ssl_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/transport/client_auth_filter.c: $(OPENSSL_DEP)
src/core/lib/security/transport/lb_targets_info.c: $(OPENSSL_DEP)
src/core/lib/security/transport/secure_endpoint.c: $(OPENSSL_DEP)
src/core/lib/security/transport/security_connector.c: $(OPENSSL_DEP)
src/core/lib/security/transport/security_handshaker.c: $(OPENSSL_DEP)

@ -707,6 +707,7 @@
'src/core/lib/surface/server.c',
'src/core/lib/surface/validate_metadata.c',
'src/core/lib/surface/version.c',
'src/core/lib/transport/bdp_estimator.c',
'src/core/lib/transport/byte_stream.c',
'src/core/lib/transport/connectivity_state.c',
'src/core/lib/transport/error_utils.c',
@ -757,6 +758,7 @@
'src/core/lib/security/credentials/plugin/plugin_credentials.c',
'src/core/lib/security/credentials/ssl/ssl_credentials.c',
'src/core/lib/security/transport/client_auth_filter.c',
'src/core/lib/security/transport/lb_targets_info.c',
'src/core/lib/security/transport/secure_endpoint.c',
'src/core/lib/security/transport/security_connector.c',
'src/core/lib/security/transport/security_handshaker.c',
@ -797,6 +799,7 @@
'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
'src/core/ext/lb_policy/grpclb/grpclb.c',
'src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c',
'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'third_party/nanopb/pb_common.c',

@ -12,9 +12,9 @@ settings:
'#08': Use "-preN" suffixes to identify pre-release versions
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 2.0.0-dev
g_stands_for: good
version: 1.1.0-dev
core_version: 3.0.0-dev
g_stands_for: green
version: 1.2.0-dev
filegroups:
- name: census
public_headers:
@ -31,6 +31,11 @@ filegroups:
- src/core/ext/census/resource.h
- src/core/ext/census/rpc_metric_id.h
- src/core/ext/census/trace_context.h
- src/core/ext/census/trace_label.h
- src/core/ext/census/trace_propagation.h
- src/core/ext/census/trace_status.h
- src/core/ext/census/trace_string.h
- src/core/ext/census/tracing.h
src:
- src/core/ext/census/base_resources.c
- src/core/ext/census/context.c
@ -256,6 +261,7 @@ filegroups:
- src/core/lib/surface/lame_client.h
- src/core/lib/surface/server.h
- src/core/lib/surface/validate_metadata.h
- src/core/lib/transport/bdp_estimator.h
- src/core/lib/transport/byte_stream.h
- src/core/lib/transport/connectivity_state.h
- src/core/lib/transport/error_utils.h
@ -375,6 +381,7 @@ filegroups:
- src/core/lib/surface/server.c
- src/core/lib/surface/validate_metadata.c
- src/core/lib/surface/version.c
- src/core/lib/transport/bdp_estimator.c
- src/core/lib/transport/byte_stream.c
- src/core/lib/transport/connectivity_state.c
- src/core/lib/transport/error_utils.c
@ -450,10 +457,28 @@ filegroups:
- name: grpc_lb_policy_grpclb
headers:
- src/core/ext/lb_policy/grpclb/grpclb.h
- src/core/ext/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/lb_policy/grpclb/load_balancer_api.h
- src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
src:
- src/core/ext/lb_policy/grpclb/grpclb.c
- src/core/ext/lb_policy/grpclb/grpclb_channel.c
- src/core/ext/lb_policy/grpclb/load_balancer_api.c
- src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
plugin: grpc_lb_policy_grpclb
uses:
- grpc_base
- grpc_client_channel
- nanopb
- name: grpc_lb_policy_grpclb_secure
headers:
- src/core/ext/lb_policy/grpclb/grpclb.h
- src/core/ext/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/lb_policy/grpclb/load_balancer_api.h
- src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
src:
- src/core/ext/lb_policy/grpclb/grpclb.c
- src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c
- src/core/ext/lb_policy/grpclb/load_balancer_api.c
- src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
plugin: grpc_lb_policy_grpclb
@ -516,6 +541,7 @@ filegroups:
- src/core/lib/security/credentials/plugin/plugin_credentials.h
- src/core/lib/security/credentials/ssl/ssl_credentials.h
- src/core/lib/security/transport/auth_filters.h
- src/core/lib/security/transport/lb_targets_info.h
- src/core/lib/security/transport/secure_endpoint.h
- src/core/lib/security/transport/security_connector.h
- src/core/lib/security/transport/security_handshaker.h
@ -539,6 +565,7 @@ filegroups:
- src/core/lib/security/credentials/plugin/plugin_credentials.c
- src/core/lib/security/credentials/ssl/ssl_credentials.c
- src/core/lib/security/transport/client_auth_filter.c
- src/core/lib/security/transport/lb_targets_info.c
- src/core/lib/security/transport/secure_endpoint.c
- src/core/lib/security/transport/security_connector.c
- src/core/lib/security/transport/security_handshaker.c
@ -560,6 +587,7 @@ filegroups:
- test/core/end2end/fixtures/http_proxy.h
- test/core/end2end/fixtures/proxy.h
- test/core/iomgr/endpoint_tests.h
- test/core/util/debugger_macros.h
- test/core/util/grpc_profiler.h
- test/core/util/memory_counters.h
- test/core/util/mock_endpoint.h
@ -574,6 +602,7 @@ filegroups:
- test/core/end2end/fixtures/http_proxy.c
- test/core/end2end/fixtures/proxy.c
- test/core/iomgr/endpoint_tests.c
- test/core/util/debugger_macros.c
- test/core/util/grpc_profiler.c
- test/core/util/memory_counters.c
- test/core/util/mock_endpoint.c
@ -695,7 +724,7 @@ filegroups:
- include/grpc/grpc_security.h
- include/grpc/grpc_security_constants.h
headers:
- third_party/Cronet/bidirectional_stream_c.h
- third_party/objective_c/Cronet/bidirectional_stream_c.h
src:
- src/core/ext/transport/cronet/client/secure/cronet_channel_create.c
- src/core/ext/transport/cronet/transport/cronet_api_dummy.c
@ -825,6 +854,7 @@ filegroups:
- include/grpc++/impl/codegen/core_codegen_interface.h
- include/grpc++/impl/codegen/create_auth_context.h
- include/grpc++/impl/codegen/grpc_library.h
- include/grpc++/impl/codegen/metadata_map.h
- include/grpc++/impl/codegen/method_handler_impl.h
- include/grpc++/impl/codegen/rpc_method.h
- include/grpc++/impl/codegen/rpc_service_method.h
@ -904,7 +934,7 @@ libs:
- grpc_transport_chttp2_client_secure
- grpc_transport_chttp2_server_insecure
- grpc_transport_chttp2_client_insecure
- grpc_lb_policy_grpclb
- grpc_lb_policy_grpclb_secure
- grpc_lb_policy_pick_first
- grpc_lb_policy_round_robin
- grpc_resolver_dns_native
@ -1058,6 +1088,7 @@ libs:
filegroups:
- grpc++_base
- grpc++_codegen_base
- grpc++_codegen_proto
- grpc++_codegen_base_src
secure: check
vs_project_guid: '{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}'
@ -1439,6 +1470,16 @@ targets:
- gpr
exclude_iomgrs:
- uv
- name: bdp_estimator_test
build: test
language: c
src:
- test/core/transport/bdp_estimator_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: bin_decoder_test
build: test
language: c
@ -2489,6 +2530,20 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: pollset_set_test
build: test
language: c
src:
- test/core/iomgr/pollset_set_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
exclude_iomgrs:
- uv
platforms:
- linux
- name: resolve_address_posix_test
build: test
language: c
@ -2942,6 +2997,12 @@ targets:
- grpc
- gpr_test_util
- gpr
args:
- --benchmark_min_time=0
platforms:
- mac
- linux
- posix
- name: channel_arguments_test
gtest: true
build: test
@ -3287,7 +3348,7 @@ targets:
- linux
- posix
- name: hybrid_end2end_test
gtest: true
flaky: true
build: test
language: c++
src:
@ -3368,6 +3429,10 @@ targets:
- gpr_test_util
- gpr
- grpc++_test_config
platforms:
- mac
- linux
- posix
- name: metrics_client
build: test
run: false
@ -3417,6 +3482,18 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: proto_utils_test
gtest: true
build: test
language: c++
src:
- test/cpp/codegen/proto_utils_test.cc
deps:
- grpc++
- grpc
filegroups:
- grpc++_codegen_base
- grpc++_codegen_proto
- name: qps_interarrival_test
build: test
run: false
@ -3716,6 +3793,24 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: writes_per_rpc_test
gtest: true
cpu_cost: 0.5
build: test
language: c++
src:
- test/cpp/performance/writes_per_rpc_test.cc
deps:
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
platforms:
- mac
- linux
- posix
- name: public_headers_must_be_c89
build: test
language: c89
@ -3756,7 +3851,6 @@ configs:
test_environ:
ASAN_OPTIONS: detect_leaks=1:color=always
LSAN_OPTIONS: suppressions=tools/lsan_suppressions.txt:report_objects=1
timeout_multiplier: 3
asan-noleaks:
CC: clang
CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize=address -fno-omit-frame-pointer
@ -3768,7 +3862,6 @@ configs:
compile_the_world: true
test_environ:
ASAN_OPTIONS: detect_leaks=0:color=always
timeout_multiplier: 3
asan-trace-cmp:
CC: clang
CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize-coverage=trace-cmp -fsanitize=address
@ -3781,10 +3874,12 @@ configs:
test_environ:
ASAN_OPTIONS: detect_leaks=1:color=always
LSAN_OPTIONS: suppressions=tools/lsan_suppressions.txt:report_objects=1
timeout_multiplier: 3
basicprof:
CPPFLAGS: -O2 -DGRPC_BASIC_PROFILER -DGRPC_TIMERS_RDTSC
DEFINES: NDEBUG
counters:
CPPFLAGS: -O2 -DGPR_MU_COUNTERS
DEFINES: NDEBUG
dbg:
CPPFLAGS: -O0
DEFINES: _DEBUG DEBUG
@ -3800,13 +3895,11 @@ configs:
CPPFLAGS: -O0
DEFINES: _DEBUG DEBUG
LDFLAGS: -rdynamic
timeout_multiplier: 20
valgrind: --tool=helgrind
memcheck:
CPPFLAGS: -O0
DEFINES: _DEBUG DEBUG
LDFLAGS: -rdynamic
timeout_multiplier: 10
valgrind: --tool=memcheck --leak-check=full
msan:
CC: clang
@ -3820,7 +3913,6 @@ configs:
-fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
LDXX: clang++
compile_the_world: true
timeout_multiplier: 4
mutrace:
CPPFLAGS: -O3 -fno-omit-frame-pointer
DEFINES: NDEBUG
@ -3843,7 +3935,6 @@ configs:
compile_the_world: true
test_environ:
TSAN_OPTIONS: suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1
timeout_multiplier: 5
ubsan:
CC: clang
CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize=undefined,unsigned-integer-overflow
@ -3856,7 +3947,6 @@ configs:
compile_the_world: true
test_environ:
UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1
timeout_multiplier: 1.5
defaults:
benchmark:
CPPFLAGS: -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
@ -3866,7 +3956,7 @@ defaults:
CPPFLAGS: -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM
-D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
global:
CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1
LDFLAGS: -g
zlib:
CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration

@ -28,5 +28,5 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
module GrpcBuildConfig
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-2.dll'
CORE_WINDOWS_DLL = '/tmp/libs/opt/grpc-3.dll'
end

@ -0,0 +1,14 @@
option(gRPC_MSVC_STATIC_RUNTIME "Link with static msvc runtime libraries" OFF)
if(gRPC_MSVC_STATIC_RUNTIME)
# switch from dynamic to static linking of msvcrt
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)
endif()

@ -7,8 +7,7 @@
"license": "BSD-3-Clause",
"require": {
"php": ">=5.5.0",
"ext-grpc": "*",
"google/protobuf": "v3.1.0-alpha-1"
"google/protobuf": "v3.1.0"
},
"require-dev": {
"google/auth": "v0.9"

@ -186,6 +186,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/surface/server.c \
src/core/lib/surface/validate_metadata.c \
src/core/lib/surface/version.c \
src/core/lib/transport/bdp_estimator.c \
src/core/lib/transport/byte_stream.c \
src/core/lib/transport/connectivity_state.c \
src/core/lib/transport/error_utils.c \
@ -236,6 +237,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/security/credentials/plugin/plugin_credentials.c \
src/core/lib/security/credentials/ssl/ssl_credentials.c \
src/core/lib/security/transport/client_auth_filter.c \
src/core/lib/security/transport/lb_targets_info.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
src/core/lib/security/transport/security_handshaker.c \
@ -276,6 +278,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/transport/chttp2/client/insecure/channel_create.c \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
src/core/ext/lb_policy/grpclb/grpclb.c \
src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c \
src/core/ext/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
third_party/nanopb/pb_common.c \

@ -60,21 +60,22 @@ HTTP/2 related behavior (specified in [gRPC over HTTP2](http://www.grpc.io/docs/
Message framing (vs. [http2-transport-mapping](http://www.grpc.io/docs/guides/wire.html#http2-transport-mapping))
1. Response status encoded as part of the response body
* Key-value pairs encoded in the HTTP/2 [literal header format](https://tools.ietf.org/html/rfc7541#section-6.2) as a single header block.
* Key-value pairs encoded as a HTTP/1 headers block (without the terminating newline).
2. 8th (MSB) bit of the 1st gRPC frame byte
* 0: data
* 1: trailers
3. Trailers must be the last message of the response, as enforced
by the implementation
4. Trailers-only responses: no change to the gRPC protocol spec.
Trailers will be sent together with response headers, with no message
Trailers may be sent together with response headers, with no message
in the body.
---
User Agent
User Agent and Server headers
* grpc-web-javascript/0.1
* U-A: grpc-web-javascript/0.1
* Server: grpc-web-gateway/0.1
---

@ -2,8 +2,8 @@
## Overview
This document describes the command line tool that comes with gRPC repository. It is desireable to have command line
tools written in other languages to roughly follow the same syntax and flags.
This document describes the command line tool that comes with gRPC repository. It is desirable to have command line
tools written in other languages roughly follow the same syntax and flags.
At this point, the tool needs to be built from source, and it should be moved out to grpc-tools repository as a stand
alone application once it is mature enough.
@ -30,7 +30,26 @@ The command line tool should support the following things:
## Code location
To use the tool, you need to get the grpc repository and in the grpc directory execute
To use the tool, you need to get the grpc repository and make sure your system
has the prerequisites for building grpc from source, given in the [installation
instructions](https://github.com/grpc/grpc/blob/master/INSTALL.md).
In order to build the grpc command line tool from a fresh clone of the grpc
repository, you need to run the following command to update submodules:
```
git submodule update --init
```
You also need to have the gflags library installed on your system. On Linux
systems, gflags can be installed with the following command:
```
sudo apt-get install libgflags-dev
```
Once the prerequisites are satisfied, you can build the command line tool with
the command:
```
$ make grpc_cli

@ -35,6 +35,8 @@ some configuration as environment variables that can be set.
A comma separated list of tracers that provide additional insight into how
gRPC C core is processing requests via debug logs. Available tracers include:
- api - traces api calls to the C core
- bdp_estimator - traces behavior of bdp estimation logic
- call_error - traces the possible errors contributing to final call status
- channel - traces operations on the C core channel stack
- combiner - traces combiner lock state
- compression - traces compression operations
@ -55,10 +57,10 @@ some configuration as environment variables that can be set.
- secure_endpoint - traces bytes flowing through encrypted channels
- transport_security - traces metadata about secure channel establishment
- tcp - traces bytes in and out of a channel
'all' can additionally be used to turn all traces on.
Individual traces can be disabled by prefixing them with '-'.
Example:
export GRPC_TRACE=all,-pending_tags

@ -6,3 +6,4 @@ future), and the corresponding version numbers that used them:
- 1.0 'g' stands for 'gRPC'
- 1.1 'g' stands for 'good'
- 1.2 'g' stands for 'green'

@ -34,7 +34,7 @@ setlocal
@rem enter this directory
cd /d %~dp0
set TOOLS_PATH=packages\Grpc.Tools.1.0.0\tools\windows_x86
set TOOLS_PATH=packages\Grpc.Tools.1.0.1\tools\windows_x86
%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe

@ -2,7 +2,11 @@
"name": "grpc/grpc-demo",
"description": "gRPC example for PHP",
"require": {
"ext-grpc": "*",
"grpc/grpc": "v1.0.0"
"grpc/grpc": "v1.1.0"
},
"autoload": {
"psr-4": {
"": "route_guide/"
}
}
}

@ -33,14 +33,18 @@
*/
require dirname(__FILE__).'/vendor/autoload.php';
require dirname(__FILE__).'/helloworld.php';
// The following includes are needed when using protobuf 3.1.0
// and will suppress warnings when using protobuf 3.2.0+
@include_once dirname(__FILE__).'/helloworld.pb.php';
@include_once dirname(__FILE__).'/helloworld_grpc_pb.php';
function greet($name)
{
$client = new helloworld\GreeterClient('localhost:50051', [
$client = new Helloworld\GreeterClient('localhost:50051', [
'credentials' => Grpc\ChannelCredentials::createInsecure(),
]);
$request = new helloworld\HelloRequest();
$request = new Helloworld\HelloRequest();
$request->setName($name);
list($reply, $status) = $client->SayHello($request)->wait();
$message = $reply->getMessage();

@ -0,0 +1,58 @@
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto
namespace Helloworld;
use Google\Protobuf\Internal\DescriptorPool;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;
class HelloRequest extends \Google\Protobuf\Internal\Message
{
private $name = '';
public function getName()
{
return $this->name;
}
public function setName($var)
{
GPBUtil::checkString($var, True);
$this->name = $var;
}
}
class HelloReply extends \Google\Protobuf\Internal\Message
{
private $message = '';
public function getMessage()
{
return $this->message;
}
public function setMessage($var)
{
GPBUtil::checkString($var, True);
$this->message = $var;
}
}
$pool = DescriptorPool::getGeneratedPool();
$pool->internalAddGeneratedFile(hex2bin(
"0ae6010a1068656c6c6f776f726c642e70726f746f120a68656c6c6f776f" .
"726c64221c0a0c48656c6c6f52657175657374120c0a046e616d65180120" .
"012809221d0a0a48656c6c6f5265706c79120f0a076d6573736167651801" .
"2001280932490a0747726565746572123e0a0853617948656c6c6f12182e" .
"68656c6c6f776f726c642e48656c6c6f526571756573741a162e68656c6c" .
"6f776f726c642e48656c6c6f5265706c79220042360a1b696f2e67727063" .
"2e6578616d706c65732e68656c6c6f776f726c64420f48656c6c6f576f72" .
"6c6450726f746f5001a20203484c57620670726f746f33"
));

@ -1,168 +0,0 @@
<?php
// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0
// Source: helloworld.proto
// Date: 2015-09-24 20:40:14
namespace helloworld {
class HelloRequest extends \DrSlump\Protobuf\Message
{
/** @var string */
public $name = null;
/** @var \Closure[] */
protected static $__extensions = array();
public static function descriptor()
{
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloRequest');
// OPTIONAL STRING name = 1
$f = new \DrSlump\Protobuf\Field();
$f->number = 1;
$f->name = 'name';
$f->type = \DrSlump\Protobuf::TYPE_STRING;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$descriptor->addField($f);
foreach (self::$__extensions as $cb) {
$descriptor->addField($cb(), true);
}
return $descriptor;
}
/**
* Check if <name> has a value.
*
* @return bool
*/
public function hasName()
{
return $this->_has(1);
}
/**
* Clear <name> value.
*
* @return \helloworld\HelloRequest
*/
public function clearName()
{
return $this->_clear(1);
}
/**
* Get <name> value.
*
* @return string
*/
public function getName()
{
return $this->_get(1);
}
/**
* Set <name> value.
*
* @param string $value
*
* @return \helloworld\HelloRequest
*/
public function setName($value)
{
return $this->_set(1, $value);
}
}
}
namespace helloworld {
class HelloReply extends \DrSlump\Protobuf\Message
{
/** @var string */
public $message = null;
/** @var \Closure[] */
protected static $__extensions = array();
public static function descriptor()
{
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloReply');
// OPTIONAL STRING message = 1
$f = new \DrSlump\Protobuf\Field();
$f->number = 1;
$f->name = 'message';
$f->type = \DrSlump\Protobuf::TYPE_STRING;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$descriptor->addField($f);
foreach (self::$__extensions as $cb) {
$descriptor->addField($cb(), true);
}
return $descriptor;
}
/**
* Check if <message> has a value.
*
* @return bool
*/
public function hasMessage()
{
return $this->_has(1);
}
/**
* Clear <message> value.
*
* @return \helloworld\HelloReply
*/
public function clearMessage()
{
return $this->_clear(1);
}
/**
* Get <message> value.
*
* @return string
*/
public function getMessage()
{
return $this->_get(1);
}
/**
* Set <message> value.
*
* @param string $value
*
* @return \helloworld\HelloReply
*/
public function setMessage($value)
{
return $this->_set(1, $value);
}
}
}
namespace helloworld {
class GreeterClient extends \Grpc\BaseStub
{
public function __construct($hostname, $opts)
{
parent::__construct($hostname, $opts);
}
/**
* @param helloworld\HelloRequest $input
*/
public function SayHello(\helloworld\HelloRequest $argument, $metadata = array(), $options = array())
{
return $this->_simpleRequest('/helloworld.Greeter/SayHello', $argument, '\helloworld\HelloReply::deserialize', $metadata, $options);
}
}
}

@ -0,0 +1,64 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
namespace Helloworld {
// The greeting service definition.
class GreeterClient extends \Grpc\BaseStub {
/**
* @param string $hostname hostname
* @param array $opts channel options
* @param Grpc\Channel $channel (optional) re-use channel object
*/
public function __construct($hostname, $opts, $channel = null) {
parent::__construct($hostname, $opts, $channel);
}
/**
* Sends a greeting
* @param \Helloworld\HelloRequest $argument input argument
* @param array $metadata metadata
* @param array $options call options
*/
public function SayHello(\Helloworld\HelloRequest $argument,
$metadata = [], $options = []) {
return $this->_simpleRequest('/helloworld.Greeter/SayHello',
$argument,
['\Helloworld\HelloReply', 'decode'],
$metadata, $options);
}
}
}

@ -0,0 +1,209 @@
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: route_guide.proto
namespace Routeguide;
use Google\Protobuf\Internal\DescriptorPool;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;
class Point extends \Google\Protobuf\Internal\Message
{
private $latitude = 0;
private $longitude = 0;
public function getLatitude()
{
return $this->latitude;
}
public function setLatitude($var)
{
GPBUtil::checkInt32($var);
$this->latitude = $var;
}
public function getLongitude()
{
return $this->longitude;
}
public function setLongitude($var)
{
GPBUtil::checkInt32($var);
$this->longitude = $var;
}
}
class Rectangle extends \Google\Protobuf\Internal\Message
{
private $lo = null;
private $hi = null;
public function getLo()
{
return $this->lo;
}
public function setLo(&$var)
{
GPBUtil::checkMessage($var, \Routeguide\Point::class);
$this->lo = $var;
}
public function getHi()
{
return $this->hi;
}
public function setHi(&$var)
{
GPBUtil::checkMessage($var, \Routeguide\Point::class);
$this->hi = $var;
}
}
class Feature extends \Google\Protobuf\Internal\Message
{
private $name = '';
private $location = null;
public function getName()
{
return $this->name;
}
public function setName($var)
{
GPBUtil::checkString($var, True);
$this->name = $var;
}
public function getLocation()
{
return $this->location;
}
public function setLocation(&$var)
{
GPBUtil::checkMessage($var, \Routeguide\Point::class);
$this->location = $var;
}
}
class RouteNote extends \Google\Protobuf\Internal\Message
{
private $location = null;
private $message = '';
public function getLocation()
{
return $this->location;
}
public function setLocation(&$var)
{
GPBUtil::checkMessage($var, \Routeguide\Point::class);
$this->location = $var;
}
public function getMessage()
{
return $this->message;
}
public function setMessage($var)
{
GPBUtil::checkString($var, True);
$this->message = $var;
}
}
class RouteSummary extends \Google\Protobuf\Internal\Message
{
private $point_count = 0;
private $feature_count = 0;
private $distance = 0;
private $elapsed_time = 0;
public function getPointCount()
{
return $this->point_count;
}
public function setPointCount($var)
{
GPBUtil::checkInt32($var);
$this->point_count = $var;
}
public function getFeatureCount()
{
return $this->feature_count;
}
public function setFeatureCount($var)
{
GPBUtil::checkInt32($var);
$this->feature_count = $var;
}
public function getDistance()
{
return $this->distance;
}
public function setDistance($var)
{
GPBUtil::checkInt32($var);
$this->distance = $var;
}
public function getElapsedTime()
{
return $this->elapsed_time;
}
public function setElapsedTime($var)
{
GPBUtil::checkInt32($var);
$this->elapsed_time = $var;
}
}
$pool = DescriptorPool::getGeneratedPool();
$pool->internalAddGeneratedFile(hex2bin(
"0ac5050a11726f7574655f67756964652e70726f746f120a726f75746567" .
"75696465222c0a05506f696e7412100a086c617469747564651801200128" .
"0512110a096c6f6e67697475646518022001280522490a0952656374616e" .
"676c65121d0a026c6f18012001280b32112e726f75746567756964652e50" .
"6f696e74121d0a02686918022001280b32112e726f75746567756964652e" .
"506f696e74223c0a0746656174757265120c0a046e616d65180120012809" .
"12230a086c6f636174696f6e18022001280b32112e726f75746567756964" .
"652e506f696e7422410a09526f7574654e6f746512230a086c6f63617469" .
"6f6e18012001280b32112e726f75746567756964652e506f696e74120f0a" .
"076d65737361676518022001280922620a0c526f75746553756d6d617279" .
"12130a0b706f696e745f636f756e7418012001280512150a0d6665617475" .
"72655f636f756e7418022001280512100a0864697374616e636518032001" .
"280512140a0c656c61707365645f74696d651804200128053285020a0a52" .
"6f757465477569646512360a0a4765744665617475726512112e726f7574" .
"6567756964652e506f696e741a132e726f75746567756964652e46656174" .
"7572652200123e0a0c4c697374466561747572657312152e726f75746567" .
"756964652e52656374616e676c651a132e726f75746567756964652e4665" .
"617475726522003001123e0a0b5265636f7264526f75746512112e726f75" .
"746567756964652e506f696e741a182e726f75746567756964652e526f75" .
"746553756d6d61727922002801123f0a09526f7574654368617412152e72" .
"6f75746567756964652e526f7574654e6f74651a152e726f757465677569" .
"64652e526f7574654e6f746522002801300142360a1b696f2e677270632e" .
"6578616d706c65732e726f7574656775696465420f526f75746547756964" .
"6550726f746f5001a20203525447620670726f746f33"
));

@ -1,789 +0,0 @@
<?php
// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0
// Source: route_guide.proto
// Date: 2015-09-24 21:21:51
namespace routeguide {
class Point extends \DrSlump\Protobuf\Message
{
/** @var int */
public $latitude = 0;
/** @var int */
public $longitude = 0;
/** @var \Closure[] */
protected static $__extensions = array();
public static function descriptor()
{
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Point');
// OPTIONAL INT32 latitude = 1
$f = new \DrSlump\Protobuf\Field();
$f->number = 1;
$f->name = 'latitude';
$f->type = \DrSlump\Protobuf::TYPE_INT32;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$f->default = 0;
$descriptor->addField($f);
// OPTIONAL INT32 longitude = 2
$f = new \DrSlump\Protobuf\Field();
$f->number = 2;
$f->name = 'longitude';
$f->type = \DrSlump\Protobuf::TYPE_INT32;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$f->default = 0;
$descriptor->addField($f);
foreach (self::$__extensions as $cb) {
$descriptor->addField($cb(), true);
}
return $descriptor;
}
/**
* Check if <latitude> has a value.
*
* @return bool
*/
public function hasLatitude()
{
return $this->_has(1);
}
/**
* Clear <latitude> value.
*
* @return \routeguide\Point
*/
public function clearLatitude()
{
return $this->_clear(1);
}
/**
* Get <latitude> value.
*
* @return int
*/
public function getLatitude()
{
return $this->_get(1);
}
/**
* Set <latitude> value.
*
* @param int $value
*
* @return \routeguide\Point
*/
public function setLatitude($value)
{
return $this->_set(1, $value);
}
/**
* Check if <longitude> has a value.
*
* @return bool
*/
public function hasLongitude()
{
return $this->_has(2);
}
/**
* Clear <longitude> value.
*
* @return \routeguide\Point
*/
public function clearLongitude()
{
return $this->_clear(2);
}
/**
* Get <longitude> value.
*
* @return int
*/
public function getLongitude()
{
return $this->_get(2);
}
/**
* Set <longitude> value.
*
* @param int $value
*
* @return \routeguide\Point
*/
public function setLongitude($value)
{
return $this->_set(2, $value);
}
}
}
namespace routeguide {
class Rectangle extends \DrSlump\Protobuf\Message
{
/** @var \routeguide\Point */
public $lo = null;
/** @var \routeguide\Point */
public $hi = null;
/** @var \Closure[] */
protected static $__extensions = array();
public static function descriptor()
{
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Rectangle');
// OPTIONAL MESSAGE lo = 1
$f = new \DrSlump\Protobuf\Field();
$f->number = 1;
$f->name = 'lo';
$f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$f->reference = '\routeguide\Point';
$descriptor->addField($f);
// OPTIONAL MESSAGE hi = 2
$f = new \DrSlump\Protobuf\Field();
$f->number = 2;
$f->name = 'hi';
$f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$f->reference = '\routeguide\Point';
$descriptor->addField($f);
foreach (self::$__extensions as $cb) {
$descriptor->addField($cb(), true);
}
return $descriptor;
}
/**
* Check if <lo> has a value.
*
* @return bool
*/
public function hasLo()
{
return $this->_has(1);
}
/**
* Clear <lo> value.
*
* @return \routeguide\Rectangle
*/
public function clearLo()
{
return $this->_clear(1);
}
/**
* Get <lo> value.
*
* @return \routeguide\Point
*/
public function getLo()
{
return $this->_get(1);
}
/**
* Set <lo> value.
*
* @param \routeguide\Point $value
*
* @return \routeguide\Rectangle
*/
public function setLo(\routeguide\Point $value)
{
return $this->_set(1, $value);
}
/**
* Check if <hi> has a value.
*
* @return bool
*/
public function hasHi()
{
return $this->_has(2);
}
/**
* Clear <hi> value.
*
* @return \routeguide\Rectangle
*/
public function clearHi()
{
return $this->_clear(2);
}
/**
* Get <hi> value.
*
* @return \routeguide\Point
*/
public function getHi()
{
return $this->_get(2);
}
/**
* Set <hi> value.
*
* @param \routeguide\Point $value
*
* @return \routeguide\Rectangle
*/
public function setHi(\routeguide\Point $value)
{
return $this->_set(2, $value);
}
}
}
namespace routeguide {
class Feature extends \DrSlump\Protobuf\Message
{
/** @var string */
public $name = null;
/** @var \routeguide\Point */
public $location = null;
/** @var \Closure[] */
protected static $__extensions = array();
public static function descriptor()
{
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Feature');
// OPTIONAL STRING name = 1
$f = new \DrSlump\Protobuf\Field();
$f->number = 1;
$f->name = 'name';
$f->type = \DrSlump\Protobuf::TYPE_STRING;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$descriptor->addField($f);
// OPTIONAL MESSAGE location = 2
$f = new \DrSlump\Protobuf\Field();
$f->number = 2;
$f->name = 'location';
$f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$f->reference = '\routeguide\Point';
$descriptor->addField($f);
foreach (self::$__extensions as $cb) {
$descriptor->addField($cb(), true);
}
return $descriptor;
}
/**
* Check if <name> has a value.
*
* @return bool
*/
public function hasName()
{
return $this->_has(1);
}
/**
* Clear <name> value.
*
* @return \routeguide\Feature
*/
public function clearName()
{
return $this->_clear(1);
}
/**
* Get <name> value.
*
* @return string
*/
public function getName()
{
return $this->_get(1);
}
/**
* Set <name> value.
*
* @param string $value
*
* @return \routeguide\Feature
*/
public function setName($value)
{
return $this->_set(1, $value);
}
/**
* Check if <location> has a value.
*
* @return bool
*/
public function hasLocation()
{
return $this->_has(2);
}
/**
* Clear <location> value.
*
* @return \routeguide\Feature
*/
public function clearLocation()
{
return $this->_clear(2);
}
/**
* Get <location> value.
*
* @return \routeguide\Point
*/
public function getLocation()
{
return $this->_get(2);
}
/**
* Set <location> value.
*
* @param \routeguide\Point $value
*
* @return \routeguide\Feature
*/
public function setLocation(\routeguide\Point $value)
{
return $this->_set(2, $value);
}
}
}
namespace routeguide {
class RouteNote extends \DrSlump\Protobuf\Message
{
/** @var \routeguide\Point */
public $location = null;
/** @var string */
public $message = null;
/** @var \Closure[] */
protected static $__extensions = array();
public static function descriptor()
{
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.RouteNote');
// OPTIONAL MESSAGE location = 1
$f = new \DrSlump\Protobuf\Field();
$f->number = 1;
$f->name = 'location';
$f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$f->reference = '\routeguide\Point';
$descriptor->addField($f);
// OPTIONAL STRING message = 2
$f = new \DrSlump\Protobuf\Field();
$f->number = 2;
$f->name = 'message';
$f->type = \DrSlump\Protobuf::TYPE_STRING;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$descriptor->addField($f);
foreach (self::$__extensions as $cb) {
$descriptor->addField($cb(), true);
}
return $descriptor;
}
/**
* Check if <location> has a value.
*
* @return bool
*/
public function hasLocation()
{
return $this->_has(1);
}
/**
* Clear <location> value.
*
* @return \routeguide\RouteNote
*/
public function clearLocation()
{
return $this->_clear(1);
}
/**
* Get <location> value.
*
* @return \routeguide\Point
*/
public function getLocation()
{
return $this->_get(1);
}
/**
* Set <location> value.
*
* @param \routeguide\Point $value
*
* @return \routeguide\RouteNote
*/
public function setLocation(\routeguide\Point $value)
{
return $this->_set(1, $value);
}
/**
* Check if <message> has a value.
*
* @return bool
*/
public function hasMessage()
{
return $this->_has(2);
}
/**
* Clear <message> value.
*
* @return \routeguide\RouteNote
*/
public function clearMessage()
{
return $this->_clear(2);
}
/**
* Get <message> value.
*
* @return string
*/
public function getMessage()
{
return $this->_get(2);
}
/**
* Set <message> value.
*
* @param string $value
*
* @return \routeguide\RouteNote
*/
public function setMessage($value)
{
return $this->_set(2, $value);
}
}
}
namespace routeguide {
class RouteSummary extends \DrSlump\Protobuf\Message
{
/** @var int */
public $point_count = 0;
/** @var int */
public $feature_count = 0;
/** @var int */
public $distance = 0;
/** @var int */
public $elapsed_time = 0;
/** @var \Closure[] */
protected static $__extensions = array();
public static function descriptor()
{
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.RouteSummary');
// OPTIONAL INT32 point_count = 1
$f = new \DrSlump\Protobuf\Field();
$f->number = 1;
$f->name = 'point_count';
$f->type = \DrSlump\Protobuf::TYPE_INT32;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$f->default = 0;
$descriptor->addField($f);
// OPTIONAL INT32 feature_count = 2
$f = new \DrSlump\Protobuf\Field();
$f->number = 2;
$f->name = 'feature_count';
$f->type = \DrSlump\Protobuf::TYPE_INT32;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$f->default = 0;
$descriptor->addField($f);
// OPTIONAL INT32 distance = 3
$f = new \DrSlump\Protobuf\Field();
$f->number = 3;
$f->name = 'distance';
$f->type = \DrSlump\Protobuf::TYPE_INT32;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$f->default = 0;
$descriptor->addField($f);
// OPTIONAL INT32 elapsed_time = 4
$f = new \DrSlump\Protobuf\Field();
$f->number = 4;
$f->name = 'elapsed_time';
$f->type = \DrSlump\Protobuf::TYPE_INT32;
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
$f->default = 0;
$descriptor->addField($f);
foreach (self::$__extensions as $cb) {
$descriptor->addField($cb(), true);
}
return $descriptor;
}
/**
* Check if <point_count> has a value.
*
* @return bool
*/
public function hasPointCount()
{
return $this->_has(1);
}
/**
* Clear <point_count> value.
*
* @return \routeguide\RouteSummary
*/
public function clearPointCount()
{
return $this->_clear(1);
}
/**
* Get <point_count> value.
*
* @return int
*/
public function getPointCount()
{
return $this->_get(1);
}
/**
* Set <point_count> value.
*
* @param int $value
*
* @return \routeguide\RouteSummary
*/
public function setPointCount($value)
{
return $this->_set(1, $value);
}
/**
* Check if <feature_count> has a value.
*
* @return bool
*/
public function hasFeatureCount()
{
return $this->_has(2);
}
/**
* Clear <feature_count> value.
*
* @return \routeguide\RouteSummary
*/
public function clearFeatureCount()
{
return $this->_clear(2);
}
/**
* Get <feature_count> value.
*
* @return int
*/
public function getFeatureCount()
{
return $this->_get(2);
}
/**
* Set <feature_count> value.
*
* @param int $value
*
* @return \routeguide\RouteSummary
*/
public function setFeatureCount($value)
{
return $this->_set(2, $value);
}
/**
* Check if <distance> has a value.
*
* @return bool
*/
public function hasDistance()
{
return $this->_has(3);
}
/**
* Clear <distance> value.
*
* @return \routeguide\RouteSummary
*/
public function clearDistance()
{
return $this->_clear(3);
}
/**
* Get <distance> value.
*
* @return int
*/
public function getDistance()
{
return $this->_get(3);
}
/**
* Set <distance> value.
*
* @param int $value
*
* @return \routeguide\RouteSummary
*/
public function setDistance($value)
{
return $this->_set(3, $value);
}
/**
* Check if <elapsed_time> has a value.
*
* @return bool
*/
public function hasElapsedTime()
{
return $this->_has(4);
}
/**
* Clear <elapsed_time> value.
*
* @return \routeguide\RouteSummary
*/
public function clearElapsedTime()
{
return $this->_clear(4);
}
/**
* Get <elapsed_time> value.
*
* @return int
*/
public function getElapsedTime()
{
return $this->_get(4);
}
/**
* Set <elapsed_time> value.
*
* @param int $value
*
* @return \routeguide\RouteSummary
*/
public function setElapsedTime($value)
{
return $this->_set(4, $value);
}
}
}
namespace routeguide {
class RouteGuideClient extends \Grpc\BaseStub
{
public function __construct($hostname, $opts)
{
parent::__construct($hostname, $opts);
}
/**
* @param routeguide\Point $input
*/
public function GetFeature(\routeguide\Point $argument, $metadata = array(), $options = array())
{
return $this->_simpleRequest('/routeguide.RouteGuide/GetFeature', $argument, '\routeguide\Feature::deserialize', $metadata, $options);
}
/**
* @param routeguide\Rectangle $input
*/
public function ListFeatures($argument, $metadata = array(), $options = array())
{
return $this->_serverStreamRequest('/routeguide.RouteGuide/ListFeatures', $argument, '\routeguide\Feature::deserialize', $metadata, $options);
}
/**
* @param routeguide\Point $input
*/
public function RecordRoute($metadata = array())
{
return $this->_clientStreamRequest('/routeguide.RouteGuide/RecordRoute', '\routeguide\RouteSummary::deserialize', $metadata);
}
/**
* @param routeguide\RouteNote $input
*/
public function RouteChat($metadata = array())
{
return $this->_bidiRequest('/routeguide.RouteGuide/RouteChat', '\routeguide\RouteNote::deserialize', $metadata);
}
}
}

@ -1,120 +0,0 @@
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
option java_package = "io.grpc.examples";
package routeguide;
// Interface exported by the server.
service RouteGuide {
// A simple RPC.
//
// Obtains the feature at a given position.
rpc GetFeature(Point) returns (Feature) {}
// A server-to-client streaming RPC.
//
// Obtains the Features available within the given Rectangle. Results are
// streamed rather than returned at once (e.g. in a response message with a
// repeated field), as the rectangle may cover a large area and contain a
// huge number of features.
rpc ListFeatures(Rectangle) returns (stream Feature) {}
// A client-to-server streaming RPC.
//
// Accepts a stream of Points on a route being traversed, returning a
// RouteSummary when traversal is completed.
rpc RecordRoute(stream Point) returns (RouteSummary) {}
// A Bidirectional streaming RPC.
//
// Accepts a stream of RouteNotes sent while a route is being traversed,
// while receiving other RouteNotes (e.g. from other users).
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}
// Points are represented as latitude-longitude pairs in the E7 representation
// (degrees multiplied by 10**7 and rounded to the nearest integer).
// Latitudes should be in the range +/- 90 degrees and longitude should be in
// the range +/- 180 degrees (inclusive).
message Point {
optional int32 latitude = 1 [default = 0];
optional int32 longitude = 2 [default = 0];
}
// A latitude-longitude rectangle, represented as two diagonally opposite
// points "lo" and "hi".
message Rectangle {
// One corner of the rectangle.
optional Point lo = 1;
// The other corner of the rectangle.
optional Point hi = 2;
}
// A feature names something at a given point.
//
// If a feature could not be named, the name is empty.
message Feature {
// The name of the feature.
optional string name = 1;
// The point where the feature is detected.
optional Point location = 2;
}
// A RouteNote is a message sent while at a given point.
message RouteNote {
// The location from which the message is sent.
optional Point location = 1;
// The message to be sent.
optional string message = 2;
}
// A RouteSummary is received in response to a RecordRoute rpc.
//
// It contains the number of individual points received, the number of
// detected features, and the total distance covered as the cumulative sum of
// the distance between each point.
message RouteSummary {
// The number of points received.
optional int32 point_count = 1 [default = 0];
// The number of known features passed while traversing the route.
optional int32 feature_count = 2 [default = 0];
// The distance covered in metres.
optional int32 distance = 3 [default = 0];
// The duration of the traversal in seconds.
optional int32 elapsed_time = 4 [default = 0];
}

@ -33,11 +33,15 @@
*/
require dirname(__FILE__).'/../vendor/autoload.php';
require dirname(__FILE__).'/route_guide.php';
// The following includes are needed when using protobuf 3.1.0
// and will suppress warnings when using protobuf 3.2.0+
@include_once dirname(__FILE__).'/route_guide.pb.php';
@include_once dirname(__FILE__).'/route_guide_grpc_pb.php';
define('COORD_FACTOR', 1e7);
$client = new routeguide\RouteGuideClient('localhost:50051', [
$client = new Routeguide\RouteGuideClient('localhost:50051', [
'credentials' => Grpc\ChannelCredentials::createInsecure(),
]);
@ -63,7 +67,7 @@ function runGetFeature()
echo "Running GetFeature...\n";
global $client;
$point = new routeguide\Point();
$point = new Routeguide\Point();
$points = array(
array(409146138, -746188906),
array(0, 0),
@ -88,15 +92,15 @@ function runListFeatures()
echo "Running ListFeatures...\n";
global $client;
$lo_point = new routeguide\Point();
$hi_point = new routeguide\Point();
$lo_point = new Routeguide\Point();
$hi_point = new Routeguide\Point();
$lo_point->setLatitude(400000000);
$lo_point->setLongitude(-750000000);
$hi_point->setLatitude(420000000);
$hi_point->setLongitude(-730000000);
$rectangle = new routeguide\Rectangle();
$rectangle = new Routeguide\Rectangle();
$rectangle->setLo($lo_point);
$rectangle->setHi($hi_point);
@ -126,7 +130,7 @@ function runRecordRoute()
$num_points_in_db = count($db);
$num_points = 10;
for ($i = 0; $i < $num_points; ++$i) {
$point = new routeguide\Point();
$point = new Routeguide\Point();
$index = rand(0, $num_points_in_db - 1);
$lat = $db[$index]['location']['latitude'];
$long = $db[$index]['location']['longitude'];
@ -169,11 +173,11 @@ function runRouteChat()
);
foreach ($notes as $n) {
$point = new routeguide\Point();
$point = new Routeguide\Point();
$point->setLatitude($lat = $n[0]);
$point->setLongitude($long = $n[1]);
$route_note = new routeguide\RouteNote();
$route_note = new Routeguide\RouteNote();
$route_note->setLocation($point);
$route_note->setMessage($message = $n[2]);

@ -0,0 +1,116 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
namespace Routeguide {
// Interface exported by the server.
class RouteGuideClient extends \Grpc\BaseStub {
/**
* @param string $hostname hostname
* @param array $opts channel options
* @param Grpc\Channel $channel (optional) re-use channel object
*/
public function __construct($hostname, $opts, $channel = null) {
parent::__construct($hostname, $opts, $channel);
}
/**
* A simple RPC.
*
* Obtains the feature at a given position.
*
* A feature with an empty name is returned if there's no feature at the given
* position.
* @param \Routeguide\Point $argument input argument
* @param array $metadata metadata
* @param array $options call options
*/
public function GetFeature(\Routeguide\Point $argument,
$metadata = [], $options = []) {
return $this->_simpleRequest('/routeguide.RouteGuide/GetFeature',
$argument,
['\Routeguide\Feature', 'decode'],
$metadata, $options);
}
/**
* A server-to-client streaming RPC.
*
* Obtains the Features available within the given Rectangle. Results are
* streamed rather than returned at once (e.g. in a response message with a
* repeated field), as the rectangle may cover a large area and contain a
* huge number of features.
* @param \Routeguide\Rectangle $argument input argument
* @param array $metadata metadata
* @param array $options call options
*/
public function ListFeatures(\Routeguide\Rectangle $argument,
$metadata = [], $options = []) {
return $this->_serverStreamRequest('/routeguide.RouteGuide/ListFeatures',
$argument,
['\Routeguide\Feature', 'decode'],
$metadata, $options);
}
/**
* A client-to-server streaming RPC.
*
* Accepts a stream of Points on a route being traversed, returning a
* RouteSummary when traversal is completed.
* @param array $metadata metadata
* @param array $options call options
*/
public function RecordRoute($metadata = [], $options = []) {
return $this->_clientStreamRequest('/routeguide.RouteGuide/RecordRoute',
['\Routeguide\RouteSummary','decode'],
$metadata, $options);
}
/**
* A Bidirectional streaming RPC.
*
* Accepts a stream of RouteNotes sent while a route is being traversed,
* while receiving other RouteNotes (e.g. from other users).
* @param array $metadata metadata
* @param array $options call options
*/
public function RouteChat($metadata = [], $options = []) {
return $this->_bidiRequest('/routeguide.RouteGuide/RouteChat',
['\Routeguide\RouteNote','decode'],
$metadata, $options);
}
}
}

@ -1,8 +1,10 @@
# GRPC CocoaPods podspec
# This file has been automatically generated from a template file. Please make modifications to
# `templates/gRPC-Core.podspec.template` instead. This file can be regenerated from the template by
# running `tools/buildgen/generate_projects.sh`.
# This file has been automatically generated from a template file.
# Please make modifications to `templates/gRPC-Core.podspec.template`
# instead. This file can be regenerated from the template by running
# `tools/buildgen/generate_projects.sh`.
# gRPC Core CocoaPods podspec
#
# Copyright 2015, Google Inc.
# All rights reserved.
#
@ -35,7 +37,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
version = '1.0.2'
version = '1.2.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'http://www.grpc.io'
@ -44,9 +46,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
# TODO(mxyan): Change back to "v#{version}" for next release
#:tag => "v#{version}",
:tag => "objective-c-v#{version}",
:tag => "v#{version}",
# TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
:submodules => true,
}
@ -191,7 +191,7 @@ Pod::Spec.new do |s|
ss.header_mappings_dir = '.'
ss.libraries = 'z'
ss.dependency "#{s.name}/Interface", version
ss.dependency 'BoringSSL', '~> 7.0'
ss.dependency 'BoringSSL', '~> 8.0'
# To save you from scrolling, this is the last part of the podspec.
ss.source_files = 'src/core/lib/profiling/timers.h',
@ -342,6 +342,7 @@ Pod::Spec.new do |s|
'src/core/lib/surface/lame_client.h',
'src/core/lib/surface/server.h',
'src/core/lib/surface/validate_metadata.h',
'src/core/lib/transport/bdp_estimator.h',
'src/core/lib/transport/byte_stream.h',
'src/core/lib/transport/connectivity_state.h',
'src/core/lib/transport/error_utils.h',
@ -387,6 +388,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/lb_targets_info.h',
'src/core/lib/security/transport/secure_endpoint.h',
'src/core/lib/security/transport/security_connector.h',
'src/core/lib/security/transport/security_handshaker.h',
@ -419,6 +421,7 @@ Pod::Spec.new do |s|
'src/core/ext/client_channel/uri_parser.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/lb_policy/grpclb/grpclb.h',
'src/core/ext/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'third_party/nanopb/pb.h',
@ -438,6 +441,11 @@ Pod::Spec.new do |s|
'src/core/ext/census/resource.h',
'src/core/ext/census/rpc_metric_id.h',
'src/core/ext/census/trace_context.h',
'src/core/ext/census/trace_label.h',
'src/core/ext/census/trace_propagation.h',
'src/core/ext/census/trace_status.h',
'src/core/ext/census/trace_string.h',
'src/core/ext/census/tracing.h',
'src/core/lib/surface/init.c',
'src/core/lib/channel/channel_args.c',
'src/core/lib/channel/channel_stack.c',
@ -544,6 +552,7 @@ Pod::Spec.new do |s|
'src/core/lib/surface/server.c',
'src/core/lib/surface/validate_metadata.c',
'src/core/lib/surface/version.c',
'src/core/lib/transport/bdp_estimator.c',
'src/core/lib/transport/byte_stream.c',
'src/core/lib/transport/connectivity_state.c',
'src/core/lib/transport/error_utils.c',
@ -594,6 +603,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.c',
'src/core/lib/security/credentials/ssl/ssl_credentials.c',
'src/core/lib/security/transport/client_auth_filter.c',
'src/core/lib/security/transport/lb_targets_info.c',
'src/core/lib/security/transport/secure_endpoint.c',
'src/core/lib/security/transport/security_connector.c',
'src/core/lib/security/transport/security_handshaker.c',
@ -634,6 +644,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
'src/core/ext/lb_policy/grpclb/grpclb.c',
'src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c',
'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
'third_party/nanopb/pb_common.c',
@ -765,6 +776,7 @@ Pod::Spec.new do |s|
'src/core/lib/surface/lame_client.h',
'src/core/lib/surface/server.h',
'src/core/lib/surface/validate_metadata.h',
'src/core/lib/transport/bdp_estimator.h',
'src/core/lib/transport/byte_stream.h',
'src/core/lib/transport/connectivity_state.h',
'src/core/lib/transport/error_utils.h',
@ -810,6 +822,7 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/lb_targets_info.h',
'src/core/lib/security/transport/secure_endpoint.h',
'src/core/lib/security/transport/security_connector.h',
'src/core/lib/security/transport/security_handshaker.h',
@ -842,6 +855,7 @@ Pod::Spec.new do |s|
'src/core/ext/client_channel/uri_parser.h',
'src/core/ext/transport/chttp2/client/chttp2_connector.h',
'src/core/ext/lb_policy/grpclb/grpclb.h',
'src/core/ext/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'third_party/nanopb/pb.h',
@ -860,7 +874,12 @@ Pod::Spec.new do |s|
'src/core/ext/census/mlog.h',
'src/core/ext/census/resource.h',
'src/core/ext/census/rpc_metric_id.h',
'src/core/ext/census/trace_context.h'
'src/core/ext/census/trace_context.h',
'src/core/ext/census/trace_label.h',
'src/core/ext/census/trace_propagation.h',
'src/core/ext/census/trace_status.h',
'src/core/ext/census/trace_string.h',
'src/core/ext/census/tracing.h'
end
s.subspec 'Cronet-Interface' do |ss|
@ -870,23 +889,31 @@ Pod::Spec.new do |s|
s.subspec 'Cronet-Implementation' do |ss|
ss.header_mappings_dir = '.'
ss.dependency "#{s.name}/Interface", version
ss.dependency "#{s.name}/Implementation", version
ss.dependency "#{s.name}/Cronet-Interface", version
ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
'src/core/ext/transport/cronet/transport/cronet_transport.c'
'src/core/ext/transport/cronet/transport/cronet_transport.c',
'third_party/objective_c/Cronet/bidirectional_stream_c.h'
end
s.subspec 'Tests' do |ss|
ss.header_mappings_dir = '.'
ss.dependency "#{s.name}/Interface", version
ss.dependency "#{s.name}/Implementation", version
ss.source_files = 'test/core/end2end/cq_verifier.{c,h}',
'test/core/end2end/end2end_tests.{c,h}',
'test/core/end2end/end2end_test_utils.c',
'test/core/end2end/tests/*.{c,h}',
'test/core/end2end/data/*.{c,h}',
'test/core/util/debugger_macros.c',
'test/core/util/test_config.{c,h}',
'test/core/util/port.h',
'test/core/util/port_posix.c',
'test/core/util/port_server_client.{c,h}'
ss.dependency 'CronetFramework'
end
end

@ -1,3 +1,9 @@
# This file has been automatically generated from a template file.
# Please make modifications to
# `templates/gRPC-ProtoRPC.podspec.template` instead. This file can be
# regenerated from the template by running
# `tools/buildgen/generate_projects.sh`.
# Copyright 2015, Google Inc.
# All rights reserved.
#
@ -30,7 +36,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
version = '1.0.2'
version = '1.2.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'http://www.grpc.io'
@ -39,7 +45,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
:tag => "objective-c-v#{version}",
:tag => "v#{version}",
}
s.ios.deployment_target = '7.1'

@ -1,3 +1,9 @@
# This file has been automatically generated from a template file.
# Please make modifications to
# `templates/gRPC-RxLibrary.podspec.template` instead. This file can be
# regenerated from the template by running
# `tools/buildgen/generate_projects.sh`.
# Copyright 2015, Google Inc.
# All rights reserved.
#
@ -30,7 +36,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
version = '1.0.2'
version = '1.2.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'http://www.grpc.io'
@ -39,7 +45,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
:tag => "objective-c-v#{version}",
:tag => "v#{version}",
}
s.ios.deployment_target = '7.1'

@ -1,3 +1,8 @@
# This file has been automatically generated from a template file.
# Please make modifications to `templates/gRPC.podspec.template`
# instead. This file can be regenerated from the template by running
# `tools/buildgen/generate_projects.sh`.
# Copyright 2015, Google Inc.
# All rights reserved.
#
@ -30,7 +35,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
version = '1.0.2'
version = '1.2.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'http://www.grpc.io'
@ -39,7 +44,7 @@ Pod::Spec.new do |s|
s.source = {
:git => 'https://github.com/grpc/grpc.git',
:tag => "objective-c-v#{version}",
:tag => "v#{version}",
}
s.ios.deployment_target = '7.1'

@ -259,6 +259,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/surface/lame_client.h )
s.files += %w( src/core/lib/surface/server.h )
s.files += %w( src/core/lib/surface/validate_metadata.h )
s.files += %w( src/core/lib/transport/bdp_estimator.h )
s.files += %w( src/core/lib/transport/byte_stream.h )
s.files += %w( src/core/lib/transport/connectivity_state.h )
s.files += %w( src/core/lib/transport/error_utils.h )
@ -304,6 +305,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h )
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h )
s.files += %w( src/core/lib/security/transport/auth_filters.h )
s.files += %w( src/core/lib/security/transport/lb_targets_info.h )
s.files += %w( src/core/lib/security/transport/secure_endpoint.h )
s.files += %w( src/core/lib/security/transport/security_connector.h )
s.files += %w( src/core/lib/security/transport/security_handshaker.h )
@ -336,6 +338,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/client_channel/uri_parser.h )
s.files += %w( src/core/ext/transport/chttp2/client/chttp2_connector.h )
s.files += %w( src/core/ext/lb_policy/grpclb/grpclb.h )
s.files += %w( src/core/ext/lb_policy/grpclb/grpclb_channel.h )
s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.h )
s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
s.files += %w( third_party/nanopb/pb.h )
@ -355,6 +358,11 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/census/resource.h )
s.files += %w( src/core/ext/census/rpc_metric_id.h )
s.files += %w( src/core/ext/census/trace_context.h )
s.files += %w( src/core/ext/census/trace_label.h )
s.files += %w( src/core/ext/census/trace_propagation.h )
s.files += %w( src/core/ext/census/trace_status.h )
s.files += %w( src/core/ext/census/trace_string.h )
s.files += %w( src/core/ext/census/tracing.h )
s.files += %w( src/core/lib/surface/init.c )
s.files += %w( src/core/lib/channel/channel_args.c )
s.files += %w( src/core/lib/channel/channel_stack.c )
@ -461,6 +469,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/surface/server.c )
s.files += %w( src/core/lib/surface/validate_metadata.c )
s.files += %w( src/core/lib/surface/version.c )
s.files += %w( src/core/lib/transport/bdp_estimator.c )
s.files += %w( src/core/lib/transport/byte_stream.c )
s.files += %w( src/core/lib/transport/connectivity_state.c )
s.files += %w( src/core/lib/transport/error_utils.c )
@ -511,6 +520,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.c )
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.c )
s.files += %w( src/core/lib/security/transport/client_auth_filter.c )
s.files += %w( src/core/lib/security/transport/lb_targets_info.c )
s.files += %w( src/core/lib/security/transport/secure_endpoint.c )
s.files += %w( src/core/lib/security/transport/security_connector.c )
s.files += %w( src/core/lib/security/transport/security_handshaker.c )
@ -551,6 +561,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.c )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c )
s.files += %w( src/core/ext/lb_policy/grpclb/grpclb.c )
s.files += %w( src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c )
s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.c )
s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c )
s.files += %w( third_party/nanopb/pb_common.c )

@ -50,6 +50,8 @@ extern CoreCodegenInterface* g_core_codegen_interface;
namespace internal {
class GrpcBufferWriterPeer;
const int kGrpcBufferWriterMaxBufferLength = 8192;
class GrpcBufferWriter final
@ -91,13 +93,18 @@ class GrpcBufferWriter final
&slice_, GRPC_SLICE_LENGTH(slice_) - count);
g_core_codegen_interface->grpc_slice_buffer_add(slice_buffer_, slice_);
}
have_backup_ = true;
// It's dangerous to keep an inlined grpc_slice as the backup slice, since
// on a following Next() call, a reference will be returned to this slice
// via GRPC_SLICE_START_PTR, which will not be an adddress held by
// slice_buffer_.
have_backup_ = backup_slice_.refcount != NULL;
byte_count_ -= count;
}
grpc::protobuf::int64 ByteCount() const override { return byte_count_; }
private:
friend class GrpcBufferWriterPeer;
const int block_size_;
int64_t byte_count_;
grpc_slice_buffer* slice_buffer_;

@ -88,6 +88,8 @@ class Server final : public ServerInterface, private GrpcLibraryCodegen {
virtual void PreSynchronousRequest(ServerContext* context) = 0;
/// Called after application callback for each synchronous server request
virtual void PostSynchronousRequest(ServerContext* context) = 0;
/// Called before server is started.
virtual void PreServerStart(Server* server) {}
};
/// Set the global callback object. Can only be called once. Does not take
/// ownership of callbacks, and expects the pointed to object to be alive

@ -156,7 +156,7 @@ CENSUSAPI void census_context_destroy(census_context *context);
CENSUSAPI const census_context_status *census_context_get_status(
const census_context *context);
/* Structure used for iterating over the tegs in a context. API clients should
/* Structure used for iterating over the tags in a context. API clients should
not use or reference internal fields - neither their contents or
presence/absence are guaranteed. */
typedef struct {
@ -180,7 +180,7 @@ CENSUSAPI int census_context_next_tag(census_context_iterator *iterator,
CENSUSAPI int census_context_get_tag(const census_context *context,
const char *key, census_tag *tag);
/* Tag set encode/decode functionality. These functionas are intended
/* Tag set encode/decode functionality. These functions are intended
for use by RPC systems only, for purposes of transmitting/receiving contexts.
*/
@ -205,14 +205,14 @@ enum census_trace_mask_values {
};
/** Get the current trace mask associated with this context. The value returned
will be the logical or of census_trace_mask_values values. */
will be the logical OR of census_trace_mask_values values. */
CENSUSAPI int census_trace_mask(const census_context *context);
/** Set the trace mask associated with a context. */
CENSUSAPI void census_set_trace_mask(int trace_mask);
/* The concept of "operation" is a fundamental concept for Census. In an RPC
system, and operation typcially represents a single RPC, or a significant
system, an operation typically represents a single RPC, or a significant
sub-part thereof (e.g. a single logical "read" RPC to a distributed storage
system might do several other actions in parallel, from looking up metadata
indices to making requests of other services - each of these could be a
@ -362,7 +362,7 @@ CENSUSAPI census_context *census_start_server_rpc_op(
@param context The base context. Can be NULL.
@param family Family name to associate with the trace
@param name Name within family to associated with traces/stats
@param name Name within family to associate with traces/stats
@param trace_mask An OR of census_trace_mask_values values. Only used if
context is NULL.
@ -454,7 +454,7 @@ CENSUSAPI void census_trace_scan_end();
protobuf, `resource_pb_size` being the size of the buffer. Returns a -ve
value on error, or a positive (>= 0) resource id (for use in
census_delete_resource() and census_record_values()). In order to be valid, a
resource must have a name, and at least one numerator in it's unit type. The
resource must have a name, and at least one numerator in its unit type. The
resource name must be unique, and an error will be returned if it is not. */
CENSUSAPI int32_t census_define_resource(const uint8_t *resource_pb,
size_t resource_pb_size);
@ -462,7 +462,7 @@ CENSUSAPI int32_t census_define_resource(const uint8_t *resource_pb,
/* Delete a resource created by census_define_resource(). */
CENSUSAPI void census_delete_resource(int32_t resource_id);
/* Determine the id of a resource, given it's name. returns -1 if the resource
/* Determine the id of a resource, given its name. returns -1 if the resource
does not exist. */
CENSUSAPI int32_t census_resource_id(const char *name);

@ -179,6 +179,17 @@ typedef struct {
Larger values give lower CPU usage for large messages, but more head of line
blocking for small messages. */
#define GRPC_ARG_HTTP2_MAX_FRAME_SIZE "grpc.http2.max_frame_size"
/** Should BDP probing be performed? */
#define GRPC_ARG_HTTP2_BDP_PROBE "grpc.http2.bdp_probe"
/** Minimum time (in milliseconds) between successive ping frames being sent */
#define GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS \
"grpc.http2.min_time_between_pings_ms"
/** How many pings can we send before needing to send a data frame or header
frame?
(0 indicates that an infinite number of pings can be sent without sending
a data frame or header frame) */
#define GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA \
"grpc.http2.max_pings_without_data"
/** How much data are we willing to queue up per stream if
GRPC_WRITE_BUFFER_HINT is set? This is an upper bound */
#define GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE "grpc.http2.write_buffer_size"
@ -211,6 +222,8 @@ typedef struct {
/** If non-zero, a pointer to a buffer pool (use grpc_resource_quota_arg_vtable
to fetch an appropriate pointer arg vtable) */
#define GRPC_ARG_RESOURCE_QUOTA "grpc.resource_quota"
/** If non-zero, expand wildcard addresses to a list of local addresses. */
#define GRPC_ARG_EXPAND_WILDCARD_ADDRS "grpc.expand_wildcard_addrs"
/** Service config data in JSON form. Not intended for use outside of tests. */
#define GRPC_ARG_SERVICE_CONFIG "grpc.service_config"
/** LB policy name. */

@ -1,6 +1,6 @@
{
"name": "grpc",
"version": "1.1.0-dev",
"version": "1.2.0-dev",
"author": "Google Inc.",
"description": "gRPC Library for Node",
"homepage": "http://www.grpc.io/",

@ -13,8 +13,8 @@
<date>2017-01-13</date>
<time>16:06:07</time>
<version>
<release>1.1.0dev</release>
<api>1.1.0dev</api>
<release>1.2.0dev</release>
<api>1.2.0dev</api>
</version>
<stability>
<release>beta</release>
@ -268,6 +268,7 @@
<file baseinstalldir="/" name="src/core/lib/surface/lame_client.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/server.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/validate_metadata.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/bdp_estimator.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/byte_stream.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/error_utils.h" role="src" />
@ -313,6 +314,7 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/lb_targets_info.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.h" role="src" />
@ -345,6 +347,7 @@
<file baseinstalldir="/" name="src/core/ext/client_channel/uri_parser.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/chttp2_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb_channel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb.h" role="src" />
@ -364,6 +367,11 @@
<file baseinstalldir="/" name="src/core/ext/census/resource.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/rpc_metric_id.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/trace_context.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/trace_label.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/trace_propagation.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/trace_status.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/trace_string.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/tracing.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/init.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/channel/channel_args.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/channel/channel_stack.c" role="src" />
@ -470,6 +478,7 @@
<file baseinstalldir="/" name="src/core/lib/surface/server.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/validate_metadata.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/version.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/bdp_estimator.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/byte_stream.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/error_utils.c" role="src" />
@ -520,6 +529,7 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/client_auth_filter.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/lb_targets_info.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_connector.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.c" role="src" />
@ -560,6 +570,7 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_common.c" role="src" />

@ -134,29 +134,15 @@ void PrintService(const ServiceDescriptor *service, Printer *out) {
out->Outdent();
out->Print("}\n\n");
}
void PrintServices(const FileDescriptor *file, Printer *out) {
map<grpc::string, grpc::string> vars;
vars["package"] = MessageIdentifierName(file->package());
out->Print(vars, "namespace $package$ {\n\n");
out->Indent();
for (int i = 0; i < file->service_count(); i++) {
PrintService(file->service(i), out);
}
out->Outdent();
out->Print("}\n");
}
}
grpc::string GenerateFile(const FileDescriptor *file) {
grpc::string GenerateFile(const FileDescriptor *file,
const ServiceDescriptor *service) {
grpc::string output;
{
StringOutputStream output_stream(&output);
Printer out(&output_stream, '$');
if (file->service_count() == 0) {
return output;
}
out.Print("<?php\n");
out.Print("// GENERATED CODE -- DO NOT EDIT!\n\n");
@ -166,7 +152,15 @@ grpc::string GenerateFile(const FileDescriptor *file) {
out.Print(leading_comments.c_str());
}
PrintServices(file, &out);
map<grpc::string, grpc::string> vars;
vars["package"] = MessageIdentifierName(file->package());
out.Print(vars, "namespace $package$ {\n\n");
out.Indent();
PrintService(service, &out);
out.Outdent();
out.Print("}\n");
}
return output;
}

@ -38,7 +38,8 @@
namespace grpc_php_generator {
grpc::string GenerateFile(const grpc::protobuf::FileDescriptor *file);
grpc::string GenerateFile(const grpc::protobuf::FileDescriptor *file,
const grpc::protobuf::ServiceDescriptor *service);
} // namespace grpc_php_generator

@ -41,14 +41,23 @@
namespace grpc_php_generator {
inline grpc::string GetPHPServiceFilename(const grpc::string& filename) {
return grpc_generator::StripProto(filename) + "_grpc_pb.php";
inline grpc::string GetPHPServiceFilename(
const grpc::protobuf::FileDescriptor *file,
const grpc::protobuf::ServiceDescriptor *service) {
std::vector<grpc::string> tokens =
grpc_generator::tokenize(file->package(), ".");
std::ostringstream oss;
for (unsigned int i = 0; i < tokens.size(); i++) {
oss << (i == 0 ? "" : "/")
<< grpc_generator::CapitalizeFirstLetter(tokens[i]);
}
return oss.str() + "/" + service->name() + "Client.php";
}
// Get leading or trailing comments in a string. Comment lines start with "// ".
// Leading detached comments are put in in front of leading comments.
template <typename DescriptorType>
inline grpc::string GetPHPComments(const DescriptorType* desc,
inline grpc::string GetPHPComments(const DescriptorType *desc,
grpc::string prefix) {
return grpc_generator::GetPrefixedComments(desc, true, prefix);
}

@ -51,18 +51,22 @@ class PHPGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
const grpc::string &parameter,
grpc::protobuf::compiler::GeneratorContext *context,
grpc::string *error) const {
grpc::string code = GenerateFile(file);
if (code.size() == 0) {
if (file->service_count() == 0) {
return true;
}
// Get output file name
grpc::string file_name = GetPHPServiceFilename(file->name());
for (int i = 0; i < file->service_count(); i++) {
grpc::string code = GenerateFile(file, file->service(i));
// Get output file name
grpc::string file_name = GetPHPServiceFilename(file, file->service(i));
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
context->Open(file_name));
grpc::protobuf::io::CodedOutputStream coded_out(output.get());
coded_out.WriteRaw(code.data(), code.size());
}
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
context->Open(file_name));
grpc::protobuf::io::CodedOutputStream coded_out(output.get());
coded_out.WriteRaw(code.data(), code.size());
return true;
}
};

@ -1,6 +1,6 @@
/*
*
* Copyright 2016, Google Inc.
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -31,51 +31,24 @@
*
*/
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.5-dev */
/* Generated by nanopb-0.3.7-dev at Fri Jan 20 16:14:22 2017. */
#include "src/core/ext/census/gen/trace_context.pb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
const pb_field_t google_trace_TraceId_fields[3] = {
PB_FIELD( 1, FIXED64 , OPTIONAL, STATIC , FIRST, google_trace_TraceId, hi, hi, 0),
PB_FIELD( 2, FIXED64 , OPTIONAL, STATIC , OTHER, google_trace_TraceId, lo, hi, 0),
const pb_field_t google_trace_TraceContext_fields[5] = {
PB_FIELD( 1, FIXED64 , OPTIONAL, STATIC , FIRST, google_trace_TraceContext, trace_id_hi, trace_id_hi, 0),
PB_FIELD( 2, FIXED64 , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, trace_id_lo, trace_id_hi, 0),
PB_FIELD( 3, FIXED64 , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, span_id, trace_id_lo, 0),
PB_FIELD( 4, FIXED32 , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, span_options, span_id, 0),
PB_LAST_FIELD
};
const pb_field_t google_trace_TraceContext_fields[4] = {
PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, google_trace_TraceContext, trace_id, trace_id, &google_trace_TraceId_fields),
PB_FIELD( 2, FIXED64 , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, span_id, trace_id, 0),
PB_FIELD( 3, BOOL , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, is_sampled, span_id, 0),
PB_LAST_FIELD
};
/* Check that field information fits in pb_field_t */
#if !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_32BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
* field descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(google_trace_TraceContext, trace_id) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_trace_TraceId_google_trace_TraceContext)
#endif
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_16BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in the default
* 8 bit descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(google_trace_TraceContext, trace_id) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_trace_TraceId_google_trace_TraceContext)
#endif
/* @@protoc_insertion_point(eof) */

@ -1,6 +1,6 @@
/*
*
* Copyright 2016, Google Inc.
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -31,11 +31,13 @@
*
*/
/* Automatically generated nanopb header */
/* Generated by nanopb-0.3.5-dev */
/* Generated by nanopb-0.3.7-dev at Fri Jan 20 16:14:22 2017. */
#ifndef GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H
#define GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H
#include "third_party/nanopb/pb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
@ -45,44 +47,35 @@ extern "C" {
#endif
/* Struct definitions */
typedef struct _google_trace_TraceId {
bool has_hi;
uint64_t hi;
bool has_lo;
uint64_t lo;
} google_trace_TraceId;
typedef struct _google_trace_TraceContext {
bool has_trace_id;
google_trace_TraceId trace_id;
bool has_trace_id_hi;
uint64_t trace_id_hi;
bool has_trace_id_lo;
uint64_t trace_id_lo;
bool has_span_id;
uint64_t span_id;
bool has_is_sampled;
bool is_sampled;
bool has_span_options;
uint32_t span_options;
/* @@protoc_insertion_point(struct:google_trace_TraceContext) */
} google_trace_TraceContext;
/* Default values for struct fields */
/* Initializer values for message structs */
#define google_trace_TraceId_init_default {false, 0, false, 0}
#define google_trace_TraceContext_init_default {false, google_trace_TraceId_init_default, false, 0, false, 0}
#define google_trace_TraceId_init_zero {false, 0, false, 0}
#define google_trace_TraceContext_init_zero {false, google_trace_TraceId_init_zero, false, 0, false, 0}
#define google_trace_TraceContext_init_default {false, 0, false, 0, false, 0, false, 0}
#define google_trace_TraceContext_init_zero {false, 0, false, 0, false, 0, false, 0}
/* Field tags (for use in manual encoding/decoding) */
#define google_trace_TraceId_hi_tag 1
#define google_trace_TraceId_lo_tag 2
#define google_trace_TraceContext_trace_id_tag 1
#define google_trace_TraceContext_span_id_tag 2
#define google_trace_TraceContext_is_sampled_tag 3
#define google_trace_TraceContext_trace_id_hi_tag 1
#define google_trace_TraceContext_trace_id_lo_tag 2
#define google_trace_TraceContext_span_id_tag 3
#define google_trace_TraceContext_span_options_tag 4
/* Struct field encoding specification for nanopb */
extern const pb_field_t google_trace_TraceId_fields[3];
extern const pb_field_t google_trace_TraceContext_fields[4];
extern const pb_field_t google_trace_TraceContext_fields[5];
/* Maximum encoded size of messages (where known) */
#define google_trace_TraceId_size 18
#define google_trace_TraceContext_size 31
#define google_trace_TraceContext_size 32
/* Message IDs (where set with "msgid" option) */
#ifdef PB_MSGID
@ -95,5 +88,6 @@ extern const pb_field_t google_trace_TraceContext_fields[4];
#ifdef __cplusplus
} /* extern "C" */
#endif
/* @@protoc_insertion_point(eof) */
#endif /* GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H */
#endif

@ -73,7 +73,7 @@ bool decode_trace_context(google_trace_TraceContext *ctxt, uint8_t *buffer,
}
// check fields
if (!ctxt->has_trace_id) {
if (!ctxt->has_trace_id_hi || !ctxt->has_trace_id_lo) {
gpr_log(GPR_DEBUG, "Invalid TraceContext: missing trace_id");
return false;
}

@ -38,6 +38,9 @@
#include "src/core/ext/census/gen/trace_context.pb.h"
/* Span option flags. */
#define SPAN_OPTIONS_IS_SAMPLED 0x01
/* Maximum number of bytes required to encode a TraceContext (31)
1 byte for trace_id field
1 byte for trace_id length

@ -0,0 +1,61 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CENSUS_TRACE_LABEL_H
#define GRPC_CORE_EXT_CENSUS_TRACE_LABEL_H
#include "src/core/ext/census/trace_string.h"
/* Trace label (key/value pair) stores a label name and the label value. The
value can be one of trace_string/int64_t/bool. */
typedef struct trace_label {
trace_string key;
enum label_type {
/* Unknown value for debugging/error purposes */
LABEL_UNKNOWN = 0,
/* A string value */
LABEL_STRING = 1,
/* An integer value. */
LABEL_INT = 2,
/* A boolean value. */
LABEL_BOOL = 3,
} value_type;
union value {
trace_string label_str;
int64_t label_int;
bool label_bool;
} value;
} trace_label;
#endif

@ -0,0 +1,63 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CENSUS_TRACE_PROPAGATION_H
#define GRPC_CORE_EXT_CENSUS_TRACE_PROPAGATION_H
#include "src/core/ext/census/tracing.h"
/* Encoding and decoding functions for receiving and sending trace contexts
over the wire. Only RPC libraries should be calling these
functions. These functions return the number of bytes encoded/decoded
(0 if a failure has occurred). buf_size indicates the size of the
input/output buffer. trace_span_context is a struct that includes the
trace ID, span ID, and a set of option flags (is_sampled, etc.). */
/* Converts a span context to a binary byte buffer. */
size_t trace_span_context_to_binary(const trace_span_context *ctxt,
uint8_t *buf, size_t buf_size);
/* Reads a binary byte buffer and populates a span context structure. */
size_t binary_to_trace_span_context(const uint8_t *buf, size_t buf_size,
trace_span_context *ctxt);
/* Converts a span context to an http metadata compatible string. */
size_t trace_span_context_to_http_format(const trace_span_context *ctxt,
char *buf, size_t buf_size);
/* Reads an http metadata compatible string and populates a span context
structure. */
size_t http_format_to_trace_span_context(const char *buf, size_t buf_size,
trace_span_context *ctxt);
#endif

@ -0,0 +1,45 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CENSUS_TRACE_STATUS_H
#define GRPC_CORE_EXT_CENSUS_TRACE_STATUS_H
#include "src/core/ext/census/trace_string.h"
/* Stores a status code and status message for a trace. */
typedef struct trace_status {
int64_t errorCode;
trace_string errorMessage;
} trace_status;
#endif

@ -0,0 +1,50 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CENSUS_TRACE_STRING_H
#define GRPC_CORE_EXT_CENSUS_TRACE_STRING_H
#include <grpc/slice.h>
/* String struct for tracing messages. Since this is a C API, we do not have
access to a string class. This is intended for use by higher level
languages which wrap around the C API, as most of them have a string class.
This will also be more efficient when copying, as we have an explicitly
specified length. Also, grpc_slice has reference counting which allows for
interning. */
typedef struct trace_string {
char *string;
size_t length;
} trace_string;
#endif

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -31,21 +31,41 @@
*
*/
//#include "src/core/ext/census/tracing.h"
#include "src/core/ext/census/tracing.h"
#include <grpc/census.h>
#include <stdlib.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <openssl/rand.h>
#include "src/core/ext/census/mlog.h"
/* TODO(aveitch): These are all placeholder implementations. */
void trace_start_span(const trace_span_context *span_ctxt,
const trace_string name, const start_span_options *opts,
trace_span_context *new_span_ctxt,
bool has_remote_parent) {
// Noop implementation.
}
void trace_add_span_annotation(const trace_string description,
const trace_label *labels, const size_t n_labels,
trace_span_context *span_ctxt) {
// Noop implementation.
}
int census_trace_mask(const census_context *context) {
abort();
return CENSUS_TRACE_MASK_NONE;
void trace_add_span_network_event_annotation(const trace_string description,
const trace_label *labels,
const size_t n_labels,
const gpr_timespec timestamp,
bool sent, uint64_t id,
trace_span_context *span_ctxt) {
// Noop implementation.
}
void census_set_trace_mask(int trace_mask) { abort(); }
void trace_add_span_labels(const trace_label *labels, const size_t n_labels,
trace_span_context *span_ctxt) {
// Noop implementation.
}
void census_trace_print(census_context *context, uint32_t type,
const char *buffer, size_t n) {
abort();
void trace_end_span(const trace_status *status, trace_span_context *span_ctxt) {
// Noop implementation.
}

@ -0,0 +1,124 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CENSUS_TRACING_H
#define GRPC_CORE_EXT_CENSUS_TRACING_H
#include <grpc/support/time.h>
#include <stdbool.h>
#include "src/core/ext/census/trace_context.h"
#include "src/core/ext/census/trace_label.h"
#include "src/core/ext/census/trace_status.h"
/* This is the low level tracing API that other languages will interface with.
This is not intended to be accessed by the end-user, therefore it has been
designed with performance in mind rather than ease of use. */
/* The tracing level. */
enum TraceLevel {
/* Annotations on this context will be silently discarded. */
NO_TRACING = 0,
/* Annotations will not be saved to a persistent store. They will be
available via local APIs only. This setting is not propagated to child
spans. */
TRANSIENT_TRACING = 1,
/* Annotations are recorded for the entire distributed trace and they are
saved to a persistent store. This setting is propagated to child spans. */
PERSISTENT_TRACING = 2,
};
typedef struct trace_span_context {
/* Trace span context stores Span ID, Trace ID, and option flags. */
/* Trace ID is 128 bits split into 2 64-bit chunks (hi and lo). */
uint64_t trace_id_hi;
uint64_t trace_id_lo;
/* Span ID is 64 bits. */
uint64_t span_id;
/* Span-options is 32-bit value which contains flag options. */
uint32_t span_options;
} trace_span_context;
typedef struct start_span_options {
/* If set, this will override the Span.local_start_time for the Span. */
gpr_timespec local_start_timestamp;
/* Linked spans can be used to identify spans that are linked to this span in
a different trace. This can be used (for example) in batching operations,
where a single batch handler processes multiple requests from different
traces. If set, points to a list of Spans are linked to the created Span.*/
trace_span_context *linked_spans;
/* The number of linked spans. */
size_t n_linked_spans;
} start_span_options;
/* Create a new child Span (or root if parent is NULL), with parent being the
designated Span. The child span will have the provided name and starting
span options (optional). The bool has_remote_parent marks whether the
context refers to a remote parent span or not. */
void trace_start_span(const trace_span_context *span_ctxt,
const trace_string name, const start_span_options *opts,
trace_span_context *new_span_ctxt,
bool has_remote_parent);
/* Add a new Annotation to the Span. Annotations consist of a description
(trace_string) and a set of n labels (trace_label). This can be populated
with arbitrary user data. */
void trace_add_span_annotation(const trace_string description,
const trace_label *labels, const size_t n_labels,
trace_span_context *span_ctxt);
/* Add a new NetworkEvent annotation to a Span. This function is only intended
to be used by RPC systems (either client or server), not by higher level
applications. The timestamp type will be system-defined, the sent argument
designates whether this is a network send event (client request, server
reply)or receive (server request, client reply). The id argument corresponds
to Span.Annotation.NetworkEvent.id from the data model, and serves to uniquely
identify each network message. */
void trace_add_span_network_event(const trace_string description,
const trace_label *labels,
const size_t n_labels,
const gpr_timespec timestamp, bool sent,
uint64_t id, trace_span_context *span_ctxt);
/* Add a set of labels to the Span. These will correspond to the field
Span.labels in the data model. */
void trace_add_span_labels(const trace_label *labels, const size_t n_labels,
trace_span_context *span_ctxt);
/* Mark the end of Span Execution with the given status. Only the timing of the
first EndSpan call for a given Span will be recorded, and implementations are
free to ignore all further calls using the Span. EndSpanOptions can
optionally be NULL. */
void trace_end_span(const trace_status *status, trace_span_context *span_ctxt);
#endif

@ -44,8 +44,8 @@
#include <grpc/support/useful.h>
#include "src/core/ext/client_channel/http_connect_handshaker.h"
#include "src/core/ext/client_channel/http_proxy.h"
#include "src/core/ext/client_channel/lb_policy_registry.h"
#include "src/core/ext/client_channel/proxy_mapper_registry.h"
#include "src/core/ext/client_channel/resolver_registry.h"
#include "src/core/ext/client_channel/subchannel.h"
#include "src/core/lib/channel/channel_args.h"
@ -153,10 +153,6 @@ static void *method_parameters_create_from_json(const grpc_json *json) {
*/
typedef struct client_channel_channel_data {
/** server name */
char *server_name;
/** HTTP CONNECT proxy to use, if any */
char *proxy_name;
/** resolver for this channel */
grpc_resolver *resolver;
/** have we started resolving this channel */
@ -317,17 +313,6 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
// Use pick_first if nothing was specified and we didn't select grpclb
// above.
if (lb_policy_name == NULL) lb_policy_name = "pick_first";
// If using a proxy, add channel arg for server in HTTP CONNECT request.
if (chand->proxy_name != NULL) {
grpc_arg new_arg;
new_arg.key = GRPC_ARG_HTTP_CONNECT_SERVER;
new_arg.type = GRPC_ARG_STRING;
new_arg.value.string = chand->server_name;
grpc_channel_args *tmp_args = chand->resolver_result;
chand->resolver_result =
grpc_channel_args_copy_and_add(chand->resolver_result, &new_arg, 1);
grpc_channel_args_destroy(exec_ctx, tmp_args);
}
// Instantiate LB policy.
grpc_lb_policy_args lb_policy_args;
lb_policy_args.args = chand->resolver_result;
@ -542,16 +527,21 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
grpc_client_channel_factory_ref(arg->value.pointer.p);
chand->client_channel_factory = arg->value.pointer.p;
// Instantiate resolver.
// Get server name to resolve, using proxy mapper if needed.
arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI);
GPR_ASSERT(arg != NULL);
GPR_ASSERT(arg->type == GRPC_ARG_STRING);
chand->server_name = gpr_strdup(arg->value.string);
chand->proxy_name = grpc_get_http_proxy_server();
char *name_to_resolve =
chand->proxy_name == NULL ? chand->server_name : chand->proxy_name;
char *proxy_name = NULL;
grpc_channel_args *new_args = NULL;
grpc_proxy_mappers_map_name(exec_ctx, arg->value.string, args->channel_args,
&proxy_name, &new_args);
// Instantiate resolver.
chand->resolver = grpc_resolver_create(
exec_ctx, name_to_resolve, args->channel_args, chand->interested_parties);
exec_ctx, proxy_name != NULL ? proxy_name : arg->value.string,
new_args != NULL ? new_args : args->channel_args,
chand->interested_parties);
if (proxy_name != NULL) gpr_free(proxy_name);
if (new_args != NULL) grpc_channel_args_destroy(exec_ctx, new_args);
if (chand->resolver == NULL) {
return GRPC_ERROR_CREATE("resolver creation failed");
}
@ -562,8 +552,6 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
channel_data *chand = elem->channel_data;
gpr_free(chand->server_name);
gpr_free(chand->proxy_name);
if (chand->resolver != NULL) {
grpc_resolver_shutdown(exec_ctx, chand->resolver);
GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel");
@ -644,6 +632,12 @@ typedef struct client_channel_call_data {
grpc_linked_mdelem lb_token_mdelem;
} call_data;
grpc_subchannel_call *grpc_client_channel_get_subchannel_call(
grpc_call_element *call_elem) {
grpc_subchannel_call *scc = GET_CALL((call_data *)call_elem->call_data);
return scc == CANCELLED_CALL ? NULL : scc;
}
static void add_waiting_locked(call_data *calld, grpc_transport_stream_op *op) {
GPR_TIMER_BEGIN("add_waiting_locked", 0);
if (calld->waiting_ops_count == calld->waiting_ops_capacity) {

@ -57,4 +57,8 @@ void grpc_client_channel_watch_connectivity_state(
grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset,
grpc_connectivity_state *state, grpc_closure *on_complete);
/* Debug helper: pull the subchannel call from a call stack element */
grpc_subchannel_call *grpc_client_channel_get_subchannel_call(
grpc_call_element *elem);
#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_CLIENT_CHANNEL_H */

@ -39,6 +39,7 @@
#include "src/core/ext/client_channel/client_channel.h"
#include "src/core/ext/client_channel/http_connect_handshaker.h"
#include "src/core/ext/client_channel/http_proxy.h"
#include "src/core/ext/client_channel/lb_policy_registry.h"
#include "src/core/ext/client_channel/proxy_mapper_registry.h"
#include "src/core/ext/client_channel/resolver_registry.h"
@ -82,6 +83,7 @@ void grpc_client_channel_init(void) {
grpc_lb_policy_registry_init();
grpc_resolver_registry_init();
grpc_proxy_mapper_registry_init();
grpc_register_http_proxy_mapper();
grpc_subchannel_index_init();
grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MIN,
set_default_host_if_unset, NULL);

@ -40,10 +40,13 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/http_connect_handshaker.h"
#include "src/core/ext/client_channel/proxy_mapper_registry.h"
#include "src/core/ext/client_channel/uri_parser.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/support/env.h"
char* grpc_get_http_proxy_server() {
static char* grpc_get_http_proxy_server() {
char* uri_str = gpr_getenv("http_proxy");
if (uri_str == NULL) return NULL;
grpc_uri* uri = grpc_uri_parse(uri_str, false /* suppress_errors */);
@ -66,3 +69,55 @@ done:
grpc_uri_destroy(uri);
return proxy_name;
}
static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args) {
*name_to_resolve = grpc_get_http_proxy_server();
if (*name_to_resolve == NULL) return false;
grpc_uri* uri = grpc_uri_parse(server_uri, false /* suppress_errors */);
if (uri == NULL || uri->path[0] == '\0') {
gpr_log(GPR_ERROR,
"'http_proxy' environment variable set, but cannot "
"parse server URI '%s' -- not using proxy",
server_uri);
if (uri != NULL) grpc_uri_destroy(uri);
return false;
}
if (strcmp(uri->scheme, "unix") == 0) {
gpr_log(GPR_INFO, "not using proxy for Unix domain socket '%s'",
server_uri);
grpc_uri_destroy(uri);
return false;
}
grpc_arg new_arg;
new_arg.key = GRPC_ARG_HTTP_CONNECT_SERVER;
new_arg.type = GRPC_ARG_STRING;
new_arg.value.string = uri->path[0] == '/' ? uri->path + 1 : uri->path;
*new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
grpc_uri_destroy(uri);
return true;
}
static bool proxy_mapper_map_address(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args) {
return false;
}
static void proxy_mapper_destroy(grpc_proxy_mapper* mapper) {}
static const grpc_proxy_mapper_vtable proxy_mapper_vtable = {
proxy_mapper_map_name, proxy_mapper_map_address, proxy_mapper_destroy};
static grpc_proxy_mapper proxy_mapper = {&proxy_mapper_vtable};
void grpc_register_http_proxy_mapper() {
grpc_proxy_mapper_register(true /* at_start */, &proxy_mapper);
}

@ -34,8 +34,6 @@
#ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_PROXY_H
#define GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_PROXY_H
/// Returns the name of the proxy to use, or NULL if no proxy is configured.
/// Caller takes ownership of result.
char* grpc_get_http_proxy_server();
void grpc_register_http_proxy_mapper();
#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_PROXY_H */

@ -38,13 +38,24 @@ void grpc_proxy_mapper_init(const grpc_proxy_mapper_vtable* vtable,
mapper->vtable = vtable;
}
bool grpc_proxy_mapper_map(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args) {
return mapper->vtable->map(exec_ctx, mapper, address, args, new_address,
new_args);
bool grpc_proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args) {
return mapper->vtable->map_name(exec_ctx, mapper, server_uri, args,
name_to_resolve, new_args);
}
bool grpc_proxy_mapper_map_address(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args) {
return mapper->vtable->map_address(exec_ctx, mapper, address, args,
new_address, new_args);
}
void grpc_proxy_mapper_destroy(grpc_proxy_mapper* mapper) {

@ -43,15 +43,22 @@
typedef struct grpc_proxy_mapper grpc_proxy_mapper;
typedef struct {
/// Determines the proxy name to resolve for \a server_uri.
/// If no proxy is needed, returns false.
/// Otherwise, sets \a name_to_resolve, optionally sets \a new_args,
/// and returns true.
bool (*map_name)(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper,
const char* server_uri, const grpc_channel_args* args,
char** name_to_resolve, grpc_channel_args** new_args);
/// Determines the proxy address to use to contact \a address.
/// If no proxy is needed, returns false.
/// Otherwise, sets \a new_address, optionally sets \a new_args, and
/// returns true.
bool (*map)(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args);
bool (*map_address)(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args);
/// Destroys \a mapper.
void (*destroy)(grpc_proxy_mapper* mapper);
} grpc_proxy_mapper_vtable;
@ -63,11 +70,20 @@ struct grpc_proxy_mapper {
void grpc_proxy_mapper_init(const grpc_proxy_mapper_vtable* vtable,
grpc_proxy_mapper* mapper);
bool grpc_proxy_mapper_map(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args);
bool grpc_proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args);
bool grpc_proxy_mapper_map_address(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args);
void grpc_proxy_mapper_destroy(grpc_proxy_mapper* mapper);
#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_H */

@ -61,15 +61,28 @@ static void grpc_proxy_mapper_list_register(grpc_proxy_mapper_list* list,
++list->num_mappers;
}
static bool grpc_proxy_mapper_list_map(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper_list* list,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args) {
static bool grpc_proxy_mapper_list_map_name(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper_list* list,
const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args) {
for (size_t i = 0; i < list->num_mappers; ++i) {
if (grpc_proxy_mapper_map(exec_ctx, list->list[i], address, args,
new_address, new_args)) {
if (grpc_proxy_mapper_map_name(exec_ctx, list->list[i], server_uri, args,
name_to_resolve, new_args)) {
return true;
}
}
return false;
}
static bool grpc_proxy_mapper_list_map_address(
grpc_exec_ctx* exec_ctx, grpc_proxy_mapper_list* list,
const grpc_resolved_address* address, const grpc_channel_args* args,
grpc_resolved_address** new_address, grpc_channel_args** new_args) {
for (size_t i = 0; i < list->num_mappers; ++i) {
if (grpc_proxy_mapper_map_address(exec_ctx, list->list[i], address, args,
new_address, new_args)) {
return true;
}
}
@ -101,11 +114,20 @@ void grpc_proxy_mapper_register(bool at_start, grpc_proxy_mapper* mapper) {
grpc_proxy_mapper_list_register(&g_proxy_mapper_list, at_start, mapper);
}
bool grpc_proxy_mappers_map(grpc_exec_ctx* exec_ctx,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args) {
return grpc_proxy_mapper_list_map(exec_ctx, &g_proxy_mapper_list, address,
args, new_address, new_args);
bool grpc_proxy_mappers_map_name(grpc_exec_ctx* exec_ctx,
const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args) {
return grpc_proxy_mapper_list_map_name(exec_ctx, &g_proxy_mapper_list,
server_uri, args, name_to_resolve,
new_args);
}
bool grpc_proxy_mappers_map_address(grpc_exec_ctx* exec_ctx,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args) {
return grpc_proxy_mapper_list_map_address(
exec_ctx, &g_proxy_mapper_list, address, args, new_address, new_args);
}

@ -44,10 +44,16 @@ void grpc_proxy_mapper_registry_shutdown();
/// the list. Otherwise, it will be added to the end.
void grpc_proxy_mapper_register(bool at_start, grpc_proxy_mapper* mapper);
bool grpc_proxy_mappers_map(grpc_exec_ctx* exec_ctx,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args);
bool grpc_proxy_mappers_map_name(grpc_exec_ctx* exec_ctx,
const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args);
bool grpc_proxy_mappers_map_address(grpc_exec_ctx* exec_ctx,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args);
#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H */

@ -336,8 +336,8 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
grpc_set_initial_connect_string(&addr, &c->initial_connect_string);
grpc_resolved_address *new_address = NULL;
grpc_channel_args *new_args = NULL;
if (grpc_proxy_mappers_map(exec_ctx, addr, args->args, &new_address,
&new_args)) {
if (grpc_proxy_mappers_map_address(exec_ctx, addr, args->args, &new_address,
&new_args)) {
GPR_ASSERT(new_address != NULL);
gpr_free(addr);
addr = new_address;
@ -788,7 +788,8 @@ grpc_call_stack *grpc_subchannel_call_get_call_stack(
return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
}
static void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
static void grpc_uri_to_sockaddr(const char *uri_str,
grpc_resolved_address *addr) {
grpc_uri *uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */);
GPR_ASSERT(uri != NULL);
if (strcmp(uri->scheme, "ipv4") == 0) {
@ -803,14 +804,19 @@ static void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
grpc_resolved_address *addr) {
const char *addr_uri_str = grpc_get_subchannel_address_uri_arg(args);
memset(addr, 0, sizeof(*addr));
if (*addr_uri_str != '\0') {
grpc_uri_to_sockaddr(addr_uri_str, addr);
}
}
const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args) {
const grpc_arg *addr_arg =
grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS);
GPR_ASSERT(addr_arg != NULL); // Should have been set by LB policy.
GPR_ASSERT(addr_arg->type == GRPC_ARG_STRING);
memset(addr, 0, sizeof(*addr));
if (*addr_arg->value.string != '\0') {
grpc_uri_to_sockaddr(addr_arg->value.string, addr);
}
return addr_arg->value.string;
}
grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr) {

@ -178,6 +178,9 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
grpc_resolved_address *addr);
/// Returns the URI string for the address to connect to.
const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args);
/// Returns a new channel arg encoding the subchannel address as a string.
/// Caller is responsible for freeing the string.
grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr);

@ -112,11 +112,13 @@
#include "src/core/ext/client_channel/lb_policy_registry.h"
#include "src/core/ext/client_channel/parse_address.h"
#include "src/core/ext/lb_policy/grpclb/grpclb.h"
#include "src/core/ext/lb_policy/grpclb/grpclb_channel.h"
#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/slice/slice_hash_table.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/backoff.h"
@ -751,6 +753,96 @@ static void glb_rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
GRPC_ERROR_UNREF(error);
}
static void destroy_balancer_name(grpc_exec_ctx *exec_ctx,
void *balancer_name) {
gpr_free(balancer_name);
}
static void *copy_balancer_name(void *balancer_name) {
return gpr_strdup(balancer_name);
}
static grpc_slice_hash_table_entry targets_info_entry_create(
const char *address, const char *balancer_name) {
static const grpc_slice_hash_table_vtable vtable = {destroy_balancer_name,
copy_balancer_name};
grpc_slice_hash_table_entry entry;
entry.key = grpc_slice_from_copied_string(address);
entry.value = (void *)balancer_name;
entry.vtable = &vtable;
return entry;
}
/* Returns the target URI for the LB service whose addresses are in \a
* addresses. Using this URI, a bidirectional streaming channel will be created
* for the reception of load balancing updates.
*
* The output argument \a targets_info will be updated to contain a mapping of
* "LB server address" to "balancer name", as reported by the naming system.
* This mapping will be propagated via the channel arguments of the
* aforementioned LB streaming channel, to be used by the security connector for
* secure naming checks. The user is responsible for freeing \a targets_info. */
static char *get_lb_uri_target_addresses(grpc_exec_ctx *exec_ctx,
const grpc_lb_addresses *addresses,
grpc_slice_hash_table **targets_info) {
size_t num_grpclb_addrs = 0;
for (size_t i = 0; i < addresses->num_addresses; ++i) {
if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
}
/* All input addresses come from a resolver that claims they are LB services.
* It's the resolver's responsibility to make sure this policy is only
* instantiated and used in that case. Otherwise, something has gone wrong. */
GPR_ASSERT(num_grpclb_addrs > 0);
grpc_slice_hash_table_entry *targets_info_entries =
gpr_malloc(sizeof(*targets_info_entries) * num_grpclb_addrs);
/* construct a target ipvX://ip1:port1,ip2:port2,... from the addresses in \a
* addresses */
/* TODO(dgq): support mixed ip version */
char **addr_strs = gpr_malloc(sizeof(char *) * num_grpclb_addrs);
size_t addr_index = 0;
for (size_t i = 0; i < addresses->num_addresses; i++) {
if (addresses->addresses[i].user_data != NULL) {
gpr_log(GPR_ERROR,
"This LB policy doesn't support user data. It will be ignored");
}
if (addresses->addresses[i].is_balancer) {
char *addr_str;
GPR_ASSERT(grpc_sockaddr_to_string(
&addr_str, &addresses->addresses[i].address, true) > 0);
targets_info_entries[addr_index] = targets_info_entry_create(
addr_str, addresses->addresses[i].balancer_name);
addr_strs[addr_index++] = addr_str;
}
}
GPR_ASSERT(addr_index == num_grpclb_addrs);
size_t uri_path_len;
char *uri_path = gpr_strjoin_sep((const char **)addr_strs, num_grpclb_addrs,
",", &uri_path_len);
for (size_t i = 0; i < num_grpclb_addrs; i++) gpr_free(addr_strs[i]);
gpr_free(addr_strs);
char *target_uri_str = NULL;
/* TODO(dgq): Don't assume all addresses will share the scheme of the first
* one */
gpr_asprintf(&target_uri_str, "%s:%s",
grpc_sockaddr_get_uri_scheme(&addresses->addresses[0].address),
uri_path);
gpr_free(uri_path);
*targets_info =
grpc_slice_hash_table_create(num_grpclb_addrs, targets_info_entries);
for (size_t i = 0; i < num_grpclb_addrs; i++) {
grpc_slice_unref_internal(exec_ctx, targets_info_entries[i].key);
}
gpr_free(targets_info_entries);
return target_uri_str;
}
static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
grpc_lb_policy_factory *factory,
grpc_lb_policy_args *args) {
@ -788,85 +880,30 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
}
grpc_uri_destroy(uri);
/* All input addresses in addresses come from a resolver that claims
* they are LB services. It's the resolver's responsibility to make sure
* this policy is only instantiated and used in that case.
*
* Create a client channel over them to communicate with a LB service */
glb_policy->cc_factory = args->client_channel_factory;
glb_policy->args = grpc_channel_args_copy(args->args);
GPR_ASSERT(glb_policy->cc_factory != NULL);
/* construct a target from the addresses in args, given in the form
* ipvX://ip1:port1,ip2:port2,...
* TODO(dgq): support mixed ip version */
char **addr_strs = gpr_malloc(sizeof(char *) * num_grpclb_addrs);
size_t addr_index = 0;
for (size_t i = 0; i < addresses->num_addresses; i++) {
if (addresses->addresses[i].user_data != NULL) {
gpr_log(GPR_ERROR,
"This LB policy doesn't support user data. It will be ignored");
}
if (addresses->addresses[i].is_balancer) {
if (addr_index == 0) {
addr_strs[addr_index++] =
grpc_sockaddr_to_uri(&addresses->addresses[i].address);
} else {
GPR_ASSERT(grpc_sockaddr_to_string(&addr_strs[addr_index++],
&addresses->addresses[i].address,
true) > 0);
}
}
}
size_t uri_path_len;
char *target_uri_str = gpr_strjoin_sep((const char **)addr_strs,
num_grpclb_addrs, ",", &uri_path_len);
/* Create a channel to talk to the LBs.
*
* We strip out the channel arg for the LB policy name, since we want
* to use the default (pick_first) in this case.
*
* We also strip out the channel arg for the resolved addresses, since
* that will be generated by the name resolver used in the LB channel.
* Note that the LB channel will use the sockaddr resolver, so this
* won't actually generate a query to DNS (or some other name service).
* However, the addresses returned by the sockaddr resolver will have
* is_balancer=false, whereas our own addresses have is_balancer=true.
* We need the LB channel to return addresses with is_balancer=false
* so that it does not wind up recursively using the grpclb LB policy,
* as per the special case logic in client_channel.c.
*
* Finally, we also strip out the channel arg for the server URI,
* since that will be different for the LB channel than for the parent
* channel. (The client channel factory will re-add this arg with
* the right value.)
*/
static const char *keys_to_remove[] = {
GRPC_ARG_LB_POLICY_NAME, GRPC_ARG_LB_ADDRESSES, GRPC_ARG_SERVER_URI};
grpc_channel_args *new_args = grpc_channel_args_copy_and_remove(
args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove));
glb_policy->lb_channel = grpc_client_channel_factory_create_channel(
exec_ctx, glb_policy->cc_factory, target_uri_str,
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, new_args);
grpc_channel_args_destroy(exec_ctx, new_args);
gpr_free(target_uri_str);
for (size_t i = 0; i < num_grpclb_addrs; i++) {
gpr_free(addr_strs[i]);
}
gpr_free(addr_strs);
grpc_slice_hash_table *targets_info = NULL;
/* Create a client channel over them to communicate with a LB service */
char *lb_service_target_addresses =
get_lb_uri_target_addresses(exec_ctx, addresses, &targets_info);
grpc_channel_args *lb_channel_args =
get_lb_channel_args(exec_ctx, targets_info, args->args);
glb_policy->lb_channel = grpc_lb_policy_grpclb_create_lb_channel(
exec_ctx, lb_service_target_addresses, args->client_channel_factory,
lb_channel_args);
grpc_slice_hash_table_unref(exec_ctx, targets_info);
grpc_channel_args_destroy(exec_ctx, lb_channel_args);
gpr_free(lb_service_target_addresses);
if (glb_policy->lb_channel == NULL) {
gpr_free(glb_policy);
return NULL;
}
grpc_lb_policy_init(&glb_policy->base, &glb_lb_policy_vtable);
gpr_mu_init(&glb_policy->mu);
grpc_connectivity_state_init(&glb_policy->state_tracker, GRPC_CHANNEL_IDLE,
"grpclb");
return &glb_policy->base;
}

@ -0,0 +1,77 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
#include "src/core/ext/lb_policy/grpclb/grpclb_channel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/support/string.h"
grpc_channel *grpc_lb_policy_grpclb_create_lb_channel(
grpc_exec_ctx *exec_ctx, const char *lb_service_target_addresses,
grpc_client_channel_factory *client_channel_factory,
grpc_channel_args *args) {
grpc_channel *lb_channel = grpc_client_channel_factory_create_channel(
exec_ctx, client_channel_factory, lb_service_target_addresses,
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, args);
return lb_channel;
}
grpc_channel_args *get_lb_channel_args(grpc_exec_ctx *exec_ctx,
grpc_slice_hash_table *targets_info,
const grpc_channel_args *args) {
/* We strip out the channel arg for the LB policy name, since we want
* to use the default (pick_first) in this case.
*
* We also strip out the channel arg for the resolved addresses, since
* that will be generated by the name resolver used in the LB channel.
* Note that the LB channel will use the sockaddr resolver, so this
* won't actually generate a query to DNS (or some other name service).
* However, the addresses returned by the sockaddr resolver will have
* is_balancer=false, whereas our own addresses have is_balancer=true.
* We need the LB channel to return addresses with is_balancer=false
* so that it does not wind up recursively using the grpclb LB policy,
* as per the special case logic in client_channel.c.
*
* Lastly, we also strip out the channel arg for the server URI,
* since that will be different for the LB channel than for the parent
* channel (the client channel factory will re-add this arg with
* the right value). */
static const char *keys_to_remove[] = {
GRPC_ARG_LB_POLICY_NAME, GRPC_ARG_LB_ADDRESSES, GRPC_ARG_SERVER_URI};
return grpc_channel_args_copy_and_remove(args, keys_to_remove,
GPR_ARRAY_SIZE(keys_to_remove));
}

@ -0,0 +1,56 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H
#define GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H
#include "src/core/ext/client_channel/lb_policy_factory.h"
#include "src/core/lib/slice/slice_hash_table.h"
/** Create the channel used for communicating with an LB service.
* Note that an LB *service* may be comprised of several LB *servers*.
*
* \a lb_service_target_addresses is the target URI containing the addresses
* from resolving the LB service's name (eg, ipv4:10.0.0.1:1234,10.2.3.4:9876).
* \a client_channel_factory will be used for the creation of the LB channel,
* alongside the channel args passed in \a args. */
grpc_channel *grpc_lb_policy_grpclb_create_lb_channel(
grpc_exec_ctx *exec_ctx, const char *lb_service_target_addresses,
grpc_client_channel_factory *client_channel_factory,
grpc_channel_args *args);
grpc_channel_args *get_lb_channel_args(grpc_exec_ctx *exec_ctx,
grpc_slice_hash_table *targets_info,
const grpc_channel_args *args);
#endif /* GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H */

@ -0,0 +1,107 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
#include "src/core/ext/lb_policy/grpclb/grpclb_channel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/string.h"
grpc_channel *grpc_lb_policy_grpclb_create_lb_channel(
grpc_exec_ctx *exec_ctx, const char *lb_service_target_addresses,
grpc_client_channel_factory *client_channel_factory,
grpc_channel_args *args) {
grpc_channel_args *new_args = args;
grpc_channel_credentials *channel_credentials =
grpc_channel_credentials_find_in_args(args);
if (channel_credentials != NULL) {
/* Substitute the channel credentials with a version without call
* credentials: the load balancer is not necessarily trusted to handle
* bearer token credentials */
static const char *keys_to_remove[] = {GRPC_ARG_CHANNEL_CREDENTIALS};
grpc_channel_credentials *creds_sans_call_creds =
grpc_channel_credentials_duplicate_without_call_credentials(
channel_credentials);
GPR_ASSERT(creds_sans_call_creds != NULL);
grpc_arg args_to_add[] = {
grpc_channel_credentials_to_arg(creds_sans_call_creds)};
/* Create the new set of channel args */
new_args = grpc_channel_args_copy_and_add_and_remove(
args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
grpc_channel_credentials_unref(exec_ctx, creds_sans_call_creds);
}
grpc_channel *lb_channel = grpc_client_channel_factory_create_channel(
exec_ctx, client_channel_factory, lb_service_target_addresses,
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, new_args);
if (channel_credentials != NULL) {
grpc_channel_args_destroy(exec_ctx, new_args);
}
return lb_channel;
}
grpc_channel_args *get_lb_channel_args(grpc_exec_ctx *exec_ctx,
grpc_slice_hash_table *targets_info,
const grpc_channel_args *args) {
const grpc_arg targets_info_arg =
grpc_lb_targets_info_create_channel_arg(targets_info);
/* We strip out the channel arg for the LB policy name, since we want
* to use the default (pick_first) in this case.
*
* We also strip out the channel arg for the resolved addresses, since
* that will be generated by the name resolver used in the LB channel.
* Note that the LB channel will use the sockaddr resolver, so this
* won't actually generate a query to DNS (or some other name service).
* However, the addresses returned by the sockaddr resolver will have
* is_balancer=false, whereas our own addresses have is_balancer=true.
* We need the LB channel to return addresses with is_balancer=false
* so that it does not wind up recursively using the grpclb LB policy,
* as per the special case logic in client_channel.c.
*
* Lastly, we also strip out the channel arg for the server URI,
* since that will be different for the LB channel than for the parent
* channel (the client channel factory will re-add this arg with
* the right value). */
static const char *keys_to_remove[] = {
GRPC_ARG_LB_POLICY_NAME, GRPC_ARG_LB_ADDRESSES, GRPC_ARG_SERVER_URI};
/* Add the targets info table to be used for secure naming */
return grpc_channel_args_copy_and_add_and_remove(
args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &targets_info_arg,
1);
}

@ -739,6 +739,13 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
sc_args.args = new_args;
grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
exec_ctx, args->client_channel_factory, &sc_args);
if (grpc_lb_round_robin_trace) {
char *address_uri =
grpc_sockaddr_to_uri(&addresses->addresses[i].address);
gpr_log(GPR_DEBUG, "Created subchannel %p for address uri %s",
(void *)subchannel, address_uri);
gpr_free(address_uri);
}
grpc_channel_args_destroy(exec_ctx, new_args);
if (subchannel != NULL) {

@ -39,6 +39,7 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
#include "src/core/ext/client_channel/resolver_registry.h"
#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/surface/api_trace.h"
@ -63,12 +64,17 @@ static grpc_channel *client_channel_factory_create_channel(
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
const char *target, grpc_client_channel_type type,
const grpc_channel_args *args) {
if (target == NULL) {
gpr_log(GPR_ERROR, "cannot create channel with NULL target name");
return NULL;
}
// Add channel arg containing the server URI.
grpc_arg arg;
arg.type = GRPC_ARG_STRING;
arg.key = GRPC_ARG_SERVER_URI;
arg.value.string = (char *)target;
arg.value.string = grpc_resolver_factory_add_default_prefix_if_needed(target);
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
gpr_free(arg.value.string);
grpc_channel *channel = grpc_channel_create(exec_ctx, target, new_args,
GRPC_CLIENT_CHANNEL, NULL);
grpc_channel_args_destroy(exec_ctx, new_args);

@ -39,10 +39,16 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
#include "src/core/ext/client_channel/resolver_registry.h"
#include "src/core/ext/client_channel/uri_parser.h"
#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
#include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/slice/slice_hash_table.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/channel.h"
@ -52,12 +58,114 @@ static void client_channel_factory_ref(
static void client_channel_factory_unref(
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {}
static grpc_subchannel_args *get_secure_naming_subchannel_args(
grpc_exec_ctx *exec_ctx, const grpc_subchannel_args *args) {
grpc_channel_credentials *channel_credentials =
grpc_channel_credentials_find_in_args(args->args);
if (channel_credentials == NULL) {
gpr_log(GPR_ERROR,
"Can't create subchannel: channel credentials missing for secure "
"channel.");
return NULL;
}
// Make sure security connector does not already exist in args.
if (grpc_security_connector_find_in_args(args->args) != NULL) {
gpr_log(GPR_ERROR,
"Can't create subchannel: security connector already present in "
"channel args.");
return NULL;
}
// To which address are we connecting? By default, use the server URI.
const grpc_arg *server_uri_arg =
grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
GPR_ASSERT(server_uri_arg != NULL);
GPR_ASSERT(server_uri_arg->type == GRPC_ARG_STRING);
const char *server_uri_str = server_uri_arg->value.string;
GPR_ASSERT(server_uri_str != NULL);
grpc_uri *server_uri =
grpc_uri_parse(server_uri_str, true /* supress errors */);
GPR_ASSERT(server_uri != NULL);
const char *server_uri_path;
server_uri_path =
server_uri->path[0] == '/' ? server_uri->path + 1 : server_uri->path;
const grpc_slice_hash_table *targets_info =
grpc_lb_targets_info_find_in_args(args->args);
char *target_name_to_check = NULL;
if (targets_info != NULL) { // LB channel
// Find the balancer name for the target.
const char *target_uri_str =
grpc_get_subchannel_address_uri_arg(args->args);
grpc_uri *target_uri =
grpc_uri_parse(target_uri_str, false /* suppress errors */);
GPR_ASSERT(target_uri != NULL);
if (target_uri->path[0] != '\0') { // "path" may be empty
const grpc_slice key = grpc_slice_from_static_string(
target_uri->path[0] == '/' ? target_uri->path + 1 : target_uri->path);
const char *value = grpc_slice_hash_table_get(targets_info, key);
if (value != NULL) target_name_to_check = gpr_strdup(value);
grpc_slice_unref_internal(exec_ctx, key);
}
if (target_name_to_check == NULL) {
// If the target name to check hasn't already been set, fall back to using
// SERVER_URI
target_name_to_check = gpr_strdup(server_uri_path);
}
grpc_uri_destroy(target_uri);
} else { // regular channel: the secure name is the original server URI.
target_name_to_check = gpr_strdup(server_uri_path);
}
grpc_uri_destroy(server_uri);
GPR_ASSERT(target_name_to_check != NULL);
grpc_channel_security_connector *subchannel_security_connector = NULL;
// Create the security connector using the credentials and target name.
grpc_channel_args *new_args_from_connector = NULL;
const grpc_security_status security_status =
grpc_channel_credentials_create_security_connector(
exec_ctx, channel_credentials, target_name_to_check, args->args,
&subchannel_security_connector, &new_args_from_connector);
if (security_status != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR,
"Failed to create secure subchannel for secure name '%s'",
target_name_to_check);
gpr_free(target_name_to_check);
return NULL;
}
gpr_free(target_name_to_check);
grpc_arg new_security_connector_arg =
grpc_security_connector_to_arg(&subchannel_security_connector->base);
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(
new_args_from_connector != NULL ? new_args_from_connector : args->args,
&new_security_connector_arg, 1);
GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &subchannel_security_connector->base,
"lb_channel_create");
if (new_args_from_connector != NULL) {
grpc_channel_args_destroy(exec_ctx, new_args_from_connector);
}
grpc_subchannel_args *final_sc_args = gpr_malloc(sizeof(*final_sc_args));
memcpy(final_sc_args, args, sizeof(*args));
final_sc_args->args = new_args;
return final_sc_args;
}
static grpc_subchannel *client_channel_factory_create_subchannel(
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
const grpc_subchannel_args *args) {
grpc_subchannel_args *subchannel_args =
get_secure_naming_subchannel_args(exec_ctx, args);
if (subchannel_args == NULL) {
gpr_log(
GPR_ERROR,
"Failed to create subchannel arguments during subchannel creation.");
return NULL;
}
grpc_connector *connector = grpc_chttp2_connector_create();
grpc_subchannel *s = grpc_subchannel_create(exec_ctx, connector, args);
grpc_subchannel *s =
grpc_subchannel_create(exec_ctx, connector, subchannel_args);
grpc_connector_unref(exec_ctx, connector);
grpc_channel_args_destroy(exec_ctx,
(grpc_channel_args *)subchannel_args->args);
gpr_free(subchannel_args);
return s;
}
@ -65,12 +173,17 @@ static grpc_channel *client_channel_factory_create_channel(
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
const char *target, grpc_client_channel_type type,
const grpc_channel_args *args) {
if (target == NULL) {
gpr_log(GPR_ERROR, "cannot create channel with NULL target name");
return NULL;
}
// Add channel arg containing the server URI.
grpc_arg arg;
arg.type = GRPC_ARG_STRING;
arg.key = GRPC_ARG_SERVER_URI;
arg.value.string = (char *)target;
arg.value.string = grpc_resolver_factory_add_default_prefix_if_needed(target);
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
gpr_free(arg.value.string);
grpc_channel *channel = grpc_channel_create(exec_ctx, target, new_args,
GRPC_CLIENT_CHANNEL, NULL);
grpc_channel_args_destroy(exec_ctx, new_args);
@ -85,10 +198,10 @@ static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
static grpc_client_channel_factory client_channel_factory = {
&client_channel_factory_vtable};
/* Create a secure client channel:
Asynchronously: - resolve target
- connect to it (trying alternatives as presented)
- perform handshakes */
// Create a secure client channel:
// Asynchronously: - resolve target
// - connect to it (trying alternatives as presented)
// - perform handshakes
grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
const char *target,
const grpc_channel_args *args,
@ -97,46 +210,27 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
GRPC_API_TRACE(
"grpc_secure_channel_create(creds=%p, target=%s, args=%p, "
"reserved=%p)",
4, (creds, target, args, reserved));
4, ((void *)creds, target, (void *)args, (void *)reserved));
GPR_ASSERT(reserved == NULL);
// Make sure security connector does not already exist in args.
if (grpc_find_security_connector_in_args(args) != NULL) {
gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
grpc_channel *channel = NULL;
if (creds != NULL) {
// Add channel args containing the client channel factory and channel
// credentials.
grpc_arg args_to_add[] = {
grpc_client_channel_factory_create_channel_arg(&client_channel_factory),
grpc_channel_credentials_to_arg(creds)};
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(
args, args_to_add, GPR_ARRAY_SIZE(args_to_add));
// Create channel.
channel = client_channel_factory_create_channel(
&exec_ctx, &client_channel_factory, target,
GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
// Clean up.
grpc_channel_args_destroy(&exec_ctx, new_args);
grpc_exec_ctx_finish(&exec_ctx);
return grpc_lame_client_channel_create(
target, GRPC_STATUS_INTERNAL,
"Security connector exists in channel args.");
}
// Create security connector and construct new channel args.
grpc_channel_security_connector *security_connector;
grpc_channel_args *new_args_from_connector;
if (grpc_channel_credentials_create_security_connector(
&exec_ctx, creds, target, args, &security_connector,
&new_args_from_connector) != GRPC_SECURITY_OK) {
grpc_exec_ctx_finish(&exec_ctx);
return grpc_lame_client_channel_create(
target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
}
// Add channel args containing the client channel factory and security
// connector.
grpc_arg args_to_add[2];
args_to_add[0] =
grpc_client_channel_factory_create_channel_arg(&client_channel_factory);
args_to_add[1] = grpc_security_connector_to_arg(&security_connector->base);
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(
new_args_from_connector != NULL ? new_args_from_connector : args,
args_to_add, GPR_ARRAY_SIZE(args_to_add));
if (new_args_from_connector != NULL) {
grpc_channel_args_destroy(&exec_ctx, new_args_from_connector);
}
// Create channel.
grpc_channel *channel = client_channel_factory_create_channel(
&exec_ctx, &client_channel_factory, target,
GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
// Clean up.
GRPC_SECURITY_CONNECTOR_UNREF(&exec_ctx, &security_connector->base,
"secure_client_channel_factory_create_channel");
grpc_channel_args_destroy(&exec_ctx, new_args);
grpc_exec_ctx_finish(&exec_ctx);
return channel; /* may be NULL */
return channel != NULL ? channel
: grpc_lame_client_channel_create(
target, GRPC_STATUS_INTERNAL,
"Failed to create secure client channel");
}

@ -124,6 +124,21 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_error *error);
static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *error);
static void finish_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *error);
static void cancel_pings(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_error *error);
static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_ping_type ping_type,
grpc_closure *on_initiate,
grpc_closure *on_complete);
#define DEFAULT_MIN_TIME_BETWEEN_PINGS_MS 0
#define DEFAULT_MAX_PINGS_BETWEEN_DATA 3
/*******************************************************************************
* CONSTRUCTION/DESTRUCTION/REFCOUNTING
*/
@ -153,18 +168,9 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
grpc_chttp2_stream_map_destroy(&t->stream_map);
grpc_connectivity_state_destroy(exec_ctx, &t->channel_callback.state_tracker);
grpc_combiner_destroy(exec_ctx, t->combiner);
GRPC_COMBINER_UNREF(exec_ctx, t->combiner, "chttp2_transport");
/* callback remaining pings: they're not allowed to call into the transpot,
and maybe they hold resources that need to be freed */
while (t->pings.next != &t->pings) {
grpc_chttp2_outstanding_ping *ping = t->pings.next;
grpc_closure_sched(exec_ctx, ping->on_recv,
GRPC_ERROR_CREATE("Transport closed"));
ping->next->prev = ping->prev;
ping->prev->next = ping->next;
gpr_free(ping);
}
cancel_pings(exec_ctx, t, GRPC_ERROR_CREATE("Transport destroyed"));
while (t->write_cb_pool) {
grpc_chttp2_write_cb *next = t->write_cb_pool->next;
@ -172,6 +178,7 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
t->write_cb_pool = next;
}
gpr_free(t->ping_acks);
gpr_free(t->peer_string);
gpr_free(t);
}
@ -224,10 +231,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->is_client = is_client;
t->outgoing_window = DEFAULT_WINDOW;
t->incoming_window = DEFAULT_WINDOW;
t->stream_lookahead = DEFAULT_WINDOW;
t->connection_window_target = DEFAULT_CONNECTION_WINDOW_TARGET;
t->ping_counter = 1;
t->pings.next = t->pings.prev = &t->pings;
t->deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
t->is_first_frame = true;
grpc_connectivity_state_init(
@ -248,6 +251,22 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_closure_init(&t->destructive_reclaimer_locked,
destructive_reclaimer_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->start_bdp_ping_locked, start_bdp_ping_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_closure_init(&t->finish_bdp_ping_locked, finish_bdp_ping_locked, t,
grpc_combiner_scheduler(t->combiner, false));
grpc_bdp_estimator_init(&t->bdp_estimator, t->peer_string);
t->last_pid_update = gpr_now(GPR_CLOCK_MONOTONIC);
grpc_pid_controller_init(
&t->pid_controller,
(grpc_pid_controller_args){.gain_p = 4,
.gain_i = 8,
.gain_d = 0,
.initial_control_value = log2(DEFAULT_WINDOW),
.min_control_value = -1,
.max_control_value = 22,
.integral_range = 10});
grpc_chttp2_goaway_parser_init(&t->goaway_parser);
grpc_chttp2_hpack_parser_init(exec_ctx, &t->hpack_parser);
@ -273,6 +292,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->force_send_settings = 1 << GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
t->sent_local_settings = 0;
t->write_buffer_size = DEFAULT_WINDOW;
t->enable_bdp_probe = true;
if (is_client) {
grpc_slice_buffer_add(&t->outbuf, grpc_slice_from_copied_string(
@ -290,6 +310,12 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
DEFAULT_MAX_HEADER_LIST_SIZE);
t->ping_policy = (grpc_chttp2_repeated_ping_policy){
.max_pings_without_data = DEFAULT_MAX_PINGS_BETWEEN_DATA,
.min_time_between_pings =
gpr_time_from_millis(DEFAULT_MIN_TIME_BETWEEN_PINGS_MS, GPR_TIMESPAN),
};
if (channel_args) {
for (i = 0; i < channel_args->num_args; i++) {
if (0 == strcmp(channel_args->args[i].key,
@ -306,14 +332,6 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->next_stream_id = (uint32_t)value;
}
}
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES)) {
const grpc_integer_options options = {-1, 5, INT_MAX};
const int value =
grpc_channel_arg_get_integer(&channel_args->args[i], options);
if (value >= 0) {
t->stream_lookahead = (uint32_t)value;
}
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER)) {
const grpc_integer_options options = {-1, 0, INT_MAX};
@ -323,35 +341,54 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_hpack_compressor_set_max_usable_size(&t->hpack_compressor,
(uint32_t)value);
}
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA)) {
t->ping_policy.max_pings_without_data = grpc_channel_arg_get_integer(
&channel_args->args[i],
(grpc_integer_options){DEFAULT_MAX_PINGS_BETWEEN_DATA, 0, INT_MAX});
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS)) {
t->ping_policy.min_time_between_pings = gpr_time_from_millis(
grpc_channel_arg_get_integer(
&channel_args->args[i],
(grpc_integer_options){DEFAULT_MIN_TIME_BETWEEN_PINGS_MS, 0,
INT_MAX}),
GPR_TIMESPAN);
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE)) {
t->write_buffer_size = (uint32_t)grpc_channel_arg_get_integer(
&channel_args->args[i],
(grpc_integer_options){0, 0, MAX_WRITE_BUFFER_SIZE});
} else if (0 ==
strcmp(channel_args->args[i].key, GRPC_ARG_HTTP2_BDP_PROBE)) {
t->enable_bdp_probe = grpc_channel_arg_get_integer(
&channel_args->args[i], (grpc_integer_options){1, 0, 1});
} else {
static const struct {
const char *channel_arg_name;
grpc_chttp2_setting_id setting_id;
grpc_integer_options integer_options;
bool availability[2] /* server, client */;
} settings_map[] = {
{GRPC_ARG_MAX_CONCURRENT_STREAMS,
GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
{-1, 0, INT_MAX},
{true, false}},
{GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER,
GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
{-1, 0, INT_MAX},
{true, true}},
{GRPC_ARG_MAX_METADATA_SIZE,
GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
{-1, 0, INT_MAX},
{true, true}},
{GRPC_ARG_HTTP2_MAX_FRAME_SIZE,
GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
{-1, 16384, 16777215},
{true, true}},
};
} settings_map[] = {{GRPC_ARG_MAX_CONCURRENT_STREAMS,
GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
{-1, 0, INT32_MAX},
{true, false}},
{GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER,
GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
{-1, 0, INT32_MAX},
{true, true}},
{GRPC_ARG_MAX_METADATA_SIZE,
GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
{-1, 0, INT32_MAX},
{true, true}},
{GRPC_ARG_HTTP2_MAX_FRAME_SIZE,
GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
{-1, 16384, 16777215},
{true, true}},
{GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES,
GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
{-1, 5, INT32_MAX},
{true, true}}};
for (j = 0; j < (int)GPR_ARRAY_SIZE(settings_map); j++) {
if (0 == strcmp(channel_args->args[i].key,
settings_map[j].channel_arg_name)) {
@ -374,6 +411,9 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
}
}
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
grpc_chttp2_initiate_write(exec_ctx, t, false, "init");
post_benign_reclaimer(exec_ctx, t);
}
@ -425,6 +465,7 @@ static void close_transport_locked(grpc_exec_ctx *exec_ctx,
GRPC_CHTTP2_STREAM_UNREF(exec_ctx, s, "chttp2_writing:close");
}
end_all_the_calls(exec_ctx, t, GRPC_ERROR_REF(error));
cancel_pings(exec_ctx, t, GRPC_ERROR_REF(error));
}
GRPC_ERROR_UNREF(error);
}
@ -475,11 +516,6 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
if (server_data) {
s->id = (uint32_t)(uintptr_t)server_data;
s->outgoing_window = t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
s->incoming_window = s->max_recv_bytes =
t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
*t->accepting_stream = s;
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
post_destructive_reclaimer(exec_ctx, t);
@ -508,6 +544,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
}
grpc_chttp2_list_remove_stalled_by_transport(t, s);
grpc_chttp2_list_remove_stalled_by_stream(t, s);
for (int i = 0; i < STREAM_LIST_COUNT; i++) {
if (s->included[i]) {
@ -647,13 +684,21 @@ void grpc_chttp2_initiate_write(grpc_exec_ctx *exec_ctx,
GPR_TIMER_END("grpc_chttp2_initiate_write", 0);
}
void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_stream *s, bool covered_by_poller,
const char *reason) {
void grpc_chttp2_become_writable(
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_chttp2_stream *s,
grpc_chttp2_stream_write_type stream_write_type, const char *reason) {
if (!t->closed && grpc_chttp2_list_add_writable_stream(t, s)) {
GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:become");
grpc_chttp2_initiate_write(exec_ctx, t, covered_by_poller, reason);
}
switch (stream_write_type) {
case GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK:
break;
case GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED:
grpc_chttp2_initiate_write(exec_ctx, t, true, reason);
break;
case GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED:
grpc_chttp2_initiate_write(exec_ctx, t, false, reason);
break;
}
}
@ -781,7 +826,6 @@ void grpc_chttp2_add_incoming_goaway(grpc_exec_ctx *exec_ctx,
static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t) {
grpc_chttp2_stream *s;
uint32_t stream_incoming_window;
/* start streams where we have free grpc_chttp2_stream ids and free
* concurrency */
while (t->next_stream_id <= MAX_CLIENT_STREAM_ID &&
@ -804,15 +848,11 @@ static void maybe_start_some_streams(grpc_exec_ctx *exec_ctx,
"no_more_stream_ids");
}
s->outgoing_window = t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
s->incoming_window = stream_incoming_window =
t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
s->max_recv_bytes = GPR_MAX(stream_incoming_window, s->max_recv_bytes);
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
post_destructive_reclaimer(exec_ctx, t);
grpc_chttp2_become_writable(exec_ctx, t, s, true, "new_stream");
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
"new_stream");
}
/* cancel out streams that will never be started */
while (t->next_stream_id >= MAX_CLIENT_STREAM_ID &&
@ -907,7 +947,9 @@ static void maybe_become_writable_due_to_send_msg(grpc_exec_ctx *exec_ctx,
grpc_chttp2_stream *s) {
if (s->id != 0 && (!s->write_buffering ||
s->flow_controlled_buffer.length > t->write_buffer_size)) {
grpc_chttp2_become_writable(exec_ctx, t, s, true, "op.send_message");
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
"op.send_message");
}
}
@ -1069,7 +1111,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
}
} else {
GPR_ASSERT(s->id != 0);
grpc_chttp2_become_writable(exec_ctx, t, s, true,
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
"op.send_initial_metadata");
}
} else {
@ -1160,7 +1203,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
} else if (s->id != 0) {
/* TODO(ctiller): check if there's flow control for any outstanding
bytes before going writable */
grpc_chttp2_become_writable(exec_ctx, t, s, true,
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
"op.send_trailing_metadata");
}
}
@ -1179,8 +1223,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
s->recv_message = op->recv_message;
if (s->id != 0 &&
(s->incoming_frames.head == NULL || s->incoming_frames.head->is_tail)) {
incoming_byte_stream_update_flow_control(exec_ctx, t, s,
t->stream_lookahead, 0);
incoming_byte_stream_update_flow_control(exec_ctx, t, s, 5, 0);
}
grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
}
@ -1224,43 +1267,46 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
GPR_TIMER_END("perform_stream_op", 0);
}
static void cancel_pings(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_error *error) {
/* callback remaining pings: they're not allowed to call into the transpot,
and maybe they hold resources that need to be freed */
for (size_t i = 0; i < GRPC_CHTTP2_PING_TYPE_COUNT; i++) {
grpc_chttp2_ping_queue *pq = &t->ping_queues[i];
for (size_t j = 0; j < GRPC_CHTTP2_PCL_COUNT; j++) {
grpc_closure_list_fail_all(&pq->lists[j], GRPC_ERROR_REF(error));
grpc_closure_list_sched(exec_ctx, &pq->lists[j]);
}
}
GRPC_ERROR_UNREF(error);
}
static void send_ping_locked(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_closure *on_recv) {
grpc_chttp2_outstanding_ping *p = gpr_malloc(sizeof(*p));
p->next = &t->pings;
p->prev = p->next->prev;
p->prev->next = p->next->prev = p;
p->id[0] = (uint8_t)((t->ping_counter >> 56) & 0xff);
p->id[1] = (uint8_t)((t->ping_counter >> 48) & 0xff);
p->id[2] = (uint8_t)((t->ping_counter >> 40) & 0xff);
p->id[3] = (uint8_t)((t->ping_counter >> 32) & 0xff);
p->id[4] = (uint8_t)((t->ping_counter >> 24) & 0xff);
p->id[5] = (uint8_t)((t->ping_counter >> 16) & 0xff);
p->id[6] = (uint8_t)((t->ping_counter >> 8) & 0xff);
p->id[7] = (uint8_t)(t->ping_counter & 0xff);
t->ping_counter++;
p->on_recv = on_recv;
grpc_slice_buffer_add(&t->qbuf, grpc_chttp2_ping_create(0, p->id));
grpc_chttp2_initiate_write(exec_ctx, t, true, "send_ping");
grpc_chttp2_ping_type ping_type,
grpc_closure *on_initiate, grpc_closure *on_ack) {
grpc_chttp2_ping_queue *pq = &t->ping_queues[ping_type];
grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_INITIATE], on_initiate,
GRPC_ERROR_NONE);
if (grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_NEXT], on_ack,
GRPC_ERROR_NONE)) {
grpc_chttp2_initiate_write(exec_ctx, t, false, "send_ping");
}
}
void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
const uint8_t *opaque_8bytes) {
grpc_chttp2_outstanding_ping *ping;
for (ping = t->pings.next; ping != &t->pings; ping = ping->next) {
if (0 == memcmp(opaque_8bytes, ping->id, 8)) {
grpc_closure_sched(exec_ctx, ping->on_recv, GRPC_ERROR_NONE);
ping->next->prev = ping->prev;
ping->prev->next = ping->next;
gpr_free(ping);
return;
}
uint64_t id) {
grpc_chttp2_ping_queue *pq =
&t->ping_queues[id % GRPC_CHTTP2_PING_TYPE_COUNT];
if (pq->inflight_id != id) {
char *from = grpc_endpoint_get_peer(t->ep);
gpr_log(GPR_DEBUG, "Unknown ping response from %s: %" PRIx64, from, id);
gpr_free(from);
return;
}
grpc_closure_list_sched(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]);
if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_NEXT])) {
grpc_chttp2_initiate_write(exec_ctx, t, false, "continue_pings");
}
char *msg = gpr_dump((const char *)opaque_8bytes, 8, GPR_DUMP_HEX);
char *from = grpc_endpoint_get_peer(t->ep);
gpr_log(GPR_DEBUG, "Unknown ping response from %s: %s", from, msg);
gpr_free(from);
gpr_free(msg);
}
static void send_goaway(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
@ -1308,7 +1354,8 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
}
if (op->send_ping) {
send_ping_locked(exec_ctx, t, op->send_ping);
send_ping_locked(exec_ctx, t, GRPC_CHTTP2_PING_ON_NEXT_WRITE, NULL,
op->send_ping);
}
if (close_transport != GRPC_ERROR_NONE) {
@ -1733,34 +1780,28 @@ static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
GRPC_ERROR_UNREF(error);
}
/** update window from a settings change */
typedef struct {
grpc_chttp2_transport *t;
grpc_exec_ctx *exec_ctx;
} update_global_window_args;
/*******************************************************************************
* INPUT PROCESSING - PARSING
*/
static void update_global_window(void *args, uint32_t id, void *stream) {
update_global_window_args *a = args;
grpc_chttp2_transport *t = a->t;
grpc_chttp2_stream *s = stream;
int was_zero;
int is_zero;
int64_t initial_window_update = t->initial_window_update;
if (initial_window_update > 0) {
was_zero = s->outgoing_window <= 0;
GRPC_CHTTP2_FLOW_CREDIT_STREAM("settings", t, s, outgoing_window,
initial_window_update);
is_zero = s->outgoing_window <= 0;
if (was_zero && !is_zero) {
grpc_chttp2_become_writable(a->exec_ctx, t, s, true,
"update_global_window");
}
static void update_bdp(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
double bdp_dbl) {
uint32_t bdp;
if (bdp_dbl <= 0) {
bdp = 0;
} else if (bdp_dbl > UINT32_MAX) {
bdp = UINT32_MAX;
} else {
GRPC_CHTTP2_FLOW_DEBIT_STREAM("settings", t, s, outgoing_window,
-initial_window_update);
bdp = (uint32_t)(bdp_dbl);
}
int64_t delta =
(int64_t)bdp -
(int64_t)t->settings[GRPC_LOCAL_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
if (delta == 0 || (bdp != 0 && delta > -1024 && delta < 1024)) {
return;
}
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, bdp);
}
/*******************************************************************************
@ -1802,6 +1843,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
GPR_TIMER_BEGIN("reading_action_locked", 0);
grpc_chttp2_transport *t = tp;
bool need_bdp_ping = false;
GRPC_ERROR_REF(error);
@ -1819,9 +1861,14 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE,
GRPC_ERROR_NONE};
for (; i < t->read_buffer.count && errors[1] == GRPC_ERROR_NONE; i++) {
if (grpc_bdp_estimator_add_incoming_bytes(
&t->bdp_estimator,
(int64_t)GRPC_SLICE_LENGTH(t->read_buffer.slices[i]))) {
need_bdp_ping = true;
}
errors[1] =
grpc_chttp2_perform_read(exec_ctx, t, t->read_buffer.slices[i]);
};
}
if (errors[1] != GRPC_ERROR_NONE) {
errors[2] = try_http_parsing(exec_ctx, t);
GRPC_ERROR_UNREF(error);
@ -1835,21 +1882,16 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
GPR_TIMER_BEGIN("post_parse_locked", 0);
if (t->initial_window_update != 0) {
update_global_window_args args = {t, exec_ctx};
grpc_chttp2_stream_map_for_each(&t->stream_map, update_global_window,
&args);
if (t->initial_window_update > 0) {
grpc_chttp2_stream *s;
while (grpc_chttp2_list_pop_stalled_by_stream(t, &s)) {
grpc_chttp2_become_writable(
exec_ctx, t, s, GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED,
"unstalled");
}
}
t->initial_window_update = 0;
}
/* handle higher level things */
if (t->incoming_window < t->connection_window_target * 3 / 4) {
int64_t announce_bytes = t->connection_window_target - t->incoming_window;
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", t, announce_incoming_window,
announce_bytes);
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parsed", t, incoming_window,
announce_bytes);
grpc_chttp2_initiate_write(exec_ctx, t, false, "global incoming window");
}
GPR_TIMER_END("post_parse_locked", 0);
}
@ -1870,6 +1912,38 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
if (keep_reading) {
grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer,
&t->read_action_locked);
if (t->enable_bdp_probe) {
if (need_bdp_ping) {
GRPC_CHTTP2_REF_TRANSPORT(t, "bdp_ping");
grpc_bdp_estimator_schedule_ping(&t->bdp_estimator);
send_ping_locked(exec_ctx, t,
GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE,
&t->start_bdp_ping_locked, &t->finish_bdp_ping_locked);
}
int64_t estimate = -1;
if (grpc_bdp_estimator_get_estimate(&t->bdp_estimator, &estimate)) {
double target = 1 + log2((double)estimate);
double memory_pressure = grpc_resource_quota_get_memory_pressure(
grpc_resource_user_quota(grpc_endpoint_get_resource_user(t->ep)));
if (memory_pressure > 0.8) {
target *= 1 - GPR_MIN(1, (memory_pressure - 0.8) / 0.1);
}
double bdp_error =
target - grpc_pid_controller_last(&t->pid_controller);
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_timespec dt_timespec = gpr_time_sub(now, t->last_pid_update);
double dt = (double)dt_timespec.tv_sec + dt_timespec.tv_nsec * 1e-9;
if (dt > 0.1) {
dt = 0.1;
}
double log2_bdp_guess =
grpc_pid_controller_update(&t->pid_controller, bdp_error, dt);
update_bdp(exec_ctx, t, pow(2, log2_bdp_guess));
t->last_pid_update = now;
}
}
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "keep_reading");
} else {
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "reading_action");
@ -1882,6 +1956,26 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
GPR_TIMER_END("reading_action_locked", 0);
}
static void start_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *error) {
grpc_chttp2_transport *t = tp;
if (grpc_http_trace) {
gpr_log(GPR_DEBUG, "%s: Start BDP ping", t->peer_string);
}
grpc_bdp_estimator_start_ping(&t->bdp_estimator);
}
static void finish_bdp_ping_locked(grpc_exec_ctx *exec_ctx, void *tp,
grpc_error *error) {
grpc_chttp2_transport *t = tp;
if (grpc_http_trace) {
gpr_log(GPR_DEBUG, "%s: Complete BDP ping", t->peer_string);
}
grpc_bdp_estimator_complete_ping(&t->bdp_estimator);
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "bdp_ping");
}
/*******************************************************************************
* CALLBACK LOOP
*/
@ -1932,10 +2026,12 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
size_t max_size_hint,
size_t have_already) {
uint32_t max_recv_bytes;
uint32_t initial_window_size =
t->settings[GRPC_SENT_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
/* clamp max recv hint to an allowable size */
if (max_size_hint >= UINT32_MAX - t->stream_lookahead) {
max_recv_bytes = UINT32_MAX - t->stream_lookahead;
if (max_size_hint >= UINT32_MAX - initial_window_size) {
max_recv_bytes = UINT32_MAX - initial_window_size;
} else {
max_recv_bytes = (uint32_t)max_size_hint;
}
@ -1948,20 +2044,26 @@ static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
}
/* add some small lookahead to keep pipelines flowing */
GPR_ASSERT(max_recv_bytes <= UINT32_MAX - t->stream_lookahead);
max_recv_bytes += t->stream_lookahead;
if (s->max_recv_bytes < max_recv_bytes) {
uint32_t add_max_recv_bytes = max_recv_bytes - s->max_recv_bytes;
bool new_window_write_is_covered_by_poller =
s->max_recv_bytes < have_already;
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, max_recv_bytes,
add_max_recv_bytes);
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, incoming_window,
GPR_ASSERT(max_recv_bytes <= UINT32_MAX - initial_window_size);
if (s->incoming_window_delta < max_recv_bytes && !s->read_closed) {
uint32_t add_max_recv_bytes =
(uint32_t)(max_recv_bytes - s->incoming_window_delta);
grpc_chttp2_stream_write_type write_type =
GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED;
if (s->incoming_window_delta + initial_window_size <
(int64_t)have_already) {
write_type = GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED;
}
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, incoming_window_delta,
add_max_recv_bytes);
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, announce_window,
add_max_recv_bytes);
grpc_chttp2_become_writable(exec_ctx, t, s,
new_window_write_is_covered_by_poller,
if ((int64_t)s->incoming_window_delta + (int64_t)initial_window_size -
(int64_t)s->announce_window >
(int64_t)initial_window_size / 2) {
write_type = GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK;
}
grpc_chttp2_become_writable(exec_ctx, t, s, write_type,
"read_incoming_stream");
}
}

@ -40,7 +40,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint8_t *opaque_8bytes) {
grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint64_t opaque_8bytes) {
grpc_slice slice = grpc_slice_malloc(9 + 8);
uint8_t *p = GRPC_SLICE_START_PTR(slice);
@ -53,7 +53,14 @@ grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint8_t *opaque_8bytes) {
*p++ = 0;
*p++ = 0;
*p++ = 0;
memcpy(p, opaque_8bytes, 8);
*p++ = (uint8_t)(opaque_8bytes >> 56);
*p++ = (uint8_t)(opaque_8bytes >> 48);
*p++ = (uint8_t)(opaque_8bytes >> 40);
*p++ = (uint8_t)(opaque_8bytes >> 32);
*p++ = (uint8_t)(opaque_8bytes >> 24);
*p++ = (uint8_t)(opaque_8bytes >> 16);
*p++ = (uint8_t)(opaque_8bytes >> 8);
*p++ = (uint8_t)(opaque_8bytes);
return slice;
}
@ -70,6 +77,7 @@ grpc_error *grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser *parser,
}
parser->byte = 0;
parser->is_ack = flags;
parser->opaque_8bytes = 0;
return GRPC_ERROR_NONE;
}
@ -83,7 +91,7 @@ grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
grpc_chttp2_ping_parser *p = parser;
while (p->byte != 8 && cur != end) {
p->opaque_8bytes[p->byte] = *cur;
p->opaque_8bytes |= (((uint64_t)*cur) << (8 * p->byte));
cur++;
p->byte++;
}
@ -93,8 +101,12 @@ grpc_error *grpc_chttp2_ping_parser_parse(grpc_exec_ctx *exec_ctx, void *parser,
if (p->is_ack) {
grpc_chttp2_ack_ping(exec_ctx, t, p->opaque_8bytes);
} else {
grpc_slice_buffer_add(&t->qbuf,
grpc_chttp2_ping_create(1, p->opaque_8bytes));
if (t->ping_ack_count == t->ping_ack_capacity) {
t->ping_ack_capacity = GPR_MAX(t->ping_ack_capacity * 3 / 2, 3);
t->ping_acks = gpr_realloc(
t->ping_acks, t->ping_ack_capacity * sizeof(*t->ping_acks));
}
t->ping_acks[t->ping_ack_count++] = p->opaque_8bytes;
grpc_chttp2_initiate_write(exec_ctx, t, false, "ping response");
}
}

@ -41,10 +41,10 @@
typedef struct {
uint8_t byte;
uint8_t is_ack;
uint8_t opaque_8bytes[8];
uint64_t opaque_8bytes;
} grpc_chttp2_ping_parser;
grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint8_t *opaque_8bytes);
grpc_slice grpc_chttp2_ping_create(uint8_t ack, uint64_t opaque_8bytes);
grpc_error *grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser *parser,
uint32_t length, uint8_t flags);

@ -109,8 +109,13 @@ grpc_error *grpc_chttp2_rst_stream_parser_parse(grpc_exec_ctx *exec_ctx,
(((uint32_t)p->reason_bytes[3]));
grpc_error *error = GRPC_ERROR_NONE;
if (reason != GRPC_HTTP2_NO_ERROR || s->header_frames_received < 2) {
error = grpc_error_set_int(GRPC_ERROR_CREATE("RST_STREAM"),
GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)reason);
char *message;
gpr_asprintf(&message, "Received RST_STREAM with error code %d", reason);
error = grpc_error_set_int(
grpc_error_set_str(GRPC_ERROR_CREATE("RST_STREAM"),
GRPC_ERROR_STR_GRPC_MESSAGE, message),
GRPC_ERROR_INT_HTTP2_ERROR, (intptr_t)reason);
gpr_free(message);
}
grpc_chttp2_mark_stream_closed(exec_ctx, t, s, true, true, error);
}

@ -236,7 +236,7 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p,
}
if (parser->id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE &&
parser->incoming_settings[parser->id] != parser->value) {
t->initial_window_update =
t->initial_window_update +=
(int64_t)parser->value - parser->incoming_settings[parser->id];
if (grpc_http_trace) {
gpr_log(GPR_DEBUG, "adding %d for initial_window change",
@ -245,8 +245,9 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p,
}
parser->incoming_settings[parser->id] = parser->value;
if (grpc_http_trace) {
gpr_log(GPR_DEBUG, "CHTTP2:%s: got setting %d = %d",
t->is_client ? "CLI" : "SVR", parser->id, parser->value);
gpr_log(GPR_DEBUG, "CHTTP2:%s:%s: got setting %d = %d",
t->is_client ? "CLI" : "SVR", t->peer_string, parser->id,
parser->value);
}
} else if (grpc_http_trace) {
gpr_log(GPR_ERROR, "CHTTP2: Ignoring unknown setting %d (value %d)",

@ -110,13 +110,12 @@ grpc_error *grpc_chttp2_window_update_parser_parse(
if (t->incoming_stream_id != 0) {
if (s != NULL) {
bool was_zero = s->outgoing_window <= 0;
GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", t, s, outgoing_window,
GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", t, s, outgoing_window_delta,
received_update);
bool is_zero = s->outgoing_window <= 0;
if (was_zero && !is_zero) {
grpc_chttp2_become_writable(exec_ctx, t, s, false,
"stream.read_flow_control");
if (grpc_chttp2_list_remove_stalled_by_stream(t, s)) {
grpc_chttp2_become_writable(
exec_ctx, t, s, GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED,
"stream.read_flow_control");
}
}
} else {

@ -50,7 +50,9 @@
#include "src/core/ext/transport/chttp2/transport/stream_map.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/transport/bdp_estimator.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/pid_controller.h"
#include "src/core/lib/transport/transport_impl.h"
/* streams are kept in various linked lists depending on what things need to
@ -59,6 +61,7 @@ typedef enum {
GRPC_CHTTP2_LIST_WRITABLE,
GRPC_CHTTP2_LIST_WRITING,
GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT,
GRPC_CHTTP2_LIST_STALLED_BY_STREAM,
/** streams that are waiting to start because there are too many concurrent
streams on the connection */
GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY,
@ -72,6 +75,34 @@ typedef enum {
GRPC_CHTTP2_WRITE_STATE_WRITING_WITH_MORE_AND_COVERED_BY_POLLER,
} grpc_chttp2_write_state;
typedef enum {
GRPC_CHTTP2_PING_ON_NEXT_WRITE = 0,
GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE,
GRPC_CHTTP2_PING_TYPE_COUNT /* must be last */
} grpc_chttp2_ping_type;
typedef enum {
GRPC_CHTTP2_PCL_INITIATE = 0,
GRPC_CHTTP2_PCL_NEXT,
GRPC_CHTTP2_PCL_INFLIGHT,
GRPC_CHTTP2_PCL_COUNT /* must be last */
} grpc_chttp2_ping_closure_list;
typedef struct {
grpc_closure_list lists[GRPC_CHTTP2_PCL_COUNT];
uint64_t inflight_id;
} grpc_chttp2_ping_queue;
typedef struct {
gpr_timespec min_time_between_pings;
int max_pings_without_data;
} grpc_chttp2_repeated_ping_policy;
typedef struct {
gpr_timespec last_ping_sent_time;
int pings_before_data_required;
} grpc_chttp2_repeated_ping_state;
/* deframer state for the overall http2 stream of bytes */
typedef enum {
/* prefix: one entry per http2 connection prefix byte */
@ -144,14 +175,6 @@ typedef enum {
GRPC_CHTTP2_GOAWAY_SENT,
} grpc_chttp2_sent_goaway_state;
/* Outstanding ping request data */
typedef struct grpc_chttp2_outstanding_ping {
uint8_t id[8];
grpc_closure *on_recv;
struct grpc_chttp2_outstanding_ping *next;
struct grpc_chttp2_outstanding_ping *prev;
} grpc_chttp2_outstanding_ping;
typedef struct grpc_chttp2_write_cb {
int64_t call_at_byte;
grpc_closure *closure;
@ -204,6 +227,9 @@ struct grpc_chttp2_transport {
/** is there a read request to the endpoint outstanding? */
uint8_t endpoint_reading;
/** should we probe bdp? */
bool enable_bdp_probe;
/** various lists of streams */
grpc_chttp2_stream_list lists[STREAM_LIST_COUNT];
@ -271,16 +297,19 @@ struct grpc_chttp2_transport {
copied to next_stream_id in parsing when parsing commences */
uint32_t next_stream_id;
/** how far to lookahead in a stream? */
uint32_t stream_lookahead;
/** last new stream id */
uint32_t last_new_stream_id;
/** pings awaiting responses */
grpc_chttp2_outstanding_ping pings;
/** next payload for an outgoing ping */
uint64_t ping_counter;
/** ping queues for various ping insertion points */
grpc_chttp2_ping_queue ping_queues[GRPC_CHTTP2_PING_TYPE_COUNT];
grpc_chttp2_repeated_ping_policy ping_policy;
grpc_chttp2_repeated_ping_state ping_state;
uint64_t ping_ctr; /* unique id for pings */
/** ping acks */
size_t ping_ack_count;
size_t ping_ack_capacity;
uint64_t *ping_acks;
/** parser for headers */
grpc_chttp2_hpack_parser hpack_parser;
@ -324,6 +353,13 @@ struct grpc_chttp2_transport {
grpc_chttp2_write_cb *write_cb_pool;
/* bdp estimator */
grpc_bdp_estimator bdp_estimator;
grpc_pid_controller pid_controller;
grpc_closure start_bdp_ping_locked;
grpc_closure finish_bdp_ping_locked;
gpr_timespec last_pid_update;
/* if non-NULL, close the transport with this error when writes are finished
*/
grpc_error *close_transport_on_writes_finished;
@ -362,12 +398,10 @@ struct grpc_chttp2_stream {
/** HTTP2 stream id for this stream, or zero if one has not been assigned */
uint32_t id;
/** window available for us to send to peer */
int64_t outgoing_window;
/** The number of bytes the upper layers have offered to receive.
As the upper layer offers more bytes, this value increases.
As bytes are read, this value decreases. */
uint32_t max_recv_bytes;
/** window available for us to send to peer, over or under the initial window
* size of the transport... ie:
* outgoing_window = outgoing_window_delta + transport.initial_window_size */
int64_t outgoing_window_delta;
/** things the upper layers would like to send */
grpc_metadata_batch *send_initial_metadata;
grpc_closure *send_initial_metadata_finished;
@ -428,8 +462,10 @@ struct grpc_chttp2_stream {
grpc_error *forced_close_error;
/** how many header frames have we received? */
uint8_t header_frames_received;
/** window available for peer to send to us */
int64_t incoming_window;
/** window available for peer to send to us (as a delta on
* transport.initial_window_size)
* incoming_window = incoming_window_delta + transport.initial_window_size */
int64_t incoming_window_delta;
/** parsing state for data frames */
grpc_chttp2_data_parser data_parser;
/** number of bytes received - reset at end of parse thread execution */
@ -478,36 +514,43 @@ bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
/** Get a writable stream
returns non-zero if there was a stream available */
int grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_remove_writable_stream(
grpc_chttp2_transport *t, grpc_chttp2_stream *s) GRPC_MUST_USE_RESULT;
bool grpc_chttp2_list_add_writing_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
int grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t);
int grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t);
bool grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
void grpc_chttp2_list_add_written_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
int grpc_chttp2_list_pop_written_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_pop_written_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
void grpc_chttp2_list_add_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
int grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
void grpc_chttp2_list_remove_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
int grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
void grpc_chttp2_list_add_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
bool grpc_chttp2_list_pop_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s);
bool grpc_chttp2_list_remove_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
grpc_chttp2_stream *grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport *t,
uint32_t id);
grpc_chttp2_stream *grpc_chttp2_parsing_accept_stream(grpc_exec_ctx *exec_ctx,
@ -672,13 +715,23 @@ void grpc_chttp2_incoming_byte_stream_finished(
grpc_error *error);
void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
const uint8_t *opaque_8bytes);
uint64_t id);
typedef enum {
/* don't initiate a transport write, but piggyback on the next one */
GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK,
/* initiate a covered write */
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
/* initiate an uncovered write */
GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED
} grpc_chttp2_stream_write_type;
/** add a ref to the stream and add it to the writable list;
ref will be dropped in writing.c */
void grpc_chttp2_become_writable(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_stream *s, bool covered_by_poller,
grpc_chttp2_stream *s,
grpc_chttp2_stream_write_type type,
const char *reason);
void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx,

@ -376,25 +376,45 @@ static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx,
return err;
}
uint32_t target_incoming_window = GPR_MAX(
t->settings[GRPC_SENT_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
1024);
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", t, incoming_window,
incoming_frame_size);
if (t->incoming_window <= target_incoming_window / 2) {
grpc_chttp2_initiate_write(exec_ctx, t, false, "flow_control");
}
if (s != NULL) {
if (incoming_frame_size > s->incoming_window) {
if (incoming_frame_size >
s->incoming_window_delta +
t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) {
char *msg;
gpr_asprintf(&msg,
"frame of size %d overflows incoming window of %" PRId64,
t->incoming_frame_size, s->incoming_window);
t->incoming_frame_size,
s->incoming_window_delta +
t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
grpc_error *err = GRPC_ERROR_CREATE(msg);
gpr_free(msg);
return err;
}
GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", t, s, incoming_window,
GRPC_CHTTP2_FLOW_DEBIT_STREAM("parse", t, s, incoming_window_delta,
incoming_frame_size);
if ((int64_t)t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] +
(int64_t)s->incoming_window_delta - (int64_t)s->announce_window <=
(int64_t)t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] /
2) {
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED,
"window-update-required");
}
s->received_bytes += incoming_frame_size;
s->max_recv_bytes -=
(uint32_t)GPR_MIN(s->max_recv_bytes, incoming_frame_size);
}
return GRPC_ERROR_NONE;

@ -37,14 +37,14 @@
/* core list management */
static int stream_list_empty(grpc_chttp2_transport *t,
grpc_chttp2_stream_list_id id) {
static bool stream_list_empty(grpc_chttp2_transport *t,
grpc_chttp2_stream_list_id id) {
return t->lists[id].head == NULL;
}
static int stream_list_pop(grpc_chttp2_transport *t,
grpc_chttp2_stream **stream,
grpc_chttp2_stream_list_id id) {
static bool stream_list_pop(grpc_chttp2_transport *t,
grpc_chttp2_stream **stream,
grpc_chttp2_stream_list_id id) {
grpc_chttp2_stream *s = t->lists[id].head;
if (s) {
grpc_chttp2_stream *new_head = s->links[id].next;
@ -124,8 +124,8 @@ bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport *t,
return stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITABLE);
}
int grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
bool grpc_chttp2_list_pop_writable_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WRITABLE);
}
@ -139,12 +139,12 @@ bool grpc_chttp2_list_add_writing_stream(grpc_chttp2_transport *t,
return stream_list_add(t, s, GRPC_CHTTP2_LIST_WRITING);
}
int grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t) {
bool grpc_chttp2_list_have_writing_streams(grpc_chttp2_transport *t) {
return !stream_list_empty(t, GRPC_CHTTP2_LIST_WRITING);
}
int grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
bool grpc_chttp2_list_pop_writing_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WRITING);
}
@ -153,8 +153,8 @@ void grpc_chttp2_list_add_waiting_for_concurrency(grpc_chttp2_transport *t,
stream_list_add(t, s, GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY);
}
int grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
bool grpc_chttp2_list_pop_waiting_for_concurrency(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY);
}
@ -168,8 +168,8 @@ void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t,
stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
}
int grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
bool grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
}
@ -177,3 +177,18 @@ void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) {
stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
}
void grpc_chttp2_list_add_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) {
stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
}
bool grpc_chttp2_list_pop_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
}
bool grpc_chttp2_list_remove_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) {
return stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
}

@ -56,6 +56,75 @@ static void finish_write_cb(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->write_cb_pool = cb;
}
static void collapse_pings_from_into(grpc_chttp2_transport *t,
grpc_chttp2_ping_type ping_type,
grpc_chttp2_ping_queue *pq) {
for (size_t i = 0; i < GRPC_CHTTP2_PCL_COUNT; i++) {
grpc_closure_list_move(&t->ping_queues[ping_type].lists[i], &pq->lists[i]);
}
}
static void maybe_initiate_ping(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_ping_type ping_type) {
grpc_chttp2_ping_queue *pq = &t->ping_queues[ping_type];
if (grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_NEXT])) {
/* no ping needed: wait */
return;
}
if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_INFLIGHT])) {
/* ping already in-flight: wait */
if (grpc_http_trace || grpc_bdp_estimator_trace) {
gpr_log(GPR_DEBUG, "Ping delayed [%p]: already pinging", t->peer_string);
}
return;
}
if (t->ping_state.pings_before_data_required == 0 &&
t->ping_policy.max_pings_without_data != 0) {
/* need to send something of substance before sending a ping again */
if (grpc_http_trace || grpc_bdp_estimator_trace) {
gpr_log(GPR_DEBUG, "Ping delayed [%p]: too many recent pings: %d/%d",
t->peer_string, t->ping_state.pings_before_data_required,
t->ping_policy.max_pings_without_data);
}
return;
}
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_timespec elapsed = gpr_time_sub(now, t->ping_state.last_ping_sent_time);
/*gpr_log(GPR_DEBUG, "elapsed:%d.%09d min:%d.%09d", (int)elapsed.tv_sec,
elapsed.tv_nsec, (int)t->ping_policy.min_time_between_pings.tv_sec,
(int)t->ping_policy.min_time_between_pings.tv_nsec);*/
if (gpr_time_cmp(elapsed, t->ping_policy.min_time_between_pings) < 0) {
/* not enough elapsed time between successive pings */
if (grpc_http_trace || grpc_bdp_estimator_trace) {
gpr_log(GPR_DEBUG,
"Ping delayed [%p]: not enough time elapsed since last ping",
t->peer_string);
}
return;
}
/* coalesce equivalent pings into this one */
switch (ping_type) {
case GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE:
collapse_pings_from_into(t, GRPC_CHTTP2_PING_ON_NEXT_WRITE, pq);
break;
case GRPC_CHTTP2_PING_ON_NEXT_WRITE:
break;
case GRPC_CHTTP2_PING_TYPE_COUNT:
GPR_UNREACHABLE_CODE(break);
}
pq->inflight_id = t->ping_ctr * GRPC_CHTTP2_PING_TYPE_COUNT + ping_type;
t->ping_ctr++;
grpc_closure_list_sched(exec_ctx, &pq->lists[GRPC_CHTTP2_PCL_INITIATE]);
grpc_closure_list_move(&pq->lists[GRPC_CHTTP2_PCL_NEXT],
&pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]);
grpc_slice_buffer_add(&t->outbuf,
grpc_chttp2_ping_create(false, pq->inflight_id));
t->ping_state.last_ping_sent_time = now;
t->ping_state.pings_before_data_required -=
(t->ping_state.pings_before_data_required != 0);
}
static void update_list(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_stream *s, int64_t send_bytes,
grpc_chttp2_write_cb **list, grpc_error *error) {
@ -139,6 +208,8 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
s->sent_initial_metadata = true;
sent_initial_metadata = true;
now_writing = true;
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
}
/* send any window updates */
if (s->announce_window > 0) {
@ -146,15 +217,22 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
grpc_slice_buffer_add(&t->outbuf,
grpc_chttp2_window_update_create(
s->id, s->announce_window, &s->stats.outgoing));
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, announce_window, announce);
}
if (sent_initial_metadata) {
/* send any body bytes, if allowed by flow control */
if (s->flow_controlled_buffer.length > 0) {
uint32_t max_outgoing =
(uint32_t)GPR_MIN(t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
GPR_MIN(s->outgoing_window, t->outgoing_window));
uint32_t stream_outgoing_window = (uint32_t)GPR_MAX(
0,
s->outgoing_window_delta +
(int64_t)t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
uint32_t max_outgoing = (uint32_t)GPR_MIN(
t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
GPR_MIN(stream_outgoing_window, t->outgoing_window));
if (max_outgoing > 0) {
uint32_t send_bytes =
(uint32_t)GPR_MIN(max_outgoing, s->flow_controlled_buffer.length);
@ -167,10 +245,12 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, send_bytes,
is_last_frame, &s->stats.outgoing,
&t->outbuf);
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window,
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window_delta,
send_bytes);
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, outgoing_window,
send_bytes);
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
if (is_last_frame) {
s->send_trailing_metadata = NULL;
s->sent_trailing_metadata = true;
@ -189,6 +269,9 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
} else if (t->outgoing_window == 0) {
grpc_chttp2_list_add_stalled_by_transport(t, s);
now_writing = true;
} else if (stream_outgoing_window == 0) {
grpc_chttp2_list_add_stalled_by_stream(t, s);
now_writing = true;
}
}
if (s->send_trailing_metadata != NULL &&
@ -227,15 +310,32 @@ bool grpc_chttp2_begin_write(grpc_exec_ctx *exec_ctx,
/* if the grpc_chttp2_transport is ready to send a window update, do so here
also; 3/4 is a magic number that will likely get tuned soon */
if (t->announce_incoming_window > 0) {
uint32_t announced =
(uint32_t)GPR_MIN(t->announce_incoming_window, UINT32_MAX);
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, announce_incoming_window,
announced);
uint32_t target_incoming_window = GPR_MAX(
t->settings[GRPC_SENT_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
1024);
uint32_t threshold_to_send_transport_window_update =
t->outbuf.count > 0 ? 3 * target_incoming_window / 4
: target_incoming_window / 2;
if (t->incoming_window <= threshold_to_send_transport_window_update) {
maybe_initiate_ping(exec_ctx, t,
GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE);
uint32_t announced = (uint32_t)GPR_CLAMP(
target_incoming_window - t->incoming_window, 0, UINT32_MAX);
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("write", t, incoming_window, announced);
grpc_transport_one_way_stats throwaway_stats;
grpc_slice_buffer_add(&t->outbuf, grpc_chttp2_window_update_create(
0, announced, &throwaway_stats));
t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data;
}
for (size_t i = 0; i < t->ping_ack_count; i++) {
grpc_slice_buffer_add(&t->outbuf,
grpc_chttp2_ping_create(1, t->ping_acks[i]));
}
t->ping_ack_count = 0;
maybe_initiate_ping(exec_ctx, t, GRPC_CHTTP2_PING_ON_NEXT_WRITE);
GPR_TIMER_END("grpc_chttp2_begin_write", 0);

@ -38,7 +38,7 @@ library, so we can build it in all environments */
#include <grpc/support/log.h>
#include "third_party/Cronet/bidirectional_stream_c.h"
#include "third_party/objective_c/Cronet/bidirectional_stream_c.h"
#ifdef GRPC_COMPILE_WITH_CRONET
/* link with the real CRONET library in the build system */

@ -51,7 +51,7 @@
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/transport_impl.h"
#include "third_party/Cronet/bidirectional_stream_c.h"
#include "third_party/objective_c/Cronet/bidirectional_stream_c.h"
#define GRPC_HEADER_SIZE_IN_BYTES 5

@ -140,7 +140,7 @@ static void con_get_channel_info(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
const grpc_channel_info *channel_info) {}
static const grpc_channel_filter connected_channel_filter = {
const grpc_channel_filter grpc_connected_filter = {
con_start_transport_stream_op,
con_start_transport_op,
sizeof(call_data),
@ -158,7 +158,7 @@ static const grpc_channel_filter connected_channel_filter = {
static void bind_transport(grpc_channel_stack *channel_stack,
grpc_channel_element *elem, void *t) {
channel_data *cd = (channel_data *)elem->channel_data;
GPR_ASSERT(elem->filter == &connected_channel_filter);
GPR_ASSERT(elem->filter == &grpc_connected_filter);
GPR_ASSERT(cd->transport == NULL);
cd->transport = t;
@ -178,7 +178,7 @@ bool grpc_add_connected_filter(grpc_exec_ctx *exec_ctx,
grpc_transport *t = grpc_channel_stack_builder_get_transport(builder);
GPR_ASSERT(t != NULL);
return grpc_channel_stack_builder_append_filter(
builder, &connected_channel_filter, bind_transport, t);
builder, &grpc_connected_filter, bind_transport, t);
}
grpc_stream *grpc_connected_channel_get_stream(grpc_call_element *elem) {

@ -36,8 +36,13 @@
#include "src/core/lib/channel/channel_stack_builder.h"
extern const grpc_channel_filter grpc_connected_filter;
bool grpc_add_connected_filter(grpc_exec_ctx *exec_ctx,
grpc_channel_stack_builder *builder,
void *arg_must_be_null);
/* Debug helper to dig the transport stream out of a call element */
grpc_stream *grpc_connected_channel_get_stream(grpc_call_element *elem);
#endif /* GRPC_CORE_LIB_CHANNEL_CONNECTED_CHANNEL_H */

@ -51,20 +51,22 @@ void grpc_closure_list_init(grpc_closure_list *closure_list) {
closure_list->head = closure_list->tail = NULL;
}
void grpc_closure_list_append(grpc_closure_list *closure_list,
bool grpc_closure_list_append(grpc_closure_list *closure_list,
grpc_closure *closure, grpc_error *error) {
if (closure == NULL) {
GRPC_ERROR_UNREF(error);
return;
return false;
}
closure->error_data.error = error;
closure->next_data.next = NULL;
if (closure_list->head == NULL) {
bool was_empty = (closure_list->head == NULL);
if (was_empty) {
closure_list->head = closure;
} else {
closure_list->tail->next_data.next = closure;
}
closure_list->tail = closure;
return was_empty;
}
void grpc_closure_list_fail_all(grpc_closure_list *list,

@ -116,8 +116,9 @@ grpc_closure *grpc_closure_create(grpc_iomgr_cb_func cb, void *cb_arg,
void grpc_closure_list_init(grpc_closure_list *list);
/** add \a closure to the end of \a list
and set \a closure's result to \a error */
void grpc_closure_list_append(grpc_closure_list *list, grpc_closure *closure,
and set \a closure's result to \a error
Returns true if \a list becomes non-empty */
bool grpc_closure_list_append(grpc_closure_list *list, grpc_closure *closure,
grpc_error *error);
/** force all success bits in \a list to false */

@ -72,6 +72,7 @@ struct grpc_combiner {
bool final_list_covered_by_poller;
grpc_closure_list final_list;
grpc_closure offload;
gpr_refcount refs;
};
static void combiner_exec_uncovered(grpc_exec_ctx *exec_ctx,
@ -126,6 +127,7 @@ static bool is_covered_by_poller(grpc_combiner *lock) {
grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue) {
grpc_combiner *lock = gpr_malloc(sizeof(*lock));
gpr_ref_init(&lock->refs, 1);
lock->next_combiner_on_this_exec_ctx = NULL;
lock->time_to_execute_final_list = false;
lock->optional_workqueue = optional_workqueue;
@ -152,7 +154,7 @@ static void really_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
gpr_free(lock);
}
void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
static void start_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
gpr_atm old_state = gpr_atm_full_fetch_add(&lock->state, -STATE_UNORPHANED);
GRPC_COMBINER_TRACE(gpr_log(
GPR_DEBUG, "C:%p really_destroy old_state=%" PRIdPTR, lock, old_state));
@ -161,6 +163,30 @@ void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
}
}
#ifdef GRPC_COMBINER_REFCOUNT_DEBUG
#define GRPC_COMBINER_DEBUG_SPAM(op, delta) \
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, \
"combiner[%p] %s %" PRIdPTR " --> %" PRIdPTR " %s", lock, (op), \
gpr_atm_no_barrier_load(&lock->refs.count), \
gpr_atm_no_barrier_load(&lock->refs.count) + (delta), reason);
#else
#define GRPC_COMBINER_DEBUG_SPAM(op, delta)
#endif
void grpc_combiner_unref(grpc_exec_ctx *exec_ctx,
grpc_combiner *lock GRPC_COMBINER_DEBUG_ARGS) {
GRPC_COMBINER_DEBUG_SPAM("UNREF", -1);
if (gpr_unref(&lock->refs)) {
start_destroy(exec_ctx, lock);
}
}
grpc_combiner *grpc_combiner_ref(grpc_combiner *lock GRPC_COMBINER_DEBUG_ARGS) {
GRPC_COMBINER_DEBUG_SPAM(" REF", 1);
gpr_ref(&lock->refs);
return lock;
}
static void push_last_on_exec_ctx(grpc_exec_ctx *exec_ctx,
grpc_combiner *lock) {
lock->next_combiner_on_this_exec_ctx = NULL;

@ -48,8 +48,27 @@
// Initialize the lock, with an optional workqueue to shift load to when
// necessary
grpc_combiner *grpc_combiner_create(grpc_workqueue *optional_workqueue);
// Destroy the lock
void grpc_combiner_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock);
//#define GRPC_COMBINER_REFCOUNT_DEBUG
#ifdef GRPC_COMBINER_REFCOUNT_DEBUG
#define GRPC_COMBINER_DEBUG_ARGS \
, const char *file, int line, const char *reason
#define GRPC_COMBINER_REF(combiner, reason) \
grpc_combiner_ref((combiner), __FILE__, __LINE__, (reason))
#define GRPC_COMBINER_UNREF(exec_ctx, combiner, reason) \
grpc_combiner_unref((exec_ctx), (combiner), __FILE__, __LINE__, (reason))
#else
#define GRPC_COMBINER_DEBUG_ARGS
#define GRPC_COMBINER_REF(combiner, reason) grpc_combiner_ref((combiner))
#define GRPC_COMBINER_UNREF(exec_ctx, combiner, reason) \
grpc_combiner_unref((exec_ctx), (combiner))
#endif
// Ref/unref the lock, for when we're sharing the lock ownership
// Prefer to use the macros above
grpc_combiner *grpc_combiner_ref(grpc_combiner *lock GRPC_COMBINER_DEBUG_ARGS);
void grpc_combiner_unref(grpc_exec_ctx *exec_ctx,
grpc_combiner *lock GRPC_COMBINER_DEBUG_ARGS);
// Fetch a scheduler to schedule closures against
grpc_closure_scheduler *grpc_combiner_scheduler(grpc_combiner *lock,
bool covered_by_poller);

@ -33,6 +33,8 @@
#include "src/core/lib/iomgr/resource_quota.h"
#include <limits.h>
#include <stdint.h>
#include <string.h>
#include <grpc/support/alloc.h>
@ -44,6 +46,8 @@
int grpc_resource_quota_trace = 0;
#define MEMORY_USAGE_ESTIMATION_MAX 65536
/* Internal linked list pointers for a resource user */
typedef struct {
grpc_resource_user *next;
@ -126,9 +130,12 @@ struct grpc_resource_quota {
/* refcount */
gpr_refcount refs;
/* estimate of current memory usage
scaled to the range [0..RESOURCE_USAGE_ESTIMATION_MAX] */
gpr_atm memory_usage_estimation;
/* Master combiner lock: all activity on a quota executes under this combiner
* (so no mutex is needed for this data structure)
*/
* (so no mutex is needed for this data structure) */
grpc_combiner *combiner;
/* Size of the resource quota */
int64_t size;
@ -269,6 +276,16 @@ static void rq_step_sched(grpc_exec_ctx *exec_ctx,
GRPC_ERROR_NONE);
}
/* update the atomically available resource estimate - use no barriers since
timeliness of delivery really doesn't matter much */
static void rq_update_estimate(grpc_resource_quota *resource_quota) {
gpr_atm_no_barrier_store(&resource_quota->memory_usage_estimation,
(gpr_atm)((1.0 -
((double)resource_quota->free_pool) /
((double)resource_quota->size)) *
MEMORY_USAGE_ESTIMATION_MAX));
}
/* returns true if all allocations are completed */
static bool rq_alloc(grpc_exec_ctx *exec_ctx,
grpc_resource_quota *resource_quota) {
@ -281,6 +298,7 @@ static bool rq_alloc(grpc_exec_ctx *exec_ctx,
int64_t amt = -resource_user->free_pool;
resource_user->free_pool = 0;
resource_quota->free_pool -= amt;
rq_update_estimate(resource_quota);
if (grpc_resource_quota_trace) {
gpr_log(GPR_DEBUG, "RQ %s %s: grant alloc %" PRId64
" bytes; rq_free_pool -> %" PRId64,
@ -315,6 +333,7 @@ static bool rq_reclaim_from_per_user_free_pool(
int64_t amt = resource_user->free_pool;
resource_user->free_pool = 0;
resource_quota->free_pool += amt;
rq_update_estimate(resource_quota);
if (grpc_resource_quota_trace) {
gpr_log(GPR_DEBUG, "RQ %s %s: reclaim_from_per_user_free_pool %" PRId64
" bytes; rq_free_pool -> %" PRId64,
@ -531,6 +550,7 @@ static void rq_resize(grpc_exec_ctx *exec_ctx, void *args, grpc_error *error) {
int64_t delta = a->size - a->resource_quota->size;
a->resource_quota->size += delta;
a->resource_quota->free_pool += delta;
rq_update_estimate(a->resource_quota);
rq_step_sched(exec_ctx, a->resource_quota);
grpc_resource_quota_unref_internal(exec_ctx, a->resource_quota);
gpr_free(a);
@ -557,6 +577,7 @@ grpc_resource_quota *grpc_resource_quota_create(const char *name) {
resource_quota->size = INT64_MAX;
resource_quota->step_scheduled = false;
resource_quota->reclaiming = false;
gpr_atm_no_barrier_store(&resource_quota->memory_usage_estimation, 0);
if (name != NULL) {
resource_quota->name = gpr_strdup(name);
} else {
@ -578,7 +599,7 @@ grpc_resource_quota *grpc_resource_quota_create(const char *name) {
void grpc_resource_quota_unref_internal(grpc_exec_ctx *exec_ctx,
grpc_resource_quota *resource_quota) {
if (gpr_unref(&resource_quota->refs)) {
grpc_combiner_destroy(exec_ctx, resource_quota->combiner);
GRPC_COMBINER_UNREF(exec_ctx, resource_quota->combiner, "resource_quota");
gpr_free(resource_quota->name);
gpr_free(resource_quota);
}
@ -602,6 +623,13 @@ void grpc_resource_quota_ref(grpc_resource_quota *resource_quota) {
grpc_resource_quota_ref_internal(resource_quota);
}
double grpc_resource_quota_get_memory_pressure(
grpc_resource_quota *resource_quota) {
return ((double)(gpr_atm_no_barrier_load(
&resource_quota->memory_usage_estimation))) /
((double)MEMORY_USAGE_ESTIMATION_MAX);
}
/* Public API */
void grpc_resource_quota_resize(grpc_resource_quota *resource_quota,
size_t size) {

@ -84,6 +84,12 @@ void grpc_resource_quota_unref_internal(grpc_exec_ctx *exec_ctx,
grpc_resource_quota *grpc_resource_quota_from_channel_args(
const grpc_channel_args *channel_args);
/* Return a number indicating current memory pressure:
0.0 ==> no memory usage
1.0 ==> maximum memory usage */
double grpc_resource_quota_get_memory_pressure(
grpc_resource_quota *resource_quota);
typedef struct grpc_resource_user grpc_resource_user;
grpc_resource_user *grpc_resource_user_create(

@ -190,31 +190,37 @@ int grpc_sockaddr_to_string(char **out,
}
char *grpc_sockaddr_to_uri(const grpc_resolved_address *resolved_addr) {
char *temp;
char *result;
grpc_resolved_address addr_normalized;
const struct sockaddr *addr;
if (grpc_sockaddr_is_v4mapped(resolved_addr, &addr_normalized)) {
resolved_addr = &addr_normalized;
}
const char *scheme = grpc_sockaddr_get_uri_scheme(resolved_addr);
if (scheme == NULL || strcmp("unix", scheme) == 0) {
return grpc_sockaddr_to_uri_unix_if_possible(resolved_addr);
}
char *path = NULL;
char *uri_str = NULL;
if (grpc_sockaddr_to_string(&path, resolved_addr,
false /* suppress errors */) &&
scheme != NULL) {
gpr_asprintf(&uri_str, "%s:%s", scheme, path);
}
gpr_free(path);
return uri_str != NULL ? uri_str : NULL;
}
addr = (const struct sockaddr *)resolved_addr->addr;
const char *grpc_sockaddr_get_uri_scheme(
const grpc_resolved_address *resolved_addr) {
const struct sockaddr *addr = (const struct sockaddr *)resolved_addr->addr;
switch (addr->sa_family) {
case AF_INET:
grpc_sockaddr_to_string(&temp, resolved_addr, 0);
gpr_asprintf(&result, "ipv4:%s", temp);
gpr_free(temp);
return result;
return "ipv4";
case AF_INET6:
grpc_sockaddr_to_string(&temp, resolved_addr, 0);
gpr_asprintf(&result, "ipv6:%s", temp);
gpr_free(temp);
return result;
default:
return grpc_sockaddr_to_uri_unix_if_possible(resolved_addr);
return "ipv6";
case AF_UNIX:
return "unix";
}
return NULL;
}
int grpc_sockaddr_get_port(const grpc_resolved_address *resolved_addr) {

@ -84,6 +84,10 @@ int grpc_sockaddr_set_port(const grpc_resolved_address *addr, int port);
int grpc_sockaddr_to_string(char **out, const grpc_resolved_address *addr,
int normalize);
/* Returns the URI string corresponding to \a addr */
char *grpc_sockaddr_to_uri(const grpc_resolved_address *addr);
/* Returns the URI scheme corresponding to \a addr */
const char *grpc_sockaddr_get_uri_scheme(const grpc_resolved_address *addr);
#endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_UTILS_H */

@ -135,12 +135,10 @@ static void on_connect(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) {
/* Tries to issue one async connection, then schedules both an IOCP
notification request for the connection, and one timeout alert. */
void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
grpc_endpoint **endpoint,
grpc_pollset_set *interested_parties,
const grpc_channel_args *channel_args,
const grpc_resolved_address *addr,
gpr_timespec deadline) {
static void tcp_client_connect_impl(
grpc_exec_ctx *exec_ctx, grpc_closure *on_done, grpc_endpoint **endpoint,
grpc_pollset_set *interested_parties, const grpc_channel_args *channel_args,
const grpc_resolved_address *addr, gpr_timespec deadline) {
SOCKET sock = INVALID_SOCKET;
BOOL success;
int status;
@ -252,4 +250,21 @@ failure:
grpc_closure_sched(exec_ctx, on_done, final_error);
}
// overridden by api_fuzzer.c
void (*grpc_tcp_client_connect_impl)(
grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_endpoint **ep,
grpc_pollset_set *interested_parties, const grpc_channel_args *channel_args,
const grpc_resolved_address *addr,
gpr_timespec deadline) = tcp_client_connect_impl;
void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
grpc_endpoint **ep,
grpc_pollset_set *interested_parties,
const grpc_channel_args *channel_args,
const grpc_resolved_address *addr,
gpr_timespec deadline) {
grpc_tcp_client_connect_impl(exec_ctx, closure, ep, interested_parties,
channel_args, addr, deadline);
}
#endif /* GRPC_WINSOCK_SOCKET */

@ -44,6 +44,7 @@
#include <errno.h>
#include <fcntl.h>
#include <ifaddrs.h>
#include <limits.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
@ -115,6 +116,8 @@ struct grpc_tcp_server {
bool shutdown;
/* use SO_REUSEPORT */
bool so_reuseport;
/* expand wildcard addresses to a list of all local addresses */
bool expand_wildcard_addrs;
/* linked list of server ports */
grpc_tcp_listener *head;
@ -161,6 +164,7 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
s->so_reuseport = has_so_reuseport;
s->resource_quota = grpc_resource_quota_create(NULL);
s->expand_wildcard_addrs = false;
for (size_t i = 0; i < (args == NULL ? 0 : args->num_args); i++) {
if (0 == strcmp(GRPC_ARG_ALLOW_REUSEPORT, args->args[i].key)) {
if (args->args[i].type == GRPC_ARG_INTEGER) {
@ -183,6 +187,15 @@ grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
" must be a pointer to a buffer pool");
}
} else if (0 == strcmp(GRPC_ARG_EXPAND_WILDCARD_ADDRS, args->args[i].key)) {
if (args->args[i].type == GRPC_ARG_INTEGER) {
s->expand_wildcard_addrs = (args->args[i].value.integer != 0);
} else {
grpc_resource_quota_unref_internal(exec_ctx, s->resource_quota);
gpr_free(s);
return GRPC_ERROR_CREATE(GRPC_ARG_EXPAND_WILDCARD_ADDRS
" must be an integer");
}
}
}
gpr_ref_init(&s->refs, 1);
@ -504,9 +517,224 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd,
return err;
}
/* Insert count new listeners after listener. Every new listener will have the
same listen address as listener (SO_REUSEPORT must be enabled). Every new
listener is a sibling of listener. */
/* If successful, add a listener to s for addr, set *dsmode for the socket, and
return the *listener. */
static grpc_error *add_addr_to_server(grpc_tcp_server *s,
const grpc_resolved_address *addr,
unsigned port_index, unsigned fd_index,
grpc_dualstack_mode *dsmode,
grpc_tcp_listener **listener) {
grpc_resolved_address addr4_copy;
int fd;
grpc_error *err =
grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, dsmode, &fd);
if (err != GRPC_ERROR_NONE) {
return err;
}
if (*dsmode == GRPC_DSMODE_IPV4 &&
grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
addr = &addr4_copy;
}
return add_socket_to_server(s, fd, addr, port_index, fd_index, listener);
}
/* Bind to "::" to get a port number not used by any address. */
static grpc_error *get_unused_port(int *port) {
grpc_resolved_address wild;
grpc_sockaddr_make_wildcard6(0, &wild);
grpc_dualstack_mode dsmode;
int fd;
grpc_error *err =
grpc_create_dualstack_socket(&wild, SOCK_STREAM, 0, &dsmode, &fd);
if (err != GRPC_ERROR_NONE) {
return err;
}
if (dsmode == GRPC_DSMODE_IPV4) {
grpc_sockaddr_make_wildcard4(0, &wild);
}
if (bind(fd, (const struct sockaddr *)wild.addr, (socklen_t)wild.len) != 0) {
err = GRPC_OS_ERROR(errno, "bind");
close(fd);
return err;
}
if (getsockname(fd, (struct sockaddr *)wild.addr, (socklen_t *)&wild.len) !=
0) {
err = GRPC_OS_ERROR(errno, "getsockname");
close(fd);
return err;
}
close(fd);
*port = grpc_sockaddr_get_port(&wild);
return *port <= 0 ? GRPC_ERROR_CREATE("Bad port") : GRPC_ERROR_NONE;
}
/* Return the listener in s with address addr or NULL. */
static grpc_tcp_listener *find_listener_with_addr(grpc_tcp_server *s,
grpc_resolved_address *addr) {
grpc_tcp_listener *l;
gpr_mu_lock(&s->mu);
for (l = s->head; l != NULL; l = l->next) {
if (l->addr.len != addr->len) {
continue;
}
if (memcmp(l->addr.addr, addr->addr, addr->len) == 0) {
break;
}
}
gpr_mu_unlock(&s->mu);
return l;
}
/* Get all addresses assigned to network interfaces on the machine and create a
listener for each. requested_port is the port to use for every listener, or 0
to select one random port that will be used for every listener. Set *out_port
to the port selected. Return GRPC_ERROR_NONE only if all listeners were
added. */
static grpc_error *add_all_local_addrs_to_server(grpc_tcp_server *s,
unsigned port_index,
int requested_port,
int *out_port) {
struct ifaddrs *ifa = NULL;
struct ifaddrs *ifa_it;
unsigned fd_index = 0;
grpc_tcp_listener *sp = NULL;
grpc_error *err = GRPC_ERROR_NONE;
if (requested_port == 0) {
/* Note: There could be a race where some local addrs can listen on the
selected port and some can't. The sane way to handle this would be to
retry by recreating the whole grpc_tcp_server. Backing out individual
listeners and orphaning the FDs looks like too much trouble. */
if ((err = get_unused_port(&requested_port)) != GRPC_ERROR_NONE) {
return err;
} else if (requested_port <= 0) {
return GRPC_ERROR_CREATE("Bad get_unused_port()");
}
gpr_log(GPR_DEBUG, "Picked unused port %d", requested_port);
}
if (getifaddrs(&ifa) != 0 || ifa == NULL) {
return GRPC_OS_ERROR(errno, "getifaddrs");
}
for (ifa_it = ifa; ifa_it != NULL; ifa_it = ifa_it->ifa_next) {
grpc_resolved_address addr;
char *addr_str = NULL;
grpc_dualstack_mode dsmode;
grpc_tcp_listener *new_sp = NULL;
const char *ifa_name = (ifa_it->ifa_name ? ifa_it->ifa_name : "<unknown>");
if (ifa_it->ifa_addr == NULL) {
continue;
} else if (ifa_it->ifa_addr->sa_family == AF_INET) {
addr.len = sizeof(struct sockaddr_in);
} else if (ifa_it->ifa_addr->sa_family == AF_INET6) {
addr.len = sizeof(struct sockaddr_in6);
} else {
continue;
}
memcpy(addr.addr, ifa_it->ifa_addr, addr.len);
if (!grpc_sockaddr_set_port(&addr, requested_port)) {
/* Should never happen, because we check sa_family above. */
err = GRPC_ERROR_CREATE("Failed to set port");
break;
}
if (grpc_sockaddr_to_string(&addr_str, &addr, 0) < 0) {
addr_str = gpr_strdup("<error>");
}
gpr_log(GPR_DEBUG,
"Adding local addr from interface %s flags 0x%x to server: %s",
ifa_name, ifa_it->ifa_flags, addr_str);
/* We could have multiple interfaces with the same address (e.g., bonding),
so look for duplicates. */
if (find_listener_with_addr(s, &addr) != NULL) {
gpr_log(GPR_DEBUG, "Skipping duplicate addr %s on interface %s", addr_str,
ifa_name);
gpr_free(addr_str);
continue;
}
if ((err = add_addr_to_server(s, &addr, port_index, fd_index, &dsmode,
&new_sp)) != GRPC_ERROR_NONE) {
char *err_str = NULL;
grpc_error *root_err;
if (gpr_asprintf(&err_str, "Failed to add listener: %s", addr_str) < 0) {
err_str = gpr_strdup("Failed to add listener");
}
root_err = GRPC_ERROR_CREATE(err_str);
gpr_free(err_str);
gpr_free(addr_str);
err = grpc_error_add_child(root_err, err);
break;
} else {
GPR_ASSERT(requested_port == new_sp->port);
++fd_index;
if (sp != NULL) {
new_sp->is_sibling = 1;
sp->sibling = new_sp;
}
sp = new_sp;
}
gpr_free(addr_str);
}
freeifaddrs(ifa);
if (err != GRPC_ERROR_NONE) {
return err;
} else if (sp == NULL) {
return GRPC_ERROR_CREATE("No local addresses");
} else {
*out_port = sp->port;
return GRPC_ERROR_NONE;
}
}
/* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
static grpc_error *add_wildcard_addrs_to_server(grpc_tcp_server *s,
unsigned port_index,
int requested_port,
int *out_port) {
grpc_resolved_address wild4;
grpc_resolved_address wild6;
unsigned fd_index = 0;
grpc_dualstack_mode dsmode;
grpc_tcp_listener *sp = NULL;
grpc_tcp_listener *sp2 = NULL;
grpc_error *v6_err = GRPC_ERROR_NONE;
grpc_error *v4_err = GRPC_ERROR_NONE;
*out_port = -1;
if (s->expand_wildcard_addrs) {
return add_all_local_addrs_to_server(s, port_index, requested_port,
out_port);
}
grpc_sockaddr_make_wildcards(requested_port, &wild4, &wild6);
/* Try listening on IPv6 first. */
if ((v6_err = add_addr_to_server(s, &wild6, port_index, fd_index, &dsmode,
&sp)) == GRPC_ERROR_NONE) {
++fd_index;
requested_port = *out_port = sp->port;
if (dsmode == GRPC_DSMODE_DUALSTACK || dsmode == GRPC_DSMODE_IPV4) {
return GRPC_ERROR_NONE;
}
}
/* If we got a v6-only socket or nothing, try adding 0.0.0.0. */
grpc_sockaddr_set_port(&wild4, requested_port);
if ((v4_err = add_addr_to_server(s, &wild4, port_index, fd_index, &dsmode,
&sp2)) == GRPC_ERROR_NONE) {
*out_port = sp2->port;
if (sp != NULL) {
sp2->is_sibling = 1;
sp->sibling = sp2;
}
}
if (*out_port > 0) {
GRPC_LOG_IF_ERROR("Failed to add :: listener", v6_err);
GRPC_LOG_IF_ERROR("Failed to add 0.0.0.0 listener", v4_err);
return GRPC_ERROR_NONE;
} else {
grpc_error *root_err =
GRPC_ERROR_CREATE("Failed to add any wildcard listeners");
GPR_ASSERT(v6_err != GRPC_ERROR_NONE && v4_err != GRPC_ERROR_NONE);
root_err = grpc_error_add_child(root_err, v6_err);
root_err = grpc_error_add_child(root_err, v4_err);
return root_err;
}
}
static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) {
grpc_tcp_listener *sp = NULL;
char *addr_str;
@ -559,19 +787,13 @@ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s,
const grpc_resolved_address *addr,
int *out_port) {
grpc_tcp_listener *sp;
grpc_tcp_listener *sp2 = NULL;
int fd;
grpc_dualstack_mode dsmode;
grpc_resolved_address addr6_v4mapped;
grpc_resolved_address wild4;
grpc_resolved_address wild6;
grpc_resolved_address addr4_copy;
grpc_resolved_address *allocated_addr = NULL;
grpc_resolved_address sockname_temp;
int port;
grpc_resolved_address addr6_v4mapped;
int requested_port = grpc_sockaddr_get_port(addr);
unsigned port_index = 0;
unsigned fd_index = 0;
grpc_error *errs[2] = {GRPC_ERROR_NONE, GRPC_ERROR_NONE};
grpc_dualstack_mode dsmode;
grpc_error *err;
*out_port = -1;
if (s->tail != NULL) {
port_index = s->tail->port_index + 1;
}
@ -579,85 +801,34 @@ grpc_error *grpc_tcp_server_add_port(grpc_tcp_server *s,
/* Check if this is a wildcard port, and if so, try to keep the port the same
as some previously created listener. */
if (grpc_sockaddr_get_port(addr) == 0) {
if (requested_port == 0) {
for (sp = s->head; sp; sp = sp->next) {
sockname_temp.len = sizeof(struct sockaddr_storage);
if (0 == getsockname(sp->fd, (struct sockaddr *)sockname_temp.addr,
if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp.addr,
(socklen_t *)&sockname_temp.len)) {
port = grpc_sockaddr_get_port(&sockname_temp);
if (port > 0) {
allocated_addr = gpr_malloc(sizeof(grpc_resolved_address));
memcpy(allocated_addr, addr, addr->len);
grpc_sockaddr_set_port(allocated_addr, port);
addr = allocated_addr;
int used_port = grpc_sockaddr_get_port(&sockname_temp);
if (used_port > 0) {
memcpy(&sockname_temp, addr, sizeof(grpc_resolved_address));
grpc_sockaddr_set_port(&sockname_temp, used_port);
requested_port = used_port;
addr = &sockname_temp;
break;
}
}
}
}
sp = NULL;
if (grpc_sockaddr_is_wildcard(addr, &requested_port)) {
return add_wildcard_addrs_to_server(s, port_index, requested_port,
out_port);
}
if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
addr = &addr6_v4mapped;
}
/* Treat :: or 0.0.0.0 as a family-agnostic wildcard. */
if (grpc_sockaddr_is_wildcard(addr, &port)) {
grpc_sockaddr_make_wildcards(port, &wild4, &wild6);
/* Try listening on IPv6 first. */
addr = &wild6;
errs[0] = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
if (errs[0] == GRPC_ERROR_NONE) {
errs[0] = add_socket_to_server(s, fd, addr, port_index, fd_index, &sp);
if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
goto done;
}
if (sp != NULL) {
++fd_index;
}
/* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
if (port == 0 && sp != NULL) {
grpc_sockaddr_set_port(&wild4, sp->port);
}
}
addr = &wild4;
}
errs[1] = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode, &fd);
if (errs[1] == GRPC_ERROR_NONE) {
if (dsmode == GRPC_DSMODE_IPV4 &&
grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
addr = &addr4_copy;
}
sp2 = sp;
errs[1] = add_socket_to_server(s, fd, addr, port_index, fd_index, &sp);
if (sp2 != NULL && sp != NULL) {
sp2->sibling = sp;
sp->is_sibling = 1;
}
}
done:
gpr_free(allocated_addr);
if (sp != NULL) {
if ((err = add_addr_to_server(s, addr, port_index, 0, &dsmode, &sp)) ==
GRPC_ERROR_NONE) {
*out_port = sp->port;
GRPC_ERROR_UNREF(errs[0]);
GRPC_ERROR_UNREF(errs[1]);
return GRPC_ERROR_NONE;
} else {
*out_port = -1;
char *addr_str = grpc_sockaddr_to_uri(addr);
grpc_error *err = grpc_error_set_str(
GRPC_ERROR_CREATE_REFERENCING("Failed to add port to server", errs,
GPR_ARRAY_SIZE(errs)),
GRPC_ERROR_STR_TARGET_ADDRESS, addr_str);
GRPC_ERROR_UNREF(errs[0]);
GRPC_ERROR_UNREF(errs[1]);
gpr_free(addr_str);
return err;
}
return err;
}
/* Return listener at port_index or NULL. Should only be called with s->mu

@ -76,8 +76,10 @@ struct grpc_udp_listener {
grpc_udp_server *server;
grpc_resolved_address addr;
grpc_closure read_closure;
grpc_closure write_closure;
grpc_closure destroyed_closure;
grpc_udp_server_read_cb read_cb;
grpc_udp_server_write_cb write_cb;
grpc_udp_server_orphan_cb orphan_cb;
struct grpc_udp_listener *next;
@ -176,7 +178,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
/* Call the orphan_cb to signal that the FD is about to be closed and
* should no longer be used. */
GPR_ASSERT(sp->orphan_cb);
sp->orphan_cb(sp->emfd);
sp->orphan_cb(exec_ctx, sp->emfd);
grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
"udp_listener_shutdown");
@ -202,7 +204,7 @@ void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
if (s->active_ports) {
for (sp = s->head; sp; sp = sp->next) {
GPR_ASSERT(sp->orphan_cb);
sp->orphan_cb(sp->emfd);
sp->orphan_cb(exec_ctx, sp->emfd);
grpc_fd_shutdown(exec_ctx, sp->emfd,
GRPC_ERROR_CREATE("Server destroyed"));
}
@ -304,9 +306,33 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
gpr_mu_unlock(&sp->server->mu);
}
static void on_write(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
grpc_udp_listener *sp = arg;
gpr_mu_lock(&(sp->server->mu));
if (error != GRPC_ERROR_NONE) {
if (0 == --sp->server->active_ports) {
gpr_mu_unlock(&sp->server->mu);
deactivated_all_ports(exec_ctx, sp->server);
} else {
gpr_mu_unlock(&sp->server->mu);
}
return;
}
/* Tell the registered callback that the socket is writeable. */
GPR_ASSERT(sp->write_cb);
sp->write_cb(exec_ctx, sp->emfd);
/* Re-arm the notification event so we get another chance to write. */
grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
gpr_mu_unlock(&sp->server->mu);
}
static int add_socket_to_server(grpc_udp_server *s, int fd,
const grpc_resolved_address *addr,
grpc_udp_server_read_cb read_cb,
grpc_udp_server_write_cb write_cb,
grpc_udp_server_orphan_cb orphan_cb) {
grpc_udp_listener *sp;
int port;
@ -333,6 +359,7 @@ static int add_socket_to_server(grpc_udp_server *s, int fd,
sp->emfd = grpc_fd_create(fd, name);
memcpy(&sp->addr, addr, sizeof(grpc_resolved_address));
sp->read_cb = read_cb;
sp->write_cb = write_cb;
sp->orphan_cb = orphan_cb;
GPR_ASSERT(sp->emfd);
gpr_mu_unlock(&s->mu);
@ -345,6 +372,7 @@ static int add_socket_to_server(grpc_udp_server *s, int fd,
int grpc_udp_server_add_port(grpc_udp_server *s,
const grpc_resolved_address *addr,
grpc_udp_server_read_cb read_cb,
grpc_udp_server_write_cb write_cb,
grpc_udp_server_orphan_cb orphan_cb) {
grpc_udp_listener *sp;
int allocated_port1 = -1;
@ -391,7 +419,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s,
// TODO(rjshade): Test and propagate the returned grpc_error*:
GRPC_ERROR_UNREF(grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP,
&dsmode, &fd));
allocated_port1 = add_socket_to_server(s, fd, addr, read_cb, orphan_cb);
allocated_port1 =
add_socket_to_server(s, fd, addr, read_cb, write_cb, orphan_cb);
if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
goto done;
}
@ -413,7 +442,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s,
grpc_sockaddr_is_v4mapped(addr, &addr4_copy)) {
addr = &addr4_copy;
}
allocated_port2 = add_socket_to_server(s, fd, addr, read_cb, orphan_cb);
allocated_port2 =
add_socket_to_server(s, fd, addr, read_cb, write_cb, orphan_cb);
done:
gpr_free(allocated_addr);
@ -451,6 +481,10 @@ void grpc_udp_server_start(grpc_exec_ctx *exec_ctx, grpc_udp_server *s,
grpc_schedule_on_exec_ctx);
grpc_fd_notify_on_read(exec_ctx, sp->emfd, &sp->read_closure);
grpc_closure_init(&sp->write_closure, on_write, sp,
grpc_schedule_on_exec_ctx);
grpc_fd_notify_on_write(exec_ctx, sp->emfd, &sp->write_closure);
s->active_ports++;
sp = sp->next;
}

@ -49,8 +49,13 @@ typedef struct grpc_udp_server grpc_udp_server;
typedef void (*grpc_udp_server_read_cb)(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
struct grpc_server *server);
/* Called when the socket is writeable. */
typedef void (*grpc_udp_server_write_cb)(grpc_exec_ctx *exec_ctx,
grpc_fd *emfd);
/* Called when the grpc_fd is about to be orphaned (and the FD closed). */
typedef void (*grpc_udp_server_orphan_cb)(grpc_fd *emfd);
typedef void (*grpc_udp_server_orphan_cb)(grpc_exec_ctx *exec_ctx,
grpc_fd *emfd);
/* Create a server, initially not bound to any ports */
grpc_udp_server *grpc_udp_server_create(void);
@ -75,6 +80,7 @@ int grpc_udp_server_get_fd(grpc_udp_server *s, unsigned port_index);
int grpc_udp_server_add_port(grpc_udp_server *s,
const grpc_resolved_address *addr,
grpc_udp_server_read_cb read_cb,
grpc_udp_server_write_cb write_cb,
grpc_udp_server_orphan_cb orphan_cb);
void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *server,

@ -43,6 +43,9 @@
#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <stdio.h>
#include <string.h>
#include "src/core/lib/support/env.h"
typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type;
@ -74,7 +77,7 @@ typedef struct gpr_timer_log_list {
static __thread gpr_timer_log *g_thread_log;
static gpr_once g_once_init = GPR_ONCE_INIT;
static FILE *output_file;
static const char *output_filename = "latency_trace.txt";
static const char *output_filename_or_null = NULL;
static pthread_mutex_t g_mu;
static pthread_cond_t g_cv;
static gpr_timer_log_list g_in_progress_logs;
@ -85,6 +88,17 @@ static __thread int g_thread_id;
static int g_next_thread_id;
static int g_writing_enabled = 1;
static const char *output_filename() {
if (output_filename_or_null == NULL) {
output_filename_or_null = gpr_getenv("LATENCY_TRACE");
if (output_filename_or_null == NULL ||
strlen(output_filename_or_null) == 0) {
output_filename_or_null = "latency_trace.txt";
}
}
return output_filename_or_null;
}
static int timer_log_push_back(gpr_timer_log_list *list, gpr_timer_log *log) {
if (list->head == NULL) {
list->head = list->tail = log;
@ -134,7 +148,7 @@ static void timer_log_remove(gpr_timer_log_list *list, gpr_timer_log *log) {
static void write_log(gpr_timer_log *log) {
size_t i;
if (output_file == NULL) {
output_file = fopen(output_filename, "w");
output_file = fopen(output_filename(), "w");
}
for (i = 0; i < log->num_entries; i++) {
gpr_timer_entry *entry = &(log->log[i]);
@ -198,7 +212,7 @@ static void finish_writing(void) {
}
void gpr_timers_set_log_filename(const char *filename) {
output_filename = filename;
output_filename_or_null = filename;
}
static void init_output() {

@ -160,6 +160,53 @@ grpc_channel_credentials_duplicate_without_call_credentials(
}
}
static void credentials_pointer_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
grpc_channel_credentials_unref(exec_ctx, p);
}
static void *credentials_pointer_arg_copy(void *p) {
return grpc_channel_credentials_ref(p);
}
static int credentials_pointer_cmp(void *a, void *b) { return GPR_ICMP(a, b); }
static const grpc_arg_pointer_vtable credentials_pointer_vtable = {
credentials_pointer_arg_copy, credentials_pointer_arg_destroy,
credentials_pointer_cmp};
grpc_arg grpc_channel_credentials_to_arg(
grpc_channel_credentials *credentials) {
grpc_arg result;
result.type = GRPC_ARG_POINTER;
result.key = GRPC_ARG_CHANNEL_CREDENTIALS;
result.value.pointer.vtable = &credentials_pointer_vtable;
result.value.pointer.p = credentials;
return result;
}
grpc_channel_credentials *grpc_channel_credentials_from_arg(
const grpc_arg *arg) {
if (strcmp(arg->key, GRPC_ARG_CHANNEL_CREDENTIALS)) return NULL;
if (arg->type != GRPC_ARG_POINTER) {
gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
GRPC_ARG_CHANNEL_CREDENTIALS);
return NULL;
}
return arg->value.pointer.p;
}
grpc_channel_credentials *grpc_channel_credentials_find_in_args(
const grpc_channel_args *args) {
size_t i;
if (args == NULL) return NULL;
for (i = 0; i < args->num_args; i++) {
grpc_channel_credentials *credentials =
grpc_channel_credentials_from_arg(&args->args[i]);
if (credentials != NULL) return credentials;
}
return NULL;
}
grpc_server_credentials *grpc_server_credentials_ref(
grpc_server_credentials *creds) {
if (creds == NULL) return NULL;

@ -100,6 +100,8 @@ void grpc_override_well_known_credentials_path_getter(
/* --- grpc_channel_credentials. --- */
#define GRPC_ARG_CHANNEL_CREDENTIALS "grpc.channel_credentials"
typedef struct {
void (*destruct)(grpc_exec_ctx *exec_ctx, grpc_channel_credentials *c);
@ -140,6 +142,17 @@ grpc_channel_credentials *
grpc_channel_credentials_duplicate_without_call_credentials(
grpc_channel_credentials *creds);
/* Util to encapsulate the channel credentials in a channel arg. */
grpc_arg grpc_channel_credentials_to_arg(grpc_channel_credentials *credentials);
/* Util to get the channel credentials from a channel arg. */
grpc_channel_credentials *grpc_channel_credentials_from_arg(
const grpc_arg *arg);
/* Util to find the channel credentials from channel args. */
grpc_channel_credentials *grpc_channel_credentials_find_in_args(
const grpc_channel_args *args);
/* --- grpc_credentials_md. --- */
typedef struct {

@ -35,13 +35,13 @@
#include <string.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/executor.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/support/string.h"
/* -- Fake transport security credentials. -- */
static grpc_security_status fake_transport_security_create_security_connector(
@ -49,7 +49,7 @@ static grpc_security_status fake_transport_security_create_security_connector(
grpc_call_credentials *call_creds, const char *target,
const grpc_channel_args *args, grpc_channel_security_connector **sc,
grpc_channel_args **new_args) {
*sc = grpc_fake_channel_security_connector_create(call_creds);
*sc = grpc_fake_channel_security_connector_create(call_creds, target, args);
return GRPC_SECURITY_OK;
}

@ -38,6 +38,21 @@
/* -- Fake transport security credentials. -- */
/* Used to verify the target names given to the fake transport security
* connector.
*
* Its syntax by example:
* For LB channels:
* "backend_target_1,backend_target_2,...;lb_target_1,lb_target_2,..."
* For regular channels:
* "backend_taget_1,backend_target_2,..."
*
* That is to say, LB channels have a heading list of LB targets separated from
* the list of backend targets by a semicolon. For non-LB channels, only the
* latter is present. */
#define GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS \
"grpc.test_only.fake_security.expected_target"
/* Creates a fake transport security credentials object for testing. */
grpc_channel_credentials *grpc_fake_transport_security_credentials_create(void);

@ -335,7 +335,7 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
grpc_security_connector *sc =
grpc_find_security_connector_in_args(args->channel_args);
grpc_security_connector_find_in_args(args->channel_args);
grpc_auth_context *auth_context =
grpc_find_auth_context_in_args(args->channel_args);

@ -0,0 +1,70 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
/* Channel arg key for the mapping of LB server addresses to their names for
* secure naming purposes. */
#define GRPC_ARG_LB_SECURE_NAMING_MAP "grpc.lb_secure_naming_map"
static void *targets_info_copy(void *p) { return grpc_slice_hash_table_ref(p); }
static void targets_info_destroy(grpc_exec_ctx *exec_ctx, void *p) {
grpc_slice_hash_table_unref(exec_ctx, p);
}
static int targets_info_cmp(void *a, void *b) { return GPR_ICMP(a, b); }
static const grpc_arg_pointer_vtable server_to_balancer_names_vtable = {
targets_info_copy, targets_info_destroy, targets_info_cmp};
grpc_arg grpc_lb_targets_info_create_channel_arg(
grpc_slice_hash_table *targets_info) {
grpc_arg arg;
arg.type = GRPC_ARG_POINTER;
arg.key = GRPC_ARG_LB_SECURE_NAMING_MAP;
arg.value.pointer.p = targets_info;
arg.value.pointer.vtable = &server_to_balancer_names_vtable;
return arg;
}
grpc_slice_hash_table *grpc_lb_targets_info_find_in_args(
const grpc_channel_args *args) {
const grpc_arg *targets_info_arg =
grpc_channel_args_find(args, GRPC_ARG_LB_SECURE_NAMING_MAP);
if (targets_info_arg != NULL) {
GPR_ASSERT(targets_info_arg->type == GRPC_ARG_POINTER);
return targets_info_arg->value.pointer.p;
}
return NULL;
}

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

Loading…
Cancel
Save