Index: net/dns/host_resolver_impl.cc |
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc |
index bd6e43198dca94319fe32227f5bc89475634f90a..767a37272542ac3a8c62c92a397feb823701194e 100644 |
--- a/net/dns/host_resolver_impl.cc |
+++ b/net/dns/host_resolver_impl.cc |
@@ -74,6 +74,15 @@ const unsigned kMinimumTTLSeconds = kCacheEntryTTLSeconds; |
const char kLocalhost[] = "localhost."; |
+// Time between IPv6 probes, i.e. for how long results of each IPv6 probe are |
+// cached. |
+const int kIPv6ProbePeriodMs = 1000; |
+ |
+// Google DNS address used for IPv6 probes. |
+const uint8_t kIPv6ProbeAddress[] = |
+ { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, |
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 }; |
+ |
// We use a separate histogram name for each platform to facilitate the |
// display of error codes by their symbolic name (since each platform has |
// different mappings). |
@@ -386,6 +395,15 @@ base::Value* NetLogDnsConfigCallback(const DnsConfig* config, |
return config->ToValue(); |
} |
+base::Value* NetLogIPv6AvailableCallback(bool ipv6_available, |
+ bool cached, |
+ NetLogCaptureMode /* capture_mode */) { |
+ base::DictionaryValue* dict = new base::DictionaryValue(); |
+ dict->SetBoolean("ipv6_available", ipv6_available); |
+ dict->SetBoolean("cached", cached); |
+ return dict; |
+} |
+ |
// The logging routines are defined here because some requests are resolved |
// without a Request object. |
@@ -1815,6 +1833,7 @@ HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log) |
num_dns_failures_(0), |
probe_ipv6_support_(true), |
use_local_ipv6_(false), |
+ last_ipv6_probe_result_(true), |
resolved_known_ipv6_hostname_(false), |
additional_resolver_flags_(0), |
fallback_to_proctask_(true), |
@@ -2167,7 +2186,7 @@ void HostResolverImpl::SetHaveOnlyLoopbackAddresses(bool result) { |
HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( |
const RequestInfo& info, |
const IPAddressNumber* ip_number, |
- const BoundNetLog& net_log) const { |
+ const BoundNetLog& net_log) { |
HostResolverFlags effective_flags = |
info.host_resolver_flags() | additional_resolver_flags_; |
AddressFamily effective_address_family = info.address_family(); |
@@ -2183,16 +2202,7 @@ HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( |
// set) so the code requesting the resolution should be amenable to |
// receiving a IPv6 resolution. |
ip_number == nullptr) { |
- // Google DNS address. |
- const uint8 kIPv6Address[] = |
- { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, |
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 }; |
- IPAddressNumber address(kIPv6Address, |
- kIPv6Address + arraysize(kIPv6Address)); |
- bool rv6 = IsGloballyReachable(address, net_log); |
- net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK, |
- NetLog::BoolCallback("ipv6_available", rv6)); |
- if (!rv6) { |
+ if (!IsIPv6Reachable(net_log)) { |
effective_address_family = ADDRESS_FAMILY_IPV4; |
effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; |
} |
@@ -2210,6 +2220,22 @@ HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( |
return Key(hostname, effective_address_family, effective_flags); |
} |
+bool HostResolverImpl::IsIPv6Reachable(const BoundNetLog& net_log) { |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ bool cached = true; |
+ if ((now - last_ipv6_probe_time_).InMilliseconds() > kIPv6ProbePeriodMs) { |
+ IPAddressNumber address(kIPv6ProbeAddress, |
+ kIPv6ProbeAddress + arraysize(kIPv6ProbeAddress)); |
+ last_ipv6_probe_result_ = IsGloballyReachable(address, net_log); |
+ last_ipv6_probe_time_ = now; |
+ cached = false; |
+ } |
+ net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK, |
+ base::Bind(&NetLogIPv6AvailableCallback, |
+ last_ipv6_probe_result_, cached)); |
+ return last_ipv6_probe_result_; |
+} |
+ |
void HostResolverImpl::AbortAllInProgressJobs() { |
// In Abort, a Request callback could spawn new Jobs with matching keys, so |
// first collect and remove all running jobs from |jobs_|. |
@@ -2279,6 +2305,7 @@ void HostResolverImpl::TryServingAllJobsFromHosts() { |
void HostResolverImpl::OnIPAddressChanged() { |
resolved_known_ipv6_hostname_ = false; |
+ last_ipv6_probe_time_ = base::TimeTicks(); |
// Abandon all ProbeJobs. |
probe_weak_ptr_factory_.InvalidateWeakPtrs(); |
if (cache_.get()) |