use std::net::SocketAddr; use async_trait::async_trait; // TODO remove * use futures::prelude::*; use futures_rustls::{TlsAcceptor, TlsStream}; use url::Url; use crate::Result; mod upgrade_tls; pub use upgrade_tls::TlsUpgrade; mod tcp; pub use tcp::TcpTransport; mod tor; pub use tor::TorTransport; mod unix; pub use unix::UnixTransport; /// A helper function to convert SocketAddr to Url and add scheme pub(crate) fn socket_addr_to_url(addr: SocketAddr, scheme: &str) -> Result { let url = Url::parse(&format!("{}://{}", scheme, addr))?; Ok(url) } /// Used as wrapper for stream used by Transport trait pub trait TransportStream: AsyncWrite + AsyncRead + Unpin + Send + Sync {} /// Used as wrapper for listener used by Transport trait #[async_trait] pub trait TransportListener: Send + Sync + Unpin { async fn next(&self) -> Result<(Box, Url)>; } #[derive(Clone)] pub enum TransportName { Tcp(Option), Tor(Option), Nym(Option), Unix, } impl TryFrom for TransportName { type Error = crate::Error; fn try_from(url: Url) -> Result { let transport_name = match url.scheme() { "tcp" => Self::Tcp(None), "tcp+tls" | "tls" => Self::Tcp(Some("tls".into())), "tor" => Self::Tor(None), "tor+tls" => Self::Tor(Some("tls".into())), "nym" => Self::Nym(None), "nym+tls" => Self::Nym(Some("tls".into())), "unix" => Self::Unix, n => return Err(crate::Error::UnsupportedTransport(n.into())), }; Ok(transport_name) } } /// The `Transport` trait serves as a base for implementing transport protocols. /// Base transports can optionally be upgraded with TLS in order to support encryption. /// The implementation of our TLS authentication can be found in the [`upgrade_tls`] module. pub trait Transport { type Acceptor; type Connector; type Listener: Future>; type Dial: Future>; type TlsListener: Future>; type TlsDialer: Future>>; fn listen_on(self, url: Url) -> Result where Self: Sized; fn upgrade_listener(self, acceptor: Self::Acceptor) -> Result where Self: Sized; fn dial(self, url: Url) -> Result where Self: Sized; fn upgrade_dialer(self, stream: Self::Connector) -> Result where Self: Sized; }