mirror of
https://github.com/aramperes/onetun.git
synced 2025-09-09 06:38:32 -04:00
Attempt reconnection in virtual client
This commit is contained in:
parent
ed835c47d3
commit
dbced52070
1 changed files with 39 additions and 11 deletions
50
src/main.rs
50
src/main.rs
|
@ -212,7 +212,7 @@ async fn handle_tcp_proxy_connection(
|
||||||
// Wait for virtual client to be ready.
|
// Wait for virtual client to be ready.
|
||||||
virtual_client_ready_rx
|
virtual_client_ready_rx
|
||||||
.await
|
.await
|
||||||
.expect("failed to wait for virtual client to be ready");
|
.with_context(|| "Virtual client dropped before being ready.")?;
|
||||||
trace!("[{}] Virtual client is ready to send data", virtual_port);
|
trace!("[{}] Virtual client is ready to send data", virtual_port);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -351,15 +351,7 @@ async fn virtual_tcp_interface(
|
||||||
static mut TCP_SERVER_TX_DATA: [u8; MAX_PACKET] = [0; MAX_PACKET];
|
static mut TCP_SERVER_TX_DATA: [u8; MAX_PACKET] = [0; MAX_PACKET];
|
||||||
let tcp_rx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_RX_DATA[..] });
|
let tcp_rx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_RX_DATA[..] });
|
||||||
let tcp_tx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_TX_DATA[..] });
|
let tcp_tx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_TX_DATA[..] });
|
||||||
let mut socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
|
let socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
|
||||||
|
|
||||||
socket
|
|
||||||
.connect(
|
|
||||||
(IpAddress::from(dest_addr.ip()), dest_addr.port()),
|
|
||||||
(IpAddress::from(source_peer_ip), virtual_port),
|
|
||||||
)
|
|
||||||
.with_context(|| "Virtual server socket failed to listen")?;
|
|
||||||
|
|
||||||
Ok(socket)
|
Ok(socket)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -372,11 +364,16 @@ async fn virtual_tcp_interface(
|
||||||
// Any data that wasn't sent because it was over the sending buffer limit
|
// Any data that wasn't sent because it was over the sending buffer limit
|
||||||
let mut tx_extra = Vec::new();
|
let mut tx_extra = Vec::new();
|
||||||
|
|
||||||
|
// Counts the connection attempts by the virtual client
|
||||||
|
let mut connection_attempts = 0;
|
||||||
|
// Whether the client has successfully connected before. Prevents the case of connecting again.
|
||||||
|
let mut has_connected = false;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let loop_start = smoltcp::time::Instant::now();
|
let loop_start = smoltcp::time::Instant::now();
|
||||||
|
|
||||||
// Shutdown occurs when the real client closes the connection,
|
// Shutdown occurs when the real client closes the connection,
|
||||||
// or if the client was in a CLOSE-WAIT state (after a server FIN) and had no data to send anmore.
|
// or if the client was in a CLOSE-WAIT state (after a server FIN) and had no data to send anymore.
|
||||||
// One last poll-loop iteration is executed so that the RST segment can be dispatched.
|
// One last poll-loop iteration is executed so that the RST segment can be dispatched.
|
||||||
let shutdown = abort.load(Ordering::Relaxed);
|
let shutdown = abort.load(Ordering::Relaxed);
|
||||||
|
|
||||||
|
@ -403,6 +400,37 @@ async fn virtual_tcp_interface(
|
||||||
{
|
{
|
||||||
let mut client_socket = socket_set.get::<TcpSocket>(client_handle);
|
let mut client_socket = socket_set.get::<TcpSocket>(client_handle);
|
||||||
|
|
||||||
|
if !shutdown && client_socket.state() == TcpState::Closed && !has_connected {
|
||||||
|
// Not shutting down, but the client socket is closed, and the client never successfully connected.
|
||||||
|
if connection_attempts < 10 {
|
||||||
|
// Try to connect
|
||||||
|
client_socket
|
||||||
|
.connect(
|
||||||
|
(IpAddress::from(dest_addr.ip()), dest_addr.port()),
|
||||||
|
(IpAddress::from(source_peer_ip), virtual_port),
|
||||||
|
)
|
||||||
|
.with_context(|| "Virtual server socket failed to listen")?;
|
||||||
|
if connection_attempts > 0 {
|
||||||
|
debug!(
|
||||||
|
"[{}] Virtual client retrying connection in 500ms",
|
||||||
|
virtual_port
|
||||||
|
);
|
||||||
|
// Not our first connection attempt, wait a little bit.
|
||||||
|
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Too many connection attempts
|
||||||
|
abort.store(true, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
connection_attempts += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if client_socket.state() == TcpState::Established {
|
||||||
|
// Prevent reconnection if the server later closes.
|
||||||
|
has_connected = true;
|
||||||
|
}
|
||||||
|
|
||||||
if client_socket.can_recv() {
|
if client_socket.can_recv() {
|
||||||
match client_socket.recv(|buffer| (buffer.len(), buffer.to_vec())) {
|
match client_socket.recv(|buffer| (buffer.len(), buffer.to_vec())) {
|
||||||
Ok(data) => {
|
Ok(data) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue