Pārlūkot izejas kodu

Fix omission of udp checksum

Allow the control flow to continue when udp parsing encounters an
invalid checksum within an ipv4 packet, instead of returning with an
error. Additionally adds a test to ensure the correct behaviour.

Closes: #280

Closes: #290
Approved by: whitequark
Andreas Molzer 6 gadi atpakaļ
vecāks
revīzija
3fec67519b
1 mainītis faili ar 17 papildinājumiem un 4 dzēšanām
  1. 17 4
      src/wire/udp.rs

+ 17 - 4
src/wire/udp.rs

@@ -214,12 +214,10 @@ impl<'a> Repr<'a> {
         // Valid checksum is expected...
         if checksum_caps.udp.rx() && !packet.verify_checksum(src_addr, dst_addr) {
             match (src_addr, dst_addr) {
+                // ... except on UDP-over-IPv4, where it can be omitted.
                 #[cfg(feature = "proto-ipv4")]
                 (&IpAddress::Ipv4(_), &IpAddress::Ipv4(_))
-                        if packet.checksum() != 0 => {
-                    // ... except on UDP-over-IPv4, where it can be omitted.
-                    return Err(Error::Checksum)
-                },
+                    if packet.checksum() == 0 => (),
                 _ => {
                     return Err(Error::Checksum)
                 }
@@ -303,6 +301,12 @@ mod test {
          0x00, 0x0c, 0x12, 0x4d,
          0xaa, 0x00, 0x00, 0xff];
 
+    #[cfg(feature = "proto-ipv4")]
+    static NO_CHECKSUM_PACKET: [u8; 12] =
+        [0xbf, 0x00, 0x00, 0x35,
+         0x00, 0x0c, 0x00, 0x00,
+         0xaa, 0x00, 0x00, 0xff];
+
     #[cfg(feature = "proto-ipv4")]
     static PAYLOAD_BYTES: [u8; 4] =
         [0xaa, 0x00, 0x00, 0xff];
@@ -381,4 +385,13 @@ mod test {
                   &ChecksumCapabilities::default());
         assert_eq!(&packet.into_inner()[..], &PACKET_BYTES[..]);
     }
+
+    #[test]
+    #[cfg(feature = "proto-ipv4")]
+    fn test_checksum_omitted() {
+        let packet = Packet::new_unchecked(&NO_CHECKSUM_PACKET[..]);
+        let repr = Repr::parse(&packet, &SRC_ADDR.into(), &DST_ADDR.into(),
+                               &ChecksumCapabilities::default()).unwrap();
+        assert_eq!(repr, packet_repr());
+    }
 }