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
@@ -16,12 +16,13 @@
16
16
  //
17
17
  //
18
18
 
19
+ #include "src/core/server/xds_server_config_fetcher.h"
20
+
19
21
  #include <grpc/credentials.h>
20
22
  #include <grpc/grpc.h>
21
23
  #include <grpc/grpc_security.h>
22
24
  #include <grpc/slice.h>
23
25
  #include <grpc/status.h>
24
- #include <grpc/support/port_platform.h>
25
26
  #include <string.h>
26
27
 
27
28
  #include <algorithm>
@@ -67,6 +68,7 @@
67
68
  #include "src/core/util/sync.h"
68
69
  #include "src/core/util/unique_type_name.h"
69
70
  #include "src/core/util/uri.h"
71
+ #include "src/core/xds/grpc/blackboard.h"
70
72
  #include "src/core/xds/grpc/certificate_provider_store.h"
71
73
  #include "src/core/xds/grpc/xds_bootstrap_grpc.h"
72
74
  #include "src/core/xds/grpc/xds_certificate_provider.h"
@@ -101,10 +103,14 @@ using ReadDelayHandle = XdsClient::ReadDelayHandle;
101
103
  // annotations and save a bit of memory.
102
104
  struct FetcherState final : public RefCounted<FetcherState> {
103
105
  RefCountedPtr<GrpcXdsClient> xds_client;
106
+ RefCountedPtr<XdsResourceNameGenerator> resource_name_generator;
104
107
  WorkSerializer work_serializer;
105
108
 
106
- explicit FetcherState(RefCountedPtr<GrpcXdsClient> xds_client_in)
109
+ FetcherState(
110
+ RefCountedPtr<GrpcXdsClient> xds_client_in,
111
+ RefCountedPtr<XdsResourceNameGenerator> resource_name_generator_in)
107
112
  : xds_client(std::move(xds_client_in)),
113
+ resource_name_generator(std::move(resource_name_generator_in)),
108
114
  work_serializer(
109
115
  grpc_event_engine::experimental::GetDefaultEventEngine()) {
110
116
  GRPC_CHECK(xds_client != nullptr);
@@ -119,8 +125,10 @@ struct FetcherState final : public RefCounted<FetcherState> {
119
125
  // listeners from the xDS control plane.
120
126
  class XdsServerConfigFetcher final : public ServerConfigFetcher {
121
127
  public:
122
- XdsServerConfigFetcher(RefCountedPtr<GrpcXdsClient> xds_client,
123
- grpc_server_xds_status_notifier notifier);
128
+ XdsServerConfigFetcher(
129
+ RefCountedPtr<GrpcXdsClient> xds_client,
130
+ grpc_server_xds_status_notifier notifier,
131
+ RefCountedPtr<XdsResourceNameGenerator> resource_name_generator);
124
132
 
125
133
  ~XdsServerConfigFetcher() override {
126
134
  fetcher_state_.reset(DEBUG_LOCATION, "XdsServerConfigFetcher");
@@ -179,6 +187,8 @@ class XdsServerConfigFetcher::ListenerWatcher final
179
187
 
180
188
  const std::string& listening_address() const { return listening_address_; }
181
189
 
190
+ std::string ResourceName() const;
191
+
182
192
  private:
183
193
  class XdsConnectionManager;
184
194
 
@@ -202,6 +212,9 @@ class XdsServerConfigFetcher::ListenerWatcher final
202
212
  ABSL_GUARDED_BY(&FetcherState::work_serializer);
203
213
  RefCountedPtr<XdsConnectionManager> pending_connection_manager_
204
214
  ABSL_GUARDED_BY(&FetcherState::work_serializer);
215
+
216
+ RefCountedPtr<Blackboard> blackboard_
217
+ ABSL_GUARDED_BY(&FetcherState::work_serializer);
205
218
  };
206
219
 
207
220
  // A connection manager used by the server listener code to inject channel args
@@ -262,6 +275,9 @@ class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager final
262
275
  // ready.
263
276
  RefCountedPtr<ListenerWatcher> listener_watcher_
264
277
  ABSL_GUARDED_BY(&FetcherState::work_serializer);
278
+
279
+ RefCountedPtr<Blackboard> blackboard_
280
+ ABSL_GUARDED_BY(&FetcherState::work_serializer);
265
281
  };
266
282
 
267
283
  class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
@@ -328,6 +344,30 @@ class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
328
344
  ABSL_GUARDED_BY(&FetcherState::work_serializer);
329
345
  };
330
346
 
347
+ using FilterInstance =
348
+ std::pair<const XdsHttpFilterFactory*, RefCountedPtr<const FilterConfig>>;
349
+
350
+ struct FilterList final : public FilterChain {
351
+ std::vector<FilterInstance> filters;
352
+ };
353
+
354
+ class FilterListBuilder final
355
+ : public XdsRouting::RouteConfigFilterChainBuilder::XdsFilterChainBuilder {
356
+ public:
357
+ void AddFilter(const XdsHttpFilterFactory* factory,
358
+ RefCountedPtr<const FilterConfig> config) override {
359
+ if (filters_ == nullptr) filters_ = MakeRefCounted<FilterList>();
360
+ filters_->filters.emplace_back(factory, std::move(config));
361
+ }
362
+
363
+ absl::StatusOr<RefCountedPtr<FilterChain>> Build() override {
364
+ if (filters_ == nullptr) return MakeRefCounted<FilterList>();
365
+ return std::move(filters_);
366
+ }
367
+
368
+ RefCountedPtr<FilterList> filters_;
369
+ };
370
+
331
371
  // An implementation of ServerConfigSelector that stores parsed xDS filter
332
372
  // configs for each route, constructs filter chains for each, and
333
373
  // selects the appropriate filter chain for each RPC.
@@ -336,12 +376,17 @@ class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
336
376
  public:
337
377
  static absl::StatusOr<RefCountedPtr<XdsServerConfigSelector>> Create(
338
378
  const XdsHttpFilterRegistry& http_filter_registry,
379
+ XdsTransportFactory& transport_factory,
339
380
  const std::vector<XdsListenerResource::HttpConnectionManager::HttpFilter>&
340
381
  http_filters,
341
- std::shared_ptr<const XdsRouteConfigResource> route_config);
382
+ std::shared_ptr<const XdsRouteConfigResource> route_config,
383
+ Blackboard& blackboard);
384
+
385
+ std::unique_ptr<ConnectionState> BuildFilterChains(
386
+ FilterChainBuilder& builder) override;
342
387
 
343
388
  absl::StatusOr<CallConfig> GetCallConfig(
344
- grpc_metadata_batch* metadata) override;
389
+ const ConnectionState* state, grpc_metadata_batch* metadata) override;
345
390
 
