grpc 1.83.1 → 1.84.0

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 (322) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +21 -17
  3. data/include/grpc/credentials.h +10 -0
  4. data/include/grpc/grpc_security_constants.h +2 -0
  5. data/include/grpc/impl/channel_arg_names.h +9 -0
  6. data/src/core/call/call_filters.h +4 -2
  7. data/src/core/call/client_call.cc +20 -8
  8. data/src/core/call/client_call.h +4 -0
  9. data/src/core/call/interception_chain.cc +2 -0
  10. data/src/core/call/interception_chain.h +14 -1
  11. data/src/core/call/metadata.cc +1 -3
  12. data/src/core/call/metadata_batch.h +13 -5
  13. data/src/core/call/server_call.cc +31 -14
  14. data/src/core/call/server_call.h +4 -0
  15. data/src/core/channelz/text_encode.cc +9 -4
  16. data/src/core/channelz/v2tov1/convert.cc +2 -2
  17. data/src/core/client_channel/backup_poller.cc +1 -2
  18. data/src/core/client_channel/client_channel.cc +6 -33
  19. data/src/core/client_channel/client_channel_filter.cc +22 -55
  20. data/src/core/client_channel/client_channel_filter.h +2 -2
  21. data/src/core/client_channel/client_channel_service_config.cc +3 -19
  22. data/src/core/client_channel/direct_channel.cc +7 -1
  23. data/src/core/client_channel/direct_channel.h +2 -2
  24. data/src/core/client_channel/load_balanced_call_destination.cc +5 -3
  25. data/src/core/client_channel/retry_filter_legacy_call_data.cc +5 -12
  26. data/src/core/client_channel/subchannel.cc +310 -1058
  27. data/src/core/client_channel/subchannel.h +44 -329
  28. data/src/core/client_channel/subchannel_metrics.cc +48 -0
  29. data/src/core/client_channel/subchannel_metrics.h +60 -0
  30. data/src/core/credentials/call/external/file_external_account_credentials.cc +1 -1
  31. data/src/core/credentials/call/external/url_external_account_credentials.cc +2 -3
  32. data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +8 -24
  33. data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.h +3 -6
  34. data/src/core/credentials/call/gdch_service_account/gdch_service_account_credentials.cc +525 -0
  35. data/src/core/credentials/call/gdch_service_account/gdch_service_account_credentials.h +138 -0
  36. data/src/core/credentials/call/json_util.h +1 -0
  37. data/src/core/credentials/call/jwt/json_token.cc +10 -2
  38. data/src/core/credentials/call/jwt/jwt_verifier.cc +15 -1
  39. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc +1 -1
  40. data/src/core/credentials/call/oauth2/oauth2_credentials.cc +42 -79
  41. data/src/core/credentials/call/oauth2/oauth2_credentials.h +2 -5
  42. data/src/core/credentials/call/token_fetcher/token_fetcher_credentials.cc +52 -31
  43. data/src/core/credentials/call/token_fetcher/token_fetcher_credentials.h +21 -8
  44. data/src/core/credentials/transport/google_default/google_default_credentials.cc +3 -4
  45. data/src/core/credentials/transport/ssl/ssl_credentials.cc +59 -72
  46. data/src/core/credentials/transport/ssl/ssl_credentials.h +9 -8
  47. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +12 -6
  48. data/src/core/credentials/transport/ssl/ssl_security_connector.h +4 -4
  49. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +29 -18
  50. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +9 -6
  51. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +45 -56
  52. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +5 -4
  53. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.h +26 -0
  54. data/src/core/credentials/transport/tls/grpc_tls_crl_provider.cc +1 -1
  55. data/src/core/credentials/transport/tls/load_system_roots.h +2 -6
  56. data/src/core/credentials/transport/tls/load_system_roots_fallback.cc +2 -4
  57. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +13 -15
  58. data/src/core/credentials/transport/tls/load_system_roots_supported.h +3 -2
  59. data/src/core/credentials/transport/tls/load_system_roots_windows.cc +5 -8
  60. data/src/core/credentials/transport/tls/spiffe_utils.cc +1 -1
  61. data/src/core/credentials/transport/tls/ssl_utils.cc +39 -28
  62. data/src/core/credentials/transport/tls/ssl_utils.h +12 -49
  63. data/src/core/credentials/transport/tls/tls_security_connector.cc +48 -33
  64. data/src/core/credentials/transport/tls/tls_security_connector.h +31 -10
  65. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +15 -11
  66. data/src/core/ext/filters/http/http_filters_plugin.cc +20 -9
  67. data/src/core/ext/filters/rbac/rbac_filter.cc +43 -21
  68. data/src/core/ext/filters/rbac/rbac_filter.h +21 -3
  69. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +2 -2
  70. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +1 -1
  71. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +6 -20
  72. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +32 -67
  73. data/src/core/ext/transport/chttp2/transport/flow_control.cc +2 -0
  74. data/src/core/ext/transport/chttp2/transport/flow_control.h +78 -4
  75. data/src/core/ext/transport/chttp2/transport/frame.h +2 -0
  76. data/src/core/ext/transport/chttp2/transport/frame_data.cc +3 -4
  77. data/src/core/ext/transport/chttp2/transport/goaway.h +7 -0
  78. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +5 -3
  79. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +3 -1
  80. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +141 -130
  81. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +22 -22
  82. data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +402 -269
  83. data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +80 -49
  84. data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +1 -2
  85. data/src/core/ext/transport/chttp2/transport/http2_status.h +38 -37
  86. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +178 -5
  87. data/src/core/ext/transport/chttp2/transport/http2_transport.h +345 -5
  88. data/src/core/ext/transport/chttp2/transport/parsing.cc +5 -5
  89. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +3 -2
  90. data/src/core/ext/transport/chttp2/transport/ping_promise.h +25 -5
  91. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +3 -4
  92. data/src/core/ext/transport/chttp2/transport/read_context.h +30 -3
  93. data/src/core/ext/transport/chttp2/transport/stream.h +65 -23
  94. data/src/core/ext/transport/chttp2/transport/writing.cc +0 -3
  95. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -5
  96. data/src/core/ext/transport/inproc/legacy_inproc_transport.cc +4 -17
  97. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/ext_proc.upb.h +1912 -0
  98. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/ext_proc.upb_minitable.c +300 -0
  99. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/ext_proc.upb_minitable.h +37 -0
  100. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/processing_mode.upb.h +187 -0
  101. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/processing_mode.upb_minitable.c +64 -0
  102. data/src/core/ext/upb-gen/envoy/extensions/filters/http/ext_proc/v3/processing_mode.upb_minitable.h +31 -0
  103. data/src/core/ext/upb-gen/envoy/service/ext_proc/v3/external_processor.upb.h +2362 -0
  104. data/src/core/ext/upb-gen/envoy/service/ext_proc/v3/external_processor.upb_minitable.c +556 -0
  105. data/src/core/ext/upb-gen/envoy/service/ext_proc/v3/external_processor.upb_minitable.h +47 -0
  106. data/src/core/ext/upb-gen/{src/proto/grpc/channelz → grpc/channelz/v1}/channelz.upb.h +5 -5
  107. data/src/core/ext/upb-gen/{src/proto/grpc/channelz → grpc/channelz/v1}/channelz.upb_minitable.c +3 -3
  108. data/src/core/ext/upb-gen/{src/proto/grpc/channelz → grpc/channelz/v1}/channelz.upb_minitable.h +5 -5
  109. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/ext_proc/v3/ext_proc.upbdefs.c +453 -0
  110. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/ext_proc/v3/ext_proc.upbdefs.h +67 -0
  111. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/ext_proc/v3/processing_mode.upbdefs.c +142 -0
  112. data/src/core/ext/upbdefs-gen/envoy/extensions/filters/http/ext_proc/v3/processing_mode.upbdefs.h +37 -0
  113. data/src/core/ext/upbdefs-gen/grpc/channelz/v1/channelz.upbdefs.c +715 -0
  114. data/src/core/ext/upbdefs-gen/{src/proto/grpc/channelz → grpc/channelz/v1}/channelz.upbdefs.h +44 -44
  115. data/src/core/filter/auth/server_auth_filter.cc +2 -3
  116. data/src/core/filter/composite/composite_filter.cc +45 -33
  117. data/src/core/filter/composite/composite_filter.h +5 -4
  118. data/src/core/filter/ext_proc/ext_proc_filter.cc +224 -0
  119. data/src/core/filter/ext_proc/ext_proc_filter.h +155 -0
  120. data/src/core/filter/ext_proc/ext_proc_messages.cc +701 -0
  121. data/src/core/filter/ext_proc/ext_proc_messages.h +297 -0
  122. data/src/core/filter/filter_args.h +13 -2
  123. data/src/core/handshaker/http_connect/http_proxy_mapper.cc +30 -3
  124. data/src/core/handshaker/security/security_handshaker.cc +9 -6
  125. data/src/core/lib/channel/channel_stack.cc +3 -0
  126. data/src/core/lib/channel/channel_stack.h +2 -0
  127. data/src/core/lib/channel/channel_stack_builder_impl.cc +1 -2
  128. data/src/core/lib/channel/promise_based_filter.cc +132 -20
  129. data/src/core/lib/channel/promise_based_filter.h +42 -12
  130. data/src/core/lib/compression/compression_internal.cc +4 -5
  131. data/src/core/lib/debug/trace_flags.cc +8 -0
  132. data/src/core/lib/debug/trace_flags.h +3 -0
  133. data/src/core/lib/event_engine/ares_resolver.cc +54 -50
  134. data/src/core/lib/event_engine/ares_resolver.h +3 -2
  135. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +3 -3
  136. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +4 -10
  137. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +74 -33
  138. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +4 -4
  139. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +6 -2
  140. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +3 -0
  141. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +3 -0
  142. data/src/core/lib/event_engine/windows/windows_endpoint.cc +1 -3
  143. data/src/core/lib/experiments/experiments.cc +60 -96
  144. data/src/core/lib/experiments/experiments.h +34 -50
  145. data/src/core/lib/iomgr/cfstream_handle.cc +2 -6
  146. data/src/core/lib/iomgr/endpoint_cfstream.cc +3 -10
  147. data/src/core/lib/iomgr/error.cc +2 -6
  148. data/src/core/lib/iomgr/error_cfstream.cc +1 -1
  149. data/src/core/lib/iomgr/ev_poll_posix.cc +5 -9
  150. data/src/core/lib/iomgr/event_engine_shims/closure.cc +1 -1
  151. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +1 -2
  152. data/src/core/lib/iomgr/event_engine_shims/tcp_client.cc +1 -2
  153. data/src/core/lib/iomgr/iomgr_posix.cc +0 -4
  154. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +0 -4
  155. data/src/core/lib/iomgr/iomgr_windows.cc +0 -4
  156. data/src/core/lib/iomgr/socket_factory_posix.h +1 -1
  157. data/src/core/lib/iomgr/socket_utils_posix.cc +3 -0
  158. data/src/core/lib/iomgr/socket_utils_posix.h +3 -0
  159. data/src/core/lib/iomgr/systemd_utils.cc +0 -1
  160. data/src/core/lib/iomgr/tcp_client.h +1 -1
  161. data/src/core/lib/iomgr/tcp_posix.cc +23 -15
  162. data/src/core/lib/iomgr/tcp_server.h +1 -1
  163. data/src/core/lib/iomgr/tcp_server_posix.cc +2 -3
  164. data/src/core/lib/iomgr/tcp_server_utils_posix.h +0 -1
  165. data/src/core/lib/iomgr/tcp_server_windows.cc +0 -1
  166. data/src/core/lib/iomgr/tcp_windows.cc +5 -10
  167. data/src/core/lib/iomgr/unix_sockets_posix.cc +2 -4
  168. data/src/core/lib/iomgr/unix_sockets_posix.h +3 -1
  169. data/src/core/lib/iomgr/vsock.h +3 -1
  170. data/src/core/lib/resource_quota/memory_quota.cc +1 -1
  171. data/src/core/lib/security/authorization/rbac_policy.cc +139 -56
  172. data/src/core/lib/security/authorization/rbac_policy.h +21 -3
  173. data/src/core/lib/surface/call.cc +3 -9
  174. data/src/core/lib/surface/call_utils.h +113 -0
  175. data/src/core/lib/surface/channel_create.cc +1 -1
  176. data/src/core/lib/surface/channel_create.h +0 -2
  177. data/src/core/lib/surface/channel_init.cc +77 -38
  178. data/src/core/lib/surface/channel_init.h +30 -16
  179. data/src/core/lib/surface/filter_stack_call.cc +5 -10
  180. data/src/core/lib/surface/init.cc +13 -27
  181. data/src/core/lib/surface/version.cc +1 -1
  182. data/src/core/lib/transport/error_utils.cc +0 -27
  183. data/src/core/lib/transport/error_utils.h +0 -16
  184. data/src/core/lib/transport/transport.h +7 -5
  185. data/src/core/load_balancing/pick_first/pick_first.cc +2 -0
  186. data/src/core/load_balancing/rls/rls.cc +28 -11
  187. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +33 -42
  188. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.h +0 -2
  189. data/src/core/load_balancing/xds/cds.cc +3 -1
  190. data/src/core/load_balancing/xds/xds_cluster_impl.cc +0 -1
  191. data/src/core/mitigation_engine/mitigation.h +14 -5
  192. data/src/core/mitigation_engine/mitigation_engine.h +7 -3
  193. data/src/core/mitigation_engine/mitigation_provider.h +2 -1
  194. data/src/core/plugin_registry/grpc_plugin_registry.cc +39 -8
  195. data/src/core/resolver/dns/{event_engine/event_engine_client_channel_resolver.cc → dns_resolver.cc} +42 -41
  196. data/src/core/resolver/dns/{event_engine/event_engine_client_channel_resolver.h → dns_resolver.h} +8 -5
  197. data/src/core/resolver/dns/{event_engine/service_config_helper.cc → service_config_helper.cc} +1 -1
  198. data/src/core/resolver/dns/{event_engine/service_config_helper.h → service_config_helper.h} +3 -3
  199. data/src/core/resolver/endpoint_addresses.h +3 -0
  200. data/src/core/resolver/google_c2p/google_c2p_resolver.cc +2 -1
  201. data/src/core/resolver/xds/xds_resolver.cc +35 -9
  202. data/src/core/server/server.cc +2 -6
  203. data/src/core/server/server_config_selector.h +18 -3
  204. data/src/core/server/server_config_selector_filter.cc +178 -91
  205. data/src/core/server/server_config_selector_filter.h +58 -3
  206. data/src/core/server/xds_server_config_fetcher.cc +196 -129
  207. data/src/core/server/xds_server_config_fetcher.h +49 -0
  208. data/src/core/server/xds_server_config_fetcher_legacy.cc +41 -37
  209. data/src/core/telemetry/histogram.h +94 -14
  210. data/src/core/telemetry/instrument.cc +179 -74
  211. data/src/core/telemetry/instrument.h +78 -30
  212. data/src/core/telemetry/metrics.h +5 -0
  213. data/src/core/{resolver/dns/dns_resolver_plugin.h → telemetry/telemetry_label.h} +12 -8
  214. data/src/core/tsi/alts/crypt/aes_gcm.cc +10 -13
  215. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +2 -2
  216. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +3 -1
  217. data/src/core/tsi/ssl_telemetry_utils.cc +216 -259
  218. data/src/core/tsi/ssl_telemetry_utils.h +12 -2
  219. data/src/core/tsi/ssl_transport_security.cc +238 -80
  220. data/src/core/tsi/ssl_transport_security.h +63 -33
  221. data/src/core/tsi/tls_telemetry.cc +31 -0
  222. data/src/core/tsi/tls_telemetry.h +47 -0
  223. data/src/core/tsi/transport_security.cc +2 -2
  224. data/src/core/tsi/transport_security.h +1 -1
  225. data/src/core/tsi/transport_security_interface.h +1 -1
  226. data/src/core/{resolver/dns/native/dns_resolver.h → util/address_sorting_init.cc} +21 -8
  227. data/src/core/{resolver/dns/c_ares/grpc_ares_wrapper_posix.cc → util/address_sorting_init.h} +7 -8
  228. data/src/core/util/http_client/httpcli.cc +16 -53
  229. data/src/core/util/http_client/httpcli.h +0 -7
  230. data/src/core/util/http_client/httpcli_security_connector.cc +13 -8
  231. data/src/core/util/linux/cpu.cc +1 -1
  232. data/src/core/util/load_file.cc +3 -9
  233. data/src/core/util/load_file.h +3 -4
  234. data/src/core/util/matchers.h +8 -0
  235. data/src/core/util/posix/cpu.cc +1 -1
  236. data/src/core/util/status_helper.cc +0 -20
  237. data/src/core/util/status_helper.h +3 -14
  238. data/src/core/xds/grpc/xds_audit_logger_registry.cc +51 -31
  239. data/src/core/xds/grpc/xds_audit_logger_registry.h +17 -3
  240. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -10
  241. data/src/core/xds/grpc/xds_bootstrap_grpc.h +8 -6
  242. data/src/core/xds/grpc/xds_bootstrap_grpc_builder.cc +488 -0
  243. data/src/core/xds/grpc/xds_bootstrap_grpc_builder.h +97 -0
  244. data/src/core/xds/grpc/xds_certificate_provider.cc +7 -7
  245. data/src/core/xds/grpc/xds_client_grpc.cc +4 -8
  246. data/src/core/xds/grpc/xds_client_grpc.h +0 -4
  247. data/src/core/xds/grpc/xds_cluster.h +1 -0
  248. data/src/core/xds/grpc/xds_cluster_parser.cc +1 -5
  249. data/src/core/xds/grpc/xds_cluster_parser.h +0 -2
  250. data/src/core/xds/grpc/xds_cluster_specifier_plugin.cc +0 -2
  251. data/src/core/xds/grpc/xds_cluster_specifier_plugin.h +0 -2
  252. data/src/core/xds/grpc/xds_common_types.cc +0 -91
  253. data/src/core/xds/grpc/xds_common_types.h +1 -47
  254. data/src/core/xds/grpc/xds_common_types_parser.cc +84 -378
  255. data/src/core/xds/grpc/xds_common_types_parser.h +9 -11
  256. data/src/core/xds/grpc/xds_endpoint_parser.cc +0 -2
  257. data/src/core/xds/grpc/xds_grpc_service_parser.cc +177 -0
  258. data/src/core/{resolver/dns/c_ares/dns_resolver_ares.h → xds/grpc/xds_grpc_service_parser.h} +14 -9
  259. data/src/core/xds/grpc/xds_http_composite_filter.cc +26 -21
  260. data/src/core/xds/grpc/xds_http_composite_filter.h +4 -3
  261. data/src/core/xds/grpc/xds_http_ext_proc_filter.cc +418 -0
  262. data/src/core/xds/grpc/xds_http_ext_proc_filter.h +89 -0
  263. data/src/core/xds/grpc/xds_http_fault_filter.cc +9 -12
  264. data/src/core/xds/grpc/xds_http_fault_filter.h +1 -4
  265. data/src/core/xds/grpc/xds_http_filter.cc +2 -1
  266. data/src/core/xds/grpc/xds_http_filter.h +6 -5
  267. data/src/core/xds/grpc/xds_http_filter_registry.cc +10 -127
  268. data/src/core/xds/grpc/xds_http_filter_registry.h +7 -59
  269. data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +13 -14
  270. data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +3 -2
  271. data/src/core/xds/grpc/xds_http_rbac_filter.cc +403 -25
  272. data/src/core/xds/grpc/xds_http_rbac_filter.h +1 -3
  273. data/src/core/xds/grpc/xds_http_stateful_session_filter.cc +8 -13
  274. data/src/core/xds/grpc/xds_http_stateful_session_filter.h +1 -4
  275. data/src/core/xds/grpc/xds_lb_policy_registry.cc +0 -292
  276. data/src/core/xds/grpc/xds_lb_policy_registry.h +7 -3
  277. data/src/core/xds/grpc/xds_listener.cc +2 -0
  278. data/src/core/xds/grpc/xds_listener.h +5 -0
  279. data/src/core/xds/grpc/xds_listener_parser.cc +16 -11
  280. data/src/core/xds/grpc/xds_matcher_parse.h +3 -1
  281. data/src/core/xds/grpc/xds_metadata_parser.cc +6 -1
  282. data/src/core/xds/grpc/xds_metadata_parser.h +2 -0
  283. data/src/core/xds/grpc/xds_route_config.cc +2 -0
  284. data/src/core/xds/grpc/xds_route_config.h +3 -1
  285. data/src/core/xds/grpc/xds_route_config_parser.cc +13 -79
  286. data/src/core/xds/grpc/xds_route_config_parser.h +0 -3
  287. data/src/core/xds/grpc/xds_routing.cc +116 -69
  288. data/src/core/xds/grpc/xds_routing.h +19 -8
  289. data/src/core/xds/grpc/xds_tls_context.cc +117 -0
  290. data/src/core/xds/grpc/xds_tls_context.h +76 -0
  291. data/src/core/xds/grpc/xds_tls_context_parser.cc +275 -0
  292. data/src/core/xds/grpc/xds_tls_context_parser.h +35 -0
  293. data/src/core/xds/grpc/xds_transport_grpc.cc +41 -38
  294. data/src/core/xds/grpc/xds_transport_grpc.h +4 -2
  295. data/src/ruby/ext/grpc/rb_call.c +26 -15
  296. data/src/ruby/ext/grpc/rb_completion_queue.c +6 -5
  297. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  298. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  299. data/src/ruby/lib/grpc/version.rb +1 -1
  300. data/src/ruby/pb/test/client.rb +5 -4
  301. data/src/ruby/spec/call_spec.rb +14 -0
  302. data/src/ruby/spec/generic/server_interceptors_spec.rb +3 -6
  303. metadata +50 -35
  304. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.c +0 -716
  305. data/src/core/lib/iomgr/resolve_address.cc +0 -59
  306. data/src/core/lib/iomgr/resolve_address.h +0 -125
  307. data/src/core/lib/iomgr/resolve_address_impl.h +0 -58
  308. data/src/core/lib/iomgr/resolve_address_posix.cc +0 -184
  309. data/src/core/lib/iomgr/resolve_address_posix.h +0 -78
  310. data/src/core/lib/iomgr/resolve_address_windows.cc +0 -169
  311. data/src/core/lib/iomgr/resolve_address_windows.h +0 -76
  312. data/src/core/resolver/dns/c_ares/dns_resolver_ares.cc +0 -781
  313. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver.h +0 -93
  314. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +0 -203
  315. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +0 -838
  316. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +0 -1237
  317. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.h +0 -130
  318. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +0 -35
  319. data/src/core/resolver/dns/dns_resolver_plugin.cc +0 -64
  320. data/src/core/resolver/dns/native/dns_resolver.cc +0 -173
  321. data/src/core/util/json/json_util.cc +0 -101
  322. data/src/core/util/json/json_util.h +0 -163
