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
@@ -34,6 +34,7 @@
34
34
  #include "src/core/channelz/channelz.h"
35
35
  #include "src/core/client_channel/buffered_call.h"
36
36
  #include "src/core/client_channel/client_channel_internal.h"
37
+ #include "src/core/client_channel/subchannel_metrics.h"
37
38
  #include "src/core/client_channel/subchannel_pool_interface.h"
38
39
  #include "src/core/client_channel/subchannel_stream_limiter.h"
39
40
  #include "src/core/config/core_configuration.h"
@@ -57,6 +58,7 @@
57
58
  #include "src/core/lib/transport/transport.h"
58
59
  #include "src/core/telemetry/stats.h"
59
60
  #include "src/core/telemetry/stats_data.h"
61
+ #include "src/core/transport/auth_context.h"
60
62
  #include "src/core/util/alloc.h"
61
63
  #include "src/core/util/backoff.h"
62
64
  #include "src/core/util/debug_location.h"
@@ -97,972 +99,56 @@ using ::grpc_event_engine::experimental::EventEngine;
97
99
  // Subchannel::ConnectivityStateWatcherInterface.
98
100
  using TransportConnectivityStateWatcher = ConnectivityStateWatcherInterface;
99
101
 
100
- //
101
- // Subchannel::Call
102
- //
103
-
104
- RefCountedPtr<Subchannel::Call> Subchannel::Call::Ref() {
105
- IncrementRefCount();
106
- return RefCountedPtr<Subchannel::Call>(this);
107
- }
108
-
109
- RefCountedPtr<Subchannel::Call> Subchannel::Call::Ref(
110
- const DebugLocation& location, const char* reason) {
111
- IncrementRefCount(location, reason);
112
- return RefCountedPtr<Subchannel::Call>(this);
113
- }
114
-
115
- //
116
- // Subchannel
117
- //
118
-
119
- RefCountedPtr<Subchannel> Subchannel::Create(
120
- OrphanablePtr<SubchannelConnector> connector,
121
- const grpc_resolved_address& address, const ChannelArgs& args) {
122
- if (!IsSubchannelConnectionScalingEnabled()) {
123
- return OldSubchannel::Create(std::move(connector), address, args);
124
- }
125
- return NewSubchannel::Create(std::move(connector), address, args);
126
- }
127
-
128
- Subchannel::Subchannel()
129
- : DualRefCounted<Subchannel>(GRPC_TRACE_FLAG_ENABLED(subchannel_refcount)
130
- ? "Subchannel"
131
- : nullptr) {}
132
-
133
- ChannelArgs Subchannel::MakeSubchannelArgs(
134
- const ChannelArgs& channel_args, const ChannelArgs& address_args,
135
- const RefCountedPtr<SubchannelPoolInterface>& subchannel_pool,
136
- const std::string& channel_default_authority) {
137
- // Note that we start with the channel-level args and then apply the
138
- // per-address args, so that if a value is present in both, the one
139
- // in the channel-level args is used. This is particularly important
140
- // for the GRPC_ARG_DEFAULT_AUTHORITY arg, which we want to allow
141
- // resolvers to set on a per-address basis only if the application
142
- // did not explicitly set it at the channel level.
143
- return channel_args.UnionWith(address_args)
144
- .SetObject(subchannel_pool)
145
- // If we haven't already set the default authority arg (i.e., it
146
- // was not explicitly set by the application nor overridden by
147
- // the resolver), add it from the channel's default.
148
- .SetIfUnset(GRPC_ARG_DEFAULT_AUTHORITY, channel_default_authority)
149
- // Remove channel args that should not affect subchannel
150
- // uniqueness.
151
- .Remove(GRPC_ARG_HEALTH_CHECK_SERVICE_NAME)
152
- .Remove(GRPC_ARG_INHIBIT_HEALTH_CHECKING)
153
- .Remove(GRPC_ARG_MAX_CONNECTIONS_PER_SUBCHANNEL)
154
- .Remove(GRPC_ARG_MAX_CONNECTIONS_PER_SUBCHANNEL_CAP)
155
- .Remove(GRPC_ARG_CHANNELZ_CHANNEL_NODE)
156
- // Remove all keys with the no-subchannel prefix.
157
- .RemoveAllKeysWithPrefix(GRPC_ARG_NO_SUBCHANNEL_PREFIX);
158
- }
159
-
160
- //
161
- // OldSubchannel::ConnectedSubchannel
162
- //
163
-
164
- class OldSubchannel::ConnectedSubchannel
165
- : public RefCounted<ConnectedSubchannel> {
166
- public:
167
- const ChannelArgs& args() const { return args_; }
168
-
169
- virtual void StartWatch(
170
- grpc_pollset_set* interested_parties,
171
- OrphanablePtr<TransportConnectivityStateWatcher> watcher) = 0;
172
-
173
- // Methods for v3 stack.
174
- virtual void Ping(absl::AnyInvocable<void(absl::Status)> on_ack) = 0;
175
- virtual RefCountedPtr<UnstartedCallDestination> unstarted_call_destination()
176
- const = 0;
177
-
178
- // Methods for legacy stack.
179
- virtual RefCountedPtr<Call> CreateCall(CreateCallArgs args,
180
- grpc_error_handle* error) = 0;
181
- virtual void Ping(grpc_closure* on_initiate, grpc_closure* on_ack) = 0;
182
-
183
- protected:
184
- explicit ConnectedSubchannel(const ChannelArgs& args)
185
- : RefCounted<ConnectedSubchannel>(
186
- GRPC_TRACE_FLAG_ENABLED(subchannel_refcount) ? "ConnectedSubchannel"
187
- : nullptr),
188
- args_(args) {}
189
-
190
- private:
191
- ChannelArgs args_;
192
- };
193
-
194
- //
195
- // OldSubchannel::LegacyConnectedSubchannel
196
- //
197
-
198
- class OldSubchannel::LegacyConnectedSubchannel final
199
- : public ConnectedSubchannel {
200
- public:
201
- LegacyConnectedSubchannel(
202
- RefCountedPtr<grpc_channel_stack> channel_stack, const ChannelArgs& args,
203
- RefCountedPtr<channelz::SubchannelNode> channelz_node)
204
- : ConnectedSubchannel(args),
205
- channelz_node_(std::move(channelz_node)),
206
- channel_stack_(std::move(channel_stack)) {}
207
-
208
- ~LegacyConnectedSubchannel() override {
209
- channel_stack_.reset(DEBUG_LOCATION, "ConnectedSubchannel");
210
- }
211
-
212
- void StartWatch(
213
- grpc_pollset_set* interested_parties,
214
- OrphanablePtr<TransportConnectivityStateWatcher> watcher) override {
215
- grpc_transport_op* op = grpc_make_transport_op(nullptr);
216
- op->start_connectivity_watch = std::move(watcher);
217
- op->start_connectivity_watch_state = GRPC_CHANNEL_READY;
218
- op->bind_pollset_set = interested_parties;
219
- grpc_channel_element* elem =
220
- grpc_channel_stack_element(channel_stack_.get(), 0);
221
- elem->filter->start_transport_op(elem, op);
222
- }
223
-
224
- void Ping(absl::AnyInvocable<void(absl::Status)>) override {
225
- Crash("call v3 ping method called in legacy impl");
226
- }
227
-
228
- RefCountedPtr<UnstartedCallDestination> unstarted_call_destination()
229
- const override {
230
- Crash("call v3 unstarted_call_destination method called in legacy impl");
231
- }
232
-
233
- RefCountedPtr<Call> CreateCall(CreateCallArgs args,
234
- grpc_error_handle* error) override {
235
- const size_t allocation_size =
236
- GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)) +
237
- channel_stack_->call_stack_size;
238
- Arena* arena = args.arena;
239
- return RefCountedPtr<SubchannelCall>(
240
- new (arena->Alloc(allocation_size)) SubchannelCall(
241
- RefAsSubclass<LegacyConnectedSubchannel>(), args, error));
242
- }
243
-
244
- void Ping(grpc_closure* on_initiate, grpc_closure* on_ack) override {
245
- grpc_transport_op* op = grpc_make_transport_op(nullptr);
246
- op->send_ping.on_initiate = on_initiate;
247
- op->send_ping.on_ack = on_ack;
248
- grpc_channel_element* elem =
249
- grpc_channel_stack_element(channel_stack_.get(), 0);
250
- elem->filter->start_transport_op(elem, op);
251
- }
252
-
253
- private:
254
- class SubchannelCall final : public Call {
255
- public:
256
- SubchannelCall(
257
- RefCountedPtr<LegacyConnectedSubchannel> connected_subchannel,
258
- CreateCallArgs args, grpc_error_handle* error);
259
-
260
- void StartTransportStreamOpBatch(
261
- grpc_transport_stream_op_batch* batch) override;
262
-
263
- void SetAfterCallStackDestroy(grpc_closure* closure) override;
264
-
265
- // When refcount drops to 0, destroys itself and the associated call stack,
266
- // but does NOT free the memory because it's in the call arena.
267
- void Unref() override;
268
- void Unref(const DebugLocation& location, const char* reason) override;
269
-
270
- private:
271
- // If channelz is enabled, intercepts recv_trailing so that we may check the
272
- // status and associate it to a subchannel.
273
- void MaybeInterceptRecvTrailingMetadata(
274
- grpc_transport_stream_op_batch* batch);
275
-
276
- static void RecvTrailingMetadataReady(void* arg, grpc_error_handle error);
277
-
278
- // Interface of RefCounted<>.
279
- void IncrementRefCount() override;
280
- void IncrementRefCount(const DebugLocation& location,
281
- const char* reason) override;
282
-
283
- static void Destroy(void* arg, grpc_error_handle error);
284
-
285
- RefCountedPtr<LegacyConnectedSubchannel> connected_subchannel_;
286
- grpc_closure* after_call_stack_destroy_ = nullptr;
287
- // State needed to support channelz interception of recv trailing metadata.
288
- grpc_closure recv_trailing_metadata_ready_;
289
- grpc_closure* original_recv_trailing_metadata_ = nullptr;
290
- grpc_metadata_batch* recv_trailing_metadata_ = nullptr;
291
- Timestamp deadline_;
292
- };
293
-
294
- RefCountedPtr<channelz::SubchannelNode> channelz_node_;
295
- RefCountedPtr<grpc_channel_stack> channel_stack_;
296
- };
297
-
298
- //
299
- // OldSubchannel::LegacyConnectedSubchannel::SubchannelCall
300
- //
301
-
302
- OldSubchannel::LegacyConnectedSubchannel::SubchannelCall::SubchannelCall(
303
- RefCountedPtr<LegacyConnectedSubchannel> connected_subchannel,
304
- CreateCallArgs args, grpc_error_handle* error)
305
- : connected_subchannel_(std::move(connected_subchannel)),
306
- deadline_(args.deadline) {
307
- grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(this);
308
- const grpc_call_element_args call_args = {
309
- callstk, // call_stack
310
- nullptr, // server_transport_data
311
- args.start_time, // start_time
312
- args.deadline, // deadline
313
- args.arena, // arena
314
- args.call_combiner // call_combiner
315
- };
316
- *error = grpc_call_stack_init(connected_subchannel_->channel_stack_.get(), 1,
317
- SubchannelCall::Destroy, this, &call_args);
318
- if (GPR_UNLIKELY(!error->ok())) {
319
- LOG(ERROR) << "error: " << StatusToString(*error);
320
- return;
321
- }
322
- grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent);
323
- if (connected_subchannel_->channelz_node_ != nullptr) {
324
- connected_subchannel_->channelz_node_->RecordCallStarted();
325
- }
326
- }
327
-
328
- void OldSubchannel::LegacyConnectedSubchannel::SubchannelCall::
329
- StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch) {
330
- MaybeInterceptRecvTrailingMetadata(batch);
331
- grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(this);
332
- grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0);
333
- GRPC_TRACE_LOG(channel, INFO)
334
- << "OP[" << top_elem->filter->name << ":" << top_elem
335
- << "]: " << grpc_transport_stream_op_batch_string(batch, false);
336
- top_elem->filter->start_transport_stream_op_batch(top_elem, batch);
337
- }
338
-
339
- void OldSubchannel::LegacyConnectedSubchannel::SubchannelCall::
340
- SetAfterCallStackDestroy(grpc_closure* closure) {
341
- GRPC_CHECK_EQ(after_call_stack_destroy_, nullptr);
342
- GRPC_CHECK_NE(closure, nullptr);
343
- after_call_stack_destroy_ = closure;
344
- }
345
-
346
- void OldSubchannel::LegacyConnectedSubchannel::SubchannelCall::Unref() {
347
- GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), "");
348
- }
349
-
350
- void OldSubchannel::LegacyConnectedSubchannel::SubchannelCall::Unref(
351
- const DebugLocation& /*location*/, const char* reason) {
352
- GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason);
353
- }
354
-
355
- void OldSubchannel::LegacyConnectedSubchannel::SubchannelCall::Destroy(
356
- void* arg, grpc_error_handle /*error*/) {
357
- SubchannelCall* self = static_cast<SubchannelCall*>(arg);
358
- // Keep some members before destroying the subchannel call.
359
- grpc_closure* after_call_stack_destroy = self->after_call_stack_destroy_;
360
- RefCountedPtr<ConnectedSubchannel> connected_subchannel =
361
- std::move(self->connected_subchannel_);
362
- // Destroy the subchannel call.
363
- self->~SubchannelCall();
364
- // Destroy the call stack. This should be after destroying the subchannel
365
- // call, because call->after_call_stack_destroy(), if not null, will free
366
- // the call arena.
367
- grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(self), nullptr,
368
- after_call_stack_destroy);
369
- // Automatically reset connected_subchannel. This should be after destroying
370
- // the call stack, because destroying call stack needs access to the channel
371
- // stack.
372
- }
373
-
374
- void OldSubchannel::LegacyConnectedSubchannel::SubchannelCall::
375
- MaybeInterceptRecvTrailingMetadata(grpc_transport_stream_op_batch* batch) {
376
- // only intercept payloads with recv trailing.
377
- if (!batch->recv_trailing_metadata) return;
378
- // only add interceptor is channelz is enabled.
379
- if (connected_subchannel_->channelz_node_ == nullptr) return;
380
- GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, RecvTrailingMetadataReady,
381
- this, grpc_schedule_on_exec_ctx);
382
- // save some state needed for the interception callback.
383
- GRPC_CHECK_EQ(recv_trailing_metadata_, nullptr);
384
- recv_trailing_metadata_ =
385
- batch->payload->recv_trailing_metadata.recv_trailing_metadata;
386
- original_recv_trailing_metadata_ =
387
- batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
388
- batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
389
- &recv_trailing_metadata_ready_;
390
- }
391
-
392
- namespace {
393
-
394
- // Sets *status based on the rest of the parameters.
395
- void GetCallStatus(grpc_status_code* status, Timestamp deadline,
396
- grpc_metadata_batch* md_batch, grpc_error_handle error) {
397
- if (!error.ok()) {
398
- grpc_error_get_status(error, deadline, status, nullptr, nullptr, nullptr);
399
- } else {
400
- *status = md_batch->get(GrpcStatusMetadata()).value_or(GRPC_STATUS_UNKNOWN);
401
- }
402
- }
403
-
404
- } // namespace
405
-
406
- void OldSubchannel::LegacyConnectedSubchannel::SubchannelCall::
407
- RecvTrailingMetadataReady(void* arg, grpc_error_handle error) {
408
- SubchannelCall* call = static_cast<SubchannelCall*>(arg);
409
- GRPC_CHECK_NE(call->recv_trailing_metadata_, nullptr);
410
- grpc_status_code status = GRPC_STATUS_OK;
411
- GetCallStatus(&status, call->deadline_, call->recv_trailing_metadata_, error);
412
- channelz::SubchannelNode* channelz_node =
413
- call->connected_subchannel_->channelz_node_.get();
414
- GRPC_CHECK_NE(channelz_node, nullptr);
415
- if (status == GRPC_STATUS_OK) {
416
- channelz_node->RecordCallSucceeded();
417
- } else {
418
- channelz_node->RecordCallFailed();
419
- }
420
- Closure::Run(DEBUG_LOCATION, call->original_recv_trailing_metadata_, error);
421
- }
422
-
423
- void OldSubchannel::LegacyConnectedSubchannel::SubchannelCall::
424
- IncrementRefCount() {
425
- GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), "");
426
- }
427
-
428
- void OldSubchannel::LegacyConnectedSubchannel::SubchannelCall::
429
- IncrementRefCount(const DebugLocation& /*location*/, const char* reason) {
430
- GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason);
431
- }
432
-
433
- //
434
- // OldSubchannel::NewConnectedSubchannel
435
- //
436
-
437
- class OldSubchannel::NewConnectedSubchannel final : public ConnectedSubchannel {
438
- public:
439
- class TransportCallDestination final : public CallDestination {
440
- public:
441
- explicit TransportCallDestination(OrphanablePtr<ClientTransport> transport)
442
- : transport_(std::move(transport)) {}
443
-
444
- ClientTransport* transport() { return transport_.get(); }
445
-
446
- void HandleCall(CallHandler handler) override {
447
- transport_->StartCall(std::move(handler));
448
- }
449
-
450
- void Orphaned() override { transport_.reset(); }
451
-
452
- private:
453
- OrphanablePtr<ClientTransport> transport_;
454
- };
455
-
456
- NewConnectedSubchannel(
457
- RefCountedPtr<UnstartedCallDestination> call_destination,
458
- RefCountedPtr<TransportCallDestination> transport,
459
- const ChannelArgs& args)
460
- : ConnectedSubchannel(args),
461
- call_destination_(std::move(call_destination)),
462
- transport_(std::move(transport)) {}
463
-
464
- void StartWatch(
465
- grpc_pollset_set*,
466
- OrphanablePtr<TransportConnectivityStateWatcher> watcher) override {
467
- transport_->transport()->StartConnectivityWatch(std::move(watcher));
468
- }
469
-
470
- void Ping(absl::AnyInvocable<void(absl::Status)>) override {
471
- // TODO(ctiller): add new transport API for this in v3 stack
472
- Crash("not implemented");
473
- }
474
-
475
- RefCountedPtr<UnstartedCallDestination> unstarted_call_destination()
476
- const override {
477
- return call_destination_;
478
- }
479
-
480
- RefCountedPtr<Call> CreateCall(CreateCallArgs, grpc_error_handle*) override {
481
- Crash("legacy CreateCall() called on v3 impl");
482
- }
483
-
484
- void Ping(grpc_closure*, grpc_closure*) override {
485
- Crash("legacy ping method called in call v3 impl");
486
- }
487
-
488
- private:
489
- RefCountedPtr<UnstartedCallDestination> call_destination_;
490
- RefCountedPtr<TransportCallDestination> transport_;
491
- };
492
-
493
- //
494
- // OldSubchannel::ConnectedSubchannelStateWatcher
495
- //
496
-
497
- class OldSubchannel::ConnectedSubchannelStateWatcher final
498
- : public AsyncConnectivityStateWatcherInterface {
499
- public:
500
- // Must be instantiated while holding c->mu.
501
- explicit ConnectedSubchannelStateWatcher(WeakRefCountedPtr<OldSubchannel> c)
502
- : subchannel_(std::move(c)) {}
503
-
504
- ~ConnectedSubchannelStateWatcher() override {
505
- subchannel_.reset(DEBUG_LOCATION, "state_watcher");
506
- }
507
-
508
- private:
509
- void OnConnectivityStateChange(grpc_connectivity_state new_state,
510
- const absl::Status& status) override {
511
- OldSubchannel* c = subchannel_.get();
512
- {
513
- MutexLock lock(&c->mu_);
514
- // If we're either shutting down or have already seen this connection
515
- // failure (i.e., c->connected_subchannel_ is null), do nothing.
516
- //
517
- // The transport reports TRANSIENT_FAILURE upon GOAWAY but SHUTDOWN
518
- // upon connection close. So if the server gracefully shuts down,
519
- // we will see TRANSIENT_FAILURE followed by SHUTDOWN, but if not, we
520
- // will see only SHUTDOWN. Either way, we react to the first one we
521
- // see, ignoring anything that happens after that.
522
- if (new_state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
523
- new_state == GRPC_CHANNEL_SHUTDOWN) {
524
- RefCountedPtr<ConnectedSubchannel> connected_subchannel =
525
- std::move(c->connected_subchannel_);
526
- if (connected_subchannel == nullptr) return;
527
- GRPC_TRACE_LOG(subchannel, INFO)
528
- << "subchannel " << c << " " << c->key_.ToString()
529
- << ": Connected subchannel " << connected_subchannel.get()
530
- << " reports " << ConnectivityStateName(new_state) << ": "
531
- << status;
532
- // If the subchannel was created from an endpoint, then we report
533
- // TRANSIENT_FAILURE here instead of IDLE. The subchannel will never
534
- // leave TRANSIENT_FAILURE state, because there is no way for us to
535
- // establish a new connection.
536
- //
537
- // Otherwise, we report IDLE here. Note that even though we're not
538
- // reporting TRANSIENT_FAILURE, we pass along the status from the
539
- // transport, since it may have keepalive info attached to it that the
540
- // channel needs.
541
- // TODO(roth): Consider whether there's a cleaner way to propagate the
542
- // keepalive info.
543
- c->SetConnectivityStateLocked(c->created_from_endpoint_
544
- ? GRPC_CHANNEL_TRANSIENT_FAILURE
545
- : GRPC_CHANNEL_IDLE,
546
- status);
547
- c->backoff_.Reset();
548
- }
549
- }
550
- }
551
-
552
- WeakRefCountedPtr<OldSubchannel> subchannel_;
553
- };
554
-
555
- //
556
- // OldSubchannel::ConnectivityStateWatcherList
557
- //
558
-
559
- void OldSubchannel::ConnectivityStateWatcherList::AddWatcherLocked(
560
- RefCountedPtr<ConnectivityStateWatcherInterface> watcher) {
561
- watchers_.insert(std::move(watcher));
562
- }
563
-
564
- void OldSubchannel::ConnectivityStateWatcherList::RemoveWatcherLocked(
565
- ConnectivityStateWatcherInterface* watcher) {
566
- watchers_.erase(watcher);
567
- }
568
-
569
- void OldSubchannel::ConnectivityStateWatcherList::NotifyLocked(
570
- grpc_connectivity_state state, const absl::Status& status) {
571
- for (const auto& watcher : watchers_) {
572
- subchannel_->work_serializer_.Run([watcher, state, status]() {
573
- watcher->OnConnectivityStateChange(state, status);
574
- });
575
- }
576
- }
577
-
578
- void OldSubchannel::ConnectivityStateWatcherList::NotifyOnKeepaliveUpdateLocked(
579
- Duration new_keepalive_time) {
580
- for (const auto& watcher : watchers_) {
581
- subchannel_->work_serializer_.Run([watcher, new_keepalive_time]() {
582
- watcher->OnKeepaliveUpdate(new_keepalive_time);
583
- });
584
- }
585
- }
586
-
587
- uint32_t
588
- OldSubchannel::ConnectivityStateWatcherList::GetMaxConnectionsPerSubchannel()
589
- const {
590
- uint32_t max_connections_per_subchannel = 1;
591
- for (const auto& watcher : watchers_) {
592
- max_connections_per_subchannel =
593
- std::max(max_connections_per_subchannel,
594
- watcher->max_connections_per_subchannel());
595
- }
596
- return max_connections_per_subchannel;
597
- }
598
-
599
- //
600
- // OldSubchannel
601
- //
602
-
603
- namespace {
604
-
605
- BackOff::Options ParseArgsForBackoffValues(const ChannelArgs& args,
606
- Duration* min_connect_timeout) {
607
- const std::optional<Duration> fixed_reconnect_backoff =
608
- args.GetDurationFromIntMillis("grpc.testing.fixed_reconnect_backoff_ms");
609
- if (fixed_reconnect_backoff.has_value()) {
610
- const Duration backoff =
611
- std::max(Duration::Milliseconds(100), *fixed_reconnect_backoff);
612
- *min_connect_timeout = backoff;
613
- return BackOff::Options()
614
- .set_initial_backoff(backoff)
615
- .set_multiplier(1.0)
616
- .set_jitter(0.0)
617
- .set_max_backoff(backoff);
618
- }
619
- const Duration initial_backoff = std::max(
620
- Duration::Milliseconds(100),
621
- args.GetDurationFromIntMillis(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS)
622
- .value_or(Duration::Seconds(
623
- GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS)));
624
- *min_connect_timeout =
625
- std::max(Duration::Milliseconds(100),
626
- args.GetDurationFromIntMillis(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS)
627
- .value_or(Duration::Seconds(
628
- GRPC_SUBCHANNEL_RECONNECT_MIN_TIMEOUT_SECONDS)));
629
- const Duration max_backoff =
630
- std::max(Duration::Milliseconds(100),
631
- args.GetDurationFromIntMillis(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS)
632
- .value_or(Duration::Seconds(
633
- GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS)));
634
- return BackOff::Options()
635
- .set_initial_backoff(initial_backoff)
636
- .set_multiplier(GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER)
637
- .set_jitter(GRPC_SUBCHANNEL_RECONNECT_JITTER)
638
- .set_max_backoff(max_backoff);
639
- }
640
-
641
- } // namespace
642
-
643
- OldSubchannel::OldSubchannel(SubchannelKey key,
644
- OrphanablePtr<SubchannelConnector> connector,
645
- const ChannelArgs& args)
646
- : key_(std::move(key)),
647
- created_from_endpoint_(args.Contains(GRPC_ARG_SUBCHANNEL_ENDPOINT)),
648
- args_(args),
649
- pollset_set_(grpc_pollset_set_create()),
650
- connector_(std::move(connector)),
651
- watcher_list_(this),
652
- work_serializer_(args_.GetObjectRef<EventEngine>()),
653
- backoff_(ParseArgsForBackoffValues(args_, &min_connect_timeout_)),
654
- event_engine_(args_.GetObjectRef<EventEngine>()) {
655
- // A grpc_init is added here to ensure that grpc_shutdown does not happen
656
- // until the subchannel is destroyed. Subchannels can persist longer than
657
- // channels because they maybe reused/shared among multiple channels. As a
658
- // result the subchannel destruction happens asynchronously to channel
659
- // destruction. If the last channel destruction triggers a grpc_shutdown
660
- // before the last subchannel destruction, then there maybe race conditions
661
- // triggering segmentation faults. To prevent this issue, we call a
662
- // grpc_init here and a grpc_shutdown in the subchannel destructor.
663
- InitInternally();
664
- global_stats().IncrementClientSubchannelsCreated();
665
- GRPC_CLOSURE_INIT(&on_connecting_finished_, OnConnectingFinished, this,
666
- grpc_schedule_on_exec_ctx);
667
- // Check proxy mapper to determine address to connect to and channel
668
- // args to use.
669
- address_for_connect_ = CoreConfiguration::Get()
670
- .proxy_mapper_registry()
671
- .MapAddress(key_.address(), &args_)
672
- .value_or(key_.address());
673
- // Initialize channelz.
674
- const bool channelz_enabled = args_.GetBool(GRPC_ARG_ENABLE_CHANNELZ)
675
- .value_or(GRPC_ENABLE_CHANNELZ_DEFAULT);
676
- if (channelz_enabled) {
677
- const size_t channel_tracer_max_memory = Clamp(
678
- args_.GetInt(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE)
679
- .value_or(GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT),
680
- 0, INT_MAX);
681
- channelz_node_ = MakeRefCounted<channelz::SubchannelNode>(
682
- grpc_sockaddr_to_uri(&key_.address())
683
- .value_or("<unknown address type>"),
684
- channel_tracer_max_memory);
685
- GRPC_CHANNELZ_LOG(channelz_node_) << "subchannel created";
686
- channelz_node_->SetChannelArgs(args_);
687
- args_ = args_.SetObject<channelz::BaseNode>(channelz_node_);
688
- }
689
- }
690
-
691
- OldSubchannel::~OldSubchannel() {
692
- if (channelz_node_ != nullptr) {
693
- GRPC_CHANNELZ_LOG(channelz_node_) << "Subchannel destroyed";
694
- channelz_node_->UpdateConnectivityState(GRPC_CHANNEL_SHUTDOWN);
695
- }
696
- connector_.reset();
697
- grpc_pollset_set_destroy(pollset_set_);
698
- // grpc_shutdown is called here because grpc_init is called in the ctor.
699
- ShutdownInternally();
700
- }
701
-
702
- RefCountedPtr<Subchannel> OldSubchannel::Create(
703
- OrphanablePtr<SubchannelConnector> connector,
704
- const grpc_resolved_address& address, const ChannelArgs& args) {
705
- SubchannelKey key(address, args);
706
- auto* subchannel_pool = args.GetObject<SubchannelPoolInterface>();
707
- GRPC_CHECK_NE(subchannel_pool, nullptr);
708
- RefCountedPtr<OldSubchannel> c =
709
- subchannel_pool->FindSubchannel(key).TakeAsSubclass<OldSubchannel>();
710
- if (c != nullptr) {
711
- return c;
712
- }
713
- c = MakeRefCounted<OldSubchannel>(std::move(key), std::move(connector), args);
714
- if (c->created_from_endpoint_) {
715
- // We don't interact with the subchannel pool in this case.
716
- // Instead, we unconditionally return the newly created subchannel.
717
- // Before returning, we explicitly trigger a connection attempt
718
- // by calling RequestConnection(), which sets the subchannel’s
719
- // connectivity state to CONNECTING.
720
- c->RequestConnection();
721
- return c;
722
- }
723
- // Try to register the subchannel before setting the subchannel pool.
724
- // Otherwise, in case of a registration race, unreffing c in
725
- // RegisterSubchannel() will cause c to be tried to be unregistered, while
726
- // its key maps to a different subchannel.
727
- RefCountedPtr<OldSubchannel> registered =
728
- subchannel_pool->RegisterSubchannel(c->key_, c)
729
- .TakeAsSubclass<OldSubchannel>();
730
- if (registered == c) c->subchannel_pool_ = subchannel_pool->Ref();
731
- return registered;
732
- }
733
-
734
- void OldSubchannel::ThrottleKeepaliveTime(Duration new_keepalive_time) {
735
- MutexLock lock(&mu_);
736
- ThrottleKeepaliveTimeLocked(new_keepalive_time);
737
- }
738
-
739
- void OldSubchannel::ThrottleKeepaliveTimeLocked(Duration new_keepalive_time) {
740
- // Only update the value if the new keepalive time is larger.
741
- if (new_keepalive_time > keepalive_time_) {
742
- keepalive_time_ = new_keepalive_time;
743
- GRPC_TRACE_LOG(subchannel, INFO)
744
- << "subchannel " << this << " " << key_.ToString()
745
- << ": throttling keepalive time to " << new_keepalive_time;
746
- args_ = args_.Set(GRPC_ARG_KEEPALIVE_TIME_MS, new_keepalive_time.millis());
747
- }
748
- }
749
-
750
- channelz::SubchannelNode* OldSubchannel::channelz_node() {
751
- return channelz_node_.get();
752
- }
753
-
754
- void OldSubchannel::WatchConnectivityState(
755
- RefCountedPtr<ConnectivityStateWatcherInterface> watcher) {
756
- MutexLock lock(&mu_);
757
- grpc_pollset_set* interested_parties = watcher->interested_parties();
758
- if (interested_parties != nullptr) {
759
- grpc_pollset_set_add_pollset_set(pollset_set_, interested_parties);
760
- }
761
- work_serializer_.Run(
762
- [watcher, state = state_, status = status_]() {
763
- watcher->OnConnectivityStateChange(state, status);
764
- },
765
- DEBUG_LOCATION);
766
- watcher_list_.AddWatcherLocked(std::move(watcher));
767
- }
768
-
769
- void OldSubchannel::CancelConnectivityStateWatch(
770
- ConnectivityStateWatcherInterface* watcher) {
771
- MutexLock lock(&mu_);
772
- grpc_pollset_set* interested_parties = watcher->interested_parties();
773
- if (interested_parties != nullptr) {
774
- grpc_pollset_set_del_pollset_set(pollset_set_, interested_parties);
775
- }
776
- watcher_list_.RemoveWatcherLocked(watcher);
777
- }
778
-
779
- void OldSubchannel::RequestConnection() {
780
- MutexLock lock(&mu_);
781
- if (state_ == GRPC_CHANNEL_IDLE) {
782
- StartConnectingLocked();
783
- }
784
- }
785
-
786
- void OldSubchannel::ResetBackoff() {
787
- // Hold a ref to ensure cancellation and subsequent deletion of the closure
788
- // does not eliminate the last ref and destroy the Subchannel before the
789
- // method returns.
790
- auto self = WeakRef(DEBUG_LOCATION, "ResetBackoff");
791
- MutexLock lock(&mu_);
792
- backoff_.Reset();
793
- if (state_ == GRPC_CHANNEL_TRANSIENT_FAILURE &&
794
- event_engine_->Cancel(retry_timer_handle_)) {
795
- OnRetryTimerLocked();
796
- } else if (state_ == GRPC_CHANNEL_CONNECTING) {
797
- next_attempt_time_ = Timestamp::Now();
798
- }
799
- }
800
-
801
- void OldSubchannel::Orphaned() {
802
- // The subchannel_pool is only used once here in this subchannel, so the
803
- // access can be outside of the lock.
804
- if (subchannel_pool_ != nullptr) {
805
- subchannel_pool_->UnregisterSubchannel(key_, this);
806
- subchannel_pool_.reset();
807
- }
808
- MutexLock lock(&mu_);
809
- GRPC_CHECK(!shutdown_);
810
- shutdown_ = true;
811
- connector_.reset();
812
- connected_subchannel_.reset();
813
- }
814
-
815
- void OldSubchannel::GetOrAddDataProducer(
816
- UniqueTypeName type,
817
- std::function<void(DataProducerInterface**)> get_or_add) {
818
- MutexLock lock(&mu_);
819
- auto it = data_producer_map_.emplace(type, nullptr).first;
820
- get_or_add(&it->second);
821
- }
822
-
823
- void OldSubchannel::RemoveDataProducer(DataProducerInterface* data_producer) {
824
- MutexLock lock(&mu_);
825
- auto it = data_producer_map_.find(data_producer->type());
826
- if (it != data_producer_map_.end() && it->second == data_producer) {
827
- data_producer_map_.erase(it);
828
- }
829
- }
830
-
831
- // Note: Must be called with a state that is different from the current state.
832
- void OldSubchannel::SetConnectivityStateLocked(grpc_connectivity_state state,
833
- const absl::Status& status) {
834
- state_ = state;
835
- if (status.ok()) {
836
- status_ = status;
837
- } else {
838
- // Augment status message to include IP address.
839
- status_ = absl::Status(status.code(),
840
- absl::StrCat(grpc_sockaddr_to_uri(&key_.address())
841
- .value_or("<unknown address type>"),
842
- ": ", status.message()));
843
- status.ForEachPayload(
844
- [this](absl::string_view key, const absl::Cord& value)
845
- // Want to use ABSL_EXCLUSIVE_LOCKS_REQUIRED(&mu_) here,
846
- // but that won't work, because we can't pass the lock
847
- // annotation through absl::Status::ForEachPayload().
848
- ABSL_NO_THREAD_SAFETY_ANALYSIS { status_.SetPayload(key, value); });
849
- }
850
- if (channelz_node_ != nullptr) {
851
- channelz_node_->UpdateConnectivityState(state);
852
- if (status.ok()) {
853
- GRPC_CHANNELZ_LOG(channelz_node_)
854
- << "Subchannel connectivity state changed to "
855
- << ConnectivityStateName(state);
856
- } else {
857
- GRPC_CHANNELZ_LOG(channelz_node_)
858
- << "Subchannel connectivity state changed to "
859
- << ConnectivityStateName(state) << ": " << status;
860
- }
861
- }
862
- // Notify watchers.
863
- watcher_list_.NotifyLocked(state, status_);
864
- }
865
-
866
- void OldSubchannel::OnRetryTimer() {
867
- MutexLock lock(&mu_);
868
- OnRetryTimerLocked();
869
- }
870
-
871
- void OldSubchannel::OnRetryTimerLocked() {
872
- if (shutdown_) return;
873
- GRPC_TRACE_LOG(subchannel, INFO)
874
- << "subchannel " << this << " " << key_.ToString()
875
- << ": backoff delay elapsed, reporting IDLE";
876
- SetConnectivityStateLocked(GRPC_CHANNEL_IDLE, absl::OkStatus());
877
- }
878
-
879
- void OldSubchannel::StartConnectingLocked() {
880
- // Set next attempt time.
881
- const Timestamp now = Timestamp::Now();
882
- const Timestamp min_deadline = now + min_connect_timeout_;
883
- next_attempt_time_ = now + backoff_.NextAttemptDelay();
884
- // Report CONNECTING.
885
- SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, absl::OkStatus());
886
- // Start connection attempt.
887
- SubchannelConnector::Args args;
888
- args.address = &address_for_connect_;
889
- args.interested_parties = pollset_set_;
890
- args.deadline = std::max(next_attempt_time_, min_deadline);
891
- args.channel_args = args_;
892
- WeakRef(DEBUG_LOCATION, "Connect").release(); // Ref held by callback.
893
- connector_->Connect(args, &connecting_result_, &on_connecting_finished_);
894
- }
895
-
896
- void OldSubchannel::OnConnectingFinished(void* arg, grpc_error_handle error) {
897
- WeakRefCountedPtr<OldSubchannel> c(static_cast<OldSubchannel*>(arg));
898
- {
899
- MutexLock lock(&c->mu_);
900
- c->OnConnectingFinishedLocked(error);
901
- }
902
- c.reset(DEBUG_LOCATION, "Connect");
903
- }
102
+ namespace {
904
103
 
905
- void OldSubchannel::OnConnectingFinishedLocked(grpc_error_handle error) {
906
- if (shutdown_) {
907
- connecting_result_.Reset();
908
- return;
909
- }
910
- // If we didn't get a transport or we fail to publish it, report
911
- // TRANSIENT_FAILURE and start the retry timer.
912
- // Note that if the connection attempt took longer than the backoff
913
- // time, then the timer will fire immediately, and we will quickly
914
- // transition back to IDLE.
915
- if (connecting_result_.transport == nullptr || !PublishTransportLocked()) {
916
- const Duration time_until_next_attempt =
917
- next_attempt_time_ - Timestamp::Now();
918
- GRPC_TRACE_LOG(subchannel, INFO)
919
- << "subchannel " << this << " " << key_.ToString()
920
- << ": connect failed (" << StatusToString(error) << ")"
921
- << (created_from_endpoint_
922
- ? ", no retry will be attempted (created from endpoint); "
923
- "remaining in TRANSIENT_FAILURE"
924
- : ", backing off for " +
925
- std::to_string(time_until_next_attempt.millis()) + " ms");
926
- SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE,
927
- grpc_error_to_absl_status(error));
928
- if (created_from_endpoint_) return;
929
- retry_timer_handle_ = event_engine_->RunAfter(
930
- time_until_next_attempt,
931
- [self = WeakRef(DEBUG_LOCATION, "RetryTimer")
932
- .TakeAsSubclass<OldSubchannel>()]() mutable {
933
- {
934
- ExecCtx exec_ctx;
935
- self->OnRetryTimer();
936
- // Subchannel deletion might require an active ExecCtx. So if
937
- // self.reset() is not called here, the WeakRefCountedPtr
938
- // destructor may run after the ExecCtx declared in the callback
939
- // is destroyed. Since subchannel may get destroyed when the
940
- // WeakRefCountedPtr destructor runs, it may not have an active
941
- // ExecCtx - thus leading to crashes.
942
- self.reset();
943
- }
944
- });
945
- }
946
- }
947
-
948
- bool OldSubchannel::PublishTransportLocked() {
949
- auto socket_node = connecting_result_.transport->GetSocketNode();
950
- if (connecting_result_.transport->filter_stack_transport() != nullptr) {
951
- // Construct channel stack.
952
- // Builder takes ownership of transport.
953
- ChannelStackBuilderImpl builder(
954
- "subchannel", GRPC_CLIENT_SUBCHANNEL,
955
- connecting_result_.channel_args.SetObject(
956
- std::exchange(connecting_result_.transport, nullptr)));
957
- if (!CoreConfiguration::Get().channel_init().CreateStack(&builder)) {
958
- return false;
959
- }
960
- absl::StatusOr<RefCountedPtr<grpc_channel_stack>> stack = builder.Build();
961
- if (!stack.ok()) {
962
- connecting_result_.Reset();
963
- LOG(ERROR) << "subchannel " << this << " " << key_.ToString()
964
- << ": error initializing subchannel stack: " << stack.status();
965
- return false;
966
- }
967
- connected_subchannel_ = MakeRefCounted<LegacyConnectedSubchannel>(
968
- std::move(*stack), args_, channelz_node_);
969
- } else {
970
- OrphanablePtr<ClientTransport> transport(
971
- std::exchange(connecting_result_.transport, nullptr)
972
- ->client_transport());
973
- InterceptionChainBuilder builder(
974
- connecting_result_.channel_args.SetObject(transport.get()));
975
- if (channelz_node_ != nullptr) {
976
- // TODO(ctiller): If/when we have a good way to access the subchannel
977
- // from a filter (maybe GetContext<Subchannel>?), consider replacing
978
- // these two hooks with a filter so that we can avoid storing two
979
- // separate refs to the channelz node in each connection.
980
- builder.AddOnClientInitialMetadata(
981
- [channelz_node = channelz_node_](ClientMetadata&) {
982
- channelz_node->RecordCallStarted();
983
- });
984
- builder.AddOnServerTrailingMetadata(
985
- [channelz_node = channelz_node_](ServerMetadata& metadata) {
986
- if (IsStatusOk(metadata)) {
987
- channelz_node->RecordCallSucceeded();
988
- } else {
989
- channelz_node->RecordCallFailed();
990
- }
991
- });
992
- }
993
- CoreConfiguration::Get().channel_init().AddToInterceptionChainBuilder(
994
- GRPC_CLIENT_SUBCHANNEL, builder);
995
- auto transport_destination =
996
- MakeRefCounted<NewConnectedSubchannel::TransportCallDestination>(
997
- std::move(transport));
998
- auto call_destination = builder.Build(transport_destination);
999
- if (!call_destination.ok()) {
1000
- connecting_result_.Reset();
1001
- LOG(ERROR) << "subchannel " << this << " " << key_.ToString()
1002
- << ": error initializing subchannel stack: "
1003
- << call_destination.status();
1004
- return false;
1005
- }
1006
- connected_subchannel_ = MakeRefCounted<NewConnectedSubchannel>(
1007
- std::move(*call_destination), std::move(transport_destination), args_);
1008
- }
1009
- connecting_result_.Reset();
1010
- // Publish.
1011
- GRPC_TRACE_LOG(subchannel, INFO)
1012
- << "subchannel " << this << " " << key_.ToString()
1013
- << ": new connected subchannel at " << connected_subchannel_.get();
1014
- if (channelz_node_ != nullptr) {
1015
- if (socket_node != nullptr) {
1016
- socket_node->AddParent(channelz_node_.get());
104
+ constexpr absl::string_view kSecurityLevelUnknown = "unknown";
105
+ constexpr absl::string_view kSecurityLevelNone = "none";
106
+ constexpr absl::string_view kSecurityLevelIntegrityOnly = "integrity_only";
107
+ constexpr absl::string_view kSecurityLevelPrivacyAndIntegrity =
108
+ "privacy_and_integrity";
109
+
110
+ absl::string_view GetSecurityLevelFromArgs(const ChannelArgs& args) {
111
+ auto auth_context = args.GetObject<grpc_auth_context>();
112
+ if (auth_context != nullptr) {
113
+ grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name(
114
+ auth_context, GRPC_TRANSPORT_SECURITY_LEVEL_PROPERTY_NAME);
115
+ const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it);
116
+ if (prop != nullptr) {
117
+ absl::string_view tsi_level(prop->value, prop->value_length);
118
+ if (tsi_level == "TSI_SECURITY_NONE") {
119
+ return kSecurityLevelNone;
120
+ } else if (tsi_level == "TSI_INTEGRITY_ONLY") {
121
+ return kSecurityLevelIntegrityOnly;
122
+ } else if (tsi_level == "TSI_PRIVACY_AND_INTEGRITY") {
123
+ return kSecurityLevelPrivacyAndIntegrity;
124
+ }
1017
125
  }
1018
126
  }
1019
- connected_subchannel_->StartWatch(
1020
- pollset_set_, MakeOrphanable<ConnectedSubchannelStateWatcher>(
1021
- WeakRef(DEBUG_LOCATION, "state_watcher")
1022
- .TakeAsSubclass<OldSubchannel>()));
1023
- // Report initial state.
1024
- SetConnectivityStateLocked(GRPC_CHANNEL_READY, absl::Status());
1025
- return true;
1026
- }
1027
-
1028
- RefCountedPtr<Subchannel::Call> OldSubchannel::CreateCall(
1029
- CreateCallArgs args, grpc_error_handle* error) {
1030
- auto connected_subchannel = GetConnectedSubchannel();
1031
- if (connected_subchannel == nullptr) return nullptr;
1032
- return connected_subchannel->CreateCall(args, error);
127
+ return kSecurityLevelUnknown;
1033
128
  }
1034
129
 
1035
- RefCountedPtr<UnstartedCallDestination> OldSubchannel::call_destination() {
1036
- auto connected_subchannel = GetConnectedSubchannel();
1037
- if (connected_subchannel == nullptr) return nullptr;
1038
- return connected_subchannel->unstarted_call_destination();
1039
- }
130
+ } // namespace
1040
131
 
1041
- void OldSubchannel::Ping(absl::AnyInvocable<void(absl::Status)>) {
1042
- // TODO(ctiller): Implement
1043
- }
132
+ //
133
+ // Subchannel::Call
134
+ //
1044
135
 
1045
- absl::Status OldSubchannel::Ping(grpc_closure* on_initiate,
1046
- grpc_closure* on_ack) {
1047
- auto connected_subchannel = GetConnectedSubchannel();
1048
- if (connected_subchannel == nullptr) {
1049
- return absl::UnavailableError("no connection");
1050
- }
1051
- connected_subchannel->Ping(on_initiate, on_ack);
1052
- return absl::OkStatus();
136
+ RefCountedPtr<Subchannel::Call> Subchannel::Call::Ref() {
137
+ IncrementRefCount();
138
+ return RefCountedPtr<Subchannel::Call>(this);
1053
139
  }
1054
140
 
1055
- RefCountedPtr<OldSubchannel::ConnectedSubchannel>
1056
- OldSubchannel::GetConnectedSubchannel() {
1057
- MutexLock lock(&mu_);
1058
- return connected_subchannel_;
141
+ RefCountedPtr<Subchannel::Call> Subchannel::Call::Ref(
142
+ const DebugLocation& location, const char* reason) {
143
+ IncrementRefCount(location, reason);
144
+ return RefCountedPtr<Subchannel::Call>(this);
1059
145
  }
1060
146
 
1061
147
  //
1062
- // NewSubchannel::ConnectedSubchannel
148
+ // Subchannel::ConnectedSubchannel
1063
149
  //
1064
150
 
1065
- class NewSubchannel::ConnectedSubchannel
151
+ class Subchannel::ConnectedSubchannel
1066
152
  : public DualRefCounted<ConnectedSubchannel> {
1067
153
  public:
1068
154
  ~ConnectedSubchannel() override {
@@ -1070,7 +156,7 @@ class NewSubchannel::ConnectedSubchannel
1070
156
  }
1071
157
 
1072
158
  const ChannelArgs& args() const { return args_; }
1073
- NewSubchannel* subchannel() const { return subchannel_.get(); }
159
+ Subchannel* subchannel() const { return subchannel_.get(); }
1074
160
 
1075
161
  virtual void StartWatch(
1076
162
  grpc_pollset_set* interested_parties,
@@ -1086,6 +172,7 @@ class NewSubchannel::ConnectedSubchannel
1086
172
  grpc_error_handle* error) = 0;
1087
173
  virtual void Ping(grpc_closure* on_initiate, grpc_closure* on_ack) = 0;
1088
174
 
175
+ absl::string_view security_level() const { return security_level_; }
1089
176
  // Returns true if there is quota for another RPC to start on this
1090
177
  // connection.
1091
178
  GRPC_MUST_USE_RESULT bool SetMaxConcurrentStreams(
@@ -1107,7 +194,7 @@ class NewSubchannel::ConnectedSubchannel
1107
194
  bool ReturnQuotaForRpc() { return stream_limiter_.ReturnQuotaForRpc(); }
1108
195
 
1109
196
  protected:
1110
- explicit ConnectedSubchannel(WeakRefCountedPtr<NewSubchannel> subchannel,
197
+ explicit ConnectedSubchannel(WeakRefCountedPtr<Subchannel> subchannel,
1111
198
  const ChannelArgs& args,
1112
199
  uint32_t max_concurrent_streams)
1113
200
  : DualRefCounted<ConnectedSubchannel>(
@@ -1115,23 +202,24 @@ class NewSubchannel::ConnectedSubchannel
1115
202
  : nullptr),
1116
203
  subchannel_(std::move(subchannel)),
1117
204
  args_(args),
205
+ security_level_(GetSecurityLevelFromArgs(args)),
1118
206
  stream_limiter_(max_concurrent_streams) {}
1119
207
 
1120
208
  private:
1121
- WeakRefCountedPtr<NewSubchannel> subchannel_;
209
+ WeakRefCountedPtr<Subchannel> subchannel_;
1122
210
  ChannelArgs args_;
211
+ const absl::string_view security_level_;
1123
212
  SubchannelStreamLimiter stream_limiter_;
1124
213
  };
1125
214
 
1126
215
  //
1127
- // NewSubchannel::LegacyConnectedSubchannel
216
+ // Subchannel::LegacyConnectedSubchannel
1128
217
  //
1129
218
 
1130
- class NewSubchannel::LegacyConnectedSubchannel final
1131
- : public ConnectedSubchannel {
219
+ class Subchannel::LegacyConnectedSubchannel final : public ConnectedSubchannel {
1132
220
  public:
1133
221
  LegacyConnectedSubchannel(
1134
- WeakRefCountedPtr<NewSubchannel> subchannel,
222
+ WeakRefCountedPtr<Subchannel> subchannel,
1135
223
  RefCountedPtr<grpc_channel_stack> channel_stack, const ChannelArgs& args,
1136
224
  RefCountedPtr<channelz::SubchannelNode> channelz_node,
1137
225
  uint32_t max_concurrent_streams)
@@ -1236,10 +324,10 @@ class NewSubchannel::LegacyConnectedSubchannel final
1236
324
  };
1237
325
 
1238
326
  //
1239
- // NewSubchannel::LegacyConnectedSubchannel::SubchannelCall
327
+ // Subchannel::LegacyConnectedSubchannel::SubchannelCall
1240
328
  //
1241
329
 
1242
- NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::SubchannelCall(
330
+ Subchannel::LegacyConnectedSubchannel::SubchannelCall::SubchannelCall(
1243
331
  RefCountedPtr<LegacyConnectedSubchannel> connected_subchannel,
1244
332
  CreateCallArgs args, grpc_error_handle* error)
1245
333
  : connected_subchannel_(std::move(connected_subchannel)),
@@ -1268,7 +356,7 @@ NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::SubchannelCall(
1268
356
  }
1269
357
  }
1270
358
 
1271
- void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::
359
+ void Subchannel::LegacyConnectedSubchannel::SubchannelCall::
1272
360
  StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch) {
1273
361
  GRPC_TRACE_LOG(subchannel_call, INFO)
1274
362
  << "subchannel " << connected_subchannel_->subchannel() << " connection "
@@ -1283,23 +371,23 @@ void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::
1283
371
  top_elem->filter->start_transport_stream_op_batch(top_elem, batch);
1284
372
  }
1285
373
 
1286
- void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::
374
+ void Subchannel::LegacyConnectedSubchannel::SubchannelCall::
1287
375
  SetAfterCallStackDestroy(grpc_closure* closure) {
1288
376
  GRPC_CHECK_EQ(after_call_stack_destroy_, nullptr);
1289
377
  GRPC_CHECK_NE(closure, nullptr);
1290
378
  after_call_stack_destroy_ = closure;
1291
379
  }
1292
380
 
1293
- void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::Unref() {
381
+ void Subchannel::LegacyConnectedSubchannel::SubchannelCall::Unref() {
1294
382
  GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), "");
1295
383
  }
1296
384
 
1297
- void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::Unref(
385
+ void Subchannel::LegacyConnectedSubchannel::SubchannelCall::Unref(
1298
386
  const DebugLocation& /*location*/, const char* reason) {
1299
387
  GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason);
1300
388
  }
1301
389
 
1302
- void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::Destroy(
390
+ void Subchannel::LegacyConnectedSubchannel::SubchannelCall::Destroy(
1303
391
  void* arg, grpc_error_handle /*error*/) {
1304
392
  SubchannelCall* self = static_cast<SubchannelCall*>(arg);
1305
393
  // Just in case we didn't already take care of this in the
@@ -1321,7 +409,7 @@ void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::Destroy(
1321
409
  // stack.
1322
410
  }
1323
411
 
1324
- void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::
412
+ void Subchannel::LegacyConnectedSubchannel::SubchannelCall::
1325
413
  MaybeInterceptRecvTrailingMetadata(grpc_transport_stream_op_batch* batch) {
1326
414
  // only intercept payloads with recv trailing.
1327
415
  if (!batch->recv_trailing_metadata) return;
@@ -1337,7 +425,21 @@ void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::
1337
425
  &recv_trailing_metadata_ready_;
1338
426
  }
1339
427
 
1340
- void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::
428
+ namespace {
429
+
430
+ // Sets *status based on the rest of the parameters.
431
+ void GetCallStatus(grpc_status_code* status, Timestamp deadline,
432
+ grpc_metadata_batch* md_batch, grpc_error_handle error) {
433
+ if (!error.ok()) {
434
+ grpc_error_get_status(error, deadline, status, nullptr, nullptr, nullptr);
435
+ } else {
436
+ *status = md_batch->get(GrpcStatusMetadata()).value_or(GRPC_STATUS_UNKNOWN);
437
+ }
438
+ }
439
+
440
+ } // namespace
441
+
442
+ void Subchannel::LegacyConnectedSubchannel::SubchannelCall::
1341
443
  RecvTrailingMetadataReady(void* arg, grpc_error_handle error) {
1342
444
  SubchannelCall* call = static_cast<SubchannelCall*>(arg);
1343
445
  GRPC_CHECK_NE(call->recv_trailing_metadata_, nullptr);
@@ -1359,8 +461,7 @@ void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::
1359
461
  Closure::Run(DEBUG_LOCATION, call->original_recv_trailing_metadata_, error);
1360
462
  }
1361
463
 
1362
- void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::
1363
- MaybeReturnQuota() {
464
+ void Subchannel::LegacyConnectedSubchannel::SubchannelCall::MaybeReturnQuota() {
1364
465
  if (returned_quota_) return; // Already returned.
1365
466
  returned_quota_ = true;
1366
467
  GRPC_TRACE_LOG(subchannel_call, INFO)
@@ -1372,23 +473,23 @@ void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::
1372
473
  }
1373
474
  }
1374
475
 
1375
- void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::
476
+ void Subchannel::LegacyConnectedSubchannel::SubchannelCall::
1376
477
  IncrementRefCount() {
1377
478
  GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), "");
1378
479
  }
1379
480
 
1380
- void NewSubchannel::LegacyConnectedSubchannel::SubchannelCall::
1381
- IncrementRefCount(const DebugLocation& /*location*/, const char* reason) {
481
+ void Subchannel::LegacyConnectedSubchannel::SubchannelCall::IncrementRefCount(
482
+ const DebugLocation& /*location*/, const char* reason) {
1382
483
  GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason);
1383
484
  }
1384
485
 
1385
486
  //
1386
- // NewSubchannel::QueuedCall
487
+ // Subchannel::QueuedCall
1387
488
  //
1388
489
 
1389
- class NewSubchannel::QueuedCall final : public Subchannel::Call {
490
+ class Subchannel::QueuedCall final : public Subchannel::Call {
1390
491
  public:
1391
- QueuedCall(WeakRefCountedPtr<NewSubchannel> subchannel, CreateCallArgs args);
492
+ QueuedCall(WeakRefCountedPtr<Subchannel> subchannel, CreateCallArgs args);
1392
493
  ~QueuedCall() override;
1393
494
 
1394
495
  void StartTransportStreamOpBatch(
@@ -1407,10 +508,10 @@ class NewSubchannel::QueuedCall final : public Subchannel::Call {
1407
508
  }
1408
509
 
1409
510
  void ResumeOnConnectionLocked(ConnectedSubchannel* connected_subchannel)
1410
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&NewSubchannel::mu_);
511
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&Subchannel::mu_);
1411
512
 
1412
513
  void FailLocked(absl::Status status)
1413
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&NewSubchannel::mu_);
514
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&Subchannel::mu_);
1414
515
 
1415
516
  private:
1416
517
  // Allow RefCountedPtr<> to access IncrementRefCount().
@@ -1429,7 +530,7 @@ class NewSubchannel::QueuedCall final : public Subchannel::Call {
1429
530
  static void RecvTrailingMetadataReady(void* arg, grpc_error_handle error);
1430
531
 
1431
532
  RefCount ref_count_;
1432
- WeakRefCountedPtr<NewSubchannel> subchannel_;
533
+ WeakRefCountedPtr<Subchannel> subchannel_;
1433
534
  CreateCallArgs args_;
1434
535
 
1435
536
  // Note that unlike in the resolver and LB code, the subchannel code
@@ -1438,7 +539,7 @@ class NewSubchannel::QueuedCall final : public Subchannel::Call {
1438
539
  // and try to resume it before buffered_call_ contains any batches.
1439
540
  // In that case, we will not be holding the call combiner here, so we
1440
541
  // need a mutex for synchronization.
1441
- Mutex mu_ ABSL_ACQUIRED_AFTER(NewSubchannel::mu_);
542
+ Mutex mu_ ABSL_ACQUIRED_AFTER(Subchannel::mu_);
1442
543
  grpc_closure* after_call_stack_destroy_ ABSL_GUARDED_BY(&mu_) = nullptr;
1443
544
  grpc_error_handle cancel_error_ ABSL_GUARDED_BY(&mu_);
1444
545
  BufferedCall buffered_call_ ABSL_GUARDED_BY(&mu_);
@@ -1451,7 +552,7 @@ class NewSubchannel::QueuedCall final : public Subchannel::Call {
1451
552
  // don't try to dequeue this call after it's been cancelled.
1452
553
  QueuedCall*& queue_entry_;
1453
554
 
1454
- Canceller* canceller_ ABSL_GUARDED_BY(&NewSubchannel::mu_);
555
+ Canceller* canceller_ ABSL_GUARDED_BY(&Subchannel::mu_);
1455
556
 
1456
557
  std::atomic<bool> is_retriable_{false};
1457
558
  grpc_closure recv_trailing_metadata_ready_;
@@ -1467,7 +568,7 @@ class NewSubchannel::QueuedCall final : public Subchannel::Call {
1467
568
  // the call is cancelled. In that case, it removes the call from the
1468
569
  // queue and fails any pending batches, thus immediately releasing the
1469
570
  // call combiner and allowing the cancellation to proceed.
1470
- class NewSubchannel::QueuedCall::Canceller final {
571
+ class Subchannel::QueuedCall::Canceller final {
1471
572
  public:
1472
573
  explicit Canceller(RefCountedPtr<QueuedCall> call) : call_(std::move(call)) {
1473
574
  GRPC_CLOSURE_INIT(&cancel_, CancelLocked, this, nullptr);
@@ -1503,8 +604,8 @@ class NewSubchannel::QueuedCall::Canceller final {
1503
604
  grpc_closure cancel_;
1504
605
  };
1505
606
 
1506
- NewSubchannel::QueuedCall::QueuedCall(
1507
- WeakRefCountedPtr<NewSubchannel> subchannel, CreateCallArgs args)
607
+ Subchannel::QueuedCall::QueuedCall(WeakRefCountedPtr<Subchannel> subchannel,
608
+ CreateCallArgs args)
1508
609
  : subchannel_(std::move(subchannel)),
1509
610
  args_(args),
1510
611
  buffered_call_(args_.call_combiner, &subchannel_call_trace),
@@ -1515,7 +616,7 @@ NewSubchannel::QueuedCall::QueuedCall(
1515
616
  canceller_ = new Canceller(Ref().TakeAsSubclass<QueuedCall>());
1516
617
  }
1517
618
 
1518
- NewSubchannel::QueuedCall::~QueuedCall() {
619
+ Subchannel::QueuedCall::~QueuedCall() {
1519
620
  GRPC_TRACE_LOG(subchannel_call, INFO) << "subchannel " << subchannel_.get()
1520
621
  << ": destroying queued call " << this;
1521
622
  if (after_call_stack_destroy_ != nullptr) {
@@ -1523,8 +624,7 @@ NewSubchannel::QueuedCall::~QueuedCall() {
1523
624
  }
1524
625
  }
1525
626
 
1526
- void NewSubchannel::QueuedCall::SetAfterCallStackDestroy(
1527
- grpc_closure* closure) {
627
+ void Subchannel::QueuedCall::SetAfterCallStackDestroy(grpc_closure* closure) {
1528
628
  GRPC_CHECK_NE(closure, nullptr);
1529
629
  MutexLock lock(&mu_);
1530
630
  if (subchannel_call_ != nullptr) {
@@ -1535,7 +635,7 @@ void NewSubchannel::QueuedCall::SetAfterCallStackDestroy(
1535
635
  }
1536
636
  }
1537
637
 
1538
- void NewSubchannel::QueuedCall::StartTransportStreamOpBatch(
638
+ void Subchannel::QueuedCall::StartTransportStreamOpBatch(
1539
639
  grpc_transport_stream_op_batch* batch) {
1540
640
  GRPC_TRACE_LOG(subchannel_call, INFO)
1541
641
  << "subchannel " << subchannel_.get() << " queued call " << this
@@ -1588,7 +688,7 @@ void NewSubchannel::QueuedCall::StartTransportStreamOpBatch(
1588
688
  }
1589
689
  }
1590
690
 
1591
- void NewSubchannel::QueuedCall::RecvTrailingMetadataReady(
691
+ void Subchannel::QueuedCall::RecvTrailingMetadataReady(
1592
692
  void* arg, grpc_error_handle error) {
1593
693
  QueuedCall* call = static_cast<QueuedCall*>(arg);
1594
694
  GRPC_CHECK_NE(call->recv_trailing_metadata_, nullptr);
@@ -1599,7 +699,7 @@ void NewSubchannel::QueuedCall::RecvTrailingMetadataReady(
1599
699
  Closure::Run(DEBUG_LOCATION, call->original_recv_trailing_metadata_, error);
1600
700
  }
1601
701
 
1602
- void NewSubchannel::QueuedCall::ResumeOnConnectionLocked(
702
+ void Subchannel::QueuedCall::ResumeOnConnectionLocked(
1603
703
  ConnectedSubchannel* connected_subchannel) {
1604
704
  GRPC_TRACE_LOG(subchannel_call, INFO)
1605
705
  << "subchannel " << subchannel_.get() << " queued call " << this
@@ -1632,7 +732,7 @@ void NewSubchannel::QueuedCall::ResumeOnConnectionLocked(
1632
732
  }
1633
733
  }
1634
734
 
1635
- void NewSubchannel::QueuedCall::FailLocked(absl::Status status) {
735
+ void Subchannel::QueuedCall::FailLocked(absl::Status status) {
1636
736
  GRPC_TRACE_LOG(subchannel_call, INFO)
1637
737
  << "subchannel " << subchannel_.get() << " queued call " << this
1638
738
  << ": failing: " << status;
@@ -1646,10 +746,10 @@ void NewSubchannel::QueuedCall::FailLocked(absl::Status status) {
1646
746
  }
1647
747
 
1648
748
  //
1649
- // NewSubchannel::NewConnectedSubchannel
749
+ // Subchannel::NewConnectedSubchannel
1650
750
  //
1651
751
 
1652
- class NewSubchannel::NewConnectedSubchannel final : public ConnectedSubchannel {
752
+ class Subchannel::NewConnectedSubchannel final : public ConnectedSubchannel {
1653
753
  public:
1654
754
  class TransportCallDestination final : public CallDestination {
1655
755
  public:
@@ -1669,7 +769,7 @@ class NewSubchannel::NewConnectedSubchannel final : public ConnectedSubchannel {
1669
769
  };
1670
770
 
1671
771
  NewConnectedSubchannel(
1672
- WeakRefCountedPtr<NewSubchannel> subchannel,
772
+ WeakRefCountedPtr<Subchannel> subchannel,
1673
773
  RefCountedPtr<UnstartedCallDestination> call_destination,
1674
774
  RefCountedPtr<TransportCallDestination> transport,
1675
775
  const ChannelArgs& args, uint32_t max_concurrent_streams)
@@ -1713,10 +813,10 @@ class NewSubchannel::NewConnectedSubchannel final : public ConnectedSubchannel {
1713
813
  };
1714
814
 
1715
815
  //
1716
- // NewSubchannel::ConnectionStateWatcher
816
+ // Subchannel::ConnectionStateWatcher
1717
817
  //
1718
818
 
1719
- class NewSubchannel::ConnectionStateWatcher final
819
+ class Subchannel::ConnectionStateWatcher final
1720
820
  : public Transport::StateWatcher {
1721
821
  public:
1722
822
  explicit ConnectionStateWatcher(
@@ -1725,11 +825,21 @@ class NewSubchannel::ConnectionStateWatcher final
1725
825
 
1726
826
  void OnDisconnect(absl::Status status,
1727
827
  DisconnectInfo disconnect_info) override {
1728
- NewSubchannel* subchannel = connected_subchannel_->subchannel();
828
+ Subchannel* subchannel = connected_subchannel_->subchannel();
1729
829
  GRPC_TRACE_LOG(subchannel, INFO)
1730
830
  << "subchannel " << subchannel << " " << subchannel->key_.ToString()
1731
831
  << ": connected subchannel " << connected_subchannel_.get()
1732
- << " reports disconnection: " << status;
832
+ << " reports disconnection: " << status
833
+ << " (reason=" << disconnect_info.reason << ", http2_error_code="
834
+ << (disconnect_info.http2_error_code.has_value()
835
+ ? http2::Http2Status::DebugGetCode(
836
+ *disconnect_info.http2_error_code)
837
+ : "<unset>")
838
+ << ", keepalive_time="
839
+ << (disconnect_info.keepalive_time.has_value()
840
+ ? disconnect_info.keepalive_time->ToString()
841
+ : "<unset>")
842
+ << ")";
1733
843
  MutexLock lock(&subchannel->mu_);
1734
844
  // Handle keepalive update.
1735
845
  if (disconnect_info.keepalive_time.has_value()) {
@@ -1739,6 +849,50 @@ class NewSubchannel::ConnectionStateWatcher final
1739
849
  }
1740
850
  // Remove the connection from the subchannel's list of connections.
1741
851
  subchannel->RemoveConnectionLocked(connected_subchannel_.get());
852
+ if (subchannel->stats_plugin_group_ != nullptr) {
853
+ // Determine disconnect reason from DisconnectInfo
854
+ std::string disconnect_reason;
855
+ if (subchannel->shutdown_) {
856
+ disconnect_reason = "subchannel shutdown";
857
+ } else {
858
+ switch (disconnect_info.reason) {
859
+ case DisconnectReason::kGoaway:
860
+ if (disconnect_info.http2_error_code.has_value()) {
861
+ disconnect_reason = absl::StrCat(
862
+ "GOAWAY ", http2::Http2Status::DebugGetCode(
863
+ *disconnect_info.http2_error_code));
864
+ } else {
865
+ disconnect_reason = "GOAWAY UNKNOWN";
866
+ }
867
+ break;
868
+ case DisconnectReason::kConnectionReset:
869
+ disconnect_reason = "connection reset";
870
+ break;
871
+ case DisconnectReason::kConnectionTimedOut:
872
+ disconnect_reason = "connection timed out";
873
+ break;
874
+ case DisconnectReason::kConnectionAborted:
875
+ disconnect_reason = "connection aborted";
876
+ break;
877
+ case DisconnectReason::kSocketError:
878
+ disconnect_reason = "socket error";
879
+ break;
880
+ case DisconnectReason::kUnknown:
881
+ disconnect_reason = "unknown";
882
+ break;
883
+ }
884
+ }
885
+ auto scope = subchannel->stats_plugin_group_->GetCollectionScope();
886
+ SubchannelMetricsDomainDisconnections::GetStorage(
887
+ scope, subchannel->target_, subchannel->backend_service_,
888
+ subchannel->locality_, disconnect_reason)
889
+ ->Increment(SubchannelMetricsDomainDisconnections::kDisconnections);
890
+ SubchannelConnectionsDomainOpenConnections::GetStorage(
891
+ scope, subchannel->target_, connected_subchannel_->security_level(),
892
+ subchannel->backend_service_, subchannel->locality_)
893
+ ->Decrement(
894
+ SubchannelConnectionsDomainOpenConnections::kOpenConnections);
895
+ }
1742
896
  // If this was the last connection, then fail all queued RPCs and
1743
897
  // update the connectivity state.
1744
898
  if (subchannel->connections_.empty()) {
@@ -1756,7 +910,7 @@ class NewSubchannel::ConnectionStateWatcher final
1756
910
  uint32_t max_concurrent_streams,
1757
911
  std::unique_ptr<MaxConcurrentStreamsUpdateDoneHandle> /*on_done*/)
1758
912
  override {
1759
- NewSubchannel* subchannel = connected_subchannel_->subchannel();
913
+ Subchannel* subchannel = connected_subchannel_->subchannel();
1760
914
  GRPC_TRACE_LOG(subchannel, INFO)
1761
915
  << "subchannel " << subchannel << " " << subchannel->key_.ToString()
1762
916
  << ": connection " << connected_subchannel_.get()
@@ -1776,20 +930,20 @@ class NewSubchannel::ConnectionStateWatcher final
1776
930
  };
1777
931
 
1778
932
  //
1779
- // NewSubchannel::ConnectivityStateWatcherList
933
+ // Subchannel::ConnectivityStateWatcherList
1780
934
  //
1781
935
 
1782
- void NewSubchannel::ConnectivityStateWatcherList::AddWatcherLocked(
936
+ void Subchannel::ConnectivityStateWatcherList::AddWatcherLocked(
1783
937
  RefCountedPtr<ConnectivityStateWatcherInterface> watcher) {
1784
938
  watchers_.insert(std::move(watcher));
1785
939
  }
1786
940
 
1787
- void NewSubchannel::ConnectivityStateWatcherList::RemoveWatcherLocked(
941
+ void Subchannel::ConnectivityStateWatcherList::RemoveWatcherLocked(
1788
942
  ConnectivityStateWatcherInterface* watcher) {
1789
943
  watchers_.erase(watcher);
1790
944
  }
1791
945
 
1792
- void NewSubchannel::ConnectivityStateWatcherList::NotifyLocked(
946
+ void Subchannel::ConnectivityStateWatcherList::NotifyLocked(
1793
947
  grpc_connectivity_state state, const absl::Status& status) {
1794
948
  for (const auto& watcher : watchers_) {
1795
949
  subchannel_->work_serializer_.Run([watcher, state, status]() {
@@ -1798,7 +952,7 @@ void NewSubchannel::ConnectivityStateWatcherList::NotifyLocked(
1798
952
  }
1799
953
  }
1800
954
 
1801
- void NewSubchannel::ConnectivityStateWatcherList::NotifyOnKeepaliveUpdateLocked(
955
+ void Subchannel::ConnectivityStateWatcherList::NotifyOnKeepaliveUpdateLocked(
1802
956
  Duration new_keepalive_time) {
1803
957
  for (const auto& watcher : watchers_) {
1804
958
  subchannel_->work_serializer_.Run([watcher, new_keepalive_time]() {
@@ -1808,7 +962,7 @@ void NewSubchannel::ConnectivityStateWatcherList::NotifyOnKeepaliveUpdateLocked(
1808
962
  }
1809
963
 
1810
964
  uint32_t
1811
- NewSubchannel::ConnectivityStateWatcherList::GetMaxConnectionsPerSubchannel()
965
+ Subchannel::ConnectivityStateWatcherList::GetMaxConnectionsPerSubchannel()
1812
966
  const {
1813
967
  uint32_t max_connections_per_subchannel = 1;
1814
968
  for (const auto& watcher : watchers_) {
@@ -1820,13 +974,56 @@ NewSubchannel::ConnectivityStateWatcherList::GetMaxConnectionsPerSubchannel()
1820
974
  }
1821
975
 
1822
976
  //
1823
- // NewSubchannel
977
+ // Subchannel
1824
978
  //
1825
979
 
1826
- NewSubchannel::NewSubchannel(SubchannelKey key,
1827
- OrphanablePtr<SubchannelConnector> connector,
1828
- const ChannelArgs& args)
1829
- : key_(std::move(key)),
980
+ namespace {
981
+
982
+ BackOff::Options ParseArgsForBackoffValues(const ChannelArgs& args,
983
+ Duration* min_connect_timeout) {
984
+ const std::optional<Duration> fixed_reconnect_backoff =
985
+ args.GetDurationFromIntMillis("grpc.testing.fixed_reconnect_backoff_ms");
986
+ if (fixed_reconnect_backoff.has_value()) {
987
+ const Duration backoff =
988
+ std::max(Duration::Milliseconds(100), *fixed_reconnect_backoff);
989
+ *min_connect_timeout = backoff;
990
+ return BackOff::Options()
991
+ .set_initial_backoff(backoff)
992
+ .set_multiplier(1.0)
993
+ .set_jitter(0.0)
994
+ .set_max_backoff(backoff);
995
+ }
996
+ const Duration initial_backoff = std::max(
997
+ Duration::Milliseconds(100),
998
+ args.GetDurationFromIntMillis(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS)
999
+ .value_or(Duration::Seconds(
1000
+ GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS)));
1001
+ *min_connect_timeout =
1002
+ std::max(Duration::Milliseconds(100),
1003
+ args.GetDurationFromIntMillis(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS)
1004
+ .value_or(Duration::Seconds(
1005
+ GRPC_SUBCHANNEL_RECONNECT_MIN_TIMEOUT_SECONDS)));
1006
+ const Duration max_backoff =
1007
+ std::max(Duration::Milliseconds(100),
1008
+ args.GetDurationFromIntMillis(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS)
1009
+ .value_or(Duration::Seconds(
1010
+ GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS)));
1011
+ return BackOff::Options()
1012
+ .set_initial_backoff(initial_backoff)
1013
+ .set_multiplier(GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER)
1014
+ .set_jitter(GRPC_SUBCHANNEL_RECONNECT_JITTER)
1015
+ .set_max_backoff(max_backoff);
1016
+ }
1017
+
1018
+ } // namespace
1019
+
1020
+ Subchannel::Subchannel(SubchannelKey key,
1021
+ OrphanablePtr<SubchannelConnector> connector,
1022
+ const ChannelArgs& args)
1023
+ : DualRefCounted<Subchannel>(GRPC_TRACE_FLAG_ENABLED(subchannel_refcount)
1024
+ ? "Subchannel"
1025
+ : nullptr),
1026
+ key_(std::move(key)),
1830
1027
  created_from_endpoint_(args.Contains(GRPC_ARG_SUBCHANNEL_ENDPOINT)),
1831
1028
  args_(args),
1832
1029
  pollset_set_(grpc_pollset_set_create()),
@@ -1834,7 +1031,17 @@ NewSubchannel::NewSubchannel(SubchannelKey key,
1834
1031
  watcher_list_(this),
1835
1032
  work_serializer_(args_.GetObjectRef<EventEngine>()),
1836
1033
  backoff_(ParseArgsForBackoffValues(args_, &min_connect_timeout_)),
1837
- event_engine_(args_.GetObjectRef<EventEngine>()) {
1034
+ event_engine_(args_.GetObjectRef<EventEngine>()),
1035
+ stats_plugin_group_(
1036
+ args_.GetObjectRef<GlobalStatsPluginRegistry::StatsPluginGroup>()),
1037
+ target_(args_.GetString(GRPC_ARG_DEFAULT_AUTHORITY).value_or("")),
1038
+ backend_service_(args_.GetString(GRPC_ARG_BACKEND_SERVICE).value_or("")),
1039
+ locality_(args_.GetString(GRPC_ARG_LB_LOCALITY).value_or("")) {
1040
+ if (stats_plugin_group_ != nullptr) {
1041
+ attempts_storage_ = SubchannelMetricsDomainAttempts::GetStorage(
1042
+ stats_plugin_group_->GetCollectionScope(), target_, backend_service_,
1043
+ locality_);
1044
+ }
1838
1045
  GRPC_TRACE_LOG(subchannel, INFO)
1839
1046
  << "subchannel " << this << " " << key_.ToString() << ": created";
1840
1047
  // A grpc_init is added here to ensure that grpc_shutdown does not happen
@@ -1873,7 +1080,7 @@ NewSubchannel::NewSubchannel(SubchannelKey key,
1873
1080
  }
1874
1081
  }
1875
1082
 
1876
- NewSubchannel::~NewSubchannel() {
1083
+ Subchannel::~Subchannel() {
1877
1084
  if (channelz_node_ != nullptr) {
1878
1085
  GRPC_CHANNELZ_LOG(channelz_node_) << "Subchannel destroyed";
1879
1086
  channelz_node_->UpdateConnectivityState(GRPC_CHANNEL_SHUTDOWN);
@@ -1884,18 +1091,18 @@ NewSubchannel::~NewSubchannel() {
1884
1091
  ShutdownInternally();
1885
1092
  }
1886
1093
 
1887
- RefCountedPtr<Subchannel> NewSubchannel::Create(
1094
+ RefCountedPtr<Subchannel> Subchannel::Create(
1888
1095
  OrphanablePtr<SubchannelConnector> connector,
1889
1096
  const grpc_resolved_address& address, const ChannelArgs& args) {
1890
1097
  SubchannelKey key(address, args);
1891
1098
  auto* subchannel_pool = args.GetObject<SubchannelPoolInterface>();
1892
1099
  GRPC_CHECK_NE(subchannel_pool, nullptr);
1893
- RefCountedPtr<NewSubchannel> c =
1894
- subchannel_pool->FindSubchannel(key).TakeAsSubclass<NewSubchannel>();
1100
+ RefCountedPtr<Subchannel> c =
1101
+ subchannel_pool->FindSubchannel(key).TakeAsSubclass<Subchannel>();
1895
1102
  if (c != nullptr) {
1896
1103
  return c;
1897
1104
  }
1898
- c = MakeRefCounted<NewSubchannel>(std::move(key), std::move(connector), args);
1105
+ c = MakeRefCounted<Subchannel>(std::move(key), std::move(connector), args);
1899
1106
  if (c->created_from_endpoint_) {
1900
1107
  // We don't interact with the subchannel pool in this case.
1901
1108
  // Instead, we unconditionally return the newly created subchannel.
@@ -1909,19 +1116,19 @@ RefCountedPtr<Subchannel> NewSubchannel::Create(
1909
1116
  // Otherwise, in case of a registration race, unreffing c in
1910
1117
  // RegisterSubchannel() will cause c to be tried to be unregistered, while
1911
1118
  // its key maps to a different subchannel.
1912
- RefCountedPtr<NewSubchannel> registered =
1119
+ RefCountedPtr<Subchannel> registered =
1913
1120
  subchannel_pool->RegisterSubchannel(c->key_, c)
1914
- .TakeAsSubclass<NewSubchannel>();
1121
+ .TakeAsSubclass<Subchannel>();
1915
1122
  if (registered == c) c->subchannel_pool_ = subchannel_pool->Ref();
1916
1123
  return registered;
1917
1124
  }
1918
1125
 
1919
- void NewSubchannel::ThrottleKeepaliveTime(Duration new_keepalive_time) {
1126
+ void Subchannel::ThrottleKeepaliveTime(Duration new_keepalive_time) {
1920
1127
  MutexLock lock(&mu_);
1921
1128
  ThrottleKeepaliveTimeLocked(new_keepalive_time);
1922
1129
  }
1923
1130
 
1924
- void NewSubchannel::ThrottleKeepaliveTimeLocked(Duration new_keepalive_time) {
1131
+ void Subchannel::ThrottleKeepaliveTimeLocked(Duration new_keepalive_time) {
1925
1132
  // Only update the value if the new keepalive time is larger.
1926
1133
  if (new_keepalive_time > keepalive_time_) {
1927
1134
  keepalive_time_ = new_keepalive_time;
@@ -1932,11 +1139,11 @@ void NewSubchannel::ThrottleKeepaliveTimeLocked(Duration new_keepalive_time) {
1932
1139
  }
1933
1140
  }
1934
1141
 
1935
- channelz::SubchannelNode* NewSubchannel::channelz_node() {
1142
+ channelz::SubchannelNode* Subchannel::channelz_node() {
1936
1143
  return channelz_node_.get();
1937
1144
  }
1938
1145
 
1939
- void NewSubchannel::WatchConnectivityState(
1146
+ void Subchannel::WatchConnectivityState(
1940
1147
  RefCountedPtr<ConnectivityStateWatcherInterface> watcher) {
1941
1148
  MutexLock lock(&mu_);
1942
1149
  grpc_pollset_set* interested_parties = watcher->interested_parties();
@@ -1954,7 +1161,7 @@ void NewSubchannel::WatchConnectivityState(
1954
1161
  RetryQueuedRpcsLocked();
1955
1162
  }
1956
1163
 
1957
- void NewSubchannel::CancelConnectivityStateWatch(
1164
+ void Subchannel::CancelConnectivityStateWatch(
1958
1165
  ConnectivityStateWatcherInterface* watcher) {
1959
1166
  MutexLock lock(&mu_);
1960
1167
  grpc_pollset_set* interested_parties = watcher->interested_parties();
@@ -1964,7 +1171,7 @@ void NewSubchannel::CancelConnectivityStateWatch(
1964
1171
  watcher_list_.RemoveWatcherLocked(watcher);
1965
1172
  }
1966
1173
 
1967
- void NewSubchannel::RequestConnection() {
1174
+ void Subchannel::RequestConnection() {
1968
1175
  GRPC_TRACE_LOG(subchannel, INFO)
1969
1176
  << "subchannel " << this << " " << key_.ToString()
1970
1177
  << ": RequestConnection()";
@@ -1974,7 +1181,7 @@ void NewSubchannel::RequestConnection() {
1974
1181
  }
1975
1182
  }
1976
1183
 
1977
- void NewSubchannel::ResetBackoff() {
1184
+ void Subchannel::ResetBackoff() {
1978
1185
  GRPC_TRACE_LOG(subchannel, INFO)
1979
1186
  << "subchannel " << this << " " << key_.ToString() << ": ResetBackoff()";
1980
1187
  // Hold a ref to ensure cancellation and subsequent deletion of the closure
@@ -1991,7 +1198,7 @@ void NewSubchannel::ResetBackoff() {
1991
1198
  }
1992
1199
  }
1993
1200
 
1994
- void NewSubchannel::Orphaned() {
1201
+ void Subchannel::Orphaned() {
1995
1202
  GRPC_TRACE_LOG(subchannel, INFO)
1996
1203
  << "subchannel " << this << " " << key_.ToString() << ": shutting down";
1997
1204
  // The subchannel_pool is only used once here in this subchannel, so the
@@ -2010,7 +1217,7 @@ void NewSubchannel::Orphaned() {
2010
1217
  }
2011
1218
  }
2012
1219
 
2013
- void NewSubchannel::GetOrAddDataProducer(
1220
+ void Subchannel::GetOrAddDataProducer(
2014
1221
  UniqueTypeName type,
2015
1222
  std::function<void(DataProducerInterface**)> get_or_add) {
2016
1223
  MutexLock lock(&mu_);
@@ -2018,7 +1225,7 @@ void NewSubchannel::GetOrAddDataProducer(
2018
1225
  get_or_add(&it->second);
2019
1226
  }
2020
1227
 
2021
- void NewSubchannel::RemoveDataProducer(DataProducerInterface* data_producer) {
1228
+ void Subchannel::RemoveDataProducer(DataProducerInterface* data_producer) {
2022
1229
  MutexLock lock(&mu_);
2023
1230
  auto it = data_producer_map_.find(data_producer->type());
2024
1231
  if (it != data_producer_map_.end() && it->second == data_producer) {
@@ -2037,12 +1244,12 @@ absl::Status PrependAddressToStatusMessage(const SubchannelKey& key,
2037
1244
 
2038
1245
  } // namespace
2039
1246
 
2040
- void NewSubchannel::SetLastFailureLocked(const absl::Status& status) {
1247
+ void Subchannel::SetLastFailureLocked(const absl::Status& status) {
2041
1248
  // Augment status message to include IP address.
2042
1249
  last_failure_status_ = PrependAddressToStatusMessage(key_, status);
2043
1250
  }
2044
1251
 
2045
- grpc_connectivity_state NewSubchannel::ComputeConnectivityStateLocked() const {
1252
+ grpc_connectivity_state Subchannel::ComputeConnectivityStateLocked() const {
2046
1253
  // If we have at least one connection, report READY.
2047
1254
  if (!connections_.empty()) return GRPC_CHANNEL_READY;
2048
1255
  // If we were created from an endpoint and the connection is closed,
@@ -2059,13 +1266,13 @@ grpc_connectivity_state NewSubchannel::ComputeConnectivityStateLocked() const {
2059
1266
  return GRPC_CHANNEL_IDLE;
2060
1267
  }
2061
1268
 
2062
- absl::Status NewSubchannel::ConnectivityStatusToReportLocked() const {
1269
+ absl::Status Subchannel::ConnectivityStatusToReportLocked() const {
2063
1270
  // Report status in TRANSIENT_FAILURE state.
2064
1271
  if (state_ == GRPC_CHANNEL_TRANSIENT_FAILURE) return last_failure_status_;
2065
1272
  return absl::OkStatus();
2066
1273
  }
2067
1274
 
2068
- void NewSubchannel::MaybeUpdateConnectivityStateLocked() {
1275
+ void Subchannel::MaybeUpdateConnectivityStateLocked() {
2069
1276
  // Determine what state we are in.
2070
1277
  grpc_connectivity_state new_state = ComputeConnectivityStateLocked();
2071
1278
  // If we're already in that state, no need to report a change.
@@ -2093,7 +1300,7 @@ void NewSubchannel::MaybeUpdateConnectivityStateLocked() {
2093
1300
  watcher_list_.NotifyLocked(new_state, status);
2094
1301
  }
2095
1302
 
2096
- bool NewSubchannel::RemoveConnectionLocked(
1303
+ bool Subchannel::RemoveConnectionLocked(
2097
1304
  ConnectedSubchannel* connected_subchannel) {
2098
1305
  for (auto it = connections_.begin(); it != connections_.end(); ++it) {
2099
1306
  if (*it == connected_subchannel) {
@@ -2107,12 +1314,12 @@ bool NewSubchannel::RemoveConnectionLocked(
2107
1314
  return false;
2108
1315
  }
2109
1316
 
2110
- void NewSubchannel::OnRetryTimer() {
1317
+ void Subchannel::OnRetryTimer() {
2111
1318
  MutexLock lock(&mu_);
2112
1319
  OnRetryTimerLocked();
2113
1320
  }
2114
1321
 
2115
- void NewSubchannel::OnRetryTimerLocked() {
1322
+ void Subchannel::OnRetryTimerLocked() {
2116
1323
  retry_timer_handle_.reset();
2117
1324
  if (shutdown_) return;
2118
1325
  GRPC_TRACE_LOG(subchannel, INFO)
@@ -2122,7 +1329,7 @@ void NewSubchannel::OnRetryTimerLocked() {
2122
1329
  MaybeUpdateConnectivityStateLocked();
2123
1330
  }
2124
1331
 
2125
- void NewSubchannel::StartConnectingLocked() {
1332
+ void Subchannel::StartConnectingLocked() {
2126
1333
  // Set next attempt time.
2127
1334
  const Timestamp now = Timestamp::Now();
2128
1335
  const Timestamp min_deadline = now + min_connect_timeout_;
@@ -2141,8 +1348,8 @@ void NewSubchannel::StartConnectingLocked() {
2141
1348
  connector_->Connect(args, &connecting_result_, &on_connecting_finished_);
2142
1349
  }
2143
1350
 
2144
- void NewSubchannel::OnConnectingFinished(void* arg, grpc_error_handle error) {
2145
- WeakRefCountedPtr<NewSubchannel> c(static_cast<NewSubchannel*>(arg));
1351
+ void Subchannel::OnConnectingFinished(void* arg, grpc_error_handle error) {
1352
+ WeakRefCountedPtr<Subchannel> c(static_cast<Subchannel*>(arg));
2146
1353
  {
2147
1354
  MutexLock lock(&c->mu_);
2148
1355
  c->OnConnectingFinishedLocked(error);
@@ -2150,7 +1357,7 @@ void NewSubchannel::OnConnectingFinished(void* arg, grpc_error_handle error) {
2150
1357
  c.reset(DEBUG_LOCATION, "Connect");
2151
1358
  }
2152
1359
 
2153
- void NewSubchannel::OnConnectingFinishedLocked(grpc_error_handle error) {
1360
+ void Subchannel::OnConnectingFinishedLocked(grpc_error_handle error) {
2154
1361
  connection_attempt_in_flight_ = false;
2155
1362
  if (shutdown_) {
2156
1363
  connecting_result_.Reset();
@@ -2172,11 +1379,16 @@ void NewSubchannel::OnConnectingFinishedLocked(grpc_error_handle error) {
2172
1379
  "remaining in TRANSIENT_FAILURE"
2173
1380
  : ", backing off for " +
2174
1381
  std::to_string(time_until_next_attempt.millis()) + " ms");
1382
+ // Record failed connection attempt
1383
+ if (attempts_storage_ != nullptr) {
1384
+ attempts_storage_->Increment(
1385
+ SubchannelMetricsDomainAttempts::kConnectionAttemptsFailed);
1386
+ }
2175
1387
  if (!created_from_endpoint_) {
2176
1388
  retry_timer_handle_ = event_engine_->RunAfter(
2177
1389
  time_until_next_attempt,
2178
1390
  [self = WeakRef(DEBUG_LOCATION, "RetryTimer")
2179
- .TakeAsSubclass<NewSubchannel>()]() mutable {
1391
+ .TakeAsSubclass<Subchannel>()]() mutable {
2180
1392
  {
2181
1393
  ExecCtx exec_ctx;
2182
1394
  self->OnRetryTimer();
@@ -2190,12 +1402,12 @@ void NewSubchannel::OnConnectingFinishedLocked(grpc_error_handle error) {
2190
1402
  }
2191
1403
  });
2192
1404
  }
2193
- SetLastFailureLocked(grpc_error_to_absl_status(error));
1405
+ SetLastFailureLocked(error);
2194
1406
  MaybeUpdateConnectivityStateLocked();
2195
1407
  }
2196
1408
  }
2197
1409
 
2198
- bool NewSubchannel::PublishTransportLocked() {
1410
+ bool Subchannel::PublishTransportLocked() {
2199
1411
  auto socket_node = connecting_result_.transport->GetSocketNode();
2200
1412
  Transport* transport = connecting_result_.transport;
2201
1413
  RefCountedPtr<ConnectedSubchannel> connected_subchannel;
@@ -2217,8 +1429,9 @@ bool NewSubchannel::PublishTransportLocked() {
2217
1429
  return false;
2218
1430
  }
2219
1431
  connected_subchannel = MakeRefCounted<LegacyConnectedSubchannel>(
2220
- WeakRef().TakeAsSubclass<NewSubchannel>(), std::move(*stack), args_,
2221
- channelz_node_, connecting_result_.max_concurrent_streams);
1432
+ WeakRef().TakeAsSubclass<Subchannel>(), std::move(*stack),
1433
+ connecting_result_.channel_args, channelz_node_,
1434
+ connecting_result_.max_concurrent_streams);
2222
1435
  } else {
2223
1436
  OrphanablePtr<ClientTransport> transport(
2224
1437
  std::exchange(connecting_result_.transport, nullptr)
@@ -2257,8 +1470,8 @@ bool NewSubchannel::PublishTransportLocked() {
2257
1470
  return false;
2258
1471
  }
2259
1472
  connected_subchannel = MakeRefCounted<NewConnectedSubchannel>(
2260
- WeakRef().TakeAsSubclass<NewSubchannel>(), std::move(*call_destination),
2261
- std::move(transport_destination), args_,
1473
+ WeakRef().TakeAsSubclass<Subchannel>(), std::move(*call_destination),
1474
+ std::move(transport_destination), connecting_result_.channel_args,
2262
1475
  connecting_result_.max_concurrent_streams);
2263
1476
  }
2264
1477
  connecting_result_.Reset();
@@ -2275,6 +1488,19 @@ bool NewSubchannel::PublishTransportLocked() {
2275
1488
  socket_node->AddParent(channelz_node_.get());
2276
1489
  }
2277
1490
  }
1491
+ // Record successful connection attempt
1492
+ if (attempts_storage_ != nullptr) {
1493
+ attempts_storage_->Increment(
1494
+ SubchannelMetricsDomainAttempts::kConnectionAttemptsSucceeded);
1495
+ }
1496
+ if (stats_plugin_group_ != nullptr) {
1497
+ auto scope = stats_plugin_group_->GetCollectionScope();
1498
+ SubchannelConnectionsDomainOpenConnections::GetStorage(
1499
+ scope, target_, connected_subchannel->security_level(),
1500
+ backend_service_, locality_)
1501
+ ->Increment(
1502
+ SubchannelConnectionsDomainOpenConnections::kOpenConnections);
1503
+ }
2278
1504
  transport->StartWatch(
2279
1505
  MakeRefCounted<ConnectionStateWatcher>(connected_subchannel->WeakRef()));
2280
1506
  connections_.push_back(std::move(connected_subchannel));
@@ -2283,7 +1509,7 @@ bool NewSubchannel::PublishTransportLocked() {
2283
1509
  return true;
2284
1510
  }
2285
1511
 
2286
- RefCountedPtr<Subchannel::Call> NewSubchannel::CreateCall(
1512
+ RefCountedPtr<Subchannel::Call> Subchannel::CreateCall(
2287
1513
  CreateCallArgs args, grpc_error_handle* error) {
2288
1514
  RefCountedPtr<ConnectedSubchannel> connected_subchannel;
2289
1515
  {
@@ -2300,7 +1526,7 @@ RefCountedPtr<Subchannel::Call> NewSubchannel::CreateCall(
2300
1526
  if (connected_subchannel == nullptr) {
2301
1527
  // The QueuedCall object adds itself to queued_calls_.
2302
1528
  auto queued_call = RefCountedPtr<QueuedCall>(args.arena->New<QueuedCall>(
2303
- WeakRef().TakeAsSubclass<NewSubchannel>(), args));
1529
+ WeakRef().TakeAsSubclass<Subchannel>(), args));
2304
1530
  MaybeFailAllQueuedRpcsLocked();
2305
1531
  return queued_call;
2306
1532
  }
@@ -2312,7 +1538,7 @@ RefCountedPtr<Subchannel::Call> NewSubchannel::CreateCall(
2312
1538
  return connected_subchannel->CreateCall(args, error);
2313
1539
  }
2314
1540
 
2315
- RefCountedPtr<UnstartedCallDestination> NewSubchannel::call_destination() {
1541
+ RefCountedPtr<UnstartedCallDestination> Subchannel::call_destination() {
2316
1542
  // TODO(roth): Implement connection scaling for v3.
2317
1543
  RefCountedPtr<ConnectedSubchannel> connected_subchannel;
2318
1544
  {
@@ -2331,8 +1557,8 @@ void TestOnlySetSubchannelAlwaysSendCallsToTransport(bool enabled) {
2331
1557
  g_test_only_always_send_calls_to_transport = enabled;
2332
1558
  }
2333
1559
 
2334
- RefCountedPtr<NewSubchannel::ConnectedSubchannel>
2335
- NewSubchannel::ChooseConnectionLocked() {
1560
+ RefCountedPtr<Subchannel::ConnectedSubchannel>
1561
+ Subchannel::ChooseConnectionLocked() {
2336
1562
  // Try to find a connection with quota available for the RPC.
2337
1563
  for (auto& connection : connections_) {
2338
1564
  if (connection->GetQuotaForRpc()) return connection;
@@ -2355,13 +1581,13 @@ NewSubchannel::ChooseConnectionLocked() {
2355
1581
  return nullptr;
2356
1582
  }
2357
1583
 
2358
- void NewSubchannel::RetryQueuedRpcs() {
1584
+ void Subchannel::RetryQueuedRpcs() {
2359
1585
  MutexLock lock(&mu_);
2360
1586
  if (shutdown_) return;
2361
1587
  RetryQueuedRpcsLocked();
2362
1588
  }
2363
1589
 
2364
- void NewSubchannel::RetryQueuedRpcsLocked() {
1590
+ void Subchannel::RetryQueuedRpcsLocked() {
2365
1591
  GRPC_TRACE_LOG(subchannel_call, INFO)
2366
1592
  << "subchannel " << this << " " << key_.ToString()
2367
1593
  << ": retrying RPCs from queue, queue size=" << queued_calls_.size();
@@ -2389,7 +1615,7 @@ void NewSubchannel::RetryQueuedRpcsLocked() {
2389
1615
  }
2390
1616
  }
2391
1617
 
2392
- void NewSubchannel::MaybeFailAllQueuedRpcsLocked() {
1618
+ void Subchannel::MaybeFailAllQueuedRpcsLocked() {
2393
1619
  bool fail_instead_of_queuing =
2394
1620
  args_.GetInt(GRPC_ARG_MAX_CONCURRENT_STREAMS_REJECT_ON_CLIENT)
2395
1621
  .value_or(false);
@@ -2401,7 +1627,7 @@ void NewSubchannel::MaybeFailAllQueuedRpcsLocked() {
2401
1627
  }
2402
1628
  }
2403
1629
 
2404
- void NewSubchannel::FailAllQueuedRpcsLocked(absl::Status status) {
1630
+ void Subchannel::FailAllQueuedRpcsLocked(absl::Status status) {
2405
1631
  GRPC_TRACE_LOG(subchannel_call, INFO)
2406
1632
  << "subchannel " << this << ": failing all queued RPCs: " << status;
2407
1633
  status = PrependAddressToStatusMessage(key_, status);
@@ -2411,12 +1637,11 @@ void NewSubchannel::FailAllQueuedRpcsLocked(absl::Status status) {
2411
1637
  queued_calls_.clear();
2412
1638
  }
2413
1639
 
2414
- void NewSubchannel::Ping(absl::AnyInvocable<void(absl::Status)>) {
1640
+ void Subchannel::Ping(absl::AnyInvocable<void(absl::Status)>) {
2415
1641
  // TODO(ctiller): Implement
2416
1642
  }
2417
1643
 
2418
- absl::Status NewSubchannel::Ping(grpc_closure* on_initiate,
2419
- grpc_closure* on_ack) {
1644
+ absl::Status Subchannel::Ping(grpc_closure* on_initiate, grpc_closure* on_ack) {
2420
1645
  RefCountedPtr<ConnectedSubchannel> connected_subchannel;
2421
1646
  {
2422
1647
  MutexLock lock(&mu_);
@@ -2429,4 +1654,31 @@ absl::Status NewSubchannel::Ping(grpc_closure* on_initiate,
2429
1654
  return absl::OkStatus();
2430
1655
  }
2431
1656
 
1657
+ ChannelArgs Subchannel::MakeSubchannelArgs(
1658
+ const ChannelArgs& channel_args, const ChannelArgs& address_args,
1659
+ const RefCountedPtr<SubchannelPoolInterface>& subchannel_pool,
1660
+ const std::string& channel_default_authority) {
1661
+ // Note that we start with the channel-level args and then apply the
1662
+ // per-address args, so that if a value is present in both, the one
1663
+ // in the channel-level args is used. This is particularly important
1664
+ // for the GRPC_ARG_DEFAULT_AUTHORITY arg, which we want to allow
1665
+ // resolvers to set on a per-address basis only if the application
1666
+ // did not explicitly set it at the channel level.
1667
+ return channel_args.UnionWith(address_args)
1668
+ .SetObject(subchannel_pool)
1669
+ // If we haven't already set the default authority arg (i.e., it
1670
+ // was not explicitly set by the application nor overridden by
1671
+ // the resolver), add it from the channel's default.
1672
+ .SetIfUnset(GRPC_ARG_DEFAULT_AUTHORITY, channel_default_authority)
1673
+ // Remove channel args that should not affect subchannel
1674
+ // uniqueness.
1675
+ .Remove(GRPC_ARG_HEALTH_CHECK_SERVICE_NAME)
1676
+ .Remove(GRPC_ARG_INHIBIT_HEALTH_CHECKING)
1677
+ .Remove(GRPC_ARG_MAX_CONNECTIONS_PER_SUBCHANNEL)
1678
+ .Remove(GRPC_ARG_MAX_CONNECTIONS_PER_SUBCHANNEL_CAP)
1679
+ .Remove(GRPC_ARG_CHANNELZ_CHANNEL_NODE)
1680
+ // Remove all keys with the no-subchannel prefix.
1681
+ .RemoveAllKeysWithPrefix(GRPC_ARG_NO_SUBCHANNEL_PREFIX);
1682
+ }
1683
+
2432
1684
  } // namespace grpc_core