summaryrefslogtreecommitdiffstats
path: root/net/socket
diff options
context:
space:
mode:
authorszym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-07 21:44:56 +0000
committerszym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-07 21:44:56 +0000
commit7054e78fe6a2fcda72b06dc196b5f91cfdc75872 (patch)
tree2efdd9b07a784a17905d737df9b762d88a6cd1c4 /net/socket
parentcd46545164adf645d744f3955b256cf89412cdc6 (diff)
downloadchromium_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.h2
-rw-r--r--net/socket/socks5_client_socket.cc1
-rw-r--r--net/socket/socks5_client_socket_unittest.cc1
-rw-r--r--net/socket/socks_client_socket.cc14
-rw-r--r--net/socket/ssl_client_socket_mac.cc6
-rw-r--r--net/socket/ssl_client_socket_nss.cc13
-rw-r--r--net/socket/ssl_client_socket_pool_unittest.cc7
-rw-r--r--net/socket/tcp_client_socket_libevent.cc80
-rw-r--r--net/socket/tcp_client_socket_libevent.h6
-rw-r--r--net/socket/tcp_client_socket_unittest.cc13
-rw-r--r--net/socket/tcp_client_socket_win.cc50
-rw-r--r--net/socket/tcp_client_socket_win.h6
-rw-r--r--net/socket/tcp_server_socket_libevent.cc31
-rw-r--r--net/socket/tcp_server_socket_unittest.cc9
-rw-r--r--net/socket/tcp_server_socket_win.cc29
-rw-r--r--net/socket/transport_client_socket_pool.cc68
-rw-r--r--net/socket/transport_client_socket_pool.h9
-rw-r--r--net/socket/transport_client_socket_pool_unittest.cc119
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) {