346
391
  private:
347
392
  struct VirtualHost {
@@ -350,7 +395,8 @@ class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
350
395
  bool unsupported_action;
351
396
  // Points inside of XdsServerConfigSelector::route_config_.
352
397
  const XdsRouteConfigResource::Route::Matchers* matchers;
353
- RefCountedPtr<ServiceConfig> method_config;
398
+ // The list of filter instances and configs to use for this route.
399
+ RefCountedPtr<const FilterList> filter_list;
354
400
  };
355
401
 
356
402
  class RouteListIterator final : public XdsRouting::RouteListIterator {
@@ -392,6 +438,12 @@ class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
392
438
  const std::vector<VirtualHost>& virtual_hosts_;
393
439
  };
394
440
 
441
+ struct XdsConnectionState final : public ConnectionState {
442
+ absl::flat_hash_map<const VirtualHost::Route*,
443
+ absl::StatusOr<RefCountedPtr<const FilterChain>>>
444
+ filter_chains;
445
+ };
446
+
395
447
  std::shared_ptr<const XdsRouteConfigResource> route_config_;
396
448
  std::vector<VirtualHost> virtual_hosts_;
397
449
  };
@@ -402,21 +454,12 @@ class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
402
454
 
403
455
  XdsServerConfigFetcher::XdsServerConfigFetcher(
404
456
  RefCountedPtr<GrpcXdsClient> xds_client,
405
- grpc_server_xds_status_notifier notifier)
406
- : fetcher_state_(MakeRefCounted<FetcherState>(std::move(xds_client))),
457
+ grpc_server_xds_status_notifier notifier,
458
+ RefCountedPtr<XdsResourceNameGenerator> resource_name_generator)
459
+ : fetcher_state_(MakeRefCounted<FetcherState>(
460
+ std::move(xds_client), std::move(resource_name_generator))),
407
461
  serving_status_notifier_(notifier) {}
