s2n_quic_core/frame/
path_validation.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use core::ops::{BitOr, BitOrAssign};
5
6#[cfg(any(test, feature = "generator"))]
7use bolero_generator::prelude::*;
8
9/// Describes if a frame is probing
10#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
11#[cfg_attr(any(feature = "generator", test), derive(TypeGenerator))]
12pub enum Probe {
13    NonProbing,
14    Probing,
15}
16
17impl Probe {
18    /// Returns true if the `Probe` is set to `Probing`
19    pub fn is_probing(self) -> bool {
20        matches!(self, Self::Probing)
21    }
22}
23
24impl Default for Probe {
25    /// A packet is Probing only if all frames within the packet are
26    /// also Probing.
27    ///
28    /// This coupled with the Bit-Or logic makes `Probing` a good default:
29    /// Probing | Probing = Probing
30    /// Probing | NonProbing = NonProbing
31    fn default() -> Self {
32        Self::Probing
33    }
34}
35
36//= https://www.rfc-editor.org/rfc/rfc9000#section-9.1
37//# A packet containing only probing frames is a "probing packet", and a
38//# packet containing any other frame is a "non-probing packet".
39impl BitOr<Probe> for Probe {
40    type Output = Self;
41
42    fn bitor(self, rhs: Self) -> Self {
43        match (self, rhs) {
44            (Self::Probing, Self::Probing) => Self::Probing,
45            (_, _) => Self::NonProbing,
46        }
47    }
48}
49
50impl BitOrAssign<Probe> for Probe {
51    fn bitor_assign(&mut self, rhs: Self) {
52        *self = *self | rhs;
53    }
54}
55
56/// Trait to retrieve if a frame is probing
57pub trait Probing {
58    #[inline]
59    fn path_validation(&self) -> Probe {
60        Probe::NonProbing
61    }
62}
63
64//= https://www.rfc-editor.org/rfc/rfc9000#section-9.1
65//# PATH_CHALLENGE, PATH_RESPONSE, NEW_CONNECTION_ID, and PADDING frames
66//# are "probing frames", and all other frames are "non-probing frames".
67impl<AckRanges> Probing for crate::frame::Ack<AckRanges> {}
68impl Probing for crate::frame::ConnectionClose<'_> {}
69impl<Data> Probing for crate::frame::Crypto<Data> {}
70impl<Data> Probing for crate::frame::Datagram<Data> {}
71impl Probing for crate::frame::DataBlocked {}
72impl Probing for crate::frame::DcStatelessResetTokens<'_> {}
73impl Probing for crate::frame::MtuProbingComplete {}
74impl Probing for crate::frame::HandshakeDone {}
75impl Probing for crate::frame::MaxData {}
76impl Probing for crate::frame::MaxStreamData {}
77impl Probing for crate::frame::MaxStreams {}
78impl Probing for crate::frame::NewConnectionId<'_> {
79    #[inline]
80    fn path_validation(&self) -> Probe {
81        Probe::Probing
82    }
83}
84impl Probing for crate::frame::NewToken<'_> {}
85impl Probing for crate::frame::Padding {
86    #[inline]
87    fn path_validation(&self) -> Probe {
88        Probe::Probing
89    }
90}
91impl Probing for crate::frame::PathChallenge<'_> {
92    #[inline]
93    fn path_validation(&self) -> Probe {
94        Probe::Probing
95    }
96}
97impl Probing for crate::frame::PathResponse<'_> {
98    #[inline]
99    fn path_validation(&self) -> Probe {
100        Probe::Probing
101    }
102}
103impl Probing for crate::frame::Ping {}
104impl Probing for crate::frame::ResetStream {}
105impl Probing for crate::frame::RetireConnectionId {}
106impl Probing for crate::frame::StopSending {}
107impl<Data> Probing for crate::frame::Stream<Data> {}
108impl Probing for crate::frame::StreamDataBlocked {}
109impl Probing for crate::frame::StreamsBlocked {}
110
111//= https://www.rfc-editor.org/rfc/rfc9000#section-9.1
112//= type=test
113//# A packet containing only probing frames is a "probing packet", and a
114//# packet containing any other frame is a "non-probing packet".
115#[cfg(test)]
116mod test {
117    use super::*;
118
119    #[test]
120    fn probing_packet_test() {
121        let mut probe = Probe::Probing;
122        probe |= Probe::Probing;
123
124        assert!(probe.is_probing())
125    }
126
127    #[test]
128    fn probing_and_non_probing_packet_test() {
129        let mut probe = Probe::Probing;
130        probe |= Probe::NonProbing;
131
132        assert!(!probe.is_probing())
133    }
134}