1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/dns/host_resolver.h"
6
7 #include <optional>
8 #include <set>
9 #include <string>
10 #include <string_view>
11 #include <utility>
12 #include <vector>
13
14 #include "base/check.h"
15 #include "base/functional/bind.h"
16 #include "base/no_destructor.h"
17 #include "base/notreached.h"
18 #include "base/ranges/algorithm.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "base/time/time_delta_from_string.h"
21 #include "base/values.h"
22 #include "net/base/address_list.h"
23 #include "net/base/features.h"
24 #include "net/base/host_port_pair.h"
25 #include "net/base/net_errors.h"
26 #include "net/base/network_change_notifier.h"
27 #include "net/dns/context_host_resolver.h"
28 #include "net/dns/dns_client.h"
29 #include "net/dns/dns_util.h"
30 #include "net/dns/host_cache.h"
31 #include "net/dns/host_resolver_manager.h"
32 #include "net/dns/mapped_host_resolver.h"
33 #include "net/dns/public/host_resolver_results.h"
34 #include "net/dns/resolve_context.h"
35 #include "third_party/abseil-cpp/absl/types/variant.h"
36 #include "url/scheme_host_port.h"
37
38 #if BUILDFLAG(IS_ANDROID)
39 #include "base/android/build_info.h"
40 #include "net/android/network_library.h"
41 #endif // BUILDFLAG(IS_ANDROID)
42
43 namespace net {
44
45 namespace {
46
47 // The experiment settings of features::kUseDnsHttpsSvcb. See the comments in
48 // net/base/features.h for more details.
49 const char kUseDnsHttpsSvcbEnable[] = "enable";
50 const char kUseDnsHttpsSvcbInsecureExtraTimeMax[] = "insecure_extra_time_max";
51 const char kUseDnsHttpsSvcbInsecureExtraTimePercent[] =
52 "insecure_extra_time_percent";
53 const char kUseDnsHttpsSvcbInsecureExtraTimeMin[] = "insecure_extra_time_min";
54 const char kUseDnsHttpsSvcbSecureExtraTimeMax[] = "secure_extra_time_max";
55 const char kUseDnsHttpsSvcbSecureExtraTimePercent[] =
56 "secure_extra_time_percent";
57 const char kUseDnsHttpsSvcbSecureExtraTimeMin[] = "secure_extra_time_min";
58
59 // An implementation of HostResolver::{ResolveHost,Probe}Request that always
60 // fails immediately.
61 class FailingRequestImpl : public HostResolver::ResolveHostRequest,
62 public HostResolver::ProbeRequest {
63 public:
FailingRequestImpl(int error)64 explicit FailingRequestImpl(int error) : error_(error) {}
65
66 FailingRequestImpl(const FailingRequestImpl&) = delete;
67 FailingRequestImpl& operator=(const FailingRequestImpl&) = delete;
68
69 ~FailingRequestImpl() override = default;
70
Start(CompletionOnceCallback callback)71 int Start(CompletionOnceCallback callback) override { return error_; }
Start()72 int Start() override { return error_; }
73
GetAddressResults() const74 AddressList* GetAddressResults() const override { return nullptr; }
75
GetEndpointResults() const76 std::vector<HostResolverEndpointResult>* GetEndpointResults() const override {
77 return nullptr;
78 }
79
GetTextResults() const80 const std::vector<std::string>* GetTextResults() const override {
81 return nullptr;
82 }
83
GetHostnameResults() const84 const std::vector<HostPortPair>* GetHostnameResults() const override {
85 return nullptr;
86 }
87
GetDnsAliasResults() const88 const std::set<std::string>* GetDnsAliasResults() const override {
89 return nullptr;
90 }
91
GetResolveErrorInfo() const92 ResolveErrorInfo GetResolveErrorInfo() const override {
93 return ResolveErrorInfo(error_);
94 }
95
GetStaleInfo() const96 const std::optional<HostCache::EntryStaleness>& GetStaleInfo()
97 const override {
98 static const std::optional<HostCache::EntryStaleness> nullopt_result;
99 return nullopt_result;
100 }
101
102 private:
103 const int error_;
104 };
105
106 // Similar to FailingRequestImpl, but for ServiceEndpointRequest.
107 class FailingServiceEndpointRequestImpl
108 : public HostResolver::ServiceEndpointRequest {
109 public:
FailingServiceEndpointRequestImpl(int error)110 explicit FailingServiceEndpointRequestImpl(int error) : error_(error) {}
111
112 FailingServiceEndpointRequestImpl(const FailingServiceEndpointRequestImpl&) =
113 delete;
114 FailingServiceEndpointRequestImpl& operator=(
115 const FailingServiceEndpointRequestImpl&) = delete;
116
117 ~FailingServiceEndpointRequestImpl() override = default;
118
Start(Delegate * delegate)119 int Start(Delegate* delegate) override { return error_; }
120
GetEndpointResults()121 const std::vector<ServiceEndpoint>& GetEndpointResults() override {
122 static const base::NoDestructor<std::vector<ServiceEndpoint>> kEmptyResult;
123 return *kEmptyResult.get();
124 }
125
GetDnsAliasResults()126 const std::set<std::string>& GetDnsAliasResults() override {
127 static const base::NoDestructor<std::set<std::string>> kEmptyResult;
128 return *kEmptyResult.get();
129 }
130
EndpointsCryptoReady()131 bool EndpointsCryptoReady() override { return false; }
132
GetResolveErrorInfo()133 ResolveErrorInfo GetResolveErrorInfo() override {
134 return ResolveErrorInfo(error_);
135 }
136
ChangeRequestPriority(RequestPriority priority)137 void ChangeRequestPriority(RequestPriority priority) override {}
138
139 private:
140 const int error_;
141 };
142
EndpointResultIsNonProtocol(const HostResolverEndpointResult & result)143 bool EndpointResultIsNonProtocol(const HostResolverEndpointResult& result) {
144 return result.metadata.supported_protocol_alpns.empty();
145 }
146
GetTimeDeltaFromDictString(const base::Value::Dict & args,std::string_view key,base::TimeDelta * out)147 void GetTimeDeltaFromDictString(const base::Value::Dict& args,
148 std::string_view key,
149 base::TimeDelta* out) {
150 const std::string* value_string = args.FindString(key);
151 if (!value_string)
152 return;
153 *out = base::TimeDeltaFromString(*value_string).value_or(*out);
154 }
155
156 } // namespace
157
Host(absl::variant<url::SchemeHostPort,HostPortPair> host)158 HostResolver::Host::Host(absl::variant<url::SchemeHostPort, HostPortPair> host)
159 : host_(std::move(host)) {
160 #if DCHECK_IS_ON()
161 if (absl::holds_alternative<url::SchemeHostPort>(host_)) {
162 DCHECK(absl::get<url::SchemeHostPort>(host_).IsValid());
163 } else {
164 DCHECK(absl::holds_alternative<HostPortPair>(host_));
165 DCHECK(!absl::get<HostPortPair>(host_).IsEmpty());
166 }
167 #endif // DCHECK_IS_ON()
168 }
169
170 HostResolver::Host::~Host() = default;
171
172 HostResolver::Host::Host(const Host&) = default;
173
174 HostResolver::Host& HostResolver::Host::operator=(const Host&) = default;
175
176 HostResolver::Host::Host(Host&&) = default;
177
178 HostResolver::Host& HostResolver::Host::operator=(Host&&) = default;
179
HasScheme() const180 bool HostResolver::Host::HasScheme() const {
181 return absl::holds_alternative<url::SchemeHostPort>(host_);
182 }
183
GetScheme() const184 const std::string& HostResolver::Host::GetScheme() const {
185 DCHECK(absl::holds_alternative<url::SchemeHostPort>(host_));
186 return absl::get<url::SchemeHostPort>(host_).scheme();
187 }
188
GetHostname() const189 std::string HostResolver::Host::GetHostname() const {
190 if (absl::holds_alternative<url::SchemeHostPort>(host_)) {
191 return absl::get<url::SchemeHostPort>(host_).host();
192 } else {
193 DCHECK(absl::holds_alternative<HostPortPair>(host_));
194 return absl::get<HostPortPair>(host_).HostForURL();
195 }
196 }
197
GetHostnameWithoutBrackets() const198 std::string_view HostResolver::Host::GetHostnameWithoutBrackets() const {
199 if (absl::holds_alternative<url::SchemeHostPort>(host_)) {
200 std::string_view hostname = absl::get<url::SchemeHostPort>(host_).host();
201 if (hostname.size() > 2 && hostname.front() == '[' &&
202 hostname.back() == ']') {
203 return hostname.substr(1, hostname.size() - 2);
204 } else {
205 return hostname;
206 }
207 } else {
208 DCHECK(absl::holds_alternative<HostPortPair>(host_));
209 return absl::get<HostPortPair>(host_).host();
210 }
211 }
212
GetPort() const213 uint16_t HostResolver::Host::GetPort() const {
214 if (absl::holds_alternative<url::SchemeHostPort>(host_)) {
215 return absl::get<url::SchemeHostPort>(host_).port();
216 } else {
217 DCHECK(absl::holds_alternative<HostPortPair>(host_));
218 return absl::get<HostPortPair>(host_).port();
219 }
220 }
221
ToString() const222 std::string HostResolver::Host::ToString() const {
223 if (absl::holds_alternative<url::SchemeHostPort>(host_)) {
224 return absl::get<url::SchemeHostPort>(host_).Serialize();
225 } else {
226 DCHECK(absl::holds_alternative<HostPortPair>(host_));
227 return absl::get<HostPortPair>(host_).ToString();
228 }
229 }
230
AsSchemeHostPort() const231 const url::SchemeHostPort& HostResolver::Host::AsSchemeHostPort() const {
232 const url::SchemeHostPort* scheme_host_port =
233 absl::get_if<url::SchemeHostPort>(&host_);
234 DCHECK(scheme_host_port);
235 return *scheme_host_port;
236 }
237
238 HostResolver::HttpsSvcbOptions::HttpsSvcbOptions() = default;
239
240 HostResolver::HttpsSvcbOptions::HttpsSvcbOptions(
241 const HttpsSvcbOptions& other) = default;
242 HostResolver::HttpsSvcbOptions::HttpsSvcbOptions(HttpsSvcbOptions&& other) =
243 default;
244
245 HostResolver::HttpsSvcbOptions::~HttpsSvcbOptions() = default;
246
247 // static
FromDict(const base::Value::Dict & dict)248 HostResolver::HttpsSvcbOptions HostResolver::HttpsSvcbOptions::FromDict(
249 const base::Value::Dict& dict) {
250 net::HostResolver::HttpsSvcbOptions options;
251 options.enable =
252 dict.FindBool(kUseDnsHttpsSvcbEnable).value_or(options.enable);
253 GetTimeDeltaFromDictString(dict, kUseDnsHttpsSvcbInsecureExtraTimeMax,
254 &options.insecure_extra_time_max);
255
256 options.insecure_extra_time_percent =
257 dict.FindInt(kUseDnsHttpsSvcbInsecureExtraTimePercent)
258 .value_or(options.insecure_extra_time_percent);
259 GetTimeDeltaFromDictString(dict, kUseDnsHttpsSvcbInsecureExtraTimeMin,
260 &options.insecure_extra_time_min);
261
262 GetTimeDeltaFromDictString(dict, kUseDnsHttpsSvcbSecureExtraTimeMax,
263 &options.secure_extra_time_max);
264
265 options.secure_extra_time_percent =
266 dict.FindInt(kUseDnsHttpsSvcbSecureExtraTimePercent)
267 .value_or(options.secure_extra_time_percent);
268 GetTimeDeltaFromDictString(dict, kUseDnsHttpsSvcbSecureExtraTimeMin,
269 &options.secure_extra_time_min);
270
271 return options;
272 }
273
274 // static
FromFeatures()275 HostResolver::HttpsSvcbOptions HostResolver::HttpsSvcbOptions::FromFeatures() {
276 net::HostResolver::HttpsSvcbOptions options;
277 options.enable = base::FeatureList::IsEnabled(features::kUseDnsHttpsSvcb);
278 options.insecure_extra_time_max =
279 features::kUseDnsHttpsSvcbInsecureExtraTimeMax.Get();
280 options.insecure_extra_time_percent =
281 features::kUseDnsHttpsSvcbInsecureExtraTimePercent.Get();
282 options.insecure_extra_time_min =
283 features::kUseDnsHttpsSvcbInsecureExtraTimeMin.Get();
284 options.secure_extra_time_max =
285 features::kUseDnsHttpsSvcbSecureExtraTimeMax.Get();
286 options.secure_extra_time_percent =
287 features::kUseDnsHttpsSvcbSecureExtraTimePercent.Get();
288 options.secure_extra_time_min =
289 features::kUseDnsHttpsSvcbSecureExtraTimeMin.Get();
290 return options;
291 }
292
293 HostResolver::ManagerOptions::ManagerOptions() = default;
294
295 HostResolver::ManagerOptions::ManagerOptions(const ManagerOptions& other) =
296 default;
297 HostResolver::ManagerOptions::ManagerOptions(ManagerOptions&& other) = default;
298
299 HostResolver::ManagerOptions::~ManagerOptions() = default;
300
301 const std::vector<bool>*
GetExperimentalResultsForTesting() const302 HostResolver::ResolveHostRequest::GetExperimentalResultsForTesting() const {
303 NOTREACHED();
304 }
305
CreateResolver(HostResolverManager * manager,std::string_view host_mapping_rules,bool enable_caching)306 std::unique_ptr<HostResolver> HostResolver::Factory::CreateResolver(
307 HostResolverManager* manager,
308 std::string_view host_mapping_rules,
309 bool enable_caching) {
310 return HostResolver::CreateResolver(manager, host_mapping_rules,
311 enable_caching);
312 }
313
CreateStandaloneResolver(NetLog * net_log,const ManagerOptions & options,std::string_view host_mapping_rules,bool enable_caching)314 std::unique_ptr<HostResolver> HostResolver::Factory::CreateStandaloneResolver(
315 NetLog* net_log,
316 const ManagerOptions& options,
317 std::string_view host_mapping_rules,
318 bool enable_caching) {
319 return HostResolver::CreateStandaloneResolver(
320 net_log, options, host_mapping_rules, enable_caching);
321 }
322
323 HostResolver::ResolveHostParameters::ResolveHostParameters() = default;
324
325 HostResolver::~HostResolver() = default;
326
327 std::unique_ptr<HostResolver::ProbeRequest>
CreateDohProbeRequest()328 HostResolver::CreateDohProbeRequest() {
329 // Should be overridden in any HostResolver implementation where this method
330 // may be called.
331 NOTREACHED();
332 }
333
CreateMdnsListener(const HostPortPair & host,DnsQueryType query_type)334 std::unique_ptr<HostResolver::MdnsListener> HostResolver::CreateMdnsListener(
335 const HostPortPair& host,
336 DnsQueryType query_type) {
337 // Should be overridden in any HostResolver implementation where this method
338 // may be called.
339 NOTREACHED();
340 }
341
GetHostCache()342 HostCache* HostResolver::GetHostCache() {
343 return nullptr;
344 }
345
GetDnsConfigAsValue() const346 base::Value::Dict HostResolver::GetDnsConfigAsValue() const {
347 return base::Value::Dict();
348 }
349
SetRequestContext(URLRequestContext * request_context)350 void HostResolver::SetRequestContext(URLRequestContext* request_context) {
351 // Should be overridden in any HostResolver implementation where this method
352 // may be called.
353 NOTREACHED();
354 }
355
GetManagerForTesting()356 HostResolverManager* HostResolver::GetManagerForTesting() {
357 // Should be overridden in any HostResolver implementation where this method
358 // may be called.
359 NOTREACHED();
360 }
361
GetContextForTesting() const362 const URLRequestContext* HostResolver::GetContextForTesting() const {
363 // Should be overridden in any HostResolver implementation where this method
364 // may be called.
365 NOTREACHED();
366 }
367
GetTargetNetworkForTesting() const368 handles::NetworkHandle HostResolver::GetTargetNetworkForTesting() const {
369 return handles::kInvalidNetworkHandle;
370 }
371
372 // static
CreateResolver(HostResolverManager * manager,std::string_view host_mapping_rules,bool enable_caching)373 std::unique_ptr<HostResolver> HostResolver::CreateResolver(
374 HostResolverManager* manager,
375 std::string_view host_mapping_rules,
376 bool enable_caching) {
377 DCHECK(manager);
378
379 auto resolve_context = std::make_unique<ResolveContext>(
380 nullptr /* url_request_context */, enable_caching);
381
382 auto resolver = std::make_unique<ContextHostResolver>(
383 manager, std::move(resolve_context));
384
385 if (host_mapping_rules.empty())
386 return resolver;
387 auto remapped_resolver =
388 std::make_unique<MappedHostResolver>(std::move(resolver));
389 remapped_resolver->SetRulesFromString(host_mapping_rules);
390 return remapped_resolver;
391 }
392
393 // static
CreateStandaloneResolver(NetLog * net_log,std::optional<ManagerOptions> options,std::string_view host_mapping_rules,bool enable_caching)394 std::unique_ptr<HostResolver> HostResolver::CreateStandaloneResolver(
395 NetLog* net_log,
396 std::optional<ManagerOptions> options,
397 std::string_view host_mapping_rules,
398 bool enable_caching) {
399 std::unique_ptr<ContextHostResolver> resolver =
400 CreateStandaloneContextResolver(net_log, std::move(options),
401 enable_caching);
402
403 if (host_mapping_rules.empty())
404 return resolver;
405 auto remapped_resolver =
406 std::make_unique<MappedHostResolver>(std::move(resolver));
407 remapped_resolver->SetRulesFromString(host_mapping_rules);
408 return remapped_resolver;
409 }
410
411 // static
412 std::unique_ptr<ContextHostResolver>
CreateStandaloneContextResolver(NetLog * net_log,std::optional<ManagerOptions> options,bool enable_caching)413 HostResolver::CreateStandaloneContextResolver(
414 NetLog* net_log,
415 std::optional<ManagerOptions> options,
416 bool enable_caching) {
417 auto resolve_context = std::make_unique<ResolveContext>(
418 nullptr /* url_request_context */, enable_caching);
419
420 return std::make_unique<ContextHostResolver>(
421 std::make_unique<HostResolverManager>(
422 std::move(options).value_or(ManagerOptions()),
423 NetworkChangeNotifier::GetSystemDnsConfigNotifier(), net_log),
424 std::move(resolve_context));
425 }
426
427 // static
428 std::unique_ptr<HostResolver>
CreateStandaloneNetworkBoundResolver(NetLog * net_log,handles::NetworkHandle target_network,std::optional<ManagerOptions> options,std::string_view host_mapping_rules,bool enable_caching)429 HostResolver::CreateStandaloneNetworkBoundResolver(
430 NetLog* net_log,
431 handles::NetworkHandle target_network,
432 std::optional<ManagerOptions> options,
433 std::string_view host_mapping_rules,
434 bool enable_caching) {
435 #if BUILDFLAG(IS_ANDROID)
436 // Note that the logic below uses Android APIs that don't work on a sandboxed
437 // process: This is not problematic because this function is used only by
438 // Cronet which doesn't enable sandboxing.
439
440 auto resolve_context = std::make_unique<ResolveContext>(
441 nullptr /*url_request_context */, enable_caching);
442 auto manager_options = std::move(options).value_or(ManagerOptions());
443 // Support the use of the built-in resolver when possible.
444 bool is_builtin_resolver_supported =
445 manager_options.insecure_dns_client_enabled &&
446 base::android::BuildInfo::GetInstance()->sdk_int() >=
447 base::android::SDK_VERSION_P;
448 if (is_builtin_resolver_supported) {
449 // Pre-existing DnsConfigOverrides is currently ignored, consider extending
450 // if a use case arises.
451 DCHECK(manager_options.dns_config_overrides == DnsConfigOverrides());
452
453 std::vector<IPEndPoint> dns_servers;
454 bool dns_over_tls_active;
455 std::string dns_over_tls_hostname;
456 std::vector<std::string> search_suffixes;
457 if (android::GetDnsServersForNetwork(&dns_servers, &dns_over_tls_active,
458 &dns_over_tls_hostname,
459 &search_suffixes, target_network)) {
460 DnsConfigOverrides dns_config_overrides =
461 DnsConfigOverrides::CreateOverridingEverythingWithDefaults();
462 dns_config_overrides.nameservers = dns_servers;
463 // Android APIs don't specify whether to use DoT or DoH. So, leave the
464 // decision to `DnsConfig::allow_dns_over_https_upgrade` default value.
465 dns_config_overrides.dns_over_tls_active = dns_over_tls_active;
466 dns_config_overrides.dns_over_tls_hostname = dns_over_tls_hostname;
467 dns_config_overrides.search = search_suffixes;
468
469 manager_options.dns_config_overrides = dns_config_overrides;
470 // Regardless of DoH vs DoT, the important contract to respect is not to
471 // perform insecure DNS lookups if `dns_over_tls_active` == true.
472 manager_options.additional_types_via_insecure_dns_enabled =
473 !dns_over_tls_active;
474 } else {
475 // Disable when android::GetDnsServersForNetwork fails.
476 is_builtin_resolver_supported = false;
477 }
478 }
479
480 manager_options.insecure_dns_client_enabled = is_builtin_resolver_supported;
481 return std::make_unique<ContextHostResolver>(
482 HostResolverManager::CreateNetworkBoundHostResolverManager(
483 manager_options, target_network, net_log),
484 std::move(resolve_context));
485 #else // !BUILDFLAG(IS_ANDROID)
486 NOTIMPLEMENTED();
487 return nullptr;
488 #endif // BUILDFLAG(IS_ANDROID)
489 }
490
491 // static
DnsQueryTypeSetToAddressFamily(DnsQueryTypeSet dns_query_types)492 AddressFamily HostResolver::DnsQueryTypeSetToAddressFamily(
493 DnsQueryTypeSet dns_query_types) {
494 DCHECK(HasAddressType(dns_query_types));
495 // If the set of query types contains A and AAAA, defer the choice of address
496 // family. Otherwise, pick the corresponding address family.
497 if (dns_query_types.HasAll({DnsQueryType::A, DnsQueryType::AAAA}))
498 return ADDRESS_FAMILY_UNSPECIFIED;
499 if (dns_query_types.Has(DnsQueryType::AAAA))
500 return ADDRESS_FAMILY_IPV6;
501 DCHECK(dns_query_types.Has(DnsQueryType::A));
502 return ADDRESS_FAMILY_IPV4;
503 }
504
505 // static
ParametersToHostResolverFlags(const ResolveHostParameters & parameters)506 HostResolverFlags HostResolver::ParametersToHostResolverFlags(
507 const ResolveHostParameters& parameters) {
508 HostResolverFlags flags = 0;
509 if (parameters.include_canonical_name)
510 flags |= HOST_RESOLVER_CANONNAME;
511 if (parameters.loopback_only)
512 flags |= HOST_RESOLVER_LOOPBACK_ONLY;
513 if (parameters.avoid_multicast_resolution)
514 flags |= HOST_RESOLVER_AVOID_MULTICAST;
515 return flags;
516 }
517
518 // static
SquashErrorCode(int error)519 int HostResolver::SquashErrorCode(int error) {
520 // TODO(crbug.com/40668952): Consider squashing ERR_INTERNET_DISCONNECTED.
521 if (error == OK || error == ERR_IO_PENDING ||
522 error == ERR_INTERNET_DISCONNECTED || error == ERR_NAME_NOT_RESOLVED ||
523 error == ERR_DNS_NAME_HTTPS_ONLY) {
524 return error;
525 } else {
526 return ERR_NAME_NOT_RESOLVED;
527 }
528 }
529
530 // static
EndpointResultToAddressList(base::span<const HostResolverEndpointResult> endpoints,const std::set<std::string> & aliases)531 AddressList HostResolver::EndpointResultToAddressList(
532 base::span<const HostResolverEndpointResult> endpoints,
533 const std::set<std::string>& aliases) {
534 AddressList list;
535
536 auto non_protocol_endpoint =
537 base::ranges::find_if(endpoints, &EndpointResultIsNonProtocol);
538 if (non_protocol_endpoint == endpoints.end())
539 return list;
540
541 list.endpoints() = non_protocol_endpoint->ip_endpoints;
542
543 std::vector<std::string> aliases_vector(aliases.begin(), aliases.end());
544 list.SetDnsAliases(std::move(aliases_vector));
545
546 return list;
547 }
548
549 // static
MayUseNAT64ForIPv4Literal(HostResolverFlags flags,HostResolverSource source,const IPAddress & ip_address)550 bool HostResolver::MayUseNAT64ForIPv4Literal(HostResolverFlags flags,
551 HostResolverSource source,
552 const IPAddress& ip_address) {
553 return !(flags & HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6) &&
554 ip_address.IsValid() && ip_address.IsIPv4() &&
555 (source != HostResolverSource::LOCAL_ONLY);
556 }
557
558 HostResolver::HostResolver() = default;
559
560 // static
561 std::unique_ptr<HostResolver::ResolveHostRequest>
CreateFailingRequest(int error)562 HostResolver::CreateFailingRequest(int error) {
563 return std::make_unique<FailingRequestImpl>(error);
564 }
565
566 // static
567 std::unique_ptr<HostResolver::ProbeRequest>
CreateFailingProbeRequest(int error)568 HostResolver::CreateFailingProbeRequest(int error) {
569 return std::make_unique<FailingRequestImpl>(error);
570 }
571
572 // static
573 std::unique_ptr<HostResolver::ServiceEndpointRequest>
CreateFailingServiceEndpointRequest(int error)574 HostResolver::CreateFailingServiceEndpointRequest(int error) {
575 return std::make_unique<FailingServiceEndpointRequestImpl>(error);
576 }
577
578 } // namespace net
579