Selaa lähdekoodia

socket: Make process() infallible.

Malformed/unexpected packets are logged and ignored. See #281 on rationale
for why this is better.
Dario Nieuwenhuis 2 vuotta sitten
vanhempi
commit
37a276bcf2
7 muutettua tiedostoa jossa 253 lisäystä ja 401 poistoa
  1. 29 151
      src/iface/interface.rs
  2. 12 17
      src/socket/dhcpv4.rs
  3. 51 17
      src/socket/dns.rs
  4. 31 52
      src/socket/icmp.rs
  5. 32 48
      src/socket/raw.rs
  6. 81 88
      src/socket/tcp.rs
  7. 17 28
      src/socket/udp.rs

+ 29 - 151
src/iface/interface.rs

@@ -1398,18 +1398,14 @@ impl<'a> InterfaceInner<'a> {
                             .iter_mut()
                             .filter_map(|i| udp::Socket::downcast(&mut i.socket))
                         {
-                            if !udp_socket.accepts(self, &IpRepr::Ipv6(ipv6_repr), &udp_repr) {
-                                continue;
-                            }
-
-                            match udp_socket.process(
-                                self,
-                                &IpRepr::Ipv6(ipv6_repr),
-                                &udp_repr,
-                                udp_packet.payload(),
-                            ) {
-                                Ok(()) => return Ok(None),
-                                Err(e) => return Err(e),
+                            if udp_socket.accepts(self, &IpRepr::Ipv6(ipv6_repr), &udp_repr) {
+                                udp_socket.process(
+                                    self,
+                                    &IpRepr::Ipv6(ipv6_repr),
+                                    &udp_repr,
+                                    udp_packet.payload(),
+                                );
+                                return Ok(None);
                             }
                         }
 
@@ -1523,17 +1519,9 @@ impl<'a> InterfaceInner<'a> {
             .iter_mut()
             .filter_map(|i| raw::Socket::downcast(&mut i.socket))
         {
-            if !raw_socket.accepts(ip_repr) {
-                continue;
-            }
-
-            match raw_socket.process(self, ip_repr, ip_payload) {
-                // The packet is valid and handled by socket.
-                Ok(()) => handled_by_raw_socket = true,
-                // The socket buffer is full or the packet was truncated
-                Err(Error::Exhausted) | Err(Error::Truncated) => (),
-                // Raw sockets don't validate the packets in any way.
-                Err(_) => unreachable!(),
+            if raw_socket.accepts(ip_repr) {
+                raw_socket.process(self, ip_repr, ip_payload);
+                handled_by_raw_socket = true;
             }
         }
         handled_by_raw_socket
@@ -1655,12 +1643,8 @@ impl<'a> InterfaceInner<'a> {
                             UdpRepr::parse(&udp_packet, &src_addr, &dst_addr, &self.caps.checksum)?;
                         let udp_payload = udp_packet.payload();
 
-                        match dhcp_socket.process(self, &ipv4_repr, &udp_repr, udp_payload) {
-                            // The packet is valid and handled by socket.
-                            Ok(()) => return Ok(None),
-                            // The packet is malformed, or the socket buffer is full.
-                            Err(e) => return Err(e),
-                        }
+                        dhcp_socket.process(self, &ipv4_repr, &udp_repr, udp_payload);
+                        return Ok(None);
                     }
                 }
             }
@@ -1828,17 +1812,9 @@ impl<'a> InterfaceInner<'a> {
             .iter_mut()
             .filter_map(|i| icmp::Socket::downcast(&mut i.socket))
         {
-            if !icmp_socket.accepts(self, &ip_repr, &icmp_repr.into()) {
-                continue;
-            }
-
-            match icmp_socket.process(self, &ip_repr, &icmp_repr.into()) {
-                // The packet is valid and handled by socket.
-                Ok(()) => handled_by_icmp_socket = true,
-                // The socket buffer is full.
-                Err(Error::Exhausted) => (),
-                // ICMP sockets don't validate the packets in any way.
-                Err(_) => unreachable!(),
+            if icmp_socket.accepts(self, &ip_repr, &icmp_repr.into()) {
+                icmp_socket.process(self, &ip_repr, &icmp_repr.into());
+                handled_by_icmp_socket = true;
             }
         }
 
@@ -2015,17 +1991,9 @@ impl<'a> InterfaceInner<'a> {
             .iter_mut()
             .filter_map(|i| icmp::Socket::downcast(&mut i.socket))
         {
-            if !icmp_socket.accepts(self, &ip_repr, &icmp_repr.into()) {
-                continue;
-            }
-
-            match icmp_socket.process(self, &ip_repr, &icmp_repr.into()) {
-                // The packet is valid and handled by socket.
-                Ok(()) => handled_by_icmp_socket = true,
-                // The socket buffer is full.
-                Err(Error::Exhausted) => (),
-                // ICMP sockets don't validate the packets in any way.
-                Err(_) => unreachable!(),
+            if icmp_socket.accepts(self, &ip_repr, &icmp_repr.into()) {
+                icmp_socket.process(self, &ip_repr, &icmp_repr.into());
+                handled_by_icmp_socket = true;
             }
         }
 
@@ -2143,15 +2111,9 @@ impl<'a> InterfaceInner<'a> {
             .iter_mut()
             .filter_map(|i| udp::Socket::downcast(&mut i.socket))
         {
-            if !udp_socket.accepts(self, &ip_repr, &udp_repr) {
-                continue;
-            }
-
-            match udp_socket.process(self, &ip_repr, &udp_repr, udp_payload) {
-                // The packet is valid and handled by socket.
-                Ok(()) => return Ok(None),
-                // The packet is malformed, or the socket buffer is full.
-                Err(e) => return Err(e),
+            if udp_socket.accepts(self, &ip_repr, &udp_repr) {
+                udp_socket.process(self, &ip_repr, &udp_repr, udp_payload);
+                return Ok(None);
             }
         }
 
@@ -2160,15 +2122,9 @@ impl<'a> InterfaceInner<'a> {
             .iter_mut()
             .filter_map(|i| dns::Socket::downcast(&mut i.socket))
         {
-            if !dns_socket.accepts(&ip_repr, &udp_repr) {
-                continue;
-            }
-
-            match dns_socket.process(self, &ip_repr, &udp_repr, udp_payload) {
-                // The packet is valid and handled by socket.
-                Ok(()) => return Ok(None),
-                // The packet is malformed, or the socket buffer is full.
-                Err(e) => return Err(e),
+            if dns_socket.accepts(&ip_repr, &udp_repr) {
+                dns_socket.process(self, &ip_repr, &udp_repr, udp_payload);
+                return Ok(None);
             }
         }
 
@@ -2218,16 +2174,10 @@ impl<'a> InterfaceInner<'a> {
             .iter_mut()
             .filter_map(|i| tcp::Socket::downcast(&mut i.socket))
         {
-            if !tcp_socket.accepts(self, &ip_repr, &tcp_repr) {
-                continue;
-            }
-
-            match tcp_socket.process(self, &ip_repr, &tcp_repr) {
-                // The packet is valid and handled by socket.
-                Ok(reply) => return Ok(reply.map(IpPacket::Tcp)),
-                // The packet is malformed, or doesn't match the socket state,
-                // or the socket buffer is full.
-                Err(e) => return Err(e),
+            if tcp_socket.accepts(self, &ip_repr, &tcp_repr) {
+                return Ok(tcp_socket
+                    .process(self, &ip_repr, &tcp_repr)
+                    .map(IpPacket::Tcp));
             }
         }
 
@@ -3919,78 +3869,6 @@ mod test {
         );
     }
 
-    #[test]
-    #[cfg(all(feature = "proto-ipv4", feature = "socket-raw"))]
-    fn test_raw_socket_truncated_packet() {
-        use crate::wire::{IpVersion, Ipv4Packet, UdpPacket, UdpRepr};
-
-        let mut iface = create_loopback();
-
-        let packets = 1;
-        let rx_buffer =
-            raw::PacketBuffer::new(vec![raw::PacketMetadata::EMPTY; packets], vec![0; 48 * 1]);
-        let tx_buffer = raw::PacketBuffer::new(
-            vec![raw::PacketMetadata::EMPTY; packets],
-            vec![0; 48 * packets],
-        );
-        let raw_socket = raw::Socket::new(IpVersion::Ipv4, IpProtocol::Udp, rx_buffer, tx_buffer);
-        iface.add_socket(raw_socket);
-
-        let src_addr = Ipv4Address([127, 0, 0, 2]);
-        let dst_addr = Ipv4Address([127, 0, 0, 1]);
-
-        const PAYLOAD_LEN: usize = 49; // 49 > 48, hence packet will be truncated
-
-        let udp_repr = UdpRepr {
-            src_port: 67,
-            dst_port: 68,
-        };
-        let mut bytes = vec![0xff; udp_repr.header_len() + PAYLOAD_LEN];
-        let mut packet = UdpPacket::new_unchecked(&mut bytes[..]);
-        udp_repr.emit(
-            &mut packet,
-            &src_addr.into(),
-            &dst_addr.into(),
-            PAYLOAD_LEN,
-            |buf| fill_slice(buf, 0x2a),
-            &ChecksumCapabilities::default(),
-        );
-
-        let ipv4_repr = Ipv4Repr {
-            src_addr: src_addr,
-            dst_addr: dst_addr,
-            next_header: IpProtocol::Udp,
-            hop_limit: 64,
-            payload_len: udp_repr.header_len() + PAYLOAD_LEN,
-        };
-
-        // Emit to frame
-        let mut bytes = vec![0u8; ipv4_repr.buffer_len() + udp_repr.header_len() + PAYLOAD_LEN];
-        let frame = {
-            ipv4_repr.emit(
-                &mut Ipv4Packet::new_unchecked(&mut bytes),
-                &ChecksumCapabilities::default(),
-            );
-            udp_repr.emit(
-                &mut UdpPacket::new_unchecked(&mut bytes[ipv4_repr.buffer_len()..]),
-                &src_addr.into(),
-                &dst_addr.into(),
-                PAYLOAD_LEN,
-                |buf| fill_slice(buf, 0x2a),
-                &ChecksumCapabilities::default(),
-            );
-            Ipv4Packet::new_unchecked(&bytes)
-        };
-
-        let frame = iface.inner.process_ipv4(&mut iface.sockets, &frame);
-
-        // because the packet could not be handled we should send an Icmp message
-        assert!(match frame {
-            Ok(Some(IpPacket::Icmpv4(_))) => true,
-            _ => false,
-        });
-    }
-
     #[test]
     #[cfg(all(feature = "proto-ipv4", feature = "socket-raw", feature = "socket-udp"))]
     fn test_raw_socket_with_udp_socket() {

+ 12 - 17
src/socket/dhcpv4.rs

@@ -196,7 +196,7 @@ impl Socket {
         ip_repr: &Ipv4Repr,
         repr: &UdpRepr,
         payload: &[u8],
-    ) -> Result<()> {
+    ) {
         let src_ip = ip_repr.src_addr;
 
         // This is enforced in interface.rs.
@@ -206,27 +206,26 @@ impl Socket {
             Ok(dhcp_packet) => dhcp_packet,
             Err(e) => {
                 net_debug!("DHCP invalid pkt from {}: {:?}", src_ip, e);
-                return Ok(());
+                return;
             }
         };
         let dhcp_repr = match DhcpRepr::parse(&dhcp_packet) {
             Ok(dhcp_repr) => dhcp_repr,
             Err(e) => {
                 net_debug!("DHCP error parsing pkt from {}: {:?}", src_ip, e);
-                return Ok(());
+                return;
             }
         };
-        let hardware_addr = if let Some(HardwareAddress::Ethernet(addr)) = cx.hardware_addr() {
-            addr
-        } else {
-            return Err(Error::Malformed);
+        let hardware_addr = match cx.hardware_addr() {
+            Some(HardwareAddress::Ethernet(addr)) => addr,
+            _ => return,
         };
 
         if dhcp_repr.client_hardware_address != hardware_addr {
-            return Ok(());
+            return;
         }
         if dhcp_repr.transaction_id != self.transaction_id {
-            return Ok(());
+            return;
         }
         let server_identifier = match dhcp_repr.server_identifier {
             Some(server_identifier) => server_identifier,
@@ -235,7 +234,7 @@ impl Socket {
                     "DHCP ignoring {:?} because missing server_identifier",
                     dhcp_repr.message_type
                 );
-                return Ok(());
+                return;
             }
         };
 
@@ -250,7 +249,7 @@ impl Socket {
             (ClientState::Discovering(_state), DhcpMessageType::Offer) => {
                 if !dhcp_repr.your_ip.is_unicast() {
                     net_debug!("DHCP ignoring OFFER because your_ip is not unicast");
-                    return Ok(());
+                    return;
                 }
 
                 self.state = ClientState::Requesting(RequestState {
@@ -305,8 +304,6 @@ impl Socket {
                 );
             }
         }
-
-        Ok(())
     }
 
     fn parse_ack(
@@ -582,7 +579,7 @@ mod test {
         s: &mut TestSocket,
         timestamp: Instant,
         (ip_repr, udp_repr, dhcp_repr): (Ipv4Repr, UdpRepr, DhcpRepr),
-    ) -> Result<()> {
+    ) {
         s.cx.set_now(timestamp);
 
         net_trace!("send: {:?}", ip_repr);
@@ -636,9 +633,7 @@ mod test {
         ($socket:ident, $repr:expr) =>
             (send!($socket, time 0, $repr));
         ($socket:ident, time $time:expr, $repr:expr) =>
-            (send!($socket, time $time, $repr, Ok(( ))));
-        ($socket:ident, time $time:expr, $repr:expr, $result:expr) =>
-            (assert_eq!(send(&mut $socket, Instant::from_millis($time), $repr), $result));
+            (send(&mut $socket, Instant::from_millis($time), $repr));
     }
 
     macro_rules! recv {

+ 51 - 17
src/socket/dns.rs

@@ -276,7 +276,7 @@ impl<'a> Socket<'a> {
         ip_repr: &IpRepr,
         udp_repr: &UdpRepr,
         payload: &[u8],
-    ) -> Result<()> {
+    ) {
         debug_assert!(self.accepts(ip_repr, udp_repr));
 
         let size = payload.len();
@@ -288,20 +288,26 @@ impl<'a> Socket<'a> {
             udp_repr.dst_port
         );
 
-        let p = Packet::new_checked(payload)?;
+        let p = match Packet::new_checked(payload) {
+            Ok(x) => x,
+            Err(_) => {
+                net_trace!("dns packet malformed");
+                return;
+            }
+        };
         if p.opcode() != Opcode::Query {
             net_trace!("unwanted opcode {:?}", p.opcode());
-            return Err(Error::Malformed);
+            return;
         }
 
         if !p.flags().contains(Flags::RESPONSE) {
             net_trace!("packet doesn't have response bit set");
-            return Err(Error::Malformed);
+            return;
         }
 
         if p.question_count() != 1 {
             net_trace!("bad question count {:?}", p.question_count());
-            return Err(Error::Malformed);
+            return;
         }
 
         // Find pending query
@@ -318,27 +324,53 @@ impl<'a> Socket<'a> {
                 }
 
                 let payload = p.payload();
-                let (mut payload, question) = Question::parse(payload)?;
+                let (mut payload, question) = match Question::parse(payload) {
+                    Ok(x) => x,
+                    Err(_) => {
+                        net_trace!("question malformed");
+                        return;
+                    }
+                };
 
                 if question.type_ != pq.type_ {
                     net_trace!("question type mismatch");
-                    return Err(Error::Malformed);
+                    return;
                 }
 
-                if !eq_names(p.parse_name(question.name), p.parse_name(&pq.name))? {
-                    net_trace!("question name mismatch");
-                    return Err(Error::Malformed);
+                match eq_names(p.parse_name(question.name), p.parse_name(&pq.name)) {
+                    Ok(true) => {}
+                    Ok(false) => {
+                        net_trace!("question name mismatch");
+                        return;
+                    }
+                    Err(_) => {
+                        net_trace!("dns question name malformed");
+                        return;
+                    }
                 }
 
                 let mut addresses = Vec::new();
 
                 for _ in 0..p.answer_record_count() {
-                    let (payload2, r) = Record::parse(payload)?;
+                    let (payload2, r) = match Record::parse(payload) {
+                        Ok(x) => x,
+                        Err(_) => {
+                            net_trace!("dns answer record malformed");
+                            return;
+                        }
+                    };
                     payload = payload2;
 
-                    if !eq_names(p.parse_name(r.name), p.parse_name(&pq.name))? {
-                        net_trace!("answer name mismatch: {:?}", r);
-                        continue;
+                    match eq_names(p.parse_name(r.name), p.parse_name(&pq.name)) {
+                        Ok(true) => {}
+                        Ok(false) => {
+                            net_trace!("answer name mismatch: {:?}", r);
+                            continue;
+                        }
+                        Err(_) => {
+                            net_trace!("dns answer record name malformed");
+                            return;
+                        }
                     }
 
                     match r.data {
@@ -366,7 +398,10 @@ impl<'a> Socket<'a> {
                             // records for the CNAME when we parse them later.
                             // I believe it's mandatory the CNAME results MUST come *after* in the
                             // packet, so it's enough to do one linear pass over it.
-                            copy_name(&mut pq.name, p.parse_name(name))?;
+                            if copy_name(&mut pq.name, p.parse_name(name)).is_err() {
+                                net_trace!("dns answer cname malformed");
+                                return;
+                            }
                         }
                         RecordData::Other(type_, data) => {
                             net_trace!("unknown: {:?} {:?}", type_, data)
@@ -381,13 +416,12 @@ impl<'a> Socket<'a> {
                 });
 
                 // If we get here, packet matched the current query, stop processing.
-                return Ok(());
+                return;
             }
         }
 
         // If we get here, packet matched with no query.
         net_trace!("no query matched");
-        Ok(())
     }
 
     pub(crate) fn dispatch<F>(&mut self, cx: &mut Context, emit: F) -> Result<()>

+ 31 - 52
src/socket/icmp.rs

@@ -409,55 +409,46 @@ impl<'a> Socket<'a> {
         }
     }
 
-    pub(crate) fn process(
-        &mut self,
-        _cx: &mut Context,
-        ip_repr: &IpRepr,
-        icmp_repr: &IcmpRepr,
-    ) -> Result<(), Error> {
+    pub(crate) fn process(&mut self, _cx: &mut Context, ip_repr: &IpRepr, icmp_repr: &IcmpRepr) {
         match *icmp_repr {
             #[cfg(feature = "proto-ipv4")]
             IcmpRepr::Ipv4(ref icmp_repr) => {
-                let packet_buf = self
+                net_trace!("icmp: receiving {} octets", icmp_repr.buffer_len());
+
+                match self
                     .rx_buffer
                     .enqueue(icmp_repr.buffer_len(), ip_repr.src_addr())
-                    .map_err(|_| Error::Exhausted)?;
-                icmp_repr.emit(
-                    &mut Icmpv4Packet::new_unchecked(packet_buf),
-                    &ChecksumCapabilities::default(),
-                );
-
-                net_trace!(
-                    "icmp:{}: receiving {} octets",
-                    icmp_repr.buffer_len(),
-                    packet_buf.len()
-                );
+                {
+                    Ok(packet_buf) => {
+                        icmp_repr.emit(
+                            &mut Icmpv4Packet::new_unchecked(packet_buf),
+                            &ChecksumCapabilities::default(),
+                        );
+                    }
+                    Err(_) => net_trace!("icmp: buffer full, dropped incoming packet"),
+                }
             }
             #[cfg(feature = "proto-ipv6")]
             IcmpRepr::Ipv6(ref icmp_repr) => {
-                let packet_buf = self
+                net_trace!("icmp: receiving {} octets", icmp_repr.buffer_len());
+
+                match self
                     .rx_buffer
                     .enqueue(icmp_repr.buffer_len(), ip_repr.src_addr())
-                    .map_err(|_| Error::Exhausted)?;
-                icmp_repr.emit(
-                    &ip_repr.src_addr(),
-                    &ip_repr.dst_addr(),
-                    &mut Icmpv6Packet::new_unchecked(packet_buf),
-                    &ChecksumCapabilities::default(),
-                );
-
-                net_trace!(
-                    "icmp:{}: receiving {} octets",
-                    icmp_repr.buffer_len(),
-                    packet_buf.len()
-                );
+                {
+                    Ok(packet_buf) => icmp_repr.emit(
+                        &ip_repr.src_addr(),
+                        &ip_repr.dst_addr(),
+                        &mut Icmpv6Packet::new_unchecked(packet_buf),
+                        &ChecksumCapabilities::default(),
+                    ),
+                    Err(_) => net_trace!("icmp: buffer full, dropped incoming packet"),
+                }
             }
         }
 
         #[cfg(feature = "async")]
         self.rx_waker.wake();
-
-        Ok(())
     }
 
     pub(crate) fn dispatch<F>(&mut self, cx: &mut Context, emit: F) -> Result<(), Error>
@@ -709,17 +700,11 @@ mod test_ipv4 {
         let data = &packet.into_inner()[..];
 
         assert!(socket.accepts(&mut cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()));
-        assert_eq!(
-            socket.process(&mut cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()),
-            Ok(())
-        );
+        socket.process(&mut cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into());
         assert!(socket.can_recv());
 
         assert!(socket.accepts(&mut cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()));
-        assert_eq!(
-            socket.process(&mut cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into()),
-            Err(Error::Exhausted)
-        );
+        socket.process(&mut cx, &REMOTE_IPV4_REPR, &ECHOV4_REPR.into());
 
         assert_eq!(socket.recv(), Ok((data, REMOTE_IPV4.into())));
         assert!(!socket.can_recv());
@@ -791,7 +776,7 @@ mod test_ipv4 {
         // Ensure we can accept ICMP error response to the bound
         // UDP port
         assert!(socket.accepts(&mut cx, &ip_repr, &icmp_repr.into()));
-        assert_eq!(socket.process(&mut cx, &ip_repr, &icmp_repr.into()), Ok(()));
+        socket.process(&mut cx, &ip_repr, &icmp_repr.into());
         assert!(socket.can_recv());
 
         let mut bytes = [0x00; 46];
@@ -972,17 +957,11 @@ mod test_ipv6 {
         let data = &packet.into_inner()[..];
 
         assert!(socket.accepts(&mut cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()));
-        assert_eq!(
-            socket.process(&mut cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()),
-            Ok(())
-        );
+        socket.process(&mut cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into());
         assert!(socket.can_recv());
 
         assert!(socket.accepts(&mut cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()));
-        assert_eq!(
-            socket.process(&mut cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into()),
-            Err(Error::Exhausted)
-        );
+        socket.process(&mut cx, &REMOTE_IPV6_REPR, &ECHOV6_REPR.into());
 
         assert_eq!(socket.recv(), Ok((data, REMOTE_IPV6.into())));
         assert!(!socket.can_recv());
@@ -1059,7 +1038,7 @@ mod test_ipv6 {
         // Ensure we can accept ICMP error response to the bound
         // UDP port
         assert!(socket.accepts(&mut cx, &ip_repr, &icmp_repr.into()));
-        assert_eq!(socket.process(&mut cx, &ip_repr, &icmp_repr.into()), Ok(()));
+        socket.process(&mut cx, &ip_repr, &icmp_repr.into());
         assert!(socket.can_recv());
 
         let mut bytes = [0x00; 66];

+ 32 - 48
src/socket/raw.rs

@@ -236,34 +236,33 @@ impl<'a> Socket<'a> {
         true
     }
 
-    pub(crate) fn process(
-        &mut self,
-        cx: &mut Context,
-        ip_repr: &IpRepr,
-        payload: &[u8],
-    ) -> Result<(), Error> {
+    pub(crate) fn process(&mut self, cx: &mut Context, ip_repr: &IpRepr, payload: &[u8]) {
         debug_assert!(self.accepts(ip_repr));
 
         let header_len = ip_repr.buffer_len();
         let total_len = header_len + payload.len();
-        let packet_buf = self
-            .rx_buffer
-            .enqueue(total_len, ())
-            .map_err(|_| Error::Exhausted)?;
-        ip_repr.emit(&mut packet_buf[..header_len], &cx.checksum_caps());
-        packet_buf[header_len..].copy_from_slice(payload);
 
         net_trace!(
             "raw:{}:{}: receiving {} octets",
             self.ip_version,
             self.ip_protocol,
-            packet_buf.len()
+            total_len
         );
 
+        match self.rx_buffer.enqueue(total_len, ()) {
+            Ok(buf) => {
+                ip_repr.emit(&mut buf[..header_len], &cx.checksum_caps());
+                buf[header_len..].copy_from_slice(payload);
+            }
+            Err(_) => net_trace!(
+                "raw:{}:{}: buffer full, dropped incoming packet",
+                self.ip_version,
+                self.ip_protocol
+            ),
+        }
+
         #[cfg(feature = "async")]
         self.rx_waker.wake();
-
-        Ok(())
     }
 
     pub(crate) fn dispatch<F>(&mut self, cx: &mut Context, emit: F) -> Result<(), Error>
@@ -488,7 +487,7 @@ mod test {
                     let mut cx = Context::mock();
 
                     assert!(socket.accepts(&$hdr));
-                    assert_eq!(socket.process(&mut cx, &$hdr, &$payload), Ok(()));
+                    socket.process(&mut cx, &$hdr, &$payload);
 
                     let mut slice = [0; 4];
                     assert_eq!(socket.recv_slice(&mut slice[..]), Ok(4));
@@ -504,10 +503,7 @@ mod test {
                     buffer[..$packet.len()].copy_from_slice(&$packet[..]);
 
                     assert!(socket.accepts(&$hdr));
-                    assert_eq!(
-                        socket.process(&mut cx, &$hdr, &buffer),
-                        Err(Error::Exhausted)
-                    );
+                    socket.process(&mut cx, &$hdr, &buffer);
                 }
             }
         };
@@ -583,24 +579,18 @@ mod test {
 
             assert_eq!(socket.recv(), Err(RecvError::Exhausted));
             assert!(socket.accepts(&ipv4_locals::HEADER_REPR));
-            assert_eq!(
-                socket.process(
-                    &mut cx,
-                    &ipv4_locals::HEADER_REPR,
-                    &ipv4_locals::PACKET_PAYLOAD
-                ),
-                Ok(())
+            socket.process(
+                &mut cx,
+                &ipv4_locals::HEADER_REPR,
+                &ipv4_locals::PACKET_PAYLOAD,
             );
             assert!(socket.can_recv());
 
             assert!(socket.accepts(&ipv4_locals::HEADER_REPR));
-            assert_eq!(
-                socket.process(
-                    &mut cx,
-                    &ipv4_locals::HEADER_REPR,
-                    &ipv4_locals::PACKET_PAYLOAD
-                ),
-                Err(Error::Exhausted)
+            socket.process(
+                &mut cx,
+                &ipv4_locals::HEADER_REPR,
+                &ipv4_locals::PACKET_PAYLOAD,
             );
             assert_eq!(socket.recv(), Ok(&cksumd_packet[..]));
             assert!(!socket.can_recv());
@@ -613,24 +603,18 @@ mod test {
 
             assert_eq!(socket.recv(), Err(RecvError::Exhausted));
             assert!(socket.accepts(&ipv6_locals::HEADER_REPR));
-            assert_eq!(
-                socket.process(
-                    &mut cx,
-                    &ipv6_locals::HEADER_REPR,
-                    &ipv6_locals::PACKET_PAYLOAD
-                ),
-                Ok(())
+            socket.process(
+                &mut cx,
+                &ipv6_locals::HEADER_REPR,
+                &ipv6_locals::PACKET_PAYLOAD,
             );
             assert!(socket.can_recv());
 
             assert!(socket.accepts(&ipv6_locals::HEADER_REPR));
-            assert_eq!(
-                socket.process(
-                    &mut cx,
-                    &ipv6_locals::HEADER_REPR,
-                    &ipv6_locals::PACKET_PAYLOAD
-                ),
-                Err(Error::Exhausted)
+            socket.process(
+                &mut cx,
+                &ipv6_locals::HEADER_REPR,
+                &ipv6_locals::PACKET_PAYLOAD,
             );
             assert_eq!(socket.recv(), Ok(&ipv6_locals::PACKET_BYTES[..]));
             assert!(!socket.can_recv());

+ 81 - 88
src/socket/tcp.rs

@@ -1293,7 +1293,7 @@ impl<'a> Socket<'a> {
         cx: &mut Context,
         ip_repr: &IpRepr,
         repr: &TcpRepr,
-    ) -> Result<Option<(IpRepr, TcpRepr<'static>)>, Error> {
+    ) -> Option<(IpRepr, TcpRepr<'static>)> {
         debug_assert!(self.accepts(cx, ip_repr, repr));
 
         // Consider how much the sequence number space differs from the transmit buffer space.
@@ -1314,12 +1314,12 @@ impl<'a> Socket<'a> {
             // the initial SYN.
             (State::SynSent, TcpControl::Rst, None) => {
                 net_debug!("unacceptable RST (expecting RST|ACK) in response to initial SYN");
-                return Err(Error::Dropped);
+                return None;
             }
             (State::SynSent, TcpControl::Rst, Some(ack_number)) => {
                 if ack_number != self.local_seq_no + 1 {
                     net_debug!("unacceptable RST|ACK in response to initial SYN");
-                    return Err(Error::Dropped);
+                    return None;
                 }
             }
             // Any other RST need only have a valid sequence number.
@@ -1331,13 +1331,13 @@ impl<'a> Socket<'a> {
             // Every packet after the initial SYN must be an acknowledgement.
             (_, _, None) => {
                 net_debug!("expecting an ACK");
-                return Err(Error::Dropped);
+                return None;
             }
             // SYN|ACK in the SYN-SENT state must have the exact ACK number.
             (State::SynSent, TcpControl::Syn, Some(ack_number)) => {
                 if ack_number != self.local_seq_no + 1 {
                     net_debug!("unacceptable SYN|ACK in response to initial SYN");
-                    return Ok(Some(Self::rst_reply(ip_repr, repr)));
+                    return Some(Self::rst_reply(ip_repr, repr));
                 }
             }
             // ACKs in the SYN-SENT state are invalid.
@@ -1350,24 +1350,24 @@ impl<'a> Socket<'a> {
                     net_debug!(
                         "expecting a SYN|ACK, received an ACK with the right ack_number, ignoring."
                     );
-                    return Err(Error::Dropped);
+                    return None;
                 }
 
                 net_debug!(
                     "expecting a SYN|ACK, received an ACK with the wrong ack_number, sending RST."
                 );
-                return Ok(Some(Self::rst_reply(ip_repr, repr)));
+                return Some(Self::rst_reply(ip_repr, repr));
             }
             // Anything else in the SYN-SENT state is invalid.
             (State::SynSent, _, _) => {
                 net_debug!("expecting a SYN|ACK");
-                return Err(Error::Dropped);
+                return None;
             }
             // ACK in the SYN-RECEIVED state must have the exact ACK number, or we RST it.
             (State::SynReceived, _, Some(ack_number)) => {
                 if ack_number != self.local_seq_no + 1 {
                     net_debug!("unacceptable ACK in response to SYN|ACK");
-                    return Ok(Some(Self::rst_reply(ip_repr, repr)));
+                    return Some(Self::rst_reply(ip_repr, repr));
                 }
             }
             // Every acknowledgement must be for transmitted but unacknowledged data.
@@ -1390,7 +1390,7 @@ impl<'a> Socket<'a> {
                         ack_min,
                         ack_max
                     );
-                    return Err(Error::Dropped);
+                    return None;
                 }
 
                 if ack_number > ack_max {
@@ -1400,7 +1400,7 @@ impl<'a> Socket<'a> {
                         ack_min,
                         ack_max
                     );
-                    return Ok(self.challenge_ack_reply(cx, ip_repr, repr));
+                    return self.challenge_ack_reply(cx, ip_repr, repr);
                 }
             }
         }
@@ -1452,7 +1452,7 @@ impl<'a> Socket<'a> {
                         self.timer.set_for_close(cx.now());
                     }
 
-                    return Ok(self.challenge_ack_reply(cx, ip_repr, repr));
+                    return self.challenge_ack_reply(cx, ip_repr, repr);
                 }
             }
         }
@@ -1497,14 +1497,14 @@ impl<'a> Socket<'a> {
         // Validate and update the state.
         match (self.state, control) {
             // RSTs are not accepted in the LISTEN state.
-            (State::Listen, TcpControl::Rst) => return Err(Error::Dropped),
+            (State::Listen, TcpControl::Rst) => return None,
 
             // RSTs in SYN-RECEIVED flip the socket back to the LISTEN state.
             (State::SynReceived, TcpControl::Rst) => {
                 tcp_trace!("received RST");
                 self.tuple = None;
                 self.set_state(State::Listen);
-                return Ok(None);
+                return None;
             }
 
             // RSTs in any other state close the socket.
@@ -1512,7 +1512,7 @@ impl<'a> Socket<'a> {
                 tcp_trace!("received RST");
                 self.set_state(State::Closed);
                 self.tuple = None;
-                return Ok(None);
+                return None;
             }
 
             // SYN packets in the LISTEN state change it to SYN-RECEIVED.
@@ -1521,7 +1521,7 @@ impl<'a> Socket<'a> {
                 if let Some(max_seg_size) = repr.max_seg_size {
                     if max_seg_size == 0 {
                         tcp_trace!("received SYNACK with zero MSS, ignoring");
-                        return Ok(None);
+                        return None;
                     }
                     self.remote_mss = max_seg_size as usize
                 }
@@ -1565,7 +1565,7 @@ impl<'a> Socket<'a> {
                 if let Some(max_seg_size) = repr.max_seg_size {
                     if max_seg_size == 0 {
                         tcp_trace!("received SYNACK with zero MSS, ignoring");
-                        return Ok(None);
+                        return None;
                     }
                     self.remote_mss = max_seg_size as usize;
                 }
@@ -1663,7 +1663,7 @@ impl<'a> Socket<'a> {
 
             _ => {
                 net_debug!("unexpected packet {}", repr);
-                return Err(Error::Dropped);
+                return None;
             }
         }
 
@@ -1753,7 +1753,7 @@ impl<'a> Socket<'a> {
 
         let payload_len = repr.payload.len();
         if payload_len == 0 {
-            return Ok(None);
+            return None;
         }
 
         let assembler_was_empty = self.assembler.is_empty();
@@ -1779,7 +1779,7 @@ impl<'a> Socket<'a> {
                     payload_len,
                     payload_offset
                 );
-                return Err(Error::Dropped);
+                return None;
             }
         }
 
@@ -1835,9 +1835,9 @@ impl<'a> Socket<'a> {
             // This is fine because smoltcp assumes that it can always transmit zero or one
             // packets for every packet it receives.
             tcp_trace!("ACKing incoming segment");
-            Ok(Some(self.ack_reply(ip_repr, repr)))
+            Some(self.ack_reply(ip_repr, repr))
         } else {
-            Ok(None)
+            None
         }
     }
 
@@ -2396,7 +2396,7 @@ mod test {
         socket: &mut TestSocket,
         timestamp: Instant,
         repr: &TcpRepr,
-    ) -> Result<Option<TcpRepr<'static>>, Error> {
+    ) -> Option<TcpRepr<'static>> {
         socket.cx.set_now(timestamp);
 
         let ip_repr = IpReprIpvX(IpvXRepr {
@@ -2411,12 +2411,11 @@ mod test {
         assert!(socket.socket.accepts(&mut socket.cx, &ip_repr, repr));
 
         match socket.socket.process(&mut socket.cx, &ip_repr, repr) {
-            Ok(Some((_ip_repr, repr))) => {
+            Some((_ip_repr, repr)) => {
                 net_trace!("recv: {}", repr);
-                Ok(Some(repr))
+                Some(repr)
             }
-            Ok(None) => Ok(None),
-            Err(err) => Err(err),
+            None => None,
         }
     }
 
@@ -2449,7 +2448,7 @@ mod test {
         ($socket:ident, $repr:expr, $result:expr) =>
             (send!($socket, time 0, $repr, $result));
         ($socket:ident, time $time:expr, $repr:expr) =>
-            (send!($socket, time $time, $repr, Ok(None)));
+            (send!($socket, time $time, $repr, None));
         ($socket:ident, time $time:expr, $repr:expr, $result:expr) =>
             (assert_eq!(send(&mut $socket, Instant::from_millis($time), &$repr), $result));
     }
@@ -2817,9 +2816,9 @@ mod test {
                 seq_number: REMOTE_SEQ,
                 ack_number: None,
                 ..SEND_TEMPL
-            },
-            Err(Error::Dropped)
+            }
         );
+        assert_eq!(s.state, State::Listen);
     }
 
     #[test]
@@ -2878,13 +2877,13 @@ mod test {
                 ack_number: Some(LOCAL_SEQ), // wrong
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 control: TcpControl::Rst,
                 seq_number: LOCAL_SEQ,
                 ack_number: None,
                 window_len: 0,
                 ..RECV_TEMPL
-            }))
+            })
         );
         assert_eq!(s.state, State::SynReceived);
     }
@@ -2909,13 +2908,13 @@ mod test {
                 ack_number: Some(LOCAL_SEQ + 2), // wrong
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 control: TcpControl::Rst,
                 seq_number: LOCAL_SEQ + 2,
                 ack_number: None,
                 window_len: 0,
                 ..RECV_TEMPL
-            }))
+            })
         );
         assert_eq!(s.state, State::SynReceived);
     }
@@ -3232,13 +3231,13 @@ mod test {
                 window_scale: Some(0),
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 control: TcpControl::Rst,
                 seq_number: LOCAL_SEQ,
                 ack_number: None,
                 window_len: 0,
                 ..RECV_TEMPL
-            }))
+            })
         );
         assert_eq!(s.state, State::SynSent);
     }
@@ -3268,8 +3267,7 @@ mod test {
                 seq_number: REMOTE_SEQ,
                 ack_number: None,
                 ..SEND_TEMPL
-            },
-            Err(Error::Dropped)
+            }
         );
         assert_eq!(s.state, State::SynSent);
     }
@@ -3284,8 +3282,7 @@ mod test {
                 seq_number: REMOTE_SEQ,
                 ack_number: Some(TcpSeqNumber(1234)),
                 ..SEND_TEMPL
-            },
-            Err(Error::Dropped)
+            }
         );
         assert_eq!(s.state, State::SynSent);
     }
@@ -3312,8 +3309,7 @@ mod test {
                 seq_number: REMOTE_SEQ,
                 ack_number: Some(LOCAL_SEQ + 1), // Correct
                 ..SEND_TEMPL
-            },
-            Err(Error::Dropped)
+            }
         );
 
         // It should trigger no response and change no state
