2
2
3
3
#include < net/if.h>
4
4
5
+ #include < memory>
6
+
5
7
#include " envoy/common/platform.h"
6
8
7
9
#include " source/common/api/os_sys_calls_impl.h"
@@ -79,11 +81,13 @@ constexpr unsigned int InitialFaultThreshold = 1;
79
81
// L7 bytes) before switching socket mode.
80
82
constexpr unsigned int MaxFaultThreshold = 3 ;
81
83
82
- ConnectivityManagerImpl::NetworkState ConnectivityManagerImpl::network_state_{
83
- 1 , 0 , MaxFaultThreshold, SocketMode::DefaultPreferredNetworkMode, Thread::MutexBasicLockable{}};
84
+ ConnectivityManagerImpl::DefaultNetworkState ConnectivityManagerImpl::network_state_{
85
+ 1 , 0 , MaxFaultThreshold, SocketMode::DefaultPreferredNetworkMode};
86
+
87
+ Thread::MutexBasicLockable ConnectivityManagerImpl::network_mutex_{};
84
88
85
89
envoy_netconf_t ConnectivityManagerImpl::setPreferredNetwork (int network) {
86
- Thread::LockGuard lock{network_state_. mutex_ };
90
+ Thread::LockGuard lock{network_mutex_ };
87
91
88
92
// TODO(goaway): Re-enable this guard. There's some concern that this will miss network updates
89
93
// moving from offline to online states. We should address this then re-enable this guard to
@@ -120,17 +124,17 @@ void ConnectivityManagerImpl::setProxySettings(ProxySettingsConstSharedPtr new_p
120
124
ProxySettingsConstSharedPtr ConnectivityManagerImpl::getProxySettings () { return proxy_settings_; }
121
125
122
126
int ConnectivityManagerImpl::getPreferredNetwork () {
123
- Thread::LockGuard lock{network_state_. mutex_ };
127
+ Thread::LockGuard lock{network_mutex_ };
124
128
return network_state_.network_ ;
125
129
}
126
130
127
131
SocketMode ConnectivityManagerImpl::getSocketMode () {
128
- Thread::LockGuard lock{network_state_. mutex_ };
132
+ Thread::LockGuard lock{network_mutex_ };
129
133
return network_state_.socket_mode_ ;
130
134
}
131
135
132
136
envoy_netconf_t ConnectivityManagerImpl::getConfigurationKey () {
133
- Thread::LockGuard lock{network_state_. mutex_ };
137
+ Thread::LockGuard lock{network_mutex_ };
134
138
return network_state_.configuration_key_ ;
135
139
}
136
140
@@ -152,7 +156,7 @@ void ConnectivityManagerImpl::reportNetworkUsage(envoy_netconf_t configuration_k
152
156
153
157
bool configuration_updated = false ;
154
158
{
155
- Thread::LockGuard lock{network_state_. mutex_ };
159
+ Thread::LockGuard lock{network_mutex_ };
156
160
157
161
// If the configuration_key isn't current, don't do anything.
158
162
if (configuration_key != network_state_.configuration_key_ ) {
@@ -200,40 +204,55 @@ void ConnectivityManagerImpl::reportNetworkUsage(envoy_netconf_t configuration_k
200
204
}
201
205
}
202
206
203
- void ConnectivityManagerImpl::onDnsResolutionComplete (
207
+ void RefreshDnsWithPostDrainHandler::refreshDnsAndDrainHosts () {
208
+ Extensions::Common::DynamicForwardProxy::DnsCacheSharedPtr dns_cache =
209
+ dns_cache_manager_->lookUpCacheByName (BaseDnsCache);
210
+ if (!dns_cache) {
211
+ // There may not be a DNS cache during initialization, but if one is available, it should always
212
+ // exist by the time this handler is instantiated from the NetworkConfigurationFilter.
213
+ ENVOY_LOG_EVENT (warn, " netconf_dns_cache_missing" , " {}" , std::string (BaseDnsCache));
214
+ return ;
215
+ }
216
+ if (dns_callbacks_handle_ == nullptr ) {
217
+ // Register callbacks once, on demand, using the handler as a sentinel.
218
+ dns_callbacks_handle_ = dns_cache->addUpdateCallbacks (*this );
219
+ }
220
+ dns_cache->iterateHostMap (
221
+ [&](absl::string_view host,
222
+ const Extensions::Common::DynamicForwardProxy::DnsHostInfoSharedPtr&) {
223
+ hosts_to_drain_.emplace (host);
224
+ });
225
+
226
+ dns_cache->forceRefreshHosts ();
227
+ }
228
+
229
+ void RefreshDnsWithPostDrainHandler::onDnsResolutionComplete (
204
230
const std::string& resolved_host,
205
231
const Extensions::Common::DynamicForwardProxy::DnsHostInfoSharedPtr&,
206
232
Network::DnsResolver::ResolutionStatus) {
207
- if (enable_drain_post_dns_refresh_) {
208
- // Check if the set of hosts pending drain contains the current resolved host.
209
- if (hosts_to_drain_.erase (resolved_host) == 0 ) {
210
- return ;
211
- }
233
+ // Check if the set of hosts pending drain contains the current resolved host.
234
+ if (hosts_to_drain_.erase (resolved_host) == 0 ) {
235
+ return ;
236
+ }
212
237
213
- // We ignore whether DNS resolution has succeeded here. If it failed, we may be offline and
214
- // should probably drain connections. If it succeeds, we may have new DNS entries and so we
215
- // drain connections. It may be possible to refine this logic in the future.
216
- // TODO(goaway): check the set of cached hosts from the last triggered DNS refresh for this
217
- // host, and if present, remove it and trigger connection drain for this host specifically.
218
- ENVOY_LOG_EVENT (debug, " netconf_post_dns_drain_cx" , " {}" , resolved_host);
238
+ // We ignore whether DNS resolution has succeeded here. If it failed, we may be offline and
239
+ // should probably drain connections. If it succeeds, we may have new DNS entries and so we
240
+ // drain connections. It may be possible to refine this logic in the future.
241
+ // TODO(goaway): check the set of cached hosts from the last triggered DNS refresh for this
242
+ // host, and if present, remove it and trigger connection drain for this host specifically.
243
+ ENVOY_LOG_EVENT (debug, " netconf_post_dns_drain_cx" , " {}" , resolved_host);
219
244
220
- // Pass predicate to only drain connections to the resolved host (for any cluster).
221
- cluster_manager_.drainConnections (
222
- [resolved_host](const Upstream::Host& host) { return host.hostname () == resolved_host; });
223
- }
245
+ // Pass predicate to only drain connections to the resolved host (for any cluster).
246
+ cluster_manager_.drainConnections (
247
+ [resolved_host](const Upstream::Host& host) { return host.hostname () == resolved_host; });
224
248
}
225
249
226
250
void ConnectivityManagerImpl::setDrainPostDnsRefreshEnabled (bool enabled) {
227
- enable_drain_post_dns_refresh_ = enabled;
228
251
if (!enabled) {
229
- hosts_to_drain_.clear ();
230
- } else if (!dns_callbacks_handle_) {
231
- // Register callbacks once, on demand, using the handle as a sentinel. There may not be
232
- // a DNS cache during initialization, but if one is available, it should always exist by the
233
- // time this function is called from the NetworkConfigurationFilter.
234
- if (auto dns_cache = dnsCache ()) {
235
- dns_callbacks_handle_ = dns_cache->addUpdateCallbacks (*this );
236
- }
252
+ dns_refresh_handler_ = nullptr ;
253
+ } else if (!dns_refresh_handler_) {
254
+ dns_refresh_handler_ =
255
+ std::make_unique<RefreshDnsWithPostDrainHandler>(dns_cache_manager_, cluster_manager_);
237
256
}
238
257
}
239
258
@@ -244,7 +263,7 @@ void ConnectivityManagerImpl::setInterfaceBindingEnabled(bool enabled) {
244
263
void ConnectivityManagerImpl::refreshDns (envoy_netconf_t configuration_key,
245
264
bool drain_connections) {
246
265
{
247
- Thread::LockGuard lock{network_state_. mutex_ };
266
+ Thread::LockGuard lock{network_mutex_ };
248
267
249
268
// refreshDns must be queued on Envoy's event loop, whereas network_state_ is updated
250
269
// synchronously. In the event that multiple refreshes become queued on the event loop,
@@ -260,15 +279,11 @@ void ConnectivityManagerImpl::refreshDns(envoy_netconf_t configuration_key,
260
279
if (auto dns_cache = dnsCache ()) {
261
280
ENVOY_LOG_EVENT (debug, " netconf_refresh_dns" , " {}" , std::to_string (configuration_key));
262
281
263
- if (drain_connections && enable_drain_post_dns_refresh_) {
264
- dns_cache->iterateHostMap (
265
- [&](absl::string_view host,
266
- const Extensions::Common::DynamicForwardProxy::DnsHostInfoSharedPtr&) {
267
- hosts_to_drain_.emplace (host);
268
- });
282
+ if (drain_connections && (dns_refresh_handler_ != nullptr )) {
283
+ dns_refresh_handler_->refreshDnsAndDrainHosts ();
284
+ } else {
285
+ dns_cache->forceRefreshHosts ();
269
286
}
270
-
271
- dns_cache->forceRefreshHosts ();
272
287
}
273
288
}
274
289
@@ -283,7 +298,7 @@ Extensions::Common::DynamicForwardProxy::DnsCacheSharedPtr ConnectivityManagerIm
283
298
void ConnectivityManagerImpl::resetConnectivityState () {
284
299
envoy_netconf_t configuration_key;
285
300
{
286
- Thread::LockGuard lock{network_state_. mutex_ };
301
+ Thread::LockGuard lock{network_mutex_ };
287
302
network_state_.network_ = 0 ;
288
303
network_state_.remaining_faults_ = 1 ;
289
304
network_state_.socket_mode_ = SocketMode::DefaultPreferredNetworkMode;
@@ -359,7 +374,7 @@ ConnectivityManagerImpl::addUpstreamSocketOptions(Socket::OptionsSharedPtr optio
359
374
SocketMode socket_mode;
360
375
361
376
{
362
- Thread::LockGuard lock{network_state_. mutex_ };
377
+ Thread::LockGuard lock{network_mutex_ };
363
378
configuration_key = network_state_.configuration_key_ ;
364
379
network = network_state_.network_ ;
365
380
socket_mode = network_state_.socket_mode_ ;
0 commit comments