@@ -27,7 +27,7 @@ use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode};
27
27
use rustls:: { ClientConfig , ClientSession , StreamOwned } ;
28
28
29
29
#[ cfg( any( feature = "default" , feature = "proxy" ) ) ]
30
- use socks:: { Socks5Stream , ToTargetAddr } ;
30
+ use socks:: { Socks5Stream , TargetAddr , ToTargetAddr } ;
31
31
32
32
use stream:: ClonableStream ;
33
33
@@ -75,6 +75,28 @@ impl ToSocketAddrsDomain for (&str, u16) {
75
75
}
76
76
}
77
77
78
+ impl ToSocketAddrsDomain for TargetAddr {
79
+ fn domain ( & self ) -> Option < & str > {
80
+ match self {
81
+ TargetAddr :: Ip ( _) => None ,
82
+ TargetAddr :: Domain ( domain, _) => Some ( domain. as_str ( ) ) ,
83
+ }
84
+ }
85
+ }
86
+
87
+ macro_rules! impl_to_socket_addrs_domain {
88
+ ( $ty: ty ) => {
89
+ impl ToSocketAddrsDomain for $ty { }
90
+ } ;
91
+ }
92
+
93
+ impl_to_socket_addrs_domain ! ( std:: net:: SocketAddr ) ;
94
+ impl_to_socket_addrs_domain ! ( std:: net:: SocketAddrV4 ) ;
95
+ impl_to_socket_addrs_domain ! ( std:: net:: SocketAddrV6 ) ;
96
+ impl_to_socket_addrs_domain ! ( ( std:: net:: IpAddr , u16 ) ) ;
97
+ impl_to_socket_addrs_domain ! ( ( std:: net:: Ipv4Addr , u16 ) ) ;
98
+ impl_to_socket_addrs_domain ! ( ( std:: net:: Ipv6Addr , u16 ) ) ;
99
+
78
100
/// Instance of an Electrum client
79
101
///
80
102
/// A `Client` maintains a constant connection with an Electrum server and exposes methods to
@@ -327,8 +349,8 @@ impl RawClient<ElectrumSslStream> {
327
349
pub type ElectrumProxyStream = Socks5Stream ;
328
350
#[ cfg( any( feature = "default" , feature = "proxy" ) ) ]
329
351
impl RawClient < ElectrumProxyStream > {
330
- /// Creates a new socks client and tries to connect to `target_addr` using `proxy_addr` as an
331
- /// unauthenticated socks proxy server. The DNS resolution of `target_addr`, if required, is done
352
+ /// Creates a new socks client and tries to connect to `target_addr` using `proxy_addr` as a
353
+ /// socks proxy server. The DNS resolution of `target_addr`, if required, is done
332
354
/// through the proxy. This allows to specify, for instance, `.onion` addresses.
333
355
pub fn new_proxy < T : ToTargetAddr > (
334
356
target_addr : T ,
@@ -346,6 +368,30 @@ impl RawClient<ElectrumProxyStream> {
346
368
347
369
Ok ( stream. into ( ) )
348
370
}
371
+
372
+ #[ cfg( any( feature = "use-openssl" , feature = "use-rustls" ) ) ]
373
+ /// Creates a new TLS client that connects to `target_addr` using `proxy_addr` as a socks proxy
374
+ /// server. The DNS resolution of `target_addr`, if required, is done through the proxy. This
375
+ /// allows to specify, for instance, `.onion` addresses.
376
+ pub fn new_proxy_ssl < T : ToTargetAddr > (
377
+ target_addr : T ,
378
+ validate_domain : bool ,
379
+ proxy : & crate :: Socks5Config ,
380
+ ) -> Result < RawClient < ElectrumSslStream > , Error > {
381
+ let target = target_addr. to_target_addr ( ) ?;
382
+
383
+ let stream = match proxy. credentials . as_ref ( ) {
384
+ Some ( cred) => Socks5Stream :: connect_with_password (
385
+ & proxy. addr ,
386
+ target_addr,
387
+ & cred. username ,
388
+ & cred. password ,
389
+ ) ?,
390
+ None => Socks5Stream :: connect ( & proxy. addr , target. clone ( ) ) ?,
391
+ } ;
392
+
393
+ RawClient :: new_ssl_from_stream ( target, validate_domain, stream. into_inner ( ) )
394
+ }
349
395
}
350
396
351
397
#[ derive( Debug ) ]
0 commit comments