use tokio::net::{TcpListener, TcpStream};
use tokio::io::copy_bidirectional;
use tokio_socks::tcp::Socks5Stream;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let listen_addr = "127.0.0.1:5656";
let socks5_proxy = "127.0.0.1:9050"; let hidden_service_addr = "5i6blbmuflq4s4im6zby26a7g22oef6kyp7vbwyru6oq5e36akzo3ayd.onion:2001";
let listener = TcpListener::bind(listen_addr).await?;
println!("Tunnel is listening on {}", listen_addr);
loop {
let (client_stream, client_addr) = listener.accept().await?;
println!("Accepted connection from {}", client_addr);
let hidden_service_addr = hidden_service_addr.to_string();
let socks5_proxy = socks5_proxy.to_string();
tokio::spawn(async move {
if let Err(e) = handle_client(client_stream, &socks5_proxy, &hidden_service_addr).await {
eprintln!("Error handling client {}: {:?}", client_addr, e);
}
});
}
}
async fn handle_client(
mut client_stream: TcpStream,
socks5_proxy: &str,
hidden_service_addr: &str,
) -> Result<(), Box<dyn Error>> {
let mut remote_stream = Socks5Stream::connect(socks5_proxy, hidden_service_addr).await?.into_inner();
println!("Connected to hidden service at {}", hidden_service_addr);
copy_bidirectional(&mut client_stream, &mut remote_stream).await?;
println!("Connection to {} closed", hidden_service_addr);
Ok(())
}