Merge github.com:grpc/grpc into poffy

pull/4238/head
Craig Tiller 9 years ago
commit 8032828dff
  1. 29
      BUILD
  2. 15864
      Makefile
  3. 38
      README.md
  4. 4
      binding.gyp
  5. 198
      build.yaml
  6. 2
      doc/PROTOCOL-HTTP2.md
  7. 289
      doc/grpc-auth-support.md
  8. 28
      examples/cpp/helloworld/README.md
  9. 2
      examples/objective-c/auth_sample/AuthTestService.podspec
  10. 1
      examples/objective-c/auth_sample/Podfile
  11. 2
      examples/objective-c/helloworld/HelloWorld.podspec
  12. 1
      examples/objective-c/helloworld/Podfile
  13. 1
      examples/objective-c/route_guide/Podfile
  14. 2
      examples/objective-c/route_guide/RouteGuide.podspec
  15. 14
      gRPC.podspec
  16. 13
      include/grpc++/client_context.h
  17. 7
      include/grpc++/impl/rpc_service_method.h
  18. 25
      include/grpc++/impl/server_builder_option.h
  19. 11
      include/grpc++/security/credentials.h
  20. 23
      include/grpc++/server.h
  21. 6
      include/grpc++/server_builder.h
  22. 5
      include/grpc++/support/channel_arguments.h
  23. 6
      include/grpc/compression.h
  24. 5
      include/grpc/grpc.h
  25. 177
      include/grpc/grpc_security.h
  26. 14
      include/grpc/support/alloc.h
  27. 8
      include/grpc/support/cmdline.h
  28. 9
      include/grpc/support/port_platform.h
  29. 4
      include/grpc/support/time.h
  30. 5
      package.json
  31. 8
      src/core/census/context.h
  32. 6
      src/core/census/grpc_filter.c
  33. 17
      src/core/channel/client_channel.c
  34. 4
      src/core/channel/compress_filter.c
  35. 4
      src/core/channel/http_client_filter.c
  36. 3
      src/core/channel/http_server_filter.c
  37. 118
      src/core/channel/noop_filter.c
  38. 4
      src/core/channel/subchannel_call_holder.c
  39. 14
      src/core/client_config/lb_policies/pick_first.c
  40. 18
      src/core/client_config/lb_policies/round_robin.c
  41. 5
      src/core/client_config/lb_policy.c
  42. 6
      src/core/client_config/lb_policy.h
  43. 1
      src/core/client_config/resolvers/dns_resolver.c
  44. 3
      src/core/client_config/resolvers/sockaddr_resolver.c
  45. 7
      src/core/client_config/resolvers/zookeeper_resolver.c
  46. 11
      src/core/client_config/subchannel.c
  47. 3
      src/core/client_config/subchannel.h
  48. 86
      src/core/client_config/subchannel_factory_decorators/merge_channel_args.c
  49. 46
      src/core/client_config/subchannel_factory_decorators/merge_channel_args.h
  50. 24
      src/core/compression/algorithm.c
  51. 28
      src/core/compression/message_compress.c
  52. 9
      src/core/httpcli/httpcli.c
  53. 2
      src/core/httpcli/httpcli.h
  54. 5
      src/core/httpcli/httpcli_security_connector.c
  55. 3
      src/core/iomgr/endpoint_pair_posix.c
  56. 17
      src/core/iomgr/fd_posix.c
  57. 4
      src/core/iomgr/fd_posix.h
  58. 1
      src/core/iomgr/iomgr.c
  59. 22
      src/core/iomgr/pollset_multipoller_with_epoll.c
  60. 19
      src/core/iomgr/pollset_multipoller_with_poll_posix.c
  61. 38
      src/core/iomgr/pollset_posix.c
  62. 6
      src/core/iomgr/pollset_posix.h
  63. 4
      src/core/iomgr/tcp_client_posix.c
  64. 16
      src/core/iomgr/tcp_posix.c
  65. 6
      src/core/iomgr/tcp_posix.h
  66. 20
      src/core/iomgr/tcp_server_posix.c
  67. 8
      src/core/iomgr/tcp_server_windows.c
  68. 14
      src/core/iomgr/tcp_windows.c
  69. 12
      src/core/iomgr/timer.c
  70. 2
      src/core/iomgr/timer_internal.h
  71. 4
      src/core/iomgr/udp_server.c
  72. 8
      src/core/iomgr/wakeup_fd_posix.c
  73. 2
      src/core/iomgr/wakeup_fd_posix.h
  74. 5
      src/core/iomgr/workqueue_posix.c
  75. 15
      src/core/json/json_reader.c
  76. 2
      src/core/json/json_string.c
  77. 7
      src/core/profiling/basic_timers.c
  78. 54
      src/core/security/client_auth_filter.c
  79. 103
      src/core/security/credentials.c
  80. 22
      src/core/security/credentials.h
  81. 2
      src/core/security/credentials_posix.c
  82. 2
      src/core/security/credentials_win32.c
  83. 15
      src/core/security/google_default_credentials.c
  84. 49
      src/core/security/handshake.c
  85. 2
      src/core/security/handshake.h
  86. 4
      src/core/security/json_token.c
  87. 27
      src/core/security/security_connector.c
  88. 14
      src/core/security/security_connector.h
  89. 78
      src/core/security/server_secure_chttp2.c
  90. 2
      src/core/statistics/window_stats.c
  91. 20
      src/core/support/alloc.c
  92. 62
      src/core/support/cmdline.c
  93. 3
      src/core/support/log.c
  94. 4
      src/core/support/log_linux.c
  95. 4
      src/core/support/log_posix.c
  96. 4
      src/core/support/log_win32.c
  97. 7
      src/core/support/slice.c
  98. 8
      src/core/support/stack_lockfree.c
  99. 29
      src/core/support/string.c
  100. 10
      src/core/support/string.h
  101. Some files were not shown because too many files have changed in this diff Show More

29
BUILD

