/* * Copyright (c) 2022, Ali Mohammad Pur * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace Core { class SOCKSProxyClient final : public Stream::Socket { public: enum class Version : u8 { V4 = 0x04, V5 = 0x05, }; struct UsernamePasswordAuthenticationData { DeprecatedString username; DeprecatedString password; }; enum class Command : u8 { Connect = 0x01, Bind = 0x02, UDPAssociate = 0x03, }; using HostOrIPV4 = Variant; static ErrorOr> connect(Socket& underlying, Version, HostOrIPV4 const& target, int target_port, Variant const& auth_data = {}, Command = Command::Connect); static ErrorOr> connect(HostOrIPV4 const& server, int server_port, Version, HostOrIPV4 const& target, int target_port, Variant const& auth_data = {}, Command = Command::Connect); virtual ~SOCKSProxyClient() override; // ^Stream::Stream virtual ErrorOr read(Bytes bytes) override { return m_socket.read(bytes); } virtual ErrorOr write(ReadonlyBytes bytes) override { return m_socket.write(bytes); } virtual bool is_eof() const override { return m_socket.is_eof(); } virtual bool is_open() const override { return m_socket.is_open(); } virtual void close() override { m_socket.close(); } // ^Stream::Socket virtual ErrorOr pending_bytes() const override { return m_socket.pending_bytes(); } virtual ErrorOr can_read_without_blocking(int timeout = 0) const override { return m_socket.can_read_without_blocking(timeout); } virtual ErrorOr set_blocking(bool enabled) override { return m_socket.set_blocking(enabled); } virtual ErrorOr set_close_on_exec(bool enabled) override { return m_socket.set_close_on_exec(enabled); } virtual void set_notifications_enabled(bool enabled) override { m_socket.set_notifications_enabled(enabled); } private: SOCKSProxyClient(Socket& socket, OwnPtr own_socket) : m_socket(socket) , m_own_underlying_socket(move(own_socket)) { m_socket.on_ready_to_read = [this] { on_ready_to_read(); }; } Socket& m_socket; OwnPtr m_own_underlying_socket; }; }