From 1a1fb1f5e1da687d3d8a0f2b2aa68bc2bddd1814 Mon Sep 17 00:00:00 2001
From: Jeremy Soller <jackpot51@gmail.com>
Date: Wed, 26 Oct 2016 13:19:56 -0600
Subject: [PATCH] Redo networking (#22)

* Rewriting network functions

* Add buffer to dup
Fix non-blocking handling by triggering once on enabling events to read to EOF

* Modifications for UDP API

* Implement TCP client side

* Add active close

* Add DMAR parser

* Implement basic TCP listening. Need to improve the state machine

* Reduce debugging

* Fixes for close procedure

* Updates to fix path processing in libstd
---
 scheme/debug.rs    |  2 +-
 scheme/env.rs      |  2 +-
 scheme/event.rs    |  2 +-
 scheme/initfs.rs   |  2 +-
 scheme/irq.rs      |  2 +-
 scheme/pipe.rs     |  2 +-
 scheme/root.rs     | 22 +++++++++++++++++-----
 scheme/sys/mod.rs  |  2 +-
 scheme/user.rs     | 20 ++++++++++++++------
 syscall/fs.rs      | 20 ++++++++++----------
 syscall/mod.rs     |  2 +-
 syscall/process.rs |  2 +-
 12 files changed, 50 insertions(+), 30 deletions(-)

diff --git a/scheme/debug.rs b/scheme/debug.rs
index 27ab6261..8a8f556a 100644
--- a/scheme/debug.rs
+++ b/scheme/debug.rs
@@ -33,7 +33,7 @@ impl Scheme for DebugScheme {
         Ok(0)
     }
 
-    fn dup(&self, _file: usize) -> Result<usize> {
+    fn dup(&self, _file: usize, _buf: &[u8]) -> Result<usize> {
         Ok(0)
     }
 
diff --git a/scheme/env.rs b/scheme/env.rs
index 4a514850..3c88b1e1 100644
--- a/scheme/env.rs
+++ b/scheme/env.rs
@@ -88,7 +88,7 @@ impl Scheme for EnvScheme {
         }
     }
 
-    fn dup(&self, id: usize) -> Result<usize> {
+    fn dup(&self, id: usize, _buf: &[u8]) -> Result<usize> {
         let new_handle = {
             let handles = self.handles.read();
             let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
diff --git a/scheme/event.rs b/scheme/event.rs
index cca7420c..2266141e 100644
--- a/scheme/event.rs
+++ b/scheme/event.rs
@@ -39,7 +39,7 @@ impl Scheme for EventScheme {
         Ok(id)
     }
 
-    fn dup(&self, id: usize) -> Result<usize> {
+    fn dup(&self, id: usize, _buf: &[u8]) -> Result<usize> {
         let handle = {
             let handles = self.handles.read();
             let handle_weak = handles.get(&id).ok_or(Error::new(EBADF))?;
diff --git a/scheme/initfs.rs b/scheme/initfs.rs
index 18696ed0..99f1f7d2 100644
--- a/scheme/initfs.rs
+++ b/scheme/initfs.rs
@@ -57,7 +57,7 @@ impl Scheme for InitFsScheme {
         Err(Error::new(ENOENT))
     }
 
-    fn dup(&self, id: usize) -> Result<usize> {
+    fn dup(&self, id: usize, _buf: &[u8]) -> Result<usize> {
         let (path, data, mode, seek) = {
             let handles = self.handles.read();
             let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
diff --git a/scheme/irq.rs b/scheme/irq.rs
index f91118e8..a20aca71 100644
--- a/scheme/irq.rs
+++ b/scheme/irq.rs
@@ -40,7 +40,7 @@ impl Scheme for IrqScheme {
         }
     }
 
-    fn dup(&self, file: usize) -> Result<usize> {
+    fn dup(&self, file: usize, _buf: &[u8]) -> Result<usize> {
         Ok(file)
     }
 
diff --git a/scheme/pipe.rs b/scheme/pipe.rs
index 35dfd004..49d48956 100644
--- a/scheme/pipe.rs
+++ b/scheme/pipe.rs
@@ -42,7 +42,7 @@ pub fn pipe(flags: usize) -> (usize, usize) {
 pub struct PipeScheme;
 
 impl Scheme for PipeScheme {
-    fn dup(&self, id: usize) -> Result<usize> {
+    fn dup(&self, id: usize, _buf: &[u8]) -> Result<usize> {
         let mut pipes = pipes_mut();
 
         let read_option = pipes.0.get(&id).map(|pipe| pipe.clone());
diff --git a/scheme/root.rs b/scheme/root.rs
index a2531328..737e74b6 100644
--- a/scheme/root.rs
+++ b/scheme/root.rs
@@ -56,7 +56,7 @@ impl Scheme for RootScheme {
         }
     }
 
-    fn dup(&self, file: usize) -> Result<usize> {
+    fn dup(&self, file: usize, _buf: &[u8]) -> Result<usize> {
         let mut handles = self.handles.write();
         let inner = {
             let inner = handles.get(&file).ok_or(Error::new(EBADF))?;
@@ -89,12 +89,24 @@ impl Scheme for RootScheme {
         inner.write(buf)
     }
 
-    fn fevent(&self, file: usize, _flags: usize) -> Result<usize> {
-        Ok(file)
+    fn fevent(&self, file: usize, flags: usize) -> Result<usize> {
+        let inner = {
+            let handles = self.handles.read();
+            let inner = handles.get(&file).ok_or(Error::new(EBADF))?;
+            inner.clone()
+        };
+
+        inner.fevent(flags)
     }
 
-    fn fsync(&self, _file: usize) -> Result<usize> {
-        Ok(0)
+    fn fsync(&self, file: usize) -> Result<usize> {
+        let inner = {
+            let handles = self.handles.read();
+            let inner = handles.get(&file).ok_or(Error::new(EBADF))?;
+            inner.clone()
+        };
+
+        inner.fsync()
     }
 
     fn close(&self, file: usize) -> Result<usize> {
diff --git a/scheme/sys/mod.rs b/scheme/sys/mod.rs
index 917b9071..7d560d37 100644
--- a/scheme/sys/mod.rs
+++ b/scheme/sys/mod.rs
@@ -92,7 +92,7 @@ impl Scheme for SysScheme {
         Err(Error::new(ENOENT))
     }
 
-    fn dup(&self, id: usize) -> Result<usize> {
+    fn dup(&self, id: usize, _buf: &[u8]) -> Result<usize> {
         let (path, data, mode, seek) = {
             let handles = self.handles.read();
             let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
diff --git a/scheme/user.rs b/scheme/user.rs
index 8f1c95a7..28548217 100644
--- a/scheme/user.rs
+++ b/scheme/user.rs
@@ -61,10 +61,7 @@ impl UserInner {
         };
 
         let len = self.todo.send(packet);
-        //TODO: Use O_NONBLOCK and send one notification
-        for _i in 0 .. len {
-            context::event::trigger(ROOT_SCHEME_ID.load(Ordering::SeqCst), self.handle_id, EVENT_READ, mem::size_of::<Packet>());
-        }
+        context::event::trigger(ROOT_SCHEME_ID.load(Ordering::SeqCst), self.handle_id, EVENT_READ, mem::size_of::<Packet>() * len);
 
         Error::demux(self.done.receive(&id))
     }
@@ -182,6 +179,14 @@ impl UserInner {
 
         Ok(i * packet_size)
     }
+
+    pub fn fevent(&self, _flags: usize) -> Result<usize> {
+        Ok(self.handle_id)
+    }
+
+    pub fn fsync(&self) -> Result<usize> {
+        Ok(0)
+    }
 }
 
 /// UserInner has to be wrapped
@@ -230,9 +235,12 @@ impl Scheme for UserScheme {
         result
     }
 
-    fn dup(&self, file: usize) -> Result<usize> {
+    fn dup(&self, file: usize, buf: &[u8]) -> Result<usize> {
         let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
-        inner.call(SYS_DUP, file, 0, 0)
+        let address = inner.capture(buf)?;
+        let result = inner.call(SYS_DUP, file, address, buf.len());
+        let _ = inner.release(address);
+        result
     }
 
     fn read(&self, file: usize, buf: &mut [u8]) -> Result<usize> {
diff --git a/syscall/fs.rs b/syscall/fs.rs
index 6c953e46..ff4a51d8 100644
--- a/syscall/fs.rs
+++ b/syscall/fs.rs
@@ -83,10 +83,10 @@ pub fn open(path: &[u8], flags: usize) -> Result<usize> {
     let reference_opt = parts.next();
 
     let (scheme_id, file_id) = {
-        let namespace = namespace_opt.ok_or(Error::new(ENOENT))?;
+        let namespace = namespace_opt.ok_or(Error::new(ENODEV))?;
         let (scheme_id, scheme) = {
             let schemes = scheme::schemes();
-            let (scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?;
+            let (scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENODEV))?;
             (scheme_id, scheme.clone())
         };
         let file_id = scheme.open(reference_opt.unwrap_or(b""), flags, uid, gid)?;
@@ -146,10 +146,10 @@ pub fn mkdir(path: &[u8], mode: u16) -> Result<usize> {
     let namespace_opt = parts.next();
     let reference_opt = parts.next();
 
-    let namespace = namespace_opt.ok_or(Error::new(ENOENT))?;
+    let namespace = namespace_opt.ok_or(Error::new(ENODEV))?;
     let scheme = {
         let schemes = scheme::schemes();
-        let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?;
+        let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENODEV))?;
         scheme.clone()
     };
     scheme.mkdir(reference_opt.unwrap_or(b""), mode, uid, gid)
@@ -168,10 +168,10 @@ pub fn rmdir(path: &[u8]) -> Result<usize> {
     let namespace_opt = parts.next();
     let reference_opt = parts.next();
 
-    let namespace = namespace_opt.ok_or(Error::new(ENOENT))?;
+    let namespace = namespace_opt.ok_or(Error::new(ENODEV))?;
     let scheme = {
         let schemes = scheme::schemes();
-        let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?;
+        let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENODEV))?;
         scheme.clone()
     };
     scheme.rmdir(reference_opt.unwrap_or(b""), uid, gid)
@@ -190,10 +190,10 @@ pub fn unlink(path: &[u8]) -> Result<usize> {
     let namespace_opt = parts.next();
     let reference_opt = parts.next();
 
-    let namespace = namespace_opt.ok_or(Error::new(ENOENT))?;
+    let namespace = namespace_opt.ok_or(Error::new(ENODEV))?;
     let scheme = {
         let schemes = scheme::schemes();
-        let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENOENT))?;
+        let (_scheme_id, scheme) = schemes.get_name(namespace).ok_or(Error::new(ENODEV))?;
         scheme.clone()
     };
     scheme.unlink(reference_opt.unwrap_or(b""), uid, gid)
@@ -222,7 +222,7 @@ pub fn close(fd: usize) -> Result<usize> {
 }
 
 /// Duplicate file descriptor
-pub fn dup(fd: usize) -> Result<usize> {
+pub fn dup(fd: usize, buf: &[u8]) -> Result<usize> {
     let file = {
         let contexts = context::contexts();
         let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
@@ -237,7 +237,7 @@ pub fn dup(fd: usize) -> Result<usize> {
             let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
             scheme.clone()
         };
-        scheme.dup(file.number)?
+        scheme.dup(file.number, buf)?
     };
 
     let contexts = context::contexts();
diff --git a/syscall/mod.rs b/syscall/mod.rs
index 8e1c190e..2598cfa5 100644
--- a/syscall/mod.rs
+++ b/syscall/mod.rs
@@ -39,7 +39,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
                 SYS_ARG_MSLICE => file_op_mut_slice(a, b, validate_slice_mut(c as *mut u8, d)?),
                 _ => match a {
                     SYS_CLOSE => close(b),
-                    SYS_DUP => dup(b),
+                    SYS_DUP => dup(b, validate_slice(c as *const u8, d)?),
                     SYS_FEVENT => fevent(b, c),
                     _ => file_op(a, b, c, d)
                 }
diff --git a/syscall/process.rs b/syscall/process.rs
index 39dd822c..e3cd886c 100644
--- a/syscall/process.rs
+++ b/syscall/process.rs
@@ -227,7 +227,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
                             let scheme = schemes.get(file.scheme).ok_or(Error::new(EBADF))?;
                             scheme.clone()
                         };
-                        let result = scheme.dup(file.number);
+                        let result = scheme.dup(file.number, &[]);
                         result
                     };
                     match result {
-- 
GitLab