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::HandshakeDone {}
74impl Probing for crate::frame::MaxData {}
75impl Probing for crate::frame::MaxStreamData {}
76impl Probing for crate::frame::MaxStreams {}
77impl Probing for crate::frame::NewConnectionId<'_> {
78    #[inline]
79    fn path_validation(&self) -> Probe {
80        Probe::Probing
81    }
82}
83impl Probing for crate::frame::NewToken<'_> {}
84impl Probing for crate::frame::Padding {
85    #[inline]
86    fn path_validation(&self) -> Probe {
87        Probe::Probing
88    }
89}
90impl Probing for crate::frame::PathChallenge<'_> {
91    #[inline]
92    fn path_validation(&self) -> Probe {
93        Probe::Probing
94    }
95}
96impl Probing for crate::frame::PathResponse<'_> {
97    #[inline]
98    fn path_validation(&self) -> Probe {
99        Probe::Probing
100    }
101}
102impl Probing for crate::frame::Ping {}
103impl Probing for crate::frame::ResetStream {}
104impl Probing for crate::frame::RetireConnectionId {}
105impl Probing for crate::frame::StopSending {}
106impl<Data> Probing for crate::frame::Stream<Data> {}
107impl Probing for crate::frame::StreamDataBlocked {}
108impl Probing for crate::frame::StreamsBlocked {}
109
110//= https://www.rfc-editor.org/rfc/rfc9000#section-9.1
111//= type=test
112//# A packet containing only probing frames is a "probing packet", and a
113//# packet containing any other frame is a "non-probing packet".
114#[cfg(test)]
115mod test {
116    use super::*;
117
118    #[test]
119    fn probing_packet_test() {
120        let mut probe = Probe::Probing;
121        probe |= Probe::Probing;
122
123        assert!(probe.is_probing())
124    }
125
126    #[test]
127    fn probing_and_non_probing_packet_test() {
128        let mut probe = Probe::Probing;
129        probe |= Probe::NonProbing;
130
131        assert!(!probe.is_probing())
132    }
133}