diff --git a/Cargo.lock b/Cargo.lock index cbb61bcc90..07d2ef2b3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -260,7 +260,7 @@ dependencies = [ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", "redox_event 0.1.0 (git+https://github.com/redox-os/event.git)", "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", - "smoltcp 0.4.0 (git+https://github.com/redox-os/smoltcp.git)", + "smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp.git)", ] [[package]] @@ -314,7 +314,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smoltcp" version = "0.4.0" -source = "git+https://github.com/redox-os/smoltcp.git#a6fc036ad65e07523e271304bb96d99a9f9a2707" +source = "git+https://github.com/m-labs/smoltcp.git#fd7109b2e4352db6e1ad919780c770c4fdb7a72d" dependencies = [ "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "managed 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -461,7 +461,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustls 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17727f4b991294da2c84d75a43c003151ff58072212768800f66c56ee46dca43" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum smoltcp 0.4.0 (git+https://github.com/redox-os/smoltcp.git)" = "" +"checksum smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp.git)" = "" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" diff --git a/Cargo.toml b/Cargo.toml index 1b5fa8329e..7a979767f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,6 @@ default-features = false features = ["release_max_level_off"] [dependencies.smoltcp] -git = "https://github.com/redox-os/smoltcp.git" +git = "https://github.com/m-labs/smoltcp.git" default-features = false features = ["std", "proto-raw", "proto-udp", "proto-tcp"] diff --git a/src/smolnetd/device.rs b/src/smolnetd/device.rs index a62d3741b1..08ab9228f6 100644 --- a/src/smolnetd/device.rs +++ b/src/smolnetd/device.rs @@ -8,13 +8,17 @@ use std::rc::Rc; use buffer_pool::{Buffer, BufferPool}; use arp_cache::LOOPBACK_HWADDR; -pub struct NetworkDevice { +struct NetworkDeviceData { network_file: Rc>, input_queue: Rc>>, local_hwaddr: smoltcp::wire::EthernetAddress, buffer_pool: Rc>, } +pub struct NetworkDevice { + data: Rc>, +} + impl NetworkDevice { pub const MTU: usize = 1520; @@ -25,57 +29,67 @@ impl NetworkDevice { buffer_pool: Rc>, ) -> NetworkDevice { NetworkDevice { - network_file, - input_queue, - local_hwaddr, - buffer_pool, + data: Rc::new(RefCell::new(NetworkDeviceData { + network_file, + input_queue, + local_hwaddr, + buffer_pool, + })), } } } -pub struct TxBuffer { +pub struct RxToken { buffer: Buffer, - network_file: Rc>, - input_queue: Rc>>, - local_hwaddr: smoltcp::wire::EthernetAddress, } -impl AsRef<[u8]> for TxBuffer { - fn as_ref(&self) -> &[u8] { - self.buffer.as_ref() +impl smoltcp::phy::RxToken for RxToken { + fn consume(self, _timestamp: u64, f: F) -> smoltcp::Result + where + F: FnOnce(&[u8]) -> smoltcp::Result, + { + f(&self.buffer) } } -impl AsMut<[u8]> for TxBuffer { - fn as_mut(&mut self) -> &mut [u8] { - self.buffer.as_mut() - } +pub struct TxToken { + data: Rc>, } -impl Drop for TxBuffer { - fn drop(&mut self) { +impl smoltcp::phy::TxToken for TxToken { + fn consume(self, _timestamp: u64, len: usize, f: F) -> smoltcp::Result + where + F: FnOnce(&mut [u8]) -> smoltcp::Result, + { + let data = self.data.borrow_mut(); + let mut buffer = data.buffer_pool.borrow_mut().get_buffer(); + buffer.resize(len); + let res = f(&mut buffer)?; + let mut loopback = false; - - if let Ok(mut frame) = smoltcp::wire::EthernetFrame::new_checked(&mut self.buffer) { + if let Ok(mut frame) = smoltcp::wire::EthernetFrame::new_checked(&mut buffer) { if frame.dst_addr() == LOOPBACK_HWADDR { - frame.set_dst_addr(self.local_hwaddr); + frame.set_dst_addr(data.local_hwaddr); loopback = true; } } if loopback { - self.input_queue - .borrow_mut() - .push_back(self.buffer.move_out()); + data.input_queue.borrow_mut().push_back(buffer.move_out()); } else { - let _ = self.network_file.borrow_mut().write(&self.buffer); + data.network_file + .borrow_mut() + .write(&buffer) + .map_err(|_| smoltcp::Error::Dropped)?; } + + Ok(res) } } -impl smoltcp::phy::Device for NetworkDevice { - type RxBuffer = Buffer; - type TxBuffer = TxBuffer; +impl<'a> smoltcp::phy::Device<'a> for NetworkDevice { + type RxToken = RxToken; + type TxToken = TxToken; fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities { let mut limits = smoltcp::phy::DeviceCapabilities::default(); @@ -84,21 +98,25 @@ impl smoltcp::phy::Device for NetworkDevice { limits } - fn receive(&mut self, _timestamp: u64) -> smoltcp::Result { - self.input_queue - .borrow_mut() - .pop_front() - .ok_or(smoltcp::Error::Exhausted) + fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { + let data = self.data.borrow_mut(); + let buffer = data.input_queue.borrow_mut().pop_front(); + + if let Some(buffer) = buffer { + Some(( + RxToken { buffer }, + TxToken { + data: Rc::clone(&self.data), + }, + )) + } else { + None + } } - fn transmit(&mut self, _timestamp: u64, length: usize) -> smoltcp::Result { - let mut buffer = self.buffer_pool.borrow_mut().get_buffer(); - buffer.resize(length); - Ok(TxBuffer { - network_file: Rc::clone(&self.network_file), - buffer, - input_queue: Rc::clone(&self.input_queue), - local_hwaddr: self.local_hwaddr, + fn transmit(&'a mut self) -> Option { + Some(TxToken { + data: Rc::clone(&self.data), }) } }