summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-08 15:35:13 +0000
committercbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-08 15:35:13 +0000
commit5ea28dea56c771da6bdf7471c14844332129f718 (patch)
treeb474c2f97f021b431e9fee2a7df094e68c6ee0eb
parent0dc72bbeb04070039490e39c43f796c69601a796 (diff)
downloadchromium_src-5ea28dea56c771da6bdf7471c14844332129f718.zip
chromium_src-5ea28dea56c771da6bdf7471c14844332129f718.tar.gz
chromium_src-5ea28dea56c771da6bdf7471c14844332129f718.tar.bz2
HostResolver now adds AI_CANONNAME to the hint flags if a requester needs the information.
Requests which want the canonical name should be treated differently from requests that do not for the same host in both the HostCache as well as in the HostResolver when combining multiple outstanding requests into a job. The motivation for this is that Kerberos SPN's for a web server are typically generated using the canonical name of the server rather than a DNS alias (both Firefox and IE have this behavior). (note: I had to revert http://codereview.chromium.org/1566012/show because net_unittests were crashing/hanging on the main buildbot, even though they weren't on the trybots. Trying to figure out why). BUG=29862 TEST=net_unittests Review URL: http://codereview.chromium.org/1593015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43947 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/intranet_redirect_detector.cc10
-rw-r--r--chrome/browser/intranet_redirect_detector.h1
-rw-r--r--chrome/browser/net/view_net_internals_job_factory.cc8
-rw-r--r--chrome/test/unit/chrome_test_suite.h4
-rw-r--r--net/base/address_family.h11
-rw-r--r--net/base/address_list.cc10
-rw-r--r--net/base/address_list.h11
-rw-r--r--net/base/address_list_unittest.cc68
-rw-r--r--net/base/host_cache.h29
-rw-r--r--net/base/host_cache_unittest.cc87
-rw-r--r--net/base/host_resolver.h11
-rw-r--r--net/base/host_resolver_impl.cc16
-rw-r--r--net/base/host_resolver_impl_unittest.cc10
-rw-r--r--net/base/host_resolver_proc.cc18
-rw-r--r--net/base/host_resolver_proc.h3
-rw-r--r--net/base/mock_host_resolver.cc12
-rw-r--r--net/base/mock_host_resolver.h5
-rw-r--r--net/proxy/proxy_resolver_js_bindings_unittest.cc3
-rw-r--r--net/socket/socket_test_util.cc4
19 files changed, 260 insertions, 61 deletions
diff --git a/chrome/browser/intranet_redirect_detector.cc b/chrome/browser/intranet_redirect_detector.cc
index 3a527f6..c491a309 100644
--- a/chrome/browser/intranet_redirect_detector.cc
+++ b/chrome/browser/intranet_redirect_detector.cc
@@ -156,9 +156,11 @@ IntranetRedirectHostResolverProc::IntranetRedirectHostResolverProc(
: net::HostResolverProc(previous) {
}
-int IntranetRedirectHostResolverProc::Resolve(const std::string& host,
- net::AddressFamily address_family,
- net::AddressList* addrlist) {
+int IntranetRedirectHostResolverProc::Resolve(
+ const std::string& host,
+ net::AddressFamily address_family,
+ net::HostResolverFlags host_resolver_flags,
+ net::AddressList* addrlist) {
// We'd love to just ask the IntranetRedirectDetector, but we may not be on
// the same thread. So just use the heuristic that any all-lowercase a-z
// hostname with the right number of characters is likely from the detector
@@ -167,5 +169,5 @@ int IntranetRedirectHostResolverProc::Resolve(const std::string& host,
(host.find_first_not_of("abcdefghijklmnopqrstuvwxyz") ==
std::string::npos)) ?
net::ERR_NAME_NOT_RESOLVED :
- ResolveUsingPrevious(host, address_family, addrlist);
+ ResolveUsingPrevious(host, address_family, host_resolver_flags, addrlist);
}
diff --git a/chrome/browser/intranet_redirect_detector.h b/chrome/browser/intranet_redirect_detector.h
index f1e38ae..b8c5dca 100644
--- a/chrome/browser/intranet_redirect_detector.h
+++ b/chrome/browser/intranet_redirect_detector.h
@@ -100,6 +100,7 @@ class IntranetRedirectHostResolverProc : public net::HostResolverProc {
virtual int Resolve(const std::string& host,
net::AddressFamily address_family,
+ net::HostResolverFlags host_resolver_flags,
net::AddressList* addrlist);
};
diff --git a/chrome/browser/net/view_net_internals_job_factory.cc b/chrome/browser/net/view_net_internals_job_factory.cc
index aa39f1f..722559a 100644
--- a/chrome/browser/net/view_net_internals_job_factory.cc
+++ b/chrome/browser/net/view_net_internals_job_factory.cc
@@ -349,6 +349,7 @@ class HostResolverCacheSubSection : public SubSection {
"<th>Host</th>"
"<th>Address family</th>"
"<th>Address list</th>"
+ "<th>Canonical name</th>"
"<th>Time to live (ms)</th>"
"</tr>");
@@ -377,6 +378,7 @@ class HostResolverCacheSubSection : public SubSection {
// Stringify all of the addresses in the address list, separated
// by newlines (br).
std::string address_list_html;
+ std::string canonical_name_html;
if (entry->error != net::OK) {
address_list_html = "<span style='font-weight: bold; color:red'>" +
@@ -391,14 +393,18 @@ class HostResolverCacheSubSection : public SubSection {
net::NetAddressToString(current_address));
current_address = current_address->ai_next;
}
+ std::string canonical_name;
+ if (entry->addrlist.GetCanonicalName(&canonical_name))
+ canonical_name_html = EscapeForHTML(canonical_name);
}
StringAppendF(out,
"<td>%s</td><td>%s</td><td>%s</td>"
- "<td>%d</td></tr>",
+ "<td>%s</td><td>%d</td></tr>",
EscapeForHTML(key.hostname).c_str(),
EscapeForHTML(address_family_str).c_str(),
address_list_html.c_str(),
+ canonical_name_html.c_str(),
ttl_ms);
}
diff --git a/chrome/test/unit/chrome_test_suite.h b/chrome/test/unit/chrome_test_suite.h
index 9532579..3529801 100644
--- a/chrome/test/unit/chrome_test_suite.h
+++ b/chrome/test/unit/chrome_test_suite.h
@@ -59,6 +59,7 @@ class WarningHostResolverProc : public net::HostResolverProc {
virtual int Resolve(const std::string& host,
net::AddressFamily address_family,
+ net::HostResolverFlags host_resolver_flags,
net::AddressList* addrlist) {
const char* kLocalHostNames[] = {"localhost", "127.0.0.1"};
bool local = false;
@@ -78,7 +79,8 @@ class WarningHostResolverProc : public net::HostResolverProc {
// net::RuleBasedHostResolverProc and its AllowDirectLookup method.
EXPECT_TRUE(local) << "Making external DNS lookup of " << host;
- return ResolveUsingPrevious(host, address_family, addrlist);
+ return ResolveUsingPrevious(host, address_family, host_resolver_flags,
+ addrlist);
}
};
diff --git a/net/base/address_family.h b/net/base/address_family.h
index 065927f..fee0584 100644
--- a/net/base/address_family.h
+++ b/net/base/address_family.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,6 +15,13 @@ enum AddressFamily {
ADDRESS_FAMILY_IPV6, // AF_INET6
};
-} // namesapce net
+// HostResolverFlags is a bitflag enum wrapper around the addrinfo.ai_flags
+// supported by host resolver procedures.
+enum {
+ HOST_RESOLVER_CANONNAME = 1 << 0, // 0x1, AI_CANONNAME
+};
+typedef int HostResolverFlags;
+
+} // namespace net
#endif // NET_BASE_ADDRESS_FAMILY_H_
diff --git a/net/base/address_list.cc b/net/base/address_list.cc
index d1624be..55a5992 100644
--- a/net/base/address_list.cc
+++ b/net/base/address_list.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -133,6 +133,14 @@ int AddressList::GetPort() const {
return ntohs(*port_field);
}
+bool AddressList::GetCanonicalName(std::string* canonical_name) const {
+ DCHECK(canonical_name);
+ if (!data_->head || !data_->head->ai_canonname)
+ return false;
+ canonical_name->assign(data_->head->ai_canonname);
+ return true;
+}
+
void AddressList::SetFrom(const AddressList& src, int port) {
if (src.GetPort() == port) {
// We can reference the data from |src| directly.
diff --git a/net/base/address_list.h b/net/base/address_list.h
index b477987..f0eb0ce 100644
--- a/net/base/address_list.h
+++ b/net/base/address_list.h
@@ -1,10 +1,12 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_BASE_ADDRESS_LIST_H_
#define NET_BASE_ADDRESS_LIST_H_
+#include <string>
+
#include "base/ref_counted.h"
struct addrinfo;
@@ -46,6 +48,13 @@ class AddressList {
// a reference to |src|'s data.) Otherwise we will make a copy.
void SetFrom(const AddressList& src, int port);
+ // Gets the canonical name for the address.
+ // If the canonical name exists, |*canonical_name| is filled in with the
+ // value and true is returned. If it does not exist, |*canonical_name| is
+ // not altered and false is returned.
+ // |canonical_name| must be a non-null value.
+ bool GetCanonicalName(std::string* canonical_name) const;
+
// Clears all data from this address list. This leaves the list in the same
// empty state as when first constructed.
void Reset();
diff --git a/net/base/address_list_unittest.cc b/net/base/address_list_unittest.cc
index dbd0f24..6ebd0f3 100644
--- a/net/base/address_list_unittest.cc
+++ b/net/base/address_list_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -17,27 +17,29 @@ namespace {
// Use getaddrinfo() to allocate an addrinfo structure.
void CreateAddressList(const std::string& hostname,
- net::AddressList* addrlist, int port) {
+ int port,
+ net::AddressList* addrlist) {
#if defined(OS_WIN)
net::EnsureWinsockInit();
#endif
int rv = SystemHostResolverProc(hostname,
net::ADDRESS_FAMILY_UNSPECIFIED,
+ 0,
addrlist);
EXPECT_EQ(0, rv);
addrlist->SetPort(port);
}
void CreateLongAddressList(net::AddressList* addrlist, int port) {
- CreateAddressList("192.168.1.1", addrlist, port);
+ CreateAddressList("192.168.1.1", port, addrlist);
net::AddressList second_list;
- CreateAddressList("192.168.1.2", &second_list, port);
+ CreateAddressList("192.168.1.2", port, &second_list);
addrlist->Append(second_list.head());
}
TEST(AddressListTest, GetPort) {
net::AddressList addrlist;
- CreateAddressList("192.168.1.1", &addrlist, 81);
+ CreateAddressList("192.168.1.1", 81, &addrlist);
EXPECT_EQ(81, addrlist.GetPort());
addrlist.SetPort(83);
@@ -46,7 +48,7 @@ TEST(AddressListTest, GetPort) {
TEST(AddressListTest, Assignment) {
net::AddressList addrlist1;
- CreateAddressList("192.168.1.1", &addrlist1, 85);
+ CreateAddressList("192.168.1.1", 85, &addrlist1);
EXPECT_EQ(85, addrlist1.GetPort());
// Should reference the same data as addrlist1 -- so when we change addrlist1
@@ -105,10 +107,10 @@ TEST(AddressListTest, CopyNonRecursive) {
TEST(AddressListTest, Append) {
net::AddressList addrlist1;
- CreateAddressList("192.168.1.1", &addrlist1, 11);
+ CreateAddressList("192.168.1.1", 11, &addrlist1);
EXPECT_EQ(11, addrlist1.GetPort());
net::AddressList addrlist2;
- CreateAddressList("192.168.1.2", &addrlist2, 12);
+ CreateAddressList("192.168.1.2", 12, &addrlist2);
EXPECT_EQ(12, addrlist2.GetPort());
ASSERT_TRUE(addrlist1.head()->ai_next == NULL);
@@ -120,4 +122,54 @@ TEST(AddressListTest, Append) {
EXPECT_EQ(12, addrlist3.GetPort());
}
+static const char* kCanonicalHostname = "canonical.bar.com";
+
+TEST(AddressListTest, Canonical) {
+ // Create an addrinfo with a canonical name.
+ sockaddr_in address;
+ // The contents of address do not matter for this test,
+ // so just zero-ing them out for consistency.
+ memset(&address, 0x0, sizeof(address));
+ struct addrinfo ai;
+ memset(&ai, 0x0, sizeof(ai));
+ ai.ai_family = AF_INET;
+ ai.ai_socktype = SOCK_STREAM;
+ ai.ai_addrlen = sizeof(address);
+ ai.ai_addr = reinterpret_cast<sockaddr*>(&address);
+ ai.ai_canonname = const_cast<char *>(kCanonicalHostname);
+
+ // Copy the addrinfo struct into an AddressList object and
+ // make sure it seems correct.
+ net::AddressList addrlist1;
+ addrlist1.Copy(&ai, true);
+ const struct addrinfo* addrinfo1 = addrlist1.head();
+ EXPECT_TRUE(addrinfo1 != NULL);
+ EXPECT_TRUE(addrinfo1->ai_next == NULL);
+ std::string canon_name1;
+ EXPECT_TRUE(addrlist1.GetCanonicalName(&canon_name1));
+ EXPECT_EQ("canonical.bar.com", canon_name1);
+
+ // Copy the AddressList to another one.
+ net::AddressList addrlist2;
+ addrlist2.Copy(addrinfo1, true);
+ const struct addrinfo* addrinfo2 = addrlist2.head();
+ EXPECT_TRUE(addrinfo2 != NULL);
+ EXPECT_TRUE(addrinfo2->ai_next == NULL);
+ EXPECT_TRUE(addrinfo2->ai_canonname != NULL);
+ EXPECT_NE(addrinfo1, addrinfo2);
+ EXPECT_NE(addrinfo1->ai_canonname, addrinfo2->ai_canonname);
+ std::string canon_name2;
+ EXPECT_TRUE(addrlist2.GetCanonicalName(&canon_name2));
+ EXPECT_EQ("canonical.bar.com", canon_name2);
+
+ // Make sure that GetCanonicalName correctly returns false
+ // when ai_canonname is NULL.
+ ai.ai_canonname = NULL;
+ net::AddressList addrlist_no_canon;
+ addrlist_no_canon.Copy(&ai, true);
+ std::string canon_name3 = "blah";
+ EXPECT_FALSE(addrlist_no_canon.GetCanonicalName(&canon_name3));
+ EXPECT_EQ("blah", canon_name3);
+}
+
} // namespace
diff --git a/net/base/host_cache.h b/net/base/host_cache.h
index c13c6a0..94022e4 100644
--- a/net/base/host_cache.h
+++ b/net/base/host_cache.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -37,22 +37,35 @@ class HostCache {
};
struct Key {
- Key(const std::string& hostname, AddressFamily address_family)
- : hostname(hostname), address_family(address_family) {}
+ Key(const std::string& hostname, AddressFamily address_family,
+ HostResolverFlags host_resolver_flags)
+ : hostname(hostname),
+ address_family(address_family),
+ host_resolver_flags(host_resolver_flags) {}
bool operator==(const Key& other) const {
- return other.hostname == hostname &&
- other.address_family == address_family;
+ // |address_family| and |host_resolver_flags| are compared before
+ // |hostname| under assumption that integer comparisons are faster than
+ // string comparisons.
+ return (other.address_family == address_family &&
+ other.host_resolver_flags == host_resolver_flags &&
+ other.hostname == hostname);
}
bool operator<(const Key& other) const {
- if (address_family == other.address_family)
- return hostname < other.hostname;
- return address_family < other.address_family;
+ // |address_family| and |host_resolver_flags| are compared before
+ // |hostname| under assumption that integer comparisons are faster than
+ // string comparisons.
+ if (address_family != other.address_family)
+ return address_family < other.address_family;
+ if (host_resolver_flags != other.host_resolver_flags)
+ return host_resolver_flags < other.host_resolver_flags;
+ return hostname < other.hostname;
}
std::string hostname;
AddressFamily address_family;
+ HostResolverFlags host_resolver_flags;
};
typedef std::map<Key, scoped_refptr<Entry> > EntryMap;
diff --git a/net/base/host_cache_unittest.cc b/net/base/host_cache_unittest.cc
index 141cfde..a851c0b 100644
--- a/net/base/host_cache_unittest.cc
+++ b/net/base/host_cache_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -20,7 +20,7 @@ const base::TimeDelta kFailureEntryTTL = base::TimeDelta::FromSeconds(0);
// Builds a key for |hostname|, defaulting the address family to unspecified.
HostCache::Key Key(const std::string& hostname) {
- return HostCache::Key(hostname, ADDRESS_FAMILY_UNSPECIFIED);
+ return HostCache::Key(hostname, ADDRESS_FAMILY_UNSPECIFIED, 0);
}
} // namespace
@@ -276,8 +276,8 @@ TEST(HostCacheTest, AddressFamilyIsPartOfKey) {
// t=0.
base::TimeTicks now;
- HostCache::Key key1("foobar.com", ADDRESS_FAMILY_UNSPECIFIED);
- HostCache::Key key2("foobar.com", ADDRESS_FAMILY_IPV4);
+ HostCache::Key key1("foobar.com", ADDRESS_FAMILY_UNSPECIFIED, 0);
+ HostCache::Key key2("foobar.com", ADDRESS_FAMILY_IPV4, 0);
const HostCache::Entry* entry1 = NULL; // Entry for key1
const HostCache::Entry* entry2 = NULL; // Entry for key2
@@ -303,6 +303,42 @@ TEST(HostCacheTest, AddressFamilyIsPartOfKey) {
EXPECT_NE(entry1, entry2);
}
+// Tests that the same hostname can be duplicated in the cache, so long as
+// the HostResolverFlags differ.
+TEST(HostCacheTest, HostResolverFlagsArePartOfKey) {
+ HostCache cache(kMaxCacheEntries, kSuccessEntryTTL, kFailureEntryTTL);
+
+ // t=0.
+ base::TimeTicks now;
+
+ HostCache::Key key1("foobar.com", ADDRESS_FAMILY_IPV4, 0);
+ HostCache::Key key2("foobar.com", ADDRESS_FAMILY_IPV4,
+ HOST_RESOLVER_CANONNAME);
+
+ const HostCache::Entry* entry1 = NULL; // Entry for key1
+ const HostCache::Entry* entry2 = NULL; // Entry for key2
+
+ EXPECT_EQ(0U, cache.size());
+
+ // Add an entry for ("foobar.com", IPV4, NONE) at t=0.
+ EXPECT_TRUE(cache.Lookup(key1, base::TimeTicks()) == NULL);
+ cache.Set(key1, OK, AddressList(), now);
+ entry1 = cache.Lookup(key1, base::TimeTicks());
+ EXPECT_FALSE(entry1 == NULL);
+ EXPECT_EQ(1U, cache.size());
+
+ // Add an entry for ("foobar.com", IPV4, CANONNAME) at t=0.
+ EXPECT_TRUE(cache.Lookup(key2, base::TimeTicks()) == NULL);
+ cache.Set(key2, OK, AddressList(), now);
+ entry2 = cache.Lookup(key2, base::TimeTicks());
+ EXPECT_FALSE(entry2 == NULL);
+ EXPECT_EQ(2U, cache.size());
+
+ // Even though the hostnames were the same, we should have two unique
+ // entries (because the HostResolverFlags differ).
+ EXPECT_NE(entry1, entry2);
+}
+
TEST(HostCacheTest, NoCache) {
// Disable caching.
HostCache cache(0, kSuccessEntryTTL, kFailureEntryTTL);
@@ -353,33 +389,52 @@ TEST(HostCacheTest, KeyComparators) {
int expected_comparison;
} tests[] = {
{
- HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED),
- HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED),
+ HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED, 0),
+ HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED, 0),
0
},
{
- HostCache::Key("host1", ADDRESS_FAMILY_IPV4),
- HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED),
+ HostCache::Key("host1", ADDRESS_FAMILY_IPV4, 0),
+ HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED, 0),
1
},
{
- HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED),
- HostCache::Key("host1", ADDRESS_FAMILY_IPV4),
+ HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED, 0),
+ HostCache::Key("host1", ADDRESS_FAMILY_IPV4, 0),
-1
},
{
- HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED),
- HostCache::Key("host2", ADDRESS_FAMILY_UNSPECIFIED),
+ HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED, 0),
+ HostCache::Key("host2", ADDRESS_FAMILY_UNSPECIFIED, 0),
+ -1
+ },
+ {
+ HostCache::Key("host1", ADDRESS_FAMILY_IPV4, 0),
+ HostCache::Key("host2", ADDRESS_FAMILY_UNSPECIFIED, 0),
+ 1
+ },
+ {
+ HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED, 0),
+ HostCache::Key("host2", ADDRESS_FAMILY_IPV4, 0),
+ -1
+ },
+ {
+ HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED, 0),
+ HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED,
+ HOST_RESOLVER_CANONNAME),
-1
},
{
- HostCache::Key("host1", ADDRESS_FAMILY_IPV4),
- HostCache::Key("host2", ADDRESS_FAMILY_UNSPECIFIED),
+ HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED,
+ HOST_RESOLVER_CANONNAME),
+ HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED, 0),
1
},
{
- HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED),
- HostCache::Key("host2", ADDRESS_FAMILY_IPV4),
+ HostCache::Key("host1", ADDRESS_FAMILY_UNSPECIFIED,
+ HOST_RESOLVER_CANONNAME),
+ HostCache::Key("host2", ADDRESS_FAMILY_UNSPECIFIED,
+ HOST_RESOLVER_CANONNAME),
-1
},
};
diff --git a/net/base/host_resolver.h b/net/base/host_resolver.h
index a65bc6b..9fd8dbe4 100644
--- a/net/base/host_resolver.h
+++ b/net/base/host_resolver.h
@@ -41,6 +41,7 @@ class HostResolver : public base::RefCountedThreadSafe<HostResolver> {
RequestInfo(const std::string& hostname, int port)
: hostname_(hostname),
address_family_(ADDRESS_FAMILY_UNSPECIFIED),
+ host_resolver_flags_(0),
port_(port),
allow_cached_response_(true),
is_speculative_(false),
@@ -61,6 +62,13 @@ class HostResolver : public base::RefCountedThreadSafe<HostResolver> {
address_family_ = address_family;
}
+ HostResolverFlags host_resolver_flags() const {
+ return host_resolver_flags_;
+ }
+ void set_host_resolver_flags(HostResolverFlags host_resolver_flags) {
+ host_resolver_flags_ = host_resolver_flags;
+ }
+
bool allow_cached_response() const { return allow_cached_response_; }
void set_allow_cached_response(bool b) { allow_cached_response_ = b; }
@@ -80,6 +88,9 @@ class HostResolver : public base::RefCountedThreadSafe<HostResolver> {
// The address family to restrict results to.
AddressFamily address_family_;
+ // Flags to use when resolving this request.
+ HostResolverFlags host_resolver_flags_;
+
// The port number to set in the result's sockaddrs.
int port_;
diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc
index a891920..f7a3b4f 100644
--- a/net/base/host_resolver_impl.cc
+++ b/net/base/host_resolver_impl.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -60,13 +60,16 @@ HostResolver* CreateSystemHostResolver(
static int ResolveAddrInfo(HostResolverProc* resolver_proc,
const std::string& host,
AddressFamily address_family,
+ HostResolverFlags host_resolver_flags,
AddressList* out) {
if (resolver_proc) {
// Use the custom procedure.
- return resolver_proc->Resolve(host, address_family, out);
+ return resolver_proc->Resolve(host, address_family,
+ host_resolver_flags, out);
} else {
// Use the system procedure (getaddrinfo).
- return SystemHostResolverProc(host, address_family, out);
+ return SystemHostResolverProc(host, address_family,
+ host_resolver_flags, out);
}
}
@@ -323,6 +326,7 @@ class HostResolverImpl::Job
error_ = ResolveAddrInfo(resolver_proc_,
key_.hostname,
key_.address_family,
+ key_.host_resolver_flags,
&results_);
if (requests_trace_) {
@@ -738,7 +742,8 @@ int HostResolverImpl::Resolve(const RequestInfo& info,
if (!callback) {
AddressList addrlist;
int error = ResolveAddrInfo(
- effective_resolver_proc(), key.hostname, key.address_family, &addrlist);
+ effective_resolver_proc(), key.hostname, key.address_family,
+ key.host_resolver_flags, &addrlist);
if (error == OK) {
addrlist.SetPort(info.port());
*addresses = addrlist;
@@ -1146,7 +1151,8 @@ HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest(
AddressFamily effective_address_family = info.address_family();
if (effective_address_family == ADDRESS_FAMILY_UNSPECIFIED)
effective_address_family = default_address_family_;
- return Key(info.hostname(), effective_address_family);
+ return Key(info.hostname(), effective_address_family,
+ info.host_resolver_flags());
}
HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) {
diff --git a/net/base/host_resolver_impl_unittest.cc b/net/base/host_resolver_impl_unittest.cc
index e439491..e9a721c 100644
--- a/net/base/host_resolver_impl_unittest.cc
+++ b/net/base/host_resolver_impl_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -90,13 +90,15 @@ class CapturingHostResolverProc : public HostResolverProc {
virtual int Resolve(const std::string& hostname,
AddressFamily address_family,
+ HostResolverFlags host_resolver_flags,
AddressList* addrlist) {
event_.Wait();
{
AutoLock l(lock_);
capture_list_.push_back(CaptureEntry(hostname, address_family));
}
- return ResolveUsingPrevious(hostname, address_family, addrlist);
+ return ResolveUsingPrevious(hostname, address_family,
+ host_resolver_flags, addrlist);
}
CaptureList GetCaptureList() const {
@@ -134,6 +136,7 @@ class EchoingHostResolverProc : public HostResolverProc {
virtual int Resolve(const std::string& hostname,
AddressFamily address_family,
+ HostResolverFlags host_resolver_flags,
AddressList* addrlist) {
// Encode the request's hostname and address_family in the output address.
std::string ip_literal = StringPrintf("192.%d.%d.%d",
@@ -143,6 +146,7 @@ class EchoingHostResolverProc : public HostResolverProc {
return SystemHostResolverProc(ip_literal,
ADDRESS_FAMILY_UNSPECIFIED,
+ host_resolver_flags,
addrlist);
}
};
@@ -1459,6 +1463,8 @@ TEST_F(HostResolverImplTest, SetDefaultAddressFamily_Synchronous) {
EXPECT_EQ("192.1.98.1", NetAddressToString(addrlist[3].head()));
}
+// TODO(cbentzel): Test a mix of requests with different HostResolverFlags.
+
} // namespace
} // namespace net
diff --git a/net/base/host_resolver_proc.cc b/net/base/host_resolver_proc.cc
index 5ccf01a..84daae0 100644
--- a/net/base/host_resolver_proc.cc
+++ b/net/base/host_resolver_proc.cc
@@ -67,14 +67,18 @@ HostResolverProc* HostResolverProc::GetDefault() {
return default_proc_;
}
-int HostResolverProc::ResolveUsingPrevious(const std::string& host,
- AddressFamily address_family,
- AddressList* addrlist) {
+int HostResolverProc::ResolveUsingPrevious(
+ const std::string& host,
+ AddressFamily address_family,
+ HostResolverFlags host_resolver_flags,
+ AddressList* addrlist) {
if (previous_proc_)
- return previous_proc_->Resolve(host, address_family, addrlist);
+ return previous_proc_->Resolve(host, address_family,
+ host_resolver_flags, addrlist);
// Final fallback is the system resolver.
- return SystemHostResolverProc(host, address_family, addrlist);
+ return SystemHostResolverProc(host, address_family,
+ host_resolver_flags, addrlist);
}
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
@@ -152,6 +156,7 @@ ThreadLocalStorage::Slot DnsReloadTimer::tls_index_(base::LINKER_INITIALIZED);
int SystemHostResolverProc(const std::string& host,
AddressFamily address_family,
+ HostResolverFlags host_resolver_flags,
AddressList* addrlist) {
// The result of |getaddrinfo| for empty hosts is inconsistent across systems.
// On Windows it gives the default interface's address, whereas on Linux it
@@ -205,6 +210,9 @@ int SystemHostResolverProc(const std::string& host,
hints.ai_flags = AI_ADDRCONFIG;
#endif
+ if (host_resolver_flags & HOST_RESOLVER_CANONNAME)
+ hints.ai_flags |= AI_CANONNAME;
+
// Restrict result set to only this socket type to avoid duplicates.
hints.ai_socktype = SOCK_STREAM;
diff --git a/net/base/host_resolver_proc.h b/net/base/host_resolver_proc.h
index ca0c55d..6f32280 100644
--- a/net/base/host_resolver_proc.h
+++ b/net/base/host_resolver_proc.h
@@ -30,6 +30,7 @@ class HostResolverProc : public base::RefCountedThreadSafe<HostResolverProc> {
// a list of socket addresses. Otherwise returns a network error code.
virtual int Resolve(const std::string& host,
AddressFamily address_family,
+ HostResolverFlags host_resolver_flags,
AddressList* addrlist) = 0;
protected:
@@ -40,6 +41,7 @@ class HostResolverProc : public base::RefCountedThreadSafe<HostResolverProc> {
// Asks the fallback procedure (if set) to do the resolve.
int ResolveUsingPrevious(const std::string& host,
AddressFamily address_family,
+ HostResolverFlags host_resolver_flags,
AddressList* addrlist);
private:
@@ -78,6 +80,7 @@ class HostResolverProc : public base::RefCountedThreadSafe<HostResolverProc> {
// network error code.
int SystemHostResolverProc(const std::string& host,
AddressFamily address_family,
+ HostResolverFlags host_resolver_flags,
AddressList* addrlist);
} // namespace net
diff --git a/net/base/mock_host_resolver.cc b/net/base/mock_host_resolver.cc
index c079fc1..9e57fd1 100644
--- a/net/base/mock_host_resolver.cc
+++ b/net/base/mock_host_resolver.cc
@@ -153,8 +153,11 @@ void RuleBasedHostResolverProc::AddRuleForAddressFamily(
void RuleBasedHostResolverProc::AddIPv6Rule(const std::string& host_pattern,
const std::string& ipv6_literal) {
- Rule rule(Rule::kResolverTypeIPV6Literal, host_pattern,
- ADDRESS_FAMILY_UNSPECIFIED, ipv6_literal, 0);
+ Rule rule(Rule::kResolverTypeIPV6Literal,
+ host_pattern,
+ ADDRESS_FAMILY_UNSPECIFIED,
+ ipv6_literal,
+ 0);
rules_.push_back(rule);
}
@@ -184,6 +187,7 @@ void RuleBasedHostResolverProc::AddSimulatedFailure(
int RuleBasedHostResolverProc::Resolve(const std::string& host,
AddressFamily address_family,
+ HostResolverFlags host_resolver_flags,
AddressList* addrlist) {
RuleList::iterator r;
for (r = rules_.begin(); r != rules_.end(); ++r) {
@@ -206,6 +210,7 @@ int RuleBasedHostResolverProc::Resolve(const std::string& host,
case Rule::kResolverTypeSystem:
return SystemHostResolverProc(effective_host,
address_family,
+ host_resolver_flags,
addrlist);
case Rule::kResolverTypeIPV6Literal:
return ResolveIPV6LiteralUsingGURL(effective_host, addrlist);
@@ -215,7 +220,8 @@ int RuleBasedHostResolverProc::Resolve(const std::string& host,
}
}
}
- return ResolveUsingPrevious(host, address_family, addrlist);
+ return ResolveUsingPrevious(host, address_family,
+ host_resolver_flags, addrlist);
}
//-----------------------------------------------------------------------------
diff --git a/net/base/mock_host_resolver.h b/net/base/mock_host_resolver.h
index 661e2dd..ff9f9fc 100644
--- a/net/base/mock_host_resolver.h
+++ b/net/base/mock_host_resolver.h
@@ -131,6 +131,7 @@ class RuleBasedHostResolverProc : public HostResolverProc {
// HostResolverProc methods:
virtual int Resolve(const std::string& host,
AddressFamily address_family,
+ HostResolverFlags host_resolver_flags,
AddressList* addrlist);
private:
@@ -155,9 +156,11 @@ class WaitingHostResolverProc : public HostResolverProc {
// HostResolverProc methods:
virtual int Resolve(const std::string& host,
AddressFamily address_family,
+ HostResolverFlags host_resolver_flags,
AddressList* addrlist) {
event_.Wait();
- return ResolveUsingPrevious(host, address_family, addrlist);
+ return ResolveUsingPrevious(host, address_family, host_resolver_flags,
+ addrlist);
}
private:
diff --git a/net/proxy/proxy_resolver_js_bindings_unittest.cc b/net/proxy/proxy_resolver_js_bindings_unittest.cc
index 3271e92..2d525f7 100644
--- a/net/proxy/proxy_resolver_js_bindings_unittest.cc
+++ b/net/proxy/proxy_resolver_js_bindings_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -48,6 +48,7 @@ class MockHostResolverWithMultipleResults : public HostResolver {
AddressList result;
int rv = SystemHostResolverProc(ip_literal,
ADDRESS_FAMILY_UNSPECIFIED,
+ 0,
&result);
EXPECT_EQ(OK, rv);
EXPECT_EQ(NULL, result.head()->ai_next);
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 4a8311c..7e2afc7 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -52,7 +52,7 @@ bool MockClientSocket::IsConnectedAndIdle() const {
int MockClientSocket::GetPeerAddress(AddressList* address) const {
return net::SystemHostResolverProc("localhost", ADDRESS_FAMILY_UNSPECIFIED,
- address);
+ 0, address);
}
void MockClientSocket::RunCallbackAsync(net::CompletionCallback* callback,