Browse Source

net/acceptor: Handle accept(2) errors more robustly.

parazyd 2 years ago
parent
commit
b80b4b755e
5 changed files with 25 additions and 14 deletions
  1. 1 0
      Cargo.lock
  2. 11 2
      src/net/acceptor.rs
  3. 1 1
      src/net/transport.rs
  4. 8 8
      src/net/transport/tcp.rs
  5. 4 3
      src/net/transport/unix.rs

+ 1 - 0
Cargo.lock

@@ -1599,6 +1599,7 @@ name = "darkfi-serial"
 version = "0.4.1"
 dependencies = [
  "async-trait",
+ "blake2b_simd",
  "blake3",
  "bridgetree",
  "darkfi-derive",

+ 11 - 2
src/net/acceptor.rs

@@ -86,16 +86,25 @@ impl Acceptor {
         loop {
             match listener.next().await {
                 Ok((stream, url)) => {
-                    let channel =
-                        Channel::new(stream, url, self.session.lock().await.clone().unwrap()).await;
+                    let session = self.session.lock().await.clone().unwrap();
+                    let channel = Channel::new(stream, url, session).await;
                     self.channel_subscriber.notify(Ok(channel)).await;
                 }
 
+                // As per accept(2) recommendation:
+                Err(e) if e.raw_os_error().unwrap() == libc::EAGAIN => continue,
+                Err(e) if e.raw_os_error().unwrap() == libc::EWOULDBLOCK => continue,
+                Err(e) if e.raw_os_error().unwrap() == libc::ECONNABORTED => continue,
+                Err(e) if e.raw_os_error().unwrap() == libc::EPROTO => continue,
+                // TODO: Should EINTR actually break out? Check if StoppableTask does this.
+                Err(e) if e.raw_os_error().unwrap() == libc::EINTR => continue,
+
                 Err(e) => {
                     error!(
                         target: "net::acceptor::run_accept_loop()",
                         "[P2P] Acceptor failed listening: {}", e,
                     );
+                    return Err(e.into())
                 }
             }
         }

+ 1 - 1
src/net/transport.rs

@@ -351,5 +351,5 @@ impl PtStream for smol::net::unix::UnixStream {}
 /// Wrapper trait for async listeners
 #[async_trait]
 pub trait PtListener: Send + Sync + Unpin {
-    async fn next(&self) -> Result<(Box<dyn PtStream>, Url)>;
+    async fn next(&self) -> std::io::Result<(Box<dyn PtStream>, Url)>;
 }

+ 8 - 8
src/net/transport/tcp.rs

@@ -140,32 +140,32 @@ impl TcpListener {
 
 #[async_trait]
 impl PtListener for SmolTcpListener {
-    async fn next(&self) -> Result<(Box<dyn PtStream>, Url)> {
+    async fn next(&self) -> std::io::Result<(Box<dyn PtStream>, Url)> {
         let (stream, peer_addr) = match self.accept().await {
             Ok((s, a)) => (s, a),
-            Err(e) => return Err(e.into()),
+            Err(e) => return Err(e),
         };
 
-        let url = Url::parse(&format!("tcp://{}", peer_addr))?;
+        let url = Url::parse(&format!("tcp://{}", peer_addr)).unwrap();
         Ok((Box::new(stream), url))
     }
 }
 
 #[async_trait]
 impl PtListener for (TlsAcceptor, SmolTcpListener) {
-    async fn next(&self) -> Result<(Box<dyn PtStream>, Url)> {
+    async fn next(&self) -> std::io::Result<(Box<dyn PtStream>, Url)> {
         let (stream, peer_addr) = match self.1.accept().await {
             Ok((s, a)) => (s, a),
-            Err(e) => return Err(e.into()),
+            Err(e) => return Err(e),
         };
 
         let stream = match self.0.accept(stream).await {
             Ok(v) => v,
-            Err(e) => return Err(e.into()),
+            Err(e) => return Err(e),
         };
 
-        let url = Url::parse(&format!("tcp+tls://{}", peer_addr))?;
+        let url = Url::parse(&format!("tcp+tls://{}", peer_addr)).unwrap();
 
-        Ok((Box::new(TlsStream::Server(stream.unwrap())), url))
+        Ok((Box::new(TlsStream::Server(stream)), url))
     }
 }

+ 4 - 3
src/net/transport/unix.rs

@@ -71,14 +71,15 @@ impl UnixListener {
 
 #[async_trait]
 impl PtListener for SmolUnixListener {
-    async fn next(&self) -> Result<(Box<dyn PtStream>, Url)> {
+    async fn next(&self) -> std::io::Result<(Box<dyn PtStream>, Url)> {
         let (stream, _peer_addr) = match self.accept().await {
             Ok((s, a)) => (s, a),
-            Err(e) => return Err(e.into()),
+            Err(e) => return Err(e),
         };
 
         let addr = self.local_addr().unwrap();
-        let url = Url::parse(&format!("unix://{}", addr.as_pathname().unwrap().to_str().unwrap()))?;
+        let addr = addr.as_pathname().unwrap().to_str().unwrap();
+        let url = Url::parse(&format!("unix://{}", addr)).unwrap();
 
         Ok((Box::new(stream), url))
     }