socks5_client.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Copyright (c) 2017-2023 zhllxt
  3. *
  4. * author : zhllxt
  5. * email : 37792738@qq.com
  6. *
  7. * Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. */
  10. #ifndef __ASIO2_SOCKS5_CLIENT_HPP__
  11. #define __ASIO2_SOCKS5_CLIENT_HPP__
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. #pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <asio2/base/detail/push_options.hpp>
  16. #include <asio2/tcp/tcp_client.hpp>
  17. namespace asio2::detail
  18. {
  19. ASIO2_CLASS_FORWARD_DECLARE_BASE;
  20. ASIO2_CLASS_FORWARD_DECLARE_TCP_BASE;
  21. ASIO2_CLASS_FORWARD_DECLARE_UDP_BASE;
  22. ASIO2_CLASS_FORWARD_DECLARE_TCP_CLIENT;
  23. ASIO2_CLASS_FORWARD_DECLARE_UDP_CLIENT;
  24. template<class, class> class socks5_session_impl_t;
  25. template<class derived_t, class executor_t>
  26. class socks5_client_impl_t
  27. : public executor_t
  28. {
  29. ASIO2_CLASS_FRIEND_DECLARE_BASE;
  30. ASIO2_CLASS_FRIEND_DECLARE_TCP_BASE;
  31. ASIO2_CLASS_FRIEND_DECLARE_UDP_BASE;
  32. ASIO2_CLASS_FRIEND_DECLARE_TCP_CLIENT;
  33. ASIO2_CLASS_FRIEND_DECLARE_UDP_CLIENT;
  34. template<class, class> friend class socks5_session_impl_t;
  35. public:
  36. using super = executor_t;
  37. using self = socks5_client_impl_t<derived_t, executor_t>;
  38. using executor_type = executor_t;
  39. using args_type = typename executor_t::args_type;
  40. using super::async_start;
  41. public:
  42. /**
  43. * @brief constructor
  44. */
  45. template<class... Args>
  46. explicit socks5_client_impl_t(Args&&... args)
  47. : super(std::forward<Args>(args)...)
  48. {
  49. this->connect_finish_timer_ = std::make_shared<asio::steady_timer>(this->io_->context());
  50. }
  51. /**
  52. * @brief destructor
  53. */
  54. ~socks5_client_impl_t()
  55. {
  56. this->stop();
  57. }
  58. /**
  59. * @brief destroy the content of all member variables, this is used for solve the memory leaks.
  60. * After this function is called, this class object cannot be used again.
  61. */
  62. inline void destroy()
  63. {
  64. derived_t& derive = this->derived();
  65. derive.connect_finish_timer_.reset();
  66. super::destroy();
  67. }
  68. /**
  69. * @brief async start the client, asynchronous connect to server.
  70. * @param host - A string identifying a location. May be a descriptive name or
  71. * a numeric address string.
  72. * @param port - A string identifying the requested service. This may be a
  73. * descriptive name or a numeric string corresponding to a port number.
  74. */
  75. template<typename String, typename StrOrInt, typename CompletionToken, typename... Args>
  76. auto async_start(String&& host, StrOrInt&& port, CompletionToken&& token, Args&&... args)
  77. {
  78. derived_t& derive = this->derived();
  79. bool f = executor_t::template async_start(
  80. std::forward<String>(host), std::forward<StrOrInt>(port), std::forward<Args>(args)...);
  81. derive.connect_finish_timer_->expires_after(f ?
  82. (std::chrono::steady_clock::duration::max)() :
  83. (std::chrono::steady_clock::duration::zero)());
  84. return asio::async_compose<CompletionToken, void(asio::error_code)>(
  85. detail::wait_timer_op{*(derive.connect_finish_timer_)},
  86. token, derive.socket());
  87. }
  88. protected:
  89. template<typename C, typename DeferEvent>
  90. inline void _handle_connect(
  91. const error_code& ec,
  92. std::shared_ptr<derived_t> this_ptr, std::shared_ptr<ecs_t<C>> ecs, DeferEvent chain)
  93. {
  94. detail::cancel_timer(*(this->derived().connect_finish_timer_));
  95. super::_handle_connect(ec, std::move(this_ptr), std::move(ecs), std::move(chain));
  96. }
  97. protected:
  98. std::shared_ptr<asio::steady_timer> connect_finish_timer_;
  99. };
  100. }
  101. namespace asio2
  102. {
  103. template<class derived_t, class executor_t>
  104. using socks5_client_impl_t = detail::socks5_client_impl_t<derived_t, executor_t>;
  105. /**
  106. * @brief socks5 tcp client
  107. */
  108. template<class derived_t>
  109. class socks5_tcp_client_t : public detail::socks5_client_impl_t<derived_t, tcp_client_t<derived_t>>
  110. {
  111. public:
  112. using detail::socks5_client_impl_t<derived_t, tcp_client_t<derived_t>>::socks5_client_impl_t;
  113. };
  114. /**
  115. * @brief socks5 tcp client
  116. */
  117. class socks5_tcp_client : public socks5_tcp_client_t<socks5_tcp_client>
  118. {
  119. public:
  120. using socks5_tcp_client_t<socks5_tcp_client>::socks5_tcp_client_t;
  121. };
  122. }
  123. #include <asio2/base/detail/pop_options.hpp>
  124. #endif // !__ASIO2_SOCKS5_CLIENT_HPP__