Transmit actual UDP checksum of all-zeroes as all-ones instead.

v0.7.x
whitequark 2017-06-26 16:57:21 +00:00
parent cbf6e5cdbc
commit 6cd8cb4422
1 changed files with 16 additions and 1 deletions

View File

@ -173,7 +173,11 @@ impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T> {
checksum::data(&data[..self.len() as usize])
])
};
self.set_checksum(checksum)
// UDP checksum value of 0 means no checksum; if the checksum really is zero,
// use all-ones, which indicates that the remote end must verify the checksum.
// Arithmetically, RFC 1071 checksums of all-zeroes and all-ones behave identically,
// so no action is necessary on the remote end.
self.set_checksum(if checksum == 0 { 0xffff } else { checksum })
}
}
@ -317,6 +321,17 @@ mod test {
assert_eq!(packet.check_len(), Err(Error::Malformed));
}
#[test]
fn test_zero_checksum() {
let mut bytes = vec![0; 8];
let mut packet = Packet::new(&mut bytes);
packet.set_src_port(1);
packet.set_dst_port(31881);
packet.set_len(8);
packet.fill_checksum(&SRC_ADDR.into(), &DST_ADDR.into());
assert_eq!(packet.checksum(), 0xffff);
}
fn packet_repr() -> Repr<'static> {
Repr {
src_port: 48896,