grpc 1.78.0 → 1.80.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +22 -8
  3. data/include/grpc/credentials.h +47 -37
  4. data/include/grpc/credentials_cpp.h +39 -0
  5. data/include/grpc/event_engine/event_engine.h +8 -3
  6. data/include/grpc/grpc.h +4 -0
  7. data/include/grpc/impl/call.h +9 -0
  8. data/include/grpc/impl/channel_arg_names.h +7 -0
  9. data/include/grpc/module.modulemap +2 -0
  10. data/include/grpc/private_key_signer.h +104 -0
  11. data/include/grpc/support/port_platform.h +6 -0
  12. data/src/core/call/call_filters.h +101 -78
  13. data/src/core/call/call_spine.h +91 -68
  14. data/src/core/call/call_state.h +60 -4
  15. data/src/core/call/client_call.cc +9 -9
  16. data/src/core/call/client_call.h +1 -1
  17. data/src/core/call/metadata_batch.cc +2 -0
  18. data/src/core/call/metadata_batch.h +48 -1
  19. data/src/core/call/metadata_info.cc +35 -0
  20. data/src/core/call/metadata_info.h +2 -0
  21. data/src/core/call/simple_slice_based_metadata.h +2 -1
  22. data/src/core/channelz/channelz.cc +9 -6
  23. data/src/core/channelz/channelz.h +7 -4
  24. data/src/core/channelz/property_list.h +5 -0
  25. data/src/core/channelz/v2tov1/convert.cc +1 -1
  26. data/src/core/channelz/v2tov1/legacy_api.cc +164 -307
  27. data/src/core/client_channel/buffered_call.cc +7 -3
  28. data/src/core/client_channel/buffered_call.h +11 -5
  29. data/src/core/client_channel/client_channel.cc +106 -44
  30. data/src/core/client_channel/client_channel.h +3 -6
  31. data/src/core/client_channel/client_channel_filter.cc +90 -64
  32. data/src/core/client_channel/client_channel_filter.h +3 -6
  33. data/src/core/client_channel/client_channel_internal.h +5 -0
  34. data/src/core/client_channel/config_selector.h +17 -12
  35. data/src/core/client_channel/dynamic_filters.cc +8 -7
  36. data/src/core/client_channel/dynamic_filters.h +7 -5
  37. data/src/core/client_channel/retry_filter.cc +1 -1
  38. data/src/core/client_channel/retry_filter.h +2 -2
  39. data/src/core/client_channel/subchannel.cc +1682 -266
  40. data/src/core/client_channel/subchannel.h +411 -134
  41. data/src/core/client_channel/subchannel_stream_client.cc +22 -18
  42. data/src/core/client_channel/subchannel_stream_client.h +8 -9
  43. data/src/core/client_channel/subchannel_stream_limiter.cc +76 -0
  44. data/src/core/client_channel/subchannel_stream_limiter.h +51 -0
  45. data/src/core/config/config_vars.cc +9 -1
  46. data/src/core/config/config_vars.h +6 -0
  47. data/src/core/credentials/call/call_creds_registry.h +51 -22
  48. data/src/core/credentials/call/call_creds_registry_init.cc +86 -2
  49. data/src/core/credentials/call/external/aws_external_account_credentials.cc +2 -2
  50. data/src/core/credentials/call/external/external_account_credentials.cc +11 -4
  51. data/src/core/credentials/call/external/file_external_account_credentials.cc +2 -2
  52. data/src/core/credentials/transport/channel_creds_registry.h +71 -20
  53. data/src/core/credentials/transport/channel_creds_registry_init.cc +338 -29
  54. data/src/core/credentials/transport/ssl/ssl_credentials.cc +43 -24
  55. data/src/core/credentials/transport/ssl/ssl_credentials.h +7 -1
  56. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +2 -8
  57. data/src/core/credentials/transport/ssl/ssl_security_connector.h +4 -3
  58. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +25 -5
  59. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +7 -5
  60. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +181 -109
  61. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +55 -42
  62. data/src/core/credentials/transport/tls/grpc_tls_credentials_options.cc +28 -23
  63. data/src/core/credentials/transport/tls/grpc_tls_credentials_options.h +26 -23
  64. data/src/core/credentials/transport/tls/spiffe_utils.cc +2 -2
  65. data/src/core/credentials/transport/tls/ssl_utils.cc +18 -18
  66. data/src/core/credentials/transport/tls/ssl_utils.h +12 -10
  67. data/src/core/credentials/transport/tls/tls_security_connector.cc +106 -74
  68. data/src/core/credentials/transport/tls/tls_security_connector.h +12 -8
  69. data/src/core/credentials/transport/xds/xds_credentials.cc +76 -32
  70. data/src/core/credentials/transport/xds/xds_credentials.h +4 -2
  71. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +117 -35
  72. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +42 -4
  73. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +58 -29
  74. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +19 -11
  75. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +82 -25
  76. data/src/core/ext/filters/stateful_session/stateful_session_filter.h +28 -3
  77. data/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.cc +9 -7
  78. data/src/core/ext/filters/stateful_session/stateful_session_service_config_parser.h +1 -1
  79. data/src/core/ext/transport/chttp2/transport/call_tracer_wrapper.h +7 -1
  80. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +117 -67
  81. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +2 -0
  82. data/src/core/ext/transport/chttp2/transport/flow_control.h +11 -1
  83. data/src/core/ext/transport/chttp2/transport/frame.cc +2 -15
  84. data/src/core/ext/transport/chttp2/transport/frame.h +0 -4
  85. data/src/core/ext/transport/chttp2/transport/goaway.cc +17 -2
  86. data/src/core/ext/transport/chttp2/transport/goaway.h +27 -6
  87. data/src/core/ext/transport/chttp2/transport/header_assembler.h +8 -21
  88. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +101 -40
  89. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +95 -0
  90. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +923 -772
  91. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +406 -423
  92. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +1 -0
  93. data/src/core/ext/transport/chttp2/transport/http2_settings.h +8 -1
  94. data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +25 -13
  95. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +71 -24
  96. data/src/core/ext/transport/chttp2/transport/http2_transport.h +25 -49
  97. data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +2 -2
  98. data/src/core/ext/transport/chttp2/transport/incoming_metadata_tracker.h +29 -9
  99. data/src/core/ext/transport/chttp2/transport/internal.h +6 -2
  100. data/src/core/ext/transport/chttp2/transport/keepalive.cc +14 -20
  101. data/src/core/ext/transport/chttp2/transport/keepalive.h +9 -6
  102. data/src/core/ext/transport/chttp2/transport/parsing.cc +11 -0
  103. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +34 -74
  104. data/src/core/ext/transport/chttp2/transport/ping_promise.h +123 -79
  105. data/src/core/ext/transport/chttp2/transport/security_frame.h +233 -3
  106. data/src/core/ext/transport/chttp2/transport/stream.h +152 -73
  107. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +155 -85
  108. data/src/core/ext/transport/chttp2/transport/transport_common.h +0 -5
  109. data/src/core/ext/transport/chttp2/transport/writable_streams.h +8 -7
  110. data/src/core/ext/transport/chttp2/transport/write_cycle.cc +86 -0
  111. data/src/core/ext/transport/chttp2/transport/write_cycle.h +355 -0
  112. data/src/core/ext/transport/chttp2/transport/writing.cc +31 -29
  113. data/src/core/ext/upb-gen/cel/expr/checked.upb.h +1875 -0
  114. data/src/core/ext/upb-gen/cel/expr/checked.upb_minitable.c +409 -0
  115. data/src/core/ext/upb-gen/cel/expr/checked.upb_minitable.h +56 -0
  116. data/src/core/ext/upb-gen/cel/expr/syntax.upb.h +2223 -0
  117. data/src/core/ext/upb-gen/cel/expr/syntax.upb_minitable.c +489 -0
  118. data/src/core/ext/upb-gen/cel/expr/syntax.upb_minitable.h +60 -0
  119. data/src/core/ext/upb-gen/envoy/config/accesslog/v3/accesslog.upb.h +2 -1
  120. data/src/core/ext/upb-gen/envoy/config/bootstrap/v3/bootstrap.upb.h +130 -18
  121. data/src/core/ext/upb-gen/envoy/config/bootstrap/v3/bootstrap.upb_minitable.c +18 -13
  122. data/src/core/ext/upb-gen/envoy/config/cluster/v3/cluster.upb.h +70 -38
  123. data/src/core/ext/upb-gen/envoy/config/cluster/v3/cluster.upb_minitable.c +20 -17
  124. data/src/core/ext/upb-gen/envoy/config/common/matcher/v3/matcher.upb.h +26 -10
  125. data/src/core/ext/upb-gen/envoy/config/common/matcher/v3/matcher.upb_minitable.c +8 -7
  126. data/src/core/ext/upb-gen/envoy/config/common/mutation_rules/v3/mutation_rules.upb.h +495 -0
  127. data/src/core/ext/upb-gen/envoy/config/common/mutation_rules/v3/mutation_rules.upb_minitable.c +114 -0
  128. data/src/core/ext/upb-gen/envoy/config/common/mutation_rules/v3/mutation_rules.upb_minitable.h +36 -0
  129. data/src/core/ext/upb-gen/envoy/config/core/v3/address.upb.h +26 -10
  130. data/src/core/ext/upb-gen/envoy/config/core/v3/address.upb_minitable.c +8 -7
  131. data/src/core/ext/upb-gen/envoy/config/core/v3/cel.upb.h +121 -0
  132. data/src/core/ext/upb-gen/envoy/config/core/v3/cel.upb_minitable.c +54 -0
  133. data/src/core/ext/upb-gen/envoy/config/core/v3/cel.upb_minitable.h +32 -0
  134. data/src/core/ext/upb-gen/envoy/config/core/v3/grpc_service.upb.h +143 -9
  135. data/src/core/ext/upb-gen/envoy/config/core/v3/grpc_service.upb_minitable.c +18 -6
  136. data/src/core/ext/upb-gen/envoy/config/core/v3/protocol.upb.h +112 -11
  137. data/src/core/ext/upb-gen/envoy/config/core/v3/protocol.upb_minitable.c +22 -9
  138. data/src/core/ext/upb-gen/envoy/config/core/v3/proxy_protocol.upb.h +276 -0
  139. data/src/core/ext/upb-gen/envoy/config/core/v3/proxy_protocol.upb_minitable.c +60 -5
  140. data/src/core/ext/upb-gen/envoy/config/core/v3/proxy_protocol.upb_minitable.h +4 -0
  141. data/src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint_components.upb.h +72 -0
  142. data/src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint_components.upb_minitable.c +23 -2
  143. data/src/core/ext/upb-gen/envoy/config/endpoint/v3/endpoint_components.upb_minitable.h +2 -0
  144. data/src/core/ext/upb-gen/envoy/config/listener/v3/listener.upb.h +129 -13
  145. data/src/core/ext/upb-gen/envoy/config/listener/v3/listener.upb_minitable.c +36 -10
  146. data/src/core/ext/upb-gen/envoy/config/listener/v3/listener.upb_minitable.h +2 -0
  147. data/src/core/ext/upb-gen/envoy/config/listener/v3/quic_config.upb.h +30 -0
  148. data/src/core/ext/upb-gen/envoy/config/listener/v3/quic_config.upb_minitable.c +5 -3
  149. data/src/core/ext/upb-gen/envoy/config/metrics/v3/metrics_service.upb.h +16 -0
  150. data/src/core/ext/upb-gen/envoy/config/metrics/v3/metrics_service.upb_minitable.c +4 -3
  151. data/src/core/ext/upb-gen/envoy/config/metrics/v3/stats.upb.h +31 -0
  152. data/src/core/ext/upb-gen/envoy/config/metrics/v3/stats.upb_minitable.c +5 -3
  153. data/src/core/ext/upb-gen/envoy/config/overload/v3/overload.upb.h +2 -1
  154. data/src/core/ext/upb-gen/envoy/config/rbac/v3/rbac.upb.h +63 -0
  155. data/src/core/ext/upb-gen/envoy/config/rbac/v3/rbac.upb_minitable.c +12 -7
  156. data/src/core/ext/upb-gen/envoy/config/route/v3/route.upb.h +97 -81
  157. data/src/core/ext/upb-gen/envoy/config/route/v3/route.upb_minitable.c +40 -23
  158. data/src/core/ext/upb-gen/envoy/config/route/v3/route_components.upb.h +604 -228
  159. data/src/core/ext/upb-gen/envoy/config/route/v3/route_components.upb_minitable.c +146 -100
  160. data/src/core/ext/upb-gen/envoy/config/tap/v3/common.upb.h +30 -0
  161. data/src/core/ext/upb-gen/envoy/config/tap/v3/common.upb_minitable.c +5 -3
  162. data/src/core/ext/upb-gen/envoy/config/trace/v3/opentelemetry.upb.h +35 -3
  163. data/src/core/ext/upb-gen/envoy/config/trace/v3/opentelemetry.upb_minitable.c +7 -4
  164. data/src/core/ext/upb-gen/envoy/config/trace/v3/zipkin.upb.h +66 -14
  165. data/src/core/ext/upb-gen/envoy/config/trace/v3/zipkin.upb_minitable.c +22 -11
  166. data/src/core/ext/upb-gen/envoy/extensions/clusters/aggregate/v3/cluster.upb.h +87 -0
  167. data/src/core/ext/upb-gen/envoy/extensions/clusters/aggregate/v3/cluster.upb_minitable.c +29 -2
  168. data/src/core/ext/upb-gen/envoy/extensions/clusters/aggregate/v3/cluster.upb_minitable.h +2 -0
  169. data/src/core/ext/upb-gen/envoy/extensions/filters/http/rbac/v3/rbac.upb.h +0 -1
  170. data/src/core/ext/upb-gen/envoy/extensions/filters/http/rbac/v3/rbac.upb_minitable.c +0 -1
  171. data/src/core/ext/upb-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upb.h +20 -4
  172. data/src/core/ext/upb-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upb_minitable.c +5 -4
  173. data/src/core/ext/upb-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +239 -60
  174. data/src/core/ext/upb-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb_minitable.c +59 -28
  175. data/src/core/ext/upb-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb_minitable.h +2 -0
  176. data/src/core/ext/upb-gen/envoy/extensions/grpc_service/call_credentials/access_token/v3/access_token_credentials.upb.h +89 -0
  177. data/src/core/ext/upb-gen/envoy/extensions/grpc_service/call_credentials/access_token/v3/access_token_credentials.upb_minitable.c +50 -0
  178. data/src/core/ext/upb-gen/envoy/extensions/grpc_service/call_credentials/access_token/v3/access_token_credentials.upb_minitable.h +32 -0
  179. data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/tls/v3/tls_credentials.upb.h +135 -0
  180. data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/tls/v3/tls_credentials.upb_minitable.c +53 -0
  181. data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/tls/v3/tls_credentials.upb_minitable.h +32 -0
  182. data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/xds/v3/xds_credentials.upb.h +105 -0
  183. data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/xds/v3/xds_credentials.upb_minitable.c +51 -0
  184. data/src/core/ext/upb-gen/envoy/extensions/grpc_service/channel_credentials/xds/v3/xds_credentials.upb_minitable.h +32 -0
  185. data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.upb.h +32 -0
  186. data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.upb_minitable.c +6 -3
  187. data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/common/v3/common.upb.h +206 -0
  188. data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/common/v3/common.upb_minitable.c +41 -8
  189. data/src/core/ext/upb-gen/envoy/extensions/load_balancing_policies/common/v3/common.upb_minitable.h +2 -0
  190. data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/common.upb.h +64 -0
  191. data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/common.upb_minitable.c +4 -3
  192. data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb.h +64 -0
  193. data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.c +31 -5
  194. data/src/core/ext/upb-gen/envoy/extensions/transport_sockets/tls/v3/secret.upb_minitable.h +2 -0
  195. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h +283 -14
  196. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c +48 -11
  197. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h +2 -0
  198. data/src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb.h +144 -6
  199. data/src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb_minitable.c +35 -7
  200. data/src/core/ext/upb-gen/envoy/type/http/v3/cookie.upb_minitable.h +2 -0
  201. data/src/core/ext/upb-gen/envoy/type/tracing/v3/custom_tag.upb.h +42 -21
  202. data/src/core/ext/upb-gen/envoy/type/tracing/v3/custom_tag.upb_minitable.c +9 -8
  203. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h +164 -1
  204. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c +37 -6
  205. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h +2 -0
  206. data/src/core/ext/upb-gen/xds/type/matcher/v3/cel.upb.h +0 -1
  207. data/src/core/ext/upb-gen/xds/type/matcher/v3/cel.upb_minitable.c +0 -1
  208. data/src/core/ext/upb-gen/xds/type/matcher/v3/http_inputs.upb.h +0 -1
  209. data/src/core/ext/upb-gen/xds/type/matcher/v3/http_inputs.upb_minitable.c +0 -1
  210. data/src/core/ext/upb-gen/xds/type/matcher/v3/matcher.upb.h +26 -11
  211. data/src/core/ext/upb-gen/xds/type/matcher/v3/matcher.upb_minitable.c +8 -8
  212. data/src/core/ext/upb-gen/xds/type/matcher/v3/string.upb.h +33 -0
  213. data/src/core/ext/upb-gen/xds/type/matcher/v3/string.upb_minitable.c +14 -3
  214. data/src/core/ext/upb-gen/xds/type/v3/cel.upb.h +90 -10
  215. data/src/core/ext/upb-gen/xds/type/v3/cel.upb_minitable.c +18 -7
  216. data/src/core/ext/upbdefs-gen/cel/expr/checked.upbdefs.c +248 -0
  217. data/src/core/ext/upbdefs-gen/cel/expr/checked.upbdefs.h +97 -0
  218. data/src/core/ext/upbdefs-gen/cel/expr/syntax.upbdefs.c +283 -0
  219. data/src/core/ext/upbdefs-gen/cel/expr/syntax.upbdefs.h +107 -0
  220. data/src/core/ext/upbdefs-gen/envoy/config/accesslog/v3/accesslog.upbdefs.c +213 -211
  221. data/src/core/ext/upbdefs-gen/envoy/config/bootstrap/v3/bootstrap.upbdefs.c +635 -614
  222. data/src/core/ext/upbdefs-gen/envoy/config/cluster/v3/cluster.upbdefs.c +1012 -1000
  223. data/src/core/ext/upbdefs-gen/envoy/config/common/matcher/v3/matcher.upbdefs.c +276 -273
  224. data/src/core/ext/upbdefs-gen/envoy/config/common/mutation_rules/v3/mutation_rules.upbdefs.c +152 -0
  225. data/src/core/ext/upbdefs-gen/envoy/config/common/mutation_rules/v3/mutation_rules.upbdefs.h +47 -0
  226. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/address.upbdefs.c +149 -144
  227. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/base.upbdefs.c +367 -370
  228. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/cel.upbdefs.c +63 -0
  229. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/cel.upbdefs.h +37 -0
  230. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/grpc_service.upbdefs.c +297 -284
  231. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/protocol.upbdefs.c +492 -469
  232. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/proxy_protocol.upbdefs.c +74 -43
  233. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/proxy_protocol.upbdefs.h +10 -0
  234. data/src/core/ext/upbdefs-gen/envoy/config/core/v3/substitution_format_string.upbdefs.c +60 -59
  235. data/src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint_components.upbdefs.c +202 -184
  236. data/src/core/ext/upbdefs-gen/envoy/config/endpoint/v3/endpoint_components.upbdefs.h +5 -0
  237. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener.upbdefs.c +354 -339
  238. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/listener.upbdefs.h +5 -0
  239. data/src/core/ext/upbdefs-gen/envoy/config/listener/v3/quic_config.upbdefs.c +28 -19
  240. data/src/core/ext/upbdefs-gen/envoy/config/metrics/v3/metrics_service.upbdefs.c +30 -27
  241. data/src/core/ext/upbdefs-gen/envoy/config/metrics/v3/stats.upbdefs.c +71 -66
  242. data/src/core/ext/upbdefs-gen/envoy/config/overload/v3/overload.upbdefs.c +94 -91
  243. data/src/core/ext/upbdefs-gen/envoy/config/rbac/v3/rbac.upbdefs.c +386 -369
  244. data/src/core/ext/upbdefs-gen/envoy/config/route/v3/route.upbdefs.c +60 -57
  245. data/src/core/ext/upbdefs-gen/envoy/config/route/v3/route_components.upbdefs.c +1974 -1884
  246. data/src/core/ext/upbdefs-gen/envoy/config/tap/v3/common.upbdefs.c +119 -112
  247. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/opentelemetry.upbdefs.c +62 -51
  248. data/src/core/ext/upbdefs-gen/envoy/config/trace/v3/zipkin.upbdefs.c +109 -88
  249. data/src/core/ext/upbdefs-gen/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c +54 -36
  250. data/src/core/ext/upbdefs-gen/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h +5 -0
  251. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.c +78 -84
  252. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/stateful_session/v3/stateful_session.upbdefs.c +48 -46
  253. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c +1041 -984
  254. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h +5 -0
  255. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c +304 -290
  256. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c +94 -77
  257. data/src/core/ext/upbdefs-gen/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.h +5 -0
  258. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c +246 -193
  259. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h +5 -0
  260. data/src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.c +37 -23
  261. data/src/core/ext/upbdefs-gen/envoy/type/http/v3/cookie.upbdefs.h +5 -0
  262. data/src/core/ext/upbdefs-gen/envoy/type/tracing/v3/custom_tag.upbdefs.c +5 -3
  263. data/src/core/ext/upbdefs-gen/google/api/http.upbdefs.c +4 -4
  264. data/src/core/ext/upbdefs-gen/google/api/httpbody.upbdefs.c +4 -5
  265. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c +113 -87
  266. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h +5 -0
  267. data/src/core/ext/upbdefs-gen/udpa/annotations/migrate.upbdefs.c +5 -5
  268. data/src/core/ext/upbdefs-gen/udpa/annotations/security.upbdefs.c +6 -5
  269. data/src/core/ext/upbdefs-gen/udpa/annotations/sensitive.upbdefs.c +5 -5
  270. data/src/core/ext/upbdefs-gen/udpa/annotations/status.upbdefs.c +5 -5
  271. data/src/core/ext/upbdefs-gen/udpa/annotations/versioning.upbdefs.c +5 -5
  272. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/cel.upbdefs.c +25 -30
  273. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/http_inputs.upbdefs.c +14 -20
  274. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/matcher.upbdefs.c +180 -183
  275. data/src/core/ext/upbdefs-gen/xds/type/matcher/v3/string.upbdefs.c +56 -47
  276. data/src/core/ext/upbdefs-gen/xds/type/v3/cel.upbdefs.c +69 -47
  277. data/src/core/filter/filter_chain.h +95 -0
  278. data/src/core/handshaker/http_connect/{http_connect_handshaker.cc → http_connect_client_handshaker.cc} +32 -31
  279. data/src/core/handshaker/http_connect/{http_connect_handshaker.h → http_connect_client_handshaker.h} +4 -4
  280. data/src/core/handshaker/http_connect/http_proxy_mapper.cc +1 -1
  281. data/src/core/handshaker/http_connect/xds_http_proxy_mapper.cc +1 -1
  282. data/src/core/handshaker/security/pipelined_secure_endpoint.cc +14 -13
  283. data/src/core/handshaker/security/secure_endpoint.cc +282 -68
  284. data/src/core/handshaker/security/secure_endpoint.h +0 -7
  285. data/src/core/lib/channel/channel_args.h +1 -1
  286. data/src/core/lib/channel/promise_based_filter.cc +17 -4
  287. data/src/core/lib/channel/promise_based_filter.h +3 -2
  288. data/src/core/lib/debug/trace_flags.cc +2 -0
  289. data/src/core/lib/debug/trace_flags.h +1 -0
  290. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +35 -8
  291. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.h +1 -2
  292. data/src/core/lib/event_engine/event_engine.cc +9 -0
  293. data/src/core/lib/event_engine/extensions/tcp_trace.h +0 -3
  294. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +2 -2
  295. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +1 -1
  296. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +34 -9
  297. data/src/core/lib/event_engine/posix_engine/posix_engine.h +24 -2
  298. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +1 -3
  299. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +141 -14
  300. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h +19 -2
  301. data/src/core/lib/event_engine/posix_engine/posix_interface.h +7 -0
  302. data/src/core/lib/event_engine/posix_engine/posix_interface_posix.cc +21 -3
  303. data/src/core/lib/event_engine/posix_engine/posix_interface_windows.cc +16 -0
  304. data/src/core/lib/experiments/experiments.cc +309 -201
  305. data/src/core/lib/experiments/experiments.h +141 -80
  306. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +2 -2
  307. data/src/core/lib/iomgr/resolve_address.h +0 -2
  308. data/src/core/lib/iomgr/resolved_address.h +0 -2
  309. data/src/core/lib/iomgr/tcp_posix.cc +13 -5
  310. data/src/core/lib/iomgr/tcp_server.cc +0 -5
  311. data/src/core/lib/iomgr/tcp_server.h +0 -7
  312. data/src/core/lib/iomgr/tcp_server_posix.cc +0 -17
  313. data/src/core/lib/iomgr/tcp_server_utils_posix.h +0 -3
  314. data/src/core/lib/iomgr/tcp_server_windows.cc +12 -51
  315. data/src/core/lib/promise/all_ok.h +17 -12
  316. data/src/core/lib/promise/cancel_callback.h +12 -13
  317. data/src/core/lib/promise/detail/join_state.h +626 -0
  318. data/src/core/lib/promise/detail/promise_factory.h +14 -14
  319. data/src/core/lib/promise/for_each.h +32 -8
  320. data/src/core/lib/promise/if.h +9 -7
  321. data/src/core/lib/promise/loop.h +18 -16
  322. data/src/core/lib/promise/map.h +54 -47
  323. data/src/core/lib/promise/mpsc.h +11 -10
  324. data/src/core/lib/promise/observable.h +6 -6
  325. data/src/core/lib/promise/party.h +25 -19
  326. data/src/core/lib/promise/poll.h +5 -5
  327. data/src/core/lib/promise/prioritized_race.h +10 -7
  328. data/src/core/lib/promise/promise.h +16 -11
  329. data/src/core/lib/promise/race.h +6 -5
  330. data/src/core/lib/promise/seq.h +109 -74
  331. data/src/core/lib/promise/try_join.h +14 -6
  332. data/src/core/lib/promise/try_seq.h +76 -60
  333. data/src/core/lib/resource_quota/api.cc +7 -0
  334. data/src/core/lib/resource_quota/arena.h +1 -1
  335. data/src/core/lib/resource_quota/memory_quota.cc +4 -1
  336. data/src/core/lib/resource_quota/resource_quota.cc +2 -1
  337. data/src/core/lib/resource_quota/resource_quota.h +3 -0
  338. data/src/core/lib/resource_quota/stream_quota.cc +77 -1
  339. data/src/core/lib/resource_quota/stream_quota.h +64 -1
  340. data/src/core/lib/resource_quota/telemetry.h +1 -1
  341. data/src/core/lib/surface/call.cc +13 -0
  342. data/src/core/lib/surface/call_utils.h +58 -43
  343. data/src/core/lib/surface/channel.h +1 -4
  344. data/src/core/lib/surface/completion_queue.cc +13 -6
  345. data/src/core/lib/surface/validate_metadata.cc +20 -15
  346. data/src/core/lib/surface/validate_metadata.h +3 -1
  347. data/src/core/lib/surface/version.cc +2 -2
  348. data/src/core/lib/transport/promise_endpoint.cc +1 -1
  349. data/src/core/lib/transport/promise_endpoint.h +1 -1
  350. data/src/core/lib/transport/transport.h +5 -0
  351. data/src/core/load_balancing/health_check_client.cc +1 -15
  352. data/src/core/load_balancing/health_check_client_internal.h +0 -2
  353. data/src/core/load_balancing/oob_backend_metric.cc +1 -5
  354. data/src/core/load_balancing/oob_backend_metric_internal.h +0 -1
  355. data/src/core/load_balancing/xds/xds_cluster_impl.cc +12 -9
  356. data/src/core/plugin_registry/grpc_plugin_registry.cc +3 -2
  357. data/src/core/resolver/xds/xds_resolver.cc +162 -116
  358. data/src/core/server/server.cc +18 -1
  359. data/src/core/server/server.h +2 -0
  360. data/src/core/server/xds_server_config_fetcher.cc +4 -4
  361. data/src/core/telemetry/call_tracer.cc +87 -2
  362. data/src/core/telemetry/call_tracer.h +46 -8
  363. data/src/core/telemetry/instrument.cc +102 -40
  364. data/src/core/telemetry/instrument.h +246 -65
  365. data/src/core/tsi/fake_transport_security.cc +3 -1
  366. data/src/core/tsi/ssl_transport_security.cc +516 -137
  367. data/src/core/tsi/ssl_transport_security.h +28 -22
  368. data/src/core/tsi/ssl_transport_security_utils.cc +2 -2
  369. data/src/core/tsi/ssl_transport_security_utils.h +2 -2
  370. data/src/core/util/bitset.h +6 -0
  371. data/src/core/util/function_signature.h +3 -1
  372. data/src/core/util/http_client/httpcli_security_connector.cc +2 -1
  373. data/src/core/util/json/json_reader.cc +0 -4
  374. data/src/core/xds/grpc/certificate_provider_store.cc +2 -1
  375. data/src/core/xds/grpc/certificate_provider_store.h +3 -17
  376. data/src/core/xds/grpc/certificate_provider_store_interface.h +61 -0
  377. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +48 -0
  378. data/src/core/xds/grpc/xds_bootstrap_grpc.h +18 -0
  379. data/src/core/xds/grpc/xds_certificate_provider.cc +7 -2
  380. data/src/core/xds/grpc/xds_certificate_provider.h +13 -2
  381. data/src/core/xds/grpc/xds_client_grpc.cc +13 -6
  382. data/src/core/xds/grpc/xds_client_grpc.h +10 -7
  383. data/src/core/xds/grpc/xds_cluster.cc +18 -4
  384. data/src/core/xds/grpc/xds_cluster.h +17 -2
  385. data/src/core/xds/grpc/xds_cluster_parser.cc +36 -11
  386. data/src/core/xds/grpc/xds_common_types.cc +45 -0
  387. data/src/core/xds/grpc/xds_common_types.h +31 -0
  388. data/src/core/xds/grpc/xds_common_types_parser.cc +274 -16
  389. data/src/core/xds/grpc/xds_common_types_parser.h +12 -0
  390. data/src/core/xds/grpc/xds_http_fault_filter.cc +128 -24
  391. data/src/core/xds/grpc/xds_http_fault_filter.h +19 -10
  392. data/src/core/xds/grpc/xds_http_filter.cc +38 -0
  393. data/src/core/xds/grpc/xds_http_filter.h +70 -47
  394. data/src/core/xds/grpc/xds_http_filter_registry.cc +48 -14
  395. data/src/core/xds/grpc/xds_http_filter_registry.h +29 -15
  396. data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +88 -22
  397. data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +22 -11
  398. data/src/core/xds/grpc/xds_http_rbac_filter.cc +36 -20
  399. data/src/core/xds/grpc/xds_http_rbac_filter.h +19 -10
  400. data/src/core/xds/grpc/xds_http_stateful_session_filter.cc +143 -26
  401. data/src/core/xds/grpc/xds_http_stateful_session_filter.h +19 -10
  402. data/src/core/xds/grpc/xds_listener.cc +4 -1
  403. data/src/core/xds/grpc/xds_listener.h +10 -2
  404. data/src/core/xds/grpc/xds_listener_parser.cc +23 -18
  405. data/src/core/xds/grpc/xds_matcher.cc +40 -5
  406. data/src/core/xds/grpc/xds_matcher.h +13 -0
  407. data/src/core/xds/grpc/xds_matcher_action.h +1 -1
  408. data/src/core/xds/grpc/xds_matcher_parse.cc +60 -40
  409. data/src/core/xds/grpc/xds_matcher_parse.h +2 -1
  410. data/src/core/xds/grpc/xds_route_config.cc +12 -1
  411. data/src/core/xds/grpc/xds_route_config.h +15 -2
  412. data/src/core/xds/grpc/xds_route_config_parser.cc +11 -5
  413. data/src/core/xds/grpc/xds_routing.cc +181 -6
  414. data/src/core/xds/grpc/xds_routing.h +57 -0
  415. data/src/core/xds/grpc/xds_server_grpc.cc +55 -43
  416. data/src/core/xds/grpc/xds_server_grpc.h +13 -6
  417. data/src/core/xds/grpc/xds_server_grpc_interface.h +3 -2
  418. data/src/core/xds/grpc/xds_transport_grpc.cc +12 -6
  419. data/src/core/xds/grpc/xds_transport_grpc.h +5 -1
  420. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +12 -8
  421. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +18 -12
  422. data/src/ruby/lib/grpc/grpc.rb +7 -9
  423. data/src/ruby/lib/grpc/version.rb +1 -1
  424. data/src/ruby/pb/generate_proto_ruby.sh +1 -1
  425. data/src/ruby/spec/client_server_spec.rb +1 -1
  426. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +1 -1
  427. data/src/ruby/spec/generic/rpc_server_spec.rb +3 -4
  428. data/src/ruby/spec/spec_helper.rb +1 -1
  429. metadata +64 -14
  430. data/src/core/ext/transport/chttp2/transport/security_frame.cc +0 -31
  431. data/src/core/handshaker/security/legacy_secure_endpoint.cc +0 -597
