xref: /aosp_15_r20/external/cronet/net/dns/host_resolver_manager.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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