408
462
 
409
- std::string ListenerResourceName(absl::string_view resource_name_template,
410
- absl::string_view listening_address) {
411
- std::string tmp;
412
- if (absl::StartsWith(resource_name_template, "xdstp:")) {
413
- tmp = URI::PercentEncodePath(listening_address);
414
- listening_address = tmp;
415
- }
416
- return absl::StrReplaceAll(resource_name_template,
417
- {{"%s", listening_address}});
418
- }
419
-
420
463
  void XdsServerConfigFetcher::StartWatch(
421
464
  std::string listening_address,
422
465
  std::unique_ptr<ServerConfigFetcher::WatcherInterface> watcher) {
@@ -426,20 +469,16 @@ void XdsServerConfigFetcher::StartWatch(
426
469
  watcher = std::move(watcher)]()
427
470
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(
428
471
  &FetcherState::work_serializer) mutable {
429
- std::string resource_name = ListenerResourceName(
430
- DownCast<const GrpcXdsBootstrap&>(
431
- self->fetcher_state_->xds_client->bootstrap())
432
- .server_listener_resource_name_template(),
433
- listening_address);
434
- GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
435
- << "[XdsServerConfigFetcher " << self.get()
436
- << "]: starting watch for LDS resource " << resource_name;
437
472
  ServerConfigFetcher::WatcherInterface* watcher_ptr = watcher.get();
438
473
  auto listener_watcher = MakeRefCounted<ListenerWatcher>(
439
474
  self->fetcher_state_.Ref(DEBUG_LOCATION, "ListenerWatcher"),
440
475
  std::move(watcher), self->serving_status_notifier_,
441
476
  listening_address);
442
477
  auto* listener_watcher_ptr = listener_watcher.get();
478
+ std::string resource_name = listener_watcher->ResourceName();
479
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
480
+ << "[XdsServerConfigFetcher " << self.get()
481
+ << "]: starting watch for LDS resource " << resource_name;
443
482
  XdsListenerResourceType::StartWatch(
444
483
  self->fetcher_state_->xds_client.get(), resource_name,
445
484
  std::move(listener_watcher));
@@ -454,18 +493,13 @@ void XdsServerConfigFetcher::CancelWatch(
454
493
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer) {
455
494
  auto it = self->listener_watchers_.find(watcher);
456
495
  if (it == self->listener_watchers_.end()) return;
457
- std::string resource_name = ListenerResourceName(
458
- DownCast<const GrpcXdsBootstrap&>(
459
- self->fetcher_state_->xds_client->bootstrap())
460
- .server_listener_resource_name_template(),
461
- it->second->listening_address());
496
+ std::string resource_name = it->second->ResourceName();
462
497
  GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
463
498
  << "[XdsServerConfigFetcher " << self.get()
464
499
  << "]: cancelling watch for LDS resource " << resource_name;
465
500
  XdsListenerResourceType::CancelWatch(
466
501
  self->fetcher_state_->xds_client.get(), resource_name,
467
- it->second,
468
- /*delay_unsubscription=*/false);
502
+ it->second, /*delay_unsubscription=*/false);
469
503
  self->listener_watchers_.erase(it);
470
504
  });
