xref: /aosp_15_r20/external/cronet/net/dns/mock_host_resolver.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/dns/mock_host_resolver.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <memory>
10*6777b538SAndroid Build Coastguard Worker #include <optional>
11*6777b538SAndroid Build Coastguard Worker #include <string>
12*6777b538SAndroid Build Coastguard Worker #include <string_view>
13*6777b538SAndroid Build Coastguard Worker #include <utility>
14*6777b538SAndroid Build Coastguard Worker #include <vector>
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/no_destructor.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/strings/pattern.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/time/default_tick_clock.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/time/tick_clock.h"
33*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
34*6777b538SAndroid Build Coastguard Worker #include "base/types/optional_util.h"
35*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
36*6777b538SAndroid Build Coastguard Worker #include "net/base/address_family.h"
37*6777b538SAndroid Build Coastguard Worker #include "net/base/address_list.h"
38*6777b538SAndroid Build Coastguard Worker #include "net/base/host_port_pair.h"
39*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_address.h"
40*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_endpoint.h"
41*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
42*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h"
43*6777b538SAndroid Build Coastguard Worker #include "net/base/network_anonymization_key.h"
44*6777b538SAndroid Build Coastguard Worker #include "net/base/test_completion_callback.h"
45*6777b538SAndroid Build Coastguard Worker #include "net/dns/dns_alias_utility.h"
46*6777b538SAndroid Build Coastguard Worker #include "net/dns/dns_names_util.h"
47*6777b538SAndroid Build Coastguard Worker #include "net/dns/dns_util.h"
48*6777b538SAndroid Build Coastguard Worker #include "net/dns/host_cache.h"
49*6777b538SAndroid Build Coastguard Worker #include "net/dns/host_resolver.h"
50*6777b538SAndroid Build Coastguard Worker #include "net/dns/host_resolver_manager.h"
51*6777b538SAndroid Build Coastguard Worker #include "net/dns/host_resolver_system_task.h"
52*6777b538SAndroid Build Coastguard Worker #include "net/dns/https_record_rdata.h"
53*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/dns_query_type.h"
54*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/host_resolver_results.h"
55*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/host_resolver_source.h"
56*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/mdns_listener_update_type.h"
57*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/resolve_error_info.h"
58*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/secure_dns_policy.h"
59*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_with_source.h"
60*6777b538SAndroid Build Coastguard Worker #include "net/url_request/url_request_context.h"
61*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/types/variant.h"
62*6777b538SAndroid Build Coastguard Worker #include "url/scheme_host_port.h"
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
65*6777b538SAndroid Build Coastguard Worker #include "net/base/winsock_init.h"
66*6777b538SAndroid Build Coastguard Worker #endif
67*6777b538SAndroid Build Coastguard Worker 
68*6777b538SAndroid Build Coastguard Worker namespace net {
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker namespace {
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker // Cache size for the MockCachingHostResolver.
73*6777b538SAndroid Build Coastguard Worker const unsigned kMaxCacheEntries = 100;
74*6777b538SAndroid Build Coastguard Worker // TTL for the successful resolutions. Failures are not cached.
75*6777b538SAndroid Build Coastguard Worker const unsigned kCacheEntryTTLSeconds = 60;
76*6777b538SAndroid Build Coastguard Worker 
GetCacheHost(const HostResolver::Host & endpoint)77*6777b538SAndroid Build Coastguard Worker absl::variant<url::SchemeHostPort, std::string> GetCacheHost(
78*6777b538SAndroid Build Coastguard Worker     const HostResolver::Host& endpoint) {
79*6777b538SAndroid Build Coastguard Worker   if (endpoint.HasScheme()) {
80*6777b538SAndroid Build Coastguard Worker     return endpoint.AsSchemeHostPort();
81*6777b538SAndroid Build Coastguard Worker   }
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker   return endpoint.GetHostname();
84*6777b538SAndroid Build Coastguard Worker }
85*6777b538SAndroid Build Coastguard Worker 
CreateCacheEntry(std::string_view canonical_name,const std::vector<HostResolverEndpointResult> & endpoint_results,const std::set<std::string> & aliases)86*6777b538SAndroid Build Coastguard Worker std::optional<HostCache::Entry> CreateCacheEntry(
87*6777b538SAndroid Build Coastguard Worker     std::string_view canonical_name,
88*6777b538SAndroid Build Coastguard Worker     const std::vector<HostResolverEndpointResult>& endpoint_results,
89*6777b538SAndroid Build Coastguard Worker     const std::set<std::string>& aliases) {
90*6777b538SAndroid Build Coastguard Worker   std::optional<std::vector<net::IPEndPoint>> ip_endpoints;
91*6777b538SAndroid Build Coastguard Worker   std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>
92*6777b538SAndroid Build Coastguard Worker       endpoint_metadatas;
93*6777b538SAndroid Build Coastguard Worker   for (const auto& endpoint_result : endpoint_results) {
94*6777b538SAndroid Build Coastguard Worker     if (!ip_endpoints) {
95*6777b538SAndroid Build Coastguard Worker       ip_endpoints = endpoint_result.ip_endpoints;
96*6777b538SAndroid Build Coastguard Worker     } else {
97*6777b538SAndroid Build Coastguard Worker       // TODO(crbug.com/1264933): Support caching different IP endpoints
98*6777b538SAndroid Build Coastguard Worker       // resutls.
99*6777b538SAndroid Build Coastguard Worker       CHECK(*ip_endpoints == endpoint_result.ip_endpoints)
100*6777b538SAndroid Build Coastguard Worker           << "Currently caching MockHostResolver only supports same IP "
101*6777b538SAndroid Build Coastguard Worker              "endpoints results.";
102*6777b538SAndroid Build Coastguard Worker     }
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker     if (!endpoint_result.metadata.supported_protocol_alpns.empty()) {
105*6777b538SAndroid Build Coastguard Worker       endpoint_metadatas.emplace(/*priority=*/1, endpoint_result.metadata);
106*6777b538SAndroid Build Coastguard Worker     }
107*6777b538SAndroid Build Coastguard Worker   }
108*6777b538SAndroid Build Coastguard Worker   DCHECK(ip_endpoints);
109*6777b538SAndroid Build Coastguard Worker   auto endpoint_entry = HostCache::Entry(OK, *ip_endpoints, aliases,
110*6777b538SAndroid Build Coastguard Worker                                          HostCache::Entry::SOURCE_UNKNOWN);
111*6777b538SAndroid Build Coastguard Worker   endpoint_entry.set_canonical_names(std::set{std::string(canonical_name)});
112*6777b538SAndroid Build Coastguard Worker   if (endpoint_metadatas.empty()) {
113*6777b538SAndroid Build Coastguard Worker     return endpoint_entry;
114*6777b538SAndroid Build Coastguard Worker   }
115*6777b538SAndroid Build Coastguard Worker   return HostCache::Entry::MergeEntries(
116*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, std::move(endpoint_metadatas),
117*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN),
118*6777b538SAndroid Build Coastguard Worker       endpoint_entry);
119*6777b538SAndroid Build Coastguard Worker }
120*6777b538SAndroid Build Coastguard Worker }  // namespace
121*6777b538SAndroid Build Coastguard Worker 
ParseAddressList(std::string_view host_list,std::vector<net::IPEndPoint> * ip_endpoints)122*6777b538SAndroid Build Coastguard Worker int ParseAddressList(std::string_view host_list,
123*6777b538SAndroid Build Coastguard Worker                      std::vector<net::IPEndPoint>* ip_endpoints) {
124*6777b538SAndroid Build Coastguard Worker   ip_endpoints->clear();
125*6777b538SAndroid Build Coastguard Worker   for (std::string_view address : base::SplitStringPiece(
126*6777b538SAndroid Build Coastguard Worker            host_list, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
127*6777b538SAndroid Build Coastguard Worker     IPAddress ip_address;
128*6777b538SAndroid Build Coastguard Worker     if (!ip_address.AssignFromIPLiteral(address)) {
129*6777b538SAndroid Build Coastguard Worker       LOG(WARNING) << "Not a supported IP literal: " << address;
130*6777b538SAndroid Build Coastguard Worker       return ERR_UNEXPECTED;
131*6777b538SAndroid Build Coastguard Worker     }
132*6777b538SAndroid Build Coastguard Worker     ip_endpoints->push_back(IPEndPoint(ip_address, 0));
133*6777b538SAndroid Build Coastguard Worker   }
134*6777b538SAndroid Build Coastguard Worker   return OK;
135*6777b538SAndroid Build Coastguard Worker }
136*6777b538SAndroid Build Coastguard Worker 
137*6777b538SAndroid Build Coastguard Worker class MockHostResolverBase::RequestImpl
138*6777b538SAndroid Build Coastguard Worker     : public HostResolver::ResolveHostRequest {
139*6777b538SAndroid Build Coastguard Worker  public:
RequestImpl(Host request_endpoint,const NetworkAnonymizationKey & network_anonymization_key,const std::optional<ResolveHostParameters> & optional_parameters,base::WeakPtr<MockHostResolverBase> resolver)140*6777b538SAndroid Build Coastguard Worker   RequestImpl(Host request_endpoint,
141*6777b538SAndroid Build Coastguard Worker               const NetworkAnonymizationKey& network_anonymization_key,
142*6777b538SAndroid Build Coastguard Worker               const std::optional<ResolveHostParameters>& optional_parameters,
143*6777b538SAndroid Build Coastguard Worker               base::WeakPtr<MockHostResolverBase> resolver)
144*6777b538SAndroid Build Coastguard Worker       : request_endpoint_(std::move(request_endpoint)),
145*6777b538SAndroid Build Coastguard Worker         network_anonymization_key_(network_anonymization_key),
146*6777b538SAndroid Build Coastguard Worker         parameters_(optional_parameters ? optional_parameters.value()
147*6777b538SAndroid Build Coastguard Worker                                         : ResolveHostParameters()),
148*6777b538SAndroid Build Coastguard Worker         priority_(parameters_.initial_priority),
149*6777b538SAndroid Build Coastguard Worker         host_resolver_flags_(ParametersToHostResolverFlags(parameters_)),
150*6777b538SAndroid Build Coastguard Worker         resolve_error_info_(ResolveErrorInfo(ERR_IO_PENDING)),
151*6777b538SAndroid Build Coastguard Worker         resolver_(resolver) {}
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker   RequestImpl(const RequestImpl&) = delete;
154*6777b538SAndroid Build Coastguard Worker   RequestImpl& operator=(const RequestImpl&) = delete;
155*6777b538SAndroid Build Coastguard Worker 
~RequestImpl()156*6777b538SAndroid Build Coastguard Worker   ~RequestImpl() override {
157*6777b538SAndroid Build Coastguard Worker     if (id_ > 0) {
158*6777b538SAndroid Build Coastguard Worker       if (resolver_)
159*6777b538SAndroid Build Coastguard Worker         resolver_->DetachRequest(id_);
160*6777b538SAndroid Build Coastguard Worker       id_ = 0;
161*6777b538SAndroid Build Coastguard Worker       resolver_ = nullptr;
162*6777b538SAndroid Build Coastguard Worker     }
163*6777b538SAndroid Build Coastguard Worker   }
164*6777b538SAndroid Build Coastguard Worker 
DetachFromResolver()165*6777b538SAndroid Build Coastguard Worker   void DetachFromResolver() {
166*6777b538SAndroid Build Coastguard Worker     id_ = 0;
167*6777b538SAndroid Build Coastguard Worker     resolver_ = nullptr;
168*6777b538SAndroid Build Coastguard Worker   }
169*6777b538SAndroid Build Coastguard Worker 
Start(CompletionOnceCallback callback)170*6777b538SAndroid Build Coastguard Worker   int Start(CompletionOnceCallback callback) override {
171*6777b538SAndroid Build Coastguard Worker     DCHECK(callback);
172*6777b538SAndroid Build Coastguard Worker     // Start() may only be called once per request.
173*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(0u, id_);
174*6777b538SAndroid Build Coastguard Worker     DCHECK(!complete_);
175*6777b538SAndroid Build Coastguard Worker     DCHECK(!callback_);
176*6777b538SAndroid Build Coastguard Worker     // Parent HostResolver must still be alive to call Start().
177*6777b538SAndroid Build Coastguard Worker     DCHECK(resolver_);
178*6777b538SAndroid Build Coastguard Worker 
179*6777b538SAndroid Build Coastguard Worker     int rv = resolver_->Resolve(this);
180*6777b538SAndroid Build Coastguard Worker     DCHECK(!complete_);
181*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING) {
182*6777b538SAndroid Build Coastguard Worker       DCHECK_GT(id_, 0u);
183*6777b538SAndroid Build Coastguard Worker       callback_ = std::move(callback);
184*6777b538SAndroid Build Coastguard Worker     } else {
185*6777b538SAndroid Build Coastguard Worker       DCHECK_EQ(0u, id_);
186*6777b538SAndroid Build Coastguard Worker       complete_ = true;
187*6777b538SAndroid Build Coastguard Worker     }
188*6777b538SAndroid Build Coastguard Worker 
189*6777b538SAndroid Build Coastguard Worker     return rv;
190*6777b538SAndroid Build Coastguard Worker   }
191*6777b538SAndroid Build Coastguard Worker 
GetAddressResults() const192*6777b538SAndroid Build Coastguard Worker   const AddressList* GetAddressResults() const override {
193*6777b538SAndroid Build Coastguard Worker     DCHECK(complete_);
194*6777b538SAndroid Build Coastguard Worker     return base::OptionalToPtr(address_results_);
195*6777b538SAndroid Build Coastguard Worker   }
196*6777b538SAndroid Build Coastguard Worker 
GetEndpointResults() const197*6777b538SAndroid Build Coastguard Worker   const std::vector<HostResolverEndpointResult>* GetEndpointResults()
198*6777b538SAndroid Build Coastguard Worker       const override {
199*6777b538SAndroid Build Coastguard Worker     DCHECK(complete_);
200*6777b538SAndroid Build Coastguard Worker     return base::OptionalToPtr(endpoint_results_);
201*6777b538SAndroid Build Coastguard Worker   }
202*6777b538SAndroid Build Coastguard Worker 
GetTextResults() const203*6777b538SAndroid Build Coastguard Worker   const std::vector<std::string>* GetTextResults() const override {
204*6777b538SAndroid Build Coastguard Worker     DCHECK(complete_);
205*6777b538SAndroid Build Coastguard Worker     static const base::NoDestructor<std::vector<std::string>> empty_result;
206*6777b538SAndroid Build Coastguard Worker     return empty_result.get();
207*6777b538SAndroid Build Coastguard Worker   }
208*6777b538SAndroid Build Coastguard Worker 
GetHostnameResults() const209*6777b538SAndroid Build Coastguard Worker   const std::vector<HostPortPair>* GetHostnameResults() const override {
210*6777b538SAndroid Build Coastguard Worker     DCHECK(complete_);
211*6777b538SAndroid Build Coastguard Worker     static const base::NoDestructor<std::vector<HostPortPair>> empty_result;
212*6777b538SAndroid Build Coastguard Worker     return empty_result.get();
213*6777b538SAndroid Build Coastguard Worker   }
214*6777b538SAndroid Build Coastguard Worker 
GetDnsAliasResults() const215*6777b538SAndroid Build Coastguard Worker   const std::set<std::string>* GetDnsAliasResults() const override {
216*6777b538SAndroid Build Coastguard Worker     DCHECK(complete_);
217*6777b538SAndroid Build Coastguard Worker     return base::OptionalToPtr(fixed_up_dns_alias_results_);
218*6777b538SAndroid Build Coastguard Worker   }
219*6777b538SAndroid Build Coastguard Worker 
GetResolveErrorInfo() const220*6777b538SAndroid Build Coastguard Worker   net::ResolveErrorInfo GetResolveErrorInfo() const override {
221*6777b538SAndroid Build Coastguard Worker     DCHECK(complete_);
222*6777b538SAndroid Build Coastguard Worker     return resolve_error_info_;
223*6777b538SAndroid Build Coastguard Worker   }
224*6777b538SAndroid Build Coastguard Worker 
GetStaleInfo() const225*6777b538SAndroid Build Coastguard Worker   const std::optional<HostCache::EntryStaleness>& GetStaleInfo()
226*6777b538SAndroid Build Coastguard Worker       const override {
227*6777b538SAndroid Build Coastguard Worker     DCHECK(complete_);
228*6777b538SAndroid Build Coastguard Worker     return staleness_;
229*6777b538SAndroid Build Coastguard Worker   }
230*6777b538SAndroid Build Coastguard Worker 
ChangeRequestPriority(RequestPriority priority)231*6777b538SAndroid Build Coastguard Worker   void ChangeRequestPriority(RequestPriority priority) override {
232*6777b538SAndroid Build Coastguard Worker     priority_ = priority;
233*6777b538SAndroid Build Coastguard Worker   }
234*6777b538SAndroid Build Coastguard Worker 
SetError(int error)235*6777b538SAndroid Build Coastguard Worker   void SetError(int error) {
236*6777b538SAndroid Build Coastguard Worker     // Should only be called before request is marked completed.
237*6777b538SAndroid Build Coastguard Worker     DCHECK(!complete_);
238*6777b538SAndroid Build Coastguard Worker     resolve_error_info_ = ResolveErrorInfo(error);
239*6777b538SAndroid Build Coastguard Worker   }
240*6777b538SAndroid Build Coastguard Worker 
241*6777b538SAndroid Build Coastguard Worker   // Sets `endpoint_results_`, `fixed_up_dns_alias_results_`,
242*6777b538SAndroid Build Coastguard Worker   // `address_results_` and `staleness_` after fixing them up.
243*6777b538SAndroid Build Coastguard Worker   // Also sets `error` to OK.
SetEndpointResults(std::vector<HostResolverEndpointResult> endpoint_results,std::set<std::string> aliases,std::optional<HostCache::EntryStaleness> staleness)244*6777b538SAndroid Build Coastguard Worker   void SetEndpointResults(
245*6777b538SAndroid Build Coastguard Worker       std::vector<HostResolverEndpointResult> endpoint_results,
246*6777b538SAndroid Build Coastguard Worker       std::set<std::string> aliases,
247*6777b538SAndroid Build Coastguard Worker       std::optional<HostCache::EntryStaleness> staleness) {
248*6777b538SAndroid Build Coastguard Worker     DCHECK(!complete_);
249*6777b538SAndroid Build Coastguard Worker     DCHECK(!endpoint_results_);
250*6777b538SAndroid Build Coastguard Worker     DCHECK(!parameters_.is_speculative);
251*6777b538SAndroid Build Coastguard Worker 
252*6777b538SAndroid Build Coastguard Worker     endpoint_results_ = std::move(endpoint_results);
253*6777b538SAndroid Build Coastguard Worker     for (auto& result : *endpoint_results_) {
254*6777b538SAndroid Build Coastguard Worker       result.ip_endpoints = FixupEndPoints(result.ip_endpoints);
255*6777b538SAndroid Build Coastguard Worker     }
256*6777b538SAndroid Build Coastguard Worker 
257*6777b538SAndroid Build Coastguard Worker     fixed_up_dns_alias_results_ = FixupAliases(aliases);
258*6777b538SAndroid Build Coastguard Worker 
259*6777b538SAndroid Build Coastguard Worker     // `HostResolver` implementations are expected to provide an `AddressList`
260*6777b538SAndroid Build Coastguard Worker     // result whenever `HostResolverEndpointResult` is also available.
261*6777b538SAndroid Build Coastguard Worker     address_results_ = EndpointResultToAddressList(
262*6777b538SAndroid Build Coastguard Worker         *endpoint_results_, *fixed_up_dns_alias_results_);
263*6777b538SAndroid Build Coastguard Worker 
264*6777b538SAndroid Build Coastguard Worker     staleness_ = std::move(staleness);
265*6777b538SAndroid Build Coastguard Worker 
266*6777b538SAndroid Build Coastguard Worker     SetError(OK);
267*6777b538SAndroid Build Coastguard Worker   }
268*6777b538SAndroid Build Coastguard Worker 
OnAsyncCompleted(size_t id,int error)269*6777b538SAndroid Build Coastguard Worker   void OnAsyncCompleted(size_t id, int error) {
270*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(id_, id);
271*6777b538SAndroid Build Coastguard Worker     id_ = 0;
272*6777b538SAndroid Build Coastguard Worker 
273*6777b538SAndroid Build Coastguard Worker     // Check that error information has been set and that the top-level error
274*6777b538SAndroid Build Coastguard Worker     // code is valid.
275*6777b538SAndroid Build Coastguard Worker     DCHECK(resolve_error_info_.error != ERR_IO_PENDING);
276*6777b538SAndroid Build Coastguard Worker     DCHECK(error == OK || error == ERR_NAME_NOT_RESOLVED ||
277*6777b538SAndroid Build Coastguard Worker            error == ERR_DNS_NAME_HTTPS_ONLY);
278*6777b538SAndroid Build Coastguard Worker 
279*6777b538SAndroid Build Coastguard Worker     DCHECK(!complete_);
280*6777b538SAndroid Build Coastguard Worker     complete_ = true;
281*6777b538SAndroid Build Coastguard Worker 
282*6777b538SAndroid Build Coastguard Worker     DCHECK(callback_);
283*6777b538SAndroid Build Coastguard Worker     std::move(callback_).Run(error);
284*6777b538SAndroid Build Coastguard Worker   }
285*6777b538SAndroid Build Coastguard Worker 
request_endpoint() const286*6777b538SAndroid Build Coastguard Worker   const Host& request_endpoint() const { return request_endpoint_; }
287*6777b538SAndroid Build Coastguard Worker 
network_anonymization_key() const288*6777b538SAndroid Build Coastguard Worker   const NetworkAnonymizationKey& network_anonymization_key() const {
289*6777b538SAndroid Build Coastguard Worker     return network_anonymization_key_;
290*6777b538SAndroid Build Coastguard Worker   }
291*6777b538SAndroid Build Coastguard Worker 
parameters() const292*6777b538SAndroid Build Coastguard Worker   const ResolveHostParameters& parameters() const { return parameters_; }
293*6777b538SAndroid Build Coastguard Worker 
host_resolver_flags() const294*6777b538SAndroid Build Coastguard Worker   int host_resolver_flags() const { return host_resolver_flags_; }
295*6777b538SAndroid Build Coastguard Worker 
id()296*6777b538SAndroid Build Coastguard Worker   size_t id() { return id_; }
297*6777b538SAndroid Build Coastguard Worker 
priority() const298*6777b538SAndroid Build Coastguard Worker   RequestPriority priority() const { return priority_; }
299*6777b538SAndroid Build Coastguard Worker 
set_id(size_t id)300*6777b538SAndroid Build Coastguard Worker   void set_id(size_t id) {
301*6777b538SAndroid Build Coastguard Worker     DCHECK_GT(id, 0u);
302*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(0u, id_);
303*6777b538SAndroid Build Coastguard Worker 
304*6777b538SAndroid Build Coastguard Worker     id_ = id;
305*6777b538SAndroid Build Coastguard Worker   }
306*6777b538SAndroid Build Coastguard Worker 
complete()307*6777b538SAndroid Build Coastguard Worker   bool complete() { return complete_; }
308*6777b538SAndroid Build Coastguard Worker 
309*6777b538SAndroid Build Coastguard Worker   // Similar get GetAddressResults() and GetResolveErrorInfo(), but only exposed
310*6777b538SAndroid Build Coastguard Worker   // through the HostResolver::ResolveHostRequest interface, and don't have the
311*6777b538SAndroid Build Coastguard Worker   // DCHECKs that `complete_` is true.
address_results() const312*6777b538SAndroid Build Coastguard Worker   const std::optional<AddressList>& address_results() const {
313*6777b538SAndroid Build Coastguard Worker     return address_results_;
314*6777b538SAndroid Build Coastguard Worker   }
resolve_error_info() const315*6777b538SAndroid Build Coastguard Worker   ResolveErrorInfo resolve_error_info() const { return resolve_error_info_; }
316*6777b538SAndroid Build Coastguard Worker 
317*6777b538SAndroid Build Coastguard Worker  private:
FixupEndPoints(const std::vector<IPEndPoint> & endpoints)318*6777b538SAndroid Build Coastguard Worker   std::vector<IPEndPoint> FixupEndPoints(
319*6777b538SAndroid Build Coastguard Worker       const std::vector<IPEndPoint>& endpoints) {
320*6777b538SAndroid Build Coastguard Worker     std::vector<IPEndPoint> corrected;
321*6777b538SAndroid Build Coastguard Worker     for (const IPEndPoint& endpoint : endpoints) {
322*6777b538SAndroid Build Coastguard Worker       DCHECK_NE(endpoint.GetFamily(), ADDRESS_FAMILY_UNSPECIFIED);
323*6777b538SAndroid Build Coastguard Worker       if (parameters_.dns_query_type == DnsQueryType::UNSPECIFIED ||
324*6777b538SAndroid Build Coastguard Worker           parameters_.dns_query_type ==
325*6777b538SAndroid Build Coastguard Worker               AddressFamilyToDnsQueryType(endpoint.GetFamily())) {
326*6777b538SAndroid Build Coastguard Worker         if (endpoint.port() == 0) {
327*6777b538SAndroid Build Coastguard Worker           corrected.emplace_back(endpoint.address(),
328*6777b538SAndroid Build Coastguard Worker                                  request_endpoint_.GetPort());
329*6777b538SAndroid Build Coastguard Worker         } else {
330*6777b538SAndroid Build Coastguard Worker           corrected.push_back(endpoint);
331*6777b538SAndroid Build Coastguard Worker         }
332*6777b538SAndroid Build Coastguard Worker       }
333*6777b538SAndroid Build Coastguard Worker     }
334*6777b538SAndroid Build Coastguard Worker     return corrected;
335*6777b538SAndroid Build Coastguard Worker   }
FixupAliases(const std::set<std::string> aliases)336*6777b538SAndroid Build Coastguard Worker   std::set<std::string> FixupAliases(const std::set<std::string> aliases) {
337*6777b538SAndroid Build Coastguard Worker     if (aliases.empty())
338*6777b538SAndroid Build Coastguard Worker       return std::set<std::string>{
339*6777b538SAndroid Build Coastguard Worker           std::string(request_endpoint_.GetHostnameWithoutBrackets())};
340*6777b538SAndroid Build Coastguard Worker     return aliases;
341*6777b538SAndroid Build Coastguard Worker   }
342*6777b538SAndroid Build Coastguard Worker 
343*6777b538SAndroid Build Coastguard Worker   const Host request_endpoint_;
344*6777b538SAndroid Build Coastguard Worker   const NetworkAnonymizationKey network_anonymization_key_;
345*6777b538SAndroid Build Coastguard Worker   const ResolveHostParameters parameters_;
346*6777b538SAndroid Build Coastguard Worker   RequestPriority priority_;
347*6777b538SAndroid Build Coastguard Worker   int host_resolver_flags_;
348*6777b538SAndroid Build Coastguard Worker 
349*6777b538SAndroid Build Coastguard Worker   std::optional<AddressList> address_results_;
350*6777b538SAndroid Build Coastguard Worker   std::optional<std::vector<HostResolverEndpointResult>> endpoint_results_;
351*6777b538SAndroid Build Coastguard Worker   std::optional<std::set<std::string>> fixed_up_dns_alias_results_;
352*6777b538SAndroid Build Coastguard Worker   std::optional<HostCache::EntryStaleness> staleness_;
353*6777b538SAndroid Build Coastguard Worker   ResolveErrorInfo resolve_error_info_;
354*6777b538SAndroid Build Coastguard Worker 
355*6777b538SAndroid Build Coastguard Worker   // Used while stored with the resolver for async resolution.  Otherwise 0.
356*6777b538SAndroid Build Coastguard Worker   size_t id_ = 0;
357*6777b538SAndroid Build Coastguard Worker 
358*6777b538SAndroid Build Coastguard Worker   CompletionOnceCallback callback_;
359*6777b538SAndroid Build Coastguard Worker   // Use a WeakPtr as the resolver may be destroyed while there are still
360*6777b538SAndroid Build Coastguard Worker   // outstanding request objects.
361*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<MockHostResolverBase> resolver_;
362*6777b538SAndroid Build Coastguard Worker   bool complete_ = false;
363*6777b538SAndroid Build Coastguard Worker };
364*6777b538SAndroid Build Coastguard Worker 
365*6777b538SAndroid Build Coastguard Worker class MockHostResolverBase::ProbeRequestImpl
366*6777b538SAndroid Build Coastguard Worker     : public HostResolver::ProbeRequest {
367*6777b538SAndroid Build Coastguard Worker  public:
ProbeRequestImpl(base::WeakPtr<MockHostResolverBase> resolver)368*6777b538SAndroid Build Coastguard Worker   explicit ProbeRequestImpl(base::WeakPtr<MockHostResolverBase> resolver)
369*6777b538SAndroid Build Coastguard Worker       : resolver_(std::move(resolver)) {}
370*6777b538SAndroid Build Coastguard Worker 
371*6777b538SAndroid Build Coastguard Worker   ProbeRequestImpl(const ProbeRequestImpl&) = delete;
372*6777b538SAndroid Build Coastguard Worker   ProbeRequestImpl& operator=(const ProbeRequestImpl&) = delete;
373*6777b538SAndroid Build Coastguard Worker 
~ProbeRequestImpl()374*6777b538SAndroid Build Coastguard Worker   ~ProbeRequestImpl() override {
375*6777b538SAndroid Build Coastguard Worker     if (resolver_) {
376*6777b538SAndroid Build Coastguard Worker       resolver_->state_->ClearDohProbeRequestIfMatching(this);
377*6777b538SAndroid Build Coastguard Worker     }
378*6777b538SAndroid Build Coastguard Worker   }
379*6777b538SAndroid Build Coastguard Worker 
Start()380*6777b538SAndroid Build Coastguard Worker   int Start() override {
381*6777b538SAndroid Build Coastguard Worker     DCHECK(resolver_);
382*6777b538SAndroid Build Coastguard Worker     resolver_->state_->set_doh_probe_request(this);
383*6777b538SAndroid Build Coastguard Worker 
384*6777b538SAndroid Build Coastguard Worker     return ERR_IO_PENDING;
385*6777b538SAndroid Build Coastguard Worker   }
386*6777b538SAndroid Build Coastguard Worker 
387*6777b538SAndroid Build Coastguard Worker  private:
388*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<MockHostResolverBase> resolver_;
389*6777b538SAndroid Build Coastguard Worker };
390*6777b538SAndroid Build Coastguard Worker 
391*6777b538SAndroid Build Coastguard Worker class MockHostResolverBase::MdnsListenerImpl
392*6777b538SAndroid Build Coastguard Worker     : public HostResolver::MdnsListener {
393*6777b538SAndroid Build Coastguard Worker  public:
MdnsListenerImpl(const HostPortPair & host,DnsQueryType query_type,base::WeakPtr<MockHostResolverBase> resolver)394*6777b538SAndroid Build Coastguard Worker   MdnsListenerImpl(const HostPortPair& host,
395*6777b538SAndroid Build Coastguard Worker                    DnsQueryType query_type,
396*6777b538SAndroid Build Coastguard Worker                    base::WeakPtr<MockHostResolverBase> resolver)
397*6777b538SAndroid Build Coastguard Worker       : host_(host), query_type_(query_type), resolver_(resolver) {
398*6777b538SAndroid Build Coastguard Worker     DCHECK_NE(DnsQueryType::UNSPECIFIED, query_type_);
399*6777b538SAndroid Build Coastguard Worker     DCHECK(resolver_);
400*6777b538SAndroid Build Coastguard Worker   }
401*6777b538SAndroid Build Coastguard Worker 
~MdnsListenerImpl()402*6777b538SAndroid Build Coastguard Worker   ~MdnsListenerImpl() override {
403*6777b538SAndroid Build Coastguard Worker     if (resolver_)
404*6777b538SAndroid Build Coastguard Worker       resolver_->RemoveCancelledListener(this);
405*6777b538SAndroid Build Coastguard Worker   }
406*6777b538SAndroid Build Coastguard Worker 
Start(Delegate * delegate)407*6777b538SAndroid Build Coastguard Worker   int Start(Delegate* delegate) override {
408*6777b538SAndroid Build Coastguard Worker     DCHECK(delegate);
409*6777b538SAndroid Build Coastguard Worker     DCHECK(!delegate_);
410*6777b538SAndroid Build Coastguard Worker     DCHECK(resolver_);
411*6777b538SAndroid Build Coastguard Worker 
412*6777b538SAndroid Build Coastguard Worker     delegate_ = delegate;
413*6777b538SAndroid Build Coastguard Worker     resolver_->AddListener(this);
414*6777b538SAndroid Build Coastguard Worker 
415*6777b538SAndroid Build Coastguard Worker     return OK;
416*6777b538SAndroid Build Coastguard Worker   }
417*6777b538SAndroid Build Coastguard Worker 
TriggerAddressResult(MdnsListenerUpdateType update_type,IPEndPoint address)418*6777b538SAndroid Build Coastguard Worker   void TriggerAddressResult(MdnsListenerUpdateType update_type,
419*6777b538SAndroid Build Coastguard Worker                             IPEndPoint address) {
420*6777b538SAndroid Build Coastguard Worker     delegate_->OnAddressResult(update_type, query_type_, std::move(address));
421*6777b538SAndroid Build Coastguard Worker   }
422*6777b538SAndroid Build Coastguard Worker 
TriggerTextResult(MdnsListenerUpdateType update_type,std::vector<std::string> text_records)423*6777b538SAndroid Build Coastguard Worker   void TriggerTextResult(MdnsListenerUpdateType update_type,
424*6777b538SAndroid Build Coastguard Worker                          std::vector<std::string> text_records) {
425*6777b538SAndroid Build Coastguard Worker     delegate_->OnTextResult(update_type, query_type_, std::move(text_records));
426*6777b538SAndroid Build Coastguard Worker   }
427*6777b538SAndroid Build Coastguard Worker 
TriggerHostnameResult(MdnsListenerUpdateType update_type,HostPortPair host)428*6777b538SAndroid Build Coastguard Worker   void TriggerHostnameResult(MdnsListenerUpdateType update_type,
429*6777b538SAndroid Build Coastguard Worker                              HostPortPair host) {
430*6777b538SAndroid Build Coastguard Worker     delegate_->OnHostnameResult(update_type, query_type_, std::move(host));
431*6777b538SAndroid Build Coastguard Worker   }
432*6777b538SAndroid Build Coastguard Worker 
TriggerUnhandledResult(MdnsListenerUpdateType update_type)433*6777b538SAndroid Build Coastguard Worker   void TriggerUnhandledResult(MdnsListenerUpdateType update_type) {
434*6777b538SAndroid Build Coastguard Worker     delegate_->OnUnhandledResult(update_type, query_type_);
435*6777b538SAndroid Build Coastguard Worker   }
436*6777b538SAndroid Build Coastguard Worker 
host() const437*6777b538SAndroid Build Coastguard Worker   const HostPortPair& host() const { return host_; }
query_type() const438*6777b538SAndroid Build Coastguard Worker   DnsQueryType query_type() const { return query_type_; }
439*6777b538SAndroid Build Coastguard Worker 
440*6777b538SAndroid Build Coastguard Worker  private:
441*6777b538SAndroid Build Coastguard Worker   const HostPortPair host_;
442*6777b538SAndroid Build Coastguard Worker   const DnsQueryType query_type_;
443*6777b538SAndroid Build Coastguard Worker 
444*6777b538SAndroid Build Coastguard Worker   raw_ptr<Delegate> delegate_ = nullptr;
445*6777b538SAndroid Build Coastguard Worker 
446*6777b538SAndroid Build Coastguard Worker   // Use a WeakPtr as the resolver may be destroyed while there are still
447*6777b538SAndroid Build Coastguard Worker   // outstanding listener objects.
448*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<MockHostResolverBase> resolver_;
449*6777b538SAndroid Build Coastguard Worker };
450*6777b538SAndroid Build Coastguard Worker 
451*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleKey::RuleKey() = default;
452*6777b538SAndroid Build Coastguard Worker 
453*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleKey::~RuleKey() = default;
454*6777b538SAndroid Build Coastguard Worker 
455*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleKey::RuleKey(const RuleKey&) = default;
456*6777b538SAndroid Build Coastguard Worker 
457*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleKey&
458*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleKey::operator=(const RuleKey&) =
459*6777b538SAndroid Build Coastguard Worker     default;
460*6777b538SAndroid Build Coastguard Worker 
461*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleKey::RuleKey(RuleKey&&) = default;
462*6777b538SAndroid Build Coastguard Worker 
463*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleKey&
464*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleKey::operator=(RuleKey&&) = default;
465*6777b538SAndroid Build Coastguard Worker 
466*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResult::RuleResult() = default;
467*6777b538SAndroid Build Coastguard Worker 
RuleResult(std::vector<HostResolverEndpointResult> endpoints,std::set<std::string> aliases)468*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResult::RuleResult(
469*6777b538SAndroid Build Coastguard Worker     std::vector<HostResolverEndpointResult> endpoints,
470*6777b538SAndroid Build Coastguard Worker     std::set<std::string> aliases)
471*6777b538SAndroid Build Coastguard Worker     : endpoints(std::move(endpoints)), aliases(std::move(aliases)) {}
472*6777b538SAndroid Build Coastguard Worker 
473*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResult::~RuleResult() = default;
474*6777b538SAndroid Build Coastguard Worker 
475*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResult::RuleResult(const RuleResult&) =
476*6777b538SAndroid Build Coastguard Worker     default;
477*6777b538SAndroid Build Coastguard Worker 
478*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResult&
479*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResult::operator=(const RuleResult&) =
480*6777b538SAndroid Build Coastguard Worker     default;
481*6777b538SAndroid Build Coastguard Worker 
482*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResult::RuleResult(RuleResult&&) =
483*6777b538SAndroid Build Coastguard Worker     default;
484*6777b538SAndroid Build Coastguard Worker 
485*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResult&
486*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResult::operator=(RuleResult&&) =
487*6777b538SAndroid Build Coastguard Worker     default;
488*6777b538SAndroid Build Coastguard Worker 
RuleResolver(std::optional<RuleResultOrError> default_result)489*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResolver(
490*6777b538SAndroid Build Coastguard Worker     std::optional<RuleResultOrError> default_result)
491*6777b538SAndroid Build Coastguard Worker     : default_result_(std::move(default_result)) {}
492*6777b538SAndroid Build Coastguard Worker 
493*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::~RuleResolver() = default;
494*6777b538SAndroid Build Coastguard Worker 
495*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResolver(const RuleResolver&) = default;
496*6777b538SAndroid Build Coastguard Worker 
497*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver&
498*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::operator=(const RuleResolver&) = default;
499*6777b538SAndroid Build Coastguard Worker 
500*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResolver(RuleResolver&&) = default;
501*6777b538SAndroid Build Coastguard Worker 
502*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver&
503*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::operator=(RuleResolver&&) = default;
504*6777b538SAndroid Build Coastguard Worker 
505*6777b538SAndroid Build Coastguard Worker const MockHostResolverBase::RuleResolver::RuleResultOrError&
Resolve(const Host & request_endpoint,DnsQueryTypeSet request_types,HostResolverSource request_source) const506*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::Resolve(
507*6777b538SAndroid Build Coastguard Worker     const Host& request_endpoint,
508*6777b538SAndroid Build Coastguard Worker     DnsQueryTypeSet request_types,
509*6777b538SAndroid Build Coastguard Worker     HostResolverSource request_source) const {
510*6777b538SAndroid Build Coastguard Worker   for (const auto& rule : rules_) {
511*6777b538SAndroid Build Coastguard Worker     const RuleKey& key = rule.first;
512*6777b538SAndroid Build Coastguard Worker     const RuleResultOrError& result = rule.second;
513*6777b538SAndroid Build Coastguard Worker 
514*6777b538SAndroid Build Coastguard Worker     if (absl::holds_alternative<RuleKey::NoScheme>(key.scheme) &&
515*6777b538SAndroid Build Coastguard Worker         request_endpoint.HasScheme()) {
516*6777b538SAndroid Build Coastguard Worker       continue;
517*6777b538SAndroid Build Coastguard Worker     }
518*6777b538SAndroid Build Coastguard Worker 
519*6777b538SAndroid Build Coastguard Worker     if (key.port.has_value() &&
520*6777b538SAndroid Build Coastguard Worker         key.port.value() != request_endpoint.GetPort()) {
521*6777b538SAndroid Build Coastguard Worker       continue;
522*6777b538SAndroid Build Coastguard Worker     }
523*6777b538SAndroid Build Coastguard Worker 
524*6777b538SAndroid Build Coastguard Worker     DCHECK(!key.query_type.has_value() ||
525*6777b538SAndroid Build Coastguard Worker            key.query_type.value() != DnsQueryType::UNSPECIFIED);
526*6777b538SAndroid Build Coastguard Worker     if (key.query_type.has_value() &&
527*6777b538SAndroid Build Coastguard Worker         !request_types.Has(key.query_type.value())) {
528*6777b538SAndroid Build Coastguard Worker       continue;
529*6777b538SAndroid Build Coastguard Worker     }
530*6777b538SAndroid Build Coastguard Worker 
531*6777b538SAndroid Build Coastguard Worker     if (key.query_source.has_value() &&
532*6777b538SAndroid Build Coastguard Worker         request_source != key.query_source.value()) {
533*6777b538SAndroid Build Coastguard Worker       continue;
534*6777b538SAndroid Build Coastguard Worker     }
535*6777b538SAndroid Build Coastguard Worker 
536*6777b538SAndroid Build Coastguard Worker     if (absl::holds_alternative<RuleKey::Scheme>(key.scheme) &&
537*6777b538SAndroid Build Coastguard Worker         (!request_endpoint.HasScheme() ||
538*6777b538SAndroid Build Coastguard Worker          request_endpoint.GetScheme() !=
539*6777b538SAndroid Build Coastguard Worker              absl::get<RuleKey::Scheme>(key.scheme))) {
540*6777b538SAndroid Build Coastguard Worker       continue;
541*6777b538SAndroid Build Coastguard Worker     }
542*6777b538SAndroid Build Coastguard Worker 
543*6777b538SAndroid Build Coastguard Worker     if (!base::MatchPattern(request_endpoint.GetHostnameWithoutBrackets(),
544*6777b538SAndroid Build Coastguard Worker                             key.hostname_pattern)) {
545*6777b538SAndroid Build Coastguard Worker       continue;
546*6777b538SAndroid Build Coastguard Worker     }
547*6777b538SAndroid Build Coastguard Worker 
548*6777b538SAndroid Build Coastguard Worker     return result;
549*6777b538SAndroid Build Coastguard Worker   }
550*6777b538SAndroid Build Coastguard Worker 
551*6777b538SAndroid Build Coastguard Worker   if (default_result_)
552*6777b538SAndroid Build Coastguard Worker     return default_result_.value();
553*6777b538SAndroid Build Coastguard Worker 
554*6777b538SAndroid Build Coastguard Worker   NOTREACHED() << "Request " << request_endpoint.GetHostname()
555*6777b538SAndroid Build Coastguard Worker                << " did not match any MockHostResolver rules.";
556*6777b538SAndroid Build Coastguard Worker   static const RuleResultOrError kUnexpected = ERR_UNEXPECTED;
557*6777b538SAndroid Build Coastguard Worker   return kUnexpected;
558*6777b538SAndroid Build Coastguard Worker }
559*6777b538SAndroid Build Coastguard Worker 
ClearRules()560*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::ClearRules() {
561*6777b538SAndroid Build Coastguard Worker   rules_.clear();
562*6777b538SAndroid Build Coastguard Worker }
563*6777b538SAndroid Build Coastguard Worker 
564*6777b538SAndroid Build Coastguard Worker // static
565*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::RuleResultOrError
GetLocalhostResult()566*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RuleResolver::GetLocalhostResult() {
567*6777b538SAndroid Build Coastguard Worker   HostResolverEndpointResult endpoint;
568*6777b538SAndroid Build Coastguard Worker   endpoint.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), /*port=*/0)};
569*6777b538SAndroid Build Coastguard Worker   return RuleResult(std::vector{endpoint});
570*6777b538SAndroid Build Coastguard Worker }
571*6777b538SAndroid Build Coastguard Worker 
AddRule(RuleKey key,RuleResultOrError result)572*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::AddRule(RuleKey key,
573*6777b538SAndroid Build Coastguard Worker                                                  RuleResultOrError result) {
574*6777b538SAndroid Build Coastguard Worker   // Literals are always resolved to themselves by MockHostResolverBase,
575*6777b538SAndroid Build Coastguard Worker   // consequently we do not support remapping them.
576*6777b538SAndroid Build Coastguard Worker   IPAddress ip_address;
577*6777b538SAndroid Build Coastguard Worker   DCHECK(!ip_address.AssignFromIPLiteral(key.hostname_pattern));
578*6777b538SAndroid Build Coastguard Worker 
579*6777b538SAndroid Build Coastguard Worker   CHECK(rules_.emplace(std::move(key), std::move(result)).second)
580*6777b538SAndroid Build Coastguard Worker       << "Duplicate rule key";
581*6777b538SAndroid Build Coastguard Worker }
582*6777b538SAndroid Build Coastguard Worker 
AddRule(RuleKey key,std::string_view ip_literal)583*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::AddRule(RuleKey key,
584*6777b538SAndroid Build Coastguard Worker                                                  std::string_view ip_literal) {
585*6777b538SAndroid Build Coastguard Worker   std::vector<HostResolverEndpointResult> endpoints;
586*6777b538SAndroid Build Coastguard Worker   endpoints.emplace_back();
587*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(ParseAddressList(ip_literal, &endpoints[0].ip_endpoints), OK);
588*6777b538SAndroid Build Coastguard Worker   AddRule(std::move(key), RuleResult(std::move(endpoints)));
589*6777b538SAndroid Build Coastguard Worker }
590*6777b538SAndroid Build Coastguard Worker 
AddRule(std::string_view hostname_pattern,RuleResultOrError result)591*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::AddRule(
592*6777b538SAndroid Build Coastguard Worker     std::string_view hostname_pattern,
593*6777b538SAndroid Build Coastguard Worker     RuleResultOrError result) {
594*6777b538SAndroid Build Coastguard Worker   RuleKey key;
595*6777b538SAndroid Build Coastguard Worker   key.hostname_pattern = std::string(hostname_pattern);
596*6777b538SAndroid Build Coastguard Worker   AddRule(std::move(key), std::move(result));
597*6777b538SAndroid Build Coastguard Worker }
598*6777b538SAndroid Build Coastguard Worker 
AddRule(std::string_view hostname_pattern,std::string_view ip_literal)599*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::AddRule(
600*6777b538SAndroid Build Coastguard Worker     std::string_view hostname_pattern,
601*6777b538SAndroid Build Coastguard Worker     std::string_view ip_literal) {
602*6777b538SAndroid Build Coastguard Worker   std::vector<HostResolverEndpointResult> endpoints;
603*6777b538SAndroid Build Coastguard Worker   endpoints.emplace_back();
604*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(ParseAddressList(ip_literal, &endpoints[0].ip_endpoints), OK);
605*6777b538SAndroid Build Coastguard Worker   AddRule(hostname_pattern, RuleResult(std::move(endpoints)));
606*6777b538SAndroid Build Coastguard Worker }
607*6777b538SAndroid Build Coastguard Worker 
AddRule(std::string_view hostname_pattern,Error error)608*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::AddRule(
609*6777b538SAndroid Build Coastguard Worker     std::string_view hostname_pattern,
610*6777b538SAndroid Build Coastguard Worker     Error error) {
611*6777b538SAndroid Build Coastguard Worker   RuleKey key;
612*6777b538SAndroid Build Coastguard Worker   key.hostname_pattern = std::string(hostname_pattern);
613*6777b538SAndroid Build Coastguard Worker 
614*6777b538SAndroid Build Coastguard Worker   AddRule(std::move(key), error);
615*6777b538SAndroid Build Coastguard Worker }
616*6777b538SAndroid Build Coastguard Worker 
AddIPLiteralRule(std::string_view hostname_pattern,std::string_view ip_literal,std::string_view canonical_name)617*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::AddIPLiteralRule(
618*6777b538SAndroid Build Coastguard Worker     std::string_view hostname_pattern,
619*6777b538SAndroid Build Coastguard Worker     std::string_view ip_literal,
620*6777b538SAndroid Build Coastguard Worker     std::string_view canonical_name) {
621*6777b538SAndroid Build Coastguard Worker   RuleKey key;
622*6777b538SAndroid Build Coastguard Worker   key.hostname_pattern = std::string(hostname_pattern);
623*6777b538SAndroid Build Coastguard Worker 
624*6777b538SAndroid Build Coastguard Worker   std::set<std::string> aliases;
625*6777b538SAndroid Build Coastguard Worker   if (!canonical_name.empty())
626*6777b538SAndroid Build Coastguard Worker     aliases.emplace(canonical_name);
627*6777b538SAndroid Build Coastguard Worker 
628*6777b538SAndroid Build Coastguard Worker   std::vector<HostResolverEndpointResult> endpoints;
629*6777b538SAndroid Build Coastguard Worker   endpoints.emplace_back();
630*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(ParseAddressList(ip_literal, &endpoints[0].ip_endpoints), OK);
631*6777b538SAndroid Build Coastguard Worker   AddRule(std::move(key), RuleResult(std::move(endpoints), std::move(aliases)));
632*6777b538SAndroid Build Coastguard Worker }
633*6777b538SAndroid Build Coastguard Worker 
AddIPLiteralRuleWithDnsAliases(std::string_view hostname_pattern,std::string_view ip_literal,std::vector<std::string> dns_aliases)634*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::AddIPLiteralRuleWithDnsAliases(
635*6777b538SAndroid Build Coastguard Worker     std::string_view hostname_pattern,
636*6777b538SAndroid Build Coastguard Worker     std::string_view ip_literal,
637*6777b538SAndroid Build Coastguard Worker     std::vector<std::string> dns_aliases) {
638*6777b538SAndroid Build Coastguard Worker   std::vector<HostResolverEndpointResult> endpoints;
639*6777b538SAndroid Build Coastguard Worker   endpoints.emplace_back();
640*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(ParseAddressList(ip_literal, &endpoints[0].ip_endpoints), OK);
641*6777b538SAndroid Build Coastguard Worker   AddRule(hostname_pattern,
642*6777b538SAndroid Build Coastguard Worker           RuleResult(
643*6777b538SAndroid Build Coastguard Worker               std::move(endpoints),
644*6777b538SAndroid Build Coastguard Worker               std::set<std::string>(dns_aliases.begin(), dns_aliases.end())));
645*6777b538SAndroid Build Coastguard Worker }
646*6777b538SAndroid Build Coastguard Worker 
AddIPLiteralRuleWithDnsAliases(std::string_view hostname_pattern,std::string_view ip_literal,std::set<std::string> dns_aliases)647*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::AddIPLiteralRuleWithDnsAliases(
648*6777b538SAndroid Build Coastguard Worker     std::string_view hostname_pattern,
649*6777b538SAndroid Build Coastguard Worker     std::string_view ip_literal,
650*6777b538SAndroid Build Coastguard Worker     std::set<std::string> dns_aliases) {
651*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> aliases_vector;
652*6777b538SAndroid Build Coastguard Worker   base::ranges::move(dns_aliases, std::back_inserter(aliases_vector));
653*6777b538SAndroid Build Coastguard Worker 
654*6777b538SAndroid Build Coastguard Worker   AddIPLiteralRuleWithDnsAliases(hostname_pattern, ip_literal,
655*6777b538SAndroid Build Coastguard Worker                                  std::move(aliases_vector));
656*6777b538SAndroid Build Coastguard Worker }
657*6777b538SAndroid Build Coastguard Worker 
AddSimulatedFailure(std::string_view hostname_pattern)658*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::AddSimulatedFailure(
659*6777b538SAndroid Build Coastguard Worker     std::string_view hostname_pattern) {
660*6777b538SAndroid Build Coastguard Worker   AddRule(hostname_pattern, ERR_NAME_NOT_RESOLVED);
661*6777b538SAndroid Build Coastguard Worker }
662*6777b538SAndroid Build Coastguard Worker 
AddSimulatedTimeoutFailure(std::string_view hostname_pattern)663*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::AddSimulatedTimeoutFailure(
664*6777b538SAndroid Build Coastguard Worker     std::string_view hostname_pattern) {
665*6777b538SAndroid Build Coastguard Worker   AddRule(hostname_pattern, ERR_DNS_TIMED_OUT);
666*6777b538SAndroid Build Coastguard Worker }
667*6777b538SAndroid Build Coastguard Worker 
AddRuleWithFlags(std::string_view host_pattern,std::string_view ip_literal,HostResolverFlags,std::vector<std::string> dns_aliases)668*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RuleResolver::AddRuleWithFlags(
669*6777b538SAndroid Build Coastguard Worker     std::string_view host_pattern,
670*6777b538SAndroid Build Coastguard Worker     std::string_view ip_literal,
671*6777b538SAndroid Build Coastguard Worker     HostResolverFlags /*flags*/,
672*6777b538SAndroid Build Coastguard Worker     std::vector<std::string> dns_aliases) {
673*6777b538SAndroid Build Coastguard Worker   std::vector<HostResolverEndpointResult> endpoints;
674*6777b538SAndroid Build Coastguard Worker   endpoints.emplace_back();
675*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(ParseAddressList(ip_literal, &endpoints[0].ip_endpoints), OK);
676*6777b538SAndroid Build Coastguard Worker   AddRule(host_pattern, RuleResult(std::move(endpoints),
677*6777b538SAndroid Build Coastguard Worker                                    std::set<std::string>(dns_aliases.begin(),
678*6777b538SAndroid Build Coastguard Worker                                                          dns_aliases.end())));
679*6777b538SAndroid Build Coastguard Worker }
680*6777b538SAndroid Build Coastguard Worker 
681*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::State::State() = default;
682*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::State::~State() = default;
683*6777b538SAndroid Build Coastguard Worker 
~MockHostResolverBase()684*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::~MockHostResolverBase() {
685*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
686*6777b538SAndroid Build Coastguard Worker 
687*6777b538SAndroid Build Coastguard Worker   // Sanity check that pending requests are always cleaned up, by waiting for
688*6777b538SAndroid Build Coastguard Worker   // completion, manually cancelling, or calling OnShutdown().
689*6777b538SAndroid Build Coastguard Worker   DCHECK(!state_->has_pending_requests());
690*6777b538SAndroid Build Coastguard Worker }
691*6777b538SAndroid Build Coastguard Worker 
OnShutdown()692*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::OnShutdown() {
693*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
694*6777b538SAndroid Build Coastguard Worker 
695*6777b538SAndroid Build Coastguard Worker   // Cancel all pending requests.
696*6777b538SAndroid Build Coastguard Worker   for (auto& request : state_->mutable_requests()) {
697*6777b538SAndroid Build Coastguard Worker     request.second->DetachFromResolver();
698*6777b538SAndroid Build Coastguard Worker   }
699*6777b538SAndroid Build Coastguard Worker   state_->mutable_requests().clear();
700*6777b538SAndroid Build Coastguard Worker 
701*6777b538SAndroid Build Coastguard Worker   // Prevent future requests by clearing resolution rules and the cache.
702*6777b538SAndroid Build Coastguard Worker   rule_resolver_.ClearRules();
703*6777b538SAndroid Build Coastguard Worker   cache_ = nullptr;
704*6777b538SAndroid Build Coastguard Worker 
705*6777b538SAndroid Build Coastguard Worker   state_->ClearDohProbeRequest();
706*6777b538SAndroid Build Coastguard Worker }
707*6777b538SAndroid Build Coastguard Worker 
708*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HostResolver::ResolveHostRequest>
CreateRequest(url::SchemeHostPort host,NetworkAnonymizationKey network_anonymization_key,NetLogWithSource net_log,std::optional<ResolveHostParameters> optional_parameters)709*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::CreateRequest(
710*6777b538SAndroid Build Coastguard Worker     url::SchemeHostPort host,
711*6777b538SAndroid Build Coastguard Worker     NetworkAnonymizationKey network_anonymization_key,
712*6777b538SAndroid Build Coastguard Worker     NetLogWithSource net_log,
713*6777b538SAndroid Build Coastguard Worker     std::optional<ResolveHostParameters> optional_parameters) {
714*6777b538SAndroid Build Coastguard Worker   return std::make_unique<RequestImpl>(Host(std::move(host)),
715*6777b538SAndroid Build Coastguard Worker                                        network_anonymization_key,
716*6777b538SAndroid Build Coastguard Worker                                        optional_parameters, AsWeakPtr());
717*6777b538SAndroid Build Coastguard Worker }
718*6777b538SAndroid Build Coastguard Worker 
719*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HostResolver::ResolveHostRequest>
CreateRequest(const HostPortPair & host,const NetworkAnonymizationKey & network_anonymization_key,const NetLogWithSource & source_net_log,const std::optional<ResolveHostParameters> & optional_parameters)720*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::CreateRequest(
721*6777b538SAndroid Build Coastguard Worker     const HostPortPair& host,
722*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
723*6777b538SAndroid Build Coastguard Worker     const NetLogWithSource& source_net_log,
724*6777b538SAndroid Build Coastguard Worker     const std::optional<ResolveHostParameters>& optional_parameters) {
725*6777b538SAndroid Build Coastguard Worker   return std::make_unique<RequestImpl>(Host(host), network_anonymization_key,
726*6777b538SAndroid Build Coastguard Worker                                        optional_parameters, AsWeakPtr());
727*6777b538SAndroid Build Coastguard Worker }
728*6777b538SAndroid Build Coastguard Worker 
729*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HostResolver::ServiceEndpointRequest>
CreateServiceEndpointRequest(Host host,NetworkAnonymizationKey network_anonymization_key,NetLogWithSource net_log,ResolveHostParameters parameters)730*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::CreateServiceEndpointRequest(
731*6777b538SAndroid Build Coastguard Worker     Host host,
732*6777b538SAndroid Build Coastguard Worker     NetworkAnonymizationKey network_anonymization_key,
733*6777b538SAndroid Build Coastguard Worker     NetLogWithSource net_log,
734*6777b538SAndroid Build Coastguard Worker     ResolveHostParameters parameters) {
735*6777b538SAndroid Build Coastguard Worker   NOTIMPLEMENTED();
736*6777b538SAndroid Build Coastguard Worker   return nullptr;
737*6777b538SAndroid Build Coastguard Worker }
738*6777b538SAndroid Build Coastguard Worker 
739*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HostResolver::ProbeRequest>
CreateDohProbeRequest()740*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::CreateDohProbeRequest() {
741*6777b538SAndroid Build Coastguard Worker   return std::make_unique<ProbeRequestImpl>(AsWeakPtr());
742*6777b538SAndroid Build Coastguard Worker }
743*6777b538SAndroid Build Coastguard Worker 
744*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HostResolver::MdnsListener>
CreateMdnsListener(const HostPortPair & host,DnsQueryType query_type)745*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::CreateMdnsListener(const HostPortPair& host,
746*6777b538SAndroid Build Coastguard Worker                                          DnsQueryType query_type) {
747*6777b538SAndroid Build Coastguard Worker   return std::make_unique<MdnsListenerImpl>(host, query_type, AsWeakPtr());
748*6777b538SAndroid Build Coastguard Worker }
749*6777b538SAndroid Build Coastguard Worker 
GetHostCache()750*6777b538SAndroid Build Coastguard Worker HostCache* MockHostResolverBase::GetHostCache() {
751*6777b538SAndroid Build Coastguard Worker   return cache_.get();
752*6777b538SAndroid Build Coastguard Worker }
753*6777b538SAndroid Build Coastguard Worker 
LoadIntoCache(absl::variant<url::SchemeHostPort,HostPortPair> endpoint,const NetworkAnonymizationKey & network_anonymization_key,const std::optional<ResolveHostParameters> & optional_parameters)754*6777b538SAndroid Build Coastguard Worker int MockHostResolverBase::LoadIntoCache(
755*6777b538SAndroid Build Coastguard Worker     absl::variant<url::SchemeHostPort, HostPortPair> endpoint,
756*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
757*6777b538SAndroid Build Coastguard Worker     const std::optional<ResolveHostParameters>& optional_parameters) {
758*6777b538SAndroid Build Coastguard Worker   return LoadIntoCache(Host(std::move(endpoint)), network_anonymization_key,
759*6777b538SAndroid Build Coastguard Worker                        optional_parameters);
760*6777b538SAndroid Build Coastguard Worker }
761*6777b538SAndroid Build Coastguard Worker 
LoadIntoCache(const Host & endpoint,const NetworkAnonymizationKey & network_anonymization_key,const std::optional<ResolveHostParameters> & optional_parameters)762*6777b538SAndroid Build Coastguard Worker int MockHostResolverBase::LoadIntoCache(
763*6777b538SAndroid Build Coastguard Worker     const Host& endpoint,
764*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
765*6777b538SAndroid Build Coastguard Worker     const std::optional<ResolveHostParameters>& optional_parameters) {
766*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
767*6777b538SAndroid Build Coastguard Worker   DCHECK(cache_);
768*6777b538SAndroid Build Coastguard Worker 
769*6777b538SAndroid Build Coastguard Worker   ResolveHostParameters parameters =
770*6777b538SAndroid Build Coastguard Worker       optional_parameters.value_or(ResolveHostParameters());
771*6777b538SAndroid Build Coastguard Worker 
772*6777b538SAndroid Build Coastguard Worker   std::vector<HostResolverEndpointResult> endpoints;
773*6777b538SAndroid Build Coastguard Worker   std::set<std::string> aliases;
774*6777b538SAndroid Build Coastguard Worker   std::optional<HostCache::EntryStaleness> stale_info;
775*6777b538SAndroid Build Coastguard Worker   int rv = ResolveFromIPLiteralOrCache(
776*6777b538SAndroid Build Coastguard Worker       endpoint, network_anonymization_key, parameters.dns_query_type,
777*6777b538SAndroid Build Coastguard Worker       ParametersToHostResolverFlags(parameters), parameters.source,
778*6777b538SAndroid Build Coastguard Worker       parameters.cache_usage, &endpoints, &aliases, &stale_info);
779*6777b538SAndroid Build Coastguard Worker   if (rv != ERR_DNS_CACHE_MISS) {
780*6777b538SAndroid Build Coastguard Worker     // Request already in cache (or IP literal). No need to load it.
781*6777b538SAndroid Build Coastguard Worker     return rv;
782*6777b538SAndroid Build Coastguard Worker   }
783*6777b538SAndroid Build Coastguard Worker 
784*6777b538SAndroid Build Coastguard Worker   // Just like the real resolver, refuse to do anything with invalid
785*6777b538SAndroid Build Coastguard Worker   // hostnames.
786*6777b538SAndroid Build Coastguard Worker   if (!dns_names_util::IsValidDnsName(endpoint.GetHostnameWithoutBrackets()))
787*6777b538SAndroid Build Coastguard Worker     return ERR_NAME_NOT_RESOLVED;
788*6777b538SAndroid Build Coastguard Worker 
789*6777b538SAndroid Build Coastguard Worker   RequestImpl request(endpoint, network_anonymization_key, optional_parameters,
790*6777b538SAndroid Build Coastguard Worker                       AsWeakPtr());
791*6777b538SAndroid Build Coastguard Worker   return DoSynchronousResolution(request);
792*6777b538SAndroid Build Coastguard Worker }
793*6777b538SAndroid Build Coastguard Worker 
ResolveAllPending()794*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::ResolveAllPending() {
795*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
796*6777b538SAndroid Build Coastguard Worker   DCHECK(ondemand_mode_);
797*6777b538SAndroid Build Coastguard Worker   for (auto& [id, request] : state_->mutable_requests()) {
798*6777b538SAndroid Build Coastguard Worker     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
799*6777b538SAndroid Build Coastguard Worker         FROM_HERE,
800*6777b538SAndroid Build Coastguard Worker         base::BindOnce(&MockHostResolverBase::ResolveNow, AsWeakPtr(), id));
801*6777b538SAndroid Build Coastguard Worker   }
802*6777b538SAndroid Build Coastguard Worker }
803*6777b538SAndroid Build Coastguard Worker 
last_id()804*6777b538SAndroid Build Coastguard Worker size_t MockHostResolverBase::last_id() {
805*6777b538SAndroid Build Coastguard Worker   if (!has_pending_requests())
806*6777b538SAndroid Build Coastguard Worker     return 0;
807*6777b538SAndroid Build Coastguard Worker   return state_->mutable_requests().rbegin()->first;
808*6777b538SAndroid Build Coastguard Worker }
809*6777b538SAndroid Build Coastguard Worker 
ResolveNow(size_t id)810*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::ResolveNow(size_t id) {
811*6777b538SAndroid Build Coastguard Worker   auto it = state_->mutable_requests().find(id);
812*6777b538SAndroid Build Coastguard Worker   if (it == state_->mutable_requests().end())
813*6777b538SAndroid Build Coastguard Worker     return;  // was canceled
814*6777b538SAndroid Build Coastguard Worker 
815*6777b538SAndroid Build Coastguard Worker   RequestImpl* req = it->second;
816*6777b538SAndroid Build Coastguard Worker   state_->mutable_requests().erase(it);
817*6777b538SAndroid Build Coastguard Worker 
818*6777b538SAndroid Build Coastguard Worker   int error = DoSynchronousResolution(*req);
819*6777b538SAndroid Build Coastguard Worker   req->OnAsyncCompleted(id, error);
820*6777b538SAndroid Build Coastguard Worker }
821*6777b538SAndroid Build Coastguard Worker 
DetachRequest(size_t id)822*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::DetachRequest(size_t id) {
823*6777b538SAndroid Build Coastguard Worker   auto it = state_->mutable_requests().find(id);
824*6777b538SAndroid Build Coastguard Worker   CHECK(it != state_->mutable_requests().end());
825*6777b538SAndroid Build Coastguard Worker   state_->mutable_requests().erase(it);
826*6777b538SAndroid Build Coastguard Worker }
827*6777b538SAndroid Build Coastguard Worker 
request_host(size_t id)828*6777b538SAndroid Build Coastguard Worker std::string_view MockHostResolverBase::request_host(size_t id) {
829*6777b538SAndroid Build Coastguard Worker   DCHECK(request(id));
830*6777b538SAndroid Build Coastguard Worker   return request(id)->request_endpoint().GetHostnameWithoutBrackets();
831*6777b538SAndroid Build Coastguard Worker }
832*6777b538SAndroid Build Coastguard Worker 
request_priority(size_t id)833*6777b538SAndroid Build Coastguard Worker RequestPriority MockHostResolverBase::request_priority(size_t id) {
834*6777b538SAndroid Build Coastguard Worker   DCHECK(request(id));
835*6777b538SAndroid Build Coastguard Worker   return request(id)->priority();
836*6777b538SAndroid Build Coastguard Worker }
837*6777b538SAndroid Build Coastguard Worker 
838*6777b538SAndroid Build Coastguard Worker const NetworkAnonymizationKey&
request_network_anonymization_key(size_t id)839*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::request_network_anonymization_key(size_t id) {
840*6777b538SAndroid Build Coastguard Worker   DCHECK(request(id));
841*6777b538SAndroid Build Coastguard Worker   return request(id)->network_anonymization_key();
842*6777b538SAndroid Build Coastguard Worker }
843*6777b538SAndroid Build Coastguard Worker 
ResolveOnlyRequestNow()844*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::ResolveOnlyRequestNow() {
845*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(1u, state_->mutable_requests().size());
846*6777b538SAndroid Build Coastguard Worker   ResolveNow(state_->mutable_requests().begin()->first);
847*6777b538SAndroid Build Coastguard Worker }
848*6777b538SAndroid Build Coastguard Worker 
TriggerMdnsListeners(const HostPortPair & host,DnsQueryType query_type,MdnsListenerUpdateType update_type,const IPEndPoint & address_result)849*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::TriggerMdnsListeners(
850*6777b538SAndroid Build Coastguard Worker     const HostPortPair& host,
851*6777b538SAndroid Build Coastguard Worker     DnsQueryType query_type,
852*6777b538SAndroid Build Coastguard Worker     MdnsListenerUpdateType update_type,
853*6777b538SAndroid Build Coastguard Worker     const IPEndPoint& address_result) {
854*6777b538SAndroid Build Coastguard Worker   for (MdnsListenerImpl* listener : listeners_) {
855*6777b538SAndroid Build Coastguard Worker     if (listener->host() == host && listener->query_type() == query_type)
856*6777b538SAndroid Build Coastguard Worker       listener->TriggerAddressResult(update_type, address_result);
857*6777b538SAndroid Build Coastguard Worker   }
858*6777b538SAndroid Build Coastguard Worker }
859*6777b538SAndroid Build Coastguard Worker 
TriggerMdnsListeners(const HostPortPair & host,DnsQueryType query_type,MdnsListenerUpdateType update_type,const std::vector<std::string> & text_result)860*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::TriggerMdnsListeners(
861*6777b538SAndroid Build Coastguard Worker     const HostPortPair& host,
862*6777b538SAndroid Build Coastguard Worker     DnsQueryType query_type,
863*6777b538SAndroid Build Coastguard Worker     MdnsListenerUpdateType update_type,
864*6777b538SAndroid Build Coastguard Worker     const std::vector<std::string>& text_result) {
865*6777b538SAndroid Build Coastguard Worker   for (MdnsListenerImpl* listener : listeners_) {
866*6777b538SAndroid Build Coastguard Worker     if (listener->host() == host && listener->query_type() == query_type)
867*6777b538SAndroid Build Coastguard Worker       listener->TriggerTextResult(update_type, text_result);
868*6777b538SAndroid Build Coastguard Worker   }
869*6777b538SAndroid Build Coastguard Worker }
870*6777b538SAndroid Build Coastguard Worker 
TriggerMdnsListeners(const HostPortPair & host,DnsQueryType query_type,MdnsListenerUpdateType update_type,const HostPortPair & host_result)871*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::TriggerMdnsListeners(
872*6777b538SAndroid Build Coastguard Worker     const HostPortPair& host,
873*6777b538SAndroid Build Coastguard Worker     DnsQueryType query_type,
874*6777b538SAndroid Build Coastguard Worker     MdnsListenerUpdateType update_type,
875*6777b538SAndroid Build Coastguard Worker     const HostPortPair& host_result) {
876*6777b538SAndroid Build Coastguard Worker   for (MdnsListenerImpl* listener : listeners_) {
877*6777b538SAndroid Build Coastguard Worker     if (listener->host() == host && listener->query_type() == query_type)
878*6777b538SAndroid Build Coastguard Worker       listener->TriggerHostnameResult(update_type, host_result);
879*6777b538SAndroid Build Coastguard Worker   }
880*6777b538SAndroid Build Coastguard Worker }
881*6777b538SAndroid Build Coastguard Worker 
TriggerMdnsListeners(const HostPortPair & host,DnsQueryType query_type,MdnsListenerUpdateType update_type)882*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::TriggerMdnsListeners(
883*6777b538SAndroid Build Coastguard Worker     const HostPortPair& host,
884*6777b538SAndroid Build Coastguard Worker     DnsQueryType query_type,
885*6777b538SAndroid Build Coastguard Worker     MdnsListenerUpdateType update_type) {
886*6777b538SAndroid Build Coastguard Worker   for (MdnsListenerImpl* listener : listeners_) {
887*6777b538SAndroid Build Coastguard Worker     if (listener->host() == host && listener->query_type() == query_type)
888*6777b538SAndroid Build Coastguard Worker       listener->TriggerUnhandledResult(update_type);
889*6777b538SAndroid Build Coastguard Worker   }
890*6777b538SAndroid Build Coastguard Worker }
891*6777b538SAndroid Build Coastguard Worker 
request(size_t id)892*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::RequestImpl* MockHostResolverBase::request(size_t id) {
893*6777b538SAndroid Build Coastguard Worker   RequestMap::iterator request = state_->mutable_requests().find(id);
894*6777b538SAndroid Build Coastguard Worker   CHECK(request != state_->mutable_requests().end());
895*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(request->second->id(), id);
896*6777b538SAndroid Build Coastguard Worker   return (*request).second;
897*6777b538SAndroid Build Coastguard Worker }
898*6777b538SAndroid Build Coastguard Worker 
899*6777b538SAndroid Build Coastguard Worker // start id from 1 to distinguish from NULL RequestHandle
MockHostResolverBase(bool use_caching,int cache_invalidation_num,RuleResolver rule_resolver)900*6777b538SAndroid Build Coastguard Worker MockHostResolverBase::MockHostResolverBase(bool use_caching,
901*6777b538SAndroid Build Coastguard Worker                                            int cache_invalidation_num,
902*6777b538SAndroid Build Coastguard Worker                                            RuleResolver rule_resolver)
903*6777b538SAndroid Build Coastguard Worker     : rule_resolver_(std::move(rule_resolver)),
904*6777b538SAndroid Build Coastguard Worker       initial_cache_invalidation_num_(cache_invalidation_num),
905*6777b538SAndroid Build Coastguard Worker       tick_clock_(base::DefaultTickClock::GetInstance()),
906*6777b538SAndroid Build Coastguard Worker       state_(base::MakeRefCounted<State>()) {
907*6777b538SAndroid Build Coastguard Worker   if (use_caching)
908*6777b538SAndroid Build Coastguard Worker     cache_ = std::make_unique<HostCache>(kMaxCacheEntries);
909*6777b538SAndroid Build Coastguard Worker   else
910*6777b538SAndroid Build Coastguard Worker     DCHECK_GE(0, cache_invalidation_num);
911*6777b538SAndroid Build Coastguard Worker }
912*6777b538SAndroid Build Coastguard Worker 
Resolve(RequestImpl * request)913*6777b538SAndroid Build Coastguard Worker int MockHostResolverBase::Resolve(RequestImpl* request) {
914*6777b538SAndroid Build Coastguard Worker   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
915*6777b538SAndroid Build Coastguard Worker 
916*6777b538SAndroid Build Coastguard Worker   last_request_priority_ = request->parameters().initial_priority;
917*6777b538SAndroid Build Coastguard Worker   last_request_network_anonymization_key_ =
918*6777b538SAndroid Build Coastguard Worker       request->network_anonymization_key();
919*6777b538SAndroid Build Coastguard Worker   last_secure_dns_policy_ = request->parameters().secure_dns_policy;
920*6777b538SAndroid Build Coastguard Worker   state_->IncrementNumResolve();
921*6777b538SAndroid Build Coastguard Worker   std::vector<HostResolverEndpointResult> endpoints;
922*6777b538SAndroid Build Coastguard Worker   std::set<std::string> aliases;
923*6777b538SAndroid Build Coastguard Worker   std::optional<HostCache::EntryStaleness> stale_info;
924*6777b538SAndroid Build Coastguard Worker   // TODO(crbug.com/1264933): Allow caching `ConnectionEndpoint` results.
925*6777b538SAndroid Build Coastguard Worker   int rv = ResolveFromIPLiteralOrCache(
926*6777b538SAndroid Build Coastguard Worker       request->request_endpoint(), request->network_anonymization_key(),
927*6777b538SAndroid Build Coastguard Worker       request->parameters().dns_query_type, request->host_resolver_flags(),
928*6777b538SAndroid Build Coastguard Worker       request->parameters().source, request->parameters().cache_usage,
929*6777b538SAndroid Build Coastguard Worker       &endpoints, &aliases, &stale_info);
930*6777b538SAndroid Build Coastguard Worker 
931*6777b538SAndroid Build Coastguard Worker   if (rv == OK && !request->parameters().is_speculative) {
932*6777b538SAndroid Build Coastguard Worker     request->SetEndpointResults(std::move(endpoints), std::move(aliases),
933*6777b538SAndroid Build Coastguard Worker                                 std::move(stale_info));
934*6777b538SAndroid Build Coastguard Worker   } else {
935*6777b538SAndroid Build Coastguard Worker     request->SetError(rv);
936*6777b538SAndroid Build Coastguard Worker   }
937*6777b538SAndroid Build Coastguard Worker 
938*6777b538SAndroid Build Coastguard Worker   if (rv != ERR_DNS_CACHE_MISS ||
939*6777b538SAndroid Build Coastguard Worker       request->parameters().source == HostResolverSource::LOCAL_ONLY) {
940*6777b538SAndroid Build Coastguard Worker     return SquashErrorCode(rv);
941*6777b538SAndroid Build Coastguard Worker   }
942*6777b538SAndroid Build Coastguard Worker 
943*6777b538SAndroid Build Coastguard Worker   // Just like the real resolver, refuse to do anything with invalid
944*6777b538SAndroid Build Coastguard Worker   // hostnames.
945*6777b538SAndroid Build Coastguard Worker   if (!dns_names_util::IsValidDnsName(
946*6777b538SAndroid Build Coastguard Worker           request->request_endpoint().GetHostnameWithoutBrackets())) {
947*6777b538SAndroid Build Coastguard Worker     request->SetError(ERR_NAME_NOT_RESOLVED);
948*6777b538SAndroid Build Coastguard Worker     return ERR_NAME_NOT_RESOLVED;
949*6777b538SAndroid Build Coastguard Worker   }
950*6777b538SAndroid Build Coastguard Worker 
951*6777b538SAndroid Build Coastguard Worker   if (synchronous_mode_)
952*6777b538SAndroid Build Coastguard Worker     return DoSynchronousResolution(*request);
953*6777b538SAndroid Build Coastguard Worker 
954*6777b538SAndroid Build Coastguard Worker   // Store the request for asynchronous resolution
955*6777b538SAndroid Build Coastguard Worker   size_t id = next_request_id_++;
956*6777b538SAndroid Build Coastguard Worker   request->set_id(id);
957*6777b538SAndroid Build Coastguard Worker   state_->mutable_requests()[id] = request;
958*6777b538SAndroid Build Coastguard Worker 
959*6777b538SAndroid Build Coastguard Worker   if (!ondemand_mode_) {
960*6777b538SAndroid Build Coastguard Worker     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
961*6777b538SAndroid Build Coastguard Worker         FROM_HERE,
962*6777b538SAndroid Build Coastguard Worker         base::BindOnce(&MockHostResolverBase::ResolveNow, AsWeakPtr(), id));
963*6777b538SAndroid Build Coastguard Worker   }
964*6777b538SAndroid Build Coastguard Worker 
965*6777b538SAndroid Build Coastguard Worker   return ERR_IO_PENDING;
966*6777b538SAndroid Build Coastguard Worker }
967*6777b538SAndroid Build Coastguard Worker 
ResolveFromIPLiteralOrCache(const Host & endpoint,const NetworkAnonymizationKey & network_anonymization_key,DnsQueryType dns_query_type,HostResolverFlags flags,HostResolverSource source,HostResolver::ResolveHostParameters::CacheUsage cache_usage,std::vector<HostResolverEndpointResult> * out_endpoints,std::set<std::string> * out_aliases,std::optional<HostCache::EntryStaleness> * out_stale_info)968*6777b538SAndroid Build Coastguard Worker int MockHostResolverBase::ResolveFromIPLiteralOrCache(
969*6777b538SAndroid Build Coastguard Worker     const Host& endpoint,
970*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
971*6777b538SAndroid Build Coastguard Worker     DnsQueryType dns_query_type,
972*6777b538SAndroid Build Coastguard Worker     HostResolverFlags flags,
973*6777b538SAndroid Build Coastguard Worker     HostResolverSource source,
974*6777b538SAndroid Build Coastguard Worker     HostResolver::ResolveHostParameters::CacheUsage cache_usage,
975*6777b538SAndroid Build Coastguard Worker     std::vector<HostResolverEndpointResult>* out_endpoints,
976*6777b538SAndroid Build Coastguard Worker     std::set<std::string>* out_aliases,
977*6777b538SAndroid Build Coastguard Worker     std::optional<HostCache::EntryStaleness>* out_stale_info) {
978*6777b538SAndroid Build Coastguard Worker   DCHECK(out_endpoints);
979*6777b538SAndroid Build Coastguard Worker   DCHECK(out_aliases);
980*6777b538SAndroid Build Coastguard Worker   DCHECK(out_stale_info);
981*6777b538SAndroid Build Coastguard Worker   out_endpoints->clear();
982*6777b538SAndroid Build Coastguard Worker   out_aliases->clear();
983*6777b538SAndroid Build Coastguard Worker   *out_stale_info = std::nullopt;
984*6777b538SAndroid Build Coastguard Worker 
985*6777b538SAndroid Build Coastguard Worker   IPAddress ip_address;
986*6777b538SAndroid Build Coastguard Worker   if (ip_address.AssignFromIPLiteral(endpoint.GetHostnameWithoutBrackets())) {
987*6777b538SAndroid Build Coastguard Worker     const DnsQueryType desired_address_query =
988*6777b538SAndroid Build Coastguard Worker         AddressFamilyToDnsQueryType(GetAddressFamily(ip_address));
989*6777b538SAndroid Build Coastguard Worker     DCHECK_NE(desired_address_query, DnsQueryType::UNSPECIFIED);
990*6777b538SAndroid Build Coastguard Worker 
991*6777b538SAndroid Build Coastguard Worker     // This matches the behavior HostResolverImpl.
992*6777b538SAndroid Build Coastguard Worker     if (dns_query_type != DnsQueryType::UNSPECIFIED &&
993*6777b538SAndroid Build Coastguard Worker         dns_query_type != desired_address_query) {
994*6777b538SAndroid Build Coastguard Worker       return ERR_NAME_NOT_RESOLVED;
995*6777b538SAndroid Build Coastguard Worker     }
996*6777b538SAndroid Build Coastguard Worker 
997*6777b538SAndroid Build Coastguard Worker     *out_endpoints = std::vector<HostResolverEndpointResult>(1);
998*6777b538SAndroid Build Coastguard Worker     (*out_endpoints)[0].ip_endpoints.emplace_back(ip_address,
999*6777b538SAndroid Build Coastguard Worker                                                   endpoint.GetPort());
1000*6777b538SAndroid Build Coastguard Worker     if (flags & HOST_RESOLVER_CANONNAME)
1001*6777b538SAndroid Build Coastguard Worker       *out_aliases = {ip_address.ToString()};
1002*6777b538SAndroid Build Coastguard Worker     return OK;
1003*6777b538SAndroid Build Coastguard Worker   }
1004*6777b538SAndroid Build Coastguard Worker 
1005*6777b538SAndroid Build Coastguard Worker   std::vector<IPEndPoint> localhost_endpoints;
1006*6777b538SAndroid Build Coastguard Worker   // Immediately resolve any "localhost" or recognized similar names.
1007*6777b538SAndroid Build Coastguard Worker   if (IsAddressType(dns_query_type) &&
1008*6777b538SAndroid Build Coastguard Worker       ResolveLocalHostname(endpoint.GetHostnameWithoutBrackets(),
1009*6777b538SAndroid Build Coastguard Worker                            &localhost_endpoints)) {
1010*6777b538SAndroid Build Coastguard Worker     *out_endpoints = std::vector<HostResolverEndpointResult>(1);
1011*6777b538SAndroid Build Coastguard Worker     (*out_endpoints)[0].ip_endpoints = localhost_endpoints;
1012*6777b538SAndroid Build Coastguard Worker     return OK;
1013*6777b538SAndroid Build Coastguard Worker   }
1014*6777b538SAndroid Build Coastguard Worker   int rv = ERR_DNS_CACHE_MISS;
1015*6777b538SAndroid Build Coastguard Worker   bool cache_allowed =
1016*6777b538SAndroid Build Coastguard Worker       cache_usage == HostResolver::ResolveHostParameters::CacheUsage::ALLOWED ||
1017*6777b538SAndroid Build Coastguard Worker       cache_usage ==
1018*6777b538SAndroid Build Coastguard Worker           HostResolver::ResolveHostParameters::CacheUsage::STALE_ALLOWED;
1019*6777b538SAndroid Build Coastguard Worker   if (cache_.get() && cache_allowed) {
1020*6777b538SAndroid Build Coastguard Worker     // Local-only requests search the cache for non-local-only results.
1021*6777b538SAndroid Build Coastguard Worker     HostResolverSource effective_source =
1022*6777b538SAndroid Build Coastguard Worker         source == HostResolverSource::LOCAL_ONLY ? HostResolverSource::ANY
1023*6777b538SAndroid Build Coastguard Worker                                                  : source;
1024*6777b538SAndroid Build Coastguard Worker     HostCache::Key key(GetCacheHost(endpoint), dns_query_type, flags,
1025*6777b538SAndroid Build Coastguard Worker                        effective_source, network_anonymization_key);
1026*6777b538SAndroid Build Coastguard Worker     const std::pair<const HostCache::Key, HostCache::Entry>* cache_result;
1027*6777b538SAndroid Build Coastguard Worker     HostCache::EntryStaleness stale_info = HostCache::kNotStale;
1028*6777b538SAndroid Build Coastguard Worker     if (cache_usage ==
1029*6777b538SAndroid Build Coastguard Worker         HostResolver::ResolveHostParameters::CacheUsage::STALE_ALLOWED) {
1030*6777b538SAndroid Build Coastguard Worker       cache_result = cache_->LookupStale(key, tick_clock_->NowTicks(),
1031*6777b538SAndroid Build Coastguard Worker                                          &stale_info, true /* ignore_secure */);
1032*6777b538SAndroid Build Coastguard Worker     } else {
1033*6777b538SAndroid Build Coastguard Worker       cache_result = cache_->Lookup(key, tick_clock_->NowTicks(),
1034*6777b538SAndroid Build Coastguard Worker                                     true /* ignore_secure */);
1035*6777b538SAndroid Build Coastguard Worker     }
1036*6777b538SAndroid Build Coastguard Worker     if (cache_result) {
1037*6777b538SAndroid Build Coastguard Worker       rv = cache_result->second.error();
1038*6777b538SAndroid Build Coastguard Worker       if (rv == OK) {
1039*6777b538SAndroid Build Coastguard Worker         *out_endpoints = cache_result->second.GetEndpoints();
1040*6777b538SAndroid Build Coastguard Worker 
1041*6777b538SAndroid Build Coastguard Worker         *out_aliases = cache_result->second.aliases();
1042*6777b538SAndroid Build Coastguard Worker         *out_stale_info = std::move(stale_info);
1043*6777b538SAndroid Build Coastguard Worker       }
1044*6777b538SAndroid Build Coastguard Worker 
1045*6777b538SAndroid Build Coastguard Worker       auto cache_invalidation_iterator = cache_invalidation_nums_.find(key);
1046*6777b538SAndroid Build Coastguard Worker       if (cache_invalidation_iterator != cache_invalidation_nums_.end()) {
1047*6777b538SAndroid Build Coastguard Worker         DCHECK_LE(1, cache_invalidation_iterator->second);
1048*6777b538SAndroid Build Coastguard Worker         cache_invalidation_iterator->second--;
1049*6777b538SAndroid Build Coastguard Worker         if (cache_invalidation_iterator->second == 0) {
1050*6777b538SAndroid Build Coastguard Worker           HostCache::Entry new_entry(cache_result->second);
1051*6777b538SAndroid Build Coastguard Worker           cache_->Set(key, new_entry, tick_clock_->NowTicks(),
1052*6777b538SAndroid Build Coastguard Worker                       base::TimeDelta());
1053*6777b538SAndroid Build Coastguard Worker           cache_invalidation_nums_.erase(cache_invalidation_iterator);
1054*6777b538SAndroid Build Coastguard Worker         }
1055*6777b538SAndroid Build Coastguard Worker       }
1056*6777b538SAndroid Build Coastguard Worker     }
1057*6777b538SAndroid Build Coastguard Worker   }
1058*6777b538SAndroid Build Coastguard Worker   return rv;
1059*6777b538SAndroid Build Coastguard Worker }
1060*6777b538SAndroid Build Coastguard Worker 
DoSynchronousResolution(RequestImpl & request)1061*6777b538SAndroid Build Coastguard Worker int MockHostResolverBase::DoSynchronousResolution(RequestImpl& request) {
1062*6777b538SAndroid Build Coastguard Worker   state_->IncrementNumNonLocalResolves();
1063*6777b538SAndroid Build Coastguard Worker 
1064*6777b538SAndroid Build Coastguard Worker   const RuleResolver::RuleResultOrError& result = rule_resolver_.Resolve(
1065*6777b538SAndroid Build Coastguard Worker       request.request_endpoint(), {request.parameters().dns_query_type},
1066*6777b538SAndroid Build Coastguard Worker       request.parameters().source);
1067*6777b538SAndroid Build Coastguard Worker 
1068*6777b538SAndroid Build Coastguard Worker   int error = ERR_UNEXPECTED;
1069*6777b538SAndroid Build Coastguard Worker   std::optional<HostCache::Entry> cache_entry;
1070*6777b538SAndroid Build Coastguard Worker   if (absl::holds_alternative<RuleResolver::RuleResult>(result)) {
1071*6777b538SAndroid Build Coastguard Worker     const auto& rule_result = absl::get<RuleResolver::RuleResult>(result);
1072*6777b538SAndroid Build Coastguard Worker     const auto& endpoint_results = rule_result.endpoints;
1073*6777b538SAndroid Build Coastguard Worker     const auto& aliases = rule_result.aliases;
1074*6777b538SAndroid Build Coastguard Worker     request.SetEndpointResults(endpoint_results, aliases,
1075*6777b538SAndroid Build Coastguard Worker                                /*staleness=*/std::nullopt);
1076*6777b538SAndroid Build Coastguard Worker     // TODO(crbug.com/1264933): Change `error` on empty results?
1077*6777b538SAndroid Build Coastguard Worker     error = OK;
1078*6777b538SAndroid Build Coastguard Worker     if (cache_.get()) {
1079*6777b538SAndroid Build Coastguard Worker       cache_entry = CreateCacheEntry(request.request_endpoint().GetHostname(),
1080*6777b538SAndroid Build Coastguard Worker                                      endpoint_results, aliases);
1081*6777b538SAndroid Build Coastguard Worker     }
1082*6777b538SAndroid Build Coastguard Worker   } else {
1083*6777b538SAndroid Build Coastguard Worker     DCHECK(absl::holds_alternative<RuleResolver::ErrorResult>(result));
1084*6777b538SAndroid Build Coastguard Worker     error = absl::get<RuleResolver::ErrorResult>(result);
1085*6777b538SAndroid Build Coastguard Worker     request.SetError(error);
1086*6777b538SAndroid Build Coastguard Worker     if (cache_.get()) {
1087*6777b538SAndroid Build Coastguard Worker       cache_entry.emplace(error, HostCache::Entry::SOURCE_UNKNOWN);
1088*6777b538SAndroid Build Coastguard Worker     }
1089*6777b538SAndroid Build Coastguard Worker   }
1090*6777b538SAndroid Build Coastguard Worker   if (cache_.get() && cache_entry.has_value()) {
1091*6777b538SAndroid Build Coastguard Worker     HostCache::Key key(
1092*6777b538SAndroid Build Coastguard Worker         GetCacheHost(request.request_endpoint()),
1093*6777b538SAndroid Build Coastguard Worker         request.parameters().dns_query_type, request.host_resolver_flags(),
1094*6777b538SAndroid Build Coastguard Worker         request.parameters().source, request.network_anonymization_key());
1095*6777b538SAndroid Build Coastguard Worker     // Storing a failure with TTL 0 so that it overwrites previous value.
1096*6777b538SAndroid Build Coastguard Worker     base::TimeDelta ttl;
1097*6777b538SAndroid Build Coastguard Worker     if (error == OK) {
1098*6777b538SAndroid Build Coastguard Worker       ttl = base::Seconds(kCacheEntryTTLSeconds);
1099*6777b538SAndroid Build Coastguard Worker       if (initial_cache_invalidation_num_ > 0)
1100*6777b538SAndroid Build Coastguard Worker         cache_invalidation_nums_[key] = initial_cache_invalidation_num_;
1101*6777b538SAndroid Build Coastguard Worker     }
1102*6777b538SAndroid Build Coastguard Worker     cache_->Set(key, cache_entry.value(), tick_clock_->NowTicks(), ttl);
1103*6777b538SAndroid Build Coastguard Worker   }
1104*6777b538SAndroid Build Coastguard Worker 
1105*6777b538SAndroid Build Coastguard Worker   return SquashErrorCode(error);
1106*6777b538SAndroid Build Coastguard Worker }
1107*6777b538SAndroid Build Coastguard Worker 
AddListener(MdnsListenerImpl * listener)1108*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::AddListener(MdnsListenerImpl* listener) {
1109*6777b538SAndroid Build Coastguard Worker   listeners_.insert(listener);
1110*6777b538SAndroid Build Coastguard Worker }
1111*6777b538SAndroid Build Coastguard Worker 
RemoveCancelledListener(MdnsListenerImpl * listener)1112*6777b538SAndroid Build Coastguard Worker void MockHostResolverBase::RemoveCancelledListener(MdnsListenerImpl* listener) {
1113*6777b538SAndroid Build Coastguard Worker   listeners_.erase(listener);
1114*6777b538SAndroid Build Coastguard Worker }
1115*6777b538SAndroid Build Coastguard Worker 
MockHostResolverFactory(MockHostResolverBase::RuleResolver rules,bool use_caching,int cache_invalidation_num)1116*6777b538SAndroid Build Coastguard Worker MockHostResolverFactory::MockHostResolverFactory(
1117*6777b538SAndroid Build Coastguard Worker     MockHostResolverBase::RuleResolver rules,
1118*6777b538SAndroid Build Coastguard Worker     bool use_caching,
1119*6777b538SAndroid Build Coastguard Worker     int cache_invalidation_num)
1120*6777b538SAndroid Build Coastguard Worker     : rules_(std::move(rules)),
1121*6777b538SAndroid Build Coastguard Worker       use_caching_(use_caching),
1122*6777b538SAndroid Build Coastguard Worker       cache_invalidation_num_(cache_invalidation_num) {}
1123*6777b538SAndroid Build Coastguard Worker 
1124*6777b538SAndroid Build Coastguard Worker MockHostResolverFactory::~MockHostResolverFactory() = default;
1125*6777b538SAndroid Build Coastguard Worker 
CreateResolver(HostResolverManager * manager,std::string_view host_mapping_rules,bool enable_caching)1126*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HostResolver> MockHostResolverFactory::CreateResolver(
1127*6777b538SAndroid Build Coastguard Worker     HostResolverManager* manager,
1128*6777b538SAndroid Build Coastguard Worker     std::string_view host_mapping_rules,
1129*6777b538SAndroid Build Coastguard Worker     bool enable_caching) {
1130*6777b538SAndroid Build Coastguard Worker   DCHECK(host_mapping_rules.empty());
1131*6777b538SAndroid Build Coastguard Worker 
1132*6777b538SAndroid Build Coastguard Worker   // Explicit new to access private constructor.
1133*6777b538SAndroid Build Coastguard Worker   auto resolver = base::WrapUnique(new MockHostResolverBase(
1134*6777b538SAndroid Build Coastguard Worker       enable_caching && use_caching_, cache_invalidation_num_, rules_));
1135*6777b538SAndroid Build Coastguard Worker   return resolver;
1136*6777b538SAndroid Build Coastguard Worker }
1137*6777b538SAndroid Build Coastguard Worker 
CreateStandaloneResolver(NetLog * net_log,const HostResolver::ManagerOptions & options,std::string_view host_mapping_rules,bool enable_caching)1138*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HostResolver> MockHostResolverFactory::CreateStandaloneResolver(
1139*6777b538SAndroid Build Coastguard Worker     NetLog* net_log,
1140*6777b538SAndroid Build Coastguard Worker     const HostResolver::ManagerOptions& options,
1141*6777b538SAndroid Build Coastguard Worker     std::string_view host_mapping_rules,
1142*6777b538SAndroid Build Coastguard Worker     bool enable_caching) {
1143*6777b538SAndroid Build Coastguard Worker   return CreateResolver(nullptr, host_mapping_rules, enable_caching);
1144*6777b538SAndroid Build Coastguard Worker }
1145*6777b538SAndroid Build Coastguard Worker 
1146*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
1147*6777b538SAndroid Build Coastguard Worker 
Rule(ResolverType resolver_type,std::string_view host_pattern,AddressFamily address_family,HostResolverFlags host_resolver_flags,std::string_view replacement,std::vector<std::string> dns_aliases,int latency_ms)1148*6777b538SAndroid Build Coastguard Worker RuleBasedHostResolverProc::Rule::Rule(ResolverType resolver_type,
1149*6777b538SAndroid Build Coastguard Worker                                       std::string_view host_pattern,
1150*6777b538SAndroid Build Coastguard Worker                                       AddressFamily address_family,
1151*6777b538SAndroid Build Coastguard Worker                                       HostResolverFlags host_resolver_flags,
1152*6777b538SAndroid Build Coastguard Worker                                       std::string_view replacement,
1153*6777b538SAndroid Build Coastguard Worker                                       std::vector<std::string> dns_aliases,
1154*6777b538SAndroid Build Coastguard Worker                                       int latency_ms)
1155*6777b538SAndroid Build Coastguard Worker     : resolver_type(resolver_type),
1156*6777b538SAndroid Build Coastguard Worker       host_pattern(host_pattern),
1157*6777b538SAndroid Build Coastguard Worker       address_family(address_family),
1158*6777b538SAndroid Build Coastguard Worker       host_resolver_flags(host_resolver_flags),
1159*6777b538SAndroid Build Coastguard Worker       replacement(replacement),
1160*6777b538SAndroid Build Coastguard Worker       dns_aliases(std::move(dns_aliases)),
1161*6777b538SAndroid Build Coastguard Worker       latency_ms(latency_ms) {
1162*6777b538SAndroid Build Coastguard Worker   DCHECK(this->dns_aliases != std::vector<std::string>({""}));
1163*6777b538SAndroid Build Coastguard Worker }
1164*6777b538SAndroid Build Coastguard Worker 
1165*6777b538SAndroid Build Coastguard Worker RuleBasedHostResolverProc::Rule::Rule(const Rule& other) = default;
1166*6777b538SAndroid Build Coastguard Worker 
1167*6777b538SAndroid Build Coastguard Worker RuleBasedHostResolverProc::Rule::~Rule() = default;
1168*6777b538SAndroid Build Coastguard Worker 
RuleBasedHostResolverProc(scoped_refptr<HostResolverProc> previous,bool allow_fallback)1169*6777b538SAndroid Build Coastguard Worker RuleBasedHostResolverProc::RuleBasedHostResolverProc(
1170*6777b538SAndroid Build Coastguard Worker     scoped_refptr<HostResolverProc> previous,
1171*6777b538SAndroid Build Coastguard Worker     bool allow_fallback)
1172*6777b538SAndroid Build Coastguard Worker     : HostResolverProc(std::move(previous), allow_fallback) {}
1173*6777b538SAndroid Build Coastguard Worker 
AddRule(std::string_view host_pattern,std::string_view replacement)1174*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::AddRule(std::string_view host_pattern,
1175*6777b538SAndroid Build Coastguard Worker                                         std::string_view replacement) {
1176*6777b538SAndroid Build Coastguard Worker   AddRuleForAddressFamily(host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
1177*6777b538SAndroid Build Coastguard Worker                           replacement);
1178*6777b538SAndroid Build Coastguard Worker }
1179*6777b538SAndroid Build Coastguard Worker 
AddRuleForAddressFamily(std::string_view host_pattern,AddressFamily address_family,std::string_view replacement)1180*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::AddRuleForAddressFamily(
1181*6777b538SAndroid Build Coastguard Worker     std::string_view host_pattern,
1182*6777b538SAndroid Build Coastguard Worker     AddressFamily address_family,
1183*6777b538SAndroid Build Coastguard Worker     std::string_view replacement) {
1184*6777b538SAndroid Build Coastguard Worker   DCHECK(!replacement.empty());
1185*6777b538SAndroid Build Coastguard Worker   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY;
1186*6777b538SAndroid Build Coastguard Worker   Rule rule(Rule::kResolverTypeSystem, host_pattern, address_family, flags,
1187*6777b538SAndroid Build Coastguard Worker             replacement, {} /* dns_aliases */, 0);
1188*6777b538SAndroid Build Coastguard Worker   AddRuleInternal(rule);
1189*6777b538SAndroid Build Coastguard Worker }
1190*6777b538SAndroid Build Coastguard Worker 
AddRuleWithFlags(std::string_view host_pattern,std::string_view replacement,HostResolverFlags flags,std::vector<std::string> dns_aliases)1191*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::AddRuleWithFlags(
1192*6777b538SAndroid Build Coastguard Worker     std::string_view host_pattern,
1193*6777b538SAndroid Build Coastguard Worker     std::string_view replacement,
1194*6777b538SAndroid Build Coastguard Worker     HostResolverFlags flags,
1195*6777b538SAndroid Build Coastguard Worker     std::vector<std::string> dns_aliases) {
1196*6777b538SAndroid Build Coastguard Worker   DCHECK(!replacement.empty());
1197*6777b538SAndroid Build Coastguard Worker   Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
1198*6777b538SAndroid Build Coastguard Worker             flags, replacement, std::move(dns_aliases), 0);
1199*6777b538SAndroid Build Coastguard Worker   AddRuleInternal(rule);
1200*6777b538SAndroid Build Coastguard Worker }
1201*6777b538SAndroid Build Coastguard Worker 
AddIPLiteralRule(std::string_view host_pattern,std::string_view ip_literal,std::string_view canonical_name)1202*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::AddIPLiteralRule(
1203*6777b538SAndroid Build Coastguard Worker     std::string_view host_pattern,
1204*6777b538SAndroid Build Coastguard Worker     std::string_view ip_literal,
1205*6777b538SAndroid Build Coastguard Worker     std::string_view canonical_name) {
1206*6777b538SAndroid Build Coastguard Worker   // Literals are always resolved to themselves by HostResolverImpl,
1207*6777b538SAndroid Build Coastguard Worker   // consequently we do not support remapping them.
1208*6777b538SAndroid Build Coastguard Worker   IPAddress ip_address;
1209*6777b538SAndroid Build Coastguard Worker   DCHECK(!ip_address.AssignFromIPLiteral(host_pattern));
1210*6777b538SAndroid Build Coastguard Worker   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY;
1211*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> aliases;
1212*6777b538SAndroid Build Coastguard Worker   if (!canonical_name.empty()) {
1213*6777b538SAndroid Build Coastguard Worker     flags |= HOST_RESOLVER_CANONNAME;
1214*6777b538SAndroid Build Coastguard Worker     aliases.emplace_back(canonical_name);
1215*6777b538SAndroid Build Coastguard Worker   }
1216*6777b538SAndroid Build Coastguard Worker 
1217*6777b538SAndroid Build Coastguard Worker   Rule rule(Rule::kResolverTypeIPLiteral, host_pattern,
1218*6777b538SAndroid Build Coastguard Worker             ADDRESS_FAMILY_UNSPECIFIED, flags, ip_literal, std::move(aliases),
1219*6777b538SAndroid Build Coastguard Worker             0);
1220*6777b538SAndroid Build Coastguard Worker   AddRuleInternal(rule);
1221*6777b538SAndroid Build Coastguard Worker }
1222*6777b538SAndroid Build Coastguard Worker 
AddIPLiteralRuleWithDnsAliases(std::string_view host_pattern,std::string_view ip_literal,std::vector<std::string> dns_aliases)1223*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::AddIPLiteralRuleWithDnsAliases(
1224*6777b538SAndroid Build Coastguard Worker     std::string_view host_pattern,
1225*6777b538SAndroid Build Coastguard Worker     std::string_view ip_literal,
1226*6777b538SAndroid Build Coastguard Worker     std::vector<std::string> dns_aliases) {
1227*6777b538SAndroid Build Coastguard Worker   // Literals are always resolved to themselves by HostResolverImpl,
1228*6777b538SAndroid Build Coastguard Worker   // consequently we do not support remapping them.
1229*6777b538SAndroid Build Coastguard Worker   IPAddress ip_address;
1230*6777b538SAndroid Build Coastguard Worker   DCHECK(!ip_address.AssignFromIPLiteral(host_pattern));
1231*6777b538SAndroid Build Coastguard Worker   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY;
1232*6777b538SAndroid Build Coastguard Worker   if (!dns_aliases.empty())
1233*6777b538SAndroid Build Coastguard Worker     flags |= HOST_RESOLVER_CANONNAME;
1234*6777b538SAndroid Build Coastguard Worker 
1235*6777b538SAndroid Build Coastguard Worker   Rule rule(Rule::kResolverTypeIPLiteral, host_pattern,
1236*6777b538SAndroid Build Coastguard Worker             ADDRESS_FAMILY_UNSPECIFIED, flags, ip_literal,
1237*6777b538SAndroid Build Coastguard Worker             std::move(dns_aliases), 0);
1238*6777b538SAndroid Build Coastguard Worker   AddRuleInternal(rule);
1239*6777b538SAndroid Build Coastguard Worker }
1240*6777b538SAndroid Build Coastguard Worker 
AddRuleWithLatency(std::string_view host_pattern,std::string_view replacement,int latency_ms)1241*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::AddRuleWithLatency(
1242*6777b538SAndroid Build Coastguard Worker     std::string_view host_pattern,
1243*6777b538SAndroid Build Coastguard Worker     std::string_view replacement,
1244*6777b538SAndroid Build Coastguard Worker     int latency_ms) {
1245*6777b538SAndroid Build Coastguard Worker   DCHECK(!replacement.empty());
1246*6777b538SAndroid Build Coastguard Worker   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY;
1247*6777b538SAndroid Build Coastguard Worker   Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
1248*6777b538SAndroid Build Coastguard Worker             flags, replacement, /*dns_aliases=*/{}, latency_ms);
1249*6777b538SAndroid Build Coastguard Worker   AddRuleInternal(rule);
1250*6777b538SAndroid Build Coastguard Worker }
1251*6777b538SAndroid Build Coastguard Worker 
AllowDirectLookup(std::string_view host_pattern)1252*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::AllowDirectLookup(
1253*6777b538SAndroid Build Coastguard Worker     std::string_view host_pattern) {
1254*6777b538SAndroid Build Coastguard Worker   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY;
1255*6777b538SAndroid Build Coastguard Worker   Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
1256*6777b538SAndroid Build Coastguard Worker             flags, std::string(), /*dns_aliases=*/{}, 0);
1257*6777b538SAndroid Build Coastguard Worker   AddRuleInternal(rule);
1258*6777b538SAndroid Build Coastguard Worker }
1259*6777b538SAndroid Build Coastguard Worker 
AddSimulatedFailure(std::string_view host_pattern,HostResolverFlags flags)1260*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::AddSimulatedFailure(
1261*6777b538SAndroid Build Coastguard Worker     std::string_view host_pattern,
1262*6777b538SAndroid Build Coastguard Worker     HostResolverFlags flags) {
1263*6777b538SAndroid Build Coastguard Worker   Rule rule(Rule::kResolverTypeFail, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
1264*6777b538SAndroid Build Coastguard Worker             flags, std::string(), /*dns_aliases=*/{}, 0);
1265*6777b538SAndroid Build Coastguard Worker   AddRuleInternal(rule);
1266*6777b538SAndroid Build Coastguard Worker }
1267*6777b538SAndroid Build Coastguard Worker 
AddSimulatedTimeoutFailure(std::string_view host_pattern,HostResolverFlags flags)1268*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::AddSimulatedTimeoutFailure(
1269*6777b538SAndroid Build Coastguard Worker     std::string_view host_pattern,
1270*6777b538SAndroid Build Coastguard Worker     HostResolverFlags flags) {
1271*6777b538SAndroid Build Coastguard Worker   Rule rule(Rule::kResolverTypeFailTimeout, host_pattern,
1272*6777b538SAndroid Build Coastguard Worker             ADDRESS_FAMILY_UNSPECIFIED, flags, std::string(),
1273*6777b538SAndroid Build Coastguard Worker             /*dns_aliases=*/{}, 0);
1274*6777b538SAndroid Build Coastguard Worker   AddRuleInternal(rule);
1275*6777b538SAndroid Build Coastguard Worker }
1276*6777b538SAndroid Build Coastguard Worker 
ClearRules()1277*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::ClearRules() {
1278*6777b538SAndroid Build Coastguard Worker   CHECK(modifications_allowed_);
1279*6777b538SAndroid Build Coastguard Worker   base::AutoLock lock(rule_lock_);
1280*6777b538SAndroid Build Coastguard Worker   rules_.clear();
1281*6777b538SAndroid Build Coastguard Worker }
1282*6777b538SAndroid Build Coastguard Worker 
DisableModifications()1283*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::DisableModifications() {
1284*6777b538SAndroid Build Coastguard Worker   modifications_allowed_ = false;
1285*6777b538SAndroid Build Coastguard Worker }
1286*6777b538SAndroid Build Coastguard Worker 
GetRules()1287*6777b538SAndroid Build Coastguard Worker RuleBasedHostResolverProc::RuleList RuleBasedHostResolverProc::GetRules() {
1288*6777b538SAndroid Build Coastguard Worker   RuleList rv;
1289*6777b538SAndroid Build Coastguard Worker   {
1290*6777b538SAndroid Build Coastguard Worker     base::AutoLock lock(rule_lock_);
1291*6777b538SAndroid Build Coastguard Worker     rv = rules_;
1292*6777b538SAndroid Build Coastguard Worker   }
1293*6777b538SAndroid Build Coastguard Worker   return rv;
1294*6777b538SAndroid Build Coastguard Worker }
1295*6777b538SAndroid Build Coastguard Worker 
NumResolvesForHostPattern(std::string_view host_pattern)1296*6777b538SAndroid Build Coastguard Worker size_t RuleBasedHostResolverProc::NumResolvesForHostPattern(
1297*6777b538SAndroid Build Coastguard Worker     std::string_view host_pattern) {
1298*6777b538SAndroid Build Coastguard Worker   base::AutoLock lock(rule_lock_);
1299*6777b538SAndroid Build Coastguard Worker   return num_resolves_per_host_pattern_[host_pattern];
1300*6777b538SAndroid Build Coastguard Worker }
1301*6777b538SAndroid Build Coastguard Worker 
Resolve(const std::string & host,AddressFamily address_family,HostResolverFlags host_resolver_flags,AddressList * addrlist,int * os_error)1302*6777b538SAndroid Build Coastguard Worker int RuleBasedHostResolverProc::Resolve(const std::string& host,
1303*6777b538SAndroid Build Coastguard Worker                                        AddressFamily address_family,
1304*6777b538SAndroid Build Coastguard Worker                                        HostResolverFlags host_resolver_flags,
1305*6777b538SAndroid Build Coastguard Worker                                        AddressList* addrlist,
1306*6777b538SAndroid Build Coastguard Worker                                        int* os_error) {
1307*6777b538SAndroid Build Coastguard Worker   base::AutoLock lock(rule_lock_);
1308*6777b538SAndroid Build Coastguard Worker   RuleList::iterator r;
1309*6777b538SAndroid Build Coastguard Worker   for (r = rules_.begin(); r != rules_.end(); ++r) {
1310*6777b538SAndroid Build Coastguard Worker     bool matches_address_family =
1311*6777b538SAndroid Build Coastguard Worker         r->address_family == ADDRESS_FAMILY_UNSPECIFIED ||
1312*6777b538SAndroid Build Coastguard Worker         r->address_family == address_family;
1313*6777b538SAndroid Build Coastguard Worker     // Ignore HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6, since it should
1314*6777b538SAndroid Build Coastguard Worker     // have no impact on whether a rule matches.
1315*6777b538SAndroid Build Coastguard Worker     HostResolverFlags flags =
1316*6777b538SAndroid Build Coastguard Worker         host_resolver_flags & ~HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
1317*6777b538SAndroid Build Coastguard Worker     // Flags match if all of the bitflags in host_resolver_flags are enabled
1318*6777b538SAndroid Build Coastguard Worker     // in the rule's host_resolver_flags. However, the rule may have additional
1319*6777b538SAndroid Build Coastguard Worker     // flags specified, in which case the flags should still be considered a
1320*6777b538SAndroid Build Coastguard Worker     // match.
1321*6777b538SAndroid Build Coastguard Worker     bool matches_flags = (r->host_resolver_flags & flags) == flags;
1322*6777b538SAndroid Build Coastguard Worker     if (matches_flags && matches_address_family &&
1323*6777b538SAndroid Build Coastguard Worker         base::MatchPattern(host, r->host_pattern)) {
1324*6777b538SAndroid Build Coastguard Worker       num_resolves_per_host_pattern_[r->host_pattern]++;
1325*6777b538SAndroid Build Coastguard Worker 
1326*6777b538SAndroid Build Coastguard Worker       if (r->latency_ms != 0) {
1327*6777b538SAndroid Build Coastguard Worker         base::PlatformThread::Sleep(base::Milliseconds(r->latency_ms));
1328*6777b538SAndroid Build Coastguard Worker       }
1329*6777b538SAndroid Build Coastguard Worker 
1330*6777b538SAndroid Build Coastguard Worker       // Remap to a new host.
1331*6777b538SAndroid Build Coastguard Worker       const std::string& effective_host =
1332*6777b538SAndroid Build Coastguard Worker           r->replacement.empty() ? host : r->replacement;
1333*6777b538SAndroid Build Coastguard Worker 
1334*6777b538SAndroid Build Coastguard Worker       // Apply the resolving function to the remapped hostname.
1335*6777b538SAndroid Build Coastguard Worker       switch (r->resolver_type) {
1336*6777b538SAndroid Build Coastguard Worker         case Rule::kResolverTypeFail:
1337*6777b538SAndroid Build Coastguard Worker           return ERR_NAME_NOT_RESOLVED;
1338*6777b538SAndroid Build Coastguard Worker         case Rule::kResolverTypeFailTimeout:
1339*6777b538SAndroid Build Coastguard Worker           return ERR_DNS_TIMED_OUT;
1340*6777b538SAndroid Build Coastguard Worker         case Rule::kResolverTypeSystem:
1341*6777b538SAndroid Build Coastguard Worker           EnsureSystemHostResolverCallReady();
1342*6777b538SAndroid Build Coastguard Worker           return SystemHostResolverCall(effective_host, address_family,
1343*6777b538SAndroid Build Coastguard Worker                                         host_resolver_flags, addrlist,
1344*6777b538SAndroid Build Coastguard Worker                                         os_error);
1345*6777b538SAndroid Build Coastguard Worker         case Rule::kResolverTypeIPLiteral: {
1346*6777b538SAndroid Build Coastguard Worker           AddressList raw_addr_list;
1347*6777b538SAndroid Build Coastguard Worker           std::vector<std::string> aliases;
1348*6777b538SAndroid Build Coastguard Worker           aliases = (!r->dns_aliases.empty())
1349*6777b538SAndroid Build Coastguard Worker                         ? r->dns_aliases
1350*6777b538SAndroid Build Coastguard Worker                         : std::vector<std::string>({host});
1351*6777b538SAndroid Build Coastguard Worker           std::vector<net::IPEndPoint> ip_endpoints;
1352*6777b538SAndroid Build Coastguard Worker           int result = ParseAddressList(effective_host, &ip_endpoints);
1353*6777b538SAndroid Build Coastguard Worker           // Filter out addresses with the wrong family.
1354*6777b538SAndroid Build Coastguard Worker           *addrlist = AddressList();
1355*6777b538SAndroid Build Coastguard Worker           for (const auto& address : ip_endpoints) {
1356*6777b538SAndroid Build Coastguard Worker             if (address_family == ADDRESS_FAMILY_UNSPECIFIED ||
1357*6777b538SAndroid Build Coastguard Worker                 address_family == address.GetFamily()) {
1358*6777b538SAndroid Build Coastguard Worker               addrlist->push_back(address);
1359*6777b538SAndroid Build Coastguard Worker             }
1360*6777b538SAndroid Build Coastguard Worker           }
1361*6777b538SAndroid Build Coastguard Worker           addrlist->SetDnsAliases(aliases);
1362*6777b538SAndroid Build Coastguard Worker 
1363*6777b538SAndroid Build Coastguard Worker           if (result == OK && addrlist->empty())
1364*6777b538SAndroid Build Coastguard Worker             return ERR_NAME_NOT_RESOLVED;
1365*6777b538SAndroid Build Coastguard Worker           return result;
1366*6777b538SAndroid Build Coastguard Worker         }
1367*6777b538SAndroid Build Coastguard Worker         default:
1368*6777b538SAndroid Build Coastguard Worker           NOTREACHED();
1369*6777b538SAndroid Build Coastguard Worker           return ERR_UNEXPECTED;
1370*6777b538SAndroid Build Coastguard Worker       }
1371*6777b538SAndroid Build Coastguard Worker     }
1372*6777b538SAndroid Build Coastguard Worker   }
1373*6777b538SAndroid Build Coastguard Worker 
1374*6777b538SAndroid Build Coastguard Worker   return ResolveUsingPrevious(host, address_family, host_resolver_flags,
1375*6777b538SAndroid Build Coastguard Worker                               addrlist, os_error);
1376*6777b538SAndroid Build Coastguard Worker }
1377*6777b538SAndroid Build Coastguard Worker 
1378*6777b538SAndroid Build Coastguard Worker RuleBasedHostResolverProc::~RuleBasedHostResolverProc() = default;
1379*6777b538SAndroid Build Coastguard Worker 
AddRuleInternal(const Rule & rule)1380*6777b538SAndroid Build Coastguard Worker void RuleBasedHostResolverProc::AddRuleInternal(const Rule& rule) {
1381*6777b538SAndroid Build Coastguard Worker   Rule fixed_rule = rule;
1382*6777b538SAndroid Build Coastguard Worker   // SystemResolverProc expects valid DNS addresses.
1383*6777b538SAndroid Build Coastguard Worker   // So for kResolverTypeSystem rules:
1384*6777b538SAndroid Build Coastguard Worker   // * CHECK that replacement is empty (empty domain names mean use a direct
1385*6777b538SAndroid Build Coastguard Worker   //   lookup) or a valid DNS name (which includes IP addresses).
1386*6777b538SAndroid Build Coastguard Worker   // * If the replacement is an IP address, switch to an IP literal rule.
1387*6777b538SAndroid Build Coastguard Worker   if (fixed_rule.resolver_type == Rule::kResolverTypeSystem) {
1388*6777b538SAndroid Build Coastguard Worker     CHECK(fixed_rule.replacement.empty() ||
1389*6777b538SAndroid Build Coastguard Worker           dns_names_util::IsValidDnsName(fixed_rule.replacement));
1390*6777b538SAndroid Build Coastguard Worker 
1391*6777b538SAndroid Build Coastguard Worker     IPAddress ip_address;
1392*6777b538SAndroid Build Coastguard Worker     bool valid_address = ip_address.AssignFromIPLiteral(fixed_rule.replacement);
1393*6777b538SAndroid Build Coastguard Worker     if (valid_address) {
1394*6777b538SAndroid Build Coastguard Worker       fixed_rule.resolver_type = Rule::kResolverTypeIPLiteral;
1395*6777b538SAndroid Build Coastguard Worker     }
1396*6777b538SAndroid Build Coastguard Worker   }
1397*6777b538SAndroid Build Coastguard Worker 
1398*6777b538SAndroid Build Coastguard Worker   CHECK(modifications_allowed_);
1399*6777b538SAndroid Build Coastguard Worker   base::AutoLock lock(rule_lock_);
1400*6777b538SAndroid Build Coastguard Worker   rules_.push_back(fixed_rule);
1401*6777b538SAndroid Build Coastguard Worker }
1402*6777b538SAndroid Build Coastguard Worker 
CreateCatchAllHostResolverProc()1403*6777b538SAndroid Build Coastguard Worker scoped_refptr<RuleBasedHostResolverProc> CreateCatchAllHostResolverProc() {
1404*6777b538SAndroid Build Coastguard Worker   auto catchall =
1405*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<RuleBasedHostResolverProc>(/*previous=*/nullptr,
1406*6777b538SAndroid Build Coastguard Worker                                                       /*allow_fallback=*/false);
1407*6777b538SAndroid Build Coastguard Worker   // Note that IPv6 lookups fail.
1408*6777b538SAndroid Build Coastguard Worker   catchall->AddIPLiteralRule("*", "127.0.0.1", "localhost");
1409*6777b538SAndroid Build Coastguard Worker 
1410*6777b538SAndroid Build Coastguard Worker   // Next add a rules-based layer that the test controls.
1411*6777b538SAndroid Build Coastguard Worker   return base::MakeRefCounted<RuleBasedHostResolverProc>(
1412*6777b538SAndroid Build Coastguard Worker       std::move(catchall), /*allow_fallback=*/false);
1413*6777b538SAndroid Build Coastguard Worker }
1414*6777b538SAndroid Build Coastguard Worker 
1415*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
1416*6777b538SAndroid Build Coastguard Worker 
1417*6777b538SAndroid Build Coastguard Worker // Implementation of ResolveHostRequest that tracks cancellations when the
1418*6777b538SAndroid Build Coastguard Worker // request is destroyed after being started.
1419*6777b538SAndroid Build Coastguard Worker class HangingHostResolver::RequestImpl
1420*6777b538SAndroid Build Coastguard Worker     : public HostResolver::ResolveHostRequest,
1421*6777b538SAndroid Build Coastguard Worker       public HostResolver::ProbeRequest {
1422*6777b538SAndroid Build Coastguard Worker  public:
RequestImpl(base::WeakPtr<HangingHostResolver> resolver)1423*6777b538SAndroid Build Coastguard Worker   explicit RequestImpl(base::WeakPtr<HangingHostResolver> resolver)
1424*6777b538SAndroid Build Coastguard Worker       : resolver_(resolver) {}
1425*6777b538SAndroid Build Coastguard Worker 
1426*6777b538SAndroid Build Coastguard Worker   RequestImpl(const RequestImpl&) = delete;
1427*6777b538SAndroid Build Coastguard Worker   RequestImpl& operator=(const RequestImpl&) = delete;
1428*6777b538SAndroid Build Coastguard Worker 
~RequestImpl()1429*6777b538SAndroid Build Coastguard Worker   ~RequestImpl() override {
1430*6777b538SAndroid Build Coastguard Worker     if (is_running_ && resolver_)
1431*6777b538SAndroid Build Coastguard Worker       resolver_->state_->IncrementNumCancellations();
1432*6777b538SAndroid Build Coastguard Worker   }
1433*6777b538SAndroid Build Coastguard Worker 
Start(CompletionOnceCallback callback)1434*6777b538SAndroid Build Coastguard Worker   int Start(CompletionOnceCallback callback) override { return Start(); }
1435*6777b538SAndroid Build Coastguard Worker 
Start()1436*6777b538SAndroid Build Coastguard Worker   int Start() override {
1437*6777b538SAndroid Build Coastguard Worker     DCHECK(resolver_);
1438*6777b538SAndroid Build Coastguard Worker     is_running_ = true;
1439*6777b538SAndroid Build Coastguard Worker     return ERR_IO_PENDING;
1440*6777b538SAndroid Build Coastguard Worker   }
1441*6777b538SAndroid Build Coastguard Worker 
GetAddressResults() const1442*6777b538SAndroid Build Coastguard Worker   const AddressList* GetAddressResults() const override {
1443*6777b538SAndroid Build Coastguard Worker     base::ImmediateCrash();
1444*6777b538SAndroid Build Coastguard Worker   }
1445*6777b538SAndroid Build Coastguard Worker 
GetEndpointResults() const1446*6777b538SAndroid Build Coastguard Worker   const std::vector<HostResolverEndpointResult>* GetEndpointResults()
1447*6777b538SAndroid Build Coastguard Worker       const override {
1448*6777b538SAndroid Build Coastguard Worker     base::ImmediateCrash();
1449*6777b538SAndroid Build Coastguard Worker   }
1450*6777b538SAndroid Build Coastguard Worker 
GetTextResults() const1451*6777b538SAndroid Build Coastguard Worker   const std::vector<std::string>* GetTextResults() const override {
1452*6777b538SAndroid Build Coastguard Worker     base::ImmediateCrash();
1453*6777b538SAndroid Build Coastguard Worker   }
1454*6777b538SAndroid Build Coastguard Worker 
GetHostnameResults() const1455*6777b538SAndroid Build Coastguard Worker   const std::vector<HostPortPair>* GetHostnameResults() const override {
1456*6777b538SAndroid Build Coastguard Worker     base::ImmediateCrash();
1457*6777b538SAndroid Build Coastguard Worker   }
1458*6777b538SAndroid Build Coastguard Worker 
GetDnsAliasResults() const1459*6777b538SAndroid Build Coastguard Worker   const std::set<std::string>* GetDnsAliasResults() const override {
1460*6777b538SAndroid Build Coastguard Worker     base::ImmediateCrash();
1461*6777b538SAndroid Build Coastguard Worker   }
1462*6777b538SAndroid Build Coastguard Worker 
GetResolveErrorInfo() const1463*6777b538SAndroid Build Coastguard Worker   net::ResolveErrorInfo GetResolveErrorInfo() const override {
1464*6777b538SAndroid Build Coastguard Worker     base::ImmediateCrash();
1465*6777b538SAndroid Build Coastguard Worker   }
1466*6777b538SAndroid Build Coastguard Worker 
GetStaleInfo() const1467*6777b538SAndroid Build Coastguard Worker   const std::optional<HostCache::EntryStaleness>& GetStaleInfo()
1468*6777b538SAndroid Build Coastguard Worker       const override {
1469*6777b538SAndroid Build Coastguard Worker     base::ImmediateCrash();
1470*6777b538SAndroid Build Coastguard Worker   }
1471*6777b538SAndroid Build Coastguard Worker 
ChangeRequestPriority(RequestPriority priority)1472*6777b538SAndroid Build Coastguard Worker   void ChangeRequestPriority(RequestPriority priority) override {}
1473*6777b538SAndroid Build Coastguard Worker 
1474*6777b538SAndroid Build Coastguard Worker  private:
1475*6777b538SAndroid Build Coastguard Worker   // Use a WeakPtr as the resolver may be destroyed while there are still
1476*6777b538SAndroid Build Coastguard Worker   // outstanding request objects.
1477*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<HangingHostResolver> resolver_;
1478*6777b538SAndroid Build Coastguard Worker   bool is_running_ = false;
1479*6777b538SAndroid Build Coastguard Worker };
1480*6777b538SAndroid Build Coastguard Worker 
1481*6777b538SAndroid Build Coastguard Worker HangingHostResolver::State::State() = default;
1482*6777b538SAndroid Build Coastguard Worker HangingHostResolver::State::~State() = default;
1483*6777b538SAndroid Build Coastguard Worker 
HangingHostResolver()1484*6777b538SAndroid Build Coastguard Worker HangingHostResolver::HangingHostResolver()
1485*6777b538SAndroid Build Coastguard Worker     : state_(base::MakeRefCounted<State>()) {}
1486*6777b538SAndroid Build Coastguard Worker 
1487*6777b538SAndroid Build Coastguard Worker HangingHostResolver::~HangingHostResolver() = default;
1488*6777b538SAndroid Build Coastguard Worker 
OnShutdown()1489*6777b538SAndroid Build Coastguard Worker void HangingHostResolver::OnShutdown() {
1490*6777b538SAndroid Build Coastguard Worker   shutting_down_ = true;
1491*6777b538SAndroid Build Coastguard Worker }
1492*6777b538SAndroid Build Coastguard Worker 
1493*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HostResolver::ResolveHostRequest>
CreateRequest(url::SchemeHostPort host,NetworkAnonymizationKey network_anonymization_key,NetLogWithSource net_log,std::optional<ResolveHostParameters> optional_parameters)1494*6777b538SAndroid Build Coastguard Worker HangingHostResolver::CreateRequest(
1495*6777b538SAndroid Build Coastguard Worker     url::SchemeHostPort host,
1496*6777b538SAndroid Build Coastguard Worker     NetworkAnonymizationKey network_anonymization_key,
1497*6777b538SAndroid Build Coastguard Worker     NetLogWithSource net_log,
1498*6777b538SAndroid Build Coastguard Worker     std::optional<ResolveHostParameters> optional_parameters) {
1499*6777b538SAndroid Build Coastguard Worker   // TODO(crbug.com/1206799): Propagate scheme and make affect behavior.
1500*6777b538SAndroid Build Coastguard Worker   return CreateRequest(HostPortPair::FromSchemeHostPort(host),
1501*6777b538SAndroid Build Coastguard Worker                        network_anonymization_key, net_log, optional_parameters);
1502*6777b538SAndroid Build Coastguard Worker }
1503*6777b538SAndroid Build Coastguard Worker 
1504*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HostResolver::ResolveHostRequest>
CreateRequest(const HostPortPair & host,const NetworkAnonymizationKey & network_anonymization_key,const NetLogWithSource & source_net_log,const std::optional<ResolveHostParameters> & optional_parameters)1505*6777b538SAndroid Build Coastguard Worker HangingHostResolver::CreateRequest(
1506*6777b538SAndroid Build Coastguard Worker     const HostPortPair& host,
1507*6777b538SAndroid Build Coastguard Worker     const NetworkAnonymizationKey& network_anonymization_key,
1508*6777b538SAndroid Build Coastguard Worker     const NetLogWithSource& source_net_log,
1509*6777b538SAndroid Build Coastguard Worker     const std::optional<ResolveHostParameters>& optional_parameters) {
1510*6777b538SAndroid Build Coastguard Worker   last_host_ = host;
1511*6777b538SAndroid Build Coastguard Worker   last_network_anonymization_key_ = network_anonymization_key;
1512*6777b538SAndroid Build Coastguard Worker 
1513*6777b538SAndroid Build Coastguard Worker   if (shutting_down_)
1514*6777b538SAndroid Build Coastguard Worker     return CreateFailingRequest(ERR_CONTEXT_SHUT_DOWN);
1515*6777b538SAndroid Build Coastguard Worker 
1516*6777b538SAndroid Build Coastguard Worker   if (optional_parameters &&
1517*6777b538SAndroid Build Coastguard Worker       optional_parameters.value().source == HostResolverSource::LOCAL_ONLY) {
1518*6777b538SAndroid Build Coastguard Worker     return CreateFailingRequest(ERR_DNS_CACHE_MISS);
1519*6777b538SAndroid Build Coastguard Worker   }
1520*6777b538SAndroid Build Coastguard Worker 
1521*6777b538SAndroid Build Coastguard Worker   return std::make_unique<RequestImpl>(weak_ptr_factory_.GetWeakPtr());
1522*6777b538SAndroid Build Coastguard Worker }
1523*6777b538SAndroid Build Coastguard Worker 
1524*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HostResolver::ServiceEndpointRequest>
CreateServiceEndpointRequest(Host host,NetworkAnonymizationKey network_anonymization_key,NetLogWithSource net_log,ResolveHostParameters parameters)1525*6777b538SAndroid Build Coastguard Worker HangingHostResolver::CreateServiceEndpointRequest(
1526*6777b538SAndroid Build Coastguard Worker     Host host,
1527*6777b538SAndroid Build Coastguard Worker     NetworkAnonymizationKey network_anonymization_key,
1528*6777b538SAndroid Build Coastguard Worker     NetLogWithSource net_log,
1529*6777b538SAndroid Build Coastguard Worker     ResolveHostParameters parameters) {
1530*6777b538SAndroid Build Coastguard Worker   NOTIMPLEMENTED();
1531*6777b538SAndroid Build Coastguard Worker   return nullptr;
1532*6777b538SAndroid Build Coastguard Worker }
1533*6777b538SAndroid Build Coastguard Worker 
1534*6777b538SAndroid Build Coastguard Worker std::unique_ptr<HostResolver::ProbeRequest>
CreateDohProbeRequest()1535*6777b538SAndroid Build Coastguard Worker HangingHostResolver::CreateDohProbeRequest() {
1536*6777b538SAndroid Build Coastguard Worker   if (shutting_down_)
1537*6777b538SAndroid Build Coastguard Worker     return CreateFailingProbeRequest(ERR_CONTEXT_SHUT_DOWN);
1538*6777b538SAndroid Build Coastguard Worker 
1539*6777b538SAndroid Build Coastguard Worker   return std::make_unique<RequestImpl>(weak_ptr_factory_.GetWeakPtr());
1540*6777b538SAndroid Build Coastguard Worker }
1541*6777b538SAndroid Build Coastguard Worker 
SetRequestContext(URLRequestContext * url_request_context)1542*6777b538SAndroid Build Coastguard Worker void HangingHostResolver::SetRequestContext(
1543*6777b538SAndroid Build Coastguard Worker     URLRequestContext* url_request_context) {}
1544*6777b538SAndroid Build Coastguard Worker 
1545*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
1546*6777b538SAndroid Build Coastguard Worker 
1547*6777b538SAndroid Build Coastguard Worker ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc() = default;
1548*6777b538SAndroid Build Coastguard Worker 
ScopedDefaultHostResolverProc(HostResolverProc * proc)1549*6777b538SAndroid Build Coastguard Worker ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc(
1550*6777b538SAndroid Build Coastguard Worker     HostResolverProc* proc) {
1551*6777b538SAndroid Build Coastguard Worker   Init(proc);
1552*6777b538SAndroid Build Coastguard Worker }
1553*6777b538SAndroid Build Coastguard Worker 
~ScopedDefaultHostResolverProc()1554*6777b538SAndroid Build Coastguard Worker ScopedDefaultHostResolverProc::~ScopedDefaultHostResolverProc() {
1555*6777b538SAndroid Build Coastguard Worker   HostResolverProc* old_proc =
1556*6777b538SAndroid Build Coastguard Worker       HostResolverProc::SetDefault(previous_proc_.get());
1557*6777b538SAndroid Build Coastguard Worker   // The lifetimes of multiple instances must be nested.
1558*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(old_proc, current_proc_.get());
1559*6777b538SAndroid Build Coastguard Worker }
1560*6777b538SAndroid Build Coastguard Worker 
Init(HostResolverProc * proc)1561*6777b538SAndroid Build Coastguard Worker void ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) {
1562*6777b538SAndroid Build Coastguard Worker   current_proc_ = proc;
1563*6777b538SAndroid Build Coastguard Worker   previous_proc_ = HostResolverProc::SetDefault(current_proc_.get());
1564*6777b538SAndroid Build Coastguard Worker   current_proc_->SetLastProc(previous_proc_);
1565*6777b538SAndroid Build Coastguard Worker }
1566*6777b538SAndroid Build Coastguard Worker 
1567*6777b538SAndroid Build Coastguard Worker }  // namespace net
1568