#ifndef NET_SOCKET_TCP_CLIENT_SOCKET_H_
#define NET_SOCKET_TCP_CLIENT_SOCKET_H_
#include <stdint.h>
#include <memory>
#include "base/compiler_specific.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/power_monitor/power_observer.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "net/base/address_list.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_export.h"
#include "net/socket/socket_descriptor.h"
#include "net/socket/stream_socket.h"
#include "net/socket/tcp_socket.h"
#include "net/socket/transport_client_socket.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#if !BUILDFLAG(IS_ANDROID)
#define TCP_CLIENT_SOCKET_OBSERVES_SUSPEND
#endif
namespace net {
class IPEndPoint;
class NetLog;
struct NetLogSource;
class SocketPerformanceWatcher;
class NetworkQualityEstimator;
class NET_EXPORT TCPClientSocket : public TransportClientSocket,
public base::PowerSuspendObserver {
public:
TCPClientSocket(
const AddressList& addresses,
std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
NetworkQualityEstimator* network_quality_estimator,
net::NetLog* net_log,
const net::NetLogSource& source,
handles::NetworkHandle network = handles::kInvalidNetworkHandle);
TCPClientSocket(std::unique_ptr<TCPSocket> connected_socket,
const IPEndPoint& peer_address);
TCPClientSocket(std::unique_ptr<TCPSocket> unconnected_socket,
const AddressList& addresses,
NetworkQualityEstimator* network_quality_estimator);
static std::unique_ptr<TCPClientSocket> CreateFromBoundSocket(
std::unique_ptr<TCPSocket> bound_socket,
const AddressList& addresses,
const IPEndPoint& bound_address,
NetworkQualityEstimator* network_quality_estimator);
TCPClientSocket(const TCPClientSocket&) = delete;
TCPClientSocket& operator=(const TCPClientSocket&) = delete;
~TCPClientSocket() override;
int Bind(const IPEndPoint& address) override;
bool SetKeepAlive(bool enable, int delay) override;
bool SetNoDelay(bool no_delay) override;
void SetBeforeConnectCallback(
const BeforeConnectCallback& before_connect_callback) override;
int Connect(CompletionOnceCallback callback) override;
void Disconnect() override;
bool IsConnected() const override;
bool IsConnectedAndIdle() const override;
int GetPeerAddress(IPEndPoint* address) const override;
int GetLocalAddress(IPEndPoint* address) const override;
const NetLogWithSource& NetLog() const override;
bool WasEverUsed() const override;
bool WasAlpnNegotiated() const override;
NextProto GetNegotiatedProtocol() const override;
bool GetSSLInfo(SSLInfo* ssl_info) override;
int64_t GetTotalReceivedBytes() const override;
void ApplySocketTag(const SocketTag& tag) override;
int Read(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) override;
int ReadIfReady(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) override;
int CancelReadIfReady() override;
int Write(IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback,
const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
SocketDescriptor SocketDescriptorForTesting() const;
void OnSuspend() override;
private:
enum ConnectState {
CONNECT_STATE_CONNECT,
CONNECT_STATE_CONNECT_COMPLETE,
CONNECT_STATE_NONE,
};
TCPClientSocket(std::unique_ptr<TCPSocket> socket,
const AddressList& addresses,
int current_address_index,
std::unique_ptr<IPEndPoint> bind_address,
NetworkQualityEstimator* network_quality_estimator,
handles::NetworkHandle network);
int ReadCommon(IOBuffer* buf,
int buf_len,
const CompletionOnceCallback callback,
bool read_if_ready);
int DoConnectLoop(int result);
int DoConnect();
int DoConnectComplete(int result);
void OnConnectAttemptTimeout();
virtual int ConnectInternal(const IPEndPoint& endpoint);
void DoDisconnect();
void DidCompleteConnect(int result);
void DidCompleteRead(int result);
void DidCompleteWrite(int result);
void DidCompleteReadWrite(CompletionOnceCallback callback, int result);
int OpenSocket(AddressFamily family);
void EmitTCPMetricsHistogramsOnDisconnect();
void EmitConnectAttemptHistograms(int result);
base::TimeDelta GetConnectAttemptTimeout();
std::unique_ptr<TCPSocket> socket_;
std::unique_ptr<IPEndPoint> bind_address_;
AddressList addresses_;
int current_address_index_;
CompletionOnceCallback connect_callback_;
CompletionOnceCallback read_callback_;
CompletionOnceCallback write_callback_;
ConnectState next_connect_state_ = CONNECT_STATE_NONE;
bool previously_disconnected_ = false;
int64_t total_received_bytes_ = 0;
BeforeConnectCallback before_connect_callback_;
bool was_ever_used_ = false;
bool was_disconnected_on_suspend_ = false;
absl::optional<base::TimeTicks> start_connect_attempt_;
raw_ptr<NetworkQualityEstimator> network_quality_estimator_;
base::OneShotTimer connect_attempt_timer_;
handles::NetworkHandle network_;
base::WeakPtrFactory<TCPClientSocket> weak_ptr_factory_{this};
};
}
#endif