#ifndef SERVICES_NETWORK_TCP_SERVER_SOCKET_H_
#define SERVICES_NETWORK_TCP_SERVER_SOCKET_H_
#include <memory>
#include <vector>
#include "base/component_export.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/types/expected.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/base/ip_endpoint.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/mojom/tcp_socket.mojom.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "services/network/public/mojom/socket_connection_tracker.mojom.h"
#endif
namespace net {
class NetLog;
class ServerSocket;
class StreamSocket;
}
namespace network {
class TCPConnectedSocket;
class COMPONENT_EXPORT(NETWORK_SERVICE) TCPServerSocket
: public mojom::TCPServerSocket {
public:
class Delegate {
public:
Delegate() {}
~Delegate() {}
virtual void OnAccept(
std::unique_ptr<TCPConnectedSocket> socket,
mojo::PendingReceiver<mojom::TCPConnectedSocket> receiver) = 0;
};
TCPServerSocket(Delegate* delegate,
net::NetLog* net_log,
const net::NetworkTrafficAnnotationTag& traffic_annotation);
TCPServerSocket(std::unique_ptr<net::ServerSocket> server_socket,
int backlog,
Delegate* delegate,
const net::NetworkTrafficAnnotationTag& traffic_annotation);
TCPServerSocket(const TCPServerSocket&) = delete;
TCPServerSocket& operator=(const TCPServerSocket&) = delete;
~TCPServerSocket() override;
base::expected<net::IPEndPoint, int32_t> Listen(
const net::IPEndPoint& local_addr,
int backlog,
absl::optional<bool> ipv6_only);
void Accept(mojo::PendingRemote<mojom::SocketObserver> observer,
AcceptCallback callback) override;
#if BUILDFLAG(IS_CHROMEOS)
void AttachConnectionTracker(
mojo::PendingRemote<mojom::SocketConnectionTracker>);
#endif
void SetSocketForTest(std::unique_ptr<net::ServerSocket> socket);
private:
struct PendingAccept {
PendingAccept(AcceptCallback callback,
mojo::PendingRemote<mojom::SocketObserver> observer);
~PendingAccept();
AcceptCallback callback;
mojo::PendingRemote<mojom::SocketObserver> observer;
};
void OnAcceptCompleted(int result);
void ProcessNextAccept();
const raw_ptr<Delegate> delegate_;
std::unique_ptr<net::ServerSocket> socket_;
int backlog_;
std::vector<std::unique_ptr<PendingAccept>> pending_accepts_queue_;
std::unique_ptr<net::StreamSocket> accepted_socket_;
net::IPEndPoint accepted_address_;
net::NetworkTrafficAnnotationTag traffic_annotation_;
#if BUILDFLAG(IS_CHROMEOS)
mojo::PendingRemote<mojom::SocketConnectionTracker> connection_tracker_;
#endif
base::WeakPtrFactory<TCPServerSocket> weak_factory_{this};
};
}
#endif