grpc 1.82.0 → 1.83.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +8 -5
  3. data/etc/roots.pem +10400 -3855
  4. data/include/grpc/grpc_audit_logging.h +2 -2
  5. data/include/grpc/grpc_security_constants.h +2 -0
  6. data/include/grpc/impl/channel_arg_names.h +23 -0
  7. data/src/core/call/call_filters.h +19 -3
  8. data/src/core/call/call_spine.h +4 -4
  9. data/src/core/call/client_call.cc +1 -1
  10. data/src/core/call/metadata.cc +7 -2
  11. data/src/core/call/server_call.cc +13 -3
  12. data/src/core/call/server_call.h +5 -3
  13. data/src/core/client_channel/backup_poller.cc +2 -17
  14. data/src/core/client_channel/client_channel.cc +17 -14
  15. data/src/core/client_channel/client_channel.h +3 -1
  16. data/src/core/client_channel/client_channel_filter.cc +11 -13
  17. data/src/core/client_channel/client_channel_service_config.cc +5 -13
  18. data/src/core/client_channel/direct_channel.cc +5 -1
  19. data/src/core/client_channel/direct_channel.h +3 -1
  20. data/src/core/config/experiment_env_var.cc +30 -0
  21. data/src/core/config/experiment_env_var.h +26 -0
  22. data/src/core/credentials/call/regional_access_boundary_fetcher.cc +6 -6
  23. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +14 -2
  24. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.cc +172 -0
  25. data/src/core/credentials/transport/tls/grpc_tls_certificate_selector.h +103 -0
  26. data/src/core/credentials/transport/tls/load_system_roots_fallback.cc +3 -2
  27. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +10 -3
  28. data/src/core/credentials/transport/tls/tls_security_connector.cc +14 -2
  29. data/src/core/credentials/transport/xds/xds_credentials.cc +4 -12
  30. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +2 -1
  31. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +19 -13
  32. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +11 -9
  33. data/src/core/ext/transport/chttp2/transport/flow_control.cc +2 -2
  34. data/src/core/ext/transport/chttp2/transport/flow_control.h +3 -2
  35. data/src/core/ext/transport/chttp2/transport/frame.cc +58 -1
  36. data/src/core/ext/transport/chttp2/transport/frame.h +13 -1
  37. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +2 -4
  38. data/src/core/ext/transport/chttp2/transport/frame_security.cc +10 -1
  39. data/src/core/ext/transport/chttp2/transport/frame_security.h +2 -1
  40. data/src/core/ext/transport/chttp2/transport/goaway.cc +11 -1
  41. data/src/core/ext/transport/chttp2/transport/goaway.h +17 -1
  42. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +9 -0
  43. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +117 -276
  44. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +44 -17
  45. data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +382 -496
  46. data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +75 -77
  47. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +1 -1
  48. data/src/core/ext/transport/chttp2/transport/http2_settings.h +30 -11
  49. data/src/core/ext/transport/chttp2/transport/http2_settings_promises.h +24 -9
  50. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +26 -0
  51. data/src/core/ext/transport/chttp2/transport/http2_transport.h +2 -0
  52. data/src/core/ext/transport/chttp2/transport/internal.h +4 -0
  53. data/src/core/ext/transport/chttp2/transport/parsing.cc +3 -2
  54. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +1 -1
  55. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +4 -10
  56. data/src/core/ext/transport/chttp2/transport/read_context.h +62 -20
  57. data/src/core/ext/transport/chttp2/transport/security_frame.h +1 -0
  58. data/src/core/ext/transport/chttp2/transport/stream.h +271 -120
  59. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +77 -61
  60. data/src/core/handshaker/security/secure_endpoint.cc +0 -13
  61. data/src/core/lib/channel/promise_based_filter.cc +77 -3
  62. data/src/core/lib/channel/promise_based_filter.h +238 -184
  63. data/src/core/lib/event_engine/extensions/receive_coalescing_extension.h +0 -4
  64. data/src/core/lib/event_engine/extensions/tcp_trace.h +1 -1
  65. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +2 -12
  66. data/src/core/lib/event_engine/shim.cc +2 -16
  67. data/src/core/lib/event_engine/shim.h +0 -4
  68. data/src/core/lib/experiments/experiments.cc +51 -102
  69. data/src/core/lib/experiments/experiments.h +37 -59
  70. data/src/core/lib/iomgr/error.cc +3 -73
  71. data/src/core/lib/iomgr/error.h +8 -6
  72. data/src/core/lib/iomgr/error_cfstream.cc +1 -2
  73. data/src/core/lib/iomgr/ev_epoll1_linux.cc +2 -6
  74. data/src/core/lib/iomgr/ev_poll_posix.cc +2 -6
  75. data/src/core/lib/iomgr/tcp_posix.cc +2 -6
  76. data/src/core/lib/security/authorization/audit_logging.cc +2 -2
  77. data/src/core/lib/security/authorization/audit_logging.h +3 -3
  78. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +11 -13
  79. data/src/core/lib/security/authorization/grpc_authorization_engine.h +1 -1
  80. data/src/core/lib/security/authorization/matchers.cc +20 -20
  81. data/src/core/lib/security/authorization/matchers.h +15 -16
  82. data/src/core/lib/security/authorization/rbac_policy.h +1 -1
  83. data/src/core/lib/security/authorization/stdout_logger.cc +3 -3
  84. data/src/core/lib/security/authorization/stdout_logger.h +6 -5
  85. data/src/core/lib/surface/call.cc +0 -8
  86. data/src/core/lib/surface/call.h +2 -0
  87. data/src/core/lib/surface/channel.cc +21 -2
  88. data/src/core/lib/surface/channel.h +14 -6
  89. data/src/core/lib/surface/filter_stack_call.cc +10 -29
  90. data/src/core/lib/surface/legacy_channel.cc +7 -7
  91. data/src/core/lib/surface/legacy_channel.h +3 -1
  92. data/src/core/lib/surface/version.cc +2 -2
  93. data/src/core/lib/transport/bdp_estimator.cc +13 -13
  94. data/src/core/lib/transport/bdp_estimator.h +9 -5
  95. data/src/core/lib/transport/error_utils.cc +26 -138
  96. data/src/core/lib/transport/promise_endpoint.h +2 -4
  97. data/src/core/load_balancing/grpclb/grpclb.cc +2 -1
  98. data/src/core/load_balancing/pick_first/pick_first.cc +33 -2
  99. data/src/core/load_balancing/pick_first/pick_first.h +6 -0
  100. data/src/core/load_balancing/ring_hash/ring_hash.cc +3 -10
  101. data/src/core/load_balancing/rls/rls.cc +2 -1
  102. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +2 -7
  103. data/src/core/load_balancing/xds/cds.cc +80 -56
  104. data/src/core/load_balancing/xds/cds.h +21 -0
  105. data/src/core/mitigation_engine/mitigation.h +53 -0
  106. data/src/core/mitigation_engine/mitigation_provider.h +62 -0
  107. data/src/core/resolver/dns/dns_resolver_plugin.cc +1 -6
  108. data/src/core/resolver/xds/xds_resolver.cc +14 -11
  109. data/src/core/server/server.h +1 -4
  110. data/src/core/server/server_config_selector.h +5 -4
  111. data/src/core/server/server_config_selector_filter.cc +67 -80
  112. data/src/core/server/xds_server_config_fetcher.cc +681 -692
  113. data/src/core/server/xds_server_config_fetcher_legacy.cc +15 -12
  114. data/src/core/telemetry/call_tracer.cc +49 -2
  115. data/src/core/telemetry/call_tracer.h +1 -0
  116. data/src/core/telemetry/tcp_tracer.h +38 -0
  117. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  118. data/src/core/tsi/ssl_telemetry_utils.cc +343 -0
  119. data/src/core/tsi/ssl_telemetry_utils.h +74 -0
  120. data/src/core/tsi/ssl_transport_security.cc +577 -301
  121. data/src/core/tsi/ssl_transport_security.h +22 -6
  122. data/src/core/tsi/ssl_transport_security_utils.cc +2 -0
  123. data/src/core/tsi/transport_security.h +7 -0
  124. data/src/core/util/http_client/httpcli.cc +1 -4
  125. data/src/core/util/http_client/httpcli_security_connector.cc +2 -1
  126. data/src/core/util/status_helper.cc +71 -192
  127. data/src/core/util/status_helper.h +16 -21
  128. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +2 -11
  129. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -7
  130. data/src/core/xds/grpc/xds_cluster_parser.cc +5 -16
  131. data/src/core/xds/grpc/xds_common_types.cc +94 -38
  132. data/src/core/xds/grpc/xds_common_types.h +33 -18
  133. data/src/core/xds/grpc/xds_common_types_parser.cc +168 -100
  134. data/src/core/xds/grpc/xds_common_types_parser.h +18 -1
  135. data/src/core/xds/grpc/xds_endpoint_parser.cc +6 -17
  136. data/src/core/xds/grpc/xds_http_filter_registry.cc +2 -10
  137. data/src/core/xds/grpc/xds_http_rbac_filter.cc +3 -12
  138. data/src/core/xds/grpc/xds_metadata_parser.cc +0 -2
  139. data/src/core/xds/grpc/xds_route_config_parser.cc +7 -11
  140. data/src/core/xds/grpc/xds_routing.cc +113 -82
  141. data/src/core/xds/grpc/xds_routing.h +70 -20
  142. data/src/core/xds/grpc/xds_server_grpc.cc +22 -13
  143. data/src/core/xds/grpc/xds_server_grpc.h +16 -2
  144. data/src/core/xds/grpc/xds_server_grpc_interface.h +10 -0
  145. data/src/core/xds/grpc/xds_transport_grpc.cc +123 -18
  146. data/src/core/xds/grpc/xds_transport_grpc.h +28 -4
  147. data/src/core/xds/xds_client/lrs_client.cc +3 -7
  148. data/src/core/xds/xds_client/xds_bootstrap.cc +4 -16
  149. data/src/core/xds/xds_client/xds_client.cc +2 -15
  150. data/src/core/xds/xds_client/xds_transport.h +3 -0
  151. data/src/ruby/lib/grpc/version.rb +1 -1
  152. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +1 -1
  153. metadata +9 -1
