Browse Source

net: implement unix transport

ghassmo 4 years ago
parent
commit
525efd7dd9
6 changed files with 88 additions and 12 deletions
  1. 3 0
      src/error.rs
  2. 8 8
      src/net/acceptor.rs
  3. 4 4
      src/net/connector.rs
  4. 1 0
      src/net/mod.rs
  5. 3 0
      src/net/transport.rs
  6. 69 0
      src/net/transport/unix.rs

+ 3 - 0
src/error.rs

@@ -297,6 +297,9 @@ pub enum Error {
     #[error("System clock is not correct!")]
     InvalidClock,
 
+    #[error("Unsupported OS")]
+    UnsupportedOS,
+
     // ==============================================
     // Wrappers for other error types in this library
     // ==============================================

+ 8 - 8
src/net/acceptor.rs

@@ -43,15 +43,15 @@ impl Acceptor {
                 let listener = transport.listen_on(accept_url.clone());
 
                 if let Err(err) = listener {
-                    error!("TCP Setup failed: {}", err);
-                    return Err(Error::BindFailed(accept_url.clone().to_string()))
+                    error!("Setup for {} failed: {}", accept_url, err);
+                    return Err(Error::BindFailed(accept_url.as_str().into()))
                 }
 
                 let listener = listener?.await;
 
                 if let Err(err) = listener {
-                    error!("TCP Bind listener failed: {}", err);
-                    return Err(Error::BindFailed(accept_url.to_string()))
+                    error!("Bind listener to {} failed: {}", accept_url, err);
+                    return Err(Error::BindFailed(accept_url.as_str().into()))
                 }
 
                 let listener = listener?;
@@ -103,15 +103,15 @@ impl Acceptor {
                 let listener = transport.clone().listen_on(accept_url.clone());
 
                 if let Err(err) = listener {
-                    error!("TOR Setup failed: {}", err);
-                    return Err(Error::BindFailed(accept_url.clone().to_string()))
+                    error!("Setup for {} failed: {}", accept_url, err);
+                    return Err(Error::BindFailed(accept_url.as_str().into()))
                 }
 
                 let listener = listener?.await;
 
                 if let Err(err) = listener {
-                    error!("TOR Bind listener failed: {}", err);
-                    return Err(Error::BindFailed(accept_url.to_string()))
+                    error!("Bind listener to {} failed: {}", accept_url, err);
+                    return Err(Error::BindFailed(accept_url.as_str().into()))
                 }
 
                 let listener = listener?;

+ 4 - 4
src/net/connector.rs

@@ -43,14 +43,14 @@ impl Connector {
                 let stream = transport.dial(connect_url.clone());
 
                 if let Err(err) = stream {
-                    error!("TCP Setup failed: {}", err);
+                    error!("Setup for {} failed: {}", connect_url, err);
                     return Err(Error::ConnectFailed)
                 }
 
                 let stream = stream?.await;
 
                 if let Err(err) = stream {
-                    error!("TCP Connection failed: {}", err);
+                    error!("Connection to {}  failed: {}", connect_url, err);
                     return Err(Error::ConnectFailed)
                 }
 
@@ -76,14 +76,14 @@ impl Connector {
                 let stream = transport.clone().dial(connect_url.clone());
 
                 if let Err(err) = stream {
-                    error!("TOR Setup failed: {}", err);
+                    error!("Setup for {} failed: {}", connect_url, err);
                     return Err(Error::ConnectFailed)
                 }
 
                 let stream = stream?.await;
 
                 if let Err(err) = stream {
-                    error!("TOR Connection failed: {}", err);
+                    error!("Connection to {}  failed: {}", connect_url, err);
                     return Err(Error::ConnectFailed)
                 }
 

+ 1 - 0
src/net/mod.rs

@@ -100,4 +100,5 @@ pub use session::{SESSION_ALL, SESSION_INBOUND, SESSION_MANUAL, SESSION_OUTBOUND
 pub use settings::{Settings, SettingsPtr};
 pub use transport::{
     TcpTransport, TorTransport, Transport, TransportListener, TransportName, TransportStream,
+    UnixTransport,
 };

+ 3 - 0
src/net/transport.rs

@@ -17,6 +17,9 @@ 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<Url> {
     let url = Url::parse(&format!("{}://{}", scheme, addr))?;

+ 69 - 0
src/net/transport/unix.rs

@@ -0,0 +1,69 @@
+use async_std::os::unix::net::{UnixListener, UnixStream};
+
+use async_trait::async_trait;
+use log::{debug, error};
+use url::Url;
+
+use super::{TransportListener, TransportStream};
+use crate::{Error, Result};
+
+fn unix_socket_addr_to_string(addr: std::os::unix::net::SocketAddr) -> String {
+    addr.as_pathname().unwrap_or(&std::path::PathBuf::from("")).to_str().unwrap_or("").into()
+}
+
+#[async_trait]
+impl TransportListener for UnixListener {
+    async fn next(&self) -> Result<(Box<dyn TransportStream>, Url)> {
+        let (stream, peer_addr) = match self.accept().await {
+            Ok((s, a)) => (s, a),
+            Err(err) => {
+                error!("Error listening for connections: {}", err);
+                return Err(Error::AcceptConnectionFailed(unix_socket_addr_to_string(
+                    self.local_addr()?,
+                )))
+            }
+        };
+        let url = Url::parse(&unix_socket_addr_to_string(peer_addr))?;
+        Ok((Box::new(stream), url))
+    }
+}
+
+impl TransportStream for UnixStream {}
+
+#[derive(Copy, Clone)]
+pub struct UnixTransport {}
+
+impl UnixTransport {
+    pub fn new() -> Self {
+        Self {}
+    }
+    pub async fn listen(self, url: Url) -> Result<UnixListener> {
+        match url.scheme() {
+            "unix" => {}
+            x => return Err(Error::UnsupportedTransport(x.to_string())),
+        }
+
+        if !cfg!(unix) {
+            return Err(Error::UnsupportedOS)
+        }
+
+        let listener = UnixListener::bind(url.as_str()).await?;
+        debug!("{} transport: listening on {}", url.scheme(), url);
+        Ok(listener)
+    }
+
+    pub async fn dial(self, url: Url) -> Result<UnixStream> {
+        match url.scheme() {
+            "unix" => {}
+            x => return Err(Error::UnsupportedTransport(x.to_string())),
+        }
+
+        if !cfg!(unix) {
+            return Err(Error::UnsupportedOS)
+        }
+
+        let stream = UnixStream::connect(url.as_str()).await?;
+        debug!("{} transport: dialing to {}", url.scheme(), url);
+        Ok(stream)
+    }
+}