Index: net/base/host_resolver_impl.cc |
diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc |
index ecbbd582a75879344fd00f2818483e55c5100466..d1f30855b7bbf5c98bdbb0e2a7776c4f4b750ae2 100644 |
--- a/net/base/host_resolver_impl.cc |
+++ b/net/base/host_resolver_impl.cc |
@@ -1205,6 +1205,17 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job { |
base::TimeDelta()); |
} |
+ // Attempt to serve the job from hosts. |
+ void ServeFromHosts() { |
szym
2012/03/10 06:48:49
Add a bool return so that the caller knows if this
|
+ DCHECK_GT(num_active_requests(), 0u); |
+ AddressList addr_list; |
+ if (resolver_->ServeFromHosts(key(), |
+ requests_.front()->info(), |
+ &addr_list)) { |
+ CompleteRequests(OK, addr_list, base::TimeDelta()); |
+ } |
+ } |
+ |
private: |
RequestPriority priority() const { |
return priority_tracker_.highest_priority(); |
@@ -1292,6 +1303,10 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job { |
if (net_error != OK) { |
dns_task_.reset(); |
+ |
+ // TODO(szym): Run ServeFromHosts now if nsswitch.conf says so. |
+ // http://crbug.com/117655 |
+ |
// TODO(szym): Some net errors indicate lack of connectivity. Starting |
// ProcTask in that case is a waste of time. |
StartProcTask(); |
@@ -1344,9 +1359,11 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job { |
net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
net_error); |
+ DCHECK(!requests_.empty()); |
+ |
// We are the only consumer of |list|, so we can safely change the port |
// without copy-on-write. This pays off, when job has only one request. |
- if (net_error == OK && !requests_.empty()) |
+ if (net_error == OK) |
MutableSetPort(requests_.front()->info().port(), &list); |
if ((net_error != ERR_ABORTED) && |
@@ -1552,9 +1569,17 @@ int HostResolverImpl::ResolveHelper(const Key& key, |
int net_error = ERR_UNEXPECTED; |
if (ResolveAsIP(key, info, &net_error, addresses)) |
return net_error; |
- net_error = ERR_DNS_CACHE_MISS; |
- ServeFromCache(key, info, request_net_log, &net_error, addresses); |
- return net_error; |
+ if (ServeFromCache(key, info, &net_error, addresses)) { |
+ request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); |
+ return net_error; |
+ } |
+ // TODO(szym): Do not do this if nsswitch.conf instructs not to. |
+ // http://crbug.com/117655 |
+ if (ServeFromHosts(key, info, addresses)) { |
+ request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT, NULL); |
+ return OK; |
+ } |
+ return ERR_DNS_CACHE_MISS; |
} |
int HostResolverImpl::ResolveFromCache(const RequestInfo& info, |
@@ -1637,7 +1662,6 @@ bool HostResolverImpl::ResolveAsIP(const Key& key, |
bool HostResolverImpl::ServeFromCache(const Key& key, |
const RequestInfo& info, |
- const BoundNetLog& request_net_log, |
int* net_error, |
AddressList* addresses) { |
DCHECK(addresses); |
@@ -1650,13 +1674,30 @@ bool HostResolverImpl::ServeFromCache(const Key& key, |
if (!cache_entry) |
return false; |
- request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); |
+ |
*net_error = cache_entry->error; |
if (*net_error == OK) |
*addresses = CreateAddressListUsingPort(cache_entry->addrlist, info.port()); |
return true; |
} |
+bool HostResolverImpl::ServeFromHosts(const Key& key, |
+ const RequestInfo& info, |
+ AddressList* addresses) { |
+ DCHECK(addresses); |
+ if (!dns_session_) |
+ return false; |
+ |
+ const DnsHosts& hosts = dns_session_->config().hosts; |
+ DnsHosts::const_iterator it = hosts.find(DnsHostsKey(key.hostname, |
+ key.address_family)); |
+ if (it == hosts.end()) |
+ return false; |
+ |
+ *addresses = AddressList::CreateFromIPAddress(it->second, info.port()); |
+ return true; |
+} |
+ |
void HostResolverImpl::CacheResult(const Key& key, |
int net_error, |
const AddressList& addr_list, |
@@ -1734,6 +1775,20 @@ void HostResolverImpl::AbortAllInProgressJobs() { |
} |
} |
+void HostResolverImpl::TryServingAllJobsFromHosts() { |
+ if (!dns_session_) |
+ return; |
+ |
+ // TODO(szym): Do not do this if nsswitch.conf instructs not to. |
+ // http://crbug.com/117655 |
+ |
+ for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) { |
+ Job* job = (it++)->second; |
+ // This could remove |job| from |jobs_|, but iterators remain valid. |
+ job->ServeFromHosts(); |
szym
2012/03/10 06:48:49
HostResolverImpl could be destroyed in Request cal
|
+ } |
+} |
+ |
void HostResolverImpl::OnIPAddressChanged() { |
if (cache_.get()) |
cache_->clear(); |
@@ -1771,13 +1826,17 @@ void HostResolverImpl::OnConfigChanged(const DnsConfig& dns_config) { |
// newly started jobs use the new factory. |
bool had_factory = (dns_transaction_factory_.get() != NULL); |
if (dns_config.IsValid()) { |
- dns_transaction_factory_ = DnsTransactionFactory::CreateFactory( |
- new DnsSession(dns_config, |
- ClientSocketFactory::GetDefaultFactory(), |
- base::Bind(&base::RandInt), |
- net_log_)); |
+ dns_session_ = new DnsSession(dns_config, |
+ ClientSocketFactory::GetDefaultFactory(), |
+ base::Bind(&base::RandInt), |
+ net_log_); |
+ dns_transaction_factory_ = |
+ DnsTransactionFactory::CreateFactory(dns_session_); |
+ |
+ TryServingAllJobsFromHosts(); |
} else { |
dns_transaction_factory_.reset(); |
+ dns_session_.release(); |
} |
// Don't Abort running Jobs unless they were running on DnsTransaction. |
// TODO(szym): This will change once http://crbug.com/114827 is fixed. |