@ -161,7 +161,6 @@ cc_library(
"src/core/channel/context.h",
"src/core/channel/http_client_filter.h",
"src/core/channel/http_server_filter.h",
"src/core/channel/noop_filter.h",
"src/core/channel/subchannel_call_holder.h",
"src/core/client_config/client_config.h",
"src/core/client_config/connector.h",
@ -178,8 +177,6 @@ cc_library(
"src/core/client_config/resolvers/sockaddr_resolver.h",
"src/core/client_config/subchannel.h",
"src/core/client_config/subchannel_factory.h",
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
@ -301,7 +298,6 @@ cc_library(
"src/core/channel/connected_channel.c",
"src/core/channel/http_client_filter.c",
"src/core/channel/http_server_filter.c",
"src/core/channel/noop_filter.c",
"src/core/channel/subchannel_call_holder.c",
"src/core/client_config/client_config.c",
"src/core/client_config/connector.c",
@ -319,8 +315,6 @@ cc_library(
"src/core/client_config/resolvers/sockaddr_resolver.c",
"src/core/client_config/subchannel.c",
"src/core/client_config/subchannel_factory.c",
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.c",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.c",
"src/core/client_config/uri_parser.c",
"src/core/compression/algorithm.c",
"src/core/compression/message_compress.c",
@ -381,6 +375,7 @@ cc_library(
"src/core/surface/channel.c",
"src/core/surface/channel_connectivity.c",
"src/core/surface/channel_create.c",
"src/core/surface/channel_ping.c",
"src/core/surface/completion_queue.c",
"src/core/surface/event_string.c",
"src/core/surface/init.c",
@ -457,7 +452,6 @@ cc_library(
"src/core/channel/context.h",
"src/core/channel/http_client_filter.h",
"src/core/channel/http_server_filter.h",
"src/core/channel/noop_filter.h",
"src/core/channel/subchannel_call_holder.h",
"src/core/client_config/client_config.h",
"src/core/client_config/connector.h",
@ -474,8 +468,6 @@ cc_library(
"src/core/client_config/resolvers/sockaddr_resolver.h",
"src/core/client_config/subchannel.h",
"src/core/client_config/subchannel_factory.h",
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",
@ -577,7 +569,6 @@ cc_library(
"src/core/channel/connected_channel.c",
"src/core/channel/http_client_filter.c",
"src/core/channel/http_server_filter.c",
"src/core/channel/noop_filter.c",
"src/core/channel/subchannel_call_holder.c",
"src/core/client_config/client_config.c",
"src/core/client_config/connector.c",
@ -595,8 +586,6 @@ cc_library(
"src/core/client_config/resolvers/sockaddr_resolver.c",
"src/core/client_config/subchannel.c",
"src/core/client_config/subchannel_factory.c",
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.c",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.c",
"src/core/client_config/uri_parser.c",
"src/core/compression/algorithm.c",
"src/core/compression/message_compress.c",
@ -657,6 +646,7 @@ cc_library(
"src/core/surface/channel.c",
"src/core/surface/channel_connectivity.c",
"src/core/surface/channel_create.c",
"src/core/surface/channel_ping.c",
"src/core/surface/completion_queue.c",
"src/core/surface/event_string.c",
"src/core/surface/init.c",
@ -748,14 +738,13 @@ cc_library(
"src/cpp/server/dynamic_thread_pool.h",
"src/cpp/server/fixed_size_thread_pool.h",
"src/cpp/server/thread_pool_interface.h",
"src/cpp/client/secure_channel_arguments.cc",
"src/cpp/client/secure_credentials.cc",
"src/cpp/common/auth_property_iterator.cc",
"src/cpp/common/secure_auth_context.cc",
"src/cpp/common/secure_channel_arguments.cc",
"src/cpp/common/secure_create_auth_context.cc",
"src/cpp/server/secure_server_credentials.cc",
"src/cpp/client/channel.cc",
"src/cpp/client/channel_arguments.cc",
"src/cpp/client/client_context.cc",
"src/cpp/client/create_channel.cc",
"src/cpp/client/create_channel_internal.cc",
@ -763,6 +752,7 @@ cc_library(
"src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/common/call.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/completion_queue.cc",
"src/cpp/common/rpc_method.cc",
"src/cpp/proto/proto_utils.cc",
@ -796,6 +786,7 @@ cc_library(
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
"include/grpc++/impl/serialization_traits.h",
"include/grpc++/impl/server_builder_option.h",
"include/grpc++/impl/service_type.h",
"include/grpc++/impl/sync.h",
"include/grpc++/impl/sync_cxx11.h",
@ -847,7 +838,6 @@ cc_library(
"src/cpp/server/thread_pool_interface.h",
"src/cpp/common/insecure_create_auth_context.cc",
"src/cpp/client/channel.cc",
"src/cpp/client/channel_arguments.cc",
"src/cpp/client/client_context.cc",
"src/cpp/client/create_channel.cc",
"src/cpp/client/create_channel_internal.cc",
@ -855,6 +845,7 @@ cc_library(
"src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/common/call.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/completion_queue.cc",
"src/cpp/common/rpc_method.cc",
"src/cpp/proto/proto_utils.cc",
@ -888,6 +879,7 @@ cc_library(
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
"include/grpc++/impl/serialization_traits.h",
"include/grpc++/impl/server_builder_option.h",
"include/grpc++/impl/service_type.h",
"include/grpc++/impl/sync.h",
"include/grpc++/impl/sync_cxx11.h",
@ -1111,7 +1103,6 @@ objc_library(
"src/core/channel/connected_channel.c",
"src/core/channel/http_client_filter.c",
"src/core/channel/http_server_filter.c",
"src/core/channel/noop_filter.c",
"src/core/channel/subchannel_call_holder.c",
"src/core/client_config/client_config.c",
"src/core/client_config/connector.c",
@ -1129,8 +1120,6 @@ objc_library(
"src/core/client_config/resolvers/sockaddr_resolver.c",
"src/core/client_config/subchannel.c",
"src/core/client_config/subchannel_factory.c",
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.c",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.c",
"src/core/client_config/uri_parser.c",
"src/core/compression/algorithm.c",
"src/core/compression/message_compress.c",
@ -1191,6 +1180,7 @@ objc_library(
"src/core/surface/channel.c",
"src/core/surface/channel_connectivity.c",
"src/core/surface/channel_create.c",
"src/core/surface/channel_ping.c",
"src/core/surface/completion_queue.c",
"src/core/surface/event_string.c",
"src/core/surface/init.c",
@ -1264,7 +1254,6 @@ objc_library(
"src/core/channel/context.h",
"src/core/channel/http_client_filter.h",
"src/core/channel/http_server_filter.h",
"src/core/channel/noop_filter.h",
"src/core/channel/subchannel_call_holder.h",
"src/core/client_config/client_config.h",
"src/core/client_config/connector.h",
@ -1281,8 +1270,6 @@ objc_library(
"src/core/client_config/resolvers/sockaddr_resolver.h",
"src/core/client_config/subchannel.h",
"src/core/client_config/subchannel_factory.h",
"src/core/client_config/subchannel_factory_decorators/add_channel_arg.h",
"src/core/client_config/subchannel_factory_decorators/merge_channel_args.h",
"src/core/client_config/uri_parser.h",
"src/core/compression/algorithm_metadata.h",
"src/core/compression/message_compress.h",

15864
Makefile

File diff suppressed because one or more lines are too long

@ -13,34 +13,28 @@ You can find more detailed documentation and examples in the [doc](doc) and [exa
See grpc/INSTALL for installation instructions for various platforms.
#Repository Structure
#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).
* C++ source code: [src/cpp] (src/cpp)
* Ruby source code: [src/ruby] (src/ruby)
* NodeJS source code: [src/node] (src/node)
* Python source code: [src/python] (src/python)
* PHP source code: [src/php] (src/php)
* C# source code: [src/csharp] (src/csharp)
* Objective-C source code: [src/objective-c] (src/objective-c)
Libraries in different languages are in different state of development. We are seeking contributions for all of these libraries.
| Language | Source | Status |
|-------------------------|-------------------------------------|---------------------------------|
| Shared C [core library] | [src/core] (src/core) | Beta - the surface API is stable |
| C++ | [src/cpp] (src/cpp) | Beta - the surface API is stable |
| Ruby | [src/ruby] (src/ruby) | Beta - the surface API is stable |
| NodeJS | [src/node] (src/node) | Beta - the surface API is stable |
| Python | [src/python] (src/python) | Beta - the surface API is stable |
| PHP | [src/php] (src/php) | Beta - the surface API is stable |
| C# | [src/csharp] (src/csharp) | Beta - the surface API is stable |
| Objective-C | [src/objective-c] (src/objective-c) | Beta - the surface API is stable |
<small>
Java source code is in [grpc-java] (http://github.com/grpc/grpc-java) repository.
Go source code is in [grpc-go] (http://github.com/grpc/grpc-go) repository.
</small>
#Current Status of libraries
Libraries in different languages are in different state of development. We are seeking contributions for all of these libraries.
* shared C core library [src/core] (src/core) : Beta - the surface API is stable
* C++ Library: [src/cpp] (src/cpp) : Beta - the surface API is stable
* Ruby Library: [src/ruby] (src/ruby) : Beta - the surface API is stable
* NodeJS Library: [src/node] (src/node) : Beta - the surface API is stable
* Python Library: [src/python] (src/python) : Beta - the surface API is stable
* C# Library: [src/csharp] (src/csharp) : Beta - the surface API is stable
* Objective-C Library: [src/objective-c] (src/objective-c): Beta - the surface API is stable
* PHP Library: [src/php] (src/php) : Beta - the surface API is stable
#Overview

@ -183,7 +183,6 @@
'src/core/channel/connected_channel.c',
'src/core/channel/http_client_filter.c',
'src/core/channel/http_server_filter.c',
'src/core/channel/noop_filter.c',
'src/core/channel/subchannel_call_holder.c',
'src/core/client_config/client_config.c',
'src/core/client_config/connector.c',
@ -201,8 +200,6 @@
'src/core/client_config/resolvers/sockaddr_resolver.c',
'src/core/client_config/subchannel.c',
'src/core/client_config/subchannel_factory.c',
'src/core/client_config/subchannel_factory_decorators/add_channel_arg.c',
'src/core/client_config/subchannel_factory_decorators/merge_channel_args.c',
'src/core/client_config/uri_parser.c',
'src/core/compression/algorithm.c',
'src/core/compression/message_compress.c',
@ -263,6 +260,7 @@
'src/core/surface/channel.c',
'src/core/surface/channel_connectivity.c',
'src/core/surface/channel_create.c',
'src/core/surface/channel_ping.c',
'src/core/surface/completion_queue.c',
'src/core/surface/event_string.c',
'src/core/surface/init.c',

@ -37,6 +37,7 @@ filegroups:
- include/grpc++/impl/rpc_method.h
- include/grpc++/impl/rpc_service_method.h
- include/grpc++/impl/serialization_traits.h
- include/grpc++/impl/server_builder_option.h
- include/grpc++/impl/service_type.h
- include/grpc++/impl/sync.h
- include/grpc++/impl/sync_cxx11.h
@ -72,7 +73,6 @@ filegroups:
- src/cpp/server/thread_pool_interface.h
src:
- src/cpp/client/channel.cc
- src/cpp/client/channel_arguments.cc
- src/cpp/client/client_context.cc
- src/cpp/client/create_channel.cc
- src/cpp/client/create_channel_internal.cc
@ -80,6 +80,7 @@ filegroups:
- src/cpp/client/generic_stub.cc
- src/cpp/client/insecure_credentials.cc
- src/cpp/common/call.cc
- src/cpp/common/channel_arguments.cc
- src/cpp/common/completion_queue.cc
- src/cpp/common/rpc_method.cc
- src/cpp/proto/proto_utils.cc
@ -115,7 +116,6 @@ filegroups:
- src/core/channel/context.h
- src/core/channel/http_client_filter.h
- src/core/channel/http_server_filter.h
- src/core/channel/noop_filter.h
- src/core/channel/subchannel_call_holder.h
- src/core/client_config/client_config.h
- src/core/client_config/connector.h
@ -132,8 +132,6 @@ filegroups:
- src/core/client_config/resolvers/sockaddr_resolver.h
- src/core/client_config/subchannel.h
- src/core/client_config/subchannel_factory.h
- src/core/client_config/subchannel_factory_decorators/add_channel_arg.h
- src/core/client_config/subchannel_factory_decorators/merge_channel_args.h
- src/core/client_config/uri_parser.h
- src/core/compression/algorithm_metadata.h
- src/core/compression/message_compress.h
@ -232,7 +230,6 @@ filegroups:
- src/core/channel/connected_channel.c
- src/core/channel/http_client_filter.c
- src/core/channel/http_server_filter.c
- src/core/channel/noop_filter.c
- src/core/channel/subchannel_call_holder.c
- src/core/client_config/client_config.c
- src/core/client_config/connector.c
@ -250,8 +247,6 @@ filegroups:
- src/core/client_config/resolvers/sockaddr_resolver.c
- src/core/client_config/subchannel.c
- src/core/client_config/subchannel_factory.c
- src/core/client_config/subchannel_factory_decorators/add_channel_arg.c
- src/core/client_config/subchannel_factory_decorators/merge_channel_args.c
- src/core/client_config/uri_parser.c
- src/core/compression/algorithm.c
- src/core/compression/message_compress.c
@ -312,6 +307,7 @@ filegroups:
- src/core/surface/channel.c
- src/core/surface/channel_connectivity.c
- src/core/surface/channel_create.c
- src/core/surface/channel_ping.c
- src/core/surface/completion_queue.c
- src/core/surface/event_string.c
- src/core/surface/init.c
@ -354,7 +350,6 @@ filegroups:
- test/core/end2end/cq_verifier.h
- test/core/end2end/fixtures/proxy.h
- test/core/iomgr/endpoint_tests.h
- test/core/security/oauth2_utils.h
- test/core/util/grpc_profiler.h
- test/core/util/parse_hexstring.h
- test/core/util/port.h
@ -363,7 +358,6 @@ filegroups:
- test/core/end2end/cq_verifier.c
- test/core/end2end/fixtures/proxy.c
- test/core/iomgr/endpoint_tests.c
- test/core/security/oauth2_utils.c
- test/core/util/grpc_profiler.c
- test/core/util/parse_hexstring.c
- test/core/util/port_posix.c
@ -526,10 +520,12 @@ libs:
language: c
headers:
- test/core/end2end/data/ssl_test_data.h
- test/core/security/oauth2_utils.h
src:
- test/core/end2end/data/server1_cert.c
- test/core/end2end/data/server1_key.c
- test/core/end2end/data/test_root_cert.c
- test/core/security/oauth2_utils.c
deps:
- gpr
- gpr_test_util
@ -543,7 +539,7 @@ libs:
deps:
- gpr
- gpr_test_util
- grpc
- grpc_unsecure
filegroups:
- grpc_test_util_base
secure: false
@ -612,10 +608,10 @@ libs:
- src/cpp/common/secure_auth_context.h
- src/cpp/server/secure_server_credentials.h
src:
- src/cpp/client/secure_channel_arguments.cc
- src/cpp/client/secure_credentials.cc
- src/cpp/common/auth_property_iterator.cc
- src/cpp/common/secure_auth_context.cc
- src/cpp/common/secure_channel_arguments.cc
- src/cpp/common/secure_create_auth_context.cc
- src/cpp/server/secure_server_credentials.cc
deps:
@ -814,6 +810,24 @@ libs:
- winsock
- global
targets:
- name: algorithm_test
build: test
language: c
src:
- test/core/compression/algorithm_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: alloc_test
build: test
language: c
src:
- test/core/support/alloc_test.c
deps:
- gpr_test_util
- gpr
- name: alpn_test
build: test
language: c
@ -834,6 +848,16 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: channel_create_test
build: test
language: c
src:
- test/core/surface/channel_create_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: chttp2_hpack_encoder_test
build: test
language: c
@ -864,6 +888,16 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: chttp2_varint_test
build: test
language: c
src:
- test/core/transport/chttp2/varint_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: compression_test
build: test
language: c
@ -874,6 +908,16 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: dns_resolver_test
build: test
language: c
src:
- test/core/client_config/resolvers/dns_resolver_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: dualstack_socket_test
build: test
language: c
@ -1216,6 +1260,16 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: grpc_invalid_channel_args_test
build: test
language: c
src:
- test/core/surface/invalid_channel_args_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: grpc_json_token_test
build: test
language: c
@ -1324,6 +1378,38 @@ targets:
- mac
- linux
- posix
- name: httpscli_test
build: test
language: c
src:
- test/core/httpcli/httpscli_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
platforms:
- linux
- name: init_test
build: test
language: c
src:
- test/core/surface/init_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: invalid_call_argument_test
build: test
language: c
src:
- test/core/end2end/invalid_call_argument_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: json_rewrite
build: test
run: false
@ -1343,6 +1429,16 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: json_stream_error_test
build: test
language: c
src:
- test/core/json/json_stream_error_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: json_test
build: test
language: c
@ -1397,16 +1493,6 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: multi_init_test
build: test
language: c
src:
- test/core/surface/multi_init_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: multiple_server_queues_test
build: test
language: c
@ -1445,6 +1531,16 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: secure_channel_create_test
build: test
language: c
src:
- test/core/surface/secure_channel_create_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: secure_endpoint_test
build: test
language: c
@ -1455,6 +1551,26 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: server_chttp2_test
build: test
language: c
src:
- test/core/surface/server_chttp2_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: server_test
build: test
language: c
src:
- test/core/surface/server_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: set_initial_connect_string_test
build: test
language: c
@ -1466,6 +1582,16 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: sockaddr_resolver_test
build: test
language: c
src:
- test/core/client_config/resolvers/sockaddr_resolver_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: sockaddr_utils_test
build: test
language: c
@ -1476,6 +1602,20 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: socket_utils_test
build: test
language: c
src:
- test/core/iomgr/socket_utils_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
platforms:
- mac
- linux
- posix
- name: tcp_client_posix_test
build: test
language: c
@ -1568,6 +1708,16 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: transport_connectivity_state_test
build: test
language: c
src:
- test/core/transport/connectivity_state_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: transport_metadata_test
build: test
language: c
@ -1692,7 +1842,7 @@ targets:
build: test
language: c++
src:
- test/cpp/client/channel_arguments_test.cc
- test/cpp/common/channel_arguments_test.cc
deps:
- grpc++
- grpc
@ -2269,11 +2419,11 @@ vspackages:
name: grpc.dependencies.zlib
props: false
redist: true
version: 1.2.8.9
version: 1.2.8.10
- name: grpc.dependencies.openssl
props: true
redist: true
version: 1.0.2.3
version: 1.0.204.1
- name: gflags
props: false
redist: false

@ -45,7 +45,7 @@ Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames.
* **Custom-Metadata** → Binary-Header / ASCII-Header
* **Binary-Header** → {Header-Name "-bin" } {_base64 encoded value_}
* **ASCII-Header** → Header-Name ASCII-Value
* **Header-Name** → 1\*( %x30-39 / %x61-7A / "\_" / "-") ; 0-9 a-z \_ -
* **Header-Name** → 1\*( %x30-39 / %x61-7A / "\_" / "-" / ".") ; 0-9 a-z \_ - .
* **ASCII-Value** → 1\*( %x20-%x7E ) ; space and printable ASCII

@ -1,289 +0,0 @@
#gRPC Authentication support
gRPC is designed to plug-in a number of authentication mechanisms. This document
provides a quick overview of the various auth mechanisms supported, discusses
the API with some examples, and concludes with a discussion of extensibility.
More documentation and examples are coming soon!
## Supported auth mechanisms
###SSL/TLS
gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the
server, and encrypt all the data exchanged between the client and the server.
Optional mechanisms are available for clients to provide certificates to
accomplish mutual authentication.
###OAuth 2.0
gRPC provides a generic mechanism (described below) to attach metadata to
requests and responses. This mechanism can be used to attach OAuth 2.0 Access
Tokens to RPCs being made at a client. Additional support for acquiring Access
Tokens while accessing Google APIs through gRPC is provided for certain auth
flows, demonstrated through code examples below.
## API
To reduce complexity and minimize API clutter, gRPC works with a unified concept
of a Credentials object. Users construct gRPC credentials using corresponding
bootstrap credentials (e.g., SSL client certs or Service Account Keys), and use
the credentials while creating a gRPC channel to any server. Depending on the
type of credential supplied, the channel uses the credentials during the initial
SSL/TLS handshake with the server, or uses the credential to generate and
attach Access Tokens to each request being made on the channel.
###SSL/TLS for server authentication and encryption
This is the simplest authentication scenario, where a client just wants to
authenticate the server and encrypt all data.
```cpp
SslCredentialsOptions ssl_opts; // Options to override SSL params, empty by default
// Create the credentials object by providing service account key in constructor
std::shared_ptr<ChannelCredentials> creds = SslCredentials(ssl_opts);
// Create a channel using the credentials created in the previous step
std::shared_ptr<Channel> channel = CreateChannel(server_name, creds);
// Create a stub on the channel
std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
// Make actual RPC calls on the stub.
grpc::Status s = stub->sayHello(&context, *request, response);
```
For advanced use cases such as modifying the root CA or using client certs,
the corresponding options can be set in the SslCredentialsOptions parameter
passed to the factory method.
###Authenticating with Google
gRPC applications can use a simple API to create a credential that works in various deployment scenarios.
```cpp
std::shared_ptr<ChannelCredentials> creds = GoogleDefaultCredentials();
// Create a channel, stub and make RPC calls (same as in the previous example)
std::shared_ptr<Channel> channel = CreateChannel(server_name, creds);
std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
grpc::Status s = stub->sayHello(&context, *request, response);
```
This credential works for applications using Service Accounts as well as for
applications running in [Google Compute Engine (GCE)](https://cloud.google.com/compute/). In the former case, the
service account’s private keys are loaded from the file named in the environment
variable `GOOGLE_APPLICATION_CREDENTIALS`. The
keys are used to generate bearer tokens that are attached to each outgoing RPC
on the corresponding channel.
For applications running in GCE, a default service account and corresponding
OAuth scopes can be configured during VM setup. At run-time, this credential
handles communication with the authentication systems to obtain OAuth2 access
tokens and attaches them to each outgoing RPC on the corresponding channel.
Extending gRPC to support other authentication mechanisms
The gRPC protocol is designed with a general mechanism for sending metadata
associated with RPC. Clients can send metadata at the beginning of an RPC and
servers can send back metadata at the beginning and end of the RPC. This
provides a natural mechanism to support OAuth2 and other authentication
mechanisms that need attach bearer tokens to individual request.
In the simplest case, there is a single line of code required on the client
to add a specific token as metadata to an RPC and a corresponding access on
the server to retrieve this piece of metadata. The generation of the token
on the client side and its verification at the server can be done separately.
A deeper integration can be achieved by plugging in a gRPC credentials implementation for any custom authentication mechanism that needs to attach per-request tokens. gRPC internals also allow switching out SSL/TLS with other encryption mechanisms.
## Examples
These authentication mechanisms will be available in all gRPC's supported languages.
The following sections demonstrate how authentication and authorization features described above appear in each language: more languages are coming soon.
###SSL/TLS for server authentication and encryption (Ruby)
```ruby
# Base case - No encryption
stub = Helloworld::Greeter::Stub.new('localhost:50051')
...
# With server authentication SSL/TLS
creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file
stub = Helloworld::Greeter::Stub.new('localhost:50051', creds: creds)
```
###SSL/TLS for server authentication and encryption (C#)
```csharp
// Base case - No encryption
var channel = new Channel("localhost:50051");
var client = new Greeter.GreeterClient(channel);
...
// With server authentication SSL/TLS
var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file
var channel = new Channel("localhost:50051", credentials);
var client = new Greeter.GreeterClient(channel);
```
###SSL/TLS for server authentication and encryption (Objective-C)
The default for Objective-C is to use SSL/TLS, as that's the most common use case when accessing
remote APIs.
```objective-c
// Base case - With server authentication SSL/TLS
HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"localhost:50051"];
// Same as using @"https://localhost:50051".
...
// No encryption
HLWGreeter *client = [[HLWGreeter alloc] initWithHost:@"http://localhost:50051"];
// Specifying the HTTP scheme explicitly forces no encryption.
```
###SSL/TLS for server authentication and encryption (Python)
```python
# Base case - No encryption
stub = early_adopter_create_GreeterService_stub('localhost', 50051)
...
# With server authentication SSL/TLS
stub = early_adopter_create_GreeterService_stub(
'localhost', 50051, secure=True, root_certificates=open('ca.pem').read())
...
```
n.b.: the beta API will look different
###Authenticating with Google (Ruby)
```ruby
# Base case - No encryption/authorization
stub = Helloworld::Greeter::Stub.new('localhost:50051')
...
# Authenticating with Google
require 'googleauth' # from http://www.rubydoc.info/gems/googleauth/0.1.0
...
creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a CA roots file
scope = 'https://www.googleapis.com/auth/grpc-testing'
authorization = Google::Auth.get_application_default(scope)
stub = Helloworld::Greeter::Stub.new('localhost:50051',
creds: creds,
update_metadata: authorization.updater_proc)
```
###Authenticating with Google (Node.js)
```node
// Base case - No encryption/authorization
var stub = new helloworld.Greeter('localhost:50051');
...
// Authenticating with Google
var GoogleAuth = require('google-auth-library'); // from https://www.npmjs.com/package/google-auth-library
...
var creds = grpc.Credentials.createSsl(load_certs); // load_certs typically loads a CA roots file
var scope = 'https://www.googleapis.com/auth/grpc-testing';
(new GoogleAuth()).getApplicationDefault(function(err, auth) {
if (auth.createScopeRequired()) {
auth = auth.createScoped(scope);
}
var stub = new helloworld.Greeter('localhost:50051',
{credentials: creds},
grpc.getGoogleAuthDelegate(auth));
});
```
###Authenticating with Google (C#)
```csharp
// Base case - No encryption/authorization
var channel = new Channel("localhost:50051");
var client = new Greeter.GreeterClient(channel);
...
// Authenticating with Google
using Grpc.Auth; // from Grpc.Auth NuGet package
...
var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file
var channel = new Channel("localhost:50051", credentials);
string scope = "https://www.googleapis.com/auth/grpc-testing";
var authorization = GoogleCredential.GetApplicationDefault();
if (authorization.IsCreateScopedRequired)
{
authorization = credential.CreateScoped(new[] { scope });
}
var client = new Greeter.GreeterClient(channel,
new StubConfiguration(OAuth2InterceptorFactory.Create(credential)));
```
###Authenticating with Google (PHP)
```php
// Base case - No encryption/authorization
$client = new helloworld\GreeterClient(
new Grpc\BaseStub('localhost:50051', []));
...
// Authenticating with Google
// the environment variable "GOOGLE_APPLICATION_CREDENTIALS" needs to be set
$scope = "https://www.googleapis.com/auth/grpc-testing";
$auth = Google\Auth\ApplicationDefaultCredentials::getCredentials($scope);
$opts = [
'credentials' => Grpc\Credentials::createSsl(file_get_contents('ca.pem'));
'update_metadata' => $auth->getUpdateMetadataFunc(),
];
$client = new helloworld\GreeterClient(
new Grpc\BaseStub('localhost:50051', $opts));
```
###Authenticating with Google (Objective-C)
This example uses the [Google iOS Sign-In library](https://developers.google.com/identity/sign-in/ios/),
but it's easily extrapolated to any other OAuth2 library.
```objective-c
// Base case - No authentication
[client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
...
}];
...
// Authenticating with Google
// When signing the user in, ask her for the relevant scopes.
GIDSignIn.sharedInstance.scopes = @[@"https://www.googleapis.com/auth/grpc-testing"];
...
#import <ProtoRPC/ProtoRPC.h>
// Create a not-yet-started RPC. We want to set the request headers on this object before starting
// it.
ProtoRPC *call =
[client RPCToSayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
...
}];
// Set the access token to be used.
NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken;
call.requestMetadata[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]}];
// Start the RPC.
[call start];
```
You can see a working example app, with a more detailed explanation, [here](examples/objective-c/auth_sample).
### Authenticating with Google (Python)
```python
# Base case - No encryption
stub = early_adopter_create_GreeterService_stub('localhost', 50051)
...
# With server authentication SSL/TLS
import oauth2client.client
credentials = oauth2client.GoogleCredentials.get_application_default()
scope = 'https://www.googleapis.com/auth/grpc-testing'
scoped_credentials = credentials.create_scoped([scope])
access_token = scoped_credentials.get_access_token().access_token
metadata_transformer = (
lambda x: [('Authorization', 'Bearer {}'.format(access_token))])
stub = early_adopter_create_GreeterService_stub(
'localhost', 50051, secure=True, root_certificates=open('ca.pem').read(),
metadata_transformer=metadata_transformer)
...
```
n.b.: the beta API will look different

@ -41,7 +41,7 @@ message from the remote client containing the user's name, then send back
a greeting in a single `HelloReply`. This is the simplest type of RPC you
can specify in gRPC - we'll look at some other types later in this document.
```
```protobuf
syntax = "proto3";
option java_package = "ex.grpc";
@ -93,20 +93,20 @@ $ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto
channel can be created with the target address, credentials to use and
arguments as follows
```
```cpp
auto channel = CreateChannel("localhost:50051", InsecureChannelCredentials());
```
- Create a stub. A stub implements the rpc methods of a service and in the
generated code, a method is provided to created a stub with a channel:
```
```cpp
auto stub = helloworld::Greeter::NewStub(channel);
```
- Make a unary rpc, with `ClientContext` and request/response proto messages.
```
```cpp
ClientContext context;
HelloRequest request;
request.set_name("hello");
@ -116,7 +116,7 @@ $ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto
- Check returned status and response.
```
```cpp
if (status.ok()) {
// check reply.message()
} else {
@ -130,7 +130,7 @@ For a working example, refer to [greeter_client.cc](greeter_client.cc).
- Implement the service interface
```
```cpp
class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
@ -144,7 +144,7 @@ For a working example, refer to [greeter_client.cc](greeter_client.cc).
- Build a server exporting the service
```
```cpp
GreeterServiceImpl service;
ServerBuilder builder;
builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials());
@ -170,14 +170,14 @@ The channel and stub creation code is the same as the sync client.
- Initiate the rpc and create a handle for the rpc. Bind the rpc to a
`CompletionQueue`.
```
```cpp
CompletionQueue cq;
auto rpc = stub->AsyncSayHello(&context, request, &cq);
```
- Ask for reply and final status, with a unique tag
```
```cpp
Status status;
rpc->Finish(&reply, &status, (void*)1);
```
@ -185,7 +185,7 @@ The channel and stub creation code is the same as the sync client.
- Wait for the completion queue to return the next tag. The reply and status are
ready once the tag passed into the corresponding `Finish()` call is returned.
```
```cpp
void* got_tag;
bool ok = false;
cq.Next(&got_tag, &ok);
@ -203,7 +203,7 @@ completion queue to return the tag. The basic flow is
- Build a server exporting the async service
```
```cpp
helloworld::Greeter::AsyncService service;
ServerBuilder builder;
builder.AddListeningPort("0.0.0.0:50051", InsecureServerCredentials());
@ -214,7 +214,7 @@ completion queue to return the tag. The basic flow is
- Request one rpc
```
```cpp
ServerContext context;
HelloRequest request;
ServerAsyncResponseWriter<HelloReply> responder;
@ -224,7 +224,7 @@ completion queue to return the tag. The basic flow is
- Wait for the completion queue to return the tag. The context, request and
responder are ready once the tag is retrieved.
```
```cpp
HelloReply reply;
Status status;
void* got_tag;
@ -239,7 +239,7 @@ completion queue to return the tag. The basic flow is
- Wait for the completion queue to return the tag. The rpc is finished when the
tag is back.
```
```cpp
void* got_tag;
bool ok = false;
cq.Next(&got_tag, &ok);

@ -29,7 +29,7 @@ Pod::Spec.new do |s|
ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}"
ss.header_mappings_dir = dir
ss.requires_arc = true
ss.dependency "gRPC", "~> 0.11"
ss.dependency "gRPC", "~> 0.12"
ss.dependency "#{s.name}/Messages"
end
end

@ -2,6 +2,7 @@ source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'Protobuf', :path => "../../../third_party/protobuf"
pod 'BoringSSL', :podspec => "../../../src/objective-c"
pod 'gRPC', :path => "../../.."
target 'AuthSample' do

@ -29,7 +29,7 @@ Pod::Spec.new do |s|
ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}"
ss.header_mappings_dir = dir
ss.requires_arc = true
ss.dependency "gRPC", "~> 0.11"
ss.dependency "gRPC", "~> 0.12"
ss.dependency "#{s.name}/Messages"
end
end

@ -2,6 +2,7 @@ source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'Protobuf', :path => "../../../third_party/protobuf"
pod 'BoringSSL', :podspec => "../../../src/objective-c"
pod 'gRPC', :path => "../../.."
target 'HelloWorld' do

@ -3,6 +3,7 @@ platform :ios, '8.0'
target 'RouteGuideClient' do
pod 'Protobuf', :path => "../../../third_party/protobuf"
pod 'BoringSSL', :podspec => "../../../src/objective-c"
pod 'gRPC', :path => "../../.."
# Depend on the generated RouteGuide library.
pod 'RouteGuide', :path => '.'

@ -29,7 +29,7 @@ Pod::Spec.new do |s|
ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}"
ss.header_mappings_dir = dir
ss.requires_arc = true
ss.dependency "gRPC", "~> 0.11"
ss.dependency "gRPC", "~> 0.12"
ss.dependency "#{s.name}/Messages"
end
end

@ -36,7 +36,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
version = '0.11.2'
version = '0.12.0'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'http://www.grpc.io'
@ -165,7 +165,6 @@ Pod::Spec.new do |s|
'src/core/channel/context.h',
'src/core/channel/http_client_filter.h',
'src/core/channel/http_server_filter.h',
'src/core/channel/noop_filter.h',
'src/core/channel/subchannel_call_holder.h',
'src/core/client_config/client_config.h',
'src/core/client_config/connector.h',
@ -182,8 +181,6 @@ Pod::Spec.new do |s|
'src/core/client_config/resolvers/sockaddr_resolver.h',
'src/core/client_config/subchannel.h',
'src/core/client_config/subchannel_factory.h',
'src/core/client_config/subchannel_factory_decorators/add_channel_arg.h',
'src/core/client_config/subchannel_factory_decorators/merge_channel_args.h',
'src/core/client_config/uri_parser.h',
'src/core/compression/algorithm_metadata.h',
'src/core/compression/message_compress.h',
@ -312,7 +309,6 @@ Pod::Spec.new do |s|
'src/core/channel/connected_channel.c',
'src/core/channel/http_client_filter.c',
'src/core/channel/http_server_filter.c',
'src/core/channel/noop_filter.c',
'src/core/channel/subchannel_call_holder.c',
'src/core/client_config/client_config.c',
'src/core/client_config/connector.c',
@ -330,8 +326,6 @@ Pod::Spec.new do |s|
'src/core/client_config/resolvers/sockaddr_resolver.c',
'src/core/client_config/subchannel.c',
'src/core/client_config/subchannel_factory.c',
'src/core/client_config/subchannel_factory_decorators/add_channel_arg.c',
'src/core/client_config/subchannel_factory_decorators/merge_channel_args.c',
'src/core/client_config/uri_parser.c',
'src/core/compression/algorithm.c',
'src/core/compression/message_compress.c',
@ -392,6 +386,7 @@ Pod::Spec.new do |s|
'src/core/surface/channel.c',
'src/core/surface/channel_connectivity.c',
'src/core/surface/channel_create.c',
'src/core/surface/channel_ping.c',
'src/core/surface/completion_queue.c',
'src/core/surface/event_string.c',
'src/core/surface/init.c',
@ -467,7 +462,6 @@ Pod::Spec.new do |s|
'src/core/channel/context.h',
'src/core/channel/http_client_filter.h',
'src/core/channel/http_server_filter.h',
'src/core/channel/noop_filter.h',
'src/core/channel/subchannel_call_holder.h',
'src/core/client_config/client_config.h',
'src/core/client_config/connector.h',
@ -484,8 +478,6 @@ Pod::Spec.new do |s|
'src/core/client_config/resolvers/sockaddr_resolver.h',
'src/core/client_config/subchannel.h',
'src/core/client_config/subchannel_factory.h',
'src/core/client_config/subchannel_factory_decorators/add_channel_arg.h',
'src/core/client_config/subchannel_factory_decorators/merge_channel_args.h',
'src/core/client_config/uri_parser.h',
'src/core/compression/algorithm_metadata.h',
'src/core/compression/message_compress.h',
@ -589,7 +581,7 @@ Pod::Spec.new do |s|
ss.requires_arc = false
ss.libraries = 'z'
ss.dependency 'OpenSSL', '~> 1.0.200'
ss.dependency 'BoringSSL', '~> 1.0'
# ss.compiler_flags = '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w'
end

@ -268,7 +268,7 @@ class ClientContext {
/// \return The call's peer URI.
grpc::string peer() const;
/// Get and set census context
/// Get and set census context.
void set_census_context(struct census_context* ccp) { census_context_ = ccp; }
struct census_context* census_context() const {
return census_context_;
@ -280,6 +280,17 @@ class ClientContext {
/// There is no guarantee the call will be cancelled.
void TryCancel();
/// Global Callbacks
///
/// Can be set exactly once per application to install hooks whenever
/// a client context is constructed and destructed.
class GlobalCallbacks {
public:
virtual void DefaultConstructor(ClientContext* context) = 0;
virtual void Destructor(ClientContext* context) = 0;
};
static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
private:
// Disallow copy and assign.
ClientContext(const ClientContext&);

@ -34,6 +34,7 @@
#ifndef GRPCXX_IMPL_RPC_SERVICE_METHOD_H
#define GRPCXX_IMPL_RPC_SERVICE_METHOD_H
#include <climits>
#include <functional>
#include <map>
#include <memory>
@ -251,7 +252,11 @@ class RpcService {
void AddMethod(RpcServiceMethod* method) { methods_.emplace_back(method); }
RpcServiceMethod* GetMethod(int i) { return methods_[i].get(); }
int GetMethodCount() const { return methods_.size(); }
int GetMethodCount() const {
// On win x64, int is only 32bit
GPR_ASSERT(methods_.size() <= INT_MAX);
return (int)methods_.size();
}
private:
std::vector<std::unique_ptr<RpcServiceMethod>> methods_;

@ -31,16 +31,21 @@
*
*/
#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_DECORATORS_ADD_CHANNEL_ARG_H
#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_DECORATORS_ADD_CHANNEL_ARG_H
#ifndef GRPCXX_IMPL_SERVER_BUILDER_OPTION_H
#define GRPCXX_IMPL_SERVER_BUILDER_OPTION_H
#include "src/core/client_config/subchannel_factory.h"
#include <grpc++/support/channel_arguments.h>
/** Takes a subchannel factory, returns a new one that mutates incoming
channel_args by adding a new argument; ownership of input, arg is retained
by the caller. */
grpc_subchannel_factory *grpc_subchannel_factory_add_channel_arg(
grpc_subchannel_factory *input, const grpc_arg *arg);
namespace grpc {
#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_DECORATORS_ADD_CHANNEL_ARG_H \
*/
/// Interface to pass an option to a \a ServerBuilder.
class ServerBuilderOption {
public:
virtual ~ServerBuilderOption() {}
/// Alter the \a ChannelArguments used to create the gRPC server.
virtual void UpdateArguments(ChannelArguments* args) = 0;
};
} // namespace grpc
#endif // GRPCXX_IMPL_SERVER_BUILDER_OPTION_H

@ -38,6 +38,7 @@
#include <memory>
#include <grpc++/impl/grpc_library.h>
#include <grpc++/security/auth_context.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
#include <grpc++/support/string_ref.h>
@ -206,9 +207,17 @@ class MetadataCredentialsPlugin {
// a different thread from the one processing the call.
virtual bool IsBlocking() const { return true; }
// Type of credentials this plugin is implementing.
virtual const char* GetType() const { return ""; }
// Gets the auth metatada produced by this plugin.
// The fully qualified method name is:
// service_url + "/" + method_name.
// The channel_auth_context contains (among other things), the identity of
// the server.
virtual Status GetMetadata(
grpc::string_ref service_url,
grpc::string_ref service_url, grpc::string_ref method_name,
const AuthContext& channel_auth_context,
std::multimap<grpc::string, grpc::string>* metadata) = 0;
};

@ -37,14 +37,15 @@
#include <list>
#include <memory>
#include <grpc/compression.h>
#include <grpc++/completion_queue.h>
#include <grpc++/impl/call.h>
#include <grpc++/impl/grpc_library.h>
#include <grpc++/impl/sync.h>
#include <grpc++/security/server_credentials.h>
#include <grpc++/support/channel_arguments.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
#include <grpc/compression.h>
struct grpc_server;
@ -56,6 +57,7 @@ class AsyncGenericService;
class RpcService;
class RpcServiceMethod;
class ServerAsyncStreamingInterface;
class ServerContext;
class ThreadPoolInterface;
/// Models a gRPC server.
@ -84,6 +86,23 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
/// call \a Shutdown for this function to ever return.
void Wait();
/// Global Callbacks
///
/// Can be set exactly once per application to install hooks whenever
/// a server event occurs
class GlobalCallbacks {
public:
virtual ~GlobalCallbacks() {}
/// Called before application callback for each synchronous server request
virtual void PreSynchronousRequest(ServerContext* context) = 0;
/// Called after application callback for each synchronous server request
virtual void PostSynchronousRequest(ServerContext* context) = 0;
};
/// Set the global callback object. Can only be called once. Does not take
/// ownership of callbacks, and expects the pointed to object to be alive
/// until all server objects in the process have been destroyed.
static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
private:
friend class AsyncGenericService;
friend class AsynchronousService;
@ -100,7 +119,7 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
/// \param max_message_size Maximum message length that the channel can
/// receive.
Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
int max_message_size, grpc_compression_options compression_options);
int max_message_size, const ChannelArguments& args);
/// Register a service. This call does not take ownership of the service.
/// The service must exist for the lifetime of the Server instance.

@ -37,8 +37,9 @@
#include <memory>
#include <vector>
#include <grpc/compression.h>
#include <grpc++/impl/server_builder_option.h>
#include <grpc++/support/config.h>
#include <grpc/compression.h>
namespace grpc {
@ -98,6 +99,8 @@ class ServerBuilder {
compression_options_ = options;
}
void SetOption(std::unique_ptr<ServerBuilderOption> option);
/// Tries to bind \a server to the given \a addr.
///
/// It can be invoked multiple times.
@ -140,6 +143,7 @@ class ServerBuilder {
int max_message_size_;
grpc_compression_options compression_options_;
std::vector<std::unique_ptr<ServerBuilderOption>> options_;
std::vector<std::unique_ptr<NamedService<RpcService>>> services_;
std::vector<std::unique_ptr<NamedService<AsynchronousService>>>
async_services_;

@ -80,6 +80,11 @@ class ChannelArguments {
// Generic channel argument setters. Only for advanced use cases.
/// Set an integer argument \a value under \a key.
void SetInt(const grpc::string& key, int value);
// Generic channel argument setter. Only for advanced use cases.
/// Set a pointer argument \a value under \a key. Owership is not transferred.
void SetPointer(const grpc::string& key, void* value);
/// Set a textual argument \a value under \a key.
void SetString(const grpc::string& key, const grpc::string& value);

@ -79,12 +79,6 @@ int grpc_compression_algorithm_parse(const char *name, size_t name_length,
int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
char **name);
/** Returns the compression level corresponding to \a algorithm.
*
* It abort()s for unknown algorithms. */
grpc_compression_level grpc_compression_level_for_algorithm(
grpc_compression_algorithm algorithm);
/** Returns the compression algorithm corresponding to \a level.
*
* It abort()s for unknown levels . */

@ -531,6 +531,11 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
const char *method, const char *host,
gpr_timespec deadline, void *reserved);
/** Ping the channels peer (load balanced channels will select one sub-channel
to ping); if the channel is not connected, posts a failed. */
void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq,
void *tag, void *reserved);
/** Pre-register a method/host pair on a channel. */
void *grpc_channel_register_call(grpc_channel *channel, const char *method,
const char *host, void *reserved);

@ -41,6 +41,81 @@
extern "C" {
#endif
/* --- Authentication Context. --- */
#define GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME "transport_security_type"
#define GRPC_SSL_TRANSPORT_SECURITY_TYPE "ssl"
#define GRPC_X509_CN_PROPERTY_NAME "x509_common_name"
#define GRPC_X509_SAN_PROPERTY_NAME "x509_subject_alternative_name"
typedef struct grpc_auth_context grpc_auth_context;
typedef struct grpc_auth_property_iterator {
const grpc_auth_context *ctx;
size_t index;
const char *name;
} grpc_auth_property_iterator;
/* value, if not NULL, is guaranteed to be NULL terminated. */
typedef struct grpc_auth_property {
char *name;
char *value;
size_t value_length;
} grpc_auth_property;
/* Returns NULL when the iterator is at the end. */
const grpc_auth_property *grpc_auth_property_iterator_next(
grpc_auth_property_iterator *it);
/* Iterates over the auth context. */
grpc_auth_property_iterator grpc_auth_context_property_iterator(
const grpc_auth_context *ctx);
/* Gets the peer identity. Returns an empty iterator (first _next will return
NULL) if the peer is not authenticated. */
grpc_auth_property_iterator grpc_auth_context_peer_identity(
const grpc_auth_context *ctx);
/* Finds a property in the context. May return an empty iterator (first _next
will return NULL) if no property with this name was found in the context. */
grpc_auth_property_iterator grpc_auth_context_find_properties_by_name(
const grpc_auth_context *ctx, const char *name);
/* Gets the name of the property that indicates the peer identity. Will return
NULL if the peer is not authenticated. */
const char *grpc_auth_context_peer_identity_property_name(
const grpc_auth_context *ctx);
/* Returns 1 if the peer is authenticated, 0 otherwise. */
int grpc_auth_context_peer_is_authenticated(const grpc_auth_context *ctx);
/* Gets the auth context from the call. Caller needs to call
grpc_auth_context_release on the returned context. */
grpc_auth_context *grpc_call_auth_context(grpc_call *call);
/* Releases the auth context returned from grpc_call_auth_context. */
void grpc_auth_context_release(grpc_auth_context *context);
/* --
The following auth context methods should only be called by a server metadata
processor to set properties extracted from auth metadata.
-- */
/* Add a property. */
void grpc_auth_context_add_property(grpc_auth_context *ctx, const char *name,
const char *value, size_t value_length);
/* Add a C string property. */
void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx,
const char *name,
const char *value);
/* Sets the property name. Returns 1 if successful or 0 in case of failure
(which means that no property with this name exists). */
int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context *ctx,
const char *name);
/* --- grpc_channel_credentials object. ---
A channel credentials object represents a way to authenticate a client on a
@ -165,6 +240,24 @@ typedef void (*grpc_credentials_plugin_metadata_cb)(
void *user_data, const grpc_metadata *creds_md, size_t num_creds_md,
grpc_status_code status, const char *error_details);
/* Context that can be used by metadata credentials plugin in order to create
auth related metadata. */
typedef struct {
/* The fully qualifed service url. */
const char *service_url;
/* The method name of the RPC being called (not fully qualified).
The fully qualified method name can be built from the service_url:
full_qualified_method_name = ctx->service_url + '/' + ctx->method_name. */
const char *method_name;
/* The auth_context of the channel which gives the server's identity. */
const grpc_auth_context *channel_auth_context;
/* Reserved for future use. */
void *reserved;
} grpc_auth_metadata_context;
/* grpc_metadata_credentials plugin is an API user provided structure used to
create grpc_credentials objects that can be set on a channel (composed) or
a call. See grpc_credentials_metadata_create_from_plugin below.
@ -172,11 +265,11 @@ typedef void (*grpc_credentials_plugin_metadata_cb)(
every call in scope for the credentials created from it. */
typedef struct {
/* The implementation of this method has to be non-blocking.
- service_url is the fully qualified URL that the client stack is
connecting to.
- context is the information that can be used by the plugin to create auth
metadata.
- cb is the callback that needs to be called when the metadata is ready.
- user_data needs to be passed as the first parameter of the callback. */
void (*get_metadata)(void *state, const char *service_url,
void (*get_metadata)(void *state, grpc_auth_metadata_context context,
grpc_credentials_plugin_metadata_cb cb, void *user_data);
/* Destroys the plugin state. */
@ -184,6 +277,9 @@ typedef struct {
/* State that will be set as the first parameter of the methods above. */
void *state;
/* Type of credentials that this plugin is implementing. */
const char *type;
} grpc_metadata_credentials_plugin;
/* Creates a credentials object from a plugin. */
@ -239,81 +335,6 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
grpc_call_error grpc_call_set_credentials(grpc_call *call,
grpc_call_credentials *creds);
/* --- Authentication Context. --- */
#define GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME "transport_security_type"
#define GRPC_SSL_TRANSPORT_SECURITY_TYPE "ssl"
#define GRPC_X509_CN_PROPERTY_NAME "x509_common_name"
#define GRPC_X509_SAN_PROPERTY_NAME "x509_subject_alternative_name"
typedef struct grpc_auth_context grpc_auth_context;
typedef struct grpc_auth_property_iterator {
const grpc_auth_context *ctx;
size_t index;
const char *name;
} grpc_auth_property_iterator;
/* value, if not NULL, is guaranteed to be NULL terminated. */
typedef struct grpc_auth_property {
char *name;
char *value;
size_t value_length;
} grpc_auth_property;
/* Returns NULL when the iterator is at the end. */
const grpc_auth_property *grpc_auth_property_iterator_next(
grpc_auth_property_iterator *it);
/* Iterates over the auth context. */
grpc_auth_property_iterator grpc_auth_context_property_iterator(
const grpc_auth_context *ctx);
/* Gets the peer identity. Returns an empty iterator (first _next will return
NULL) if the peer is not authenticated. */
grpc_auth_property_iterator grpc_auth_context_peer_identity(
const grpc_auth_context *ctx);
/* Finds a property in the context. May return an empty iterator (first _next
will return NULL) if no property with this name was found in the context. */
grpc_auth_property_iterator grpc_auth_context_find_properties_by_name(
const grpc_auth_context *ctx, const char *name);
/* Gets the name of the property that indicates the peer identity. Will return
NULL if the peer is not authenticated. */
const char *grpc_auth_context_peer_identity_property_name(
const grpc_auth_context *ctx);
/* Returns 1 if the peer is authenticated, 0 otherwise. */
int grpc_auth_context_peer_is_authenticated(const grpc_auth_context *ctx);
/* Gets the auth context from the call. Caller needs to call
grpc_auth_context_release on the returned context. */
grpc_auth_context *grpc_call_auth_context(grpc_call *call);
/* Releases the auth context returned from grpc_call_auth_context. */
void grpc_auth_context_release(grpc_auth_context *context);
/* --
The following auth context methods should only be called by a server metadata
processor to set properties extracted from auth metadata.
-- */
/* Add a property. */
void grpc_auth_context_add_property(grpc_auth_context *ctx, const char *name,
const char *value, size_t value_length);
/* Add a C string property. */
void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx,
const char *name,
const char *value);
/* Sets the property name. Returns 1 if successful or 0 in case of failure
(which means that no property with this name exists). */
int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context *ctx,
const char *name);
/* --- Auth Metadata Processing --- */
/* Callback function that is called when the metadata processing is done.

@ -40,6 +40,12 @@
extern "C" {
#endif
typedef struct gpr_allocation_functions {
void *(*malloc_fn)(size_t size);
void *(*realloc_fn)(void *ptr, size_t size);
void (*free_fn)(void *ptr);
} gpr_allocation_functions;
/* malloc, never returns NULL */
void *gpr_malloc(size_t size);
/* free */
@ -51,6 +57,14 @@ void *gpr_malloc_aligned(size_t size, size_t alignment_log);
/* free memory allocated by gpr_malloc_aligned */
void gpr_free_aligned(void *ptr);
/** Request the family of allocation functions in \a functions be used. NOTE
* that this request will be honored in a *best effort* basis and that no
* guarantees are made about the default functions (eg, malloc) being called. */
void gpr_set_allocation_functions(gpr_allocation_functions functions);
/** Return the family of allocation functions currently in effect. */
gpr_allocation_functions gpr_get_allocation_functions();
#ifdef __cplusplus
}
#endif

@ -83,8 +83,12 @@ void gpr_cmdline_add_string(gpr_cmdline *cl, const char *name, const char *help,
void gpr_cmdline_on_extra_arg(
gpr_cmdline *cl, const char *name, const char *help,
void (*on_extra_arg)(void *user_data, const char *arg), void *user_data);
/* Parse the command line */
void gpr_cmdline_parse(gpr_cmdline *cl, int argc, char **argv);
/* Enable surviving failure: default behavior is to exit the process */
void gpr_cmdline_set_survive_failure(gpr_cmdline *cl);
/* Parse the command line; returns 1 on success, on failure either dies
(by default) or returns 0 if gpr_cmdline_set_survive_failure() has been
called */
int gpr_cmdline_parse(gpr_cmdline *cl, int argc, char **argv);
/* Destroy the parser */
void gpr_cmdline_destroy(gpr_cmdline *cl);
/* Get a string describing usage */

@ -183,7 +183,7 @@
#endif
#define GPR_MSG_IOVLEN_TYPE int
#if TARGET_OS_IPHONE
#define GPR_FORBID_UNREACHABLE_CODE
#define GPR_FORBID_UNREACHABLE_CODE 1
#define GPR_PLATFORM_STRING "ios"
#define GPR_CPU_IPHONE 1
#define GPR_PTHREAD_TLS 1
@ -252,6 +252,11 @@
#define GPR_PLATFORM_STRING "unknown"
#endif
#ifdef GPR_GCOV
#undef GPR_FORBID_UNREACHABLE_CODE
#define GPR_FORBID_UNREACHABLE_CODE 1
#endif
/* For a common case, assume that the platform has a C99-like stdint.h */
#include <stdint.h>
@ -337,7 +342,7 @@ typedef uintptr_t gpr_uintptr;
#endif
#endif
#ifdef GPR_FORBID_UNREACHABLE_CODE
#if GPR_FORBID_UNREACHABLE_CODE
#define GPR_UNREACHABLE_CODE(STATEMENT)
#else
#define GPR_UNREACHABLE_CODE(STATEMENT) \

@ -61,8 +61,8 @@ typedef enum {
} gpr_clock_type;
typedef struct gpr_timespec {
time_t tv_sec;
int tv_nsec;
gpr_int64 tv_sec;
gpr_int32 tv_nsec;
/** Against which clock was this time measured? (or GPR_TIMESPAN if
this is a relative time meaure) */
gpr_clock_type clock_type;

@ -1,6 +1,6 @@
{
"name": "grpc",
"version": "0.11.1",
"version": "0.12.0",
"author": "Google Inc.",
"description": "gRPC Library for Node",
"homepage": "http://www.grpc.io/",
@ -39,7 +39,8 @@
"minimist": "^1.1.0",
"mocha": "~1.21.0",
"mocha-jenkins-reporter": "^0.1.9",
"mustache": "^2.0.0"
"mustache": "^2.0.0",
"poisson-process": "^0.2.1"
},
"engines": {
"node": ">=0.10.13"

@ -36,14 +36,12 @@
#include <grpc/census.h>
#define GRPC_CENSUS_MAX_ON_THE_WIRE_TAG_BYTES 2048
/* census_context is the in-memory representation of information needed to
* maintain tracing, RPC statistics and resource usage information. */
struct census_context {
gpr_uint64 op_id; /* Operation identifier - unique per-context */
gpr_uint64 trace_id; /* Globally unique trace identifier */
/* TODO(aveitch) Add census tags:
const census_tag_set *tags;
*/
census_tag_set *tags; /* Opaque data structure for census tags. */
};
#endif /* GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H */

@ -43,7 +43,6 @@
#include <grpc/support/time.h>
#include "src/core/channel/channel_stack.h"
#include "src/core/channel/noop_filter.h"
#include "src/core/statistics/census_interface.h"
#include "src/core/statistics/census_rpc_stats.h"
#include "src/core/transport/static_metadata.h"
@ -116,8 +115,11 @@ static void server_mutate_op(grpc_call_element *elem,
static void server_start_transport_op(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_transport_stream_op *op) {
/* TODO(ctiller): this code fails. I don't know why. I expect it's
incomplete, and someone should look at it soon.
call_data *calld = elem->call_data;
GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0));
GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0)); */
server_mutate_op(elem, op);
grpc_call_next_op(exec_ctx, elem, op);
}

@ -124,6 +124,8 @@ static void on_lb_policy_state_changed_locked(
w->chand->resolver != NULL) {
publish_state = GRPC_CHANNEL_TRANSIENT_FAILURE;
grpc_resolver_channel_saw_error(exec_ctx, w->chand->resolver);
GRPC_LB_POLICY_UNREF(exec_ctx, w->chand->lb_policy, "channel");
w->chand->lb_policy = NULL;
}
grpc_connectivity_state_set(exec_ctx, &w->chand->state_tracker, publish_state,
"lb_changed");
@ -250,7 +252,10 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
grpc_exec_ctx_enqueue(exec_ctx, op->on_consumed, 1);
GPR_ASSERT(op->set_accept_stream == NULL);
GPR_ASSERT(op->bind_pollset == NULL);
if (op->bind_pollset != NULL) {
grpc_pollset_set_add_pollset(exec_ctx, &chand->interested_parties,
op->bind_pollset);
}
gpr_mu_lock(&chand->mu_config);
if (op->on_connectivity_state_change != NULL) {
@ -261,6 +266,16 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
op->connectivity_state = NULL;
}
if (op->send_ping != NULL) {
if (chand->lb_policy == NULL) {
grpc_exec_ctx_enqueue(exec_ctx, op->send_ping, 0);
} else {
grpc_lb_policy_ping_one(exec_ctx, chand->lb_policy, op->send_ping);
op->bind_pollset = NULL;
}
op->send_ping = NULL;
}
if (op->disconnect && chand->resolver != NULL) {
grpc_connectivity_state_set(exec_ctx, &chand->state_tracker,
GRPC_CHANNEL_FATAL_FAILURE, "disconnect");

@ -39,11 +39,11 @@
#include <grpc/support/log.h>
#include <grpc/support/slice_buffer.h>
#include "src/core/channel/compress_filter.h"
#include "src/core/channel/channel_args.h"
#include "src/core/profiling/timers.h"
#include "src/core/channel/compress_filter.h"
#include "src/core/compression/algorithm_metadata.h"
#include "src/core/compression/message_compress.h"
#include "src/core/profiling/timers.h"
#include "src/core/support/string.h"
#include "src/core/transport/static_metadata.h"

@ -31,12 +31,12 @@
*/
#include "src/core/channel/http_client_filter.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/support/string.h"
#include <string.h>
#include "src/core/profiling/timers.h"
#include "src/core/support/string.h"
#include "src/core/transport/static_metadata.h"
typedef struct call_data {

@ -33,9 +33,9 @@
#include "src/core/channel/http_server_filter.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <string.h>
#include "src/core/profiling/timers.h"
#include "src/core/transport/static_metadata.h"
@ -124,7 +124,6 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
omitted */
grpc_mdelem *authority = grpc_mdelem_from_metadata_strings(
GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value));
GRPC_MDELEM_UNREF(md);
calld->seen_authority = 1;
return authority;
} else {

@ -1,118 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/channel/noop_filter.h"
#include <grpc/support/log.h>
typedef struct call_data {
int unused; /* C89 requires at least one struct element */
} call_data;
typedef struct channel_data {
int unused; /* C89 requires at least one struct element */
} channel_data;
/* used to silence 'variable not used' warnings */
static void ignore_unused(void *ignored) {}
static void noop_mutate_op(grpc_call_element *elem,
grpc_transport_stream_op *op) {
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;
ignore_unused(calld);
ignore_unused(channeld);
/* do nothing */
}
/* Called either:
- in response to an API call (or similar) from above, to send something
- a network event (or similar) from below, to receive something
op contains type and call direction information, in addition to the data
that is being sent or received. */
static void noop_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_transport_stream_op *op) {
noop_mutate_op(elem, op);
/* pass control down the stack */
grpc_call_next_op(exec_ctx, elem, op);
}
/* Constructor for call_data */
static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_call_element_args *args) {
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;
/* initialize members */
calld->unused = channeld->unused;
}
/* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem) {}
/* Constructor for channel_data */
static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
/* grab pointers to our data from the channel element */
channel_data *channeld = elem->channel_data;
/* The last filter tends to be implemented differently to
handle the case that there's no 'next' filter to call on the down
path */
GPR_ASSERT(!args->is_last);
/* initialize members */
channeld->unused = 0;
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
/* grab pointers to our data from the channel element */
channel_data *channeld = elem->channel_data;
ignore_unused(channeld);
}
const grpc_channel_filter grpc_no_op_filter = {
noop_start_transport_stream_op, grpc_channel_next_op, sizeof(call_data),
init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem,
sizeof(channel_data), init_channel_elem, destroy_channel_elem,
grpc_call_next_get_peer, "no-op"};

@ -155,7 +155,7 @@ retry:
holder->connected_subchannel != NULL) {
gpr_atm_rel_store(
&holder->subchannel_call,
grpc_connected_subchannel_create_call(
(gpr_atm)(gpr_uintptr)grpc_connected_subchannel_create_call(
exec_ctx, holder->connected_subchannel, holder->pollset));
retry_waiting_locked(exec_ctx, holder);
goto retry;
@ -180,7 +180,7 @@ static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, int success) {
} else {
gpr_atm_rel_store(
&holder->subchannel_call,
grpc_connected_subchannel_create_call(
(gpr_atm)(gpr_uintptr)grpc_connected_subchannel_create_call(
exec_ctx, holder->connected_subchannel, holder->pollset));
retry_waiting_locked(exec_ctx, holder);
}

@ -360,8 +360,20 @@ void pf_notify_on_state_change(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
gpr_mu_unlock(&p->mu);
}
void pf_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
grpc_closure *closure) {
pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
gpr_mu_lock(&p->mu);
if (p->selected) {
grpc_connected_subchannel_ping(exec_ctx, p->selected, closure);
} else {
grpc_exec_ctx_enqueue(exec_ctx, closure, 0);
}
gpr_mu_unlock(&p->mu);
}
static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = {
pf_destroy, pf_shutdown, pf_pick, pf_cancel_pick, pf_exit_idle,
pf_destroy, pf_shutdown, pf_pick, pf_cancel_pick, pf_ping_one, pf_exit_idle,
pf_check_connectivity, pf_notify_on_state_change};
static void pick_first_factory_ref(grpc_lb_policy_factory *factory) {}

@ -467,8 +467,24 @@ static void rr_notify_on_state_change(grpc_exec_ctx *exec_ctx,
gpr_mu_unlock(&p->mu);
}
static void rr_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
grpc_closure *closure) {
round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
ready_list *selected;
grpc_connected_subchannel *target;
gpr_mu_lock(&p->mu);
if ((selected = peek_next_connected_locked(p))) {
gpr_mu_unlock(&p->mu);
target = grpc_subchannel_get_connected_subchannel(selected->subchannel);
grpc_connected_subchannel_ping(exec_ctx, target, closure);
} else {
gpr_mu_unlock(&p->mu);
grpc_exec_ctx_enqueue(exec_ctx, closure, 0);
}
}
static const grpc_lb_policy_vtable round_robin_lb_policy_vtable = {
rr_destroy, rr_shutdown, rr_pick, rr_cancel_pick, rr_exit_idle,
rr_destroy, rr_shutdown, rr_pick, rr_cancel_pick, rr_ping_one, rr_exit_idle,
rr_check_connectivity, rr_notify_on_state_change};
static void round_robin_factory_ref(grpc_lb_policy_factory *factory) {}

@ -116,6 +116,11 @@ void grpc_lb_policy_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy) {
policy->vtable->exit_idle(exec_ctx, policy);
}
void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
grpc_closure *closure) {
policy->vtable->ping_one(exec_ctx, policy, closure);
}
void grpc_lb_policy_notify_on_state_change(grpc_exec_ctx *exec_ctx,
grpc_lb_policy *policy,
grpc_connectivity_state *state,

@ -63,6 +63,9 @@ struct grpc_lb_policy_vtable {
void (*cancel_pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
grpc_connected_subchannel **target);
void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
grpc_closure *closure);
/** try to enter a READY connectivity state */
void (*exit_idle)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy);
@ -121,6 +124,9 @@ int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
grpc_connected_subchannel **target,
grpc_closure *on_complete);
void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
grpc_closure *closure);
void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
grpc_connected_subchannel **target);

@ -40,7 +40,6 @@
#include <grpc/support/string_util.h>
#include "src/core/client_config/lb_policy_registry.h"
#include "src/core/client_config/subchannel_factory_decorators/add_channel_arg.h"
#include "src/core/iomgr/resolve_address.h"
#include "src/core/support/string.h"

@ -347,6 +347,9 @@ static grpc_resolver *sockaddr_create(
gpr_slice_buffer_destroy(&path_parts);
gpr_slice_unref(path_slice);
if (errors_found) {
gpr_free(r->lb_policy_name);
gpr_free(r->addrs);
gpr_free(r->addrs_len);
gpr_free(r);
return NULL;
}

@ -96,9 +96,7 @@ static void zookeeper_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
static void zookeeper_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
static void zookeeper_channel_saw_error(grpc_exec_ctx *exec_ctx,
grpc_resolver *r,
struct sockaddr *failing_address,
int failing_address_len);
grpc_resolver *r);
static void zookeeper_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r,
grpc_client_config **target_config,
grpc_closure *on_complete);
@ -125,8 +123,7 @@ static void zookeeper_shutdown(grpc_exec_ctx *exec_ctx,
}
static void zookeeper_channel_saw_error(grpc_exec_ctx *exec_ctx,
grpc_resolver *resolver,
struct sockaddr *sa, int len) {
grpc_resolver *resolver) {
zookeeper_resolver *r = (zookeeper_resolver *)resolver;
gpr_mu_lock(&r->mu);
if (r->resolving == 0) {

@ -461,6 +461,17 @@ void grpc_connected_subchannel_notify_on_state_change(
closure);
}
void grpc_connected_subchannel_ping(grpc_exec_ctx *exec_ctx,
grpc_connected_subchannel *con,
grpc_closure *closure) {
grpc_transport_op op;
grpc_channel_element *elem;
memset(&op, 0, sizeof(op));
op.send_ping = closure;
elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0);
elem->filter->start_transport_op(exec_ctx, elem, &op);
}
static void publish_transport(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
size_t channel_stack_size;
grpc_connected_subchannel *con;

@ -124,6 +124,9 @@ void grpc_connected_subchannel_notify_on_state_change(
grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *channel,
grpc_pollset_set *interested_parties, grpc_connectivity_state *state,
grpc_closure *notify);
void grpc_connected_subchannel_ping(grpc_exec_ctx *exec_ctx,
grpc_connected_subchannel *channel,
grpc_closure *notify);
/** retrieve the grpc_connected_subchannel - or NULL if called before
the subchannel becomes connected */

@ -1,86 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/client_config/subchannel_factory_decorators/merge_channel_args.h"
#include <grpc/support/alloc.h>
#include "src/core/channel/channel_args.h"
typedef struct {
grpc_subchannel_factory base;
gpr_refcount refs;
grpc_subchannel_factory *wrapped;
grpc_channel_args *merge_args;
} merge_args_factory;
static void merge_args_factory_ref(grpc_subchannel_factory *scf) {
merge_args_factory *f = (merge_args_factory *)scf;
gpr_ref(&f->refs);
}
static void merge_args_factory_unref(grpc_exec_ctx *exec_ctx,
grpc_subchannel_factory *scf) {
merge_args_factory *f = (merge_args_factory *)scf;
if (gpr_unref(&f->refs)) {
grpc_subchannel_factory_unref(exec_ctx, f->wrapped);
grpc_channel_args_destroy(f->merge_args);
gpr_free(f);
}
}
static grpc_subchannel *merge_args_factory_create_subchannel(
grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf,
grpc_subchannel_args *args) {
merge_args_factory *f = (merge_args_factory *)scf;
grpc_channel_args *final_args =
grpc_channel_args_merge(args->args, f->merge_args);
grpc_subchannel *s;
args->args = final_args;
s = grpc_subchannel_factory_create_subchannel(exec_ctx, f->wrapped, args);
grpc_channel_args_destroy(final_args);
return s;
}
static const grpc_subchannel_factory_vtable merge_args_factory_vtable = {
merge_args_factory_ref, merge_args_factory_unref,
merge_args_factory_create_subchannel};
grpc_subchannel_factory *grpc_subchannel_factory_merge_channel_args(
grpc_subchannel_factory *input, const grpc_channel_args *args) {
merge_args_factory *f = gpr_malloc(sizeof(*f));
f->base.vtable = &merge_args_factory_vtable;
gpr_ref_init(&f->refs, 1);
grpc_subchannel_factory_ref(input);
f->wrapped = input;
f->merge_args = grpc_channel_args_copy(args);
return &f->base;
}

@ -1,46 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_DECORATORS_MERGE_CHANNEL_ARGS_H
#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_DECORATORS_MERGE_CHANNEL_ARGS_H
#include "src/core/client_config/subchannel_factory.h"
/** Takes a subchannel factory, returns a new one that mutates incoming
channel_args by adding a new argument; ownership of input, args is retained
by the caller. */
grpc_subchannel_factory *grpc_subchannel_factory_merge_channel_args(
grpc_subchannel_factory *input, const grpc_channel_args *args);
#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_DECORATORS_MERGE_CHANNEL_ARGS_H \
*/

@ -119,8 +119,8 @@ grpc_mdelem *grpc_compression_encoding_mdelem(
return GRPC_MDELEM_GRPC_ENCODING_DEFLATE;
case GRPC_COMPRESS_GZIP:
return GRPC_MDELEM_GRPC_ENCODING_GZIP;
case GRPC_COMPRESS_ALGORITHMS_COUNT:
return NULL;
default:
break;
}
return NULL;
}
@ -139,25 +139,9 @@ grpc_compression_algorithm grpc_compression_algorithm_for_level(
case GRPC_COMPRESS_LEVEL_HIGH:
return GRPC_COMPRESS_DEFLATE;
default:
/* we shouldn't be making it here */
abort();
return GRPC_COMPRESS_NONE;
}
}
grpc_compression_level grpc_compression_level_for_algorithm(
grpc_compression_algorithm algorithm) {
grpc_compression_level clevel;
GRPC_API_TRACE("grpc_compression_level_for_algorithm(algorithm=%d)", 1,
((int)algorithm));
for (clevel = GRPC_COMPRESS_LEVEL_NONE; clevel < GRPC_COMPRESS_LEVEL_COUNT;
++clevel) {
if (grpc_compression_algorithm_for_level(clevel) == algorithm) {
return clevel;
}
break;
}
abort();
return GRPC_COMPRESS_LEVEL_NONE;
GPR_UNREACHABLE_CODE(return GRPC_COMPRESS_NONE);
}
void grpc_compression_options_init(grpc_compression_options *opts) {

@ -69,8 +69,8 @@ static int zlib_body(z_stream* zs, gpr_slice_buffer* input,
zs->next_out = GPR_SLICE_START_PTR(outbuf);
}
r = flate(zs, flush);
if (r == Z_STREAM_ERROR) {
gpr_log(GPR_INFO, "zlib: stream error");
if (r < 0 && r != Z_BUF_ERROR /* not fatal */) {
gpr_log(GPR_INFO, "zlib error (%d)", r);
goto error;
}
} while (zs->avail_out == 0);
@ -91,6 +91,12 @@ error:
return 0;
}
static void* zalloc_gpr(void* opaque, unsigned int items, unsigned int size) {
return gpr_malloc(items * size);
}
static void zfree_gpr(void* opaque, void* address) { gpr_free(address); }
static int zlib_compress(gpr_slice_buffer* input, gpr_slice_buffer* output,
int gzip) {
z_stream zs;
@ -99,12 +105,11 @@ static int zlib_compress(gpr_slice_buffer* input, gpr_slice_buffer* output,
size_t count_before = output->count;
size_t length_before = output->length;
memset(&zs, 0, sizeof(zs));
zs.zalloc = zalloc_gpr;
zs.zfree = zfree_gpr;
r = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | (gzip ? 16 : 0),
8, Z_DEFAULT_STRATEGY);
if (r != Z_OK) {
gpr_log(GPR_ERROR, "deflateInit2 returns %d", r);
return 0;
}
GPR_ASSERT(r == Z_OK);
r = zlib_body(&zs, input, output, deflate) && output->length < input->length;
if (!r) {
for (i = count_before; i < output->count; i++) {
@ -125,11 +130,10 @@ static int zlib_decompress(gpr_slice_buffer* input, gpr_slice_buffer* output,
size_t count_before = output->count;
size_t length_before = output->length;
memset(&zs, 0, sizeof(zs));
zs.zalloc = zalloc_gpr;
zs.zfree = zfree_gpr;
r = inflateInit2(&zs, 15 | (gzip ? 16 : 0));
if (r != Z_OK) {
gpr_log(GPR_ERROR, "inflateInit2 returns %d", r);
return 0;
}
GPR_ASSERT(r == Z_OK);
r = zlib_body(&zs, input, output, inflate);
if (!r) {
for (i = count_before; i < output->count; i++) {
@ -150,8 +154,8 @@ static int copy(gpr_slice_buffer* input, gpr_slice_buffer* output) {
return 1;
}
int compress_inner(grpc_compression_algorithm algorithm,
gpr_slice_buffer* input, gpr_slice_buffer* output) {
static int compress_inner(grpc_compression_algorithm algorithm,
gpr_slice_buffer* input, gpr_slice_buffer* output) {
switch (algorithm) {
case GRPC_COMPRESS_NONE:
/* the fallback path always needs to be send uncompressed: we simply

@ -53,6 +53,7 @@ typedef struct {
size_t next_address;
grpc_endpoint *ep;
char *host;
char *ssl_host_override;
gpr_timespec deadline;
int have_read_byte;
const grpc_httpcli_handshaker *handshaker;
@ -106,6 +107,7 @@ static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
}
gpr_slice_unref(req->request_text);
gpr_free(req->host);
gpr_free(req->ssl_host_override);
grpc_iomgr_unregister_object(&req->iomgr_obj);
gpr_slice_buffer_destroy(&req->incoming);
gpr_slice_buffer_destroy(&req->outgoing);
@ -180,8 +182,10 @@ static void on_connected(grpc_exec_ctx *exec_ctx, void *arg, int success) {
next_address(exec_ctx, req);
return;
}
req->handshaker->handshake(exec_ctx, req, req->ep, req->host,
on_handshake_done);
req->handshaker->handshake(
exec_ctx, req, req->ep,
req->ssl_host_override ? req->ssl_host_override : req->host,
on_handshake_done);
}
static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req) {
@ -231,6 +235,7 @@ static void internal_request_begin(
gpr_slice_buffer_init(&req->outgoing);
grpc_iomgr_register_object(&req->iomgr_obj, name);
req->host = gpr_strdup(request->host);
req->ssl_host_override = gpr_strdup(request->ssl_host_override);
grpc_pollset_set_add_pollset(exec_ctx, &req->context->pollset_set,
req->pollset);

@ -74,6 +74,8 @@ extern const grpc_httpcli_handshaker grpc_httpcli_ssl;
typedef struct grpc_httpcli_request {
/* The host name to connect to */
char *host;
/* The host to verify in the SSL handshake (or NULL) */
char *ssl_host_override;
/* The path of the resource to fetch */
char *path;
/* Additional headers: count and key/values; the following are supplied

@ -68,7 +68,7 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
tsi_result result = TSI_OK;
tsi_handshaker *handshaker;
if (c->handshaker_factory == NULL) {
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL);
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL);
return;
}
result = tsi_ssl_handshaker_factory_create_handshaker(
@ -76,7 +76,7 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
tsi_result_to_string(result));
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL);
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL);
} else {
grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb,
user_data);
@ -149,7 +149,6 @@ typedef struct {
static void on_secure_transport_setup_done(grpc_exec_ctx *exec_ctx, void *rp,
grpc_security_status status,
grpc_endpoint *wrapped_endpoint,
grpc_endpoint *secure_endpoint) {
on_done_closure *c = rp;
if (status != GRPC_SECURITY_OK) {

@ -36,6 +36,7 @@
#ifdef GPR_POSIX_SOCKET
#include "src/core/iomgr/endpoint_pair.h"
#include "src/core/iomgr/socket_utils_posix.h"
#include <errno.h>
#include <fcntl.h>
@ -56,6 +57,8 @@ static void create_sockets(int sv[2]) {
GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0);
flags = fcntl(sv[1], F_GETFL, 0);
GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0);
GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[0]));
GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[1]));
}
grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name,

@ -211,14 +211,21 @@ static int has_watchers(grpc_fd *fd) {
}
void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done,
const char *reason) {
int *release_fd, const char *reason) {
fd->on_done_closure = on_done;
shutdown(fd->fd, SHUT_RDWR);
fd->released = release_fd != NULL;
if (!fd->released) {
shutdown(fd->fd, SHUT_RDWR);
} else {
*release_fd = fd->fd;
}
gpr_mu_lock(&fd->mu);
REF_BY(fd, 1, reason); /* remove active status, but keep referenced */
if (!has_watchers(fd)) {
fd->closed = 1;
close(fd->fd);
if (!fd->released) {
close(fd->fd);
}
grpc_exec_ctx_enqueue(exec_ctx, fd->on_done_closure, 1);
} else {
wake_all_watchers_locked(fd);
@ -410,7 +417,9 @@ void grpc_fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher,
}
if (grpc_fd_is_orphaned(fd) && !has_watchers(fd) && !fd->closed) {
fd->closed = 1;
close(fd->fd);
if (!fd->released) {
close(fd->fd);
}
grpc_exec_ctx_enqueue(exec_ctx, fd->on_done_closure, 1);
}
gpr_mu_unlock(&fd->mu);

@ -62,6 +62,7 @@ struct grpc_fd {
gpr_mu mu;
int shutdown;
int closed;
int released;
/* The watcher list.
@ -107,11 +108,12 @@ grpc_fd *grpc_fd_create(int fd, const char *name);
/* Releases fd to be asynchronously destroyed.
on_done is called when the underlying file descriptor is definitely close()d.
If on_done is NULL, no callback will be made.
If release_fd is not NULL, it's set to fd and fd will not be closed.
Requires: *fd initialized; no outstanding notify_on_read or
notify_on_write.
MUST NOT be called with a pollset lock taken */
void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done,
const char *reason);
int *release_fd, const char *reason);
/* Begin polling on an fd.
Registers that the given pollset is interested in this fd - so that if read

@ -116,7 +116,6 @@ void grpc_iomgr_shutdown(void) {
"memory leaks are likely",
count_objects());
dump_objects("LEAKED");
abort();
}
break;
}

@ -123,26 +123,6 @@ static void multipoll_with_epoll_pollset_add_fd(grpc_exec_ctx *exec_ctx,
}
}
static void multipoll_with_epoll_pollset_del_fd(grpc_exec_ctx *exec_ctx,
grpc_pollset *pollset,
grpc_fd *fd,
int and_unlock_pollset) {
pollset_hdr *h = pollset->data.ptr;
int err;
if (and_unlock_pollset) {
gpr_mu_unlock(&pollset->mu);
}
/* Note that this can race with concurrent poll, but that should be fine since
* at worst it creates a spurious read event on a reused grpc_fd object. */
err = epoll_ctl(h->epoll_fd, EPOLL_CTL_DEL, fd->fd, NULL);
if (err < 0) {
gpr_log(GPR_ERROR, "epoll_ctl del for %d failed: %s", fd->fd,
strerror(errno));
}
}
/* TODO(klempner): We probably want to turn this down a bit */
#define GRPC_EPOLL_MAX_EVENTS 1000
@ -235,7 +215,7 @@ static void multipoll_with_epoll_pollset_destroy(grpc_pollset *pollset) {
}
static const grpc_pollset_vtable multipoll_with_epoll_pollset = {
multipoll_with_epoll_pollset_add_fd, multipoll_with_epoll_pollset_del_fd,
multipoll_with_epoll_pollset_add_fd,
multipoll_with_epoll_pollset_maybe_work_and_unlock,
multipoll_with_epoll_pollset_finish_shutdown,
multipoll_with_epoll_pollset_destroy};

@ -82,23 +82,6 @@ exit:
}
}
static void multipoll_with_poll_pollset_del_fd(grpc_exec_ctx *exec_ctx,
grpc_pollset *pollset,
grpc_fd *fd,
int and_unlock_pollset) {
/* will get removed next poll cycle */
pollset_hdr *h = pollset->data.ptr;
if (h->del_count == h->del_capacity) {
h->del_capacity = GPR_MAX(h->del_capacity + 8, h->del_count * 3 / 2);
h->dels = gpr_realloc(h->dels, sizeof(grpc_fd *) * h->del_capacity);
}
h->dels[h->del_count++] = fd;
GRPC_FD_REF(fd, "multipoller_del");
if (and_unlock_pollset) {
gpr_mu_unlock(&pollset->mu);
}
}
static void multipoll_with_poll_pollset_maybe_work_and_unlock(
grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker,
gpr_timespec deadline, gpr_timespec now) {
@ -212,7 +195,7 @@ static void multipoll_with_poll_pollset_destroy(grpc_pollset *pollset) {
}
static const grpc_pollset_vtable multipoll_with_poll_pollset = {
multipoll_with_poll_pollset_add_fd, multipoll_with_poll_pollset_del_fd,
multipoll_with_poll_pollset_add_fd,
multipoll_with_poll_pollset_maybe_work_and_unlock,
multipoll_with_poll_pollset_finish_shutdown,
multipoll_with_poll_pollset_destroy};

@ -232,21 +232,7 @@ void grpc_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
gpr_mu_lock(&pollset->mu);
pollset->vtable->add_fd(exec_ctx, pollset, fd, 1);
/* the following (enabled only in debug) will reacquire and then release
our lock - meaning that if the unlocking flag passed to del_fd above is
not respected, the code will deadlock (in a way that we have a chance of
debugging) */
#ifndef NDEBUG
gpr_mu_lock(&pollset->mu);
gpr_mu_unlock(&pollset->mu);
#endif
}
void grpc_pollset_del_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
grpc_fd *fd) {
gpr_mu_lock(&pollset->mu);
pollset->vtable->del_fd(exec_ctx, pollset, fd, 1);
/* the following (enabled only in debug) will reacquire and then release
our lock - meaning that if the unlocking flag passed to del_fd above is
our lock - meaning that if the unlocking flag passed to add_fd above is
not respected, the code will deadlock (in a way that we have a chance of
debugging) */
#ifndef NDEBUG
@ -547,19 +533,6 @@ exit:
}
}
static void basic_pollset_del_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
grpc_fd *fd, int and_unlock_pollset) {
GPR_ASSERT(fd);
if (fd == pollset->data.ptr) {
GRPC_FD_UNREF(pollset->data.ptr, "basicpoll");
pollset->data.ptr = NULL;
}
if (and_unlock_pollset) {
gpr_mu_unlock(&pollset->mu);
}
}
static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx,
grpc_pollset *pollset,
grpc_pollset_worker *worker,
@ -613,7 +586,9 @@ static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx,
GPR_TIMER_END("poll", 0);
if (r < 0) {
gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
if (errno != EINTR) {
gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
}
if (fd) {
grpc_fd_end_poll(exec_ctx, &fd_watcher, 0, 0);
}
@ -649,9 +624,8 @@ static void basic_pollset_destroy(grpc_pollset *pollset) {
}
static const grpc_pollset_vtable basic_pollset = {
basic_pollset_add_fd, basic_pollset_del_fd,
basic_pollset_maybe_work_and_unlock, basic_pollset_destroy,
basic_pollset_destroy};
basic_pollset_add_fd, basic_pollset_maybe_work_and_unlock,
basic_pollset_destroy, basic_pollset_destroy};
static void become_basic_pollset(grpc_pollset *pollset, grpc_fd *fd_or_null) {
pollset->vtable = &basic_pollset;

@ -86,8 +86,6 @@ typedef struct grpc_pollset {
struct grpc_pollset_vtable {
void (*add_fd)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
struct grpc_fd *fd, int and_unlock_pollset);
void (*del_fd)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
struct grpc_fd *fd, int and_unlock_pollset);
void (*maybe_work_and_unlock)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
grpc_pollset_worker *worker,
gpr_timespec deadline, gpr_timespec now);
@ -100,10 +98,6 @@ struct grpc_pollset_vtable {
/* Add an fd to a pollset */
void grpc_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
struct grpc_fd *fd);
/* Force remove an fd from a pollset (normally they are removed on the next
poll after an fd is orphaned) */
void grpc_pollset_del_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
struct grpc_fd *fd);
/* Returns the fd to listen on for kicks */
int grpc_kick_read_fd(grpc_pollset *p);

@ -196,7 +196,7 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, int success) {
finish:
if (fd != NULL) {
grpc_pollset_set_del_fd(exec_ctx, ac->interested_parties, fd);
grpc_fd_orphan(exec_ctx, fd, NULL, "tcp_client_orphan");
grpc_fd_orphan(exec_ctx, fd, NULL, NULL, "tcp_client_orphan");
fd = NULL;
}
done = (--ac->refs == 0);
@ -265,7 +265,7 @@ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
gpr_log(GPR_ERROR, "connect error to '%s': %s", addr_str, strerror(errno));
grpc_fd_orphan(exec_ctx, fdobj, NULL, "tcp_client_connect_error");
grpc_fd_orphan(exec_ctx, fdobj, NULL, NULL, "tcp_client_connect_error");
grpc_exec_ctx_enqueue(exec_ctx, closure, 0);
goto done;
}

@ -90,6 +90,8 @@ typedef struct {
grpc_closure *read_cb;
grpc_closure *write_cb;
grpc_closure *release_fd_cb;
int *release_fd;
grpc_closure read_closure;
grpc_closure write_closure;
@ -108,7 +110,8 @@ static void tcp_shutdown(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep) {
}
static void tcp_free(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
grpc_fd_orphan(exec_ctx, tcp->em_fd, NULL, "tcp_unref_orphan");
grpc_fd_orphan(exec_ctx, tcp->em_fd, tcp->release_fd_cb, tcp->release_fd,
"tcp_unref_orphan");
gpr_slice_buffer_destroy(&tcp->last_read_buffer);
gpr_free(tcp->peer_string);
gpr_free(tcp);
@ -452,6 +455,8 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size,
tcp->fd = em_fd->fd;
tcp->read_cb = NULL;
tcp->write_cb = NULL;
tcp->release_fd_cb = NULL;
tcp->release_fd = NULL;
tcp->incoming_buffer = NULL;
tcp->slice_size = slice_size;
tcp->iov_size = 1;
@ -468,4 +473,13 @@ grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd, size_t slice_size,
return &tcp->base;
}
void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
int *fd, grpc_closure *done) {
grpc_tcp *tcp = (grpc_tcp *)ep;
GPR_ASSERT(ep->vtable == &vtable);
tcp->release_fd = fd;
tcp->release_fd_cb = done;
TCP_UNREF(exec_ctx, tcp, "destroy");
}
#endif

@ -56,4 +56,10 @@ extern int grpc_tcp_trace;
grpc_endpoint *grpc_tcp_create(grpc_fd *fd, size_t read_slice_size,
const char *peer_string);
/* Destroy the tcp endpoint without closing its fd. *fd will be set and done
* will be called when the endpoint is destroyed.
* Requires: ep must be a tcp endpoint and fd must not be NULL. */
void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
int *fd, grpc_closure *done);
#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_POSIX_H */

@ -193,7 +193,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
}
sp->destroyed_closure.cb = destroyed_port;
sp->destroyed_closure.cb_arg = s;
grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure,
grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
"tcp_listener_shutdown");
}
gpr_mu_unlock(&s->mu);
@ -411,7 +411,6 @@ static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd,
grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
const void *addr, size_t addr_len) {
int allocated_port = -1;
grpc_tcp_listener *sp;
grpc_tcp_listener *sp2 = NULL;
int fd;
@ -464,14 +463,13 @@ grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
addr_len = sizeof(wild6);
fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
sp = add_socket_to_server(s, fd, addr, addr_len);
allocated_port = sp->port;
if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
goto done;
}
/* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
if (port == 0 && allocated_port > 0) {
grpc_sockaddr_set_port((struct sockaddr *)&wild4, allocated_port);
if (port == 0 && sp != NULL) {
grpc_sockaddr_set_port((struct sockaddr *)&wild4, sp->port);
sp2 = sp;
}
addr = (struct sockaddr *)&wild4;
@ -488,8 +486,8 @@ grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
addr_len = sizeof(addr4_copy);
}
sp = add_socket_to_server(s, fd, addr, addr_len);
sp->sibling = sp2;
if (sp2) sp2->is_sibling = 1;
if (sp != NULL) sp->sibling = sp2;
if (sp2 != NULL) sp2->is_sibling = 1;
done:
gpr_free(allocated_addr);
@ -534,8 +532,12 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
}
int grpc_tcp_listener_get_port(grpc_tcp_listener *listener) {
grpc_tcp_listener *sp = listener;
return sp->port;
if (listener != NULL) {
grpc_tcp_listener *sp = listener;
return sp->port;
} else {
return 0;
}
}
void grpc_tcp_listener_ref(grpc_tcp_listener *listener) {

@ -486,8 +486,12 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
}
int grpc_tcp_listener_get_port(grpc_tcp_listener *listener) {
grpc_tcp_listener *sp = listener;
return sp->port;
if (listener != NULL) {
grpc_tcp_listener *sp = listener;
return sp->port;
} else {
return 0;
}
}
void grpc_tcp_listener_ref(grpc_tcp_listener *listener) {

@ -197,7 +197,8 @@ static void win_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
tcp->read_slice = gpr_slice_malloc(8192);
buffer.len = GPR_SLICE_LENGTH(tcp->read_slice);
buffer.len = (ULONG)GPR_SLICE_LENGTH(
tcp->read_slice); // we know slice size fits in 32bit.
buffer.buf = (char *)GPR_SLICE_START_PTR(tcp->read_slice);
TCP_REF(tcp, "read");
@ -273,6 +274,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
WSABUF local_buffers[16];
WSABUF *allocated = NULL;
WSABUF *buffers = local_buffers;
size_t len;
if (tcp->shutting_down) {
grpc_exec_ctx_enqueue(exec_ctx, cb, 0);
@ -281,19 +283,21 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
tcp->write_cb = cb;
tcp->write_slices = slices;
GPR_ASSERT(tcp->write_slices->count <= UINT_MAX);
if (tcp->write_slices->count > GPR_ARRAY_SIZE(local_buffers)) {
buffers = (WSABUF *)gpr_malloc(sizeof(WSABUF) * tcp->write_slices->count);
allocated = buffers;
}
for (i = 0; i < tcp->write_slices->count; i++) {
buffers[i].len = GPR_SLICE_LENGTH(tcp->write_slices->slices[i]);
len = GPR_SLICE_LENGTH(tcp->write_slices->slices[i]);
GPR_ASSERT(len <= ULONG_MAX);
buffers[i].len = (ULONG)len;
buffers[i].buf = (char *)GPR_SLICE_START_PTR(tcp->write_slices->slices[i]);
}
/* First, let's try a synchronous, non-blocking write. */
status = WSASend(socket->socket, buffers, tcp->write_slices->count,
status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count,
&bytes_sent, 0, NULL, NULL);
info->wsa_error = status == 0 ? 0 : WSAGetLastError();
@ -322,7 +326,7 @@ static void win_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
/* If we got a WSAEWOULDBLOCK earlier, then we need to re-do the same
operation, this time asynchronously. */
memset(&socket->write_info.overlapped, 0, sizeof(OVERLAPPED));
status = WSASend(socket->socket, buffers, tcp->write_slices->count,
status = WSASend(socket->socket, buffers, (DWORD)tcp->write_slices->count,
&bytes_sent, 0, &socket->write_info.overlapped, NULL);
if (allocated) gpr_free(allocated);

@ -126,8 +126,8 @@ static double ts_to_dbl(gpr_timespec ts) {
static gpr_timespec dbl_to_ts(double d) {
gpr_timespec ts;
ts.tv_sec = (time_t)d;
ts.tv_nsec = (int)(1e9 * (d - (double)ts.tv_sec));
ts.tv_sec = (gpr_int64)d;
ts.tv_nsec = (gpr_int32)(1e9 * (d - (double)ts.tv_sec));
ts.clock_type = GPR_TIMESPAN;
return ts;
}
@ -343,11 +343,3 @@ int grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now,
exec_ctx, now, next,
gpr_time_cmp(now, gpr_inf_future(now.clock_type)) != 0);
}
gpr_timespec grpc_timer_list_next_timeout(void) {
gpr_timespec out;
gpr_mu_lock(&g_mu);
out = g_shard_queue[0]->min_deadline;
gpr_mu_unlock(&g_mu);
return out;
}

@ -54,8 +54,6 @@ int grpc_timer_check(grpc_exec_ctx* exec_ctx, gpr_timespec now,
void grpc_timer_list_init(gpr_timespec now);
void grpc_timer_list_shutdown(grpc_exec_ctx* exec_ctx);
gpr_timespec grpc_timer_list_next_timeout(void);
/* the following must be implemented by each iomgr implementation */
void grpc_kick_poller(void);

@ -38,6 +38,7 @@
#include <grpc/support/port_platform.h>
#ifdef GRPC_NEED_UDP
#ifdef GPR_POSIX_SOCKET
#include "src/core/iomgr/udp_server.h"
@ -179,7 +180,7 @@ static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) {
}
sp->destroyed_closure.cb = destroyed_port;
sp->destroyed_closure.cb_arg = s;
grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure,
grpc_fd_orphan(exec_ctx, sp->emfd, &sp->destroyed_closure, NULL,
"udp_listener_shutdown");
}
gpr_mu_unlock(&s->mu);
@ -435,3 +436,4 @@ void grpc_udp_server_write(server_port *sp, const char *buffer, size_t buf_len,
}
#endif
#endif

@ -40,19 +40,17 @@
#include <stddef.h>
static const grpc_wakeup_fd_vtable *wakeup_fd_vtable = NULL;
int grpc_allow_specialized_wakeup_fd = 1;
void grpc_wakeup_fd_global_init(void) {
if (grpc_specialized_wakeup_fd_vtable.check_availability()) {
if (grpc_allow_specialized_wakeup_fd &&
grpc_specialized_wakeup_fd_vtable.check_availability()) {
wakeup_fd_vtable = &grpc_specialized_wakeup_fd_vtable;
} else {
wakeup_fd_vtable = &grpc_pipe_wakeup_fd_vtable;
}
}
void grpc_wakeup_fd_global_init_force_fallback(void) {
wakeup_fd_vtable = &grpc_pipe_wakeup_fd_vtable;
}
void grpc_wakeup_fd_global_destroy(void) { wakeup_fd_vtable = NULL; }
void grpc_wakeup_fd_init(grpc_wakeup_fd *fd_info) {

@ -85,6 +85,8 @@ struct grpc_wakeup_fd {
int write_fd;
};
extern int grpc_allow_specialized_wakeup_fd;
#define GRPC_WAKEUP_FD_GET_READ_FD(fd_info) ((fd_info)->read_fd)
void grpc_wakeup_fd_init(grpc_wakeup_fd* fd_info);

@ -103,6 +103,9 @@ void grpc_workqueue_add_to_pollset(grpc_exec_ctx *exec_ctx,
void grpc_workqueue_flush(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue) {
gpr_mu_lock(&workqueue->mu);
if (grpc_closure_list_empty(workqueue->closure_list)) {
grpc_wakeup_fd_wakeup(&workqueue->wakeup_fd);
}
grpc_closure_list_move(&exec_ctx->closure_list, &workqueue->closure_list);
gpr_mu_unlock(&workqueue->mu);
}
@ -115,7 +118,7 @@ static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, int success) {
/* HACK: let wakeup_fd code know that we stole the fd */
workqueue->wakeup_fd.read_fd = 0;
grpc_wakeup_fd_destroy(&workqueue->wakeup_fd);
grpc_fd_orphan(exec_ctx, workqueue->wakeup_read_fd, NULL, "destroy");
grpc_fd_orphan(exec_ctx, workqueue->wakeup_read_fd, NULL, NULL, "destroy");
gpr_free(workqueue);
} else {
gpr_mu_lock(&workqueue->mu);

@ -35,6 +35,8 @@
#include <grpc/support/port_platform.h>
#include <grpc/support/log.h>
#include "src/core/json/json_reader.h"
static void json_reader_string_clear(grpc_json_reader *reader) {
@ -224,13 +226,13 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) {
reader->in_array = 1;
break;
case GRPC_JSON_TOP_LEVEL:
if (reader->depth != 0) return GRPC_JSON_INTERNAL_ERROR;
GPR_ASSERT(reader->depth == 0);
reader->in_object = 0;
reader->in_array = 0;
reader->state = GRPC_JSON_STATE_END;
break;
default:
return GRPC_JSON_INTERNAL_ERROR;
GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
}
}
break;
@ -279,8 +281,7 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) {
break;
case GRPC_JSON_STATE_OBJECT_KEY_STRING:
if (reader->unicode_high_surrogate != 0)
return GRPC_JSON_PARSE_ERROR;
GPR_ASSERT(reader->unicode_high_surrogate == 0);
if (c == '"') {
reader->state = GRPC_JSON_STATE_OBJECT_KEY_END;
json_reader_set_key(reader);
@ -461,7 +462,7 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) {
}
break;
default:
return GRPC_JSON_INTERNAL_ERROR;
GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
}
break;
@ -641,7 +642,7 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) {
case ',':
case '}':
case ']':
return GRPC_JSON_INTERNAL_ERROR;
GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
break;
default:
@ -655,5 +656,5 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) {
}
}
return GRPC_JSON_INTERNAL_ERROR;
GPR_UNREACHABLE_CODE(return GRPC_JSON_INTERNAL_ERROR);
}

@ -353,7 +353,7 @@ static void json_dump_recursive(grpc_json_writer *writer, grpc_json *json,
grpc_json_writer_value_raw_with_len(writer, "null", 4);
break;
default:
abort();
GPR_UNREACHABLE_CODE(abort());
}
json = json->next;
}

@ -141,10 +141,11 @@ static void write_log(gpr_timer_log *log) {
entry->tm = gpr_time_0(entry->tm.clock_type);
}
fprintf(output_file,
"{\"t\": %ld.%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": "
"{\"t\": %lld.%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": "
"\"%s\", \"file\": \"%s\", \"line\": %d, \"imp\": %d}\n",
entry->tm.tv_sec, entry->tm.tv_nsec, entry->thd, entry->type,
entry->tagstr, entry->file, entry->line, entry->important);
(long long)entry->tm.tv_sec, (int)entry->tm.tv_nsec, entry->thd,
entry->type, entry->tagstr, entry->file, entry->line,
entry->important);
}
}

@ -39,11 +39,11 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/support/string.h"
#include "src/core/channel/channel_stack.h"
#include "src/core/security/security_context.h"
#include "src/core/security/security_connector.h"
#include "src/core/security/credentials.h"
#include "src/core/security/security_connector.h"
#include "src/core/security/security_context.h"
#include "src/core/support/string.h"
#include "src/core/surface/call.h"
#include "src/core/transport/static_metadata.h"
@ -62,7 +62,7 @@ typedef struct {
grpc_transport_stream_op op;
gpr_uint8 security_context_set;
grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
char *service_url;
grpc_auth_metadata_context auth_md_context;
} call_data;
/* We can have a per-channel credentials. */
@ -70,11 +70,20 @@ typedef struct {
grpc_channel_security_connector *security_connector;
} channel_data;
static void reset_service_url(call_data *calld) {
if (calld->service_url != NULL) {
gpr_free(calld->service_url);
calld->service_url = NULL;
static void reset_auth_metadata_context(
grpc_auth_metadata_context *auth_md_context) {
if (auth_md_context->service_url != NULL) {
gpr_free((char *)auth_md_context->service_url);
auth_md_context->service_url = NULL;
}
if (auth_md_context->method_name != NULL) {
gpr_free((char *)auth_md_context->method_name);
auth_md_context->method_name = NULL;
}
GRPC_AUTH_CONTEXT_UNREF(
(grpc_auth_context *)auth_md_context->channel_auth_context,
"grpc_auth_metadata_context");
auth_md_context->channel_auth_context = NULL;
}
static void bubble_up_error(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
@ -94,7 +103,7 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_transport_stream_op *op = &calld->op;
grpc_metadata_batch *mdb;
size_t i;
reset_service_url(calld);
reset_auth_metadata_context(&calld->auth_md_context);
if (status != GRPC_CREDENTIALS_OK) {
bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED,
"Credentials failed to get metadata.");
@ -112,9 +121,13 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_call_next_op(exec_ctx, elem, op);
}
void build_service_url(const char *url_scheme, call_data *calld) {
void build_auth_metadata_context(grpc_security_connector *sc,
call_data *calld) {
char *service = gpr_strdup(grpc_mdstr_as_c_string(calld->method));
char *last_slash = strrchr(service, '/');
char *method_name = NULL;
char *service_url = NULL;
reset_auth_metadata_context(&calld->auth_md_context);
if (last_slash == NULL) {
gpr_log(GPR_ERROR, "No '/' found in fully qualified method name");
service[0] = '\0';
@ -123,11 +136,16 @@ void build_service_url(const char *url_scheme, call_data *calld) {
service[1] = '\0';
} else {
*last_slash = '\0';
method_name = gpr_strdup(last_slash + 1);
}
if (url_scheme == NULL) url_scheme = "";
reset_service_url(calld);
gpr_asprintf(&calld->service_url, "%s://%s%s", url_scheme,
if (method_name == NULL) method_name = gpr_strdup("");
gpr_asprintf(&service_url, "%s://%s%s",
sc->url_scheme == NULL ? "" : sc->url_scheme,
grpc_mdstr_as_c_string(calld->host), service);
calld->auth_md_context.service_url = service_url;
calld->auth_md_context.method_name = method_name;
calld->auth_md_context.channel_auth_context =
GRPC_AUTH_CONTEXT_REF(sc->auth_context, "grpc_auth_metadata_context");
gpr_free(service);
}
@ -161,12 +179,12 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx,
call_creds_has_md ? ctx->creds : channel_call_creds);
}
build_service_url(chand->security_connector->base.url_scheme, calld);
build_auth_metadata_context(&chand->security_connector->base, calld);
calld->op = *op; /* Copy op (originates from the caller's stack). */
GPR_ASSERT(calld->pollset);
grpc_call_credentials_get_request_metadata(exec_ctx, calld->creds,
calld->pollset, calld->service_url,
on_credentials_metadata, elem);
grpc_call_credentials_get_request_metadata(
exec_ctx, calld->creds, calld->pollset, calld->auth_md_context,
on_credentials_metadata, elem);
}
static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data,
@ -280,7 +298,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
if (calld->method != NULL) {
GRPC_MDSTR_UNREF(calld->method);
}
reset_service_url(calld);
reset_auth_metadata_context(&calld->auth_md_context);
}
/* Constructor for channel_data */

@ -33,22 +33,21 @@
#include "src/core/security/credentials.h"
#include <string.h>
#include <stdio.h>
#include <string.h>
#include "src/core/channel/channel_args.h"
#include "src/core/channel/http_client_filter.h"
#include "src/core/json/json.h"
#include "src/core/httpcli/httpcli.h"
#include "src/core/iomgr/iomgr.h"
#include "src/core/surface/api_trace.h"
#include "src/core/iomgr/executor.h"
#include "src/core/json/json.h"
#include "src/core/support/string.h"
#include "src/core/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/thd.h>
#include <grpc/support/time.h>
/* -- Common. -- */
@ -116,19 +115,17 @@ void grpc_call_credentials_release(grpc_call_credentials *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,
const char *service_url,
grpc_credentials_metadata_cb cb,
void *user_data) {
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, service_url, cb,
creds->vtable->get_request_metadata(exec_ctx, creds, pollset, context, cb,
user_data);
}
@ -429,7 +426,7 @@ static void jwt_destruct(grpc_call_credentials *creds) {
static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds,
grpc_pollset *pollset,
const char *service_url,
grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb,
void *user_data) {
grpc_service_account_jwt_access_credentials *c =
@ -442,7 +439,7 @@ static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
{
gpr_mu_lock(&c->cache_mu);
if (c->cached.service_url != NULL &&
strcmp(c->cached.service_url, service_url) == 0 &&
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)),
@ -457,14 +454,15 @@ static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
/* Generate a new jwt. */
gpr_mu_lock(&c->cache_mu);
jwt_reset_cache(c);
jwt = grpc_jwt_encode_and_sign(&c->key, service_url, c->jwt_lifetime, NULL);
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(service_url);
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);
@ -512,10 +510,11 @@ grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
"grpc_service_account_jwt_access_credentials_create("
"json_key=%s, "
"token_lifetime="
"gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, "
"gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
5, (json_key, (long)token_lifetime.tv_sec, token_lifetime.tv_nsec,
(int)token_lifetime.clock_type, reserved));
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);
@ -649,7 +648,7 @@ static void on_oauth2_token_fetcher_http_response(
static void oauth2_token_fetcher_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
grpc_pollset *pollset, const char *service_url,
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;
@ -793,30 +792,27 @@ static void md_only_test_destruct(grpc_call_credentials *creds) {
grpc_credentials_md_store_unref(c->md_store);
}
static void on_simulated_token_fetch_done(void *user_data) {
static void on_simulated_token_fetch_done(grpc_exec_ctx *exec_ctx,
void *user_data, int 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;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
r->cb(&exec_ctx, r->user_data, c->md_store->entries, c->md_store->num_entries,
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);
grpc_exec_ctx_finish(&exec_ctx);
}
static void md_only_test_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds,
grpc_pollset *pollset,
const char *service_url,
grpc_credentials_metadata_cb cb,
void *user_data) {
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) {
gpr_thd_id thd_id;
grpc_credentials_metadata_request *cb_arg =
grpc_credentials_metadata_request_create(creds, cb, user_data);
gpr_thd_new(&thd_id, on_simulated_token_fetch_done, cb_arg, NULL);
grpc_executor_enqueue(
grpc_closure_create(on_simulated_token_fetch_done, cb_arg), 1);
} else {
cb(exec_ctx, user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK);
}
@ -846,12 +842,10 @@ static void access_token_destruct(grpc_call_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,
const char *service_url,
grpc_credentials_metadata_cb cb,
void *user_data) {
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);
}
@ -932,7 +926,7 @@ typedef struct {
grpc_composite_call_credentials *composite_creds;
size_t creds_index;
grpc_credentials_md_store *md_elems;
char *service_url;
grpc_auth_metadata_context auth_md_context;
void *user_data;
grpc_pollset *pollset;
grpc_credentials_metadata_cb cb;
@ -950,7 +944,6 @@ static void composite_call_destruct(grpc_call_credentials *creds) {
static void composite_call_md_context_destroy(
grpc_composite_call_credentials_metadata_context *ctx) {
grpc_credentials_md_store_unref(ctx->md_elems);
if (ctx->service_url != NULL) gpr_free(ctx->service_url);
gpr_free(ctx);
}
@ -978,9 +971,9 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
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->service_url,
composite_call_metadata_cb, ctx);
grpc_call_credentials_get_request_metadata(
exec_ctx, inner_creds, ctx->pollset, ctx->auth_md_context,
composite_call_metadata_cb, ctx);
return;
}
@ -990,26 +983,24 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
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,
const char *service_url,
grpc_credentials_metadata_cb cb,
void *user_data) {
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->service_url = gpr_strdup(service_url);
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, service_url,
composite_call_metadata_cb, ctx);
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 = {
@ -1103,7 +1094,7 @@ static void iam_destruct(grpc_call_credentials *creds) {
static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds,
grpc_pollset *pollset,
const char *service_url,
grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb,
void *user_data) {
grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
@ -1192,7 +1183,7 @@ static void plugin_md_request_metadata_ready(void *request,
static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds,
grpc_pollset *pollset,
const char *service_url,
grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb,
void *user_data) {
grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
@ -1201,7 +1192,7 @@ static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
memset(request, 0, sizeof(*request));
request->user_data = user_data;
request->cb = cb;
c->plugin.get_metadata(c->plugin.state, service_url,
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);
@ -1218,7 +1209,7 @@ grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
(reserved));
GPR_ASSERT(reserved == NULL);
memset(c, 0, sizeof(*c));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_METADATA_PLUGIN;
c->base.type = plugin.type;
c->base.vtable = &plugin_vtable;
gpr_ref_init(&c->base.refcount, 1);
c->plugin = plugin;

@ -59,7 +59,6 @@ typedef enum {
"FakeTransportSecurity"
#define GRPC_CALL_CREDENTIALS_TYPE_OAUTH2 "Oauth2"
#define GRPC_CALL_CREDENTIALS_TYPE_METADATA_PLUGIN "Plugin"
#define GRPC_CALL_CREDENTIALS_TYPE_JWT "Jwt"
#define GRPC_CALL_CREDENTIALS_TYPE_IAM "Iam"
#define GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE "Composite"
@ -94,6 +93,14 @@ typedef enum {
/* It is the caller's responsibility to gpr_free the result if not NULL. */
char *grpc_get_well_known_google_credentials_file_path(void);
/* Implementation function for the different platforms. */
char *grpc_get_well_known_google_credentials_file_path_impl(void);
/* Override for testing only. Not thread-safe */
typedef char *(*grpc_well_known_credentials_path_getter)(void);
void grpc_override_well_known_credentials_path_getter(
grpc_well_known_credentials_path_getter getter);
/* --- grpc_channel_credentials. --- */
typedef struct {
@ -162,7 +169,7 @@ typedef struct {
void (*destruct)(grpc_call_credentials *c);
void (*get_request_metadata)(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *c, grpc_pollset *pollset,
const char *service_url,
grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb,
void *user_data);
} grpc_call_credentials_vtable;
@ -175,12 +182,10 @@ struct grpc_call_credentials {
grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds);
void grpc_call_credentials_unref(grpc_call_credentials *creds);
void grpc_call_credentials_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds,
grpc_pollset *pollset,
const char *service_url,
grpc_credentials_metadata_cb cb,
void *user_data);
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);
typedef struct {
grpc_call_credentials **creds_array;
@ -204,6 +209,7 @@ grpc_credentials_status
grpc_oauth2_token_fetcher_credentials_parse_server_response(
const struct grpc_httpcli_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

@ -44,7 +44,7 @@
#include "src/core/support/env.h"
#include "src/core/support/string.h"
char *grpc_get_well_known_google_credentials_file_path(void) {
char *grpc_get_well_known_google_credentials_file_path_impl(void) {
char *result = NULL;
char *home = gpr_getenv("HOME");
if (home == NULL) {

@ -44,7 +44,7 @@
#include "src/core/support/env.h"
#include "src/core/support/string.h"
char *grpc_get_well_known_google_credentials_file_path(void) {
char *grpc_get_well_known_google_credentials_file_path_impl(void) {
char *result = NULL;
char *appdata_path = gpr_getenv("APPDATA");
if (appdata_path == NULL) {

@ -241,5 +241,20 @@ void grpc_flush_cached_google_default_credentials(void) {
grpc_channel_credentials_unref(default_credentials);
default_credentials = NULL;
}
compute_engine_detection_done = 0;
gpr_mu_unlock(&g_mu);
}
/* -- Well known credentials path. -- */
static grpc_well_known_credentials_path_getter creds_path_getter = NULL;
char *grpc_get_well_known_google_credentials_file_path(void) {
if (creds_path_getter != NULL) return creds_path_getter();
return grpc_get_well_known_google_credentials_file_path_impl();
}
void grpc_override_well_known_credentials_path_getter(
grpc_well_known_credentials_path_getter getter) {
creds_path_getter = getter;
}

@ -64,12 +64,39 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *setup,
int success);
static void security_connector_remove_handshake(grpc_security_handshake *h) {
grpc_security_connector_handshake_list *node;
grpc_security_connector_handshake_list *tmp;
grpc_security_connector *sc = h->connector;
gpr_mu_lock(&sc->mu);
node = sc->handshaking_handshakes;
if (node && node->handshake == h) {
sc->handshaking_handshakes = node->next;
gpr_free(node);
gpr_mu_unlock(&sc->mu);
return;
}
while (node) {
if (node->next->handshake == h) {
tmp = node->next;
node->next = node->next->next;
gpr_free(tmp);
gpr_mu_unlock(&sc->mu);
return;
}
node = node->next;
}
gpr_mu_unlock(&sc->mu);
}
static void security_handshake_done(grpc_exec_ctx *exec_ctx,
grpc_security_handshake *h,
int is_success) {
if (!h->connector->is_client_side) {
security_connector_remove_handshake(h);
}
if (is_success) {
h->cb(exec_ctx, h->user_data, GRPC_SECURITY_OK, h->wrapped_endpoint,
h->secure_endpoint);
h->cb(exec_ctx, h->user_data, GRPC_SECURITY_OK, h->secure_endpoint);
} else {
if (h->secure_endpoint != NULL) {
grpc_endpoint_shutdown(exec_ctx, h->secure_endpoint);
@ -77,8 +104,7 @@ static void security_handshake_done(grpc_exec_ctx *exec_ctx,
} else {
grpc_endpoint_destroy(exec_ctx, h->wrapped_endpoint);
}
h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, h->wrapped_endpoint,
NULL);
h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, NULL);
}
if (h->handshaker != NULL) tsi_handshaker_destroy(h->handshaker);
if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer);
@ -268,6 +294,7 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
grpc_security_connector_handshake_list *handshake_node;
grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake));
memset(h, 0, sizeof(grpc_security_handshake));
h->handshaker = handshaker;
@ -284,5 +311,19 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
gpr_slice_buffer_init(&h->left_overs);
gpr_slice_buffer_init(&h->outgoing);
gpr_slice_buffer_init(&h->incoming);
if (!connector->is_client_side) {
handshake_node = gpr_malloc(sizeof(grpc_security_connector_handshake_list));
handshake_node->handshake = h;
gpr_mu_lock(&connector->mu);
handshake_node->next = connector->handshaking_handshakes;
connector->handshaking_handshakes = handshake_node;
gpr_mu_unlock(&connector->mu);
}
send_handshake_bytes_to_peer(exec_ctx, h);
}
void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx,
void *handshake) {
grpc_security_handshake *h = handshake;
grpc_endpoint_shutdown(exec_ctx, h->wrapped_endpoint);
}

@ -45,4 +45,6 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
grpc_security_handshake_done_cb cb,
void *user_data);
void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake);
#endif /* GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H */

@ -215,8 +215,8 @@ static char *encoded_jwt_claim(const grpc_auth_json_key *json_key,
gpr_log(GPR_INFO, "Cropping token lifetime to maximum allowed value.");
expiration = gpr_time_add(now, grpc_max_auth_token_lifetime);
}
gpr_ltoa(now.tv_sec, now_str);
gpr_ltoa(expiration.tv_sec, expiration_str);
gpr_int64toa(now.tv_sec, now_str);
gpr_int64toa(expiration.tv_sec, expiration_str);
child =
create_child(NULL, json, "iss", json_key->client_email, GRPC_JSON_STRING);

@ -102,13 +102,29 @@ const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
return NULL;
}
void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx,
grpc_security_connector *connector) {
grpc_security_connector_handshake_list *tmp;
if (!connector->is_client_side) {
gpr_mu_lock(&connector->mu);
while (connector->handshaking_handshakes) {
tmp = connector->handshaking_handshakes;
grpc_security_handshake_shutdown(
exec_ctx, connector->handshaking_handshakes->handshake);
connector->handshaking_handshakes = tmp->next;
gpr_free(tmp);
}
gpr_mu_unlock(&connector->mu);
}
}
void grpc_security_connector_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data) {
if (sc == NULL || nonsecure_endpoint == NULL) {
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, nonsecure_endpoint, NULL);
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL);
} else {
sc->vtable->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data);
}
@ -219,6 +235,7 @@ static void fake_channel_destroy(grpc_security_connector *sc) {
static void fake_server_destroy(grpc_security_connector *sc) {
GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_mu_destroy(&sc->mu);
gpr_free(sc);
}
@ -319,6 +336,7 @@ grpc_security_connector *grpc_fake_server_security_connector_create(void) {
c->is_client_side = 0;
c->vtable = &fake_server_vtable;
c->url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
gpr_mu_init(&c->mu);
return c;
}
@ -354,10 +372,12 @@ static void ssl_channel_destroy(grpc_security_connector *sc) {
static void ssl_server_destroy(grpc_security_connector *sc) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)sc;
if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_mu_destroy(&sc->mu);
gpr_free(sc);
}
@ -390,7 +410,7 @@ static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
: c->target_name,
&handshaker);
if (status != GRPC_SECURITY_OK) {
cb(exec_ctx, user_data, status, nonsecure_endpoint, NULL);
cb(exec_ctx, user_data, status, NULL);
} else {
grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb,
user_data);
@ -408,7 +428,7 @@ static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_security_status status =
ssl_create_handshaker(c->handshaker_factory, 0, NULL, &handshaker);
if (status != GRPC_SECURITY_OK) {
cb(exec_ctx, user_data, status, nonsecure_endpoint, NULL);
cb(exec_ctx, user_data, status, NULL);
} else {
grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb,
user_data);
@ -691,6 +711,7 @@ grpc_security_status grpc_ssl_server_security_connector_create(
*sc = NULL;
goto error;
}
gpr_mu_init(&c->base.mu);
*sc = &c->base;
gpr_free((void *)alpn_protocol_strings);
gpr_free(alpn_protocol_string_lengths);

@ -67,7 +67,6 @@ typedef void (*grpc_security_check_cb)(grpc_exec_ctx *exec_ctx, void *user_data,
typedef void (*grpc_security_handshake_done_cb)(grpc_exec_ctx *exec_ctx,
void *user_data,
grpc_security_status status,
grpc_endpoint *wrapped_endpoint,
grpc_endpoint *secure_endpoint);
typedef struct {
@ -80,12 +79,22 @@ typedef struct {
void *user_data);
} grpc_security_connector_vtable;
typedef struct grpc_security_connector_handshake_list {
void *handshake;
struct grpc_security_connector_handshake_list *next;
} grpc_security_connector_handshake_list;
struct grpc_security_connector {
const grpc_security_connector_vtable *vtable;
gpr_refcount refcount;
int is_client_side;
const char *url_scheme;
grpc_auth_context *auth_context; /* Populated after the peer is checked. */
/* Used on server side only. */
/* TODO(yangg) maybe create a grpc_server_security_connector with these */
gpr_mu mu;
grpc_security_connector_handshake_list *handshaking_handshakes;
const grpc_channel_args *channel_args;
};
/* Refcounting. */
@ -126,6 +135,9 @@ grpc_security_status grpc_security_connector_check_peer(
grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb,
void *user_data);
void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx,
grpc_security_connector *connector);
/* Util to encapsulate the connector in a channel arg. */
grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc);

