From e0b48caca3cb45de2747b6a5ab3357b8ce58cd86 Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Sat, 10 Feb 2018 01:50:28 +0000 Subject: [PATCH] Update phy mod to use new time types Update everything but the socket types to use the new time types instead of a basic u64 Closes: #141 Approved by: whitequark --- examples/tcpdump.rs | 3 +- examples/utils.rs | 4 +-- src/iface/ethernet.rs | 55 +++++++++++++++--------------- src/iface/neighbor.rs | 71 ++++++++++++++++++++------------------- src/phy/fault_injector.rs | 25 +++++++------- src/phy/loopback.rs | 5 +-- src/phy/mod.rs | 10 +++--- src/phy/pcap_writer.rs | 16 ++++----- src/phy/raw_socket.rs | 5 +-- src/phy/tap_interface.rs | 5 +-- src/phy/tracer.rs | 13 +++---- utils/packet2pcap.rs | 3 +- 12 files changed, 114 insertions(+), 101 deletions(-) diff --git a/examples/tcpdump.rs b/examples/tcpdump.rs index 8a63f14..166ac1e 100644 --- a/examples/tcpdump.rs +++ b/examples/tcpdump.rs @@ -5,6 +5,7 @@ use std::os::unix::io::AsRawFd; use smoltcp::phy::wait as phy_wait; use smoltcp::phy::{Device, RxToken, RawSocket}; use smoltcp::wire::{PrettyPrinter, EthernetFrame}; +use smoltcp::time::Instant; fn main() { let ifname = env::args().nth(1).unwrap(); @@ -12,7 +13,7 @@ fn main() { loop { phy_wait(socket.as_raw_fd(), None).unwrap(); let (rx_token, _) = socket.receive().unwrap(); - rx_token.consume(/*timestamp = */ 0, |buffer| { + rx_token.consume(Instant::now(), |buffer| { println!("{}", PrettyPrinter::>::new("", &buffer)); Ok(()) }).unwrap(); diff --git a/examples/utils.rs b/examples/utils.rs index f976a7c..7707e7d 100644 --- a/examples/utils.rs +++ b/examples/utils.rs @@ -18,7 +18,7 @@ use smoltcp::phy::{Device, EthernetTracer, FaultInjector}; #[cfg(feature = "phy-tap_interface")] use smoltcp::phy::TapInterface; use smoltcp::phy::{PcapWriter, PcapSink, PcapMode, PcapLinkType}; -use smoltcp::time::Instant; +use smoltcp::time::{Duration, Instant}; #[cfg(feature = "log")] pub fn setup_logging_with_clock(filter: &str, since_startup: F) @@ -138,6 +138,6 @@ pub fn parse_middleware_options(matches: &mut Matches, device: D, loopback: b device.set_max_packet_size(size_limit); device.set_max_tx_rate(tx_rate_limit); device.set_max_rx_rate(rx_rate_limit); - device.set_bucket_interval(shaping_interval); + device.set_bucket_interval(Duration::from_millis(shaping_interval)); device } diff --git a/src/iface/ethernet.rs b/src/iface/ethernet.rs index 9ebc5da..bce4f9d 100644 --- a/src/iface/ethernet.rs +++ b/src/iface/ethernet.rs @@ -5,8 +5,8 @@ use core::cmp; use managed::ManagedSlice; use {Error, Result}; -use time::{Duration, Instant}; use phy::{Device, DeviceCapabilities, RxToken, TxToken}; +use time::{Duration, Instant}; use wire::pretty_print::PrettyPrinter; use wire::{EthernetAddress, EthernetProtocol, EthernetFrame}; use wire::{IpAddress, IpProtocol, IpRepr, IpCidr}; @@ -341,7 +341,7 @@ impl<'b, 'c, DeviceT> Interface<'b, 'c, DeviceT> sockets.iter().filter_map(|socket| { let socket_poll_at = socket.poll_at(); socket.meta().poll_at(socket_poll_at, |ip_addr| - self.inner.has_neighbor(&ip_addr, timestamp.total_millis() as u64)) + self.inner.has_neighbor(&ip_addr, timestamp)) }).min().map(|x| Instant::from_millis(x as i64)) } @@ -373,15 +373,15 @@ impl<'b, 'c, DeviceT> Interface<'b, 'c, DeviceT> None => break, Some(tokens) => tokens, }; - rx_token.consume(timestamp.total_millis() as u64, |frame| { - inner.process_ethernet(sockets, timestamp.total_millis() as u64, &frame).map_err(|err| { + rx_token.consume(timestamp, |frame| { + inner.process_ethernet(sockets, timestamp, &frame).map_err(|err| { net_debug!("cannot process ingress packet: {}", err); net_debug!("packet dump follows:\n{}", PrettyPrinter::>::new("", &frame)); err }).and_then(|response| { processed_any = true; - inner.dispatch(tx_token, timestamp.total_millis() as u64, response).map_err(|err| { + inner.dispatch(tx_token, timestamp, response).map_err(|err| { net_debug!("cannot dispatch response packet: {}", err); err }) @@ -398,7 +398,7 @@ impl<'b, 'c, DeviceT> Interface<'b, 'c, DeviceT> let mut emitted_any = false; for mut socket in sockets.iter_mut() { if !socket.meta_mut().egress_permitted(|ip_addr| - self.inner.has_neighbor(&ip_addr, timestamp.total_millis() as u64)) { + self.inner.has_neighbor(&ip_addr, timestamp)) { continue } @@ -411,7 +411,7 @@ impl<'b, 'c, DeviceT> Interface<'b, 'c, DeviceT> let response = $response; neighbor_addr = response.neighbor_addr(); let tx_token = device.transmit().ok_or(Error::Exhausted)?; - device_result = inner.dispatch(tx_token, timestamp.total_millis() as u64, response); + device_result = inner.dispatch(tx_token, timestamp, response); device_result }) } @@ -496,7 +496,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { } fn process_ethernet<'frame, T: AsRef<[u8]>> - (&mut self, sockets: &mut SocketSet, timestamp: u64, frame: &'frame T) -> + (&mut self, sockets: &mut SocketSet, timestamp: Instant, frame: &'frame T) -> Result> { let eth_frame = EthernetFrame::new_checked(frame)?; @@ -524,7 +524,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { #[cfg(feature = "proto-ipv4")] fn process_arp<'frame, T: AsRef<[u8]>> - (&mut self, timestamp: u64, eth_frame: &EthernetFrame<&'frame T>) -> + (&mut self, timestamp: Instant, eth_frame: &EthernetFrame<&'frame T>) -> Result> { let arp_packet = ArpPacket::new_checked(eth_frame.payload())?; @@ -588,7 +588,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { #[cfg(feature = "proto-ipv6")] fn process_ipv6<'frame, T: AsRef<[u8]>> - (&mut self, sockets: &mut SocketSet, timestamp: u64, + (&mut self, sockets: &mut SocketSet, timestamp: Instant, eth_frame: &EthernetFrame<&'frame T>) -> Result> { @@ -625,7 +625,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { #[cfg(feature = "socket-tcp")] IpProtocol::Tcp => - self.process_tcp(sockets, timestamp, ip_repr, ip_payload), + self.process_tcp(sockets, timestamp.total_millis() as u64, ip_repr, ip_payload), #[cfg(feature = "socket-raw")] _ if handled_by_raw_socket => @@ -649,7 +649,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { #[cfg(feature = "proto-ipv4")] fn process_ipv4<'frame, T: AsRef<[u8]>> - (&mut self, sockets: &mut SocketSet, timestamp: u64, + (&mut self, sockets: &mut SocketSet, timestamp: Instant, eth_frame: &EthernetFrame<&'frame T>) -> Result> { @@ -692,7 +692,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { #[cfg(feature = "socket-tcp")] IpProtocol::Tcp => - self.process_tcp(sockets, timestamp, ip_repr, ip_payload), + self.process_tcp(sockets, timestamp.total_millis() as u64, ip_repr, ip_payload), #[cfg(feature = "socket-raw")] _ if handled_by_raw_socket => @@ -917,7 +917,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { } } - fn dispatch(&mut self, tx_token: Tx, timestamp: u64, + fn dispatch(&mut self, tx_token: Tx, timestamp: Instant, packet: Packet) -> Result<()> where Tx: TxToken { @@ -999,7 +999,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { } } - fn dispatch_ethernet(&mut self, tx_token: Tx, timestamp: u64, + fn dispatch_ethernet(&mut self, tx_token: Tx, timestamp: Instant, buffer_len: usize, f: F) -> Result<()> where Tx: TxToken, F: FnOnce(EthernetFrame<&mut [u8]>) { @@ -1039,7 +1039,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { } } - fn has_neighbor<'a>(&self, addr: &'a IpAddress, timestamp: u64) -> bool { + fn has_neighbor<'a>(&self, addr: &'a IpAddress, timestamp: Instant) -> bool { match self.route(addr) { Ok(routed_addr) => { self.neighbor_cache @@ -1050,7 +1050,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { } } - fn lookup_hardware_addr(&mut self, tx_token: Tx, timestamp: u64, + fn lookup_hardware_addr(&mut self, tx_token: Tx, timestamp: Instant, src_addr: &IpAddress, dst_addr: &IpAddress) -> Result<(EthernetAddress, Tx)> where Tx: TxToken @@ -1092,7 +1092,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { } } - fn dispatch_ip(&mut self, tx_token: Tx, timestamp: u64, + fn dispatch_ip(&mut self, tx_token: Tx, timestamp: Instant, ip_repr: IpRepr, f: F) -> Result<()> where Tx: TxToken, F: FnOnce(IpRepr, &mut [u8]) { @@ -1129,6 +1129,7 @@ mod test { use super::InterfaceBuilder; use iface::{NeighborCache, EthernetInterface}; use phy::{self, Loopback, ChecksumCapabilities}; + use time::Instant; use socket::SocketSet; #[cfg(feature = "proto-ipv4")] use wire::{ArpOperation, ArpPacket, ArpRepr}; @@ -1171,7 +1172,7 @@ mod test { struct MockTxToken; impl phy::TxToken for MockTxToken { - fn consume(self, _: u64, _: usize, _: F) -> Result + fn consume(self, _: Instant, _: usize, _: F) -> Result where F: FnOnce(&mut [u8]) -> Result { Err(Error::__Nonexhaustive) } @@ -1215,7 +1216,7 @@ mod test { // Ensure that the unknown protocol frame does not trigger an // ICMP error response when the destination address is a // broadcast address - assert_eq!(iface.inner.process_ipv4(&mut socket_set, 0, &frame), + assert_eq!(iface.inner.process_ipv4(&mut socket_set, Instant::from_millis(0), &frame), Ok(Packet::None)); } @@ -1273,7 +1274,7 @@ mod test { // Ensure that the unknown protocol triggers an error response. // And we correctly handle no payload. - assert_eq!(iface.inner.process_ipv4(&mut socket_set, 0, &frame), + assert_eq!(iface.inner.process_ipv4(&mut socket_set, Instant::from_millis(0), &frame), Ok(expected_repr)); } @@ -1507,7 +1508,7 @@ mod test { } // Ensure an ARP Request for us triggers an ARP Reply - assert_eq!(iface.inner.process_ethernet(&mut socket_set, 0, frame.into_inner()), + assert_eq!(iface.inner.process_ethernet(&mut socket_set, Instant::from_millis(0), frame.into_inner()), Ok(Packet::Arp(ArpRepr::EthernetIpv4 { operation: ArpOperation::Reply, source_hardware_addr: local_hw_addr, @@ -1517,7 +1518,7 @@ mod test { }))); // Ensure the address of the requestor was entered in the cache - assert_eq!(iface.inner.lookup_hardware_addr(MockTxToken, 0, + assert_eq!(iface.inner.lookup_hardware_addr(MockTxToken, Instant::from_secs(0), &IpAddress::Ipv4(local_ip_addr), &IpAddress::Ipv4(remote_ip_addr)), Ok((remote_hw_addr, MockTxToken))); } @@ -1550,11 +1551,11 @@ mod test { } // Ensure an ARP Request for someone else does not trigger an ARP Reply - assert_eq!(iface.inner.process_ethernet(&mut socket_set, 0, frame.into_inner()), + assert_eq!(iface.inner.process_ethernet(&mut socket_set, Instant::from_millis(0), frame.into_inner()), Ok(Packet::None)); // Ensure the address of the requestor was entered in the cache - assert_eq!(iface.inner.lookup_hardware_addr(MockTxToken, 0, + assert_eq!(iface.inner.lookup_hardware_addr(MockTxToken, Instant::from_secs(0), &IpAddress::Ipv4(Ipv4Address([0x7f, 0x00, 0x00, 0x01])), &IpAddress::Ipv4(remote_ip_addr)), Ok((remote_hw_addr, MockTxToken))); @@ -1673,11 +1674,11 @@ mod test { // Ensure the unknown next header causes a ICMPv6 Parameter Problem // error message to be sent to the sender. - assert_eq!(iface.inner.process_ipv6(&mut socket_set, 0, &frame), + assert_eq!(iface.inner.process_ipv6(&mut socket_set, Instant::from_millis(0), &frame), Ok(Packet::Icmpv6((reply_ipv6_repr, reply_icmp_repr)))); // Ensure the address of the requestor was entered in the cache - assert_eq!(iface.inner.lookup_hardware_addr(MockTxToken, 0, + assert_eq!(iface.inner.lookup_hardware_addr(MockTxToken, Instant::from_secs(0), &IpAddress::Ipv6(Ipv6Address::LOOPBACK), &IpAddress::Ipv6(remote_ip_addr)), Ok((remote_hw_addr, MockTxToken))); diff --git a/src/iface/neighbor.rs b/src/iface/neighbor.rs index edb4792..ce747ed 100644 --- a/src/iface/neighbor.rs +++ b/src/iface/neighbor.rs @@ -4,6 +4,7 @@ use managed::ManagedMap; use wire::{EthernetAddress, IpAddress}; +use time::{Duration, Instant}; /// A cached neighbor. /// @@ -12,7 +13,7 @@ use wire::{EthernetAddress, IpAddress}; #[derive(Debug, Clone, Copy)] pub struct Neighbor { hardware_addr: EthernetAddress, - expires_at: u64, + expires_at: Instant, } /// An answer to a neighbor cache lookup. @@ -49,15 +50,15 @@ pub(crate) enum Answer { #[derive(Debug)] pub struct Cache<'a> { storage: ManagedMap<'a, IpAddress, Neighbor>, - silent_until: u64, + silent_until: Instant, } impl<'a> Cache<'a> { /// Minimum delay between discovery requests, in milliseconds. - pub(crate) const SILENT_TIME: u64 = 1_000; + pub(crate) const SILENT_TIME: Duration = Duration { millis: 1_000 }; /// Neighbor entry lifetime, in milliseconds. - pub(crate) const ENTRY_LIFETIME: u64 = 60_000; + pub(crate) const ENTRY_LIFETIME: Duration = Duration { millis: 60_000 }; /// Create a cache. The backing storage is cleared upon creation. /// @@ -68,11 +69,11 @@ impl<'a> Cache<'a> { let mut storage = storage.into(); storage.clear(); - Cache { storage, silent_until: 0 } + Cache { storage, silent_until: Instant::from_millis(0) } } pub(crate) fn fill(&mut self, protocol_addr: IpAddress, hardware_addr: EthernetAddress, - timestamp: u64) { + timestamp: Instant) { debug_assert!(protocol_addr.is_unicast()); debug_assert!(hardware_addr.is_unicast()); @@ -125,7 +126,7 @@ impl<'a> Cache<'a> { } } - pub(crate) fn lookup_pure(&self, protocol_addr: &IpAddress, timestamp: u64) -> + pub(crate) fn lookup_pure(&self, protocol_addr: &IpAddress, timestamp: Instant) -> Option { if protocol_addr.is_broadcast() { return Some(EthernetAddress::BROADCAST) @@ -143,7 +144,7 @@ impl<'a> Cache<'a> { None } - pub(crate) fn lookup(&mut self, protocol_addr: &IpAddress, timestamp: u64) -> Answer { + pub(crate) fn lookup(&mut self, protocol_addr: &IpAddress, timestamp: Instant) -> Answer { match self.lookup_pure(protocol_addr, timestamp) { Some(hardware_addr) => Answer::Found(hardware_addr), @@ -172,16 +173,17 @@ mod test { let mut cache_storage = [Default::default(); 3]; let mut cache = Cache::new(&mut cache_storage[..]); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, 0), None); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_2, 0), None); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, Instant::from_millis(0)), None); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_2, Instant::from_millis(0)), None); - cache.fill(MOCK_IP_ADDR_1, HADDR_A, 0); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, 0), Some(HADDR_A)); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_2, 0), None); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, 2 * Cache::ENTRY_LIFETIME), None); + cache.fill(MOCK_IP_ADDR_1, HADDR_A, Instant::from_millis(0)); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, Instant::from_millis(0)), Some(HADDR_A)); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_2, Instant::from_millis(0)), None); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, Instant::from_millis(0) + Cache::ENTRY_LIFETIME * 2), + None); - cache.fill(MOCK_IP_ADDR_1, HADDR_A, 0); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_2, 0), None); + cache.fill(MOCK_IP_ADDR_1, HADDR_A, Instant::from_millis(0)); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_2, Instant::from_millis(0)), None); } #[test] @@ -189,9 +191,10 @@ mod test { let mut cache_storage = [Default::default(); 3]; let mut cache = Cache::new(&mut cache_storage[..]); - cache.fill(MOCK_IP_ADDR_1, HADDR_A, 0); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, 0), Some(HADDR_A)); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, 2 * Cache::ENTRY_LIFETIME), None); + cache.fill(MOCK_IP_ADDR_1, HADDR_A, Instant::from_millis(0)); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, Instant::from_millis(0)), Some(HADDR_A)); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, Instant::from_millis(0) + Cache::ENTRY_LIFETIME * 2), + None); } #[test] @@ -199,10 +202,10 @@ mod test { let mut cache_storage = [Default::default(); 3]; let mut cache = Cache::new(&mut cache_storage[..]); - cache.fill(MOCK_IP_ADDR_1, HADDR_A, 0); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, 0), Some(HADDR_A)); - cache.fill(MOCK_IP_ADDR_1, HADDR_B, 0); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, 0), Some(HADDR_B)); + cache.fill(MOCK_IP_ADDR_1, HADDR_A, Instant::from_millis(0)); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, Instant::from_millis(0)), Some(HADDR_A)); + cache.fill(MOCK_IP_ADDR_1, HADDR_B, Instant::from_millis(0)); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_1, Instant::from_millis(0)), Some(HADDR_B)); } #[test] @@ -210,15 +213,15 @@ mod test { let mut cache_storage = [Default::default(); 3]; let mut cache = Cache::new(&mut cache_storage[..]); - cache.fill(MOCK_IP_ADDR_1, HADDR_A, 100); - cache.fill(MOCK_IP_ADDR_2, HADDR_B, 50); - cache.fill(MOCK_IP_ADDR_3, HADDR_C, 200); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_2, 1000), Some(HADDR_B)); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_4, 1000), None); + cache.fill(MOCK_IP_ADDR_1, HADDR_A, Instant::from_millis(100)); + cache.fill(MOCK_IP_ADDR_2, HADDR_B, Instant::from_millis(50)); + cache.fill(MOCK_IP_ADDR_3, HADDR_C, Instant::from_millis(200)); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_2, Instant::from_millis(1000)), Some(HADDR_B)); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_4, Instant::from_millis(1000)), None); - cache.fill(MOCK_IP_ADDR_4, HADDR_D, 300); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_2, 1000), None); - assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_4, 1000), Some(HADDR_D)); + cache.fill(MOCK_IP_ADDR_4, HADDR_D, Instant::from_millis(300)); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_2, Instant::from_millis(1000)), None); + assert_eq!(cache.lookup_pure(&MOCK_IP_ADDR_4, Instant::from_millis(1000)), Some(HADDR_D)); } #[test] @@ -226,8 +229,8 @@ mod test { let mut cache_storage = [Default::default(); 3]; let mut cache = Cache::new(&mut cache_storage[..]); - assert_eq!(cache.lookup(&MOCK_IP_ADDR_1, 0), Answer::NotFound); - assert_eq!(cache.lookup(&MOCK_IP_ADDR_1, 100), Answer::RateLimited); - assert_eq!(cache.lookup(&MOCK_IP_ADDR_1, 2000), Answer::NotFound); + assert_eq!(cache.lookup(&MOCK_IP_ADDR_1, Instant::from_millis(0)), Answer::NotFound); + assert_eq!(cache.lookup(&MOCK_IP_ADDR_1, Instant::from_millis(100)), Answer::RateLimited); + assert_eq!(cache.lookup(&MOCK_IP_ADDR_1, Instant::from_millis(2000)), Answer::NotFound); } } diff --git a/src/phy/fault_injector.rs b/src/phy/fault_injector.rs index 8ffbce7..75b8c01 100644 --- a/src/phy/fault_injector.rs +++ b/src/phy/fault_injector.rs @@ -2,6 +2,7 @@ use core::cell::RefCell; use {Error, Result}; use phy::{self, DeviceCapabilities, Device}; +use time::{Duration, Instant}; // We use our own RNG to stay compatible with #![no_std]. // The use of the RNG below has a slight bias, but it doesn't matter. @@ -17,7 +18,7 @@ fn xorshift32(state: &mut u32) -> u32 { // This could be fixed once associated consts are stable. const MTU: usize = 1536; -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Default, Clone, Copy)] struct Config { corrupt_pct: u8, drop_pct: u8, @@ -25,13 +26,13 @@ struct Config { max_size: usize, max_tx_rate: u64, max_rx_rate: u64, - interval: u64, + interval: Duration, } #[derive(Debug, Clone)] struct State { rng_seed: u32, - refilled_at: u64, + refilled_at: Instant, tx_bucket: u64, rx_bucket: u64, } @@ -49,7 +50,7 @@ impl State { buffer[index] ^= bit; } - fn refill(&mut self, config: &Config, timestamp: u64) { + fn refill(&mut self, config: &Config, timestamp: Instant) { if timestamp - self.refilled_at > config.interval { self.tx_bucket = config.max_tx_rate; self.rx_bucket = config.max_rx_rate; @@ -57,7 +58,7 @@ impl State { } } - fn maybe_transmit(&mut self, config: &Config, timestamp: u64) -> bool { + fn maybe_transmit(&mut self, config: &Config, timestamp: Instant) -> bool { if config.max_tx_rate == 0 { return true } self.refill(config, timestamp); @@ -69,7 +70,7 @@ impl State { } } - fn maybe_receive(&mut self, config: &Config, timestamp: u64) -> bool { + fn maybe_receive(&mut self, config: &Config, timestamp: Instant) -> bool { if config.max_rx_rate == 0 { return true } self.refill(config, timestamp); @@ -99,7 +100,7 @@ impl Device<'a>> FaultInjector { pub fn new(inner: D, seed: u32) -> FaultInjector { let state = State { rng_seed: seed, - refilled_at: 0, + refilled_at: Instant::from_millis(0), tx_bucket: 0, rx_bucket: 0, }; @@ -141,7 +142,7 @@ impl Device<'a>> FaultInjector { } /// Return the interval for packet rate limiting, in milliseconds. - pub fn bucket_interval(&self) -> u64 { + pub fn bucket_interval(&self) -> Duration { self.config.interval } @@ -179,8 +180,8 @@ impl Device<'a>> FaultInjector { } /// Set the interval for packet rate limiting, in milliseconds. - pub fn set_bucket_interval(&mut self, interval: u64) { - self.state.borrow_mut().refilled_at = 0; + pub fn set_bucket_interval(&mut self, interval: Duration) { + self.state.borrow_mut().refilled_at = Instant::from_millis(0); self.config.interval = interval } } @@ -238,7 +239,7 @@ pub struct RxToken<'a, Rx: phy::RxToken> { } impl<'a, Rx: phy::RxToken> phy::RxToken for RxToken<'a, Rx> { - fn consume(self, timestamp: u64, f: F) -> Result + fn consume(self, timestamp: Instant, f: F) -> Result where F: FnOnce(&[u8]) -> Result { if self.state.borrow_mut().maybe(self.config.drop_pct) { @@ -277,7 +278,7 @@ pub struct TxToken<'a, Tx: phy::TxToken> { } impl<'a, Tx: phy::TxToken> phy::TxToken for TxToken<'a, Tx> { - fn consume(mut self, timestamp: u64, len: usize, f: F) -> Result + fn consume(mut self, timestamp: Instant, len: usize, f: F) -> Result where F: FnOnce(&mut [u8]) -> Result { let drop = if self.state.borrow_mut().maybe(self.config.drop_pct) { diff --git a/src/phy/loopback.rs b/src/phy/loopback.rs index a73e844..b24c37c 100644 --- a/src/phy/loopback.rs +++ b/src/phy/loopback.rs @@ -7,6 +7,7 @@ use alloc::{Vec, VecDeque}; use Result; use phy::{self, Device, DeviceCapabilities}; +use time::Instant; /// A loopback device. #[derive(Debug)] @@ -58,7 +59,7 @@ pub struct RxToken { } impl phy::RxToken for RxToken { - fn consume Result>(self, _timestamp: u64, f: F) -> Result { + fn consume Result>(self, _timestamp: Instant, f: F) -> Result { f(&self.buffer) } } @@ -69,7 +70,7 @@ pub struct TxToken<'a> { } impl<'a> phy::TxToken for TxToken<'a> { - fn consume(self, _timestamp: u64, len: usize, f: F) -> Result + fn consume(self, _timestamp: Instant, len: usize, f: F) -> Result where F: FnOnce(&mut [u8]) -> Result { let mut buffer = Vec::new(); diff --git a/src/phy/mod.rs b/src/phy/mod.rs index 549a0ba..f628591 100644 --- a/src/phy/mod.rs +++ b/src/phy/mod.rs @@ -19,6 +19,7 @@ Ethernet controller could look as follows: ```rust use smoltcp::Result; use smoltcp::phy::{self, DeviceCapabilities, Device}; +use smoltcp::time::Instant; struct StmPhy { rx_buffer: [u8; 1536], @@ -58,7 +59,7 @@ impl<'a> phy::Device<'a> for StmPhy { struct StmPhyRxToken<'a>(&'a [u8]); impl<'a> phy::RxToken for StmPhyRxToken<'a> { - fn consume(self, _timestamp: u64, f: F) -> Result + fn consume(self, _timestamp: Instant, f: F) -> Result where F: FnOnce(&[u8]) -> Result { // TODO: receive packet into buffer @@ -71,7 +72,7 @@ impl<'a> phy::RxToken for StmPhyRxToken<'a> { struct StmPhyTxToken<'a>(&'a mut [u8]); impl<'a> phy::TxToken for StmPhyTxToken<'a> { - fn consume(self, _timestamp: u64, len: usize, f: F) -> Result + fn consume(self, _timestamp: Instant, len: usize, f: F) -> Result where F: FnOnce(&mut [u8]) -> Result { let result = f(&mut self.0[..len]); @@ -84,6 +85,7 @@ impl<'a> phy::TxToken for StmPhyTxToken<'a> { */ use Result; +use time::Instant; #[cfg(any(feature = "phy-raw_socket", feature = "phy-tap_interface"))] mod sys; @@ -245,7 +247,7 @@ pub trait RxToken { /// /// The timestamp must be a number of milliseconds, monotonically increasing since an /// arbitrary moment in time, such as system startup. - fn consume(self, timestamp: u64, f: F) -> Result + fn consume(self, timestamp: Instant, f: F) -> Result where F: FnOnce(&[u8]) -> Result; } @@ -260,6 +262,6 @@ pub trait TxToken { /// /// The timestamp must be a number of milliseconds, monotonically increasing since an /// arbitrary moment in time, such as system startup. - fn consume(self, timestamp: u64, len: usize, f: F) -> Result + fn consume(self, timestamp: Instant, len: usize, f: F) -> Result where F: FnOnce(&mut [u8]) -> Result; } diff --git a/src/phy/pcap_writer.rs b/src/phy/pcap_writer.rs index 20778d9..033a763 100644 --- a/src/phy/pcap_writer.rs +++ b/src/phy/pcap_writer.rs @@ -6,6 +6,7 @@ use byteorder::{ByteOrder, NativeEndian}; use Result; use phy::{self, DeviceCapabilities, Device}; +use time::Instant; enum_with_unknown! { /// Captured packet header type. @@ -66,12 +67,11 @@ pub trait PcapSink { /// /// # Panics /// This function panics if `length` is greater than 65535. - fn packet_header(&self, timestamp: u64, length: usize) { + fn packet_header(&self, timestamp: Instant, length: usize) { assert!(length <= 65535); - let (seconds, micros) = (timestamp / 1000, timestamp % 1000 * 1000); - self.write_u32(seconds as u32); // timestamp seconds - self.write_u32(micros as u32); // timestamp microseconds + self.write_u32(timestamp.secs() as u32); // timestamp seconds + self.write_u32(timestamp.millis() as u32); // timestamp microseconds self.write_u32(length as u32); // captured length self.write_u32(length as u32); // original length } @@ -79,7 +79,7 @@ pub trait PcapSink { /// Write the libpcap packet header followed by packet data into the sink. /// /// See also the note for [global_header](#method.global_header). - fn packet(&self, timestamp: u64, packet: &[u8]) { + fn packet(&self, timestamp: Instant, packet: &[u8]) { self.packet_header(timestamp, packet.len()); self.write(packet) } @@ -97,7 +97,7 @@ impl PcapSink for RefCell { self.borrow_mut().write_all(data).expect("cannot write") } - fn packet(&self, timestamp: u64, packet: &[u8]) { + fn packet(&self, timestamp: Instant, packet: &[u8]) { self.packet_header(timestamp, packet.len()); PcapSink::write(self, packet); self.borrow_mut().flush().expect("cannot flush") @@ -168,7 +168,7 @@ pub struct RxToken { } impl phy::RxToken for RxToken { - fn consume Result>(self, timestamp: u64, f: F) -> Result { + fn consume Result>(self, timestamp: Instant, f: F) -> Result { let Self { token, sink, mode } = self; token.consume(timestamp, |buffer| { match mode { @@ -189,7 +189,7 @@ pub struct TxToken { } impl phy::TxToken for TxToken { - fn consume(self, timestamp: u64, len: usize, f: F) -> Result + fn consume(self, timestamp: Instant, len: usize, f: F) -> Result where F: FnOnce(&mut [u8]) -> Result { let Self { token, sink, mode } = self; diff --git a/src/phy/raw_socket.rs b/src/phy/raw_socket.rs index 662416f..5303d7d 100644 --- a/src/phy/raw_socket.rs +++ b/src/phy/raw_socket.rs @@ -6,6 +6,7 @@ use std::os::unix::io::{RawFd, AsRawFd}; use Result; use phy::{self, sys, DeviceCapabilities, Device}; +use time::Instant; /// A socket that captures or transmits the complete frame. #[derive(Debug)] @@ -77,7 +78,7 @@ pub struct RxToken { } impl phy::RxToken for RxToken { - fn consume Result>(self, _timestamp: u64, f: F) -> Result { + fn consume Result>(self, _timestamp: Instant, f: F) -> Result { f(&self.buffer[..]) } } @@ -88,7 +89,7 @@ pub struct TxToken { } impl phy::TxToken for TxToken { - fn consume Result>(self, _timestamp: u64, len: usize, f: F) + fn consume Result>(self, _timestamp: Instant, len: usize, f: F) -> Result { let mut lower = self.lower.borrow_mut(); diff --git a/src/phy/tap_interface.rs b/src/phy/tap_interface.rs index 70d0444..1455874 100644 --- a/src/phy/tap_interface.rs +++ b/src/phy/tap_interface.rs @@ -6,6 +6,7 @@ use std::os::unix::io::{RawFd, AsRawFd}; use Result; use phy::{self, sys, DeviceCapabilities, Device}; +use time::Instant; /// A virtual Ethernet interface. #[derive(Debug)] @@ -78,7 +79,7 @@ pub struct RxToken { } impl phy::RxToken for RxToken { - fn consume(self, _timestamp: u64, f: F) -> Result + fn consume(self, _timestamp: Instant, f: F) -> Result where F: FnOnce(&[u8]) -> Result { f(&self.buffer[..]) @@ -91,7 +92,7 @@ pub struct TxToken { } impl phy::TxToken for TxToken { - fn consume(self, _timestamp: u64, len: usize, f: F) -> Result + fn consume(self, _timestamp: Instant, len: usize, f: F) -> Result where F: FnOnce(&mut [u8]) -> Result { let mut lower = self.lower.borrow_mut(); diff --git a/src/phy/tracer.rs b/src/phy/tracer.rs index b20d20a..dee26ed 100644 --- a/src/phy/tracer.rs +++ b/src/phy/tracer.rs @@ -1,6 +1,7 @@ use Result; use wire::pretty_print::{PrettyPrint, PrettyPrinter}; use phy::{self, DeviceCapabilities, Device}; +use time::Instant; /// A tracer device. /// @@ -9,12 +10,12 @@ use phy::{self, DeviceCapabilities, Device}; /// device. pub struct Tracer Device<'a>, P: PrettyPrint> { inner: D, - writer: fn(u64, PrettyPrinter

), + writer: fn(Instant, PrettyPrinter

), } impl Device<'a>, P: PrettyPrint> Tracer { /// Create a tracer device. - pub fn new(inner: D, writer: fn(timestamp: u64, printer: PrettyPrinter

)) -> Tracer { + pub fn new(inner: D, writer: fn(timestamp: Instant, printer: PrettyPrinter

)) -> Tracer { Tracer { inner, writer } } @@ -53,11 +54,11 @@ impl<'a, D, P> Device<'a> for Tracer #[doc(hidden)] pub struct RxToken { token: Rx, - writer: fn(u64, PrettyPrinter

) + writer: fn(Instant, PrettyPrinter

) } impl phy::RxToken for RxToken { - fn consume(self, timestamp: u64, f: F) -> Result + fn consume(self, timestamp: Instant, f: F) -> Result where F: FnOnce(&[u8]) -> Result { let Self { token, writer } = self; @@ -71,11 +72,11 @@ impl phy::RxToken for RxToken { #[doc(hidden)] pub struct TxToken { token: Tx, - writer: fn(u64, PrettyPrinter

) + writer: fn(Instant, PrettyPrinter

) } impl phy::TxToken for TxToken { - fn consume(self, timestamp: u64, len: usize, f: F) -> Result + fn consume(self, timestamp: Instant, len: usize, f: F) -> Result where F: FnOnce(&mut [u8]) -> Result { let Self { token, writer } = self; diff --git a/utils/packet2pcap.rs b/utils/packet2pcap.rs index 87c8f66..b821186 100644 --- a/utils/packet2pcap.rs +++ b/utils/packet2pcap.rs @@ -8,6 +8,7 @@ use std::fs::File; use std::env; use std::process::exit; use smoltcp::phy::{PcapLinkType, PcapSink}; +use smoltcp::time::Instant; use getopts::Options; fn convert(packet_filename: &Path, pcap_filename: &Path, link_type: PcapLinkType) @@ -18,7 +19,7 @@ fn convert(packet_filename: &Path, pcap_filename: &Path, link_type: PcapLinkType let pcap = RefCell::new(Vec::new()); PcapSink::global_header(&pcap, link_type); - PcapSink::packet(&pcap, 0, &packet[..]); + PcapSink::packet(&pcap, Instant::from_millis(0), &packet[..]); let mut pcap_file = File::create(pcap_filename)?; pcap_file.write_all(&pcap.borrow()[..])?;