Fix remaining localhost resolution issues.

If host resolution is restricted to a single address family and the results of a resolution are all localhost of that type, try again without the address family restriction.

Also make --disable-ipv6 apply to resolution of ip literals.

BUG=42058, 49024, 32522
TEST=Manual testing in various network configurations. See https://spreadsheets.google.com/ccc?key=0AhSnKEusL6UgdFZIRmxTUnYtZDhjX3lKclBqMHo4YUE&hl=en&authkey=CLKDxMYB

Review URL: http://codereview.chromium.org/3231005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58534 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc
index 2118cb47..4b4649d 100644
--- a/net/base/host_resolver_impl.cc
+++ b/net/base/host_resolver_impl.cc
@@ -875,26 +875,33 @@
   // Update the net log and notify registered observers.
   OnStartRequest(source_net_log, request_net_log, request_id, info);
 
-  // Check for IP literal.
-  IPAddressNumber ip_number;
-  if (ParseIPLiteralToNumber(info.hostname(), &ip_number)) {
-    DCHECK_EQ((info.host_resolver_flags() &
-               ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY)), 0)
-        << " Unhandled flag";
-    AddressList result(ip_number, info.port(),
-                       (info.host_resolver_flags() & HOST_RESOLVER_CANONNAME));
-
-    *addresses = result;
-    // Update the net log and notify registered observers.
-    OnFinishRequest(source_net_log, request_net_log, request_id, info, OK,
-                    0  /* os_error (unknown since from cache) */);
-    return OK;
-  }
-
   // Build a key that identifies the request in the cache and in the
   // outstanding jobs map.
   Key key = GetEffectiveKeyForRequest(info);
 
+  // Check for IP literal.
+  IPAddressNumber ip_number;
+  if (ParseIPLiteralToNumber(info.hostname(), &ip_number)) {
+    DCHECK_EQ(key.host_resolver_flags &
+                  ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY |
+                    HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6),
+              0) << " Unhandled flag";
+    bool ipv6_disabled = default_address_family_ == ADDRESS_FAMILY_IPV4 &&
+        !ipv6_probe_monitoring_;
+    int net_error = OK;
+    if (ip_number.size() == 16 && ipv6_disabled) {
+      net_error = ERR_NAME_NOT_RESOLVED;
+    } else {
+      AddressList result(ip_number, info.port(),
+                         (key.host_resolver_flags & HOST_RESOLVER_CANONNAME));
+      *addresses = result;
+    }
+    // Update the net log and notify registered observers.
+    OnFinishRequest(source_net_log, request_net_log, request_id, info,
+                    net_error, 0  /* os_error (unknown since from cache) */);
+    return net_error;
+  }
+
   // If we have an unexpired cache entry, use it.
   if (info.allow_cached_response() && cache_.get()) {
     const HostCache::Entry* cache_entry = cache_->Lookup(
@@ -1285,11 +1292,16 @@
 
 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest(
     const RequestInfo& info) const {
+  HostResolverFlags effective_flags =
+      info.host_resolver_flags() | additional_resolver_flags_;
   AddressFamily effective_address_family = info.address_family();
-  if (effective_address_family == ADDRESS_FAMILY_UNSPECIFIED)
+  if (effective_address_family == ADDRESS_FAMILY_UNSPECIFIED &&
+      default_address_family_ != ADDRESS_FAMILY_UNSPECIFIED) {
     effective_address_family = default_address_family_;
-  return Key(info.hostname(), effective_address_family,
-             info.host_resolver_flags() | additional_resolver_flags_);
+    if (ipv6_probe_monitoring_)
+      effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
+  }
+  return Key(info.hostname(), effective_address_family, effective_flags);
 }
 
 HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) {