@@ -19,24 +19,45 @@
19
19
  #ifndef GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_TRANSPORT_H
20
20
  #define GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_TRANSPORT_H
21
21
 
22
+ #include <grpc/event_engine/event_engine.h>
23
+
24
+ #include <algorithm>
22
25
  #include <cstdint>
26
+ #include <functional>
27
+ #include <memory>
28
+ #include <optional>
29
+ #include <queue>
23
30
  #include <string>
24
31
  #include <type_traits>
32
+ #include <utility>
33
+ #include <variant>
34
+ #include <vector>
25
35
 
36
+ #include "src/core/call/metadata.h"
26
37
  #include "src/core/channelz/channelz.h"
38
+ #include "src/core/channelz/property_list.h"
27
39
  #include "src/core/ext/transport/chttp2/transport/flow_control.h"
28
40
  #include "src/core/ext/transport/chttp2/transport/frame.h"
29
- #include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
30
41
  #include "src/core/ext/transport/chttp2/transport/http2_settings.h"
31
42
  #include "src/core/ext/transport/chttp2/transport/http2_status.h"
32
43
  #include "src/core/ext/transport/chttp2/transport/stream.h"
33
44
  #include "src/core/ext/transport/chttp2/transport/write_cycle.h"
45
+ #include "src/core/lib/channel/channel_args.h"
34
46
  #include "src/core/lib/promise/activity.h"
