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
v0.7.x
Dan Robertson 2018-02-10 01:50:28 +00:00 committed by Homu
parent 20d1dd8a4a
commit e0b48caca3
12 changed files with 114 additions and 101 deletions

View File

@ -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::<EthernetFrame<&[u8]>>::new("", &buffer));
Ok(())
}).unwrap();

View File

@ -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<F>(filter: &str, since_startup: F)
@ -138,6 +138,6 @@ pub fn parse_middleware_options<D>(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
}

View File

@ -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::<EthernetFrame<&[u8]>>::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<Packet<'frame>>
{
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<Packet<'frame>>
{
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<Packet<'frame>>
{
@ -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<Packet<'frame>>
{
@ -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<Tx>(&mut self, tx_token: Tx, timestamp: u64,
fn dispatch<Tx>(&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<Tx, F>(&mut self, tx_token: Tx, timestamp: u64,
fn dispatch_ethernet<Tx, F>(&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<Tx>(&mut self, tx_token: Tx, timestamp: u64,
fn lookup_hardware_addr<Tx>(&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<Tx, F>(&mut self, tx_token: Tx, timestamp: u64,
fn dispatch_ip<Tx, F>(&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<R, F>(self, _: u64, _: usize, _: F) -> Result<R>
fn consume<R, F>(self, _: Instant, _: usize, _: F) -> Result<R>
where F: FnOnce(&mut [u8]) -> Result<R> {
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)));

View File

@ -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<EthernetAddress> {
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);
}
}

View File

@ -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<D: for<'a> Device<'a>> FaultInjector<D> {
pub fn new(inner: D, seed: u32) -> FaultInjector<D> {
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<D: for<'a> Device<'a>> FaultInjector<D> {
}
/// 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<D: for<'a> Device<'a>> FaultInjector<D> {
}
/// 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<R, F>(self, timestamp: u64, f: F) -> Result<R>
fn consume<R, F>(self, timestamp: Instant, f: F) -> Result<R>
where F: FnOnce(&[u8]) -> Result<R>
{
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<R, F>(mut self, timestamp: u64, len: usize, f: F) -> Result<R>
fn consume<R, F>(mut self, timestamp: Instant, len: usize, f: F) -> Result<R>
where F: FnOnce(&mut [u8]) -> Result<R>
{
let drop = if self.state.borrow_mut().maybe(self.config.drop_pct) {

View File

@ -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<R, F: FnOnce(&[u8]) -> Result<R>>(self, _timestamp: u64, f: F) -> Result<R> {
fn consume<R, F: FnOnce(&[u8]) -> Result<R>>(self, _timestamp: Instant, f: F) -> Result<R> {
f(&self.buffer)
}
}
@ -69,7 +70,7 @@ pub struct TxToken<'a> {
}
impl<'a> phy::TxToken for TxToken<'a> {
fn consume<R, F>(self, _timestamp: u64, len: usize, f: F) -> Result<R>
fn consume<R, F>(self, _timestamp: Instant, len: usize, f: F) -> Result<R>
where F: FnOnce(&mut [u8]) -> Result<R>
{
let mut buffer = Vec::new();

View File

@ -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<R, F>(self, _timestamp: u64, f: F) -> Result<R>
fn consume<R, F>(self, _timestamp: Instant, f: F) -> Result<R>
where F: FnOnce(&[u8]) -> Result<R>
{
// 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<R, F>(self, _timestamp: u64, len: usize, f: F) -> Result<R>
fn consume<R, F>(self, _timestamp: Instant, len: usize, f: F) -> Result<R>
where F: FnOnce(&mut [u8]) -> Result<R>
{
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<R, F>(self, timestamp: u64, f: F) -> Result<R>
fn consume<R, F>(self, timestamp: Instant, f: F) -> Result<R>
where F: FnOnce(&[u8]) -> Result<R>;
}
@ -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<R, F>(self, timestamp: u64, len: usize, f: F) -> Result<R>
fn consume<R, F>(self, timestamp: Instant, len: usize, f: F) -> Result<R>
where F: FnOnce(&mut [u8]) -> Result<R>;
}

View File

@ -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<T: Write> PcapSink for RefCell<T> {
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<Rx: phy::RxToken, S: PcapSink> {
}
impl<Rx: phy::RxToken, S: PcapSink> phy::RxToken for RxToken<Rx, S> {
fn consume<R, F: FnOnce(&[u8]) -> Result<R>>(self, timestamp: u64, f: F) -> Result<R> {
fn consume<R, F: FnOnce(&[u8]) -> Result<R>>(self, timestamp: Instant, f: F) -> Result<R> {
let Self { token, sink, mode } = self;
token.consume(timestamp, |buffer| {
match mode {
@ -189,7 +189,7 @@ pub struct TxToken<Tx: phy::TxToken, S: PcapSink> {
}
impl<Tx: phy::TxToken, S: PcapSink> phy::TxToken for TxToken<Tx, S> {
fn consume<R, F>(self, timestamp: u64, len: usize, f: F) -> Result<R>
fn consume<R, F>(self, timestamp: Instant, len: usize, f: F) -> Result<R>
where F: FnOnce(&mut [u8]) -> Result<R>
{
let Self { token, sink, mode } = self;

View File

@ -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<R, F: FnOnce(&[u8]) -> Result<R>>(self, _timestamp: u64, f: F) -> Result<R> {
fn consume<R, F: FnOnce(&[u8]) -> Result<R>>(self, _timestamp: Instant, f: F) -> Result<R> {
f(&self.buffer[..])
}
}
@ -88,7 +89,7 @@ pub struct TxToken {
}
impl phy::TxToken for TxToken {
fn consume<R, F: FnOnce(&mut [u8]) -> Result<R>>(self, _timestamp: u64, len: usize, f: F)
fn consume<R, F: FnOnce(&mut [u8]) -> Result<R>>(self, _timestamp: Instant, len: usize, f: F)
-> Result<R>
{
let mut lower = self.lower.borrow_mut();

View File

@ -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<R, F>(self, _timestamp: u64, f: F) -> Result<R>
fn consume<R, F>(self, _timestamp: Instant, f: F) -> Result<R>
where F: FnOnce(&[u8]) -> Result<R>
{
f(&self.buffer[..])
@ -91,7 +92,7 @@ pub struct TxToken {
}
impl phy::TxToken for TxToken {
fn consume<R, F>(self, _timestamp: u64, len: usize, f: F) -> Result<R>
fn consume<R, F>(self, _timestamp: Instant, len: usize, f: F) -> Result<R>
where F: FnOnce(&mut [u8]) -> Result<R>
{
let mut lower = self.lower.borrow_mut();

View File

@ -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<D: for<'a> Device<'a>, P: PrettyPrint> {
inner: D,
writer: fn(u64, PrettyPrinter<P>),
writer: fn(Instant, PrettyPrinter<P>),
}
impl<D: for<'a> Device<'a>, P: PrettyPrint> Tracer<D, P> {
/// Create a tracer device.
pub fn new(inner: D, writer: fn(timestamp: u64, printer: PrettyPrinter<P>)) -> Tracer<D, P> {
pub fn new(inner: D, writer: fn(timestamp: Instant, printer: PrettyPrinter<P>)) -> Tracer<D, P> {
Tracer { inner, writer }
}
@ -53,11 +54,11 @@ impl<'a, D, P> Device<'a> for Tracer<D, P>
#[doc(hidden)]
pub struct RxToken<Rx: phy::RxToken, P: PrettyPrint> {
token: Rx,
writer: fn(u64, PrettyPrinter<P>)
writer: fn(Instant, PrettyPrinter<P>)
}
impl<Rx: phy::RxToken, P: PrettyPrint> phy::RxToken for RxToken<Rx, P> {
fn consume<R, F>(self, timestamp: u64, f: F) -> Result<R>
fn consume<R, F>(self, timestamp: Instant, f: F) -> Result<R>
where F: FnOnce(&[u8]) -> Result<R>
{
let Self { token, writer } = self;
@ -71,11 +72,11 @@ impl<Rx: phy::RxToken, P: PrettyPrint> phy::RxToken for RxToken<Rx, P> {
#[doc(hidden)]
pub struct TxToken<Tx: phy::TxToken, P: PrettyPrint> {
token: Tx,
writer: fn(u64, PrettyPrinter<P>)
writer: fn(Instant, PrettyPrinter<P>)
}
impl<Tx: phy::TxToken, P: PrettyPrint> phy::TxToken for TxToken<Tx, P> {
fn consume<R, F>(self, timestamp: u64, len: usize, f: F) -> Result<R>
fn consume<R, F>(self, timestamp: Instant, len: usize, f: F) -> Result<R>
where F: FnOnce(&mut [u8]) -> Result<R>
{
let Self { token, writer } = self;

View File

@ -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()[..])?;