471
505
  }
@@ -483,12 +517,32 @@ XdsServerConfigFetcher::ListenerWatcher::ListenerWatcher(
483
517
  : fetcher_state_(std::move(fetcher_state)),
484
518
  server_config_watcher_(std::move(server_config_watcher)),
485
519
  serving_status_notifier_(serving_status_notifier),
486
- listening_address_(std::move(listening_address)) {
520
+ listening_address_(std::move(listening_address)),
521
+ blackboard_(MakeRefCounted<Blackboard>()) {
487
522
  GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
488
523
  << "[ListenerWatcher " << this << "]: created for address "
489
524
  << listening_address_;
490
525
  }
491
526
 
527
+ // Returns true if the listener address matches the address that the
528
+ // server is actually listening on.
529
+ bool ListenerAddressMatches(absl::string_view listener_address,
530
+ absl::string_view server_address) {
531
+ if (listener_address == server_address) return true;
532
+ absl::string_view listener_host;
533
+ absl::string_view listener_port;
534
+ if (!SplitHostPort(listener_address, &listener_host, &listener_port)) {
535
+ return false;
536
+ }
537
+ absl::string_view server_host;
538
+ absl::string_view server_port;
539
+ if (!SplitHostPort(server_address, &server_host, &server_port)) {
540
+ return false;
541
+ }
542
+ if (listener_host != server_host) return false;
543
+ return listener_port == "0" || listener_port == server_port;
544
+ }
545
+
492
546
  void XdsServerConfigFetcher::ListenerWatcher::OnResourceChanged(
493
547
  absl::StatusOr<std::shared_ptr<const XdsListenerResource>> listener,
494
548
  RefCountedPtr<ReadDelayHandle> read_delay_handle) {
@@ -498,9 +552,9 @@ void XdsServerConfigFetcher::ListenerWatcher::OnResourceChanged(
498
552
  ABSL_EXCLUSIVE_LOCKS_REQUIRED(
499
553
  &FetcherState::work_serializer) mutable {
500
554
  if (!listener.ok()) {
501
- self->OnFatalError(absl::Status(
502
- listener.status().code(),
503
- absl::StrCat("LDS resource: ", listener.status().message())));
555
+ self->OnFatalError(AddMessagePrefix(
556
+ absl::StrCat("LDS resource ", self->ResourceName()),
557
+ listener.status()));
504
558
  return;
505
559
  }
506
560
  GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
@@ -512,12 +566,15 @@ void XdsServerConfigFetcher::ListenerWatcher::OnResourceChanged(
512
566
  &(*listener)->listener);
513
567
  if (tcp_listener == nullptr) {
514
568
  self->OnFatalError(absl::FailedPreconditionError(
515
- "LDS resource is not a TCP listener"));
569
+ absl::StrCat("LDS resource ", self->ResourceName(),
570
+ " is not a TCP listener")));
516
571
  return;
517
572
  }
518
- if (tcp_listener->address != self->listening_address_) {
573
+ if (!ListenerAddressMatches(tcp_listener->address,
574
+ self->listening_address_)) {
519
575
  self->OnFatalError(absl::FailedPreconditionError(
520
- "Address in LDS update does not match listening address"));
576
+ absl::StrCat("LDS resource ", self->ResourceName(),
577
+ " address does not match listening address")));
521
578
  return;
522
579
  }
523
580
  if (self->connection_manager_ != nullptr &&
@@ -593,6 +650,24 @@ void XdsServerConfigFetcher::ListenerWatcher::MaybeUpdateConnectionManager(
593
650
  }
594
651
  }
595
652
 
653
+ std::string XdsServerConfigFetcher::ListenerWatcher::ResourceName() const {
654
+ if (fetcher_state_->resource_name_generator != nullptr) {
655
+ return fetcher_state_->resource_name_generator->GetResourceName(
656
+ listening_address_);
657
+ }
658
+ absl::string_view resource_name_template =
659
+ DownCast<const GrpcXdsBootstrap&>(fetcher_state_->xds_client->bootstrap())
660
+ .server_listener_resource_name_template();
661
+ absl::string_view listening_address = listening_address_;
662
+ std::string tmp;
663
+ if (absl::StartsWith(resource_name_template, "xdstp:")) {
664
+ tmp = URI::PercentEncodePath(listening_address);
665
+ listening_address = tmp;
666
+ }
667
+ return absl::StrReplaceAll(resource_name_template,
668
+ {{"%s", listening_address}});
669
+ }
670
+
596
671
  //
597
672
  // XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager
598
673
  //
@@ -604,7 +679,8 @@ XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
604
679
  RefCountedPtr<ListenerWatcher> listener_watcher)
605
680
  : fetcher_state_(std::move(fetcher_state)),
606
681
  listener_resource_(std::move(listener_resource)),
607
- listener_watcher_(std::move(listener_watcher)) {
682
+ listener_watcher_(std::move(listener_watcher)),
683
+ blackboard_(listener_watcher_->blackboard_) {
608
684
  GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
609
685
  << "[XdsConnectionManager " << this << "]: created";
610
686
  }
@@ -1087,43 +1163,12 @@ absl::StatusOr<ChannelArgs> XdsServerConfigFetcher::ListenerWatcher::
1087
1163
  XdsConnectionManager::L4FilterChain::UpdateChannelArgsForConnection(
1088
1164
  const ChannelArgs& args) const {
1089
1165
  if (!certificate_provider_.ok()) return certificate_provider_.status();
1090
- ChannelArgs new_args = args.SetObject(*certificate_provider_);
1091
- // Add channel stack modifier to insert HTTP filters.
1092
- // TODO(roth): Instead of using a channel stack modifier, register the
1093
- // ServerConfigSelectorInterceptor whenever there is a
1094
- // ServerConfigSelectorProvider in channel args, and have that
1095
- // interceptor inject the necessary HTTP filters.
1096
- std::vector<const grpc_channel_filter*> filters;
1097
- const auto& http_filter_registry =
1098
- DownCast<const GrpcXdsBootstrap&>(fetcher_state_->xds_client->bootstrap())
1099
- .http_filter_registry();
1100
- for (const auto& http_filter :
1101
- filter_chain_data_.http_connection_manager.http_filters) {
1102
- // Find filter. This is guaranteed to succeed, because it's checked
1103
- // at config validation time in the XdsApi code.
1104
- const XdsHttpFilterImpl* filter_impl =
1105
- http_filter_registry.GetFilterForTopLevelType(
1106
- http_filter.config_proto_type);
1107
- GRPC_CHECK_NE(filter_impl, nullptr);
1108
- // Some filters like the router filter are no-op filters and do not have
1109
- // an implementation.
1110
- if (filter_impl->channel_filter() != nullptr) {
1111
- filters.push_back(filter_impl->channel_filter());
1112
- }
1113
- }
1114
- // Reverse the order, since filters flow *up* the stack on the server side.
1115
- std::reverse(filters.begin(), filters.end());
1116
- // Add config selector filter.
1117
- filters.push_back(&kServerConfigSelectorFilter);
1118
- new_args = new_args.SetObject(
1119
- MakeRefCounted<XdsChannelStackModifier>(std::move(filters)));
1120
- // TODO(roth): Don't add ConfigSelectorProvider if there are no filters.
1121
- new_args = new_args.SetObject(
1122
- // This is the only place where the provider is accessed from outside
1123
- // of the WorkSerializer, and it will always be set before this
1124
- // happens, so this read is safe even though the compiler can't tell.
1125
- ABSL_TS_UNCHECKED_READ(config_selector_provider_));
1126
- return new_args;
1166
+ return args.SetObject(*certificate_provider_)
1167
+ .SetObject(
1168
+ // This is the only place where the provider is accessed from outside
1169
+ // of the WorkSerializer, and it will always be set before this
1170
+ // happens, so this read is safe even though the compiler can't tell.
1171
+ ABSL_TS_UNCHECKED_READ(config_selector_provider_));
1127
1172
  }
1128
1173
 
1129
1174
  absl::StatusOr<RefCountedPtr<ServerConfigSelector>>
@@ -1135,8 +1180,9 @@ XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::
1135
1180
  return XdsServerConfigSelector::Create(
1136
1181
  DownCast<const GrpcXdsBootstrap&>(fetcher_state_->xds_client->bootstrap())
1137
1182
  .http_filter_registry(),
1183
+ *fetcher_state_->xds_client->transport_factory(),
1138
1184
  filter_chain_data_.http_connection_manager.http_filters,
1139
- std::move(*route_config));
1185
+ std::move(*route_config), *connection_manager_->blackboard_);
1140
1186
  }
