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: whitequarkv0.7.x
parent
20d1dd8a4a
commit
e0b48caca3
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()[..])?;
|
||||
|
|
Loading…
Reference in New Issue