@@ -96,6 +96,25 @@ namespace {
96
96
 
97
97
  using ReadDelayHandle = XdsClient::ReadDelayHandle;
98
98
 
99
+ // Some common fields needed by most of the objects below. Refactored
100
+ // into a separate struct with its own ref-count to simplify lock
101
+ // annotations and save a bit of memory.
102
+ struct FetcherState final : public RefCounted<FetcherState> {
103
+ RefCountedPtr<GrpcXdsClient> xds_client;
104
+ WorkSerializer work_serializer;
105
+
106
+ explicit FetcherState(RefCountedPtr<GrpcXdsClient> xds_client_in)
107
+ : xds_client(std::move(xds_client_in)),
108
+ work_serializer(
109
+ grpc_event_engine::experimental::GetDefaultEventEngine()) {
110
+ GRPC_CHECK(xds_client != nullptr);
111
+ }
112
+
113
+ ~FetcherState() override {
114
+ xds_client.reset(DEBUG_LOCATION, "XdsServerConfigFetcher");
115
+ }
116
+ };
117
+
99
118
  // A server config fetcher that fetches the information for configuring server
100
119
  // listeners from the xDS control plane.
101
120
  class XdsServerConfigFetcher final : public ServerConfigFetcher {
@@ -104,7 +123,7 @@ class XdsServerConfigFetcher final : public ServerConfigFetcher {
104
123
  grpc_server_xds_status_notifier notifier);
105
124
 
106
125
  ~XdsServerConfigFetcher() override {
107
- xds_client_.reset(DEBUG_LOCATION, "XdsServerConfigFetcher");
126
+ fetcher_state_.reset(DEBUG_LOCATION, "XdsServerConfigFetcher");
108
127
  }
109
128
 
110
129
  void StartWatch(
@@ -115,40 +134,39 @@ class XdsServerConfigFetcher final : public ServerConfigFetcher {
115
134
 
116
135
  // Return the interested parties from the xds client so that it can be polled.
117
136
  grpc_pollset_set* interested_parties() override {
118
- return xds_client_->interested_parties();
137
+ return fetcher_state_->xds_client->interested_parties();
119
138
  }
120
139
 
121
140
  private:
122
141
  class ListenerWatcher;
123
142
 
124
- RefCountedPtr<GrpcXdsClient> xds_client_;
143
+ RefCountedPtr<FetcherState> fetcher_state_;
125
144
  const grpc_server_xds_status_notifier serving_status_notifier_;
126
- Mutex mu_;
127
145
  std::map<ServerConfigFetcher::WatcherInterface*, ListenerWatcher*>
128
- listener_watchers_ ABSL_GUARDED_BY(mu_);
146
+ listener_watchers_ ABSL_GUARDED_BY(&FetcherState::work_serializer);
129
147
  };
130
148
 
131
149
  // A watcher implementation for listening on LDS updates from the xDS control
132
150
  // plane. When a good LDS update is received, it creates a
133
- // FilterChainMatchManager object that would replace the existing (if any)
134
- // FilterChainMatchManager object after all referenced RDS resources are
151
+ // XdsConnectionManager object that would replace the existing (if any)
152
+ // XdsConnectionManager object after all referenced RDS resources are
135
153
  // fetched. Note that a good update also causes the server listener to start
136
154
  // listening if it isn't already. If an error LDS update is received (NACKed
137
- // resource, timeouts), the previous good FilterChainMatchManager, if any,
155
+ // resource, timeouts), the previous good XdsConnectionManager, if any,
138
156
  // continues to be used. If there isn't any previous good update or if the
139
157
  // update received was a fatal error (resource does not exist), the server
140
158
  // listener is made to stop listening.
141
159
  class XdsServerConfigFetcher::ListenerWatcher final
142
160
  : public XdsListenerResourceType::WatcherInterface {
143
161
  public:
144
- ListenerWatcher(RefCountedPtr<GrpcXdsClient> xds_client,
162
+ ListenerWatcher(RefCountedPtr<FetcherState> fetcher_state,
145
163
  std::unique_ptr<ServerConfigFetcher::WatcherInterface>
146
164
  server_config_watcher,
147
165
  grpc_server_xds_status_notifier serving_status_notifier,
148
166
  std::string listening_address);
149
167
 
150
168
  ~ListenerWatcher() override {
151
- xds_client_.reset(DEBUG_LOCATION, "ListenerWatcher");
169
+ fetcher_state_.reset(DEBUG_LOCATION, "ListenerWatcher");
152
170
  }
153
171
 
154
172
  void OnResourceChanged(
@@ -162,33 +180,28 @@ class XdsServerConfigFetcher::ListenerWatcher final
162
180
  const std::string& listening_address() const { return listening_address_; }
163
181
 
164
182
  private:
165
- class FilterChainMatchManager;
166
-
167
- void OnFatalError(absl::Status status) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
168
-
169
- // Invoked by FilterChainMatchManager that is done fetching all referenced RDS
170
- // resources. If the calling FilterChainMatchManager is the
171
- // pending_filter_chain_match_manager_, it is promoted to be the
172
- // filter_chain_match_manager_ in use.
173
- void PendingFilterChainMatchManagerReady(
174
- FilterChainMatchManager* filter_chain_match_manager) {
175
- MutexLock lock(&mu_);
176
- PendingFilterChainMatchManagerReadyLocked(filter_chain_match_manager);
177
- }
178
- void PendingFilterChainMatchManagerReadyLocked(
179
- FilterChainMatchManager* filter_chain_match_manager)
180
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&mu_);
183
+ class XdsConnectionManager;
184
+
185
+ void OnFatalError(absl::Status status)
186
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer);
181
187
 
182
- RefCountedPtr<GrpcXdsClient> xds_client_;
188
+ // Invoked by XdsConnectionManager that is done fetching all referenced RDS
189
+ // resources. If the calling XdsConnectionManager is the
190
+ // pending_connection_manager_, it is promoted to be the
191
+ // connection_manager_ in use.
192
+ void MaybeUpdateConnectionManager(XdsConnectionManager* connection_manager)
193
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer);
194
+
195
+ RefCountedPtr<FetcherState> fetcher_state_;
183
196
  const std::unique_ptr<ServerConfigFetcher::WatcherInterface>
184
197
  server_config_watcher_;
185
198
  const grpc_server_xds_status_notifier serving_status_notifier_;
186
199
  const std::string listening_address_;
187
- Mutex mu_;
188
- RefCountedPtr<FilterChainMatchManager> filter_chain_match_manager_
189
- ABSL_GUARDED_BY(mu_);
190
- RefCountedPtr<FilterChainMatchManager> pending_filter_chain_match_manager_
191
- ABSL_GUARDED_BY(mu_);
200
+
201
+ RefCountedPtr<XdsConnectionManager> connection_manager_
202
+ ABSL_GUARDED_BY(&FetcherState::work_serializer);
203
+ RefCountedPtr<XdsConnectionManager> pending_connection_manager_
204
+ ABSL_GUARDED_BY(&FetcherState::work_serializer);
192
205
  };
193
206
 
194
207
  // A connection manager used by the server listener code to inject channel args
@@ -196,131 +209,136 @@ class XdsServerConfigFetcher::ListenerWatcher final
196
209
  // appropriate filter chain from the xDS Listener resource and injects channel
197
210
  // args that configure the right mTLS certs and cause the right set of HTTP
198
211
  // filters to be injected.
199
- class XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager final
212
+ class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager final
200
213
  : public ServerConfigFetcher::ConnectionManager {
201
214
  public:
202
- FilterChainMatchManager(
203
- RefCountedPtr<GrpcXdsClient> xds_client,
204
- XdsListenerResource::FilterChainMap filter_chain_map,
205
- std::optional<XdsListenerResource::FilterChainData> default_filter_chain);
215
+ XdsConnectionManager(
216
+ RefCountedPtr<FetcherState> fetcher_state,
217
+ std::shared_ptr<const XdsListenerResource> listener_resource,
218
+ RefCountedPtr<ListenerWatcher> listener_watcher);
206
219
 
207
- ~FilterChainMatchManager() override {
208
- xds_client_.reset(DEBUG_LOCATION, "FilterChainMatchManager");
220
+ ~XdsConnectionManager() override {
221
+ fetcher_state_.reset(DEBUG_LOCATION, "XdsConnectionManager");
209
222
  }
210
223
 
224
+ void Start() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer);
225
+
211
226
  absl::StatusOr<ChannelArgs> UpdateChannelArgsForConnection(
212
227
  const ChannelArgs& args, grpc_endpoint* tcp) override;
213
228
 
214
- // Invoked by ListenerWatcher to start fetching referenced RDS resources.
215
- void StartRdsWatch(RefCountedPtr<ListenerWatcher> listener_watcher)
216
- ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ListenerWatcher::mu_);
217
-
218
- const XdsListenerResource::FilterChainMap& filter_chain_map() const {
219
- return filter_chain_map_;
220
- }
221
-
222
- const std::optional<XdsListenerResource::FilterChainData>&
223
- default_filter_chain() const {
224
- return default_filter_chain_;
229
+ const XdsListenerResource& listener_resource() const {
230
+ return *listener_resource_;
225
231
  }
226
232
 
227
233
  private:
228
- class RouteConfigWatcher;
229
- struct RdsUpdateState {
230
- RouteConfigWatcher* watcher;
231
- std::optional<absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>>
232
- rds_update;
233
- };
234
-
235
- class XdsServerConfigSelector;
236
- class StaticXdsServerConfigSelectorProvider;
237
- class DynamicXdsServerConfigSelectorProvider;
234
+ class L4FilterChain;
238
235
 
239
- absl::StatusOr<RefCountedPtr<XdsCertificateProvider>>
240
- CreateOrGetXdsCertificateProviderFromFilterChainData(
241
- const XdsListenerResource::FilterChainData* filter_chain);
242
236
  void Orphaned() override;
243
237
 
244
- // Helper functions invoked by RouteConfigWatcher when there are updates to
245
- // RDS resources.
246
- void OnRouteConfigChanged(
247
- const std::string& resource_name,
248
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
249
- route_config);
250
- void OnAmbientError(const std::string& resource_name, absl::Status status);
238
+ // Checks if all L4FilterChains have their RouteConfig. If so,
239
+ // promotes this XdsConnectionManager to be the current one.
240
+ void MaybeUpdateConnectionManager()
241
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer);
251
242
 
252
243
  // Executes cb once for each unique filter chain object in the LDS resource.
253
244
  void ForEachFilterChain(
254
- absl::FunctionRef<void(XdsListenerResource::FilterChainData&)> cb);
245
+ absl::FunctionRef<void(const XdsListenerResource::FilterChainData&)> cb)
246
+ const;
255
247
 
256
- RefCountedPtr<GrpcXdsClient> xds_client_;
257
- // This ref is only kept around till the FilterChainMatchManager becomes
258
- // ready.
259
- RefCountedPtr<ListenerWatcher> listener_watcher_;
260
- // TODO(roth): Consider holding a ref to the LDS resource and storing
261
- // a pointer to the filter chain data within that LDS resource, rather
262
- // than copying the filter chain data here.
263
- XdsListenerResource::FilterChainMap filter_chain_map_;
264
- std::optional<XdsListenerResource::FilterChainData> default_filter_chain_;
265
- Mutex mu_;
266
- size_t rds_resources_yet_to_fetch_ ABSL_GUARDED_BY(mu_) = 0;
267
- std::map<std::string /* resource_name */, RdsUpdateState> rds_map_
268
- ABSL_GUARDED_BY(mu_);
248
+ RefCountedPtr<FetcherState> fetcher_state_;
249
+
250
+ std::shared_ptr<const XdsListenerResource> listener_resource_;
251
+
252
+ // TODO(roth): Consider refactoring the FilterChainMap data structure
253
+ // such that we construct it here rather than at config parsing time,
254
+ // so that we don't need to maintain two different data structures
255
+ // here (first we find the FilterChainData object in FilterChainMap,
256
+ // and then we look up that FilterChainData object in this map).
269
257
  std::map<const XdsListenerResource::FilterChainData*,
270
- RefCountedPtr<XdsCertificateProvider>>
271
- certificate_providers_map_ ABSL_GUARDED_BY(mu_);
258
+ OrphanablePtr<L4FilterChain>>
259
+ l4_filter_chains_;
260
+
261
+ // This ref is only kept around until the XdsConnectionManager becomes
262
+ // ready.
263
+ RefCountedPtr<ListenerWatcher> listener_watcher_
264
+ ABSL_GUARDED_BY(&FetcherState::work_serializer);
272
265
  };
273
266
 
274
- // A watcher implementation for listening on RDS updates referenced to by a
275
- // FilterChainMatchManager object. After all referenced RDS resources are
276
- // fetched (errors are allowed), the FilterChainMatchManager tries to replace
277
- // the current object. The watcher continues to update the referenced RDS
278
- // resources so that new XdsServerConfigSelectorProvider objects are created
279
- // with the latest updates and new connections do not need to wait for the RDS
280
- // resources to be fetched.
281
- class XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
282
- RouteConfigWatcher final
283
- : public XdsRouteConfigResourceType::WatcherInterface {
267
+ class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
268
+ L4FilterChain final : public InternallyRefCounted<L4FilterChain> {
284
269
  public:
285
- RouteConfigWatcher(
286
- std::string resource_name,
287
- WeakRefCountedPtr<FilterChainMatchManager> filter_chain_match_manager)
288
- : resource_name_(std::move(resource_name)),
289
- filter_chain_match_manager_(std::move(filter_chain_match_manager)) {}
270
+ L4FilterChain(RefCountedPtr<FetcherState> fetcher_state,
271
+ WeakRefCountedPtr<XdsConnectionManager> connection_manager,
272
+ const XdsListenerResource::FilterChainData& filter_chain_data);
290
273
 
291
- void OnResourceChanged(
292
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
293
- route_config,
294
- RefCountedPtr<ReadDelayHandle> /* read_delay_handle */) override {
295
- filter_chain_match_manager_->OnRouteConfigChanged(resource_name_,
296
- std::move(route_config));
297
- }
274
+ void Orphan() override
275
+ // Always called within WorkSerializer, but the compiler can't tell.
276
+ ABSL_NO_THREAD_SAFETY_ANALYSIS;
298
277
 
299
- void OnAmbientError(
300
- absl::Status status,
301
- RefCountedPtr<ReadDelayHandle> /* read_delay_handle */) override {
302
- filter_chain_match_manager_->OnAmbientError(resource_name_,
303
- std::move(status));
278
+ bool HasRouteConfig() const
279
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer) {
280
+ return config_selector_provider_ != nullptr;
304
281
  }
305
282
 
283
+ absl::StatusOr<ChannelArgs> UpdateChannelArgsForConnection(
284
+ const ChannelArgs& args) const;
285
+
306
286
  private:
307
- std::string resource_name_;
308
- WeakRefCountedPtr<FilterChainMatchManager> filter_chain_match_manager_;
287
+ class XdsServerConfigSelector;
288
+ class XdsServerConfigSelectorProvider;
289
+ class RouteConfigWatcher;
290
+
291
+ void OnRouteConfigChanged(
292
+ absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
293
+ route_config)
294
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer);
295
+ void OnAmbientError(absl::Status status)
296
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer);
297
+
298
+ void UpdateServerConfigSelector(
299
+ absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
300
+ route_config)
301
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer);
302
+
303
+ absl::StatusOr<RefCountedPtr<ServerConfigSelector>>
304
+ CreateServerConfigSelector(
305
+ absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
306
+ route_config)
307
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer);
308
+
309
+ RefCountedPtr<FetcherState> fetcher_state_;
310
+ WeakRefCountedPtr<XdsConnectionManager> connection_manager_;
311
+
312
+ // Reference into data owned by XdsConnectionManager.
313
+ const XdsListenerResource::FilterChainData& filter_chain_data_;
314
+
315
+ absl::StatusOr<RefCountedPtr<XdsCertificateProvider>> certificate_provider_;
316
+
317
+ RouteConfigWatcher* watcher_ = nullptr;
318
+
319
+ // Will be null until we get the initial RouteConfiguration.
320
+ //
321
+ // The lock annotation here is a little misleading: this is actually
322
+ // set only once inside of the WorkSerializer, but after that it gets
323
+ // accessed from outside of the WorkSerializer. We use the lock
324
+ // annotation just to make sure we don't accidentally modify this
325
+ // field anywhere else in the future, and we inhibit the lock
326
+ // annotation for the known-safe read from outside of the WorkSerializer.
327
+ RefCountedPtr<XdsServerConfigSelectorProvider> config_selector_provider_
328
+ ABSL_GUARDED_BY(&FetcherState::work_serializer);
309
329
  };
310
330
 
311
- // An implementation of ServerConfigSelector used by
312
- // StaticXdsServerConfigSelectorProvider and
313
- // DynamicXdsServerConfigSelectorProvider to parse the RDS update and get
314
- // per-call configuration based on incoming metadata.
315
- class XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
316
- XdsServerConfigSelector final : public ServerConfigSelector {
331
+ // An implementation of ServerConfigSelector that stores parsed xDS filter
332
+ // configs for each route, constructs filter chains for each, and
333
+ // selects the appropriate filter chain for each RPC.
334
+ class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
335
+ L4FilterChain::XdsServerConfigSelector final : public ServerConfigSelector {
317
336
  public:
318
337
  static absl::StatusOr<RefCountedPtr<XdsServerConfigSelector>> Create(
319
338
  const XdsHttpFilterRegistry& http_filter_registry,
320
- std::shared_ptr<const XdsRouteConfigResource> rds_update,
321
339
  const std::vector<XdsListenerResource::HttpConnectionManager::HttpFilter>&
322
- http_filters);
323
- ~XdsServerConfigSelector() override = default;
340
+ http_filters,
341
+ std::shared_ptr<const XdsRouteConfigResource> route_config);
324
342
 
325
343
  absl::StatusOr<CallConfig> GetCallConfig(
326
344
  grpc_metadata_batch* metadata) override;
@@ -328,32 +346,31 @@ class XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
328
346
  private:
329
347
  struct VirtualHost {
330
348
  struct Route {
331
- // true if an action other than kNonForwardingAction is configured.
349
+ // True if an action other than kNonForwardingAction is configured.
332
350
  bool unsupported_action;
333
- // TODO(roth): Consider holding a ref to the RDS resource and storing
334
- // a pointer to the matchers within that RDS resource, rather than
335
- // copying the matchers here.
336
- XdsRouteConfigResource::Route::Matchers matchers;
351
+ // Points inside of XdsServerConfigSelector::route_config_.
352
+ const XdsRouteConfigResource::Route::Matchers* matchers;
337
353
  RefCountedPtr<ServiceConfig> method_config;
338
354
  };
339
355
 
340
356
  class RouteListIterator final : public XdsRouting::RouteListIterator {
341
357
  public:
342
- explicit RouteListIterator(const std::vector<Route>* routes)
358
+ explicit RouteListIterator(const std::vector<Route>& routes)
343
359
  : routes_(routes) {}
344
360
 
345
- size_t Size() const override { return routes_->size(); }
361
+ size_t Size() const override { return routes_.size(); }
346
362
 
347
363
  const XdsRouteConfigResource::Route::Matchers& GetMatchersForRoute(
348
364
  size_t index) const override {
349
- return (*routes_)[index].matchers;
365
+ return *routes_[index].matchers;
350
366
  }
351
367
 
352
368
  private:
353
- const std::vector<Route>* routes_;
369
+ const std::vector<Route>& routes_;
354
370
  };
355
371
 
356
- std::vector<std::string> domains;
372
+ // Points inside of XdsServerConfigSelector::route_config_.
373
+ const std::vector<std::string>* domains;
357
374
  std::vector<Route> routes;
358
375
  };
359
376
 
@@ -361,146 +378,24 @@ class XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
361
378
  : public XdsRouting::VirtualHostListIterator {
362
379
  public:
363
380
  explicit VirtualHostListIterator(
364
- const std::vector<VirtualHost>* virtual_hosts)
381
+ const std::vector<VirtualHost>& virtual_hosts)
365
382
  : virtual_hosts_(virtual_hosts) {}
366
383
 
367
- size_t Size() const override { return virtual_hosts_->size(); }
384
+ size_t Size() const override { return virtual_hosts_.size(); }
368
385
 
369
386
  const std::vector<std::string>& GetDomainsForVirtualHost(
370
387
  size_t index) const override {
371
- return (*virtual_hosts_)[index].domains;
388
+ return *virtual_hosts_[index].domains;
372
389
  }
373
390
 
374
391
  private:
375
- const std::vector<VirtualHost>* virtual_hosts_;
392
+ const std::vector<VirtualHost>& virtual_hosts_;
376
393
  };
377
394
 
395
+ std::shared_ptr<const XdsRouteConfigResource> route_config_;
378
396
  std::vector<VirtualHost> virtual_hosts_;
379
397
  };
380
398
 
