Handle a single tunneled connection: open a WebSocket to the edge and bidirectionally copy bytes.
(tcp_stream: TcpStream, config: &TunnelConfig)
| 120 | /// Handle a single tunneled connection: open a WebSocket to the edge and |
| 121 | /// bidirectionally copy bytes. |
| 122 | async fn handle_connection(tcp_stream: TcpStream, config: &TunnelConfig) -> Result<()> { |
| 123 | let ws_stream = open_ws(config).await?; |
| 124 | let (ws_sink, ws_source) = ws_stream.split(); |
| 125 | let (tcp_read, tcp_write) = tokio::io::split(tcp_stream); |
| 126 | |
| 127 | // Two tasks: TCP->WS and WS->TCP. Abort the peer task once either |
| 128 | // direction finishes so the connection tears down promptly. |
| 129 | let mut tcp_to_ws = tokio::spawn(copy_tcp_to_ws(tcp_read, ws_sink)); |
| 130 | let mut ws_to_tcp = tokio::spawn(copy_ws_to_tcp(ws_source, tcp_write)); |
| 131 | |
| 132 | tokio::select! { |
| 133 | res = &mut tcp_to_ws => { |
| 134 | if let Err(e) = res { |
| 135 | debug!(error = %e, "tcp->ws task panicked"); |
| 136 | } |
| 137 | ws_to_tcp.abort(); |
| 138 | } |
| 139 | res = &mut ws_to_tcp => { |
| 140 | if let Err(e) = res { |
| 141 | debug!(error = %e, "ws->tcp task panicked"); |
| 142 | } |
| 143 | tcp_to_ws.abort(); |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | Ok(()) |
| 148 | } |
| 149 | |
| 150 | /// Open a WebSocket connection to the edge proxy. |
| 151 | async fn open_ws(config: &TunnelConfig) -> Result<WebSocketStream<MaybeTlsStream<TcpStream>>> { |
no test coverage detected