tokio_fast_udp/ecn.rs
1/// Explicit Congestion Notification codepoint.
2///
3/// Represents the 2-bit ECN field in the IP header (ToS for IPv4, Traffic
4/// Class for IPv6).
5///
6/// See [RFC 9331](https://datatracker.ietf.org/doc/rfc9331/) for the use of
7/// ECN with QUIC and [RFC 3168](https://datatracker.ietf.org/doc/rfc3168/)
8/// for the original specification.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub enum Ecn {
11 /// Not ECN-Capable Transport — routers may drop the packet on congestion.
12 NotEct,
13 /// ECN-Capable Transport, codepoint 1.
14 Ect1,
15 /// ECN-Capable Transport, codepoint 0.
16 Ect0,
17 /// Congestion Experienced — set by a router on an ECT-marked packet.
18 Ce,
19}
20
21impl Ecn {
22 /// Encode the ECN codepoint as the low 2 bits of a TOS/Traffic Class byte.
23 pub fn to_tos_bits(self) -> u8 {
24 match self {
25 Ecn::NotEct => 0b00,
26 Ecn::Ect1 => 0b01,
27 Ecn::Ect0 => 0b10,
28 Ecn::Ce => 0b11,
29 }
30 }
31
32 /// Decode the ECN codepoint from the low 2 bits of a TOS/Traffic Class byte.
33 pub fn from_tos_bits(tos: u8) -> Self {
34 match tos & 0b11 {
35 0b00 => Ecn::NotEct,
36 0b01 => Ecn::Ect1,
37 0b10 => Ecn::Ect0,
38 _ => Ecn::Ce,
39 }
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn test_round_trip() {
49 for ecn in [Ecn::NotEct, Ecn::Ect1, Ecn::Ect0, Ecn::Ce] {
50 assert_eq!(Ecn::from_tos_bits(ecn.to_tos_bits()), ecn);
51 }
52 }
53
54 #[test]
55 fn test_masks_high_bits() {
56 assert_eq!(Ecn::from_tos_bits(0b1010), Ecn::Ect0);
57 assert_eq!(Ecn::from_tos_bits(0b1111), Ecn::Ce);
58 }
59}