@@ -31,6 +31,7 @@
31
31
  #include <algorithm>
32
32
  #include <atomic>
33
33
  #include <cstddef>
34
+ #include <cstdint>
34
35
  #include <memory>
35
36
  #include <optional>
36
37
  #include <regex>
@@ -100,12 +101,14 @@ class FrameProtector : public RefCounted<FrameProtector> {
100
101
  }
101
102
  }
102
103
  if (zero_copy_protector_ != nullptr) {
103
- if (IsTrackZeroCopyAllocationsInResourceQuotaEnabled()) {
104
- tsi_zero_copy_grpc_protector_set_allocator(zero_copy_protector_,
105
- &AllocSlice, &memory_owner_);
106
- }
104
+ tsi_zero_copy_grpc_protector_set_allocator(zero_copy_protector_,
105
+ &AllocSlice, &memory_owner_);
107
106
  read_staging_buffer_ = grpc_empty_slice();
108
107
  write_staging_buffer_ = grpc_empty_slice();
108
+ } else if (IsSecureEndpointReadCoalescingEnabled()) {
109
+ read_staging_buffer_ = grpc_empty_slice();
110
+ write_staging_buffer_ =
111
+ memory_owner_.MakeSlice(MemoryRequest(STAGING_BUFFER_SIZE));
109
112
  } else {
110
113
  read_staging_buffer_ =
111
114
  memory_owner_.MakeSlice(MemoryRequest(STAGING_BUFFER_SIZE));
@@ -179,9 +182,17 @@ class FrameProtector : public RefCounted<FrameProtector> {
179
182
 
180
183
  void FlushReadStagingBuffer(uint8_t** cur, uint8_t** end)
181
184
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_mu_) {
182
- grpc_slice_buffer_add_indexed(read_buffer_, read_staging_buffer_);
183
- read_staging_buffer_ =
184
- memory_owner_.MakeSlice(MemoryRequest(STAGING_BUFFER_SIZE));
185
+ grpc_slice_buffer_add(read_buffer_, read_staging_buffer_);
186
+ if (required_read_bytes_ > 0) {
187
+ read_staging_buffer_ = grpc_empty_slice();
188
+
189
+ // If we had set a read hint, we must have read at least that many
190
+ // bytes when we do a FlushReadStagingBuffer.
191
+ GRPC_CHECK(read_buffer_->length >= required_read_bytes_);
192
+ } else {
193
+ read_staging_buffer_ =
194
+ memory_owner_.MakeSlice(MemoryRequest(STAGING_BUFFER_SIZE));
195
+ }
185
196
  *cur = GRPC_SLICE_START_PTR(read_staging_buffer_);
186
197
  *end = GRPC_SLICE_END_PTR(read_staging_buffer_);
187
198
  }
@@ -195,6 +206,85 @@ class FrameProtector : public RefCounted<FrameProtector> {
195
206
  read_buffer_ = nullptr;
196
207
  }
197
208
 
209
+ // Unprotects data from the protected buffer and drains the unprotected data
210
+ // into the read buffer. It exits early if the read hint is satisfied or if
211
+ // there's an error.
212
+ // protected_buffer: The ciphertext to unprotect.
213
+ // protected_buffer_size: The length of the protected buffer.
214
+ // cur: Pointer to the current position in the staging buffer.
215
+ // end: Pointer to the end of the staging buffer.
216
+ // encrypted_bytes_processed: The number of ciphertext bytes that were
217
+ // successfully unprotected.
218
+ // hint_satisfied: Set to true if the read hint was satisfied.
219
+ tsi_result UnprotectAndDrain(const uint8_t* protected_buffer,
220
+ size_t protected_buffer_size, uint8_t** cur,
221
+ uint8_t** end, size_t& encrypted_bytes_processed,
222
+ bool& hint_satisfied)
223
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_mu_) {
224
+ tsi_result result = TSI_OK;
225
+
226
+ // 1. If read_hint_bytes_ is 0, we need to keep looping until we have
227
+ // drained all the ciphertext bytes from the protector. We will exit
228
+ // from the inner loop if we have processed all the ciphertext bytes
229
+ // i.e, protected_buffer_size == 0 && unprotected_buffer_size_written == 0.
230
+ //
231
+ // 2. If read_hint_bytes_ is greater than 0, we will exit from the
232
+ // inner loop if we have satisfied the read hint or if we have
233
+ // processed all the ciphertext bytes. i.e,
234
+ // a) read_buffer->length >= read_hint_bytes_ (hint_satisfied), or
235
+ // b) protected_buffer_size == 0 && unprotected_buffer_size_written == 0.
236
+ //
237
+ // 3. We will also exit from the inner loop if the protector returns
238
+ // an error.
239
+ while (true) {
240
+ size_t unprotected_buffer_size_written = static_cast<size_t>(*end - *cur);
241
+ size_t processed_message_size = protected_buffer_size;
242
+
243
+ if (IsTsiFrameProtectorWithoutLocksEnabled()) {
244
+ result = tsi_frame_protector_unprotect(
245
+ protector_, protected_buffer, &processed_message_size, *cur,
246
+ &unprotected_buffer_size_written);
247
+ } else {
248
+ protector_mu_.Lock();
249
+ result = tsi_frame_protector_unprotect(
250
+ protector_, protected_buffer, &processed_message_size, *cur,
251
+ &unprotected_buffer_size_written);
252
+ protector_mu_.Unlock();
253
+ }
254
+ if (result != TSI_OK) {
255
+ LOG(ERROR) << "Decryption error: " << tsi_result_to_string(result);
256
+ break;
257
+ }
258
+ protected_buffer += processed_message_size;
259
+ protected_buffer_size -= processed_message_size;
260
+ encrypted_bytes_processed += processed_message_size;
261
+ *cur += unprotected_buffer_size_written;
262
+
263
+ // Staging buffer is full, flush it.
264
+ if (*cur == *end) {
265
+ FlushReadStagingBuffer(cur, end);
266
+ }
267
+
268
+ // If we have processed all the ciphertext bytes, and the protector
269
+ // is drained, exit the loop.
270
+ if (protected_buffer_size == 0 && unprotected_buffer_size_written == 0) {
271
+ break;
272
+ }
273
+
274
+ // If the read hint is satisfied, exit the loop early.
275
+ if (required_read_bytes_ > 0 &&
276
+ read_buffer_->length +
277
+ (*cur - GRPC_SLICE_START_PTR(read_staging_buffer_)) >=
278
+ required_read_bytes_) {
279
+ // TODO(aananthv): Maybe change the above condition to ==.
280
+ GRPC_DCHECK(read_buffer_->length == required_read_bytes_);
281
+ hint_satisfied = true;
282
+ break;
283
+ }
284
+ }
285
+ return result;
286
+ }
287
+
198
288
  absl::Status Unprotect(absl::Status read_status)