@@ -3344,13 +3340,13 @@ mod test {
                 ack_number: Some(LOCAL_SEQ), // WRONG
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 control: TcpControl::Rst,
                 seq_number: LOCAL_SEQ, // matching the ack_number of the unexpected ack
                 ack_number: None,
                 window_len: 0,
                 ..RECV_TEMPL
-            }))
+            })
         );
 
         // It should trigger a RST, and change no state
@@ -3380,13 +3376,13 @@ mod test {
                 ack_number: Some(LOCAL_SEQ + 123456), // WRONG
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 control: TcpControl::Rst,
                 seq_number: LOCAL_SEQ + 123456, // matching the ack_number of the unexpected ack
                 ack_number: None,
                 window_len: 0,
                 ..RECV_TEMPL
-            }))
+            })
         );
 
         // It should trigger a RST, and change no state
@@ -3614,7 +3610,7 @@ mod test {
                     payload: &segment,
                     ..SEND_TEMPL
                 },
-                Ok(Some(TcpRepr {
+                Some(TcpRepr {
                     seq_number: LOCAL_SEQ + 1,
                     ack_number: Some(REMOTE_SEQ + 1 + 5000),
                     window_len: 4000,
@@ -3627,7 +3623,7 @@ mod test {
                         None
                     ],
                     ..RECV_TEMPL
-                }))
+                })
             );
         }
     }
