Electroneum
socks.h
Go to the documentation of this file.
1 // Copyright (c) 2018-2019, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #pragma once
30 
31 #include <cstdint>
32 #include <boost/asio/ip/tcp.hpp>
33 #include <boost/asio/io_service.hpp>
34 #include <boost/asio/strand.hpp>
35 #include <boost/system/error_code.hpp>
36 #include <boost/type_traits/integral_constant.hpp>
37 #include <boost/utility/string_ref.hpp>
38 #include <memory>
39 #include <utility>
40 
41 #include "net/fwd.h"
42 #include "span.h"
43 
44 namespace epee
45 {
46 namespace net_utils
47 {
48  class ipv4_network_address;
49 }
50 }
51 
52 namespace net
53 {
54 namespace socks
55 {
57  enum class version : std::uint8_t
58  {
59  v4 = 0,
60  v4a,
61  v4a_tor
62  };
63 
65  enum class error : int
66  {
67  // 0 is reserved for success value
68  // 1-256 -> reserved for error values from socks server (+1 from wire value).
69  rejected = 92,
72  // Specific to application
73  bad_read = 257,
74  bad_write,
76  };
77 
78  /* boost::system::error_code is extended for easier compatibility with
79  boost::asio errors. If std::error_code is needed (with expect<T> for
80  instance), then upgrade to boost 1.65+ or use conversion code in
81  develop branch at boost/system/detail/std_interoperability.hpp */
82 
85 
87  inline boost::system::error_code make_error_code(error value) noexcept
88  {
89  return boost::system::error_code{int(value), socks::error_category()};
90  }
91 
93  class client
94  {
96  boost::asio::io_service::strand strand_;
97  std::uint16_t buffer_size_;
98  std::uint8_t buffer_[1024];
99  socks::version ver_;
100 
112  virtual void done(boost::system::error_code error, std::shared_ptr<client> self) = 0;
113 
114  public:
115  using stream_type = boost::asio::ip::tcp;
116 
117  // defined in cpp
118  struct write;
119  struct read;
120  struct completed;
121 
127  explicit client(stream_type::socket&& proxy, socks::version ver);
128 
129  client(const client&) = delete;
130  virtual ~client();
131  client& operator=(const client&) = delete;
132 
135  {
136  return stream_type::socket{std::move(proxy_)};
137  }
138 
140  socks::version socks_version() const noexcept { return ver_; }
141 
144  {
145  return {buffer_, buffer_size_};
146  }
147 
149  void clear_command() noexcept { buffer_size_ = 0; }
150 
153 
155  bool set_connect_command(boost::string_ref domain, std::uint16_t port);
156 
159 
162 
164  bool set_resolve_command(boost::string_ref domain);
165 
180  static bool connect_and_send(std::shared_ptr<client> self, const stream_type::endpoint& proxy_address);
181 
195  static bool send(std::shared_ptr<client> self);
196 
199  struct async_close
200  {
201  std::shared_ptr<client> self_;
202  void operator()(boost::system::error_code error = boost::system::error_code{});
203  };
204  };
205 
206  template<typename Handler>
207  class connect_client : public client
208  {
209  Handler handler_;
210 
211  virtual void done(boost::system::error_code error, std::shared_ptr<client>) override
212  {
213  handler_(error, take_socket());
214  }
215 
216  public:
217  explicit connect_client(stream_type::socket&& proxy, socks::version ver, Handler&& handler)
218  : client(std::move(proxy), ver), handler_(std::move(handler))
219  {}
220 
221  virtual ~connect_client() override {}
222  };
223 
224  template<typename Handler>
225  inline std::shared_ptr<client>
227  {
228  return std::make_shared<connect_client<Handler>>(std::move(proxy), ver, std::move(handler));
229  }
230 } // socks
231 } // net
232 
233 namespace boost
234 {
235 namespace system
236 {
237  template<>
238  struct is_error_code_enum<net::socks::error>
239  : true_type
240  {};
241 } // system
242 } // boost
std::error_category const & error_category() noexcept
Definition: error.cpp:92
epee::span< const std::uint8_t > buffer() const noexcept
Definition: socks.h:143
socks::version socks_version() const noexcept
Definition: socks.h:140
static bool connect_and_send(std::shared_ptr< client > self, const stream_type::endpoint &proxy_address)
Definition: socks.cpp:294
b32 i2p address; internal format not condensed/decoded.
Definition: i2p_address.h:51
bool set_resolve_command(boost::string_ref domain)
Try to set domain as remote DNS A record lookup request.
Definition: socks.cpp:284
std::unique_ptr< void, close > socket
Unique ZMQ socket handle, calls zmq_close on destruction.
Definition: zmq.h:101
STL namespace.
unsigned short uint16_t
Definition: stdint.h:125
void clear_command() noexcept
Definition: socks.h:149
unsigned char uint8_t
Definition: stdint.h:124
std::shared_ptr< client > make_connect_client(client::stream_type::socket &&proxy, socks::version ver, Handler handler)
Definition: socks.h:226
stream_type::socket take_socket()
Definition: socks.h:134
Extensions defined in Tor codebase.
bool_constant< true > true_type
Definition: gtest-port.h:2210
boost::asio::ip::tcp stream_type
Definition: socks.h:115
bool set_connect_command(const epee::net_utils::ipv4_network_address &address)
Try to set address as remote connection request.
Definition: socks.cpp:229
void operator()(boost::system::error_code error=boost::system::error_code{})
Definition: socks.cpp:316
virtual ~connect_client() override
Definition: socks.h:221
std::shared_ptr< client > self_
Definition: socks.h:201
virtual ~client()
Definition: socks.cpp:227
version
Supported socks variants.
Definition: socks.h:57
boost::endian::big_uint16_t port
Definition: socks.cpp:60
Client support for socks connect and resolve commands.
Definition: socks.h:93
boost::system::error_code make_error_code(error value) noexcept
Definition: socks.h:87
error
Possible errors with socks communication. Defined in https://www.openssh.com/txt/socks4.protocol.
Definition: socks.h:65
const T & move(const T &t)
Definition: gtest-port.h:1317
Tor onion address; internal format not condensed/decoded.
Definition: tor_address.h:51
client & operator=(const client &)=delete
client(stream_type::socket &&proxy, socks::version ver)
Definition: socks.cpp:223
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225
const boost::system::error_category & error_category() noexcept
Definition: socks.cpp:143
const char * address
Definition: multisig.cpp:37
connect_client(stream_type::socket &&proxy, socks::version ver, Handler &&handler)
Definition: socks.h:217
static bool send(std::shared_ptr< client > self)
Definition: socks.cpp:305
#define inline
Definition: inline_c.h:35