199
289
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(read_mu_) {
200
290
  GRPC_LATENT_SEE_ALWAYS_ON_SCOPE("unprotect");
@@ -204,12 +294,8 @@ class FrameProtector : public RefCounted<FrameProtector> {
204
294
  }
205
295
 
206
296
  GRPC_TRACE_LOG(secure_endpoint, INFO) << "Starting unprotect for " << this;
207
- bool keep_looping = false;
208
297
  tsi_result result = TSI_OK;
209
298
 
210
- uint8_t* cur = GRPC_SLICE_START_PTR(read_staging_buffer_);
211
- uint8_t* end = GRPC_SLICE_END_PTR(read_staging_buffer_);
212
-
213
299
  if (!read_status.ok()) {
214
300
  grpc_slice_buffer_reset_and_unref(read_buffer_);
215
301
  } else if (zero_copy_protector_ != nullptr) {
@@ -229,52 +315,74 @@ class FrameProtector : public RefCounted<FrameProtector> {
229
315
  min_progress_size_ = result != TSI_OK ? 1 : min_progress_size;
230
316
  } else {
231
317
  // Use frame protector to unprotect.
232
- // TODO(yangg) check error, maybe bail out early
233
- for (size_t i = 0; i < source_buffer_.Count(); i++) {
234
- grpc_slice encrypted = source_buffer_.c_slice_buffer()->slices[i];
235
- uint8_t* message_bytes = GRPC_SLICE_START_PTR(encrypted);
236
- size_t message_size = GRPC_SLICE_LENGTH(encrypted);
237
-
238
- while (message_size > 0 || keep_looping) {
239
- size_t unprotected_buffer_size_written =
240
- static_cast<size_t>(end - cur);
241
- size_t processed_message_size = message_size;
242
- if (IsTsiFrameProtectorWithoutLocksEnabled()) {
243
- result = tsi_frame_protector_unprotect(
244
- protector_, message_bytes, &processed_message_size, cur,
245
- &unprotected_buffer_size_written);
246
- } else {
247
- protector_mu_.Lock();
248
- result = tsi_frame_protector_unprotect(
249
- protector_, message_bytes, &processed_message_size, cur,
250
- &unprotected_buffer_size_written);
251
- protector_mu_.Unlock();
252
- }
253
- if (result != TSI_OK) {
254
- LOG(ERROR) << "Decryption error: " << tsi_result_to_string(result);
318
+ size_t read_buffer_len = read_buffer_ ? read_buffer_->length : 0;
319
+ bool hint_satisfied = false;
320
+
321
+ if (required_read_bytes_ > 0) {
322
+ if (required_read_bytes_ >
323
+ read_buffer_len + GRPC_SLICE_LENGTH(read_staging_buffer_)) {
324
+ CSliceUnref(read_staging_buffer_);
325
+ size_t size_to_request = required_read_bytes_ - read_buffer_len;
326
+ read_staging_buffer_ =
327
+ memory_owner_.MakeSlice(MemoryRequest(size_to_request));
328
+ }
329
+ } else if (required_read_bytes_ == 0) {
330
+ if (GRPC_SLICE_IS_EMPTY(read_staging_buffer_)) {
331
+ CSliceUnref(read_staging_buffer_);
332
+ read_staging_buffer_ =
333
+ memory_owner_.MakeSlice(MemoryRequest(STAGING_BUFFER_SIZE));
334
+ }
335
+ }
336
+ uint8_t* cur = GRPC_SLICE_START_PTR(read_staging_buffer_);
337
+ uint8_t* end = GRPC_SLICE_END_PTR(read_staging_buffer_);
338
+
339
+ // Extract any buffered bytes in the protector before processing new
340
+ // slices. The frame_protector will decrypt one TLS record at a time. If
341
+ // we requested a read hint less than the size of a decrypted TLS record,
342
+ // the remaining bytes will be buffered in the frame protector.
343
+ uint8_t kEmptyBuffer[] = {0};
344
+ size_t encrypted_bytes_processed = 0;
345
+ result = UnprotectAndDrain(kEmptyBuffer, 0, &cur, &end,
346
+ encrypted_bytes_processed, hint_satisfied);
347
+ GRPC_DCHECK(encrypted_bytes_processed == 0);
348
+
349
+ // This is the main block where we call the protector to unprotect the
350
+ // newly read ciphertext bytes in the source buffer.
351
+ if (result == TSI_OK && !hint_satisfied && source_buffer_.Count() > 0) {
352
+ for (size_t i = 0; i < source_buffer_.Count(); i++) {
353
+ grpc_slice encrypted = source_buffer_.c_slice_buffer()->slices[i];
354
+ result = UnprotectAndDrain(GRPC_SLICE_START_PTR(encrypted),
355
+ GRPC_SLICE_LENGTH(encrypted), &cur, &end,
356
+ encrypted_bytes_processed, hint_satisfied);
357
+ if (result != TSI_OK || hint_satisfied) {
255
358
  break;
256
359
  }
257
- message_bytes += processed_message_size;
258
- message_size -= processed_message_size;
259
- cur += unprotected_buffer_size_written;
360
+ }
361
+ }
260
362
 
261
- if (cur == end) {
262
- FlushReadStagingBuffer(&cur, &end);
263
- // Force to enter the loop again to extract buffered bytes in
264
- // protector. The bytes could be buffered because of running out
265
- // of staging_buffer. If this happens at the end of all slices,
266
- // doing another unprotect avoids leaving data in the protector.
267
- keep_looping = true;
268
- } else if (unprotected_buffer_size_written > 0) {
269
- keep_looping = true;
270
- } else {
271
- keep_looping = false;
272
- }
363
+ // If the read hint is satisfied, move the remaining encrypted bytes from
364
+ // the source buffer to the leftover bytes buffer.
365
+ if (result == TSI_OK &&
366
+ encrypted_bytes_processed < source_buffer_.Length()) {
367
+ GRPC_CHECK(hint_satisfied)
368
+ << "We should not be here unless the read hint is satisfied.";
369
+
370
+ if (leftover_bytes_ == nullptr) {
371
+ leftover_bytes_ = std::make_unique<SliceBuffer>();
273
372
  }
274
- if (result != TSI_OK) break;
373
+
374
+ grpc_event_engine::experimental::SliceBuffer temp;
375
+ source_buffer_.MoveFirstNBytesIntoSliceBuffer(encrypted_bytes_processed,
376
+ temp);
377
+ temp.Clear();
378
+ grpc_slice_buffer_swap(source_buffer_.c_slice_buffer(),
379
+ leftover_bytes_->c_slice_buffer());
275
380
  }
276
381
 
277
- if (cur != GRPC_SLICE_START_PTR(read_staging_buffer_)) {
382
+ // If the staging buffer is not flushed, move the unprotected bytes in the
383
+ // staging buffer to the read buffer.
384
+ if (result == TSI_OK &&
385
+ cur != GRPC_SLICE_START_PTR(read_staging_buffer_)) {
278
386
  grpc_slice_buffer_add(
279
387
  read_buffer_,
280
388
  grpc_slice_split_head(
@@ -282,6 +390,11 @@ class FrameProtector : public RefCounted<FrameProtector> {
282
390
  static_cast<size_t>(
283
391
  cur - GRPC_SLICE_START_PTR(read_staging_buffer_))));
284
392
  }
393
+ source_buffer_.Clear();
394
+ }
395
+
396
+ if (result != TSI_OK || !read_status.ok()) {
397
+ leftover_bytes_.reset();
285
398
  }
286
399
 
287
400
  if (read_status.ok() && result != TSI_OK) {
@@ -295,16 +408,17 @@ class FrameProtector : public RefCounted<FrameProtector> {
295
408
  return read_status;
296
409
  }
297
410
 
298
- void BeginRead(grpc_slice_buffer* slices) {
411
+ void BeginRead(grpc_slice_buffer* slices, size_t required_read_bytes) {
299
412
  read_buffer_ = slices;
300
413
  grpc_slice_buffer_reset_and_unref(read_buffer_);
414
+ required_read_bytes_ = required_read_bytes;
301
415
  }
302
416
 
303
417
  bool IsZeroCopyProtector() const { return is_zero_copy_protector_; }
304
418
 
305
- bool MaybeCompleteReadImmediately() {
419
+ bool ConsumeLeftovers() {
306
420
  GRPC_TRACE_LOG(secure_endpoint, INFO)
307
- << "MaybeCompleteReadImmediately: " << this
421
+ << "ConsumeLeftovers: " << this
308
422
  << " leftover_bytes_: " << leftover_bytes_.get();
309
423
  if (leftover_bytes_ != nullptr) {
310
424
  grpc_slice_buffer_swap(leftover_bytes_->c_slice_buffer(),
@@ -470,6 +584,7 @@ class FrameProtector : public RefCounted<FrameProtector> {
470
584
  SliceBuffer protector_staging_buffer_;
471
585
  bool shutdown_ = false;
472
586
  bool is_zero_copy_protector_ = false;
587
+ size_t required_read_bytes_ = 0;
473
588
  };
474
589
  } // namespace
475
590
  } // namespace grpc_core
@@ -577,10 +692,10 @@ static void endpoint_read(grpc_endpoint* secure_ep, grpc_slice_buffer* slices,
577
692
  int /*min_progress_size*/) {
578
693
  secure_endpoint* ep = reinterpret_cast<secure_endpoint*>(secure_ep);
579
694
  ep->read_cb = cb;
580
- ep->frame_protector.BeginRead(slices);
695
+ ep->frame_protector.BeginRead(slices, /*required_read_bytes=*/0);
581
696
 
582
697
  SECURE_ENDPOINT_REF(ep, "read");
583
- if (ep->frame_protector.MaybeCompleteReadImmediately()) {
698
+ if (ep->frame_protector.ConsumeLeftovers()) {
584
699
  on_read(ep, absl::OkStatus());
585
700
  return;
586
701
  }
@@ -707,7 +822,7 @@ class SecureEndpoint final : public EventEngine::Endpoint {
707
822
 
708
823
  bool Read(absl::AnyInvocable<void(absl::Status)> on_read, SliceBuffer* buffer,
709
824
  ReadArgs in_args) override {
710
- return impl_->Read(std::move(on_read), buffer, std::move(in_args));
825
+ return impl_->Read(std::move(on_read), buffer, in_args);
711
826
  }
712
827
 
713
828
  bool Write(absl::AnyInvocable<void(absl::Status)> on_writable,
@@ -805,19 +920,38 @@ class SecureEndpoint final : public EventEngine::Endpoint {
805
920
  bool Read(absl::AnyInvocable<void(absl::Status)> on_read,
806
921
  SliceBuffer* buffer, ReadArgs args) {
807
922
  on_read_ = std::move(on_read);
808
- frame_protector_.BeginRead(buffer->c_slice_buffer());
809
- if (frame_protector_.MaybeCompleteReadImmediately()) {
810
- return MaybeFinishReadImmediately();
923
+
924
+ // TODO(aananthv): Evaluate if we need to add a channel_arg to enable this
925
+ // selectively.
926
+ if (grpc_core::IsSecureEndpointReadCoalescingEnabled()) {
927
+ read_buffer_ = buffer;
928
+ // TODO(aananthv): Make required_read_bytes_ a separate field in
929
+ // ReadArgs to avoid confusion between min_progress_size and
930
+ // read_hint_bytes, especially if we enable coalescing by default.
931
+ required_read_bytes_ = std::max<int64_t>(0, args.read_hint_bytes());
932
+ read_args_ = args;
933
+ frame_protector_.BeginRead(buffer->c_slice_buffer(),
934
+ required_read_bytes_);
935
+ frame_protector_.ConsumeLeftovers();
936
+ return ContinueRead(/*is_initial_call=*/true,
937
+ /*status=*/absl::OkStatus());
811
938
  }
812
- if (frame_protector_.IsZeroCopyProtector()) {
813
- args.set_read_hint_bytes(frame_protector_.min_progress_size());
939
+
940
+ frame_protector_.BeginRead(buffer->c_slice_buffer(),
941
+ /*required_read_bytes=*/0);
942
+ if (frame_protector_.ConsumeLeftovers()) {
943
+ return MaybeFinishReadImmediately();
814
944
  }
945
+ // min_progress_size is always 1 for non-zero copy frame protectors. This
946
+ // effectively disables read coalescing, but this is necessary since it
947
+ // is not trivial to determine the encrypted payload size in advance.
948
+ args.set_read_hint_bytes(frame_protector_.min_progress_size());
815
949
  bool read_completed_immediately = wrapped_ep_->Read(
816
950
  [impl = Ref()](absl::Status status) mutable {
817
951
  grpc_core::ExecCtx exec_ctx;
818
952
  FinishAsyncRead(std::move(impl), std::move(status));
819
953
  },
820
- frame_protector_.source_buffer(), std::move(args));
954
+ frame_protector_.source_buffer(), args);
821
955
  if (read_completed_immediately) return MaybeFinishReadImmediately();
822
956
  return false;
823
957
  }
@@ -973,6 +1107,88 @@ class SecureEndpoint final : public EventEngine::Endpoint {
973
1107
  on_read(status);
974
1108
  }
975
1109
 
1110
+ bool ContinueRead(bool is_initial_call, absl::Status status) {
1111
+ while (true) {
1112
+ if (is_initial_call && status.ok() &&
1113
+ grpc_core::IsSecureEndpointOffloadLargeReadsEnabled() &&
1114
+ frame_protector_.source_buffer()->Length() >
1115
+ large_read_threshold_) {
1116
+ event_engine_->Run([impl = Ref()]() mutable {
1117
+ grpc_core::ExecCtx exec_ctx;
1118
+ impl->ContinueRead(/*is_initial_call=*/false,
1119
+ /*status=*/absl::OkStatus());
1120
+ });
1121
+ return false;
1122
+ }
1123
+
1124
+ bool had_source_data = false;
1125
+ {
1126
+ grpc_core::MutexLock lock(frame_protector_.read_mu());
1127
+ if (status.ok() && wrapped_ep_ == nullptr) {
1128
+ status = absl::CancelledError("secure endpoint shutdown");
1129
+ } else {
1130
+ had_source_data = frame_protector_.source_buffer()->Length() > 0;
1131
+ if (had_source_data || is_initial_call) {
1132
+ status = frame_protector_.Unprotect(status);
1133
+ }
1134
+ }
1135
+ }
1136
+
1137
+ if (!status.ok()) {
1138
+ // If status is not OK, abort the read.
1139
+ auto on_read = std::move(on_read_);
1140
+ frame_protector_.FinishRead(false);
1141
+ if (is_initial_call) {
1142
+ // Failures on the initial call are still async.
1143
+ event_engine_->Run(
1144
+ [impl = Ref(), status = std::move(status)]() mutable {
1145
+ auto on_read = std::move(impl->on_read_);
1146
+ impl.reset();
1147
+ on_read(status);
1148
+ });
1149
+ return false;
1150
+ }
1151
+ on_read(status);
1152
+ return false;
1153
+ }
1154
+
1155
+ // If status is OK and we are not in the initial call, we must have
1156
+ // source data (since we would have returned above otherwise).
1157
+ GRPC_DCHECK(had_source_data || is_initial_call);
1158
+
1159
+ // Do not perform an additional read if:
1160
+ // 1. We are in coalescing mode and have accumulated sufficient data
1161
+ // (i.e. required_read_bytes_ bytes).
1162
+ // 2. We are not in coalescing mode, and we have any some data in the
1163
+ // read buffer.
1164
+ bool coalescing_active = required_read_bytes_ > 0;
1165
+ if ((coalescing_active &&
1166
+ read_buffer_->Length() >= required_read_bytes_) ||
1167
+ (!coalescing_active && had_source_data)) {
1168
+ frame_protector_.TraceOp(
1169
+ is_initial_call ? "Read(Imm)" : "Read",
1170
+ frame_protector_.source_buffer()->c_slice_buffer());
1171
+ frame_protector_.FinishRead(true);
1172
+ auto on_read = std::move(on_read_);
1173
+ if (is_initial_call) return true;
1174
+ on_read(absl::OkStatus());
1175
+ return false;
1176
+ }
1177
+
1178
+ // Otherwise, we need to read more data from the underlying endpoint.
1179
+ ReadArgs args = read_args_;
1180
+ args.set_read_hint_bytes(frame_protector_.min_progress_size());
1181
+ bool read_completed_immediately = wrapped_ep_->Read(
1182
+ [impl = Ref()](absl::Status status) mutable {
1183
+ grpc_core::ExecCtx exec_ctx;
1184
+ impl->ContinueRead(/*is_initial_call=*/false,
1185
+ /*status=*/std::move(status));
1186
+ },
1187
+ frame_protector_.source_buffer(), args);
1188
+ if (!read_completed_immediately) return false;
1189
+ }
1190
+ }
1191
+
976
1192
  std::string WritingString() ABSL_EXCLUSIVE_LOCKS_REQUIRED(write_queue_mu_) {
977
1193
  if (!writing_.ok()) return writing_.status().ToString();
978
1194
  return *writing_ ? "true" : "false";
@@ -1065,6 +1281,9 @@ class SecureEndpoint final : public EventEngine::Endpoint {
1065
1281
  ABSL_GUARDED_BY(write_queue_mu_);
1066
1282
  grpc_core::FrameProtector frame_protector_;
1067
1283
  absl::AnyInvocable<void(absl::Status)> on_read_;
1284
+ SliceBuffer* read_buffer_ = nullptr;
1285
+ size_t required_read_bytes_ = 0;
1286
+ ReadArgs read_args_;
1068
1287
  absl::AnyInvocable<void(absl::Status)> on_write_;
1069
1288
  std::unique_ptr<EventEngine::Endpoint> wrapped_ep_;
1070
1289
  std::shared_ptr<EventEngine> event_engine_;
@@ -1085,11 +1304,6 @@ grpc_core::OrphanablePtr<grpc_endpoint> grpc_secure_endpoint_create(
1085
1304
  grpc_core::OrphanablePtr<grpc_endpoint> to_wrap,
1086
1305
  grpc_slice* leftover_slices, size_t leftover_nslices,
1087
1306
  const grpc_core::ChannelArgs& channel_args) {
1088
- if (!grpc_core::IsEventEngineSecureEndpointEnabled()) {
1089
- return grpc_legacy_secure_endpoint_create(
1090
- protector, zero_copy_protector, std::move(to_wrap), leftover_slices,
1091
- channel_args.ToC().get(), leftover_nslices);
1092
- }
1093
1307
  if (grpc_event_engine::experimental::grpc_get_wrapped_event_engine_endpoint(
1094
1308
  to_wrap.get()) != nullptr) {
1095
1309
  std::unique_ptr<grpc_event_engine::experimental::EventEngine::Endpoint>
@@ -48,13 +48,6 @@ grpc_core::OrphanablePtr<grpc_endpoint> grpc_secure_endpoint_create(
48
48
  grpc_slice* leftover_slices, size_t leftover_nslices,
49
49
  const grpc_core::ChannelArgs& channel_args);
50
50
 
51
- grpc_core::OrphanablePtr<grpc_endpoint> grpc_legacy_secure_endpoint_create(
52
- struct tsi_frame_protector* protector,
53
- struct tsi_zero_copy_grpc_protector* zero_copy_protector,
54
- grpc_core::OrphanablePtr<grpc_endpoint> to_wrap,
55
- grpc_slice* leftover_slices, const grpc_channel_args* channel_args,
56
- size_t leftover_nslices);
57
-
58
51
  grpc_core::OrphanablePtr<grpc_endpoint> grpc_pipelined_secure_endpoint_create(
59
52
  struct tsi_frame_protector* protector,
60
53
  struct tsi_zero_copy_grpc_protector* zero_copy_protector,
@@ -49,7 +49,7 @@
49
49
  // TODO(hork): When we're ready to allow setting via a channel arg from the
50
50
  // application, replace this with a macro in
51
51
  // include/grpc/impl/codegen/grpc_types.h.
52
- #define GRPC_INTERNAL_ARG_EVENT_ENGINE "grpc.internal.event_engine"
52
+ #define GRPC_INTERNAL_ARG_EVENT_ENGINE "grpc.experimental.event_engine"
53
53
 
54
54
  // Channel args are intentionally immutable, to avoid the need for locking.
55
55
 
@@ -23,6 +23,7 @@
23
23
  #include <utility>
24
24
  #include <vector>
25
25
 
26
+ #include "src/core/call/metadata.h"
26
27
  #include "src/core/lib/channel/channel_stack.h"
27
28
  #include "src/core/lib/debug/trace.h"
28
29
  #include "src/core/lib/iomgr/error.h"
@@ -2040,6 +2041,7 @@ void ServerCallData::StartBatch(grpc_transport_stream_op_batch* b) {
2040
2041
  !batch->recv_trailing_metadata);
2041
2042
  PollContext poll_ctx(this, &flusher);
2042
2043
  Completed(batch->payload->cancel_stream.cancel_error,
2044
+ std::move(batch->payload->cancel_stream.send_trailing_metadata),
2043
2045
  batch->payload->cancel_stream.tarpit, &flusher);
2044
2046
  if (is_last()) {
2045
2047
  batch.CompleteWith(&flusher);
@@ -2160,6 +2162,7 @@ void ServerCallData::StartBatch(grpc_transport_stream_op_batch* b) {
2160
2162
 
2161
2163
  // Handle cancellation.
2162
2164
  void ServerCallData::Completed(grpc_error_handle error,
2165
+ ServerMetadataHandle trailing_metadata,
2163
2166
  bool tarpit_cancellation, Flusher* flusher) {
2164
2167
  GRPC_TRACE_VLOG(channel, 2)
2165
2168
  << LogTag() << "ServerCallData::Completed: send_trailing_state="
@@ -2187,6 +2190,10 @@ void ServerCallData::Completed(grpc_error_handle error,
2187
2190
  batch->cancel_stream = true;
2188
2191
  batch->payload->cancel_stream.cancel_error = error;
2189
2192
  batch->payload->cancel_stream.tarpit = tarpit_cancellation;
2193
+ if (IsPromiseFilterSendCancelMetadataEnabled()) {
2194
+ batch->payload->cancel_stream.send_trailing_metadata =
2195
+ std::move(trailing_metadata);
2196
+ }
2190
2197
  flusher->Resume(batch);
2191
2198
  }
2192
2199
  break;
@@ -2319,8 +2326,8 @@ void ServerCallData::RecvTrailingMetadataReady(grpc_error_handle error) {
2319
2326
  << " md=" << recv_trailing_metadata_->DebugString();
2320
2327
  Flusher flusher(this);
2321
2328
  PollContext poll_ctx(this, &flusher);
2322
- Completed(error, recv_trailing_metadata_->get(GrpcTarPit()).has_value(),
2323
- &flusher);
2329
+ Completed(error, /*trailing_metadata=*/nullptr,
2330
+ recv_trailing_metadata_->get(GrpcTarPit()).has_value(), &flusher);
2324
2331
  flusher.AddClosure(original_recv_trailing_metadata_ready_, std::move(error),
2325
2332
  "continue recv trailing");
2326
2333
  }
@@ -2527,8 +2534,14 @@ void ServerCallData::WakeInsideCombiner(Flusher* flusher) {
2527
2534
  break;
2528
2535
  case SendTrailingState::kInitial: {
2529
2536
  GRPC_CHECK(*md->get_pointer(GrpcStatusMetadata()) != GRPC_STATUS_OK);
2530
- Completed(StatusFromMetadata(*md), md->get(GrpcTarPit()).has_value(),
2531
- flusher);
2537
+ if (IsPromiseFilterSendCancelMetadataEnabled()) {
2538
+ absl::Status status = StatusFromMetadata(*md);
2539
+ bool tar_pit_set = md->get(GrpcTarPit()).has_value();
2540
+ Completed(std::move(status), std::move(md), tar_pit_set, flusher);
2541
+ } else {
2542
+ Completed(StatusFromMetadata(*md), /*trailing_metadata=*/nullptr,
2543
+ md->get(GrpcTarPit()).has_value(), flusher);
2544
+ }
2532
2545
  } break;
2533
2546
  case SendTrailingState::kCancelled:
2534
2547
  // Nothing to do.
@@ -1843,8 +1843,9 @@ class ServerCallData : public BaseCallData {
1843
1843
  struct SendInitialMetadata;
1844
1844
 
1845
1845
  // Shut things down when the call completes.
1846
- void Completed(grpc_error_handle error, bool tarpit_cancellation,
1847
- Flusher* flusher);
1846
+ void Completed(grpc_error_handle error,
1847
+ ServerMetadataHandle trailing_metadata,
1848
+ bool tarpit_cancellation, Flusher* flusher);
1848
1849
  // Construct a promise that will "call" the next filter.
1849
1850
  // Effectively:
1850
1851
  // - put the modified initial metadata into the batch being sent up.
@@ -111,6 +111,7 @@ TraceFlag secure_endpoint_trace(false, "secure_endpoint");
111
111
  TraceFlag server_channel_trace(false, "server_channel");
112
112
  TraceFlag stateful_session_filter_trace(false, "stateful_session_filter");
113
113
  TraceFlag subchannel_trace(false, "subchannel");
114
+ TraceFlag subchannel_call_trace(false, "subchannel_call");
114
115
  TraceFlag subchannel_pool_trace(false, "subchannel_pool");
115
116
  TraceFlag tcp_trace(false, "tcp");
116
117
  TraceFlag timer_trace(false, "timer");
@@ -193,6 +194,7 @@ const absl::flat_hash_map<std::string, TraceFlag*>& GetAllTraceFlags() {
193
194
  {"server_channel", &server_channel_trace},
194
195
  {"stateful_session_filter", &stateful_session_filter_trace},
195
196
  {"subchannel", &subchannel_trace},
197
+ {"subchannel_call", &subchannel_call_trace},
196
198
  {"subchannel_pool", &subchannel_pool_trace},
197
199
  {"tcp", &tcp_trace},
198
200
  {"timer", &timer_trace},
@@ -109,6 +109,7 @@ extern TraceFlag secure_endpoint_trace;
109
109
  extern TraceFlag server_channel_trace;
110
110
  extern TraceFlag stateful_session_filter_trace;
111
111
  extern TraceFlag subchannel_trace;
112
+ extern TraceFlag subchannel_call_trace;
112
113
  extern TraceFlag subchannel_pool_trace;
113
114
  extern TraceFlag tcp_trace;
114
115
  extern TraceFlag timer_trace;
@@ -17,6 +17,8 @@
17
17
  #ifdef GPR_APPLE
18
18
  #include <AvailabilityMacros.h>
19
19
  #ifdef AVAILABLE_MAC_OS_X_VERSION_10_12_AND_LATER
20
+ #include <sys/socket.h>
21
+ #include <sys/un.h>
20
22
 
21
23
  #include "src/core/lib/event_engine/cf_engine/cfstream_endpoint.h"
22
24
  #include "src/core/util/strerror.h"
@@ -116,14 +118,39 @@ void CFStreamEndpointImpl::Connect(
116
118
  GRPC_TRACE_LOG(event_engine_endpoint, INFO)
117
119
  << "CFStreamEndpointImpl::Connect, host_port: " << peer_address_string_;
118
120
 
119
- std::string host_string;
120
- std::string port_string;
121
- grpc_core::SplitHostPort(host_port.value(), &host_string, &port_string);
122
- CFTypeUniqueRef<CFStringRef> host = CFStringCreateWithCString(
123
- NULL, host_string.c_str(), kCFStringEncodingUTF8);
124
- int port = ResolvedAddressGetPort(peer_address_);
125
- CFStreamCreatePairWithSocketToHost(NULL, host, port, &cf_read_stream_,
126
- &cf_write_stream_);
121
+ if (peer_address_.address()->sa_family == AF_UNIX) {
122
+ struct sockaddr_un server_addr =
123
+ *reinterpret_cast<const struct sockaddr_un*>(peer_address_.address());
124
+ // ResolvedAddress does not set the length field, which does not exist on
125
+ // Linux.
126
+ server_addr.sun_len = sizeof(server_addr);
127
+ CFDataRef address =
128
+ CFDataCreate(NULL, reinterpret_cast<const UInt8*>(&server_addr),
129
+ sizeof(server_addr));
130
+ if (address == NULL) {
131
+ on_connect(absl::UnknownError("Failed to allocate CFData for address"));
132
+ return;
133
+ }
134
+
135
+ CFSocketSignature signature = {
136
+ .protocolFamily = PF_UNIX,
137
+ .socketType = SOCK_STREAM,
138
+ .protocol = 0,
139
+ .address = address,
140
+ };
141
+ CFStreamCreatePairWithPeerSocketSignature(
142
+ NULL, &signature, &cf_read_stream_, &cf_write_stream_);
143
+ CFRelease(address);
144
+ } else {
145
+ std::string host_string;
146
+ std::string port_string;
147
+ grpc_core::SplitHostPort(host_port.value(), &host_string, &port_string);
148
+ CFTypeUniqueRef<CFStringRef> host = CFStringCreateWithCString(
149
+ NULL, host_string.c_str(), kCFStringEncodingUTF8);
150
+ int port = ResolvedAddressGetPort(peer_address_);
151
+ CFStreamCreatePairWithSocketToHost(NULL, host, port, &cf_read_stream_,
152
+ &cf_write_stream_);
153
+ }
127
154
 
128
155
  SetupStreams(std::move(on_connect));
129
156
  }