Transmit actual UDP checksum of all-zeroes as all-ones instead.
parent
cbf6e5cdbc
commit
6cd8cb4422
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue