diff options
author | vandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-17 18:00:02 +0000 |
---|---|---|
committer | vandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-17 18:00:02 +0000 |
commit | fc21277e73baabd1fb1fd02cc1d3cf228aa8512a (patch) | |
tree | 18549e02ef7d938c85c8074ecf81578733ccf748 | |
parent | 2aa021282aa83a7493bc72677ffe83a8e5183892 (diff) | |
download | chromium_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.cc | 2 | ||||
-rw-r--r-- | net/base/address_list.cc | 91 | ||||
-rw-r--r-- | net/base/address_list.h | 20 | ||||
-rw-r--r-- | net/base/address_list_unittest.cc | 62 | ||||
-rw-r--r-- | net/base/host_resolver_impl.cc | 19 | ||||
-rw-r--r-- | net/base/host_resolver_impl_unittest.cc | 5 | ||||
-rw-r--r-- | net/base/mock_host_resolver.cc | 18 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_unittest.cc | 6 |
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); |