Do not use DeviceCapabilities in sockets.

DeviceCapabilities contains the `medium` field, so tests had to give it a value
even if it was unused. This is impossible to do with no `medium-*` enabled, because
it makes `Medium` uninhabited (empty enum).
master
Dario Nieuwenhuis 2020-12-28 00:23:57 +01:00
parent af4a1e6436
commit b6220a04c8
3 changed files with 66 additions and 72 deletions

View File

@ -634,13 +634,7 @@ impl<'a, DeviceT> Interface<'a, DeviceT>
}
fn socket_egress(&mut self, sockets: &mut SocketSet, timestamp: Instant) -> Result<bool> {
let mut caps = self.device.capabilities();
caps.max_transmission_unit = match caps.medium {
#[cfg(feature = "medium-ethernet")]
Medium::Ethernet => caps.max_transmission_unit - EthernetFrame::<&[u8]>::header_len(),
#[cfg(feature = "medium-ip")]
Medium::Ip => caps.max_transmission_unit,
};
let _caps = self.device.capabilities();
let mut emitted_any = false;
for mut socket in sockets.iter_mut() {
@ -667,11 +661,11 @@ impl<'a, DeviceT> Interface<'a, DeviceT>
match *socket {
#[cfg(feature = "socket-raw")]
Socket::Raw(ref mut socket) =>
socket.dispatch(&caps.checksum, |response|
socket.dispatch(&_caps.checksum, |response|
respond!(IpPacket::Raw(response))),
#[cfg(all(feature = "socket-icmp", any(feature = "proto-ipv4", feature = "proto-ipv6")))]
Socket::Icmp(ref mut socket) =>
socket.dispatch(&caps, |response| {
socket.dispatch(|response| {
match response {
#[cfg(feature = "proto-ipv4")]
(IpRepr::Ipv4(ipv4_repr), IcmpRepr::Ipv4(icmpv4_repr)) =>
@ -687,9 +681,16 @@ impl<'a, DeviceT> Interface<'a, DeviceT>
socket.dispatch(|response|
respond!(IpPacket::Udp(response))),
#[cfg(feature = "socket-tcp")]
Socket::Tcp(ref mut socket) =>
socket.dispatch(timestamp, &caps, |response|
respond!(IpPacket::Tcp(response))),
Socket::Tcp(ref mut socket) => {
let ip_mtu = match _caps.medium {
#[cfg(feature = "medium-ethernet")]
Medium::Ethernet => _caps.max_transmission_unit - EthernetFrame::<&[u8]>::header_len(),
#[cfg(feature = "medium-ip")]
Medium::Ip => _caps.max_transmission_unit,
};
socket.dispatch(timestamp, ip_mtu, |response|
respond!(IpPacket::Tcp(response)))
}
};
match (device_result, socket_result) {

View File

@ -3,7 +3,7 @@ use core::cmp;
use core::task::Waker;
use crate::{Error, Result};
use crate::phy::{ChecksumCapabilities, DeviceCapabilities};
use crate::phy::ChecksumCapabilities;
use crate::socket::{Socket, SocketMeta, SocketHandle, PollAt};
use crate::storage::{PacketBuffer, PacketMetadata};
#[cfg(feature = "async")]
@ -400,7 +400,7 @@ impl<'a> IcmpSocket<'a> {
Ok(())
}
pub(crate) fn dispatch<F>(&mut self, _caps: &DeviceCapabilities, emit: F) -> Result<()>
pub(crate) fn dispatch<F>(&mut self, emit: F) -> Result<()>
where F: FnOnce((IpRepr, IcmpRepr)) -> Result<()>
{
let handle = self.meta.handle;
@ -528,9 +528,9 @@ mod test_ipv4 {
#[test]
fn test_send_dispatch() {
let mut socket = socket(buffer(0), buffer(1));
let caps = DeviceCapabilities::default();
let checksum = ChecksumCapabilities::default();
assert_eq!(socket.dispatch(&caps, |_| unreachable!()),
assert_eq!(socket.dispatch(|_| unreachable!()),
Err(Error::Exhausted));
// This buffer is too long
@ -539,13 +539,13 @@ mod test_ipv4 {
let mut bytes = [0xff; 24];
let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
ECHOV4_REPR.emit(&mut packet, &caps.checksum);
ECHOV4_REPR.emit(&mut packet, &checksum);
assert_eq!(socket.send_slice(&packet.into_inner()[..], REMOTE_IPV4.into()), Ok(()));
assert_eq!(socket.send_slice(b"123456", REMOTE_IPV4.into()), Err(Error::Exhausted));
assert!(!socket.can_send());
assert_eq!(socket.dispatch(&caps, |(ip_repr, icmp_repr)| {
assert_eq!(socket.dispatch(|(ip_repr, icmp_repr)| {
assert_eq!(ip_repr, LOCAL_IPV4_REPR);
assert_eq!(icmp_repr, ECHOV4_REPR.into());
Err(Error::Unaddressable)
@ -553,7 +553,7 @@ mod test_ipv4 {
// buffer is not taken off of the tx queue due to the error
assert!(!socket.can_send());
assert_eq!(socket.dispatch(&caps, |(ip_repr, icmp_repr)| {
assert_eq!(socket.dispatch(|(ip_repr, icmp_repr)| {
assert_eq!(ip_repr, LOCAL_IPV4_REPR);
assert_eq!(icmp_repr, ECHOV4_REPR.into());
Ok(())
@ -565,16 +565,16 @@ mod test_ipv4 {
#[test]
fn test_set_hop_limit_v4() {
let mut s = socket(buffer(0), buffer(1));
let caps = DeviceCapabilities::default();
let checksum = ChecksumCapabilities::default();
let mut bytes = [0xff; 24];
let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
ECHOV4_REPR.emit(&mut packet, &caps.checksum);
ECHOV4_REPR.emit(&mut packet, &checksum);
s.set_hop_limit(Some(0x2a));
assert_eq!(s.send_slice(&packet.into_inner()[..], REMOTE_IPV4.into()), Ok(()));
assert_eq!(s.dispatch(&caps, |(ip_repr, _)| {
assert_eq!(s.dispatch(|(ip_repr, _)| {
assert_eq!(ip_repr, IpRepr::Ipv4(Ipv4Repr {
src_addr: Ipv4Address::UNSPECIFIED,
dst_addr: REMOTE_IPV4,
@ -594,20 +594,20 @@ mod test_ipv4 {
assert!(!socket.can_recv());
assert_eq!(socket.recv(), Err(Error::Exhausted));
let caps = DeviceCapabilities::default();
let checksum = ChecksumCapabilities::default();
let mut bytes = [0xff; 24];
let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
ECHOV4_REPR.emit(&mut packet, &caps.checksum);
ECHOV4_REPR.emit(&mut packet, &checksum);
let data = &packet.into_inner()[..];
assert!(socket.accepts(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &caps.checksum));
assert_eq!(socket.process(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &caps.checksum),
assert!(socket.accepts(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &checksum));
assert_eq!(socket.process(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &checksum),
Ok(()));
assert!(socket.can_recv());
assert!(socket.accepts(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &caps.checksum));
assert_eq!(socket.process(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &caps.checksum),
assert!(socket.accepts(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &checksum));
assert_eq!(socket.process(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &checksum),
Err(Error::Exhausted));
assert_eq!(socket.recv(), Ok((&data[..], REMOTE_IPV4.into())));
@ -619,7 +619,7 @@ mod test_ipv4 {
let mut socket = socket(buffer(1), buffer(1));
assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(()));
let caps = DeviceCapabilities::default();
let checksum = ChecksumCapabilities::default();
let mut bytes = [0xff; 20];
let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
let icmp_repr = Icmpv4Repr::EchoRequest {
@ -627,11 +627,11 @@ mod test_ipv4 {
seq_no: 0x5678,
data: &[0xff; 16]
};
icmp_repr.emit(&mut packet, &caps.checksum);
icmp_repr.emit(&mut packet, &checksum);
// Ensure that a packet with an identifier that isn't the bound
// ID is not accepted
assert!(!socket.accepts(&REMOTE_IPV4_REPR, &icmp_repr.into(), &caps.checksum));
assert!(!socket.accepts(&REMOTE_IPV4_REPR, &icmp_repr.into(), &checksum));
}
#[test]
@ -639,11 +639,11 @@ mod test_ipv4 {
let mut socket = socket(buffer(1), buffer(1));
assert_eq!(socket.bind(Endpoint::Udp(LOCAL_END_V4)), Ok(()));
let caps = DeviceCapabilities::default();
let checksum = ChecksumCapabilities::default();
let mut bytes = [0xff; 18];
let mut packet = UdpPacket::new_unchecked(&mut bytes);
UDP_REPR.emit(&mut packet, &REMOTE_IPV4.into(), &LOCAL_IPV4.into(), &caps.checksum);
UDP_REPR.emit(&mut packet, &REMOTE_IPV4.into(), &LOCAL_IPV4.into(), &checksum);
let data = &packet.into_inner()[..];
@ -670,14 +670,14 @@ mod test_ipv4 {
// Ensure we can accept ICMP error response to the bound
// UDP port
assert!(socket.accepts(&ip_repr, &icmp_repr.into(), &caps.checksum));
assert_eq!(socket.process(&ip_repr, &icmp_repr.into(), &caps.checksum),
assert!(socket.accepts(&ip_repr, &icmp_repr.into(), &checksum));
assert_eq!(socket.process(&ip_repr, &icmp_repr.into(), &checksum),
Ok(()));
assert!(socket.can_recv());
let mut bytes = [0x00; 46];
let mut packet = Icmpv4Packet::new_unchecked(&mut bytes[..]);
icmp_repr.emit(&mut packet, &caps.checksum);
icmp_repr.emit(&mut packet, &checksum);
assert_eq!(socket.recv(), Ok((&packet.into_inner()[..], REMOTE_IPV4.into())));
assert!(!socket.can_recv());
}
@ -727,9 +727,9 @@ mod test_ipv6 {
#[test]
fn test_send_dispatch() {
let mut socket = socket(buffer(0), buffer(1));
let caps = DeviceCapabilities::default();
let checksum = ChecksumCapabilities::default();
assert_eq!(socket.dispatch(&caps, |_| unreachable!()),
assert_eq!(socket.dispatch(|_| unreachable!()),
Err(Error::Exhausted));
// This buffer is too long
@ -738,13 +738,13 @@ mod test_ipv6 {
let mut bytes = vec![0xff; 24];
let mut packet = Icmpv6Packet::new_unchecked(&mut bytes);
ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &caps.checksum);
ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum);
assert_eq!(socket.send_slice(&packet.into_inner()[..], REMOTE_IPV6.into()), Ok(()));
assert_eq!(socket.send_slice(b"123456", REMOTE_IPV6.into()), Err(Error::Exhausted));
assert!(!socket.can_send());
assert_eq!(socket.dispatch(&caps, |(ip_repr, icmp_repr)| {
assert_eq!(socket.dispatch(|(ip_repr, icmp_repr)| {
assert_eq!(ip_repr, LOCAL_IPV6_REPR);
assert_eq!(icmp_repr, ECHOV6_REPR.into());
Err(Error::Unaddressable)
@ -752,7 +752,7 @@ mod test_ipv6 {
// buffer is not taken off of the tx queue due to the error
assert!(!socket.can_send());
assert_eq!(socket.dispatch(&caps, |(ip_repr, icmp_repr)| {
assert_eq!(socket.dispatch(|(ip_repr, icmp_repr)| {
assert_eq!(ip_repr, LOCAL_IPV6_REPR);
assert_eq!(icmp_repr, ECHOV6_REPR.into());
Ok(())
@ -764,16 +764,16 @@ mod test_ipv6 {
#[test]
fn test_set_hop_limit() {
let mut s = socket(buffer(0), buffer(1));
let caps = DeviceCapabilities::default();
let checksum = ChecksumCapabilities::default();
let mut bytes = vec![0xff; 24];
let mut packet = Icmpv6Packet::new_unchecked(&mut bytes);
ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &caps.checksum);
ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum);
s.set_hop_limit(Some(0x2a));
assert_eq!(s.send_slice(&packet.into_inner()[..], REMOTE_IPV6.into()), Ok(()));
assert_eq!(s.dispatch(&caps, |(ip_repr, _)| {
assert_eq!(s.dispatch(|(ip_repr, _)| {
assert_eq!(ip_repr, IpRepr::Ipv6(Ipv6Repr {
src_addr: Ipv6Address::UNSPECIFIED,
dst_addr: REMOTE_IPV6,
@ -793,20 +793,20 @@ mod test_ipv6 {
assert!(!socket.can_recv());
assert_eq!(socket.recv(), Err(Error::Exhausted));
let caps = DeviceCapabilities::default();
let checksum = ChecksumCapabilities::default();
let mut bytes = [0xff; 24];
let mut packet = Icmpv6Packet::new_unchecked(&mut bytes);
ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &caps.checksum);
ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum);
let data = &packet.into_inner()[..];
assert!(socket.accepts(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &caps.checksum));
assert_eq!(socket.process(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &caps.checksum),
assert!(socket.accepts(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &checksum));
assert_eq!(socket.process(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &checksum),
Ok(()));
assert!(socket.can_recv());
assert!(socket.accepts(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &caps.checksum));
assert_eq!(socket.process(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &caps.checksum),
assert!(socket.accepts(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &checksum));
assert_eq!(socket.process(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &checksum),
Err(Error::Exhausted));
assert_eq!(socket.recv(), Ok((&data[..], REMOTE_IPV6.into())));
@ -818,7 +818,7 @@ mod test_ipv6 {
let mut socket = socket(buffer(1), buffer(1));
assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(()));
let caps = DeviceCapabilities::default();
let checksum = ChecksumCapabilities::default();
let mut bytes = [0xff; 20];
let mut packet = Icmpv6Packet::new_unchecked(&mut bytes);
let icmp_repr = Icmpv6Repr::EchoRequest {
@ -826,11 +826,11 @@ mod test_ipv6 {
seq_no: 0x5678,
data: &[0xff; 16]
};
icmp_repr.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &caps.checksum);
icmp_repr.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum);
// Ensure that a packet with an identifier that isn't the bound
// ID is not accepted
assert!(!socket.accepts(&REMOTE_IPV6_REPR, &icmp_repr.into(), &caps.checksum));
assert!(!socket.accepts(&REMOTE_IPV6_REPR, &icmp_repr.into(), &checksum));
}
#[test]
@ -838,11 +838,11 @@ mod test_ipv6 {
let mut socket = socket(buffer(1), buffer(1));
assert_eq!(socket.bind(Endpoint::Udp(LOCAL_END_V6)), Ok(()));
let caps = DeviceCapabilities::default();
let checksum = ChecksumCapabilities::default();
let mut bytes = [0xff; 18];
let mut packet = UdpPacket::new_unchecked(&mut bytes);
UDP_REPR.emit(&mut packet, &REMOTE_IPV6.into(), &LOCAL_IPV6.into(), &caps.checksum);
UDP_REPR.emit(&mut packet, &REMOTE_IPV6.into(), &LOCAL_IPV6.into(), &checksum);
let data = &packet.into_inner()[..];
@ -869,14 +869,14 @@ mod test_ipv6 {
// Ensure we can accept ICMP error response to the bound
// UDP port
assert!(socket.accepts(&ip_repr, &icmp_repr.into(), &caps.checksum));
assert_eq!(socket.process(&ip_repr, &icmp_repr.into(), &caps.checksum),
assert!(socket.accepts(&ip_repr, &icmp_repr.into(), &checksum));
assert_eq!(socket.process(&ip_repr, &icmp_repr.into(), &checksum),
Ok(()));
assert!(socket.can_recv());
let mut bytes = [0x00; 66];
let mut packet = Icmpv6Packet::new_unchecked(&mut bytes[..]);
icmp_repr.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &caps.checksum);
icmp_repr.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum);
assert_eq!(socket.recv(), Ok((&packet.into_inner()[..], REMOTE_IPV6.into())));
assert!(!socket.can_recv());
}

View File

@ -7,7 +7,6 @@ use core::{cmp, fmt, mem};
use core::task::Waker;
use crate::{Error, Result};
use crate::phy::DeviceCapabilities;
use crate::time::{Duration, Instant};
use crate::socket::{Socket, SocketMeta, SocketHandle, PollAt};
use crate::storage::{Assembler, RingBuffer};
@ -1662,7 +1661,7 @@ impl<'a> TcpSocket<'a> {
}
}
pub(crate) fn dispatch<F>(&mut self, timestamp: Instant, caps: &DeviceCapabilities,
pub(crate) fn dispatch<F>(&mut self, timestamp: Instant, ip_mtu: usize,
emit: F) -> Result<()>
where F: FnOnce((IpRepr, TcpRepr)) -> Result<()> {
if !self.remote_endpoint.is_specified() { return Err(Error::Exhausted) }
@ -1789,7 +1788,7 @@ impl<'a> TcpSocket<'a> {
let offset = self.remote_last_seq - self.local_seq_no;
let win_limit = self.local_seq_no + self.remote_win_len - self.remote_last_seq;
let size = cmp::min(cmp::min(win_limit, self.remote_mss),
caps.max_transmission_unit - ip_repr.buffer_len() - repr.mss_header_len());
ip_mtu - ip_repr.buffer_len() - repr.mss_header_len());
repr.payload = self.tx_buffer.get_allocated(offset, size);
// If we've sent everything we had in the buffer, follow it with the PSH or FIN
// flags, depending on whether the transmit half of the connection is open.
@ -1848,7 +1847,7 @@ impl<'a> TcpSocket<'a> {
if repr.control == TcpControl::Syn {
// Fill the MSS option. See RFC 6691 for an explanation of this calculation.
let mut max_segment_size = caps.max_transmission_unit;
let mut max_segment_size = ip_mtu;
max_segment_size -= ip_repr.buffer_len();
max_segment_size -= repr.mss_header_len();
repr.max_seg_size = Some(max_segment_size as u16);
@ -2044,11 +2043,8 @@ mod test {
fn recv<F>(socket: &mut TcpSocket, timestamp: Instant, mut f: F)
where F: FnMut(Result<TcpRepr>) {
let caps = DeviceCapabilities {
max_transmission_unit: 1520,
..Default::default()
};
let result = socket.dispatch(timestamp, &caps, |(ip_repr, tcp_repr)| {
let mtu = 1520;
let result = socket.dispatch(timestamp, mtu, |(ip_repr, tcp_repr)| {
let ip_repr = ip_repr.lower(&[IpCidr::new(LOCAL_END.addr, 24)]).unwrap();
assert_eq!(ip_repr.protocol(), IpProtocol::Tcp);
@ -4897,13 +4893,10 @@ mod test {
#[test]
fn test_set_hop_limit() {
let mut s = socket_syn_received();
let caps = DeviceCapabilities {
max_transmission_unit: 1520,
..Default::default()
};
let mtu = 1520;
s.set_hop_limit(Some(0x2a));
assert_eq!(s.dispatch(Instant::from_millis(0), &caps, |(ip_repr, _)| {
assert_eq!(s.dispatch(Instant::from_millis(0), mtu, |(ip_repr, _)| {
assert_eq!(ip_repr.hop_limit(), 0x2a);
Ok(())
}), Ok(()));