Index: net/dns/host_resolver_impl.cc |
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc |
index 74a76755ce4ebe5c1eaae88a8ac1b21ff9a555a2..d96ec2667502879ae5cfee6a784497de22724ba4 100644 |
--- a/net/dns/host_resolver_impl.cc |
+++ b/net/dns/host_resolver_impl.cc |
@@ -250,6 +250,26 @@ AddressList EnsurePortOnAddressList(const AddressList& list, uint16 port) { |
return AddressList::CopyWithPort(list, port); |
} |
+bool IsAllLocalhostOfOneFamily(const AddressList& list) { |
mmenke
2013/04/17 15:42:32
Think this function is worth a short description.
mmenke
2013/04/17 15:42:32
This function name seems to be inaccurate. We che
mmenke
2013/04/17 15:42:32
optional nit: Suggest using "addresses" rather th
szym
2013/04/17 17:09:16
Done.
szym
2013/04/17 17:09:16
Done. Also changed "localhost" to "loopback" which
szym
2013/04/17 17:09:16
Done.
|
+ const uint8 kIPv6Loopback[] = { 0, 0, 0, 0, 0, 0, 0, 0, |
+ 0, 0, 0, 0, 0, 0, 0, 1 }; |
+ for (unsigned i = 0; i < list.size(); ++i) { |
+ const IPAddressNumber& address = list[i].address(); |
+ switch (list[i].GetFamily()) { |
mmenke
2013/04/17 15:42:32
nit: address.GetFamily()
szym
2013/04/17 17:09:16
GetFamily is a function of IPEndPoint. IPAddressNu
|
+ case ADDRESS_FAMILY_IPV4: |
+ if (address[0] != 127) return false; |
mmenke
2013/04/17 15:42:32
nit: Line break before "return".
szym
2013/04/17 17:09:16
Done.
|
+ break; |
+ case ADDRESS_FAMILY_IPV6: |
mmenke
2013/04/17 15:42:32
Do we even need to check for IPv6? I'm not partic
szym
2013/04/17 17:09:16
We don't, and this code path will not be exercised
mmenke
2013/04/17 17:35:00
I think we should go ahead and do that. If we nee
|
+ if (!std::equal(address.begin(), address.end(), kIPv6Loopback)) |
+ return false; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
+ } |
+ return true; |
+} |
+ |
// Creates NetLog parameters when the resolve failed. |
base::Value* NetLogProcTaskFailedCallback(uint32 attempt_number, |
int net_error, |
@@ -1950,7 +1970,6 @@ bool HostResolverImpl::ServeFromHosts(const Key& key, |
DCHECK(addresses); |
if (!HaveDnsConfig()) |
return false; |
- |
addresses->clear(); |
// HOSTS lookups are case-insensitive. |
@@ -1979,6 +1998,17 @@ bool HostResolverImpl::ServeFromHosts(const Key& key, |
addresses->push_back(IPEndPoint(it->second, info.port())); |
} |
+ // If got only loopback addresses and the family was restricted, resolve |
+ // again, without restrictions. See SystemHostResolverCall for rationale. |
+ if ((key.host_resolver_flags & |
+ HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6) && |
+ IsAllLocalhostOfOneFamily(*addresses)) { |
+ Key new_key(key); |
+ new_key.address_family = ADDRESS_FAMILY_UNSPECIFIED; |
+ new_key.host_resolver_flags &= |
+ ~HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; |
+ return ServeFromHosts(new_key, info, addresses); |
+ } |
return !addresses->empty(); |
} |
@@ -2118,6 +2148,7 @@ void HostResolverImpl::OnIPAddressChanged() { |
void HostResolverImpl::OnDNSChanged() { |
DnsConfig dns_config; |
NetworkChangeNotifier::GetDnsConfig(&dns_config); |
+ |
if (net_log_) { |
net_log_->AddGlobalEntry( |
NetLog::TYPE_DNS_CONFIG_CHANGED, |