0

I am trying to create socks5 proxy but I have problem to read valid address type. I have configured the socks5 proxy in firefox to test. I also tried with firewall disabled. No matter if I enter domain name,ipv4 or ipv6 address there is always address_type 0. I also tried using read_some or read with client_socket but the result was the same.

#include <boost/asio.hpp>
#include <iostream>

const int BUFFER_SIZE = 4096;
const int SOCKS_VERSION = 5;
const int PORT = 1080;

class server {
public:
  server(boost::asio::io_context& io_context)
  : acceptor_(io_context, boost::asio::ip::tcp::endpoint(
                              boost::asio::ip::tcp::v4(), PORT)) {
start_accept();
}

private:
class session : public std::enable_shared_from_this<session> {
public:
explicit session(boost::asio::ip::tcp::socket socket)
    : client_socket_(std::move(socket)),
      server_socket_(client_socket_.get_executor()) {
  memset(client_data_, 0, BUFFER_SIZE);
}

void start() { read_socks_request(); }

private:
void read_socks_request() {
  std::cout << "Reading SOCKS request from client..." << std::endl;
  client_socket_.async_read_some(
      boost::asio::buffer(client_data_, BUFFER_SIZE),
      [self = shared_from_this()](boost::system::error_code error,
                                  std::size_t bytes_transferred) {
        self->handle_socks_request(error, bytes_transferred);
      });

  int version = static_cast<unsigned char>(client_data_[0]);
  std::cout << "SENT SOCKS version: " << version << std::endl;
  int address_type = static_cast<unsigned char>(client_data_[3]);
  std::cout << "sent SOCKS address type: " << address_type << std::endl;
  std::endl(std::cout);
}

void handle_socks_request(const boost::system::error_code& error,
                          std::size_t bytes_transferred) {
  if (!error) {
    int version = static_cast<unsigned char>(client_data_[0]);
    int command = static_cast<unsigned char>(client_data_[1]);
    int reserved = static_cast<unsigned char>(client_data_[2]);
    int address_type = static_cast<unsigned char>(client_data_[3]);

    std::cout << "Received SOCKS version: " << version << std::endl;
    std::cout << "Received SOCKS command: " << command << std::endl;
    std::cout << "Received SOCKS reserved: " << reserved << std::endl;
    std::cout << "Received SOCKS address type: " << address_type
              << std::endl;

    if (version == SOCKS_VERSION) {
      if (address_type == 1) {
        std::cout << "Ipv4 address" << std::endl;
      } else if (address_type == 3) {
        std::cout << "Domain name" << std::endl;
      } else if (address_type == 4) {
        std::cout << "IPv6 address" << std::endl;
      } else {
        std::cerr << "Invalid SOCKS address type " << std::endl;
      }
    } else {
      std::cerr << "Invalid SOCKS version" << std::endl;
    }
  } else {
    std::cerr << "Error in handle_socks_request: " << error.message()
              << std::endl;
  }
}
boost::asio::ip::tcp::socket client_socket_;
boost::asio::ip::tcp::socket server_socket_;

char client_data_[BUFFER_SIZE];
char server_data_[BUFFER_SIZE];
};

void start_accept() {
auto socket = std::make_shared<boost::asio::ip::tcp::socket>(
    acceptor_.get_executor());

acceptor_.async_accept(
    *socket, [this, socket](const boost::system::error_code& error) {
      if (!error) {
        std::make_shared<session>(std::move(*socket))->start();
      }
      start_accept();
    });
}

boost::asio::ip::tcp::acceptor acceptor_;
};

int main() {
try {
boost::asio::io_context io_context;
server server(io_context);
std::cout << "Proxy server started." << std::endl;

io_context.run();
} catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "\n";
}

return 0;
}

My output

Proxy server started.
Reading SOCKS request from client...
SENT SOCKS version: 5
sent SOCKS address type: 0

Received SOCKS version: 5
Received SOCKS command: 1
Received SOCKS reserved: 0
Received SOCKS address type: 0
Invalid SOCKS address type
manjitolo
  • 53
  • 6
  • You ignore bytes_transferred. Really, `read_some` isn't the right abstraction level. At least check how many bytes you receive. You may still compare notes with my client implementation that I linked on your previous question: https://stackoverflow.com/a/69781530/85371 – sehe Aug 20 '23 at 10:16

0 Answers0