Browse Source

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).
Dario Nieuwenhuis 4 years ago
parent
commit
56c779ed63
3 changed files with 66 additions and 72 deletions
  1. 13 12
      src/iface/interface.rs
  2. 46 46
      src/socket/icmp.rs
  3. 7 14
      src/socket/tcp.rs

+ 13 - 12
src/iface/interface.rs

@@ -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) {

+ 46 - 46
src/socket/icmp.rs

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

+ 7 - 14
src/socket/tcp.rs

@@ -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(()));