35
- #include "src/core/lib/promise/poll.h"
47
+ #include "src/core/lib/promise/context.h"
48
+ #include "src/core/lib/promise/for_each.h"
49
+ #include "src/core/lib/promise/if.h"
50
+ #include "src/core/lib/promise/latch.h"
51
+ #include "src/core/lib/promise/loop.h"
52
+ #include "src/core/lib/promise/mpsc.h"
53
+ #include "src/core/lib/promise/sleep.h"
54
+ #include "src/core/lib/promise/status_flag.h"
55
+ #include "src/core/lib/promise/try_seq.h"
36
56
  #include "src/core/lib/slice/slice.h"
37
57
  #include "src/core/util/ref_counted_ptr.h"
58
+ #include "src/core/util/sync.h"
59
+ #include "src/core/util/time.h"
38
60
  #include "absl/log/log.h"
39
- #include "absl/status/status.h"
40
61
 
41
62
  namespace grpc_core {
42
63
  namespace http2 {
@@ -75,7 +96,7 @@ inline bool ShouldEnablePh2Server() {
75
96
  return IsPh2ServerEnabled() || IsPh2ClientServerEnabled();
76
97
  }
77
98
 
78
- // TODO(akshitpatel) [PH2][P3] : Write a way to measure the total size of a
99
+ // TODO(akshitpatel) [PH2][P5] : Write a way to measure the total size of a
79
100
  // transport object. Reference :
80
101
  // https://github.com/grpc/grpc/pull/41294/files#diff-c685cc4847f228327938326e2a45083a2d0845bacff0ac004bd802027a670c4e
81
102
 
@@ -91,7 +112,7 @@ template <typename T, typename Tracker>
91
112
  inline Http2Status ValidateMetadataFrameState(
92
113
  T& frame, Stream& stream, Tracker& incoming_headers,
93
114
  const uint32_t max_header_list_size) {
94
- if (stream.IsStreamHalfClosedRemote()) {
115
+ if (stream.IsClosedForReads()) {
95
116
  return incoming_headers.ParseAndDiscardHeaders(
96
117
  std::move(frame.payload), frame.end_headers,
97
118
  Http2Status::Http2StreamError(
@@ -153,6 +174,11 @@ uint32_t MaxNewStreamsPerRead(const ChannelArgs& channel_args);
153
174
 
154
175
  uint32_t GetMaxSecurityFrameSize(const ChannelArgs& channel_args);
155
176
 
177
+ // Returns the percentage of RST streams on which we should send a ping.
178
+ // Always returns 0 for client transport.
179
+ uint8_t GetPingOnRstStreamPercent(const ChannelArgs& channel_args,
180
+ bool is_client);
181
+
156
182
  ///////////////////////////////////////////////////////////////////////////////
157
183
  // ChannelZ helpers
158
184
 
@@ -183,7 +209,321 @@ void MaybeAddTransportWindowUpdateFrame(
183
209
 
184
210
  void MaybeAddStreamWindowUpdateFrame(Stream& stream, FrameSender& frame_sender);
185
211
 
212
+ // ===========================================================================
213
+ // 3-Stage Transport Shutdown State Machine
214
+ // ===========================================================================
215
+ // Transport shutdown progresses through three distinct stages to ensure
216
+ // thread-safe, lock-free (where possible), and protocol-compliant cleanup.
217
+ //
218
+ // Stage 1: Shutdown Initiated
219
+ // Triggered by MaybeSpawnCloseTransport(). Rejects new external watches
220
+ // and immediately clears stream_list_ (Snapshot 1) to stop read/write
221
+ // processing for active streams.
222
+ // Note: MaybeSpawnCloseTransport is invoked from both transport party and
223
+ // other threads (Orphan flow).
224
+ //
225
+ // Stage 2: Party Shutdown Initiated (Party Lockdown)
226
+ // Triggered when the CloseTransport promise starts running on the transport
227
+ // party. Thread-confined to the party (no locks/atomics needed).
228
+ // Clears stream_list_ again (Snapshot 2) to capture raced streams, and
229
+ // causes the transport to immediately reject any new or queued streams
230
+ // (via InitializeStream() on client, or IncomingStream() on server).
186
231
  //
232
+ // Stage 3: Shutdown Completed (Final Termination)
233
+ // Triggered when CloseTransport() finishes (GOAWAY sent or timed out on
234
+ // client). Wakes up and cancels all remaining promises on the transport
235
+ // party.
236
+ // ===========================================================================
237
+ class TransportShutdownTracker {
238
+ public:
239
+ TransportShutdownTracker() = default;
240
+
241
+ // Transport shutdown is not copyable or movable.
242
+ TransportShutdownTracker(const TransportShutdownTracker&) = delete;
243
+ TransportShutdownTracker& operator=(const TransportShutdownTracker&) = delete;
244
+ TransportShutdownTracker(TransportShutdownTracker&&) = delete;
245
+ TransportShutdownTracker& operator=(TransportShutdownTracker&&) = delete;
246
+
247
+ // Stage 1: Shutdown Initiated
248
+ void InitiateShutdown(const Mutex& mu) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu) {
249
+ shutdown_initiated_ = true;
250
+ }
251
+ bool IsShutdownInitiated(const Mutex& mu) const
252
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu) {
253
+ return shutdown_initiated_;
254
+ }
255
+
256
+ // Stage 2: Party Shutdown Initiated (Party Lockdown)
257
+ void InitiatePartyShutdown() { party_shutdown_initiated_ = true; }
258
+ bool IsPartyShutdownInitiated() const { return party_shutdown_initiated_; }
259
+
260
+ // Stage 3: Shutdown Completed (Final Termination)
261
+ void MarkShutdownComplete() { shutdown_completed_latch_.Set(); }
262
+ auto WaitShutdownComplete() { return shutdown_completed_latch_.Wait(); }
263
+
264
+ private:
265
+ bool shutdown_initiated_ = false;
266
+ bool party_shutdown_initiated_ = false;
267
+ Latch<void> shutdown_completed_latch_;
268
+ };
269
+
270
+ // Represents a stream queued for tarpitting and its scheduled expiration time.
271
+ // The payload variant defines the terminal action to perform once the tarpit
272
+ // duration elapses:
273
+ // - OutgoingResetPayload: sends a delayed RST_STREAM.
274
+ // - OutgoingTrailingMetadataPayload: sends delayed server trailing metadata.
275
+ // - IncomingResetPayload: Stream closure triggered by Client sending an
276
+ // RST_STREAM.
277
+ // The functions in this class are not thread-safe.
278
+ class TarpitEntry {
279
+ public:
280
+ struct OutgoingResetPayload {
281
+ absl::Status trailing_metadata_status;
282
+ uint32_t http2_error_code = 0;
283
+ };
284
+
285
+ struct OutgoingTrailingMetadataPayload {
286
+ ServerMetadataHandle metadata;
287
+ };
288
+
289
+ struct IncomingResetPayload {
290
+ absl::Status status;
291
+ };
292
+
293
+ TarpitEntry(TarpitEntry&&) = default;
294
+ TarpitEntry& operator=(TarpitEntry&&) = default;
295
+ TarpitEntry(const TarpitEntry&) = delete;
296
+ TarpitEntry& operator=(const TarpitEntry&) = delete;
297
+
298
+ // Factory methods for constructing tarpit entries from producers across
299
+ // different parties.
300
+ static TarpitEntry CreateOutgoingReset(const uint32_t stream_id,
301
+ const uint32_t http2_error_code,
302
+ absl::Status trailing_metadata_status,
303
+ const Timestamp expire_time) {
304
+ return TarpitEntry(stream_id,
305
+ OutgoingResetPayload{std::move(trailing_metadata_status),
306
+ http2_error_code},
307
+ expire_time);
308
+ }
309
+ static TarpitEntry CreateOutgoingTrailingMetadata(
310
+ const uint32_t stream_id, ServerMetadataHandle metadata,
311
+ const Timestamp expire_time) {
312
+ return TarpitEntry(stream_id,
313
+ OutgoingTrailingMetadataPayload{std::move(metadata)},
314
+ expire_time);
315
+ }
316
+ static TarpitEntry CreateIncomingReset(const uint32_t stream_id,
317
+ absl::Status status,
318
+ const Timestamp expire_time) {
319
+ return TarpitEntry(stream_id, IncomingResetPayload{std::move(status)},
320
+ expire_time);
321
+ }
322
+
323
+ Timestamp GetExpireTime() const { return expire_time_; }
324
+ uint32_t GetStreamId() const { return stream_id_; }
325
+
326
+ bool IsOutgoingReset() const {
327
+ return std::holds_alternative<OutgoingResetPayload>(payload_);
328
+ }
329
+ bool IsOutgoingTrailingMetadata() const {
330
+ return std::holds_alternative<OutgoingTrailingMetadataPayload>(payload_);
331
+ }
332
+ bool IsIncomingReset() const {
333
+ return std::holds_alternative<IncomingResetPayload>(payload_);
334
+ }
335
+
336
+ // Consumes and extracts the payload when executing the post-tarpit action.
337
+ // Returns std::nullopt if the payload type does not match.
338
+ std::optional<OutgoingResetPayload> TakeOutgoingResetPayload() {
339
+ OutgoingResetPayload* const p =
340
+ std::get_if<OutgoingResetPayload>(&payload_);
341
+ if (p != nullptr) {
342
+ return std::move(*p);
343
+ }
344
+ return std::nullopt;
345
+ }
346
+ std::optional<OutgoingTrailingMetadataPayload>
347
+ TakeOutgoingTrailingMetadataPayload() {
348
+ OutgoingTrailingMetadataPayload* const p =
349
+ std::get_if<OutgoingTrailingMetadataPayload>(&payload_);
350
+ if (p != nullptr) {
351
+ return std::move(*p);
352
+ }
353
+ return std::nullopt;
354
+ }
355
+ std::optional<IncomingResetPayload> TakeIncomingResetPayload() {
356
+ IncomingResetPayload* const p =
357
+ std::get_if<IncomingResetPayload>(&payload_);
358
+ if (p != nullptr) {
359
+ return std::move(*p);
360
+ }
361
+ return std::nullopt;
362
+ }
363
+
364
+ std::string DebugString() const;
365
+
366
+ bool operator>(const TarpitEntry& other) const {
367
+ return expire_time_ > other.expire_time_;
368
+ }
369
+
370
+ private:
371
+ using Payload =
372
+ std::variant<OutgoingResetPayload, OutgoingTrailingMetadataPayload,
373
+ IncomingResetPayload>;
374
+
375
+ TarpitEntry(const uint32_t stream_id, Payload payload,
376
+ const Timestamp expire_time)
377
+ : stream_id_(stream_id),
378
+ expire_time_(expire_time),
379
+ payload_(std::move(payload)) {}
380
+
381
+ uint32_t stream_id_ = 0;
382
+ Timestamp expire_time_ = Timestamp::InfPast();
383
+ Payload payload_;
384
+ };
385
+
386
+ class TarpitQueue {
387
+ public:
388
+ TarpitQueue() = default;
389
+ TarpitQueue(const TarpitQueue&) = delete;
390
+ TarpitQueue& operator=(const TarpitQueue&) = delete;
391
+ TarpitQueue(TarpitQueue&&) = default;
392
+ TarpitQueue& operator=(TarpitQueue&&) = default;
393
+
394
+ bool IsEmpty() const { return entries_.empty(); }
395
+ size_t Size() const { return entries_.size(); }
396
+
397
+ const TarpitEntry& Top() const {
398
+ GRPC_DCHECK(!entries_.empty());
399
+ return entries_.front();
400
+ }
401
+
402
+ void Push(TarpitEntry entry) {
403
+ entries_.push_back(std::move(entry));
404
+ std::push_heap(entries_.begin(), entries_.end(), std::greater<>());
405
+ }
406
+
407
+ TarpitEntry Pop() {
408
+ GRPC_DCHECK(!entries_.empty());
409
+ std::pop_heap(entries_.begin(), entries_.end(), std::greater<>());
410
+ TarpitEntry top_entry = std::move(entries_.back());
411
+ entries_.pop_back();
412
+ return top_entry;
413
+ }
414
+
415
+ void Clear() { entries_.clear(); }
416
+
417
+ private:
418
+ std::vector<TarpitEntry> entries_;
419
+ };
420
+
421
+ class TarpitManager {
422
+ public:
423
+ explicit TarpitManager(const ChannelArgs& channel_args);
424
+
425
+ ~TarpitManager() = default;
426
+
427
+ // TarpitManager is neither copyable nor movable.
428
+ TarpitManager(const TarpitManager&) = delete;
429
+ TarpitManager& operator=(const TarpitManager&) = delete;
430
+ TarpitManager(TarpitManager&&) = delete;
431
+ TarpitManager& operator=(TarpitManager&&) = delete;
432
+
433
+ //----------------------------------------------------------------------------
434
+ // Off-Party Producer Methods (Can be called from any thread/party)
435
+ //----------------------------------------------------------------------------
436
+
437
+ // Producer APIs called by the transport to enqueue delayed stream actions.
438
+ //
439
+ // Note:
440
+ // - Callers MUST verify allow_tarpit() is true before invoking these APIs.
441
+ // - Returns StatusFlag::kFailure if the MPSC channel is closed or full, in
442
+ // which case the caller MUST initiate transport teardown (connection
443
+ // error). In theory the MPSC queue can never be full , because it cannot
444
+ // have more than MAX_CONCURRENT_STREAMS number of streams in it.
445
+
446
+ // Sends a delayed RST_STREAM.
447
+ StatusFlag RequestCloseStream(uint32_t stream_id,
448
+ uint32_t reset_stream_error_code,
449
+ absl::Status trailing_metadata_status);
450
+
451
+ // Sends delayed server trailing metadata.
452
+ StatusFlag StartTarpitTrailers(uint32_t stream_id,
453
+ ServerMetadataHandle metadata);
454
+
455
+ // Performs delayed stream closure following an incoming RST_STREAM.
456
+ StatusFlag RequestTarpitIncomingReset(uint32_t stream_id,
457
+ absl::Status status);
458
+
459
+ //----------------------------------------------------------------------------
460
+ // Transport-Party Confined Methods (Must be run on TransportParty)
461
+ //----------------------------------------------------------------------------
462
+
463
+ // Prepares an incoming Stream on the transport party by marking the stream
464
+ // tarpitted and initiating read-silencing. Returns the StreamStateChange to
465
+ // be handled by the server transport.
466
+ StreamStateChange OnTarpit(Stream& stream);
467
+
468
+ void AddToQueue(TarpitEntry&& entry);
469
+ std::vector<TarpitEntry> OnTimerExpired();
470
+ void Shutdown();
471
+
472
+ channelz::PropertyList ChannelzProperties() const;
473
+
474
+ bool allow_tarpit() const { return allow_tarpit_; }
475
+
476
+ auto NextMessage() { return receiver_.Next(); }
477
+
478
+ // Returns a promise that waits for the earliest expiration time of tarpitted
479
+ // streams, or suspends if the queue is empty.
480
+ auto WaitForTimerExpire() {
481
+ return If(
482
+ [this]() -> Poll<bool> {
483
+ if (GPR_UNLIKELY(shutdown_)) {
484
+ return false;
485
+ }
486
+ if (tarpit_queue_.IsEmpty()) {
487
+ empty_queue_waker_ = GetContext<Activity>()->MakeNonOwningWaker();
488
+ return Pending{};
489
+ }
490
+ return true;
491
+ },
492
+ [this]() {
493
+ // Sleep at least for kMinTarpitSleepDuration to avoid potential
494
+ // busy-looping if there are lot of entries with expiration time in
495
+ // near future. This works for the tarpit use case as this guarantees
496
+ // we would close stream strictly after the expiration time.
497
+ return Sleep(std::max(tarpit_queue_.Top().GetExpireTime(),
498
+ Timestamp::Now() + kMinTarpitSleepDuration));
499
+ },
500
+ []() -> Poll<absl::Status> {
501
+ return absl::CancelledError("TarpitManager shutdown");
502
+ });
503
+ }
504
+
505
+ private:
506
+ static constexpr Duration kMinTarpitSleepDuration =
507
+ Duration::Milliseconds(10);
508
+
509
+ Duration GetTarpitDuration() const;
510
+
511
+ const bool allow_tarpit_ = true;
512
+ const Duration min_tarpit_duration_;
513
+ const Duration max_tarpit_duration_;
514
+ bool shutdown_ = false;
515
+
516
+ MpscReceiver<TarpitEntry> receiver_;
517
+ MpscSender<TarpitEntry> sender_;
518
+
519
+ // Queue ordered by earliest expiration time for pending tarpitted streams.
520
+ TarpitQueue tarpit_queue_;
521
+
522
+ // Waker for resuming WaitForTimerExpire when transitioning from an empty
523
+ // queue to a non-empty queue.
524
+ Waker empty_queue_waker_;
525
+ };
526
+
187
527
  } // namespace http2
188
528
  } // namespace grpc_core
189
529
 
@@ -544,7 +544,7 @@ static grpc_error_handle init_header_skip_frame_parser(
544
544
  t->settings.acked().max_header_list_size(),
545
545
  hpack_boundary_type(t, is_eoh), priority_type,
546
546
  hpack_parser_log_info(t, HPackParser::LogInfo::kDontKnow),
547
- t->mitigation_engine.get());
547
+ t->mitigation_engine.get(), t->peer_string.as_string_view());
548
548
  return absl::OkStatus();
549
549
  }
550
550
 
@@ -631,8 +631,7 @@ error_handler:
631
631
  return absl::OkStatus();
632
632
  } else if (s != nullptr) {
633
633
  // handle stream errors by closing the stream
634
- grpc_chttp2_mark_stream_closed(t, s, true, false,
635
- absl_status_to_grpc_error(status));
634
+ grpc_chttp2_mark_stream_closed(t, s, true, false, status);
636
635
  grpc_error_handle rst_error = grpc_chttp2_add_rst_stream_to_next_write(
637
636
  t, t->incoming_stream_id,
638
637
  static_cast<uint32_t>(Http2ErrorCode::kProtocolError),
@@ -640,7 +639,7 @@ error_handler:
640
639
  if (GPR_UNLIKELY(!rst_error.ok())) return rst_error;
641
640
  return init_non_header_skip_frame_parser(t);
642
641
  } else {
643
- return absl_status_to_grpc_error(status);
642
+ return status;
644
643
  }
645
644
  }
646
645
 
@@ -895,7 +894,8 @@ static grpc_error_handle init_header_frame_parser(grpc_chttp2_transport* t,
895
894
  t->settings.acked().max_header_list_size(),
896
895
  hpack_boundary_type(t, is_eoh), priority_type,
897
896
  hpack_parser_log_info(t, frame_type),
898
- t->mitigation_engine.get());
897
+ t->mitigation_engine.get(),
898
+ t->peer_string.as_string_view());
899
899
  return absl::OkStatus();
