/* * Copyright (c) 2017-2023 zhllxt * * author : zhllxt * email : 37792738@qq.com * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef __ASIO2_SOCKS5_CLIENT_HPP__ #define __ASIO2_SOCKS5_CLIENT_HPP__ #if defined(_MSC_VER) && (_MSC_VER >= 1200) #pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include namespace asio2::detail { ASIO2_CLASS_FORWARD_DECLARE_BASE; ASIO2_CLASS_FORWARD_DECLARE_TCP_BASE; ASIO2_CLASS_FORWARD_DECLARE_UDP_BASE; ASIO2_CLASS_FORWARD_DECLARE_TCP_CLIENT; ASIO2_CLASS_FORWARD_DECLARE_UDP_CLIENT; template class socks5_session_impl_t; template class socks5_client_impl_t : public executor_t { ASIO2_CLASS_FRIEND_DECLARE_BASE; ASIO2_CLASS_FRIEND_DECLARE_TCP_BASE; ASIO2_CLASS_FRIEND_DECLARE_UDP_BASE; ASIO2_CLASS_FRIEND_DECLARE_TCP_CLIENT; ASIO2_CLASS_FRIEND_DECLARE_UDP_CLIENT; template friend class socks5_session_impl_t; public: using super = executor_t; using self = socks5_client_impl_t; using executor_type = executor_t; using args_type = typename executor_t::args_type; using super::async_start; public: /** * @brief constructor */ template explicit socks5_client_impl_t(Args&&... args) : super(std::forward(args)...) { this->connect_finish_timer_ = std::make_shared(this->io_->context()); } /** * @brief destructor */ ~socks5_client_impl_t() { this->stop(); } /** * @brief destroy the content of all member variables, this is used for solve the memory leaks. * After this function is called, this class object cannot be used again. */ inline void destroy() { derived_t& derive = this->derived(); derive.connect_finish_timer_.reset(); super::destroy(); } /** * @brief async start the client, asynchronous connect to server. * @param host - A string identifying a location. May be a descriptive name or * a numeric address string. * @param port - A string identifying the requested service. This may be a * descriptive name or a numeric string corresponding to a port number. */ template auto async_start(String&& host, StrOrInt&& port, CompletionToken&& token, Args&&... args) { derived_t& derive = this->derived(); bool f = executor_t::template async_start( std::forward(host), std::forward(port), std::forward(args)...); derive.connect_finish_timer_->expires_after(f ? (std::chrono::steady_clock::duration::max)() : (std::chrono::steady_clock::duration::zero)()); return asio::async_compose( detail::wait_timer_op{*(derive.connect_finish_timer_)}, token, derive.socket()); } protected: template inline void _handle_connect( const error_code& ec, std::shared_ptr this_ptr, std::shared_ptr> ecs, DeferEvent chain) { detail::cancel_timer(*(this->derived().connect_finish_timer_)); super::_handle_connect(ec, std::move(this_ptr), std::move(ecs), std::move(chain)); } protected: std::shared_ptr connect_finish_timer_; }; } namespace asio2 { template using socks5_client_impl_t = detail::socks5_client_impl_t; /** * @brief socks5 tcp client */ template class socks5_tcp_client_t : public detail::socks5_client_impl_t> { public: using detail::socks5_client_impl_t>::socks5_client_impl_t; }; /** * @brief socks5 tcp client */ class socks5_tcp_client : public socks5_tcp_client_t { public: using socks5_tcp_client_t::socks5_tcp_client_t; }; } #include #endif // !__ASIO2_SOCKS5_CLIENT_HPP__