@@ -3846,8 +3842,7 @@ mod test {
                 seq_number: REMOTE_SEQ + 1,
                 ack_number: None,
                 ..SEND_TEMPL
-            },
-            Err(Error::Dropped)
+            }
         );
     }
 
@@ -3861,8 +3856,7 @@ mod test {
                 seq_number: REMOTE_SEQ + 1,
                 ack_number: Some(TcpSeqNumber(LOCAL_SEQ.0 - 1)),
                 ..SEND_TEMPL
-            },
-            Err(Error::Dropped)
+            }
         );
         assert_eq!(s.local_seq_no, LOCAL_SEQ + 1);
         // Data not yet transmitted.
@@ -3873,11 +3867,11 @@ mod test {
                 ack_number: Some(LOCAL_SEQ + 10),
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1),
                 ..RECV_TEMPL
-            }))
+            })
         );
         assert_eq!(s.local_seq_no, LOCAL_SEQ + 1);
     }
@@ -3893,11 +3887,11 @@ mod test {
                 ack_number: Some(LOCAL_SEQ + 1),
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1),
                 ..RECV_TEMPL
-            }))
+            })
         );
         assert_eq!(s.remote_seq_no, REMOTE_SEQ + 1);
 
@@ -3909,8 +3903,7 @@ mod test {
                 seq_number: REMOTE_SEQ + 1 + 256,
                 ack_number: Some(LOCAL_SEQ + 1),
                 ..SEND_TEMPL
-            },
-            Ok(None)
+            }
         );
 
         // If we wait a bit, we do get a new one.
