Accept loop: for each incoming TCP connection, spawn a handler that opens a WebSocket to the edge and pipes bytes bidirectionally.
(listener: TcpListener, config: Arc<TunnelConfig>)
| 97 | /// Accept loop: for each incoming TCP connection, spawn a handler that |
| 98 | /// opens a WebSocket to the edge and pipes bytes bidirectionally. |
| 99 | async fn accept_loop(listener: TcpListener, config: Arc<TunnelConfig>) { |
| 100 | loop { |
| 101 | match listener.accept().await { |
| 102 | Ok((stream, peer)) => { |
| 103 | debug!(peer = %peer, "accepted local tunnel connection"); |
| 104 | let config = Arc::clone(&config); |
| 105 | tokio::spawn(async move { |
| 106 | if let Err(e) = handle_connection(stream, &config).await { |
| 107 | warn!(peer = %peer, error = %e, "tunnel connection failed"); |
| 108 | } |
| 109 | }); |
| 110 | } |
| 111 | Err(e) => { |
| 112 | error!(error = %e, "failed to accept tunnel connection"); |
| 113 | // Brief backoff to avoid tight error loops. |
| 114 | tokio::time::sleep(std::time::Duration::from_millis(100)).await; |
| 115 | } |
| 116 | } |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | /// Handle a single tunneled connection: open a WebSocket to the edge and |
| 121 | /// bidirectionally copy bytes. |
no test coverage detected