381
- // An XdsServerConfigSelectorProvider implementation for when the
382
- // RouteConfiguration is available inline.
383
- class XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
384
- StaticXdsServerConfigSelectorProvider final
385
- : public ServerConfigSelectorProvider {
386
- public:
387
- StaticXdsServerConfigSelectorProvider(
388
- RefCountedPtr<GrpcXdsClient> xds_client,
389
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
390
- static_resource,
391
- std::vector<XdsListenerResource::HttpConnectionManager::HttpFilter>
392
- http_filters)
393
- : xds_client_(std::move(xds_client)),
394
- static_resource_(std::move(static_resource)),
395
- http_filters_(std::move(http_filters)) {}
396
-
397
- ~StaticXdsServerConfigSelectorProvider() override {
398
- xds_client_.reset(DEBUG_LOCATION, "StaticXdsServerConfigSelectorProvider");
399
- }
400
-
401
- absl::StatusOr<RefCountedPtr<ServerConfigSelector>> Watch(
402
- std::unique_ptr<ServerConfigSelectorProvider::ServerConfigSelectorWatcher>
403
- watcher) override {
404
- GRPC_CHECK(watcher_ == nullptr);
405
- watcher_ = std::move(watcher);
406
- if (!static_resource_.ok()) {
407
- return static_resource_.status();
408
- }
409
- return XdsServerConfigSelector::Create(
410
- DownCast<const GrpcXdsBootstrap&>(xds_client_->bootstrap())
411
- .http_filter_registry(),
412
- static_resource_.value(), http_filters_);
413
- }
414
-
415
- void CancelWatch() override { watcher_.reset(); }
416
-
417
- private:
418
- void Orphaned() override {}
419
-
420
- RefCountedPtr<GrpcXdsClient> xds_client_;
421
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
422
- static_resource_;
423
- // TODO(roth): Consider holding a ref to the LDS resource and storing
424
- // a pointer to the HTTP filters within that LDS resource, rather than
425
- // copying the HTTP filters here.
426
- std::vector<XdsListenerResource::HttpConnectionManager::HttpFilter>
427
- http_filters_;
428
- std::unique_ptr<ServerConfigSelectorProvider::ServerConfigSelectorWatcher>
429
- watcher_;
430
- };
431
-
432
- // An XdsServerConfigSelectorProvider implementation for when the
433
- // RouteConfiguration is to be fetched separately via RDS.
434
- class XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
435
- DynamicXdsServerConfigSelectorProvider final
436
- : public ServerConfigSelectorProvider {
437
- public:
438
- DynamicXdsServerConfigSelectorProvider(
439
- RefCountedPtr<GrpcXdsClient> xds_client, std::string resource_name,
440
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
441
- initial_resource,
442
- std::vector<XdsListenerResource::HttpConnectionManager::HttpFilter>
443
- http_filters);
444
-
445
- ~DynamicXdsServerConfigSelectorProvider() override {
446
- xds_client_.reset(DEBUG_LOCATION, "DynamicXdsServerConfigSelectorProvider");
447
- }
448
-
449
- absl::StatusOr<RefCountedPtr<ServerConfigSelector>> Watch(
450
- std::unique_ptr<ServerConfigSelectorProvider::ServerConfigSelectorWatcher>
451
- watcher) override;
452
- void CancelWatch() override;
453
-
454
- private:
455
- class RouteConfigWatcher;
456
-
457
- void Orphaned() override;
458
- void OnRouteConfigChanged(
459
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>> rds_update);
460
- void OnAmbientError(absl::Status status);
461
-
462
- RefCountedPtr<GrpcXdsClient> xds_client_;
463
- std::string resource_name_;
464
- // TODO(roth): Consider holding a ref to the LDS resource and storing
465
- // a pointer to the HTTP filters within that LDS resource, rather than
466
- // copying the HTTP filters here.
467
- std::vector<XdsListenerResource::HttpConnectionManager::HttpFilter>
468
- http_filters_;
469
- RouteConfigWatcher* route_config_watcher_ = nullptr;
470
- Mutex mu_;
471
- std::unique_ptr<ServerConfigSelectorProvider::ServerConfigSelectorWatcher>
472
- watcher_ ABSL_GUARDED_BY(mu_);
473
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>> resource_
474
- ABSL_GUARDED_BY(mu_);
475
- };
476
-
477
- // A watcher implementation for updating the RDS resource used by
478
- // DynamicXdsServerConfigSelectorProvider
479
- class XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
480
- DynamicXdsServerConfigSelectorProvider::RouteConfigWatcher final
481
- : public XdsRouteConfigResourceType::WatcherInterface {
482
- public:
483
- explicit RouteConfigWatcher(
484
- WeakRefCountedPtr<DynamicXdsServerConfigSelectorProvider> parent)
485
- : parent_(std::move(parent)) {}
486
-
487
- void OnResourceChanged(
488
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
489
- route_config,
490
- RefCountedPtr<ReadDelayHandle> /* read_delay_handle */) override {
491
- parent_->OnRouteConfigChanged(std::move(route_config));
492
- }
493
-
494
- void OnAmbientError(
495
- absl::Status status,
496
- RefCountedPtr<ReadDelayHandle> /* read_delay_handle */) override {
497
- parent_->OnAmbientError(std::move(status));
498
- }
499
-
500
- private:
501
- WeakRefCountedPtr<DynamicXdsServerConfigSelectorProvider> parent_;
502
- };
503
-
504
399
  //
505
400
  // XdsServerConfigFetcher
506
401
  //
@@ -508,9 +403,8 @@ class XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
508
403
  XdsServerConfigFetcher::XdsServerConfigFetcher(
509
404
  RefCountedPtr<GrpcXdsClient> xds_client,
510
405
  grpc_server_xds_status_notifier notifier)
511
- : xds_client_(std::move(xds_client)), serving_status_notifier_(notifier) {
512
- GRPC_CHECK(xds_client_ != nullptr);
513
- }
406
+ : fetcher_state_(MakeRefCounted<FetcherState>(std::move(xds_client))),
407
+ serving_status_notifier_(notifier) {}
514
408
 
515
409
  std::string ListenerResourceName(absl::string_view resource_name_template,
516
410
  absl::string_view listening_address) {
@@ -526,37 +420,54 @@ std::string ListenerResourceName(absl::string_view resource_name_template,
526
420
  void XdsServerConfigFetcher::StartWatch(
527
421
  std::string listening_address,
528
422
  std::unique_ptr<ServerConfigFetcher::WatcherInterface> watcher) {
529
- ServerConfigFetcher::WatcherInterface* watcher_ptr = watcher.get();
530
- auto listener_watcher = MakeRefCounted<ListenerWatcher>(
531
- xds_client_.Ref(DEBUG_LOCATION, "ListenerWatcher"), std::move(watcher),
532
- serving_status_notifier_, listening_address);
533
- auto* listener_watcher_ptr = listener_watcher.get();
534
- XdsListenerResourceType::StartWatch(
535
- xds_client_.get(),
536
- ListenerResourceName(
537
- DownCast<const GrpcXdsBootstrap&>(xds_client_->bootstrap())
538
- .server_listener_resource_name_template(),
539
- listening_address),
540
- std::move(listener_watcher));
541
- MutexLock lock(&mu_);
542
- listener_watchers_.emplace(watcher_ptr, listener_watcher_ptr);
423
+ fetcher_state_->work_serializer.Run(
424
+ [self = RefAsSubclass<XdsServerConfigFetcher>(),
425
+ listening_address = std::move(listening_address),
426
+ watcher = std::move(watcher)]()
427
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(
428
+ &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
+ ServerConfigFetcher::WatcherInterface* watcher_ptr = watcher.get();
438
+ auto listener_watcher = MakeRefCounted<ListenerWatcher>(
439
+ self->fetcher_state_.Ref(DEBUG_LOCATION, "ListenerWatcher"),
440
+ std::move(watcher), self->serving_status_notifier_,
441
+ listening_address);
442
+ auto* listener_watcher_ptr = listener_watcher.get();
443
+ XdsListenerResourceType::StartWatch(
444
+ self->fetcher_state_->xds_client.get(), resource_name,
445
+ std::move(listener_watcher));
446
+ self->listener_watchers_.emplace(watcher_ptr, listener_watcher_ptr);
447
+ });
543
448
  }
544
449
 
545
450
  void XdsServerConfigFetcher::CancelWatch(
546
451
  ServerConfigFetcher::WatcherInterface* watcher) {
547
- MutexLock lock(&mu_);
548
- auto it = listener_watchers_.find(watcher);
549
- if (it != listener_watchers_.end()) {
550
- // Cancel the watch on the listener before erasing
551
- XdsListenerResourceType::CancelWatch(
552
- xds_client_.get(),
553
- ListenerResourceName(
554
- DownCast<const GrpcXdsBootstrap&>(xds_client_->bootstrap())
555
- .server_listener_resource_name_template(),
556
- it->second->listening_address()),
557
- it->second, false /* delay_unsubscription */);
558
- listener_watchers_.erase(it);
559
- }
452
+ fetcher_state_->work_serializer.Run(
453
+ [self = RefAsSubclass<XdsServerConfigFetcher>(), watcher]()
454
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer) {
455
+ auto it = self->listener_watchers_.find(watcher);
456
+ 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());
462
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
463
+ << "[XdsServerConfigFetcher " << self.get()
464
+ << "]: cancelling watch for LDS resource " << resource_name;
465
+ XdsListenerResourceType::CancelWatch(
466
+ self->fetcher_state_->xds_client.get(), resource_name,
467
+ it->second,
468
+ /*delay_unsubscription=*/false);
469
+ self->listener_watchers_.erase(it);
470
+ });
560
471
  }
561
472
 
562
473
  //
