summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-17 18:00:02 +0000
committervandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-17 18:00:02 +0000
commitfc21277e73baabd1fb1fd02cc1d3cf228aa8512a (patch)
tree18549e02ef7d938c85c8074ecf81578733ccf748
parent2aa021282aa83a7493bc72677ffe83a8e5183892 (diff)
downloadchromium_src-fc21277e73baabd1fb1fd02cc1d3cf228aa8512a.zip
chromium_src-fc21277e73baabd1fb1fd02cc1d3cf228aa8512a.tar.gz
chromium_src-fc21277e73baabd1fb1fd02cc1d3cf228aa8512a.tar.bz2
Revert 56384 - Don't resolve IP literals.
For each resolution request this checks to see if this 'host' is a literal ip address. If so, it synthesises a struct addrinfo and returns it without adding it to the cache. BUG=39830 TEST=unit tests, new and old Review URL: http://codereview.chromium.org/3023048 TBR=vandebo@chromium.org Review URL: http://codereview.chromium.org/3115014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@56385 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/net/predictor_unittest.cc2
-rw-r--r--net/base/address_list.cc91
-rw-r--r--net/base/address_list.h20
-rw-r--r--net/base/address_list_unittest.cc62
-rw-r--r--net/base/host_resolver_impl.cc19
-rw-r--r--net/base/host_resolver_impl_unittest.cc5
-rw-r--r--net/base/mock_host_resolver.cc18
-rw-r--r--net/socket/ssl_client_socket_unittest.cc6
8 files changed, 92 insertions, 131 deletions
diff --git a/chrome/browser/net/predictor_unittest.cc b/chrome/browser/net/predictor_unittest.cc
index 3e42d62..5bc650a 100644
--- a/chrome/browser/net/predictor_unittest.cc
+++ b/chrome/browser/net/predictor_unittest.cc
@@ -127,7 +127,7 @@ TEST_F(PredictorTest, ShutdownWhenResolutionIsPendingTest) {
PredictorInit::kMaxPrefetchConcurrentLookups,
false);
- GURL localhost("http://localhost:80");
+ GURL localhost("http://127.0.0.1:80");
UrlList names;
names.push_back(localhost);
diff --git a/net/base/address_list.cc b/net/base/address_list.cc
index 75c30b8..1c97311 100644
--- a/net/base/address_list.cc
+++ b/net/base/address_list.cc
@@ -85,53 +85,6 @@ void SetPortRecursive(struct addrinfo* info, int port) {
} // namespace
-AddressList::AddressList(const IPAddressNumber& address, int port,
- bool canonicalize_name) {
- struct addrinfo* ai = new addrinfo;
- memset(ai, 0, sizeof(addrinfo));
- ai->ai_socktype = SOCK_STREAM;
-
- switch (address.size()) {
- case 4: {
- ai->ai_family = AF_INET;
- const size_t sockaddr_in_size = sizeof(struct sockaddr_in);
- ai->ai_addrlen = sockaddr_in_size;
-
- struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(
- new char[sockaddr_in_size]);
- memset(addr, 0, sockaddr_in_size);
- addr->sin_family = AF_INET;
- memcpy(&addr->sin_addr, &address[0], 4);
- ai->ai_addr = reinterpret_cast<struct sockaddr*>(addr);
- break;
- }
- case 16: {
- ai->ai_family = AF_INET6;
- const size_t sockaddr_in6_size = sizeof(struct sockaddr_in6);
- ai->ai_addrlen = sockaddr_in6_size;
-
- struct sockaddr_in6* addr6 = reinterpret_cast<struct sockaddr_in6*>(
- new char[sockaddr_in6_size]);
- memset(addr6, 0, sockaddr_in6_size);
- addr6->sin6_family = AF_INET6;
- memcpy(&addr6->sin6_addr, &address[0], 16);
- ai->ai_addr = reinterpret_cast<struct sockaddr*>(addr6);
- break;
- }
- default: {
- NOTREACHED() << "Bad IP address";
- break;
- }
- }
-
- if (canonicalize_name) {
- std::string name = NetAddressToString(ai);
- ai->ai_canonname = do_strdup(name.c_str());
- }
- data_ = new Data(ai, false /*is_system_created*/);
- SetPort(port);
-}
-
void AddressList::Adopt(struct addrinfo* head) {
data_ = new Data(head, true /*is_system_created*/);
}
@@ -190,6 +143,50 @@ void AddressList::Reset() {
data_ = NULL;
}
+// static
+AddressList AddressList::CreateIPv4Address(unsigned char data[4],
+ const std::string& canonical_name) {
+ struct addrinfo* ai = new addrinfo;
+ memset(ai, 0, sizeof(addrinfo));
+ ai->ai_family = AF_INET;
+ ai->ai_socktype = SOCK_STREAM;
+ const size_t sockaddr_in_size = sizeof(struct sockaddr_in);
+ ai->ai_addrlen = sockaddr_in_size;
+ if (!canonical_name.empty())
+ ai->ai_canonname = do_strdup(canonical_name.c_str());
+
+ struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(
+ new char[sockaddr_in_size]);
+ memset(addr, 0, sockaddr_in_size);
+ addr->sin_family = AF_INET;
+ memcpy(&addr->sin_addr, data, 4);
+ ai->ai_addr = reinterpret_cast<struct sockaddr*>(addr);
+
+ return AddressList(new Data(ai, false /*is_system_created*/));
+}
+
+// static
+AddressList AddressList::CreateIPv6Address(unsigned char data[16],
+ const std::string& canonical_name) {
+ struct addrinfo* ai = new addrinfo;
+ memset(ai, 0, sizeof(addrinfo));
+ ai->ai_family = AF_INET6;
+ ai->ai_socktype = SOCK_STREAM;
+ const size_t sockaddr_in6_size = sizeof(struct sockaddr_in6);
+ ai->ai_addrlen = sockaddr_in6_size;
+ if (!canonical_name.empty())
+ ai->ai_canonname = do_strdup(canonical_name.c_str());
+
+ struct sockaddr_in6* addr6 = reinterpret_cast<struct sockaddr_in6*>(
+ new char[sockaddr_in6_size]);
+ memset(addr6, 0, sockaddr_in6_size);
+ addr6->sin6_family = AF_INET6;
+ memcpy(&addr6->sin6_addr, data, 16);
+ ai->ai_addr = reinterpret_cast<struct sockaddr*>(addr6);
+
+ return AddressList(new Data(ai, false /*is_system_created*/));
+}
+
AddressList::Data::Data(struct addrinfo* ai, bool is_system_created)
: head(ai), is_system_created(is_system_created) {
DCHECK(head);
diff --git a/net/base/address_list.h b/net/base/address_list.h
index 1ca86a1..996d871 100644
--- a/net/base/address_list.h
+++ b/net/base/address_list.h
@@ -9,7 +9,6 @@
#include <string>
#include "base/ref_counted.h"
-#include "net/base/net_util.h"
struct addrinfo;
@@ -22,11 +21,6 @@ class AddressList {
// Constructs an empty address list.
AddressList() {}
- // Constructs an address list for a single IP literal. If
- // |canonicalize_name| is true, fill the ai_canonname field with the
- // canonicalized IP address.
- AddressList(const IPAddressNumber& address, int port, bool canonicalize_name);
-
// Adopt the given addrinfo list in place of the existing one if any. This
// hands over responsibility for freeing the addrinfo list to the AddressList
// object.
@@ -66,6 +60,20 @@ class AddressList {
// empty state as when first constructed.
void Reset();
+ // Used by unit-tests to manually create an IPv4 AddressList. |data| should
+ // be an IPv4 address in network order (big endian).
+ // If |canonical_name| is non-empty, it will be duplicated in the
+ // ai_canonname field of the addrinfo struct.
+ static AddressList CreateIPv4Address(unsigned char data[4],
+ const std::string& canonical_name);
+
+ // Used by unit-tests to manually create an IPv6 AddressList. |data| should
+ // be an IPv6 address in network order (big endian).
+ // If |canonical_name| is non-empty, it will be duplicated in the
+ // ai_canonname field of the addrinfo struct.
+ static AddressList CreateIPv6Address(unsigned char data[16],
+ const std::string& canonical_name);
+
// Get access to the head of the addrinfo list.
const struct addrinfo* head() const { return data_->head; }
diff --git a/net/base/address_list_unittest.cc b/net/base/address_list_unittest.cc
index 7386dc9..6e38c7d 100644
--- a/net/base/address_list_unittest.cc
+++ b/net/base/address_list_unittest.cc
@@ -16,8 +16,9 @@
namespace {
// Use getaddrinfo() to allocate an addrinfo structure.
-int CreateAddressList(const std::string& hostname, int port,
- net::AddressList* addrlist) {
+void CreateAddressList(const std::string& hostname,
+ int port,
+ net::AddressList* addrlist) {
#if defined(OS_WIN)
net::EnsureWinsockInit();
#endif
@@ -25,21 +26,20 @@ int CreateAddressList(const std::string& hostname, int port,
net::ADDRESS_FAMILY_UNSPECIFIED,
0,
addrlist, NULL);
- if (rv == 0)
- addrlist->SetPort(port);
- return rv;
+ EXPECT_EQ(0, rv);
+ addrlist->SetPort(port);
}
void CreateLongAddressList(net::AddressList* addrlist, int port) {
- EXPECT_EQ(0, CreateAddressList("192.168.1.1", port, addrlist));
+ CreateAddressList("192.168.1.1", port, addrlist);
net::AddressList second_list;
- EXPECT_EQ(0, CreateAddressList("192.168.1.2", port, &second_list));
+ CreateAddressList("192.168.1.2", port, &second_list);
addrlist->Append(second_list.head());
}
TEST(AddressListTest, GetPort) {
net::AddressList addrlist;
- EXPECT_EQ(0, CreateAddressList("192.168.1.1", 81, &addrlist));
+ CreateAddressList("192.168.1.1", 81, &addrlist);
EXPECT_EQ(81, addrlist.GetPort());
addrlist.SetPort(83);
@@ -48,7 +48,7 @@ TEST(AddressListTest, GetPort) {
TEST(AddressListTest, Assignment) {
net::AddressList addrlist1;
- EXPECT_EQ(0, CreateAddressList("192.168.1.1", 85, &addrlist1));
+ CreateAddressList("192.168.1.1", 85, &addrlist1);
EXPECT_EQ(85, addrlist1.GetPort());
// Should reference the same data as addrlist1 -- so when we change addrlist1
@@ -107,10 +107,10 @@ TEST(AddressListTest, CopyNonRecursive) {
TEST(AddressListTest, Append) {
net::AddressList addrlist1;
- EXPECT_EQ(0, CreateAddressList("192.168.1.1", 11, &addrlist1));
+ CreateAddressList("192.168.1.1", 11, &addrlist1);
EXPECT_EQ(11, addrlist1.GetPort());
net::AddressList addrlist2;
- EXPECT_EQ(0, CreateAddressList("192.168.1.2", 12, &addrlist2));
+ CreateAddressList("192.168.1.2", 12, &addrlist2);
EXPECT_EQ(12, addrlist2.GetPort());
ASSERT_TRUE(addrlist1.head()->ai_next == NULL);
@@ -172,44 +172,4 @@ TEST(AddressListTest, Canonical) {
EXPECT_EQ("blah", canon_name3);
}
-TEST(AddressListTest, IPLiteralConstructor) {
- struct TestData {
- std::string ip_address;
- std::string canonical_ip_address;
- bool is_ipv6;
- } tests[] = {
- { "127.0.00.1", "127.0.0.1", false },
- { "192.168.1.1", "192.168.1.1", false },
- { "::1", "::1", true },
- { "2001:db8:0::42", "2001:db8::42", true },
- };
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); i++) {
- net::AddressList expected_list;
- int rv = CreateAddressList(tests[i].ip_address, 80, &expected_list);
- if (tests[i].is_ipv6 && rv != 0) {
- LOG(WARNING) << "Unable to resolve ip literal '" << tests[i].ip_address
- << "' test skipped.";
- continue;
- }
- ASSERT_EQ(0, rv);
- const struct addrinfo* good_ai = expected_list.head();
-
- net::IPAddressNumber ip_number;
- net::ParseIPLiteralToNumber(tests[i].ip_address, &ip_number);
- net::AddressList test_list(ip_number, 80, true);
- const struct addrinfo* test_ai = test_list.head();
-
- EXPECT_EQ(good_ai->ai_family, test_ai->ai_family);
- EXPECT_EQ(good_ai->ai_socktype, test_ai->ai_socktype);
- EXPECT_EQ(good_ai->ai_addrlen, test_ai->ai_addrlen);
- size_t sockaddr_size =
- good_ai->ai_socktype == AF_INET ? sizeof(struct sockaddr_in) :
- good_ai->ai_socktype == AF_INET6 ? sizeof(struct sockaddr_in6) : 0;
- EXPECT_EQ(memcmp(good_ai->ai_addr, test_ai->ai_addr, sockaddr_size), 0);
- EXPECT_EQ(good_ai->ai_next, test_ai->ai_next);
- EXPECT_EQ(strcmp(tests[i].canonical_ip_address.c_str(),
- test_ai->ai_canonname), 0);
- }
-}
-
} // namespace
diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc
index 11d9306..aa1ed9c 100644
--- a/net/base/host_resolver_impl.cc
+++ b/net/base/host_resolver_impl.cc
@@ -754,6 +754,8 @@ HostResolverImpl::~HostResolverImpl() {
delete job_pools_[i];
}
+// TODO(eroman): Don't create cache entries for hostnames which are simply IP
+// address literals.
int HostResolverImpl::Resolve(const RequestInfo& info,
AddressList* addresses,
CompletionCallback* callback,
@@ -770,23 +772,6 @@ int HostResolverImpl::Resolve(const RequestInfo& info,
// Update the net log and notify registered observers.
OnStartRequest(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(net_log, request_id, info, OK,
- 0, /* os_error (unknown since from cache) */
- false /* was_from_cache */);
- return OK;
- }
-
// Build a key that identifies the request in the cache and in the
// outstanding jobs map.
Key key = GetEffectiveKeyForRequest(info);
diff --git a/net/base/host_resolver_impl_unittest.cc b/net/base/host_resolver_impl_unittest.cc
index a3b863d..be0e2cb 100644
--- a/net/base/host_resolver_impl_unittest.cc
+++ b/net/base/host_resolver_impl_unittest.cc
@@ -399,6 +399,11 @@ TEST_F(HostResolverImplTest, NumericIPv6Address) {
const int kPortnum = 5555;
HostResolver::RequestInfo info("2001:db8::1", kPortnum);
int err = host_resolver->Resolve(info, &adrlist, NULL, NULL, BoundNetLog());
+ // On computers without IPv6 support, getaddrinfo cannot convert IPv6
+ // address literals to addresses (getaddrinfo returns EAI_NONAME). So this
+ // test has to allow host_resolver->Resolve to fail.
+ if (err == ERR_NAME_NOT_RESOLVED)
+ return;
EXPECT_EQ(OK, err);
const struct addrinfo* ainfo = adrlist.head();
diff --git a/net/base/mock_host_resolver.cc b/net/base/mock_host_resolver.cc
index 543c3a8..8d1fd89 100644
--- a/net/base/mock_host_resolver.cc
+++ b/net/base/mock_host_resolver.cc
@@ -9,7 +9,6 @@
#include "base/ref_counted.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
-#include "net/base/sys_addrinfo.h"
namespace net {
@@ -28,10 +27,15 @@ int CreateIPAddress(const std::string& host,
return ERR_UNEXPECTED;
}
- AddressList result(ip_number, -1, false);
- struct addrinfo* ai = const_cast<struct addrinfo*>(result.head());
- ai->ai_canonname = strdup(canonical_name.c_str());
- *addrlist = result;
+ if (ip_number.size() == 4) {
+ *addrlist = AddressList::CreateIPv4Address(&ip_number[0], canonical_name);
+ } else if (ip_number.size() == 16) {
+ *addrlist = AddressList::CreateIPv6Address(&ip_number[0], canonical_name);
+ } else {
+ NOTREACHED();
+ return ERR_UNEXPECTED;
+ }
+
return OK;
}
@@ -157,10 +161,6 @@ void RuleBasedHostResolverProc::AddIPLiteralRule(
const std::string& host_pattern,
const std::string& ip_literal,
const std::string& canonical_name) {
- // Literals are always resolved to themselves by HostResolverImpl,
- // consequently we do not support remapping them.
- IPAddressNumber ip_number;
- DCHECK(!ParseIPLiteralToNumber(host_pattern, &ip_number));
Rule rule(Rule::kResolverTypeIPLiteral,
host_pattern,
ADDRESS_FAMILY_UNSPECIFIED,
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index 1131c0c..c242db1 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -257,6 +257,9 @@ TEST_F(SSLClientSocketTest, Read) {
net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
int rv = resolver_->Resolve(info, &addr, &callback, NULL, net::BoundNetLog());
+ EXPECT_EQ(net::ERR_IO_PENDING, rv);
+
+ rv = callback.WaitForResult();
EXPECT_EQ(net::OK, rv);
net::ClientSocket* transport = new net::TCPClientSocket(addr, NULL);
@@ -316,6 +319,9 @@ TEST_F(SSLClientSocketTest, Read_FullDuplex) {
net::HostResolver::RequestInfo info(server_.kHostName, server_.kOKHTTPSPort);
int rv = resolver_->Resolve(info, &addr, &callback, NULL, net::BoundNetLog());
+ EXPECT_EQ(net::ERR_IO_PENDING, rv);
+
+ rv = callback.WaitForResult();
EXPECT_EQ(net::OK, rv);
net::ClientSocket* transport = new net::TCPClientSocket(addr, NULL);