fn Device::mtu() -> usize → Device::limits() -> DeviceLimits
This commit is contained in:
parent
6ad8872e15
commit
1d46ccf432
|
@ -367,11 +367,13 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
|
|||
let src_protocol_addrs = self.protocol_addrs.as_ref();
|
||||
let arp_cache = &mut self.arp_cache;
|
||||
let device = &mut self.device;
|
||||
let mtu = device.mtu() - EthernetFrame::<&[u8]>::header_len();
|
||||
|
||||
let mut limits = device.limits();
|
||||
limits.max_transmission_unit -= EthernetFrame::<&[u8]>::header_len();
|
||||
|
||||
let mut nothing_to_transmit = true;
|
||||
for socket in sockets.iter_mut() {
|
||||
let result = socket.dispatch(timestamp, mtu, &mut |repr, payload| {
|
||||
let result = socket.dispatch(timestamp, &limits, &mut |repr, payload| {
|
||||
let repr = try!(repr.lower(src_protocol_addrs));
|
||||
|
||||
match arp_cache.lookup(&repr.dst_addr()) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use Error;
|
||||
use super::Device;
|
||||
use super::{DeviceLimits, Device};
|
||||
|
||||
// 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.
|
||||
|
@ -98,12 +98,12 @@ impl<T: Device> Device for FaultInjector<T>
|
|||
type RxBuffer = T::RxBuffer;
|
||||
type TxBuffer = TxBuffer<T::TxBuffer>;
|
||||
|
||||
fn mtu(&self) -> usize {
|
||||
if self.lower.mtu() < MTU {
|
||||
self.lower.mtu()
|
||||
} else {
|
||||
MTU
|
||||
fn limits(&self) -> DeviceLimits {
|
||||
let mut limits = self.lower.limits();
|
||||
if limits.max_transmission_unit > MTU {
|
||||
limits.max_transmission_unit = MTU;
|
||||
}
|
||||
limits
|
||||
}
|
||||
|
||||
fn receive(&mut self) -> Result<Self::RxBuffer, Error> {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
```rust
|
||||
use std::slice;
|
||||
use smoltcp::Error;
|
||||
use smoltcp::phy::Device;
|
||||
use smoltcp::phy::{DeviceLimits, Device};
|
||||
|
||||
const TX_BUFFERS: [*mut u8; 2] = [0x10000000 as *mut u8, 0x10001000 as *mut u8];
|
||||
const RX_BUFFERS: [*mut u8; 2] = [0x10002000 as *mut u8, 0x10003000 as *mut u8];
|
||||
|
@ -50,7 +50,12 @@ impl Device for EthernetDevice {
|
|||
type RxBuffer = &'static [u8];
|
||||
type TxBuffer = EthernetTxBuffer;
|
||||
|
||||
fn mtu(&self) -> usize { 1536 }
|
||||
fn limits(&self) -> DeviceLimits {
|
||||
let mut limits = DeviceLimits::default();
|
||||
limits.max_transmission_unit = 1536;
|
||||
limits.max_burst_size = Some(2);
|
||||
limits
|
||||
}
|
||||
|
||||
fn receive(&mut self) -> Result<Self::RxBuffer, Error> {
|
||||
if rx_full() {
|
||||
|
@ -114,6 +119,34 @@ pub use self::raw_socket::RawSocket;
|
|||
#[cfg(all(feature = "std", target_os = "linux"))]
|
||||
pub use self::tap_interface::TapInterface;
|
||||
|
||||
/// A description of device limitations.
|
||||
///
|
||||
/// Higher-level protocols may achieve higher throughput or lower latency if they consider
|
||||
/// the bandwidth or packet size limitations.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct DeviceLimits {
|
||||
/// Maximum transmission unit.
|
||||
///
|
||||
/// The network device is unable to send or receive frames larger than the value returned
|
||||
/// by this function.
|
||||
///
|
||||
/// For Ethernet, MTU will fall between 576 (for IPv4) or 1280 (for IPv6) and 9216 octets.
|
||||
pub max_transmission_unit: usize,
|
||||
|
||||
/// Maximum burst size, in terms of MTU.
|
||||
///
|
||||
/// The network device is unable to send or receive bursts large than the value returned
|
||||
/// by this function.
|
||||
///
|
||||
/// If `None`, there is no fixed limit on burst size, e.g. if network buffers are
|
||||
/// dynamically allocated.
|
||||
pub max_burst_size: Option<usize>,
|
||||
|
||||
/// Only present to prevent people from trying to initialize every field of DeviceLimits,
|
||||
/// which would not let us add new fields in the future.
|
||||
dummy: ()
|
||||
}
|
||||
|
||||
/// An interface for sending and receiving raw network frames.
|
||||
///
|
||||
/// It is expected that a `Device` implementation would allocate memory for both sending
|
||||
|
@ -123,11 +156,8 @@ pub trait Device {
|
|||
type RxBuffer: AsRef<[u8]>;
|
||||
type TxBuffer: AsRef<[u8]> + AsMut<[u8]>;
|
||||
|
||||
/// Get maximum transmission unit.
|
||||
///
|
||||
/// The network device is unable to send or receive frames larger than the MTU.
|
||||
/// In practice, MTU will fall between 576 (for IPv4) or 1280 (for IPv6) and 9216 octets.
|
||||
fn mtu(&self) -> usize;
|
||||
/// Get a description of device limitations.
|
||||
fn limits(&self) -> DeviceLimits;
|
||||
|
||||
/// Receive a frame.
|
||||
///
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::rc::Rc;
|
|||
use std::io;
|
||||
|
||||
use Error;
|
||||
use super::{sys, Device};
|
||||
use super::{sys, DeviceLimits, Device};
|
||||
|
||||
/// A socket that captures or transmits the complete frame.
|
||||
#[derive(Debug)]
|
||||
|
@ -33,7 +33,12 @@ impl Device for RawSocket {
|
|||
type RxBuffer = Vec<u8>;
|
||||
type TxBuffer = TxBuffer;
|
||||
|
||||
fn mtu(&self) -> usize { self.mtu }
|
||||
fn limits(&self) -> DeviceLimits {
|
||||
DeviceLimits {
|
||||
max_transmission_unit: self.mtu,
|
||||
..DeviceLimits::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn receive(&mut self) -> Result<Self::RxBuffer, Error> {
|
||||
let mut lower = self.lower.borrow_mut();
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::rc::Rc;
|
|||
use std::io;
|
||||
|
||||
use Error;
|
||||
use super::{sys, Device};
|
||||
use super::{sys, DeviceLimits, Device};
|
||||
|
||||
/// A virtual Ethernet interface.
|
||||
#[derive(Debug)]
|
||||
|
@ -33,7 +33,12 @@ impl Device for TapInterface {
|
|||
type RxBuffer = Vec<u8>;
|
||||
type TxBuffer = TxBuffer;
|
||||
|
||||
fn mtu(&self) -> usize { self.mtu }
|
||||
fn limits(&self) -> DeviceLimits {
|
||||
DeviceLimits {
|
||||
max_transmission_unit: self.mtu,
|
||||
..DeviceLimits::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn receive(&mut self) -> Result<Self::RxBuffer, Error> {
|
||||
let mut lower = self.lower.borrow_mut();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use Error;
|
||||
use wire::pretty_print::{PrettyPrint, PrettyPrinter};
|
||||
use super::Device;
|
||||
use super::{DeviceLimits, Device};
|
||||
|
||||
/// A tracer device.
|
||||
///
|
||||
|
@ -43,7 +43,7 @@ impl<T: Device, U: PrettyPrint> Device for Tracer<T, U> {
|
|||
type RxBuffer = T::RxBuffer;
|
||||
type TxBuffer = TxBuffer<T::TxBuffer, U>;
|
||||
|
||||
fn mtu(&self) -> usize { self.lower.mtu() }
|
||||
fn limits(&self) -> DeviceLimits { self.lower.limits() }
|
||||
|
||||
fn receive(&mut self) -> Result<Self::RxBuffer, Error> {
|
||||
let buffer = try!(self.lower.receive());
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
//! size for a buffer, allocate it, and let the networking stack use it.
|
||||
|
||||
use Error;
|
||||
use phy::DeviceLimits;
|
||||
use wire::IpRepr;
|
||||
|
||||
mod udp;
|
||||
|
@ -92,10 +93,10 @@ impl<'a, 'b> Socket<'a, 'b> {
|
|||
/// is returned.
|
||||
///
|
||||
/// This function is used internally by the networking stack.
|
||||
pub fn dispatch<F, R>(&mut self, timestamp: u64, mtu: usize,
|
||||
pub fn dispatch<F, R>(&mut self, timestamp: u64, limits: &DeviceLimits,
|
||||
emit: &mut F) -> Result<R, Error>
|
||||
where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
|
||||
dispatch_socket!(self, |socket [mut]| socket.dispatch(timestamp, mtu, emit))
|
||||
dispatch_socket!(self, |socket [mut]| socket.dispatch(timestamp, limits, emit))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ use core::fmt;
|
|||
use managed::Managed;
|
||||
|
||||
use Error;
|
||||
use phy::DeviceLimits;
|
||||
use wire::{IpProtocol, IpAddress, IpEndpoint};
|
||||
use wire::{TcpSeqNumber, TcpPacket, TcpRepr, TcpControl};
|
||||
use socket::{Socket, IpRepr, IpPayload};
|
||||
|
@ -916,7 +917,7 @@ impl<'a> TcpSocket<'a> {
|
|||
}
|
||||
|
||||
/// See [Socket::dispatch](enum.Socket.html#method.dispatch).
|
||||
pub fn dispatch<F, R>(&mut self, timestamp: u64, mtu: usize,
|
||||
pub fn dispatch<F, R>(&mut self, timestamp: u64, limits: &DeviceLimits,
|
||||
emit: &mut F) -> Result<R, Error>
|
||||
where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
|
||||
if self.remote_endpoint.is_unspecified() { return Err(Error::Exhausted) }
|
||||
|
@ -1080,8 +1081,10 @@ impl<'a> TcpSocket<'a> {
|
|||
let ip_repr = try!(ip_repr.lower(&[]));
|
||||
|
||||
if repr.control == TcpControl::Syn {
|
||||
let mtu = mtu - header_len - ip_repr.buffer_len();
|
||||
repr.max_seg_size = Some(mtu as u16);
|
||||
let mut max_segment_size = limits.max_transmission_unit;
|
||||
max_segment_size -= header_len;
|
||||
max_segment_size -= ip_repr.buffer_len();
|
||||
repr.max_seg_size = Some(max_segment_size as u16);
|
||||
}
|
||||
|
||||
emit(&ip_repr, &repr)
|
||||
|
@ -1196,7 +1199,9 @@ mod test {
|
|||
fn recv<F>(socket: &mut TcpSocket, timestamp: u64, mut f: F)
|
||||
where F: FnMut(Result<TcpRepr, Error>) {
|
||||
let mut buffer = vec![];
|
||||
let result = socket.dispatch(timestamp, 1520, &mut |ip_repr, payload| {
|
||||
let mut limits = DeviceLimits::default();
|
||||
limits.max_transmission_unit = 1520;
|
||||
let result = socket.dispatch(timestamp, &limits, &mut |ip_repr, payload| {
|
||||
assert_eq!(ip_repr.protocol(), IpProtocol::Tcp);
|
||||
assert_eq!(ip_repr.src_addr(), LOCAL_IP);
|
||||
assert_eq!(ip_repr.dst_addr(), REMOTE_IP);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use managed::Managed;
|
||||
|
||||
use Error;
|
||||
use phy::DeviceLimits;
|
||||
use wire::{IpProtocol, IpEndpoint};
|
||||
use wire::{UdpPacket, UdpRepr};
|
||||
use socket::{Socket, IpRepr, IpPayload};
|
||||
|
@ -232,7 +233,7 @@ impl<'a, 'b> UdpSocket<'a, 'b> {
|
|||
}
|
||||
|
||||
/// See [Socket::dispatch](enum.Socket.html#method.dispatch).
|
||||
pub fn dispatch<F, R>(&mut self, _timestamp: u64, _mtu: usize,
|
||||
pub fn dispatch<F, R>(&mut self, _timestamp: u64, _limits: &DeviceLimits,
|
||||
emit: &mut F) -> Result<R, Error>
|
||||
where F: FnMut(&IpRepr, &IpPayload) -> Result<R, Error> {
|
||||
let packet_buf = try!(self.tx_buffer.dequeue().map_err(|()| Error::Exhausted));
|
||||
|
|
Loading…
Reference in New Issue