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