1#![forbid(unsafe_code)]
5
6use crate::{
7 event,
8 frame::{ack_elicitation::AckElicitable, congestion_controlled::CongestionControlled},
9 varint::VarInt,
10};
11use core::fmt;
12use s2n_codec::{
13 DecoderBuffer, DecoderBufferMut, DecoderBufferMutResult, DecoderError,
14 DecoderParameterizedValueMut, DecoderValueMut, Encoder, EncoderValue,
15};
16
17pub mod ack_elicitation;
18pub mod congestion_controlled;
19pub mod path_validation;
20
21#[cfg(test)]
22mod tests;
23
24pub(crate) type Tag = u8;
30pub(crate) type ExtensionTag = VarInt;
31
32pub type FrameRef<'a> = Frame<'a, ack::AckRangesDecoder<'a>, DecoderBuffer<'a>>;
33pub type FrameMut<'a> = Frame<'a, ack::AckRangesDecoder<'a>, DecoderBufferMut<'a>>;
34
35pub trait FrameTrait: AckElicitable + CongestionControlled + path_validation::Probing {}
36
37impl<T: AckElicitable + CongestionControlled + path_validation::Probing> FrameTrait for T {}
39
40macro_rules! frames {
41 ($ack:ident, $data:ident | $($([$tag_macro:ident])? $(extension[$extension_tag_macro:ident])? => $module:ident, $handler:ident, $ty:ident $([$($generics:tt)+])?;)*) => {
42 $(
43 #[macro_use]
44 pub mod $module;
45 pub use $module::$ty;
46 )*
47
48 pub type RemainingBuffer<'a> = Option<DecoderBufferMut<'a>>;
49
50 #[derive(Debug, PartialEq, Eq)]
51 pub enum Frame<'a, $ack, $data> {
52 $(
53 $ty($module::$ty $(<$($generics)*>)?),
54 )*
55 }
56
57 impl<'a, $ack, $data> event::IntoEvent<event::builder::Frame> for &Frame<'a, $ack, $data>
58 where
59 $ack: crate::frame::ack::AckRanges,
60 $data: EncoderValue,
61 {
62 #[inline]
63 fn into_event(self) -> event::builder::Frame {
64 match self {
65 $(
66 Frame::$ty(inner) => inner.into_event(),
67 )*
68 }
69 }
70 }
71
72 impl<'a, $ack, $data> ack_elicitation::AckElicitable for Frame<'a, $ack, $data> {
73 #[inline]
74 fn ack_elicitation(&self) -> ack_elicitation::AckElicitation {
75 match self {
76 $(
77 Frame::$ty(frame) => frame.ack_elicitation(),
78 )*
79 }
80 }
81 }
82
83 impl<'a, $ack, $data> path_validation::Probing for Frame<'a, $ack, $data> {
84 #[inline]
85 fn path_validation(&self) -> path_validation::Probe {
86 match self {
87 $(
88 Frame::$ty(frame) => frame.path_validation(),
89 )*
90 }
91 }
92 }
93
94 $(
95 impl<'a, $ack, $data> From<$module::$ty $(<$($generics)*>)?> for Frame<'a, $ack, $data> {
96 #[inline]
97 fn from(v: $module::$ty $(<$($generics)*>)?) -> Frame<'a, $ack, $data> {
98 Frame::$ty(v)
99 }
100 }
101 )*
102
103 impl<'a, $ack, $data: DecoderValueMut<'a>> DecoderValueMut<'a> for Frame<'a, $ack, $data>
104 where ack::Ack<$ack>: DecoderParameterizedValueMut<'a, Parameter = Tag> {
105 #[inline]
106 fn decode_mut(buffer: DecoderBufferMut<'a>) -> DecoderBufferMutResult<'a, Self> {
107 BasicFrameDecoder.decode_frame(buffer)
108 }
109 }
110
111 impl<'a, $ack: ack::AckRanges, $data: EncoderValue> EncoderValue for Frame<'a, $ack, $data> {
112 #[inline]
113 fn encode<E: Encoder>(&self, buffer: &mut E) {
114 match self {
115 $(
116 Frame::$ty(frame) => buffer.encode(frame),
117 )*
118 }
119 }
120 }
121
122 struct BasicFrameDecoder;
123
124 impl<'a, $ack, $data: DecoderValueMut<'a>> FrameDecoder<'a, $ack, $data> for BasicFrameDecoder
125 where ack::Ack<$ack>: DecoderParameterizedValueMut<'a, Parameter = Tag> {
126 type Output = Frame<'a, $ack, $data>;
127
128 $(
129 #[inline]
130 fn $handler(&mut self, frame: $module::$ty $(<$($generics)*>)?) -> Result<Self::Output, DecoderError> {
131 Ok(Frame::$ty(frame))
132 }
133 )*
134 }
135
136 pub trait FrameDecoder<'a, $ack, $data: DecoderValueMut<'a>>
137 where ack::Ack<$ack>: DecoderParameterizedValueMut<'a, Parameter = Tag> {
138 type Output;
139
140 $(
141 fn $handler(&mut self, frame: $module::$ty $(<$($generics)*>)?) -> Result<Self::Output, DecoderError>;
142 )*
143
144 #[inline]
145 fn handle_extension_frame(&mut self, buffer: DecoderBufferMut<'a>) -> DecoderBufferMutResult<'a, Self::Output> {
146 let (tag, buffer) = buffer.decode::<ExtensionTag>()?;
147
148 match tag.as_u64() {
149 $(
150 $(
151 $extension_tag_macro!() => {
152 let (frame, buffer) = buffer.decode_parameterized(tag)?;
153 let output = self.$handler(frame)?;
154 Ok((output, buffer))
155 },
156 )?
157 )*
158 _ => {
159 let _ = buffer;
160 Err(DecoderError::InvariantViolation("invalid frame"))
161 }
162 }
163 }
164
165 #[inline]
166 fn decode_frame(
167 &mut self,
168 buffer: DecoderBufferMut<'a>,
169 ) -> DecoderBufferMutResult<'a, Self::Output> {
170 let tag = buffer.peek_byte(0)?;
171 match tag {
172 0b0100_0000..=0xff => self.handle_extension_frame(buffer),
175 $(
176 $(
177 $tag_macro!() => {
178 let buffer = buffer.skip(core::mem::size_of::<Tag>())?;
179 let (frame, buffer) = buffer.decode_parameterized(tag)?;
180 let output = self.$handler(frame)?;
181 Ok((output, buffer))
182 },
183 )?
184 )*
185 _ => self.handle_extension_frame(buffer),
186 }
187 }
188 }
189
190 #[cfg(test)]
191 mod snapshots {
192 use super::*;
193 use s2n_codec::assert_codec_round_trip_sample_file;
194
195 $(
196 #[test]
197 fn $module() {
198 assert_codec_round_trip_sample_file!(FrameMut, concat!(
199 "src/frame/test_samples/",
200 stringify!($module),
201 ".bin"
202 ));
203 }
204 )*
205 }
206 };
207}
208
209macro_rules! simple_frame_codec {
212 ($name:ident {
213 $(
214 $field:ident
215 ),*
216 }, $tag:expr) => {
217 s2n_codec::decoder_parameterized_value!(
218 impl<'a> $name {
219 fn decode(_tag: crate::frame::Tag, buffer: Buffer) -> Result<Self> {
220 $(
221 let ($field, buffer) = buffer.decode()?;
222 )*
223
224 let frame = $name { $($field),* };
225
226 Ok((frame, buffer))
227 }
228 }
229 );
230
231 impl s2n_codec::EncoderValue for $name {
232 #[inline]
233 fn encode<E: s2n_codec::Encoder>(&self, buffer: &mut E) {
234 buffer.encode(&$tag);
235 $(
236 buffer.encode(&self.$field);
237 )*
238 }
239 }
240 };
241}
242
243frames! {
244 AckRanges, Data |
245 [padding_tag] => padding, handle_padding_frame, Padding;
246 [ping_tag] => ping, handle_ping_frame, Ping;
247 [ack_tag] => ack, handle_ack_frame, Ack[AckRanges];
248 [reset_stream_tag] => reset_stream, handle_reset_stream_frame, ResetStream;
249 [stop_sending_tag] => stop_sending, handle_stop_sending_frame, StopSending;
250 [crypto_tag] => crypto, handle_crypto_frame, Crypto[Data];
251 [new_token_tag] => new_token, handle_new_token_frame, NewToken['a];
252 [stream_tag] => stream, handle_stream_frame, Stream[Data];
253 [max_data_tag] => max_data, handle_max_data_frame, MaxData;
254 [max_stream_data_tag] => max_stream_data, handle_max_stream_data_frame, MaxStreamData;
255 [max_streams_tag] => max_streams, handle_max_streams_frame, MaxStreams;
256 [data_blocked_tag] => data_blocked, handle_data_blocked_frame, DataBlocked;
257 [stream_data_blocked_tag] => stream_data_blocked, handle_stream_data_blocked_frame, StreamDataBlocked;
258 [streams_blocked_tag] => streams_blocked, handle_streams_blocked_frame, StreamsBlocked;
259 [new_connection_id_tag] => new_connection_id, handle_new_connection_id_frame, NewConnectionId['a];
260 [retire_connection_id_tag] => retire_connection_id, handle_retire_connection_id_frame, RetireConnectionId;
261 [path_challenge_tag] => path_challenge, handle_path_challenge_frame, PathChallenge['a];
262 [path_response_tag] => path_response, handle_path_response_frame, PathResponse['a];
263 [connection_close_tag] => connection_close, handle_connection_close_frame, ConnectionClose['a];
264 [handshake_done_tag] => handshake_done, handle_handshake_done_frame, HandshakeDone;
265 [datagram_tag] => datagram, handle_datagram_frame, Datagram[Data];
266 extension[dc_stateless_reset_tokens_tag] => dc_stateless_reset_tokens, handle_dc_stateless_reset_tokens_frame, DcStatelessResetTokens['a];
267}
268
269#[derive(Clone, Copy, Debug, Default)]
270pub struct FitError;
272
273impl fmt::Display for FitError {
274 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
275 write!(f, "the frame could not fit into the provided capacity")
276 }
277}