fix: TCP 双向转发半关闭时不再截断对端数据
问题:tcp_port_mapping::stream_copy 与 tcp_nat::stream_nat 用 tokio::select! 组合两个 io::copy,任一方向先结束就 drop 另一方向。 客户端半关闭(shutdown 写方向)后,服务端的响应数据会被静默截断。 修复:抽出 copy_bidirectional_split,用 tokio::io::join 合并分离的 读写半部后走 copy_bidirectional——任一方向 EOF 时对另一端 shutdown 并继续转发剩余方向,直到双向完成。 测试:test_half_close_no_truncation 用 duplex 流验证半关闭后响应 完整送达(旧实现此处读到空数据)。
This commit is contained in:
@@ -78,8 +78,8 @@ async fn stream_task(
|
||||
}
|
||||
|
||||
pub(crate) async fn stream_nat<R, W, A: ToSocketAddrs + Debug>(
|
||||
mut recv_stream: R,
|
||||
mut send_stream: W,
|
||||
recv_stream: R,
|
||||
send_stream: W,
|
||||
addr: A,
|
||||
) -> anyhow::Result<()>
|
||||
where
|
||||
@@ -89,10 +89,11 @@ where
|
||||
let mut tokio_stream = TcpStream::connect(&addr)
|
||||
.await
|
||||
.with_context(|| format!("error connecting to {:?}", addr))?;
|
||||
let (mut tcp_r, mut tcp_w) = tokio_stream.split();
|
||||
tokio::select! {
|
||||
_ = tokio::io::copy(&mut recv_stream, &mut tcp_w) => {},
|
||||
_ = tokio::io::copy(&mut tcp_r, &mut send_stream) => {},
|
||||
}
|
||||
crate::port_mapping::tcp_port_mapping::copy_bidirectional_split(
|
||||
&mut tokio_stream,
|
||||
recv_stream,
|
||||
send_stream,
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user