diff options
Diffstat (limited to '3rdparty/asio/src/examples/cpp03/socks4')
-rw-r--r-- | 3rdparty/asio/src/examples/cpp03/socks4/.gitignore | 10 | ||||
-rw-r--r-- | 3rdparty/asio/src/examples/cpp03/socks4/socks4.hpp | 144 | ||||
-rw-r--r-- | 3rdparty/asio/src/examples/cpp03/socks4/sync_client.cpp | 94 |
3 files changed, 248 insertions, 0 deletions
diff --git a/3rdparty/asio/src/examples/cpp03/socks4/.gitignore b/3rdparty/asio/src/examples/cpp03/socks4/.gitignore new file mode 100644 index 00000000000..e11e0de344e --- /dev/null +++ b/3rdparty/asio/src/examples/cpp03/socks4/.gitignore @@ -0,0 +1,10 @@ +.deps +.dirstamp +*.o +*.obj +*.exe +sync_client +*.ilk +*.manifest +*.pdb +*.tds diff --git a/3rdparty/asio/src/examples/cpp03/socks4/socks4.hpp b/3rdparty/asio/src/examples/cpp03/socks4/socks4.hpp new file mode 100644 index 00000000000..c5558756558 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp03/socks4/socks4.hpp @@ -0,0 +1,144 @@ +// +// socks4.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot 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 SOCKS4_HPP +#define SOCKS4_HPP + +#include <string> +#include <asio.hpp> +#include <boost/array.hpp> + +namespace socks4 { + +const unsigned char version = 0x04; + +class request +{ +public: + enum command_type + { + connect = 0x01, + bind = 0x02 + }; + + request(command_type cmd, const asio::ip::tcp::endpoint& endpoint, + const std::string& user_id) + : version_(version), + command_(cmd), + user_id_(user_id), + null_byte_(0) + { + // Only IPv4 is supported by the SOCKS 4 protocol. + if (endpoint.protocol() != asio::ip::tcp::v4()) + { + throw asio::system_error( + asio::error::address_family_not_supported); + } + + // Convert port number to network byte order. + unsigned short port = endpoint.port(); + port_high_byte_ = (port >> 8) & 0xff; + port_low_byte_ = port & 0xff; + + // Save IP address in network byte order. + address_ = endpoint.address().to_v4().to_bytes(); + } + + boost::array<asio::const_buffer, 7> buffers() const + { + boost::array<asio::const_buffer, 7> bufs = + { + { + asio::buffer(&version_, 1), + asio::buffer(&command_, 1), + asio::buffer(&port_high_byte_, 1), + asio::buffer(&port_low_byte_, 1), + asio::buffer(address_), + asio::buffer(user_id_), + asio::buffer(&null_byte_, 1) + } + }; + return bufs; + } + +private: + unsigned char version_; + unsigned char command_; + unsigned char port_high_byte_; + unsigned char port_low_byte_; + asio::ip::address_v4::bytes_type address_; + std::string user_id_; + unsigned char null_byte_; +}; + +class reply +{ +public: + enum status_type + { + request_granted = 0x5a, + request_failed = 0x5b, + request_failed_no_identd = 0x5c, + request_failed_bad_user_id = 0x5d + }; + + reply() + : null_byte_(0), + status_() + { + } + + boost::array<asio::mutable_buffer, 5> buffers() + { + boost::array<asio::mutable_buffer, 5> bufs = + { + { + asio::buffer(&null_byte_, 1), + asio::buffer(&status_, 1), + asio::buffer(&port_high_byte_, 1), + asio::buffer(&port_low_byte_, 1), + asio::buffer(address_) + } + }; + return bufs; + } + + bool success() const + { + return null_byte_ == 0 && status_ == request_granted; + } + + unsigned char status() const + { + return status_; + } + + asio::ip::tcp::endpoint endpoint() const + { + unsigned short port = port_high_byte_; + port = (port << 8) & 0xff00; + port = port | port_low_byte_; + + asio::ip::address_v4 address(address_); + + return asio::ip::tcp::endpoint(address, port); + } + +private: + unsigned char null_byte_; + unsigned char status_; + unsigned char port_high_byte_; + unsigned char port_low_byte_; + asio::ip::address_v4::bytes_type address_; +}; + +} // namespace socks4 + +#endif // SOCKS4_HPP diff --git a/3rdparty/asio/src/examples/cpp03/socks4/sync_client.cpp b/3rdparty/asio/src/examples/cpp03/socks4/sync_client.cpp new file mode 100644 index 00000000000..7b82564ab53 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp03/socks4/sync_client.cpp @@ -0,0 +1,94 @@ +// +// sync_client.cpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot 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) +// + +#include <iostream> +#include <iomanip> +#include <ostream> +#include <string> +#include <asio.hpp> +#include <boost/array.hpp> +#include "socks4.hpp" + +using asio::ip::tcp; + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 4) + { + std::cout << "Usage: sync_client <socks4server> <socks4port> <user>\n"; + std::cout << "Examples:\n"; + std::cout << " sync_client 127.0.0.1 1080 chris\n"; + std::cout << " sync_client localhost socks chris\n"; + return 1; + } + + asio::io_context io_context; + + // Get a list of endpoints corresponding to the SOCKS 4 server name. + tcp::resolver resolver(io_context); + tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]); + + // Try each endpoint until we successfully establish a connection to the + // SOCKS 4 server. + tcp::socket socket(io_context); + asio::connect(socket, endpoints); + + // Get an endpoint for the Boost website. This will be passed to the SOCKS + // 4 server. Explicitly specify IPv4 since SOCKS 4 does not support IPv6. + tcp::endpoint http_endpoint = + *resolver.resolve(tcp::v4(), "www.boost.org", "http").begin(); + + // Send the request to the SOCKS 4 server. + socks4::request socks_request( + socks4::request::connect, http_endpoint, argv[3]); + asio::write(socket, socks_request.buffers()); + + // Receive a response from the SOCKS 4 server. + socks4::reply socks_reply; + asio::read(socket, socks_reply.buffers()); + + // Check whether we successfully negotiated with the SOCKS 4 server. + if (!socks_reply.success()) + { + std::cout << "Connection failed.\n"; + std::cout << "status = 0x" << std::hex << socks_reply.status(); + return 1; + } + + // Form the HTTP request. We specify the "Connection: close" header so that + // the server will close the socket after transmitting the response. This + // will allow us to treat all data up until the EOF as the response. + std::string request = + "GET / HTTP/1.0\r\n" + "Host: www.boost.org\r\n" + "Accept: */*\r\n" + "Connection: close\r\n\r\n"; + + // Send the HTTP request. + asio::write(socket, asio::buffer(request)); + + // Read until EOF, writing data to output as we go. + boost::array<char, 512> response; + asio::error_code error; + while (std::size_t s = socket.read_some( + asio::buffer(response), error)) + std::cout.write(response.data(), s); + if (error != asio::error::eof) + throw asio::system_error(error); + } + catch (std::exception& e) + { + std::cout << "Exception: " << e.what() << "\n"; + } + + return 0; +} |