This commit is contained in:
parent
2477ab4440
commit
b08c59815d
@ -87,17 +87,20 @@ macro_rules! impl_inner_call {
|
||||
}
|
||||
|
||||
impl ClientType {
|
||||
/// Constructor that supports multiple backends and allows configuration through
|
||||
/// Constructor that supports multiple backends and allows configuration through
|
||||
/// the [Config]
|
||||
pub fn from_config(url: &str, config: &Config) -> Result<Self, Error> {
|
||||
if url.starts_with("ssl://") {
|
||||
if config.socks5().is_some() {
|
||||
return Err(Error::SSLOverSocks5);
|
||||
}
|
||||
|
||||
let url = url.replacen("ssl://", "", 1);
|
||||
let client =
|
||||
RawClient::new_ssl(url.as_str(), config.validate_domain(), config.timeout())?;
|
||||
let client = match config.socks5() {
|
||||
Some(socks5) => {
|
||||
RawClient::new_proxy_ssl(url.as_str(), config.validate_domain(), socks5)?
|
||||
}
|
||||
None => {
|
||||
RawClient::new_ssl(url.as_str(), config.validate_domain(), config.timeout())?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(ClientType::SSL(client))
|
||||
} else {
|
||||
let url = url.replacen("tcp://", "", 1);
|
||||
@ -127,9 +130,6 @@ impl Client {
|
||||
|
||||
/// Generic constructor that supports multiple backends and allows configuration through
|
||||
/// the [Config]
|
||||
///
|
||||
/// **NOTE**: SSL-over-socks5 is currently not supported and will generate a runtime error.
|
||||
///
|
||||
pub fn from_config(url: &str, config: Config) -> Result<Self, Error> {
|
||||
let client_type = RwLock::new(ClientType::from_config(url, &config)?);
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ use openssl::ssl::{SslConnector, SslMethod, SslStream, SslVerifyMode};
|
||||
use rustls::{ClientConfig, ClientSession, StreamOwned};
|
||||
|
||||
#[cfg(any(feature = "default", feature = "proxy"))]
|
||||
use socks::{Socks5Stream, ToTargetAddr};
|
||||
use socks::{Socks5Stream, TargetAddr, ToTargetAddr};
|
||||
|
||||
use stream::ClonableStream;
|
||||
|
||||
@ -75,6 +75,28 @@ impl ToSocketAddrsDomain for (&str, u16) {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSocketAddrsDomain for TargetAddr {
|
||||
fn domain(&self) -> Option<&str> {
|
||||
match self {
|
||||
TargetAddr::Ip(_) => None,
|
||||
TargetAddr::Domain(domain, _) => Some(domain.as_str()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_to_socket_addrs_domain {
|
||||
( $ty:ty ) => {
|
||||
impl ToSocketAddrsDomain for $ty {}
|
||||
};
|
||||
}
|
||||
|
||||
impl_to_socket_addrs_domain!(std::net::SocketAddr);
|
||||
impl_to_socket_addrs_domain!(std::net::SocketAddrV4);
|
||||
impl_to_socket_addrs_domain!(std::net::SocketAddrV6);
|
||||
impl_to_socket_addrs_domain!((std::net::IpAddr, u16));
|
||||
impl_to_socket_addrs_domain!((std::net::Ipv4Addr, u16));
|
||||
impl_to_socket_addrs_domain!((std::net::Ipv6Addr, u16));
|
||||
|
||||
/// Instance of an Electrum client
|
||||
///
|
||||
/// A `Client` maintains a constant connection with an Electrum server and exposes methods to
|
||||
@ -327,8 +349,8 @@ impl RawClient<ElectrumSslStream> {
|
||||
pub type ElectrumProxyStream = Socks5Stream;
|
||||
#[cfg(any(feature = "default", feature = "proxy"))]
|
||||
impl RawClient<ElectrumProxyStream> {
|
||||
/// Creates a new socks client and tries to connect to `target_addr` using `proxy_addr` as an
|
||||
/// unauthenticated socks proxy server. The DNS resolution of `target_addr`, if required, is done
|
||||
/// Creates a new socks client and tries to connect to `target_addr` using `proxy_addr` as a
|
||||
/// socks proxy server. The DNS resolution of `target_addr`, if required, is done
|
||||
/// through the proxy. This allows to specify, for instance, `.onion` addresses.
|
||||
pub fn new_proxy<T: ToTargetAddr>(
|
||||
target_addr: T,
|
||||
@ -346,6 +368,30 @@ impl RawClient<ElectrumProxyStream> {
|
||||
|
||||
Ok(stream.into())
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "use-openssl", feature = "use-rustls"))]
|
||||
/// Creates a new TLS client that connects to `target_addr` using `proxy_addr` as a socks proxy
|
||||
/// server. The DNS resolution of `target_addr`, if required, is done through the proxy. This
|
||||
/// allows to specify, for instance, `.onion` addresses.
|
||||
pub fn new_proxy_ssl<T: ToTargetAddr>(
|
||||
target_addr: T,
|
||||
validate_domain: bool,
|
||||
proxy: &crate::Socks5Config,
|
||||
) -> Result<RawClient<ElectrumSslStream>, Error> {
|
||||
let target = target_addr.to_target_addr()?;
|
||||
|
||||
let stream = match proxy.credentials.as_ref() {
|
||||
Some(cred) => Socks5Stream::connect_with_password(
|
||||
&proxy.addr,
|
||||
target_addr,
|
||||
&cred.username,
|
||||
&cred.password,
|
||||
)?,
|
||||
None => Socks5Stream::connect(&proxy.addr, target.clone())?,
|
||||
};
|
||||
|
||||
RawClient::new_ssl_from_stream(target, validate_domain, stream.into_inner())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@ -287,8 +287,6 @@ pub enum Error {
|
||||
InvalidDNSNameError(String),
|
||||
/// Missing domain while it was explicitly asked to validate it
|
||||
MissingDomain,
|
||||
/// SSL over a socks5 proxy is currently not supported
|
||||
SSLOverSocks5,
|
||||
/// Made one or multiple attempts, always in Error
|
||||
AllAttemptsErrored(Vec<Error>),
|
||||
/// There was an io error reading the socket, to be shared between threads
|
||||
|
||||
Loading…
Reference in New Issue
Block a user