1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef NET_SOCKET_TCP_CLIENT_SOCKET_H_ 6*6777b538SAndroid Build Coastguard Worker #define NET_SOCKET_TCP_CLIENT_SOCKET_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stdint.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <memory> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h" 15*6777b538SAndroid Build Coastguard Worker #include "base/power_monitor/power_observer.h" 16*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 17*6777b538SAndroid Build Coastguard Worker #include "base/timer/timer.h" 18*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h" 19*6777b538SAndroid Build Coastguard Worker #include "net/base/address_list.h" 20*6777b538SAndroid Build Coastguard Worker #include "net/base/completion_once_callback.h" 21*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 22*6777b538SAndroid Build Coastguard Worker #include "net/socket/socket_descriptor.h" 23*6777b538SAndroid Build Coastguard Worker #include "net/socket/stream_socket.h" 24*6777b538SAndroid Build Coastguard Worker #include "net/socket/tcp_socket.h" 25*6777b538SAndroid Build Coastguard Worker #include "net/socket/transport_client_socket.h" 26*6777b538SAndroid Build Coastguard Worker #include "net/traffic_annotation/network_traffic_annotation.h" 27*6777b538SAndroid Build Coastguard Worker 28*6777b538SAndroid Build Coastguard Worker // PowerMonitor doesn't get suspend mode signals on Android, so don't use it to 29*6777b538SAndroid Build Coastguard Worker // watch for suspend events. 30*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_ANDROID) 31*6777b538SAndroid Build Coastguard Worker // Define SOCKETS_OBSERVE_SUSPEND if sockets should watch for suspend events so 32*6777b538SAndroid Build Coastguard Worker // they can fail pending socket operations on suspend. Otherwise, connections 33*6777b538SAndroid Build Coastguard Worker // hang for varying lengths of time when leaving suspend mode before failing 34*6777b538SAndroid Build Coastguard Worker // with TCP keepalive errors (~1 minute on macOS 10.14, up to several minutes on 35*6777b538SAndroid Build Coastguard Worker // Windows 10 1803). Firefox doesn't seems to need this logic, for unclear 36*6777b538SAndroid Build Coastguard Worker // reasons (experimentally, it doesn't seem to be the differences in the keep 37*6777b538SAndroid Build Coastguard Worker // alive settings it sets TCP sockets). 38*6777b538SAndroid Build Coastguard Worker #define TCP_CLIENT_SOCKET_OBSERVES_SUSPEND 39*6777b538SAndroid Build Coastguard Worker #endif 40*6777b538SAndroid Build Coastguard Worker 41*6777b538SAndroid Build Coastguard Worker namespace net { 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard Worker class IPEndPoint; 44*6777b538SAndroid Build Coastguard Worker class NetLog; 45*6777b538SAndroid Build Coastguard Worker struct NetLogSource; 46*6777b538SAndroid Build Coastguard Worker class SocketPerformanceWatcher; 47*6777b538SAndroid Build Coastguard Worker class NetworkQualityEstimator; 48*6777b538SAndroid Build Coastguard Worker 49*6777b538SAndroid Build Coastguard Worker // A client socket that uses TCP as the transport layer. 50*6777b538SAndroid Build Coastguard Worker class NET_EXPORT TCPClientSocket : public TransportClientSocket, 51*6777b538SAndroid Build Coastguard Worker public base::PowerSuspendObserver { 52*6777b538SAndroid Build Coastguard Worker public: 53*6777b538SAndroid Build Coastguard Worker // The IP address(es) and port number to connect to. The TCP socket will try 54*6777b538SAndroid Build Coastguard Worker // each IP address in the list until it succeeds in establishing a 55*6777b538SAndroid Build Coastguard Worker // connection. 56*6777b538SAndroid Build Coastguard Worker // If `network` is specified, the socket will be bound to it. All data traffic 57*6777b538SAndroid Build Coastguard Worker // on the socket will be sent and received via `network`. Communication using 58*6777b538SAndroid Build Coastguard Worker // this socket will fail if `network` disconnects. 59*6777b538SAndroid Build Coastguard Worker TCPClientSocket( 60*6777b538SAndroid Build Coastguard Worker const AddressList& addresses, 61*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher, 62*6777b538SAndroid Build Coastguard Worker NetworkQualityEstimator* network_quality_estimator, 63*6777b538SAndroid Build Coastguard Worker net::NetLog* net_log, 64*6777b538SAndroid Build Coastguard Worker const net::NetLogSource& source, 65*6777b538SAndroid Build Coastguard Worker handles::NetworkHandle network = handles::kInvalidNetworkHandle); 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Worker // Adopts the given, connected socket and then acts as if Connect() had been 68*6777b538SAndroid Build Coastguard Worker // called. This function is used by TCPServerSocket and for testing. 69*6777b538SAndroid Build Coastguard Worker TCPClientSocket(std::unique_ptr<TCPSocket> connected_socket, 70*6777b538SAndroid Build Coastguard Worker const IPEndPoint& peer_address); 71*6777b538SAndroid Build Coastguard Worker 72*6777b538SAndroid Build Coastguard Worker // Adopts an unconnected TCPSocket. TCPSocket may be bound or unbound. This 73*6777b538SAndroid Build Coastguard Worker // function is used by BrokeredTcpClientSocket. 74*6777b538SAndroid Build Coastguard Worker TCPClientSocket(std::unique_ptr<TCPSocket> unconnected_socket, 75*6777b538SAndroid Build Coastguard Worker const AddressList& addresses, 76*6777b538SAndroid Build Coastguard Worker std::unique_ptr<IPEndPoint> bound_address, 77*6777b538SAndroid Build Coastguard Worker NetworkQualityEstimator* network_quality_estimator); 78*6777b538SAndroid Build Coastguard Worker 79*6777b538SAndroid Build Coastguard Worker // Creates a TCPClientSocket from a bound-but-not-connected socket. 80*6777b538SAndroid Build Coastguard Worker static std::unique_ptr<TCPClientSocket> CreateFromBoundSocket( 81*6777b538SAndroid Build Coastguard Worker std::unique_ptr<TCPSocket> bound_socket, 82*6777b538SAndroid Build Coastguard Worker const AddressList& addresses, 83*6777b538SAndroid Build Coastguard Worker const IPEndPoint& bound_address, 84*6777b538SAndroid Build Coastguard Worker NetworkQualityEstimator* network_quality_estimator); 85*6777b538SAndroid Build Coastguard Worker 86*6777b538SAndroid Build Coastguard Worker TCPClientSocket(const TCPClientSocket&) = delete; 87*6777b538SAndroid Build Coastguard Worker TCPClientSocket& operator=(const TCPClientSocket&) = delete; 88*6777b538SAndroid Build Coastguard Worker 89*6777b538SAndroid Build Coastguard Worker ~TCPClientSocket() override; 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard Worker // TransportClientSocket implementation. 92*6777b538SAndroid Build Coastguard Worker int Bind(const IPEndPoint& address) override; 93*6777b538SAndroid Build Coastguard Worker bool SetKeepAlive(bool enable, int delay) override; 94*6777b538SAndroid Build Coastguard Worker bool SetNoDelay(bool no_delay) override; 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker // StreamSocket implementation. 97*6777b538SAndroid Build Coastguard Worker void SetBeforeConnectCallback( 98*6777b538SAndroid Build Coastguard Worker const BeforeConnectCallback& before_connect_callback) override; 99*6777b538SAndroid Build Coastguard Worker int Connect(CompletionOnceCallback callback) override; 100*6777b538SAndroid Build Coastguard Worker void Disconnect() override; 101*6777b538SAndroid Build Coastguard Worker bool IsConnected() const override; 102*6777b538SAndroid Build Coastguard Worker bool IsConnectedAndIdle() const override; 103*6777b538SAndroid Build Coastguard Worker int GetPeerAddress(IPEndPoint* address) const override; 104*6777b538SAndroid Build Coastguard Worker int GetLocalAddress(IPEndPoint* address) const override; 105*6777b538SAndroid Build Coastguard Worker const NetLogWithSource& NetLog() const override; 106*6777b538SAndroid Build Coastguard Worker bool WasEverUsed() const override; 107*6777b538SAndroid Build Coastguard Worker NextProto GetNegotiatedProtocol() const override; 108*6777b538SAndroid Build Coastguard Worker bool GetSSLInfo(SSLInfo* ssl_info) override; 109*6777b538SAndroid Build Coastguard Worker int64_t GetTotalReceivedBytes() const override; 110*6777b538SAndroid Build Coastguard Worker void ApplySocketTag(const SocketTag& tag) override; 111*6777b538SAndroid Build Coastguard Worker 112*6777b538SAndroid Build Coastguard Worker // Socket implementation. 113*6777b538SAndroid Build Coastguard Worker // Multiple outstanding requests are not supported. 114*6777b538SAndroid Build Coastguard Worker // Full duplex mode (reading and writing at the same time) is supported. 115*6777b538SAndroid Build Coastguard Worker int Read(IOBuffer* buf, 116*6777b538SAndroid Build Coastguard Worker int buf_len, 117*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback) override; 118*6777b538SAndroid Build Coastguard Worker int ReadIfReady(IOBuffer* buf, 119*6777b538SAndroid Build Coastguard Worker int buf_len, 120*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback) override; 121*6777b538SAndroid Build Coastguard Worker int CancelReadIfReady() override; 122*6777b538SAndroid Build Coastguard Worker int Write(IOBuffer* buf, 123*6777b538SAndroid Build Coastguard Worker int buf_len, 124*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback, 125*6777b538SAndroid Build Coastguard Worker const NetworkTrafficAnnotationTag& traffic_annotation) override; 126*6777b538SAndroid Build Coastguard Worker int SetReceiveBufferSize(int32_t size) override; 127*6777b538SAndroid Build Coastguard Worker int SetSendBufferSize(int32_t size) override; 128*6777b538SAndroid Build Coastguard Worker 129*6777b538SAndroid Build Coastguard Worker // Exposes the underlying socket descriptor for testing its state. Does not 130*6777b538SAndroid Build Coastguard Worker // release ownership of the descriptor. 131*6777b538SAndroid Build Coastguard Worker SocketDescriptor SocketDescriptorForTesting() const; 132*6777b538SAndroid Build Coastguard Worker 133*6777b538SAndroid Build Coastguard Worker // base::PowerSuspendObserver methods: 134*6777b538SAndroid Build Coastguard Worker void OnSuspend() override; 135*6777b538SAndroid Build Coastguard Worker 136*6777b538SAndroid Build Coastguard Worker private: 137*6777b538SAndroid Build Coastguard Worker // State machine for connecting the socket. 138*6777b538SAndroid Build Coastguard Worker enum ConnectState { 139*6777b538SAndroid Build Coastguard Worker CONNECT_STATE_CONNECT, 140*6777b538SAndroid Build Coastguard Worker CONNECT_STATE_CONNECT_COMPLETE, 141*6777b538SAndroid Build Coastguard Worker CONNECT_STATE_NONE, 142*6777b538SAndroid Build Coastguard Worker }; 143*6777b538SAndroid Build Coastguard Worker 144*6777b538SAndroid Build Coastguard Worker // Main constructor. `socket` must be non-null. `current_address_index` is the 145*6777b538SAndroid Build Coastguard Worker // address index in `addresses` of the server `socket` is connected to, or -1 146*6777b538SAndroid Build Coastguard Worker // if not connected. `bind_address`, if present, is the address `socket` is 147*6777b538SAndroid Build Coastguard Worker // bound to. `network` is the network the socket is required to be bound to, 148*6777b538SAndroid Build Coastguard Worker // or handles::kInvalidNetworkHandle if no binding is required. 149*6777b538SAndroid Build Coastguard Worker TCPClientSocket(std::unique_ptr<TCPSocket> socket, 150*6777b538SAndroid Build Coastguard Worker const AddressList& addresses, 151*6777b538SAndroid Build Coastguard Worker int current_address_index, 152*6777b538SAndroid Build Coastguard Worker std::unique_ptr<IPEndPoint> bind_address, 153*6777b538SAndroid Build Coastguard Worker NetworkQualityEstimator* network_quality_estimator, 154*6777b538SAndroid Build Coastguard Worker handles::NetworkHandle network); 155*6777b538SAndroid Build Coastguard Worker 156*6777b538SAndroid Build Coastguard Worker // A helper method shared by Read() and ReadIfReady(). If |read_if_ready| is 157*6777b538SAndroid Build Coastguard Worker // set to true, ReadIfReady() will be used instead of Read(). 158*6777b538SAndroid Build Coastguard Worker int ReadCommon(IOBuffer* buf, 159*6777b538SAndroid Build Coastguard Worker int buf_len, 160*6777b538SAndroid Build Coastguard Worker const CompletionOnceCallback callback, 161*6777b538SAndroid Build Coastguard Worker bool read_if_ready); 162*6777b538SAndroid Build Coastguard Worker 163*6777b538SAndroid Build Coastguard Worker // State machine used by Connect(). 164*6777b538SAndroid Build Coastguard Worker int DoConnectLoop(int result); 165*6777b538SAndroid Build Coastguard Worker int DoConnect(); 166*6777b538SAndroid Build Coastguard Worker int DoConnectComplete(int result); 167*6777b538SAndroid Build Coastguard Worker 168*6777b538SAndroid Build Coastguard Worker void OnConnectAttemptTimeout(); 169*6777b538SAndroid Build Coastguard Worker 170*6777b538SAndroid Build Coastguard Worker // Calls the connect method of |socket_|. Used in tests, to ensure a socket 171*6777b538SAndroid Build Coastguard Worker // never connects. 172*6777b538SAndroid Build Coastguard Worker virtual int ConnectInternal(const IPEndPoint& endpoint); 173*6777b538SAndroid Build Coastguard Worker 174*6777b538SAndroid Build Coastguard Worker // Helper used by Disconnect(), which disconnects minus resetting 175*6777b538SAndroid Build Coastguard Worker // current_address_index_ and bind_address_. 176*6777b538SAndroid Build Coastguard Worker void DoDisconnect(); 177*6777b538SAndroid Build Coastguard Worker 178*6777b538SAndroid Build Coastguard Worker void DidCompleteConnect(int result); 179*6777b538SAndroid Build Coastguard Worker void DidCompleteRead(int result); 180*6777b538SAndroid Build Coastguard Worker void DidCompleteWrite(int result); 181*6777b538SAndroid Build Coastguard Worker void DidCompleteReadWrite(CompletionOnceCallback callback, int result); 182*6777b538SAndroid Build Coastguard Worker 183*6777b538SAndroid Build Coastguard Worker int OpenSocket(AddressFamily family); 184*6777b538SAndroid Build Coastguard Worker 185*6777b538SAndroid Build Coastguard Worker // Emits histograms for TCP metrics, at the time the socket is 186*6777b538SAndroid Build Coastguard Worker // disconnected. 187*6777b538SAndroid Build Coastguard Worker void EmitTCPMetricsHistogramsOnDisconnect(); 188*6777b538SAndroid Build Coastguard Worker 189*6777b538SAndroid Build Coastguard Worker // Emits histograms for the TCP connect attempt that just completed with 190*6777b538SAndroid Build Coastguard Worker // |result|. 191*6777b538SAndroid Build Coastguard Worker void EmitConnectAttemptHistograms(int result); 192*6777b538SAndroid Build Coastguard Worker 193*6777b538SAndroid Build Coastguard Worker // Gets the timeout to use for the next TCP connect attempt. This is an 194*6777b538SAndroid Build Coastguard Worker // experimentally controlled value based on the estimated transport round 195*6777b538SAndroid Build Coastguard Worker // trip time. If no timeout is to be enforced, returns 196*6777b538SAndroid Build Coastguard Worker // base::TimeDelta::Max(). 197*6777b538SAndroid Build Coastguard Worker base::TimeDelta GetConnectAttemptTimeout(); 198*6777b538SAndroid Build Coastguard Worker 199*6777b538SAndroid Build Coastguard Worker std::unique_ptr<TCPSocket> socket_; 200*6777b538SAndroid Build Coastguard Worker 201*6777b538SAndroid Build Coastguard Worker // Local IP address and port we are bound to. Set to NULL if Bind() 202*6777b538SAndroid Build Coastguard Worker // wasn't called (in that case OS chooses address/port). 203*6777b538SAndroid Build Coastguard Worker std::unique_ptr<IPEndPoint> bind_address_; 204*6777b538SAndroid Build Coastguard Worker 205*6777b538SAndroid Build Coastguard Worker // The list of addresses we should try in order to establish a connection. 206*6777b538SAndroid Build Coastguard Worker AddressList addresses_; 207*6777b538SAndroid Build Coastguard Worker 208*6777b538SAndroid Build Coastguard Worker // Where we are in above list. Set to -1 if uninitialized. 209*6777b538SAndroid Build Coastguard Worker int current_address_index_; 210*6777b538SAndroid Build Coastguard Worker 211*6777b538SAndroid Build Coastguard Worker // External callbacks; called when corresponding operations are complete. 212*6777b538SAndroid Build Coastguard Worker // Cleared when no such operation is pending. 213*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback connect_callback_; 214*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback read_callback_; 215*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback write_callback_; 216*6777b538SAndroid Build Coastguard Worker 217*6777b538SAndroid Build Coastguard Worker // The next state for the Connect() state machine. 218*6777b538SAndroid Build Coastguard Worker ConnectState next_connect_state_ = CONNECT_STATE_NONE; 219*6777b538SAndroid Build Coastguard Worker 220*6777b538SAndroid Build Coastguard Worker // This socket was previously disconnected and has not been re-connected. 221*6777b538SAndroid Build Coastguard Worker bool previously_disconnected_ = false; 222*6777b538SAndroid Build Coastguard Worker 223*6777b538SAndroid Build Coastguard Worker // Total number of bytes received by the socket. 224*6777b538SAndroid Build Coastguard Worker int64_t total_received_bytes_ = 0; 225*6777b538SAndroid Build Coastguard Worker 226*6777b538SAndroid Build Coastguard Worker BeforeConnectCallback before_connect_callback_; 227*6777b538SAndroid Build Coastguard Worker 228*6777b538SAndroid Build Coastguard Worker bool was_ever_used_ = false; 229*6777b538SAndroid Build Coastguard Worker 230*6777b538SAndroid Build Coastguard Worker // Set to true if the socket was disconnected due to entering suspend mode. 231*6777b538SAndroid Build Coastguard Worker // Once set, read/write operations return ERR_NETWORK_IO_SUSPENDED, until 232*6777b538SAndroid Build Coastguard Worker // Connect() or Disconnect() is called. 233*6777b538SAndroid Build Coastguard Worker bool was_disconnected_on_suspend_ = false; 234*6777b538SAndroid Build Coastguard Worker 235*6777b538SAndroid Build Coastguard Worker // The time when the latest connect attempt was started. 236*6777b538SAndroid Build Coastguard Worker std::optional<base::TimeTicks> start_connect_attempt_; 237*6777b538SAndroid Build Coastguard Worker 238*6777b538SAndroid Build Coastguard Worker // The NetworkQualityEstimator for the context this socket is associated with. 239*6777b538SAndroid Build Coastguard Worker // Can be nullptr. 240*6777b538SAndroid Build Coastguard Worker raw_ptr<NetworkQualityEstimator> network_quality_estimator_; 241*6777b538SAndroid Build Coastguard Worker 242*6777b538SAndroid Build Coastguard Worker base::OneShotTimer connect_attempt_timer_; 243*6777b538SAndroid Build Coastguard Worker 244*6777b538SAndroid Build Coastguard Worker handles::NetworkHandle network_; 245*6777b538SAndroid Build Coastguard Worker 246*6777b538SAndroid Build Coastguard Worker base::WeakPtrFactory<TCPClientSocket> weak_ptr_factory_{this}; 247*6777b538SAndroid Build Coastguard Worker }; 248*6777b538SAndroid Build Coastguard Worker 249*6777b538SAndroid Build Coastguard Worker } // namespace net 250*6777b538SAndroid Build Coastguard Worker 251*6777b538SAndroid Build Coastguard Worker #endif // NET_SOCKET_TCP_CLIENT_SOCKET_H_ 252