// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include #include #if defined(_WIN32) #elif !YUZU_UNIX #error "Platform not implemented" #endif #include "common/common_types.h" #include "core/internal_network/network.h" // TODO: C++20 Replace std::vector usages with std::span namespace Network { struct ProxyPacket; class SocketBase { public: #ifdef YUZU_UNIX using SOCKET = int; static constexpr SOCKET INVALID_SOCKET = -1; static constexpr SOCKET SOCKET_ERROR = -1; #endif struct AcceptResult { std::unique_ptr socket; SockAddrIn sockaddr_in; }; SocketBase() = default; explicit SocketBase(SOCKET fd_) : fd{fd_} {} virtual ~SocketBase() = default; YUZU_NON_COPYABLE(SocketBase); YUZU_NON_MOVEABLE(SocketBase); virtual Errno Initialize(Domain domain, Type type, Protocol protocol) = 0; virtual Errno Close() = 0; virtual std::pair Accept() = 0; virtual Errno Connect(SockAddrIn addr_in) = 0; virtual std::pair GetPeerName() = 0; virtual std::pair GetSockName() = 0; virtual Errno Bind(SockAddrIn addr) = 0; virtual Errno Listen(s32 backlog) = 0; virtual Errno Shutdown(ShutdownHow how) = 0; virtual std::pair Recv(int flags, std::span message) = 0; virtual std::pair RecvFrom(int flags, std::span message, SockAddrIn* addr) = 0; virtual std::pair Send(std::span message, int flags) = 0; virtual std::pair SendTo(u32 flags, std::span message, const SockAddrIn* addr) = 0; virtual Errno SetLinger(bool enable, u32 linger) = 0; virtual Errno SetReuseAddr(bool enable) = 0; virtual Errno SetKeepAlive(bool enable) = 0; virtual Errno SetBroadcast(bool enable) = 0; virtual Errno SetSndBuf(u32 value) = 0; virtual Errno SetRcvBuf(u32 value) = 0; virtual Errno SetSndTimeo(u32 value) = 0; virtual Errno SetRcvTimeo(u32 value) = 0; virtual Errno SetNonBlock(bool enable) = 0; virtual std::pair GetPendingError() = 0; virtual bool IsOpened() const = 0; virtual void HandleProxyPacket(const ProxyPacket& packet) = 0; [[nodiscard]] SOCKET GetFD() const { return fd; } protected: SOCKET fd = INVALID_SOCKET; }; class Socket : public SocketBase { public: Socket() = default; explicit Socket(SOCKET fd_) : SocketBase{fd_} {} ~Socket() override; Socket(Socket&& rhs) noexcept; Errno Initialize(Domain domain, Type type, Protocol protocol) override; Errno Close() override; std::pair Accept() override; Errno Connect(SockAddrIn addr_in) override; std::pair GetPeerName() override; std::pair GetSockName() override; Errno Bind(SockAddrIn addr) override; Errno Listen(s32 backlog) override; Errno Shutdown(ShutdownHow how) override; std::pair Recv(int flags, std::span message) override; std::pair RecvFrom(int flags, std::span message, SockAddrIn* addr) override; std::pair Send(std::span message, int flags) override; std::pair SendTo(u32 flags, std::span message, const SockAddrIn* addr) override; Errno SetLinger(bool enable, u32 linger) override; Errno SetReuseAddr(bool enable) override; Errno SetKeepAlive(bool enable) override; Errno SetBroadcast(bool enable) override; Errno SetSndBuf(u32 value) override; Errno SetRcvBuf(u32 value) override; Errno SetSndTimeo(u32 value) override; Errno SetRcvTimeo(u32 value) override; Errno SetNonBlock(bool enable) override; template Errno SetSockOpt(SOCKET fd, int option, T value); std::pair GetPendingError() override; template std::pair GetSockOpt(SOCKET fd, int option); bool IsOpened() const override; void HandleProxyPacket(const ProxyPacket& packet) override; }; std::pair Poll(std::vector& poll_fds, s32 timeout); } // namespace Network