1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/dns/host_resolver_manager.h"
6
7 #include <cmath>
8 #include <cstdint>
9 #include <iterator>
10 #include <limits>
11 #include <memory>
12 #include <numeric>
13 #include <optional>
14 #include <set>
15 #include <string>
16 #include <string_view>
17 #include <tuple>
18 #include <unordered_set>
19 #include <utility>
20 #include <vector>
21
22 #include "base/check_op.h"
23 #include "base/compiler_specific.h"
24 #include "base/containers/circular_deque.h"
25 #include "base/containers/contains.h"
26 #include "base/containers/flat_set.h"
27 #include "base/containers/linked_list.h"
28 #include "base/debug/debugger.h"
29 #include "base/feature_list.h"
30 #include "base/functional/bind.h"
31 #include "base/functional/callback.h"
32 #include "base/functional/callback_helpers.h"
33 #include "base/location.h"
34 #include "base/logging.h"
35 #include "base/memory/ptr_util.h"
36 #include "base/memory/raw_ptr.h"
37 #include "base/memory/safe_ref.h"
38 #include "base/memory/weak_ptr.h"
39 #include "base/metrics/field_trial.h"
40 #include "base/metrics/field_trial_params.h"
41 #include "base/metrics/histogram_functions.h"
42 #include "base/metrics/histogram_macros.h"
43 #include "base/no_destructor.h"
44 #include "base/numerics/safe_conversions.h"
45 #include "base/observer_list.h"
46 #include "base/ranges/algorithm.h"
47 #include "base/sequence_checker.h"
48 #include "base/strings/strcat.h"
49 #include "base/strings/string_number_conversions.h"
50 #include "base/strings/string_split.h"
51 #include "base/strings/string_util.h"
52 #include "base/strings/stringprintf.h"
53 #include "base/strings/utf_string_conversions.h"
54 #include "base/task/sequenced_task_runner.h"
55 #include "base/task/single_thread_task_runner.h"
56 #include "base/task/thread_pool.h"
57 #include "base/threading/scoped_blocking_call.h"
58 #include "base/time/default_tick_clock.h"
59 #include "base/time/time.h"
60 #include "base/types/optional_util.h"
61 #include "base/values.h"
62 #include "build/build_config.h"
63 #include "net/base/address_family.h"
64 #include "net/base/address_list.h"
65 #include "net/base/completion_once_callback.h"
66 #include "net/base/features.h"
67 #include "net/base/host_port_pair.h"
68 #include "net/base/ip_address.h"
69 #include "net/base/ip_endpoint.h"
70 #include "net/base/net_errors.h"
71 #include "net/base/network_anonymization_key.h"
72 #include "net/base/network_change_notifier.h"
73 #include "net/base/network_interfaces.h"
74 #include "net/base/prioritized_dispatcher.h"
75 #include "net/base/request_priority.h"
76 #include "net/base/trace_constants.h"
77 #include "net/base/tracing.h"
78 #include "net/base/url_util.h"
79 #include "net/dns/dns_alias_utility.h"
80 #include "net/dns/dns_client.h"
81 #include "net/dns/dns_names_util.h"
82 #include "net/dns/dns_response.h"
83 #include "net/dns/dns_response_result_extractor.h"
84 #include "net/dns/dns_transaction.h"
85 #include "net/dns/dns_util.h"
86 #include "net/dns/host_cache.h"
87 #include "net/dns/host_resolver_dns_task.h"
88 #include "net/dns/host_resolver_internal_result.h"
89 #include "net/dns/host_resolver_manager_job.h"
90 #include "net/dns/host_resolver_manager_request_impl.h"
91 #include "net/dns/host_resolver_manager_service_endpoint_request_impl.h"
92 #include "net/dns/host_resolver_mdns_listener_impl.h"
93 #include "net/dns/host_resolver_mdns_task.h"
94 #include "net/dns/host_resolver_nat64_task.h"
95 #include "net/dns/host_resolver_proc.h"
96 #include "net/dns/host_resolver_system_task.h"
97 #include "net/dns/httpssvc_metrics.h"
98 #include "net/dns/loopback_only.h"
99 #include "net/dns/mdns_client.h"
100 #include "net/dns/public/dns_protocol.h"
101 #include "net/dns/public/dns_query_type.h"
102 #include "net/dns/public/host_resolver_results.h"
103 #include "net/dns/public/resolve_error_info.h"
104 #include "net/dns/public/secure_dns_mode.h"
105 #include "net/dns/public/secure_dns_policy.h"
106 #include "net/dns/public/util.h"
107 #include "net/dns/record_parsed.h"
108 #include "net/dns/resolve_context.h"
109 #include "net/dns/test_dns_config_service.h"
110 #include "net/http/http_network_session.h"
111 #include "net/log/net_log.h"
112 #include "net/log/net_log_capture_mode.h"
113 #include "net/log/net_log_event_type.h"
114 #include "net/log/net_log_source.h"
115 #include "net/log/net_log_source_type.h"
116 #include "net/log/net_log_with_source.h"
117 #include "net/socket/client_socket_factory.h"
118 #include "net/url_request/url_request_context.h"
119 #include "third_party/abseil-cpp/absl/types/variant.h"
120 #include "url/scheme_host_port.h"
121 #include "url/url_constants.h"
122
123 #if BUILDFLAG(ENABLE_MDNS)
124 #include "net/dns/mdns_client_impl.h"
125 #endif
126
127 #if BUILDFLAG(IS_WIN)
128 #include <Winsock2.h>
129 #include "net/base/winsock_init.h"
130 #endif
131
132 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
133 #include <net/if.h>
134 #include "net/base/sys_addrinfo.h"
135 #if BUILDFLAG(IS_ANDROID)
136 #include "base/android/build_info.h"
137 #else // !BUILDFLAG(IS_ANDROID)
138 #include <ifaddrs.h>
139 #endif // BUILDFLAG(IS_ANDROID)
140 #endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
141
142 namespace net {
143
144 namespace {
145
146 // Limit the size of hostnames that will be resolved to combat issues in
147 // some platform's resolvers.
148 const size_t kMaxHostLength = 4096;
149
150 // Time between IPv6 probes, i.e. for how long results of each IPv6 probe are
151 // cached.
152 const int kIPv6ProbePeriodMs = 1000;
153
154 // Google DNS address used for IPv6 probes.
155 const uint8_t kIPv6ProbeAddress[] = {0x20, 0x01, 0x48, 0x60, 0x48, 0x60,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x88, 0x88};
158
159 // True if |hostname| ends with either ".local" or ".local.".
ResemblesMulticastDNSName(std::string_view hostname)160 bool ResemblesMulticastDNSName(std::string_view hostname) {
161 return hostname.ends_with(".local") || hostname.ends_with(".local.");
162 }
163
ConfigureAsyncDnsNoFallbackFieldTrial()164 bool ConfigureAsyncDnsNoFallbackFieldTrial() {
165 const bool kDefault = false;
166
167 // Configure the AsyncDns field trial as follows:
168 // groups AsyncDnsNoFallbackA and AsyncDnsNoFallbackB: return true,
169 // groups AsyncDnsA and AsyncDnsB: return false,
170 // groups SystemDnsA and SystemDnsB: return false,
171 // otherwise (trial absent): return default.
172 std::string group_name = base::FieldTrialList::FindFullName("AsyncDns");
173 if (!group_name.empty()) {
174 return base::StartsWith(group_name, "AsyncDnsNoFallback",
175 base::CompareCase::INSENSITIVE_ASCII);
176 }
177 return kDefault;
178 }
179
NetLogIPv6AvailableParams(bool ipv6_available,bool cached)180 base::Value::Dict NetLogIPv6AvailableParams(bool ipv6_available, bool cached) {
181 base::Value::Dict dict;
182 dict.Set("ipv6_available", ipv6_available);
183 dict.Set("cached", cached);
184 return dict;
185 }
186
187 // Maximum of 64 concurrent resolver calls (excluding retries).
188 // Between 2010 and 2020, the limit was set to 6 because of a report of a broken
189 // home router that would fail in the presence of more simultaneous queries.
190 // In 2020, we conducted an experiment to see if this kind of router was still
191 // present on the Internet, and found no evidence of any remaining issues, so
192 // we increased the limit to 64 at that time.
193 const size_t kDefaultMaxSystemTasks = 64u;
194
GetDispatcherLimits(const HostResolver::ManagerOptions & options)195 PrioritizedDispatcher::Limits GetDispatcherLimits(
196 const HostResolver::ManagerOptions& options) {
197 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES,
198 options.max_concurrent_resolves);
199
200 // If not using default, do not use the field trial.
201 if (limits.total_jobs != HostResolver::ManagerOptions::kDefaultParallelism)
202 return limits;
203
204 // Default, without trial is no reserved slots.
205 limits.total_jobs = kDefaultMaxSystemTasks;
206
207 // Parallelism is determined by the field trial.
208 std::string group =
209 base::FieldTrialList::FindFullName("HostResolverDispatch");
210
211 if (group.empty())
212 return limits;
213
214 // The format of the group name is a list of non-negative integers separated
215 // by ':'. Each of the elements in the list corresponds to an element in
216 // |reserved_slots|, except the last one which is the |total_jobs|.
217 std::vector<std::string_view> group_parts = base::SplitStringPiece(
218 group, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
219 if (group_parts.size() != NUM_PRIORITIES + 1) {
220 NOTREACHED();
221 return limits;
222 }
223
224 std::vector<size_t> parsed(group_parts.size());
225 for (size_t i = 0; i < group_parts.size(); ++i) {
226 if (!base::StringToSizeT(group_parts[i], &parsed[i])) {
227 NOTREACHED();
228 return limits;
229 }
230 }
231
232 const size_t total_jobs = parsed.back();
233 parsed.pop_back();
234
235 const size_t total_reserved_slots =
236 std::accumulate(parsed.begin(), parsed.end(), 0u);
237
238 // There must be some unreserved slots available for the all priorities.
239 if (total_reserved_slots > total_jobs ||
240 (total_reserved_slots == total_jobs && parsed[MINIMUM_PRIORITY] == 0)) {
241 NOTREACHED();
242 return limits;
243 }
244
245 limits.total_jobs = total_jobs;
246 limits.reserved_slots = parsed;
247 return limits;
248 }
249
NetLogResults(const HostCache::Entry & results)250 base::Value::Dict NetLogResults(const HostCache::Entry& results) {
251 base::Value::Dict dict;
252 dict.Set("results", results.NetLogParams());
253 return dict;
254 }
255
FilterAddresses(std::vector<IPEndPoint> addresses,DnsQueryTypeSet query_types)256 std::vector<IPEndPoint> FilterAddresses(std::vector<IPEndPoint> addresses,
257 DnsQueryTypeSet query_types) {
258 DCHECK(!query_types.Has(DnsQueryType::UNSPECIFIED));
259 DCHECK(!query_types.empty());
260
261 const AddressFamily want_family =
262 HostResolver::DnsQueryTypeSetToAddressFamily(query_types);
263
264 if (want_family == ADDRESS_FAMILY_UNSPECIFIED)
265 return addresses;
266
267 // Keep only the endpoints that match `want_family`.
268 addresses.erase(
269 base::ranges::remove_if(
270 addresses,
271 [want_family](AddressFamily family) { return family != want_family; },
272 &IPEndPoint::GetFamily),
273 addresses.end());
274 return addresses;
275 }
276
GetPortForGloballyReachableCheck()277 int GetPortForGloballyReachableCheck() {
278 if (!base::FeatureList::IsEnabled(
279 features::kUseAlternativePortForGloballyReachableCheck)) {
280 return 443;
281 }
282 return features::kAlternativePortForGloballyReachableCheck.Get();
283 }
284
285 } // namespace
286
287 //-----------------------------------------------------------------------------
288
ResolveLocalHostname(std::string_view host,std::vector<IPEndPoint> * address_list)289 bool ResolveLocalHostname(std::string_view host,
290 std::vector<IPEndPoint>* address_list) {
291 address_list->clear();
292 if (!IsLocalHostname(host))
293 return false;
294
295 address_list->emplace_back(IPAddress::IPv6Localhost(), 0);
296 address_list->emplace_back(IPAddress::IPv4Localhost(), 0);
297
298 return true;
299 }
300
301 class HostResolverManager::ProbeRequestImpl
302 : public HostResolver::ProbeRequest,
303 public ResolveContext::DohStatusObserver {
304 public:
ProbeRequestImpl(base::WeakPtr<ResolveContext> context,base::WeakPtr<HostResolverManager> resolver)305 ProbeRequestImpl(base::WeakPtr<ResolveContext> context,
306 base::WeakPtr<HostResolverManager> resolver)
307 : context_(std::move(context)), resolver_(std::move(resolver)) {}
308
309 ProbeRequestImpl(const ProbeRequestImpl&) = delete;
310 ProbeRequestImpl& operator=(const ProbeRequestImpl&) = delete;
311
~ProbeRequestImpl()312 ~ProbeRequestImpl() override {
313 // Ensure that observers are deregistered to avoid wasting memory.
314 if (context_)
315 context_->UnregisterDohStatusObserver(this);
316 }
317
Start()318 int Start() override {
319 DCHECK(resolver_);
320 DCHECK(!runner_);
321
322 if (!context_)
323 return ERR_CONTEXT_SHUT_DOWN;
324
325 context_->RegisterDohStatusObserver(this);
326
327 StartRunner(false /* network_change */);
328 return ERR_IO_PENDING;
329 }
330
331 // ResolveContext::DohStatusObserver
OnSessionChanged()332 void OnSessionChanged() override { CancelRunner(); }
333
OnDohServerUnavailable(bool network_change)334 void OnDohServerUnavailable(bool network_change) override {
335 // Start the runner asynchronously, as this may trigger reentrant calls into
336 // HostResolverManager, which are not allowed during notification handling.
337 base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
338 FROM_HERE,
339 base::BindOnce(&ProbeRequestImpl::StartRunner,
340 weak_ptr_factory_.GetWeakPtr(), network_change));
341 }
342
343 private:
StartRunner(bool network_change)344 void StartRunner(bool network_change) {
345 DCHECK(resolver_);
346 DCHECK(!resolver_->invalidation_in_progress_);
347
348 if (!context_)
349 return; // Reachable if the context ends before a posted task runs.
350
351 if (!runner_)
352 runner_ = resolver_->CreateDohProbeRunner(context_.get());
353 if (runner_)
354 runner_->Start(network_change);
355 }
356
CancelRunner()357 void CancelRunner() {
358 runner_.reset();
359
360 // Cancel any asynchronous StartRunner() calls.
361 weak_ptr_factory_.InvalidateWeakPtrs();
362 }
363
364 base::WeakPtr<ResolveContext> context_;
365
366 std::unique_ptr<DnsProbeRunner> runner_;
367 base::WeakPtr<HostResolverManager> resolver_;
368
369 base::WeakPtrFactory<ProbeRequestImpl> weak_ptr_factory_{this};
370 };
371
372 //-----------------------------------------------------------------------------
373
HostResolverManager(const HostResolver::ManagerOptions & options,SystemDnsConfigChangeNotifier * system_dns_config_notifier,NetLog * net_log)374 HostResolverManager::HostResolverManager(
375 const HostResolver::ManagerOptions& options,
376 SystemDnsConfigChangeNotifier* system_dns_config_notifier,
377 NetLog* net_log)
378 : HostResolverManager(PassKey(),
379 options,
380 system_dns_config_notifier,
381 handles::kInvalidNetworkHandle,
382 net_log) {}
383
HostResolverManager(base::PassKey<HostResolverManager>,const HostResolver::ManagerOptions & options,SystemDnsConfigChangeNotifier * system_dns_config_notifier,handles::NetworkHandle target_network,NetLog * net_log)384 HostResolverManager::HostResolverManager(
385 base::PassKey<HostResolverManager>,
386 const HostResolver::ManagerOptions& options,
387 SystemDnsConfigChangeNotifier* system_dns_config_notifier,
388 handles::NetworkHandle target_network,
389 NetLog* net_log)
390 : host_resolver_system_params_(nullptr, options.max_system_retry_attempts),
391 net_log_(net_log),
392 system_dns_config_notifier_(system_dns_config_notifier),
393 target_network_(target_network),
394 check_ipv6_on_wifi_(options.check_ipv6_on_wifi),
395 ipv6_reachability_override_(base::FeatureList::IsEnabled(
396 features::kEnableIPv6ReachabilityOverride)),
397 tick_clock_(base::DefaultTickClock::GetInstance()),
398 https_svcb_options_(
399 options.https_svcb_options
400 ? *options.https_svcb_options
401 : HostResolver::HttpsSvcbOptions::FromFeatures()) {
402 PrioritizedDispatcher::Limits job_limits = GetDispatcherLimits(options);
403 dispatcher_ = std::make_unique<PrioritizedDispatcher>(job_limits);
404 max_queued_jobs_ = job_limits.total_jobs * 100u;
405
406 DCHECK_GE(dispatcher_->num_priorities(), static_cast<size_t>(NUM_PRIORITIES));
407
408 #if BUILDFLAG(IS_WIN)
409 EnsureWinsockInit();
410 #endif
411 #if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_ANDROID)) || \
412 BUILDFLAG(IS_FUCHSIA)
413 RunLoopbackProbeJob();
414 #endif
415 // Network-bound HostResolverManagers don't need to act on network changes.
416 if (!IsBoundToNetwork()) {
417 NetworkChangeNotifier::AddIPAddressObserver(this);
418 NetworkChangeNotifier::AddConnectionTypeObserver(this);
419 }
420 if (system_dns_config_notifier_)
421 system_dns_config_notifier_->AddObserver(this);
422 EnsureSystemHostResolverCallReady();
423
424 auto connection_type =
425 IsBoundToNetwork()
426 ? NetworkChangeNotifier::GetNetworkConnectionType(target_network)
427 : NetworkChangeNotifier::GetConnectionType();
428 UpdateConnectionType(connection_type);
429
430 #if defined(ENABLE_BUILT_IN_DNS)
431 dns_client_ = DnsClient::CreateClient(net_log_);
432 dns_client_->SetInsecureEnabled(
433 options.insecure_dns_client_enabled,
434 options.additional_types_via_insecure_dns_enabled);
435 dns_client_->SetConfigOverrides(options.dns_config_overrides);
436 #else
437 DCHECK(options.dns_config_overrides == DnsConfigOverrides());
438 #endif
439
440 allow_fallback_to_systemtask_ = !ConfigureAsyncDnsNoFallbackFieldTrial();
441 }
442
~HostResolverManager()443 HostResolverManager::~HostResolverManager() {
444 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
445 // Prevent the dispatcher from starting new jobs.
446 dispatcher_->SetLimitsToZero();
447 // It's now safe for Jobs to call KillDnsTask on destruction, because
448 // OnJobComplete will not start any new jobs.
449 jobs_.clear();
450
451 if (target_network_ == handles::kInvalidNetworkHandle) {
452 NetworkChangeNotifier::RemoveIPAddressObserver(this);
453 NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
454 }
455 if (system_dns_config_notifier_)
456 system_dns_config_notifier_->RemoveObserver(this);
457 }
458
459 // static
460 std::unique_ptr<HostResolverManager>
CreateNetworkBoundHostResolverManager(const HostResolver::ManagerOptions & options,handles::NetworkHandle target_network,NetLog * net_log)461 HostResolverManager::CreateNetworkBoundHostResolverManager(
462 const HostResolver::ManagerOptions& options,
463 handles::NetworkHandle target_network,
464 NetLog* net_log) {
465 #if BUILDFLAG(IS_ANDROID)
466 DCHECK(NetworkChangeNotifier::AreNetworkHandlesSupported());
467 return std::make_unique<HostResolverManager>(
468 PassKey(), options, nullptr /* system_dns_config_notifier */,
469 target_network, net_log);
470 #else // !BUILDFLAG(IS_ANDROID)
471 NOTIMPLEMENTED();
472 return nullptr;
473 #endif // BUILDFLAG(IS_ANDROID)
474 }
475
476 std::unique_ptr<HostResolver::ResolveHostRequest>
CreateRequest(absl::variant<url::SchemeHostPort,HostPortPair> host,NetworkAnonymizationKey network_anonymization_key,NetLogWithSource net_log,std::optional<ResolveHostParameters> optional_parameters,ResolveContext * resolve_context)477 HostResolverManager::CreateRequest(
478 absl::variant<url::SchemeHostPort, HostPortPair> host,
479 NetworkAnonymizationKey network_anonymization_key,
480 NetLogWithSource net_log,
481 std::optional<ResolveHostParameters> optional_parameters,
482 ResolveContext* resolve_context) {
483 return CreateRequest(HostResolver::Host(std::move(host)),
484 std::move(network_anonymization_key), std::move(net_log),
485 std::move(optional_parameters), resolve_context);
486 }
487
488 std::unique_ptr<HostResolver::ResolveHostRequest>
CreateRequest(HostResolver::Host host,NetworkAnonymizationKey network_anonymization_key,NetLogWithSource net_log,std::optional<ResolveHostParameters> optional_parameters,ResolveContext * resolve_context)489 HostResolverManager::CreateRequest(
490 HostResolver::Host host,
491 NetworkAnonymizationKey network_anonymization_key,
492 NetLogWithSource net_log,
493 std::optional<ResolveHostParameters> optional_parameters,
494 ResolveContext* resolve_context) {
495 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
496 DCHECK(!invalidation_in_progress_);
497
498 DCHECK_EQ(resolve_context->GetTargetNetwork(), target_network_);
499 // ResolveContexts must register (via RegisterResolveContext()) before use to
500 // ensure cached data is invalidated on network and configuration changes.
501 DCHECK(registered_contexts_.HasObserver(resolve_context));
502
503 return std::make_unique<RequestImpl>(
504 std::move(net_log), std::move(host), std::move(network_anonymization_key),
505 std::move(optional_parameters), resolve_context->GetWeakPtr(),
506 weak_ptr_factory_.GetWeakPtr(), tick_clock_);
507 }
508
509 std::unique_ptr<HostResolver::ProbeRequest>
CreateDohProbeRequest(ResolveContext * context)510 HostResolverManager::CreateDohProbeRequest(ResolveContext* context) {
511 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
512
513 return std::make_unique<ProbeRequestImpl>(context->GetWeakPtr(),
514 weak_ptr_factory_.GetWeakPtr());
515 }
516
517 std::unique_ptr<HostResolver::MdnsListener>
CreateMdnsListener(const HostPortPair & host,DnsQueryType query_type)518 HostResolverManager::CreateMdnsListener(const HostPortPair& host,
519 DnsQueryType query_type) {
520 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
521 DCHECK_NE(DnsQueryType::UNSPECIFIED, query_type);
522
523 auto listener =
524 std::make_unique<HostResolverMdnsListenerImpl>(host, query_type);
525
526 MDnsClient* client;
527 int rv = GetOrCreateMdnsClient(&client);
528
529 if (rv == OK) {
530 std::unique_ptr<net::MDnsListener> inner_listener = client->CreateListener(
531 DnsQueryTypeToQtype(query_type), host.host(), listener.get());
532 listener->set_inner_listener(std::move(inner_listener));
533 } else {
534 listener->set_initialization_error(rv);
535 }
536 return listener;
537 }
538
539 std::unique_ptr<HostResolver::ServiceEndpointRequest>
CreateServiceEndpointRequest(url::SchemeHostPort scheme_host_port,NetworkAnonymizationKey network_anonymization_key,NetLogWithSource net_log,ResolveHostParameters parameters,ResolveContext * resolve_context)540 HostResolverManager::CreateServiceEndpointRequest(
541 url::SchemeHostPort scheme_host_port,
542 NetworkAnonymizationKey network_anonymization_key,
543 NetLogWithSource net_log,
544 ResolveHostParameters parameters,
545 ResolveContext* resolve_context) {
546 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
547 DCHECK(!invalidation_in_progress_);
548 DCHECK_EQ(resolve_context->GetTargetNetwork(), target_network_);
549 if (resolve_context) {
550 DCHECK(registered_contexts_.HasObserver(resolve_context));
551 }
552
553 return std::make_unique<ServiceEndpointRequestImpl>(
554 std::move(scheme_host_port), std::move(network_anonymization_key),
555 std::move(net_log), std::move(parameters),
556 resolve_context ? resolve_context->GetWeakPtr() : nullptr,
557 weak_ptr_factory_.GetWeakPtr(), tick_clock_);
558 }
559
SetInsecureDnsClientEnabled(bool enabled,bool additional_dns_types_enabled)560 void HostResolverManager::SetInsecureDnsClientEnabled(
561 bool enabled,
562 bool additional_dns_types_enabled) {
563 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
564
565 if (!dns_client_)
566 return;
567
568 bool enabled_before = dns_client_->CanUseInsecureDnsTransactions();
569 bool additional_types_before =
570 enabled_before && dns_client_->CanQueryAdditionalTypesViaInsecureDns();
571 dns_client_->SetInsecureEnabled(enabled, additional_dns_types_enabled);
572
573 // Abort current tasks if `CanUseInsecureDnsTransactions()` changes or if
574 // insecure transactions are enabled and
575 // `CanQueryAdditionalTypesViaInsecureDns()` changes. Changes to allowing
576 // additional types don't matter if insecure transactions are completely
577 // disabled.
578 if (dns_client_->CanUseInsecureDnsTransactions() != enabled_before ||
579 (dns_client_->CanUseInsecureDnsTransactions() &&
580 dns_client_->CanQueryAdditionalTypesViaInsecureDns() !=
581 additional_types_before)) {
582 AbortInsecureDnsTasks(ERR_NETWORK_CHANGED, false /* fallback_only */);
583 }
584 }
585
GetDnsConfigAsValue() const586 base::Value::Dict HostResolverManager::GetDnsConfigAsValue() const {
587 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
588 return dns_client_ ? dns_client_->GetDnsConfigAsValueForNetLog()
589 : base::Value::Dict();
590 }
591
SetDnsConfigOverrides(DnsConfigOverrides overrides)592 void HostResolverManager::SetDnsConfigOverrides(DnsConfigOverrides overrides) {
593 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
594
595 if (!dns_client_ && overrides == DnsConfigOverrides())
596 return;
597
598 // Not allowed to set overrides if compiled without DnsClient.
599 DCHECK(dns_client_);
600
601 bool transactions_allowed_before =
602 dns_client_->CanUseSecureDnsTransactions() ||
603 dns_client_->CanUseInsecureDnsTransactions();
604 bool changed = dns_client_->SetConfigOverrides(std::move(overrides));
605
606 if (changed) {
607 NetworkChangeNotifier::TriggerNonSystemDnsChange();
608
609 // Only invalidate cache if new overrides have resulted in a config change.
610 InvalidateCaches();
611
612 // Need to update jobs iff transactions were previously allowed because
613 // in-progress jobs may be running using a now-invalid configuration.
614 if (transactions_allowed_before) {
615 UpdateJobsForChangedConfig();
616 }
617 }
618 }
619
RegisterResolveContext(ResolveContext * context)620 void HostResolverManager::RegisterResolveContext(ResolveContext* context) {
621 registered_contexts_.AddObserver(context);
622 context->InvalidateCachesAndPerSessionData(
623 dns_client_ ? dns_client_->GetCurrentSession() : nullptr,
624 false /* network_change */);
625 }
626
DeregisterResolveContext(const ResolveContext * context)627 void HostResolverManager::DeregisterResolveContext(
628 const ResolveContext* context) {
629 registered_contexts_.RemoveObserver(context);
630
631 // Destroy Jobs when their context is closed.
632 RemoveAllJobs(context);
633 }
634
SetTickClockForTesting(const base::TickClock * tick_clock)635 void HostResolverManager::SetTickClockForTesting(
636 const base::TickClock* tick_clock) {
637 tick_clock_ = tick_clock;
638 }
639
SetIPv6ReachabilityOverride(bool reachability_override)640 void HostResolverManager::SetIPv6ReachabilityOverride(
641 bool reachability_override) {
642 ipv6_reachability_override_ = reachability_override;
643 }
644
SetMaxQueuedJobsForTesting(size_t value)645 void HostResolverManager::SetMaxQueuedJobsForTesting(size_t value) {
646 DCHECK_EQ(0u, dispatcher_->num_queued_jobs());
647 DCHECK_GE(value, 0u);
648 max_queued_jobs_ = value;
649 }
650
SetHaveOnlyLoopbackAddresses(bool result)651 void HostResolverManager::SetHaveOnlyLoopbackAddresses(bool result) {
652 if (result) {
653 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY;
654 } else {
655 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY;
656 }
657 }
658
SetMdnsSocketFactoryForTesting(std::unique_ptr<MDnsSocketFactory> socket_factory)659 void HostResolverManager::SetMdnsSocketFactoryForTesting(
660 std::unique_ptr<MDnsSocketFactory> socket_factory) {
661 DCHECK(!mdns_client_);
662 mdns_socket_factory_ = std::move(socket_factory);
663 }
664
SetMdnsClientForTesting(std::unique_ptr<MDnsClient> client)665 void HostResolverManager::SetMdnsClientForTesting(
666 std::unique_ptr<MDnsClient> client) {
667 mdns_client_ = std::move(client);
668 }
669
SetDnsClientForTesting(std::unique_ptr<DnsClient> dns_client)670 void HostResolverManager::SetDnsClientForTesting(
671 std::unique_ptr<DnsClient> dns_client) {
672 DCHECK(dns_client);
673 if (dns_client_) {
674 if (!dns_client->GetSystemConfigForTesting())
675 dns_client->SetSystemConfig(dns_client_->GetSystemConfigForTesting());
676 dns_client->SetConfigOverrides(dns_client_->GetConfigOverridesForTesting());
677 }
678 dns_client_ = std::move(dns_client);
679 // Inform `registered_contexts_` of the new `DnsClient`.
680 InvalidateCaches();
681 }
682
SetLastIPv6ProbeResultForTesting(bool last_ipv6_probe_result)683 void HostResolverManager::SetLastIPv6ProbeResultForTesting(
684 bool last_ipv6_probe_result) {
685 SetLastIPv6ProbeResult(last_ipv6_probe_result);
686 }
687
688 // static
IsLocalTask(TaskType task)689 bool HostResolverManager::IsLocalTask(TaskType task) {
690 switch (task) {
691 case TaskType::SECURE_CACHE_LOOKUP:
692 case TaskType::INSECURE_CACHE_LOOKUP:
693 case TaskType::CACHE_LOOKUP:
694 case TaskType::CONFIG_PRESET:
695 case TaskType::HOSTS:
696 return true;
697 default:
698 return false;
699 }
700 }
701
InitializeJobKeyAndIPAddress(const NetworkAnonymizationKey & network_anonymization_key,const ResolveHostParameters & parameters,const NetLogWithSource & source_net_log,JobKey & out_job_key,IPAddress & out_ip_address)702 void HostResolverManager::InitializeJobKeyAndIPAddress(
703 const NetworkAnonymizationKey& network_anonymization_key,
704 const ResolveHostParameters& parameters,
705 const NetLogWithSource& source_net_log,
706 JobKey& out_job_key,
707 IPAddress& out_ip_address) {
708 out_job_key.network_anonymization_key = network_anonymization_key;
709 out_job_key.source = parameters.source;
710
711 const bool is_ip = out_ip_address.AssignFromIPLiteral(
712 out_job_key.host.GetHostnameWithoutBrackets());
713
714 out_job_key.secure_dns_mode =
715 GetEffectiveSecureDnsMode(parameters.secure_dns_policy);
716 out_job_key.flags = HostResolver::ParametersToHostResolverFlags(parameters) |
717 additional_resolver_flags_;
718
719 if (parameters.dns_query_type != DnsQueryType::UNSPECIFIED) {
720 out_job_key.query_types = {parameters.dns_query_type};
721 return;
722 }
723
724 DnsQueryTypeSet effective_types = {DnsQueryType::A, DnsQueryType::AAAA};
725
726 // Disable AAAA queries when we cannot do anything with the results.
727 bool use_local_ipv6 = true;
728 if (dns_client_) {
729 const DnsConfig* config = dns_client_->GetEffectiveConfig();
730 if (config) {
731 use_local_ipv6 = config->use_local_ipv6;
732 }
733 }
734 // When resolving IPv4 literals, there's no need to probe for IPv6. When
735 // resolving IPv6 literals, there's no benefit to artificially limiting our
736 // resolution based on a probe. Prior logic ensures that this is an automatic
737 // query, so the code requesting the resolution should be amenable to
738 // receiving an IPv6 resolution.
739 if (!use_local_ipv6 && !is_ip && !last_ipv6_probe_result_ &&
740 !ipv6_reachability_override_) {
741 out_job_key.flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
742 effective_types.Remove(DnsQueryType::AAAA);
743 }
744
745 // Optimistically enable feature-controlled queries. These queries may be
746 // skipped at a later point.
747
748 // `https_svcb_options_.enable` has precedence, so if enabled, ignore any
749 // other related features.
750 if (https_svcb_options_.enable && out_job_key.host.HasScheme()) {
751 static const char* const kSchemesForHttpsQuery[] = {
752 url::kHttpScheme, url::kHttpsScheme, url::kWsScheme, url::kWssScheme};
753 if (base::Contains(kSchemesForHttpsQuery, out_job_key.host.GetScheme())) {
754 effective_types.Put(DnsQueryType::HTTPS);
755 }
756 }
757
758 out_job_key.query_types = effective_types;
759 }
760
ResolveLocally(bool only_ipv6_reachable,const JobKey & job_key,const IPAddress & ip_address,ResolveHostParameters::CacheUsage cache_usage,SecureDnsPolicy secure_dns_policy,HostResolverSource source,const NetLogWithSource & source_net_log,HostCache * cache,std::deque<TaskType> * out_tasks,std::optional<HostCache::EntryStaleness> * out_stale_info)761 HostCache::Entry HostResolverManager::ResolveLocally(
762 bool only_ipv6_reachable,
763 const JobKey& job_key,
764 const IPAddress& ip_address,
765 ResolveHostParameters::CacheUsage cache_usage,
766 SecureDnsPolicy secure_dns_policy,
767 HostResolverSource source,
768 const NetLogWithSource& source_net_log,
769 HostCache* cache,
770 std::deque<TaskType>* out_tasks,
771 std::optional<HostCache::EntryStaleness>* out_stale_info) {
772 DCHECK(out_stale_info);
773 *out_stale_info = std::nullopt;
774
775 CreateTaskSequence(job_key, cache_usage, secure_dns_policy, out_tasks);
776
777 if (!ip_address.IsValid()) {
778 // Check that the caller supplied a valid hostname to resolve. For
779 // MULTICAST_DNS, we are less restrictive.
780 // TODO(ericorth): Control validation based on an explicit flag rather
781 // than implicitly based on |source|.
782 const bool is_valid_hostname =
783 job_key.source == HostResolverSource::MULTICAST_DNS
784 ? dns_names_util::IsValidDnsName(job_key.host.GetHostname())
785 : IsCanonicalizedHostCompliant(job_key.host.GetHostname());
786 if (!is_valid_hostname) {
787 return HostCache::Entry(ERR_NAME_NOT_RESOLVED,
788 HostCache::Entry::SOURCE_UNKNOWN);
789 }
790 }
791
792 bool resolve_canonname = job_key.flags & HOST_RESOLVER_CANONNAME;
793 bool default_family_due_to_no_ipv6 =
794 job_key.flags & HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
795
796 // The result of |getaddrinfo| for empty hosts is inconsistent across systems.
797 // On Windows it gives the default interface's address, whereas on Linux it
798 // gives an error. We will make it fail on all platforms for consistency.
799 if (job_key.host.GetHostname().empty() ||
800 job_key.host.GetHostname().size() > kMaxHostLength) {
801 return HostCache::Entry(ERR_NAME_NOT_RESOLVED,
802 HostCache::Entry::SOURCE_UNKNOWN);
803 }
804
805 if (ip_address.IsValid()) {
806 // Use NAT64Task for IPv4 literal when the network is IPv6 only.
807 if (HostResolver::MayUseNAT64ForIPv4Literal(job_key.flags, source,
808 ip_address) &&
809 only_ipv6_reachable) {
810 out_tasks->push_front(TaskType::NAT64);
811 return HostCache::Entry(ERR_DNS_CACHE_MISS,
812 HostCache::Entry::SOURCE_UNKNOWN);
813 }
814
815 return ResolveAsIP(job_key.query_types, resolve_canonname, ip_address);
816 }
817
818 // Special-case localhost names, as per the recommendations in
819 // https://tools.ietf.org/html/draft-west-let-localhost-be-localhost.
820 std::optional<HostCache::Entry> resolved =
821 ServeLocalhost(job_key.host.GetHostname(), job_key.query_types,
822 default_family_due_to_no_ipv6);
823 if (resolved)
824 return resolved.value();
825
826 // Do initial cache lookups.
827 while (!out_tasks->empty() && IsLocalTask(out_tasks->front())) {
828 TaskType task = out_tasks->front();
829 out_tasks->pop_front();
830 if (task == TaskType::SECURE_CACHE_LOOKUP ||
831 task == TaskType::INSECURE_CACHE_LOOKUP ||
832 task == TaskType::CACHE_LOOKUP) {
833 bool secure = task == TaskType::SECURE_CACHE_LOOKUP;
834 HostCache::Key key = job_key.ToCacheKey(secure);
835
836 bool ignore_secure = task == TaskType::CACHE_LOOKUP;
837 resolved = MaybeServeFromCache(cache, key, cache_usage, ignore_secure,
838 source_net_log, out_stale_info);
839 if (resolved) {
840 // |MaybeServeFromCache()| will update |*out_stale_info| as needed.
841 DCHECK(out_stale_info->has_value());
842 source_net_log.AddEvent(
843 NetLogEventType::HOST_RESOLVER_MANAGER_CACHE_HIT,
844 [&] { return NetLogResults(resolved.value()); });
845
846 // TODO(crbug.com/1200908): Call StartBootstrapFollowup() if the Secure
847 // DNS Policy is kBootstrap and the result is not secure. Note: A naive
848 // implementation could cause an infinite loop if |resolved| always
849 // expires or is evicted before the followup runs.
850 return resolved.value();
851 }
852 DCHECK(!out_stale_info->has_value());
853 } else if (task == TaskType::CONFIG_PRESET) {
854 resolved = MaybeReadFromConfig(job_key);
855 if (resolved) {
856 source_net_log.AddEvent(
857 NetLogEventType::HOST_RESOLVER_MANAGER_CONFIG_PRESET_MATCH,
858 [&] { return NetLogResults(resolved.value()); });
859 StartBootstrapFollowup(job_key, cache, source_net_log);
860 return resolved.value();
861 }
862 } else if (task == TaskType::HOSTS) {
863 resolved = ServeFromHosts(job_key.host.GetHostname(), job_key.query_types,
864 default_family_due_to_no_ipv6, *out_tasks);
865 if (resolved) {
866 source_net_log.AddEvent(
867 NetLogEventType::HOST_RESOLVER_MANAGER_HOSTS_HIT,
868 [&] { return NetLogResults(resolved.value()); });
869 return resolved.value();
870 }
871 } else {
872 NOTREACHED();
873 }
874 }
875
876 return HostCache::Entry(ERR_DNS_CACHE_MISS, HostCache::Entry::SOURCE_UNKNOWN);
877 }
878
CreateAndStartJob(JobKey key,std::deque<TaskType> tasks,RequestImpl * request)879 void HostResolverManager::CreateAndStartJob(JobKey key,
880 std::deque<TaskType> tasks,
881 RequestImpl* request) {
882 DCHECK(!tasks.empty());
883
884 auto jobit = jobs_.find(key);
885 Job* job;
886 if (jobit == jobs_.end()) {
887 job = AddJobWithoutRequest(key, request->parameters().cache_usage,
888 request->host_cache(), std::move(tasks),
889 request->priority(), request->source_net_log());
890 job->AddRequest(request);
891 job->RunNextTask();
892 } else {
893 job = jobit->second.get();
894 job->AddRequest(request);
895 }
896 }
897
AddJobWithoutRequest(JobKey key,ResolveHostParameters::CacheUsage cache_usage,HostCache * host_cache,std::deque<TaskType> tasks,RequestPriority priority,const NetLogWithSource & source_net_log)898 HostResolverManager::Job* HostResolverManager::AddJobWithoutRequest(
899 JobKey key,
900 ResolveHostParameters::CacheUsage cache_usage,
901 HostCache* host_cache,
902 std::deque<TaskType> tasks,
903 RequestPriority priority,
904 const NetLogWithSource& source_net_log) {
905 auto new_job =
906 std::make_unique<Job>(weak_ptr_factory_.GetWeakPtr(), key, cache_usage,
907 host_cache, std::move(tasks), priority,
908 source_net_log, tick_clock_, https_svcb_options_);
909 auto insert_result = jobs_.emplace(std::move(key), std::move(new_job));
910 auto& iterator = insert_result.first;
911 bool is_new = insert_result.second;
912 DCHECK(is_new);
913 auto& job = iterator->second;
914 job->OnAddedToJobMap(iterator);
915 return job.get();
916 }
917
CreateAndStartJobForServiceEndpointRequest(JobKey key,std::deque<TaskType> tasks,ServiceEndpointRequestImpl * request)918 void HostResolverManager::CreateAndStartJobForServiceEndpointRequest(
919 JobKey key,
920 std::deque<TaskType> tasks,
921 ServiceEndpointRequestImpl* request) {
922 CHECK(!tasks.empty());
923
924 auto jobit = jobs_.find(key);
925 if (jobit == jobs_.end()) {
926 Job* job = AddJobWithoutRequest(key, request->parameters().cache_usage,
927 request->host_cache(), std::move(tasks),
928 request->priority(), request->net_log());
929 job->AddServiceEndpointRequest(request);
930 job->RunNextTask();
931 } else {
932 jobit->second->AddServiceEndpointRequest(request);
933 }
934 }
935
ResolveAsIP(DnsQueryTypeSet query_types,bool resolve_canonname,const IPAddress & ip_address)936 HostCache::Entry HostResolverManager::ResolveAsIP(DnsQueryTypeSet query_types,
937 bool resolve_canonname,
938 const IPAddress& ip_address) {
939 DCHECK(ip_address.IsValid());
940 DCHECK(!query_types.Has(DnsQueryType::UNSPECIFIED));
941
942 // IP literals cannot resolve unless the query type is an address query that
943 // allows addresses with the same address family as the literal. E.g., don't
944 // return IPv6 addresses for IPv4 queries or anything for a non-address query.
945 AddressFamily family = GetAddressFamily(ip_address);
946 if (!query_types.Has(AddressFamilyToDnsQueryType(family))) {
947 return HostCache::Entry(ERR_NAME_NOT_RESOLVED,
948 HostCache::Entry::SOURCE_UNKNOWN);
949 }
950
951 std::set<std::string> aliases;
952 if (resolve_canonname) {
953 aliases = {ip_address.ToString()};
954 }
955 return HostCache::Entry(OK, {IPEndPoint(ip_address, 0)}, std::move(aliases),
956 HostCache::Entry::SOURCE_UNKNOWN);
957 }
958
MaybeServeFromCache(HostCache * cache,const HostCache::Key & key,ResolveHostParameters::CacheUsage cache_usage,bool ignore_secure,const NetLogWithSource & source_net_log,std::optional<HostCache::EntryStaleness> * out_stale_info)959 std::optional<HostCache::Entry> HostResolverManager::MaybeServeFromCache(
960 HostCache* cache,
961 const HostCache::Key& key,
962 ResolveHostParameters::CacheUsage cache_usage,
963 bool ignore_secure,
964 const NetLogWithSource& source_net_log,
965 std::optional<HostCache::EntryStaleness>* out_stale_info) {
966 DCHECK(out_stale_info);
967 *out_stale_info = std::nullopt;
968
969 if (!cache)
970 return std::nullopt;
971
972 if (cache_usage == ResolveHostParameters::CacheUsage::DISALLOWED)
973 return std::nullopt;
974
975 // Local-only requests search the cache for non-local-only results.
976 HostCache::Key effective_key = key;
977 if (effective_key.host_resolver_source == HostResolverSource::LOCAL_ONLY)
978 effective_key.host_resolver_source = HostResolverSource::ANY;
979
980 const std::pair<const HostCache::Key, HostCache::Entry>* cache_result;
981 HostCache::EntryStaleness staleness;
982 if (cache_usage == ResolveHostParameters::CacheUsage::STALE_ALLOWED) {
983 cache_result = cache->LookupStale(effective_key, tick_clock_->NowTicks(),
984 &staleness, ignore_secure);
985 } else {
986 DCHECK(cache_usage == ResolveHostParameters::CacheUsage::ALLOWED);
987 cache_result =
988 cache->Lookup(effective_key, tick_clock_->NowTicks(), ignore_secure);
989 staleness = HostCache::kNotStale;
990 }
991 if (cache_result) {
992 *out_stale_info = std::move(staleness);
993 source_net_log.AddEvent(
994 NetLogEventType::HOST_RESOLVER_MANAGER_CACHE_HIT,
995 [&] { return NetLogResults(cache_result->second); });
996 return cache_result->second;
997 }
998 return std::nullopt;
999 }
1000
MaybeReadFromConfig(const JobKey & key)1001 std::optional<HostCache::Entry> HostResolverManager::MaybeReadFromConfig(
1002 const JobKey& key) {
1003 DCHECK(HasAddressType(key.query_types));
1004 if (!key.host.HasScheme()) {
1005 return std::nullopt;
1006 }
1007 std::optional<std::vector<IPEndPoint>> preset_addrs =
1008 dns_client_->GetPresetAddrs(key.host.AsSchemeHostPort());
1009 if (!preset_addrs)
1010 return std::nullopt;
1011
1012 std::vector<IPEndPoint> filtered_addresses =
1013 FilterAddresses(std::move(*preset_addrs), key.query_types);
1014 if (filtered_addresses.empty())
1015 return std::nullopt;
1016
1017 return HostCache::Entry(OK, std::move(filtered_addresses), /*aliases=*/{},
1018 HostCache::Entry::SOURCE_CONFIG);
1019 }
1020
StartBootstrapFollowup(JobKey key,HostCache * host_cache,const NetLogWithSource & source_net_log)1021 void HostResolverManager::StartBootstrapFollowup(
1022 JobKey key,
1023 HostCache* host_cache,
1024 const NetLogWithSource& source_net_log) {
1025 DCHECK_EQ(SecureDnsMode::kOff, key.secure_dns_mode);
1026 DCHECK(host_cache);
1027
1028 key.secure_dns_mode = SecureDnsMode::kSecure;
1029 if (jobs_.count(key) != 0)
1030 return;
1031
1032 Job* job = AddJobWithoutRequest(
1033 key, ResolveHostParameters::CacheUsage::ALLOWED, host_cache,
1034 {TaskType::SECURE_DNS}, RequestPriority::LOW, source_net_log);
1035 job->RunNextTask();
1036 }
1037
ServeFromHosts(std::string_view hostname,DnsQueryTypeSet query_types,bool default_family_due_to_no_ipv6,const std::deque<TaskType> & tasks)1038 std::optional<HostCache::Entry> HostResolverManager::ServeFromHosts(
1039 std::string_view hostname,
1040 DnsQueryTypeSet query_types,
1041 bool default_family_due_to_no_ipv6,
1042 const std::deque<TaskType>& tasks) {
1043 DCHECK(!query_types.Has(DnsQueryType::UNSPECIFIED));
1044 // Don't attempt a HOSTS lookup if there is no DnsConfig or the HOSTS lookup
1045 // is going to be done next as part of a system lookup.
1046 if (!dns_client_ || !HasAddressType(query_types) ||
1047 (!tasks.empty() && tasks.front() == TaskType::SYSTEM))
1048 return std::nullopt;
1049 const DnsHosts* hosts = dns_client_->GetHosts();
1050
1051 if (!hosts || hosts->empty())
1052 return std::nullopt;
1053
1054 // HOSTS lookups are case-insensitive.
1055 std::string effective_hostname = base::ToLowerASCII(hostname);
1056
1057 // If |address_family| is ADDRESS_FAMILY_UNSPECIFIED other implementations
1058 // (glibc and c-ares) return the first matching line. We have more
1059 // flexibility, but lose implicit ordering.
1060 // We prefer IPv6 because "happy eyeballs" will fall back to IPv4 if
1061 // necessary.
1062 std::vector<IPEndPoint> addresses;
1063 if (query_types.Has(DnsQueryType::AAAA)) {
1064 auto it = hosts->find(DnsHostsKey(effective_hostname, ADDRESS_FAMILY_IPV6));
1065 if (it != hosts->end()) {
1066 addresses.emplace_back(it->second, 0);
1067 }
1068 }
1069
1070 if (query_types.Has(DnsQueryType::A)) {
1071 auto it = hosts->find(DnsHostsKey(effective_hostname, ADDRESS_FAMILY_IPV4));
1072 if (it != hosts->end()) {
1073 addresses.emplace_back(it->second, 0);
1074 }
1075 }
1076
1077 // If got only loopback addresses and the family was restricted, resolve
1078 // again, without restrictions. See SystemHostResolverCall for rationale.
1079 if (default_family_due_to_no_ipv6 &&
1080 base::ranges::all_of(addresses, &IPAddress::IsIPv4,
1081 &IPEndPoint::address) &&
1082 base::ranges::all_of(addresses, &IPAddress::IsLoopback,
1083 &IPEndPoint::address)) {
1084 query_types.Put(DnsQueryType::AAAA);
1085 return ServeFromHosts(hostname, query_types, false, tasks);
1086 }
1087
1088 if (addresses.empty())
1089 return std::nullopt;
1090
1091 return HostCache::Entry(OK, std::move(addresses),
1092 /*aliases=*/{}, HostCache::Entry::SOURCE_HOSTS);
1093 }
1094
ServeLocalhost(std::string_view hostname,DnsQueryTypeSet query_types,bool default_family_due_to_no_ipv6)1095 std::optional<HostCache::Entry> HostResolverManager::ServeLocalhost(
1096 std::string_view hostname,
1097 DnsQueryTypeSet query_types,
1098 bool default_family_due_to_no_ipv6) {
1099 DCHECK(!query_types.Has(DnsQueryType::UNSPECIFIED));
1100
1101 std::vector<IPEndPoint> resolved_addresses;
1102 if (!HasAddressType(query_types) ||
1103 !ResolveLocalHostname(hostname, &resolved_addresses)) {
1104 return std::nullopt;
1105 }
1106
1107 if (default_family_due_to_no_ipv6 && query_types.Has(DnsQueryType::A) &&
1108 !query_types.Has(DnsQueryType::AAAA)) {
1109 // The caller disabled the AAAA query due to lack of detected IPv6 support.
1110 // (See SystemHostResolverCall for rationale).
1111 query_types.Put(DnsQueryType::AAAA);
1112 }
1113 std::vector<IPEndPoint> filtered_addresses =
1114 FilterAddresses(std::move(resolved_addresses), query_types);
1115 return HostCache::Entry(OK, std::move(filtered_addresses), /*aliases=*/{},
1116 HostCache::Entry::SOURCE_UNKNOWN);
1117 }
1118
CacheResult(HostCache * cache,const HostCache::Key & key,const HostCache::Entry & entry,base::TimeDelta ttl)1119 void HostResolverManager::CacheResult(HostCache* cache,
1120 const HostCache::Key& key,
1121 const HostCache::Entry& entry,
1122 base::TimeDelta ttl) {
1123 // Don't cache an error unless it has a positive TTL.
1124 if (cache && (entry.error() == OK || ttl.is_positive()))
1125 cache->Set(key, entry, tick_clock_->NowTicks(), ttl);
1126 }
1127
RemoveJob(JobMap::iterator job_it)1128 std::unique_ptr<HostResolverManager::Job> HostResolverManager::RemoveJob(
1129 JobMap::iterator job_it) {
1130 DCHECK(job_it != jobs_.end());
1131 DCHECK(job_it->second);
1132 DCHECK_EQ(1u, jobs_.count(job_it->first));
1133
1134 std::unique_ptr<Job> job;
1135 job_it->second.swap(job);
1136 jobs_.erase(job_it);
1137 job->OnRemovedFromJobMap();
1138
1139 return job;
1140 }
1141
GetEffectiveSecureDnsMode(SecureDnsPolicy secure_dns_policy)1142 SecureDnsMode HostResolverManager::GetEffectiveSecureDnsMode(
1143 SecureDnsPolicy secure_dns_policy) {
1144 // Use switch() instead of if() to ensure that all policies are handled.
1145 switch (secure_dns_policy) {
1146 case SecureDnsPolicy::kDisable:
1147 case SecureDnsPolicy::kBootstrap:
1148 return SecureDnsMode::kOff;
1149 case SecureDnsPolicy::kAllow:
1150 break;
1151 }
1152
1153 const DnsConfig* config =
1154 dns_client_ ? dns_client_->GetEffectiveConfig() : nullptr;
1155
1156 SecureDnsMode secure_dns_mode = SecureDnsMode::kOff;
1157 if (config) {
1158 secure_dns_mode = config->secure_dns_mode;
1159 }
1160 return secure_dns_mode;
1161 }
1162
ShouldForceSystemResolverDueToTestOverride() const1163 bool HostResolverManager::ShouldForceSystemResolverDueToTestOverride() const {
1164 // If tests have provided a catch-all DNS block and then disabled it, check
1165 // that we are not at risk of sending queries beyond the local network.
1166 if (HostResolverProc::GetDefault() && system_resolver_disabled_for_testing_) {
1167 DCHECK(dns_client_);
1168 DCHECK(dns_client_->GetEffectiveConfig());
1169 DCHECK(base::ranges::none_of(dns_client_->GetEffectiveConfig()->nameservers,
1170 &IPAddress::IsPubliclyRoutable,
1171 &IPEndPoint::address))
1172 << "Test could query a publicly-routable address.";
1173 }
1174 return !host_resolver_system_params_.resolver_proc &&
1175 HostResolverProc::GetDefault() &&
1176 !system_resolver_disabled_for_testing_;
1177 }
1178
PushDnsTasks(bool system_task_allowed,SecureDnsMode secure_dns_mode,bool insecure_tasks_allowed,bool allow_cache,bool prioritize_local_lookups,ResolveContext * resolve_context,std::deque<TaskType> * out_tasks)1179 void HostResolverManager::PushDnsTasks(bool system_task_allowed,
1180 SecureDnsMode secure_dns_mode,
1181 bool insecure_tasks_allowed,
1182 bool allow_cache,
1183 bool prioritize_local_lookups,
1184 ResolveContext* resolve_context,
1185 std::deque<TaskType>* out_tasks) {
1186 DCHECK(dns_client_);
1187 DCHECK(dns_client_->GetEffectiveConfig());
1188
1189 // If a catch-all DNS block has been set for unit tests, we shouldn't send
1190 // DnsTasks. It is still necessary to call this method, however, so that the
1191 // correct cache tasks for the secure dns mode are added.
1192 const bool dns_tasks_allowed = !ShouldForceSystemResolverDueToTestOverride();
1193 // Upgrade the insecure DnsTask depending on the secure dns mode.
1194 switch (secure_dns_mode) {
1195 case SecureDnsMode::kSecure:
1196 DCHECK(!allow_cache ||
1197 out_tasks->front() == TaskType::SECURE_CACHE_LOOKUP);
1198 // Policy misconfiguration can put us in secure DNS mode without any DoH
1199 // servers to query. See https://crbug.com/1326526.
1200 if (dns_tasks_allowed && dns_client_->CanUseSecureDnsTransactions())
1201 out_tasks->push_back(TaskType::SECURE_DNS);
1202 break;
1203 case SecureDnsMode::kAutomatic:
1204 DCHECK(!allow_cache || out_tasks->front() == TaskType::CACHE_LOOKUP);
1205 if (dns_client_->FallbackFromSecureTransactionPreferred(
1206 resolve_context)) {
1207 // Don't run a secure DnsTask if there are no available DoH servers.
1208 if (dns_tasks_allowed && insecure_tasks_allowed)
1209 out_tasks->push_back(TaskType::DNS);
1210 } else if (prioritize_local_lookups) {
1211 // If local lookups are prioritized, the cache should be checked for
1212 // both secure and insecure results prior to running a secure DnsTask.
1213 // The task sequence should already contain the appropriate cache task.
1214 if (dns_tasks_allowed) {
1215 out_tasks->push_back(TaskType::SECURE_DNS);
1216 if (insecure_tasks_allowed)
1217 out_tasks->push_back(TaskType::DNS);
1218 }
1219 } else {
1220 if (allow_cache) {
1221 // Remove the initial cache lookup task so that the secure and
1222 // insecure lookups can be separated.
1223 out_tasks->pop_front();
1224 out_tasks->push_back(TaskType::SECURE_CACHE_LOOKUP);
1225 }
1226 if (dns_tasks_allowed)
1227 out_tasks->push_back(TaskType::SECURE_DNS);
1228 if (allow_cache)
1229 out_tasks->push_back(TaskType::INSECURE_CACHE_LOOKUP);
1230 if (dns_tasks_allowed && insecure_tasks_allowed)
1231 out_tasks->push_back(TaskType::DNS);
1232 }
1233 break;
1234 case SecureDnsMode::kOff:
1235 DCHECK(!allow_cache || IsLocalTask(out_tasks->front()));
1236 if (dns_tasks_allowed && insecure_tasks_allowed)
1237 out_tasks->push_back(TaskType::DNS);
1238 break;
1239 default:
1240 NOTREACHED();
1241 break;
1242 }
1243
1244 constexpr TaskType kWantTasks[] = {TaskType::DNS, TaskType::SECURE_DNS};
1245 const bool no_dns_or_secure_tasks =
1246 base::ranges::find_first_of(*out_tasks, kWantTasks) == out_tasks->end();
1247 // The system resolver can be used as a fallback for a non-existent or
1248 // failing DnsTask if allowed by the request parameters.
1249 if (system_task_allowed &&
1250 (no_dns_or_secure_tasks || allow_fallback_to_systemtask_))
1251 out_tasks->push_back(TaskType::SYSTEM);
1252 }
1253
CreateTaskSequence(const JobKey & job_key,ResolveHostParameters::CacheUsage cache_usage,SecureDnsPolicy secure_dns_policy,std::deque<TaskType> * out_tasks)1254 void HostResolverManager::CreateTaskSequence(
1255 const JobKey& job_key,
1256 ResolveHostParameters::CacheUsage cache_usage,
1257 SecureDnsPolicy secure_dns_policy,
1258 std::deque<TaskType>* out_tasks) {
1259 DCHECK(out_tasks->empty());
1260
1261 // A cache lookup should generally be performed first. For jobs involving a
1262 // DnsTask, this task may be replaced.
1263 bool allow_cache =
1264 cache_usage != ResolveHostParameters::CacheUsage::DISALLOWED;
1265 if (secure_dns_policy == SecureDnsPolicy::kBootstrap) {
1266 DCHECK_EQ(SecureDnsMode::kOff, job_key.secure_dns_mode);
1267 if (allow_cache)
1268 out_tasks->push_front(TaskType::INSECURE_CACHE_LOOKUP);
1269 out_tasks->push_front(TaskType::CONFIG_PRESET);
1270 if (allow_cache)
1271 out_tasks->push_front(TaskType::SECURE_CACHE_LOOKUP);
1272 } else if (allow_cache) {
1273 if (job_key.secure_dns_mode == SecureDnsMode::kSecure) {
1274 out_tasks->push_front(TaskType::SECURE_CACHE_LOOKUP);
1275 } else {
1276 out_tasks->push_front(TaskType::CACHE_LOOKUP);
1277 }
1278 }
1279 out_tasks->push_back(TaskType::HOSTS);
1280
1281 // Determine what type of task a future Job should start.
1282 bool prioritize_local_lookups =
1283 cache_usage ==
1284 HostResolver::ResolveHostParameters::CacheUsage::STALE_ALLOWED;
1285
1286 const bool has_address_type = HasAddressType(job_key.query_types);
1287
1288 switch (job_key.source) {
1289 case HostResolverSource::ANY:
1290 // Force address queries with canonname to use HostResolverSystemTask to
1291 // counter poor CNAME support in DnsTask. See https://crbug.com/872665
1292 //
1293 // Otherwise, default to DnsTask (with allowed fallback to
1294 // HostResolverSystemTask for address queries). But if hostname appears to
1295 // be an MDNS name (ends in *.local), go with HostResolverSystemTask for
1296 // address queries and MdnsTask for non- address queries.
1297 if ((job_key.flags & HOST_RESOLVER_CANONNAME) && has_address_type) {
1298 out_tasks->push_back(TaskType::SYSTEM);
1299 } else if (!ResemblesMulticastDNSName(job_key.host.GetHostname())) {
1300 bool system_task_allowed =
1301 has_address_type &&
1302 job_key.secure_dns_mode != SecureDnsMode::kSecure;
1303 if (dns_client_ && dns_client_->GetEffectiveConfig()) {
1304 bool insecure_allowed =
1305 dns_client_->CanUseInsecureDnsTransactions() &&
1306 !dns_client_->FallbackFromInsecureTransactionPreferred() &&
1307 (has_address_type ||
1308 dns_client_->CanQueryAdditionalTypesViaInsecureDns());
1309 PushDnsTasks(system_task_allowed, job_key.secure_dns_mode,
1310 insecure_allowed, allow_cache, prioritize_local_lookups,
1311 &*job_key.resolve_context, out_tasks);
1312 } else if (system_task_allowed) {
1313 out_tasks->push_back(TaskType::SYSTEM);
1314 }
1315 } else if (has_address_type) {
1316 // For *.local address queries, try the system resolver even if the
1317 // secure dns mode is SECURE. Public recursive resolvers aren't expected
1318 // to handle these queries.
1319 out_tasks->push_back(TaskType::SYSTEM);
1320 } else {
1321 out_tasks->push_back(TaskType::MDNS);
1322 }
1323 break;
1324 case HostResolverSource::SYSTEM:
1325 out_tasks->push_back(TaskType::SYSTEM);
1326 break;
1327 case HostResolverSource::DNS:
1328 if (dns_client_ && dns_client_->GetEffectiveConfig()) {
1329 bool insecure_allowed =
1330 dns_client_->CanUseInsecureDnsTransactions() &&
1331 (has_address_type ||
1332 dns_client_->CanQueryAdditionalTypesViaInsecureDns());
1333 PushDnsTasks(false /* system_task_allowed */, job_key.secure_dns_mode,
1334 insecure_allowed, allow_cache, prioritize_local_lookups,
1335 &*job_key.resolve_context, out_tasks);
1336 }
1337 break;
1338 case HostResolverSource::MULTICAST_DNS:
1339 out_tasks->push_back(TaskType::MDNS);
1340 break;
1341 case HostResolverSource::LOCAL_ONLY:
1342 // If no external source allowed, a job should not be created or started
1343 break;
1344 }
1345
1346 // `HOST_RESOLVER_CANONNAME` is only supported through system resolution.
1347 if (job_key.flags & HOST_RESOLVER_CANONNAME) {
1348 DCHECK(base::ranges::find(*out_tasks, TaskType::DNS) == out_tasks->end());
1349 DCHECK(base::ranges::find(*out_tasks, TaskType::MDNS) == out_tasks->end());
1350 }
1351 }
1352
1353 namespace {
1354
RequestWillUseWiFi(handles::NetworkHandle network)1355 bool RequestWillUseWiFi(handles::NetworkHandle network) {
1356 NetworkChangeNotifier::ConnectionType connection_type;
1357 if (network == handles::kInvalidNetworkHandle)
1358 connection_type = NetworkChangeNotifier::GetConnectionType();
1359 else
1360 connection_type = NetworkChangeNotifier::GetNetworkConnectionType(network);
1361
1362 return connection_type == NetworkChangeNotifier::CONNECTION_WIFI;
1363 }
1364
1365 } // namespace
1366
FinishIPv6ReachabilityCheck(CompletionOnceCallback callback,int rv)1367 void HostResolverManager::FinishIPv6ReachabilityCheck(
1368 CompletionOnceCallback callback,
1369 int rv) {
1370 SetLastIPv6ProbeResult((rv == OK) ? true : false);
1371 std::move(callback).Run(OK);
1372 if (!ipv6_request_callbacks_.empty()) {
1373 std::vector<CompletionOnceCallback> tmp_request_callbacks;
1374 ipv6_request_callbacks_.swap(tmp_request_callbacks);
1375 for (auto& request_callback : tmp_request_callbacks) {
1376 std::move(request_callback).Run(OK);
1377 }
1378 }
1379 }
1380
StartIPv6ReachabilityCheck(const NetLogWithSource & net_log,ClientSocketFactory * client_socket_factory,CompletionOnceCallback callback)1381 int HostResolverManager::StartIPv6ReachabilityCheck(
1382 const NetLogWithSource& net_log,
1383 ClientSocketFactory* client_socket_factory,
1384 CompletionOnceCallback callback) {
1385 // Don't bother checking if the request will use WiFi and IPv6 is assumed to
1386 // not work on WiFi.
1387 if (!check_ipv6_on_wifi_ && RequestWillUseWiFi(target_network_)) {
1388 probing_ipv6_ = false;
1389 last_ipv6_probe_result_ = false;
1390 last_ipv6_probe_time_ = base::TimeTicks();
1391 return OK;
1392 }
1393
1394 if (probing_ipv6_) {
1395 ipv6_request_callbacks_.push_back(std::move(callback));
1396 return ERR_IO_PENDING;
1397 }
1398 // Cache the result for kIPv6ProbePeriodMs (measured from after
1399 // StartGloballyReachableCheck() completes).
1400 int rv = OK;
1401 bool cached = true;
1402 if (last_ipv6_probe_time_.is_null() ||
1403 (tick_clock_->NowTicks() - last_ipv6_probe_time_).InMilliseconds() >
1404 kIPv6ProbePeriodMs) {
1405 probing_ipv6_ = true;
1406 rv = StartGloballyReachableCheck(
1407 IPAddress(kIPv6ProbeAddress), net_log, client_socket_factory,
1408 base::BindOnce(&HostResolverManager::FinishIPv6ReachabilityCheck,
1409 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
1410 if (rv != ERR_IO_PENDING) {
1411 SetLastIPv6ProbeResult((rv == OK) ? true : false);
1412 rv = OK;
1413 }
1414 cached = false;
1415 }
1416 net_log.AddEvent(
1417 NetLogEventType::HOST_RESOLVER_MANAGER_IPV6_REACHABILITY_CHECK, [&] {
1418 return NetLogIPv6AvailableParams(last_ipv6_probe_result_, cached);
1419 });
1420 return rv;
1421 }
1422
SetLastIPv6ProbeResult(bool last_ipv6_probe_result)1423 void HostResolverManager::SetLastIPv6ProbeResult(bool last_ipv6_probe_result) {
1424 probing_ipv6_ = false;
1425 last_ipv6_probe_result_ = last_ipv6_probe_result;
1426 last_ipv6_probe_time_ = tick_clock_->NowTicks();
1427 }
1428
StartGloballyReachableCheck(const IPAddress & dest,const NetLogWithSource & net_log,ClientSocketFactory * client_socket_factory,CompletionOnceCallback callback)1429 int HostResolverManager::StartGloballyReachableCheck(
1430 const IPAddress& dest,
1431 const NetLogWithSource& net_log,
1432 ClientSocketFactory* client_socket_factory,
1433 CompletionOnceCallback callback) {
1434 std::unique_ptr<DatagramClientSocket> probing_socket =
1435 client_socket_factory->CreateDatagramClientSocket(
1436 DatagramSocket::DEFAULT_BIND, net_log.net_log(), net_log.source());
1437 DatagramClientSocket* probing_socket_ptr = probing_socket.get();
1438 auto refcounted_socket = base::MakeRefCounted<
1439 base::RefCountedData<std::unique_ptr<DatagramClientSocket>>>(
1440 std::move(probing_socket));
1441 int rv = probing_socket_ptr->ConnectAsync(
1442 IPEndPoint(dest, GetPortForGloballyReachableCheck()),
1443 base::BindOnce(&HostResolverManager::RunFinishGloballyReachableCheck,
1444 weak_ptr_factory_.GetWeakPtr(), refcounted_socket,
1445 std::move(callback)));
1446 if (rv != ERR_IO_PENDING) {
1447 rv = FinishGloballyReachableCheck(probing_socket_ptr, rv) ? OK : ERR_FAILED;
1448 }
1449 return rv;
1450 }
1451
FinishGloballyReachableCheck(DatagramClientSocket * socket,int rv)1452 bool HostResolverManager::FinishGloballyReachableCheck(
1453 DatagramClientSocket* socket,
1454 int rv) {
1455 if (rv != OK) {
1456 return false;
1457 }
1458 IPEndPoint endpoint;
1459 rv = socket->GetLocalAddress(&endpoint);
1460
1461 if (rv != OK) {
1462 return false;
1463 }
1464 const IPAddress& address = endpoint.address();
1465
1466 if (address.IsLinkLocal()) {
1467 return false;
1468 }
1469
1470 if (address.IsIPv6()) {
1471 const uint8_t kTeredoPrefix[] = {0x20, 0x01, 0, 0};
1472 if (IPAddressStartsWith(address, kTeredoPrefix)) {
1473 return false;
1474 }
1475 }
1476
1477 return true;
1478 }
1479
RunFinishGloballyReachableCheck(scoped_refptr<base::RefCountedData<std::unique_ptr<DatagramClientSocket>>> socket,CompletionOnceCallback callback,int rv)1480 void HostResolverManager::RunFinishGloballyReachableCheck(
1481 scoped_refptr<base::RefCountedData<std::unique_ptr<DatagramClientSocket>>>
1482 socket,
1483 CompletionOnceCallback callback,
1484 int rv) {
1485 bool is_reachable = FinishGloballyReachableCheck(socket->data.get(), rv);
1486 std::move(callback).Run(is_reachable ? OK : ERR_FAILED);
1487 }
1488
RunLoopbackProbeJob()1489 void HostResolverManager::RunLoopbackProbeJob() {
1490 RunHaveOnlyLoopbackAddressesJob(
1491 base::BindOnce(&HostResolverManager::SetHaveOnlyLoopbackAddresses,
1492 weak_ptr_factory_.GetWeakPtr()));
1493 }
1494
RemoveAllJobs(const ResolveContext * context)1495 void HostResolverManager::RemoveAllJobs(const ResolveContext* context) {
1496 for (auto it = jobs_.begin(); it != jobs_.end();) {
1497 const JobKey& key = it->first;
1498 if (&*key.resolve_context == context) {
1499 RemoveJob(it++);
1500 } else {
1501 ++it;
1502 }
1503 }
1504 }
1505
AbortJobsWithoutTargetNetwork(bool in_progress_only)1506 void HostResolverManager::AbortJobsWithoutTargetNetwork(bool in_progress_only) {
1507 // In Abort, a Request callback could spawn new Jobs with matching keys, so
1508 // first collect and remove all running jobs from `jobs_`.
1509 std::vector<std::unique_ptr<Job>> jobs_to_abort;
1510 for (auto it = jobs_.begin(); it != jobs_.end();) {
1511 Job* job = it->second.get();
1512 if (!job->HasTargetNetwork() && (!in_progress_only || job->is_running())) {
1513 jobs_to_abort.push_back(RemoveJob(it++));
1514 } else {
1515 ++it;
1516 }
1517 }
1518
1519 // Pause the dispatcher so it won't start any new dispatcher jobs while
1520 // aborting the old ones. This is needed so that it won't start the second
1521 // DnsTransaction for a job in `jobs_to_abort` if the DnsConfig just became
1522 // invalid.
1523 PrioritizedDispatcher::Limits limits = dispatcher_->GetLimits();
1524 dispatcher_->SetLimits(
1525 PrioritizedDispatcher::Limits(limits.reserved_slots.size(), 0));
1526
1527 // Life check to bail once `this` is deleted.
1528 base::WeakPtr<HostResolverManager> self = weak_ptr_factory_.GetWeakPtr();
1529
1530 // Then Abort them.
1531 for (size_t i = 0; self.get() && i < jobs_to_abort.size(); ++i) {
1532 jobs_to_abort[i]->Abort();
1533 }
1534
1535 if (self)
1536 dispatcher_->SetLimits(limits);
1537 }
1538
AbortInsecureDnsTasks(int error,bool fallback_only)1539 void HostResolverManager::AbortInsecureDnsTasks(int error, bool fallback_only) {
1540 // Aborting jobs potentially modifies |jobs_| and may even delete some jobs.
1541 // Create safe closures of all current jobs.
1542 std::vector<base::OnceClosure> job_abort_closures;
1543 for (auto& job : jobs_) {
1544 job_abort_closures.push_back(
1545 job.second->GetAbortInsecureDnsTaskClosure(error, fallback_only));
1546 }
1547
1548 // Pause the dispatcher so it won't start any new dispatcher jobs while
1549 // aborting the old ones. This is needed so that it won't start the second
1550 // DnsTransaction for a job if the DnsConfig just changed.
1551 PrioritizedDispatcher::Limits limits = dispatcher_->GetLimits();
1552 dispatcher_->SetLimits(
1553 PrioritizedDispatcher::Limits(limits.reserved_slots.size(), 0));
1554
1555 for (base::OnceClosure& closure : job_abort_closures)
1556 std::move(closure).Run();
1557
1558 dispatcher_->SetLimits(limits);
1559 }
1560
1561 // TODO(crbug.com/995984): Consider removing this and its usage.
TryServingAllJobsFromHosts()1562 void HostResolverManager::TryServingAllJobsFromHosts() {
1563 if (!dns_client_ || !dns_client_->GetEffectiveConfig())
1564 return;
1565
1566 // TODO(szym): Do not do this if nsswitch.conf instructs not to.
1567 // http://crbug.com/117655
1568
1569 // Life check to bail once |this| is deleted.
1570 base::WeakPtr<HostResolverManager> self = weak_ptr_factory_.GetWeakPtr();
1571
1572 for (auto it = jobs_.begin(); self.get() && it != jobs_.end();) {
1573 Job* job = it->second.get();
1574 ++it;
1575 // This could remove |job| from |jobs_|, but iterator will remain valid.
1576 job->ServeFromHosts();
1577 }
1578 }
1579
OnIPAddressChanged()1580 void HostResolverManager::OnIPAddressChanged() {
1581 DCHECK(!IsBoundToNetwork());
1582 last_ipv6_probe_time_ = base::TimeTicks();
1583 // Abandon all ProbeJobs.
1584 probe_weak_ptr_factory_.InvalidateWeakPtrs();
1585 InvalidateCaches();
1586 #if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_ANDROID)) || \
1587 BUILDFLAG(IS_FUCHSIA)
1588 RunLoopbackProbeJob();
1589 #endif
1590 AbortJobsWithoutTargetNetwork(true /* in_progress_only */);
1591 // `this` may be deleted inside AbortJobsWithoutTargetNetwork().
1592 }
1593
OnConnectionTypeChanged(NetworkChangeNotifier::ConnectionType type)1594 void HostResolverManager::OnConnectionTypeChanged(
1595 NetworkChangeNotifier::ConnectionType type) {
1596 DCHECK(!IsBoundToNetwork());
1597 UpdateConnectionType(type);
1598 }
1599
OnSystemDnsConfigChanged(std::optional<DnsConfig> config)1600 void HostResolverManager::OnSystemDnsConfigChanged(
1601 std::optional<DnsConfig> config) {
1602 DCHECK(!IsBoundToNetwork());
1603 // If tests have provided a catch-all DNS block and then disabled it, check
1604 // that we are not at risk of sending queries beyond the local network.
1605 if (HostResolverProc::GetDefault() && system_resolver_disabled_for_testing_ &&
1606 config.has_value()) {
1607 DCHECK(base::ranges::none_of(config->nameservers,
1608 &IPAddress::IsPubliclyRoutable,
1609 &IPEndPoint::address))
1610 << "Test could query a publicly-routable address.";
1611 }
1612
1613 bool changed = false;
1614 bool transactions_allowed_before = false;
1615 if (dns_client_) {
1616 transactions_allowed_before = dns_client_->CanUseSecureDnsTransactions() ||
1617 dns_client_->CanUseInsecureDnsTransactions();
1618 changed = dns_client_->SetSystemConfig(std::move(config));
1619 }
1620
1621 // Always invalidate cache, even if no change is seen.
1622 InvalidateCaches();
1623
1624 if (changed) {
1625 // Need to update jobs iff transactions were previously allowed because
1626 // in-progress jobs may be running using a now-invalid configuration.
1627 if (transactions_allowed_before)
1628 UpdateJobsForChangedConfig();
1629 }
1630 }
1631
UpdateJobsForChangedConfig()1632 void HostResolverManager::UpdateJobsForChangedConfig() {
1633 // Life check to bail once `this` is deleted.
1634 base::WeakPtr<HostResolverManager> self = weak_ptr_factory_.GetWeakPtr();
1635
1636 // Existing jobs that were set up using the nameservers and secure dns mode
1637 // from the original config need to be aborted (does not apply to jobs
1638 // targeting a specific network).
1639 AbortJobsWithoutTargetNetwork(false /* in_progress_only */);
1640
1641 // `this` may be deleted inside AbortJobsWithoutTargetNetwork().
1642 if (self.get())
1643 TryServingAllJobsFromHosts();
1644 }
1645
OnFallbackResolve(int dns_task_error)1646 void HostResolverManager::OnFallbackResolve(int dns_task_error) {
1647 DCHECK(dns_client_);
1648 DCHECK_NE(OK, dns_task_error);
1649
1650 // Nothing to do if DnsTask is already not preferred.
1651 if (dns_client_->FallbackFromInsecureTransactionPreferred())
1652 return;
1653
1654 dns_client_->IncrementInsecureFallbackFailures();
1655
1656 // If DnsClient became not preferred, fallback all fallback-allowed insecure
1657 // DnsTasks to HostResolverSystemTasks.
1658 if (dns_client_->FallbackFromInsecureTransactionPreferred())
1659 AbortInsecureDnsTasks(ERR_FAILED, true /* fallback_only */);
1660 }
1661
GetOrCreateMdnsClient(MDnsClient ** out_client)1662 int HostResolverManager::GetOrCreateMdnsClient(MDnsClient** out_client) {
1663 #if BUILDFLAG(ENABLE_MDNS)
1664 if (!mdns_client_) {
1665 if (!mdns_socket_factory_)
1666 mdns_socket_factory_ = std::make_unique<MDnsSocketFactoryImpl>(net_log_);
1667 mdns_client_ = MDnsClient::CreateDefault();
1668 }
1669
1670 int rv = OK;
1671 if (!mdns_client_->IsListening())
1672 rv = mdns_client_->StartListening(mdns_socket_factory_.get());
1673
1674 DCHECK_NE(ERR_IO_PENDING, rv);
1675 DCHECK(rv != OK || mdns_client_->IsListening());
1676 if (rv == OK)
1677 *out_client = mdns_client_.get();
1678 return rv;
1679 #else
1680 // Should not request MDNS resoltuion unless MDNS is enabled.
1681 NOTREACHED();
1682 return ERR_UNEXPECTED;
1683 #endif
1684 }
1685
InvalidateCaches(bool network_change)1686 void HostResolverManager::InvalidateCaches(bool network_change) {
1687 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
1688 DCHECK(!invalidation_in_progress_);
1689
1690 #if DCHECK_IS_ON()
1691 base::WeakPtr<HostResolverManager> self_ptr = weak_ptr_factory_.GetWeakPtr();
1692 size_t num_jobs = jobs_.size();
1693 #endif
1694
1695 invalidation_in_progress_ = true;
1696 for (auto& context : registered_contexts_) {
1697 context.InvalidateCachesAndPerSessionData(
1698 dns_client_ ? dns_client_->GetCurrentSession() : nullptr,
1699 network_change);
1700 }
1701 invalidation_in_progress_ = false;
1702
1703 #if DCHECK_IS_ON()
1704 // Sanity checks that invalidation does not have reentrancy issues.
1705 DCHECK(self_ptr);
1706 DCHECK_EQ(num_jobs, jobs_.size());
1707 #endif
1708 }
1709
UpdateConnectionType(NetworkChangeNotifier::ConnectionType type)1710 void HostResolverManager::UpdateConnectionType(
1711 NetworkChangeNotifier::ConnectionType type) {
1712 host_resolver_system_params_.unresponsive_delay =
1713 GetTimeDeltaForConnectionTypeFromFieldTrialOrDefault(
1714 "DnsUnresponsiveDelayMsByConnectionType",
1715 HostResolverSystemTask::Params::kDnsDefaultUnresponsiveDelay, type);
1716
1717 // Note that NetworkChangeNotifier always sends a CONNECTION_NONE notification
1718 // before non-NONE notifications. This check therefore just ensures each
1719 // connection change notification is handled once and has nothing to do with
1720 // whether the change is to offline or online.
1721 if (type == NetworkChangeNotifier::CONNECTION_NONE && dns_client_) {
1722 dns_client_->ReplaceCurrentSession();
1723 InvalidateCaches(true /* network_change */);
1724 }
1725 }
1726
CreateDohProbeRunner(ResolveContext * resolve_context)1727 std::unique_ptr<DnsProbeRunner> HostResolverManager::CreateDohProbeRunner(
1728 ResolveContext* resolve_context) {
1729 DCHECK(resolve_context);
1730 DCHECK(registered_contexts_.HasObserver(resolve_context));
1731 if (!dns_client_ || !dns_client_->CanUseSecureDnsTransactions()) {
1732 return nullptr;
1733 }
1734
1735 return dns_client_->GetTransactionFactory()->CreateDohProbeRunner(
1736 resolve_context);
1737 }
1738
1739 } // namespace net
1740