Imported Upstream version 1.51.0
[platform/upstream/boost.git] / doc / html / boost_asio / example / socks4 / socks4.hpp
1 //
2 // socks4.hpp
3 // ~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot 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
11 #ifndef SOCKS4_HPP
12 #define SOCKS4_HPP
13
14 #include <string>
15 #include <boost/asio.hpp>
16 #include <boost/array.hpp>
17
18 namespace socks4 {
19
20 const unsigned char version = 0x04;
21
22 class request
23 {
24 public:
25   enum command_type
26   {
27     connect = 0x01,
28     bind = 0x02
29   };
30
31   request(command_type cmd, const boost::asio::ip::tcp::endpoint& endpoint,
32       const std::string& user_id)
33     : version_(version),
34       command_(cmd),
35       user_id_(user_id),
36       null_byte_(0)
37   {
38     // Only IPv4 is supported by the SOCKS 4 protocol.
39     if (endpoint.protocol() != boost::asio::ip::tcp::v4())
40     {
41       throw boost::system::system_error(
42           boost::asio::error::address_family_not_supported);
43     }
44
45     // Convert port number to network byte order.
46     unsigned short port = endpoint.port();
47     port_high_byte_ = (port >> 8) & 0xff;
48     port_low_byte_ = port & 0xff;
49
50     // Save IP address in network byte order.
51     address_ = endpoint.address().to_v4().to_bytes();
52   }
53
54   boost::array<boost::asio::const_buffer, 7> buffers() const
55   {
56     boost::array<boost::asio::const_buffer, 7> bufs =
57     {
58       {
59         boost::asio::buffer(&version_, 1),
60         boost::asio::buffer(&command_, 1),
61         boost::asio::buffer(&port_high_byte_, 1),
62         boost::asio::buffer(&port_low_byte_, 1),
63         boost::asio::buffer(address_),
64         boost::asio::buffer(user_id_),
65         boost::asio::buffer(&null_byte_, 1)
66       }
67     };
68     return bufs;
69   }
70
71 private:
72   unsigned char version_;
73   unsigned char command_;
74   unsigned char port_high_byte_;
75   unsigned char port_low_byte_;
76   boost::asio::ip::address_v4::bytes_type address_;
77   std::string user_id_;
78   unsigned char null_byte_;
79 };
80
81 class reply
82 {
83 public:
84   enum status_type
85   {
86     request_granted = 0x5a,
87     request_failed = 0x5b,
88     request_failed_no_identd = 0x5c,
89     request_failed_bad_user_id = 0x5d
90   };
91
92   reply()
93     : null_byte_(0),
94       status_()
95   {
96   }
97
98   boost::array<boost::asio::mutable_buffer, 5> buffers()
99   {
100     boost::array<boost::asio::mutable_buffer, 5> bufs =
101     {
102       {
103         boost::asio::buffer(&null_byte_, 1),
104         boost::asio::buffer(&status_, 1),
105         boost::asio::buffer(&port_high_byte_, 1),
106         boost::asio::buffer(&port_low_byte_, 1),
107         boost::asio::buffer(address_)
108       }
109     };
110     return bufs;
111   }
112
113   bool success() const
114   {
115     return null_byte_ == 0 && status_ == request_granted;
116   }
117
118   unsigned char status() const
119   {
120     return status_;
121   }
122
123   boost::asio::ip::tcp::endpoint endpoint() const
124   {
125     unsigned short port = port_high_byte_;
126     port = (port << 8) & 0xff00;
127     port = port | port_low_byte_;
128
129     boost::asio::ip::address_v4 address(address_);
130
131     return boost::asio::ip::tcp::endpoint(address, port);
132   }
133
134 private:
135   unsigned char null_byte_;
136   unsigned char status_;
137   unsigned char port_high_byte_;
138   unsigned char port_low_byte_;
139   boost::asio::ip::address_v4::bytes_type address_;
140 };
141
142 } // namespace socks4
143
144 #endif // SOCKS4_HPP