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

pull/5901/head
David Garcia Quintas 9 years ago
commit e7518461c2
  1. 132
      BUILD
  2. 376
      Makefile
  3. 4
      README.md
  4. 37
      binding.gyp
  5. 176
      build.yaml
  6. 51
      config.m4
  7. 2
      doc/connectivity-semantics-and-api.md
  8. 2
      examples/cpp/helloworld/Makefile
  9. 93
      gRPC.podspec
  10. 1
      grpc.def
  11. 65
      grpc.gemspec
  12. 13
      include/grpc++/impl/codegen/completion_queue.h
  13. 12
      include/grpc++/server_builder.h
  14. 11
      include/grpc/grpc.h
  15. 65
      package.xml
  16. 6
      src/core/ext/census/gen/README.md
  17. 179
      src/core/ext/census/gen/census.pb.c
  18. 294
      src/core/ext/census/gen/census.pb.h
  19. 2
      src/core/ext/client_config/subchannel.c
  20. 29
      src/core/ext/client_config/subchannel_index.c
  21. 4
      src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
  22. 6
      src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
  23. 11
      src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
  24. 82
      src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
  25. 3
      src/core/ext/transport/chttp2/transport/frame_goaway.c
  26. 6
      src/core/ext/transport/chttp2/transport/hpack_parser.c
  27. 20
      src/core/ext/transport/cronet/transport/cronet_transport.c
  28. 3
      src/core/lib/channel/channel_args.c
  29. 1
      src/core/lib/compression/compression_algorithm.c
  30. 2
      src/core/lib/http/httpcli_security_connector.c
  31. 76
      src/core/lib/iomgr/ev_poll_and_epoll_posix.c
  32. 80
      src/core/lib/iomgr/ev_poll_posix.c
  33. 5
      src/core/lib/iomgr/ev_posix.c
  34. 6
      src/core/lib/iomgr/ev_posix.h
  35. 1
      src/core/lib/iomgr/tcp_server.h
  36. 24
      src/core/lib/iomgr/tcp_server_posix.c
  37. 5
      src/core/lib/iomgr/tcp_server_windows.c
  38. 2
      src/core/lib/security/context/security_context.c
  39. 8
      src/core/lib/security/context/security_context.h
  40. 1296
      src/core/lib/security/credentials.c
  41. 262
      src/core/lib/security/credentials/composite/composite_credentials.c
  42. 72
      src/core/lib/security/credentials/composite/composite_credentials.h
  43. 231
      src/core/lib/security/credentials/credentials.c
  44. 169
      src/core/lib/security/credentials/credentials.h
  45. 2
      src/core/lib/security/credentials/credentials_metadata.c
  46. 138
      src/core/lib/security/credentials/fake/fake_credentials.c
  47. 56
      src/core/lib/security/credentials/fake/fake_credentials.h
  48. 2
      src/core/lib/security/credentials/google_default/credentials_posix.c
  49. 2
      src/core/lib/security/credentials/google_default/credentials_win32.c
  50. 4
      src/core/lib/security/credentials/google_default/google_default_credentials.c
  51. 46
      src/core/lib/security/credentials/google_default/google_default_credentials.h
  52. 85
      src/core/lib/security/credentials/iam/iam_credentials.c
  53. 44
      src/core/lib/security/credentials/iam/iam_credentials.h
  54. 111
      src/core/lib/security/credentials/jwt/json_token.c
  55. 36
      src/core/lib/security/credentials/jwt/json_token.h
  56. 160
      src/core/lib/security/credentials/jwt/jwt_credentials.c
  57. 64
      src/core/lib/security/credentials/jwt/jwt_credentials.h
  58. 4
      src/core/lib/security/credentials/jwt/jwt_verifier.c
  59. 6
      src/core/lib/security/credentials/jwt/jwt_verifier.h
  60. 428
      src/core/lib/security/credentials/oauth2/oauth2_credentials.c
  61. 109
      src/core/lib/security/credentials/oauth2/oauth2_credentials.h
  62. 129
      src/core/lib/security/credentials/plugin/plugin_credentials.c
  63. 45
      src/core/lib/security/credentials/plugin/plugin_credentials.h
  64. 240
      src/core/lib/security/credentials/ssl/ssl_credentials.c
  65. 48
      src/core/lib/security/credentials/ssl/ssl_credentials.h
  66. 6
      src/core/lib/security/transport/auth_filters.h
  67. 8
      src/core/lib/security/transport/client_auth_filter.c
  68. 6
      src/core/lib/security/transport/handshake.c
  69. 8
      src/core/lib/security/transport/handshake.h
  70. 2
      src/core/lib/security/transport/secure_endpoint.c
  71. 6
      src/core/lib/security/transport/secure_endpoint.h
  72. 10
      src/core/lib/security/transport/security_connector.c
  73. 6
      src/core/lib/security/transport/security_connector.h
  74. 6
      src/core/lib/security/transport/server_auth_filter.c
  75. 2
      src/core/lib/security/util/b64.c
  76. 6
      src/core/lib/security/util/b64.h
  77. 62
      src/core/lib/security/util/json_util.c
  78. 53
      src/core/lib/security/util/json_util.h
  79. 8
      src/core/lib/support/murmur_hash.c
  80. 25
      src/core/lib/surface/call.c
  81. 18
      src/core/lib/surface/completion_queue.c
  82. 5
      src/core/lib/surface/completion_queue.h
  83. 8
      src/core/lib/surface/init_secure.c
  84. 227
      src/core/lib/surface/server.c
  85. 1
      src/core/lib/surface/server.h
  86. 3
      src/core/lib/transport/metadata.c
  87. 11
      src/cpp/server/server.cc
  88. 37
      src/cpp/server/server_builder.cc
  89. 24
      src/csharp/Grpc.Core.Tests/ClientServerTest.cs
  90. 10
      src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs
  91. 8
      src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
  92. 20
      src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
  93. 39
      src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
  94. 2
      src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs
  95. 10
      src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs
  96. 10
      src/csharp/Grpc.Core.Tests/MarshallingErrorsTest.cs
  97. 13
      src/csharp/Grpc.Core/Channel.cs
  98. 6
      src/csharp/Grpc.Core/Grpc.Core.csproj
  99. 53
      src/csharp/Grpc.Core/GrpcEnvironment.cs
  100. 102
      src/csharp/Grpc.Core/Internal/AsyncCall.cs
  101. Some files were not shown because too many files have changed in this diff Show More

132
BUILD

