diff --git a/src/relay/tcprelay/connection.rs b/src/relay/tcprelay/connection.rs index 47f8ccf8..9ea22cb8 100644 --- a/src/relay/tcprelay/connection.rs +++ b/src/relay/tcprelay/connection.rs @@ -90,6 +90,11 @@ where pub fn get_ref(&self) -> &S { self.stream.get_ref() } + + /// Get the internal stream and consume this Connection + pub fn into_inner(self) -> S { + self.stream.into_inner() + } } #[inline] diff --git a/src/relay/tcprelay/crypto_io.rs b/src/relay/tcprelay/crypto_io.rs index 21b845dc..191f8d06 100644 --- a/src/relay/tcprelay/crypto_io.rs +++ b/src/relay/tcprelay/crypto_io.rs @@ -140,6 +140,11 @@ impl CryptoStream { pub fn get_ref(&self) -> &S { &self.stream } + + /// Consume the CryptoStream and return the internal stream instance + pub fn into_inner(self) -> S { + self.stream + } } impl CryptoStream diff --git a/src/relay/tcprelay/monitor.rs b/src/relay/tcprelay/monitor.rs index b569dc5f..86bd6a2f 100644 --- a/src/relay/tcprelay/monitor.rs +++ b/src/relay/tcprelay/monitor.rs @@ -24,6 +24,10 @@ impl TcpMonStream { pub fn new(flow_stat: SharedServerFlowStatistic, stream: S) -> TcpMonStream { TcpMonStream { stream, flow_stat } } + + pub fn into_inner(self) -> S { + self.stream + } } impl AsyncRead for TcpMonStream diff --git a/src/relay/tcprelay/server.rs b/src/relay/tcprelay/server.rs index 94232720..0e93bb70 100644 --- a/src/relay/tcprelay/server.rs +++ b/src/relay/tcprelay/server.rs @@ -58,6 +58,12 @@ async fn handle_client( "failed to decode Address, may be wrong method or key, from client {}, error: {}", peer_addr, err ); + + // Hold the TCP connection until it closes by itself for preventing active probing. + // Further discussion: https://github.com/shadowsocks/shadowsocks-rust/issues/292 + let mut tcp = stream.into_inner().into_inner().into_inner(); + let _ = super::ignore_until_end(&mut tcp).await; + return Err(From::from(err)); } };