grpc 1.6.7 → 1.7.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (277) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +579 -77
  3. data/include/grpc/byte_buffer.h +1 -63
  4. data/include/grpc/compression.h +27 -5
  5. data/include/grpc/fork.h +24 -0
  6. data/include/grpc/grpc.h +12 -6
  7. data/include/grpc/grpc_security.h +28 -7
  8. data/include/grpc/impl/codegen/atm.h +1 -0
  9. data/include/grpc/impl/codegen/byte_buffer.h +86 -0
  10. data/include/grpc/impl/codegen/compression_types.h +63 -5
  11. data/include/grpc/impl/codegen/fork.h +48 -0
  12. data/include/grpc/impl/codegen/grpc_types.h +26 -9
  13. data/include/grpc/impl/codegen/port_platform.h +11 -4
  14. data/include/grpc/impl/codegen/slice.h +6 -1
  15. data/include/grpc/impl/codegen/sync.h +3 -1
  16. data/include/grpc/impl/codegen/sync_custom.h +36 -0
  17. data/include/grpc/module.modulemap +75 -3
  18. data/include/grpc/slice.h +1 -5
  19. data/include/grpc/support/sync_custom.h +24 -0
  20. data/src/core/ext/census/base_resources.c +14 -14
  21. data/src/core/ext/census/context.c +7 -5
  22. data/src/core/ext/census/grpc_filter.c +12 -14
  23. data/src/core/ext/census/mlog.c +2 -1
  24. data/src/core/ext/census/resource.c +13 -9
  25. data/src/core/ext/filters/client_channel/channel_connectivity.c +15 -8
  26. data/src/core/ext/filters/client_channel/client_channel.c +418 -439
  27. data/src/core/ext/filters/client_channel/client_channel_factory.c +4 -5
  28. data/src/core/ext/filters/client_channel/client_channel_plugin.c +2 -2
  29. data/src/core/ext/filters/client_channel/http_connect_handshaker.c +7 -5
  30. data/src/core/ext/filters/client_channel/http_proxy.c +17 -21
  31. data/src/core/ext/filters/client_channel/lb_policy.c +1 -1
  32. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c +7 -7
  33. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c +371 -257
  34. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c +7 -5
  35. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c +25 -14
  36. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c +16 -16
  37. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c +33 -28
  38. data/src/core/ext/filters/client_channel/lb_policy_factory.c +10 -8
  39. data/src/core/ext/filters/client_channel/lb_policy_factory.h +1 -1
  40. data/src/core/ext/filters/client_channel/proxy_mapper_registry.c +1 -1
  41. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c +7 -6
  42. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c +62 -28
  43. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c +29 -23
  44. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c +25 -14
  45. data/src/core/ext/filters/client_channel/retry_throttle.c +9 -6
  46. data/src/core/ext/filters/client_channel/subchannel.c +30 -30
  47. data/src/core/ext/filters/client_channel/subchannel.h +1 -4
  48. data/src/core/ext/filters/client_channel/subchannel_index.c +31 -15
  49. data/src/core/ext/filters/client_channel/subchannel_index.h +7 -0
  50. data/src/core/ext/filters/client_channel/uri_parser.c +4 -3
  51. data/src/core/ext/filters/deadline/deadline_filter.c +78 -39
  52. data/src/core/ext/filters/deadline/deadline_filter.h +7 -1
  53. data/src/core/ext/filters/http/client/http_client_filter.c +14 -14
  54. data/src/core/ext/filters/http/http_filters_plugin.c +1 -1
  55. data/src/core/ext/filters/http/message_compress/message_compress_filter.c +240 -175
  56. data/src/core/ext/filters/http/server/http_server_filter.c +48 -36
  57. data/src/core/ext/filters/load_reporting/{load_reporting_filter.c → server_load_reporting_filter.c} +11 -12
  58. data/src/core/ext/filters/load_reporting/{load_reporting_filter.h → server_load_reporting_filter.h} +6 -5
  59. data/src/core/ext/filters/load_reporting/{load_reporting.c → server_load_reporting_plugin.c} +19 -13
  60. data/src/core/ext/filters/load_reporting/{load_reporting.h → server_load_reporting_plugin.h} +4 -3
  61. data/src/core/ext/filters/max_age/max_age_filter.c +2 -3
  62. data/src/core/ext/filters/message_size/message_size_filter.c +4 -2
  63. data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c +0 -1
  64. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +5 -5
  65. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +1 -1
  66. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c +1 -1
  67. data/src/core/ext/transport/chttp2/server/chttp2_server.c +20 -18
  68. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +1 -0
  69. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +493 -210
  70. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +1 -0
  71. data/src/core/ext/transport/chttp2/transport/flow_control.c +9 -8
  72. data/src/core/ext/transport/chttp2/transport/frame_data.c +2 -2
  73. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +2 -2
  74. data/src/core/ext/transport/chttp2/transport/frame_ping.c +5 -4
  75. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +1 -1
  76. data/src/core/ext/transport/chttp2/transport/frame_settings.c +10 -9
  77. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +9 -5
  78. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +62 -41
  79. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +52 -8
  80. data/src/core/ext/transport/chttp2/transport/hpack_table.c +2 -2
  81. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +3 -2
  82. data/src/core/ext/transport/chttp2/transport/internal.h +60 -30
  83. data/src/core/ext/transport/chttp2/transport/parsing.c +16 -5
  84. data/src/core/ext/transport/chttp2/transport/stream_lists.c +36 -16
  85. data/src/core/ext/transport/chttp2/transport/stream_map.c +6 -4
  86. data/src/core/ext/transport/chttp2/transport/writing.c +133 -105
  87. data/src/core/ext/transport/inproc/inproc_transport.c +61 -65
  88. data/src/core/lib/channel/channel_args.c +112 -12
  89. data/src/core/lib/channel/channel_args.h +31 -0
  90. data/src/core/lib/channel/channel_stack.c +1 -15
  91. data/src/core/lib/channel/channel_stack.h +3 -10
  92. data/src/core/lib/channel/channel_stack_builder.c +41 -10
  93. data/src/core/lib/channel/channel_stack_builder.h +10 -0
  94. data/src/core/lib/channel/connected_channel.c +94 -23
  95. data/src/core/lib/channel/handshaker.c +8 -6
  96. data/src/core/lib/channel/handshaker_registry.c +1 -1
  97. data/src/core/lib/compression/algorithm_metadata.h +14 -0
  98. data/src/core/lib/compression/compression.c +101 -1
  99. data/src/core/lib/compression/stream_compression.c +32 -146
  100. data/src/core/lib/compression/stream_compression.h +28 -4
  101. data/src/core/lib/compression/stream_compression_gzip.c +228 -0
  102. data/src/core/lib/{iomgr/ev_epoll_thread_pool_linux.h → compression/stream_compression_gzip.h} +5 -7
  103. data/src/core/lib/compression/stream_compression_identity.c +94 -0
  104. data/src/core/lib/{iomgr/ev_epoll_limited_pollers_linux.h → compression/stream_compression_identity.h} +7 -8
  105. data/src/core/lib/debug/stats.c +174 -0
  106. data/src/core/lib/debug/stats.h +61 -0
  107. data/src/core/lib/debug/stats_data.c +687 -0
  108. data/src/core/lib/debug/stats_data.h +470 -0
  109. data/src/core/lib/debug/trace.c +3 -3
  110. data/src/core/lib/debug/trace.h +1 -1
  111. data/src/core/lib/http/format_request.c +1 -1
  112. data/src/core/lib/http/httpcli.c +8 -7
  113. data/src/core/lib/http/httpcli_security_connector.c +2 -1
  114. data/src/core/lib/http/parser.c +4 -3
  115. data/src/core/lib/iomgr/call_combiner.c +202 -0
  116. data/src/core/lib/iomgr/call_combiner.h +121 -0
  117. data/src/core/lib/iomgr/closure.c +18 -4
  118. data/src/core/lib/iomgr/combiner.c +11 -4
  119. data/src/core/lib/iomgr/error.c +26 -24
  120. data/src/core/lib/iomgr/ev_epoll1_linux.c +395 -212
  121. data/src/core/lib/iomgr/ev_epollex_linux.c +141 -128
  122. data/src/core/lib/iomgr/ev_epollsig_linux.c +44 -41
  123. data/src/core/lib/iomgr/ev_poll_posix.c +99 -75
  124. data/src/core/lib/iomgr/ev_posix.c +5 -9
  125. data/src/core/lib/iomgr/ev_posix.h +1 -1
  126. data/src/core/lib/iomgr/exec_ctx.h +6 -1
  127. data/src/core/lib/iomgr/executor.c +142 -36
  128. data/src/core/lib/iomgr/executor.h +6 -1
  129. data/src/core/lib/iomgr/fork_posix.c +88 -0
  130. data/src/core/lib/iomgr/fork_windows.c +39 -0
  131. data/src/core/lib/iomgr/iocp_windows.c +2 -0
  132. data/src/core/lib/iomgr/iomgr.c +2 -8
  133. data/src/core/lib/iomgr/is_epollexclusive_available.c +6 -6
  134. data/src/core/lib/iomgr/load_file.c +2 -1
  135. data/src/core/lib/iomgr/polling_entity.c +9 -9
  136. data/src/core/lib/iomgr/polling_entity.h +7 -1
  137. data/src/core/lib/iomgr/pollset.h +1 -1
  138. data/src/core/lib/iomgr/pollset_uv.c +1 -1
  139. data/src/core/lib/iomgr/pollset_windows.c +3 -3
  140. data/src/core/lib/iomgr/port.h +4 -0
  141. data/src/core/lib/iomgr/resolve_address_posix.c +8 -7
  142. data/src/core/lib/iomgr/resolve_address_windows.c +1 -1
  143. data/src/core/lib/iomgr/resource_quota.c +24 -19
  144. data/src/core/lib/iomgr/socket_factory_posix.c +4 -4
  145. data/src/core/lib/iomgr/socket_mutator.c +4 -4
  146. data/src/core/lib/iomgr/socket_utils_windows.c +0 -4
  147. data/src/core/lib/iomgr/tcp_client_posix.c +5 -4
  148. data/src/core/lib/iomgr/tcp_posix.c +181 -20
  149. data/src/core/lib/iomgr/tcp_server_posix.c +8 -7
  150. data/src/core/lib/iomgr/tcp_server_utils_posix_common.c +1 -1
  151. data/src/core/lib/iomgr/timer.h +4 -0
  152. data/src/core/lib/iomgr/timer_generic.c +138 -3
  153. data/src/core/lib/iomgr/timer_generic.h +3 -0
  154. data/src/core/lib/iomgr/timer_heap.c +4 -4
  155. data/src/core/lib/iomgr/timer_manager.c +2 -2
  156. data/src/core/lib/iomgr/timer_uv.c +2 -0
  157. data/src/core/lib/iomgr/udp_server.c +10 -8
  158. data/src/core/lib/iomgr/unix_sockets_posix.c +4 -2
  159. data/src/core/lib/iomgr/wakeup_fd_cv.c +9 -8
  160. data/src/core/lib/iomgr/wakeup_fd_cv.h +2 -2
  161. data/src/core/lib/json/json.c +1 -1
  162. data/src/core/lib/json/json_string.c +13 -13
  163. data/src/core/lib/profiling/timers.h +18 -8
  164. data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -10
  165. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +2 -1
  166. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +11 -6
  167. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +4 -4
  168. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +132 -50
  169. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +2 -0
  170. data/src/core/lib/security/transport/client_auth_filter.c +68 -135
  171. data/src/core/lib/security/transport/secure_endpoint.c +110 -90
  172. data/src/core/lib/security/transport/secure_endpoint.h +8 -3
  173. data/src/core/lib/security/transport/security_connector.c +10 -12
  174. data/src/core/lib/security/transport/security_handshaker.c +45 -24
  175. data/src/core/lib/security/transport/server_auth_filter.c +71 -20
  176. data/src/core/lib/slice/b64.c +2 -2
  177. data/src/core/lib/slice/slice.c +16 -14
  178. data/src/core/lib/slice/slice_buffer.c +5 -4
  179. data/src/core/lib/slice/slice_hash_table.c +3 -2
  180. data/src/core/lib/slice/slice_intern.c +8 -5
  181. data/src/core/lib/support/block_annotate.h +22 -0
  182. data/src/core/lib/support/fork.c +62 -0
  183. data/src/core/lib/support/fork.h +35 -0
  184. data/src/core/lib/support/log_linux.c +1 -1
  185. data/src/core/lib/support/string.c +15 -1
  186. data/src/core/lib/support/string.h +3 -0
  187. data/src/core/lib/support/thd_internal.h +6 -0
  188. data/src/core/lib/support/thd_posix.c +56 -0
  189. data/src/core/lib/support/thd_windows.c +2 -0
  190. data/src/core/lib/surface/alarm.c +22 -15
  191. data/src/core/lib/surface/byte_buffer.c +4 -2
  192. data/src/core/lib/surface/call.c +442 -141
  193. data/src/core/lib/surface/call.h +6 -6
  194. data/src/core/lib/surface/call_log_batch.c +1 -1
  195. data/src/core/lib/surface/call_test_only.h +12 -0
  196. data/src/core/lib/surface/channel.c +39 -4
  197. data/src/core/lib/surface/channel_init.c +6 -6
  198. data/src/core/lib/surface/channel_ping.c +2 -2
  199. data/src/core/lib/surface/completion_queue.c +56 -57
  200. data/src/core/lib/surface/init.c +17 -3
  201. data/src/core/lib/surface/init_secure.c +5 -1
  202. data/src/core/lib/surface/lame_client.cc +9 -10
  203. data/src/core/lib/surface/server.c +81 -72
  204. data/src/core/lib/surface/version.c +2 -2
  205. data/src/core/lib/transport/byte_stream.c +1 -0
  206. data/src/core/lib/transport/byte_stream.h +3 -1
  207. data/src/core/lib/transport/connectivity_state.c +2 -1
  208. data/src/core/lib/transport/metadata.c +7 -4
  209. data/src/core/lib/transport/metadata_batch.c +18 -16
  210. data/src/core/lib/transport/metadata_batch.h +1 -0
  211. data/src/core/lib/transport/service_config.c +5 -3
  212. data/src/core/lib/transport/static_metadata.c +395 -614
  213. data/src/core/lib/transport/static_metadata.h +165 -133
  214. data/src/core/lib/transport/status_conversion.c +1 -1
  215. data/src/core/lib/transport/transport.c +20 -20
  216. data/src/core/lib/transport/transport.h +8 -5
  217. data/src/core/lib/transport/transport_impl.h +0 -3
  218. data/src/core/lib/transport/transport_op_string.c +8 -1
  219. data/src/core/plugin_registry/grpc_plugin_registry.c +4 -4
  220. data/src/core/tsi/fake_transport_security.c +133 -2
  221. data/src/core/tsi/fake_transport_security.h +5 -0
  222. data/src/core/tsi/ssl_transport_security.c +105 -8
  223. data/src/core/tsi/ssl_transport_security.h +30 -7
  224. data/src/core/tsi/transport_security.h +8 -2
  225. data/src/core/tsi/transport_security_grpc.c +20 -13
  226. data/src/core/tsi/transport_security_grpc.h +13 -9
  227. data/src/ruby/ext/grpc/rb_call_credentials.c +6 -2
  228. data/src/ruby/ext/grpc/rb_grpc.c +1 -1
  229. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +30 -20
  230. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +50 -35
  231. data/src/ruby/lib/grpc.rb +1 -0
  232. data/src/ruby/lib/grpc/generic/active_call.rb +34 -9
  233. data/src/ruby/lib/grpc/generic/bidi_call.rb +19 -10
  234. data/src/ruby/lib/grpc/generic/client_stub.rb +95 -38
  235. data/src/ruby/lib/grpc/generic/interceptor_registry.rb +53 -0
  236. data/src/ruby/lib/grpc/generic/interceptors.rb +186 -0
  237. data/src/ruby/lib/grpc/generic/rpc_desc.rb +66 -20
  238. data/src/ruby/lib/grpc/generic/rpc_server.rb +15 -3
  239. data/src/ruby/lib/grpc/google_rpc_status_utils.rb +1 -2
  240. data/src/ruby/lib/grpc/version.rb +1 -1
  241. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb +1 -0
  242. data/src/ruby/spec/channel_connection_spec.rb +1 -34
  243. data/src/ruby/spec/client_server_spec.rb +188 -82
  244. data/src/ruby/spec/generic/active_call_spec.rb +65 -11
  245. data/src/ruby/spec/generic/client_interceptors_spec.rb +153 -0
  246. data/src/ruby/spec/generic/interceptor_registry_spec.rb +65 -0
  247. data/src/ruby/spec/generic/rpc_desc_spec.rb +38 -0
  248. data/src/ruby/spec/generic/rpc_server_spec.rb +1 -34
  249. data/src/ruby/spec/generic/server_interceptors_spec.rb +218 -0
  250. data/src/ruby/spec/spec_helper.rb +4 -0
  251. data/src/ruby/spec/support/helpers.rb +73 -0
  252. data/src/ruby/spec/support/services.rb +147 -0
  253. data/third_party/cares/ares_build.h +21 -62
  254. data/third_party/cares/cares/ares.h +23 -1
  255. data/third_party/cares/cares/ares__close_sockets.c +2 -2
  256. data/third_party/cares/cares/ares_create_query.c +3 -3
  257. data/third_party/cares/cares/ares_expand_name.c +6 -2
  258. data/third_party/cares/cares/ares_expand_string.c +1 -1
  259. data/third_party/cares/cares/ares_getnameinfo.c +27 -7
  260. data/third_party/cares/cares/ares_init.c +407 -39
  261. data/third_party/cares/cares/ares_library_init.c +10 -0
  262. data/third_party/cares/cares/ares_library_init.h +2 -1
  263. data/third_party/cares/cares/ares_nowarn.c +6 -6
  264. data/third_party/cares/cares/ares_nowarn.h +2 -2
  265. data/third_party/cares/cares/ares_parse_naptr_reply.c +6 -1
  266. data/third_party/cares/cares/ares_private.h +11 -0
  267. data/third_party/cares/cares/ares_process.c +126 -37
  268. data/third_party/cares/cares/ares_version.h +2 -2
  269. data/third_party/cares/cares/ares_writev.c +2 -2
  270. data/third_party/cares/cares/config-win32.h +8 -34
  271. data/third_party/cares/cares/inet_net_pton.c +2 -2
  272. data/third_party/cares/cares/setup_once.h +5 -5
  273. data/third_party/cares/config_darwin/ares_config.h +98 -196
  274. data/third_party/cares/config_linux/ares_config.h +103 -203
  275. metadata +47 -20
  276. data/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.c +0 -1957
  277. data/src/core/lib/iomgr/ev_epoll_thread_pool_linux.c +0 -1182
