@@ -44,9 +44,10 @@ pub mod client {
4444 io,
4545 io:: { Read , Write } ,
4646 net:: { Ipv4Addr , SocketAddr , SocketAddrV4 , TcpStream , ToSocketAddrs } ,
47+ time:: Duration ,
4748 } ;
4849
49- /// A SOCKS4 client.
50+ /// A SOCKS4 and SOCKS4A client.
5051 #[ derive( Debug ) ]
5152 pub struct Socks4Stream {
5253 pub ( super ) socket : TcpStream ,
@@ -65,25 +66,41 @@ pub mod client {
6566 ///
6667 /// # Errors
6768 /// - `io::Error(std::io::ErrorKind::*, socks2::Error::*?)`
68- pub fn connect < T , U > ( proxy : T , target : & U , userid : & str ) -> io:: Result < Self >
69+ pub fn connect < T , U > (
70+ proxy : T ,
71+ target : & U ,
72+ userid : & str ,
73+ timeout : Option < Duration > ,
74+ ) -> io:: Result < Self >
6975 where
7076 T : ToSocketAddrs ,
7177 U : ToTargetAddr ,
7278 {
73- Self :: connect_raw ( 1 , proxy, target, userid)
79+ Self :: connect_raw ( 1 , proxy, target, userid, timeout )
7480 }
7581
7682 pub ( super ) fn connect_raw < T , U > (
7783 command : u8 ,
7884 proxy : T ,
7985 target : & U ,
8086 userid : & str ,
87+ timeout : Option < Duration > ,
8188 ) -> io:: Result < Self >
8289 where
8390 T : ToSocketAddrs ,
8491 U : ToTargetAddr ,
8592 {
86- let mut socket = TcpStream :: connect ( proxy) ?;
93+ let mut socket = match timeout {
94+ None => TcpStream :: connect ( proxy) ?,
95+ // TODO: Should filter to ipv4 only? Since SOCKS4 only supports that.
96+ Some ( t) => TcpStream :: connect_timeout (
97+ & proxy
98+ . to_socket_addrs ( ) ?
99+ . next ( )
100+ . ok_or_else ( || Error :: NoResolveSocketAddr { } . into_io ( ) ) ?,
101+ t,
102+ ) ?,
103+ } ;
87104
88105 let target = target. to_target_addr ( ) ?;
89106
@@ -186,9 +203,10 @@ pub mod bind {
186203 use std:: {
187204 io,
188205 net:: { SocketAddr , SocketAddrV4 , SocketAddrV6 , ToSocketAddrs } ,
206+ time:: Duration ,
189207 } ;
190208
191- /// A SOCKS4 BIND client.
209+ /// A SOCKS4 and SOCKS4A BIND client.
192210 #[ derive( Debug ) ]
193211 pub struct Socks4Listener ( Socks4Stream ) ;
194212
@@ -200,12 +218,17 @@ pub mod bind {
200218 ///
201219 /// # Errors
202220 /// - `io::Error(std::io::ErrorKind::*, socks2::Error::*?)`
203- pub fn bind < T , U > ( proxy : T , target : & U , userid : & str ) -> io:: Result < Self >
221+ pub fn bind < T , U > (
222+ proxy : T ,
223+ target : & U ,
224+ userid : & str ,
225+ timeout : Option < Duration > ,
226+ ) -> io:: Result < Self >
204227 where
205228 T : ToSocketAddrs ,
206229 U : ToTargetAddr ,
207230 {
208- Socks4Stream :: connect_raw ( 2 , proxy, target, userid) . map ( Socks4Listener )
231+ Socks4Stream :: connect_raw ( 2 , proxy, target, userid, timeout ) . map ( Socks4Listener )
209232 }
210233
211234 /// The address of the proxy-side TCP listener.
@@ -254,6 +277,7 @@ mod test {
254277 use std:: {
255278 io:: { Read , Write } ,
256279 net:: { SocketAddr , SocketAddrV4 , TcpStream , ToSocketAddrs } ,
280+ time:: Duration ,
257281 } ;
258282
259283 const PROXY_ADDR : & str = "127.0.0.1:1084" ;
@@ -272,7 +296,7 @@ mod test {
272296 #[ test]
273297 #[ cfg( feature = "client" ) ]
274298 fn google ( ) {
275- let mut socket = Socks4Stream :: connect ( PROXY_ADDR , & google_ip ( ) , "" ) . unwrap ( ) ;
299+ let mut socket = Socks4Stream :: connect ( PROXY_ADDR , & google_ip ( ) , "" , None ) . unwrap ( ) ;
276300
277301 socket. write_all ( b"GET / HTTP/1.0\r \n \r \n " ) . unwrap ( ) ;
278302 let mut result = vec ! [ ] ;
@@ -287,7 +311,13 @@ mod test {
287311 #[ ignore] // dante doesn't support SOCKS4A
288312 #[ cfg( feature = "client" ) ]
289313 fn google_dns ( ) {
290- let mut socket = Socks4Stream :: connect ( PROXY_ADDR , & "google.com:80" , "" ) . unwrap ( ) ;
314+ let mut socket = Socks4Stream :: connect (
315+ PROXY_ADDR ,
316+ & "google.com:80" ,
317+ "" ,
318+ Some ( Duration :: from_secs ( 10 ) ) ,
319+ )
320+ . unwrap ( ) ;
291321
292322 socket. write_all ( b"GET / HTTP/1.0\r \n \r \n " ) . unwrap ( ) ;
293323 let mut result = vec ! [ ] ;
@@ -302,10 +332,10 @@ mod test {
302332 #[ cfg( feature = "bind" ) ]
303333 fn bind ( ) {
304334 // First figure out our local address that we'll be connecting from
305- let socket = Socks4Stream :: connect ( PROXY_ADDR , & google_ip ( ) , "" ) . unwrap ( ) ;
335+ let socket = Socks4Stream :: connect ( PROXY_ADDR , & google_ip ( ) , "" , None ) . unwrap ( ) ;
306336 let addr = socket. proxy_addr ( ) ;
307337
308- let listener = Socks4Listener :: bind ( PROXY_ADDR , & addr, "" ) . unwrap ( ) ;
338+ let listener = Socks4Listener :: bind ( PROXY_ADDR , & addr, "" , None ) . unwrap ( ) ;
309339 let addr = listener. proxy_addr ( ) . unwrap ( ) ;
310340 let mut end = TcpStream :: connect ( addr) . unwrap ( ) ;
311341 let mut conn = listener. accept ( ) . unwrap ( ) ;
0 commit comments