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