@@ -18,7 +18,7 @@
18
18
 
19
19
  #include "src/core/lib/transport/status_conversion.h"
20
20
 
21
- int grpc_status_to_http2_error(grpc_status_code status) {
21
+ grpc_http2_error_code grpc_status_to_http2_error(grpc_status_code status) {
22
22
  switch (status) {
23
23
  case GRPC_STATUS_OK:
24
24
  return GRPC_HTTP2_NO_ERROR;
@@ -72,7 +72,8 @@ void grpc_stream_unref(grpc_exec_ctx *exec_ctx,
72
72
  cope with.
73
73
  Throw this over to the executor (on a core-owned thread) and process it
74
74
  there. */
75
- refcount->destroy.scheduler = grpc_executor_scheduler;
75
+ refcount->destroy.scheduler =
76
+ grpc_executor_scheduler(GRPC_EXECUTOR_SHORT);
76
77
  }
77
78
  GRPC_CLOSURE_SCHED(exec_ctx, &refcount->destroy, GRPC_ERROR_NONE);
78
79
  }
@@ -101,8 +102,11 @@ static void slice_stream_unref(grpc_exec_ctx *exec_ctx, void *p) {
101
102
  grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount *refcount,
102
103
  void *buffer, size_t length) {
103
104
  slice_stream_ref(&refcount->slice_refcount);
104
- return (grpc_slice){.refcount = &refcount->slice_refcount,
105
- .data.refcounted = {.bytes = buffer, .length = length}};
105
+ grpc_slice res;
106
+ res.refcount = &refcount->slice_refcount,
107
+ res.data.refcounted.bytes = (uint8_t *)buffer;
108
+ res.data.refcounted.length = length;
109
+ return res;
106
110
  }
107
111
 
108
112
  static const grpc_slice_refcount_vtable stream_ref_slice_vtable = {
@@ -197,11 +201,6 @@ void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx,
197
201
  then_schedule_closure);
198
202
  }
199
203
 
200
- char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx,
201
- grpc_transport *transport) {
202
- return transport->vtable->get_peer(exec_ctx, transport);
203
- }
204
-
205
204
  grpc_endpoint *grpc_transport_get_endpoint(grpc_exec_ctx *exec_ctx,
206
205
  grpc_transport *transport) {
207
206
  return transport->vtable->get_endpoint(exec_ctx, transport);
@@ -214,24 +213,24 @@ grpc_endpoint *grpc_transport_get_endpoint(grpc_exec_ctx *exec_ctx,
214
213
  // is a function that must always unref cancel_error
215
214
  // though it lives in lib, it handles transport stream ops sure
216
215
  // it's grpc_transport_stream_op_batch_finish_with_failure
217
-
218
216
  void grpc_transport_stream_op_batch_finish_with_failure(
219
217
  grpc_exec_ctx *exec_ctx, grpc_transport_stream_op_batch *batch,
220
- grpc_error *error) {
218
+ grpc_error *error, grpc_call_combiner *call_combiner) {
221
219
  if (batch->send_message) {
222
220
  grpc_byte_stream_destroy(exec_ctx,
223
221
  batch->payload->send_message.send_message);
224
222
  }
225
223
  if (batch->recv_message) {
226
- GRPC_CLOSURE_SCHED(exec_ctx,
227
- batch->payload->recv_message.recv_message_ready,
228
- GRPC_ERROR_REF(error));
224
+ GRPC_CALL_COMBINER_START(exec_ctx, call_combiner,
225
+ batch->payload->recv_message.recv_message_ready,
226
+ GRPC_ERROR_REF(error),
227
+ "failing recv_message_ready");
229
228
  }
230
229
  if (batch->recv_initial_metadata) {
231
- GRPC_CLOSURE_SCHED(
232
- exec_ctx,
230
+ GRPC_CALL_COMBINER_START(
231
+ exec_ctx, call_combiner,
233
232
  batch->payload->recv_initial_metadata.recv_initial_metadata_ready,
234
- GRPC_ERROR_REF(error));
233
+ GRPC_ERROR_REF(error), "failing recv_initial_metadata_ready");
235
234
  }
236
235
  GRPC_CLOSURE_SCHED(exec_ctx, batch->on_complete, error);
237
236
  if (batch->cancel_stream) {
@@ -247,13 +246,13 @@ typedef struct {
247
246
 
248
247
  static void destroy_made_transport_op(grpc_exec_ctx *exec_ctx, void *arg,
249
248
  grpc_error *error) {
250
- made_transport_op *op = arg;
249
+ made_transport_op *op = (made_transport_op *)arg;
251
250
  GRPC_CLOSURE_SCHED(exec_ctx, op->inner_on_complete, GRPC_ERROR_REF(error));
252
251
  gpr_free(op);
253
252
  }
254
253
 
255
254
  grpc_transport_op *grpc_make_transport_op(grpc_closure *on_complete) {
256
- made_transport_op *op = gpr_malloc(sizeof(*op));
255
+ made_transport_op *op = (made_transport_op *)gpr_malloc(sizeof(*op));
257
256
  GRPC_CLOSURE_INIT(&op->outer_on_complete, destroy_made_transport_op, op,
258
257
  grpc_schedule_on_exec_ctx);
259
258
  op->inner_on_complete = on_complete;
@@ -271,7 +270,7 @@ typedef struct {
271
270
 
272
271
  static void destroy_made_transport_stream_op(grpc_exec_ctx *exec_ctx, void *arg,
273
272
  grpc_error *error) {
274
- made_transport_stream_op *op = arg;
273
+ made_transport_stream_op *op = (made_transport_stream_op *)arg;
275
274
  grpc_closure *c = op->inner_on_complete;
276
275
  gpr_free(op);
277
276
  GRPC_CLOSURE_RUN(exec_ctx, c, GRPC_ERROR_REF(error));
@@ -279,7 +278,8 @@ static void destroy_made_transport_stream_op(grpc_exec_ctx *exec_ctx, void *arg,
279
278
 
280
279
  grpc_transport_stream_op_batch *grpc_make_transport_stream_op(
281
280
  grpc_closure *on_complete) {
282
- made_transport_stream_op *op = gpr_zalloc(sizeof(*op));
281
+ made_transport_stream_op *op =
282
+ (made_transport_stream_op *)gpr_zalloc(sizeof(*op));
283
283
  op->op.payload = &op->payload;
284
284
  GRPC_CLOSURE_INIT(&op->outer_on_complete, destroy_made_transport_stream_op,
285
285
  op, grpc_schedule_on_exec_ctx);
@@ -22,6 +22,7 @@
22
22
  #include <stddef.h>
23
23
 
24
24
  #include "src/core/lib/channel/context.h"
25
+ #include "src/core/lib/iomgr/call_combiner.h"
25
26
  #include "src/core/lib/iomgr/endpoint.h"
26
27
  #include "src/core/lib/iomgr/polling_entity.h"
27
28
  #include "src/core/lib/iomgr/pollset.h"
@@ -152,6 +153,9 @@ struct grpc_transport_stream_op_batch_payload {
152
153
  /** Iff send_initial_metadata != NULL, flags associated with
153
154
  send_initial_metadata: a bitfield of GRPC_INITIAL_METADATA_xxx */
154
155
  uint32_t send_initial_metadata_flags;
156
+ // If non-NULL, will be set by the transport to the peer string
157
+ // (a char*, which the caller takes ownership of).
158
+ gpr_atm *peer_string;
155
159
  } send_initial_metadata;
156
160
 
157
161
  struct {
@@ -176,6 +180,9 @@ struct grpc_transport_stream_op_batch_payload {
176
180
  // immediately available. This may be a signal that we received a
177
181
  // Trailers-Only response.
178
182
  bool *trailing_metadata_available;
183
+ // If non-NULL, will be set by the transport to the peer string
184
+ // (a char*, which the caller takes ownership of).
185
+ gpr_atm *peer_string;
179
186
  } recv_initial_metadata;
180
187
 
181
188
  struct {
@@ -293,7 +300,7 @@ void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx,
293
300
 
294
301
  void grpc_transport_stream_op_batch_finish_with_failure(
295
302
  grpc_exec_ctx *exec_ctx, grpc_transport_stream_op_batch *op,
296
- grpc_error *error);
303
+ grpc_error *error, grpc_call_combiner *call_combiner);
297
304
 
298
305
  char *grpc_transport_stream_op_batch_string(grpc_transport_stream_op_batch *op);
299
306
  char *grpc_transport_op_string(grpc_transport_op *op);
@@ -332,10 +339,6 @@ void grpc_transport_close(grpc_transport *transport);
332
339
  /* Destroy the transport */
333
340
  void grpc_transport_destroy(grpc_exec_ctx *exec_ctx, grpc_transport *transport);
334
341
 
335
- /* Get the transports peer */
336
- char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx,
337
- grpc_transport *transport);
338
-
339
342
  /* Get the endpoint used by \a transport */
340
343
  grpc_endpoint *grpc_transport_get_endpoint(grpc_exec_ctx *exec_ctx,
341
344
  grpc_transport *transport);
@@ -59,9 +59,6 @@ typedef struct grpc_transport_vtable {
59
59
  /* implementation of grpc_transport_destroy */
60
60
  void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_transport *self);
61
61
 
62
- /* implementation of grpc_transport_get_peer */
63
- char *(*get_peer)(grpc_exec_ctx *exec_ctx, grpc_transport *self);
64
-
65
62
  /* implementation of grpc_transport_get_endpoint */
66
63
  grpc_endpoint *(*get_endpoint)(grpc_exec_ctx *exec_ctx, grpc_transport *self);
67
64
  } grpc_transport_vtable;
@@ -112,6 +112,13 @@ char *grpc_transport_stream_op_batch_string(
112
112
  gpr_strvec_add(&b, tmp);
113
113
  }
114
114
 
115
+ if (op->collect_stats) {
116
+ gpr_strvec_add(&b, gpr_strdup(" "));
117
+ gpr_asprintf(&tmp, "COLLECT_STATS:%p",
118
+ op->payload->collect_stats.collect_stats);
119
+ gpr_strvec_add(&b, tmp);
120
+ }
121
+
115
122
  out = gpr_strvec_flatten(&b, NULL);
116
123
  gpr_strvec_destroy(&b);
117
124
 
@@ -190,7 +197,7 @@ char *grpc_transport_op_string(grpc_transport_op *op) {
190
197
  return out;
191
198
  }
192
199
 
193
- void grpc_call_log_op(char *file, int line, gpr_log_severity severity,
200
+ void grpc_call_log_op(const char *file, int line, gpr_log_severity severity,
194
201
  grpc_call_element *elem,
195
202
  grpc_transport_stream_op_batch *op) {
196
203
  char *str = grpc_transport_stream_op_batch_string(op);
@@ -44,8 +44,8 @@ extern void grpc_resolver_dns_native_init(void);
44
44
  extern void grpc_resolver_dns_native_shutdown(void);
45
45
  extern void grpc_resolver_sockaddr_init(void);
46
46
  extern void grpc_resolver_sockaddr_shutdown(void);
47
- extern void grpc_load_reporting_plugin_init(void);
48
- extern void grpc_load_reporting_plugin_shutdown(void);
47
+ extern void grpc_server_load_reporting_plugin_init(void);
48
+ extern void grpc_server_load_reporting_plugin_shutdown(void);
49
49
  extern void census_grpc_plugin_init(void);
50
50
  extern void census_grpc_plugin_shutdown(void);
51
51
  extern void grpc_max_age_filter_init(void);
@@ -82,8 +82,8 @@ void grpc_register_built_in_plugins(void) {
82
82
  grpc_resolver_dns_native_shutdown);
83
83
  grpc_register_plugin(grpc_resolver_sockaddr_init,
84
84
  grpc_resolver_sockaddr_shutdown);
85
- grpc_register_plugin(grpc_load_reporting_plugin_init,
86
- grpc_load_reporting_plugin_shutdown);
85
+ grpc_register_plugin(grpc_server_load_reporting_plugin_init,
86
+ grpc_server_load_reporting_plugin_shutdown);
87
87
  grpc_register_plugin(census_grpc_plugin_init,
88
88
  census_grpc_plugin_shutdown);
89
89
  grpc_register_plugin(grpc_max_age_filter_init,
@@ -25,7 +25,8 @@
25
25
  #include <grpc/support/log.h>
26
26
  #include <grpc/support/port_platform.h>
27
27
  #include <grpc/support/useful.h>
28
- #include "src/core/tsi/transport_security.h"
28
+ #include "src/core/lib/slice/slice_internal.h"
29
+ #include "src/core/tsi/transport_security_grpc.h"
29
30
 
30
31
  /* --- Constants. ---*/
31
32
  #define TSI_FAKE_FRAME_HEADER_SIZE 4
@@ -74,6 +75,14 @@ typedef struct {
74
75
  size_t max_frame_size;
75
76
  } tsi_fake_frame_protector;
76
77
 
78
+ typedef struct {
79
+ tsi_zero_copy_grpc_protector base;
80
+ grpc_slice_buffer header_sb;
81
+ grpc_slice_buffer protected_sb;
82
+ size_t max_frame_size;
83
+ size_t parsed_frame_size;
84
+ } tsi_fake_zero_copy_grpc_protector;
85
+
77
86
  /* --- Utils. ---*/
78
87
 
79
88
  static const char *tsi_fake_handshake_message_strings[] = {
@@ -113,6 +122,28 @@ static void store32_little_endian(uint32_t value, unsigned char *buf) {
113
122
  buf[0] = (unsigned char)((value)&0xFF);
114
123
  }
115
124
 
125
+ static uint32_t read_frame_size(const grpc_slice_buffer *sb) {
126
+ GPR_ASSERT(sb != NULL && sb->length >= TSI_FAKE_FRAME_HEADER_SIZE);
127
+ uint8_t frame_size_buffer[TSI_FAKE_FRAME_HEADER_SIZE];
128
+ uint8_t *buf = frame_size_buffer;
129
+ /* Copies the first 4 bytes to a temporary buffer. */
130
+ size_t remaining = TSI_FAKE_FRAME_HEADER_SIZE;
131
+ for (size_t i = 0; i < sb->count; i++) {
132
+ size_t slice_length = GRPC_SLICE_LENGTH(sb->slices[i]);
133
+ if (remaining <= slice_length) {
134
+ memcpy(buf, GRPC_SLICE_START_PTR(sb->slices[i]), remaining);
135
+ remaining = 0;
136
+ break;
137
+ } else {
138
+ memcpy(buf, GRPC_SLICE_START_PTR(sb->slices[i]), slice_length);
139
+ buf += slice_length;
140
+ remaining -= slice_length;
141
+ }
142
+ }
143
+ GPR_ASSERT(remaining == 0);
144
+ return load32_little_endian(frame_size_buffer);
145
+ }
146
+
116
147
  static void tsi_fake_frame_reset(tsi_fake_frame *frame, int needs_draining) {
117
148
  frame->offset = 0;
118
149
  frame->needs_draining = needs_draining;
@@ -363,6 +394,84 @@ static const tsi_frame_protector_vtable frame_protector_vtable = {
363
394
  fake_protector_unprotect, fake_protector_destroy,
364
395
  };
365
396
 
397
+ /* --- tsi_zero_copy_grpc_protector methods implementation. ---*/
398
+
399
+ static tsi_result fake_zero_copy_grpc_protector_protect(
400
+ grpc_exec_ctx *exec_ctx, tsi_zero_copy_grpc_protector *self,
401
+ grpc_slice_buffer *unprotected_slices,
402
+ grpc_slice_buffer *protected_slices) {
403
+ if (self == NULL || unprotected_slices == NULL || protected_slices == NULL) {
404
+ return TSI_INVALID_ARGUMENT;
405
+ }
406
+ tsi_fake_zero_copy_grpc_protector *impl =
407
+ (tsi_fake_zero_copy_grpc_protector *)self;
408
+ /* Protects each frame. */
409
+ while (unprotected_slices->length > 0) {
410
+ size_t frame_length =
411
+ GPR_MIN(impl->max_frame_size,
412
+ unprotected_slices->length + TSI_FAKE_FRAME_HEADER_SIZE);
413
+ grpc_slice slice = GRPC_SLICE_MALLOC(TSI_FAKE_FRAME_HEADER_SIZE);
414
+ store32_little_endian((uint32_t)frame_length, GRPC_SLICE_START_PTR(slice));
415
+ grpc_slice_buffer_add(protected_slices, slice);
416
+ size_t data_length = frame_length - TSI_FAKE_FRAME_HEADER_SIZE;
417
+ grpc_slice_buffer_move_first(unprotected_slices, data_length,
418
+ protected_slices);
419
+ }
420
+ return TSI_OK;
421
+ }
422
+
423
+ static tsi_result fake_zero_copy_grpc_protector_unprotect(
424
+ grpc_exec_ctx *exec_ctx, tsi_zero_copy_grpc_protector *self,
425
+ grpc_slice_buffer *protected_slices,
426
+ grpc_slice_buffer *unprotected_slices) {
427
+ if (self == NULL || unprotected_slices == NULL || protected_slices == NULL) {
428
+ return TSI_INVALID_ARGUMENT;
429
+ }
430
+ tsi_fake_zero_copy_grpc_protector *impl =
431
+ (tsi_fake_zero_copy_grpc_protector *)self;
432
+ grpc_slice_buffer_move_into(protected_slices, &impl->protected_sb);
433
+ /* Unprotect each frame, if we get a full frame. */
434
+ while (impl->protected_sb.length >= TSI_FAKE_FRAME_HEADER_SIZE) {
435
+ if (impl->parsed_frame_size == 0) {
436
+ impl->parsed_frame_size = read_frame_size(&impl->protected_sb);
437
+ if (impl->parsed_frame_size <= 4) {
438
+ gpr_log(GPR_ERROR, "Invalid frame size.");
439
+ return TSI_DATA_CORRUPTED;
440
+ }
441
+ }
442
+ /* If we do not have a full frame, return with OK status. */
443
+ if (impl->protected_sb.length < impl->parsed_frame_size) break;
444
+ /* Strips header bytes. */
445
+ grpc_slice_buffer_move_first(&impl->protected_sb,
446
+ TSI_FAKE_FRAME_HEADER_SIZE, &impl->header_sb);
447
+ /* Moves data to unprotected slices. */
448
+ grpc_slice_buffer_move_first(
449
+ &impl->protected_sb,
450
+ impl->parsed_frame_size - TSI_FAKE_FRAME_HEADER_SIZE,
451
+ unprotected_slices);
452
+ impl->parsed_frame_size = 0;
453
+ grpc_slice_buffer_reset_and_unref_internal(exec_ctx, &impl->header_sb);
454
+ }
455
+ return TSI_OK;
456
+ }
457
+
458
+ static void fake_zero_copy_grpc_protector_destroy(
459
+ grpc_exec_ctx *exec_ctx, tsi_zero_copy_grpc_protector *self) {
460
+ if (self == NULL) return;
461
+ tsi_fake_zero_copy_grpc_protector *impl =
462
+ (tsi_fake_zero_copy_grpc_protector *)self;
463
+ grpc_slice_buffer_destroy_internal(exec_ctx, &impl->header_sb);
464
+ grpc_slice_buffer_destroy_internal(exec_ctx, &impl->protected_sb);
465
+ gpr_free(impl);
466
+ }
467
+
468
+ static const tsi_zero_copy_grpc_protector_vtable
469
+ zero_copy_grpc_protector_vtable = {
470
+ fake_zero_copy_grpc_protector_protect,
471
+ fake_zero_copy_grpc_protector_unprotect,
472
+ fake_zero_copy_grpc_protector_destroy,
473
+ };
474
+
366
475
  /* --- tsi_handshaker_result methods implementation. ---*/
367
476
 
368
477
  typedef struct {
@@ -383,6 +492,15 @@ static tsi_result fake_handshaker_result_extract_peer(
383
492
  return result;
384
493
  }
385
494
 
495
+ static tsi_result fake_handshaker_result_create_zero_copy_grpc_protector(
496
+ void *exec_ctx, const tsi_handshaker_result *self,
497
+ size_t *max_output_protected_frame_size,
498
+ tsi_zero_copy_grpc_protector **protector) {
499
+ *protector =
500
+ tsi_create_fake_zero_copy_grpc_protector(max_output_protected_frame_size);
501
+ return TSI_OK;
502
+ }
503
+
386
504
  static tsi_result fake_handshaker_result_create_frame_protector(
387
505
  const tsi_handshaker_result *self, size_t *max_output_protected_frame_size,
388
506
  tsi_frame_protector **protector) {
@@ -407,7 +525,7 @@ static void fake_handshaker_result_destroy(tsi_handshaker_result *self) {
407
525
 
408
526
  static const tsi_handshaker_result_vtable handshaker_result_vtable = {
409
527
  fake_handshaker_result_extract_peer,
410
- NULL, /* create_zero_copy_grpc_protector */
528
+ fake_handshaker_result_create_zero_copy_grpc_protector,
411
529
  fake_handshaker_result_create_frame_protector,
412
530
  fake_handshaker_result_get_unused_bytes,
413
531
  fake_handshaker_result_destroy,
@@ -631,3 +749,16 @@ tsi_frame_protector *tsi_create_fake_frame_protector(
631
749
  impl->base.vtable = &frame_protector_vtable;
632
750
  return &impl->base;
633
751
  }
752
+
753
+ tsi_zero_copy_grpc_protector *tsi_create_fake_zero_copy_grpc_protector(
754
+ size_t *max_protected_frame_size) {
755
+ tsi_fake_zero_copy_grpc_protector *impl = gpr_zalloc(sizeof(*impl));
756
+ grpc_slice_buffer_init(&impl->header_sb);
757
+ grpc_slice_buffer_init(&impl->protected_sb);
758
+ impl->max_frame_size = (max_protected_frame_size == NULL)
759
+ ? TSI_FAKE_DEFAULT_FRAME_SIZE
760
+ : *max_protected_frame_size;
761
+ impl->parsed_frame_size = 0;
762
+ impl->base.vtable = &zero_copy_grpc_protector_vtable;
763
+ return &impl->base;
764
+ }
@@ -39,6 +39,11 @@ tsi_handshaker *tsi_create_fake_handshaker(int is_client);
39
39
  tsi_frame_protector *tsi_create_fake_frame_protector(
40
40
  size_t *max_protected_frame_size);
41
41
 
42
+ /* Creates a zero-copy protector directly without going through the handshake
43
+ * phase. */
44
+ tsi_zero_copy_grpc_protector *tsi_create_fake_zero_copy_grpc_protector(
45
+ size_t *max_protected_frame_size);
46
+
42
47
  #ifdef __cplusplus
43
48
  }
44
49
  #endif
@@ -67,7 +67,13 @@
67
67
 
68
68
  /* --- Structure definitions. ---*/
69
69
 
70
+ struct tsi_ssl_handshaker_factory {
71
+ const tsi_ssl_handshaker_factory_vtable *vtable;
72
+ gpr_refcount refcount;
73
+ };
74
+
70
75
  struct tsi_ssl_client_handshaker_factory {
76
+ tsi_ssl_handshaker_factory base;
71
77
  SSL_CTX *ssl_context;
72
78
  unsigned char *alpn_protocol_list;
73
79
  size_t alpn_protocol_list_length;
@@ -77,6 +83,7 @@ struct tsi_ssl_server_handshaker_factory {
77
83
  /* Several contexts to support SNI.
78
84
  The tsi_peer array contains the subject names of the server certificates
79
85
  associated with the contexts at the same index. */
86
+ tsi_ssl_handshaker_factory base;
80
87
  SSL_CTX **ssl_contexts;
81
88
  tsi_peer *ssl_context_x509_subject_names;
82
89
  size_t ssl_context_count;
@@ -90,6 +97,7 @@ typedef struct {
90
97
  BIO *into_ssl;
91
98
  BIO *from_ssl;
92
99
  tsi_result result;
100
+ tsi_ssl_handshaker_factory *factory_ref;
93
101
  } tsi_ssl_handshaker;
94
102
 
95
103
  typedef struct {
@@ -846,6 +854,47 @@ static const tsi_frame_protector_vtable frame_protector_vtable = {
846
854
  ssl_protector_destroy,
847
855
  };
848
856
 
857
+ /* --- tsi_server_handshaker_factory methods implementation. --- */
858
+
859
+ static void tsi_ssl_handshaker_factory_destroy(
860
+ tsi_ssl_handshaker_factory *self) {
861
+ if (self == NULL) return;
862
+
863
+ if (self->vtable != NULL && self->vtable->destroy != NULL) {
864
+ self->vtable->destroy(self);
865
+ }
866
+ /* Note, we don't free(self) here because this object is always directly
867
+ * embedded in another object. If tsi_ssl_handshaker_factory_init allocates
868
+ * any memory, it should be free'd here. */
869
+ }
870
+
871
+ static tsi_ssl_handshaker_factory *tsi_ssl_handshaker_factory_ref(
872
+ tsi_ssl_handshaker_factory *self) {
873
+ if (self == NULL) return NULL;
874
+ gpr_refn(&self->refcount, 1);
875
+ return self;
876
+ }
877
+
878
+ static void tsi_ssl_handshaker_factory_unref(tsi_ssl_handshaker_factory *self) {
879
+ if (self == NULL) return;
880
+
881
+ if (gpr_unref(&self->refcount)) {
882
+ tsi_ssl_handshaker_factory_destroy(self);
883
+ }
884
+ }
885
+
886
+ static tsi_ssl_handshaker_factory_vtable handshaker_factory_vtable = {NULL};
887
+
888
+ /* Initializes a tsi_ssl_handshaker_factory object. Caller is responsible for
889
+ * allocating memory for the factory. */
890
+ static void tsi_ssl_handshaker_factory_init(
891
+ tsi_ssl_handshaker_factory *factory) {
892
+ GPR_ASSERT(factory != NULL);
893
+
894
+ factory->vtable = &handshaker_factory_vtable;
895
+ gpr_ref_init(&factory->refcount, 1);
896
+ }
897
+
849
898
  /* --- tsi_handshaker methods implementation. ---*/
850
899
 
851
900
  static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self,
@@ -1013,6 +1062,7 @@ static tsi_result ssl_handshaker_create_frame_protector(
1013
1062
  static void ssl_handshaker_destroy(tsi_handshaker *self) {
1014
1063
  tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self;
1015
1064
  SSL_free(impl->ssl); /* The BIO objects are owned by ssl */
1065
+ tsi_ssl_handshaker_factory_unref(impl->factory_ref);
1016
1066
  gpr_free(impl);
1017
1067
  }
1018
1068
 
@@ -1030,6 +1080,7 @@ static const tsi_handshaker_vtable handshaker_vtable = {
1030
1080
 
1031
1081
  static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client,
1032
1082
  const char *server_name_indication,
1083
+ tsi_ssl_handshaker_factory *factory,
1033
1084
  tsi_handshaker **handshaker) {
1034
1085
  SSL *ssl = SSL_new(ctx);
1035
1086
  BIO *into_ssl = NULL;
@@ -1085,6 +1136,8 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client,
1085
1136
  impl->from_ssl = from_ssl;
1086
1137
  impl->result = TSI_HANDSHAKE_IN_PROGRESS;
1087
1138
  impl->base.vtable = &handshaker_vtable;
1139
+ impl->factory_ref = tsi_ssl_handshaker_factory_ref(factory);
1140
+
1088
1141
  *handshaker = &impl->base;
1089
1142
  return TSI_OK;
1090
1143
  }
@@ -1121,11 +1174,20 @@ tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
1121
1174
  tsi_ssl_client_handshaker_factory *self, const char *server_name_indication,
1122
1175
  tsi_handshaker **handshaker) {
1123
1176
  return create_tsi_ssl_handshaker(self->ssl_context, 1, server_name_indication,
1124
- handshaker);
1177
+ &self->base, handshaker);
1125
1178
  }
1126
1179
 
1127
- void tsi_ssl_client_handshaker_factory_destroy(
1180
+ void tsi_ssl_client_handshaker_factory_unref(
1128
1181
  tsi_ssl_client_handshaker_factory *self) {
1182
+ if (self == NULL) return;
1183
+ tsi_ssl_handshaker_factory_unref(&self->base);
1184
+ }
1185
+
1186
+ static void tsi_ssl_client_handshaker_factory_destroy(
1187
+ tsi_ssl_handshaker_factory *factory) {
1188
+ if (factory == NULL) return;
1189
+ tsi_ssl_client_handshaker_factory *self =
1190
+ (tsi_ssl_client_handshaker_factory *)factory;
1129
1191
  if (self->ssl_context != NULL) SSL_CTX_free(self->ssl_context);
1130
1192
  if (self->alpn_protocol_list != NULL) gpr_free(self->alpn_protocol_list);
1131
1193
  gpr_free(self);
@@ -1150,11 +1212,21 @@ tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
1150
1212
  if (self->ssl_context_count == 0) return TSI_INVALID_ARGUMENT;
1151
1213
  /* Create the handshaker with the first context. We will switch if needed
1152
1214
  because of SNI in ssl_server_handshaker_factory_servername_callback. */
1153
- return create_tsi_ssl_handshaker(self->ssl_contexts[0], 0, NULL, handshaker);
1215
+ return create_tsi_ssl_handshaker(self->ssl_contexts[0], 0, NULL, &self->base,
1216
+ handshaker);
1154
1217
  }
1155
1218
 
1156
- void tsi_ssl_server_handshaker_factory_destroy(
1219
+ void tsi_ssl_server_handshaker_factory_unref(
1157
1220
  tsi_ssl_server_handshaker_factory *self) {
1221
+ if (self == NULL) return;
1222
+ tsi_ssl_handshaker_factory_unref(&self->base);
1223
+ }
1224
+
1225
+ static void tsi_ssl_server_handshaker_factory_destroy(
1226
+ tsi_ssl_handshaker_factory *factory) {
1227
+ if (factory == NULL) return;
1228
+ tsi_ssl_server_handshaker_factory *self =
1229
+ (tsi_ssl_server_handshaker_factory *)factory;
1158
1230
  size_t i;
1159
1231
  for (i = 0; i < self->ssl_context_count; i++) {
1160
1232
  if (self->ssl_contexts[i] != NULL) {
@@ -1263,6 +1335,9 @@ static int server_handshaker_factory_npn_advertised_callback(
1263
1335
 
1264
1336
  /* --- tsi_ssl_handshaker_factory constructors. --- */
1265
1337
 
1338
+ static tsi_ssl_handshaker_factory_vtable client_handshaker_factory_vtable = {
1339
+ tsi_ssl_client_handshaker_factory_destroy};
1340
+
1266
1341
  tsi_result tsi_create_ssl_client_handshaker_factory(
1267
1342
  const tsi_ssl_pem_key_cert_pair *pem_key_cert_pair,
1268
1343
  const char *pem_root_certs, const char *cipher_suites,
@@ -1285,6 +1360,9 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
1285
1360
  }
1286
1361
 
1287
1362
  impl = gpr_zalloc(sizeof(*impl));
1363
+ tsi_ssl_handshaker_factory_init(&impl->base);
1364
+ impl->base.vtable = &client_handshaker_factory_vtable;
1365
+
1288
1366
  impl->ssl_context = ssl_context;
1289
1367
 
1290
1368
  do {
@@ -1322,7 +1400,7 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
1322
1400
  }
1323
1401
  } while (0);
1324
1402
  if (result != TSI_OK) {
1325
- tsi_ssl_client_handshaker_factory_destroy(impl);
1403
+ tsi_ssl_handshaker_factory_unref(&impl->base);
1326
1404
  return result;
1327
1405
  }
1328
1406
  SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NULL);
@@ -1332,6 +1410,9 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
1332
1410
  return TSI_OK;
1333
1411
  }
1334
1412
 
1413
+ static tsi_ssl_handshaker_factory_vtable server_handshaker_factory_vtable = {
1414
+ tsi_ssl_server_handshaker_factory_destroy};
1415
+
1335
1416
  tsi_result tsi_create_ssl_server_handshaker_factory(
1336
1417
  const tsi_ssl_pem_key_cert_pair *pem_key_cert_pairs,
1337
1418
  size_t num_key_cert_pairs, const char *pem_client_root_certs,
@@ -1364,12 +1445,15 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
1364
1445
  }
1365
1446
 
1366
1447
  impl = gpr_zalloc(sizeof(*impl));
1448
+ tsi_ssl_handshaker_factory_init(&impl->base);
1449
+ impl->base.vtable = &server_handshaker_factory_vtable;
1450
+
1367
1451
  impl->ssl_contexts = gpr_zalloc(num_key_cert_pairs * sizeof(SSL_CTX *));
1368
1452
  impl->ssl_context_x509_subject_names =
1369
1453
  gpr_zalloc(num_key_cert_pairs * sizeof(tsi_peer));
1370
1454
  if (impl->ssl_contexts == NULL ||
1371
1455
  impl->ssl_context_x509_subject_names == NULL) {
1372
- tsi_ssl_server_handshaker_factory_destroy(impl);
1456
+ tsi_ssl_handshaker_factory_unref(&impl->base);
1373
1457
  return TSI_OUT_OF_RESOURCES;
1374
1458
  }
1375
1459
  impl->ssl_context_count = num_key_cert_pairs;
@@ -1379,7 +1463,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
1379
1463
  &impl->alpn_protocol_list,
1380
1464
  &impl->alpn_protocol_list_length);
1381
1465
  if (result != TSI_OK) {
1382
- tsi_ssl_server_handshaker_factory_destroy(impl);
1466
+ tsi_ssl_handshaker_factory_unref(&impl->base);
1383
1467
  return result;
1384
1468
  }
1385
1469
  }
@@ -1451,10 +1535,11 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
1451
1535
  } while (0);
1452
1536
 
1453
1537
  if (result != TSI_OK) {
1454
- tsi_ssl_server_handshaker_factory_destroy(impl);
1538
+ tsi_ssl_handshaker_factory_unref(&impl->base);
1455
1539
  return result;
1456
1540
  }
1457
1541
  }
1542
+
1458
1543
  *factory = impl;
1459
1544
  return TSI_OK;
1460
1545
  }
@@ -1501,3 +1586,15 @@ int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name) {
1501
1586
 
1502
1587
  return 0; /* Not found. */
1503
1588
  }
1589
+
1590
+ /* --- Testing support. --- */
1591
+ const tsi_ssl_handshaker_factory_vtable *tsi_ssl_handshaker_factory_swap_vtable(
1592
+ tsi_ssl_handshaker_factory *factory,
1593
+ tsi_ssl_handshaker_factory_vtable *new_vtable) {
1594
+ GPR_ASSERT(factory != NULL);
1595
+ GPR_ASSERT(factory->vtable != NULL);
1596
+
1597
+ const tsi_ssl_handshaker_factory_vtable *orig_vtable = factory->vtable;
1598
+ factory->vtable = new_vtable;
1599
+ return orig_vtable;
1600
+ }