@@ -564,75 +475,84 @@ void XdsServerConfigFetcher::CancelWatch(
564
475
  //
565
476
 
566
477
  XdsServerConfigFetcher::ListenerWatcher::ListenerWatcher(
567
- RefCountedPtr<GrpcXdsClient> xds_client,
478
+ RefCountedPtr<FetcherState> fetcher_state,
568
479
  std::unique_ptr<ServerConfigFetcher::WatcherInterface>
569
480
  server_config_watcher,
570
481
  grpc_server_xds_status_notifier serving_status_notifier,
571
482
  std::string listening_address)
572
- : xds_client_(std::move(xds_client)),
483
+ : fetcher_state_(std::move(fetcher_state)),
573
484
  server_config_watcher_(std::move(server_config_watcher)),
574
485
  serving_status_notifier_(serving_status_notifier),
575
- listening_address_(std::move(listening_address)) {}
486
+ listening_address_(std::move(listening_address)) {
487
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
488
+ << "[ListenerWatcher " << this << "]: created for address "
489
+ << listening_address_;
490
+ }
576
491
 
577
492
  void XdsServerConfigFetcher::ListenerWatcher::OnResourceChanged(
578
493
  absl::StatusOr<std::shared_ptr<const XdsListenerResource>> listener,
579
- RefCountedPtr<ReadDelayHandle> /* read_delay_handle */) {
580
- if (!listener.ok()) {
581
- MutexLock lock(&mu_);
582
- OnFatalError(absl::Status(
583
- listener.status().code(),
584
- absl::StrCat("LDS resource: ", listener.status().message())));
585
- return;
586
- }
587
- GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
588
- << "[ListenerWatcher " << this << "] Received LDS update from xds client "
589
- << xds_client_.get() << ": " << (*listener)->ToString();
590
- auto* tcp_listener =
591
- std::get_if<XdsListenerResource::TcpListener>(&(*listener)->listener);
592
- if (tcp_listener == nullptr) {
593
- MutexLock lock(&mu_);
594
- OnFatalError(
595
- absl::FailedPreconditionError("LDS resource is not a TCP listener"));
596
- return;
597
- }
598
- if (tcp_listener->address != listening_address_) {
599
- MutexLock lock(&mu_);
600
- OnFatalError(absl::FailedPreconditionError(
601
- "Address in LDS update does not match listening address"));
602
- return;
603
- }
604
- auto new_filter_chain_match_manager = MakeRefCounted<FilterChainMatchManager>(
605
- xds_client_.Ref(DEBUG_LOCATION, "FilterChainMatchManager"),
606
- tcp_listener->filter_chain_map, tcp_listener->default_filter_chain);
607
- MutexLock lock(&mu_);
608
- if (filter_chain_match_manager_ == nullptr ||
609
- !(new_filter_chain_match_manager->filter_chain_map() ==
610
- filter_chain_match_manager_->filter_chain_map() &&
611
- new_filter_chain_match_manager->default_filter_chain() ==
612
- filter_chain_match_manager_->default_filter_chain())) {
613
- pending_filter_chain_match_manager_ =
614
- std::move(new_filter_chain_match_manager);
615
- pending_filter_chain_match_manager_->StartRdsWatch(
616
- RefAsSubclass<ListenerWatcher>());
617
- }
494
+ RefCountedPtr<ReadDelayHandle> read_delay_handle) {
495
+ fetcher_state_->work_serializer.Run(
496
+ [self = RefAsSubclass<ListenerWatcher>(), listener = std::move(listener),
497
+ read_delay_handle = std::move(read_delay_handle)]()
498
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(
499
+ &FetcherState::work_serializer) mutable {
500
+ if (!listener.ok()) {
501
+ self->OnFatalError(absl::Status(
502
+ listener.status().code(),
503
+ absl::StrCat("LDS resource: ", listener.status().message())));
504
+ return;
505
+ }
506
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
507
+ << "[ListenerWatcher " << self.get()
508
+ << "] Received LDS update from xds client "
509
+ << self->fetcher_state_->xds_client.get() << ": "
510
+ << (*listener)->ToString();
511
+ auto* tcp_listener = std::get_if<XdsListenerResource::TcpListener>(
512
+ &(*listener)->listener);
513
+ if (tcp_listener == nullptr) {
514
+ self->OnFatalError(absl::FailedPreconditionError(
515
+ "LDS resource is not a TCP listener"));
516
+ return;
517
+ }
518
+ if (tcp_listener->address != self->listening_address_) {
519
+ self->OnFatalError(absl::FailedPreconditionError(
520
+ "Address in LDS update does not match listening address"));
521
+ return;
522
+ }
523
+ if (self->connection_manager_ != nullptr &&
524
+ **listener == self->connection_manager_->listener_resource()) {
525
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
526
+ << "[ListenerWatcher " << self.get()
527
+ << "]: ignoring unchanged LDS resource for "
528
+ << self->listening_address_;
529
+ return;
530
+ }
531
+ self->pending_connection_manager_ =
532
+ MakeRefCounted<XdsConnectionManager>(
533
+ self->fetcher_state_.Ref(DEBUG_LOCATION,
534
+ "XdsConnectionManager"),
535
+ std::move(*listener), self);
536
+ self->pending_connection_manager_->Start();
537
+ });
618
538
  }
619
539
 
620
540
  void XdsServerConfigFetcher::ListenerWatcher::OnAmbientError(
621
541
  absl::Status status, RefCountedPtr<ReadDelayHandle> /*read_delay_handle*/) {
622
- LOG(ERROR) << "ListenerWatcher:" << this
623
- << " XdsClient reports ambient error: " << status << " for "
624
- << listening_address_
625
- << "; ignoring in favor of existing resource";
542
+ LOG(ERROR)
543
+ << "[ListenerWatcher:" << this
544
+ << "] XdsClient reports ambient error for LDS resource for address "
545
+ << listening_address_ << ": " << status;
626
546
  }
627
547
 
628
548
  void XdsServerConfigFetcher::ListenerWatcher::OnFatalError(
629
549
  absl::Status status) {
630
- pending_filter_chain_match_manager_.reset();
631
- if (filter_chain_match_manager_ != nullptr) {
550
+ pending_connection_manager_.reset();
551
+ if (connection_manager_ != nullptr) {
632
552
  // The server has started listening already, so we need to gracefully
633
553
  // stop serving.
634
554
  server_config_watcher_->StopServing();
635
- filter_chain_match_manager_.reset();
555
+ connection_manager_.reset();
636
556
  }
637
557
  if (serving_status_notifier_.on_serving_status_update != nullptr) {
638
558
  serving_status_notifier_.on_serving_status_update(
@@ -640,28 +560,26 @@ void XdsServerConfigFetcher::ListenerWatcher::OnFatalError(
640
560
  {static_cast<grpc_status_code>(status.raw_code()),
641
561
  std::string(status.message()).c_str()});
642
562
  } else {
643
- LOG(ERROR) << "ListenerWatcher:" << this << " Encountered fatal error "
563
+ LOG(ERROR) << "[ListenerWatcher:" << this << "] Encountered fatal error "
644
564
  << status << "; not serving on " << listening_address_;
645
565
  }
646
566
  }
647
567
 
648
- void XdsServerConfigFetcher::ListenerWatcher::
649
- PendingFilterChainMatchManagerReadyLocked(
650
- XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager*
651
- filter_chain_match_manager) {
652
- if (pending_filter_chain_match_manager_ != filter_chain_match_manager) {
653
- // This FilterChainMatchManager is no longer the current pending resource.
568
+ void XdsServerConfigFetcher::ListenerWatcher::MaybeUpdateConnectionManager(
569
+ XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager*
570
+ connection_manager) {
571
+ if (pending_connection_manager_ != connection_manager) {
572
+ // This XdsConnectionManager is no longer the current pending resource.
654
573
  // It should get cleaned up eventually. Ignore this update.
655
574
  return;
656
575
  }
657
- bool first_good_update = filter_chain_match_manager_ == nullptr;
658
- // Promote the pending FilterChainMatchManager
659
- filter_chain_match_manager_ = std::move(pending_filter_chain_match_manager_);
660
- // TODO(yashykt): Right now, the server_config_watcher_ does not invoke
661
- // XdsServerConfigFetcher while holding a lock, but that might change in the
662
- // future in which case we would want to execute this update outside the
663
- // critical region through a WorkSerializer similar to XdsClient.
664
- server_config_watcher_->UpdateConnectionManager(filter_chain_match_manager_);
576
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
577
+ << "[ListenerWatcher " << this << "]: promoting XdsConnectionManager "
578
+ << connection_manager;
579
+ bool first_good_update = connection_manager_ == nullptr;
580
+ // Promote the pending XdsConnectionManager
581
+ connection_manager_ = std::move(pending_connection_manager_);
582
+ server_config_watcher_->UpdateConnectionManager(connection_manager_);
665
583
  // Let the logger know about the update if there was no previous good update.
666
584
  if (first_good_update) {
667
585
  if (serving_status_notifier_.on_serving_status_update != nullptr) {
@@ -676,28 +594,50 @@ void XdsServerConfigFetcher::ListenerWatcher::
676
594
  }
677
595
 
678
596
  //
679
- // XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager
597
+ // XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager
680
598
  //
681
599
 
682
- XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
683
- FilterChainMatchManager(
684
- RefCountedPtr<GrpcXdsClient> xds_client,
685
- XdsListenerResource::FilterChainMap filter_chain_map,
686
- std::optional<XdsListenerResource::FilterChainData>
687
- default_filter_chain)
688
- : xds_client_(std::move(xds_client)),
689
- filter_chain_map_(std::move(filter_chain_map)),
690
- default_filter_chain_(std::move(default_filter_chain)) {}
691
-
692
- void XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
600
+ XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
601
+ XdsConnectionManager(
602
+ RefCountedPtr<FetcherState> fetcher_state,
603
+ std::shared_ptr<const XdsListenerResource> listener_resource,
604
+ RefCountedPtr<ListenerWatcher> listener_watcher)
605
+ : fetcher_state_(std::move(fetcher_state)),
606
+ listener_resource_(std::move(listener_resource)),
607
+ listener_watcher_(std::move(listener_watcher)) {
608
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
609
+ << "[XdsConnectionManager " << this << "]: created";
610
+ }
611
+
612
+ void XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::Start() {
613
+ // Create L4FilterChain object for each L4 filter chain.
614
+ ForEachFilterChain(
615
+ [&](const XdsListenerResource::FilterChainData& filter_chain_data)
616
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer) {
617
+ auto l4_filter_chain = MakeOrphanable<L4FilterChain>(
618
+ fetcher_state_.Ref(DEBUG_LOCATION, "L4FilterChain"),
619
+ WeakRefAsSubclass<XdsConnectionManager>(), filter_chain_data);
620
+ l4_filter_chains_.emplace(&filter_chain_data,
621
+ std::move(l4_filter_chain));
622
+ });
623
+ // If all L4 filter chains had inline RouteConfigs, then promote this
624
+ // XdsConnectionManager immediately.
625
+ MaybeUpdateConnectionManager();
626
+ }
627
+
628
+ void XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
693
629
  ForEachFilterChain(
694
- absl::FunctionRef<void(XdsListenerResource::FilterChainData&)> cb) {
630
+ absl::FunctionRef<void(const XdsListenerResource::FilterChainData&)> cb)
631
+ const {
632
+ const auto& tcp_listener =
633
+ std::get<XdsListenerResource::TcpListener>(listener_resource_->listener);
695
634
  // A given FilterChainData object may appear more than once in the map,
696
635
  // but we want to invoke the callback exactly once for each
697
636
  // FilterChainData object. Therefore, we start by constructing a set
698
637
  // of all FilterChainData objects by address, to weed out duplicates.
699
- std::set<XdsListenerResource::FilterChainData*> filter_chain_data_set;
700
- for (const auto& destination_ip : filter_chain_map_.destination_ip_vector) {
638
+ std::set<const XdsListenerResource::FilterChainData*> filter_chain_data_set;
639
+ for (const auto& destination_ip :
640
+ tcp_listener.filter_chain_map.destination_ip_vector) {
701
641
  for (const auto& source_type : destination_ip.source_types_array) {
702
642
  for (const auto& source_ip : source_type) {
703
643
  for (const auto& source_port_pair : source_ip.ports_map) {
@@ -712,156 +652,36 @@ void XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
712
652
  cb(*filter_chain_data);
713
653
  }
714
654
  // Also invoke the callback for the default filter chain, if present.
715
- if (default_filter_chain_.has_value()) {
716
- cb(*default_filter_chain_);
655
+ if (tcp_listener.default_filter_chain.has_value()) {
656
+ cb(*tcp_listener.default_filter_chain);
717
657
  }
718
658
  }
719
659
 
720
- void XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
721
- StartRdsWatch(RefCountedPtr<ListenerWatcher> listener_watcher) {
722
- // Get the set of RDS resources to watch on. Also reverse the list of
723
- // HTTP filters in each filter chain, since received data moves *up*
724
- // the stack on the server side.
725
- std::set<std::string> resource_names;
726
- ForEachFilterChain(
727
- [&](XdsListenerResource::FilterChainData& filter_chain_data) {
728
- auto& hcm = filter_chain_data.http_connection_manager;
729
- const auto* rds_name = std::get_if<std::string>(&hcm.route_config);
730
- if (rds_name != nullptr) resource_names.insert(*rds_name);
731
- std::reverse(hcm.http_filters.begin(), hcm.http_filters.end());
732
- });
733
- // Start watching referenced RDS resources.
734
- struct WatcherToStart {
735
- std::string resource_name;
736
- RefCountedPtr<RouteConfigWatcher> watcher;
737
- };
738
- std::vector<WatcherToStart> watchers_to_start;
739
- watchers_to_start.reserve(resource_names.size());
740
- {
741
- MutexLock lock(&mu_);
742
- for (const auto& resource_name : resource_names) {
743
- ++rds_resources_yet_to_fetch_;
744
- auto route_config_watcher = MakeRefCounted<RouteConfigWatcher>(
745
- resource_name, WeakRefAsSubclass<FilterChainMatchManager>());
746
- rds_map_.emplace(resource_name, RdsUpdateState{route_config_watcher.get(),
747
- std::nullopt});
748
- watchers_to_start.push_back(
749
- WatcherToStart{resource_name, std::move(route_config_watcher)});
750
- }
751
- if (rds_resources_yet_to_fetch_ != 0) {
752
- listener_watcher_ = std::move(listener_watcher);
753
- listener_watcher = nullptr;
754
- }
755
- }
756
- for (auto& watcher_to_start : watchers_to_start) {
757
- XdsRouteConfigResourceType::StartWatch(xds_client_.get(),
758
- watcher_to_start.resource_name,
759
- std::move(watcher_to_start.watcher));
760
- }
761
- // Promote this filter chain match manager if all referenced resources are
762
- // fetched.
763
- if (listener_watcher != nullptr) {
764
- listener_watcher->PendingFilterChainMatchManagerReadyLocked(this);
765
- }
766
- }
767
-
768
- void XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
769
- Orphaned() {
770
- MutexLock lock(&mu_);
771
- // Cancel the RDS watches to clear up the weak refs
772
- for (const auto& entry : rds_map_) {
773
- XdsRouteConfigResourceType::CancelWatch(xds_client_.get(), entry.first,
774
- entry.second.watcher,
775
- false /* delay_unsubscription */);
776
- }
777
- // Also give up the ref on ListenerWatcher since it won't be needed anymore
778
- listener_watcher_.reset();
660
+ void XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::Orphaned() {
661
+ fetcher_state_->work_serializer.Run(
662
+ [self = WeakRefAsSubclass<XdsConnectionManager>()]()
663
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer) {
664
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
665
+ << "[XdsConnectionManager " << self.get() << "]: orphaned";
666
+ self->listener_watcher_.reset();
667
+ self->l4_filter_chains_.clear();
668
+ });
779
669
  }
780
670
 
781
- absl::StatusOr<RefCountedPtr<XdsCertificateProvider>>
782
- XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
783
- CreateOrGetXdsCertificateProviderFromFilterChainData(
784
- const XdsListenerResource::FilterChainData* filter_chain) {
785
- MutexLock lock(&mu_);
786
- auto it = certificate_providers_map_.find(filter_chain);
787
- if (it != certificate_providers_map_.end()) return it->second;
788
- // Configure root cert.
789
- auto* ca_cert_provider =
790
- std::get_if<CommonTlsContext::CertificateProviderPluginInstance>(
791
- &filter_chain->downstream_tls_context.common_tls_context
792
- .certificate_validation_context.ca_certs);
793
- absl::string_view root_provider_cert_name;
794
- RefCountedPtr<grpc_tls_certificate_provider> root_cert_provider;
795
- if (ca_cert_provider != nullptr) {
796
- root_provider_cert_name = ca_cert_provider->certificate_name;
797
- root_cert_provider =
798
- xds_client_->certificate_provider_store()
799
- .CreateOrGetCertificateProvider(ca_cert_provider->instance_name);
800
- if (root_cert_provider == nullptr) {
801
- return absl::NotFoundError(
802
- absl::StrCat("Certificate provider instance name: \"",
803
- ca_cert_provider->instance_name, "\" not recognized."));
804
- }
805
- }
806
- // Configure identity cert.
807
- absl::string_view identity_provider_instance_name =
808
- filter_chain->downstream_tls_context.common_tls_context
809
- .tls_certificate_provider_instance.instance_name;
810
- absl::string_view identity_provider_cert_name =
811
- filter_chain->downstream_tls_context.common_tls_context
812
- .tls_certificate_provider_instance.certificate_name;
813
- RefCountedPtr<grpc_tls_certificate_provider> identity_cert_provider;
814
- if (!identity_provider_instance_name.empty()) {
815
- identity_cert_provider =
816
- xds_client_->certificate_provider_store()
817
- .CreateOrGetCertificateProvider(identity_provider_instance_name);
818
- if (identity_cert_provider == nullptr) {
819
- return absl::NotFoundError(
820
- absl::StrCat("Certificate provider instance name: \"",
821
- identity_provider_instance_name, "\" not recognized."));
822
- }
823
- }
824
- auto xds_cert_provider = MakeRefCounted<XdsCertificateProvider>(
825
- std::move(root_cert_provider), root_provider_cert_name,
826
- std::move(identity_cert_provider), identity_provider_cert_name,
827
- filter_chain->downstream_tls_context.require_client_certificate);
828
- certificate_providers_map_.emplace(filter_chain, xds_cert_provider);
829
- return xds_cert_provider;
830
- }
831
-
832
- void XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
833
- OnRouteConfigChanged(
834
- const std::string& resource_name,
835
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
836
- route_config) {
671
+ void XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
672
+ MaybeUpdateConnectionManager() {
673
+ if (listener_watcher_ == nullptr) return; // Already promoted.
837
674
  RefCountedPtr<ListenerWatcher> listener_watcher;
838
- {
839
- MutexLock lock(&mu_);
840
- auto& state = rds_map_[resource_name];
841
- if (!state.rds_update.has_value()) {
842
- if (--rds_resources_yet_to_fetch_ == 0) {
843
- listener_watcher = std::move(listener_watcher_);
844
- }
845
- }
846
- if (!route_config.ok()) {
847
- route_config = absl::UnavailableError(
848
- absl::StrCat("RDS resource ", resource_name, ": ",
849
- route_config.status().message()));
850
- }
851
- state.rds_update = std::move(route_config);
852
- }
853
- // Promote the filter chain match manager object if all the referenced
854
- // resources are fetched.
855
- if (listener_watcher != nullptr) {
856
- listener_watcher->PendingFilterChainMatchManagerReady(this);
675
+ // Check if all L4 filter chains have their route configs.
676
+ for (const auto& [_, l4_filter_chain] : l4_filter_chains_) {
677
+ if (!l4_filter_chain->HasRouteConfig()) return;
857
678
  }
858
- }
859
-
860
- void XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
861
- OnAmbientError(const std::string& resource_name, absl::Status status) {
862
- LOG(ERROR) << "RouteConfigWatcher:" << this
863
- << " XdsClient reports ambient error: " << status << " for "
864
- << resource_name << "; ignoring in favor of existing resource";
679
+ // We have all route configs, so promote the XdsConnectionManager.
680
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
681
+ << "[XdsConnectionManager " << this
682
+ << "]: obtained all necessary RDS resources";
683
+ listener_watcher_->MaybeUpdateConnectionManager(this);
684
+ listener_watcher_.reset();
865
685
  }
866
686
 
867
687
  const XdsListenerResource::FilterChainData* FindFilterChainDataForSourcePort(
@@ -1023,28 +843,262 @@ const XdsListenerResource::FilterChainData* FindFilterChainDataForDestinationIp(
1023
843
  }
1024
844
 
1025
845
  absl::StatusOr<ChannelArgs> XdsServerConfigFetcher::ListenerWatcher::
1026
- FilterChainMatchManager::UpdateChannelArgsForConnection(
1027
- const ChannelArgs& input_args, grpc_endpoint* tcp) {
1028
- ChannelArgs args = input_args;
846
+ XdsConnectionManager::UpdateChannelArgsForConnection(
847
+ const ChannelArgs& args, grpc_endpoint* tcp) {
848
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
849
+ << "[XdsConnectionManager " << this
850
+ << "]: choosing L4 filter chain for connection";
851
+ const auto& tcp_listener =
852
+ std::get<XdsListenerResource::TcpListener>(listener_resource_->listener);
1029
853
  const auto* filter_chain = FindFilterChainDataForDestinationIp(
1030
- filter_chain_map_.destination_ip_vector, tcp);
1031
- if (filter_chain == nullptr && default_filter_chain_.has_value()) {
1032
- filter_chain = &default_filter_chain_.value();
854
+ tcp_listener.filter_chain_map.destination_ip_vector, tcp);
855
+ if (filter_chain == nullptr &&
856
+ tcp_listener.default_filter_chain.has_value()) {
857
+ filter_chain = &*tcp_listener.default_filter_chain;
1033
858
  }
1034
859
  if (filter_chain == nullptr) {
1035
860
  return absl::UnavailableError("No matching filter chain found");
1036
861
  }
1037
- RefCountedPtr<ServerConfigSelectorProvider> server_config_selector_provider;
1038
- RefCountedPtr<XdsChannelStackModifier> channel_stack_modifier;
1039
- RefCountedPtr<XdsCertificateProvider> xds_certificate_provider;
1040
- // Iterate the list of HTTP filters in reverse since in Core, received data
1041
- // flows *up* the stack.
862
+ // Find the corresponding L4FilterChain.
863
+ auto it = l4_filter_chains_.find(filter_chain);
864
+ if (it == l4_filter_chains_.end()) {
865
+ // Should never happen.
866
+ return absl::InternalError("could not find L4FilterChain");
867
+ }
868
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
869
+ << "[XdsConnectionManager " << this << "]: selected L4 filter chain "
870
+ << it->second.get();
871
+ return it->second->UpdateChannelArgsForConnection(args);
872
+ }
873
+
874
+ //
875
+ // XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::XdsServerConfigSelectorProvider
876
+ //
877
+
878
+ class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
879
+ L4FilterChain::XdsServerConfigSelectorProvider final
880
+ : public ServerConfigSelectorProvider {
881
+ public:
882
+ XdsServerConfigSelectorProvider(
883
+ RefCountedPtr<FetcherState> fetcher_state,
884
+ absl::StatusOr<RefCountedPtr<ServerConfigSelector>> config_selector)
885
+ : fetcher_state_(std::move(fetcher_state)),
886
+ config_selector_(std::move(config_selector)) {}
887
+
888
+ void SetServerConfigSelector(
889
+ absl::StatusOr<RefCountedPtr<ServerConfigSelector>> config_selector)
890
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer) {
891
+ if (GRPC_TRACE_FLAG_ENABLED(xds_server_config_fetcher)) {
892
+ if (config_selector.ok()) {
893
+ LOG(INFO) << "[XdsServerConfigSelectorProvider " << this
894
+ << "]: sending new XdsServerConfigSelector "
895
+ << config_selector->get();
896
+ } else {
897
+ LOG(INFO) << "[XdsServerConfigSelectorProvider " << this
898
+ << "]: sending new XdsServerConfigSelector "
899
+ << config_selector.status();
900
+ }
901
+ }
902
+ config_selector_ = std::move(config_selector);
903
+ for (const auto& watcher : watchers_) {
904
+ watcher->OnServerConfigSelectorUpdate(config_selector_);
905
+ }
906
+ }
907
+
908
+ absl::StatusOr<RefCountedPtr<ServerConfigSelector>> Watch(
909
+ std::shared_ptr<ServerConfigSelectorWatcher> watcher) override {
910
+ fetcher_state_->work_serializer.Run(
911
+ [self = WeakRefAsSubclass<XdsServerConfigSelectorProvider>(),
912
+ watcher = std::move(watcher)]()
913
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(
914
+ &FetcherState::work_serializer) mutable {
915
+ watcher->OnServerConfigSelectorUpdate(self->config_selector_);
916
+ self->watchers_.insert(std::move(watcher));
917
+ });
918
+ return nullptr;
919
+ }
920
+
921
+ void CancelWatch(
922
+ std::shared_ptr<ServerConfigSelectorWatcher> watcher) override {
923
+ fetcher_state_->work_serializer.Run(
924
+ [self = WeakRefAsSubclass<XdsServerConfigSelectorProvider>(),
925
+ watcher = std::move(watcher)]()
926
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer) {
927
+ self->watchers_.erase(watcher);
928
+ });
929
+ }
930
+
931
+ private:
932
+ void Orphaned() override {
933
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
934
+ << "[XdsServerConfigSelectorProvider " << this << "]: orphaned";
935
+ }
936
+
937
+ RefCountedPtr<FetcherState> fetcher_state_;
938
+
939
+ absl::StatusOr<RefCountedPtr<ServerConfigSelector>> config_selector_
940
+ ABSL_GUARDED_BY(&FetcherState::work_serializer);
941
+ absl::flat_hash_set<std::shared_ptr<ServerConfigSelectorWatcher>> watchers_
942
+ ABSL_GUARDED_BY(&FetcherState::work_serializer);
943
+ };
944
+
945
+ //
946
+ // XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::RouteConfigWatcher
947
+ //
948
+
949
+ class XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
950
+ L4FilterChain::RouteConfigWatcher final
951
+ : public XdsRouteConfigResourceType::WatcherInterface {
952
+ public:
953
+ explicit RouteConfigWatcher(RefCountedPtr<L4FilterChain> l4_filter_chain)
954
+ : l4_filter_chain_(std::move(l4_filter_chain)) {}
955
+
956
+ void OnResourceChanged(
957
+ absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
958
+ route_config,
959
+ RefCountedPtr<ReadDelayHandle> read_delay_handle) override {
960
+ l4_filter_chain_->fetcher_state_->work_serializer.Run(
961
+ [l4_filter_chain = l4_filter_chain_,
962
+ route_config = std::move(route_config),
963
+ read_delay_handle = std::move(read_delay_handle)]()
964
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(
965
+ &FetcherState::work_serializer) mutable {
966
+ l4_filter_chain->OnRouteConfigChanged(std::move(route_config));
967
+ });
968
+ }
969
+
970
+ void OnAmbientError(
971
+ absl::Status status,
972
+ RefCountedPtr<ReadDelayHandle> read_delay_handle) override {
973
+ l4_filter_chain_->fetcher_state_->work_serializer.Run(
974
+ [l4_filter_chain = l4_filter_chain_, status = std::move(status),
975
+ read_delay_handle = std::move(read_delay_handle)]()
976
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(
977
+ &FetcherState::work_serializer) mutable {
978
+ l4_filter_chain->OnAmbientError(std::move(status));
979
+ });
980
+ }
981
+
982
+ private:
983
+ RefCountedPtr<L4FilterChain> l4_filter_chain_;
984
+ };
985
+
986
+ //
987
+ // XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain
988
+ //
989
+
990
+ absl::StatusOr<RefCountedPtr<XdsCertificateProvider>>
991
+ CreateCertificateProviderForFilterChain(
992
+ const XdsListenerResource::FilterChainData& filter_chain,
993
+ CertificateProviderStore& certificate_provider_store) {
994
+ // Configure root cert.
995
+ auto* ca_cert_provider =
996
+ std::get_if<CommonTlsContext::CertificateProviderPluginInstance>(
997
+ &filter_chain.downstream_tls_context.common_tls_context
998
+ .certificate_validation_context.ca_certs);
999
+ absl::string_view root_provider_cert_name;
1000
+ RefCountedPtr<grpc_tls_certificate_provider> root_cert_provider;
1001
+ if (ca_cert_provider != nullptr) {
1002
+ root_provider_cert_name = ca_cert_provider->certificate_name;
1003
+ root_cert_provider =
1004
+ certificate_provider_store.CreateOrGetCertificateProvider(
1005
+ ca_cert_provider->instance_name);
1006
+ if (root_cert_provider == nullptr) {
1007
+ return absl::NotFoundError(
1008
+ absl::StrCat("Certificate provider instance name: \"",
1009
+ ca_cert_provider->instance_name, "\" not recognized."));
1010
+ }
1011
+ }
1012
+ // Configure identity cert.
1013
+ absl::string_view identity_provider_instance_name =
1014
+ filter_chain.downstream_tls_context.common_tls_context
1015
+ .tls_certificate_provider_instance.instance_name;
1016
+ absl::string_view identity_provider_cert_name =
1017
+ filter_chain.downstream_tls_context.common_tls_context
1018
+ .tls_certificate_provider_instance.certificate_name;
1019
+ RefCountedPtr<grpc_tls_certificate_provider> identity_cert_provider;
1020
+ if (!identity_provider_instance_name.empty()) {
1021
+ identity_cert_provider =
1022
+ certificate_provider_store.CreateOrGetCertificateProvider(
1023
+ identity_provider_instance_name);
1024
+ if (identity_cert_provider == nullptr) {
1025
+ return absl::NotFoundError(
1026
+ absl::StrCat("Certificate provider instance name: \"",
1027
+ identity_provider_instance_name, "\" not recognized."));
1028
+ }
1029
+ }
1030
+ return MakeRefCounted<XdsCertificateProvider>(
1031
+ std::move(root_cert_provider), root_provider_cert_name,
1032
+ std::move(identity_cert_provider), identity_provider_cert_name,
1033
+ filter_chain.downstream_tls_context.require_client_certificate);
1034
+ }
1035
+
1036
+ XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::
1037
+ L4FilterChain(RefCountedPtr<FetcherState> fetcher_state,
1038
+ WeakRefCountedPtr<XdsConnectionManager> connection_manager,
1039
+ const XdsListenerResource::FilterChainData& filter_chain_data)
1040
+ : fetcher_state_(std::move(fetcher_state)),
1041
+ connection_manager_(std::move(connection_manager)),
1042
+ filter_chain_data_(filter_chain_data),
1043
+ certificate_provider_(CreateCertificateProviderForFilterChain(
1044
+ filter_chain_data,
1045
+ fetcher_state_->xds_client->certificate_provider_store())) {
1046
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
1047
+ << "[L4FilterChain " << this << "]: created";
1048
+ auto& hcm = filter_chain_data_.http_connection_manager;
1049
+ Match(
1050
+ hcm.route_config,
1051
+ [&](const std::string& rds_resource_name) {
1052
+ // Start RDS watch.
1053
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
1054
+ << "[L4FilterChain " << this << "]: starting RDS watch for "
1055
+ << rds_resource_name;
1056
+ auto watcher = MakeRefCounted<RouteConfigWatcher>(Ref());
1057
+ watcher_ = watcher.get();
1058
+ XdsRouteConfigResourceType::StartWatch(fetcher_state_->xds_client.get(),
1059
+ rds_resource_name,
1060
+ std::move(watcher));
1061
+ },
1062
+ [&](const std::shared_ptr<const XdsRouteConfigResource>& route_config)
1063
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(&FetcherState::work_serializer) {
1064
+ // RouteConfig was inlined in LDS.
1065
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
1066
+ << "[L4FilterChain " << this << "]: got RouteConfig from LDS";
1067
+ UpdateServerConfigSelector(route_config);
1068
+ });
1069
+ }
1070
+
1071
+ void XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
1072
+ L4FilterChain::Orphan() {
1073
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
1074
+ << "[L4FilterChain " << this << "]: orphaned";
1075
+ if (watcher_ != nullptr) {
1076
+ auto& hcm = filter_chain_data_.http_connection_manager;
1077
+ auto& rds_resource_name = std::get<std::string>(hcm.route_config);
1078
+ XdsRouteConfigResourceType::CancelWatch(fetcher_state_->xds_client.get(),
1079
+ rds_resource_name, watcher_);
1080
+ watcher_ = nullptr;
1081
+ }
1082
+ connection_manager_.reset();
1083
+ Unref();
1084
+ }
1085
+
1086
+ absl::StatusOr<ChannelArgs> XdsServerConfigFetcher::ListenerWatcher::
1087
+ XdsConnectionManager::L4FilterChain::UpdateChannelArgsForConnection(
1088
+ const ChannelArgs& args) const {
1089
+ 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.
1042
1096
  std::vector<const grpc_channel_filter*> filters;
1043
1097
  const auto& http_filter_registry =
1044
- DownCast<const GrpcXdsBootstrap&>(xds_client_->bootstrap())
1098
+ DownCast<const GrpcXdsBootstrap&>(fetcher_state_->xds_client->bootstrap())
1045
1099
  .http_filter_registry();
1046
1100
  for (const auto& http_filter :
1047
- filter_chain->http_connection_manager.http_filters) {
1101
+ filter_chain_data_.http_connection_manager.http_filters) {
1048
1102
  // Find filter. This is guaranteed to succeed, because it's checked
1049
1103
  // at config validation time in the XdsApi code.
1050
1104
  const XdsHttpFilterImpl* filter_impl =
@@ -1057,77 +1111,107 @@ absl::StatusOr<ChannelArgs> XdsServerConfigFetcher::ListenerWatcher::
1057
1111
  filters.push_back(filter_impl->channel_filter());
1058
1112
  }
1059
1113
  }
1114
+ // Reverse the order, since filters flow *up* the stack on the server side.
1115
+ std::reverse(filters.begin(), filters.end());
1060
1116
  // Add config selector filter.
1061
1117
  filters.push_back(&kServerConfigSelectorFilter);
1062
- channel_stack_modifier =
1063
- MakeRefCounted<XdsChannelStackModifier>(std::move(filters));
1064
- Match(
1065
- filter_chain->http_connection_manager.route_config,
1066
- // RDS resource name
1067
- [&](const std::string& rds_name) {
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;
1127
+ }
1128
+
1129
+ absl::StatusOr<RefCountedPtr<ServerConfigSelector>>
1130
+ XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::
1131
+ CreateServerConfigSelector(
1068
1132
  absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
1069
- initial_resource;
1070
- {
1071
- MutexLock lock(&mu_);
1072
- initial_resource = rds_map_[rds_name].rds_update.value();
1073
- }
1074
- server_config_selector_provider =
1075
- MakeRefCounted<DynamicXdsServerConfigSelectorProvider>(
1076
- xds_client_.Ref(DEBUG_LOCATION,
1077
- "DynamicXdsServerConfigSelectorProvider"),
1078
- rds_name, std::move(initial_resource),
1079
- filter_chain->http_connection_manager.http_filters);
1080
- },
1081
- // inline RouteConfig
1082
- [&](const std::shared_ptr<const XdsRouteConfigResource>& route_config) {
1083
- server_config_selector_provider =
1084
- MakeRefCounted<StaticXdsServerConfigSelectorProvider>(
1085
- xds_client_.Ref(DEBUG_LOCATION,
1086
- "StaticXdsServerConfigSelectorProvider"),
1087
- route_config,
1088
- filter_chain->http_connection_manager.http_filters);
1089
- });
1090
- args = args.SetObject(server_config_selector_provider)
1091
- .SetObject(channel_stack_modifier);
1092
- // Add XdsCertificateProvider if credentials are xDS.
1093
- auto* server_creds = args.GetObject<grpc_server_credentials>();
1094
- if (server_creds != nullptr &&
1095
- server_creds->type() == XdsServerCredentials::Type()) {
1096
- absl::StatusOr<RefCountedPtr<XdsCertificateProvider>> result =
1097
- CreateOrGetXdsCertificateProviderFromFilterChainData(filter_chain);
1098
- if (!result.ok()) {
1099
- return result.status();
1100
- }
1101
- xds_certificate_provider = std::move(*result);
1102
- GRPC_CHECK(xds_certificate_provider != nullptr);
1103
- args = args.SetObject(xds_certificate_provider);
1133
+ route_config) {
1134
+ if (!route_config.ok()) return route_config.status();
1135
+ return XdsServerConfigSelector::Create(
1136
+ DownCast<const GrpcXdsBootstrap&>(fetcher_state_->xds_client->bootstrap())
1137
+ .http_filter_registry(),
1138
+ filter_chain_data_.http_connection_manager.http_filters,
1139
+ std::move(*route_config));
1140
+ }
1141
+
1142
+ void XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
1143
+ L4FilterChain::UpdateServerConfigSelector(
1144
+ absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
1145
+ route_config) {
1146
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
1147
+ << "[L4FilterChain " << this << "]: creating new XdsServerConfigSelector";
1148
+ absl::StatusOr<RefCountedPtr<ServerConfigSelector>> config_selector =
1149
+ CreateServerConfigSelector(std::move(route_config));
1150
+ if (config_selector_provider_ == nullptr) {
1151
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
1152
+ << "[L4FilterChain " << this
1153
+ << "]: initial update; creating new XdsServerConfigSelectorProvider";
1154
+ config_selector_provider_ = MakeRefCounted<XdsServerConfigSelectorProvider>(
1155
+ fetcher_state_, std::move(config_selector));
1156
+ } else {
1157
+ // Provider already exists, so just update it.
1158
+ config_selector_provider_->SetServerConfigSelector(
1159
+ std::move(config_selector));
1104
1160
  }
1105
- return args;
1161
+ }
1162
+
1163
+ void XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
1164
+ L4FilterChain::OnRouteConfigChanged(
1165
+ absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
1166
+ route_config) {
1167
+ GRPC_TRACE_LOG(xds_server_config_fetcher, INFO)
1168
+ << "[L4FilterChain " << this << "]: received RDS update";
1169
+ if (!route_config.ok()) {
1170
+ auto& hcm = filter_chain_data_.http_connection_manager;
1171
+ auto& rds_resource_name = std::get<std::string>(hcm.route_config);
1172
+ route_config = absl::UnavailableError(
1173
+ absl::StrCat("RDS resource ", rds_resource_name, ": ",
1174
+ route_config.status().message()));
1175
+ }
1176
+ UpdateServerConfigSelector(std::move(route_config));
1177
+ connection_manager_->MaybeUpdateConnectionManager();
1178
+ }
1179
+
1180
+ void XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
1181
+ L4FilterChain::OnAmbientError(absl::Status status) {
1182
+ auto& hcm = filter_chain_data_.http_connection_manager;
1183
+ auto& rds_resource_name = std::get<std::string>(hcm.route_config);
1184
+ LOG(ERROR) << "XdsClient reports ambient error for RDS resource "
1185
+ << rds_resource_name << ": " << status;
1106
1186
  }
1107
1187
 
1108
1188
  //
1109
- // XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::XdsServerConfigSelector
1189
+ // XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::XdsServerConfigSelector
1110
1190
  //
1111
1191
 
1112
- absl::StatusOr<
1113
- RefCountedPtr<XdsServerConfigFetcher::ListenerWatcher::
1114
- FilterChainMatchManager::XdsServerConfigSelector>>
1115
- XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1192
+ absl::StatusOr<RefCountedPtr<
1193
+ XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::
1194
+ L4FilterChain::XdsServerConfigSelector>>
1195
+ XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::
1116
1196
  XdsServerConfigSelector::Create(
1117
1197
  const XdsHttpFilterRegistry& http_filter_registry,
1118
- std::shared_ptr<const XdsRouteConfigResource> rds_update,
1119
1198
  const std::vector<
1120
1199
  XdsListenerResource::HttpConnectionManager::HttpFilter>&
1121
- http_filters) {
1200
+ 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.
1122
1206
  auto config_selector = MakeRefCounted<XdsServerConfigSelector>();
1123
- for (auto& vhost : rds_update->virtual_hosts) {
1207
+ for (auto& vhost : route_config->virtual_hosts) {
1124
1208
  config_selector->virtual_hosts_.emplace_back();
1125
1209
  auto& virtual_host = config_selector->virtual_hosts_.back();
1126
- virtual_host.domains = vhost.domains;
1210
+ virtual_host.domains = &vhost.domains;
1127
1211
  for (auto& route : vhost.routes) {
1128
1212
  virtual_host.routes.emplace_back();
1129
1213
  auto& config_selector_route = virtual_host.routes.back();
1130
- config_selector_route.matchers = route.matchers;
1214
+ config_selector_route.matchers = &route.matchers;
1131
1215
  config_selector_route.unsupported_action =
1132
1216
  std::get_if<XdsRouteConfigResource::Route::NonForwardingAction>(
1133
1217
  &route.action) == nullptr;
@@ -1158,11 +1242,12 @@ XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1158
1242
  }
1159
1243
  }
1160
1244
  }
1245
+ config_selector->route_config_ = std::move(route_config);
1161
1246
  return config_selector;
1162
1247
  }
1163
1248
 
1164
1249
  absl::StatusOr<ServerConfigSelector::CallConfig>
1165
- XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1250
+ XdsServerConfigFetcher::ListenerWatcher::XdsConnectionManager::L4FilterChain::
1166
1251
  XdsServerConfigSelector::GetCallConfig(grpc_metadata_batch* metadata) {
1167
1252
  CallConfig call_config;
1168
1253
  if (metadata->get_pointer(HttpPathMetadata()) == nullptr) {
@@ -1176,7 +1261,7 @@ XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1176
1261
  absl::string_view authority =
1177
1262
  metadata->get_pointer(HttpAuthorityMetadata())->as_string_view();
1178
1263
  auto vhost_index = XdsRouting::FindVirtualHostForDomain(
1179
- VirtualHostListIterator(&virtual_hosts_), authority);
1264
+ VirtualHostListIterator(virtual_hosts_), authority);
1180
1265
  if (!vhost_index.has_value()) {
1181
1266
  return absl::UnavailableError(
1182
1267
  absl::StrCat("could not find VirtualHost for ", authority,
@@ -1184,118 +1269,22 @@ XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1184
1269
  }
1185
1270
  auto& virtual_host = virtual_hosts_[vhost_index.value()];
1186
1271
  auto route_index = XdsRouting::GetRouteForRequest(
1187
- VirtualHost::RouteListIterator(&virtual_host.routes), path, metadata);
1188
- if (route_index.has_value()) {
1189
- auto& route = virtual_host.routes[route_index.value()];
1190
- // Found the matching route
1191
- if (route.unsupported_action) {
1192
- return absl::UnavailableError("matching route has unsupported action");
1193
- }
1194
- if (route.method_config != nullptr) {
1195
- call_config.method_configs =
1196
- route.method_config->GetMethodParsedConfigVector(grpc_empty_slice());
1197
- call_config.service_config = route.method_config;
1198
- }
1199
- return call_config;
1200
- }
1201
- return absl::UnavailableError("no route matched");
1202
- }
1203
-
1204
- //
1205
- // XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::DynamicXdsServerConfigSelectorProvider
1206
- //
1207
-
1208
- XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1209
- DynamicXdsServerConfigSelectorProvider::
1210
- DynamicXdsServerConfigSelectorProvider(
1211
- RefCountedPtr<GrpcXdsClient> xds_client, std::string resource_name,
1212
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
1213
- initial_resource,
1214
- std::vector<XdsListenerResource::HttpConnectionManager::HttpFilter>
1215
- http_filters)
1216
- : xds_client_(std::move(xds_client)),
1217
- resource_name_(std::move(resource_name)),
1218
- http_filters_(std::move(http_filters)),
1219
- resource_(std::move(initial_resource)) {
1220
- GRPC_CHECK(!resource_name_.empty());
1221
- // RouteConfigWatcher is being created here instead of in Watch() to avoid
1222
- // deadlocks from invoking XdsRouteConfigResourceType::StartWatch whilst in a
1223
- // critical region.
1224
- auto route_config_watcher = MakeRefCounted<RouteConfigWatcher>(
1225
- WeakRefAsSubclass<DynamicXdsServerConfigSelectorProvider>());
1226
- route_config_watcher_ = route_config_watcher.get();
1227
- XdsRouteConfigResourceType::StartWatch(xds_client_.get(), resource_name_,
1228
- std::move(route_config_watcher));
1229
- }
1230
-
1231
- void XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1232
- DynamicXdsServerConfigSelectorProvider::Orphaned() {
1233
- XdsRouteConfigResourceType::CancelWatch(xds_client_.get(), resource_name_,
1234
- route_config_watcher_,
1235
- false /* delay_unsubscription */);
1236
- }
1237
-
1238
- absl::StatusOr<RefCountedPtr<ServerConfigSelector>>
1239
- XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1240
- DynamicXdsServerConfigSelectorProvider::Watch(
1241
- std::unique_ptr<
1242
- ServerConfigSelectorProvider::ServerConfigSelectorWatcher>
1243
- watcher) {
1244
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>> resource;
1245
- {
1246
- MutexLock lock(&mu_);
1247
- GRPC_CHECK(watcher_ == nullptr);
1248
- watcher_ = std::move(watcher);
1249
- resource = resource_;
1250
- }
1251
- if (!resource.ok()) {
1252
- return resource.status();
1253
- }
1254
- return XdsServerConfigSelector::Create(
1255
- DownCast<const GrpcXdsBootstrap&>(xds_client_->bootstrap())
1256
- .http_filter_registry(),
1257
- resource.value(), http_filters_);
1258
- }
1259
-
1260
- void XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1261
- DynamicXdsServerConfigSelectorProvider::CancelWatch() {
1262
- MutexLock lock(&mu_);
1263
- watcher_.reset();
1264
- }
1265
-
1266
- void XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1267
- DynamicXdsServerConfigSelectorProvider::OnRouteConfigChanged(
1268
- absl::StatusOr<std::shared_ptr<const XdsRouteConfigResource>>
1269
- rds_update) {
1270
- MutexLock lock(&mu_);
1271
- if (!rds_update.ok()) {
1272
- rds_update = absl::UnavailableError(absl::StrCat(
1273
- "RDS resource ", resource_name_, ": ", rds_update.status().message()));
1274
- }
1275
- resource_ = std::move(rds_update);
1276
- if (watcher_ == nullptr) {
1277
- return;
1278
- }
1279
- // Currently server_config_selector_filter does not call into
1280
- // DynamicXdsServerConfigSelectorProvider while holding a lock, but if that
1281
- // ever changes, we would want to invoke the update outside the critical
1282
- // region with the use of a WorkSerializer.
1283
- if (!resource_.ok()) {
1284
- watcher_->OnServerConfigSelectorUpdate(resource_.status());
1285
- } else {
1286
- watcher_->OnServerConfigSelectorUpdate(XdsServerConfigSelector::Create(
1287
- DownCast<const GrpcXdsBootstrap&>(xds_client_->bootstrap())
1288
- .http_filter_registry(),
1289
- *resource_, http_filters_));
1290
- }
1291
- }
1292
-
1293
- void XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
1294
- DynamicXdsServerConfigSelectorProvider::OnAmbientError(
1295
- absl::Status status) {
1296
- LOG(ERROR) << "RouteConfigWatcher:" << this
1297
- << " XdsClient reports ambient error: " << status << " for "
1298
- << resource_name_ << "; ignoring in favor of existing resource";
1272
+ VirtualHost::RouteListIterator(virtual_host.routes), path, metadata);
1273
+ if (!route_index.has_value()) {
1274
+ return absl::UnavailableError("no route matched");
1275
+ }
1276
+ auto& route = virtual_host.routes[*route_index];
1277
+ // Found the matching route
1278
+ if (route.unsupported_action) {
1279
+ return absl::UnavailableError("matching route has unsupported action");
1280
+ }
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;
1285
+ }
1286
+ // TODO(roth): Return the filter chain to use for this call.
1287
+ return call_config;
1299
1288
  }
1300
1289
 
1301
1290
  } // namespace