I am writing socks5 proxy server. The program is running asynchronously and I am trying to use tokio::select
, but the program terminates due to this error when I want to get the size of the received data:
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 54, kind: ConnectionReset, message: "Connection reset by peer" }'
The function where the error occurs:
async fn exchange_loop(mut client: TcpStream, address: SocketAddr, cmd: u8) {
let mut remote = TcpStream::connect(address).await.unwrap();
let mut buffer_client: [u8; 4096] = [0; 4096];
let mut buffer_remote: [u8; 4096] = [0; 4096];
loop {
tokio::select! {
size = client.read(&mut buffer_client) => {
let size = size.unwrap();
remote.write(buffer_client.as_ref()).await.unwrap();
println!("Send from client {} => {} {} KB", client.peer_addr().unwrap(), remote.peer_addr().unwrap(), size as f32 / 1024.);
if size <= 0 {
break;
};
buffer_client = [0; 4096];
}
size = remote.read(&mut buffer_remote) => {
let size = size.unwrap();
client.write(buffer_remote.as_ref()).await.unwrap();
println!("Send from remote {} => {} {} KB", address, client.peer_addr().unwrap(), size as f32 / 1024.);
if size <= 0 {
break;
};
buffer_remote = [0; 4096];
}
}
}
println!("End connection to {}", address);
}
You need to handle errors, as specified in the previous comments. You need to be able to recover from whatever the client does on his side, interrupting the connection for example.
An example how to recover:
I put Ok(_) as I do not know what you expect from the 2nd unwrap.