@@ -3922,11 +3915,11 @@ mod test {
                 ack_number: Some(LOCAL_SEQ + 1),
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1),
                 ..RECV_TEMPL
-            }))
+            })
         );
         assert_eq!(s.remote_seq_no, REMOTE_SEQ + 1);
     }
@@ -3967,11 +3960,11 @@ mod test {
                 payload: &b"123456"[..],
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1),
                 ..RECV_TEMPL
-            }))
+            })
         );
         assert_eq!(s.state, State::Established);
         send!(
@@ -3982,12 +3975,12 @@ mod test {
                 payload: &b"abcdef"[..],
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1 + 6 + 6),
                 window_len: 52,
                 ..RECV_TEMPL
-            }))
+            })
         );
         assert_eq!(s.state, State::Established);
     }
@@ -4082,11 +4075,11 @@ mod test {
                 ack_number: None,
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1),
                 ..RECV_TEMPL
-            }))
+            })
         );
 
         assert_eq!(s.state, State::Established);
@@ -4114,12 +4107,12 @@ mod test {
                 ack_number: None,
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 2), // this has changed
                 window_len: 63,
                 ..RECV_TEMPL
-            }))
+            })
         );
     }
 
@@ -4358,11 +4351,11 @@ mod test {
             seq_number: REMOTE_SEQ + 1,
             ack_number: Some(LOCAL_SEQ + 1 + 1),
             ..SEND_TEMPL
-        }, Ok(Some(TcpRepr {
+        }, Some(TcpRepr {
             seq_number: LOCAL_SEQ + 1 + 1,
             ack_number: Some(REMOTE_SEQ + 1 + 1),
             ..RECV_TEMPL
-        })));
+        }));
         assert_eq!(
             s.timer,
             Timer::Close {
@@ -4898,12 +4891,12 @@ mod test {
                 payload: &b"abcdef"[..],
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1 + 6),
                 window_len: 58,
                 ..RECV_TEMPL
-            }))
+            })
         );
     }
 
