11//! Shadowsocks TCP server
22
33use std:: {
4+ future:: Future ,
45 io:: { self , ErrorKind } ,
56 net:: SocketAddr ,
67 sync:: Arc ,
@@ -22,7 +23,11 @@ use shadowsocks::{
2223 ProxyListener ,
2324 ServerConfig ,
2425} ;
25- use tokio:: { net:: TcpStream as TokioTcpStream , time} ;
26+ use tokio:: {
27+ io:: { AsyncReadExt , AsyncWriteExt } ,
28+ net:: TcpStream as TokioTcpStream ,
29+ time,
30+ } ;
2631
2732use crate :: net:: { utils:: ignore_until_end, MonProxyStream } ;
2833
@@ -77,6 +82,20 @@ impl TcpServer {
7782 }
7883}
7984
85+ #[ inline]
86+ async fn timeout_fut < F , R > ( duration : Option < Duration > , f : F ) -> io:: Result < R >
87+ where
88+ F : Future < Output = io:: Result < R > > ,
89+ {
90+ match duration {
91+ None => f. await ,
92+ Some ( d) => match time:: timeout ( d, f) . await {
93+ Ok ( o) => o,
94+ Err ( ..) => Err ( ErrorKind :: TimedOut . into ( ) ) ,
95+ } ,
96+ }
97+ }
98+
8099struct TcpServerClient {
81100 context : Arc < ServiceContext > ,
82101 method : CipherKind ,
@@ -123,38 +142,56 @@ impl TcpServerClient {
123142 return Ok ( ( ) ) ;
124143 }
125144
126- let mut remote_stream = match self . timeout {
127- Some ( d) => {
128- match time:: timeout (
129- d,
130- OutboundTcpStream :: connect_remote_with_opts (
131- self . context . context_ref ( ) ,
132- & target_addr,
133- self . context . connect_opts_ref ( ) ,
134- ) ,
135- )
136- . await
137- {
138- Ok ( Ok ( s) ) => s,
139- Ok ( Err ( e) ) => return Err ( e) ,
140- Err ( ..) => {
141- return Err ( io:: Error :: new (
142- ErrorKind :: TimedOut ,
143- format ! ( "connect {} timeout" , target_addr) ,
144- ) )
145- }
146- }
147- }
148- None => {
149- OutboundTcpStream :: connect_remote_with_opts (
150- self . context . context_ref ( ) ,
151- & target_addr,
152- self . context . connect_opts_ref ( ) ,
153- )
154- . await ?
145+ let mut remote_stream = match timeout_fut (
146+ self . timeout ,
147+ OutboundTcpStream :: connect_remote_with_opts (
148+ self . context . context_ref ( ) ,
149+ & target_addr,
150+ self . context . connect_opts_ref ( ) ,
151+ ) ,
152+ )
153+ . await
154+ {
155+ Ok ( s) => s,
156+ Err ( err) => {
157+ error ! (
158+ "tcp tunnel {} -> {} connect failed, error: {}" ,
159+ self . peer_addr, target_addr, err
160+ ) ;
161+ return Err ( err) ;
155162 }
156163 } ;
157164
165+ // https://github.com/shadowsocks/shadowsocks-rust/issues/232
166+ //
167+ // Protocols like FTP, clients will wait for servers to send Welcome Message without sending anything.
168+ //
169+ // Wait at most 500ms, and then sends handshake packet to remote servers.
170+ if self . context . connect_opts_ref ( ) . tcp . fastopen {
171+ let mut buffer = [ 0u8 ; 8192 ] ;
172+ match time:: timeout ( Duration :: from_millis ( 500 ) , self . stream . read ( & mut buffer) ) . await {
173+ Ok ( Ok ( 0 ) ) => {
174+ // EOF. Just terminate right here.
175+ return Ok ( ( ) ) ;
176+ }
177+ Ok ( Ok ( n) ) => {
178+ // Send the first packet.
179+ timeout_fut ( self . timeout , remote_stream. write_all ( & buffer[ ..n] ) ) . await ?;
180+ }
181+ Ok ( Err ( err) ) => return Err ( err) ,
182+ Err ( ..) => {
183+ // Timeout. Send handshake to server.
184+ timeout_fut ( self . timeout , remote_stream. write ( & [ ] ) ) . await ?;
185+
186+ trace ! (
187+ "tcp tunnel {} -> {} sent TFO connect without data" ,
188+ self . peer_addr,
189+ target_addr
190+ ) ;
191+ }
192+ }
193+ }
194+
158195 let ( mut lr, mut lw) = self . stream . into_split ( ) ;
159196 let ( mut rr, mut rw) = remote_stream. split ( ) ;
160197
0 commit comments