TcpListener::accept() in tokio::spawn() hangs the app

⚓ Rust    📅 2026-06-18    👤 surdeus    👁️ 1      

surdeus

Hi folks! :victory_hand: Here's me again :sweat_smile:.

async fn start_ssh_tunnel(password: String) -> Result<(), Box<dyn std::error::Error>> {
    let addr = format!("{}:{}", SSH_HOST, SSH_PORT);

    let ssh_client = IHandler {};
    let mut session = russh::client::connect(
        Arc::new(Config::default()),
        addr,
        ssh_client
    ).await?;
    session.authenticate_password(SSH_USER, password).await?;

    let listener = TcpListener::bind(SocketAddrV4::new(Ipv4Addr::LOCALHOST, FORWARDING_PORT)).await?;
    let addr = listener.local_addr()?;

    tokio::spawn(async move {
        let (mut socket, _) = listener.accept().await.unwrap();

        let channel = session.channel_open_direct_tcpip(
            SSH_HOST, FORWARDING_PORT as u32,
            Ipv4Addr::LOCALHOST.to_string(), addr.port() as u32
        ).await.unwrap();
        let mut stream = channel.into_stream();

        tokio::io::copy_bidirectional(
            &mut socket, &mut stream
        ).await.unwrap();
    });

    Ok(())
}

I want to implement an SSH forwarding. Some problems begins from here:

let (mut socket, _) = listener.accept().await.unwrap();

The app just hangs in this moment, and doesn't want to execute next commands.

I've check it by adding something like this:

...

println!("Hello!");

let (mut socket, _) = listener.accept().await.unwrap();

println!("Hello!");

let channel = session.channel_open_direct_tcpip(
    SSH_HOST, FORWARDING_PORT as u32,
    Ipv4Addr::LOCALHOST.to_string(), addr.port() as u32
).await.unwrap();

...

Hello! text prints only once in a terminal.

The function above calls from this funtion:

...

pub fn connect(password: String) -> Result<Backend, String> {
    let runtime = tokio::runtime::Runtime::new().map_err(|e| format!("Failed to create async runtime: {e}"))?;

    runtime.block_on(async { 
        start_ssh_tunnel(password).await
    }).map_err(|e| format!("Failed to create SSH tunnel: {e}"))?;
    
    ...
}

...

That is not async.

Please, let me know - how to fix that? :thinking:

2 posts - 2 participants

Read full topic

🏷️ Rust_feed