@ -256,15 +256,24 @@ cc_library(
"src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/timeout_encoding.h",
"src/core/ext/transport/chttp2/transport/varint.h", "src/core/ext/transport/chttp2/transport/varint.h",
"src/core/ext/transport/chttp2/alpn/alpn.h", "src/core/ext/transport/chttp2/alpn/alpn.h",
"src/core/lib/security/auth_filters.h", "src/core/lib/security/context/security_context.h",
"src/core/lib/security/b64.h", "src/core/lib/security/credentials/composite/composite_credentials.h",
"src/core/lib/security/credentials.h", "src/core/lib/security/credentials/credentials.h",
"src/core/lib/security/handshake.h", "src/core/lib/security/credentials/fake/fake_credentials.h",
"src/core/lib/security/json_token.h", "src/core/lib/security/credentials/google_default/google_default_credentials.h",
"src/core/lib/security/jwt_verifier.h", "src/core/lib/security/credentials/iam/iam_credentials.h",
"src/core/lib/security/secure_endpoint.h", "src/core/lib/security/credentials/jwt/json_token.h",
"src/core/lib/security/security_connector.h", "src/core/lib/security/credentials/jwt/jwt_credentials.h",
"src/core/lib/security/security_context.h", "src/core/lib/security/credentials/jwt/jwt_verifier.h",
"src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/transport/auth_filters.h",
"src/core/lib/security/transport/handshake.h",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/security_connector.h",
"src/core/lib/security/util/b64.h",
"src/core/lib/security/util/json_util.h",
"src/core/lib/tsi/fake_transport_security.h", "src/core/lib/tsi/fake_transport_security.h",
"src/core/lib/tsi/ssl_transport_security.h", "src/core/lib/tsi/ssl_transport_security.h",
"src/core/lib/tsi/ssl_types.h", "src/core/lib/tsi/ssl_types.h",
@ -294,6 +303,7 @@ cc_library(
"src/core/ext/census/aggregation.h", "src/core/ext/census/aggregation.h",
"src/core/ext/census/census_interface.h", "src/core/ext/census/census_interface.h",
"src/core/ext/census/census_rpc_stats.h", "src/core/ext/census/census_rpc_stats.h",
"src/core/ext/census/gen/census.pb.h",
"src/core/ext/census/grpc_filter.h", "src/core/ext/census/grpc_filter.h",
"src/core/ext/census/mlog.h", "src/core/ext/census/mlog.h",
"src/core/ext/census/rpc_metric_id.h", "src/core/ext/census/rpc_metric_id.h",
@ -404,20 +414,28 @@ cc_library(
"src/core/ext/transport/chttp2/transport/writing.c", "src/core/ext/transport/chttp2/transport/writing.c",
"src/core/ext/transport/chttp2/alpn/alpn.c", "src/core/ext/transport/chttp2/alpn/alpn.c",
"src/core/lib/http/httpcli_security_connector.c", "src/core/lib/http/httpcli_security_connector.c",
"src/core/lib/security/b64.c", "src/core/lib/security/context/security_context.c",
"src/core/lib/security/client_auth_filter.c", "src/core/lib/security/credentials/composite/composite_credentials.c",
"src/core/lib/security/credentials.c", "src/core/lib/security/credentials/credentials.c",
"src/core/lib/security/credentials_metadata.c", "src/core/lib/security/credentials/credentials_metadata.c",
"src/core/lib/security/credentials_posix.c", "src/core/lib/security/credentials/fake/fake_credentials.c",
"src/core/lib/security/credentials_win32.c", "src/core/lib/security/credentials/google_default/credentials_posix.c",
"src/core/lib/security/google_default_credentials.c", "src/core/lib/security/credentials/google_default/credentials_win32.c",
"src/core/lib/security/handshake.c", "src/core/lib/security/credentials/google_default/google_default_credentials.c",
"src/core/lib/security/json_token.c", "src/core/lib/security/credentials/iam/iam_credentials.c",
"src/core/lib/security/jwt_verifier.c", "src/core/lib/security/credentials/jwt/json_token.c",
"src/core/lib/security/secure_endpoint.c", "src/core/lib/security/credentials/jwt/jwt_credentials.c",
"src/core/lib/security/security_connector.c", "src/core/lib/security/credentials/jwt/jwt_verifier.c",
"src/core/lib/security/security_context.c", "src/core/lib/security/credentials/oauth2/oauth2_credentials.c",
"src/core/lib/security/server_auth_filter.c", "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/handshake.c",
"src/core/lib/security/transport/secure_endpoint.c",
"src/core/lib/security/transport/security_connector.c",
"src/core/lib/security/transport/server_auth_filter.c",
"src/core/lib/security/util/b64.c",
"src/core/lib/security/util/json_util.c",
"src/core/lib/surface/init_secure.c", "src/core/lib/surface/init_secure.c",
"src/core/lib/tsi/fake_transport_security.c", "src/core/lib/tsi/fake_transport_security.c",
"src/core/lib/tsi/ssl_transport_security.c", "src/core/lib/tsi/ssl_transport_security.c",
@ -456,6 +474,7 @@ cc_library(
"src/core/ext/load_reporting/load_reporting.c", "src/core/ext/load_reporting/load_reporting.c",
"src/core/ext/load_reporting/load_reporting_filter.c", "src/core/ext/load_reporting/load_reporting_filter.c",
"src/core/ext/census/context.c", "src/core/ext/census/context.c",
"src/core/ext/census/gen/census.pb.c",
"src/core/ext/census/grpc_context.c", "src/core/ext/census/grpc_context.c",
"src/core/ext/census/grpc_filter.c", "src/core/ext/census/grpc_filter.c",
"src/core/ext/census/grpc_plugin.c", "src/core/ext/census/grpc_plugin.c",
@ -636,6 +655,7 @@ cc_library(
"src/core/ext/census/aggregation.h", "src/core/ext/census/aggregation.h",
"src/core/ext/census/census_interface.h", "src/core/ext/census/census_interface.h",
"src/core/ext/census/census_rpc_stats.h", "src/core/ext/census/census_rpc_stats.h",
"src/core/ext/census/gen/census.pb.h",
"src/core/ext/census/grpc_filter.h", "src/core/ext/census/grpc_filter.h",
"src/core/ext/census/mlog.h", "src/core/ext/census/mlog.h",
"src/core/ext/census/rpc_metric_id.h", "src/core/ext/census/rpc_metric_id.h",
@ -775,6 +795,7 @@ cc_library(
"src/core/ext/lb_policy/pick_first/pick_first.c", "src/core/ext/lb_policy/pick_first/pick_first.c",
"src/core/ext/lb_policy/round_robin/round_robin.c", "src/core/ext/lb_policy/round_robin/round_robin.c",
"src/core/ext/census/context.c", "src/core/ext/census/context.c",
"src/core/ext/census/gen/census.pb.c",
"src/core/ext/census/grpc_context.c", "src/core/ext/census/grpc_context.c",
"src/core/ext/census/grpc_filter.c", "src/core/ext/census/grpc_filter.c",
"src/core/ext/census/grpc_plugin.c", "src/core/ext/census/grpc_plugin.c",
@ -1442,20 +1463,28 @@ objc_library(
"src/core/ext/transport/chttp2/transport/writing.c", "src/core/ext/transport/chttp2/transport/writing.c",
"src/core/ext/transport/chttp2/alpn/alpn.c", "src/core/ext/transport/chttp2/alpn/alpn.c",
"src/core/lib/http/httpcli_security_connector.c", "src/core/lib/http/httpcli_security_connector.c",
"src/core/lib/security/b64.c", "src/core/lib/security/context/security_context.c",
"src/core/lib/security/client_auth_filter.c", "src/core/lib/security/credentials/composite/composite_credentials.c",
"src/core/lib/security/credentials.c", "src/core/lib/security/credentials/credentials.c",
"src/core/lib/security/credentials_metadata.c", "src/core/lib/security/credentials/credentials_metadata.c",
"src/core/lib/security/credentials_posix.c", "src/core/lib/security/credentials/fake/fake_credentials.c",
"src/core/lib/security/credentials_win32.c", "src/core/lib/security/credentials/google_default/credentials_posix.c",
"src/core/lib/security/google_default_credentials.c", "src/core/lib/security/credentials/google_default/credentials_win32.c",
"src/core/lib/security/handshake.c", "src/core/lib/security/credentials/google_default/google_default_credentials.c",
"src/core/lib/security/json_token.c", "src/core/lib/security/credentials/iam/iam_credentials.c",
"src/core/lib/security/jwt_verifier.c", "src/core/lib/security/credentials/jwt/json_token.c",
"src/core/lib/security/secure_endpoint.c", "src/core/lib/security/credentials/jwt/jwt_credentials.c",
"src/core/lib/security/security_connector.c", "src/core/lib/security/credentials/jwt/jwt_verifier.c",
"src/core/lib/security/security_context.c", "src/core/lib/security/credentials/oauth2/oauth2_credentials.c",
"src/core/lib/security/server_auth_filter.c", "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/handshake.c",
"src/core/lib/security/transport/secure_endpoint.c",
"src/core/lib/security/transport/security_connector.c",
"src/core/lib/security/transport/server_auth_filter.c",
"src/core/lib/security/util/b64.c",
"src/core/lib/security/util/json_util.c",
"src/core/lib/surface/init_secure.c", "src/core/lib/surface/init_secure.c",
"src/core/lib/tsi/fake_transport_security.c", "src/core/lib/tsi/fake_transport_security.c",
"src/core/lib/tsi/ssl_transport_security.c", "src/core/lib/tsi/ssl_transport_security.c",
@ -1494,6 +1523,7 @@ objc_library(
"src/core/ext/load_reporting/load_reporting.c", "src/core/ext/load_reporting/load_reporting.c",
"src/core/ext/load_reporting/load_reporting_filter.c", "src/core/ext/load_reporting/load_reporting_filter.c",
"src/core/ext/census/context.c", "src/core/ext/census/context.c",
"src/core/ext/census/gen/census.pb.c",
"src/core/ext/census/grpc_context.c", "src/core/ext/census/grpc_context.c",
"src/core/ext/census/grpc_filter.c", "src/core/ext/census/grpc_filter.c",
"src/core/ext/census/grpc_plugin.c", "src/core/ext/census/grpc_plugin.c",
@ -1630,15 +1660,24 @@ objc_library(
"src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/timeout_encoding.h",
"src/core/ext/transport/chttp2/transport/varint.h", "src/core/ext/transport/chttp2/transport/varint.h",
"src/core/ext/transport/chttp2/alpn/alpn.h", "src/core/ext/transport/chttp2/alpn/alpn.h",
"src/core/lib/security/auth_filters.h", "src/core/lib/security/context/security_context.h",
"src/core/lib/security/b64.h", "src/core/lib/security/credentials/composite/composite_credentials.h",
"src/core/lib/security/credentials.h", "src/core/lib/security/credentials/credentials.h",
"src/core/lib/security/handshake.h", "src/core/lib/security/credentials/fake/fake_credentials.h",
"src/core/lib/security/json_token.h", "src/core/lib/security/credentials/google_default/google_default_credentials.h",
"src/core/lib/security/jwt_verifier.h", "src/core/lib/security/credentials/iam/iam_credentials.h",
"src/core/lib/security/secure_endpoint.h", "src/core/lib/security/credentials/jwt/json_token.h",
"src/core/lib/security/security_connector.h", "src/core/lib/security/credentials/jwt/jwt_credentials.h",
"src/core/lib/security/security_context.h", "src/core/lib/security/credentials/jwt/jwt_verifier.h",
"src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
"src/core/lib/security/transport/auth_filters.h",
"src/core/lib/security/transport/handshake.h",
"src/core/lib/security/transport/secure_endpoint.h",
"src/core/lib/security/transport/security_connector.h",
"src/core/lib/security/util/b64.h",
"src/core/lib/security/util/json_util.h",
"src/core/lib/tsi/fake_transport_security.h", "src/core/lib/tsi/fake_transport_security.h",
"src/core/lib/tsi/ssl_transport_security.h", "src/core/lib/tsi/ssl_transport_security.h",
"src/core/lib/tsi/ssl_types.h", "src/core/lib/tsi/ssl_types.h",
@ -1668,6 +1707,7 @@ objc_library(
"src/core/ext/census/aggregation.h", "src/core/ext/census/aggregation.h",
"src/core/ext/census/census_interface.h", "src/core/ext/census/census_interface.h",
"src/core/ext/census/census_rpc_stats.h", "src/core/ext/census/census_rpc_stats.h",
"src/core/ext/census/gen/census.pb.h",
"src/core/ext/census/grpc_filter.h", "src/core/ext/census/grpc_filter.h",
"src/core/ext/census/mlog.h", "src/core/ext/census/mlog.h",
"src/core/ext/census/rpc_metric_id.h", "src/core/ext/census/rpc_metric_id.h",

@ -215,9 +215,9 @@ CC_mutrace = $(DEFAULT_CC)
CXX_mutrace = $(DEFAULT_CXX) CXX_mutrace = $(DEFAULT_CXX)
LD_mutrace = $(DEFAULT_CC) LD_mutrace = $(DEFAULT_CC)
LDXX_mutrace = $(DEFAULT_CXX) LDXX_mutrace = $(DEFAULT_CXX)
CPPFLAGS_mutrace = -O0 CPPFLAGS_mutrace = -O3 -fno-omit-frame-pointer
LDFLAGS_mutrace = -rdynamic LDFLAGS_mutrace = -rdynamic
DEFINES_mutrace = _DEBUG DEBUG DEFINES_mutrace = NDEBUG
VALID_CONFIG_memcheck = 1 VALID_CONFIG_memcheck = 1
CC_memcheck = $(DEFAULT_CC) CC_memcheck = $(DEFAULT_CC)
@ -1000,8 +1000,6 @@ uri_parser_test: $(BINDIR)/$(CONFIG)/uri_parser_test
workqueue_test: $(BINDIR)/$(CONFIG)/workqueue_test workqueue_test: $(BINDIR)/$(CONFIG)/workqueue_test
alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test
async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test
async_streaming_ping_pong_test: $(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test
async_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/async_unary_ping_pong_test
auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test
channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test
cli_call_test: $(BINDIR)/$(CONFIG)/cli_call_test cli_call_test: $(BINDIR)/$(CONFIG)/cli_call_test
@ -1015,7 +1013,6 @@ cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test
cxx_string_ref_test: $(BINDIR)/$(CONFIG)/cxx_string_ref_test cxx_string_ref_test: $(BINDIR)/$(CONFIG)/cxx_string_ref_test
cxx_time_test: $(BINDIR)/$(CONFIG)/cxx_time_test cxx_time_test: $(BINDIR)/$(CONFIG)/cxx_time_test
end2end_test: $(BINDIR)/$(CONFIG)/end2end_test end2end_test: $(BINDIR)/$(CONFIG)/end2end_test
generic_async_streaming_ping_pong_test: $(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test
generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test
golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test
grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli
@ -1036,7 +1033,6 @@ mock_test: $(BINDIR)/$(CONFIG)/mock_test
qps_interarrival_test: $(BINDIR)/$(CONFIG)/qps_interarrival_test qps_interarrival_test: $(BINDIR)/$(CONFIG)/qps_interarrival_test
qps_json_driver: $(BINDIR)/$(CONFIG)/qps_json_driver qps_json_driver: $(BINDIR)/$(CONFIG)/qps_json_driver
qps_openloop_test: $(BINDIR)/$(CONFIG)/qps_openloop_test qps_openloop_test: $(BINDIR)/$(CONFIG)/qps_openloop_test
qps_test: $(BINDIR)/$(CONFIG)/qps_test
qps_worker: $(BINDIR)/$(CONFIG)/qps_worker qps_worker: $(BINDIR)/$(CONFIG)/qps_worker
reconnect_interop_client: $(BINDIR)/$(CONFIG)/reconnect_interop_client reconnect_interop_client: $(BINDIR)/$(CONFIG)/reconnect_interop_client
reconnect_interop_server: $(BINDIR)/$(CONFIG)/reconnect_interop_server reconnect_interop_server: $(BINDIR)/$(CONFIG)/reconnect_interop_server
@ -1049,8 +1045,6 @@ shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test
status_test: $(BINDIR)/$(CONFIG)/status_test status_test: $(BINDIR)/$(CONFIG)/status_test
streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test
stress_test: $(BINDIR)/$(CONFIG)/stress_test stress_test: $(BINDIR)/$(CONFIG)/stress_test
sync_streaming_ping_pong_test: $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test
sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test
thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test
zookeeper_test: $(BINDIR)/$(CONFIG)/zookeeper_test zookeeper_test: $(BINDIR)/$(CONFIG)/zookeeper_test
public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89
@ -1379,8 +1373,6 @@ buildtests_c: privatelibs_c \
buildtests_cxx: buildtests_zookeeper privatelibs_cxx \ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \
$(BINDIR)/$(CONFIG)/alarm_cpp_test \ $(BINDIR)/$(CONFIG)/alarm_cpp_test \
$(BINDIR)/$(CONFIG)/async_end2end_test \ $(BINDIR)/$(CONFIG)/async_end2end_test \
$(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test \
$(BINDIR)/$(CONFIG)/async_unary_ping_pong_test \
$(BINDIR)/$(CONFIG)/auth_property_iterator_test \ $(BINDIR)/$(CONFIG)/auth_property_iterator_test \
$(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_arguments_test \
$(BINDIR)/$(CONFIG)/cli_call_test \ $(BINDIR)/$(CONFIG)/cli_call_test \
@ -1394,7 +1386,6 @@ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \
$(BINDIR)/$(CONFIG)/cxx_string_ref_test \ $(BINDIR)/$(CONFIG)/cxx_string_ref_test \
$(BINDIR)/$(CONFIG)/cxx_time_test \ $(BINDIR)/$(CONFIG)/cxx_time_test \
$(BINDIR)/$(CONFIG)/end2end_test \ $(BINDIR)/$(CONFIG)/end2end_test \
$(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test \
$(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \
$(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/golden_file_test \
$(BINDIR)/$(CONFIG)/grpc_cli \ $(BINDIR)/$(CONFIG)/grpc_cli \
@ -1409,7 +1400,6 @@ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \
$(BINDIR)/$(CONFIG)/qps_interarrival_test \ $(BINDIR)/$(CONFIG)/qps_interarrival_test \
$(BINDIR)/$(CONFIG)/qps_json_driver \ $(BINDIR)/$(CONFIG)/qps_json_driver \
$(BINDIR)/$(CONFIG)/qps_openloop_test \ $(BINDIR)/$(CONFIG)/qps_openloop_test \
$(BINDIR)/$(CONFIG)/qps_test \
$(BINDIR)/$(CONFIG)/qps_worker \ $(BINDIR)/$(CONFIG)/qps_worker \
$(BINDIR)/$(CONFIG)/reconnect_interop_client \ $(BINDIR)/$(CONFIG)/reconnect_interop_client \
$(BINDIR)/$(CONFIG)/reconnect_interop_server \ $(BINDIR)/$(CONFIG)/reconnect_interop_server \
@ -1422,8 +1412,6 @@ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \
$(BINDIR)/$(CONFIG)/status_test \ $(BINDIR)/$(CONFIG)/status_test \
$(BINDIR)/$(CONFIG)/streaming_throughput_test \ $(BINDIR)/$(CONFIG)/streaming_throughput_test \
$(BINDIR)/$(CONFIG)/stress_test \ $(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test \
$(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test \
$(BINDIR)/$(CONFIG)/thread_stress_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \
$(BINDIR)/$(CONFIG)/boringssl_aes_test \ $(BINDIR)/$(CONFIG)/boringssl_aes_test \
$(BINDIR)/$(CONFIG)/boringssl_asn1_test \ $(BINDIR)/$(CONFIG)/boringssl_asn1_test \
@ -1699,10 +1687,6 @@ test_cxx: test_zookeeper buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/alarm_cpp_test || ( echo test alarm_cpp_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/alarm_cpp_test || ( echo test alarm_cpp_test failed ; exit 1 )
$(E) "[RUN] Testing async_end2end_test" $(E) "[RUN] Testing async_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/async_end2end_test || ( echo test async_end2end_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/async_end2end_test || ( echo test async_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing async_streaming_ping_pong_test"
$(Q) $(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test || ( echo test async_streaming_ping_pong_test failed ; exit 1 )
$(E) "[RUN] Testing async_unary_ping_pong_test"
$(Q) $(BINDIR)/$(CONFIG)/async_unary_ping_pong_test || ( echo test async_unary_ping_pong_test failed ; exit 1 )
$(E) "[RUN] Testing auth_property_iterator_test" $(E) "[RUN] Testing auth_property_iterator_test"
$(Q) $(BINDIR)/$(CONFIG)/auth_property_iterator_test || ( echo test auth_property_iterator_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/auth_property_iterator_test || ( echo test auth_property_iterator_test failed ; exit 1 )
$(E) "[RUN] Testing channel_arguments_test" $(E) "[RUN] Testing channel_arguments_test"
@ -1727,8 +1711,6 @@ test_cxx: test_zookeeper buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/cxx_time_test || ( echo test cxx_time_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/cxx_time_test || ( echo test cxx_time_test failed ; exit 1 )
$(E) "[RUN] Testing end2end_test" $(E) "[RUN] Testing end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 )
$(E) "[RUN] Testing generic_async_streaming_ping_pong_test"
$(Q) $(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test || ( echo test generic_async_streaming_ping_pong_test failed ; exit 1 )
$(E) "[RUN] Testing generic_end2end_test" $(E) "[RUN] Testing generic_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing golden_file_test" $(E) "[RUN] Testing golden_file_test"
@ -1743,8 +1725,6 @@ test_cxx: test_zookeeper buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/mock_test || ( echo test mock_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/mock_test || ( echo test mock_test failed ; exit 1 )
$(E) "[RUN] Testing qps_openloop_test" $(E) "[RUN] Testing qps_openloop_test"
$(Q) $(BINDIR)/$(CONFIG)/qps_openloop_test || ( echo test qps_openloop_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/qps_openloop_test || ( echo test qps_openloop_test failed ; exit 1 )
$(E) "[RUN] Testing qps_test"
$(Q) $(BINDIR)/$(CONFIG)/qps_test || ( echo test qps_test failed ; exit 1 )
$(E) "[RUN] Testing secure_auth_context_test" $(E) "[RUN] Testing secure_auth_context_test"
$(Q) $(BINDIR)/$(CONFIG)/secure_auth_context_test || ( echo test secure_auth_context_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/secure_auth_context_test || ( echo test secure_auth_context_test failed ; exit 1 )
$(E) "[RUN] Testing secure_sync_unary_ping_pong_test" $(E) "[RUN] Testing secure_sync_unary_ping_pong_test"
@ -1759,10 +1739,6 @@ test_cxx: test_zookeeper buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/status_test || ( echo test status_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/status_test || ( echo test status_test failed ; exit 1 )
$(E) "[RUN] Testing streaming_throughput_test" $(E) "[RUN] Testing streaming_throughput_test"
$(Q) $(BINDIR)/$(CONFIG)/streaming_throughput_test || ( echo test streaming_throughput_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/streaming_throughput_test || ( echo test streaming_throughput_test failed ; exit 1 )
$(E) "[RUN] Testing sync_streaming_ping_pong_test"
$(Q) $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test || ( echo test sync_streaming_ping_pong_test failed ; exit 1 )
$(E) "[RUN] Testing sync_unary_ping_pong_test"
$(Q) $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test || ( echo test sync_unary_ping_pong_test failed ; exit 1 )
$(E) "[RUN] Testing thread_stress_test" $(E) "[RUN] Testing thread_stress_test"
$(Q) $(BINDIR)/$(CONFIG)/thread_stress_test || ( echo test thread_stress_test failed ; exit 1 ) $(Q) $(BINDIR)/$(CONFIG)/thread_stress_test || ( echo test thread_stress_test failed ; exit 1 )
@ -1876,7 +1852,7 @@ $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc:
$(LIBDIR)/$(CONFIG)/pkgconfig/grpc_zookeeper.pc: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_zookeeper.pc:
$(E) "[MAKE] Generating $@" $(E) "[MAKE] Generating $@"
$(Q) mkdir -p $(@D) $(Q) mkdir -p $(@D)
$(Q) echo -e "$(GRPC_ZOOKEEPER_PC_FILE)" >$@ $(Q) echo "$(GRPC_ZOOKEEPER_PC_FILE)" | tr , '\n' >$@
$(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc:
$(E) "[MAKE] Generating $@" $(E) "[MAKE] Generating $@"
@ -2318,17 +2294,19 @@ ifeq ($(INSTALL_OK),true)
@echo "Your system looks ready to go." @echo "Your system looks ready to go."
@echo @echo
else else
@echo "We couldn't find protoc 3.0.0+ installed on your system. While this" @echo "Warning: it looks like protoc 3.0.0+ isn't installed on your system,"
@echo "won't prevent grpc from working, you won't be able to compile" @echo "which means that you won't be able to compile .proto files for use"
@echo "and run any meaningful code with it." @echo "with gRPC."
@echo @echo
@echo "If you are just using pre-compiled protocol buffers, or you otherwise"
@echo "have no need to compile .proto files, you can ignore this."
@echo @echo
@echo "Please download and install protobuf 3.0.0+ from:" @echo "If you do need protobuf for some reason, you can download and install"
@echo "it from:"
@echo @echo
@echo " https://github.com/google/protobuf/releases" @echo " https://github.com/google/protobuf/releases"
@echo @echo
@echo "Once you've done so, or if you think this message is in error," @echo "Once you've done so, you can re-run this check by doing:"
@echo "you can re-run this check by doing:"
@echo @echo
@echo " make verify-install" @echo " make verify-install"
endif endif
@ -2603,20 +2581,28 @@ LIBGRPC_SRC = \
src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/transport/writing.c \
src/core/ext/transport/chttp2/alpn/alpn.c \ src/core/ext/transport/chttp2/alpn/alpn.c \
src/core/lib/http/httpcli_security_connector.c \ src/core/lib/http/httpcli_security_connector.c \
src/core/lib/security/b64.c \ src/core/lib/security/context/security_context.c \
src/core/lib/security/client_auth_filter.c \ src/core/lib/security/credentials/composite/composite_credentials.c \
src/core/lib/security/credentials.c \ src/core/lib/security/credentials/credentials.c \
src/core/lib/security/credentials_metadata.c \ src/core/lib/security/credentials/credentials_metadata.c \
src/core/lib/security/credentials_posix.c \ src/core/lib/security/credentials/fake/fake_credentials.c \
src/core/lib/security/credentials_win32.c \ src/core/lib/security/credentials/google_default/credentials_posix.c \
src/core/lib/security/google_default_credentials.c \ src/core/lib/security/credentials/google_default/credentials_win32.c \
src/core/lib/security/handshake.c \ src/core/lib/security/credentials/google_default/google_default_credentials.c \
src/core/lib/security/json_token.c \ src/core/lib/security/credentials/iam/iam_credentials.c \
src/core/lib/security/jwt_verifier.c \ src/core/lib/security/credentials/jwt/json_token.c \
src/core/lib/security/secure_endpoint.c \ src/core/lib/security/credentials/jwt/jwt_credentials.c \
src/core/lib/security/security_connector.c \ src/core/lib/security/credentials/jwt/jwt_verifier.c \
src/core/lib/security/security_context.c \ src/core/lib/security/credentials/oauth2/oauth2_credentials.c \
src/core/lib/security/server_auth_filter.c \ 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/handshake.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
src/core/lib/security/transport/server_auth_filter.c \
src/core/lib/security/util/b64.c \
src/core/lib/security/util/json_util.c \
src/core/lib/surface/init_secure.c \ src/core/lib/surface/init_secure.c \
src/core/lib/tsi/fake_transport_security.c \ src/core/lib/tsi/fake_transport_security.c \
src/core/lib/tsi/ssl_transport_security.c \ src/core/lib/tsi/ssl_transport_security.c \
@ -2658,6 +2644,7 @@ LIBGRPC_SRC = \
src/core/ext/load_reporting/load_reporting.c \ src/core/ext/load_reporting/load_reporting.c \
src/core/ext/load_reporting/load_reporting_filter.c \ src/core/ext/load_reporting/load_reporting_filter.c \
src/core/ext/census/context.c \ src/core/ext/census/context.c \
src/core/ext/census/gen/census.pb.c \
src/core/ext/census/grpc_context.c \ src/core/ext/census/grpc_context.c \
src/core/ext/census/grpc_filter.c \ src/core/ext/census/grpc_filter.c \
src/core/ext/census/grpc_plugin.c \ src/core/ext/census/grpc_plugin.c \
@ -2983,6 +2970,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/lb_policy/pick_first/pick_first.c \ src/core/ext/lb_policy/pick_first/pick_first.c \
src/core/ext/lb_policy/round_robin/round_robin.c \ src/core/ext/lb_policy/round_robin/round_robin.c \
src/core/ext/census/context.c \ src/core/ext/census/context.c \
src/core/ext/census/gen/census.pb.c \
src/core/ext/census/grpc_context.c \ src/core/ext/census/grpc_context.c \
src/core/ext/census/grpc_filter.c \ src/core/ext/census/grpc_filter.c \
src/core/ext/census/grpc_plugin.c \ src/core/ext/census/grpc_plugin.c \
@ -9725,92 +9713,6 @@ endif
endif endif
ASYNC_STREAMING_PING_PONG_TEST_SRC = \
test/cpp/qps/async_streaming_ping_pong_test.cc \
ASYNC_STREAMING_PING_PONG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ASYNC_STREAMING_PING_PONG_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/async_streaming_ping_pong_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)/async_streaming_ping_pong_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test: $(PROTOBUF_DEP) $(ASYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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) $(ASYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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)/async_streaming_ping_pong_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/qps/async_streaming_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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_async_streaming_ping_pong_test: $(ASYNC_STREAMING_PING_PONG_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(ASYNC_STREAMING_PING_PONG_TEST_OBJS:.o=.dep)
endif
endif
ASYNC_UNARY_PING_PONG_TEST_SRC = \
test/cpp/qps/async_unary_ping_pong_test.cc \
ASYNC_UNARY_PING_PONG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ASYNC_UNARY_PING_PONG_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/async_unary_ping_pong_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)/async_unary_ping_pong_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/async_unary_ping_pong_test: $(PROTOBUF_DEP) $(ASYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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) $(ASYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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)/async_unary_ping_pong_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/qps/async_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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_async_unary_ping_pong_test: $(ASYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(ASYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep)
endif
endif
AUTH_PROPERTY_ITERATOR_TEST_SRC = \ AUTH_PROPERTY_ITERATOR_TEST_SRC = \
test/cpp/common/auth_property_iterator_test.cc \ test/cpp/common/auth_property_iterator_test.cc \
@ -10416,49 +10318,6 @@ endif
endif endif
GENERIC_ASYNC_STREAMING_PING_PONG_TEST_SRC = \
test/cpp/qps/generic_async_streaming_ping_pong_test.cc \
GENERIC_ASYNC_STREAMING_PING_PONG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GENERIC_ASYNC_STREAMING_PING_PONG_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_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)/generic_async_streaming_ping_pong_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test: $(PROTOBUF_DEP) $(GENERIC_ASYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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) $(GENERIC_ASYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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)/generic_async_streaming_ping_pong_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/qps/generic_async_streaming_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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_generic_async_streaming_ping_pong_test: $(GENERIC_ASYNC_STREAMING_PING_PONG_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GENERIC_ASYNC_STREAMING_PING_PONG_TEST_OBJS:.o=.dep)
endif
endif
GENERIC_END2END_TEST_SRC = \ GENERIC_END2END_TEST_SRC = \
test/cpp/end2end/generic_end2end_test.cc \ test/cpp/end2end/generic_end2end_test.cc \
@ -11238,49 +11097,6 @@ endif
endif endif
QPS_TEST_SRC = \
test/cpp/qps/qps_test.cc \
QPS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/qps_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)/qps_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/qps_test: $(PROTOBUF_DEP) $(QPS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(QPS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
deps_qps_test: $(QPS_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(QPS_TEST_OBJS:.o=.dep)
endif
endif
QPS_WORKER_SRC = \ QPS_WORKER_SRC = \
test/cpp/qps/worker.cc \ test/cpp/qps/worker.cc \
@ -11842,92 +11658,6 @@ $(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(GENDIR)/src/proto/grpc/tes
$(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
SYNC_STREAMING_PING_PONG_TEST_SRC = \
test/cpp/qps/sync_streaming_ping_pong_test.cc \
SYNC_STREAMING_PING_PONG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SYNC_STREAMING_PING_PONG_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_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)/sync_streaming_ping_pong_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test: $(PROTOBUF_DEP) $(SYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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) $(SYNC_STREAMING_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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)/sync_streaming_ping_pong_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/qps/sync_streaming_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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_sync_streaming_ping_pong_test: $(SYNC_STREAMING_PING_PONG_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SYNC_STREAMING_PING_PONG_TEST_OBJS:.o=.dep)
endif
endif
SYNC_UNARY_PING_PONG_TEST_SRC = \
test/cpp/qps/sync_unary_ping_pong_test.cc \
SYNC_UNARY_PING_PONG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SYNC_UNARY_PING_PONG_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/sync_unary_ping_pong_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)/sync_unary_ping_pong_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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) $(SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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)/sync_unary_ping_pong_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/qps/sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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_sync_unary_ping_pong_test: $(SYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep)
endif
endif
THREAD_STRESS_TEST_SRC = \ THREAD_STRESS_TEST_SRC = \
test/cpp/end2end/thread_stress_test.cc \ test/cpp/end2end/thread_stress_test.cc \
@ -14469,20 +14199,28 @@ src/core/ext/transport/cronet/client/secure/cronet_channel_create.c: $(OPENSSL_D
src/core/ext/transport/cronet/transport/cronet_api_dummy.c: $(OPENSSL_DEP) src/core/ext/transport/cronet/transport/cronet_api_dummy.c: $(OPENSSL_DEP)
src/core/ext/transport/cronet/transport/cronet_transport.c: $(OPENSSL_DEP) src/core/ext/transport/cronet/transport/cronet_transport.c: $(OPENSSL_DEP)
src/core/lib/http/httpcli_security_connector.c: $(OPENSSL_DEP) src/core/lib/http/httpcli_security_connector.c: $(OPENSSL_DEP)
src/core/lib/security/b64.c: $(OPENSSL_DEP) src/core/lib/security/context/security_context.c: $(OPENSSL_DEP)
src/core/lib/security/client_auth_filter.c: $(OPENSSL_DEP) src/core/lib/security/credentials/composite/composite_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/credentials.c: $(OPENSSL_DEP) src/core/lib/security/credentials/credentials.c: $(OPENSSL_DEP)
src/core/lib/security/credentials_metadata.c: $(OPENSSL_DEP) src/core/lib/security/credentials/credentials_metadata.c: $(OPENSSL_DEP)
src/core/lib/security/credentials_posix.c: $(OPENSSL_DEP) src/core/lib/security/credentials/fake/fake_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/credentials_win32.c: $(OPENSSL_DEP) src/core/lib/security/credentials/google_default/credentials_posix.c: $(OPENSSL_DEP)
src/core/lib/security/google_default_credentials.c: $(OPENSSL_DEP) src/core/lib/security/credentials/google_default/credentials_win32.c: $(OPENSSL_DEP)
src/core/lib/security/handshake.c: $(OPENSSL_DEP) src/core/lib/security/credentials/google_default/google_default_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/json_token.c: $(OPENSSL_DEP) src/core/lib/security/credentials/iam/iam_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/jwt_verifier.c: $(OPENSSL_DEP) src/core/lib/security/credentials/jwt/json_token.c: $(OPENSSL_DEP)
src/core/lib/security/secure_endpoint.c: $(OPENSSL_DEP) src/core/lib/security/credentials/jwt/jwt_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/security_connector.c: $(OPENSSL_DEP) src/core/lib/security/credentials/jwt/jwt_verifier.c: $(OPENSSL_DEP)
src/core/lib/security/security_context.c: $(OPENSSL_DEP) src/core/lib/security/credentials/oauth2/oauth2_credentials.c: $(OPENSSL_DEP)
src/core/lib/security/server_auth_filter.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/handshake.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/server_auth_filter.c: $(OPENSSL_DEP)
src/core/lib/security/util/b64.c: $(OPENSSL_DEP)
src/core/lib/security/util/json_util.c: $(OPENSSL_DEP)
src/core/lib/surface/init_secure.c: $(OPENSSL_DEP) src/core/lib/surface/init_secure.c: $(OPENSSL_DEP)
src/core/lib/tsi/fake_transport_security.c: $(OPENSSL_DEP) src/core/lib/tsi/fake_transport_security.c: $(OPENSSL_DEP)
src/core/lib/tsi/ssl_transport_security.c: $(OPENSSL_DEP) src/core/lib/tsi/ssl_transport_security.c: $(OPENSSL_DEP)

@ -11,10 +11,12 @@ Copyright 2015 Google Inc.
You can find more detailed documentation and examples in the [doc](doc) and [examples](examples) directories respectively. You can find more detailed documentation and examples in the [doc](doc) and [examples](examples) directories respectively.
#Installation #Installation & Testing
See [INSTALL](INSTALL.md) for installation instructions for various platforms. See [INSTALL](INSTALL.md) for installation instructions for various platforms.
See [tools/run_tests](tools/run_tests) for more guidance on how to run various test suites (e.g. unit tests, interop tests, benchmarks)
#Repository Structure & Status #Repository Structure & Status
This repository contains source code for gRPC libraries for multiple languages written on top of shared C core library [src/core] (src/core). This repository contains source code for gRPC libraries for multiple languages written on top of shared C core library [src/core] (src/core).

@ -670,20 +670,28 @@
'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/transport/writing.c',
'src/core/ext/transport/chttp2/alpn/alpn.c', 'src/core/ext/transport/chttp2/alpn/alpn.c',
'src/core/lib/http/httpcli_security_connector.c', 'src/core/lib/http/httpcli_security_connector.c',
'src/core/lib/security/b64.c', 'src/core/lib/security/context/security_context.c',
'src/core/lib/security/client_auth_filter.c', 'src/core/lib/security/credentials/composite/composite_credentials.c',
'src/core/lib/security/credentials.c', 'src/core/lib/security/credentials/credentials.c',
'src/core/lib/security/credentials_metadata.c', 'src/core/lib/security/credentials/credentials_metadata.c',
'src/core/lib/security/credentials_posix.c', 'src/core/lib/security/credentials/fake/fake_credentials.c',
'src/core/lib/security/credentials_win32.c', 'src/core/lib/security/credentials/google_default/credentials_posix.c',
'src/core/lib/security/google_default_credentials.c', 'src/core/lib/security/credentials/google_default/credentials_win32.c',
'src/core/lib/security/handshake.c', 'src/core/lib/security/credentials/google_default/google_default_credentials.c',
'src/core/lib/security/json_token.c', 'src/core/lib/security/credentials/iam/iam_credentials.c',
'src/core/lib/security/jwt_verifier.c', 'src/core/lib/security/credentials/jwt/json_token.c',
'src/core/lib/security/secure_endpoint.c', 'src/core/lib/security/credentials/jwt/jwt_credentials.c',
'src/core/lib/security/security_connector.c', 'src/core/lib/security/credentials/jwt/jwt_verifier.c',
'src/core/lib/security/security_context.c', 'src/core/lib/security/credentials/oauth2/oauth2_credentials.c',
'src/core/lib/security/server_auth_filter.c', '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/handshake.c',
'src/core/lib/security/transport/secure_endpoint.c',
'src/core/lib/security/transport/security_connector.c',
'src/core/lib/security/transport/server_auth_filter.c',
'src/core/lib/security/util/b64.c',
'src/core/lib/security/util/json_util.c',
'src/core/lib/surface/init_secure.c', 'src/core/lib/surface/init_secure.c',
'src/core/lib/tsi/fake_transport_security.c', 'src/core/lib/tsi/fake_transport_security.c',
'src/core/lib/tsi/ssl_transport_security.c', 'src/core/lib/tsi/ssl_transport_security.c',
@ -725,6 +733,7 @@
'src/core/ext/load_reporting/load_reporting.c', 'src/core/ext/load_reporting/load_reporting.c',
'src/core/ext/load_reporting/load_reporting_filter.c', 'src/core/ext/load_reporting/load_reporting_filter.c',
'src/core/ext/census/context.c', 'src/core/ext/census/context.c',
'src/core/ext/census/gen/census.pb.c',
'src/core/ext/census/grpc_context.c', 'src/core/ext/census/grpc_context.c',
'src/core/ext/census/grpc_filter.c', 'src/core/ext/census/grpc_filter.c',
'src/core/ext/census/grpc_plugin.c', 'src/core/ext/census/grpc_plugin.c',

@ -16,11 +16,13 @@ filegroups:
- src/core/ext/census/aggregation.h - src/core/ext/census/aggregation.h
- src/core/ext/census/census_interface.h - src/core/ext/census/census_interface.h
- src/core/ext/census/census_rpc_stats.h - src/core/ext/census/census_rpc_stats.h
- src/core/ext/census/gen/census.pb.h
- src/core/ext/census/grpc_filter.h - src/core/ext/census/grpc_filter.h
- src/core/ext/census/mlog.h - src/core/ext/census/mlog.h
- src/core/ext/census/rpc_metric_id.h - src/core/ext/census/rpc_metric_id.h
src: src:
- src/core/ext/census/context.c - src/core/ext/census/context.c
- src/core/ext/census/gen/census.pb.c
- src/core/ext/census/grpc_context.c - src/core/ext/census/grpc_context.c
- src/core/ext/census/grpc_filter.c - src/core/ext/census/grpc_filter.c
- src/core/ext/census/grpc_plugin.c - src/core/ext/census/grpc_plugin.c
@ -32,6 +34,7 @@ filegroups:
plugin: census_grpc_plugin plugin: census_grpc_plugin
uses: uses:
- grpc_base - grpc_base
- nanopb
- name: gpr_base - name: gpr_base
public_headers: public_headers:
- include/grpc/support/alloc.h - include/grpc/support/alloc.h
@ -416,31 +419,48 @@ filegroups:
- include/grpc/grpc_security.h - include/grpc/grpc_security.h
- include/grpc/grpc_security_constants.h - include/grpc/grpc_security_constants.h
headers: headers:
- src/core/lib/security/auth_filters.h - src/core/lib/security/context/security_context.h
- src/core/lib/security/b64.h - src/core/lib/security/credentials/composite/composite_credentials.h
- src/core/lib/security/credentials.h - src/core/lib/security/credentials/credentials.h
- src/core/lib/security/handshake.h - src/core/lib/security/credentials/fake/fake_credentials.h
- src/core/lib/security/json_token.h - src/core/lib/security/credentials/google_default/google_default_credentials.h
- src/core/lib/security/jwt_verifier.h - src/core/lib/security/credentials/iam/iam_credentials.h
- src/core/lib/security/secure_endpoint.h - src/core/lib/security/credentials/jwt/json_token.h
- src/core/lib/security/security_connector.h - src/core/lib/security/credentials/jwt/jwt_credentials.h
- src/core/lib/security/security_context.h - src/core/lib/security/credentials/jwt/jwt_verifier.h
- src/core/lib/security/credentials/oauth2/oauth2_credentials.h
- src/core/lib/security/credentials/plugin/plugin_credentials.h
- src/core/lib/security/credentials/ssl/ssl_credentials.h
- src/core/lib/security/transport/auth_filters.h
- src/core/lib/security/transport/handshake.h
- src/core/lib/security/transport/secure_endpoint.h
- src/core/lib/security/transport/security_connector.h
- src/core/lib/security/util/b64.h
- src/core/lib/security/util/json_util.h
src: src:
- src/core/lib/http/httpcli_security_connector.c - src/core/lib/http/httpcli_security_connector.c
- src/core/lib/security/b64.c - src/core/lib/security/context/security_context.c
- src/core/lib/security/client_auth_filter.c - src/core/lib/security/credentials/composite/composite_credentials.c
- src/core/lib/security/credentials.c - src/core/lib/security/credentials/credentials.c
- src/core/lib/security/credentials_metadata.c - src/core/lib/security/credentials/credentials_metadata.c
- src/core/lib/security/credentials_posix.c - src/core/lib/security/credentials/fake/fake_credentials.c
- src/core/lib/security/credentials_win32.c - src/core/lib/security/credentials/google_default/credentials_posix.c
- src/core/lib/security/google_default_credentials.c - src/core/lib/security/credentials/google_default/credentials_win32.c
- src/core/lib/security/handshake.c - src/core/lib/security/credentials/google_default/google_default_credentials.c
- src/core/lib/security/json_token.c - src/core/lib/security/credentials/iam/iam_credentials.c
- src/core/lib/security/jwt_verifier.c - src/core/lib/security/credentials/jwt/json_token.c
- src/core/lib/security/secure_endpoint.c - src/core/lib/security/credentials/jwt/jwt_credentials.c
- src/core/lib/security/security_connector.c - src/core/lib/security/credentials/jwt/jwt_verifier.c
- src/core/lib/security/security_context.c - src/core/lib/security/credentials/oauth2/oauth2_credentials.c
- src/core/lib/security/server_auth_filter.c - 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/handshake.c
- src/core/lib/security/transport/secure_endpoint.c
- src/core/lib/security/transport/security_connector.c
- src/core/lib/security/transport/server_auth_filter.c
- src/core/lib/security/util/b64.c
- src/core/lib/security/util/json_util.c
- src/core/lib/surface/init_secure.c - src/core/lib/surface/init_secure.c
secure: true secure: true
uses: uses:
@ -2351,40 +2371,6 @@ targets:
- grpc - grpc
- gpr_test_util - gpr_test_util
- gpr - gpr
- name: async_streaming_ping_pong_test
build: test
language: c++
src:
- test/cpp/qps/async_streaming_ping_pong_test.cc
deps:
- qps
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
platforms:
- mac
- linux
- posix
- name: async_unary_ping_pong_test
build: test
language: c++
src:
- test/cpp/qps/async_unary_ping_pong_test.cc
deps:
- qps
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
platforms:
- mac
- linux
- posix
- name: auth_property_iterator_test - name: auth_property_iterator_test
gtest: true gtest: true
build: test build: test
@ -2552,23 +2538,6 @@ targets:
- grpc - grpc
- gpr_test_util - gpr_test_util
- gpr - gpr
- name: generic_async_streaming_ping_pong_test
build: test
language: c++
src:
- test/cpp/qps/generic_async_streaming_ping_pong_test.cc
deps:
- qps
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
platforms:
- mac
- linux
- posix
- name: generic_end2end_test - name: generic_end2end_test
gtest: true gtest: true
build: test build: test
@ -2840,25 +2809,6 @@ targets:
- mac - mac
- linux - linux
- posix - posix
- name: qps_test
cpu_cost: 10
build: test
language: c++
src:
- test/cpp/qps/qps_test.cc
deps:
- qps
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
- grpc++_test_config
platforms:
- mac
- linux
- posix
- name: qps_worker - name: qps_worker
build: test build: test
run: false run: false
@ -3054,40 +3004,6 @@ targets:
- gpr_test_util - gpr_test_util
- gpr - gpr
- grpc++_test_config - grpc++_test_config
- name: sync_streaming_ping_pong_test
build: test
language: c++
src:
- test/cpp/qps/sync_streaming_ping_pong_test.cc
deps:
- qps
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
platforms:
- mac
- linux
- posix
- name: sync_unary_ping_pong_test
build: test
language: c++
src:
- test/cpp/qps/sync_unary_ping_pong_test.cc
deps:
- qps
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
platforms:
- mac
- linux
- posix
- name: thread_stress_test - name: thread_stress_test
gtest: true gtest: true
cpu_cost: 100 cpu_cost: 100
@ -3258,8 +3174,8 @@ configs:
compile_the_world: true compile_the_world: true
timeout_multiplier: 4 timeout_multiplier: 4
mutrace: mutrace:
CPPFLAGS: -O0 CPPFLAGS: -O3 -fno-omit-frame-pointer
DEFINES: _DEBUG DEBUG DEFINES: NDEBUG
LDFLAGS: -rdynamic LDFLAGS: -rdynamic
opt: opt:
CPPFLAGS: -O2 CPPFLAGS: -O2
@ -3290,7 +3206,7 @@ configs:
LDXX: clang++ LDXX: clang++
compile_the_world: true compile_the_world: true
test_environ: test_environ:
UBSAN_OPTIONS: print_stacktrace=1 UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1
timeout_multiplier: 1.5 timeout_multiplier: 1.5
defaults: defaults:
boringssl: boringssl:

@ -189,20 +189,28 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/transport/writing.c \
src/core/ext/transport/chttp2/alpn/alpn.c \ src/core/ext/transport/chttp2/alpn/alpn.c \
src/core/lib/http/httpcli_security_connector.c \ src/core/lib/http/httpcli_security_connector.c \
src/core/lib/security/b64.c \ src/core/lib/security/context/security_context.c \
src/core/lib/security/client_auth_filter.c \ src/core/lib/security/credentials/composite/composite_credentials.c \
src/core/lib/security/credentials.c \ src/core/lib/security/credentials/credentials.c \
src/core/lib/security/credentials_metadata.c \ src/core/lib/security/credentials/credentials_metadata.c \
src/core/lib/security/credentials_posix.c \ src/core/lib/security/credentials/fake/fake_credentials.c \
src/core/lib/security/credentials_win32.c \ src/core/lib/security/credentials/google_default/credentials_posix.c \
src/core/lib/security/google_default_credentials.c \ src/core/lib/security/credentials/google_default/credentials_win32.c \
src/core/lib/security/handshake.c \ src/core/lib/security/credentials/google_default/google_default_credentials.c \
src/core/lib/security/json_token.c \ src/core/lib/security/credentials/iam/iam_credentials.c \
src/core/lib/security/jwt_verifier.c \ src/core/lib/security/credentials/jwt/json_token.c \
src/core/lib/security/secure_endpoint.c \ src/core/lib/security/credentials/jwt/jwt_credentials.c \
src/core/lib/security/security_connector.c \ src/core/lib/security/credentials/jwt/jwt_verifier.c \
src/core/lib/security/security_context.c \ src/core/lib/security/credentials/oauth2/oauth2_credentials.c \
src/core/lib/security/server_auth_filter.c \ 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/handshake.c \
src/core/lib/security/transport/secure_endpoint.c \
src/core/lib/security/transport/security_connector.c \
src/core/lib/security/transport/server_auth_filter.c \
src/core/lib/security/util/b64.c \
src/core/lib/security/util/json_util.c \
src/core/lib/surface/init_secure.c \ src/core/lib/surface/init_secure.c \
src/core/lib/tsi/fake_transport_security.c \ src/core/lib/tsi/fake_transport_security.c \
src/core/lib/tsi/ssl_transport_security.c \ src/core/lib/tsi/ssl_transport_security.c \
@ -244,6 +252,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/load_reporting/load_reporting.c \ src/core/ext/load_reporting/load_reporting.c \
src/core/ext/load_reporting/load_reporting_filter.c \ src/core/ext/load_reporting/load_reporting_filter.c \
src/core/ext/census/context.c \ src/core/ext/census/context.c \
src/core/ext/census/gen/census.pb.c \
src/core/ext/census/grpc_context.c \ src/core/ext/census/grpc_context.c \
src/core/ext/census/grpc_filter.c \ src/core/ext/census/grpc_filter.c \
src/core/ext/census/grpc_plugin.c \ src/core/ext/census/grpc_plugin.c \
@ -559,6 +568,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl) PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census/gen)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/client_config) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/client_config)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/grpclb) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/grpclb)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1)
@ -582,7 +592,18 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/json) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/json)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/profiling) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/profiling)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/context)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/composite)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/fake)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/google_default)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/iam)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/jwt)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/oauth2)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/plugin)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/ssl)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/transport)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/util)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/support) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/support)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/surface) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/surface)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/transport) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/transport)

@ -101,7 +101,7 @@ corresponding reasons. Empty cells denote disallowed transitions.
<td>Shutdown triggered by application.</td> <td>Shutdown triggered by application.</td>
</tr> </tr>
<tr> <tr>
<th>FATAL_FAILURE</th> <th>SHUTDOWN</th>
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>

@ -32,7 +32,7 @@
CXX = g++ CXX = g++
CPPFLAGS += -I/usr/local/include -pthread CPPFLAGS += -I/usr/local/include -pthread
CXXFLAGS += -std=c++11 CXXFLAGS += -std=c++11
LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` -lprotobuf -lpthread -ldl LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++ grpc` -lprotobuf -lpthread -ldl
PROTOC = protoc PROTOC = protoc
GRPC_CPP_PLUGIN = grpc_cpp_plugin GRPC_CPP_PLUGIN = grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`

@ -259,15 +259,24 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/timeout_encoding.h', 'src/core/ext/transport/chttp2/transport/timeout_encoding.h',
'src/core/ext/transport/chttp2/transport/varint.h', 'src/core/ext/transport/chttp2/transport/varint.h',
'src/core/ext/transport/chttp2/alpn/alpn.h', 'src/core/ext/transport/chttp2/alpn/alpn.h',
'src/core/lib/security/auth_filters.h', 'src/core/lib/security/context/security_context.h',
'src/core/lib/security/b64.h', 'src/core/lib/security/credentials/composite/composite_credentials.h',
'src/core/lib/security/credentials.h', 'src/core/lib/security/credentials/credentials.h',
'src/core/lib/security/handshake.h', 'src/core/lib/security/credentials/fake/fake_credentials.h',
'src/core/lib/security/json_token.h', 'src/core/lib/security/credentials/google_default/google_default_credentials.h',
'src/core/lib/security/jwt_verifier.h', 'src/core/lib/security/credentials/iam/iam_credentials.h',
'src/core/lib/security/secure_endpoint.h', 'src/core/lib/security/credentials/jwt/json_token.h',
'src/core/lib/security/security_connector.h', 'src/core/lib/security/credentials/jwt/jwt_credentials.h',
'src/core/lib/security/security_context.h', 'src/core/lib/security/credentials/jwt/jwt_verifier.h',
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/handshake.h',
'src/core/lib/security/transport/secure_endpoint.h',
'src/core/lib/security/transport/security_connector.h',
'src/core/lib/security/util/b64.h',
'src/core/lib/security/util/json_util.h',
'src/core/lib/tsi/fake_transport_security.h', 'src/core/lib/tsi/fake_transport_security.h',
'src/core/lib/tsi/ssl_transport_security.h', 'src/core/lib/tsi/ssl_transport_security.h',
'src/core/lib/tsi/ssl_types.h', 'src/core/lib/tsi/ssl_types.h',
@ -301,6 +310,7 @@ Pod::Spec.new do |s|
'src/core/ext/census/aggregation.h', 'src/core/ext/census/aggregation.h',
'src/core/ext/census/census_interface.h', 'src/core/ext/census/census_interface.h',
'src/core/ext/census/census_rpc_stats.h', 'src/core/ext/census/census_rpc_stats.h',
'src/core/ext/census/gen/census.pb.h',
'src/core/ext/census/grpc_filter.h', 'src/core/ext/census/grpc_filter.h',
'src/core/ext/census/mlog.h', 'src/core/ext/census/mlog.h',
'src/core/ext/census/rpc_metric_id.h', 'src/core/ext/census/rpc_metric_id.h',
@ -441,20 +451,28 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/transport/writing.c',
'src/core/ext/transport/chttp2/alpn/alpn.c', 'src/core/ext/transport/chttp2/alpn/alpn.c',
'src/core/lib/http/httpcli_security_connector.c', 'src/core/lib/http/httpcli_security_connector.c',
'src/core/lib/security/b64.c', 'src/core/lib/security/context/security_context.c',
'src/core/lib/security/client_auth_filter.c', 'src/core/lib/security/credentials/composite/composite_credentials.c',
'src/core/lib/security/credentials.c', 'src/core/lib/security/credentials/credentials.c',
'src/core/lib/security/credentials_metadata.c', 'src/core/lib/security/credentials/credentials_metadata.c',
'src/core/lib/security/credentials_posix.c', 'src/core/lib/security/credentials/fake/fake_credentials.c',
'src/core/lib/security/credentials_win32.c', 'src/core/lib/security/credentials/google_default/credentials_posix.c',
'src/core/lib/security/google_default_credentials.c', 'src/core/lib/security/credentials/google_default/credentials_win32.c',
'src/core/lib/security/handshake.c', 'src/core/lib/security/credentials/google_default/google_default_credentials.c',
'src/core/lib/security/json_token.c', 'src/core/lib/security/credentials/iam/iam_credentials.c',
'src/core/lib/security/jwt_verifier.c', 'src/core/lib/security/credentials/jwt/json_token.c',
'src/core/lib/security/secure_endpoint.c', 'src/core/lib/security/credentials/jwt/jwt_credentials.c',
'src/core/lib/security/security_connector.c', 'src/core/lib/security/credentials/jwt/jwt_verifier.c',
'src/core/lib/security/security_context.c', 'src/core/lib/security/credentials/oauth2/oauth2_credentials.c',
'src/core/lib/security/server_auth_filter.c', '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/handshake.c',
'src/core/lib/security/transport/secure_endpoint.c',
'src/core/lib/security/transport/security_connector.c',
'src/core/lib/security/transport/server_auth_filter.c',
'src/core/lib/security/util/b64.c',
'src/core/lib/security/util/json_util.c',
'src/core/lib/surface/init_secure.c', 'src/core/lib/surface/init_secure.c',
'src/core/lib/tsi/fake_transport_security.c', 'src/core/lib/tsi/fake_transport_security.c',
'src/core/lib/tsi/ssl_transport_security.c', 'src/core/lib/tsi/ssl_transport_security.c',
@ -496,6 +514,7 @@ Pod::Spec.new do |s|
'src/core/ext/load_reporting/load_reporting.c', 'src/core/ext/load_reporting/load_reporting.c',
'src/core/ext/load_reporting/load_reporting_filter.c', 'src/core/ext/load_reporting/load_reporting_filter.c',
'src/core/ext/census/context.c', 'src/core/ext/census/context.c',
'src/core/ext/census/gen/census.pb.c',
'src/core/ext/census/grpc_context.c', 'src/core/ext/census/grpc_context.c',
'src/core/ext/census/grpc_filter.c', 'src/core/ext/census/grpc_filter.c',
'src/core/ext/census/grpc_plugin.c', 'src/core/ext/census/grpc_plugin.c',
@ -613,15 +632,24 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/timeout_encoding.h', 'src/core/ext/transport/chttp2/transport/timeout_encoding.h',
'src/core/ext/transport/chttp2/transport/varint.h', 'src/core/ext/transport/chttp2/transport/varint.h',
'src/core/ext/transport/chttp2/alpn/alpn.h', 'src/core/ext/transport/chttp2/alpn/alpn.h',
'src/core/lib/security/auth_filters.h', 'src/core/lib/security/context/security_context.h',
'src/core/lib/security/b64.h', 'src/core/lib/security/credentials/composite/composite_credentials.h',
'src/core/lib/security/credentials.h', 'src/core/lib/security/credentials/credentials.h',
'src/core/lib/security/handshake.h', 'src/core/lib/security/credentials/fake/fake_credentials.h',
'src/core/lib/security/json_token.h', 'src/core/lib/security/credentials/google_default/google_default_credentials.h',
'src/core/lib/security/jwt_verifier.h', 'src/core/lib/security/credentials/iam/iam_credentials.h',
'src/core/lib/security/secure_endpoint.h', 'src/core/lib/security/credentials/jwt/json_token.h',
'src/core/lib/security/security_connector.h', 'src/core/lib/security/credentials/jwt/jwt_credentials.h',
'src/core/lib/security/security_context.h', 'src/core/lib/security/credentials/jwt/jwt_verifier.h',
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
'src/core/lib/security/transport/auth_filters.h',
'src/core/lib/security/transport/handshake.h',
'src/core/lib/security/transport/secure_endpoint.h',
'src/core/lib/security/transport/security_connector.h',
'src/core/lib/security/util/b64.h',
'src/core/lib/security/util/json_util.h',
'src/core/lib/tsi/fake_transport_security.h', 'src/core/lib/tsi/fake_transport_security.h',
'src/core/lib/tsi/ssl_transport_security.h', 'src/core/lib/tsi/ssl_transport_security.h',
'src/core/lib/tsi/ssl_types.h', 'src/core/lib/tsi/ssl_types.h',
@ -655,6 +683,7 @@ Pod::Spec.new do |s|
'src/core/ext/census/aggregation.h', 'src/core/ext/census/aggregation.h',
'src/core/ext/census/census_interface.h', 'src/core/ext/census/census_interface.h',
'src/core/ext/census/census_rpc_stats.h', 'src/core/ext/census/census_rpc_stats.h',
'src/core/ext/census/gen/census.pb.h',
'src/core/ext/census/grpc_filter.h', 'src/core/ext/census/grpc_filter.h',
'src/core/ext/census/mlog.h', 'src/core/ext/census/mlog.h',
'src/core/ext/census/rpc_metric_id.h' 'src/core/ext/census/rpc_metric_id.h'

@ -77,6 +77,7 @@ EXPORTS
grpc_server_request_registered_call grpc_server_request_registered_call
grpc_server_create grpc_server_create
grpc_server_register_completion_queue grpc_server_register_completion_queue
grpc_server_register_non_listening_completion_queue
grpc_server_add_insecure_http2_port grpc_server_add_insecure_http2_port
grpc_server_start grpc_server_start
grpc_server_shutdown_and_notify grpc_server_shutdown_and_notify

@ -268,15 +268,24 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/transport/timeout_encoding.h ) s.files += %w( src/core/ext/transport/chttp2/transport/timeout_encoding.h )
s.files += %w( src/core/ext/transport/chttp2/transport/varint.h ) s.files += %w( src/core/ext/transport/chttp2/transport/varint.h )
s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.h ) s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.h )
s.files += %w( src/core/lib/security/auth_filters.h ) s.files += %w( src/core/lib/security/context/security_context.h )
s.files += %w( src/core/lib/security/b64.h ) s.files += %w( src/core/lib/security/credentials/composite/composite_credentials.h )
s.files += %w( src/core/lib/security/credentials.h ) s.files += %w( src/core/lib/security/credentials/credentials.h )
s.files += %w( src/core/lib/security/handshake.h ) s.files += %w( src/core/lib/security/credentials/fake/fake_credentials.h )
s.files += %w( src/core/lib/security/json_token.h ) s.files += %w( src/core/lib/security/credentials/google_default/google_default_credentials.h )
s.files += %w( src/core/lib/security/jwt_verifier.h ) s.files += %w( src/core/lib/security/credentials/iam/iam_credentials.h )
s.files += %w( src/core/lib/security/secure_endpoint.h ) s.files += %w( src/core/lib/security/credentials/jwt/json_token.h )
s.files += %w( src/core/lib/security/security_connector.h ) s.files += %w( src/core/lib/security/credentials/jwt/jwt_credentials.h )
s.files += %w( src/core/lib/security/security_context.h ) s.files += %w( src/core/lib/security/credentials/jwt/jwt_verifier.h )
s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.h )
s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h )
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h )
s.files += %w( src/core/lib/security/transport/auth_filters.h )
s.files += %w( src/core/lib/security/transport/handshake.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/util/b64.h )
s.files += %w( src/core/lib/security/util/json_util.h )
s.files += %w( src/core/lib/tsi/fake_transport_security.h ) s.files += %w( src/core/lib/tsi/fake_transport_security.h )
s.files += %w( src/core/lib/tsi/ssl_transport_security.h ) s.files += %w( src/core/lib/tsi/ssl_transport_security.h )
s.files += %w( src/core/lib/tsi/ssl_types.h ) s.files += %w( src/core/lib/tsi/ssl_types.h )
@ -310,6 +319,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/census/aggregation.h ) s.files += %w( src/core/ext/census/aggregation.h )
s.files += %w( src/core/ext/census/census_interface.h ) s.files += %w( src/core/ext/census/census_interface.h )
s.files += %w( src/core/ext/census/census_rpc_stats.h ) s.files += %w( src/core/ext/census/census_rpc_stats.h )
s.files += %w( src/core/ext/census/gen/census.pb.h )
s.files += %w( src/core/ext/census/grpc_filter.h ) s.files += %w( src/core/ext/census/grpc_filter.h )
s.files += %w( src/core/ext/census/mlog.h ) s.files += %w( src/core/ext/census/mlog.h )
s.files += %w( src/core/ext/census/rpc_metric_id.h ) s.files += %w( src/core/ext/census/rpc_metric_id.h )
@ -420,20 +430,28 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/transport/writing.c ) s.files += %w( src/core/ext/transport/chttp2/transport/writing.c )
s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.c ) s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.c )
s.files += %w( src/core/lib/http/httpcli_security_connector.c ) s.files += %w( src/core/lib/http/httpcli_security_connector.c )
s.files += %w( src/core/lib/security/b64.c ) s.files += %w( src/core/lib/security/context/security_context.c )
s.files += %w( src/core/lib/security/client_auth_filter.c ) s.files += %w( src/core/lib/security/credentials/composite/composite_credentials.c )
s.files += %w( src/core/lib/security/credentials.c ) s.files += %w( src/core/lib/security/credentials/credentials.c )
s.files += %w( src/core/lib/security/credentials_metadata.c ) s.files += %w( src/core/lib/security/credentials/credentials_metadata.c )
s.files += %w( src/core/lib/security/credentials_posix.c ) s.files += %w( src/core/lib/security/credentials/fake/fake_credentials.c )
s.files += %w( src/core/lib/security/credentials_win32.c ) s.files += %w( src/core/lib/security/credentials/google_default/credentials_posix.c )
s.files += %w( src/core/lib/security/google_default_credentials.c ) s.files += %w( src/core/lib/security/credentials/google_default/credentials_win32.c )
s.files += %w( src/core/lib/security/handshake.c ) s.files += %w( src/core/lib/security/credentials/google_default/google_default_credentials.c )
s.files += %w( src/core/lib/security/json_token.c ) s.files += %w( src/core/lib/security/credentials/iam/iam_credentials.c )
s.files += %w( src/core/lib/security/jwt_verifier.c ) s.files += %w( src/core/lib/security/credentials/jwt/json_token.c )
s.files += %w( src/core/lib/security/secure_endpoint.c ) s.files += %w( src/core/lib/security/credentials/jwt/jwt_credentials.c )
s.files += %w( src/core/lib/security/security_connector.c ) s.files += %w( src/core/lib/security/credentials/jwt/jwt_verifier.c )
s.files += %w( src/core/lib/security/security_context.c ) s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.c )
s.files += %w( src/core/lib/security/server_auth_filter.c ) 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/handshake.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/server_auth_filter.c )
s.files += %w( src/core/lib/security/util/b64.c )
s.files += %w( src/core/lib/security/util/json_util.c )
s.files += %w( src/core/lib/surface/init_secure.c ) s.files += %w( src/core/lib/surface/init_secure.c )
s.files += %w( src/core/lib/tsi/fake_transport_security.c ) s.files += %w( src/core/lib/tsi/fake_transport_security.c )
s.files += %w( src/core/lib/tsi/ssl_transport_security.c ) s.files += %w( src/core/lib/tsi/ssl_transport_security.c )
@ -475,6 +493,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/load_reporting/load_reporting.c ) s.files += %w( src/core/ext/load_reporting/load_reporting.c )
s.files += %w( src/core/ext/load_reporting/load_reporting_filter.c ) s.files += %w( src/core/ext/load_reporting/load_reporting_filter.c )
s.files += %w( src/core/ext/census/context.c ) s.files += %w( src/core/ext/census/context.c )
s.files += %w( src/core/ext/census/gen/census.pb.c )
s.files += %w( src/core/ext/census/grpc_context.c ) s.files += %w( src/core/ext/census/grpc_context.c )
s.files += %w( src/core/ext/census/grpc_filter.c ) s.files += %w( src/core/ext/census/grpc_filter.c )
s.files += %w( src/core/ext/census/grpc_plugin.c ) s.files += %w( src/core/ext/census/grpc_plugin.c )

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -222,9 +222,18 @@ class CompletionQueue : private GrpcLibraryCodegen {
/// A specific type of completion queue used by the processing of notifications /// A specific type of completion queue used by the processing of notifications
/// by servers. Instantiated by \a ServerBuilder. /// by servers. Instantiated by \a ServerBuilder.
class ServerCompletionQueue : public CompletionQueue { class ServerCompletionQueue : public CompletionQueue {
public:
bool IsFrequentlyPolled() { return is_frequently_polled_; }
private: private:
bool is_frequently_polled_;
friend class ServerBuilder; friend class ServerBuilder;
ServerCompletionQueue() {} /// \param is_frequently_polled Informs the GPRC library about whether the
/// server completion queue would be actively polled (by calling Next() or
/// AsyncNext()). By default all server completion queues are assumed to be
/// frequently polled.
ServerCompletionQueue(bool is_frequently_polled = true)
: is_frequently_polled_(is_frequently_polled) {}
}; };
} // namespace grpc } // namespace grpc

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -108,7 +108,15 @@ class ServerBuilder {
/// Add a completion queue for handling asynchronous services /// Add a completion queue for handling asynchronous services
/// Caller is required to keep this completion queue live until /// Caller is required to keep this completion queue live until
/// the server is destroyed. /// the server is destroyed.
std::unique_ptr<ServerCompletionQueue> AddCompletionQueue(); ///
/// \param is_frequently_polled This is an optional parameter to inform GRPC
/// library about whether this completion queue would be frequently polled
/// (i.e by calling Next() or AsyncNext()). The default value is 'true' and is
/// the recommended setting. Setting this to 'false' (i.e not polling the
/// completion queue frequently) will have a significantly negative
/// performance impact and hence should not be used in production use cases.
std::unique_ptr<ServerCompletionQueue> AddCompletionQueue(
bool is_frequently_polled = true);
/// Return a running server which is ready for processing calls. /// Return a running server which is ready for processing calls.
std::unique_ptr<Server> BuildAndStart(); std::unique_ptr<Server> BuildAndStart();

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -334,6 +334,15 @@ GRPCAPI void grpc_server_register_completion_queue(grpc_server *server,
grpc_completion_queue *cq, grpc_completion_queue *cq,
void *reserved); void *reserved);
/** Register a non-listening completion queue with the server. This API is
similar to grpc_server_register_completion_queue except that the server will
not use this completion_queue to listen to any incoming channels.
Registering a non-listening completion queue will have negative performance
impact and hence this API is not recommended for production use cases. */
GRPCAPI void grpc_server_register_non_listening_completion_queue(
grpc_server *server, grpc_completion_queue *q, void *reserved);
/** Add a HTTP2 over plaintext over tcp listener. /** Add a HTTP2 over plaintext over tcp listener.
Returns bound port number on success, 0 on failure. Returns bound port number on success, 0 on failure.
REQUIRES: server not started */ REQUIRES: server not started */

@ -275,15 +275,24 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/timeout_encoding.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/timeout_encoding.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/varint.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/varint.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/alpn/alpn.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/alpn/alpn.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/auth_filters.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/context/security_context.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/b64.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/composite/composite_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/handshake.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/fake/fake_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/json_token.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/google_default/google_default_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/jwt_verifier.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/iam/iam_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/secure_endpoint.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/json_token.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/security_connector.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/security_context.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_verifier.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/handshake.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/util/b64.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/json_util.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/tsi/fake_transport_security.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/tsi/fake_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/tsi/ssl_transport_security.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/tsi/ssl_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/tsi/ssl_types.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/tsi/ssl_types.h" role="src" />
@ -317,6 +326,7 @@
<file baseinstalldir="/" name="src/core/ext/census/aggregation.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/census/aggregation.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/census_interface.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/census/census_interface.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/census_rpc_stats.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/census/census_rpc_stats.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/grpc_filter.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/census/grpc_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/mlog.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/census/mlog.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/rpc_metric_id.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/census/rpc_metric_id.h" role="src" />
@ -427,20 +437,28 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/writing.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/writing.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/alpn/alpn.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/alpn/alpn.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/httpcli_security_connector.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/http/httpcli_security_connector.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/b64.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/context/security_context.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/client_auth_filter.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/composite/composite_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials_metadata.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/credentials_metadata.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials_posix.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/fake/fake_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials_win32.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/google_default/credentials_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/google_default_credentials.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/google_default/credentials_win32.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/handshake.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/google_default/google_default_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/json_token.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/iam/iam_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/jwt_verifier.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/json_token.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/secure_endpoint.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/security_connector.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/jwt_verifier.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/security_context.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/server_auth_filter.c" role="src" /> <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/handshake.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/server_auth_filter.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/b64.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/json_util.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/init_secure.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/surface/init_secure.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/tsi/fake_transport_security.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/tsi/fake_transport_security.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/tsi/ssl_transport_security.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/tsi/ssl_transport_security.c" role="src" />
@ -482,6 +500,7 @@
<file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting_filter.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting_filter.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/context.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/census/context.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/grpc_context.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/census/grpc_context.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/grpc_filter.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/census/grpc_filter.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/grpc_plugin.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/census/grpc_plugin.c" role="src" />

@ -0,0 +1,6 @@
Files generated for use by Census stats and trace recording subsystem.
#Files
* census.pb.{h,c} - Generated from src/core/ext/census/census.proto, using the
script `tools/codegen/core/gen_nano_proto.sh src/proto/census/census.proto
$PWD/src/core/ext/census/gen src/core/ext/census/gen`

@ -0,0 +1,179 @@
/*
*
* 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.
*
*/
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.5-dev */
#include "src/core/ext/census/gen/census.pb.h"
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
const pb_field_t google_census_Duration_fields[3] = {
PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, google_census_Duration, seconds, seconds, 0),
PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, google_census_Duration, nanos, seconds, 0),
PB_LAST_FIELD
};
const pb_field_t google_census_Timestamp_fields[3] = {
PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, google_census_Timestamp, seconds, seconds, 0),
PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, google_census_Timestamp, nanos, seconds, 0),
PB_LAST_FIELD
};
const pb_field_t google_census_Metric_fields[5] = {
PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Metric, name, name, 0),
PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_Metric, description, name, 0),
PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, unit, description, &google_census_Metric_MeasurementUnit_fields),
PB_FIELD( 4, INT32 , OPTIONAL, STATIC , OTHER, google_census_Metric, id, unit, 0),
PB_LAST_FIELD
};
const pb_field_t google_census_Metric_BasicUnit_fields[2] = {
PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, google_census_Metric_BasicUnit, type, type, 0),
PB_LAST_FIELD
};
const pb_field_t google_census_Metric_MeasurementUnit_fields[4] = {
PB_FIELD( 1, INT32 , OPTIONAL, STATIC , FIRST, google_census_Metric_MeasurementUnit, prefix, prefix, 0),
PB_FIELD( 2, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Metric_MeasurementUnit, numerator, prefix, &google_census_Metric_BasicUnit_fields),
PB_FIELD( 3, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Metric_MeasurementUnit, denominator, numerator, &google_census_Metric_BasicUnit_fields),
PB_LAST_FIELD
};
const pb_field_t google_census_AggregationDescriptor_fields[3] = {
PB_ONEOF_FIELD(options, 1, MESSAGE , ONEOF, STATIC , FIRST, google_census_AggregationDescriptor, bucket_boundaries, bucket_boundaries, &google_census_AggregationDescriptor_BucketBoundaries_fields),
PB_ONEOF_FIELD(options, 2, MESSAGE , ONEOF, STATIC , FIRST, google_census_AggregationDescriptor, interval_boundaries, interval_boundaries, &google_census_AggregationDescriptor_IntervalBoundaries_fields),
PB_LAST_FIELD
};
const pb_field_t google_census_AggregationDescriptor_BucketBoundaries_fields[2] = {
PB_FIELD( 1, DOUBLE , REPEATED, CALLBACK, FIRST, google_census_AggregationDescriptor_BucketBoundaries, bounds, bounds, 0),
PB_LAST_FIELD
};
const pb_field_t google_census_AggregationDescriptor_IntervalBoundaries_fields[2] = {
PB_FIELD( 1, DOUBLE , REPEATED, CALLBACK, FIRST, google_census_AggregationDescriptor_IntervalBoundaries, window_size, window_size, 0),
PB_LAST_FIELD
};
const pb_field_t google_census_Distribution_fields[5] = {
PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, google_census_Distribution, count, count, 0),
PB_FIELD( 2, DOUBLE , OPTIONAL, STATIC , OTHER, google_census_Distribution, mean, count, 0),
PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Distribution, range, mean, &google_census_Distribution_Range_fields),
PB_FIELD( 4, INT64 , REPEATED, CALLBACK, OTHER, google_census_Distribution, bucket_count, range, 0),
PB_LAST_FIELD
};
const pb_field_t google_census_Distribution_Range_fields[3] = {
PB_FIELD( 1, DOUBLE , OPTIONAL, STATIC , FIRST, google_census_Distribution_Range, min, min, 0),
PB_FIELD( 2, DOUBLE , OPTIONAL, STATIC , OTHER, google_census_Distribution_Range, max, min, 0),
PB_LAST_FIELD
};
const pb_field_t google_census_IntervalStats_fields[2] = {
PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, google_census_IntervalStats, window, window, &google_census_IntervalStats_Window_fields),
PB_LAST_FIELD
};
const pb_field_t google_census_IntervalStats_Window_fields[4] = {
PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, google_census_IntervalStats_Window, window_size, window_size, &google_census_Duration_fields),
PB_FIELD( 2, INT64 , OPTIONAL, STATIC , OTHER, google_census_IntervalStats_Window, count, window_size, 0),
PB_FIELD( 3, DOUBLE , OPTIONAL, STATIC , OTHER, google_census_IntervalStats_Window, mean, count, 0),
PB_LAST_FIELD
};
const pb_field_t google_census_Tag_fields[3] = {
PB_FIELD( 1, STRING , OPTIONAL, STATIC , FIRST, google_census_Tag, key, key, 0),
PB_FIELD( 2, STRING , OPTIONAL, STATIC , OTHER, google_census_Tag, value, key, 0),
PB_LAST_FIELD
};
const pb_field_t google_census_View_fields[6] = {
PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_View, name, name, 0),
PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_View, description, name, 0),
PB_FIELD( 3, INT32 , OPTIONAL, STATIC , OTHER, google_census_View, metric_id, description, 0),
PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_View, aggregation, metric_id, &google_census_AggregationDescriptor_fields),
PB_FIELD( 5, STRING , REPEATED, CALLBACK, OTHER, google_census_View, tag_key, aggregation, 0),
PB_LAST_FIELD
};
const pb_field_t google_census_Aggregation_fields[6] = {
PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Aggregation, name, name, 0),
PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_Aggregation, description, name, 0),
PB_ONEOF_FIELD(data, 3, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, distribution, description, &google_census_Distribution_fields),
PB_ONEOF_FIELD(data, 4, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, interval_stats, description, &google_census_IntervalStats_fields),
PB_FIELD( 5, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Aggregation, tag, data.interval_stats, &google_census_Tag_fields),
PB_LAST_FIELD
};
const pb_field_t google_census_ViewAggregations_fields[4] = {
PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, google_census_ViewAggregations, aggregation, aggregation, &google_census_Aggregation_fields),
PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_ViewAggregations, start, aggregation, &google_census_Timestamp_fields),
PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_ViewAggregations, end, start, &google_census_Timestamp_fields),
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_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Aggregation, tag) < 65536 && pb_membersize(google_census_ViewAggregations, aggregation) < 65536 && pb_membersize(google_census_ViewAggregations, start) < 65536 && pb_membersize(google_census_ViewAggregations, end) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Metric_google_census_Metric_BasicUnit_google_census_Metric_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_ViewAggregations)
#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_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Aggregation, tag) < 256 && pb_membersize(google_census_ViewAggregations, aggregation) < 256 && pb_membersize(google_census_ViewAggregations, start) < 256 && pb_membersize(google_census_ViewAggregations, end) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Metric_google_census_Metric_BasicUnit_google_census_Metric_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_ViewAggregations)
#endif
/* On some platforms (such as AVR), double is really float.
* These are not directly supported by nanopb, but see example_avr_double.
* To get rid of this error, remove any double fields from your .proto.
*/
PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)

@ -0,0 +1,294 @@
/*
*
* 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.
*
*/
/* Automatically generated nanopb header */
/* Generated by nanopb-0.3.5-dev */
#ifndef GRPC_CORE_EXT_CENSUS_GEN_CENSUS_PB_H
#define GRPC_CORE_EXT_CENSUS_GEN_CENSUS_PB_H
#include "third_party/nanopb/pb.h"
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Enum definitions */
typedef enum _google_census_Metric_BasicUnit_Measure {
google_census_Metric_BasicUnit_Measure_UNKNOWN = 0,
google_census_Metric_BasicUnit_Measure_BITS = 1,
google_census_Metric_BasicUnit_Measure_BYTES = 2,
google_census_Metric_BasicUnit_Measure_SECS = 3,
google_census_Metric_BasicUnit_Measure_CORES = 4,
google_census_Metric_BasicUnit_Measure_MAX_UNITS = 5
} google_census_Metric_BasicUnit_Measure;
/* Struct definitions */
typedef struct _google_census_AggregationDescriptor_BucketBoundaries {
pb_callback_t bounds;
} google_census_AggregationDescriptor_BucketBoundaries;
typedef struct _google_census_AggregationDescriptor_IntervalBoundaries {
pb_callback_t window_size;
} google_census_AggregationDescriptor_IntervalBoundaries;
typedef struct _google_census_IntervalStats {
pb_callback_t window;
} google_census_IntervalStats;
typedef struct _google_census_AggregationDescriptor {
pb_size_t which_options;
union {
google_census_AggregationDescriptor_BucketBoundaries bucket_boundaries;
google_census_AggregationDescriptor_IntervalBoundaries interval_boundaries;
} options;
} google_census_AggregationDescriptor;
typedef struct _google_census_Distribution_Range {
bool has_min;
double min;
bool has_max;
double max;
} google_census_Distribution_Range;
typedef struct _google_census_Duration {
bool has_seconds;
int64_t seconds;
bool has_nanos;
int32_t nanos;
} google_census_Duration;
typedef struct _google_census_Metric_BasicUnit {
bool has_type;
google_census_Metric_BasicUnit_Measure type;
} google_census_Metric_BasicUnit;
typedef struct _google_census_Metric_MeasurementUnit {
bool has_prefix;
int32_t prefix;
pb_callback_t numerator;
pb_callback_t denominator;
} google_census_Metric_MeasurementUnit;
typedef struct _google_census_Tag {
bool has_key;
char key[255];
bool has_value;
char value[255];
} google_census_Tag;
typedef struct _google_census_Timestamp {
bool has_seconds;
int64_t seconds;
bool has_nanos;
int32_t nanos;
} google_census_Timestamp;
typedef struct _google_census_Distribution {
bool has_count;
int64_t count;
bool has_mean;
double mean;
bool has_range;
google_census_Distribution_Range range;
pb_callback_t bucket_count;
} google_census_Distribution;
typedef struct _google_census_IntervalStats_Window {
bool has_window_size;
google_census_Duration window_size;
bool has_count;
int64_t count;
bool has_mean;
double mean;
} google_census_IntervalStats_Window;
typedef struct _google_census_Metric {
pb_callback_t name;
pb_callback_t description;
bool has_unit;
google_census_Metric_MeasurementUnit unit;
bool has_id;
int32_t id;
} google_census_Metric;
typedef struct _google_census_View {
pb_callback_t name;
pb_callback_t description;
bool has_metric_id;
int32_t metric_id;
bool has_aggregation;
google_census_AggregationDescriptor aggregation;
pb_callback_t tag_key;
} google_census_View;
typedef struct _google_census_ViewAggregations {
pb_callback_t aggregation;
bool has_start;
google_census_Timestamp start;
bool has_end;
google_census_Timestamp end;
} google_census_ViewAggregations;
typedef struct _google_census_Aggregation {
pb_callback_t name;
pb_callback_t description;
pb_size_t which_data;
union {
google_census_Distribution distribution;
google_census_IntervalStats interval_stats;
} data;
pb_callback_t tag;
} google_census_Aggregation;
/* Default values for struct fields */
/* Initializer values for message structs */
#define google_census_Duration_init_default {false, 0, false, 0}
#define google_census_Timestamp_init_default {false, 0, false, 0}
#define google_census_Metric_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Metric_MeasurementUnit_init_default, false, 0}
#define google_census_Metric_BasicUnit_init_default {false, (google_census_Metric_BasicUnit_Measure)0}
#define google_census_Metric_MeasurementUnit_init_default {false, 0, {{NULL}, NULL}, {{NULL}, NULL}}
#define google_census_AggregationDescriptor_init_default {0, {google_census_AggregationDescriptor_BucketBoundaries_init_default}}
#define google_census_AggregationDescriptor_BucketBoundaries_init_default {{{NULL}, NULL}}
#define google_census_AggregationDescriptor_IntervalBoundaries_init_default {{{NULL}, NULL}}
#define google_census_Distribution_init_default {false, 0, false, 0, false, google_census_Distribution_Range_init_default, {{NULL}, NULL}}
#define google_census_Distribution_Range_init_default {false, 0, false, 0}
#define google_census_IntervalStats_init_default {{{NULL}, NULL}}
#define google_census_IntervalStats_Window_init_default {false, google_census_Duration_init_default, false, 0, false, 0}
#define google_census_Tag_init_default {false, "", false, ""}
#define google_census_View_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, 0, false, google_census_AggregationDescriptor_init_default, {{NULL}, NULL}}
#define google_census_Aggregation_init_default {{{NULL}, NULL}, {{NULL}, NULL}, 0, {google_census_Distribution_init_default}, {{NULL}, NULL}}
#define google_census_ViewAggregations_init_default {{{NULL}, NULL}, false, google_census_Timestamp_init_default, false, google_census_Timestamp_init_default}
#define google_census_Duration_init_zero {false, 0, false, 0}
#define google_census_Timestamp_init_zero {false, 0, false, 0}
#define google_census_Metric_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Metric_MeasurementUnit_init_zero, false, 0}
#define google_census_Metric_BasicUnit_init_zero {false, (google_census_Metric_BasicUnit_Measure)0}
#define google_census_Metric_MeasurementUnit_init_zero {false, 0, {{NULL}, NULL}, {{NULL}, NULL}}
#define google_census_AggregationDescriptor_init_zero {0, {google_census_AggregationDescriptor_BucketBoundaries_init_zero}}
#define google_census_AggregationDescriptor_BucketBoundaries_init_zero {{{NULL}, NULL}}
#define google_census_AggregationDescriptor_IntervalBoundaries_init_zero {{{NULL}, NULL}}
#define google_census_Distribution_init_zero {false, 0, false, 0, false, google_census_Distribution_Range_init_zero, {{NULL}, NULL}}
#define google_census_Distribution_Range_init_zero {false, 0, false, 0}
#define google_census_IntervalStats_init_zero {{{NULL}, NULL}}
#define google_census_IntervalStats_Window_init_zero {false, google_census_Duration_init_zero, false, 0, false, 0}
#define google_census_Tag_init_zero {false, "", false, ""}
#define google_census_View_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, 0, false, google_census_AggregationDescriptor_init_zero, {{NULL}, NULL}}
#define google_census_Aggregation_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, 0, {google_census_Distribution_init_zero}, {{NULL}, NULL}}
#define google_census_ViewAggregations_init_zero {{{NULL}, NULL}, false, google_census_Timestamp_init_zero, false, google_census_Timestamp_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define google_census_AggregationDescriptor_BucketBoundaries_bounds_tag 1
#define google_census_AggregationDescriptor_IntervalBoundaries_window_size_tag 1
#define google_census_IntervalStats_window_tag 1
#define google_census_AggregationDescriptor_bucket_boundaries_tag 1
#define google_census_AggregationDescriptor_interval_boundaries_tag 2
#define google_census_Distribution_Range_min_tag 1
#define google_census_Distribution_Range_max_tag 2
#define google_census_Duration_seconds_tag 1
#define google_census_Duration_nanos_tag 2
#define google_census_Metric_BasicUnit_type_tag 1
#define google_census_Metric_MeasurementUnit_prefix_tag 1
#define google_census_Metric_MeasurementUnit_numerator_tag 2
#define google_census_Metric_MeasurementUnit_denominator_tag 3
#define google_census_Tag_key_tag 1
#define google_census_Tag_value_tag 2
#define google_census_Timestamp_seconds_tag 1
#define google_census_Timestamp_nanos_tag 2
#define google_census_Distribution_count_tag 1
#define google_census_Distribution_mean_tag 2
#define google_census_Distribution_range_tag 3
#define google_census_Distribution_bucket_count_tag 4
#define google_census_IntervalStats_Window_window_size_tag 1
#define google_census_IntervalStats_Window_count_tag 2
#define google_census_IntervalStats_Window_mean_tag 3
#define google_census_Metric_name_tag 1
#define google_census_Metric_description_tag 2
#define google_census_Metric_unit_tag 3
#define google_census_Metric_id_tag 4
#define google_census_View_name_tag 1
#define google_census_View_description_tag 2
#define google_census_View_metric_id_tag 3
#define google_census_View_aggregation_tag 4
#define google_census_View_tag_key_tag 5
#define google_census_ViewAggregations_aggregation_tag 1
#define google_census_ViewAggregations_start_tag 2
#define google_census_ViewAggregations_end_tag 3
#define google_census_Aggregation_distribution_tag 3
#define google_census_Aggregation_interval_stats_tag 4
#define google_census_Aggregation_name_tag 1
#define google_census_Aggregation_description_tag 2
#define google_census_Aggregation_tag_tag 5
/* Struct field encoding specification for nanopb */
extern const pb_field_t google_census_Duration_fields[3];
extern const pb_field_t google_census_Timestamp_fields[3];
extern const pb_field_t google_census_Metric_fields[5];
extern const pb_field_t google_census_Metric_BasicUnit_fields[2];
extern const pb_field_t google_census_Metric_MeasurementUnit_fields[4];
extern const pb_field_t google_census_AggregationDescriptor_fields[3];
extern const pb_field_t google_census_AggregationDescriptor_BucketBoundaries_fields[2];
extern const pb_field_t google_census_AggregationDescriptor_IntervalBoundaries_fields[2];
extern const pb_field_t google_census_Distribution_fields[5];
extern const pb_field_t google_census_Distribution_Range_fields[3];
extern const pb_field_t google_census_IntervalStats_fields[2];
extern const pb_field_t google_census_IntervalStats_Window_fields[4];
extern const pb_field_t google_census_Tag_fields[3];
extern const pb_field_t google_census_View_fields[6];
extern const pb_field_t google_census_Aggregation_fields[6];
extern const pb_field_t google_census_ViewAggregations_fields[4];
/* Maximum encoded size of messages (where known) */
#define google_census_Duration_size 22
#define google_census_Timestamp_size 22
#define google_census_Metric_BasicUnit_size 2
#define google_census_Distribution_Range_size 18
#define google_census_IntervalStats_Window_size 44
#define google_census_Tag_size 516
/* Message IDs (where set with "msgid" option) */
#ifdef PB_MSGID
#define CENSUS_MESSAGES \
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

@ -320,7 +320,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
c->filters = NULL; c->filters = NULL;
} }
c->addr = gpr_malloc(args->addr_len); c->addr = gpr_malloc(args->addr_len);
memcpy(c->addr, args->addr, args->addr_len); if (args->addr_len) memcpy(c->addr, args->addr, args->addr_len);
c->pollset_set = grpc_pollset_set_create(); c->pollset_set = grpc_pollset_set_create();
c->addr_len = args->addr_len; c->addr_len = args->addr_len;
grpc_set_initial_connect_string(&c->addr, &c->addr_len, grpc_set_initial_connect_string(&c->addr, &c->addr_len,

@ -77,12 +77,19 @@ static grpc_subchannel_key *create_key(
grpc_subchannel_key *k = gpr_malloc(sizeof(*k)); grpc_subchannel_key *k = gpr_malloc(sizeof(*k));
k->connector = grpc_connector_ref(connector); k->connector = grpc_connector_ref(connector);
k->args.filter_count = args->filter_count; k->args.filter_count = args->filter_count;
k->args.filters = gpr_malloc(sizeof(*k->args.filters) * k->args.filter_count); if (k->args.filter_count > 0) {
memcpy((grpc_channel_filter *)k->args.filters, args->filters, k->args.filters =
sizeof(*k->args.filters) * k->args.filter_count); gpr_malloc(sizeof(*k->args.filters) * k->args.filter_count);
memcpy((grpc_channel_filter *)k->args.filters, args->filters,
sizeof(*k->args.filters) * k->args.filter_count);
} else {
k->args.filters = NULL;
}
k->args.addr_len = args->addr_len; k->args.addr_len = args->addr_len;
k->args.addr = gpr_malloc(args->addr_len); k->args.addr = gpr_malloc(args->addr_len);
memcpy(k->args.addr, args->addr, k->args.addr_len); if (k->args.addr_len > 0) {
memcpy(k->args.addr, args->addr, k->args.addr_len);
}
k->args.args = copy_channel_args(args->args); k->args.args = copy_channel_args(args->args);
return k; return k;
} }
@ -104,11 +111,15 @@ static int subchannel_key_compare(grpc_subchannel_key *a,
if (c != 0) return c; if (c != 0) return c;
c = GPR_ICMP(a->args.filter_count, b->args.filter_count); c = GPR_ICMP(a->args.filter_count, b->args.filter_count);
if (c != 0) return c; if (c != 0) return c;
c = memcmp(a->args.addr, b->args.addr, a->args.addr_len); if (a->args.addr_len) {
if (c != 0) return c; c = memcmp(a->args.addr, b->args.addr, a->args.addr_len);
c = memcmp(a->args.filters, b->args.filters, if (c != 0) return c;
a->args.filter_count * sizeof(*a->args.filters)); }
if (c != 0) return c; if (a->args.filter_count > 0) {
c = memcmp(a->args.filters, b->args.filters,
a->args.filter_count * sizeof(*a->args.filters));
if (c != 0) return c;
}
return grpc_channel_args_compare(a->args.args, b->args.args); return grpc_channel_args_compare(a->args.args, b->args.args);
} }

@ -33,8 +33,8 @@
/* Automatically generated nanopb header */ /* Automatically generated nanopb header */
/* Generated by nanopb-0.3.5-dev */ /* Generated by nanopb-0.3.5-dev */
#ifndef PB_LOAD_BALANCER_PB_H_INCLUDED #ifndef GRPC_CORE_EXT_LB_POLICY_GRPCLB_PROTO_GRPC_LB_V1_LOAD_BALANCER_PB_H
#define PB_LOAD_BALANCER_PB_H_INCLUDED #define GRPC_CORE_EXT_LB_POLICY_GRPCLB_PROTO_GRPC_LB_V1_LOAD_BALANCER_PB_H
#include "third_party/nanopb/pb.h" #include "third_party/nanopb/pb.h"
#if PB_PROTO_HEADER_VERSION != 30 #if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator. #error Regenerate this file with the current version of nanopb generator.

@ -45,9 +45,9 @@
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/iomgr/tcp_client.h"
#include "src/core/lib/security/auth_filters.h" #include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials.h" #include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_context.h" #include "src/core/lib/security/transport/auth_filters.h"
#include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/channel.h"
#include "src/core/lib/tsi/transport_security_interface.h" #include "src/core/lib/tsi/transport_security_interface.h"

@ -43,14 +43,8 @@
#include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/server.h" #include "src/core/lib/surface/server.h"
static void setup_transport(grpc_exec_ctx *exec_ctx, void *server,
grpc_transport *transport) {
grpc_server_setup_transport(exec_ctx, server, transport,
grpc_server_get_channel_args(server));
}
static void new_transport(grpc_exec_ctx *exec_ctx, void *server, static void new_transport(grpc_exec_ctx *exec_ctx, void *server,
grpc_endpoint *tcp, grpc_endpoint *tcp, grpc_pollset *accepting_pollset,
grpc_tcp_server_acceptor *acceptor) { grpc_tcp_server_acceptor *acceptor) {
/* /*
* Beware that the call to grpc_create_chttp2_transport() has to happen before * Beware that the call to grpc_create_chttp2_transport() has to happen before
@ -61,7 +55,8 @@ static void new_transport(grpc_exec_ctx *exec_ctx, void *server,
*/ */
grpc_transport *transport = grpc_create_chttp2_transport( grpc_transport *transport = grpc_create_chttp2_transport(
exec_ctx, grpc_server_get_channel_args(server), tcp, 0); exec_ctx, grpc_server_get_channel_args(server), tcp, 0);
setup_transport(exec_ctx, server, transport); grpc_server_setup_transport(exec_ctx, server, transport, accepting_pollset,
grpc_server_get_channel_args(server));
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
} }

@ -45,14 +45,14 @@
#include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/iomgr/tcp_server.h"
#include "src/core/lib/security/auth_filters.h" #include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials.h" #include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_connector.h" #include "src/core/lib/security/transport/auth_filters.h"
#include "src/core/lib/security/security_context.h" #include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/server.h" #include "src/core/lib/surface/server.h"
typedef struct grpc_server_secure_state { typedef struct server_secure_state {
grpc_server *server; grpc_server *server;
grpc_tcp_server *tcp; grpc_tcp_server *tcp;
grpc_server_security_connector *sc; grpc_server_security_connector *sc;
@ -62,13 +62,16 @@ typedef struct grpc_server_secure_state {
gpr_refcount refcount; gpr_refcount refcount;
grpc_closure destroy_closure; grpc_closure destroy_closure;
grpc_closure *destroy_callback; grpc_closure *destroy_callback;
} grpc_server_secure_state; } server_secure_state;
static void state_ref(grpc_server_secure_state *state) { typedef struct server_secure_connect {
gpr_ref(&state->refcount); server_secure_state *state;
} grpc_pollset *accepting_pollset;
} server_secure_connect;
static void state_ref(server_secure_state *state) { gpr_ref(&state->refcount); }
static void state_unref(grpc_server_secure_state *state) { static void state_unref(server_secure_state *state) {
if (gpr_unref(&state->refcount)) { if (gpr_unref(&state->refcount)) {
/* ensure all threads have unlocked */ /* ensure all threads have unlocked */
gpr_mu_lock(&state->mu); gpr_mu_lock(&state->mu);
@ -80,67 +83,66 @@ static void state_unref(grpc_server_secure_state *state) {
} }
} }
static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep,
grpc_transport *transport,
grpc_auth_context *auth_context) {
grpc_server_secure_state *state = statep;
grpc_channel_args *args_copy;
grpc_arg args_to_add[2];
args_to_add[0] = grpc_server_credentials_to_arg(state->creds);
args_to_add[1] = grpc_auth_context_to_arg(auth_context);
args_copy = grpc_channel_args_copy_and_add(
grpc_server_get_channel_args(state->server), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
grpc_server_setup_transport(exec_ctx, state->server, transport, args_copy);
grpc_channel_args_destroy(args_copy);
}
static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
grpc_security_status status, grpc_security_status status,
grpc_endpoint *secure_endpoint, grpc_endpoint *secure_endpoint,
grpc_auth_context *auth_context) { grpc_auth_context *auth_context) {
grpc_server_secure_state *state = statep; server_secure_connect *state = statep;
grpc_transport *transport; grpc_transport *transport;
if (status == GRPC_SECURITY_OK) { if (status == GRPC_SECURITY_OK) {
if (secure_endpoint) { if (secure_endpoint) {
gpr_mu_lock(&state->mu); gpr_mu_lock(&state->state->mu);
if (!state->is_shutdown) { if (!state->state->is_shutdown) {
transport = grpc_create_chttp2_transport( transport = grpc_create_chttp2_transport(
exec_ctx, grpc_server_get_channel_args(state->server), exec_ctx, grpc_server_get_channel_args(state->state->server),
secure_endpoint, 0); secure_endpoint, 0);
setup_transport(exec_ctx, state, transport, auth_context); grpc_channel_args *args_copy;
grpc_arg args_to_add[2];
args_to_add[0] = grpc_server_credentials_to_arg(state->state->creds);
args_to_add[1] = grpc_auth_context_to_arg(auth_context);
args_copy = grpc_channel_args_copy_and_add(
grpc_server_get_channel_args(state->state->server), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
grpc_server_setup_transport(exec_ctx, state->state->server, transport,
state->accepting_pollset, args_copy);
grpc_channel_args_destroy(args_copy);
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
} else { } else {
/* We need to consume this here, because the server may already have /* We need to consume this here, because the server may already have
* gone away. */ * gone away. */
grpc_endpoint_destroy(exec_ctx, secure_endpoint); grpc_endpoint_destroy(exec_ctx, secure_endpoint);
} }
gpr_mu_unlock(&state->mu); gpr_mu_unlock(&state->state->mu);
} }
} else { } else {
gpr_log(GPR_ERROR, "Secure transport failed with error %d", status); gpr_log(GPR_ERROR, "Secure transport failed with error %d", status);
} }
state_unref(state); state_unref(state->state);
gpr_free(state);
} }
static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp,
grpc_pollset *accepting_pollset,
grpc_tcp_server_acceptor *acceptor) { grpc_tcp_server_acceptor *acceptor) {
grpc_server_secure_state *state = statep; server_secure_connect *state = gpr_malloc(sizeof(*state));
state_ref(state); state->state = statep;
grpc_server_security_connector_do_handshake( state_ref(state->state);
exec_ctx, state->sc, acceptor, tcp, on_secure_handshake_done, state); state->accepting_pollset = accepting_pollset;
grpc_server_security_connector_do_handshake(exec_ctx, state->state->sc,
acceptor, tcp,
on_secure_handshake_done, state);
} }
/* Server callback: start listening on our ports */ /* Server callback: start listening on our ports */
static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep, static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep,
grpc_pollset **pollsets, size_t pollset_count) { grpc_pollset **pollsets, size_t pollset_count) {
grpc_server_secure_state *state = statep; server_secure_state *state = statep;
grpc_tcp_server_start(exec_ctx, state->tcp, pollsets, pollset_count, grpc_tcp_server_start(exec_ctx, state->tcp, pollsets, pollset_count,
on_accept, state); on_accept, state);
} }
static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep, bool success) { static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep, bool success) {
grpc_server_secure_state *state = statep; server_secure_state *state = statep;
if (state->destroy_callback != NULL) { if (state->destroy_callback != NULL) {
state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg, state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg,
success); success);
@ -153,7 +155,7 @@ static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep, bool success) {
callbacks) */ callbacks) */
static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep, static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep,
grpc_closure *callback) { grpc_closure *callback) {
grpc_server_secure_state *state = statep; server_secure_state *state = statep;
grpc_tcp_server *tcp; grpc_tcp_server *tcp;
gpr_mu_lock(&state->mu); gpr_mu_lock(&state->mu);
state->is_shutdown = 1; state->is_shutdown = 1;
@ -167,7 +169,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
grpc_server_credentials *creds) { grpc_server_credentials *creds) {
grpc_resolved_addresses *resolved = NULL; grpc_resolved_addresses *resolved = NULL;
grpc_tcp_server *tcp = NULL; grpc_tcp_server *tcp = NULL;
grpc_server_secure_state *state = NULL; server_secure_state *state = NULL;
size_t i; size_t i;
unsigned count = 0; unsigned count = 0;
int port_num = -1; int port_num = -1;

@ -137,7 +137,8 @@ grpc_chttp2_parse_error grpc_chttp2_goaway_parser_parse(
++cur; ++cur;
/* fallthrough */ /* fallthrough */
case GRPC_CHTTP2_GOAWAY_DEBUG: case GRPC_CHTTP2_GOAWAY_DEBUG:
memcpy(p->debug_data + p->debug_pos, cur, (size_t)(end - cur)); if (end != cur)
memcpy(p->debug_data + p->debug_pos, cur, (size_t)(end - cur));
GPR_ASSERT((size_t)(end - cur) < UINT32_MAX - p->debug_pos); GPR_ASSERT((size_t)(end - cur) < UINT32_MAX - p->debug_pos);
p->debug_pos += (uint32_t)(end - cur); p->debug_pos += (uint32_t)(end - cur);
p->state = GRPC_CHTTP2_GOAWAY_DEBUG; p->state = GRPC_CHTTP2_GOAWAY_DEBUG;

@ -1138,6 +1138,7 @@ static int parse_string_prefix(grpc_chttp2_hpack_parser *p, const uint8_t *cur,
/* append some bytes to a string */ /* append some bytes to a string */
static void append_bytes(grpc_chttp2_hpack_parser_string *str, static void append_bytes(grpc_chttp2_hpack_parser_string *str,
const uint8_t *data, size_t length) { const uint8_t *data, size_t length) {
if (length == 0) return;
if (length + str->length > str->capacity) { if (length + str->length > str->capacity) {
GPR_ASSERT(str->length + length <= UINT32_MAX); GPR_ASSERT(str->length + length <= UINT32_MAX);
str->capacity = (uint32_t)(str->length + length); str->capacity = (uint32_t)(str->length + length);
@ -1445,6 +1446,11 @@ grpc_chttp2_parse_error grpc_chttp2_header_parser_parse(
stream id on a header */ stream id on a header */
if (stream_parsing != NULL) { if (stream_parsing != NULL) {
if (parser->is_boundary) { if (parser->is_boundary) {
if (stream_parsing->header_frames_received ==
GPR_ARRAY_SIZE(stream_parsing->got_metadata_on_parse)) {
gpr_log(GPR_ERROR, "too many trailer frames");
return GRPC_CHTTP2_CONNECTION_ERROR;
}
stream_parsing stream_parsing
->got_metadata_on_parse[stream_parsing->header_frames_received] = 1; ->got_metadata_on_parse[stream_parsing->header_frames_received] = 1;
stream_parsing->header_frames_received++; stream_parsing->header_frames_received++;

@ -218,8 +218,11 @@ static void on_write_completed(cronet_bidirectional_stream *stream,
static void process_recv_message(stream_obj *s, const uint8_t *recv_data) { static void process_recv_message(stream_obj *s, const uint8_t *recv_data) {
gpr_slice read_data_slice = gpr_slice_malloc((uint32_t)s->total_read_bytes); gpr_slice read_data_slice = gpr_slice_malloc((uint32_t)s->total_read_bytes);
uint8_t *dst_p = GPR_SLICE_START_PTR(read_data_slice); uint8_t *dst_p = GPR_SLICE_START_PTR(read_data_slice);
memcpy(dst_p, recv_data, (size_t)s->total_read_bytes); if (s->total_read_bytes > 0) {
gpr_slice_buffer_add(&s->read_slice_buffer, read_data_slice); // Only copy if there is non-zero number of bytes
memcpy(dst_p, recv_data, (size_t)s->total_read_bytes);
gpr_slice_buffer_add(&s->read_slice_buffer, read_data_slice);
}
grpc_slice_buffer_stream_init(&s->sbs, &s->read_slice_buffer, 0); grpc_slice_buffer_stream_init(&s->sbs, &s->read_slice_buffer, 0);
*s->recv_message = (grpc_byte_buffer *)&s->sbs; *s->recv_message = (grpc_byte_buffer *)&s->sbs;
} }
@ -347,8 +350,17 @@ static void next_recv_step(stream_obj *s, enum e_caller caller) {
if (grpc_cronet_trace) { if (grpc_cronet_trace) {
gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()"); gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()");
} }
cronet_bidirectional_stream_read(s->cbs, (char *)s->read_buffer, if (s->remaining_read_bytes > 0) {
s->remaining_read_bytes); cronet_bidirectional_stream_read(s->cbs, (char *)s->read_buffer,
s->remaining_read_bytes);
} else {
// Calling the closing callback directly since this is a 0 byte read
// for an empty message.
process_recv_message(s, NULL);
enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]);
invoke_closing_callback(s);
set_recv_state(s, CRONET_RECV_CLOSED);
}
} }
} }
break; break;

@ -132,7 +132,8 @@ grpc_channel_args *grpc_channel_args_normalize(const grpc_channel_args *a) {
for (size_t i = 0; i < a->num_args; i++) { for (size_t i = 0; i < a->num_args; i++) {
args[i] = &a->args[i]; args[i] = &a->args[i];
} }
qsort(args, a->num_args, sizeof(grpc_arg *), cmp_key_stable); if (a->num_args > 1)
qsort(args, a->num_args, sizeof(grpc_arg *), cmp_key_stable);
grpc_channel_args *b = gpr_malloc(sizeof(grpc_channel_args)); grpc_channel_args *b = gpr_malloc(sizeof(grpc_channel_args));
b->num_args = a->num_args; b->num_args = a->num_args;

@ -199,5 +199,6 @@ void grpc_compression_options_disable_algorithm(
int grpc_compression_options_is_algorithm_enabled( int grpc_compression_options_is_algorithm_enabled(
const grpc_compression_options *opts, const grpc_compression_options *opts,
grpc_compression_algorithm algorithm) { grpc_compression_algorithm algorithm) {
if (algorithm >= GRPC_COMPRESS_ALGORITHMS_COUNT) return 0;
return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm); return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm);
} }

@ -38,7 +38,7 @@
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/string_util.h> #include <grpc/support/string_util.h>
#include "src/core/lib/security/handshake.h" #include "src/core/lib/security/transport/handshake.h"
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
#include "src/core/lib/tsi/ssl_transport_security.h" #include "src/core/lib/tsi/ssl_transport_security.h"

@ -126,6 +126,9 @@ struct grpc_fd {
grpc_closure *on_done_closure; grpc_closure *on_done_closure;
grpc_iomgr_object iomgr_object; grpc_iomgr_object iomgr_object;
/* The pollset that last noticed and notified that the fd is readable */
grpc_pollset *read_notifier_pollset;
}; };
/* Begin polling on an fd. /* Begin polling on an fd.
@ -147,7 +150,8 @@ static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
if got_read or got_write are 1, also does the become_{readable,writable} as if got_read or got_write are 1, also does the become_{readable,writable} as
appropriate. */ appropriate. */
static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *rec, static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *rec,
int got_read, int got_write); int got_read, int got_write,
grpc_pollset *read_notifier_pollset);
/* Return 1 if this fd is orphaned, 0 otherwise */ /* Return 1 if this fd is orphaned, 0 otherwise */
static bool fd_is_orphaned(grpc_fd *fd); static bool fd_is_orphaned(grpc_fd *fd);
@ -342,6 +346,7 @@ static grpc_fd *alloc_fd(int fd) {
r->on_done_closure = NULL; r->on_done_closure = NULL;
r->closed = 0; r->closed = 0;
r->released = 0; r->released = 0;
r->read_notifier_pollset = NULL;
gpr_mu_unlock(&r->mu); gpr_mu_unlock(&r->mu);
return r; return r;
} }
@ -545,6 +550,11 @@ static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
} }
} }
static void set_read_notifier_pollset_locked(
grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_pollset *read_notifier_pollset) {
fd->read_notifier_pollset = read_notifier_pollset;
}
static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
gpr_mu_lock(&fd->mu); gpr_mu_lock(&fd->mu);
GPR_ASSERT(!fd->shutdown); GPR_ASSERT(!fd->shutdown);
@ -568,6 +578,18 @@ static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
gpr_mu_unlock(&fd->mu); gpr_mu_unlock(&fd->mu);
} }
/* Return the read-notifier pollset */
static grpc_pollset *fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
grpc_fd *fd) {
grpc_pollset *notifier = NULL;
gpr_mu_lock(&fd->mu);
notifier = fd->read_notifier_pollset;
gpr_mu_unlock(&fd->mu);
return notifier;
}
static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset, static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
grpc_pollset_worker *worker, uint32_t read_mask, grpc_pollset_worker *worker, uint32_t read_mask,
uint32_t write_mask, grpc_fd_watcher *watcher) { uint32_t write_mask, grpc_fd_watcher *watcher) {
@ -620,7 +642,8 @@ static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
} }
static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher, static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher,
int got_read, int got_write) { int got_read, int got_write,
grpc_pollset *read_notifier_pollset) {
int was_polling = 0; int was_polling = 0;
int kick = 0; int kick = 0;
grpc_fd *fd = watcher->fd; grpc_fd *fd = watcher->fd;
@ -656,6 +679,10 @@ static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher,
if (set_ready_locked(exec_ctx, fd, &fd->read_closure)) { if (set_ready_locked(exec_ctx, fd, &fd->read_closure)) {
kick = 1; kick = 1;
} }
if (read_notifier_pollset != NULL) {
set_read_notifier_pollset_locked(exec_ctx, fd, read_notifier_pollset);
}
} }
if (got_write) { if (got_write) {
if (set_ready_locked(exec_ctx, fd, &fd->write_closure)) { if (set_ready_locked(exec_ctx, fd, &fd->write_closure)) {
@ -756,9 +783,14 @@ static void pollset_kick_ext(grpc_pollset *p,
specific_worker = pop_front_worker(p); specific_worker = pop_front_worker(p);
if (specific_worker != NULL) { if (specific_worker != NULL) {
if (gpr_tls_get(&g_current_thread_worker) == (intptr_t)specific_worker) { if (gpr_tls_get(&g_current_thread_worker) == (intptr_t)specific_worker) {
/* Prefer not to kick self. Push the worker to the end of the list and
* pop the one from front */
GPR_TIMER_MARK("kick_anonymous_not_self", 0); GPR_TIMER_MARK("kick_anonymous_not_self", 0);
push_back_worker(p, specific_worker); push_back_worker(p, specific_worker);
specific_worker = pop_front_worker(p); specific_worker = pop_front_worker(p);
/* If there was only one worker on the pollset, we would get the same
* worker we pushed (the one set on current thread local) back. If so,
* kick it only if GRPC_POLLSET_CAN_KICK_SELF flag is set */
if ((flags & GRPC_POLLSET_CAN_KICK_SELF) == 0 && if ((flags & GRPC_POLLSET_CAN_KICK_SELF) == 0 &&
gpr_tls_get(&g_current_thread_worker) == gpr_tls_get(&g_current_thread_worker) ==
(intptr_t)specific_worker) { (intptr_t)specific_worker) {
@ -1201,11 +1233,11 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx,
gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
} }
if (fd) { if (fd) {
fd_end_poll(exec_ctx, &fd_watcher, 0, 0); fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
} }
} else if (r == 0) { } else if (r == 0) {
if (fd) { if (fd) {
fd_end_poll(exec_ctx, &fd_watcher, 0, 0); fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
} }
} else { } else {
if (pfd[0].revents & POLLIN_CHECK) { if (pfd[0].revents & POLLIN_CHECK) {
@ -1216,9 +1248,9 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx,
} }
if (nfds > 2) { if (nfds > 2) {
fd_end_poll(exec_ctx, &fd_watcher, pfd[2].revents & POLLIN_CHECK, fd_end_poll(exec_ctx, &fd_watcher, pfd[2].revents & POLLIN_CHECK,
pfd[2].revents & POLLOUT_CHECK); pfd[2].revents & POLLOUT_CHECK, pollset);
} else if (fd) { } else if (fd) {
fd_end_poll(exec_ctx, &fd_watcher, 0, 0); fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
} }
} }
@ -1354,11 +1386,11 @@ static void multipoll_with_poll_pollset_maybe_work_and_unlock(
gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
} }
for (i = 2; i < pfd_count; i++) { for (i = 2; i < pfd_count; i++) {
fd_end_poll(exec_ctx, &watchers[i], 0, 0); fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
} }
} else if (r == 0) { } else if (r == 0) {
for (i = 2; i < pfd_count; i++) { for (i = 2; i < pfd_count; i++) {
fd_end_poll(exec_ctx, &watchers[i], 0, 0); fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
} }
} else { } else {
if (pfds[0].revents & POLLIN_CHECK) { if (pfds[0].revents & POLLIN_CHECK) {
@ -1369,11 +1401,11 @@ static void multipoll_with_poll_pollset_maybe_work_and_unlock(
} }
for (i = 2; i < pfd_count; i++) { for (i = 2; i < pfd_count; i++) {
if (watchers[i].fd == NULL) { if (watchers[i].fd == NULL) {
fd_end_poll(exec_ctx, &watchers[i], 0, 0); fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
continue; continue;
} }
fd_end_poll(exec_ctx, &watchers[i], pfds[i].revents & POLLIN_CHECK, fd_end_poll(exec_ctx, &watchers[i], pfds[i].revents & POLLIN_CHECK,
pfds[i].revents & POLLOUT_CHECK); pfds[i].revents & POLLOUT_CHECK, pollset);
} }
} }
@ -1449,20 +1481,31 @@ static void poll_become_multipoller(grpc_exec_ctx *exec_ctx,
#include "src/core/lib/profiling/timers.h" #include "src/core/lib/profiling/timers.h"
#include "src/core/lib/support/block_annotate.h" #include "src/core/lib/support/block_annotate.h"
static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure **st) { static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure **st,
grpc_pollset *read_notifier_pollset) {
/* only one set_ready can be active at once (but there may be a racing /* only one set_ready can be active at once (but there may be a racing
notify_on) */ notify_on) */
gpr_mu_lock(&fd->mu); gpr_mu_lock(&fd->mu);
set_ready_locked(exec_ctx, fd, st); set_ready_locked(exec_ctx, fd, st);
/* A non-NULL read_notifier_pollset means that the fd is readable. */
if (read_notifier_pollset != NULL) {
/* Note: Since the fd might be a part of multiple pollsets, this might be
* called multiple times (for each time the fd becomes readable) and it is
* okay to set the fd's read-notifier pollset to anyone of these pollsets */
set_read_notifier_pollset_locked(exec_ctx, fd, read_notifier_pollset);
}
gpr_mu_unlock(&fd->mu); gpr_mu_unlock(&fd->mu);
} }
static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
set_ready(exec_ctx, fd, &fd->read_closure); grpc_pollset *notifier_pollset) {
set_ready(exec_ctx, fd, &fd->read_closure, notifier_pollset);
} }
static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
set_ready(exec_ctx, fd, &fd->write_closure); set_ready(exec_ctx, fd, &fd->write_closure, NULL);
} }
struct epoll_fd_list { struct epoll_fd_list {
@ -1554,7 +1597,7 @@ static void finally_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
} }
} }
} }
fd_end_poll(exec_ctx, &watcher, 0, 0); fd_end_poll(exec_ctx, &watcher, 0, 0, NULL);
} }
static void perform_delayed_add(grpc_exec_ctx *exec_ctx, void *arg, static void perform_delayed_add(grpc_exec_ctx *exec_ctx, void *arg,
@ -1668,7 +1711,7 @@ static void multipoll_with_epoll_pollset_maybe_work_and_unlock(
grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd); grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd);
} else { } else {
if (read_ev || cancel) { if (read_ev || cancel) {
fd_become_readable(exec_ctx, fd); fd_become_readable(exec_ctx, fd, pollset);
} }
if (write_ev || cancel) { if (write_ev || cancel) {
fd_become_writable(exec_ctx, fd); fd_become_writable(exec_ctx, fd);
@ -1897,6 +1940,7 @@ static const grpc_event_engine_vtable vtable = {
.fd_shutdown = fd_shutdown, .fd_shutdown = fd_shutdown,
.fd_notify_on_read = fd_notify_on_read, .fd_notify_on_read = fd_notify_on_read,
.fd_notify_on_write = fd_notify_on_write, .fd_notify_on_write = fd_notify_on_write,
.fd_get_read_notifier_pollset = fd_get_read_notifier_pollset,
.pollset_init = pollset_init, .pollset_init = pollset_init,
.pollset_shutdown = pollset_shutdown, .pollset_shutdown = pollset_shutdown,

@ -113,6 +113,9 @@ struct grpc_fd {
grpc_closure *on_done_closure; grpc_closure *on_done_closure;
grpc_iomgr_object iomgr_object; grpc_iomgr_object iomgr_object;
/* The pollset that last noticed and notified that the fd is readable */
grpc_pollset *read_notifier_pollset;
}; };
/* Begin polling on an fd. /* Begin polling on an fd.
@ -134,7 +137,8 @@ static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
if got_read or got_write are 1, also does the become_{readable,writable} as if got_read or got_write are 1, also does the become_{readable,writable} as
appropriate. */ appropriate. */
static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *rec, static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *rec,
int got_read, int got_write); int got_read, int got_write,
grpc_pollset *read_notifier_pollset);
/* Return 1 if this fd is orphaned, 0 otherwise */ /* Return 1 if this fd is orphaned, 0 otherwise */
static bool fd_is_orphaned(grpc_fd *fd); static bool fd_is_orphaned(grpc_fd *fd);
@ -177,7 +181,6 @@ struct grpc_pollset_worker {
struct grpc_pollset { struct grpc_pollset {
gpr_mu mu; gpr_mu mu;
grpc_pollset_worker root_worker; grpc_pollset_worker root_worker;
int in_flight_cbs;
int shutting_down; int shutting_down;
int called_shutdown; int called_shutdown;
int kicked_without_pollers; int kicked_without_pollers;
@ -187,10 +190,6 @@ struct grpc_pollset {
size_t fd_count; size_t fd_count;
size_t fd_capacity; size_t fd_capacity;
grpc_fd **fds; grpc_fd **fds;
/* fds that have been removed from the pollset explicitly */
size_t del_count;
size_t del_capacity;
grpc_fd **dels;
/* Local cache of eventfds for workers */ /* Local cache of eventfds for workers */
grpc_cached_wakeup_fd *local_wakeup_cache; grpc_cached_wakeup_fd *local_wakeup_cache;
}; };
@ -301,6 +300,7 @@ static grpc_fd *fd_create(int fd, const char *name) {
r->on_done_closure = NULL; r->on_done_closure = NULL;
r->closed = 0; r->closed = 0;
r->released = 0; r->released = 0;
r->read_notifier_pollset = NULL;
char *name2; char *name2;
gpr_asprintf(&name2, "%s fd=%d", name, fd); gpr_asprintf(&name2, "%s fd=%d", name, fd);
@ -316,6 +316,18 @@ static bool fd_is_orphaned(grpc_fd *fd) {
return (gpr_atm_acq_load(&fd->refst) & 1) == 0; return (gpr_atm_acq_load(&fd->refst) & 1) == 0;
} }
/* Return the read-notifier pollset */
static grpc_pollset *fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
grpc_fd *fd) {
grpc_pollset *notifier = NULL;
gpr_mu_lock(&fd->mu);
notifier = fd->read_notifier_pollset;
gpr_mu_unlock(&fd->mu);
return notifier;
}
static void pollset_kick_locked(grpc_fd_watcher *watcher) { static void pollset_kick_locked(grpc_fd_watcher *watcher) {
gpr_mu_lock(&watcher->pollset->mu); gpr_mu_lock(&watcher->pollset->mu);
GPR_ASSERT(watcher->worker); GPR_ASSERT(watcher->worker);
@ -444,6 +456,11 @@ static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
} }
} }
static void set_read_notifier_pollset_locked(
grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_pollset *read_notifier_pollset) {
fd->read_notifier_pollset = read_notifier_pollset;
}
static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) { static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
gpr_mu_lock(&fd->mu); gpr_mu_lock(&fd->mu);
GPR_ASSERT(!fd->shutdown); GPR_ASSERT(!fd->shutdown);
@ -519,7 +536,8 @@ static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
} }
static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher, static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher,
int got_read, int got_write) { int got_read, int got_write,
grpc_pollset *read_notifier_pollset) {
int was_polling = 0; int was_polling = 0;
int kick = 0; int kick = 0;
grpc_fd *fd = watcher->fd; grpc_fd *fd = watcher->fd;
@ -555,6 +573,9 @@ static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher,
if (set_ready_locked(exec_ctx, fd, &fd->read_closure)) { if (set_ready_locked(exec_ctx, fd, &fd->read_closure)) {
kick = 1; kick = 1;
} }
if (read_notifier_pollset != NULL) {
set_read_notifier_pollset_locked(exec_ctx, fd, read_notifier_pollset);
}
} }
if (got_write) { if (got_write) {
if (set_ready_locked(exec_ctx, fd, &fd->write_closure)) { if (set_ready_locked(exec_ctx, fd, &fd->write_closure)) {
@ -700,7 +721,6 @@ static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
gpr_mu_init(&pollset->mu); gpr_mu_init(&pollset->mu);
*mu = &pollset->mu; *mu = &pollset->mu;
pollset->root_worker.next = pollset->root_worker.prev = &pollset->root_worker; pollset->root_worker.next = pollset->root_worker.prev = &pollset->root_worker;
pollset->in_flight_cbs = 0;
pollset->shutting_down = 0; pollset->shutting_down = 0;
pollset->called_shutdown = 0; pollset->called_shutdown = 0;
pollset->kicked_without_pollers = 0; pollset->kicked_without_pollers = 0;
@ -709,14 +729,10 @@ static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
pollset->kicked_without_pollers = 0; pollset->kicked_without_pollers = 0;
pollset->fd_count = 0; pollset->fd_count = 0;
pollset->fd_capacity = 0; pollset->fd_capacity = 0;
pollset->del_count = 0;
pollset->del_capacity = 0;
pollset->fds = NULL; pollset->fds = NULL;
pollset->dels = NULL;
} }
static void pollset_destroy(grpc_pollset *pollset) { static void pollset_destroy(grpc_pollset *pollset) {
GPR_ASSERT(pollset->in_flight_cbs == 0);
GPR_ASSERT(!pollset_has_workers(pollset)); GPR_ASSERT(!pollset_has_workers(pollset));
GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail); GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail);
while (pollset->local_wakeup_cache) { while (pollset->local_wakeup_cache) {
@ -726,17 +742,14 @@ static void pollset_destroy(grpc_pollset *pollset) {
pollset->local_wakeup_cache = next; pollset->local_wakeup_cache = next;
} }
gpr_free(pollset->fds); gpr_free(pollset->fds);
gpr_free(pollset->dels);
gpr_mu_destroy(&pollset->mu); gpr_mu_destroy(&pollset->mu);
} }
static void pollset_reset(grpc_pollset *pollset) { static void pollset_reset(grpc_pollset *pollset) {
GPR_ASSERT(pollset->shutting_down); GPR_ASSERT(pollset->shutting_down);
GPR_ASSERT(pollset->in_flight_cbs == 0);
GPR_ASSERT(!pollset_has_workers(pollset)); GPR_ASSERT(!pollset_has_workers(pollset));
GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail); GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail);
GPR_ASSERT(pollset->fd_count == 0); GPR_ASSERT(pollset->fd_count == 0);
GPR_ASSERT(pollset->del_count == 0);
pollset->shutting_down = 0; pollset->shutting_down = 0;
pollset->called_shutdown = 0; pollset->called_shutdown = 0;
pollset->kicked_without_pollers = 0; pollset->kicked_without_pollers = 0;
@ -769,11 +782,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset) {
for (i = 0; i < pollset->fd_count; i++) { for (i = 0; i < pollset->fd_count; i++) {
GRPC_FD_UNREF(pollset->fds[i], "multipoller"); GRPC_FD_UNREF(pollset->fds[i], "multipoller");
} }
for (i = 0; i < pollset->del_count; i++) {
GRPC_FD_UNREF(pollset->dels[i], "multipoller_del");
}
pollset->fd_count = 0; pollset->fd_count = 0;
pollset->del_count = 0;
grpc_exec_ctx_enqueue(exec_ctx, pollset->shutdown_done, true, NULL); grpc_exec_ctx_enqueue(exec_ctx, pollset->shutdown_done, true, NULL);
} }
@ -813,13 +822,6 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
GPR_TIMER_MARK("pollset_work.shutting_down", 0); GPR_TIMER_MARK("pollset_work.shutting_down", 0);
goto done; goto done;
} }
/* Give do_promote priority so we don't starve it out */
if (pollset->in_flight_cbs) {
GPR_TIMER_MARK("pollset_work.in_flight_cbs", 0);
gpr_mu_unlock(&pollset->mu);
locked = 0;
goto done;
}
/* Start polling, and keep doing so while we're being asked to /* Start polling, and keep doing so while we're being asked to
re-evaluate our pollers (this allows poll() based pollers to re-evaluate our pollers (this allows poll() based pollers to
ensure they don't miss wakeups) */ ensure they don't miss wakeups) */
@ -839,7 +841,7 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
int timeout; int timeout;
int r; int r;
size_t i, j, fd_count; size_t i, fd_count;
nfds_t pfd_count; nfds_t pfd_count;
/* TODO(ctiller): inline some elements to avoid an allocation */ /* TODO(ctiller): inline some elements to avoid an allocation */
grpc_fd_watcher *watchers; grpc_fd_watcher *watchers;
@ -859,11 +861,7 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
pfds[1].events = POLLIN; pfds[1].events = POLLIN;
pfds[1].revents = 0; pfds[1].revents = 0;
for (i = 0; i < pollset->fd_count; i++) { for (i = 0; i < pollset->fd_count; i++) {
int remove = fd_is_orphaned(pollset->fds[i]); if (fd_is_orphaned(pollset->fds[i])) {
for (j = 0; !remove && j < pollset->del_count; j++) {
if (pollset->fds[i] == pollset->dels[j]) remove = 1;
}
if (remove) {
GRPC_FD_UNREF(pollset->fds[i], "multipoller"); GRPC_FD_UNREF(pollset->fds[i], "multipoller");
} else { } else {
pollset->fds[fd_count++] = pollset->fds[i]; pollset->fds[fd_count++] = pollset->fds[i];
@ -874,10 +872,6 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
pfd_count++; pfd_count++;
} }
} }
for (j = 0; j < pollset->del_count; j++) {
GRPC_FD_UNREF(pollset->dels[j], "multipoller_del");
}
pollset->del_count = 0;
pollset->fd_count = fd_count; pollset->fd_count = fd_count;
gpr_mu_unlock(&pollset->mu); gpr_mu_unlock(&pollset->mu);
@ -899,11 +893,11 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno)); gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
} }
for (i = 2; i < pfd_count; i++) { for (i = 2; i < pfd_count; i++) {
fd_end_poll(exec_ctx, &watchers[i], 0, 0); fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
} }
} else if (r == 0) { } else if (r == 0) {
for (i = 2; i < pfd_count; i++) { for (i = 2; i < pfd_count; i++) {
fd_end_poll(exec_ctx, &watchers[i], 0, 0); fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
} }
} else { } else {
if (pfds[0].revents & POLLIN_CHECK) { if (pfds[0].revents & POLLIN_CHECK) {
@ -914,10 +908,10 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
} }
for (i = 2; i < pfd_count; i++) { for (i = 2; i < pfd_count; i++) {
if (watchers[i].fd == NULL) { if (watchers[i].fd == NULL) {
fd_end_poll(exec_ctx, &watchers[i], 0, 0); fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
} else { } else {
fd_end_poll(exec_ctx, &watchers[i], pfds[i].revents & POLLIN_CHECK, fd_end_poll(exec_ctx, &watchers[i], pfds[i].revents & POLLIN_CHECK,
pfds[i].revents & POLLOUT_CHECK); pfds[i].revents & POLLOUT_CHECK, pollset);
} }
} }
} }
@ -969,7 +963,7 @@ static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
if (pollset->shutting_down) { if (pollset->shutting_down) {
if (pollset_has_workers(pollset)) { if (pollset_has_workers(pollset)) {
pollset_kick(pollset, NULL); pollset_kick(pollset, NULL);
} else if (!pollset->called_shutdown && pollset->in_flight_cbs == 0) { } else if (!pollset->called_shutdown) {
pollset->called_shutdown = 1; pollset->called_shutdown = 1;
gpr_mu_unlock(&pollset->mu); gpr_mu_unlock(&pollset->mu);
finish_shutdown(exec_ctx, pollset); finish_shutdown(exec_ctx, pollset);
@ -999,8 +993,7 @@ static void pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
if (!pollset_has_workers(pollset)) { if (!pollset_has_workers(pollset)) {
grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL); grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL);
} }
if (!pollset->called_shutdown && pollset->in_flight_cbs == 0 && if (!pollset->called_shutdown && !pollset_has_workers(pollset)) {
!pollset_has_workers(pollset)) {
pollset->called_shutdown = 1; pollset->called_shutdown = 1;
finish_shutdown(exec_ctx, pollset); finish_shutdown(exec_ctx, pollset);
} }
@ -1181,6 +1174,7 @@ static const grpc_event_engine_vtable vtable = {
.fd_shutdown = fd_shutdown, .fd_shutdown = fd_shutdown,
.fd_notify_on_read = fd_notify_on_read, .fd_notify_on_read = fd_notify_on_read,
.fd_notify_on_write = fd_notify_on_write, .fd_notify_on_write = fd_notify_on_write,
.fd_get_read_notifier_pollset = fd_get_read_notifier_pollset,
.pollset_init = pollset_init, .pollset_init = pollset_init,
.pollset_shutdown = pollset_shutdown, .pollset_shutdown = pollset_shutdown,

@ -163,6 +163,11 @@ void grpc_fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
g_event_engine->fd_notify_on_write(exec_ctx, fd, closure); g_event_engine->fd_notify_on_write(exec_ctx, fd, closure);
} }
grpc_pollset *grpc_fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
grpc_fd *fd) {
return g_event_engine->fd_get_read_notifier_pollset(exec_ctx, fd);
}
size_t grpc_pollset_size(void) { return g_event_engine->pollset_size; } size_t grpc_pollset_size(void) { return g_event_engine->pollset_size; }
void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) { void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) {

@ -55,6 +55,8 @@ typedef struct grpc_event_engine_vtable {
grpc_closure *closure); grpc_closure *closure);
void (*fd_notify_on_write)(grpc_exec_ctx *exec_ctx, grpc_fd *fd, void (*fd_notify_on_write)(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
grpc_closure *closure); grpc_closure *closure);
grpc_pollset *(*fd_get_read_notifier_pollset)(grpc_exec_ctx *exec_ctx,
grpc_fd *fd);
void (*pollset_init)(grpc_pollset *pollset, gpr_mu **mu); void (*pollset_init)(grpc_pollset *pollset, gpr_mu **mu);
void (*pollset_shutdown)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, void (*pollset_shutdown)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
@ -137,6 +139,10 @@ void grpc_fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
void grpc_fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd, void grpc_fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
grpc_closure *closure); grpc_closure *closure);
/* Return the read notifier pollset from the fd */
grpc_pollset *grpc_fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
grpc_fd *fd);
/* pollset_posix functions */ /* pollset_posix functions */
/* Add an fd to a pollset */ /* Add an fd to a pollset */

@ -52,6 +52,7 @@ typedef struct grpc_tcp_server_acceptor {
/* Called for newly connected TCP connections. */ /* Called for newly connected TCP connections. */
typedef void (*grpc_tcp_server_cb)(grpc_exec_ctx *exec_ctx, void *arg, typedef void (*grpc_tcp_server_cb)(grpc_exec_ctx *exec_ctx, void *arg,
grpc_endpoint *ep, grpc_endpoint *ep,
grpc_pollset *accepting_pollset,
grpc_tcp_server_acceptor *acceptor); grpc_tcp_server_acceptor *acceptor);
/* Create a server, initially not bound to any ports. The caller owns one ref. /* Create a server, initially not bound to any ports. The caller owns one ref.

@ -128,6 +128,9 @@ struct grpc_tcp_server {
grpc_pollset **pollsets; grpc_pollset **pollsets;
/* number of pollsets in the pollsets array */ /* number of pollsets in the pollsets array */
size_t pollset_count; size_t pollset_count;
/* next pollset to assign a channel to */
size_t next_pollset_to_assign;
}; };
grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) { grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
@ -145,6 +148,7 @@ grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
s->head = NULL; s->head = NULL;
s->tail = NULL; s->tail = NULL;
s->nports = 0; s->nports = 0;
s->next_pollset_to_assign = 0;
return s; return s;
} }
@ -310,13 +314,17 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
grpc_tcp_listener *sp = arg; grpc_tcp_listener *sp = arg;
grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index, grpc_tcp_server_acceptor acceptor = {sp->server, sp->port_index,
sp->fd_index}; sp->fd_index};
grpc_pollset *read_notifier_pollset = NULL;
grpc_fd *fdobj; grpc_fd *fdobj;
size_t i;
if (!success) { if (!success) {
goto error; goto error;
} }
read_notifier_pollset =
sp->server->pollsets[(sp->server->next_pollset_to_assign++) %
sp->server->pollset_count];
/* loop until accept4 returns EAGAIN, and then re-arm notification */ /* loop until accept4 returns EAGAIN, and then re-arm notification */
for (;;) { for (;;) {
struct sockaddr_storage addr; struct sockaddr_storage addr;
@ -349,16 +357,18 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
} }
fdobj = grpc_fd_create(fd, name); fdobj = grpc_fd_create(fd, name);
/* TODO(ctiller): revise this when we have server-side sharding
of channels -- we certainly should not be automatically adding every if (read_notifier_pollset == NULL) {
incoming channel to every pollset owned by the server */ gpr_log(GPR_ERROR, "Read notifier pollset is not set on the fd");
for (i = 0; i < sp->server->pollset_count; i++) { goto error;
grpc_pollset_add_fd(exec_ctx, sp->server->pollsets[i], fdobj);
} }
grpc_pollset_add_fd(exec_ctx, read_notifier_pollset, fdobj);
sp->server->on_accept_cb( sp->server->on_accept_cb(
exec_ctx, sp->server->on_accept_cb_arg, exec_ctx, sp->server->on_accept_cb_arg,
grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str), grpc_tcp_create(fdobj, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, addr_str),
&acceptor); read_notifier_pollset, &acceptor);
gpr_free(name); gpr_free(name);
gpr_free(addr_str); gpr_free(addr_str);

@ -379,9 +379,10 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, bool from_iocp) {
/* The only time we should call our callback, is where we successfully /* The only time we should call our callback, is where we successfully
managed to accept a connection, and created an endpoint. */ managed to accept a connection, and created an endpoint. */
if (ep) if (ep) {
sp->server->on_accept_cb(exec_ctx, sp->server->on_accept_cb_arg, ep, sp->server->on_accept_cb(exec_ctx, sp->server->on_accept_cb_arg, ep, NULL,
&acceptor); &acceptor);
}
/* As we were notified from the IOCP of one and exactly one accept, /* As we were notified from the IOCP of one and exactly one accept,
the former socked we created has now either been destroy or assigned the former socked we created has now either been destroy or assigned
to the new connection. We need to create a new one for the next to the new connection. We need to create a new one for the next

@ -33,7 +33,7 @@
#include <string.h> #include <string.h>
#include "src/core/lib/security/security_context.h" #include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
#include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call.h"

@ -31,11 +31,11 @@
* *
*/ */
#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONTEXT_H #ifndef GRPC_CORE_LIB_SECURITY_CONTEXT_SECURITY_CONTEXT_H
#define GRPC_CORE_LIB_SECURITY_SECURITY_CONTEXT_H #define GRPC_CORE_LIB_SECURITY_CONTEXT_SECURITY_CONTEXT_H
#include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/security/credentials.h" #include "src/core/lib/security/credentials/credentials.h"
/* --- grpc_auth_context --- /* --- grpc_auth_context ---
@ -111,4 +111,4 @@ grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg);
grpc_auth_context *grpc_find_auth_context_in_args( grpc_auth_context *grpc_find_auth_context_in_args(
const grpc_channel_args *args); const grpc_channel_args *args);
#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONTEXT_H */ #endif /* GRPC_CORE_LIB_SECURITY_CONTEXT_SECURITY_CONTEXT_H */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,262 @@
/*
*
* 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.
*
*/
#include "src/core/lib/security/credentials/composite/composite_credentials.h"
#include <string.h>
#include "src/core/lib/surface/api_trace.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
/* -- Composite call credentials. -- */
typedef struct {
grpc_composite_call_credentials *composite_creds;
size_t creds_index;
grpc_credentials_md_store *md_elems;
grpc_auth_metadata_context auth_md_context;
void *user_data;
grpc_pollset *pollset;
grpc_credentials_metadata_cb cb;
} grpc_composite_call_credentials_metadata_context;
static void composite_call_destruct(grpc_call_credentials *creds) {
grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
size_t i;
for (i = 0; i < c->inner.num_creds; i++) {
grpc_call_credentials_unref(c->inner.creds_array[i]);
}
gpr_free(c->inner.creds_array);
}
static void composite_call_md_context_destroy(
grpc_composite_call_credentials_metadata_context *ctx) {
grpc_credentials_md_store_unref(ctx->md_elems);
gpr_free(ctx);
}
static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_credentials_md *md_elems,
size_t num_md,
grpc_credentials_status status) {
grpc_composite_call_credentials_metadata_context *ctx =
(grpc_composite_call_credentials_metadata_context *)user_data;
if (status != GRPC_CREDENTIALS_OK) {
ctx->cb(exec_ctx, ctx->user_data, NULL, 0, status);
return;
}
/* Copy the metadata in the context. */
if (num_md > 0) {
size_t i;
for (i = 0; i < num_md; i++) {
grpc_credentials_md_store_add(ctx->md_elems, md_elems[i].key,
md_elems[i].value);
}
}
/* See if we need to get some more metadata. */
if (ctx->creds_index < ctx->composite_creds->inner.num_creds) {
grpc_call_credentials *inner_creds =
ctx->composite_creds->inner.creds_array[ctx->creds_index++];
grpc_call_credentials_get_request_metadata(
exec_ctx, inner_creds, ctx->pollset, ctx->auth_md_context,
composite_call_metadata_cb, ctx);
return;
}
/* We're done!. */
ctx->cb(exec_ctx, ctx->user_data, ctx->md_elems->entries,
ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK);
composite_call_md_context_destroy(ctx);
}
static void composite_call_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
grpc_pollset *pollset, grpc_auth_metadata_context auth_md_context,
grpc_credentials_metadata_cb cb, void *user_data) {
grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
grpc_composite_call_credentials_metadata_context *ctx;
ctx = gpr_malloc(sizeof(grpc_composite_call_credentials_metadata_context));
memset(ctx, 0, sizeof(grpc_composite_call_credentials_metadata_context));
ctx->auth_md_context = auth_md_context;
ctx->user_data = user_data;
ctx->cb = cb;
ctx->composite_creds = c;
ctx->pollset = pollset;
ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds);
grpc_call_credentials_get_request_metadata(
exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset,
auth_md_context, composite_call_metadata_cb, ctx);
}
static grpc_call_credentials_vtable composite_call_credentials_vtable = {
composite_call_destruct, composite_call_get_request_metadata};
static grpc_call_credentials_array get_creds_array(
grpc_call_credentials **creds_addr) {
grpc_call_credentials_array result;
grpc_call_credentials *creds = *creds_addr;
result.creds_array = creds_addr;
result.num_creds = 1;
if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) {
result = *grpc_composite_call_credentials_get_credentials(creds);
}
return result;
}
grpc_call_credentials *grpc_composite_call_credentials_create(
grpc_call_credentials *creds1, grpc_call_credentials *creds2,
void *reserved) {
size_t i;
size_t creds_array_byte_size;
grpc_call_credentials_array creds1_array;
grpc_call_credentials_array creds2_array;
grpc_composite_call_credentials *c;
GRPC_API_TRACE(
"grpc_composite_call_credentials_create(creds1=%p, creds2=%p, "
"reserved=%p)",
3, (creds1, creds2, reserved));
GPR_ASSERT(reserved == NULL);
GPR_ASSERT(creds1 != NULL);
GPR_ASSERT(creds2 != NULL);
c = gpr_malloc(sizeof(grpc_composite_call_credentials));
memset(c, 0, sizeof(grpc_composite_call_credentials));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE;
c->base.vtable = &composite_call_credentials_vtable;
gpr_ref_init(&c->base.refcount, 1);
creds1_array = get_creds_array(&creds1);
creds2_array = get_creds_array(&creds2);
c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds;
creds_array_byte_size = c->inner.num_creds * sizeof(grpc_call_credentials *);
c->inner.creds_array = gpr_malloc(creds_array_byte_size);
memset(c->inner.creds_array, 0, creds_array_byte_size);
for (i = 0; i < creds1_array.num_creds; i++) {
grpc_call_credentials *cur_creds = creds1_array.creds_array[i];
c->inner.creds_array[i] = grpc_call_credentials_ref(cur_creds);
}
for (i = 0; i < creds2_array.num_creds; i++) {
grpc_call_credentials *cur_creds = creds2_array.creds_array[i];
c->inner.creds_array[i + creds1_array.num_creds] =
grpc_call_credentials_ref(cur_creds);
}
return &c->base;
}
const grpc_call_credentials_array *
grpc_composite_call_credentials_get_credentials(grpc_call_credentials *creds) {
const grpc_composite_call_credentials *c =
(const grpc_composite_call_credentials *)creds;
GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
return &c->inner;
}
grpc_call_credentials *grpc_credentials_contains_type(
grpc_call_credentials *creds, const char *type,
grpc_call_credentials **composite_creds) {
size_t i;
if (strcmp(creds->type, type) == 0) {
if (composite_creds != NULL) *composite_creds = NULL;
return creds;
} else if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) {
const grpc_call_credentials_array *inner_creds_array =
grpc_composite_call_credentials_get_credentials(creds);
for (i = 0; i < inner_creds_array->num_creds; i++) {
if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) {
if (composite_creds != NULL) *composite_creds = creds;
return inner_creds_array->creds_array[i];
}
}
}
return NULL;
}
/* -- Composite channel credentials. -- */
static void composite_channel_destruct(grpc_channel_credentials *creds) {
grpc_composite_channel_credentials *c =
(grpc_composite_channel_credentials *)creds;
grpc_channel_credentials_unref(c->inner_creds);
grpc_call_credentials_unref(c->call_creds);
}
static grpc_security_status composite_channel_create_security_connector(
grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
const char *target, const grpc_channel_args *args,
grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
grpc_composite_channel_credentials *c =
(grpc_composite_channel_credentials *)creds;
grpc_security_status status = GRPC_SECURITY_ERROR;
GPR_ASSERT(c->inner_creds != NULL && c->call_creds != NULL &&
c->inner_creds->vtable != NULL &&
c->inner_creds->vtable->create_security_connector != NULL);
/* If we are passed a call_creds, create a call composite to pass it
downstream. */
if (call_creds != NULL) {
grpc_call_credentials *composite_call_creds =
grpc_composite_call_credentials_create(c->call_creds, call_creds, NULL);
status = c->inner_creds->vtable->create_security_connector(
c->inner_creds, composite_call_creds, target, args, sc, new_args);
grpc_call_credentials_unref(composite_call_creds);
} else {
status = c->inner_creds->vtable->create_security_connector(
c->inner_creds, c->call_creds, target, args, sc, new_args);
}
return status;
}
static grpc_channel_credentials_vtable composite_channel_credentials_vtable = {
composite_channel_destruct, composite_channel_create_security_connector};
grpc_channel_credentials *grpc_composite_channel_credentials_create(
grpc_channel_credentials *channel_creds, grpc_call_credentials *call_creds,
void *reserved) {
grpc_composite_channel_credentials *c = gpr_malloc(sizeof(*c));
memset(c, 0, sizeof(*c));
GPR_ASSERT(channel_creds != NULL && call_creds != NULL && reserved == NULL);
GRPC_API_TRACE(
"grpc_composite_channel_credentials_create(channel_creds=%p, "
"call_creds=%p, reserved=%p)",
3, (channel_creds, call_creds, reserved));
c->base.type = channel_creds->type;
c->base.vtable = &composite_channel_credentials_vtable;
gpr_ref_init(&c->base.refcount, 1);
c->inner_creds = grpc_channel_credentials_ref(channel_creds);
c->call_creds = grpc_call_credentials_ref(call_creds);
return &c->base;
}

@ -0,0 +1,72 @@
/*
*
* 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.
*
*/
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H
#include "src/core/lib/security/credentials/credentials.h"
typedef struct {
grpc_call_credentials **creds_array;
size_t num_creds;
} grpc_call_credentials_array;
const grpc_call_credentials_array *
grpc_composite_call_credentials_get_credentials(
grpc_call_credentials *composite_creds);
/* Returns creds if creds is of the specified type or the inner creds of the
specified type (if found), if the creds is of type COMPOSITE.
If composite_creds is not NULL, *composite_creds will point to creds if of
type COMPOSITE in case of success. */
grpc_call_credentials *grpc_credentials_contains_type(
grpc_call_credentials *creds, const char *type,
grpc_call_credentials **composite_creds);
/* -- Channel composite credentials. -- */
typedef struct {
grpc_channel_credentials base;
grpc_channel_credentials *inner_creds;
grpc_call_credentials *call_creds;
} grpc_composite_channel_credentials;
/* -- Composite credentials. -- */
typedef struct {
grpc_call_credentials base;
grpc_call_credentials_array inner;
} grpc_composite_call_credentials;
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H \
*/

@ -0,0 +1,231 @@
/*
*
* 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.
*
*/
#include "src/core/lib/security/credentials/credentials.h"
#include <stdio.h>
#include <string.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/http_client_filter.h"
#include "src/core/lib/http/httpcli.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/api_trace.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
/* -- Common. -- */
grpc_credentials_metadata_request *grpc_credentials_metadata_request_create(
grpc_call_credentials *creds, grpc_credentials_metadata_cb cb,
void *user_data) {
grpc_credentials_metadata_request *r =
gpr_malloc(sizeof(grpc_credentials_metadata_request));
r->creds = grpc_call_credentials_ref(creds);
r->cb = cb;
r->user_data = user_data;
return r;
}
void grpc_credentials_metadata_request_destroy(
grpc_credentials_metadata_request *r) {
grpc_call_credentials_unref(r->creds);
gpr_free(r);
}
grpc_channel_credentials *grpc_channel_credentials_ref(
grpc_channel_credentials *creds) {
if (creds == NULL) return NULL;
gpr_ref(&creds->refcount);
return creds;
}
void grpc_channel_credentials_unref(grpc_channel_credentials *creds) {
if (creds == NULL) return;
if (gpr_unref(&creds->refcount)) {
if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
gpr_free(creds);
}
}
void grpc_channel_credentials_release(grpc_channel_credentials *creds) {
GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds));
grpc_channel_credentials_unref(creds);
}
grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds) {
if (creds == NULL) return NULL;
gpr_ref(&creds->refcount);
return creds;
}
void grpc_call_credentials_unref(grpc_call_credentials *creds) {
if (creds == NULL) return;
if (gpr_unref(&creds->refcount)) {
if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
gpr_free(creds);
}
}
void grpc_call_credentials_release(grpc_call_credentials *creds) {
GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds));
grpc_call_credentials_unref(creds);
}
void grpc_call_credentials_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
grpc_pollset *pollset, grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb, void *user_data) {
if (creds == NULL || creds->vtable->get_request_metadata == NULL) {
if (cb != NULL) {
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
}
return;
}
creds->vtable->get_request_metadata(exec_ctx, creds, pollset, context, cb,
user_data);
}
grpc_security_status grpc_channel_credentials_create_security_connector(
grpc_channel_credentials *channel_creds, const char *target,
const grpc_channel_args *args, grpc_channel_security_connector **sc,
grpc_channel_args **new_args) {
*new_args = NULL;
if (channel_creds == NULL) {
return GRPC_SECURITY_ERROR;
}
GPR_ASSERT(channel_creds->vtable->create_security_connector != NULL);
return channel_creds->vtable->create_security_connector(
channel_creds, NULL, target, args, sc, new_args);
}
grpc_server_credentials *grpc_server_credentials_ref(
grpc_server_credentials *creds) {
if (creds == NULL) return NULL;
gpr_ref(&creds->refcount);
return creds;
}
void grpc_server_credentials_unref(grpc_server_credentials *creds) {
if (creds == NULL) return;
if (gpr_unref(&creds->refcount)) {
if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
if (creds->processor.destroy != NULL && creds->processor.state != NULL) {
creds->processor.destroy(creds->processor.state);
}
gpr_free(creds);
}
}
void grpc_server_credentials_release(grpc_server_credentials *creds) {
GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds));
grpc_server_credentials_unref(creds);
}
grpc_security_status grpc_server_credentials_create_security_connector(
grpc_server_credentials *creds, grpc_server_security_connector **sc) {
if (creds == NULL || creds->vtable->create_security_connector == NULL) {
gpr_log(GPR_ERROR, "Server credentials cannot create security context.");
return GRPC_SECURITY_ERROR;
}
return creds->vtable->create_security_connector(creds, sc);
}
void grpc_server_credentials_set_auth_metadata_processor(
grpc_server_credentials *creds, grpc_auth_metadata_processor processor) {
GRPC_API_TRACE(
"grpc_server_credentials_set_auth_metadata_processor("
"creds=%p, "
"processor=grpc_auth_metadata_processor { process: %p, state: %p })",
3, (creds, (void *)(intptr_t)processor.process, processor.state));
if (creds == NULL) return;
if (creds->processor.destroy != NULL && creds->processor.state != NULL) {
creds->processor.destroy(creds->processor.state);
}
creds->processor = processor;
}
static void server_credentials_pointer_arg_destroy(void *p) {
grpc_server_credentials_unref(p);
}
static void *server_credentials_pointer_arg_copy(void *p) {
return grpc_server_credentials_ref(p);
}
static int server_credentials_pointer_cmp(void *a, void *b) {
return GPR_ICMP(a, b);
}
static const grpc_arg_pointer_vtable cred_ptr_vtable = {
server_credentials_pointer_arg_copy, server_credentials_pointer_arg_destroy,
server_credentials_pointer_cmp};
grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *p) {
grpc_arg arg;
memset(&arg, 0, sizeof(grpc_arg));
arg.type = GRPC_ARG_POINTER;
arg.key = GRPC_SERVER_CREDENTIALS_ARG;
arg.value.pointer.p = p;
arg.value.pointer.vtable = &cred_ptr_vtable;
return arg;
}
grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg) {
if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return NULL;
if (arg->type != GRPC_ARG_POINTER) {
gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
GRPC_SERVER_CREDENTIALS_ARG);
return NULL;
}
return arg->value.pointer.p;
}
grpc_server_credentials *grpc_find_server_credentials_in_args(
const grpc_channel_args *args) {
size_t i;
if (args == NULL) return NULL;
for (i = 0; i < args->num_args; i++) {
grpc_server_credentials *p =
grpc_server_credentials_from_arg(&args->args[i]);
if (p != NULL) return p;
}
return NULL;
}

@ -31,8 +31,8 @@
* *
*/ */
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_H #ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_H #define GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/grpc_security.h> #include <grpc/grpc_security.h>
@ -41,8 +41,7 @@
#include "src/core/lib/http/httpcli.h" #include "src/core/lib/http/httpcli.h"
#include "src/core/lib/http/parser.h" #include "src/core/lib/http/parser.h"
#include "src/core/lib/security/json_token.h" #include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/security/security_connector.h"
struct grpc_http_response; struct grpc_http_response;
@ -69,10 +68,6 @@ typedef enum {
"x-goog-iam-authorization-token" "x-goog-iam-authorization-token"
#define GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY "x-goog-iam-authority-selector" #define GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY "x-goog-iam-authority-selector"
#define GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY "gcloud"
#define GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE \
"application_default_credentials.json"
#define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS 60 #define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS 60
#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata" #define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata"
@ -188,48 +183,11 @@ void grpc_call_credentials_get_request_metadata(
grpc_pollset *pollset, grpc_auth_metadata_context context, grpc_pollset *pollset, grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb, void *user_data); grpc_credentials_metadata_cb cb, void *user_data);
typedef struct {
grpc_call_credentials **creds_array;
size_t num_creds;
} grpc_call_credentials_array;
const grpc_call_credentials_array *
grpc_composite_call_credentials_get_credentials(
grpc_call_credentials *composite_creds);
/* Returns creds if creds is of the specified type or the inner creds of the
specified type (if found), if the creds is of type COMPOSITE.
If composite_creds is not NULL, *composite_creds will point to creds if of
type COMPOSITE in case of success. */
grpc_call_credentials *grpc_credentials_contains_type(
grpc_call_credentials *creds, const char *type,
grpc_call_credentials **composite_creds);
/* Exposed for testing only. */
grpc_credentials_status
grpc_oauth2_token_fetcher_credentials_parse_server_response(
const struct grpc_http_response *response,
grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime);
void grpc_flush_cached_google_default_credentials(void);
/* Metadata-only credentials with the specified key and value where /* Metadata-only credentials with the specified key and value where
asynchronicity can be simulated for testing. */ asynchronicity can be simulated for testing. */
grpc_call_credentials *grpc_md_only_test_credentials_create( grpc_call_credentials *grpc_md_only_test_credentials_create(
const char *md_key, const char *md_value, int is_async); const char *md_key, const char *md_value, int is_async);
/* Private constructor for jwt credentials from an already parsed json key.
Takes ownership of the key. */
grpc_call_credentials *
grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
grpc_auth_json_key key, gpr_timespec token_lifetime);
/* Private constructor for refresh token credentials from an already parsed
refresh token. Takes ownership of the refresh token. */
grpc_call_credentials *
grpc_refresh_token_credentials_create_from_auth_refresh_token(
grpc_auth_refresh_token token);
/* --- grpc_server_credentials. --- */ /* --- grpc_server_credentials. --- */
typedef struct { typedef struct {
@ -260,118 +218,19 @@ grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg);
grpc_server_credentials *grpc_find_server_credentials_in_args( grpc_server_credentials *grpc_find_server_credentials_in_args(
const grpc_channel_args *args); const grpc_channel_args *args);
/* -- Fake transport security credentials. -- */ /* -- Credentials Metadata Request. -- */
/* Creates a fake transport security credentials object for testing. */
grpc_channel_credentials *grpc_fake_transport_security_credentials_create(void);
/* Creates a fake server transport security credentials object for testing. */
grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
void);
/* -- Ssl credentials. -- */
typedef struct {
grpc_channel_credentials base;
grpc_ssl_config config;
} grpc_ssl_credentials;
typedef struct {
grpc_server_credentials base;
grpc_ssl_server_config config;
} grpc_ssl_server_credentials;
/* -- Channel composite credentials. -- */
typedef struct {
grpc_channel_credentials base;
grpc_channel_credentials *inner_creds;
grpc_call_credentials *call_creds;
} grpc_composite_channel_credentials;
/* -- Jwt credentials -- */
typedef struct { typedef struct {
grpc_call_credentials base; grpc_call_credentials *creds;
grpc_credentials_metadata_cb cb;
/* Have a simple cache for now with just 1 entry. We could have a map based on void *user_data;
the service_url for a more sophisticated one. */ } grpc_credentials_metadata_request;
gpr_mu cache_mu;
struct {
grpc_credentials_md_store *jwt_md;
char *service_url;
gpr_timespec jwt_expiration;
} cached;
grpc_auth_json_key key;
gpr_timespec jwt_lifetime;
} grpc_service_account_jwt_access_credentials;
/* -- Oauth2TokenFetcher credentials --
This object is a base for credentials that need to acquire an oauth2 token
from an http service. */
typedef struct grpc_credentials_metadata_request
grpc_credentials_metadata_request;
typedef void (*grpc_fetch_oauth2_func)(grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *grpc_credentials_metadata_request_create(
grpc_credentials_metadata_request *req, grpc_call_credentials *creds, grpc_credentials_metadata_cb cb,
grpc_httpcli_context *http_context, void *user_data);
grpc_pollset *pollset,
grpc_httpcli_response_cb response_cb,
gpr_timespec deadline);
typedef struct { void grpc_credentials_metadata_request_destroy(
grpc_call_credentials base; grpc_credentials_metadata_request *r);
gpr_mu mu;
grpc_credentials_md_store *access_token_md;
gpr_timespec token_expiration;
grpc_httpcli_context httpcli_context;
grpc_fetch_oauth2_func fetch_func;
} grpc_oauth2_token_fetcher_credentials;
/* -- GoogleRefreshToken credentials. -- */
typedef struct {
grpc_oauth2_token_fetcher_credentials base;
grpc_auth_refresh_token refresh_token;
} grpc_google_refresh_token_credentials;
/* -- Oauth2 Access Token credentials. -- */
typedef struct {
grpc_call_credentials base;
grpc_credentials_md_store *access_token_md;
} grpc_access_token_credentials;
/* -- Metadata-only Test credentials. -- */
typedef struct {
grpc_call_credentials base;
grpc_credentials_md_store *md_store;
int is_async;
} grpc_md_only_test_credentials;
/* -- GoogleIAM credentials. -- */
typedef struct {
grpc_call_credentials base;
grpc_credentials_md_store *iam_md;
} grpc_google_iam_credentials;
/* -- Composite credentials. -- */
typedef struct {
grpc_call_credentials base;
grpc_call_credentials_array inner;
} grpc_composite_call_credentials;
/* -- Plugin credentials. -- */
typedef struct {
grpc_call_credentials base;
grpc_metadata_credentials_plugin plugin;
grpc_credentials_md_store *plugin_md;
} grpc_plugin_credentials;
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_H */ #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H */

@ -31,7 +31,7 @@
* *
*/ */
#include "src/core/lib/security/credentials.h" #include "src/core/lib/security/credentials/credentials.h"
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>

@ -0,0 +1,138 @@
/*
*
* 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.
*
*/
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
#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>
/* -- Fake transport security credentials. -- */
static grpc_security_status fake_transport_security_create_security_connector(
grpc_channel_credentials *c, 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);
return GRPC_SECURITY_OK;
}
static grpc_security_status
fake_transport_security_server_create_security_connector(
grpc_server_credentials *c, grpc_server_security_connector **sc) {
*sc = grpc_fake_server_security_connector_create();
return GRPC_SECURITY_OK;
}
static grpc_channel_credentials_vtable
fake_transport_security_credentials_vtable = {
NULL, fake_transport_security_create_security_connector};
static grpc_server_credentials_vtable
fake_transport_security_server_credentials_vtable = {
NULL, fake_transport_security_server_create_security_connector};
grpc_channel_credentials *grpc_fake_transport_security_credentials_create(
void) {
grpc_channel_credentials *c = gpr_malloc(sizeof(grpc_channel_credentials));
memset(c, 0, sizeof(grpc_channel_credentials));
c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
c->vtable = &fake_transport_security_credentials_vtable;
gpr_ref_init(&c->refcount, 1);
return c;
}
grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
void) {
grpc_server_credentials *c = gpr_malloc(sizeof(grpc_server_credentials));
memset(c, 0, sizeof(grpc_server_credentials));
c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
gpr_ref_init(&c->refcount, 1);
c->vtable = &fake_transport_security_server_credentials_vtable;
return c;
}
/* -- Metadata-only test credentials. -- */
static void md_only_test_destruct(grpc_call_credentials *creds) {
grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
grpc_credentials_md_store_unref(c->md_store);
}
static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx,
void *user_data, bool success) {
grpc_credentials_metadata_request *r =
(grpc_credentials_metadata_request *)user_data;
grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)r->creds;
r->cb(exec_ctx, r->user_data, c->md_store->entries, c->md_store->num_entries,
GRPC_CREDENTIALS_OK);
grpc_credentials_metadata_request_destroy(r);
}
static void md_only_test_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
grpc_pollset *pollset, grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb, void *user_data) {
grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
if (c->is_async) {
grpc_credentials_metadata_request *cb_arg =
grpc_credentials_metadata_request_create(creds, cb, user_data);
grpc_executor_enqueue(
grpc_closure_create(on_simulated_token_fetch_done, cb_arg), true);
} else {
cb(exec_ctx, user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK);
}
}
static grpc_call_credentials_vtable md_only_test_vtable = {
md_only_test_destruct, md_only_test_get_request_metadata};
grpc_call_credentials *grpc_md_only_test_credentials_create(
const char *md_key, const char *md_value, int is_async) {
grpc_md_only_test_credentials *c =
gpr_malloc(sizeof(grpc_md_only_test_credentials));
memset(c, 0, sizeof(grpc_md_only_test_credentials));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
c->base.vtable = &md_only_test_vtable;
gpr_ref_init(&c->base.refcount, 1);
c->md_store = grpc_credentials_md_store_create(1);
grpc_credentials_md_store_add_cstrings(c->md_store, md_key, md_value);
c->is_async = is_async;
return &c->base;
}

@ -0,0 +1,56 @@
/*
*
* 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_LIB_SECURITY_CREDENTIALS_FAKE_FAKE_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_FAKE_FAKE_CREDENTIALS_H
#include "src/core/lib/security/credentials/credentials.h"
/* -- Fake transport security credentials. -- */
/* Creates a fake transport security credentials object for testing. */
grpc_channel_credentials *grpc_fake_transport_security_credentials_create(void);
/* Creates a fake server transport security credentials object for testing. */
grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
void);
/* -- Metadata-only Test credentials. -- */
typedef struct {
grpc_call_credentials base;
grpc_credentials_md_store *md_store;
int is_async;
} grpc_md_only_test_credentials;
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_FAKE_FAKE_CREDENTIALS_H */

@ -35,7 +35,7 @@
#ifdef GPR_POSIX_FILE #ifdef GPR_POSIX_FILE
#include "src/core/lib/security/credentials.h" #include "src/core/lib/security/credentials/google_default/google_default_credentials.h"
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>

@ -35,7 +35,7 @@
#ifdef GPR_WIN32 #ifdef GPR_WIN32
#include "src/core/lib/security/credentials.h" #include "src/core/lib/security/credentials/google_default/google_default_credentials.h"
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>

@ -31,7 +31,7 @@
* *
*/ */
#include "src/core/lib/security/credentials.h" #include "src/core/lib/security/credentials/credentials.h"
#include <string.h> #include <string.h>
@ -41,6 +41,8 @@
#include "src/core/lib/http/httpcli.h" #include "src/core/lib/http/httpcli.h"
#include "src/core/lib/http/parser.h" #include "src/core/lib/http/parser.h"
#include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
#include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
#include "src/core/lib/support/env.h" #include "src/core/lib/support/env.h"
#include "src/core/lib/support/load_file.h" #include "src/core/lib/support/load_file.h"
#include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/api_trace.h"

@ -0,0 +1,46 @@
/*
*
* 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_LIB_SECURITY_CREDENTIALS_GOOGLE_DEFAULT_GOOGLE_DEFAULT_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_GOOGLE_DEFAULT_GOOGLE_DEFAULT_CREDENTIALS_H
#include "src/core/lib/security/credentials/credentials.h"
#define GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY "gcloud"
#define GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE \
"application_default_credentials.json"
void grpc_flush_cached_google_default_credentials(void);
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_GOOGLE_DEFAULT_GOOGLE_DEFAULT_CREDENTIALS_H \
*/

@ -0,0 +1,85 @@
/*
*
* 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.
*
*/
#include "src/core/lib/security/credentials/iam/iam_credentials.h"
#include <string.h>
#include "src/core/lib/surface/api_trace.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
static void iam_destruct(grpc_call_credentials *creds) {
grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
grpc_credentials_md_store_unref(c->iam_md);
}
static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds,
grpc_pollset *pollset,
grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb,
void *user_data) {
grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
cb(exec_ctx, user_data, c->iam_md->entries, c->iam_md->num_entries,
GRPC_CREDENTIALS_OK);
}
static grpc_call_credentials_vtable iam_vtable = {iam_destruct,
iam_get_request_metadata};
grpc_call_credentials *grpc_google_iam_credentials_create(
const char *token, const char *authority_selector, void *reserved) {
grpc_google_iam_credentials *c;
GRPC_API_TRACE(
"grpc_iam_credentials_create(token=%s, authority_selector=%s, "
"reserved=%p)",
3, (token, authority_selector, reserved));
GPR_ASSERT(reserved == NULL);
GPR_ASSERT(token != NULL);
GPR_ASSERT(authority_selector != NULL);
c = gpr_malloc(sizeof(grpc_google_iam_credentials));
memset(c, 0, sizeof(grpc_google_iam_credentials));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_IAM;
c->base.vtable = &iam_vtable;
gpr_ref_init(&c->base.refcount, 1);
c->iam_md = grpc_credentials_md_store_create(2);
grpc_credentials_md_store_add_cstrings(
c->iam_md, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, token);
grpc_credentials_md_store_add_cstrings(
c->iam_md, GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, authority_selector);
return &c->base;
}

@ -0,0 +1,44 @@
/*
*
* 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_LIB_SECURITY_CREDENTIALS_IAM_IAM_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_IAM_IAM_CREDENTIALS_H
#include "src/core/lib/security/credentials/credentials.h"
typedef struct {
grpc_call_credentials base;
grpc_credentials_md_store *iam_md;
} grpc_google_iam_credentials;
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_IAM_IAM_CREDENTIALS_H */

@ -31,7 +31,7 @@
* *
*/ */
#include "src/core/lib/security/json_token.h" #include "src/core/lib/security/credentials/jwt/json_token.h"
#include <string.h> #include <string.h>
@ -39,7 +39,8 @@
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/string_util.h> #include <grpc/support/string_util.h>
#include "src/core/lib/security/b64.h" #include "src/core/lib/security/util/b64.h"
#include "src/core/lib/security/util/json_util.h"
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
#include <openssl/bio.h> #include <openssl/bio.h>
@ -66,28 +67,6 @@ static grpc_jwt_encode_and_sign_override g_jwt_encode_and_sign_override = NULL;
/* --- grpc_auth_json_key. --- */ /* --- grpc_auth_json_key. --- */
static const char *json_get_string_property(const grpc_json *json,
const char *prop_name) {
grpc_json *child;
for (child = json->child; child != NULL; child = child->next) {
if (strcmp(child->key, prop_name) == 0) break;
}
if (child == NULL || child->type != GRPC_JSON_STRING) {
gpr_log(GPR_ERROR, "Invalid or missing %s property.", prop_name);
return NULL;
}
return child->value;
}
static int set_json_key_string_property(const grpc_json *json,
const char *prop_name,
char **json_key_field) {
const char *prop_value = json_get_string_property(json, prop_name);
if (prop_value == NULL) return 0;
*json_key_field = gpr_strdup(prop_value);
return 1;
}
int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key) { int grpc_auth_json_key_is_valid(const grpc_auth_json_key *json_key) {
return (json_key != NULL) && return (json_key != NULL) &&
strcmp(json_key->type, GRPC_AUTH_JSON_TYPE_INVALID); strcmp(json_key->type, GRPC_AUTH_JSON_TYPE_INVALID);
@ -106,22 +85,22 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json *json) {
goto end; goto end;
} }
prop_value = json_get_string_property(json, "type"); prop_value = grpc_json_get_string_property(json, "type");
if (prop_value == NULL || if (prop_value == NULL ||
strcmp(prop_value, GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT)) { strcmp(prop_value, GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT)) {
goto end; goto end;
} }
result.type = GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT; result.type = GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT;
if (!set_json_key_string_property(json, "private_key_id", if (!grpc_copy_json_string_property(json, "private_key_id",
&result.private_key_id) || &result.private_key_id) ||
!set_json_key_string_property(json, "client_id", &result.client_id) || !grpc_copy_json_string_property(json, "client_id", &result.client_id) ||
!set_json_key_string_property(json, "client_email", !grpc_copy_json_string_property(json, "client_email",
&result.client_email)) { &result.client_email)) {
goto end; goto end;
} }
prop_value = json_get_string_property(json, "private_key"); prop_value = grpc_json_get_string_property(json, "private_key");
if (prop_value == NULL) { if (prop_value == NULL) {
goto end; goto end;
} }
@ -339,73 +318,3 @@ void grpc_jwt_encode_and_sign_set_override(
grpc_jwt_encode_and_sign_override func) { grpc_jwt_encode_and_sign_override func) {
g_jwt_encode_and_sign_override = func; g_jwt_encode_and_sign_override = func;
} }
/* --- grpc_auth_refresh_token --- */
int grpc_auth_refresh_token_is_valid(
const grpc_auth_refresh_token *refresh_token) {
return (refresh_token != NULL) &&
strcmp(refresh_token->type, GRPC_AUTH_JSON_TYPE_INVALID);
}
grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json(
const grpc_json *json) {
grpc_auth_refresh_token result;
const char *prop_value;
int success = 0;
memset(&result, 0, sizeof(grpc_auth_refresh_token));
result.type = GRPC_AUTH_JSON_TYPE_INVALID;
if (json == NULL) {
gpr_log(GPR_ERROR, "Invalid json.");
goto end;
}
prop_value = json_get_string_property(json, "type");
if (prop_value == NULL ||
strcmp(prop_value, GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER)) {
goto end;
}
result.type = GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER;
if (!set_json_key_string_property(json, "client_secret",
&result.client_secret) ||
!set_json_key_string_property(json, "client_id", &result.client_id) ||
!set_json_key_string_property(json, "refresh_token",
&result.refresh_token)) {
goto end;
}
success = 1;
end:
if (!success) grpc_auth_refresh_token_destruct(&result);
return result;
}
grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string(
const char *json_string) {
char *scratchpad = gpr_strdup(json_string);
grpc_json *json = grpc_json_parse_string(scratchpad);
grpc_auth_refresh_token result =
grpc_auth_refresh_token_create_from_json(json);
if (json != NULL) grpc_json_destroy(json);
gpr_free(scratchpad);
return result;
}
void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token) {
if (refresh_token == NULL) return;
refresh_token->type = GRPC_AUTH_JSON_TYPE_INVALID;
if (refresh_token->client_id != NULL) {
gpr_free(refresh_token->client_id);
refresh_token->client_id = NULL;
}
if (refresh_token->client_secret != NULL) {
gpr_free(refresh_token->client_secret);
refresh_token->client_secret = NULL;
}
if (refresh_token->refresh_token != NULL) {
gpr_free(refresh_token->refresh_token);
refresh_token->refresh_token = NULL;
}
}

@ -31,8 +31,8 @@
* *
*/ */
#ifndef GRPC_CORE_LIB_SECURITY_JSON_TOKEN_H #ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JSON_TOKEN_H
#define GRPC_CORE_LIB_SECURITY_JSON_TOKEN_H #define GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JSON_TOKEN_H
#include <grpc/support/slice.h> #include <grpc/support/slice.h>
#include <openssl/rsa.h> #include <openssl/rsa.h>
@ -43,10 +43,6 @@
#define GRPC_JWT_OAUTH2_AUDIENCE "https://www.googleapis.com/oauth2/v3/token" #define GRPC_JWT_OAUTH2_AUDIENCE "https://www.googleapis.com/oauth2/v3/token"
#define GRPC_AUTH_JSON_TYPE_INVALID "invalid"
#define GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT "service_account"
#define GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER "authorized_user"
/* --- auth_json_key parsing. --- */ /* --- auth_json_key parsing. --- */
typedef struct { typedef struct {
@ -89,30 +85,4 @@ typedef char *(*grpc_jwt_encode_and_sign_override)(
void grpc_jwt_encode_and_sign_set_override( void grpc_jwt_encode_and_sign_set_override(
grpc_jwt_encode_and_sign_override func); grpc_jwt_encode_and_sign_override func);
/* --- auth_refresh_token parsing. --- */ #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JSON_TOKEN_H */
typedef struct {
const char *type;
char *client_id;
char *client_secret;
char *refresh_token;
} grpc_auth_refresh_token;
/* Returns 1 if the object is valid, 0 otherwise. */
int grpc_auth_refresh_token_is_valid(
const grpc_auth_refresh_token *refresh_token);
/* Creates a refresh token object from string. Returns an invalid object if a
parsing error has been encountered. */
grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string(
const char *json_string);
/* Creates a refresh token object from parsed json. Returns an invalid object if
a parsing error has been encountered. */
grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json(
const grpc_json *json);
/* Destructs the object. */
void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token);
#endif /* GRPC_CORE_LIB_SECURITY_JSON_TOKEN_H */

@ -0,0 +1,160 @@
/*
*
* 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.
*
*/
#include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
#include <string.h>
#include "src/core/lib/surface/api_trace.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
static void jwt_reset_cache(grpc_service_account_jwt_access_credentials *c) {
if (c->cached.jwt_md != NULL) {
grpc_credentials_md_store_unref(c->cached.jwt_md);
c->cached.jwt_md = NULL;
}
if (c->cached.service_url != NULL) {
gpr_free(c->cached.service_url);
c->cached.service_url = NULL;
}
c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
}
static void jwt_destruct(grpc_call_credentials *creds) {
grpc_service_account_jwt_access_credentials *c =
(grpc_service_account_jwt_access_credentials *)creds;
grpc_auth_json_key_destruct(&c->key);
jwt_reset_cache(c);
gpr_mu_destroy(&c->cache_mu);
}
static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds,
grpc_pollset *pollset,
grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb,
void *user_data) {
grpc_service_account_jwt_access_credentials *c =
(grpc_service_account_jwt_access_credentials *)creds;
gpr_timespec refresh_threshold = gpr_time_from_seconds(
GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN);
/* See if we can return a cached jwt. */
grpc_credentials_md_store *jwt_md = NULL;
{
gpr_mu_lock(&c->cache_mu);
if (c->cached.service_url != NULL &&
strcmp(c->cached.service_url, context.service_url) == 0 &&
c->cached.jwt_md != NULL &&
(gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration,
gpr_now(GPR_CLOCK_REALTIME)),
refresh_threshold) > 0)) {
jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md);
}
gpr_mu_unlock(&c->cache_mu);
}
if (jwt_md == NULL) {
char *jwt = NULL;
/* Generate a new jwt. */
gpr_mu_lock(&c->cache_mu);
jwt_reset_cache(c);
jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url,
c->jwt_lifetime, NULL);
if (jwt != NULL) {
char *md_value;
gpr_asprintf(&md_value, "Bearer %s", jwt);
gpr_free(jwt);
c->cached.jwt_expiration =
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime);
c->cached.service_url = gpr_strdup(context.service_url);
c->cached.jwt_md = grpc_credentials_md_store_create(1);
grpc_credentials_md_store_add_cstrings(
c->cached.jwt_md, GRPC_AUTHORIZATION_METADATA_KEY, md_value);
gpr_free(md_value);
jwt_md = grpc_credentials_md_store_ref(c->cached.jwt_md);
}
gpr_mu_unlock(&c->cache_mu);
}
if (jwt_md != NULL) {
cb(exec_ctx, user_data, jwt_md->entries, jwt_md->num_entries,
GRPC_CREDENTIALS_OK);
grpc_credentials_md_store_unref(jwt_md);
} else {
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_ERROR);
}
}
static grpc_call_credentials_vtable jwt_vtable = {jwt_destruct,
jwt_get_request_metadata};
grpc_call_credentials *
grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
grpc_auth_json_key key, gpr_timespec token_lifetime) {
grpc_service_account_jwt_access_credentials *c;
if (!grpc_auth_json_key_is_valid(&key)) {
gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation");
return NULL;
}
c = gpr_malloc(sizeof(grpc_service_account_jwt_access_credentials));
memset(c, 0, sizeof(grpc_service_account_jwt_access_credentials));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_JWT;
gpr_ref_init(&c->base.refcount, 1);
c->base.vtable = &jwt_vtable;
c->key = key;
c->jwt_lifetime = token_lifetime;
gpr_mu_init(&c->cache_mu);
jwt_reset_cache(c);
return &c->base;
}
grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
const char *json_key, gpr_timespec token_lifetime, void *reserved) {
GRPC_API_TRACE(
"grpc_service_account_jwt_access_credentials_create("
"json_key=%s, "
"token_lifetime="
"gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
5,
(json_key, (long long)token_lifetime.tv_sec, (int)token_lifetime.tv_nsec,
(int)token_lifetime.clock_type, reserved));
GPR_ASSERT(reserved == NULL);
return grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
grpc_auth_json_key_create_from_string(json_key), token_lifetime);
}

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -31,48 +31,32 @@
* *
*/ */
#include <set> #ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H
#include <grpc/support/log.h> #include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/jwt/json_token.h"
#include "test/cpp/qps/driver.h" typedef struct {
#include "test/cpp/qps/report.h" grpc_call_credentials base;
#include "test/cpp/util/benchmark_config.h"
namespace grpc { // Have a simple cache for now with just 1 entry. We could have a map based on
namespace testing { // the service_url for a more sophisticated one.
gpr_mu cache_mu;
struct {
grpc_credentials_md_store *jwt_md;
char *service_url;
gpr_timespec jwt_expiration;
} cached;
static const int WARMUP = 5; grpc_auth_json_key key;
static const int BENCHMARK = 5; gpr_timespec jwt_lifetime;
} grpc_service_account_jwt_access_credentials;
static void RunAsyncStreamingPingPong() { // Private constructor for jwt credentials from an already parsed json key.
gpr_log(GPR_INFO, "Running Async Streaming Ping Pong"); // Takes ownership of the key.
grpc_call_credentials *
grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
grpc_auth_json_key key, gpr_timespec token_lifetime);
ClientConfig client_config; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H */
client_config.set_client_type(ASYNC_CLIENT);
client_config.set_outstanding_rpcs_per_channel(1);
client_config.set_client_channels(1);
client_config.set_async_client_threads(1);
client_config.set_rpc_type(STREAMING);
client_config.mutable_load_params()->mutable_closed_loop();
ServerConfig server_config;
server_config.set_server_type(ASYNC_SERVER);
server_config.set_async_server_threads(1);
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
GetReporter()->ReportQPS(*result);
GetReporter()->ReportLatency(*result);
}
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
grpc::testing::InitBenchmark(&argc, &argv, true);
grpc::testing::RunAsyncStreamingPingPong();
return 0;
}

@ -31,13 +31,13 @@
* *
*/ */
#include "src/core/lib/security/jwt_verifier.h" #include "src/core/lib/security/credentials/jwt/jwt_verifier.h"
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include "src/core/lib/http/httpcli.h" #include "src/core/lib/http/httpcli.h"
#include "src/core/lib/security/b64.h" #include "src/core/lib/security/util/b64.h"
#include "src/core/lib/tsi/ssl_types.h" #include "src/core/lib/tsi/ssl_types.h"
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>

@ -31,8 +31,8 @@
* *
*/ */
#ifndef GRPC_CORE_LIB_SECURITY_JWT_VERIFIER_H #ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_VERIFIER_H
#define GRPC_CORE_LIB_SECURITY_JWT_VERIFIER_H #define GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_VERIFIER_H
#include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/json/json.h" #include "src/core/lib/json/json.h"
@ -133,4 +133,4 @@ grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_json *json, gpr_slice buffer);
grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims, grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
const char *audience); const char *audience);
#endif /* GRPC_CORE_LIB_SECURITY_JWT_VERIFIER_H */ #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_VERIFIER_H */

@ -0,0 +1,428 @@
/*
*
* 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.
*
*/
#include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
#include <string.h>
#include "src/core/lib/security/util/json_util.h"
#include "src/core/lib/surface/api_trace.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
//
// Auth Refresh Token.
//
int grpc_auth_refresh_token_is_valid(
const grpc_auth_refresh_token *refresh_token) {
return (refresh_token != NULL) &&
strcmp(refresh_token->type, GRPC_AUTH_JSON_TYPE_INVALID);
}
grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json(
const grpc_json *json) {
grpc_auth_refresh_token result;
const char *prop_value;
int success = 0;
memset(&result, 0, sizeof(grpc_auth_refresh_token));
result.type = GRPC_AUTH_JSON_TYPE_INVALID;
if (json == NULL) {
gpr_log(GPR_ERROR, "Invalid json.");
goto end;
}
prop_value = grpc_json_get_string_property(json, "type");
if (prop_value == NULL ||
strcmp(prop_value, GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER)) {
goto end;
}
result.type = GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER;
if (!grpc_copy_json_string_property(json, "client_secret",
&result.client_secret) ||
!grpc_copy_json_string_property(json, "client_id", &result.client_id) ||
!grpc_copy_json_string_property(json, "refresh_token",
&result.refresh_token)) {
goto end;
}
success = 1;
end:
if (!success) grpc_auth_refresh_token_destruct(&result);
return result;
}
grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string(
const char *json_string) {
char *scratchpad = gpr_strdup(json_string);
grpc_json *json = grpc_json_parse_string(scratchpad);
grpc_auth_refresh_token result =
grpc_auth_refresh_token_create_from_json(json);
if (json != NULL) grpc_json_destroy(json);
gpr_free(scratchpad);
return result;
}
void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token) {
if (refresh_token == NULL) return;
refresh_token->type = GRPC_AUTH_JSON_TYPE_INVALID;
if (refresh_token->client_id != NULL) {
gpr_free(refresh_token->client_id);
refresh_token->client_id = NULL;
}
if (refresh_token->client_secret != NULL) {
gpr_free(refresh_token->client_secret);
refresh_token->client_secret = NULL;
}
if (refresh_token->refresh_token != NULL) {
gpr_free(refresh_token->refresh_token);
refresh_token->refresh_token = NULL;
}
}
//
// Oauth2 Token Fetcher credentials.
//
static void oauth2_token_fetcher_destruct(grpc_call_credentials *creds) {
grpc_oauth2_token_fetcher_credentials *c =
(grpc_oauth2_token_fetcher_credentials *)creds;
grpc_credentials_md_store_unref(c->access_token_md);
gpr_mu_destroy(&c->mu);
grpc_httpcli_context_destroy(&c->httpcli_context);
}
grpc_credentials_status
grpc_oauth2_token_fetcher_credentials_parse_server_response(
const grpc_http_response *response, grpc_credentials_md_store **token_md,
gpr_timespec *token_lifetime) {
char *null_terminated_body = NULL;
char *new_access_token = NULL;
grpc_credentials_status status = GRPC_CREDENTIALS_OK;
grpc_json *json = NULL;
if (response == NULL) {
gpr_log(GPR_ERROR, "Received NULL response.");
status = GRPC_CREDENTIALS_ERROR;
goto end;
}
if (response->body_length > 0) {
null_terminated_body = gpr_malloc(response->body_length + 1);
null_terminated_body[response->body_length] = '\0';
memcpy(null_terminated_body, response->body, response->body_length);
}
if (response->status != 200) {
gpr_log(GPR_ERROR, "Call to http server ended with error %d [%s].",
response->status,
null_terminated_body != NULL ? null_terminated_body : "");
status = GRPC_CREDENTIALS_ERROR;
goto end;
} else {
grpc_json *access_token = NULL;
grpc_json *token_type = NULL;
grpc_json *expires_in = NULL;
grpc_json *ptr;
json = grpc_json_parse_string(null_terminated_body);
if (json == NULL) {
gpr_log(GPR_ERROR, "Could not parse JSON from %s", null_terminated_body);
status = GRPC_CREDENTIALS_ERROR;
goto end;
}
if (json->type != GRPC_JSON_OBJECT) {
gpr_log(GPR_ERROR, "Response should be a JSON object");
status = GRPC_CREDENTIALS_ERROR;
goto end;
}
for (ptr = json->child; ptr; ptr = ptr->next) {
if (strcmp(ptr->key, "access_token") == 0) {
access_token = ptr;
} else if (strcmp(ptr->key, "token_type") == 0) {
token_type = ptr;
} else if (strcmp(ptr->key, "expires_in") == 0) {
expires_in = ptr;
}
}
if (access_token == NULL || access_token->type != GRPC_JSON_STRING) {
gpr_log(GPR_ERROR, "Missing or invalid access_token in JSON.");
status = GRPC_CREDENTIALS_ERROR;
goto end;
}
if (token_type == NULL || token_type->type != GRPC_JSON_STRING) {
gpr_log(GPR_ERROR, "Missing or invalid token_type in JSON.");
status = GRPC_CREDENTIALS_ERROR;
goto end;
}
if (expires_in == NULL || expires_in->type != GRPC_JSON_NUMBER) {
gpr_log(GPR_ERROR, "Missing or invalid expires_in in JSON.");
status = GRPC_CREDENTIALS_ERROR;
goto end;
}
gpr_asprintf(&new_access_token, "%s %s", token_type->value,
access_token->value);
token_lifetime->tv_sec = strtol(expires_in->value, NULL, 10);
token_lifetime->tv_nsec = 0;
token_lifetime->clock_type = GPR_TIMESPAN;
if (*token_md != NULL) grpc_credentials_md_store_unref(*token_md);
*token_md = grpc_credentials_md_store_create(1);
grpc_credentials_md_store_add_cstrings(
*token_md, GRPC_AUTHORIZATION_METADATA_KEY, new_access_token);
status = GRPC_CREDENTIALS_OK;
}
end:
if (status != GRPC_CREDENTIALS_OK && (*token_md != NULL)) {
grpc_credentials_md_store_unref(*token_md);
*token_md = NULL;
}
if (null_terminated_body != NULL) gpr_free(null_terminated_body);
if (new_access_token != NULL) gpr_free(new_access_token);
if (json != NULL) grpc_json_destroy(json);
return status;
}
static void on_oauth2_token_fetcher_http_response(
grpc_exec_ctx *exec_ctx, void *user_data,
const grpc_http_response *response) {
grpc_credentials_metadata_request *r =
(grpc_credentials_metadata_request *)user_data;
grpc_oauth2_token_fetcher_credentials *c =
(grpc_oauth2_token_fetcher_credentials *)r->creds;
gpr_timespec token_lifetime;
grpc_credentials_status status;
gpr_mu_lock(&c->mu);
status = grpc_oauth2_token_fetcher_credentials_parse_server_response(
response, &c->access_token_md, &token_lifetime);
if (status == GRPC_CREDENTIALS_OK) {
c->token_expiration =
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime);
r->cb(exec_ctx, r->user_data, c->access_token_md->entries,
c->access_token_md->num_entries, status);
} else {
c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
r->cb(exec_ctx, r->user_data, NULL, 0, status);
}
gpr_mu_unlock(&c->mu);
grpc_credentials_metadata_request_destroy(r);
}
static void oauth2_token_fetcher_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
grpc_pollset *pollset, grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb, void *user_data) {
grpc_oauth2_token_fetcher_credentials *c =
(grpc_oauth2_token_fetcher_credentials *)creds;
gpr_timespec refresh_threshold = gpr_time_from_seconds(
GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN);
grpc_credentials_md_store *cached_access_token_md = NULL;
{
gpr_mu_lock(&c->mu);
if (c->access_token_md != NULL &&
(gpr_time_cmp(
gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_REALTIME)),
refresh_threshold) > 0)) {
cached_access_token_md =
grpc_credentials_md_store_ref(c->access_token_md);
}
gpr_mu_unlock(&c->mu);
}
if (cached_access_token_md != NULL) {
cb(exec_ctx, user_data, cached_access_token_md->entries,
cached_access_token_md->num_entries, GRPC_CREDENTIALS_OK);
grpc_credentials_md_store_unref(cached_access_token_md);
} else {
c->fetch_func(
exec_ctx,
grpc_credentials_metadata_request_create(creds, cb, user_data),
&c->httpcli_context, pollset, on_oauth2_token_fetcher_http_response,
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold));
}
}
static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials *c,
grpc_fetch_oauth2_func fetch_func) {
memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
gpr_ref_init(&c->base.refcount, 1);
gpr_mu_init(&c->mu);
c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
c->fetch_func = fetch_func;
grpc_httpcli_context_init(&c->httpcli_context);
}
//
// Google Compute Engine credentials.
//
static grpc_call_credentials_vtable compute_engine_vtable = {
oauth2_token_fetcher_destruct, oauth2_token_fetcher_get_request_metadata};
static void compute_engine_fetch_oauth2(
grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
grpc_httpcli_context *httpcli_context, grpc_pollset *pollset,
grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
grpc_http_header header = {"Metadata-Flavor", "Google"};
grpc_httpcli_request request;
memset(&request, 0, sizeof(grpc_httpcli_request));
request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST;
request.http.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
request.http.hdr_count = 1;
request.http.hdrs = &header;
grpc_httpcli_get(exec_ctx, httpcli_context, pollset, &request, deadline,
response_cb, metadata_req);
}
grpc_call_credentials *grpc_google_compute_engine_credentials_create(
void *reserved) {
grpc_oauth2_token_fetcher_credentials *c =
gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials));
GRPC_API_TRACE("grpc_compute_engine_credentials_create(reserved=%p)", 1,
(reserved));
GPR_ASSERT(reserved == NULL);
init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2);
c->base.vtable = &compute_engine_vtable;
return &c->base;
}
//
// Google Refresh Token credentials.
//
static void refresh_token_destruct(grpc_call_credentials *creds) {
grpc_google_refresh_token_credentials *c =
(grpc_google_refresh_token_credentials *)creds;
grpc_auth_refresh_token_destruct(&c->refresh_token);
oauth2_token_fetcher_destruct(&c->base.base);
}
static grpc_call_credentials_vtable refresh_token_vtable = {
refresh_token_destruct, oauth2_token_fetcher_get_request_metadata};
static void refresh_token_fetch_oauth2(
grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
grpc_httpcli_context *httpcli_context, grpc_pollset *pollset,
grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
grpc_google_refresh_token_credentials *c =
(grpc_google_refresh_token_credentials *)metadata_req->creds;
grpc_http_header header = {"Content-Type",
"application/x-www-form-urlencoded"};
grpc_httpcli_request request;
char *body = NULL;
gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
c->refresh_token.client_id, c->refresh_token.client_secret,
c->refresh_token.refresh_token);
memset(&request, 0, sizeof(grpc_httpcli_request));
request.host = GRPC_GOOGLE_OAUTH2_SERVICE_HOST;
request.http.path = GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH;
request.http.hdr_count = 1;
request.http.hdrs = &header;
request.handshaker = &grpc_httpcli_ssl;
grpc_httpcli_post(exec_ctx, httpcli_context, pollset, &request, body,
strlen(body), deadline, response_cb, metadata_req);
gpr_free(body);
}
grpc_call_credentials *
grpc_refresh_token_credentials_create_from_auth_refresh_token(
grpc_auth_refresh_token refresh_token) {
grpc_google_refresh_token_credentials *c;
if (!grpc_auth_refresh_token_is_valid(&refresh_token)) {
gpr_log(GPR_ERROR, "Invalid input for refresh token credentials creation");
return NULL;
}
c = gpr_malloc(sizeof(grpc_google_refresh_token_credentials));
memset(c, 0, sizeof(grpc_google_refresh_token_credentials));
init_oauth2_token_fetcher(&c->base, refresh_token_fetch_oauth2);
c->base.base.vtable = &refresh_token_vtable;
c->refresh_token = refresh_token;
return &c->base.base;
}
grpc_call_credentials *grpc_google_refresh_token_credentials_create(
const char *json_refresh_token, void *reserved) {
GRPC_API_TRACE(
"grpc_refresh_token_credentials_create(json_refresh_token=%s, "
"reserved=%p)",
2, (json_refresh_token, reserved));
GPR_ASSERT(reserved == NULL);
return grpc_refresh_token_credentials_create_from_auth_refresh_token(
grpc_auth_refresh_token_create_from_string(json_refresh_token));
}
//
// Oauth2 Access Token credentials.
//
static void access_token_destruct(grpc_call_credentials *creds) {
grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
grpc_credentials_md_store_unref(c->access_token_md);
}
static void access_token_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
grpc_pollset *pollset, grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb, void *user_data) {
grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK);
}
static grpc_call_credentials_vtable access_token_vtable = {
access_token_destruct, access_token_get_request_metadata};
grpc_call_credentials *grpc_access_token_credentials_create(
const char *access_token, void *reserved) {
grpc_access_token_credentials *c =
gpr_malloc(sizeof(grpc_access_token_credentials));
char *token_md_value;
GRPC_API_TRACE(
"grpc_access_token_credentials_create(access_token=%s, "
"reserved=%p)",
2, (access_token, reserved));
GPR_ASSERT(reserved == NULL);
memset(c, 0, sizeof(grpc_access_token_credentials));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
c->base.vtable = &access_token_vtable;
gpr_ref_init(&c->base.refcount, 1);
c->access_token_md = grpc_credentials_md_store_create(1);
gpr_asprintf(&token_md_value, "Bearer %s", access_token);
grpc_credentials_md_store_add_cstrings(
c->access_token_md, GRPC_AUTHORIZATION_METADATA_KEY, token_md_value);
gpr_free(token_md_value);
return &c->base;
}

@ -0,0 +1,109 @@
/*
*
* 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_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H
#include "src/core/lib/json/json.h"
#include "src/core/lib/security/credentials/credentials.h"
// auth_refresh_token parsing.
typedef struct {
const char *type;
char *client_id;
char *client_secret;
char *refresh_token;
} grpc_auth_refresh_token;
/// Returns 1 if the object is valid, 0 otherwise.
int grpc_auth_refresh_token_is_valid(
const grpc_auth_refresh_token *refresh_token);
/// Creates a refresh token object from string. Returns an invalid object if a
/// parsing error has been encountered.
grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string(
const char *json_string);
/// Creates a refresh token object from parsed json. Returns an invalid object
/// if a parsing error has been encountered.
grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json(
const grpc_json *json);
/// Destructs the object.
void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token);
// -- Oauth2 Token Fetcher credentials --
//
// This object is a base for credentials that need to acquire an oauth2 token
// from an http service.
typedef void (*grpc_fetch_oauth2_func)(grpc_exec_ctx *exec_ctx,
grpc_credentials_metadata_request *req,
grpc_httpcli_context *http_context,
grpc_pollset *pollset,
grpc_httpcli_response_cb response_cb,
gpr_timespec deadline);
typedef struct {
grpc_call_credentials base;
gpr_mu mu;
grpc_credentials_md_store *access_token_md;
gpr_timespec token_expiration;
grpc_httpcli_context httpcli_context;
grpc_fetch_oauth2_func fetch_func;
} grpc_oauth2_token_fetcher_credentials;
// Google refresh token credentials.
typedef struct {
grpc_oauth2_token_fetcher_credentials base;
grpc_auth_refresh_token refresh_token;
} grpc_google_refresh_token_credentials;
// Access token credentials.
typedef struct {
grpc_call_credentials base;
grpc_credentials_md_store *access_token_md;
} grpc_access_token_credentials;
// Private constructor for refresh token credentials from an already parsed
// refresh token. Takes ownership of the refresh token.
grpc_call_credentials *
grpc_refresh_token_credentials_create_from_auth_refresh_token(
grpc_auth_refresh_token token);
// Exposed for testing only.
grpc_credentials_status
grpc_oauth2_token_fetcher_credentials_parse_server_response(
const struct grpc_http_response *response,
grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime);
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H */

@ -0,0 +1,129 @@
/*
*
* 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.
*
*/
#include "src/core/lib/security/credentials/plugin/plugin_credentials.h"
#include <string.h>
#include "src/core/lib/surface/api_trace.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
typedef struct {
void *user_data;
grpc_credentials_metadata_cb cb;
} grpc_metadata_plugin_request;
static void plugin_destruct(grpc_call_credentials *creds) {
grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
if (c->plugin.state != NULL && c->plugin.destroy != NULL) {
c->plugin.destroy(c->plugin.state);
}
}
static void plugin_md_request_metadata_ready(void *request,
const grpc_metadata *md,
size_t num_md,
grpc_status_code status,
const char *error_details) {
/* called from application code */
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_metadata_plugin_request *r = (grpc_metadata_plugin_request *)request;
if (status != GRPC_STATUS_OK) {
if (error_details != NULL) {
gpr_log(GPR_ERROR, "Getting metadata from plugin failed with error: %s",
error_details);
}
r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_ERROR);
} else {
size_t i;
grpc_credentials_md *md_array = NULL;
if (num_md > 0) {
md_array = gpr_malloc(num_md * sizeof(grpc_credentials_md));
for (i = 0; i < num_md; i++) {
md_array[i].key = gpr_slice_from_copied_string(md[i].key);
md_array[i].value =
gpr_slice_from_copied_buffer(md[i].value, md[i].value_length);
}
}
r->cb(&exec_ctx, r->user_data, md_array, num_md, GRPC_CREDENTIALS_OK);
if (md_array != NULL) {
for (i = 0; i < num_md; i++) {
gpr_slice_unref(md_array[i].key);
gpr_slice_unref(md_array[i].value);
}
gpr_free(md_array);
}
}
gpr_free(r);
grpc_exec_ctx_finish(&exec_ctx);
}
static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds,
grpc_pollset *pollset,
grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb,
void *user_data) {
grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
if (c->plugin.get_metadata != NULL) {
grpc_metadata_plugin_request *request = gpr_malloc(sizeof(*request));
memset(request, 0, sizeof(*request));
request->user_data = user_data;
request->cb = cb;
c->plugin.get_metadata(c->plugin.state, context,
plugin_md_request_metadata_ready, request);
} else {
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
}
}
static grpc_call_credentials_vtable plugin_vtable = {
plugin_destruct, plugin_get_request_metadata};
grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
grpc_metadata_credentials_plugin plugin, void *reserved) {
grpc_plugin_credentials *c = gpr_malloc(sizeof(*c));
GRPC_API_TRACE("grpc_metadata_credentials_create_from_plugin(reserved=%p)", 1,
(reserved));
GPR_ASSERT(reserved == NULL);
memset(c, 0, sizeof(*c));
c->base.type = plugin.type;
c->base.vtable = &plugin_vtable;
gpr_ref_init(&c->base.refcount, 1);
c->plugin = plugin;
return &c->base;
}

@ -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_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H
#include "src/core/lib/security/credentials/credentials.h"
typedef struct {
grpc_call_credentials base;
grpc_metadata_credentials_plugin plugin;
grpc_credentials_md_store *plugin_md;
} grpc_plugin_credentials;
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H */

@ -0,0 +1,240 @@
/*
*
* 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.
*
*/
#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
#include <string.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/http_client_filter.h"
#include "src/core/lib/surface/api_trace.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
//
// Utils
//
static void ssl_copy_key_material(const char *input, unsigned char **output,
size_t *output_size) {
*output_size = strlen(input);
*output = gpr_malloc(*output_size);
memcpy(*output, input, *output_size);
}
//
// SSL Channel Credentials.
//
static void ssl_destruct(grpc_channel_credentials *creds) {
grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key);
if (c->config.pem_cert_chain != NULL) gpr_free(c->config.pem_cert_chain);
}
static grpc_security_status ssl_create_security_connector(
grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
const char *target, const grpc_channel_args *args,
grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
grpc_security_status status = GRPC_SECURITY_OK;
size_t i = 0;
const char *overridden_target_name = NULL;
grpc_arg new_arg;
for (i = 0; args && i < args->num_args; i++) {
grpc_arg *arg = &args->args[i];
if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 &&
arg->type == GRPC_ARG_STRING) {
overridden_target_name = arg->value.string;
break;
}
}
status = grpc_ssl_channel_security_connector_create(
call_creds, &c->config, target, overridden_target_name, sc);
if (status != GRPC_SECURITY_OK) {
return status;
}
new_arg.type = GRPC_ARG_STRING;
new_arg.key = GRPC_ARG_HTTP2_SCHEME;
new_arg.value.string = "https";
*new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
return status;
}
static grpc_channel_credentials_vtable ssl_vtable = {
ssl_destruct, ssl_create_security_connector};
static void ssl_build_config(const char *pem_root_certs,
grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
grpc_ssl_config *config) {
if (pem_root_certs != NULL) {
ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
&config->pem_root_certs_size);
}
if (pem_key_cert_pair != NULL) {
GPR_ASSERT(pem_key_cert_pair->private_key != NULL);
GPR_ASSERT(pem_key_cert_pair->cert_chain != NULL);
ssl_copy_key_material(pem_key_cert_pair->private_key,
&config->pem_private_key,
&config->pem_private_key_size);
ssl_copy_key_material(pem_key_cert_pair->cert_chain,
&config->pem_cert_chain,
&config->pem_cert_chain_size);
}
}
grpc_channel_credentials *grpc_ssl_credentials_create(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
void *reserved) {
grpc_ssl_credentials *c = gpr_malloc(sizeof(grpc_ssl_credentials));
GRPC_API_TRACE(
"grpc_ssl_credentials_create(pem_root_certs=%s, "
"pem_key_cert_pair=%p, "
"reserved=%p)",
3, (pem_root_certs, pem_key_cert_pair, reserved));
GPR_ASSERT(reserved == NULL);
memset(c, 0, sizeof(grpc_ssl_credentials));
c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
c->base.vtable = &ssl_vtable;
gpr_ref_init(&c->base.refcount, 1);
ssl_build_config(pem_root_certs, pem_key_cert_pair, &c->config);
return &c->base;
}
//
// SSL Server Credentials.
//
static void ssl_server_destruct(grpc_server_credentials *creds) {
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
size_t i;
for (i = 0; i < c->config.num_key_cert_pairs; i++) {
if (c->config.pem_private_keys[i] != NULL) {
gpr_free(c->config.pem_private_keys[i]);
}
if (c->config.pem_cert_chains[i] != NULL) {
gpr_free(c->config.pem_cert_chains[i]);
}
}
if (c->config.pem_private_keys != NULL) gpr_free(c->config.pem_private_keys);
if (c->config.pem_private_keys_sizes != NULL) {
gpr_free(c->config.pem_private_keys_sizes);
}
if (c->config.pem_cert_chains != NULL) gpr_free(c->config.pem_cert_chains);
if (c->config.pem_cert_chains_sizes != NULL) {
gpr_free(c->config.pem_cert_chains_sizes);
}
if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
}
static grpc_security_status ssl_server_create_security_connector(
grpc_server_credentials *creds, grpc_server_security_connector **sc) {
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
return grpc_ssl_server_security_connector_create(&c->config, sc);
}
static grpc_server_credentials_vtable ssl_server_vtable = {
ssl_server_destruct, ssl_server_create_security_connector};
static void ssl_build_server_config(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs,
grpc_ssl_client_certificate_request_type client_certificate_request,
grpc_ssl_server_config *config) {
size_t i;
config->client_certificate_request = client_certificate_request;
if (pem_root_certs != NULL) {
ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
&config->pem_root_certs_size);
}
if (num_key_cert_pairs > 0) {
GPR_ASSERT(pem_key_cert_pairs != NULL);
config->pem_private_keys =
gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *));
config->pem_cert_chains =
gpr_malloc(num_key_cert_pairs * sizeof(unsigned char *));
config->pem_private_keys_sizes =
gpr_malloc(num_key_cert_pairs * sizeof(size_t));
config->pem_cert_chains_sizes =
gpr_malloc(num_key_cert_pairs * sizeof(size_t));
}
config->num_key_cert_pairs = num_key_cert_pairs;
for (i = 0; i < num_key_cert_pairs; i++) {
GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL);
GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL);
ssl_copy_key_material(pem_key_cert_pairs[i].private_key,
&config->pem_private_keys[i],
&config->pem_private_keys_sizes[i]);
ssl_copy_key_material(pem_key_cert_pairs[i].cert_chain,
&config->pem_cert_chains[i],
&config->pem_cert_chains_sizes[i]);
}
}
grpc_server_credentials *grpc_ssl_server_credentials_create(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs, int force_client_auth, void *reserved) {
return grpc_ssl_server_credentials_create_ex(
pem_root_certs, pem_key_cert_pairs, num_key_cert_pairs,
force_client_auth
? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
: GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
reserved);
}
grpc_server_credentials *grpc_ssl_server_credentials_create_ex(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs,
grpc_ssl_client_certificate_request_type client_certificate_request,
void *reserved) {
grpc_ssl_server_credentials *c =
gpr_malloc(sizeof(grpc_ssl_server_credentials));
GRPC_API_TRACE(
"grpc_ssl_server_credentials_create_ex("
"pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, "
"client_certificate_request=%d, reserved=%p)",
5, (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs,
client_certificate_request, reserved));
GPR_ASSERT(reserved == NULL);
memset(c, 0, sizeof(grpc_ssl_server_credentials));
c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
gpr_ref_init(&c->base.refcount, 1);
c->base.vtable = &ssl_server_vtable;
ssl_build_server_config(pem_root_certs, pem_key_cert_pairs,
num_key_cert_pairs, client_certificate_request,
&c->config);
return &c->base;
}

@ -0,0 +1,48 @@
/*
*
* 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_LIB_SECURITY_CREDENTIALS_SSL_SSL_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_SSL_SSL_CREDENTIALS_H
#include "src/core/lib/security/credentials/credentials.h"
typedef struct {
grpc_channel_credentials base;
grpc_ssl_config config;
} grpc_ssl_credentials;
typedef struct {
grpc_server_credentials base;
grpc_ssl_server_config config;
} grpc_ssl_server_credentials;
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_SSL_SSL_CREDENTIALS_H */

@ -31,12 +31,12 @@
* *
*/ */
#ifndef GRPC_CORE_LIB_SECURITY_AUTH_FILTERS_H #ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H
#define GRPC_CORE_LIB_SECURITY_AUTH_FILTERS_H #define GRPC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H
#include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/channel_stack.h"
extern const grpc_channel_filter grpc_client_auth_filter; extern const grpc_channel_filter grpc_client_auth_filter;
extern const grpc_channel_filter grpc_server_auth_filter; extern const grpc_channel_filter grpc_server_auth_filter;
#endif /* GRPC_CORE_LIB_SECURITY_AUTH_FILTERS_H */ #endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H */

@ -31,7 +31,7 @@
* *
*/ */
#include "src/core/lib/security/auth_filters.h" #include "src/core/lib/security/transport/auth_filters.h"
#include <string.h> #include <string.h>
@ -40,9 +40,9 @@
#include <grpc/support/string_util.h> #include <grpc/support/string_util.h>
#include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/security/credentials.h" #include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/security_connector.h" #include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_context.h" #include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
#include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call.h"
#include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/static_metadata.h"

@ -31,7 +31,7 @@
* *
*/ */
#include "src/core/lib/security/handshake.h" #include "src/core/lib/security/transport/handshake.h"
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
@ -39,8 +39,8 @@
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/slice_buffer.h> #include <grpc/support/slice_buffer.h>
#include "src/core/lib/security/secure_endpoint.h" #include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/security_context.h" #include "src/core/lib/security/transport/secure_endpoint.h"
#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256 #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256

@ -31,11 +31,11 @@
* *
*/ */
#ifndef GRPC_CORE_LIB_SECURITY_HANDSHAKE_H #ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_HANDSHAKE_H
#define GRPC_CORE_LIB_SECURITY_HANDSHAKE_H #define GRPC_CORE_LIB_SECURITY_TRANSPORT_HANDSHAKE_H
#include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/security/security_connector.h" #include "src/core/lib/security/transport/security_connector.h"
/* Calls the callback upon completion. Takes owership of handshaker. */ /* Calls the callback upon completion. Takes owership of handshaker. */
void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
@ -48,4 +48,4 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake); void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake);
#endif /* GRPC_CORE_LIB_SECURITY_HANDSHAKE_H */ #endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_HANDSHAKE_H */

@ -31,7 +31,7 @@
* *
*/ */
#include "src/core/lib/security/secure_endpoint.h" #include "src/core/lib/security/transport/secure_endpoint.h"
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/slice.h> #include <grpc/support/slice.h>

@ -31,8 +31,8 @@
* *
*/ */
#ifndef GRPC_CORE_LIB_SECURITY_SECURE_ENDPOINT_H #ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURE_ENDPOINT_H
#define GRPC_CORE_LIB_SECURITY_SECURE_ENDPOINT_H #define GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURE_ENDPOINT_H
#include <grpc/support/slice.h> #include <grpc/support/slice.h>
#include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/endpoint.h"
@ -46,4 +46,4 @@ grpc_endpoint *grpc_secure_endpoint_create(
struct tsi_frame_protector *protector, grpc_endpoint *to_wrap, struct tsi_frame_protector *protector, grpc_endpoint *to_wrap,
gpr_slice *leftover_slices, size_t leftover_nslices); gpr_slice *leftover_slices, size_t leftover_nslices);
#endif /* GRPC_CORE_LIB_SECURITY_SECURE_ENDPOINT_H */ #endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURE_ENDPOINT_H */

@ -31,7 +31,7 @@
* *
*/ */
#include "src/core/lib/security/security_connector.h" #include "src/core/lib/security/transport/security_connector.h"
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
@ -43,10 +43,10 @@
#include <grpc/support/string_util.h> #include <grpc/support/string_util.h>
#include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/ext/transport/chttp2/alpn/alpn.h"
#include "src/core/lib/security/credentials.h" #include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/handshake.h" #include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/secure_endpoint.h" #include "src/core/lib/security/transport/handshake.h"
#include "src/core/lib/security/security_context.h" #include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/support/env.h" #include "src/core/lib/support/env.h"
#include "src/core/lib/support/load_file.h" #include "src/core/lib/support/load_file.h"
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"

@ -31,8 +31,8 @@
* *
*/ */
#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_H #ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H
#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_H #define GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H
#include <grpc/grpc_security.h> #include <grpc/grpc_security.h>
#include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/endpoint.h"
@ -263,4 +263,4 @@ tsi_peer tsi_shallow_peer_from_ssl_auth_context(
const grpc_auth_context *auth_context); const grpc_auth_context *auth_context);
void tsi_shallow_peer_destruct(tsi_peer *peer); void tsi_shallow_peer_destruct(tsi_peer *peer);
#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_H */ #endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H */

@ -33,9 +33,9 @@
#include <string.h> #include <string.h>
#include "src/core/lib/security/auth_filters.h" #include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials.h" #include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_context.h" #include "src/core/lib/security/transport/auth_filters.h"
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>

@ -31,7 +31,7 @@
* *
*/ */
#include "src/core/lib/security/b64.h" #include "src/core/lib/security/util/b64.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>

@ -31,8 +31,8 @@
* *
*/ */
#ifndef GRPC_CORE_LIB_SECURITY_B64_H #ifndef GRPC_CORE_LIB_SECURITY_UTIL_B64_H
#define GRPC_CORE_LIB_SECURITY_B64_H #define GRPC_CORE_LIB_SECURITY_UTIL_B64_H
#include <grpc/support/slice.h> #include <grpc/support/slice.h>
@ -49,4 +49,4 @@ gpr_slice grpc_base64_decode(const char *b64, int url_safe);
gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len, gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
int url_safe); int url_safe);
#endif /* GRPC_CORE_LIB_SECURITY_B64_H */ #endif /* GRPC_CORE_LIB_SECURITY_UTIL_B64_H */

@ -31,47 +31,31 @@
* *
*/ */
#include <set> #include "src/core/lib/security/util/json_util.h"
#include <grpc/support/log.h> #include <string.h>
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/report.h"
#include "test/cpp/util/benchmark_config.h"
namespace grpc {
namespace testing {
static const int WARMUP = 5;
static const int BENCHMARK = 5;
static void RunSynchronousUnaryPingPong() {
gpr_log(GPR_INFO, "Running Synchronous Unary Ping Pong");
ClientConfig client_config;
client_config.set_client_type(SYNC_CLIENT);
client_config.set_outstanding_rpcs_per_channel(1);
client_config.set_client_channels(1);
client_config.set_rpc_type(UNARY);
client_config.mutable_load_params()->mutable_closed_loop();
ServerConfig server_config; #include <grpc/support/log.h>
server_config.set_server_type(SYNC_SERVER); #include <grpc/support/string_util.h>
const auto result = const char *grpc_json_get_string_property(const grpc_json *json,
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2); const char *prop_name) {
grpc_json *child;
GetReporter()->ReportQPS(*result); for (child = json->child; child != NULL; child = child->next) {
GetReporter()->ReportLatency(*result); if (strcmp(child->key, prop_name) == 0) break;
}
if (child == NULL || child->type != GRPC_JSON_STRING) {
gpr_log(GPR_ERROR, "Invalid or missing %s property.", prop_name);
return NULL;
}
return child->value;
} }
} // namespace testing bool grpc_copy_json_string_property(const grpc_json *json,
} // namespace grpc const char *prop_name,
char **copied_value) {
int main(int argc, char** argv) { const char *prop_value = grpc_json_get_string_property(json, prop_name);
grpc::testing::InitBenchmark(&argc, &argv, true); if (prop_value == NULL) return false;
*copied_value = gpr_strdup(prop_value);
grpc::testing::RunSynchronousUnaryPingPong(); return true;
return 0;
} }

@ -31,46 +31,25 @@
* *
*/ */
#include <set> #ifndef GRPC_CORE_LIB_SECURITY_UTIL_JSON_UTIL_H
#define GRPC_CORE_LIB_SECURITY_UTIL_JSON_UTIL_H
#include <grpc/support/log.h> #include <stdbool.h>
#include "test/cpp/qps/driver.h" #include "src/core/lib/json/json.h"
#include "test/cpp/qps/report.h"
#include "test/cpp/util/benchmark_config.h"
namespace grpc { // Constants.
namespace testing { #define GRPC_AUTH_JSON_TYPE_INVALID "invalid"
#define GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT "service_account"
#define GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER "authorized_user"
static const int WARMUP = 5; // Gets a child property from a json node.
static const int BENCHMARK = 5; const char *grpc_json_get_string_property(const grpc_json *json,
const char *prop_name);
static void RunSynchronousStreamingPingPong() { // Copies the value of the json child property specified by prop_name.
gpr_log(GPR_INFO, "Running Synchronous Streaming Ping Pong"); // Returns false if the property was not found.
bool grpc_copy_json_string_property(const grpc_json *json,
const char *prop_name, char **copied_value);
ClientConfig client_config; #endif /* GRPC_CORE_LIB_SECURITY_UTIL_JSON_UTIL_H */
client_config.set_client_type(SYNC_CLIENT);
client_config.set_outstanding_rpcs_per_channel(1);
client_config.set_client_channels(1);
client_config.set_rpc_type(STREAMING);
client_config.mutable_load_params()->mutable_closed_loop();
ServerConfig server_config;
server_config.set_server_type(SYNC_SERVER);
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
GetReporter()->ReportQPS(*result);
GetReporter()->ReportLatency(*result);
}
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
grpc::testing::InitBenchmark(&argc, &argv, true);
grpc::testing::RunSynchronousStreamingPingPong();
return 0;
}

@ -33,6 +33,8 @@
#include "src/core/lib/support/murmur_hash.h" #include "src/core/lib/support/murmur_hash.h"
#include <string.h>
#define ROTL32(x, r) ((x) << (r)) | ((x) >> (32 - (r))) #define ROTL32(x, r) ((x) << (r)) | ((x) >> (32 - (r)))
#define FMIX32(h) \ #define FMIX32(h) \
@ -42,10 +44,6 @@
(h) *= 0xc2b2ae35; \ (h) *= 0xc2b2ae35; \
(h) ^= (h) >> 16; (h) ^= (h) >> 16;
/* Block read - if your platform needs to do endian-swapping or can only
handle aligned reads, do the conversion here */
#define GETBLOCK32(p, i) (p)[(i)]
uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed) { uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed) {
const uint8_t *data = (const uint8_t *)key; const uint8_t *data = (const uint8_t *)key;
const size_t nblocks = len / 4; const size_t nblocks = len / 4;
@ -62,7 +60,7 @@ uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed) {
/* body */ /* body */
for (i = -(int)nblocks; i; i++) { for (i = -(int)nblocks; i; i++) {
k1 = GETBLOCK32(blocks, i); memcpy(&k1, blocks + i, sizeof(uint32_t));
k1 *= c1; k1 *= c1;
k1 = ROTL32(k1, 15); k1 = ROTL32(k1, 15);

@ -65,12 +65,6 @@
- status/close recv (depending on client/server) */ - status/close recv (depending on client/server) */
#define MAX_CONCURRENT_BATCHES 6 #define MAX_CONCURRENT_BATCHES 6
typedef struct {
grpc_ioreq_completion_func on_complete;
void *user_data;
int success;
} completed_request;
#define MAX_SEND_EXTRA_METADATA_COUNT 3 #define MAX_SEND_EXTRA_METADATA_COUNT 3
/* Status data for a request can come from several sources; this /* Status data for a request can come from several sources; this
@ -97,25 +91,6 @@ typedef struct {
grpc_mdstr *details; grpc_mdstr *details;
} received_status; } received_status;
/* How far through the GRPC stream have we read? */
typedef enum {
/* We are still waiting for initial metadata to complete */
READ_STATE_INITIAL = 0,
/* We have gotten initial metadata, and are reading either
messages or trailing metadata */
READ_STATE_GOT_INITIAL_METADATA,
/* The stream is closed for reading */
READ_STATE_READ_CLOSED,
/* The stream is closed for reading & writing */
READ_STATE_STREAM_CLOSED
} read_state;
typedef enum {
WRITE_STATE_INITIAL = 0,
WRITE_STATE_STARTED,
WRITE_STATE_WRITE_CLOSED
} write_state;
typedef struct batch_control { typedef struct batch_control {
grpc_call *call; grpc_call *call;
grpc_cq_completion cq_completion; grpc_cq_completion cq_completion;

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -70,6 +70,8 @@ struct grpc_completion_queue {
int shutdown; int shutdown;
int shutdown_called; int shutdown_called;
int is_server_cq; int is_server_cq;
/** Can the server cq accept incoming channels */
int is_non_listening_server_cq;
int num_pluckers; int num_pluckers;
plucker pluckers[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS]; plucker pluckers[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS];
grpc_closure pollset_shutdown_done; grpc_closure pollset_shutdown_done;
@ -84,6 +86,7 @@ struct grpc_completion_queue {
}; };
#define POLLSET_FROM_CQ(cq) ((grpc_pollset *)(cq + 1)) #define POLLSET_FROM_CQ(cq) ((grpc_pollset *)(cq + 1))
#define CQ_FROM_POLLSET(ps) (((grpc_completion_queue *)ps) - 1)
static gpr_mu g_freelist_mu; static gpr_mu g_freelist_mu;
static grpc_completion_queue *g_freelist; static grpc_completion_queue *g_freelist;
@ -149,6 +152,7 @@ grpc_completion_queue *grpc_completion_queue_create(void *reserved) {
cc->shutdown = 0; cc->shutdown = 0;
cc->shutdown_called = 0; cc->shutdown_called = 0;
cc->is_server_cq = 0; cc->is_server_cq = 0;
cc->is_non_listening_server_cq = 0;
cc->num_pluckers = 0; cc->num_pluckers = 0;
#ifndef NDEBUG #ifndef NDEBUG
cc->outstanding_tag_count = 0; cc->outstanding_tag_count = 0;
@ -511,6 +515,18 @@ grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) {
return POLLSET_FROM_CQ(cc); return POLLSET_FROM_CQ(cc);
} }
grpc_completion_queue *grpc_cq_from_pollset(grpc_pollset *ps) {
return CQ_FROM_POLLSET(ps);
}
void grpc_cq_mark_non_listening_server_cq(grpc_completion_queue *cc) {
cc->is_non_listening_server_cq = 1;
}
bool grpc_cq_is_non_listening_server_cq(grpc_completion_queue *cc) {
return (cc->is_non_listening_server_cq == 1);
}
void grpc_cq_mark_server_cq(grpc_completion_queue *cc) { cc->is_server_cq = 1; } void grpc_cq_mark_server_cq(grpc_completion_queue *cc) { cc->is_server_cq = 1; }
int grpc_cq_is_server_cq(grpc_completion_queue *cc) { return cc->is_server_cq; } int grpc_cq_is_server_cq(grpc_completion_queue *cc) { return cc->is_server_cq; }

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -81,7 +81,10 @@ void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
void *done_arg, grpc_cq_completion *storage); void *done_arg, grpc_cq_completion *storage);
grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc); grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc);
grpc_completion_queue *grpc_cq_from_pollset(grpc_pollset *ps);
void grpc_cq_mark_non_listening_server_cq(grpc_completion_queue *cc);
bool grpc_cq_is_non_listening_server_cq(grpc_completion_queue *cc);
void grpc_cq_mark_server_cq(grpc_completion_queue *cc); void grpc_cq_mark_server_cq(grpc_completion_queue *cc);
int grpc_cq_is_server_cq(grpc_completion_queue *cc); int grpc_cq_is_server_cq(grpc_completion_queue *cc);

@ -37,10 +37,10 @@
#include <string.h> #include <string.h>
#include "src/core/lib/debug/trace.h" #include "src/core/lib/debug/trace.h"
#include "src/core/lib/security/auth_filters.h" #include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials.h" #include "src/core/lib/security/transport/auth_filters.h"
#include "src/core/lib/security/secure_endpoint.h" #include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/security/security_connector.h" #include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/surface/channel_init.h" #include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/tsi/transport_security_interface.h" #include "src/core/lib/tsi/transport_security_interface.h"

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -69,11 +69,6 @@ typedef struct call_data call_data;
typedef struct channel_data channel_data; typedef struct channel_data channel_data;
typedef struct registered_method registered_method; typedef struct registered_method registered_method;
typedef struct {
call_data *next;
call_data *prev;
} call_link;
typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type; typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type;
typedef struct requested_call { typedef struct requested_call {
@ -81,7 +76,6 @@ typedef struct requested_call {
void *tag; void *tag;
grpc_server *server; grpc_server *server;
grpc_completion_queue *cq_bound_to_call; grpc_completion_queue *cq_bound_to_call;
grpc_completion_queue *cq_for_notification;
grpc_call **call; grpc_call **call;
grpc_cq_completion completion; grpc_cq_completion completion;
grpc_metadata_array *initial_metadata; grpc_metadata_array *initial_metadata;
@ -108,6 +102,7 @@ struct channel_data {
grpc_server *server; grpc_server *server;
grpc_connectivity_state connectivity_state; grpc_connectivity_state connectivity_state;
grpc_channel *channel; grpc_channel *channel;
size_t cq_idx;
/* linked list of all channels on a server */ /* linked list of all channels on a server */
channel_data *next; channel_data *next;
channel_data *prev; channel_data *prev;
@ -172,7 +167,7 @@ struct request_matcher {
grpc_server *server; grpc_server *server;
call_data *pending_head; call_data *pending_head;
call_data *pending_tail; call_data *pending_tail;
gpr_stack_lockfree *requests; gpr_stack_lockfree **requests_per_cq;
}; };
struct registered_method { struct registered_method {
@ -180,6 +175,7 @@ struct registered_method {
char *host; char *host;
grpc_server_register_method_payload_handling payload_handling; grpc_server_register_method_payload_handling payload_handling;
uint32_t flags; uint32_t flags;
/* one request matcher per method */
request_matcher request_matcher; request_matcher request_matcher;
registered_method *next; registered_method *next;
}; };
@ -195,6 +191,7 @@ struct grpc_server {
grpc_completion_queue **cqs; grpc_completion_queue **cqs;
grpc_pollset **pollsets; grpc_pollset **pollsets;
size_t cq_count; size_t cq_count;
bool started;
/* The two following mutexes control access to server-state /* The two following mutexes control access to server-state
mu_global controls access to non-call-related state (e.g., channel state) mu_global controls access to non-call-related state (e.g., channel state)
@ -207,6 +204,7 @@ struct grpc_server {
gpr_mu mu_call; /* mutex for call-specific state */ gpr_mu mu_call; /* mutex for call-specific state */
registered_method *registered_methods; registered_method *registered_methods;
/** one request matcher for unregistered methods */
request_matcher unregistered_request_matcher; request_matcher unregistered_request_matcher;
/** free list of available requested_calls indices */ /** free list of available requested_calls indices */
gpr_stack_lockfree *request_freelist; gpr_stack_lockfree *request_freelist;
@ -234,7 +232,7 @@ struct grpc_server {
static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *calld, bool success); static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *calld, bool success);
static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server, static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
requested_call *rc); size_t cq_idx, requested_call *rc);
/* Before calling maybe_finish_shutdown, we must hold mu_global and not /* Before calling maybe_finish_shutdown, we must hold mu_global and not
hold mu_call */ hold mu_call */
static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_server *server); static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_server *server);
@ -312,12 +310,19 @@ static void request_matcher_init(request_matcher *rm, size_t entries,
grpc_server *server) { grpc_server *server) {
memset(rm, 0, sizeof(*rm)); memset(rm, 0, sizeof(*rm));
rm->server = server; rm->server = server;
rm->requests = gpr_stack_lockfree_create(entries); rm->requests_per_cq =
gpr_malloc(sizeof(*rm->requests_per_cq) * server->cq_count);
for (size_t i = 0; i < server->cq_count; i++) {
rm->requests_per_cq[i] = gpr_stack_lockfree_create(entries);
}
} }
static void request_matcher_destroy(request_matcher *rm) { static void request_matcher_destroy(request_matcher *rm) {
GPR_ASSERT(gpr_stack_lockfree_pop(rm->requests) == -1); for (size_t i = 0; i < rm->server->cq_count; i++) {
gpr_stack_lockfree_destroy(rm->requests); GPR_ASSERT(gpr_stack_lockfree_pop(rm->requests_per_cq[i]) == -1);
gpr_stack_lockfree_destroy(rm->requests_per_cq[i]);
}
gpr_free(rm->requests_per_cq);
} }
static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, bool success) { static void kill_zombie(grpc_exec_ctx *exec_ctx, void *elem, bool success) {
@ -343,8 +348,11 @@ static void request_matcher_kill_requests(grpc_exec_ctx *exec_ctx,
grpc_server *server, grpc_server *server,
request_matcher *rm) { request_matcher *rm) {
int request_id; int request_id;
while ((request_id = gpr_stack_lockfree_pop(rm->requests)) != -1) { for (size_t i = 0; i < server->cq_count; i++) {
fail_call(exec_ctx, server, &server->requested_calls[request_id]); while ((request_id = gpr_stack_lockfree_pop(rm->requests_per_cq[i])) !=
-1) {
fail_call(exec_ctx, server, i, &server->requested_calls[request_id]);
}
} }
} }
@ -364,15 +372,19 @@ static void server_delete(grpc_exec_ctx *exec_ctx, grpc_server *server) {
gpr_mu_destroy(&server->mu_call); gpr_mu_destroy(&server->mu_call);
while ((rm = server->registered_methods) != NULL) { while ((rm = server->registered_methods) != NULL) {
server->registered_methods = rm->next; server->registered_methods = rm->next;
request_matcher_destroy(&rm->request_matcher); if (server->started) {
request_matcher_destroy(&rm->request_matcher);
}
gpr_free(rm->method); gpr_free(rm->method);
gpr_free(rm->host); gpr_free(rm->host);
gpr_free(rm); gpr_free(rm);
} }
if (server->started) {
request_matcher_destroy(&server->unregistered_request_matcher);
}
for (i = 0; i < server->cq_count; i++) { for (i = 0; i < server->cq_count; i++) {
GRPC_CQ_INTERNAL_UNREF(server->cqs[i], "server"); GRPC_CQ_INTERNAL_UNREF(server->cqs[i], "server");
} }
request_matcher_destroy(&server->unregistered_request_matcher);
gpr_stack_lockfree_destroy(server->request_freelist); gpr_stack_lockfree_destroy(server->request_freelist);
gpr_free(server->cqs); gpr_free(server->cqs);
gpr_free(server->pollsets); gpr_free(server->pollsets);
@ -453,11 +465,11 @@ static void done_request_event(grpc_exec_ctx *exec_ctx, void *req,
} }
static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server, static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
call_data *calld, requested_call *rc) { call_data *calld, size_t cq_idx, requested_call *rc) {
grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call); grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
grpc_call *call = calld->call; grpc_call *call = calld->call;
*rc->call = call; *rc->call = call;
calld->cq_new = rc->cq_for_notification; calld->cq_new = server->cqs[cq_idx];
GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata); GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
switch (rc->type) { switch (rc->type) {
case BATCH_CALL: case BATCH_CALL:
@ -492,7 +504,9 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
} }
static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *arg, bool success) { static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
call_data *calld = arg; grpc_call_element *call_elem = arg;
call_data *calld = call_elem->call_data;
channel_data *chand = call_elem->channel_data;
request_matcher *rm = calld->request_matcher; request_matcher *rm = calld->request_matcher;
grpc_server *server = rm->server; grpc_server *server = rm->server;
@ -507,26 +521,34 @@ static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
return; return;
} }
int request_id = gpr_stack_lockfree_pop(rm->requests); for (size_t i = 0; i < server->cq_count; i++) {
if (request_id == -1) { size_t cq_idx = (chand->cq_idx + i) % server->cq_count;
gpr_mu_lock(&server->mu_call); int request_id = gpr_stack_lockfree_pop(rm->requests_per_cq[cq_idx]);
gpr_mu_lock(&calld->mu_state); if (request_id == -1) {
calld->state = PENDING; continue;
gpr_mu_unlock(&calld->mu_state);
if (rm->pending_head == NULL) {
rm->pending_tail = rm->pending_head = calld;
} else { } else {
rm->pending_tail->pending_next = calld; gpr_mu_lock(&calld->mu_state);
rm->pending_tail = calld; calld->state = ACTIVATED;
gpr_mu_unlock(&calld->mu_state);
publish_call(exec_ctx, server, calld, cq_idx,
&server->requested_calls[request_id]);
return; /* early out */
} }
calld->pending_next = NULL; }
gpr_mu_unlock(&server->mu_call);
/* no cq to take the request found: queue it on the slow list */
gpr_mu_lock(&server->mu_call);
gpr_mu_lock(&calld->mu_state);
calld->state = PENDING;
gpr_mu_unlock(&calld->mu_state);
if (rm->pending_head == NULL) {
rm->pending_tail = rm->pending_head = calld;
} else { } else {
gpr_mu_lock(&calld->mu_state); rm->pending_tail->pending_next = calld;
calld->state = ACTIVATED; rm->pending_tail = calld;
gpr_mu_unlock(&calld->mu_state);
publish_call(exec_ctx, server, calld, &server->requested_calls[request_id]);
} }
calld->pending_next = NULL;
gpr_mu_unlock(&server->mu_call);
} }
static void finish_start_new_rpc( static void finish_start_new_rpc(
@ -548,14 +570,14 @@ static void finish_start_new_rpc(
switch (payload_handling) { switch (payload_handling) {
case GRPC_SRM_PAYLOAD_NONE: case GRPC_SRM_PAYLOAD_NONE:
publish_new_rpc(exec_ctx, calld, true); publish_new_rpc(exec_ctx, elem, true);
break; break;
case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: { case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: {
grpc_op op; grpc_op op;
memset(&op, 0, sizeof(op)); memset(&op, 0, sizeof(op));
op.op = GRPC_OP_RECV_MESSAGE; op.op = GRPC_OP_RECV_MESSAGE;
op.data.recv_message = &calld->payload; op.data.recv_message = &calld->payload;
grpc_closure_init(&calld->publish, publish_new_rpc, calld); grpc_closure_init(&calld->publish, publish_new_rpc, elem);
grpc_call_start_batch_and_execute(exec_ctx, calld->call, &op, 1, grpc_call_start_batch_and_execute(exec_ctx, calld->call, &op, 1,
&calld->publish); &calld->publish);
break; break;
@ -637,14 +659,16 @@ static int num_channels(grpc_server *server) {
static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx, static void kill_pending_work_locked(grpc_exec_ctx *exec_ctx,
grpc_server *server) { grpc_server *server) {
registered_method *rm; if (server->started) {
request_matcher_kill_requests(exec_ctx, server, request_matcher_kill_requests(exec_ctx, server,
&server->unregistered_request_matcher); &server->unregistered_request_matcher);
request_matcher_zombify_all_pending_calls( request_matcher_zombify_all_pending_calls(
exec_ctx, &server->unregistered_request_matcher); exec_ctx, &server->unregistered_request_matcher);
for (rm = server->registered_methods; rm; rm = rm->next) { for (registered_method *rm = server->registered_methods; rm;
request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher); rm = rm->next) {
request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher); request_matcher_kill_requests(exec_ctx, server, &rm->request_matcher);
request_matcher_zombify_all_pending_calls(exec_ctx, &rm->request_matcher);
}
} }
} }
@ -895,25 +919,46 @@ const grpc_channel_filter grpc_server_top_filter = {
"server", "server",
}; };
void grpc_server_register_completion_queue(grpc_server *server, static void register_completion_queue(grpc_server *server,
grpc_completion_queue *cq, grpc_completion_queue *cq,
void *reserved) { bool is_non_listening, void *reserved) {
size_t i, n; size_t i, n;
GRPC_API_TRACE(
"grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
(server, cq, reserved));
GPR_ASSERT(!reserved); GPR_ASSERT(!reserved);
for (i = 0; i < server->cq_count; i++) { for (i = 0; i < server->cq_count; i++) {
if (server->cqs[i] == cq) return; if (server->cqs[i] == cq) return;
} }
GRPC_CQ_INTERNAL_REF(cq, "server");
grpc_cq_mark_server_cq(cq); grpc_cq_mark_server_cq(cq);
if (is_non_listening) {
grpc_cq_mark_non_listening_server_cq(cq);
}
GRPC_CQ_INTERNAL_REF(cq, "server");
n = server->cq_count++; n = server->cq_count++;
server->cqs = gpr_realloc(server->cqs, server->cqs = gpr_realloc(server->cqs,
server->cq_count * sizeof(grpc_completion_queue *)); server->cq_count * sizeof(grpc_completion_queue *));
server->cqs[n] = cq; server->cqs[n] = cq;
} }
void grpc_server_register_completion_queue(grpc_server *server,
grpc_completion_queue *cq,
void *reserved) {
GRPC_API_TRACE(
"grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
(server, cq, reserved));
register_completion_queue(server, cq, false, reserved);
}
void grpc_server_register_non_listening_completion_queue(
grpc_server *server, grpc_completion_queue *cq, void *reserved) {
GRPC_API_TRACE(
"grpc_server_register_non_listening_completion_queue(server=%p, cq=%p, "
"reserved=%p)",
3, (server, cq, reserved));
register_completion_queue(server, cq, true, reserved);
}
grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) { grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
size_t i; size_t i;
@ -940,8 +985,6 @@ grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
for (i = 0; i < (size_t)server->max_requested_calls; i++) { for (i = 0; i < (size_t)server->max_requested_calls; i++) {
gpr_stack_lockfree_push(server->request_freelist, (int)i); gpr_stack_lockfree_push(server->request_freelist, (int)i);
} }
request_matcher_init(&server->unregistered_request_matcher,
server->max_requested_calls, server);
server->requested_calls = gpr_malloc(server->max_requested_calls * server->requested_calls = gpr_malloc(server->max_requested_calls *
sizeof(*server->requested_calls)); sizeof(*server->requested_calls));
@ -985,8 +1028,6 @@ void *grpc_server_register_method(
} }
m = gpr_malloc(sizeof(registered_method)); m = gpr_malloc(sizeof(registered_method));
memset(m, 0, sizeof(*m)); memset(m, 0, sizeof(*m));
request_matcher_init(&m->request_matcher, server->max_requested_calls,
server);
m->method = gpr_strdup(method); m->method = gpr_strdup(method);
m->host = gpr_strdup(host); m->host = gpr_strdup(host);
m->next = server->registered_methods; m->next = server->registered_methods;
@ -1003,13 +1044,23 @@ void grpc_server_start(grpc_server *server) {
GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server)); GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server));
server->started = true;
size_t pollset_count = 0;
server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count); server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count);
for (i = 0; i < server->cq_count; i++) { for (i = 0; i < server->cq_count; i++) {
server->pollsets[i] = grpc_cq_pollset(server->cqs[i]); if (!grpc_cq_is_non_listening_server_cq(server->cqs[i])) {
server->pollsets[pollset_count++] = grpc_cq_pollset(server->cqs[i]);
}
}
request_matcher_init(&server->unregistered_request_matcher,
server->max_requested_calls, server);
for (registered_method *rm = server->registered_methods; rm; rm = rm->next) {
request_matcher_init(&rm->request_matcher, server->max_requested_calls,
server);
} }
for (l = server->listeners; l; l = l->next) { for (l = server->listeners; l; l = l->next) {
l->start(&exec_ctx, server, l->arg, server->pollsets, server->cq_count); l->start(&exec_ctx, server, l->arg, server->pollsets, pollset_count);
} }
grpc_exec_ctx_finish(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx);
@ -1017,8 +1068,8 @@ void grpc_server_start(grpc_server *server) {
void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s, void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
grpc_transport *transport, grpc_transport *transport,
grpc_pollset *accepting_pollset,
const grpc_channel_args *args) { const grpc_channel_args *args) {
size_t i;
size_t num_registered_methods; size_t num_registered_methods;
size_t alloc; size_t alloc;
registered_method *rm; registered_method *rm;
@ -1033,12 +1084,6 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
uint32_t max_probes = 0; uint32_t max_probes = 0;
grpc_transport_op op; grpc_transport_op op;
for (i = 0; i < s->cq_count; i++) {
memset(&op, 0, sizeof(op));
op.bind_pollset = grpc_cq_pollset(s->cqs[i]);
grpc_transport_perform_op(exec_ctx, transport, &op);
}
channel = channel =
grpc_channel_create(exec_ctx, NULL, args, GRPC_SERVER_CHANNEL, transport); grpc_channel_create(exec_ctx, NULL, args, GRPC_SERVER_CHANNEL, transport);
chand = (channel_data *)grpc_channel_stack_element( chand = (channel_data *)grpc_channel_stack_element(
@ -1048,6 +1093,17 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
server_ref(s); server_ref(s);
chand->channel = channel; chand->channel = channel;
size_t cq_idx;
grpc_completion_queue *accepting_cq = grpc_cq_from_pollset(accepting_pollset);
for (cq_idx = 0; cq_idx < s->cq_count; cq_idx++) {
if (s->cqs[cq_idx] == accepting_cq) break;
}
if (cq_idx == s->cq_count) {
/* completion queue not found: pick a random one to publish new calls to */
cq_idx = (size_t)rand() % s->cq_count;
}
chand->cq_idx = cq_idx;
num_registered_methods = 0; num_registered_methods = 0;
for (rm = s->registered_methods; rm; rm = rm->next) { for (rm = s->registered_methods; rm; rm = rm->next) {
num_registered_methods++; num_registered_methods++;
@ -1218,19 +1274,19 @@ void grpc_server_add_listener(
} }
static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx, static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
grpc_server *server, grpc_server *server, size_t cq_idx,
requested_call *rc) { requested_call *rc) {
call_data *calld = NULL; call_data *calld = NULL;
request_matcher *rm = NULL; request_matcher *rm = NULL;
int request_id; int request_id;
if (gpr_atm_acq_load(&server->shutdown_flag)) { if (gpr_atm_acq_load(&server->shutdown_flag)) {
fail_call(exec_ctx, server, rc); fail_call(exec_ctx, server, cq_idx, rc);
return GRPC_CALL_OK; return GRPC_CALL_OK;
} }
request_id = gpr_stack_lockfree_pop(server->request_freelist); request_id = gpr_stack_lockfree_pop(server->request_freelist);
if (request_id == -1) { if (request_id == -1) {
/* out of request ids: just fail this one */ /* out of request ids: just fail this one */
fail_call(exec_ctx, server, rc); fail_call(exec_ctx, server, cq_idx, rc);
return GRPC_CALL_OK; return GRPC_CALL_OK;
} }
switch (rc->type) { switch (rc->type) {
@ -1243,12 +1299,12 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
} }
server->requested_calls[request_id] = *rc; server->requested_calls[request_id] = *rc;
gpr_free(rc); gpr_free(rc);
if (gpr_stack_lockfree_push(rm->requests, request_id)) { if (gpr_stack_lockfree_push(rm->requests_per_cq[cq_idx], request_id)) {
/* this was the first queued request: we need to lock and start /* this was the first queued request: we need to lock and start
matching calls */ matching calls */
gpr_mu_lock(&server->mu_call); gpr_mu_lock(&server->mu_call);
while ((calld = rm->pending_head) != NULL) { while ((calld = rm->pending_head) != NULL) {
request_id = gpr_stack_lockfree_pop(rm->requests); request_id = gpr_stack_lockfree_pop(rm->requests_per_cq[cq_idx]);
if (request_id == -1) break; if (request_id == -1) break;
rm->pending_head = calld->pending_next; rm->pending_head = calld->pending_next;
gpr_mu_unlock(&server->mu_call); gpr_mu_unlock(&server->mu_call);
@ -1264,7 +1320,7 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(calld->state == PENDING); GPR_ASSERT(calld->state == PENDING);
calld->state = ACTIVATED; calld->state = ACTIVATED;
gpr_mu_unlock(&calld->mu_state); gpr_mu_unlock(&calld->mu_state);
publish_call(exec_ctx, server, calld, publish_call(exec_ctx, server, calld, cq_idx,
&server->requested_calls[request_id]); &server->requested_calls[request_id]);
} }
gpr_mu_lock(&server->mu_call); gpr_mu_lock(&server->mu_call);
@ -1288,7 +1344,13 @@ grpc_call_error grpc_server_request_call(
"cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)", "cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)",
7, (server, call, details, initial_metadata, cq_bound_to_call, 7, (server, call, details, initial_metadata, cq_bound_to_call,
cq_for_notification, tag)); cq_for_notification, tag));
if (!grpc_cq_is_server_cq(cq_for_notification)) { size_t cq_idx;
for (cq_idx = 0; cq_idx < server->cq_count; cq_idx++) {
if (server->cqs[cq_idx] == cq_for_notification) {
break;
}
}
if (cq_idx == server->cq_count) {
gpr_free(rc); gpr_free(rc);
error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE; error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
goto done; goto done;
@ -1299,11 +1361,10 @@ grpc_call_error grpc_server_request_call(
rc->server = server; rc->server = server;
rc->tag = tag; rc->tag = tag;
rc->cq_bound_to_call = cq_bound_to_call; rc->cq_bound_to_call = cq_bound_to_call;
rc->cq_for_notification = cq_for_notification;
rc->call = call; rc->call = call;
rc->data.batch.details = details; rc->data.batch.details = details;
rc->initial_metadata = initial_metadata; rc->initial_metadata = initial_metadata;
error = queue_call_request(&exec_ctx, server, rc); error = queue_call_request(&exec_ctx, server, cq_idx, rc);
done: done:
grpc_exec_ctx_finish(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx);
return error; return error;
@ -1325,7 +1386,14 @@ grpc_call_error grpc_server_request_registered_call(
"tag=%p)", "tag=%p)",
9, (server, rmp, call, deadline, initial_metadata, optional_payload, 9, (server, rmp, call, deadline, initial_metadata, optional_payload,
cq_bound_to_call, cq_for_notification, tag)); cq_bound_to_call, cq_for_notification, tag));
if (!grpc_cq_is_server_cq(cq_for_notification)) {
size_t cq_idx;
for (cq_idx = 0; cq_idx < server->cq_count; cq_idx++) {
if (server->cqs[cq_idx] == cq_for_notification) {
break;
}
}
if (cq_idx == server->cq_count) {
gpr_free(rc); gpr_free(rc);
error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE; error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
goto done; goto done;
@ -1341,26 +1409,25 @@ grpc_call_error grpc_server_request_registered_call(
rc->server = server; rc->server = server;
rc->tag = tag; rc->tag = tag;
rc->cq_bound_to_call = cq_bound_to_call; rc->cq_bound_to_call = cq_bound_to_call;
rc->cq_for_notification = cq_for_notification;
rc->call = call; rc->call = call;
rc->data.registered.registered_method = rm; rc->data.registered.registered_method = rm;
rc->data.registered.deadline = deadline; rc->data.registered.deadline = deadline;
rc->initial_metadata = initial_metadata; rc->initial_metadata = initial_metadata;
rc->data.registered.optional_payload = optional_payload; rc->data.registered.optional_payload = optional_payload;
error = queue_call_request(&exec_ctx, server, rc); error = queue_call_request(&exec_ctx, server, cq_idx, rc);
done: done:
grpc_exec_ctx_finish(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx);
return error; return error;
} }
static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server, static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
requested_call *rc) { size_t cq_idx, requested_call *rc) {
*rc->call = NULL; *rc->call = NULL;
rc->initial_metadata->count = 0; rc->initial_metadata->count = 0;
server_ref(server); server_ref(server);
grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0, grpc_cq_end_op(exec_ctx, server->cqs[cq_idx], rc->tag, 0, done_request_event,
done_request_event, rc, &rc->completion); rc, &rc->completion);
} }
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) { const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {

@ -53,6 +53,7 @@ void grpc_server_add_listener(
server */ server */
void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *server, void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *server,
grpc_transport *transport, grpc_transport *transport,
grpc_pollset *accepting_pollset,
const grpc_channel_args *args); const grpc_channel_args *args);
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server); const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server);

@ -373,7 +373,8 @@ grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) {
ss = g_static_strtab[idx]; ss = g_static_strtab[idx];
if (ss == NULL) break; if (ss == NULL) break;
if (ss->hash == hash && GPR_SLICE_LENGTH(ss->slice) == length && if (ss->hash == hash && GPR_SLICE_LENGTH(ss->slice) == length &&
0 == memcmp(buf, GPR_SLICE_START_PTR(ss->slice), length)) { (length == 0 ||
0 == memcmp(buf, GPR_SLICE_START_PTR(ss->slice), length))) {
GPR_TIMER_END("grpc_mdstr_from_buffer", 0); GPR_TIMER_END("grpc_mdstr_from_buffer", 0);
return ss; return ss;
} }

@ -295,7 +295,12 @@ Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
grpc_channel_args channel_args; grpc_channel_args channel_args;
args->SetChannelArgs(&channel_args); args->SetChannelArgs(&channel_args);
server_ = grpc_server_create(&channel_args, nullptr); server_ = grpc_server_create(&channel_args, nullptr);
grpc_server_register_completion_queue(server_, cq_.cq(), nullptr); if (thread_pool_ == nullptr) {
grpc_server_register_non_listening_completion_queue(server_, cq_.cq(),
nullptr);
} else {
grpc_server_register_completion_queue(server_, cq_.cq(), nullptr);
}
} }
Server::~Server() { Server::~Server() {
@ -407,7 +412,9 @@ bool Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) {
sync_methods_->push_back(SyncRequest(unknown_method_.get(), nullptr)); sync_methods_->push_back(SyncRequest(unknown_method_.get(), nullptr));
} }
for (size_t i = 0; i < num_cqs; i++) { for (size_t i = 0; i < num_cqs; i++) {
new UnimplementedAsyncRequest(this, cqs[i]); if (cqs[i]->IsFrequentlyPolled()) {
new UnimplementedAsyncRequest(this, cqs[i]);
}
} }
} }
// Start processing rpcs. // Start processing rpcs.

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -60,8 +60,9 @@ ServerBuilder::ServerBuilder()
} }
} }
std::unique_ptr<ServerCompletionQueue> ServerBuilder::AddCompletionQueue() { std::unique_ptr<ServerCompletionQueue> ServerBuilder::AddCompletionQueue(
ServerCompletionQueue* cq = new ServerCompletionQueue(); bool is_frequently_polled) {
ServerCompletionQueue* cq = new ServerCompletionQueue(is_frequently_polled);
cqs_.push_back(cq); cqs_.push_back(cq);
return std::unique_ptr<ServerCompletionQueue>(cq); return std::unique_ptr<ServerCompletionQueue>(cq);
} }
@ -99,10 +100,12 @@ void ServerBuilder::AddListeningPort(const grpc::string& addr,
std::unique_ptr<Server> ServerBuilder::BuildAndStart() { std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
std::unique_ptr<ThreadPoolInterface> thread_pool; std::unique_ptr<ThreadPoolInterface> thread_pool;
bool has_sync_methods = false;
for (auto it = services_.begin(); it != services_.end(); ++it) { for (auto it = services_.begin(); it != services_.end(); ++it) {
if ((*it)->service->has_synchronous_methods()) { if ((*it)->service->has_synchronous_methods()) {
if (thread_pool == nullptr) { if (thread_pool == nullptr) {
thread_pool.reset(CreateDefaultThreadPool()); thread_pool.reset(CreateDefaultThreadPool());
has_sync_methods = true;
break; break;
} }
} }
@ -116,6 +119,7 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) { for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
if ((*plugin).second->has_sync_methods()) { if ((*plugin).second->has_sync_methods()) {
thread_pool.reset(CreateDefaultThreadPool()); thread_pool.reset(CreateDefaultThreadPool());
has_sync_methods = true;
break; break;
} }
} }
@ -128,10 +132,33 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
std::unique_ptr<Server> server( std::unique_ptr<Server> server(
new Server(thread_pool.release(), true, max_message_size_, &args)); new Server(thread_pool.release(), true, max_message_size_, &args));
ServerInitializer* initializer = server->initializer(); ServerInitializer* initializer = server->initializer();
// If the server has atleast one sync methods, we know that this is a Sync
// server or a Hybrid server and the completion queue (server->cq_) would be
// frequently polled.
int num_frequently_polled_cqs = has_sync_methods ? 1 : 0;
for (auto cq = cqs_.begin(); cq != cqs_.end(); ++cq) { for (auto cq = cqs_.begin(); cq != cqs_.end(); ++cq) {
grpc_server_register_completion_queue(server->server_, (*cq)->cq(), // A completion queue that is not polled frequently (by calling Next() or
nullptr); // AsyncNext()) is not safe to use for listening to incoming channels.
// Register all such completion queues as non-listening completion queues
// with the GRPC core library.
if ((*cq)->IsFrequentlyPolled()) {
grpc_server_register_completion_queue(server->server_, (*cq)->cq(),
nullptr);
num_frequently_polled_cqs++;
} else {
grpc_server_register_non_listening_completion_queue(server->server_,
(*cq)->cq(), nullptr);
}
}
if (num_frequently_polled_cqs == 0) {
gpr_log(GPR_ERROR,
"At least one of the completion queues must be frequently polled");
return nullptr;
} }
for (auto service = services_.begin(); service != services_.end(); for (auto service = services_.begin(); service != services_.end();
service++) { service++) {
if (!server->RegisterService((*service)->host.get(), (*service)->service)) { if (!server->RegisterService((*service)->host.get(), (*service)->service)) {

@ -235,8 +235,16 @@ namespace Grpc.Core.Tests
await barrier.Task; // make sure the handler has started. await barrier.Task; // make sure the handler has started.
cts.Cancel(); cts.Cancel();
var ex = Assert.ThrowsAsync<RpcException>(async () => await call.ResponseAsync); try
Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode); {
// cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
await call.ResponseAsync;
Assert.Fail();
}
catch (RpcException ex)
{
Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
}
} }
[Test] [Test]
@ -265,9 +273,15 @@ namespace Grpc.Core.Tests
await handlerStartedBarrier.Task; await handlerStartedBarrier.Task;
cts.Cancel(); cts.Cancel();
var ex = Assert.ThrowsAsync<RpcException>(async () => await call.ResponseAsync); try
Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode); {
await call.ResponseAsync;
Assert.Fail();
}
catch (RpcException ex)
{
Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
}
Assert.AreEqual("SUCCESS", await successTcs.Task); Assert.AreEqual("SUCCESS", await successTcs.Task);
} }

@ -105,7 +105,15 @@ namespace Grpc.Core.Tests
var parentCall = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall(new CallOptions(cancellationToken: cts.Token))); var parentCall = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall(new CallOptions(cancellationToken: cts.Token)));
await readyToCancelTcs.Task; await readyToCancelTcs.Task;
cts.Cancel(); cts.Cancel();
Assert.ThrowsAsync(typeof(RpcException), async () => await parentCall); try
{
// cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
await parentCall;
Assert.Fail();
}
catch (RpcException)
{
}
Assert.AreEqual("CHILD_CALL_CANCELLED", await successTcs.Task); Assert.AreEqual("CHILD_CALL_CANCELLED", await successTcs.Task);
} }

@ -32,7 +32,7 @@
#endregion #endregion
using System; using System;
using System.Threading; using System.Linq;
using Grpc.Core; using Grpc.Core;
using NUnit.Framework; using NUnit.Framework;
@ -44,7 +44,11 @@ namespace Grpc.Core.Tests
public void InitializeAndShutdownGrpcEnvironment() public void InitializeAndShutdownGrpcEnvironment()
{ {
var env = GrpcEnvironment.AddRef(); var env = GrpcEnvironment.AddRef();
Assert.IsNotNull(env.CompletionQueue); Assert.IsTrue(env.CompletionQueues.Count > 0);
for (int i = 0; i < env.CompletionQueues.Count; i++)
{
Assert.IsNotNull(env.CompletionQueues.ElementAt(i));
}
GrpcEnvironment.Release(); GrpcEnvironment.Release();
} }

@ -53,8 +53,6 @@ namespace Grpc.Core.Internal.Tests
[SetUp] [SetUp]
public void Init() public void Init()
{ {
var environment = GrpcEnvironment.AddRef();
// Create a fake server just so we have an instance to refer to. // Create a fake server just so we have an instance to refer to.
// The server won't actually be used at all. // The server won't actually be used at all.
server = new Server() server = new Server()
@ -66,7 +64,6 @@ namespace Grpc.Core.Internal.Tests
fakeCall = new FakeNativeCall(); fakeCall = new FakeNativeCall();
asyncCallServer = new AsyncCallServer<string, string>( asyncCallServer = new AsyncCallServer<string, string>(
Marshallers.StringMarshaller.Serializer, Marshallers.StringMarshaller.Deserializer, Marshallers.StringMarshaller.Serializer, Marshallers.StringMarshaller.Deserializer,
environment,
server); server);
asyncCallServer.InitializeForTesting(fakeCall); asyncCallServer.InitializeForTesting(fakeCall);
} }
@ -75,7 +72,6 @@ namespace Grpc.Core.Internal.Tests
public void Cleanup() public void Cleanup()
{ {
server.ShutdownAsync().Wait(); server.ShutdownAsync().Wait();
GrpcEnvironment.Release();
} }
[Test] [Test]
@ -136,7 +132,6 @@ namespace Grpc.Core.Internal.Tests
public void WriteAfterCancelNotificationFails() public void WriteAfterCancelNotificationFails()
{ {
var finishedTask = asyncCallServer.ServerSideCallAsync(); var finishedTask = asyncCallServer.ServerSideCallAsync();
var requestStream = new ServerRequestStream<string, string>(asyncCallServer);
var responseStream = new ServerResponseStream<string, string>(asyncCallServer); var responseStream = new ServerResponseStream<string, string>(asyncCallServer);
fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true); fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
@ -181,6 +176,21 @@ namespace Grpc.Core.Internal.Tests
AssertFinished(asyncCallServer, fakeCall, finishedTask); AssertFinished(asyncCallServer, fakeCall, finishedTask);
} }
[Test]
public void WriteAfterWriteStatusThrowsInvalidOperationException()
{
var finishedTask = asyncCallServer.ServerSideCallAsync();
var responseStream = new ServerResponseStream<string, string>(asyncCallServer);
asyncCallServer.SendStatusFromServerAsync(Status.DefaultSuccess, new Metadata(), null);
Assert.ThrowsAsync(typeof(InvalidOperationException), async () => await responseStream.WriteAsync("request1"));
fakeCall.SendStatusFromServerHandler(true);
fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
AssertFinished(asyncCallServer, fakeCall, finishedTask);
}
static void AssertFinished(AsyncCallServer<string, string> asyncCallServer, FakeNativeCall fakeCall, Task finishedTask) static void AssertFinished(AsyncCallServer<string, string> asyncCallServer, FakeNativeCall fakeCall, Task finishedTask)
{ {
Assert.IsTrue(fakeCall.IsDisposed); Assert.IsTrue(fakeCall.IsDisposed);

@ -33,7 +33,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Grpc.Core.Internal; using Grpc.Core.Internal;
@ -82,7 +81,7 @@ namespace Grpc.Core.Internal.Tests
Assert.ThrowsAsync(typeof(InvalidOperationException), Assert.ThrowsAsync(typeof(InvalidOperationException),
async () => await asyncCall.ReadMessageAsync()); async () => await asyncCall.ReadMessageAsync());
Assert.Throws(typeof(InvalidOperationException), Assert.Throws(typeof(InvalidOperationException),
() => asyncCall.StartSendMessage("abc", new WriteFlags(), (x,y) => {})); () => asyncCall.SendMessageAsync("abc", new WriteFlags()));
} }
[Test] [Test]
@ -103,7 +102,7 @@ namespace Grpc.Core.Internal.Tests
var resultTask = asyncCall.UnaryCallAsync("request1"); var resultTask = asyncCall.UnaryCallAsync("request1");
fakeCall.UnaryResponseClientHandler(true, fakeCall.UnaryResponseClientHandler(true,
CreateClientSideStatus(StatusCode.InvalidArgument), CreateClientSideStatus(StatusCode.InvalidArgument),
CreateResponsePayload(), null,
new Metadata()); new Metadata());
AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument); AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument);
@ -148,7 +147,7 @@ namespace Grpc.Core.Internal.Tests
var resultTask = asyncCall.ClientStreamingCallAsync(); var resultTask = asyncCall.ClientStreamingCallAsync();
fakeCall.UnaryResponseClientHandler(true, fakeCall.UnaryResponseClientHandler(true,
CreateClientSideStatus(StatusCode.InvalidArgument), CreateClientSideStatus(StatusCode.InvalidArgument),
CreateResponsePayload(), null,
new Metadata()); new Metadata());
AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument); AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument);
@ -193,7 +192,7 @@ namespace Grpc.Core.Internal.Tests
fakeCall.UnaryResponseClientHandler(true, fakeCall.UnaryResponseClientHandler(true,
CreateClientSideStatus(StatusCode.Internal), CreateClientSideStatus(StatusCode.Internal),
CreateResponsePayload(), null,
new Metadata()); new Metadata());
AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal); AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal);
@ -211,7 +210,9 @@ namespace Grpc.Core.Internal.Tests
new Metadata()); new Metadata());
AssertUnaryResponseSuccess(asyncCall, fakeCall, resultTask); AssertUnaryResponseSuccess(asyncCall, fakeCall, resultTask);
var ex = Assert.Throws<RpcException>(() => requestStream.WriteAsync("request1"));
var writeTask = requestStream.WriteAsync("request1");
var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
Assert.AreEqual(Status.DefaultSuccess, ex.Status); Assert.AreEqual(Status.DefaultSuccess, ex.Status);
} }
@ -223,11 +224,13 @@ namespace Grpc.Core.Internal.Tests
fakeCall.UnaryResponseClientHandler(true, fakeCall.UnaryResponseClientHandler(true,
new ClientSideStatus(new Status(StatusCode.OutOfRange, ""), new Metadata()), new ClientSideStatus(new Status(StatusCode.OutOfRange, ""), new Metadata()),
CreateResponsePayload(), null,
new Metadata()); new Metadata());
AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.OutOfRange); AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.OutOfRange);
var ex = Assert.Throws<RpcException>(() => requestStream.WriteAsync("request1"));
var writeTask = requestStream.WriteAsync("request1");
var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
Assert.AreEqual(StatusCode.OutOfRange, ex.Status.StatusCode); Assert.AreEqual(StatusCode.OutOfRange, ex.Status.StatusCode);
} }
@ -267,7 +270,7 @@ namespace Grpc.Core.Internal.Tests
} }
[Test] [Test]
public void ClientStreaming_WriteAfterCancellationRequestThrowsOperationCancelledException() public void ClientStreaming_WriteAfterCancellationRequestThrowsTaskCanceledException()
{ {
var resultTask = asyncCall.ClientStreamingCallAsync(); var resultTask = asyncCall.ClientStreamingCallAsync();
var requestStream = new ClientRequestStream<string, string>(asyncCall); var requestStream = new ClientRequestStream<string, string>(asyncCall);
@ -275,11 +278,12 @@ namespace Grpc.Core.Internal.Tests
asyncCall.Cancel(); asyncCall.Cancel();
Assert.IsTrue(fakeCall.IsCancelled); Assert.IsTrue(fakeCall.IsCancelled);
Assert.Throws(typeof(OperationCanceledException), () => requestStream.WriteAsync("request1")); var writeTask = requestStream.WriteAsync("request1");
Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask);
fakeCall.UnaryResponseClientHandler(true, fakeCall.UnaryResponseClientHandler(true,
CreateClientSideStatus(StatusCode.Cancelled), CreateClientSideStatus(StatusCode.Cancelled),
CreateResponsePayload(), null,
new Metadata()); new Metadata());
AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Cancelled); AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Cancelled);
@ -290,7 +294,7 @@ namespace Grpc.Core.Internal.Tests
{ {
asyncCall.StartServerStreamingCall("request1"); asyncCall.StartServerStreamingCall("request1");
Assert.Throws(typeof(InvalidOperationException), Assert.Throws(typeof(InvalidOperationException),
() => asyncCall.StartSendMessage("abc", new WriteFlags(), (x,y) => {})); () => asyncCall.SendMessageAsync("abc", new WriteFlags()));
} }
[Test] [Test]
@ -390,12 +394,13 @@ namespace Grpc.Core.Internal.Tests
AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
var ex = Assert.ThrowsAsync<RpcException>(async () => await requestStream.WriteAsync("request1")); var writeTask = requestStream.WriteAsync("request1");
var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
Assert.AreEqual(Status.DefaultSuccess, ex.Status); Assert.AreEqual(Status.DefaultSuccess, ex.Status);
} }
[Test] [Test]
public void DuplexStreaming_CompleteAfterReceivingStatusFails() public void DuplexStreaming_CompleteAfterReceivingStatusSuceeds()
{ {
asyncCall.StartDuplexStreamingCall(); asyncCall.StartDuplexStreamingCall();
var requestStream = new ClientRequestStream<string, string>(asyncCall); var requestStream = new ClientRequestStream<string, string>(asyncCall);
@ -411,7 +416,7 @@ namespace Grpc.Core.Internal.Tests
} }
[Test] [Test]
public void DuplexStreaming_WriteAfterCancellationRequestThrowsOperationCancelledException() public void DuplexStreaming_WriteAfterCancellationRequestThrowsTaskCanceledException()
{ {
asyncCall.StartDuplexStreamingCall(); asyncCall.StartDuplexStreamingCall();
var requestStream = new ClientRequestStream<string, string>(asyncCall); var requestStream = new ClientRequestStream<string, string>(asyncCall);
@ -419,7 +424,9 @@ namespace Grpc.Core.Internal.Tests
asyncCall.Cancel(); asyncCall.Cancel();
Assert.IsTrue(fakeCall.IsCancelled); Assert.IsTrue(fakeCall.IsCancelled);
Assert.Throws(typeof(OperationCanceledException), () => requestStream.WriteAsync("request1"));
var writeTask = requestStream.WriteAsync("request1");
Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask);
var readTask = responseStream.MoveNext(); var readTask = responseStream.MoveNext();
fakeCall.ReceivedMessageHandler(true, null); fakeCall.ReceivedMessageHandler(true, null);

@ -60,7 +60,7 @@ namespace Grpc.Core.Internal.Tests
var ev = cq.Next(); var ev = cq.Next();
cq.Dispose(); cq.Dispose();
GrpcEnvironment.Release(); GrpcEnvironment.Release();
Assert.AreEqual(GRPCCompletionType.Shutdown, ev.type); Assert.AreEqual(CompletionQueueEvent.CompletionType.Shutdown, ev.type);
Assert.AreNotEqual(IntPtr.Zero, ev.success); Assert.AreNotEqual(IntPtr.Zero, ev.success);
Assert.AreEqual(IntPtr.Zero, ev.tag); Assert.AreEqual(IntPtr.Zero, ev.tag);
} }

@ -61,15 +61,15 @@ namespace Grpc.Core.Internal.Tests
} }
[Test] [Test]
public void InfFuture() public void InfFutureMatchesNativeValue()
{ {
var timespec = Timespec.InfFuture; Assert.AreEqual(Timespec.NativeInfFuture, Timespec.InfFuture);
} }
[Test] [Test]
public void InfPast() public void InfPastMatchesNativeValue()
{ {
var timespec = Timespec.InfPast; Assert.AreEqual(Timespec.NativeInfPast, Timespec.InfPast);
} }
[Test] [Test]
@ -108,7 +108,7 @@ namespace Grpc.Core.Internal.Tests
Assert.Throws(typeof(InvalidOperationException), Assert.Throws(typeof(InvalidOperationException),
() => new Timespec(0, 1000 * 1000 * 1000).ToDateTime()); () => new Timespec(0, 1000 * 1000 * 1000).ToDateTime());
Assert.Throws(typeof(InvalidOperationException), Assert.Throws(typeof(InvalidOperationException),
() => new Timespec(0, 0, GPRClockType.Monotonic).ToDateTime()); () => new Timespec(0, 0, ClockType.Monotonic).ToDateTime());
} }
[Test] [Test]

@ -134,7 +134,15 @@ namespace Grpc.Core.Tests
{ {
helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) => helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) =>
{ {
Assert.ThrowsAsync<IOException>(async () => await requestStream.MoveNext()); try
{
// cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
await requestStream.MoveNext();
Assert.Fail();
}
catch (IOException)
{
}
return "RESPONSE"; return "RESPONSE";
}); });

@ -31,7 +31,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -56,6 +55,7 @@ namespace Grpc.Core
readonly string target; readonly string target;
readonly GrpcEnvironment environment; readonly GrpcEnvironment environment;
readonly CompletionQueueSafeHandle completionQueue;
readonly ChannelSafeHandle handle; readonly ChannelSafeHandle handle;
readonly Dictionary<string, ChannelOption> options; readonly Dictionary<string, ChannelOption> options;
@ -75,6 +75,7 @@ namespace Grpc.Core
EnsureUserAgentChannelOption(this.options); EnsureUserAgentChannelOption(this.options);
this.environment = GrpcEnvironment.AddRef(); this.environment = GrpcEnvironment.AddRef();
this.completionQueue = this.environment.PickCompletionQueue();
using (var nativeCredentials = credentials.ToNativeCredentials()) using (var nativeCredentials = credentials.ToNativeCredentials())
using (var nativeChannelArgs = ChannelOptions.CreateChannelArgs(this.options.Values)) using (var nativeChannelArgs = ChannelOptions.CreateChannelArgs(this.options.Values))
{ {
@ -135,7 +136,7 @@ namespace Grpc.Core
tcs.SetCanceled(); tcs.SetCanceled();
} }
}); });
handle.WatchConnectivityState(lastObservedState, deadlineTimespec, environment.CompletionQueue, environment.CompletionRegistry, handler); handle.WatchConnectivityState(lastObservedState, deadlineTimespec, completionQueue, handler);
return tcs.Task; return tcs.Task;
} }
@ -231,6 +232,14 @@ namespace Grpc.Core
} }
} }
internal CompletionQueueSafeHandle CompletionQueue
{
get
{
return this.completionQueue;
}
}
internal void AddCallReference(object call) internal void AddCallReference(object call)
{ {
activeCallCounter.Increment(); activeCallCounter.Increment();

@ -74,7 +74,6 @@
<Compile Include="Internal\CallSafeHandle.cs" /> <Compile Include="Internal\CallSafeHandle.cs" />
<Compile Include="Internal\ChannelSafeHandle.cs" /> <Compile Include="Internal\ChannelSafeHandle.cs" />
<Compile Include="Internal\CompletionQueueSafeHandle.cs" /> <Compile Include="Internal\CompletionQueueSafeHandle.cs" />
<Compile Include="Internal\Enums.cs" />
<Compile Include="Internal\SafeHandleZeroIsInvalid.cs" /> <Compile Include="Internal\SafeHandleZeroIsInvalid.cs" />
<Compile Include="Internal\Timespec.cs" /> <Compile Include="Internal\Timespec.cs" />
<Compile Include="Internal\GrpcThreadPool.cs" /> <Compile Include="Internal\GrpcThreadPool.cs" />
@ -87,7 +86,6 @@
<Compile Include="Utils\BenchmarkUtil.cs" /> <Compile Include="Utils\BenchmarkUtil.cs" />
<Compile Include="ChannelCredentials.cs" /> <Compile Include="ChannelCredentials.cs" />
<Compile Include="Internal\ChannelArgsSafeHandle.cs" /> <Compile Include="Internal\ChannelArgsSafeHandle.cs" />
<Compile Include="Internal\AsyncCompletion.cs" />
<Compile Include="Internal\AsyncCallBase.cs" /> <Compile Include="Internal\AsyncCallBase.cs" />
<Compile Include="Internal\AsyncCallServer.cs" /> <Compile Include="Internal\AsyncCallServer.cs" />
<Compile Include="Internal\AsyncCall.cs" /> <Compile Include="Internal\AsyncCall.cs" />
@ -134,6 +132,10 @@
<Compile Include="DefaultCallInvoker.cs" /> <Compile Include="DefaultCallInvoker.cs" />
<Compile Include="Internal\UnimplementedCallInvoker.cs" /> <Compile Include="Internal\UnimplementedCallInvoker.cs" />
<Compile Include="Internal\InterceptingCallInvoker.cs" /> <Compile Include="Internal\InterceptingCallInvoker.cs" />
<Compile Include="Internal\ServerRpcNew.cs" />
<Compile Include="Internal\ClientSideStatus.cs" />
<Compile Include="Internal\ClockType.cs" />
<Compile Include="Internal\CallError.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Grpc.Core.nuspec" /> <None Include="Grpc.Core.nuspec" />

@ -32,8 +32,9 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Grpc.Core.Internal; using Grpc.Core.Internal;
using Grpc.Core.Logging; using Grpc.Core.Logging;
using Grpc.Core.Utils; using Grpc.Core.Utils;
@ -51,12 +52,13 @@ namespace Grpc.Core
static GrpcEnvironment instance; static GrpcEnvironment instance;
static int refCount; static int refCount;
static int? customThreadPoolSize; static int? customThreadPoolSize;
static int? customCompletionQueueCount;
static ILogger logger = new ConsoleLogger(); static ILogger logger = new ConsoleLogger();
readonly GrpcThreadPool threadPool; readonly GrpcThreadPool threadPool;
readonly CompletionRegistry completionRegistry;
readonly DebugStats debugStats = new DebugStats(); readonly DebugStats debugStats = new DebugStats();
readonly AtomicCounter cqPickerCounter = new AtomicCounter();
bool isClosed; bool isClosed;
/// <summary> /// <summary>
@ -140,37 +142,52 @@ namespace Grpc.Core
} }
} }
/// <summary>
/// Sets the number of completion queues in the gRPC thread pool that polls for internal RPC events.
/// Can be only invoke before the <c>GrpcEnviroment</c> is started and cannot be changed afterwards.
/// Setting the number of completions queues is an advanced setting and you should only use it if you know what you are doing.
/// Most users should rely on the default value provided by gRPC library.
/// Note: this method is part of an experimental API that can change or be removed without any prior notice.
/// </summary>
public static void SetCompletionQueueCount(int completionQueueCount)
{
lock (staticLock)
{
GrpcPreconditions.CheckState(instance == null, "Can only be set before GrpcEnvironment is initialized");
GrpcPreconditions.CheckArgument(completionQueueCount > 0, "threadCount needs to be a positive number");
customCompletionQueueCount = completionQueueCount;
}
}
/// <summary> /// <summary>
/// Creates gRPC environment. /// Creates gRPC environment.
/// </summary> /// </summary>
private GrpcEnvironment() private GrpcEnvironment()
{ {
GrpcNativeInit(); GrpcNativeInit();
completionRegistry = new CompletionRegistry(this); threadPool = new GrpcThreadPool(this, GetThreadPoolSizeOrDefault(), GetCompletionQueueCountOrDefault());
threadPool = new GrpcThreadPool(this, GetThreadPoolSizeOrDefault());
threadPool.Start(); threadPool.Start();
} }
/// <summary> /// <summary>
/// Gets the completion registry used by this gRPC environment. /// Gets the completion queues used by this gRPC environment.
/// </summary> /// </summary>
internal CompletionRegistry CompletionRegistry internal IReadOnlyCollection<CompletionQueueSafeHandle> CompletionQueues
{ {
get get
{ {
return this.completionRegistry; return this.threadPool.CompletionQueues;
} }
} }
/// <summary> /// <summary>
/// Gets the completion queue used by this gRPC environment. /// Picks a completion queue in a round-robin fashion.
/// Shouldn't be invoked on a per-call basis (used at per-channel basis).
/// </summary> /// </summary>
internal CompletionQueueSafeHandle CompletionQueue internal CompletionQueueSafeHandle PickCompletionQueue()
{ {
get var cqIndex = (int) ((cqPickerCounter.Increment() - 1) % this.threadPool.CompletionQueues.Count);
{ return this.threadPool.CompletionQueues.ElementAt(cqIndex);
return this.threadPool.CompletionQueue;
}
} }
/// <summary> /// <summary>
@ -230,5 +247,15 @@ namespace Grpc.Core
// more work, but seems to work reasonably well for a start. // more work, but seems to work reasonably well for a start.
return Math.Max(MinDefaultThreadPoolSize, Environment.ProcessorCount / 2); return Math.Max(MinDefaultThreadPoolSize, Environment.ProcessorCount / 2);
} }
private int GetCompletionQueueCountOrDefault()
{
if (customCompletionQueueCount.HasValue)
{
return customCompletionQueueCount.Value;
}
// by default, create a completion queue for each thread
return GetThreadPoolSizeOrDefault();
}
} }
} }

@ -32,12 +32,7 @@
#endregion #endregion
using System; using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Grpc.Core.Internal;
using Grpc.Core.Logging; using Grpc.Core.Logging;
using Grpc.Core.Profiling; using Grpc.Core.Profiling;
using Grpc.Core.Utils; using Grpc.Core.Utils;
@ -57,9 +52,11 @@ namespace Grpc.Core.Internal
// Completion of a pending unary response if not null. // Completion of a pending unary response if not null.
TaskCompletionSource<TResponse> unaryResponseTcs; TaskCompletionSource<TResponse> unaryResponseTcs;
// TODO(jtattermusch): this field doesn't need to be initialized for unary response calls.
// Indicates that response streaming call has finished. // Indicates that response streaming call has finished.
TaskCompletionSource<object> streamingCallFinishedTcs = new TaskCompletionSource<object>(); TaskCompletionSource<object> streamingCallFinishedTcs = new TaskCompletionSource<object>();
// TODO(jtattermusch): this field could be lazy-initialized (only if someone requests the response headers).
// Response headers set here once received. // Response headers set here once received.
TaskCompletionSource<Metadata> responseHeadersTcs = new TaskCompletionSource<Metadata>(); TaskCompletionSource<Metadata> responseHeadersTcs = new TaskCompletionSource<Metadata>();
@ -67,7 +64,7 @@ namespace Grpc.Core.Internal
ClientSideStatus? finishedStatus; ClientSideStatus? finishedStatus;
public AsyncCall(CallInvocationDetails<TRequest, TResponse> callDetails) public AsyncCall(CallInvocationDetails<TRequest, TResponse> callDetails)
: base(callDetails.RequestMarshaller.Serializer, callDetails.ResponseMarshaller.Deserializer, callDetails.Channel.Environment) : base(callDetails.RequestMarshaller.Serializer, callDetails.ResponseMarshaller.Deserializer)
{ {
this.details = callDetails.WithOptions(callDetails.Options.Normalize()); this.details = callDetails.WithOptions(callDetails.Options.Normalize());
this.initialMetadataSent = true; // we always send metadata at the very beginning of the call. this.initialMetadataSent = true; // we always send metadata at the very beginning of the call.
@ -144,7 +141,7 @@ namespace Grpc.Core.Internal
GrpcPreconditions.CheckState(!started); GrpcPreconditions.CheckState(!started);
started = true; started = true;
Initialize(environment.CompletionQueue); Initialize(details.Channel.CompletionQueue);
halfcloseRequested = true; halfcloseRequested = true;
readingDone = true; readingDone = true;
@ -171,7 +168,7 @@ namespace Grpc.Core.Internal
GrpcPreconditions.CheckState(!started); GrpcPreconditions.CheckState(!started);
started = true; started = true;
Initialize(environment.CompletionQueue); Initialize(details.Channel.CompletionQueue);
readingDone = true; readingDone = true;
@ -195,7 +192,7 @@ namespace Grpc.Core.Internal
GrpcPreconditions.CheckState(!started); GrpcPreconditions.CheckState(!started);
started = true; started = true;
Initialize(environment.CompletionQueue); Initialize(details.Channel.CompletionQueue);
halfcloseRequested = true; halfcloseRequested = true;
@ -220,7 +217,7 @@ namespace Grpc.Core.Internal
GrpcPreconditions.CheckState(!started); GrpcPreconditions.CheckState(!started);
started = true; started = true;
Initialize(environment.CompletionQueue); Initialize(details.Channel.CompletionQueue);
using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
{ {
@ -232,11 +229,10 @@ namespace Grpc.Core.Internal
/// <summary> /// <summary>
/// Sends a streaming request. Only one pending send action is allowed at any given time. /// Sends a streaming request. Only one pending send action is allowed at any given time.
/// completionDelegate is called when the operation finishes.
/// </summary> /// </summary>
public void StartSendMessage(TRequest msg, WriteFlags writeFlags, AsyncCompletionDelegate<object> completionDelegate) public Task SendMessageAsync(TRequest msg, WriteFlags writeFlags)
{ {
StartSendMessageInternal(msg, writeFlags, completionDelegate); return SendMessageInternalAsync(msg, writeFlags);
} }
/// <summary> /// <summary>
@ -250,29 +246,32 @@ namespace Grpc.Core.Internal
/// <summary> /// <summary>
/// Sends halfclose, indicating client is done with streaming requests. /// Sends halfclose, indicating client is done with streaming requests.
/// Only one pending send action is allowed at any given time. /// Only one pending send action is allowed at any given time.
/// completionDelegate is called when the operation finishes.
/// </summary> /// </summary>
public void StartSendCloseFromClient(AsyncCompletionDelegate<object> completionDelegate) public Task SendCloseFromClientAsync()
{ {
lock (myLock) lock (myLock)
{ {
GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); GrpcPreconditions.CheckState(started);
CheckSendingAllowed(allowFinished: true);
if (!disposed && !finished) var earlyResult = CheckSendPreconditionsClientSide();
if (earlyResult != null)
{ {
call.StartSendCloseFromClient(HandleSendCloseFromClientFinished); return earlyResult;
} }
else
if (disposed || finished)
{ {
// In case the call has already been finished by the serverside, // In case the call has already been finished by the serverside,
// the halfclose has already been done implicitly, so we only // the halfclose has already been done implicitly, so just return
// emit the notification for the completion delegate. // completed task here.
Task.Run(() => HandleSendCloseFromClientFinished(true)); halfcloseRequested = true;
return Task.FromResult<object>(null);
} }
call.StartSendCloseFromClient(HandleSendCloseFromClientFinished);
halfcloseRequested = true; halfcloseRequested = true;
sendCompletionDelegate = completionDelegate; streamingWriteTcs = new TaskCompletionSource<object>();
return streamingWriteTcs.Task;
} }
} }
@ -342,6 +341,45 @@ namespace Grpc.Core.Internal
get { return true; } get { return true; }
} }
protected override Task CheckSendAllowedOrEarlyResult()
{
var earlyResult = CheckSendPreconditionsClientSide();
if (earlyResult != null)
{
return earlyResult;
}
if (finishedStatus.HasValue)
{
// throwing RpcException if we already received status on client
// side makes the most sense.
// Note that this throws even for StatusCode.OK.
// Writing after the call has finished is not a programming error because server can close
// the call anytime, so don't throw directly, but let the write task finish with an error.
var tcs = new TaskCompletionSource<object>();
tcs.SetException(new RpcException(finishedStatus.Value.Status));
return tcs.Task;
}
return null;
}
private Task CheckSendPreconditionsClientSide()
{
GrpcPreconditions.CheckState(!halfcloseRequested, "Request stream has already been completed.");
GrpcPreconditions.CheckState(streamingWriteTcs == null, "Only one write can be pending at a time.");
if (cancelRequested)
{
// Return a cancelled task.
var tcs = new TaskCompletionSource<object>();
tcs.SetCanceled();
return tcs.Task;
}
return null;
}
private void Initialize(CompletionQueueSafeHandle cq) private void Initialize(CompletionQueueSafeHandle cq)
{ {
using (Profilers.ForCurrentThread().NewScope("AsyncCall.Initialize")) using (Profilers.ForCurrentThread().NewScope("AsyncCall.Initialize"))
@ -368,7 +406,7 @@ namespace Grpc.Core.Internal
var credentials = details.Options.Credentials; var credentials = details.Options.Credentials;
using (var nativeCredentials = credentials != null ? credentials.ToNativeCredentials() : null) using (var nativeCredentials = credentials != null ? credentials.ToNativeCredentials() : null)
{ {
var result = details.Channel.Handle.CreateCall(environment.CompletionRegistry, var result = details.Channel.Handle.CreateCall(
parentCall, ContextPropagationToken.DefaultMask, cq, parentCall, ContextPropagationToken.DefaultMask, cq,
details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value), nativeCredentials); details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value), nativeCredentials);
return result; return result;
@ -400,6 +438,7 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
private void HandleReceivedResponseHeaders(bool success, Metadata responseHeaders) private void HandleReceivedResponseHeaders(bool success, Metadata responseHeaders)
{ {
// TODO(jtattermusch): handle success==false
responseHeadersTcs.SetResult(responseHeaders); responseHeadersTcs.SetResult(responseHeaders);
} }
@ -443,19 +482,6 @@ namespace Grpc.Core.Internal
} }
} }
protected override void CheckSendingAllowed(bool allowFinished)
{
base.CheckSendingAllowed(true);
// throwing RpcException if we already received status on client
// side makes the most sense.
// Note that this throws even for StatusCode.OK.
if (!allowFinished && finishedStatus.HasValue)
{
throw new RpcException(finishedStatus.Value.Status);
}
}
/// <summary> /// <summary>
/// Handles receive status completion for calls with streaming response. /// Handles receive status completion for calls with streaming response.
/// </summary> /// </summary>

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

Loading…
Cancel
Save