@ -52,17 +52,11 @@
#include <grpc/support/sync.h>
#include <grpc/support/useful.h>
typedef struct tcp_endpoint_list {
grpc_endpoint *tcp_endpoint;
struct tcp_endpoint_list *next;
} tcp_endpoint_list;
typedef struct grpc_server_secure_state {
grpc_server *server;
grpc_tcp_server *tcp;
grpc_security_connector *sc;
grpc_server_credentials *creds;
tcp_endpoint_list *handshaking_tcp_endpoints;
int is_shutdown;
gpr_mu mu;
gpr_refcount refcount;
@ -103,52 +97,28 @@ static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep,
grpc_channel_args_destroy(args_copy);
}
static int remove_tcp_from_list_locked(grpc_server_secure_state *state,
grpc_endpoint *tcp) {
tcp_endpoint_list *node = state->handshaking_tcp_endpoints;
tcp_endpoint_list *tmp = NULL;
if (node && node->tcp_endpoint == tcp) {
state->handshaking_tcp_endpoints = state->handshaking_tcp_endpoints->next;
gpr_free(node);
return 0;
}
while (node) {
if (node->next->tcp_endpoint == tcp) {
tmp = node->next;
node->next = node->next->next;
gpr_free(tmp);
return 0;
}
node = node->next;
}
return -1;
}
static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
grpc_security_status status,
grpc_endpoint *wrapped_endpoint,
grpc_endpoint *secure_endpoint) {
grpc_server_secure_state *state = statep;
grpc_transport *transport;
if (status == GRPC_SECURITY_OK) {
gpr_mu_lock(&state->mu);
remove_tcp_from_list_locked(state, wrapped_endpoint);
if (!state->is_shutdown) {
transport = grpc_create_chttp2_transport(
exec_ctx, grpc_server_get_channel_args(state->server),
secure_endpoint, 0);
setup_transport(exec_ctx, state, transport);
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
} else {
/* We need to consume this here, because the server may already have gone
* away. */
grpc_endpoint_destroy(exec_ctx, secure_endpoint);
if (secure_endpoint) {
gpr_mu_lock(&state->mu);
if (!state->is_shutdown) {
transport = grpc_create_chttp2_transport(
exec_ctx, grpc_server_get_channel_args(state->server),
secure_endpoint, 0);
setup_transport(exec_ctx, state, transport);
grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
} else {
/* We need to consume this here, because the server may already have
* gone away. */
grpc_endpoint_destroy(exec_ctx, secure_endpoint);
}
gpr_mu_unlock(&state->mu);
}
gpr_mu_unlock(&state->mu);
} else {
gpr_mu_lock(&state->mu);
remove_tcp_from_list_locked(state, wrapped_endpoint);
gpr_mu_unlock(&state->mu);
gpr_log(GPR_ERROR, "Secure transport failed with error %d", status);
}
state_unref(state);
@ -157,14 +127,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
static void on_accept(grpc_exec_ctx *exec_ctx, void *statep,
grpc_endpoint *tcp) {
grpc_server_secure_state *state = statep;
tcp_endpoint_list *node;
state_ref(state);
node = gpr_malloc(sizeof(tcp_endpoint_list));
node->tcp_endpoint = tcp;
gpr_mu_lock(&state->mu);
node->next = state->handshaking_tcp_endpoints;
state->handshaking_tcp_endpoints = node;
gpr_mu_unlock(&state->mu);
grpc_security_connector_do_handshake(exec_ctx, state->sc, tcp,
on_secure_handshake_done, state);
}
@ -181,14 +144,7 @@ static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep, int success) {
grpc_server_secure_state *state = statep;
state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg,
success);
gpr_mu_lock(&state->mu);
while (state->handshaking_tcp_endpoints != NULL) {
grpc_endpoint_shutdown(exec_ctx,
state->handshaking_tcp_endpoints->tcp_endpoint);
remove_tcp_from_list_locked(state,
state->handshaking_tcp_endpoints->tcp_endpoint);
}
gpr_mu_unlock(&state->mu);
grpc_security_connector_shutdown(exec_ctx, state->sc);
state_unref(state);
}
@ -234,6 +190,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
creds->type);
goto error;
}
sc->channel_args = grpc_server_get_channel_args(server);
/* resolve address */
resolved = grpc_blocking_resolve_address(addr, "https");
@ -252,7 +209,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
tcp, (struct sockaddr *)&resolved->addrs[i].addr,
resolved->addrs[i].len);
port_temp = grpc_tcp_listener_get_port(listener);
if (port_temp >= 0) {
if (port_temp > 0) {
if (port_num == -1) {
port_num = port_temp;
} else {
@ -280,7 +237,6 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
state->sc = sc;
state->creds = grpc_server_credentials_ref(creds);
state->handshaking_tcp_endpoints = NULL;
state->is_shutdown = 0;
gpr_mu_init(&state->mu);
gpr_ref_init(&state->refcount, 1);

@ -94,7 +94,7 @@ static gpr_int64 timespec_to_ns(const gpr_timespec ts) {
if (ts.tv_sec > max_seconds) {
return GPR_INT64_MAX - 1;
}
return (gpr_int64)ts.tv_sec * GPR_NS_PER_SEC + ts.tv_nsec;
return ts.tv_sec * GPR_NS_PER_SEC + ts.tv_nsec;
}
static void cws_initialize_statistic(void *statistic,

@ -34,13 +34,27 @@
#include <grpc/support/alloc.h>
#include <stdlib.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include "src/core/profiling/timers.h"
static gpr_allocation_functions g_alloc_functions = {malloc, realloc, free};
gpr_allocation_functions gpr_get_allocation_functions() {
return g_alloc_functions;
}
void gpr_set_allocation_functions(gpr_allocation_functions functions) {
GPR_ASSERT(functions.malloc_fn != NULL);
GPR_ASSERT(functions.realloc_fn != NULL);
GPR_ASSERT(functions.free_fn != NULL);
g_alloc_functions = functions;
}
void *gpr_malloc(size_t size) {
void *p;
GPR_TIMER_BEGIN("gpr_malloc", 0);
p = malloc(size);
p = g_alloc_functions.malloc_fn(size);
if (!p) {
abort();
}
@ -50,13 +64,13 @@ void *gpr_malloc(size_t size) {
void gpr_free(void *p) {
GPR_TIMER_BEGIN("gpr_free", 0);
free(p);
g_alloc_functions.free_fn(p);
GPR_TIMER_END("gpr_free", 0);
}
void *gpr_realloc(void *p, size_t size) {
GPR_TIMER_BEGIN("gpr_realloc", 0);
p = realloc(p, size);
p = g_alloc_functions.realloc_fn(p, size);
if (!p) {
abort();
}

@ -62,11 +62,13 @@ struct gpr_cmdline {
void (*extra_arg)(void *user_data, const char *arg);
void *extra_arg_user_data;
void (*state)(gpr_cmdline *cl, char *arg);
int (*state)(gpr_cmdline *cl, char *arg);
arg *cur_arg;
int survive_failure;
};
static void normal_state(gpr_cmdline *cl, char *arg);
static int normal_state(gpr_cmdline *cl, char *arg);
gpr_cmdline *gpr_cmdline_create(const char *description) {
gpr_cmdline *cl = gpr_malloc(sizeof(gpr_cmdline));
@ -78,6 +80,10 @@ gpr_cmdline *gpr_cmdline_create(const char *description) {
return cl;
}
void gpr_cmdline_set_survive_failure(gpr_cmdline *cl) {
cl->survive_failure = 1;
}
void gpr_cmdline_destroy(gpr_cmdline *cl) {
while (cl->args) {
arg *a = cl->args;
@ -185,16 +191,22 @@ char *gpr_cmdline_usage_string(gpr_cmdline *cl, const char *argv0) {
return tmp;
}
static void print_usage_and_die(gpr_cmdline *cl) {
static int print_usage_and_die(gpr_cmdline *cl) {
char *usage = gpr_cmdline_usage_string(cl, cl->argv0);
fprintf(stderr, "%s", usage);
gpr_free(usage);
exit(1);
if (!cl->survive_failure) {
exit(1);
}
return 0;
}
static void extra_state(gpr_cmdline *cl, char *str) {
if (!cl->extra_arg) print_usage_and_die(cl);
static int extra_state(gpr_cmdline *cl, char *str) {
if (!cl->extra_arg) {
return print_usage_and_die(cl);
}
cl->extra_arg(cl->extra_arg_user_data, str);
return 1;
}
static arg *find_arg(gpr_cmdline *cl, char *name) {
@ -208,13 +220,13 @@ static arg *find_arg(gpr_cmdline *cl, char *name) {
if (!a) {
fprintf(stderr, "Unknown argument: %s\n", name);
print_usage_and_die(cl);
return NULL;
}
return a;
}
static void value_state(gpr_cmdline *cl, char *str) {
static int value_state(gpr_cmdline *cl, char *str) {
long intval;
char *end;
@ -226,7 +238,7 @@ static void value_state(gpr_cmdline *cl, char *str) {
if (*end || intval < INT_MIN || intval > INT_MAX) {
fprintf(stderr, "expected integer, got '%s' for %s\n", str,
cl->cur_arg->name);
print_usage_and_die(cl);
return print_usage_and_die(cl);
}
*(int *)cl->cur_arg->value = (int)intval;
break;
@ -238,7 +250,7 @@ static void value_state(gpr_cmdline *cl, char *str) {
} else {
fprintf(stderr, "expected boolean, got '%s' for %s\n", str,
cl->cur_arg->name);
print_usage_and_die(cl);
return print_usage_and_die(cl);
}
break;
case ARGTYPE_STRING:
@ -247,16 +259,18 @@ static void value_state(gpr_cmdline *cl, char *str) {
}
cl->state = normal_state;
return 1;
}
static void normal_state(gpr_cmdline *cl, char *str) {
static int normal_state(gpr_cmdline *cl, char *str) {
char *eq = NULL;
char *tmp = NULL;
char *arg_name = NULL;
int r = 1;
if (0 == strcmp(str, "-help") || 0 == strcmp(str, "--help") ||
0 == strcmp(str, "-h")) {
print_usage_and_die(cl);
return print_usage_and_die(cl);
}
cl->cur_arg = NULL;
@ -266,7 +280,7 @@ static void normal_state(gpr_cmdline *cl, char *str) {
if (str[2] == 0) {
/* handle '--' to move to just extra args */
cl->state = extra_state;
return;
return 1;
}
str += 2;
} else {
@ -277,12 +291,15 @@ static void normal_state(gpr_cmdline *cl, char *str) {
/* str is of the form '--no-foo' - it's a flag disable */
str += 3;
cl->cur_arg = find_arg(cl, str);
if (cl->cur_arg == NULL) {
return print_usage_and_die(cl);
}
if (cl->cur_arg->type != ARGTYPE_BOOL) {
fprintf(stderr, "%s is not a flag argument\n", str);
print_usage_and_die(cl);
return print_usage_and_die(cl);
}
*(int *)cl->cur_arg->value = 0;
return; /* early out */
return 1; /* early out */
}
eq = strchr(str, '=');
if (eq != NULL) {
@ -294,9 +311,12 @@ static void normal_state(gpr_cmdline *cl, char *str) {
arg_name = str;
}
cl->cur_arg = find_arg(cl, arg_name);
if (cl->cur_arg == NULL) {
return print_usage_and_die(cl);
}
if (eq != NULL) {
/* str was of the type --foo=value, parse the value */
value_state(cl, eq + 1);
r = value_state(cl, eq + 1);
} else if (cl->cur_arg->type != ARGTYPE_BOOL) {
/* flag types don't have a '--foo value' variant, other types do */
cl->state = value_state;
@ -305,19 +325,23 @@ static void normal_state(gpr_cmdline *cl, char *str) {
*(int *)cl->cur_arg->value = 1;
}
} else {
extra_state(cl, str);
r = extra_state(cl, str);
}
gpr_free(tmp);
return r;
}
void gpr_cmdline_parse(gpr_cmdline *cl, int argc, char **argv) {
int gpr_cmdline_parse(gpr_cmdline *cl, int argc, char **argv) {
int i;
GPR_ASSERT(argc >= 1);
cl->argv0 = argv[0];
for (i = 1; i < argc; i++) {
cl->state(cl, argv[i]);
if (!cl->state(cl, argv[i])) {
return 0;
}
}
return 1;
}

@ -32,6 +32,7 @@
*/
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <stdio.h>
#include <string.h>
@ -48,7 +49,7 @@ const char *gpr_log_severity_string(gpr_log_severity severity) {
case GPR_LOG_SEVERITY_ERROR:
return "E";
}
return "UNKNOWN";
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
void gpr_log_message(const char *file, int line, gpr_log_severity severity,

@ -76,16 +76,18 @@ void gpr_default_log(gpr_log_func_args *args) {
char *prefix;
const char *display_file;
char time_buffer[64];
time_t timer;
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
struct tm tm;
timer = (time_t)now.tv_sec;
final_slash = strrchr(args->file, '/');
if (final_slash == NULL)
display_file = args->file;
else
display_file = final_slash + 1;
if (!localtime_r(&now.tv_sec, &tm)) {
if (!localtime_r(&timer, &tm)) {
strcpy(time_buffer, "error:localtime");
} else if (0 ==
strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) {

@ -75,16 +75,18 @@ void gpr_default_log(gpr_log_func_args *args) {
char *final_slash;
const char *display_file;
char time_buffer[64];
time_t timer;
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
struct tm tm;
timer = (time_t)now.tv_sec;
final_slash = strrchr(args->file, '/');
if (final_slash == NULL)
display_file = args->file;
else
display_file = final_slash + 1;
if (!localtime_r(&now.tv_sec, &tm)) {
if (!localtime_r(&timer, &tm)) {
strcpy(time_buffer, "error:localtime");
} else if (0 ==
strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) {

@ -84,16 +84,18 @@ void gpr_default_log(gpr_log_func_args *args) {
char *final_slash;
const char *display_file;
char time_buffer[64];
time_t timer;
gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
struct tm tm;
timer = (time_t)now.tv_sec;
final_slash = strrchr(args->file, '\\');
if (final_slash == NULL)
display_file = args->file;
else
display_file = final_slash + 1;
if (localtime_s(&tm, &now.tv_sec)) {
if (localtime_s(&tm, &timer)) {
strcpy(time_buffer, "error:localtime");
} else if (0 ==
strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) {

@ -341,10 +341,3 @@ int gpr_slice_str_cmp(gpr_slice a, const char *b) {
if (d != 0) return d;
return memcmp(GPR_SLICE_START_PTR(a), b, b_length);
}
char *gpr_slice_to_cstring(gpr_slice slice) {
char *result = gpr_malloc(GPR_SLICE_LENGTH(slice) + 1);
memcpy(result, GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice));
result[GPR_SLICE_LENGTH(slice)] = '\0';
return result;
}

@ -128,8 +128,8 @@ int gpr_stack_lockfree_push(gpr_stack_lockfree *stack, int entry) {
gpr_atm old_val;
old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index],
(gpr_atm)(1UL << pushed_bit));
GPR_ASSERT((old_val & (gpr_atm)(1UL << pushed_bit)) == 0);
((gpr_atm)1 << pushed_bit));
GPR_ASSERT((old_val & (((gpr_atm)1) << pushed_bit)) == 0);
}
#endif
@ -166,8 +166,8 @@ int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack) {
gpr_atm old_val;
old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index],
-(gpr_atm)(1UL << pushed_bit));
GPR_ASSERT((old_val & (gpr_atm)(1UL << pushed_bit)) != 0);
-((gpr_atm)1 << pushed_bit));
GPR_ASSERT((old_val & (((gpr_atm)1) << pushed_bit)) != 0);
}
#endif

@ -153,8 +153,8 @@ void gpr_reverse_bytes(char *str, int len) {
}
int gpr_ltoa(long value, char *string) {
long sign;
int i = 0;
int neg = value < 0;
if (value == 0) {
string[0] = '0';
@ -162,12 +162,33 @@ int gpr_ltoa(long value, char *string) {
return 1;
}
if (neg) value = -value;
sign = value < 0 ? -1 : 1;
while (value) {
string[i++] = (char)('0' + value % 10);
string[i++] = (char)('0' + sign * (value % 10));
value /= 10;
}
if (neg) string[i++] = '-';
if (sign < 0) string[i++] = '-';
gpr_reverse_bytes(string, i);
string[i] = 0;
return i;
}
int gpr_int64toa(gpr_int64 value, char *string) {
gpr_int64 sign;
int i = 0;
if (value == 0) {
string[0] = '0';
string[1] = 0;
return 1;
}
sign = value < 0 ? -1 : 1;
while (value) {
string[i++] = (char)('0' + sign * (value % 10));
value /= 10;
}
if (sign < 0) string[i++] = '-';
gpr_reverse_bytes(string, i);
string[i] = 0;
return i;

@ -70,6 +70,16 @@ int gpr_parse_bytes_to_uint32(const char *data, size_t length,
output must be at least GPR_LTOA_MIN_BUFSIZE bytes long. */
int gpr_ltoa(long value, char *output);
/* Minimum buffer size for calling int64toa */
#define GPR_INT64TOA_MIN_BUFSIZE (3 * sizeof(gpr_int64))
/* Convert an int64 to a string in base 10; returns the length of the
output string (or 0 on failure).
output must be at least GPR_INT64TOA_MIN_BUFSIZE bytes long.
NOTE: This function ensures sufficient bit width even on Win x64,
where long is 32bit is size.*/
int gpr_int64toa(gpr_int64 value, char *output);
/* Reverse a run of bytes */
void gpr_reverse_bytes(char *str, int len);

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

Loading…
Cancel
Save