1141
1187
 
1142
1188
  void XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
@@ -1166,6 +1212,7 @@ void XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
1166
1212
  route_config) {
1167
1213
  GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
1168
1214
  << "[L4FilterChain " << this << "]: received RDS update";
1215
+ if (connection_manager_ == nullptr) return;
1169
1216
  if (!route_config.ok()) {
1170
1217
  auto& hcm = filter_chain_data_.http_connection_manager;
1171
1218
  auto& rds_resource_name = std::get<std::string>(hcm.route_config);
@@ -1195,60 +1242,71 @@ absl::StatusOr<RefCountedPtr<
1195
1242
  XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::
1196
1243
  XdsServerConfigSelector::Create(
1197
1244
  const XdsHttpFilterRegistry& http_filter_registry,
1245
+ XdsTransportFactory& transport_factory,
1198
1246
  const std::vector<
1199
1247
  XdsListenerResource::HttpConnectionManager::HttpFilter>&
1200
1248
  http_filters,
1201
- std::shared_ptr<const XdsRouteConfigResource> route_config) {
1202
- // TODO(roth): For each route, construct merged filter configs and
1203
- // update blackboard. Also add support for building filter chains for
1204
- // each connection. And make sure to reverse the order of the filters
1205
- // when we construct the filter chain.
1249
+ std::shared_ptr<const XdsRouteConfigResource> route_config,
1250
+ Blackboard& blackboard) {
1206
1251
  auto config_selector = MakeRefCounted<XdsServerConfigSelector>();
1252
+ FilterListBuilder filter_list_builder;
1253
+ XdsRouting::RouteConfigFilterChainBuilder route_config_builder(
1254
+ http_filters, http_filter_registry, filter_list_builder,
1255
+ transport_factory, blackboard);
1207
1256
  for (auto& vhost : route_config->virtual_hosts) {
1208
- config_selector->virtual_hosts_.emplace_back();
1209
- auto& virtual_host = config_selector->virtual_hosts_.back();
1257
+ auto vhost_builder =
1258
+ route_config_builder.MakeVirtualHostFilterChainBuilder(vhost);
1259
+ auto& virtual_host = config_selector->virtual_hosts_.emplace_back();
1210
1260
  virtual_host.domains = &vhost.domains;
1211
1261
  for (auto& route : vhost.routes) {
1212
- virtual_host.routes.emplace_back();
1213
- auto& config_selector_route = virtual_host.routes.back();
1262
+ auto& config_selector_route = virtual_host.routes.emplace_back();
1214
1263
  config_selector_route.matchers = &route.matchers;
1215
1264
  config_selector_route.unsupported_action =
1216
1265
  std::get_if<XdsRouteConfigResource::Route::NonForwardingAction>(
1217
1266
  &route.action) == nullptr;
1218
- auto result = XdsRouting::GeneratePerHTTPFilterConfigsForMethodConfig(
1219
- http_filter_registry, http_filters, vhost, route, nullptr,
1220
- ChannelArgs());
1221
- if (!result.ok()) return result.status();
1222
- std::vector<std::string> fields;
1223
- fields.reserve(result->per_filter_configs.size());
1224
- for (const auto& p : result->per_filter_configs) {
1225
- fields.emplace_back(absl::StrCat(" \"", p.first, "\": [\n",
1226
- absl::StrJoin(p.second, ",\n"),
1227
- "\n ]"));
1228
- }
1229
- if (!fields.empty()) {
1230
- std::string json = absl::StrCat(
1231
- "{\n"
1232
- " \"methodConfig\": [ {\n"
1233
- " \"name\": [\n"
1234
- " {}\n"
1235
- " ],\n"
1236
- " ",
1237
- absl::StrJoin(fields, ",\n"),
1238
- "\n } ]\n"
1239
- "}");
1240
- config_selector_route.method_config =
1241
- ServiceConfigImpl::Create(result->args, json.c_str()).value();
1242
- }
1267
+ auto filter_list = vhost_builder.BuildFilterChainForRoute(route);
1268
+ if (!filter_list.ok()) return filter_list.status();
1269
+ config_selector_route.filter_list =
1270
+ filter_list->TakeAsSubclass<const FilterList>();
1243
1271
  }
1244
1272
  }
1245
1273
  config_selector->route_config_ = std::move(route_config);
1246
1274
  return config_selector;
1247
1275
  }
1248
1276
 
1277
+ std::unique_ptr<ServerConfigSelector::ConnectionState>
1278
+ XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::
1279
+ XdsServerConfigSelector::BuildFilterChains(FilterChainBuilder& builder) {
1280
+ auto connection_state = std::make_unique<XdsConnectionState>();
1281
+ // It's likely that multiple routes have the same filter list, so we
1282
+ // reuse filter chains if possible.
1283
+ absl::flat_hash_map<const FilterList*,
1284
+ absl::StatusOr<RefCountedPtr<const FilterChain>>>
1285
+ cache;
1286
+ for (const auto& vhost : virtual_hosts_) {
1287
+ for (const auto& route : vhost.routes) {
1288
+ absl::StatusOr<RefCountedPtr<const FilterChain>> filter_chain;
1289
+ auto it = cache.find(route.filter_list.get());
1290
+ if (it == cache.end()) {
1291
+ // Not found in cache, so construct a new filter chain.
1292
+ for (const auto& [factory, config] : route.filter_list->filters) {
1293
+ factory->AddFilter(builder, config);
1294
+ }
1295
+ filter_chain = builder.Build();
1296
+ cache.emplace(route.filter_list.get(), filter_chain);
1297
+ } else {
1298
+ filter_chain = it->second;
1299
+ }
1300
+ connection_state->filter_chains.emplace(&route, std::move(filter_chain));
1301
+ }
1302
+ }
1303
+ return connection_state;
1304
+ }
1305
+
1249
1306
  absl::StatusOr<ServerConfigSelector::CallConfig>
1250
1307
  XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::
1251
- XdsServerConfigSelector::GetCallConfig(grpc_metadata_batch* metadata) {
1308
+ XdsServerConfigSelector::GetCallConfig(const ConnectionState* state,
1309
+ grpc_metadata_batch* metadata) {
1252
1310
  CallConfig call_config;
1253
1311
  if (metadata->get_pointer(HttpPathMetadata()) == nullptr) {
1254
1312
  return absl::InternalError("no path found");
@@ -1278,12 +1336,17 @@ XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::
1278
1336
  if (route.unsupported_action) {
1279
1337
  return absl::UnavailableError("matching route has unsupported action");
1280
1338
  }
1281
- if (route.method_config != nullptr) {
1282
- call_config.method_configs =
1283
- route.method_config->GetMethodParsedConfigVector(grpc_empty_slice());
1284
- call_config.service_config = route.method_config;
1339
+ // Find filter chain.
1340
+ const auto& filter_chains =
1341
+ DownCast<const XdsConnectionState*>(state)->filter_chains;
1342
+ auto it = filter_chains.find(&route);
1343
+ if (it == filter_chains.end()) {
1344
+ // Should never happen.
1345
+ call_config.filter_chain =
1346
+ absl::InternalError("no filter chain found for route");
1347
+ } else {
1348
+ call_config.filter_chain = it->second;
1285
1349
  }
1286
- // TODO(roth): Return the filter chain to use for this call.
1287
1350
  return call_config;
1288
1351
  }
1289
1352
 
@@ -1314,15 +1377,19 @@ grpc_server_config_fetcher* grpc_server_config_fetcher_xds_create(
1314
1377
  LOG(ERROR) << "Failed to create xds client: " << xds_client.status();
1315
1378
  return nullptr;
1316
1379
  }
1317
- if (grpc_core::DownCast<const grpc_core::GrpcXdsBootstrap&>(
1318
- (*xds_client)->bootstrap())
1319
- .server_listener_resource_name_template()
1320
- .empty()) {
1321
- LOG(ERROR) << "server_listener_resource_name_template not provided in "
1322
- "bootstrap file.";
1323
- return nullptr;
1380
+ auto generator =
1381
+ channel_args.GetObjectRef<grpc_core::XdsResourceNameGenerator>();
1382
+ if (generator == nullptr) {
1383
+ if (grpc_core::DownCast<const grpc_core::GrpcXdsBootstrap&>(
1384
+ (*xds_client)->bootstrap())
1385
+ .server_listener_resource_name_template()
1386
+ .empty()) {
1387
+ LOG(ERROR) << "server_listener_resource_name_template not provided in "
1388
+ "bootstrap file.";
1389
+ return nullptr;
1390
+ }
1324
1391
  }
1325
1392
  return (new grpc_core::XdsServerConfigFetcher(std::move(*xds_client),
1326
- notifier))
1393
+ notifier, std::move(generator)))
1327
1394
  ->c_ptr();
1328
1395
  }
@@ -0,0 +1,49 @@
1
+ //
2
+ //
3
+ // Copyright 2026 gRPC authors.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ //
18
+
19
+ #ifndef GRPC_SRC_CORE_SERVER_XDS_SERVER_CONFIG_FETCHER_H
20
+ #define GRPC_SRC_CORE_SERVER_XDS_SERVER_CONFIG_FETCHER_H
21
+
22
+ #include <string>
23
+
24
+ #include "src/core/util/ref_counted.h"
25
+ #include "src/core/util/useful.h"
26
+ #include "absl/strings/string_view.h"
27
+
28
+ namespace grpc_core {
29
+
30
+ // Generates the LDS resource name to watch for a given listening address.
31
+ // An implementation can be supplied via a channel arg to override the default
32
+ // behavior of formatting the resource name from the bootstrap's
33
+ // server_listener_resource_name_template.
34
+ class XdsResourceNameGenerator : public RefCounted<XdsResourceNameGenerator> {
35
+ public:
36
+ virtual std::string GetResourceName(absl::string_view listening_address) = 0;
37
+
38
+ static absl::string_view ChannelArgName() {
39
+ return "grpc.xds_resource_name_generator";
40
+ }
41
+ static int ChannelArgsCompare(const XdsResourceNameGenerator* a,
42
+ const XdsResourceNameGenerator* b) {
43
+ return QsortCompare(a, b);
44
+ }
45
+ };
46
+
47
+ } // namespace grpc_core
48
+
49
+ #endif // GRPC_SRC_CORE_SERVER_XDS_SERVER_CONFIG_FETCHER_H