summaryrefslogtreecommitdiffstats
path: root/net/socket/tcp_client_socket_libevent.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket/tcp_client_socket_libevent.cc')
-rw-r--r--net/socket/tcp_client_socket_libevent.cc80
1 files changed, 41 insertions, 39 deletions
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;