Merge branch 'improvements' into 'master'
Couple of improvements See merge request redox-os/netstack!53
This commit is contained in:
Generated
+1
-7
@@ -1,6 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
@@ -459,7 +459,6 @@ name = "redox_netstack"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"byteorder 1.5.0",
|
||||
"dns-parser",
|
||||
"ioslice",
|
||||
"libredox",
|
||||
@@ -822,8 +821,3 @@ name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[patch.unused]]
|
||||
name = "mio"
|
||||
version = "0.6.14"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/mio.git?branch=redox-unix#c9a70849ced97387e2607c9c466d23b130ec8901"
|
||||
|
||||
@@ -21,7 +21,6 @@ redox_event = "0.4.1"
|
||||
redox-daemon = "0.1.2"
|
||||
redox_syscall = "0.5"
|
||||
redox-log = "0.1"
|
||||
byteorder = { version = "1.0", default-features = false }
|
||||
dns-parser = "0.7.1"
|
||||
libredox = { version = "0.1.3", features = ["mkns"] }
|
||||
anyhow = "1.0.81"
|
||||
@@ -49,5 +48,4 @@ features = [
|
||||
lto = true
|
||||
|
||||
[patch.crates-io]
|
||||
mio = { git = "https://gitlab.redox-os.org/redox-os/mio.git", branch = "redox-unix" }
|
||||
net2 = { git = "https://gitlab.redox-os.org/redox-os/net2-rs.git", branch = "master" }
|
||||
|
||||
-1
Submodule smoltcp deleted from be52c19154
+26
-16
@@ -1,7 +1,7 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
use anyhow::{Error, Result, Context};
|
||||
use anyhow::{Context, Result};
|
||||
use event::EventQueue;
|
||||
use ioslice::IoSlice;
|
||||
use libredox::Fd;
|
||||
@@ -16,27 +16,34 @@ mod scheme;
|
||||
fn run(daemon: redox_daemon::Daemon) -> Result<()> {
|
||||
use libredox::flag::*;
|
||||
|
||||
let dns_fd = Fd::open(":dns", O_RDWR | O_CREAT | O_NONBLOCK, 0)
|
||||
.context("failed to open :dns")?;
|
||||
let dns_fd =
|
||||
Fd::open(":dns", O_RDWR | O_CREAT | O_NONBLOCK, 0).context("failed to open :dns")?;
|
||||
|
||||
let time_path = format!("/scheme/time/{}", CLOCK_MONOTONIC);
|
||||
let time_fd = Fd::open(&time_path, O_RDWR, 0)
|
||||
.context("failed to open time")?;
|
||||
let time_fd = Fd::open(&time_path, O_RDWR, 0).context("failed to open time")?;
|
||||
|
||||
let nameserver_fd = Fd::open(
|
||||
"/scheme/netcfg/resolv/nameserver",
|
||||
O_RDWR | O_CREAT | O_NONBLOCK,
|
||||
0,
|
||||
).context("failed to open nameserver")?;
|
||||
)
|
||||
.context("failed to open nameserver")?;
|
||||
|
||||
let event_queue = EventQueue::<EventSource>::new()
|
||||
.context("failed to create event queue")?;
|
||||
let event_queue = EventQueue::<EventSource>::new().context("failed to create event queue")?;
|
||||
|
||||
event_queue
|
||||
.subscribe(dns_fd.raw(), EventSource::DnsScheme, event::EventFlags::READ)
|
||||
.subscribe(
|
||||
dns_fd.raw(),
|
||||
EventSource::DnsScheme,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
.context("failed to listen to time events")?;
|
||||
event_queue
|
||||
.subscribe(nameserver_fd.raw(), EventSource::NameserverScheme, event::EventFlags::READ)
|
||||
.subscribe(
|
||||
nameserver_fd.raw(),
|
||||
EventSource::NameserverScheme,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
.context("failed to listen to nameserver socket events")?;
|
||||
event_queue
|
||||
.subscribe(time_fd.raw(), EventSource::Timer, event::EventFlags::READ)
|
||||
@@ -51,8 +58,8 @@ fn run(daemon: redox_daemon::Daemon) -> Result<()> {
|
||||
|
||||
let mut dnsd = Dnsd::new(dns_file, time_file, &event_queue);
|
||||
|
||||
let new_ns = libredox::call::mkns(&[IoSlice::new(b"dns")])
|
||||
.expect("dnsd: failed to create namespace");
|
||||
let new_ns =
|
||||
libredox::call::mkns(&[IoSlice::new(b"dns")]).expect("dnsd: failed to create namespace");
|
||||
libredox::call::setrens(new_ns, new_ns).expect("dnsd: failed to enter namespace");
|
||||
|
||||
daemon.ready().expect("dnsd: failed to notify parent");
|
||||
@@ -60,9 +67,11 @@ fn run(daemon: redox_daemon::Daemon) -> Result<()> {
|
||||
for event_res in event_queue.iter() {
|
||||
let event = event_res.context("failed to read from event queue")?;
|
||||
match event.user_data {
|
||||
EventSource::DnsScheme => if !dnsd.on_dns_file_event()? {
|
||||
break
|
||||
},
|
||||
EventSource::DnsScheme => {
|
||||
if !dnsd.on_dns_file_event()? {
|
||||
break;
|
||||
}
|
||||
}
|
||||
EventSource::NameserverScheme => dnsd.on_nameserver_event()?,
|
||||
EventSource::Timer => dnsd.on_time_event()?,
|
||||
EventSource::Other => dnsd.on_unknown_fd_event(event.fd as RawFd)?,
|
||||
@@ -79,7 +88,8 @@ fn main() {
|
||||
process::exit(1);
|
||||
}
|
||||
process::exit(0);
|
||||
}).expect("dnsd: failed to daemonize");
|
||||
})
|
||||
.expect("dnsd: failed to daemonize");
|
||||
}
|
||||
|
||||
event::user_data! {
|
||||
|
||||
+76
-25
@@ -1,20 +1,23 @@
|
||||
use std::borrow::ToOwned;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::collections::VecDeque;
|
||||
use std::collections::btree_map::Entry;
|
||||
use std::collections::VecDeque;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::fs::File;
|
||||
use std::io::{ErrorKind, Read, Write};
|
||||
use std::mem;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::rc::Rc;
|
||||
use std::str;
|
||||
use std::str::FromStr;
|
||||
use std::rc::Rc;
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use libredox::flag;
|
||||
use syscall::data::TimeSpec;
|
||||
use syscall::{Error as SyscallError, EventFlags as SyscallEventFlags, Packet as SyscallPacket, Result as SyscallResult, SchemeMut};
|
||||
use syscall;
|
||||
use syscall::data::TimeSpec;
|
||||
use syscall::{
|
||||
Error as SyscallError, EventFlags as SyscallEventFlags, Packet as SyscallPacket,
|
||||
Result as SyscallResult, SchemeMut,
|
||||
};
|
||||
|
||||
use event::EventQueue;
|
||||
use redox_netstack::error::{Error, Result};
|
||||
@@ -90,17 +93,25 @@ impl Domains {
|
||||
&format!("udp:{}:53", self.nameserver),
|
||||
libredox::flag::O_RDWR | libredox::flag::O_CREAT | libredox::flag::O_NONBLOCK,
|
||||
0,
|
||||
).ok()?;
|
||||
)
|
||||
.ok()?;
|
||||
if libredox::call::write(udp_fd, &packet) != Ok(packet.len()) {
|
||||
libredox::call::close(udp_fd).ok()?;
|
||||
return None;
|
||||
}
|
||||
queue.subscribe(udp_fd, EventSource::Other, event::EventFlags::READ).ok()?;
|
||||
self.requests.insert(udp_fd as RawFd, domain.to_owned().into());
|
||||
queue
|
||||
.subscribe(udp_fd, EventSource::Other, event::EventFlags::READ)
|
||||
.ok()?;
|
||||
self.requests
|
||||
.insert(udp_fd as RawFd, domain.to_owned().into());
|
||||
Some(udp_fd as RawFd)
|
||||
}
|
||||
|
||||
fn on_time_event(&mut self, cur_time: &TimeSpec, queue: &EventQueue<EventSource>) -> Result<BTreeSet<usize>> {
|
||||
fn on_time_event(
|
||||
&mut self,
|
||||
cur_time: &TimeSpec,
|
||||
queue: &EventQueue<EventSource>,
|
||||
) -> Result<BTreeSet<usize>> {
|
||||
while let Some((timeout, domain)) = self.resolved_timeouts.pop_front() {
|
||||
if timeout.tv_sec > cur_time.tv_sec
|
||||
|| (timeout.tv_sec == cur_time.tv_sec && timeout.tv_nsec > cur_time.tv_nsec)
|
||||
@@ -139,7 +150,9 @@ impl Domains {
|
||||
} = e.remove()
|
||||
{
|
||||
fds_to_wakeup.append(&mut waiting_fds);
|
||||
queue.unsubscribe(socket_fd as usize).map_err(|e| Error::from_syscall_error(e.into(), "unsubscribe failure"))?;
|
||||
queue.unsubscribe(socket_fd as usize).map_err(|e| {
|
||||
Error::from_syscall_error(e.into(), "unsubscribe failure")
|
||||
})?;
|
||||
let _ = libredox::call::close(socket_fd as usize);
|
||||
}
|
||||
}
|
||||
@@ -150,7 +163,12 @@ impl Domains {
|
||||
Ok(fds_to_wakeup)
|
||||
}
|
||||
|
||||
fn on_fd_event(&mut self, fd: RawFd, cur_time: &TimeSpec, queue: &EventQueue<EventSource>) -> Option<DnsParsingResult> {
|
||||
fn on_fd_event(
|
||||
&mut self,
|
||||
fd: RawFd,
|
||||
cur_time: &TimeSpec,
|
||||
queue: &EventQueue<EventSource>,
|
||||
) -> Option<DnsParsingResult> {
|
||||
let e = match self.requests.entry(fd) {
|
||||
Entry::Vacant(_) => {
|
||||
return None;
|
||||
@@ -227,7 +245,13 @@ impl Domains {
|
||||
}
|
||||
}
|
||||
|
||||
fn file_from_domain(&mut self, domain: &str, fd: usize, cur_time: &TimeSpec, queue: &EventQueue<EventSource>) -> DnsFile {
|
||||
fn file_from_domain(
|
||||
&mut self,
|
||||
domain: &str,
|
||||
fd: usize,
|
||||
cur_time: &TimeSpec,
|
||||
queue: &EventQueue<EventSource>,
|
||||
) -> DnsFile {
|
||||
if let Some(domain_data) = self.domains.get_mut(domain) {
|
||||
match *domain_data {
|
||||
Domain::Resolved { ref data } => DnsFile::Resolved {
|
||||
@@ -294,7 +318,7 @@ impl<'q> Dnsd<'q> {
|
||||
const REQUEST_TIMEOUT_S: i64 = 30;
|
||||
const TIME_EVENT_TIMEOUT_S: i64 = 5;
|
||||
|
||||
pub fn new(dns_file: File, time_file: File, queue: &'q EventQueue<EventSource>) -> Dnsd {
|
||||
pub fn new(dns_file: File, time_file: File, queue: &'q EventQueue<EventSource>) -> Self {
|
||||
Dnsd {
|
||||
dns_file,
|
||||
time_file,
|
||||
@@ -339,12 +363,14 @@ impl<'q> Dnsd<'q> {
|
||||
Ok(0) => {
|
||||
//TODO: Cleanup must occur
|
||||
return Ok(false);
|
||||
},
|
||||
}
|
||||
Ok(_) => (),
|
||||
Err(err) => if err.kind() == ErrorKind::WouldBlock {
|
||||
return Ok(true);
|
||||
} else {
|
||||
return Err(Error::from(err));
|
||||
Err(err) => {
|
||||
if err.kind() == ErrorKind::WouldBlock {
|
||||
return Ok(true);
|
||||
} else {
|
||||
return Err(Error::from(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: implement cancellation
|
||||
@@ -364,7 +390,10 @@ impl<'q> Dnsd<'q> {
|
||||
let cur_time = libredox::call::clock_gettime(libredox::flag::CLOCK_MONOTONIC)
|
||||
.map_err(|e| Error::from_syscall_error(e.into(), "Can't get time"))?;
|
||||
// TODO
|
||||
let cur_time = TimeSpec { tv_sec: cur_time.tv_sec, tv_nsec: cur_time.tv_nsec as _ };
|
||||
let cur_time = TimeSpec {
|
||||
tv_sec: cur_time.tv_sec,
|
||||
tv_nsec: cur_time.tv_nsec as _,
|
||||
};
|
||||
|
||||
match self.domains.on_fd_event(fd, &cur_time, self.queue) {
|
||||
Some(DnsParsingResult::FailFiles(fds_to_fail)) => {
|
||||
@@ -432,7 +461,15 @@ impl SchemeMut for Dnsd<'_> {
|
||||
let fd = self.next_fd;
|
||||
self.next_fd += 1;
|
||||
let cur_time = libredox::call::clock_gettime(flag::CLOCK_MONOTONIC)?;
|
||||
let dns_file = self.domains.file_from_domain(&domain, fd, &TimeSpec { tv_sec: cur_time.tv_sec, tv_nsec: cur_time.tv_nsec as i32 }, self.queue);
|
||||
let dns_file = self.domains.file_from_domain(
|
||||
&domain,
|
||||
fd,
|
||||
&TimeSpec {
|
||||
tv_sec: cur_time.tv_sec,
|
||||
tv_nsec: cur_time.tv_nsec as i32,
|
||||
},
|
||||
self.queue,
|
||||
);
|
||||
self.files.insert(fd, dns_file);
|
||||
trace!("Open {} {}", &domain, fd);
|
||||
Ok(fd)
|
||||
@@ -440,7 +477,8 @@ impl SchemeMut for Dnsd<'_> {
|
||||
|
||||
fn close(&mut self, fd: usize) -> SyscallResult<usize> {
|
||||
trace!("Close {}", fd);
|
||||
let file = self.files
|
||||
let file = self
|
||||
.files
|
||||
.get_mut(&fd)
|
||||
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
|
||||
|
||||
@@ -458,14 +496,23 @@ impl SchemeMut for Dnsd<'_> {
|
||||
|
||||
fn read(&mut self, fd: usize, buf: &mut [u8]) -> SyscallResult<usize> {
|
||||
trace!("Read {}", fd);
|
||||
let file = self.files
|
||||
let file = self
|
||||
.files
|
||||
.get_mut(&fd)
|
||||
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
|
||||
|
||||
let cur_time = libredox::call::clock_gettime(flag::CLOCK_MONOTONIC)?;
|
||||
|
||||
if let DnsFile::Waiting { ref domain } = *file {
|
||||
*file = self.domains.file_from_domain(domain, fd, &TimeSpec { tv_sec: cur_time.tv_sec, tv_nsec: cur_time.tv_nsec as i32 }, self.queue);
|
||||
*file = self.domains.file_from_domain(
|
||||
domain,
|
||||
fd,
|
||||
&TimeSpec {
|
||||
tv_sec: cur_time.tv_sec,
|
||||
tv_nsec: cur_time.tv_nsec as i32,
|
||||
},
|
||||
self.queue,
|
||||
);
|
||||
}
|
||||
|
||||
match *file {
|
||||
@@ -487,7 +534,11 @@ impl SchemeMut for Dnsd<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fevent(&mut self, _fd: usize, _events: SyscallEventFlags) -> SyscallResult<SyscallEventFlags> {
|
||||
fn fevent(
|
||||
&mut self,
|
||||
_fd: usize,
|
||||
_events: SyscallEventFlags,
|
||||
) -> SyscallResult<SyscallEventFlags> {
|
||||
Ok(SyscallEventFlags::empty())
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
use std::convert;
|
||||
use std::fmt;
|
||||
use std::result;
|
||||
use std::io::Error as IOError;
|
||||
use std::result;
|
||||
use syscall::error::Error as SyscallError;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -35,7 +35,7 @@ impl Error {
|
||||
pub fn other_error<S: Into<String>>(descr: S) -> Error {
|
||||
Error {
|
||||
error_type: ErrorType::Other,
|
||||
descr: descr.into()
|
||||
descr: descr.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-4
@@ -1,5 +1,2 @@
|
||||
extern crate log;
|
||||
extern crate syscall;
|
||||
|
||||
pub mod logger;
|
||||
pub mod error;
|
||||
pub mod logger;
|
||||
|
||||
+10
-9
@@ -2,15 +2,16 @@ use redox_log::{OutputBuilder, RedoxLogger};
|
||||
|
||||
pub fn init_logger(process_name: &str) {
|
||||
if let Err(_) = RedoxLogger::new()
|
||||
.with_output(
|
||||
OutputBuilder::stdout()
|
||||
.with_ansi_escape_codes()
|
||||
.flush_on_newline(true)
|
||||
.with_filter(log::LevelFilter::Trace)
|
||||
.build(),
|
||||
)
|
||||
.with_process_name(process_name.into())
|
||||
.enable() {
|
||||
.with_output(
|
||||
OutputBuilder::stdout()
|
||||
.with_ansi_escape_codes()
|
||||
.flush_on_newline(true)
|
||||
.with_filter(log::LevelFilter::Trace)
|
||||
.build(),
|
||||
)
|
||||
.with_process_name(process_name.into())
|
||||
.enable()
|
||||
{
|
||||
eprintln!("{process_name}: Failed to init logger")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::ops::{Deref, DerefMut, Drop};
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use std::mem::{replace, swap};
|
||||
use std::ops::{Deref, DerefMut, Drop};
|
||||
use std::rc::Rc;
|
||||
|
||||
type BufferStack = Rc<RefCell<Vec<Vec<u8>>>>;
|
||||
|
||||
|
||||
@@ -111,7 +111,8 @@ impl EthernetLink {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(repr) = ArpPacket::new_checked(packet).and_then(|packet| ArpRepr::parse(&packet)) else {
|
||||
let Ok(repr) = ArpPacket::new_checked(packet).and_then(|packet| ArpRepr::parse(&packet))
|
||||
else {
|
||||
debug!("Dropped incomming arp packet on {} (Malformed)", self.name);
|
||||
return;
|
||||
};
|
||||
@@ -124,7 +125,8 @@ impl EthernetLink {
|
||||
target_hardware_addr,
|
||||
target_protocol_addr,
|
||||
} => {
|
||||
let is_unicast_mac = target_hardware_addr != EMPTY_MAC && !target_hardware_addr.is_broadcast();
|
||||
let is_unicast_mac =
|
||||
target_hardware_addr != EMPTY_MAC && !target_hardware_addr.is_broadcast();
|
||||
|
||||
if is_unicast_mac && hardware_address != target_hardware_addr {
|
||||
// Only process packet that are for us
|
||||
@@ -237,7 +239,10 @@ impl EthernetLink {
|
||||
|
||||
fn handle_missing_neighbor(&mut self, next_hop: IpAddress, packet: &[u8], now: Instant) {
|
||||
let Ok(buf) = self.waiting_packets.enqueue(packet.len(), next_hop) else {
|
||||
warn!("Dropped packet on {} because waiting queue was full", self.name);
|
||||
warn!(
|
||||
"Dropped packet on {} because waiting queue was full",
|
||||
self.name
|
||||
);
|
||||
return;
|
||||
};
|
||||
buf.copy_from_slice(packet);
|
||||
|
||||
@@ -51,8 +51,7 @@ impl LinkDevice for LoopbackDevice {
|
||||
None
|
||||
}
|
||||
|
||||
fn set_mac_address(&mut self, _addr: smoltcp::wire::EthernetAddress) {
|
||||
}
|
||||
fn set_mac_address(&mut self, _addr: smoltcp::wire::EthernetAddress) {}
|
||||
|
||||
fn ip_address(&self) -> Option<smoltcp::wire::IpCidr> {
|
||||
Some("127.0.0.1/8".parse().unwrap())
|
||||
@@ -61,6 +60,4 @@ impl LinkDevice for LoopbackDevice {
|
||||
fn set_ip_address(&mut self, _addr: smoltcp::wire::IpCidr) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
pub mod loopback;
|
||||
pub mod ethernet;
|
||||
pub mod loopback;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use smoltcp::time::Instant;
|
||||
use smoltcp::wire::{IpAddress, EthernetAddress, IpCidr};
|
||||
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
|
||||
|
||||
/// Represent a link layer device (eth0, loopback...)
|
||||
pub trait LinkDevice {
|
||||
|
||||
/// Send the given packet to the machine with the `next_hop` ip address
|
||||
/// This method cannot fail so it's the implementor responsability
|
||||
/// to buffer packets which can't be sent immediatly or decide to
|
||||
|
||||
+33
-38
@@ -1,22 +1,11 @@
|
||||
extern crate event;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate byteorder;
|
||||
extern crate netutils;
|
||||
extern crate redox_netstack;
|
||||
extern crate smoltcp;
|
||||
extern crate syscall;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::fs::File;
|
||||
use std::os::unix::io::{FromRawFd, RawFd};
|
||||
use std::process;
|
||||
use std::rc::Rc;
|
||||
|
||||
use event::{EventQueue, EventFlags};
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use event::{EventFlags, EventQueue};
|
||||
use libredox::flag::{O_CREAT, O_NONBLOCK, O_RDWR};
|
||||
use libredox::Fd;
|
||||
use libredox::flag::{O_RDWR, O_NONBLOCK, O_CREAT};
|
||||
use anyhow::{Result, anyhow, bail, Context};
|
||||
|
||||
use redox_netstack::logger;
|
||||
use scheme::Smolnetd;
|
||||
@@ -72,28 +61,26 @@ fn run(daemon: redox_daemon::Daemon) -> Result<()> {
|
||||
.context("failed to get mac address from network adapter")?;
|
||||
|
||||
trace!("opening :ip");
|
||||
let ip_fd = Fd::open(":ip", O_RDWR | O_CREAT | O_NONBLOCK, 0)
|
||||
.context("failed to open :ip")?;
|
||||
let ip_fd = Fd::open(":ip", O_RDWR | O_CREAT | O_NONBLOCK, 0).context("failed to open :ip")?;
|
||||
|
||||
trace!("opening :udp");
|
||||
let udp_fd = Fd::open(":udp", O_RDWR | O_CREAT | O_NONBLOCK, 0)
|
||||
.context("failed to open :udp")?;
|
||||
let udp_fd =
|
||||
Fd::open(":udp", O_RDWR | O_CREAT | O_NONBLOCK, 0).context("failed to open :udp")?;
|
||||
|
||||
trace!("opening :tcp");
|
||||
let tcp_fd = Fd::open(":tcp", O_RDWR | O_CREAT | O_NONBLOCK, 0)
|
||||
.context("failed to open :tcp")?;
|
||||
let tcp_fd =
|
||||
Fd::open(":tcp", O_RDWR | O_CREAT | O_NONBLOCK, 0).context("failed to open :tcp")?;
|
||||
|
||||
trace!("opening :icmp");
|
||||
let icmp_fd = Fd::open(":icmp", O_RDWR | O_CREAT | O_NONBLOCK, 0)
|
||||
.context("failed to open :icmp")?;
|
||||
let icmp_fd =
|
||||
Fd::open(":icmp", O_RDWR | O_CREAT | O_NONBLOCK, 0).context("failed to open :icmp")?;
|
||||
|
||||
trace!("opening :netcfg");
|
||||
let netcfg_fd = Fd::open(":netcfg", O_RDWR | O_CREAT | O_NONBLOCK, 0)
|
||||
.context("failed to open :netcfg")?;
|
||||
let netcfg_fd =
|
||||
Fd::open(":netcfg", O_RDWR | O_CREAT | O_NONBLOCK, 0).context("failed to open :netcfg")?;
|
||||
|
||||
let time_path = format!("/scheme/time/{}", syscall::CLOCK_MONOTONIC);
|
||||
let time_fd = Fd::open(&time_path, O_RDWR, 0)
|
||||
.context("failed to open /scheme/time")?;
|
||||
let time_fd = Fd::open(&time_path, O_RDWR, 0).context("failed to open /scheme/time")?;
|
||||
|
||||
event::user_data! {
|
||||
enum EventSource {
|
||||
@@ -107,30 +94,36 @@ fn run(daemon: redox_daemon::Daemon) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
let event_queue = EventQueue::<EventSource>::new()
|
||||
.context("failed to create event queue")?;
|
||||
let event_queue = EventQueue::<EventSource>::new().context("failed to create event queue")?;
|
||||
|
||||
daemon.ready().expect("smolnetd: failed to notify parent");
|
||||
|
||||
event_queue.subscribe(network_fd.raw(), EventSource::Network, EventFlags::READ)
|
||||
event_queue
|
||||
.subscribe(network_fd.raw(), EventSource::Network, EventFlags::READ)
|
||||
.context("failed to listen to network events")?;
|
||||
|
||||
event_queue.subscribe(time_fd.raw(), EventSource::Time, EventFlags::READ)
|
||||
event_queue
|
||||
.subscribe(time_fd.raw(), EventSource::Time, EventFlags::READ)
|
||||
.context("failed to listen to timer events")?;
|
||||
|
||||
event_queue.subscribe(ip_fd.raw(), EventSource::IpScheme, EventFlags::READ)
|
||||
event_queue
|
||||
.subscribe(ip_fd.raw(), EventSource::IpScheme, EventFlags::READ)
|
||||
.context("failed to listen to ip scheme events")?;
|
||||
|
||||
event_queue.subscribe(udp_fd.raw(), EventSource::UdpScheme, EventFlags::READ)
|
||||
event_queue
|
||||
.subscribe(udp_fd.raw(), EventSource::UdpScheme, EventFlags::READ)
|
||||
.context("failed to listen to udp scheme events")?;
|
||||
|
||||
event_queue.subscribe(tcp_fd.raw(), EventSource::TcpScheme, EventFlags::READ)
|
||||
event_queue
|
||||
.subscribe(tcp_fd.raw(), EventSource::TcpScheme, EventFlags::READ)
|
||||
.context("failed to listen to tcp scheme events")?;
|
||||
|
||||
event_queue.subscribe(icmp_fd.raw(), EventSource::IcmpScheme, EventFlags::READ)
|
||||
event_queue
|
||||
.subscribe(icmp_fd.raw(), EventSource::IcmpScheme, EventFlags::READ)
|
||||
.context("failed to listen to icmp scheme events")?;
|
||||
|
||||
event_queue.subscribe(netcfg_fd.raw(), EventSource::NetcfgScheme, EventFlags::READ)
|
||||
event_queue
|
||||
.subscribe(netcfg_fd.raw(), EventSource::NetcfgScheme, EventFlags::READ)
|
||||
.context("failed to listen to netcfg scheme events")?;
|
||||
|
||||
let mut smolnetd = Smolnetd::new(
|
||||
@@ -144,15 +137,17 @@ fn run(daemon: redox_daemon::Daemon) -> Result<()> {
|
||||
netcfg_fd,
|
||||
);
|
||||
|
||||
libredox::call::setrens(0, 0)
|
||||
.context("smolnetd: failed to enter null namespace")?;
|
||||
libredox::call::setrens(0, 0).context("smolnetd: failed to enter null namespace")?;
|
||||
|
||||
let all = {
|
||||
use EventSource::*;
|
||||
[Network, Time, IpScheme, UdpScheme, IcmpScheme, NetcfgScheme].map(Ok)
|
||||
};
|
||||
|
||||
for event_res in all.into_iter().chain(event_queue.map(|r| r.map(|e| e.user_data))) {
|
||||
for event_res in all
|
||||
.into_iter()
|
||||
.chain(event_queue.map(|r| r.map(|e| e.user_data)))
|
||||
{
|
||||
match event_res? {
|
||||
EventSource::Network => smolnetd.on_network_scheme_event()?,
|
||||
EventSource::Time => smolnetd.on_time_event()?,
|
||||
|
||||
+20
-19
@@ -1,16 +1,18 @@
|
||||
use smoltcp::socket::icmp::{Endpoint as IcmpEndpoint, PacketMetadata as IcmpPacketMetadata, Socket as IcmpSocket, PacketBuffer as IcmpSocketBuffer};
|
||||
use smoltcp::iface::SocketHandle;
|
||||
use smoltcp::socket::icmp::{
|
||||
Endpoint as IcmpEndpoint, PacketBuffer as IcmpSocketBuffer,
|
||||
PacketMetadata as IcmpPacketMetadata, Socket as IcmpSocket,
|
||||
};
|
||||
use smoltcp::wire::{Icmpv4Packet, Icmpv4Repr, IpAddress, IpListenEndpoint};
|
||||
use std::mem;
|
||||
use std::str;
|
||||
use syscall::{Error as SyscallError, Result as SyscallResult};
|
||||
use syscall;
|
||||
use byteorder::{ByteOrder, NetworkEndian};
|
||||
use syscall::{Error as SyscallError, Result as SyscallResult};
|
||||
|
||||
use super::socket::{Context, DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme};
|
||||
use super::{Smolnetd, SocketSet};
|
||||
use crate::port_set::PortSet;
|
||||
use crate::router::Router;
|
||||
use super::socket::{DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme, Context};
|
||||
use super::{Smolnetd, SocketSet};
|
||||
|
||||
pub type IcmpScheme = SocketScheme<IcmpSocket<'static>>;
|
||||
|
||||
@@ -75,7 +77,7 @@ impl<'a> SchemeSocket for IcmpSocket<'a> {
|
||||
path: &str,
|
||||
_uid: u32,
|
||||
ident_set: &mut Self::SchemeDataT,
|
||||
_context: &Context
|
||||
_context: &Context,
|
||||
) -> SyscallResult<(SocketHandle, Self::DataT)> {
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -95,12 +97,12 @@ impl<'a> SchemeSocket for IcmpSocket<'a> {
|
||||
let socket = IcmpSocket::new(
|
||||
IcmpSocketBuffer::new(
|
||||
vec![IcmpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE]
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
),
|
||||
IcmpSocketBuffer::new(
|
||||
vec![IcmpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE]
|
||||
)
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
),
|
||||
);
|
||||
let handle = socket_set.add(socket);
|
||||
let icmp_socket = socket_set.get_mut::<IcmpSocket>(handle);
|
||||
@@ -127,12 +129,12 @@ impl<'a> SchemeSocket for IcmpSocket<'a> {
|
||||
let socket = IcmpSocket::new(
|
||||
IcmpSocketBuffer::new(
|
||||
vec![IcmpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE]
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
),
|
||||
IcmpSocketBuffer::new(
|
||||
vec![IcmpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE]
|
||||
)
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
),
|
||||
);
|
||||
let handle = socket_set.add(socket);
|
||||
let icmp_socket = socket_set.get_mut::<IcmpSocket>(handle);
|
||||
@@ -175,24 +177,23 @@ impl<'a> SchemeSocket for IcmpSocket<'a> {
|
||||
if buf.len() < mem::size_of::<u16>() {
|
||||
return Err(SyscallError::new(syscall::EINVAL));
|
||||
}
|
||||
let (seq_buf, payload) = buf.split_at(mem::size_of::<u16>());
|
||||
let seq_no = NetworkEndian::read_u16(seq_buf);
|
||||
let (&seq_buf, payload) = buf.split_first_chunk::<2>().unwrap();
|
||||
let seq_no = u16::from_be_bytes(seq_buf);
|
||||
let icmp_repr = Icmpv4Repr::EchoRequest {
|
||||
ident: file.data.ident,
|
||||
seq_no,
|
||||
data: payload,
|
||||
};
|
||||
|
||||
let icmp_payload = self.send(icmp_repr.buffer_len(), file.data.ip)
|
||||
let icmp_payload = self
|
||||
.send(icmp_repr.buffer_len(), file.data.ip)
|
||||
.map_err(|_| syscall::Error::new(syscall::EINVAL))?;
|
||||
let mut icmp_packet = Icmpv4Packet::new_unchecked(icmp_payload);
|
||||
//TODO: replace Default with actual caps
|
||||
icmp_repr.emit(&mut icmp_packet, &Default::default());
|
||||
Ok(Some(buf.len()))
|
||||
}
|
||||
IcmpSocketType::Udp => {
|
||||
Err(SyscallError::new(syscall::EINVAL))
|
||||
}
|
||||
IcmpSocketType::Udp => Err(SyscallError::new(syscall::EINVAL)),
|
||||
}
|
||||
} else if file.flags & syscall::O_NONBLOCK == syscall::O_NONBLOCK {
|
||||
Err(SyscallError::new(syscall::EAGAIN))
|
||||
@@ -216,7 +217,7 @@ impl<'a> SchemeSocket for IcmpSocket<'a> {
|
||||
if buf.len() < mem::size_of::<u16>() + data.len() {
|
||||
return Err(SyscallError::new(syscall::EINVAL));
|
||||
}
|
||||
NetworkEndian::write_u16(&mut buf[0..2], seq_no);
|
||||
buf[0..2].copy_from_slice(&seq_no.to_be_bytes());
|
||||
|
||||
for i in 0..data.len() {
|
||||
buf[mem::size_of::<u16>() + i] = data[i];
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
use smoltcp::socket::raw::{PacketMetadata as RawPacketMetadata, Socket as RawSocket, PacketBuffer as RawSocketBuffer};
|
||||
use smoltcp::iface::SocketHandle;
|
||||
use smoltcp::socket::raw::{
|
||||
PacketBuffer as RawSocketBuffer, PacketMetadata as RawPacketMetadata, Socket as RawSocket,
|
||||
};
|
||||
use smoltcp::wire::{IpProtocol, IpVersion};
|
||||
use std::str;
|
||||
use syscall::{Error as SyscallError, Result as SyscallResult};
|
||||
use syscall;
|
||||
use syscall::{Error as SyscallError, Result as SyscallResult};
|
||||
|
||||
use crate::router::Router;
|
||||
|
||||
use super::socket::{Context, DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme};
|
||||
use super::{Smolnetd, SocketSet};
|
||||
use super::socket::{DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme, Context};
|
||||
|
||||
pub type IpScheme = SocketScheme<RawSocket<'static>>;
|
||||
|
||||
@@ -60,7 +62,7 @@ impl<'a> SchemeSocket for RawSocket<'a> {
|
||||
path: &str,
|
||||
uid: u32,
|
||||
_: &mut Self::SchemeDataT,
|
||||
_context: &Context
|
||||
_context: &Context,
|
||||
) -> SyscallResult<(SocketHandle, Self::DataT)> {
|
||||
if uid != 0 {
|
||||
return Err(SyscallError::new(syscall::EACCES));
|
||||
@@ -70,11 +72,11 @@ impl<'a> SchemeSocket for RawSocket<'a> {
|
||||
|
||||
let rx_buffer = RawSocketBuffer::new(
|
||||
vec![RawPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE]
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
);
|
||||
let tx_buffer = RawSocketBuffer::new(
|
||||
vec![RawPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE]
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
);
|
||||
let ip_socket = RawSocket::new(
|
||||
IpVersion::Ipv4,
|
||||
|
||||
@@ -240,7 +240,7 @@ fn mk_root_node(
|
||||
dev.set_ip_address(cidr);
|
||||
// FIXME: Here, the insert 0 is a workaround to let UDP sockets
|
||||
// work with this interface only.
|
||||
// Smoltcp takes the first ip address when looking for a source
|
||||
// Smoltcp takes the first ip address when looking for a source
|
||||
// ip address when sending UDP packets.
|
||||
// This behavior will have to be fixed as it's our route table
|
||||
// job to find give this source.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::collections::BTreeMap;
|
||||
use std::rc::Rc;
|
||||
use syscall::Result as SyscallResult;
|
||||
|
||||
pub type CfgNodeRef = Rc<RefCell<dyn CfgNode>>;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::collections::btree_map::Entry;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct Notifier {
|
||||
listeners: BTreeMap<String, BTreeSet<usize>>,
|
||||
|
||||
@@ -11,9 +11,9 @@ use std::rc::Rc;
|
||||
use std::str;
|
||||
|
||||
use libredox::flag::{self, CLOCK_MONOTONIC};
|
||||
use syscall::{self, KSMSG_CANCEL};
|
||||
use syscall::data::TimeSpec;
|
||||
use syscall::flag::{EVENT_READ, EVENT_WRITE};
|
||||
use syscall::{self, KSMSG_CANCEL};
|
||||
use syscall::{
|
||||
Error as SyscallError, EventFlags as SyscallEventFlags, Packet as SyscallPacket,
|
||||
Result as SyscallResult, SchemeBlockMut,
|
||||
@@ -383,7 +383,13 @@ where
|
||||
|
||||
if let Some(ref mut timeout) = timeout {
|
||||
let cur_time = libredox::call::clock_gettime(CLOCK_MONOTONIC)?;
|
||||
*timeout = add_time(timeout, &TimeSpec { tv_sec: cur_time.tv_sec, tv_nsec: cur_time.tv_nsec as i32 })
|
||||
*timeout = add_time(
|
||||
timeout,
|
||||
&TimeSpec {
|
||||
tv_sec: cur_time.tv_sec,
|
||||
tv_nsec: cur_time.tv_nsec as i32,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Ok(timeout)
|
||||
@@ -641,11 +647,11 @@ where
|
||||
SchemeFile::Socket(ref mut file) => {
|
||||
let mut socket_set = self.socket_set.borrow_mut();
|
||||
let socket = socket_set.get_mut::<SocketT>(file.socket_handle);
|
||||
|
||||
|
||||
let ret = SocketT::read_buf(socket, file, buf);
|
||||
match ret {
|
||||
Ok(None) => {}
|
||||
_ => file.read_notified = false
|
||||
_ => file.read_notified = false,
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -199,7 +199,7 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
|
||||
"listen" => {
|
||||
if let SchemeFile::Socket(ref tcp_handle) = *file {
|
||||
let Some(listen_enpoint) = tcp_handle.data else {
|
||||
// This socket is not listening so we can't accept a connection
|
||||
// This socket is not listening so we can't accept a connection
|
||||
return Err(SyscallError::new(syscall::EINVAL));
|
||||
};
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
use smoltcp::socket::udp::{PacketMetadata as UdpPacketMetadata, Socket as UdpSocket, PacketBuffer as UdpSocketBuffer};
|
||||
use smoltcp::iface::SocketHandle;
|
||||
use smoltcp::socket::udp::{
|
||||
PacketBuffer as UdpSocketBuffer, PacketMetadata as UdpPacketMetadata, Socket as UdpSocket,
|
||||
};
|
||||
use smoltcp::wire::{IpEndpoint, IpListenEndpoint};
|
||||
use std::str;
|
||||
use syscall::{Error as SyscallError, Result as SyscallResult};
|
||||
use syscall;
|
||||
use syscall::{Error as SyscallError, Result as SyscallResult};
|
||||
|
||||
use super::socket::{Context, DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme};
|
||||
use super::{parse_endpoint, Smolnetd, SocketSet};
|
||||
use crate::port_set::PortSet;
|
||||
use crate::router::Router;
|
||||
use super::socket::{DupResult, SchemeFile, SchemeSocket, SocketFile, SocketScheme, Context};
|
||||
use super::{parse_endpoint, Smolnetd, SocketSet};
|
||||
|
||||
pub type UdpScheme = SocketScheme<UdpSocket<'static>>;
|
||||
|
||||
@@ -62,7 +64,7 @@ impl<'a> SchemeSocket for UdpSocket<'a> {
|
||||
path: &str,
|
||||
uid: u32,
|
||||
port_set: &mut Self::SchemeDataT,
|
||||
_context: &Context
|
||||
_context: &Context,
|
||||
) -> SyscallResult<(SocketHandle, Self::DataT)> {
|
||||
let mut parts = path.split('/');
|
||||
let remote_endpoint = parse_endpoint(parts.next().unwrap_or(""));
|
||||
@@ -74,11 +76,11 @@ impl<'a> SchemeSocket for UdpSocket<'a> {
|
||||
|
||||
let rx_buffer = UdpSocketBuffer::new(
|
||||
vec![UdpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE]
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
);
|
||||
let tx_buffer = UdpSocketBuffer::new(
|
||||
vec![UdpPacketMetadata::EMPTY; Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE]
|
||||
vec![0; Router::MTU * Smolnetd::SOCKET_BUFFER_SIZE],
|
||||
);
|
||||
let udp_socket = UdpSocket::new(rx_buffer, tx_buffer);
|
||||
|
||||
@@ -97,7 +99,6 @@ impl<'a> SchemeSocket for UdpSocket<'a> {
|
||||
.bind(local_endpoint)
|
||||
.expect("Can't bind udp socket to local endpoint");
|
||||
|
||||
|
||||
Ok((socket_handle, remote_endpoint))
|
||||
}
|
||||
|
||||
@@ -122,7 +123,12 @@ impl<'a> SchemeSocket for UdpSocket<'a> {
|
||||
}
|
||||
if self.can_send() {
|
||||
let endpoint = file.data;
|
||||
let endpoint = IpEndpoint::new(endpoint.addr.expect("If we can send, this should be specified"), endpoint.port);
|
||||
let endpoint = IpEndpoint::new(
|
||||
endpoint
|
||||
.addr
|
||||
.expect("If we can send, this should be specified"),
|
||||
endpoint.port,
|
||||
);
|
||||
self.send_slice(buf, endpoint).expect("Can't send slice");
|
||||
Ok(Some(buf.len()))
|
||||
} else if file.flags & syscall::O_NONBLOCK == syscall::O_NONBLOCK {
|
||||
|
||||
Reference in New Issue
Block a user