From 1ad591ad05910d91beb59da825bd11dbdf42b5df Mon Sep 17 00:00:00 2001 From: Egor Karavaev Date: Fri, 8 Sep 2017 00:02:17 +0300 Subject: [PATCH] Add Smolnetd daemon. --- Cargo.toml | 4 +++ src/smolnetd/error.rs | 52 +++++++++++++++++++++++++++++++++++ src/smolnetd/main.rs | 62 ++++++++++++++++++++++++++++++++++++++++++ src/smolnetd/scheme.rs | 23 ++++++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 src/smolnetd/error.rs create mode 100644 src/smolnetd/main.rs create mode 100644 src/smolnetd/scheme.rs diff --git a/Cargo.toml b/Cargo.toml index 16aa9d1275..73b09a4933 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,10 @@ path = "src/udpd/main.rs" name = "icmpd" path = "src/icmpd/main.rs" +[[bin]] +name = "smolnetd" +path = "src/smolnetd/main.rs" + [dependencies] netutils = { git = "https://github.com/redox-os/netutils.git" } rand = "0.3" diff --git a/src/smolnetd/error.rs b/src/smolnetd/error.rs new file mode 100644 index 0000000000..5ab5ba3071 --- /dev/null +++ b/src/smolnetd/error.rs @@ -0,0 +1,52 @@ +use std::convert; +use std::fmt; +use std::result; +use std::io::Error as IOError; +use syscall::error::Error as SyscallError; + +enum ErrorType { + Syscall(SyscallError), + IOError(IOError), +} + +pub struct Error { + error_type: ErrorType, + descr: String, +} + +impl Error { + pub fn from_syscall_error>(syscall_error: SyscallError, descr: S) -> Error { + Error { + error_type: ErrorType::Syscall(syscall_error), + descr: descr.into(), + } + } + + pub fn from_io_error>(io_error: IOError, descr: S) -> Error { + Error { + error_type: ErrorType::IOError(io_error), + descr: descr.into(), + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> { + match self.error_type { + ErrorType::Syscall(ref syscall_error) => { + write!(f, "{}: syscall error: {}", self.descr, syscall_error) + } + ErrorType::IOError(ref io_error) => { + write!(f, "{} : io error : {}", self.descr, io_error) + } + } + } +} + +impl convert::From for Error { + fn from(e: IOError) -> Self { + Error::from_io_error(e, "") + } +} + +pub type Result = result::Result; diff --git a/src/smolnetd/main.rs b/src/smolnetd/main.rs new file mode 100644 index 0000000000..be52c81a2f --- /dev/null +++ b/src/smolnetd/main.rs @@ -0,0 +1,62 @@ +extern crate event; +extern crate syscall; + +use error::{Error, Result}; +use event::EventQueue; +use scheme::Smolnetd; +use std::os::unix::io::{FromRawFd, RawFd}; +use std::process; +use std::rc::Rc; +use std::fs::File; +use std::cell::RefCell; + +mod error; +mod scheme; + +fn run() -> Result<()> { + use syscall::flag::*; + + if unsafe { syscall::clone(0).unwrap() } != 0 { + return Ok(()); + } + + println!("icmpd: opening network:"); + let network_fd = syscall::open("network:", O_RDWR | O_NONBLOCK) + .map_err(|e| Error::from_syscall_error(e, "failed to open network:"))? as + RawFd; + + println!("icmpd: opening :ip"); + let ip_fd = syscall::open(":ip", O_RDWR | O_NONBLOCK) + .map_err(|e| Error::from_syscall_error(e, "failed to open :ip"))? as RawFd; + + let (network_file, ip_file) = + unsafe { (File::from_raw_fd(network_fd), File::from_raw_fd(ip_fd)) }; + let smolnetd = Rc::new(RefCell::new(Smolnetd::new(network_file, ip_file))); + + let mut event_queue = EventQueue::<(), Error>::new() + .map_err(|e| Error::from_io_error(e, "failed to create event queue"))?; + + let smolnetd_ = smolnetd.clone(); + + event_queue + .add(network_fd, move |_| { + smolnetd_.borrow_mut().on_network_scheme_event() + }) + .map_err(|e| { + Error::from_io_error(e, "failed to listen to network events") + })?; + + event_queue + .add(ip_fd, move |_| smolnetd.borrow_mut().on_ip_scheme_event()) + .map_err(|e| Error::from_io_error(e, "failed to listen to ip events"))?; + + event_queue.run() +} + +fn main() { + if let Err(err) = run() { + println!("smoltcpd: {}", err); + process::exit(1); + } + process::exit(0); +} diff --git a/src/smolnetd/scheme.rs b/src/smolnetd/scheme.rs new file mode 100644 index 0000000000..2447d83e93 --- /dev/null +++ b/src/smolnetd/scheme.rs @@ -0,0 +1,23 @@ +use error::Result; +use std::fs::File; + +pub struct Smolnetd { + network_file: File, + ip_file: File, +} + +impl Smolnetd { + pub fn new(network_file: File, ip_file: File) -> Smolnetd { + Smolnetd { + network_file, + ip_file, + } + } + pub fn on_network_scheme_event(&mut self) -> Result> { + Ok(None) + } + + pub fn on_ip_scheme_event(&mut self) -> Result> { + Ok(None) + } +}