Index: net/dns/host_resolver_impl.cc |
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc |
index 9e6fa68d26c8d87649c1bf5172be40d7bd31a1f7..fcb0b6ee42b5479bdc5a479f4c61da98f9c42e1b 100644 |
--- a/net/dns/host_resolver_impl.cc |
+++ b/net/dns/host_resolver_impl.cc |
@@ -494,6 +494,14 @@ class PriorityTracker { |
size_t counts_[NUM_PRIORITIES]; |
}; |
+void MakeNotStale(HostCache::EntryStaleness* stale_info) { |
+ if (!stale_info) |
+ return; |
+ stale_info->expired_by = base::TimeDelta::FromSeconds(-1); |
+ stale_info->network_changes = 0; |
+ stale_info->stale_hits = 0; |
+} |
+ |
} // namespace |
//----------------------------------------------------------------------------- |
@@ -1923,7 +1931,8 @@ int HostResolverImpl::Resolve(const RequestInfo& info, |
// outstanding jobs map. |
Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log); |
- int rv = ResolveHelper(key, info, ip_address_ptr, addresses, source_net_log); |
+ int rv = ResolveHelper(key, info, ip_address_ptr, addresses, false, nullptr, |
+ source_net_log); |
if (rv != ERR_DNS_CACHE_MISS) { |
LogFinishRequest(source_net_log, info, rv); |
RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta()); |
@@ -2032,29 +2041,41 @@ int HostResolverImpl::ResolveHelper(const Key& key, |
const RequestInfo& info, |
const IPAddress* ip_address, |
AddressList* addresses, |
+ bool allow_stale, |
+ HostCache::EntryStaleness* stale_info, |
const BoundNetLog& source_net_log) { |
+ DCHECK(allow_stale == !!stale_info); |
// The result of |getaddrinfo| for empty hosts is inconsistent across systems. |
// On Windows it gives the default interface's address, whereas on Linux it |
// gives an error. We will make it fail on all platforms for consistency. |
- if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) |
+ if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) { |
+ MakeNotStale(stale_info); |
return ERR_NAME_NOT_RESOLVED; |
+ } |
int net_error = ERR_UNEXPECTED; |
- if (ResolveAsIP(key, info, ip_address, &net_error, addresses)) |
+ if (ResolveAsIP(key, info, ip_address, &net_error, addresses)) { |
+ MakeNotStale(stale_info); |
return net_error; |
- if (ServeFromCache(key, info, &net_error, addresses)) { |
+ } |
+ if (ServeFromCache(key, info, &net_error, addresses, allow_stale, |
+ stale_info)) { |
source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT); |
+ // |ServeFromCache()| will set |*stale_info| as needed. |
return net_error; |
} |
// TODO(szym): Do not do this if nsswitch.conf instructs not to. |
// http://crbug.com/117655 |
if (ServeFromHosts(key, info, addresses)) { |
source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT); |
+ MakeNotStale(stale_info); |
return OK; |
} |
- if (ServeLocalhost(key, info, addresses)) |
+ if (ServeLocalhost(key, info, addresses)) { |
+ MakeNotStale(stale_info); |
return OK; |
+ } |
return ERR_DNS_CACHE_MISS; |
} |
@@ -2075,7 +2096,8 @@ int HostResolverImpl::ResolveFromCache(const RequestInfo& info, |
Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log); |
- int rv = ResolveHelper(key, info, ip_address_ptr, addresses, source_net_log); |
+ int rv = ResolveHelper(key, info, ip_address_ptr, addresses, false, nullptr, |
+ source_net_log); |
LogFinishRequest(source_net_log, info, rv); |
return rv; |
} |
@@ -2128,6 +2150,31 @@ std::unique_ptr<base::Value> HostResolverImpl::GetDnsConfigAsValue() const { |
return dns_config->ToValue(); |
} |
+int HostResolverImpl::ResolveStaleFromCache( |
+ const RequestInfo& info, |
+ AddressList* addresses, |
+ HostCache::EntryStaleness* stale_info, |
+ const BoundNetLog& source_net_log) { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(addresses); |
+ DCHECK(stale_info); |
+ |
+ // Update the net log and notify registered observers. |
+ LogStartRequest(source_net_log, info); |
+ |
+ IPAddress ip_address; |
+ IPAddress* ip_address_ptr = nullptr; |
+ if (ip_address.AssignFromIPLiteral(info.hostname())) |
+ ip_address_ptr = &ip_address; |
+ |
+ Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log); |
+ |
+ int rv = ResolveHelper(key, info, ip_address_ptr, addresses, true, stale_info, |
+ source_net_log); |
+ LogFinishRequest(source_net_log, info, rv); |
+ return rv; |
+} |
+ |
bool HostResolverImpl::ResolveAsIP(const Key& key, |
const RequestInfo& info, |
const IPAddress* ip_address, |
@@ -2155,14 +2202,20 @@ bool HostResolverImpl::ResolveAsIP(const Key& key, |
bool HostResolverImpl::ServeFromCache(const Key& key, |
const RequestInfo& info, |
int* net_error, |
- AddressList* addresses) { |
+ AddressList* addresses, |
+ bool allow_stale, |
+ HostCache::EntryStaleness* stale_info) { |
DCHECK(addresses); |
DCHECK(net_error); |
+ DCHECK(allow_stale == !!stale_info); |
if (!info.allow_cached_response() || !cache_.get()) |
return false; |
- const HostCache::Entry* cache_entry = cache_->Lookup( |
- key, base::TimeTicks::Now()); |
+ const HostCache::Entry* cache_entry; |
+ if (allow_stale) |
+ cache_entry = cache_->LookupStale(key, base::TimeTicks::Now(), stale_info); |
+ else |
+ cache_entry = cache_->Lookup(key, base::TimeTicks::Now()); |
if (!cache_entry) |
return false; |