Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions include/simulator/socks_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,18 @@ enum socks_flag
udp_associate_respond_empty_hostname = 2
};

// Override UDP response fields to simulate malformed proxy replies.
struct socks_udp_header
{
std::uint16_t reserved = 0;
// A negative value preserves the address type of the forwarded packet.
int address_type = -1;
};

struct SIMULATOR_DECL socks_connection : std::enable_shared_from_this<socks_connection>
{
socks_connection(asio::io_context& ios, int version, std::array<int, 3>& cmd_counts
, std::uint32_t flags, int& bind_port);
, std::uint32_t flags, int& bind_port, socks_udp_header header);

asio::ip::tcp::socket& socket() { return m_client_connection; }

Expand Down Expand Up @@ -149,14 +157,15 @@ struct SIMULATOR_DECL socks_connection : std::enable_shared_from_this<socks_conn
std::array<int, 3>& m_cmd_counts;

std::uint32_t const m_flags;
socks_udp_header const m_udp_header;
};

// This is a very simple socks4 and 5 server that only supports a single
// concurrent connection
struct SIMULATOR_DECL socks_server
{
socks_server(asio::io_context& ios, unsigned short listen_port
, int version = 5, std::uint32_t flags = 0);
, int version = 5, std::uint32_t flags = 0, socks_udp_header header = {});

void stop();

Expand Down Expand Up @@ -190,6 +199,7 @@ struct SIMULATOR_DECL socks_server
std::array<int, 3> m_cmd_counts;

std::uint32_t const m_flags;
socks_udp_header const m_udp_header;
};

}
Expand Down
29 changes: 18 additions & 11 deletions src/socks_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ namespace sim
using namespace aux;

socks_server::socks_server(io_context& ios, unsigned short listen_port, int version
, std::uint32_t const flags)
, std::uint32_t const flags, socks_udp_header const header)
: m_ios(ios)
, m_listen_socket(ios)
, m_conn(std::make_shared<socks_connection>(m_ios, version, m_cmd_counts, flags, m_bind_port))
, m_conn(std::make_shared<socks_connection>(
m_ios, version, m_cmd_counts, flags, m_bind_port, header))
, m_version(version)
, m_flags(flags)
, m_udp_header(header)
{
m_cmd_counts.fill(0);
address local_ip = ios.get_ips().front();
Expand Down Expand Up @@ -77,7 +79,8 @@ namespace sim
m_conn->start();

// create a new connection to accept into
m_conn = std::make_shared<socks_connection>(m_ios, m_version, m_cmd_counts, m_flags, m_bind_port);
m_conn = std::make_shared<socks_connection>(
m_ios, m_version, m_cmd_counts, m_flags, m_bind_port, m_udp_header);

// now we can accept another connection
m_listen_socket.async_accept(m_conn->socket(), m_ep
Expand All @@ -91,7 +94,8 @@ namespace sim
}

socks_connection::socks_connection(asio::io_context& ios
, int version, std::array<int, 3>& cmd_counts, std::uint32_t const flags, int& bind_port)
, int version, std::array<int, 3>& cmd_counts, std::uint32_t const flags
, int& bind_port, socks_udp_header const header)
: m_bind_port(bind_port)
, m_ios(ios)
, m_udp_resolver(ios)
Expand All @@ -106,6 +110,7 @@ namespace sim
, m_command(0)
, m_cmd_counts(cmd_counts)
, m_flags(flags)
, m_udp_header(header)
{
}

Expand Down Expand Up @@ -620,7 +625,7 @@ namespace sim
if (atyp == 3)
{
// hostname
int const len = buf[4];
int const len = static_cast<unsigned char>(buf[4]);

buf += 5;
bytes_transferred -= 5;
Expand Down Expand Up @@ -708,10 +713,11 @@ namespace sim
if (it != m_name_mapping.left.end())
{
std::vector<char> header(7 + it->second.size());
header[0] = 0; // RSV
header[1] = 0;
header[0] = static_cast<char>(m_udp_header.reserved >> 8); // RSV
header[1] = static_cast<char>(m_udp_header.reserved & 0xff);
header[2] = 0; // fragment
header[3] = 3; // ATYP
header[3] = static_cast<char>(
m_udp_header.address_type < 0 ? 3 : m_udp_header.address_type); // ATYP
header[4] = static_cast<char>(it->second.size());
int idx = 5;
std::copy(it->second.begin(), it->second.end(), header.data() + idx);
Expand All @@ -732,10 +738,11 @@ namespace sim
// add UDP ASSOCIATE header and forward to client
std::uint32_t const from_addr = m_udp_from.address().to_v4().to_uint();
std::array<char, 10> header;
header[0] = 0; // RSV
header[1] = 0;
header[0] = static_cast<char>(m_udp_header.reserved >> 8); // RSV
header[1] = static_cast<char>(m_udp_header.reserved & 0xff);
header[2] = 0; // fragment
header[3] = 1; // ATYP
header[3] = static_cast<char>(
m_udp_header.address_type < 0 ? 1 : m_udp_header.address_type); // ATYP
header[4] = (from_addr >> 24) & 0xff; // Address
header[5] = (from_addr >> 16) & 0xff;
header[6] = (from_addr >> 8) & 0xff;
Expand Down