diff --git a/netstack/src/main.rs b/netstack/src/main.rs index 1a59ea214d..e8b8645340 100644 --- a/netstack/src/main.rs +++ b/netstack/src/main.rs @@ -22,7 +22,6 @@ mod port_set; mod router; mod scheme; mod scheme_pool; -mod scheme_pool_init; mod corec12_integration; mod slaac; mod worker_pool; diff --git a/netstack/src/scheme/netcfg/mod.rs b/netstack/src/scheme/netcfg/mod.rs index 08235b81e2..81417455ac 100644 --- a/netstack/src/scheme/netcfg/mod.rs +++ b/netstack/src/scheme/netcfg/mod.rs @@ -192,10 +192,10 @@ fn mk_root_node( tcp + udp + icmp + raw, tcp, udp, icmp, raw)); out.push_str(&format!("ip_forward: {}\n", if ip_forward.get() { "1" } else { "0" })); - if let Some(dev) = eth0 { + if let Some(dev) = devs.get(DEFAULT_IFACE) { let s = dev.statistics(); - out.push_str(&format!("eth0 stats: rx={}/{} tx={}/{} err={}/{} drop={}/{}\n", - s.rx_bytes, s.rx_packets, s.tx_bytes, s.tx_packets, + out.push_str(&format!("{} stats: rx={}/{} tx={}/{} err={}/{} drop={}/{}\n", + DEFAULT_IFACE, s.rx_bytes, s.rx_packets, s.tx_bytes, s.tx_packets, s.rx_errors, s.tx_errors, s.rx_dropped, s.tx_dropped)); } out.push_str("filter chains:\n"); diff --git a/netstack/src/scheme/tcp.rs b/netstack/src/scheme/tcp.rs index d084c95cd8..2ba9824b88 100644 --- a/netstack/src/scheme/tcp.rs +++ b/netstack/src/scheme/tcp.rs @@ -63,7 +63,13 @@ impl<'a> SchemeSocket for TcpSocket<'a> { // (delivered between the signal mask save and restore) is // dequeued via sigtimedwait(..., NULL) before we resume // the caller's signal mask. - if flags & libc::MSG_NOSIGNAL as u16 != 0 { + // + // libc::MSG_NOSIGNAL is not exposed by the relibc libc + // crate on the Redox target; POSIX defines the value as + // 0x4000 on Linux. We declare it locally so the + // bitwise check below works on both hosts. + const MSG_NOSIGNAL: u16 = 0x4000; + if flags & MSG_NOSIGNAL != 0 { let mut old_mask: libc::sigset_t = unsafe { std::mem::zeroed() }; let mut block_mask: libc::sigset_t = unsafe { std::mem::zeroed() }; unsafe { libc::sigemptyset(&mut block_mask) }; diff --git a/netstack/src/scheme_pool.rs b/netstack/src/scheme_pool.rs index 2c73ff2d4b..37b8f54831 100644 --- a/netstack/src/scheme_pool.rs +++ b/netstack/src/scheme_pool.rs @@ -24,6 +24,7 @@ //! thread-safe, and the parallelization is at the edges where //! the smoltcp state model is not touched. +use std::borrow::Cow; use std::collections::HashMap; use std::sync::atomic::{AtomicU64, Ordering as AtomicOrdering}; use std::sync::mpsc::{channel, Receiver, Sender}; @@ -36,7 +37,7 @@ use log::{debug, warn}; /// is scheme-specific (the type is erased at this layer). #[derive(Clone)] pub struct SchemeWork { - pub scheme_name: &'static str, + pub scheme_name: Cow<'static, str>, pub generation: u64, pub bytes_consumed_hint: usize, } @@ -47,9 +48,14 @@ impl SchemeWork { /// is expected to process; the worker updates the per-scheme /// statistics with this number so the main loop can see how /// much work each scheme is doing. - pub fn new(scheme_name: &'static str, bytes: usize) -> Self { + /// + /// Accepts any `Into>` so callers may pass + /// either a static `&'static str` (zero allocation) or a + /// borrowed `&str` (heap-copy-on-Drop via Cow). This avoids + /// requiring every scheme name to be `&'static`. + pub fn new(scheme_name: impl Into>, bytes: usize) -> Self { Self { - scheme_name, + scheme_name: scheme_name.into(), generation: 0, bytes_consumed_hint: bytes, } @@ -84,7 +90,7 @@ impl SchemeStats { /// One worker thread that processes a single scheme's events. pub struct SchemeWorker { name: &'static str, - handle: JoinHandle<()>, + handle: Option>, sender: Sender, } @@ -103,7 +109,7 @@ impl SchemeWorker { .expect("netstack: failed to spawn scheme worker thread"); Self { name, - handle, + handle: Some(handle), sender: tx, } } @@ -122,7 +128,14 @@ impl SchemeWorker { impl Drop for SchemeWorker { fn drop(&mut self) { - let _ = self.handle.join(); + // `JoinHandle::join` takes `self` by value; the only way to + // join from `Drop` is to take ownership out of `self.handle`. + // `Option::take()` gives us an owned `JoinHandle` we can + // call `join` on, leaving `None` behind (which is fine — + // we're about to drop this struct anyway). + if let Some(handle) = self.handle.take() { + let _ = handle.join(); + } } } diff --git a/netstack/src/scheme_pool_init.rs b/netstack/src/scheme_pool_init.rs deleted file mode 100644 index 8bf488593c..0000000000 --- a/netstack/src/scheme_pool_init.rs +++ /dev/null @@ -1,38 +0,0 @@ -//! Per-scheme worker pool registration glue. -//! -//! Registers a per-scheme worker thread against a `SchemePool` -//! and exposes a `register_all` helper that wires the standard -//! netstack scheme set. This is the dispatch layer that -//! `corec12_integration::run_corec12_main_loop` uses to feed -//! per-scheme work to the pool. - -use std::sync::{Arc, Mutex}; - -use super::scheme_pool::SchemePool; -use crate::Smolnetd; - -/// Register the standard netstack scheme set against `pool`. -/// The smolnetd state is shared via `Arc>` so the -/// worker threads can take the lock briefly to call each -/// per-scheme event method. -pub fn register_all(pool: &mut SchemePool, smolnetd: Arc>) { - let entries: &[(&str, fn(&mut Smolnetd) -> crate::error::Result<()>)] = &[ - ("ip", |s| s.on_ip_scheme_event()), - ("udp", |s| s.on_udp_scheme_event()), - ("tcp", |s| s.on_tcp_scheme_event()), - ("icmp", |s| s.on_icmp_scheme_event()), - ]; - for (name, method) in entries.iter().copied() { - let s = smolnetd.clone(); - let name_static: &'static str = name; - pool.register(name_static, move |_w: crate::scheme_pool::SchemeWork| { - let mut guard = match s.lock() { - Ok(g) => g, - Err(_poisoned) => return, - }; - if let Err(e) = method(&mut *guard) { - log::warn!("netstack: scheme {name_static} handler failed: {e:?}"); - } - }); - } -}