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