900
900
  }
901
901
 
@@ -61,12 +61,13 @@ Promise<absl::Status> PingManager::PingPromiseCallbacks::WaitForPingAck() {
61
61
  }
62
62
 
63
63
  // Ping System implementation
64
- PingManager::PingManager(const ChannelArgs& channel_args, Duration ping_timeout,
64
+ PingManager::PingManager(const ChannelArgs& channel_args, const bool is_client,
65
+ Duration ping_timeout,
65
66
  std::unique_ptr<PingInterface> ping_interface,
66
67
  std::shared_ptr<EventEngine> event_engine)
67
68
  : ping_callbacks_(event_engine),
68
69
  ping_abuse_policy_(channel_args),
69
- ping_rate_policy_(channel_args, /*is_client=*/true),
70
+ ping_rate_policy_(channel_args, is_client),
70
71
  ping_interface_(std::move(ping_interface)),
71
72
  ping_timeout_(ping_timeout) {}
72
73
 
@@ -22,6 +22,7 @@
22
22
  #include <cstdint>
23
23
  #include <memory>
24
24
  #include <optional>
25
+ #include <string>
25
26
  #include <utility>
26
27
  #include <vector>
27
28
 
@@ -46,6 +47,7 @@
46
47
  #include "absl/functional/any_invocable.h"
47
48
  #include "absl/log/log.h"
48
49
  #include "absl/status/status.h"
50
+ #include "absl/strings/str_cat.h"
49
51
 
50
52
  namespace grpc_core {
51
53
  namespace http2 {
@@ -120,12 +122,14 @@ class PingManager {
120
122
  important_ping_requested_ = false;
121
123
  return ping_callbacks_.StartPing(SharedBitGen());
122
124
  }
123
- bool PingRequested() { return ping_callbacks_.ping_requested(); }
125
+ bool PingRequested() const { return ping_callbacks_.ping_requested(); }
124
126
  bool ImportantPingRequested() const { return important_ping_requested_; }
125
127
  bool AckPing(uint64_t id) {
126
128
  return ping_callbacks_.AckPing(id, event_engine_.get());
127
129
  }
128
- size_t CountPingInflight() { return ping_callbacks_.pings_inflight(); }
130
+ size_t CountPingInflight() const {
131
+ return ping_callbacks_.pings_inflight();
132
+ }
129
133
 
130
134
  auto PingTimeout(Duration ping_timeout) {
131
135
  std::shared_ptr<InterActivityLatch<void>> latch =
@@ -184,7 +188,8 @@ class PingManager {
184
188
  void SentPing() { ping_rate_policy_.SentPing(); }
185
189
 
186
190
  public:
187
- PingManager(const ChannelArgs& channel_args, Duration ping_timeout,
191
+ PingManager(const ChannelArgs& channel_args, bool is_client,
192
+ Duration ping_timeout,
188
193
  std::unique_ptr<PingInterface> ping_interface,
189
194
  std::shared_ptr<grpc_event_engine::experimental::EventEngine>
190
195
  event_engine);
@@ -209,6 +214,19 @@ class PingManager {
209
214
  return ping_abuse_policy_.ReceivedOnePing(transport_idle);
210
215
  }
211
216
 
217
+ std::string GetDebugString(const bool transport_idle) const {
218
+ return absl::StrCat(
219
+ "delayed_ping_spawned: ", delayed_ping_spawned_, ", opaque_data: ",
220
+ opaque_data_.has_value() ? absl::StrCat(opaque_data_.value()) : "none",
221
+ ", pending_ping_acks: ", pending_ping_acks_.size(),
222
+ ", ping_timeout: ", ping_timeout_.ToString(),
223
+ ", ping_requested: ", PingRequested(),
224
+ ", important_ping_requested: ", ImportantPingRequested(),
225
+ ", pings_inflight: ", CountPingInflight(), ", ping_rate_policy: { ",
226
+ ping_rate_policy_.GetDebugString(), " }, ping_abuse_policy: { ",
227
+ ping_abuse_policy_.GetDebugString(transport_idle), " }");
228
+ }
229
+
212
230
  void ResetPingClock(bool is_client) {
213
231
  if (!is_client) {
214
232
  ping_abuse_policy_.ResetPingStrikes();
@@ -235,12 +253,14 @@ class PingManager {
235
253
  void CancelCallbacks() { ping_callbacks_.CancelCallbacks(); }
236
254
 
237
255
  uint64_t StartPing() { return ping_callbacks_.StartPing(); }
238
- bool PingRequested() { return ping_callbacks_.PingRequested(); }
256
+ bool PingRequested() const { return ping_callbacks_.PingRequested(); }
239
257
  bool ImportantPingRequested() const {
240
258
  return ping_callbacks_.ImportantPingRequested();
241
259
  }
242
260
  bool AckPing(uint64_t id) { return ping_callbacks_.AckPing(id); }
243
- size_t CountPingInflight() { return ping_callbacks_.CountPingInflight(); }
261
+ size_t CountPingInflight() const {
262
+ return ping_callbacks_.CountPingInflight();
263
+ }
244
264
 
245
265
  Http2Frame GetHttp2PingFrame(uint64_t opaque_data) {
246
266
  return Http2PingFrame{/*ack=*/false, opaque_data};
@@ -43,10 +43,9 @@ Chttp2PingRatePolicy::Chttp2PingRatePolicy(const ChannelArgs& args,
43
43
  : 0),
44
44
  // Configuration via channel arg dominates, otherwise if the multiping
45
45
  // experiment is enabled we use 100, otherwise 1.
46
- max_inflight_pings_(
47
- std::max(0, args.GetInt(GRPC_ARG_HTTP2_MAX_INFLIGHT_PINGS)
48
- .value_or(g_default_max_inflight_pings.value_or(
49
- IsMultipingEnabled() ? 100 : 1)))) {}
46
+ max_inflight_pings_(std::max(
47
+ 0, args.GetInt(GRPC_ARG_HTTP2_MAX_INFLIGHT_PINGS)
48
+ .value_or(g_default_max_inflight_pings.value_or(1)))) {}
50
49
 
51
50
  void Chttp2PingRatePolicy::SetDefaults(const ChannelArgs& args) {
52
51
  g_default_max_pings_without_data_sent =
@@ -37,14 +37,20 @@
37
37
  #include "src/core/lib/transport/promise_endpoint.h"
38
38
  #include "src/core/util/debug_location.h"
39
39
  #include "src/core/util/grpc_check.h"
40
+ #include "src/core/util/shared_bit_gen.h"
40
41
  #include "absl/log/log.h"
41
- #include "absl/status/statusor.h"
42
+ #include "absl/random/distributions.h"
42
43
  #include "absl/strings/str_cat.h"
43
44
 
44
45
  namespace grpc_core {
45
46
  namespace http2 {
46
47
  constexpr uint32_t kCurrentCycleMaxResetStreams = 1024u;
47
48
 
49
+ inline bool ShouldSendPingOnRstStream(
50
+ const uint8_t ping_on_rst_stream_percent) {
51
+ return absl::Bernoulli(SharedBitGen(), ping_on_rst_stream_percent / 100.0);
52
+ }
53
+
48
54
  class ReadLoopPauseRestart {
49
55
  public:
50
56
  ReadLoopPauseRestart() = default;
@@ -166,14 +172,20 @@ class IncomingMetadataState {
166
172
  uint32_t stream_id_ = 0;
167
173
  };
168
174
 
175
+ struct ShouldSendPing {
176
+ bool should_send_ping_on_rst_stream = false;
177
+ };
178
+
169
179
  class ReadContext {
170
180
  public:
171
181
  explicit ReadContext(const uint32_t max_new_streams_per_read_cycle,
172
182
  const PromiseEndpoint& endpoint, const bool is_client,
173
- const uint32_t max_security_frame_size)
183
+ const uint32_t max_security_frame_size,
184
+ const uint8_t ping_on_rst_stream_percent)
174
185
  : max_new_streams_per_read_cycle_(max_new_streams_per_read_cycle),
175
186
  peer_string_(GetPeerString(endpoint)),
176
187
  is_client_(is_client),
188
+ ping_on_rst_stream_percent_(ping_on_rst_stream_percent),
177
189
  max_security_frame_size_(max_security_frame_size),
178
190
  header_assembler_(is_client) {
179
191
  GRPC_DCHECK(max_new_streams_per_read_cycle > 0u)
@@ -296,7 +308,20 @@ class ReadContext {
296
308
  void OnPingFrameReceived() { IncrementInducedFrames(); }
297
309
 
298
310
  // Called when we read a RST_STREAM frame from the peer.
299
- void OnResetFrameReceived() { IncrementResetStreamFrames(); }
311
+ // Returns true if a ping should be sent in response.
312
+ ShouldSendPing OnResetFrameReceived() {
313
+ IncrementResetStreamFrames();
314
+ if (ping_on_rst_stream_percent_ > 0 && !ping_on_rst_stream_in_progress_ &&
315
+ ShouldSendPingOnRstStream(ping_on_rst_stream_percent_)) {
316
+ IncrementInducedFrames();
317
+ return ShouldSendPing{true};
318
+ }
319
+ return ShouldSendPing{false};
320
+ }
321
+ void SetPingOnRstStreamInProgress(bool value) {
322
+ GRPC_DCHECK(!is_client_);
323
+ ping_on_rst_stream_in_progress_ = value;
324
+ }
300
325
 
301
326
  // Called when a HEADER frame is received.
302
327
  void UpdateState(const Http2HeaderFrame& frame,
@@ -477,6 +502,8 @@ class ReadContext {
477
502
  const Slice peer_string_;
478
503
  const bool is_client_;
479
504
 
505
+ const uint8_t ping_on_rst_stream_percent_;
506
+ bool ping_on_rst_stream_in_progress_ = false;
480
507
  const uint32_t max_security_frame_size_;
481
508
  uint32_t max_header_list_size_soft_limit_ =
482
509
  DEFAULT_MAX_HEADER_LIST_SIZE_SOFT_LIMIT;