12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/tcp_client_socket.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/callback_helpers.h" 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/logging.h" 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/base/io_buffer.h" 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/base/ip_endpoint.h" 11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/base/net_errors.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/base/net_util.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TCPClientSocket::TCPClientSocket(const AddressList& addresses, 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) net::NetLog* net_log, 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const net::NetLog::Source& source) 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : socket_(new TCPSocket(net_log, source)), 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) addresses_(addresses), 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) current_address_index_(-1), 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) next_connect_state_(CONNECT_STATE_NONE), 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) previously_disconnected_(false) { 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TCPClientSocket::TCPClientSocket(scoped_ptr<TCPSocket> connected_socket, 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const IPEndPoint& peer_address) 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : socket_(connected_socket.Pass()), 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) addresses_(AddressList(peer_address)), 30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) current_address_index_(0), 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) next_connect_state_(CONNECT_STATE_NONE), 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) previously_disconnected_(false) { 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(socket_); 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) socket_->SetDefaultOptionsForClient(); 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) use_history_.set_was_ever_connected(); 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TCPClientSocket::~TCPClientSocket() { 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int TCPClientSocket::Bind(const IPEndPoint& address) { 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (current_address_index_ >= 0 || bind_address_) { 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Cannot bind the socket if we are already connected or connecting. 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) NOTREACHED(); 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ERR_UNEXPECTED; 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int result = OK; 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!socket_->IsValid()) { 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) result = OpenSocket(address.GetFamily()); 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result != OK) 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return result; 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) result = socket_->Bind(address); 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result != OK) 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return result; 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bind_address_.reset(new IPEndPoint(address)); 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return OK; 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int TCPClientSocket::Connect(const CompletionCallback& callback) { 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!callback.is_null()); 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If connecting or already connected, then just return OK. 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (socket_->IsValid() && current_address_index_ >= 0) 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return OK; 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) socket_->StartLoggingMultipleConnectAttempts(addresses_); 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // We will try to connect to each address in addresses_. Start with the 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // first one in the list. 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) next_connect_state_ = CONNECT_STATE_CONNECT; 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) current_address_index_ = 0; 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int rv = DoConnectLoop(OK); 79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (rv == ERR_IO_PENDING) { 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) connect_callback_ = callback; 81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) socket_->EndLoggingMultipleConnectAttempts(rv); 83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return rv; 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int TCPClientSocket::DoConnectLoop(int result) { 89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_NE(next_connect_state_, CONNECT_STATE_NONE); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int rv = result; 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) do { 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ConnectState state = next_connect_state_; 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) next_connect_state_ = CONNECT_STATE_NONE; 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) switch (state) { 96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case CONNECT_STATE_CONNECT: 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(OK, rv); 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) rv = DoConnect(); 99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case CONNECT_STATE_CONNECT_COMPLETE: 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) rv = DoConnectComplete(rv); 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) default: 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) NOTREACHED() << "bad state " << state; 105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) rv = ERR_UNEXPECTED; 106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } while (rv != ERR_IO_PENDING && next_connect_state_ != CONNECT_STATE_NONE); 109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return rv; 111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int TCPClientSocket::DoConnect() { 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_GE(current_address_index_, 0); 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_LT(current_address_index_, static_cast<int>(addresses_.size())); 116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const IPEndPoint& endpoint = addresses_[current_address_index_]; 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (previously_disconnected_) { 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) use_history_.Reset(); 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) previously_disconnected_ = false; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE; 125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (socket_->IsValid()) { 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(bind_address_); 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int result = OpenSocket(endpoint.GetFamily()); 130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result != OK) 131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return result; 132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (bind_address_) { 134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) result = socket_->Bind(*bind_address_); 135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result != OK) { 136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) socket_->Close(); 137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return result; 138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // |socket_| is owned by this class and the callback won't be run once 143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // |socket_| is gone. Therefore, it is safe to use base::Unretained() here. 144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return socket_->Connect(endpoint, 145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&TCPClientSocket::DidCompleteConnect, 146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Unretained(this))); 147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int TCPClientSocket::DoConnectComplete(int result) { 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result == OK) { 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) use_history_.set_was_ever_connected(); 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return OK; // Done! 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Close whatever partially connected socket we currently have. 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DoDisconnect(); 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Try to fall back to the next address in the list. 159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (current_address_index_ + 1 < static_cast<int>(addresses_.size())) { 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) next_connect_state_ = CONNECT_STATE_CONNECT; 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ++current_address_index_; 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return OK; 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Otherwise there is nothing to fall back to, so give up. 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return result; 167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void TCPClientSocket::Disconnect() { 170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DoDisconnect(); 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) current_address_index_ = -1; 172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bind_address_.reset(); 173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void TCPClientSocket::DoDisconnect() { 176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If connecting or already connected, record that the socket has been 177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // disconnected. 178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) previously_disconnected_ = socket_->IsValid() && current_address_index_ >= 0; 179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) socket_->Close(); 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool TCPClientSocket::IsConnected() const { 183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return socket_->IsConnected(); 184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool TCPClientSocket::IsConnectedAndIdle() const { 187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return socket_->IsConnectedAndIdle(); 188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int TCPClientSocket::GetPeerAddress(IPEndPoint* address) const { 191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return socket_->GetPeerAddress(address); 192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int TCPClientSocket::GetLocalAddress(IPEndPoint* address) const { 195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(address); 196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!socket_->IsValid()) { 198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (bind_address_) { 199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *address = *bind_address_; 200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return OK; 201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ERR_SOCKET_NOT_CONNECTED; 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return socket_->GetLocalAddress(address); 206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const BoundNetLog& TCPClientSocket::NetLog() const { 209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return socket_->net_log(); 210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void TCPClientSocket::SetSubresourceSpeculation() { 213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) use_history_.set_subresource_speculation(); 214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 215d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void TCPClientSocket::SetOmniboxSpeculation() { 217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) use_history_.set_omnibox_speculation(); 218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool TCPClientSocket::WasEverUsed() const { 221d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return use_history_.was_used_to_convey_data(); 222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool TCPClientSocket::UsingTCPFastOpen() const { 225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return socket_->UsingTCPFastOpen(); 226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid TCPClientSocket::EnableTCPFastOpenIfSupported() { 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci socket_->EnableTCPFastOpenIfSupported(); 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool TCPClientSocket::WasNpnNegotiated() const { 233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return false; 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)NextProto TCPClientSocket::GetNegotiatedProtocol() const { 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return kProtoUnknown; 238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool TCPClientSocket::GetSSLInfo(SSLInfo* ssl_info) { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int TCPClientSocket::Read(IOBuffer* buf, 245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int buf_len, 246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const CompletionCallback& callback) { 247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!callback.is_null()); 248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // |socket_| is owned by this class and the callback won't be run once 250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // |socket_| is gone. Therefore, it is safe to use base::Unretained() here. 251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CompletionCallback read_callback = base::Bind( 252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &TCPClientSocket::DidCompleteReadWrite, base::Unretained(this), callback); 253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int result = socket_->Read(buf, buf_len, read_callback); 254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result > 0) 255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) use_history_.set_was_used_to_convey_data(); 256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return result; 258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int TCPClientSocket::Write(IOBuffer* buf, 261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int buf_len, 262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const CompletionCallback& callback) { 263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!callback.is_null()); 264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // |socket_| is owned by this class and the callback won't be run once 266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // |socket_| is gone. Therefore, it is safe to use base::Unretained() here. 267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CompletionCallback write_callback = base::Bind( 268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &TCPClientSocket::DidCompleteReadWrite, base::Unretained(this), callback); 269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int result = socket_->Write(buf, buf_len, write_callback); 270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result > 0) 271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) use_history_.set_was_used_to_convey_data(); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return result; 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochint TCPClientSocket::SetReceiveBufferSize(int32 size) { 277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return socket_->SetReceiveBufferSize(size); 278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochint TCPClientSocket::SetSendBufferSize(int32 size) { 281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return socket_->SetSendBufferSize(size); 282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool TCPClientSocket::SetKeepAlive(bool enable, int delay) { 285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return socket_->SetKeepAlive(enable, delay); 286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool TCPClientSocket::SetNoDelay(bool no_delay) { 289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return socket_->SetNoDelay(no_delay); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void TCPClientSocket::DidCompleteConnect(int result) { 293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(next_connect_state_, CONNECT_STATE_CONNECT_COMPLETE); 294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_NE(result, ERR_IO_PENDING); 295d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!connect_callback_.is_null()); 296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 297d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) result = DoConnectLoop(result); 298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result != ERR_IO_PENDING) { 299d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) socket_->EndLoggingMultipleConnectAttempts(result); 300d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::ResetAndReturn(&connect_callback_).Run(result); 301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void TCPClientSocket::DidCompleteReadWrite(const CompletionCallback& callback, 305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int result) { 306d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result > 0) 307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) use_history_.set_was_used_to_convey_data(); 308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 309d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback.Run(result); 310d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 312d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)int TCPClientSocket::OpenSocket(AddressFamily family) { 313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!socket_->IsValid()); 314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int result = socket_->Open(family); 316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result != OK) 317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return result; 318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) socket_->SetDefaultOptionsForClient(); 320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return OK; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 325