diff options
author | szym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-07 21:44:56 +0000 |
---|---|---|
committer | szym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-07 21:44:56 +0000 |
commit | 7054e78fe6a2fcda72b06dc196b5f91cfdc75872 (patch) | |
tree | 2efdd9b07a784a17905d737df9b762d88a6cd1c4 /net/socket | |
parent | cd46545164adf645d744f3955b256cf89412cdc6 (diff) | |
download | chromium_src-7054e78fe6a2fcda72b06dc196b5f91cfdc75872.zip chromium_src-7054e78fe6a2fcda72b06dc196b5f91cfdc75872.tar.gz chromium_src-7054e78fe6a2fcda72b06dc196b5f91cfdc75872.tar.bz2 |
Reimplements net::AddressList without struct addrinfo.
net::AddressList extends std::vector<std::IPEndPoint> by canonical name. (Canonical name is planned to be removed as well.)
Removes dependency on sys_addrinfo.h throughout the codebase.
Introduces net::SockaddrStorage for convenience.
BUG=125696
TEST=green waterfall
Review URL: http://codereview.chromium.org/10309002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135731 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket')
-rw-r--r-- | net/socket/socket_test_util.h | 2 | ||||
-rw-r--r-- | net/socket/socks5_client_socket.cc | 1 | ||||
-rw-r--r-- | net/socket/socks5_client_socket_unittest.cc | 1 | ||||
-rw-r--r-- | net/socket/socks_client_socket.cc | 14 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_mac.cc | 6 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 13 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_pool_unittest.cc | 7 | ||||
-rw-r--r-- | net/socket/tcp_client_socket_libevent.cc | 80 | ||||
-rw-r--r-- | net/socket/tcp_client_socket_libevent.h | 6 | ||||
-rw-r--r-- | net/socket/tcp_client_socket_unittest.cc | 13 | ||||
-rw-r--r-- | net/socket/tcp_client_socket_win.cc | 50 | ||||
-rw-r--r-- | net/socket/tcp_client_socket_win.h | 6 | ||||
-rw-r--r-- | net/socket/tcp_server_socket_libevent.cc | 31 | ||||
-rw-r--r-- | net/socket/tcp_server_socket_unittest.cc | 9 | ||||
-rw-r--r-- | net/socket/tcp_server_socket_win.cc | 29 | ||||
-rw-r--r-- | net/socket/transport_client_socket_pool.cc | 68 | ||||
-rw-r--r-- | net/socket/transport_client_socket_pool.h | 9 | ||||
-rw-r--r-- | net/socket/transport_client_socket_pool_unittest.cc | 119 |
18 files changed, 193 insertions, 271 deletions
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h index d54e2ac..a0d0c65 100644 --- a/net/socket/socket_test_util.h +++ b/net/socket/socket_test_util.h @@ -627,7 +627,7 @@ class MockTCPClientSocket : public MockClientSocket, public AsyncSocket { SocketDataProvider* socket); virtual ~MockTCPClientSocket(); - AddressList addresses() const { return addresses_; } + const AddressList& addresses() const { return addresses_; } // Socket implementation. virtual int Read(IOBuffer* buf, int buf_len, diff --git a/net/socket/socks5_client_socket.cc b/net/socket/socks5_client_socket.cc index dd75a4d..5475313 100644 --- a/net/socket/socks5_client_socket.cc +++ b/net/socket/socks5_client_socket.cc @@ -13,7 +13,6 @@ #include "net/base/io_buffer.h" #include "net/base/net_log.h" #include "net/base/net_util.h" -#include "net/base/sys_addrinfo.h" #include "net/socket/client_socket_handle.h" namespace net { diff --git a/net/socket/socks5_client_socket_unittest.cc b/net/socket/socks5_client_socket_unittest.cc index 39c86bf..b5fce50 100644 --- a/net/socket/socks5_client_socket_unittest.cc +++ b/net/socket/socks5_client_socket_unittest.cc @@ -13,7 +13,6 @@ #include "net/base/net_log.h" #include "net/base/net_log_unittest.h" #include "net/base/mock_host_resolver.h" -#include "net/base/sys_addrinfo.h" #include "net/base/test_completion_callback.h" #include "net/base/winsock_init.h" #include "net/socket/client_socket_factory.h" diff --git a/net/socket/socks_client_socket.cc b/net/socket/socks_client_socket.cc index 01983d9..025d1aa 100644 --- a/net/socket/socks_client_socket.cc +++ b/net/socket/socks_client_socket.cc @@ -11,7 +11,6 @@ #include "net/base/io_buffer.h" #include "net/base/net_log.h" #include "net/base/net_util.h" -#include "net/base/sys_addrinfo.h" #include "net/socket/client_socket_handle.h" namespace net { @@ -307,20 +306,19 @@ const std::string SOCKSClientSocket::BuildHandshakeWriteBuffer() const { request.command = kSOCKSStreamRequest; request.nw_port = base::HostToNet16(host_request_info_.port()); - const struct addrinfo* ai = addresses_.head(); - DCHECK(ai); + DCHECK(!addresses_.empty()); + const IPEndPoint& endpoint = addresses_.front(); // We disabled IPv6 results when resolving the hostname, so none of the // results in the list will be IPv6. // TODO(eroman): we only ever use the first address in the list. It would be // more robust to try all the IP addresses we have before // failing the connect attempt. - CHECK_EQ(AF_INET, ai->ai_addr->sa_family); - struct sockaddr_in* ipv4_host = - reinterpret_cast<struct sockaddr_in*>(ai->ai_addr); - memcpy(&request.ip, &ipv4_host->sin_addr, sizeof(ipv4_host->sin_addr)); + CHECK_EQ(AF_INET, endpoint.GetFamily()); + CHECK_LE(endpoint.address().size(), sizeof(request.ip)); + memcpy(&request.ip, &endpoint.address()[0], endpoint.address().size()); - DVLOG(1) << "Resolved Host is : " << NetAddressToString(ai); + DVLOG(1) << "Resolved Host is : " << endpoint.ToStringWithoutPort(); std::string handshake_data(reinterpret_cast<char*>(&request), sizeof(request)); diff --git a/net/socket/ssl_client_socket_mac.cc b/net/socket/ssl_client_socket_mac.cc index e847c15..f84f3fb 100644 --- a/net/socket/ssl_client_socket_mac.cc +++ b/net/socket/ssl_client_socket_mac.cc @@ -880,10 +880,10 @@ int SSLClientSocketMac::InitializeSSLContext() { int rv = transport_->socket()->GetPeerAddress(&address); if (rv != OK) return rv; - const struct addrinfo* ai = address.head(); + const IPEndPoint& endpoint = address.front(); std::string peer_id(host_and_port_.ToString()); - peer_id += std::string(reinterpret_cast<char*>(ai->ai_addr), - ai->ai_addrlen); + peer_id += std::string(reinterpret_cast<const char*>(&endpoint.address()[0]), + endpoint.address().size()); // SSLSetPeerID() treats peer_id as a binary blob, and makes its // own copy. status = SSLSetPeerID(ssl_context_, peer_id.data(), peer_id.length()); diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index b70365d..2a824f4 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -94,7 +94,6 @@ #include "net/base/ssl_cert_request_info.h" #include "net/base/ssl_connection_status_flags.h" #include "net/base/ssl_info.h" -#include "net/base/sys_addrinfo.h" #include "net/base/x509_certificate_net_log_param.h" #include "net/ocsp/nss_ocsp.h" #include "net/socket/client_socket_handle.h" @@ -1023,20 +1022,22 @@ int SSLClientSocketNSS::InitializeSSLPeerName() { if (err != OK) return err; - const struct addrinfo* ai = peer_address.head(); + SockaddrStorage storage; + if (!peer_address.front().ToSockAddr(storage.addr, &storage.addr_len)) + return ERR_UNEXPECTED; PRNetAddr peername; memset(&peername, 0, sizeof(peername)); - DCHECK_LE(ai->ai_addrlen, sizeof(peername)); - size_t len = std::min(static_cast<size_t>(ai->ai_addrlen), + DCHECK_LE(static_cast<size_t>(storage.addr_len), sizeof(peername)); + size_t len = std::min(static_cast<size_t>(storage.addr_len), sizeof(peername)); - memcpy(&peername, ai->ai_addr, len); + memcpy(&peername, storage.addr, len); // Adjust the address family field for BSD, whose sockaddr // structure has a one-byte length and one-byte address family // field at the beginning. PRNetAddr has a two-byte address // family field at the beginning. - peername.raw.family = ai->ai_addr->sa_family; + peername.raw.family = storage.addr->sa_family; memio_SetPeerName(nss_fd_, &peername); diff --git a/net/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc index 168365d..b841c02 100644 --- a/net/socket/ssl_client_socket_pool_unittest.cc +++ b/net/socket/ssl_client_socket_pool_unittest.cc @@ -14,7 +14,6 @@ #include "net/base/mock_host_resolver.h" #include "net/base/net_errors.h" #include "net/base/ssl_config_service_defaults.h" -#include "net/base/sys_addrinfo.h" #include "net/base/test_certificate_data.h" #include "net/base/test_completion_callback.h" #include "net/http/http_auth_handler_factory.h" @@ -721,9 +720,8 @@ TEST_F(SSLClientSocketPoolTest, IPPooling) { // TODO(rtenneti): MockClientSocket::GetPeerAddress returns 0 as the port // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias. - const addrinfo* address = test_hosts[0].addresses.head(); SpdySessionPoolPeer pool_peer(session_->spdy_session_pool()); - pool_peer.AddAlias(address, test_hosts[0].pair); + pool_peer.AddAlias(test_hosts[0].addresses.front(), test_hosts[0].pair); scoped_refptr<SpdySession> spdy_session; rv = session_->spdy_session_pool()->GetSpdySessionFromSocket( @@ -807,9 +805,8 @@ TEST_F(SSLClientSocketPoolTest, IPPoolingClientCert) { // TODO(rtenneti): MockClientSocket::GetPeerAddress returns 0 as the port // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias. - const addrinfo* address = test_hosts[0].addresses.head(); SpdySessionPoolPeer pool_peer(session_->spdy_session_pool()); - pool_peer.AddAlias(address, test_hosts[0].pair); + pool_peer.AddAlias(test_hosts[0].addresses.front(), test_hosts[0].pair); scoped_refptr<SpdySession> spdy_session; rv = session_->spdy_session_pool()->GetSpdySessionFromSocket( diff --git a/net/socket/tcp_client_socket_libevent.cc b/net/socket/tcp_client_socket_libevent.cc index b17f52f..972d75d 100644 --- a/net/socket/tcp_client_socket_libevent.cc +++ b/net/socket/tcp_client_socket_libevent.cc @@ -127,7 +127,7 @@ TCPClientSocketLibevent::TCPClientSocketLibevent( : socket_(kInvalidSocket), bound_socket_(kInvalidSocket), addresses_(addresses), - current_ai_(NULL), + current_address_index_(-1), read_watcher_(this), write_watcher_(this), next_connect_state_(CONNECT_STATE_NONE), @@ -163,23 +163,21 @@ int TCPClientSocketLibevent::AdoptSocket(int socket) { // This is to make GetPeerAddress() work. It's up to the caller ensure // that |address_| contains a reasonable address for this // socket. (i.e. at least match IPv4 vs IPv6!). - current_ai_ = addresses_.head(); + current_address_index_ = 0; use_history_.set_was_ever_connected(); return OK; } int TCPClientSocketLibevent::Bind(const IPEndPoint& address) { - if (current_ai_ != NULL || bind_address_.get()) { + if (current_address_index_ >= 0 || bind_address_.get()) { // Cannot bind the socket if we are already bound connected or // connecting. return ERR_UNEXPECTED; } - sockaddr_storage addr_storage; - sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); - size_t addr_len = sizeof(addr_storage); - if (!address.ToSockAddr(addr, &addr_len)) + SockaddrStorage storage; + if (!address.ToSockAddr(storage.addr, &storage.addr_len)) return ERR_INVALID_ARGUMENT; // Create |bound_socket_| and try to bound it to |address|. @@ -187,7 +185,7 @@ int TCPClientSocketLibevent::Bind(const IPEndPoint& address) { if (error) return MapSystemError(error); - if (HANDLE_EINTR(bind(bound_socket_, addr, addr_len))) { + if (HANDLE_EINTR(bind(bound_socket_, storage.addr, storage.addr_len))) { error = errno; if (HANDLE_EINTR(close(bound_socket_)) < 0) PLOG(ERROR) << "close"; @@ -219,7 +217,7 @@ int TCPClientSocketLibevent::Connect(const CompletionCallback& callback) { // We will try to connect to each address in addresses_. Start with the // first one in the list. next_connect_state_ = CONNECT_STATE_CONNECT; - current_ai_ = addresses_.head(); + current_address_index_ = 0; int rv = DoConnectLoop(OK); if (rv == ERR_IO_PENDING) { @@ -259,10 +257,12 @@ int TCPClientSocketLibevent::DoConnectLoop(int result) { } int TCPClientSocketLibevent::DoConnect() { - DCHECK(current_ai_); - + DCHECK_GE(current_address_index_, 0); + DCHECK_LT(current_address_index_, static_cast<int>(addresses_.size())); DCHECK_EQ(0, connect_os_error_); + const IPEndPoint& endpoint = addresses_[current_address_index_]; + if (previously_disconnected_) { use_history_.Reset(); previously_disconnected_ = false; @@ -270,7 +270,8 @@ int TCPClientSocketLibevent::DoConnect() { net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, make_scoped_refptr(new NetLogStringParameter( - "address", NetAddressToStringWithPort(current_ai_)))); + "address", + endpoint.ToString()))); next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE; @@ -280,26 +281,27 @@ int TCPClientSocketLibevent::DoConnect() { bound_socket_ = kInvalidSocket; } else { // Create a non-blocking socket. - connect_os_error_ = CreateSocket(current_ai_->ai_family, &socket_); + connect_os_error_ = CreateSocket(endpoint.GetFamily(), &socket_); if (connect_os_error_) return MapSystemError(connect_os_error_); if (bind_address_.get()) { - sockaddr_storage addr_storage; - sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); - size_t addr_len = sizeof(addr_storage); - if (!bind_address_->ToSockAddr(addr, &addr_len)) + SockaddrStorage storage; + if (!bind_address_->ToSockAddr(storage.addr, &storage.addr_len)) return ERR_INVALID_ARGUMENT; - if (HANDLE_EINTR(bind(socket_, addr, addr_len))) + if (HANDLE_EINTR(bind(socket_, storage.addr, storage.addr_len))) return MapSystemError(errno); } } // Connect the socket. if (!use_tcp_fastopen_) { + SockaddrStorage storage; + if (!endpoint.ToSockAddr(storage.addr, &storage.addr_len)) + return ERR_INVALID_ARGUMENT; + connect_start_time_ = base::TimeTicks::Now(); - if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr, - static_cast<int>(current_ai_->ai_addrlen)))) { + if (!HANDLE_EINTR(connect(socket_, storage.addr, storage.addr_len))) { // Connected without waiting! return OK; } @@ -347,9 +349,9 @@ int TCPClientSocketLibevent::DoConnectComplete(int result) { DoDisconnect(); // Try to fall back to the next address in the list. - if (current_ai_->ai_next) { + if (current_address_index_ + 1 < static_cast<int>(addresses_.size())) { next_connect_state_ = CONNECT_STATE_CONNECT; - current_ai_ = current_ai_->ai_next; + ++current_address_index_; return OK; } @@ -361,7 +363,7 @@ void TCPClientSocketLibevent::Disconnect() { DCHECK(CalledOnValidThread()); DoDisconnect(); - current_ai_ = NULL; + current_address_index_ = -1; } void TCPClientSocketLibevent::DoDisconnect() { @@ -389,7 +391,7 @@ bool TCPClientSocketLibevent::IsConnected() const { // This allows GetPeerAddress() to return current_ai_ as the peer // address. Since we don't fail over to the next address if // sendto() fails, current_ai_ is the only possible peer address. - CHECK(current_ai_); + CHECK_LT(current_address_index_, static_cast<int>(addresses_.size())); return true; } @@ -505,6 +507,12 @@ int TCPClientSocketLibevent::Write(IOBuffer* buf, int TCPClientSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) { int nwrite; if (use_tcp_fastopen_ && !tcp_fastopen_connected_) { + SockaddrStorage storage; + if (!addresses_[current_address_index_].ToSockAddr(storage.addr, + &storage.addr_len)) { + return ERR_INVALID_ARGUMENT; + } + // We have a limited amount of data to send in the SYN packet. int kMaxFastOpenSendLength = 1420; @@ -515,8 +523,8 @@ int TCPClientSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) { buf->data(), buf_len, flags, - current_ai_->ai_addr, - static_cast<int>(current_ai_->ai_addrlen))); + storage.addr, + storage.addr_len)); tcp_fastopen_connected_ = true; if (nwrite < 0) { @@ -561,10 +569,8 @@ void TCPClientSocketLibevent::LogConnectCompletion(int net_error) { return; } - struct sockaddr_storage source_address; - socklen_t addrlen = sizeof(source_address); - int rv = getsockname( - socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen); + SockaddrStorage storage; + int rv = getsockname(socket_, storage.addr, &storage.addr_len); if (rv != 0) { PLOG(ERROR) << "getsockname() [rv: " << rv << "] error: "; NOTREACHED(); @@ -573,9 +579,7 @@ void TCPClientSocketLibevent::LogConnectCompletion(int net_error) { } const std::string source_address_str = - NetAddressToStringWithPort( - reinterpret_cast<const struct sockaddr*>(&source_address), - sizeof(source_address)); + NetAddressToStringWithPort(storage.addr, storage.addr_len); net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, make_scoped_refptr(new NetLogStringParameter( "source address", @@ -684,7 +688,7 @@ int TCPClientSocketLibevent::GetPeerAddress(AddressList* address) const { DCHECK(address); if (!IsConnected()) return ERR_SOCKET_NOT_CONNECTED; - *address = AddressList::CreateByCopyingFirstAddress(current_ai_); + *address = AddressList(addresses_[current_address_index_]); return OK; } @@ -694,12 +698,10 @@ int TCPClientSocketLibevent::GetLocalAddress(IPEndPoint* address) const { if (!IsConnected()) return ERR_SOCKET_NOT_CONNECTED; - struct sockaddr_storage addr_storage; - socklen_t addr_len = sizeof(addr_storage); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); - if (getsockname(socket_, addr, &addr_len)) + SockaddrStorage storage; + if (getsockname(socket_, storage.addr, &storage.addr_len)) return MapSystemError(errno); - if (!address->FromSockAddr(addr, addr_len)) + if (!address->FromSockAddr(storage.addr, storage.addr_len)) return ERR_FAILED; return OK; diff --git a/net/socket/tcp_client_socket_libevent.h b/net/socket/tcp_client_socket_libevent.h index 5519f3c..b984649 100644 --- a/net/socket/tcp_client_socket_libevent.h +++ b/net/socket/tcp_client_socket_libevent.h @@ -123,7 +123,7 @@ class NET_EXPORT_PRIVATE TCPClientSocketLibevent : public StreamSocket, int DoConnectComplete(int result); // Helper used by Disconnect(), which disconnects minus the logging and - // resetting of current_ai_. + // resetting of current_address_index_. void DoDisconnect(); void DoReadCallback(int rv); @@ -155,8 +155,8 @@ class NET_EXPORT_PRIVATE TCPClientSocketLibevent : public StreamSocket, // The list of addresses we should try in order to establish a connection. AddressList addresses_; - // Where we are in above list, or NULL if all addrinfos have been tried. - const struct addrinfo* current_ai_; + // Where we are in above list. Set to -1 if uninitialized. + int current_address_index_; // The socket's libevent wrappers MessageLoopForIO::FileDescriptorWatcher read_socket_watcher_; diff --git a/net/socket/tcp_client_socket_unittest.cc b/net/socket/tcp_client_socket_unittest.cc index 991b645..c2589b8 100644 --- a/net/socket/tcp_client_socket_unittest.cc +++ b/net/socket/tcp_client_socket_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -11,7 +11,6 @@ #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" #include "net/base/net_util.h" -#include "net/base/sys_addrinfo.h" #include "net/base/test_completion_callback.h" #include "net/socket/tcp_server_socket.h" #include "testing/gtest/include/gtest/gtest.h" @@ -31,10 +30,7 @@ TEST(TCPClientSocketTest, BindLoopbackToLoopback) { IPEndPoint server_address; ASSERT_EQ(OK, server.GetLocalAddress(&server_address)); - TCPClientSocket socket( - AddressList::CreateFromIPAddress(server_address.address(), - server_address.port()), - NULL, NetLog::Source()); + TCPClientSocket socket(AddressList(server_address), NULL, NetLog::Source()); EXPECT_EQ(OK, socket.Bind(IPEndPoint(lo_address, 0))); @@ -88,10 +84,7 @@ TEST(TCPClientSocketTest, BindLoopbackToIPv6) { IPEndPoint server_address; ASSERT_EQ(OK, server.GetLocalAddress(&server_address)); - TCPClientSocket socket( - AddressList::CreateFromIPAddress(server_address.address(), - server_address.port()), - NULL, NetLog::Source()); + TCPClientSocket socket(AddressList(server_address), NULL, NetLog::Source()); IPAddressNumber ipv4_lo_ip; ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ipv4_lo_ip)); diff --git a/net/socket/tcp_client_socket_win.cc b/net/socket/tcp_client_socket_win.cc index 28b0eef..4990887 100644 --- a/net/socket/tcp_client_socket_win.cc +++ b/net/socket/tcp_client_socket_win.cc @@ -20,7 +20,6 @@ #include "net/base/net_log.h" #include "net/base/net_util.h" #include "net/base/network_change_notifier.h" -#include "net/base/sys_addrinfo.h" #include "net/base/winsock_init.h" #include "net/base/winsock_util.h" @@ -317,7 +316,7 @@ TCPClientSocketWin::TCPClientSocketWin(const AddressList& addresses, : socket_(INVALID_SOCKET), bound_socket_(INVALID_SOCKET), addresses_(addresses), - current_ai_(NULL), + current_address_index_(-1), waiting_read_(false), waiting_write_(false), next_connect_state_(CONNECT_STATE_NONE), @@ -349,22 +348,20 @@ int TCPClientSocketWin::AdoptSocket(SOCKET socket) { core_ = new Core(this); - current_ai_ = addresses_.head(); + current_address_index_ = 0; use_history_.set_was_ever_connected(); return OK; } int TCPClientSocketWin::Bind(const IPEndPoint& address) { - if (current_ai_ != NULL || bind_address_.get()) { + if (current_address_index_ >= 0 || bind_address_.get()) { // Cannot bind the socket if we are already connected or connecting. return ERR_UNEXPECTED; } - sockaddr_storage addr_storage; - sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); - size_t addr_len = sizeof(addr_storage); - if (!address.ToSockAddr(addr, &addr_len)) + SockaddrStorage storage; + if (!address.ToSockAddr(storage.addr, &storage.addr_len)) return ERR_INVALID_ARGUMENT; // Create |bound_socket_| and try to bound it to |address|. @@ -372,7 +369,7 @@ int TCPClientSocketWin::Bind(const IPEndPoint& address) { if (error) return MapSystemError(error); - if (bind(bound_socket_, addr, addr_len)) { + if (bind(bound_socket_, storage.addr, storage.addr_len)) { error = errno; if (closesocket(bound_socket_) < 0) PLOG(ERROR) << "closesocket"; @@ -402,7 +399,7 @@ int TCPClientSocketWin::Connect(const CompletionCallback& callback) { // We will try to connect to each address in addresses_. Start with the // first one in the list. next_connect_state_ = CONNECT_STATE_CONNECT; - current_ai_ = addresses_.head(); + current_address_index_ = 0; int rv = DoConnectLoop(OK); if (rv == ERR_IO_PENDING) { @@ -443,18 +440,20 @@ int TCPClientSocketWin::DoConnectLoop(int result) { } int TCPClientSocketWin::DoConnect() { - const struct addrinfo* ai = current_ai_; - DCHECK(ai); + DCHECK_GE(current_address_index_, 0); + DCHECK_LT(current_address_index_, static_cast<int>(addresses_.size())); DCHECK_EQ(0, connect_os_error_); + const IPEndPoint& endpoint = addresses_[current_address_index_]; + if (previously_disconnected_) { use_history_.Reset(); previously_disconnected_ = false; } net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, - new NetLogStringParameter( - "address", NetAddressToStringWithPort(current_ai_))); + new NetLogStringParameter("address", + endpoint.ToString())); next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE; @@ -463,17 +462,15 @@ int TCPClientSocketWin::DoConnect() { socket_ = bound_socket_; bound_socket_ = INVALID_SOCKET; } else { - connect_os_error_ = CreateSocket(ai->ai_family, &socket_); + connect_os_error_ = CreateSocket(endpoint.GetFamily(), &socket_); if (connect_os_error_ != 0) return MapSystemError(connect_os_error_); if (bind_address_.get()) { - sockaddr_storage addr_storage; - sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); - size_t addr_len = sizeof(addr_storage); - if (!bind_address_->ToSockAddr(addr, &addr_len)) + SockaddrStorage storage; + if (!bind_address_->ToSockAddr(storage.addr, &storage.addr_len)) return ERR_INVALID_ARGUMENT; - if (bind(socket_, addr, addr_len)) + if (bind(socket_, storage.addr, storage.addr_len)) return MapSystemError(errno); } } @@ -484,8 +481,11 @@ int TCPClientSocketWin::DoConnect() { // Our connect() and recv() calls require that the socket be non-blocking. WSAEventSelect(socket_, core_->read_overlapped_.hEvent, FD_CONNECT); + SockaddrStorage storage; + if (!endpoint.ToSockAddr(storage.addr, &storage.addr_len)) + return ERR_INVALID_ARGUMENT; connect_start_time_ = base::TimeTicks::Now(); - if (!connect(socket_, ai->ai_addr, static_cast<int>(ai->ai_addrlen))) { + if (!connect(socket_, storage.addr, storage.addr_len)) { // Connected without waiting! // // The MSDN page for connect says: @@ -532,9 +532,9 @@ int TCPClientSocketWin::DoConnectComplete(int result) { DoDisconnect(); // Try to fall back to the next address in the list. - if (current_ai_->ai_next) { + if (current_address_index_ + 1 < static_cast<int>(addresses_.size())) { next_connect_state_ = CONNECT_STATE_CONNECT; - current_ai_ = current_ai_->ai_next; + ++current_address_index_; return OK; } @@ -544,7 +544,7 @@ int TCPClientSocketWin::DoConnectComplete(int result) { void TCPClientSocketWin::Disconnect() { DoDisconnect(); - current_ai_ = NULL; + current_address_index_ = -1; } void TCPClientSocketWin::DoDisconnect() { @@ -629,7 +629,7 @@ int TCPClientSocketWin::GetPeerAddress(AddressList* address) const { DCHECK(address); if (!IsConnected()) return ERR_SOCKET_NOT_CONNECTED; - *address = AddressList::CreateByCopyingFirstAddress(current_ai_); + *address = AddressList(addresses_[current_address_index_]); return OK; } diff --git a/net/socket/tcp_client_socket_win.h b/net/socket/tcp_client_socket_win.h index 9fffab8..c17a0b9 100644 --- a/net/socket/tcp_client_socket_win.h +++ b/net/socket/tcp_client_socket_win.h @@ -84,7 +84,7 @@ class NET_EXPORT TCPClientSocketWin : public StreamSocket, int DoConnectComplete(int result); // Helper used by Disconnect(), which disconnects minus the logging and - // resetting of current_ai_. + // resetting of current_address_index_. void DoDisconnect(); // Returns true if a Connect() is in progress. @@ -113,8 +113,8 @@ class NET_EXPORT TCPClientSocketWin : public StreamSocket, // The list of addresses we should try in order to establish a connection. AddressList addresses_; - // Where we are in above list, or NULL if all addrinfos have been tried. - const struct addrinfo* current_ai_; + // Where we are in above list. Set to -1 if uninitialized. + int current_address_index_; // The various states that the socket could be in. bool waiting_read_; diff --git a/net/socket/tcp_server_socket_libevent.cc b/net/socket/tcp_server_socket_libevent.cc index 904256a..34b8283 100644 --- a/net/socket/tcp_server_socket_libevent.cc +++ b/net/socket/tcp_server_socket_libevent.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -64,13 +64,11 @@ int TCPServerSocketLibevent::Listen(const IPEndPoint& address, int backlog) { return result; } - struct sockaddr_storage addr_storage; - size_t addr_len = sizeof(addr_storage); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); - if (!address.ToSockAddr(addr, &addr_len)) + SockaddrStorage storage; + if (!address.ToSockAddr(storage.addr, &storage.addr_len)) return ERR_INVALID_ARGUMENT; - int result = bind(socket_, addr, addr_len); + int result = bind(socket_, storage.addr, storage.addr_len); if (result < 0) { PLOG(ERROR) << "bind() returned an error"; result = MapSystemError(errno); @@ -93,12 +91,10 @@ int TCPServerSocketLibevent::GetLocalAddress(IPEndPoint* address) const { DCHECK(CalledOnValidThread()); DCHECK(address); - struct sockaddr_storage addr_storage; - socklen_t addr_len = sizeof(addr_storage); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); - if (getsockname(socket_, addr, &addr_len) < 0) + SockaddrStorage storage; + if (getsockname(socket_, storage.addr, &storage.addr_len) < 0) return MapSystemError(errno); - if (!address->FromSockAddr(addr, addr_len)) + if (!address->FromSockAddr(storage.addr, storage.addr_len)) return ERR_FAILED; return OK; @@ -132,11 +128,10 @@ int TCPServerSocketLibevent::Accept( int TCPServerSocketLibevent::AcceptInternal( scoped_ptr<StreamSocket>* socket) { - struct sockaddr_storage addr_storage; - socklen_t addr_len = sizeof(addr_storage); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); - - int new_socket = HANDLE_EINTR(accept(socket_, addr, &addr_len)); + SockaddrStorage storage; + int new_socket = HANDLE_EINTR(accept(socket_, + storage.addr, + &storage.addr_len)); if (new_socket < 0) { int net_error = MapSystemError(errno); if (net_error != ERR_IO_PENDING) @@ -145,7 +140,7 @@ int TCPServerSocketLibevent::AcceptInternal( } IPEndPoint address; - if (!address.FromSockAddr(addr, addr_len)) { + if (!address.FromSockAddr(storage.addr, storage.addr_len)) { NOTREACHED(); if (HANDLE_EINTR(close(new_socket)) < 0) PLOG(ERROR) << "close"; @@ -153,7 +148,7 @@ int TCPServerSocketLibevent::AcceptInternal( return ERR_FAILED; } scoped_ptr<TCPClientSocket> tcp_socket(new TCPClientSocket( - AddressList::CreateFromIPAddress(address.address(), address.port()), + AddressList(address), net_log_.net_log(), net_log_.source())); int adopt_result = tcp_socket->AdoptSocket(new_socket); if (adopt_result != OK) { diff --git a/net/socket/tcp_server_socket_unittest.cc b/net/socket/tcp_server_socket_unittest.cc index 9307297..a384b70 100644 --- a/net/socket/tcp_server_socket_unittest.cc +++ b/net/socket/tcp_server_socket_unittest.cc @@ -14,7 +14,6 @@ #include "net/base/io_buffer.h" #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" -#include "net/base/sys_addrinfo.h" #include "net/base/test_completion_callback.h" #include "net/socket/tcp_client_socket.h" #include "testing/gtest/include/gtest/gtest.h" @@ -62,15 +61,11 @@ class TCPServerSocketTest : public PlatformTest { static IPEndPoint GetPeerAddress(StreamSocket* socket) { AddressList address; EXPECT_EQ(OK, socket->GetPeerAddress(&address)); - IPEndPoint endpoint; - EXPECT_TRUE(endpoint.FromSockAddr( - address.head()->ai_addr, address.head()->ai_addrlen)); - return endpoint; + return address.front(); } AddressList local_address_list() const { - return AddressList::CreateFromIPAddress( - local_address_.address(), local_address_.port()); + return AddressList(local_address_); } TCPServerSocket socket_; diff --git a/net/socket/tcp_server_socket_win.cc b/net/socket/tcp_server_socket_win.cc index 7e5cf4d..5b88233 100644 --- a/net/socket/tcp_server_socket_win.cc +++ b/net/socket/tcp_server_socket_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -57,13 +57,11 @@ int TCPServerSocketWin::Listen(const IPEndPoint& address, int backlog) { return result; } - struct sockaddr_storage addr_storage; - size_t addr_len = sizeof(addr_storage); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); - if (!address.ToSockAddr(addr, &addr_len)) + SockaddrStorage storage; + if (!address.ToSockAddr(storage.addr, &storage.addr_len)) return ERR_INVALID_ARGUMENT; - int result = bind(socket_, addr, addr_len); + int result = bind(socket_, storage.addr, storage.addr_len); if (result < 0) { PLOG(ERROR) << "bind() returned an error"; result = MapSystemError(WSAGetLastError()); @@ -86,12 +84,10 @@ int TCPServerSocketWin::GetLocalAddress(IPEndPoint* address) const { DCHECK(CalledOnValidThread()); DCHECK(address); - struct sockaddr_storage addr_storage; - socklen_t addr_len = sizeof(addr_storage); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); - if (getsockname(socket_, addr, &addr_len)) + SockaddrStorage storage; + if (getsockname(socket_, storage.addr, &storage.addr_len)) return MapSystemError(WSAGetLastError()); - if (!address->FromSockAddr(addr, addr_len)) + if (!address->FromSockAddr(storage.addr, storage.addr_len)) return ERR_FAILED; return OK; @@ -121,11 +117,8 @@ int TCPServerSocketWin::Accept( } int TCPServerSocketWin::AcceptInternal(scoped_ptr<StreamSocket>* socket) { - struct sockaddr_storage addr_storage; - socklen_t addr_len = sizeof(addr_storage); - struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); - - int new_socket = accept(socket_, addr, &addr_len); + SockaddrStorage storage; + int new_socket = accept(socket_, storage.addr, &storage.addr_len); if (new_socket < 0) { int net_error = MapSystemError(WSAGetLastError()); if (net_error != ERR_IO_PENDING) @@ -134,7 +127,7 @@ int TCPServerSocketWin::AcceptInternal(scoped_ptr<StreamSocket>* socket) { } IPEndPoint address; - if (!address.FromSockAddr(addr, addr_len)) { + if (!address.FromSockAddr(storage.addr, storage.addr_len)) { NOTREACHED(); if (closesocket(new_socket) < 0) PLOG(ERROR) << "closesocket"; @@ -142,7 +135,7 @@ int TCPServerSocketWin::AcceptInternal(scoped_ptr<StreamSocket>* socket) { return ERR_FAILED; } scoped_ptr<TCPClientSocket> tcp_socket(new TCPClientSocket( - AddressList::CreateFromIPAddress(address.address(), address.port()), + AddressList(address), net_log_.net_log(), net_log_.source())); int adopt_result = tcp_socket->AdoptSocket(new_socket); if (adopt_result != OK) { diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc index a00e810..b2ca683 100644 --- a/net/socket/transport_client_socket_pool.cc +++ b/net/socket/transport_client_socket_pool.cc @@ -4,6 +4,8 @@ #include "net/socket/transport_client_socket_pool.h" +#include <algorithm> + #include "base/compiler_specific.h" #include "base/logging.h" #include "base/message_loop.h" @@ -14,7 +16,6 @@ #include "net/base/ip_endpoint.h" #include "net/base/net_log.h" #include "net/base/net_errors.h" -#include "net/base/sys_addrinfo.h" #include "net/socket/client_socket_factory.h" #include "net/socket/client_socket_handle.h" #include "net/socket/client_socket_pool_base.h" @@ -31,28 +32,14 @@ const int TransportConnectJob::kIPv6FallbackTimerInMs = 300; namespace { -bool AddressListStartsWithIPv6AndHasAnIPv4Addr(const AddressList& addrlist) { - const struct addrinfo* ai = addrlist.head(); - if (ai->ai_family != AF_INET6) - return false; - - ai = ai->ai_next; - while (ai) { - if (ai->ai_family != AF_INET6) - return true; - ai = ai->ai_next; - } - - return false; -} - -bool AddressListOnlyContainsIPv6Addresses(const AddressList& addrlist) { - DCHECK(addrlist.head()); - for (const struct addrinfo* ai = addrlist.head(); ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET6) +// Returns true iff all addresses in |list| are in the IPv6 family. +bool AddressListOnlyContainsIPv6(const AddressList& list) { + DCHECK(!list.empty()); + for (AddressList::const_iterator iter = list.begin(); iter != list.end(); + ++iter) { + if (iter->GetFamily() != AF_INET6) return false; } - return true; } @@ -123,35 +110,13 @@ LoadState TransportConnectJob::GetLoadState() const { } // static -void TransportConnectJob::MakeAddrListStartWithIPv4(AddressList* addrlist) { - if (addrlist->head()->ai_family != AF_INET6) - return; - bool has_ipv4 = false; - for (const struct addrinfo* ai = addrlist->head(); ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET6) { - has_ipv4 = true; +void TransportConnectJob::MakeAddressListStartWithIPv4(AddressList* list) { + for (AddressList::iterator i = list->begin(); i != list->end(); ++i) { + if (i->GetFamily() == AF_INET) { + std::rotate(list->begin(), i, list->end()); break; } } - if (!has_ipv4) - return; - - struct addrinfo* head = CreateCopyOfAddrinfo(addrlist->head(), true); - struct addrinfo* tail = head; - while (tail->ai_next) - tail = tail->ai_next; - char* canonname = head->ai_canonname; - head->ai_canonname = NULL; - while (head->ai_family == AF_INET6) { - tail->ai_next = head; - tail = head; - head = head->ai_next; - tail->ai_next = NULL; - } - head->ai_canonname = canonname; - - *addrlist = AddressList::CreateByCopying(head); - FreeCopyOfAddrinfo(head); } void TransportConnectJob::OnIOComplete(int result) { @@ -214,7 +179,8 @@ int TransportConnectJob::DoTransportConnect() { int rv = transport_socket_->Connect( base::Bind(&TransportConnectJob::OnIOComplete, base::Unretained(this))); if (rv == ERR_IO_PENDING && - AddressListStartsWithIPv6AndHasAnIPv4Addr(addresses_)) { + addresses_.front().GetFamily() == AF_INET6 && + !AddressListOnlyContainsIPv6(addresses_)) { fallback_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kIPv6FallbackTimerInMs), this, &TransportConnectJob::DoIPv6FallbackTransportConnect); @@ -224,7 +190,7 @@ int TransportConnectJob::DoTransportConnect() { int TransportConnectJob::DoTransportConnectComplete(int result) { if (result == OK) { - bool is_ipv4 = addresses_.head()->ai_family != AF_INET6; + bool is_ipv4 = addresses_.front().GetFamily() != AF_INET6; DCHECK(connect_start_time_ != base::TimeTicks()); DCHECK(start_time_ != base::TimeTicks()); base::TimeTicks now = base::TimeTicks::Now(); @@ -250,7 +216,7 @@ int TransportConnectJob::DoTransportConnectComplete(int result) { base::TimeDelta::FromMinutes(10), 100); } else { - if (AddressListOnlyContainsIPv6Addresses(addresses_)) { + if (AddressListOnlyContainsIPv6(addresses_)) { UMA_HISTOGRAM_CUSTOM_TIMES("Net.TCP_Connection_Latency_IPv6_Solo", connect_duration, base::TimeDelta::FromMilliseconds(1), @@ -287,7 +253,7 @@ void TransportConnectJob::DoIPv6FallbackTransportConnect() { DCHECK(!fallback_addresses_.get()); fallback_addresses_.reset(new AddressList(addresses_)); - MakeAddrListStartWithIPv4(fallback_addresses_.get()); + MakeAddressListStartWithIPv4(fallback_addresses_.get()); fallback_transport_socket_.reset( client_socket_factory_->CreateTransportClientSocket( *fallback_addresses_, net_log().net_log(), net_log().source())); diff --git a/net/socket/transport_client_socket_pool.h b/net/socket/transport_client_socket_pool.h index ef3f6fa..fc9ee22 100644 --- a/net/socket/transport_client_socket_pool.h +++ b/net/socket/transport_client_socket_pool.h @@ -69,12 +69,9 @@ class NET_EXPORT_PRIVATE TransportConnectJob : public ConnectJob { // ConnectJob methods. virtual LoadState GetLoadState() const OVERRIDE; - // Makes |addrlist| start with an IPv4 address if |addrlist| contains any - // IPv4 address. - // - // WARNING: this method should only be used to implement the prefer-IPv4 - // hack. It is a public method for the unit tests. - static void MakeAddrListStartWithIPv4(AddressList* addrlist); + // Rolls |addrlist| forward until the first IPv4 address, if any. + // WARNING: this method should only be used to implement the prefer-IPv4 hack. + static void MakeAddressListStartWithIPv4(AddressList* addrlist); static const int kIPv6FallbackTimerInMs; diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc index 0b31083..c335e33 100644 --- a/net/socket/transport_client_socket_pool_unittest.cc +++ b/net/socket/transport_client_socket_pool_unittest.cc @@ -15,7 +15,6 @@ #include "net/base/mock_host_resolver.h" #include "net/base/net_errors.h" #include "net/base/net_util.h" -#include "net/base/sys_addrinfo.h" #include "net/base/test_completion_callback.h" #include "net/socket/client_socket_factory.h" #include "net/socket/client_socket_handle.h" @@ -73,7 +72,7 @@ class MockClientSocket : public StreamSocket { virtual int GetLocalAddress(IPEndPoint* address) const { if (!connected_) return ERR_SOCKET_NOT_CONNECTED; - if (addrlist_.head()->ai_family == AF_INET) + if (addrlist_.front().GetFamily() == AF_INET) SetIPv4Address(address); else SetIPv6Address(address); @@ -212,7 +211,7 @@ class MockPendingClientSocket : public StreamSocket { virtual int GetLocalAddress(IPEndPoint* address) const { if (!is_connected_) return ERR_SOCKET_NOT_CONNECTED; - if (addrlist_.head()->ai_family == AF_INET) + if (addrlist_.front().GetFamily() == AF_INET) SetIPv4Address(address); else SetIPv6Address(address); @@ -435,84 +434,72 @@ class TransportClientSocketPoolTest : public testing::Test { TEST(TransportConnectJobTest, MakeAddrListStartWithIPv4) { IPAddressNumber ip_number; ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.1", &ip_number)); - AddressList addrlist_v4_1 = AddressList::CreateFromIPAddress(ip_number, 80); + IPEndPoint addrlist_v4_1(ip_number, 80); ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.2", &ip_number)); - AddressList addrlist_v4_2 = AddressList::CreateFromIPAddress(ip_number, 80); + IPEndPoint addrlist_v4_2(ip_number, 80); ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::64", &ip_number)); - AddressList addrlist_v6_1 = AddressList::CreateFromIPAddress(ip_number, 80); + IPEndPoint addrlist_v6_1(ip_number, 80); ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::66", &ip_number)); - AddressList addrlist_v6_2 = AddressList::CreateFromIPAddress(ip_number, 80); + IPEndPoint addrlist_v6_2(ip_number, 80); AddressList addrlist; - const struct addrinfo* ai; // Test 1: IPv4 only. Expect no change. - addrlist = addrlist_v4_1; - addrlist.Append(addrlist_v4_2.head()); - TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist); - ai = addrlist.head(); - EXPECT_EQ(AF_INET, ai->ai_family); - ai = ai->ai_next; - EXPECT_EQ(AF_INET, ai->ai_family); - EXPECT_TRUE(ai->ai_next == NULL); + addrlist.clear(); + addrlist.push_back(addrlist_v4_1); + addrlist.push_back(addrlist_v4_2); + TransportConnectJob::MakeAddressListStartWithIPv4(&addrlist); + ASSERT_EQ(2u, addrlist.size()); + EXPECT_EQ(AF_INET, addrlist[0].GetFamily()); + EXPECT_EQ(AF_INET, addrlist[1].GetFamily()); // Test 2: IPv6 only. Expect no change. - addrlist = addrlist_v6_1; - addrlist.Append(addrlist_v6_2.head()); - TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist); - ai = addrlist.head(); - EXPECT_EQ(AF_INET6, ai->ai_family); - ai = ai->ai_next; - EXPECT_EQ(AF_INET6, ai->ai_family); - EXPECT_TRUE(ai->ai_next == NULL); + addrlist.clear(); + addrlist.push_back(addrlist_v6_1); + addrlist.push_back(addrlist_v6_2); + TransportConnectJob::MakeAddressListStartWithIPv4(&addrlist); + ASSERT_EQ(2u, addrlist.size()); + EXPECT_EQ(AF_INET6, addrlist[0].GetFamily()); + EXPECT_EQ(AF_INET6, addrlist[1].GetFamily()); // Test 3: IPv4 then IPv6. Expect no change. - addrlist = addrlist_v4_1; - addrlist.Append(addrlist_v4_2.head()); - addrlist.Append(addrlist_v6_1.head()); - addrlist.Append(addrlist_v6_2.head()); - TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist); - ai = addrlist.head(); - EXPECT_EQ(AF_INET, ai->ai_family); - ai = ai->ai_next; - EXPECT_EQ(AF_INET, ai->ai_family); - ai = ai->ai_next; - EXPECT_EQ(AF_INET6, ai->ai_family); - ai = ai->ai_next; - EXPECT_EQ(AF_INET6, ai->ai_family); - EXPECT_TRUE(ai->ai_next == NULL); + addrlist.clear(); + addrlist.push_back(addrlist_v4_1); + addrlist.push_back(addrlist_v4_2); + addrlist.push_back(addrlist_v6_1); + addrlist.push_back(addrlist_v6_2); + TransportConnectJob::MakeAddressListStartWithIPv4(&addrlist); + ASSERT_EQ(4u, addrlist.size()); + EXPECT_EQ(AF_INET, addrlist[0].GetFamily()); + EXPECT_EQ(AF_INET, addrlist[1].GetFamily()); + EXPECT_EQ(AF_INET6, addrlist[2].GetFamily()); + EXPECT_EQ(AF_INET6, addrlist[3].GetFamily()); // Test 4: IPv6, IPv4, IPv6, IPv4. Expect first IPv6 moved to the end. - addrlist = addrlist_v6_1; - addrlist.Append(addrlist_v4_1.head()); - addrlist.Append(addrlist_v6_2.head()); - addrlist.Append(addrlist_v4_2.head()); - TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist); - ai = addrlist.head(); - EXPECT_EQ(AF_INET, ai->ai_family); - ai = ai->ai_next; - EXPECT_EQ(AF_INET6, ai->ai_family); - ai = ai->ai_next; - EXPECT_EQ(AF_INET, ai->ai_family); - ai = ai->ai_next; - EXPECT_EQ(AF_INET6, ai->ai_family); - EXPECT_TRUE(ai->ai_next == NULL); + addrlist.clear(); + addrlist.push_back(addrlist_v6_1); + addrlist.push_back(addrlist_v4_1); + addrlist.push_back(addrlist_v6_2); + addrlist.push_back(addrlist_v4_2); + TransportConnectJob::MakeAddressListStartWithIPv4(&addrlist); + ASSERT_EQ(4u, addrlist.size()); + EXPECT_EQ(AF_INET, addrlist[0].GetFamily()); + EXPECT_EQ(AF_INET6, addrlist[1].GetFamily()); + EXPECT_EQ(AF_INET, addrlist[2].GetFamily()); + EXPECT_EQ(AF_INET6, addrlist[3].GetFamily()); // Test 5: IPv6, IPv6, IPv4, IPv4. Expect first two IPv6's moved to the end. - addrlist = addrlist_v6_1; - addrlist.Append(addrlist_v6_2.head()); - addrlist.Append(addrlist_v4_1.head()); - addrlist.Append(addrlist_v4_2.head()); - TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist); - ai = addrlist.head(); - EXPECT_EQ(AF_INET, ai->ai_family); - ai = ai->ai_next; - EXPECT_EQ(AF_INET, ai->ai_family); - ai = ai->ai_next; - EXPECT_EQ(AF_INET6, ai->ai_family); - ai = ai->ai_next; - EXPECT_EQ(AF_INET6, ai->ai_family); - EXPECT_TRUE(ai->ai_next == NULL); + addrlist.clear(); + addrlist.push_back(addrlist_v6_1); + addrlist.push_back(addrlist_v6_2); + addrlist.push_back(addrlist_v4_1); + addrlist.push_back(addrlist_v4_2); + TransportConnectJob::MakeAddressListStartWithIPv4(&addrlist); + ASSERT_EQ(4u, addrlist.size()); + EXPECT_EQ(AF_INET, addrlist[0].GetFamily()); + EXPECT_EQ(AF_INET, addrlist[1].GetFamily()); + EXPECT_EQ(AF_INET6, addrlist[2].GetFamily()); + EXPECT_EQ(AF_INET6, addrlist[3].GetFamily()); } TEST_F(TransportClientSocketPoolTest, Basic) { |