@@ -5740,12 +5733,12 @@ mod test {
                 payload: &b"123456"[..],
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1 + 6),
                 window_len: 0,
                 ..RECV_TEMPL
-            }))
+            })
         );
     }
 
@@ -5874,12 +5867,12 @@ mod test {
                 payload: &b"def"[..],
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1 + 3),
                 window_len: 6,
                 ..RECV_TEMPL
-            }))
+            })
         );
         send!(
             s,
@@ -5889,12 +5882,12 @@ mod test {
                 payload: &b"abc"[..],
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1 + 9),
                 window_len: 0,
                 ..RECV_TEMPL
-            }))
+            })
         );
         assert_eq!(s.remote_last_win, s.rx_buffer.window() as u16);
         s.recv(|buffer| (buffer.len(), ())).unwrap();
@@ -6099,11 +6092,11 @@ mod test {
                 ack_number: Some(LOCAL_SEQ + 1),
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1),
                 ..RECV_TEMPL
-            }))
+            })
         );
     }
 
@@ -6208,11 +6201,11 @@ mod test {
                 payload: &b"def"[..],
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1),
                 ..RECV_TEMPL
-            }))
+            })
         );
         s.recv(|buffer| {
             assert_eq!(buffer, b"");
@@ -6227,12 +6220,12 @@ mod test {
                 payload: &b"abcdef"[..],
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1 + 6),
                 window_len: 58,
                 ..RECV_TEMPL
-            }))
+            })
         );
         s.recv(|buffer| {
             assert_eq!(buffer, b"abcdef");
@@ -6396,12 +6389,12 @@ mod test {
                 payload: &b"ghi"[..],
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1 + 3),
                 window_len: 61,
                 ..RECV_TEMPL
-            }))
+            })
         );
         s.recv(|data| {
             assert_eq!(data, b"abc");
@@ -6476,12 +6469,12 @@ mod test {
                 payload: &b"ghi"[..],
                 ..SEND_TEMPL
             },
-            Ok(Some(TcpRepr {
+            Some(TcpRepr {
                 seq_number: LOCAL_SEQ + 1,
                 ack_number: Some(REMOTE_SEQ + 1 + 3),
                 window_len: 61,
                 ..RECV_TEMPL
-            }))
+            })
         );
         send!(
             s,

+ 17 - 28
src/socket/udp.rs

@@ -353,7 +353,7 @@ impl<'a> Socket<'a> {
         ip_repr: &IpRepr,
         repr: &UdpRepr,
         payload: &[u8],
-    ) -> Result<(), Error> {
+    ) {
         debug_assert!(self.accepts(cx, ip_repr, repr));
 
         let size = payload.len();
@@ -362,10 +362,6 @@ impl<'a> Socket<'a> {
             addr: ip_repr.src_addr(),
             port: repr.src_port,
         };
-        self.rx_buffer
-            .enqueue(size, remote_endpoint)
-            .map_err(|_| Error::Exhausted)?
-            .copy_from_slice(payload);
 
         net_trace!(
             "udp:{}:{}: receiving {} octets",
@@ -374,10 +370,17 @@ impl<'a> Socket<'a> {
             size
         );
 
+        match self.rx_buffer.enqueue(size, remote_endpoint) {
+            Ok(buf) => buf.copy_from_slice(payload),
+            Err(_) => net_trace!(
+                "udp:{}:{}: buffer full, dropped incoming packet",
+                self.endpoint,
+                remote_endpoint
+            ),
+        }
+
         #[cfg(feature = "async")]
         self.rx_waker.wake();
-
-        Ok(())
     }
 
     pub(crate) fn dispatch<F>(&mut self, cx: &mut Context, emit: F) -> Result<(), Error>
@@ -630,17 +633,12 @@ mod test {
         assert_eq!(socket.recv(), Err(RecvError::Exhausted));
 
         assert!(socket.accepts(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR));
-        assert_eq!(
-            socket.process(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR, PAYLOAD),
-            Ok(())
-        );
+        socket.process(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR, PAYLOAD);
         assert!(socket.can_recv());
 
         assert!(socket.accepts(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR));
-        assert_eq!(
-            socket.process(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR, PAYLOAD),
-            Err(Error::Exhausted)
-        );
+        socket.process(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR, PAYLOAD);
+
         assert_eq!(socket.recv(), Ok((&b"abcdef"[..], REMOTE_END)));
         assert!(!socket.can_recv());
     }
@@ -654,10 +652,7 @@ mod test {
 
         assert_eq!(socket.peek(), Err(RecvError::Exhausted));
 
-        assert_eq!(
-            socket.process(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR, PAYLOAD),
-            Ok(())
-        );
+        socket.process(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR, PAYLOAD);
         assert_eq!(socket.peek(), Ok((&b"abcdef"[..], &REMOTE_END)));
         assert_eq!(socket.recv(), Ok((&b"abcdef"[..], REMOTE_END)));
         assert_eq!(socket.peek(), Err(RecvError::Exhausted));
@@ -671,10 +666,7 @@ mod test {
         assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
 
         assert!(socket.accepts(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR));
-        assert_eq!(
-            socket.process(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR, PAYLOAD),
-            Ok(())
-        );
+        socket.process(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR, PAYLOAD);
 
         let mut slice = [0; 4];
         assert_eq!(socket.recv_slice(&mut slice[..]), Ok((4, REMOTE_END)));
@@ -688,10 +680,7 @@ mod test {
 
         assert_eq!(socket.bind(LOCAL_PORT), Ok(()));
 
-        assert_eq!(
-            socket.process(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR, PAYLOAD),
-            Ok(())
-        );
+        socket.process(&mut cx, &REMOTE_IP_REPR, &REMOTE_UDP_REPR, PAYLOAD);
 
         let mut slice = [0; 4];
         assert_eq!(socket.peek_slice(&mut slice[..]), Ok((4, &REMOTE_END)));
@@ -780,7 +769,7 @@ mod test {
             src_port: REMOTE_PORT,
             dst_port: LOCAL_PORT,
         };
-        assert_eq!(socket.process(&mut cx, &REMOTE_IP_REPR, &repr, &[]), Ok(()));
+        socket.process(&mut cx, &REMOTE_IP_REPR, &repr, &[]);
         assert_eq!(socket.recv(), Ok((&[][..], REMOTE_END)));
     }