use std::net::{Ipv4Addr, SocketAddrV4};
use tokio::io::{self, AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
async fn socks5_bind_client(
socks5_addr: &str,
bind_addr: SocketAddrV4,
) -> Result<(), Box<dyn std::error::Error>> {
let mut stream = TcpStream::connect(socks5_addr).await?;
println!("Connected to SOCKS5 server");
stream.write_all(&[0x05, 0x01, 0x00]).await?;
let mut buf = [0u8; 2];
stream.read_exact(&mut buf).await?;
if buf[0] != 0x05 || buf[1] != 0x00 {
return Err("Unsupported SOCKS5 method".into());
}
println!("Handshake completed");
let mut request = vec![0x05, 0x02, 0x00, 0x01]; request.extend_from_slice(&bind_addr.ip().octets()); let s = &bind_addr.port().to_be_bytes();
request.extend(&s.to_vec());
println!("bind addr {}", bind_addr);
stream.write_all(&request).await?;
println!("BIND request sent");
let mut response = [0u8; 10]; stream.read_exact(&mut response).await?;
if response[1] != 0x00 {
return Err("BIND request failed".into());
}
println!("response {:?}", response);
let bnd_port = ((response[8] as u16) << 8) | response[9] as u16;
println!("Server is listening on port: {}", bnd_port);
let mut second_response = [0u8; 10];
stream.read_exact(&mut second_response).await?;
if second_response[1] != 0x00 {
return Err("BIND connection failed".into());
}
println!("second_response {:?}", second_response);
println!("BIND connection established");
let mut s = TcpStream::connect("127.0.0.1:8080").await?;
io::copy_bidirectional(&mut s, &mut stream).await?;
Ok(())
}
#[tokio::main]
async fn main() {
if let Err(e) = socks5_bind_client(
"127.0.0.1:1080",
SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8081),
)
.await
{
eprintln!("Error: {}", e);
}
}