net_wire/quic/packet/
datagram.rs1use core::iter::FusedIterator;
4
5use super::header::{
6 QuicLongHeader, QuicLongPacketType, QuicShortHeader, QuicShortHeaderContext, QuicVersion,
7};
8use super::long::QuicProtectedLongPacket;
9use super::parse::QuicPacketParseError;
10use super::terminal::{QuicRetryPacket, QuicVersionNegotiationPacket};
11
12#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17pub struct QuicUnknownLongPacket<'a> {
18 header: QuicLongHeader<'a>,
19 bytes: &'a [u8],
20}
21
22impl<'a> QuicUnknownLongPacket<'a> {
23 pub const fn header(self) -> QuicLongHeader<'a> {
25 self.header
26 }
27
28 pub const fn as_bytes(self) -> &'a [u8] {
30 self.bytes
31 }
32}
33
34#[derive(Clone, Copy, Debug, Eq, PartialEq)]
36pub enum QuicPacket<'a> {
37 ProtectedLong(QuicProtectedLongPacket<'a>),
39 VersionNegotiation(QuicVersionNegotiationPacket<'a>),
41 Retry(QuicRetryPacket<'a>),
43 Short(QuicShortHeader<'a>),
45 UnknownLong(QuicUnknownLongPacket<'a>),
51}
52
53impl<'a> QuicPacket<'a> {
54 pub const fn as_bytes(self) -> &'a [u8] {
56 match self {
57 Self::ProtectedLong(packet) => packet.as_bytes(),
58 Self::VersionNegotiation(packet) => packet.as_bytes(),
59 Self::Retry(packet) => packet.as_bytes(),
60 Self::Short(packet) => packet.as_bytes(),
61 Self::UnknownLong(packet) => packet.as_bytes(),
62 }
63 }
64
65 pub const fn first_byte(self) -> u8 {
67 match self {
68 Self::ProtectedLong(packet) => packet.header().first_byte(),
69 Self::VersionNegotiation(packet) => packet.header().first_byte(),
70 Self::Retry(packet) => packet.header().first_byte(),
71 Self::Short(packet) => packet.first_byte(),
72 Self::UnknownLong(packet) => packet.header().first_byte(),
73 }
74 }
75
76 pub const fn is_long_header(self) -> bool {
78 !matches!(self, Self::Short(_))
79 }
80}
81
82#[derive(Clone, Copy, Debug, Eq, PartialEq)]
88pub struct QuicDatagram<'a> {
89 bytes: &'a [u8],
90 short_context: Option<QuicShortHeaderContext>,
91}
92
93impl<'a> QuicDatagram<'a> {
94 pub fn parse(
96 bytes: &'a [u8],
97 short_context: Option<QuicShortHeaderContext>,
98 ) -> Result<Self, QuicPacketParseError> {
99 if bytes.is_empty() {
100 return Err(QuicPacketParseError::EmptyDatagram);
101 }
102
103 for packet in QuicPackets::new(bytes, short_context) {
104 packet?;
105 }
106 Ok(Self {
107 bytes,
108 short_context,
109 })
110 }
111
112 pub const fn as_bytes(self) -> &'a [u8] {
114 self.bytes
115 }
116
117 pub const fn packets(self) -> QuicPackets<'a> {
119 QuicPackets::new(self.bytes, self.short_context)
120 }
121}
122
123#[derive(Clone, Debug)]
128pub struct QuicPackets<'a> {
129 remaining: &'a [u8],
130 short_context: Option<QuicShortHeaderContext>,
131 exhausted: bool,
132}
133
134impl<'a> QuicPackets<'a> {
135 pub const fn new(bytes: &'a [u8], short_context: Option<QuicShortHeaderContext>) -> Self {
139 Self {
140 remaining: bytes,
141 short_context,
142 exhausted: false,
143 }
144 }
145}
146
147impl<'a> Iterator for QuicPackets<'a> {
148 type Item = Result<QuicPacket<'a>, QuicPacketParseError>;
149
150 fn next(&mut self) -> Option<Self::Item> {
151 if self.exhausted || self.remaining.is_empty() {
152 self.exhausted = true;
153 return None;
154 }
155
156 let bytes = self.remaining;
157 let result = if bytes[0] & 0x80 == 0 {
158 let context = match self.short_context {
159 Some(context) => context,
160 None => return self.fail(QuicPacketParseError::ShortHeaderContextRequired),
161 };
162 QuicShortHeader::parse(bytes, context).map(QuicPacket::Short)
163 } else {
164 match QuicLongHeader::parse(bytes) {
165 Err(error) => Err(error),
166 Ok(header) if header.version() == QuicVersion::NEGOTIATION => {
167 QuicVersionNegotiationPacket::parse(bytes).map(QuicPacket::VersionNegotiation)
168 }
169 Ok(header) => match header.long_packet_type() {
170 Some(QuicLongPacketType::Retry) => {
171 QuicRetryPacket::parse(bytes).map(QuicPacket::Retry)
172 }
173 Some(_) => QuicProtectedLongPacket::parse(bytes).map(|(packet, suffix)| {
174 self.remaining = suffix;
175 QuicPacket::ProtectedLong(packet)
176 }),
177 None => Ok(QuicPacket::UnknownLong(QuicUnknownLongPacket {
178 header,
179 bytes,
180 })),
181 },
182 }
183 };
184
185 match result {
186 Ok(
187 packet @ (QuicPacket::Short(_)
188 | QuicPacket::VersionNegotiation(_)
189 | QuicPacket::Retry(_)
190 | QuicPacket::UnknownLong(_)),
191 ) => {
192 self.remaining = &[];
193 self.exhausted = true;
194 Some(Ok(packet))
195 }
196 Ok(packet) => Some(Ok(packet)),
197 Err(error) => self.fail(error),
198 }
199 }
200}
201
202impl FusedIterator for QuicPackets<'_> {}
203
204impl<'a> QuicPackets<'a> {
205 fn fail(
206 &mut self,
207 error: QuicPacketParseError,
208 ) -> Option<Result<QuicPacket<'a>, QuicPacketParseError>> {
209 self.remaining = &[];
210 self.exhausted = true;
211 Some(Err(error))
212 }
213}