Run a TCP port forwarder: listen on `listen_addr`, forward to `target`.
(
listen_addr: SocketAddr,
target: SocketAddr,
cancel: CancellationToken,
)
| 11 | |
| 12 | /// Run a TCP port forwarder: listen on `listen_addr`, forward to `target`. |
| 13 | pub async fn run_tcp_forwarder( |
| 14 | listen_addr: SocketAddr, |
| 15 | target: SocketAddr, |
| 16 | cancel: CancellationToken, |
| 17 | ) { |
| 18 | let listener = match TcpListener::bind(listen_addr).await { |
| 19 | Ok(l) => l, |
| 20 | Err(e) => { |
| 21 | tracing::error!("tcp bind {listen_addr} failed: {e}"); |
| 22 | return; |
| 23 | } |
| 24 | }; |
| 25 | tracing::info!("tcp forwarding {listen_addr} -> {target}"); |
| 26 | |
| 27 | loop { |
| 28 | tokio::select! { |
| 29 | _ = cancel.cancelled() => break, |
| 30 | result = listener.accept() => { |
| 31 | let (client, peer) = match result { |
| 32 | Ok(v) => v, |
| 33 | Err(e) => { |
| 34 | tracing::warn!("tcp accept on {listen_addr}: {e}"); |
| 35 | continue; |
| 36 | } |
| 37 | }; |
| 38 | let cancel = cancel.child_token(); |
| 39 | tokio::spawn(handle_tcp_connection(client, peer, target, cancel)); |
| 40 | } |
| 41 | } |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | async fn handle_tcp_connection( |
| 46 | mut client: TcpStream, |
no outgoing calls