Procházet zdrojové kódy

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 před 6 roky
rodič
revize
3fec67519b
1 změnil soubory, kde provedl 17 přidání a 4 odebrání
  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());
+    }
 }