From dda88e3a3bcfd88c0b03582fe18bd31484959a3e Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sat, 5 Apr 2025 18:47:01 +0200 Subject: [PATCH] Migrate dnsd to redox-scheme. --- Cargo.lock | 185 ++++++++++++++++++++++------------ netstack/Cargo.toml | 4 +- netstack/src/dnsd/main.rs | 15 +-- netstack/src/dnsd/scheme.rs | 194 +++++++++++++++++++++++------------- netstack/src/lib/error.rs | 11 ++ 5 files changed, 270 insertions(+), 139 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 543e95c742..f007c41b2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -163,9 +163,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.16" +version = "1.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" dependencies = [ "shlex", ] @@ -198,18 +198,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.31" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.31" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" dependencies = [ "anstream", "anstyle", @@ -252,9 +252,18 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "defmt" -version = "0.3.10" +version = "0.3.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f6162c53f659f65d00619fe31f14556a6e9f8752ccc4a41bd177ffcf3d6130" +checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" +dependencies = [ + "defmt 1.0.1", +] + +[[package]] +name = "defmt" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" dependencies = [ "bitflags 1.3.2", "defmt-macros", @@ -262,9 +271,9 @@ dependencies = [ [[package]] name = "defmt-macros" -version = "0.4.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d135dd939bad62d7490b0002602d35b358dce5fd9233a709d3c1ef467d4bde6" +checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e" dependencies = [ "defmt-parser", "proc-macro-error2", @@ -275,9 +284,9 @@ dependencies = [ [[package]] name = "defmt-parser" -version = "0.4.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3983b127f13995e68c1e29071e5d115cd96f215ccb5e6812e3728cd6f92653b3" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" dependencies = [ "thiserror", ] @@ -349,14 +358,15 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core", ] @@ -383,9 +393,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown", @@ -416,7 +426,7 @@ dependencies = [ "redox-daemon", "redox-scheme 0.2.4", "redox_event", - "redox_syscall 0.5.10", + "redox_syscall 0.5.11", ] [[package]] @@ -437,9 +447,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.170" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libredox" @@ -461,14 +471,14 @@ dependencies = [ "bitflags 2.9.0", "ioslice", "libc", - "redox_syscall 0.5.10", + "redox_syscall 0.5.11", ] [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "logd" @@ -477,7 +487,7 @@ dependencies = [ "libredox 0.1.3", "redox-daemon", "redox-scheme 0.2.4", - "redox_syscall 0.5.10", + "redox_syscall 0.5.11", ] [[package]] @@ -555,9 +565,9 @@ checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f" [[package]] name = "once_cell" -version = "1.21.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde51589ab56b20a6f686b2c68f7a0bd6add753d697abf720d63f8db3ab7b1ad" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "opaque-debug" @@ -584,9 +594,9 @@ checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ "zerocopy", ] @@ -630,7 +640,7 @@ dependencies = [ "redox-daemon", "redox-scheme 0.3.0", "redox_event", - "redox_syscall 0.5.10", + "redox_syscall 0.5.11", "redox_termios", ] @@ -642,9 +652,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -656,8 +666,8 @@ dependencies = [ "indexmap", "libredox 0.1.3", "redox-daemon", - "redox-scheme 0.5.0", - "redox_syscall 0.5.10", + "redox-scheme 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.5.11", "slab", ] @@ -687,15 +697,15 @@ dependencies = [ "raw-cpuid", "redox-daemon", "redox-scheme 0.2.4", - "redox_syscall 0.5.10", + "redox_syscall 0.5.11", "sha2", ] [[package]] name = "raw-cpuid" -version = "11.4.0" +version = "11.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529468c1335c1c03919960dfefdb1b3648858c20d7ec2d0663e728e4a717efbc" +checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" dependencies = [ "bitflags 2.9.0", ] @@ -739,7 +749,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6143c4d307e1c99ac14f60b5b07b2dccaf9d17137f7cee4e4e29977dd8014a1b" dependencies = [ "libredox 0.1.3", - "redox_syscall 0.5.10", + "redox_syscall 0.5.11", ] [[package]] @@ -749,7 +759,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e7f06e1b19d8143043e959fbd7b76a37e759e3e9c6bbfc9c91c496b0b44d20" dependencies = [ "libredox 0.1.3", - "redox_syscall 0.5.10", + "redox_syscall 0.5.11", ] [[package]] @@ -759,7 +769,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a96b9cfb034251dfb0aaa66a67059a7f0ea344039904d1d70cd36266af9c8a2f" dependencies = [ "libredox 0.1.3", - "redox_syscall 0.5.10", + "redox_syscall 0.5.11", +] + +[[package]] +name = "redox-scheme" +version = "0.5.0" +source = "git+https://gitlab.redox-os.org/redox-os/redox-scheme.git#ce4eead6798c2d1d1d5a6d57b45481a4909ec62e" +dependencies = [ + "libredox 0.1.3", + "redox_syscall 0.5.11", ] [[package]] @@ -784,8 +803,9 @@ dependencies = [ "netutils", "redox-daemon", "redox-log", + "redox-scheme 0.5.0 (git+https://gitlab.redox-os.org/redox-os/redox-scheme.git)", "redox_event", - "redox_syscall 0.5.10", + "redox_syscall 0.5.11", "smoltcp", ] @@ -800,9 +820,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ "bitflags 2.9.0", ] @@ -877,9 +897,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "smoltcp" @@ -890,7 +910,7 @@ dependencies = [ "bitflags 1.3.2", "byteorder 1.5.0", "cfg-if 1.0.0", - "defmt", + "defmt 0.3.100", "heapless", "log", "managed", @@ -910,9 +930,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.99" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -921,9 +941,9 @@ dependencies = [ [[package]] name = "termion" -version = "4.0.4" +version = "4.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f359c854fbecc1ea65bc3683f1dcb2dce78b174a1ca7fda37acd1fff81df6ff" +checksum = "3669a69de26799d6321a5aa713f55f7e2cd37bd47be044b50f2acafc42c122bb" dependencies = [ "libc", "libredox 0.1.3", @@ -991,9 +1011,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-normalization" @@ -1109,18 +1129,62 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.52.0" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ - "windows-targets", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] name = "windows-link" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +dependencies = [ + "windows-link", +] [[package]] name = "windows-sys" @@ -1197,19 +1261,18 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ - "byteorder 1.5.0", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", @@ -1223,5 +1286,5 @@ dependencies = [ "libredox 0.1.3", "redox-daemon", "redox-scheme 0.2.4", - "redox_syscall 0.5.10", + "redox_syscall 0.5.11", ] diff --git a/netstack/Cargo.toml b/netstack/Cargo.toml index 770b92c6a1..386a6e8466 100644 --- a/netstack/Cargo.toml +++ b/netstack/Cargo.toml @@ -19,12 +19,14 @@ path = "src/lib/lib.rs" netutils = { git = "https://gitlab.redox-os.org/redox-os/netutils.git" } redox_event = "0.4.1" redox-daemon = "0.1.2" -redox_syscall = "0.5" +redox_syscall = { version = "0.5", features = ["std"] } redox-log = "0.1" dns-parser = "0.7.1" libredox = { version = "0.1.3", features = ["mkns"] } anyhow = "1.0.81" ioslice = "0.6.0" +#redox-scheme = "0.5.0" +redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" } [dependencies.log] version = "0.4" diff --git a/netstack/src/dnsd/main.rs b/netstack/src/dnsd/main.rs index d47c240084..994b45bc4f 100644 --- a/netstack/src/dnsd/main.rs +++ b/netstack/src/dnsd/main.rs @@ -6,6 +6,7 @@ use event::EventQueue; use ioslice::IoSlice; use libredox::Fd; use redox_netstack::logger; +use redox_scheme::Socket; use scheme::Dnsd; use std::fs::File; use std::os::unix::io::{FromRawFd, RawFd}; @@ -16,8 +17,7 @@ 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_socket = Socket::nonblock("dns").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")?; @@ -33,7 +33,7 @@ fn run(daemon: redox_daemon::Daemon) -> Result<()> { event_queue .subscribe( - dns_fd.raw(), + dns_socket.inner().raw(), EventSource::DnsScheme, event::EventFlags::READ, ) @@ -49,14 +49,9 @@ fn run(daemon: redox_daemon::Daemon) -> Result<()> { .subscribe(time_fd.raw(), EventSource::Timer, event::EventFlags::READ) .context("failed to listen to timer events")?; - let (dns_file, time_file) = unsafe { - ( - File::from_raw_fd(dns_fd.into_raw() as RawFd), - File::from_raw_fd(time_fd.into_raw() as RawFd), - ) - }; + let time_file = unsafe { File::from_raw_fd(time_fd.into_raw() as RawFd) }; - let mut dnsd = Dnsd::new(dns_file, time_file, &event_queue); + let mut dnsd = Dnsd::new(dns_socket, time_file, &event_queue); let new_ns = libredox::call::mkns(&[IoSlice::new(b"dns")]).expect("dnsd: failed to create namespace"); diff --git a/netstack/src/dnsd/scheme.rs b/netstack/src/dnsd/scheme.rs index dc766d366b..08a56be7e0 100644 --- a/netstack/src/dnsd/scheme.rs +++ b/netstack/src/dnsd/scheme.rs @@ -1,9 +1,9 @@ use std::borrow::ToOwned; use std::collections::btree_map::Entry; -use std::collections::VecDeque; use std::collections::{BTreeMap, BTreeSet}; +use std::collections::{HashMap, VecDeque}; use std::fs::File; -use std::io::{ErrorKind, Read, Write}; +use std::io::{Read, Write}; use std::mem; use std::net::Ipv4Addr; use std::os::unix::io::RawFd; @@ -12,15 +12,15 @@ use std::str; use std::str::FromStr; use libredox::flag; -use syscall; +use redox_scheme::scheme::{IntoTag, Op, OpRead, SchemeSync}; +use redox_scheme::{CallerCtx, Id, OpenResult, RequestKind, Response, SignalBehavior}; use syscall::data::TimeSpec; -use syscall::{ - Error as SyscallError, EventFlags as SyscallEventFlags, Packet as SyscallPacket, - Result as SyscallResult, SchemeMut, -}; +use syscall::schemev2::NewFdFlags; +use syscall::{self, EAGAIN, ECANCELED, ENOSYS, EWOULDBLOCK}; +use syscall::{Error as SyscallError, EventFlags as SyscallEventFlags, Result as SyscallResult}; use event::EventQueue; -use redox_netstack::error::{Error, Result}; +use redox_netstack::error::{Error, Result, ResultExt}; use dns_parser::{Builder, Packet as DNSPacket, RRData, ResponseCode}; use dns_parser::{QueryClass, QueryType}; @@ -304,12 +304,15 @@ impl Domains { } pub struct Dnsd<'q> { - dns_file: File, + scheme_socket: redox_scheme::Socket, time_file: File, queue: &'q EventQueue, files: BTreeMap, domains: Domains, - wait_map: BTreeMap, + + blocked_ids: HashMap, + blocked_fds: HashMap>, + next_fd: usize, } @@ -318,14 +321,19 @@ 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) -> Self { + pub fn new( + scheme_socket: redox_scheme::Socket, + time_file: File, + queue: &'q EventQueue, + ) -> Self { Dnsd { - dns_file, + scheme_socket, time_file, queue, files: BTreeMap::new(), domains: Domains::new(), - wait_map: BTreeMap::new(), + blocked_ids: HashMap::new(), + blocked_fds: HashMap::new(), next_fd: 1, } } @@ -358,30 +366,58 @@ impl<'q> Dnsd<'q> { pub fn on_dns_file_event(&mut self) -> Result { loop { - let mut packet = SyscallPacket::default(); - match self.dns_file.read(&mut packet) { - Ok(0) => { + let req = match self.scheme_socket.next_request(SignalBehavior::Restart) { + Ok(None) => { //TODO: Cleanup must occur return Ok(false); } - Ok(_) => (), - Err(err) => { - if err.kind() == ErrorKind::WouldBlock { - return Ok(true); + Ok(Some(req)) => req, + Err(err) if err.errno == EWOULDBLOCK || err.errno == EAGAIN => { + return Ok(true); + } + Err(err) => return Err(err).context("scheme read error"), + }; + let req = match req.kind() { + RequestKind::Call(call) => call, + RequestKind::OnClose { id } => { + self.on_close(id); + continue; + } + RequestKind::Cancellation(req) => { + if let Some((_, op)) = self.blocked_ids.remove(&req.id) { + if let Some(blocked) = self.blocked_fds.get_mut(&op.fd) { + blocked.retain(|id| *id != req.id); + } + self.scheme_socket + .write_response(Response::err(ECANCELED, op), SignalBehavior::Restart) + .context("scheme write fail")?; + } + continue; + } + _ => continue, + }; + let ctx = req.caller(); + + let resp = match req.op() { + Err(req) => Response::err(ENOSYS, req), + Ok(Op::Read(mut op)) => { + let fd = op.fd; + // TODO: nonblock read flag to bypass blocking + let res = self.read(fd, op.buf(), 0, 0, &ctx); + if res == Err(SyscallError::new(EWOULDBLOCK)) { + let id = op.req_id(); + self.blocked_ids.insert(id, (ctx, op)); + self.blocked_fds.entry(fd).or_default().push(id); + continue; } else { - return Err(Error::from(err)); + Response::new(res, op) } } - } - // TODO: implement cancellation - let a = packet.a; - self.handle(&mut packet); - if packet.a != (-syscall::EWOULDBLOCK) as usize { - self.dns_file.write_all(&packet)?; - } else { - packet.a = a; - self.handle_block(packet)?; - } + Ok(op) => op.handle_sync(ctx, self), + }; + self.scheme_socket + .write_response(resp, SignalBehavior::Restart) + .context("scheme write fail")?; } } @@ -418,23 +454,29 @@ impl<'q> Dnsd<'q> { } fn wakeup_fds(&mut self, fds_to_wakeup: &BTreeSet) { - let mut syscall_packets = vec![]; for fd in fds_to_wakeup { - if let Some(packet) = self.wait_map.remove(fd) { - syscall_packets.push(packet); + let Some(affected) = self.blocked_fds.remove(&fd) else { + continue; + }; + for id in affected { + let Some((ctx, mut op)) = self.blocked_ids.remove(&id) else { + continue; + }; + // TODO: deduplicate code + let fd = op.fd; + // TODO: nonblock read flag to bypass blocking + let res = self.read(fd, op.buf(), 0, 0, &ctx); + let resp = if res == Err(SyscallError::new(EWOULDBLOCK)) { + self.blocked_ids.insert(id, (ctx, op)); + self.blocked_fds.entry(fd).or_default().push(id); + continue; + } else { + Response::new(res, op) + }; + self.scheme_socket + .write_response(resp, SignalBehavior::Restart); } } - - for mut packet in syscall_packets.drain(..) { - self.handle(&mut packet); - let _ = self.dns_file.write_all(&packet); - } - } - - fn handle_block(&mut self, packet: SyscallPacket) -> Result<()> { - let fd = packet.b; - self.wait_map.insert(fd, packet); - Ok(()) } fn validate_domain(domain: &str) -> bool { @@ -452,8 +494,23 @@ impl<'q> Dnsd<'q> { } } -impl SchemeMut for Dnsd<'_> { - fn open(&mut self, url: &str, _flags: usize, _uid: u32, _gid: u32) -> SyscallResult { +impl Dnsd<'_> { + fn on_close(&mut self, fd: usize) { + trace!("Close {}", fd); + let Some(file) = self.files.get_mut(&fd) else { + return; + }; + + if let DnsFile::Waiting { ref domain } = *file { + self.domains.unwait_fd(domain, fd); + } + + self.files.remove(&fd); + } +} + +impl SchemeSync for Dnsd<'_> { + fn open(&mut self, url: &str, _flags: usize, _ctx: &CallerCtx) -> SyscallResult { let domain = url.to_lowercase(); if domain.is_empty() || !Dnsd::validate_domain(&domain) { return Err(SyscallError::new(syscall::EINVAL)); @@ -472,29 +529,31 @@ impl SchemeMut for Dnsd<'_> { ); self.files.insert(fd, dns_file); trace!("Open {} {}", &domain, fd); - Ok(fd) + Ok(OpenResult::ThisScheme { + number: fd, + flags: NewFdFlags::empty(), + }) } - fn close(&mut self, fd: usize) -> SyscallResult { - trace!("Close {}", fd); - let file = self - .files - .get_mut(&fd) - .ok_or_else(|| SyscallError::new(syscall::EBADF))?; - - if let DnsFile::Waiting { ref domain } = *file { - self.domains.unwait_fd(domain, fd); - } - - self.files.remove(&fd); - Ok(0) - } - - fn write(&mut self, _fd: usize, _buf: &[u8]) -> SyscallResult { + fn write( + &mut self, + _fd: usize, + _buf: &[u8], + _off: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> SyscallResult { Err(SyscallError::new(syscall::EINVAL)) } - fn read(&mut self, fd: usize, buf: &mut [u8]) -> SyscallResult { + fn read( + &mut self, + fd: usize, + buf: &mut [u8], + _off: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> SyscallResult { trace!("Read {}", fd); let file = self .files @@ -538,11 +597,12 @@ impl SchemeMut for Dnsd<'_> { &mut self, _fd: usize, _events: SyscallEventFlags, + _ctx: &CallerCtx, ) -> SyscallResult { Ok(SyscallEventFlags::empty()) } - fn fsync(&mut self, _fd: usize) -> SyscallResult { - Ok(0) + fn fsync(&mut self, _fd: usize, _ctx: &CallerCtx) -> SyscallResult<()> { + Ok(()) } } diff --git a/netstack/src/lib/error.rs b/netstack/src/lib/error.rs index f21d3860ea..8487c4ab19 100644 --- a/netstack/src/lib/error.rs +++ b/netstack/src/lib/error.rs @@ -17,6 +17,17 @@ pub struct Error { descr: String, } +pub trait ResultExt { + type T; + fn context(self, ctxt: impl Into) -> std::result::Result; +} +impl ResultExt for std::result::Result { + type T = T; + fn context(self, ctxt: impl Into) -> std::result::Result { + self.map_err(|err| Error::from_syscall_error(err, ctxt)) + } +} + impl Error { pub fn from_syscall_error>(syscall_error: SyscallError, descr: S) -> Error { Error {