int socks_connection::format_response(asio::ip::tcp::endpoint const& ep , int response) { int i = 0; if (m_version == 5) { // +----+-----+-------+------+----------+----------+ // |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | // +----+-----+-------+------+----------+----------+ // | 1 | 1 | X'00' | 1 | Variable | 2 | // +----+-----+-------+------+----------+----------+ m_in_buffer[i++] = m_version; // version m_in_buffer[i++] = response; // response m_in_buffer[i++] = 0; // reserved if (ep.address().is_v4()) { m_in_buffer[i++] = 1; // IPv4 address_v4::bytes_type b = ep.address().to_v4().to_bytes(); memcpy(&m_in_buffer[i], &b[0], b.size()); i += b.size(); } else { m_in_buffer[i++] = 4; // IPv6 address_v6::bytes_type b = ep.address().to_v6().to_bytes(); memcpy(&m_in_buffer[i], &b[0], b.size()); i += b.size(); } m_in_buffer[i++] = ep.port() >> 8; m_in_buffer[i++] = ep.port() & 0xff; }
void socks_connection::bind_connection(asio::ip::tcp::endpoint target) { printf("socks_connection::bind_connection(%s): binding to %s port %d\n" , command(), target.address().to_string().c_str(), target.port()); error_code ec; m_bind_socket.open(target.protocol(), ec); if (ec) { printf("ERROR: open bind socket failed: (%d) %s\n", ec.value() , ec.message().c_str()); } else { m_bind_socket.bind(target, ec); } int const response = ec ? (m_version == 4 ? 91 : 1) : (m_version == 4 ? 90 : 0); int const len = format_response( m_bind_socket.local_endpoint(), response); if (ec) { printf("ERROR: binding socket to %s %d failed: (%d) %s\n" , target.address().to_string().c_str() , target.port() , ec.value() , ec.message().c_str()); auto self = shared_from_this(); asio::async_write(m_client_connection , asio::const_buffers_1(&m_in_buffer[0], len) , [=](boost::system::error_code const& ec, size_t) { self->close_connection(); }); return; } // send response asio::async_write(m_client_connection , asio::const_buffers_1(&m_in_buffer[0], len) , std::bind(&socks_connection::start_accept, shared_from_this(), _1)); }
void socks_connection::open_forward_connection(asio::ip::tcp::endpoint target) { printf("socks_connection::open_forward_connection(%s): connecting to %s port %d\n" , command(), target.address().to_string().c_str(), target.port()); m_server_connection.open(target.protocol()); m_server_connection.async_connect(target , std::bind(&socks_connection::on_connected, shared_from_this() , _1)); }
/** If ep is local then isUseNamedPipe is true */ bool connections::isUseNamedPipe(asio::ip::tcp::endpoint& ep) { asio::ip::tcp::endpoint local(ip::address::from_string("127.0.0.1"), ep.port()); if (local == ep) return true; char buf[MAX_PATH]; if (::gethostname(buf, MAX_PATH) == 0) { boost::system::error_code ec; local = endpoint(buf, m_port, ec); if (local == ep) return true; } return false; }