1use std::{
2 fmt::{self, Display, Write},
3 mem,
4 net::{IpAddr, SocketAddr},
5 ops::{Range, RangeInclusive},
6};
7
8use bytes::{Buf, BufMut, Bytes};
9use tinyvec::TinyVec;
10
11use crate::{
12 Dir, MAX_CID_SIZE, RESET_TOKEN_SIZE, ResetToken, StreamId, TransportError, TransportErrorCode,
13 VarInt,
14 coding::{self, BufExt, BufMutExt, Decodable, Encodable, UnexpectedEnd},
15 connection::PathId,
16 range_set::ArrayRangeSet,
17 shared::{ConnectionId, EcnCodepoint},
18};
19
20#[cfg(feature = "arbitrary")]
21use arbitrary::Arbitrary;
22
23#[cfg(feature = "qlog")]
24use super::connection::qlog::ToQlog;
25
26#[derive(
27 Copy, Clone, Eq, PartialEq, derive_more::Debug, derive_more::Display, enum_assoc::Assoc,
28)]
29#[display(rename_all = "SCREAMING_SNAKE_CASE")]
30#[allow(missing_docs)]
31#[func(
32 pub(crate) const fn to_u64(self) -> u64,
33 const fn from_u64(rev: u64) -> Option<Self>,
34)]
35pub enum FrameType {
36 #[assoc(to_u64 = 0x00)]
37 Padding,
38 #[assoc(to_u64 = 0x01)]
39 Ping,
40 #[assoc(to_u64 = 0x02)]
41 Ack,
42 #[assoc(to_u64 = 0x03)]
43 AckEcn,
44 #[assoc(to_u64 = 0x04)]
45 ResetStream,
46 #[assoc(to_u64 = 0x05)]
47 StopSending,
48 #[assoc(to_u64 = 0x06)]
49 Crypto,
50 #[assoc(to_u64 = 0x07)]
51 NewToken,
52 #[assoc(to_u64 = _0.to_u64())]
54 Stream(StreamInfo),
55 #[assoc(to_u64 = 0x10)]
56 MaxData,
57 #[assoc(to_u64 = 0x11)]
58 MaxStreamData,
59 #[assoc(to_u64 = 0x12)]
60 MaxStreamsBidi,
61 #[assoc(to_u64 = 0x13)]
62 MaxStreamsUni,
63 #[assoc(to_u64 = 0x14)]
64 DataBlocked,
65 #[assoc(to_u64 = 0x15)]
66 StreamDataBlocked,
67 #[assoc(to_u64 = 0x16)]
68 StreamsBlockedBidi,
69 #[assoc(to_u64 = 0x17)]
70 StreamsBlockedUni,
71 #[assoc(to_u64 = 0x18)]
72 NewConnectionId,
73 #[assoc(to_u64 = 0x19)]
74 RetireConnectionId,
75 #[assoc(to_u64 = 0x1a)]
76 PathChallenge,
77 #[assoc(to_u64 = 0x1b)]
78 PathResponse,
79 #[assoc(to_u64 = 0x1c)]
80 ConnectionClose,
81 #[assoc(to_u64 = 0x1d)]
82 ApplicationClose,
83 #[assoc(to_u64 = 0x1e)]
84 HandshakeDone,
85 #[assoc(to_u64 = 0xaf)]
87 AckFrequency,
88 #[assoc(to_u64 = 0x1f)]
89 ImmediateAck,
90 #[assoc(to_u64 = _0.to_u64())]
92 Datagram(DatagramInfo),
93 #[assoc(to_u64 = 0x9f81a6)]
95 ObservedIpv4Addr,
96 #[assoc(to_u64 = 0x9f81a7)]
97 ObservedIpv6Addr,
98 #[assoc(to_u64 = 0x3e)]
100 PathAck,
101 #[assoc(to_u64 = 0x3f)]
102 PathAckEcn,
103 #[assoc(to_u64 = 0x3e75)]
104 PathAbandon,
105 #[assoc(to_u64 = 0x3e76)]
106 PathStatusBackup,
107 #[assoc(to_u64 = 0x3e77)]
108 PathStatusAvailable,
109 #[assoc(to_u64 = 0x3e78)]
110 PathNewConnectionId,
111 #[assoc(to_u64 = 0x3e79)]
112 PathRetireConnectionId,
113 #[assoc(to_u64 = 0x3e7a)]
114 MaxPathId,
115 #[assoc(to_u64 = 0x3e7b)]
116 PathsBlocked,
117 #[assoc(to_u64 = 0x3e7c)]
118 PathCidsBlocked,
119 #[assoc(to_u64 = 0x3d7f90)]
121 AddIpv4Address,
122 #[assoc(to_u64 = 0x3d7f91)]
123 AddIpv6Address,
124 #[assoc(to_u64 = 0x3d7f92)]
125 ReachOutAtIpv4,
126 #[assoc(to_u64 = 0x3d7f93)]
127 ReachOutAtIpv6,
128 #[assoc(to_u64 = 0x3d7f94)]
129 RemoveAddress,
130}
131
132#[derive(Debug, PartialEq, Eq)]
134pub struct InvalidFrameId(u64);
135
136impl TryFrom<u64> for FrameType {
137 type Error = InvalidFrameId;
138 fn try_from(value: u64) -> Result<Self, Self::Error> {
139 match Self::from_u64(value) {
140 Some(t) => Ok(t),
141 None => {
142 if DatagramInfo::VALUES.contains(&value) {
143 return Ok(Self::Datagram(DatagramInfo(value as u8)));
144 }
145 if StreamInfo::VALUES.contains(&value) {
146 return Ok(Self::Stream(StreamInfo(value as u8)));
147 }
148 Err(InvalidFrameId(value))
149 }
150 }
151 }
152}
153
154impl FrameType {
155 const fn size(&self) -> usize {
157 VarInt(self.to_u64()).size()
158 }
159}
160
161impl Decodable for FrameType {
162 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
163 Self::try_from(buf.get_var()?).map_err(|_| coding::UnexpectedEnd)
164 }
165}
166
167impl Encodable for FrameType {
168 fn encode<B: BufMut>(&self, buf: &mut B) {
169 buf.write_var(self.to_u64());
170 }
171}
172
173#[derive(derive_more::From, enum_assoc::Assoc, derive_more::Display)]
178#[func(fn encode_inner<B: BufMut>(&self, buf: &mut B) {_0.encode(buf)})]
179#[func(pub(crate) const fn get_type(&self) -> FrameType {_0.get_type()})]
180#[cfg_attr(feature = "qlog", func(pub(crate) fn to_qlog(&self) -> qlog::events::quic::QuicFrame {_0.to_qlog()}))]
181pub(super) enum EncodableFrame<'a> {
182 PathAck(PathAckEncoder<'a>),
183 Ack(AckEncoder<'a>),
184 Close(CloseEncoder<'a>),
185 PathResponse(PathResponse),
186 HandshakeDone(HandshakeDone),
187 ReachOut(ReachOut),
188 ObservedAddr(ObservedAddr),
189 Ping(Ping),
190 ImmediateAck(ImmediateAck),
191 AckFrequency(AckFrequency),
192 PathChallenge(PathChallenge),
193 Crypto(Crypto),
194 PathAbandon(PathAbandon),
195 PathStatusAvailable(PathStatusAvailable),
196 PathStatusBackup(PathStatusBackup),
197 MaxPathId(MaxPathId),
198 PathsBlocked(PathsBlocked),
199 PathCidsBlocked(PathCidsBlocked),
200 ResetStream(ResetStream),
201 StopSending(StopSending),
202 NewConnectionId(NewConnectionId),
203 RetireConnectionId(RetireConnectionId),
204 Datagram(Datagram),
205 NewToken(NewToken),
206 AddAddress(AddAddress),
207 RemoveAddress(RemoveAddress),
208 StreamMeta(StreamMetaEncoder),
209 MaxData(MaxData),
210 MaxStreamData(MaxStreamData),
211 MaxStreams(MaxStreams),
212}
213
214impl<'a> Encodable for EncodableFrame<'a> {
215 fn encode<B: BufMut>(&self, buf: &mut B) {
216 self.encode_inner(buf)
217 }
218}
219
220pub(crate) trait FrameStruct {
221 const SIZE_BOUND: usize;
223}
224
225#[derive(Copy, Clone, Eq, PartialEq, derive_more::Debug, derive_more::Display)]
227pub enum MaybeFrame {
228 None,
230 #[display("UNKNOWN{:02x}", _0)]
232 #[debug("Unknown{:02x}", _0)]
233 Unknown(u64),
234 Known(FrameType),
236}
237
238impl MaybeFrame {
239 const fn size(&self) -> usize {
241 match self {
242 Self::None => VarInt(0).size(),
243 Self::Unknown(other) => VarInt(*other).size(),
244 Self::Known(frame_type) => frame_type.size(),
245 }
246 }
247}
248
249impl Decodable for MaybeFrame {
250 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
251 match FrameType::try_from(buf.get_var()?) {
252 Ok(FrameType::Padding) => Ok(Self::None),
253 Ok(other_frame) => Ok(Self::Known(other_frame)),
254 Err(InvalidFrameId(other)) => Ok(Self::Unknown(other)),
255 }
256 }
257}
258
259impl Encodable for MaybeFrame {
260 fn encode<B: BufMut>(&self, buf: &mut B) {
261 match self {
262 Self::None => buf.write_var(0u64),
263 Self::Unknown(frame_id) => buf.write_var(*frame_id),
264 Self::Known(frame_type) => buf.write(*frame_type),
265 }
266 }
267}
268
269#[derive(derive_more::Display)]
270#[display("HANDSHAKE_DONE")]
271pub(crate) struct HandshakeDone;
272
273impl HandshakeDone {
274 const fn get_type(&self) -> FrameType {
275 FrameType::HandshakeDone
276 }
277}
278
279impl Encodable for HandshakeDone {
280 fn encode<B: BufMut>(&self, buf: &mut B) {
281 FrameType::HandshakeDone.encode(buf);
282 }
283}
284
285#[derive(derive_more::Display)]
286#[display("PING")]
287pub(crate) struct Ping;
288
289impl Ping {
290 const fn get_type(&self) -> FrameType {
291 FrameType::Ping
292 }
293}
294
295impl Encodable for Ping {
296 fn encode<B: BufMut>(&self, buf: &mut B) {
297 FrameType::Ping.encode(buf);
298 }
299}
300
301#[derive(derive_more::Display)]
302#[display("IMMEDIATE_ACK")]
303pub(crate) struct ImmediateAck;
304
305impl ImmediateAck {
306 const fn get_type(&self) -> FrameType {
307 FrameType::ImmediateAck
308 }
309}
310
311impl Encodable for ImmediateAck {
312 fn encode<B: BufMut>(&self, buf: &mut B) {
313 FrameType::ImmediateAck.encode(buf);
314 }
315}
316
317#[allow(missing_docs)]
318#[derive(Debug, Copy, Clone, Eq, PartialEq, derive_more::Display)]
319#[display("STREAM")]
320pub struct StreamInfo(u8);
321
322impl StreamInfo {
323 const VALUES: RangeInclusive<u64> = RangeInclusive::new(0x08, 0x0f);
324 fn fin(self) -> bool {
325 self.0 & 0x01 != 0
326 }
327 fn len(self) -> bool {
328 self.0 & 0x02 != 0
329 }
330 fn off(self) -> bool {
331 self.0 & 0x04 != 0
332 }
333
334 const fn to_u64(self) -> u64 {
335 self.0 as u64
336 }
337}
338
339#[allow(missing_docs)]
340#[derive(Debug, Copy, Clone, Eq, PartialEq, derive_more::Display)]
341#[display("DATAGRAM")]
342pub struct DatagramInfo(u8);
343
344impl DatagramInfo {
345 const VALUES: RangeInclusive<u64> = RangeInclusive::new(0x30, 0x31);
346
347 fn len(self) -> bool {
348 self.0 & 0x01 != 0
349 }
350
351 const fn to_u64(self) -> u64 {
352 self.0 as u64
353 }
354}
355
356#[derive(Debug)]
357pub(crate) enum Frame {
358 Padding,
359 Ping,
360 Ack(Ack),
361 PathAck(PathAck),
362 ResetStream(ResetStream),
363 StopSending(StopSending),
364 Crypto(Crypto),
365 NewToken(NewToken),
366 Stream(Stream),
367 MaxData(MaxData),
368 MaxStreamData(MaxStreamData),
369 MaxStreams(MaxStreams),
370 DataBlocked { offset: u64 },
371 StreamDataBlocked { id: StreamId, offset: u64 },
372 StreamsBlocked { dir: Dir, limit: u64 },
373 NewConnectionId(NewConnectionId),
374 RetireConnectionId(RetireConnectionId),
375 PathChallenge(PathChallenge),
376 PathResponse(PathResponse),
377 Close(Close),
378 Datagram(Datagram),
379 AckFrequency(AckFrequency),
380 ImmediateAck,
381 HandshakeDone,
382 ObservedAddr(ObservedAddr),
383 PathAbandon(PathAbandon),
384 PathStatusAvailable(PathStatusAvailable),
385 PathStatusBackup(PathStatusBackup),
386 MaxPathId(MaxPathId),
387 PathsBlocked(PathsBlocked),
388 PathCidsBlocked(PathCidsBlocked),
389 AddAddress(AddAddress),
390 ReachOut(ReachOut),
391 RemoveAddress(RemoveAddress),
392}
393
394impl fmt::Display for Frame {
395 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
396 match self {
399 Self::Padding => write!(f, "PADDING"),
400 Self::Ping => write!(f, "PING"),
401 Self::PathChallenge(frame) => write!(f, "{frame}"),
402 Self::PathResponse(frame) => write!(f, "{frame}"),
403 Self::ImmediateAck => write!(f, "IMMEDIATE_ACK"),
404 Self::HandshakeDone => write!(f, "HANDSHAKE_DONE"),
405 _ => write!(f, "{self:?}"),
406 }
407 }
408}
409
410impl Frame {
411 pub(crate) fn ty(&self) -> FrameType {
412 use Frame::*;
413 match &self {
414 Padding => FrameType::Padding,
415 ResetStream(_) => FrameType::ResetStream,
416 Close(self::Close::Connection(_)) => FrameType::ConnectionClose,
417 Close(self::Close::Application(_)) => FrameType::ConnectionClose,
418 MaxData(_) => FrameType::MaxData,
419 MaxStreamData(_) => FrameType::MaxStreamData,
420 MaxStreams(max_streams) => max_streams.get_type(),
421 Ping => FrameType::Ping,
422 DataBlocked { .. } => FrameType::DataBlocked,
423 StreamDataBlocked { .. } => FrameType::StreamDataBlocked,
424 StreamsBlocked { dir: Dir::Bi, .. } => FrameType::StreamsBlockedBidi,
425 StreamsBlocked { dir: Dir::Uni, .. } => FrameType::StreamsBlockedUni,
426 StopSending { .. } => FrameType::StopSending,
427 RetireConnectionId(retire_frame) => retire_frame.get_type(),
428 Ack(ack) => ack.get_type(),
429 PathAck(path_ack) => path_ack.get_type(),
430 Stream(ref x) => {
431 let mut ty = *StreamInfo::VALUES.start() as u8;
432 if x.fin {
433 ty |= 0x01;
434 }
435 if x.offset != 0 {
436 ty |= 0x04;
437 }
438 FrameType::Stream(StreamInfo(ty))
440 }
441 PathChallenge(_) => FrameType::PathChallenge,
442 PathResponse(_) => FrameType::PathResponse,
443 NewConnectionId(cid) => cid.get_type(),
444 Crypto(_) => FrameType::Crypto,
445 NewToken(_) => FrameType::NewToken,
446 Datagram(_) => FrameType::Datagram(DatagramInfo(*DatagramInfo::VALUES.start() as u8)),
447 AckFrequency(_) => FrameType::AckFrequency,
448 ImmediateAck => FrameType::ImmediateAck,
449 HandshakeDone => FrameType::HandshakeDone,
450 ObservedAddr(ref observed) => observed.get_type(),
451 PathAbandon(_) => FrameType::PathAbandon,
452 PathStatusAvailable(_) => FrameType::PathStatusAvailable,
453 PathStatusBackup(_) => FrameType::PathStatusBackup,
454 MaxPathId(_) => FrameType::MaxPathId,
455 PathsBlocked(_) => FrameType::PathsBlocked,
456 PathCidsBlocked(_) => FrameType::PathCidsBlocked,
457 AddAddress(ref frame) => frame.get_type(),
458 ReachOut(ref frame) => frame.get_type(),
459 RemoveAddress(_) => self::RemoveAddress::TYPE,
460 }
461 }
462
463 pub(crate) fn is_ack_eliciting(&self) -> bool {
464 !matches!(
465 *self,
466 Self::Ack(_) | Self::PathAck(_) | Self::Padding | Self::Close(_)
467 )
468 }
469
470 pub(crate) fn is_1rtt(&self) -> bool {
472 self.is_multipath_frame() || self.is_qad_frame()
478 }
479
480 fn is_qad_frame(&self) -> bool {
481 matches!(*self, Self::ObservedAddr(_))
482 }
483
484 fn is_multipath_frame(&self) -> bool {
485 matches!(
486 *self,
487 Self::PathAck(_)
488 | Self::PathAbandon(_)
489 | Self::PathStatusBackup(_)
490 | Self::PathStatusAvailable(_)
491 | Self::MaxPathId(_)
492 | Self::PathsBlocked(_)
493 | Self::PathCidsBlocked(_)
494 | Self::NewConnectionId(NewConnectionId {
495 path_id: Some(_),
496 ..
497 })
498 | Self::RetireConnectionId(RetireConnectionId {
499 path_id: Some(_),
500 ..
501 })
502 )
503 }
504}
505
506#[derive(Debug, Clone, Copy, PartialEq, Eq, derive_more::Display)]
507#[display("PATH_CHALLENGE({_0:08x})")]
508pub(crate) struct PathChallenge(pub(crate) u64);
509
510impl PathChallenge {
511 pub(crate) const SIZE_BOUND: usize = 9;
512
513 const fn get_type(&self) -> FrameType {
514 FrameType::PathChallenge
515 }
516}
517
518impl Decodable for PathChallenge {
519 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
520 Ok(Self(buf.get()?))
521 }
522}
523
524impl Encodable for PathChallenge {
525 fn encode<B: BufMut>(&self, buf: &mut B) {
526 buf.write(FrameType::PathChallenge);
527 buf.write(self.0);
528 }
529}
530
531#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, derive_more::Display)]
532#[display("PATH_RESPONSE({_0:08x})")]
533pub(crate) struct PathResponse(pub(crate) u64);
534
535impl PathResponse {
536 pub(crate) const SIZE_BOUND: usize = 9;
537
538 const fn get_type(&self) -> FrameType {
539 FrameType::PathResponse
540 }
541}
542
543impl Decodable for PathResponse {
544 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
545 Ok(Self(buf.get()?))
546 }
547}
548impl Encodable for PathResponse {
549 fn encode<B: BufMut>(&self, buf: &mut B) {
550 buf.write(FrameType::PathResponse);
551 buf.write(self.0);
552 }
553}
554
555#[derive(Debug, Clone, Copy, derive_more::Display)]
556#[display("MAX_DATA({_0})")]
557pub(crate) struct MaxData(pub(crate) VarInt);
558
559impl MaxData {
560 const fn get_type(&self) -> FrameType {
561 FrameType::MaxData
562 }
563}
564
565impl Decodable for MaxData {
566 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
567 Ok(Self(buf.get()?))
568 }
569}
570impl Encodable for MaxData {
571 fn encode<B: BufMut>(&self, buf: &mut B) {
572 buf.write(FrameType::MaxData);
573 buf.write(self.0);
574 }
575}
576
577#[derive(Debug, Clone, Copy, derive_more::Display)]
578#[display("MAX_STREAM_DATA id: {id} max: {offset}")]
579pub(crate) struct MaxStreamData {
580 pub(crate) id: StreamId,
581 pub(crate) offset: u64,
582}
583
584impl MaxStreamData {
585 const fn get_type(&self) -> FrameType {
586 FrameType::MaxStreamData
587 }
588}
589
590impl Decodable for MaxStreamData {
591 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
592 Ok(Self {
593 id: buf.get()?,
594 offset: buf.get_var()?,
595 })
596 }
597}
598
599impl Encodable for MaxStreamData {
600 fn encode<B: BufMut>(&self, buf: &mut B) {
601 buf.write(FrameType::MaxStreamData);
602 buf.write(self.id);
603 buf.write_var(self.offset);
604 }
605}
606
607#[derive(Debug, Clone, Copy, derive_more::Display)]
608#[display("{} count: {count}", self.get_type())]
609pub(crate) struct MaxStreams {
610 pub(crate) dir: Dir,
611 pub(crate) count: u64,
612}
613
614impl MaxStreams {
615 const fn get_type(&self) -> FrameType {
616 match self.dir {
617 Dir::Bi => FrameType::MaxStreamsBidi,
618 Dir::Uni => FrameType::MaxStreamsUni,
619 }
620 }
621}
622
623impl Encodable for MaxStreams {
624 fn encode<B: BufMut>(&self, buf: &mut B) {
625 buf.write(self.get_type());
626 buf.write_var(self.count);
627 }
628}
629
630#[derive(Debug, PartialEq, Eq, derive_more::Display)]
631#[display("{} {} seq: {sequence}", self.get_type(), DisplayOption::new("path_id", path_id.as_ref()))]
632pub(crate) struct RetireConnectionId {
633 pub(crate) path_id: Option<PathId>,
634 pub(crate) sequence: u64,
635}
636
637impl RetireConnectionId {
638 pub(crate) const SIZE_BOUND: usize = {
640 let type_len = FrameType::RetireConnectionId.size();
641 let seq_max_len = 8usize;
642 type_len + seq_max_len
643 };
644
645 pub(crate) const SIZE_BOUND_MULTIPATH: usize = {
647 let type_len = FrameType::PathRetireConnectionId.size();
648 let path_id_len = VarInt::from_u32(u32::MAX).size();
649 let seq_max_len = 8usize;
650 type_len + path_id_len + seq_max_len
651 };
652
653 pub(crate) fn decode<R: Buf>(bytes: &mut R, read_path: bool) -> coding::Result<Self> {
656 Ok(Self {
657 path_id: if read_path { Some(bytes.get()?) } else { None },
658 sequence: bytes.get_var()?,
659 })
660 }
661
662 const fn get_type(&self) -> FrameType {
664 if self.path_id.is_some() {
665 FrameType::PathRetireConnectionId
666 } else {
667 FrameType::RetireConnectionId
668 }
669 }
670
671 pub(crate) const fn size_bound(path_retire_cid: bool) -> usize {
676 match path_retire_cid {
677 true => Self::SIZE_BOUND_MULTIPATH,
678 false => Self::SIZE_BOUND,
679 }
680 }
681}
682
683impl Encodable for RetireConnectionId {
684 fn encode<W: BufMut>(&self, buf: &mut W) {
685 buf.write(self.get_type());
686 if let Some(id) = self.path_id {
687 buf.write(id);
688 }
689 buf.write_var(self.sequence);
690 }
691}
692
693#[derive(Clone, Debug, derive_more::Display)]
694pub(crate) enum Close {
695 Connection(ConnectionClose),
696 Application(ApplicationClose),
697}
698
699impl Close {
700 pub(crate) fn encoder(&self, max_len: usize) -> CloseEncoder<'_> {
701 CloseEncoder {
702 close: self,
703 max_len,
704 }
705 }
706
707 pub(crate) fn is_transport_layer(&self) -> bool {
708 matches!(*self, Self::Connection(_))
709 }
710}
711
712#[derive(derive_more::Display)]
713#[display("{close}")]
714pub(crate) struct CloseEncoder<'a> {
715 pub(crate) close: &'a Close,
716 max_len: usize,
717}
718
719impl<'a> CloseEncoder<'a> {
720 const fn get_type(&self) -> FrameType {
721 match self.close {
722 Close::Connection(_) => FrameType::ConnectionClose,
723 Close::Application(_) => FrameType::ApplicationClose,
724 }
725 }
726}
727
728impl<'a> Encodable for CloseEncoder<'a> {
729 fn encode<W: BufMut>(&self, out: &mut W) {
730 match self.close {
731 Close::Connection(x) => x.encode(out, self.max_len),
732 Close::Application(x) => x.encode(out, self.max_len),
733 }
734 }
735}
736
737impl From<TransportError> for Close {
738 fn from(x: TransportError) -> Self {
739 Self::Connection(x.into())
740 }
741}
742impl From<ConnectionClose> for Close {
743 fn from(x: ConnectionClose) -> Self {
744 Self::Connection(x)
745 }
746}
747impl From<ApplicationClose> for Close {
748 fn from(x: ApplicationClose) -> Self {
749 Self::Application(x)
750 }
751}
752
753#[derive(Debug, Clone, PartialEq, Eq)]
755pub struct ConnectionClose {
756 pub error_code: TransportErrorCode,
758 pub frame_type: MaybeFrame,
760 pub reason: Bytes,
762}
763
764impl fmt::Display for ConnectionClose {
765 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
766 self.error_code.fmt(f)?;
767 if !self.reason.as_ref().is_empty() {
768 f.write_str(": ")?;
769 f.write_str(&String::from_utf8_lossy(&self.reason))?;
770 }
771 Ok(())
772 }
773}
774
775impl From<TransportError> for ConnectionClose {
776 fn from(x: TransportError) -> Self {
777 Self {
778 error_code: x.code,
779 frame_type: x.frame,
780 reason: x.reason.into(),
781 }
782 }
783}
784
785impl FrameStruct for ConnectionClose {
786 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
787}
788
789impl ConnectionClose {
790 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
791 out.write(FrameType::ConnectionClose); out.write(self.error_code); out.write(self.frame_type); let max_len = max_len
795 - 3
796 - self.frame_type.size()
797 - VarInt::from_u64(self.reason.len() as u64).unwrap().size();
798 let actual_len = self.reason.len().min(max_len);
799 out.write_var(actual_len as u64); out.put_slice(&self.reason[0..actual_len]); }
802}
803
804#[derive(Debug, Clone, PartialEq, Eq)]
806pub struct ApplicationClose {
807 pub error_code: VarInt,
809 pub reason: Bytes,
811}
812
813impl fmt::Display for ApplicationClose {
814 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
815 if !self.reason.as_ref().is_empty() {
816 f.write_str(&String::from_utf8_lossy(&self.reason))?;
817 f.write_str(" (code ")?;
818 self.error_code.fmt(f)?;
819 f.write_str(")")?;
820 } else {
821 self.error_code.fmt(f)?;
822 }
823 Ok(())
824 }
825}
826
827impl FrameStruct for ApplicationClose {
828 const SIZE_BOUND: usize = 1 + 8 + 8;
829}
830
831impl ApplicationClose {
832 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
833 out.write(FrameType::ApplicationClose); out.write(self.error_code); let max_len = max_len - 3 - VarInt::from_u64(self.reason.len() as u64).unwrap().size();
836 let actual_len = self.reason.len().min(max_len);
837 out.write_var(actual_len as u64); out.put_slice(&self.reason[0..actual_len]); }
840}
841
842#[derive(Clone, Eq, PartialEq)]
843pub(crate) struct PathAck {
844 pub path_id: PathId,
845 pub largest: u64,
846 pub delay: u64,
847 pub additional: Bytes,
848 pub ecn: Option<EcnCounts>,
849}
850
851impl fmt::Debug for PathAck {
852 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
853 let mut ranges = "[".to_string();
854 let mut first = true;
855 for range in self.into_iter() {
856 if !first {
857 ranges.push(',');
858 }
859 write!(ranges, "{range:?}")?;
860 first = false;
861 }
862 ranges.push(']');
863
864 f.debug_struct("PathAck")
865 .field("path_id", &self.path_id)
866 .field("largest", &self.largest)
867 .field("delay", &self.delay)
868 .field("ecn", &self.ecn)
869 .field("ranges", &ranges)
870 .finish()
871 }
872}
873
874impl<'a> IntoIterator for &'a PathAck {
875 type Item = RangeInclusive<u64>;
876 #[allow(unnameable_types)]
877 type IntoIter = AckIter<'a>;
878
879 fn into_iter(self) -> Self::IntoIter {
880 AckIter::new(self.largest, &self.additional[..])
881 }
882}
883
884impl PathAck {
885 pub(crate) fn into_ack(self) -> (Ack, PathId) {
886 let ack = Ack {
887 largest: self.largest,
888 delay: self.delay,
889 additional: self.additional,
890 ecn: self.ecn,
891 };
892
893 (ack, self.path_id)
894 }
895
896 fn get_type(&self) -> FrameType {
897 if self.ecn.is_some() {
898 FrameType::PathAckEcn
899 } else {
900 FrameType::PathAck
901 }
902 }
903
904 pub(crate) fn encoder<'a>(
905 path_id: PathId,
906 delay: u64,
907 ranges: &'a ArrayRangeSet,
908 ecn: Option<&'a EcnCounts>,
909 ) -> PathAckEncoder<'a> {
910 PathAckEncoder {
911 path_id,
912 delay,
913 ranges,
914 ecn,
915 }
916 }
917}
918
919#[derive(derive_more::Display)]
920#[display("{} path_id: {path_id} ranges: {ranges:?} delay: {delay}µs", self.get_type())]
921pub(crate) struct PathAckEncoder<'a> {
922 pub(super) path_id: PathId,
923 pub(super) delay: u64,
924 pub(super) ranges: &'a ArrayRangeSet,
925 pub(super) ecn: Option<&'a EcnCounts>,
926}
927
928impl<'a> PathAckEncoder<'a> {
929 const fn get_type(&self) -> FrameType {
930 match self.ecn.is_some() {
931 true => FrameType::PathAckEcn,
932 false => FrameType::PathAck,
933 }
934 }
935}
936
937impl<'a> Encodable for PathAckEncoder<'a> {
938 fn encode<W: BufMut>(&self, buf: &mut W) {
945 let PathAckEncoder {
946 path_id,
947 delay,
948 ranges,
949 ecn,
950 } = self;
951 let mut rest = ranges.iter().rev();
952 let first = rest
953 .next()
954 .expect("Caller has verified ranges is non empty");
955 let largest = first.end - 1;
956 let first_size = first.end - first.start;
957 let kind = match ecn.is_some() {
958 true => FrameType::PathAckEcn,
959 false => FrameType::PathAck,
960 };
961 buf.write(kind);
962 buf.write(*path_id);
963 buf.write_var(largest);
964 buf.write_var(*delay);
965 buf.write_var(ranges.len() as u64 - 1);
966 buf.write_var(first_size - 1);
967 let mut prev = first.start;
968 for block in rest {
969 let size = block.end - block.start;
970 buf.write_var(prev - block.end - 1);
971 buf.write_var(size - 1);
972 prev = block.start;
973 }
974 if let Some(x) = ecn {
975 x.encode(buf)
976 }
977 }
978}
979
980#[derive(Clone, Eq, PartialEq)]
981pub(crate) struct Ack {
982 pub largest: u64,
983 pub delay: u64,
984 pub additional: Bytes,
985 pub ecn: Option<EcnCounts>,
986}
987
988impl fmt::Debug for Ack {
989 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
990 let mut ranges = "[".to_string();
991 let mut first = true;
992 for range in self.iter() {
993 if !first {
994 ranges.push(',');
995 }
996 write!(ranges, "{range:?}").unwrap();
997 first = false;
998 }
999 ranges.push(']');
1000
1001 f.debug_struct("Ack")
1002 .field("largest", &self.largest)
1003 .field("delay", &self.delay)
1004 .field("ecn", &self.ecn)
1005 .field("ranges", &ranges)
1006 .finish()
1007 }
1008}
1009
1010#[allow(unnameable_types)]
1011impl<'a> IntoIterator for &'a Ack {
1012 type Item = RangeInclusive<u64>;
1013 type IntoIter = AckIter<'a>;
1014
1015 fn into_iter(self) -> AckIter<'a> {
1016 AckIter::new(self.largest, &self.additional[..])
1017 }
1018}
1019
1020impl Ack {
1021 pub(crate) fn encoder<'a>(
1022 delay: u64,
1023 ranges: &'a ArrayRangeSet,
1024 ecn: Option<&'a EcnCounts>,
1025 ) -> AckEncoder<'a> {
1026 AckEncoder { delay, ranges, ecn }
1027 }
1028
1029 pub(crate) fn iter(&self) -> AckIter<'_> {
1030 self.into_iter()
1031 }
1032
1033 pub(crate) const fn get_type(&self) -> FrameType {
1034 if self.ecn.is_some() {
1035 FrameType::AckEcn
1036 } else {
1037 FrameType::Ack
1038 }
1039 }
1040}
1041
1042#[derive(derive_more::Display)]
1043#[display("{} ranges: {ranges:?} delay: {delay}µs", self.get_type())]
1044pub(crate) struct AckEncoder<'a> {
1045 pub(crate) delay: u64,
1046 pub(crate) ranges: &'a ArrayRangeSet,
1047 pub(crate) ecn: Option<&'a EcnCounts>,
1048}
1049
1050impl<'a> AckEncoder<'a> {
1051 const fn get_type(&self) -> FrameType {
1052 match self.ecn.is_some() {
1053 true => FrameType::AckEcn,
1054 false => FrameType::Ack,
1055 }
1056 }
1057}
1058
1059impl<'a> Encodable for AckEncoder<'a> {
1060 fn encode<W: BufMut>(&self, buf: &mut W) {
1061 let AckEncoder { delay, ranges, ecn } = self;
1062 let mut rest = ranges.iter().rev();
1063 let first = rest.next().unwrap();
1064 let largest = first.end - 1;
1065 let first_size = first.end - first.start;
1066 let kind = match ecn.is_some() {
1067 true => FrameType::AckEcn,
1068 false => FrameType::Ack,
1069 };
1070 buf.write(kind);
1071 buf.write_var(largest);
1072 buf.write_var(*delay);
1073 buf.write_var(ranges.len() as u64 - 1);
1074 buf.write_var(first_size - 1);
1075 let mut prev = first.start;
1076 for block in rest {
1077 let size = block.end - block.start;
1078 buf.write_var(prev - block.end - 1);
1079 buf.write_var(size - 1);
1080 prev = block.start;
1081 }
1082 if let Some(x) = ecn {
1083 x.encode(buf)
1084 }
1085 }
1086}
1087
1088#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1089pub(crate) struct EcnCounts {
1090 pub ect0: u64,
1091 pub ect1: u64,
1092 pub ce: u64,
1093}
1094
1095impl std::ops::AddAssign<EcnCodepoint> for EcnCounts {
1096 fn add_assign(&mut self, rhs: EcnCodepoint) {
1097 match rhs {
1098 EcnCodepoint::Ect0 => {
1099 self.ect0 += 1;
1100 }
1101 EcnCodepoint::Ect1 => {
1102 self.ect1 += 1;
1103 }
1104 EcnCodepoint::Ce => {
1105 self.ce += 1;
1106 }
1107 }
1108 }
1109}
1110
1111impl EcnCounts {
1112 pub(crate) const ZERO: Self = Self {
1113 ect0: 0,
1114 ect1: 0,
1115 ce: 0,
1116 };
1117}
1118
1119impl Encodable for EcnCounts {
1120 fn encode<W: BufMut>(&self, out: &mut W) {
1121 out.write_var(self.ect0);
1122 out.write_var(self.ect1);
1123 out.write_var(self.ce);
1124 }
1125}
1126
1127#[derive(Debug, Clone)]
1128pub(crate) struct Stream {
1129 pub(crate) id: StreamId,
1130 pub(crate) offset: u64,
1131 pub(crate) fin: bool,
1132 pub(crate) data: Bytes,
1133}
1134
1135impl FrameStruct for Stream {
1136 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
1137}
1138
1139#[derive(Debug, Clone, derive_more::Display)]
1141#[display("STREAM id: {id} off: {} len: {} fin: {fin}", offsets.start, offsets.end - offsets.start)]
1142pub(crate) struct StreamMeta {
1143 pub(crate) id: StreamId,
1144 pub(crate) offsets: Range<u64>,
1145 pub(crate) fin: bool,
1146}
1147
1148impl Default for StreamMeta {
1150 fn default() -> Self {
1151 Self {
1152 id: StreamId(0),
1153 offsets: 0..0,
1154 fin: false,
1155 }
1156 }
1157}
1158
1159impl StreamMeta {
1160 pub(crate) fn encoder(self, encode_length: bool) -> StreamMetaEncoder {
1161 StreamMetaEncoder {
1162 meta: self,
1163 encode_length,
1164 }
1165 }
1166
1167 const fn get_type(&self, encode_length: bool) -> StreamInfo {
1168 let mut ty = *StreamInfo::VALUES.start();
1169 if self.offsets.start != 0 {
1170 ty |= 0x04;
1171 }
1172 if encode_length {
1173 ty |= 0x02;
1174 }
1175 if self.fin {
1176 ty |= 0x01;
1177 }
1178 StreamInfo(ty as u8)
1179 }
1180}
1181
1182#[derive(derive_more::Display)]
1183#[display("{meta}")]
1184pub(crate) struct StreamMetaEncoder {
1185 pub(crate) meta: StreamMeta,
1186 encode_length: bool,
1187}
1188
1189impl StreamMetaEncoder {
1190 const fn get_type(&self) -> FrameType {
1191 FrameType::Stream(self.meta.get_type(self.encode_length))
1192 }
1193}
1194
1195impl Encodable for StreamMetaEncoder {
1196 fn encode<W: BufMut>(&self, out: &mut W) {
1197 let Self {
1198 meta,
1199 encode_length,
1200 } = self;
1201 out.write_var(meta.get_type(*encode_length).0 as u64); out.write(meta.id); if meta.offsets.start != 0 {
1204 out.write_var(meta.offsets.start); }
1206 if *encode_length {
1207 out.write_var(meta.offsets.end - meta.offsets.start); }
1209 }
1210}
1211
1212pub(crate) type StreamMetaVec = TinyVec<[StreamMeta; 1]>;
1214
1215#[derive(Debug, Clone, derive_more::Display)]
1216#[display("CRYPTO off: {offset} len = {}", data.len())]
1217pub(crate) struct Crypto {
1218 pub(crate) offset: u64,
1219 pub(crate) data: Bytes,
1220}
1221
1222impl Crypto {
1223 pub(crate) const SIZE_BOUND: usize = 17;
1224
1225 const fn get_type(&self) -> FrameType {
1226 FrameType::Crypto
1227 }
1228}
1229
1230impl Encodable for Crypto {
1231 fn encode<W: BufMut>(&self, out: &mut W) {
1232 out.write(FrameType::Crypto);
1233 out.write_var(self.offset);
1234 out.write_var(self.data.len() as u64);
1235 out.put_slice(&self.data);
1236 }
1237}
1238
1239#[derive(Debug, Clone, derive_more::Display)]
1240#[display("NEW_TOKEN")]
1241pub(crate) struct NewToken {
1242 pub(crate) token: Bytes,
1243}
1244
1245impl Encodable for NewToken {
1246 fn encode<W: BufMut>(&self, out: &mut W) {
1247 out.write(FrameType::NewToken);
1248 out.write_var(self.token.len() as u64);
1249 out.put_slice(&self.token);
1250 }
1251}
1252
1253impl NewToken {
1254 pub(crate) fn size(&self) -> usize {
1255 1 + VarInt::from_u64(self.token.len() as u64).unwrap().size() + self.token.len()
1256 }
1257
1258 const fn get_type(&self) -> FrameType {
1259 FrameType::NewToken
1260 }
1261}
1262
1263#[derive(Debug, Clone, derive_more::Display)]
1264#[display("MAX_PATH_ID path_id: {_0}")]
1265pub(crate) struct MaxPathId(pub(crate) PathId);
1266
1267impl MaxPathId {
1268 pub(crate) const SIZE_BOUND: usize =
1269 FrameType::MaxPathId.size() + VarInt(u32::MAX as u64).size();
1270
1271 const fn get_type(&self) -> FrameType {
1272 FrameType::MaxPathId
1273 }
1274}
1275
1276impl Decodable for MaxPathId {
1277 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
1278 Ok(Self(buf.get()?))
1279 }
1280}
1281
1282impl Encodable for MaxPathId {
1283 fn encode<B: BufMut>(&self, buf: &mut B) {
1284 buf.write(FrameType::MaxPathId);
1285 buf.write(self.0);
1286 }
1287}
1288
1289#[derive(Debug, Clone, PartialEq, Eq, derive_more::Display)]
1290#[display("PATHS_BLOCKED remote_max_path_id: {_0}")]
1291pub(crate) struct PathsBlocked(pub(crate) PathId);
1292
1293impl PathsBlocked {
1294 pub(crate) const SIZE_BOUND: usize =
1295 FrameType::PathsBlocked.size() + VarInt(u32::MAX as u64).size();
1296
1297 const fn get_type(&self) -> FrameType {
1298 FrameType::PathsBlocked
1299 }
1300}
1301
1302impl Encodable for PathsBlocked {
1303 fn encode<B: BufMut>(&self, buf: &mut B) {
1304 buf.write(FrameType::PathsBlocked);
1305 buf.write(self.0);
1306 }
1307}
1308
1309impl Decodable for PathsBlocked {
1310 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
1312 Ok(Self(buf.get()?))
1313 }
1314}
1315
1316#[derive(Debug, Clone, PartialEq, Eq, derive_more::Display)]
1317#[display("PATH_CIDS_BLOCKED path_id: {path_id} next_seq: {next_seq}")]
1318pub(crate) struct PathCidsBlocked {
1319 pub(crate) path_id: PathId,
1320 pub(crate) next_seq: VarInt,
1321}
1322
1323impl PathCidsBlocked {
1324 pub(crate) const SIZE_BOUND: usize =
1325 FrameType::PathCidsBlocked.size() + VarInt(u32::MAX as u64).size() + VarInt::MAX.size();
1326
1327 const fn get_type(&self) -> FrameType {
1328 FrameType::PathCidsBlocked
1329 }
1330}
1331
1332impl Decodable for PathCidsBlocked {
1333 fn decode<R: Buf>(buf: &mut R) -> coding::Result<Self> {
1334 Ok(Self {
1335 path_id: buf.get()?,
1336 next_seq: buf.get()?,
1337 })
1338 }
1339}
1340
1341impl Encodable for PathCidsBlocked {
1342 fn encode<W: BufMut>(&self, buf: &mut W) {
1343 buf.write(FrameType::PathCidsBlocked);
1344 buf.write(self.path_id);
1345 buf.write(self.next_seq);
1346 }
1347}
1348
1349pub(crate) struct Iter {
1350 bytes: Bytes,
1351 last_ty: MaybeFrame,
1352}
1353
1354impl Iter {
1355 pub(crate) fn new(payload: Bytes) -> Result<Self, TransportError> {
1356 if payload.is_empty() {
1357 return Err(TransportError::PROTOCOL_VIOLATION(
1361 "packet payload is empty",
1362 ));
1363 }
1364
1365 Ok(Self {
1366 bytes: payload,
1367 last_ty: MaybeFrame::None,
1368 })
1369 }
1370
1371 fn take_len(&mut self) -> Result<Bytes, UnexpectedEnd> {
1372 let len = self.bytes.get_var()?;
1373 if len > self.bytes.remaining() as u64 {
1374 return Err(UnexpectedEnd);
1375 }
1376 Ok(self.bytes.split_to(len as usize))
1377 }
1378
1379 #[track_caller]
1380 fn try_next(&mut self) -> Result<Frame, IterErr> {
1381 self.last_ty = self.bytes.get()?;
1382
1383 let ty = match self.last_ty {
1384 MaybeFrame::None => FrameType::Padding,
1385 MaybeFrame::Unknown(_other) => return Err(IterErr::InvalidFrameId),
1386 MaybeFrame::Known(frame_type) => frame_type,
1387 };
1388 Ok(match ty {
1389 FrameType::Padding => Frame::Padding,
1390 FrameType::ResetStream => Frame::ResetStream(ResetStream {
1391 id: self.bytes.get()?,
1392 error_code: self.bytes.get()?,
1393 final_offset: self.bytes.get()?,
1394 }),
1395 FrameType::ConnectionClose => Frame::Close(Close::Connection(ConnectionClose {
1396 error_code: self.bytes.get()?,
1397 frame_type: self.bytes.get()?,
1398 reason: self.take_len()?,
1399 })),
1400 FrameType::ApplicationClose => Frame::Close(Close::Application(ApplicationClose {
1401 error_code: self.bytes.get()?,
1402 reason: self.take_len()?,
1403 })),
1404 FrameType::MaxData => Frame::MaxData(self.bytes.get()?),
1405 FrameType::MaxStreamData => Frame::MaxStreamData(self.bytes.get()?),
1406 FrameType::MaxStreamsBidi => Frame::MaxStreams(MaxStreams {
1407 dir: Dir::Bi,
1408 count: self.bytes.get_var()?,
1409 }),
1410 FrameType::MaxStreamsUni => Frame::MaxStreams(MaxStreams {
1411 dir: Dir::Uni,
1412 count: self.bytes.get_var()?,
1413 }),
1414 FrameType::Ping => Frame::Ping,
1415 FrameType::DataBlocked => Frame::DataBlocked {
1416 offset: self.bytes.get_var()?,
1417 },
1418 FrameType::StreamDataBlocked => Frame::StreamDataBlocked {
1419 id: self.bytes.get()?,
1420 offset: self.bytes.get_var()?,
1421 },
1422 FrameType::StreamsBlockedBidi => Frame::StreamsBlocked {
1423 dir: Dir::Bi,
1424 limit: self.bytes.get_var()?,
1425 },
1426 FrameType::StreamsBlockedUni => Frame::StreamsBlocked {
1427 dir: Dir::Uni,
1428 limit: self.bytes.get_var()?,
1429 },
1430 FrameType::StopSending => Frame::StopSending(StopSending {
1431 id: self.bytes.get()?,
1432 error_code: self.bytes.get()?,
1433 }),
1434 FrameType::RetireConnectionId | FrameType::PathRetireConnectionId => {
1435 Frame::RetireConnectionId(RetireConnectionId::decode(
1436 &mut self.bytes,
1437 ty == FrameType::PathRetireConnectionId,
1438 )?)
1439 }
1440 FrameType::Ack | FrameType::AckEcn => {
1441 let largest = self.bytes.get_var()?;
1442 let delay = self.bytes.get_var()?;
1443 let extra_blocks = self.bytes.get_var()? as usize;
1444 let n = scan_ack_blocks(&self.bytes, largest, extra_blocks)?;
1445 Frame::Ack(Ack {
1446 delay,
1447 largest,
1448 additional: self.bytes.split_to(n),
1449 ecn: if ty != FrameType::AckEcn && ty != FrameType::PathAckEcn {
1450 None
1451 } else {
1452 Some(EcnCounts {
1453 ect0: self.bytes.get_var()?,
1454 ect1: self.bytes.get_var()?,
1455 ce: self.bytes.get_var()?,
1456 })
1457 },
1458 })
1459 }
1460 FrameType::PathAck | FrameType::PathAckEcn => {
1461 let path_id = self.bytes.get()?;
1462 let largest = self.bytes.get_var()?;
1463 let delay = self.bytes.get_var()?;
1464 let extra_blocks = self.bytes.get_var()? as usize;
1465 let n = scan_ack_blocks(&self.bytes, largest, extra_blocks)?;
1466 Frame::PathAck(PathAck {
1467 path_id,
1468 delay,
1469 largest,
1470 additional: self.bytes.split_to(n),
1471 ecn: if ty != FrameType::AckEcn && ty != FrameType::PathAckEcn {
1472 None
1473 } else {
1474 Some(EcnCounts {
1475 ect0: self.bytes.get_var()?,
1476 ect1: self.bytes.get_var()?,
1477 ce: self.bytes.get_var()?,
1478 })
1479 },
1480 })
1481 }
1482 FrameType::PathChallenge => Frame::PathChallenge(self.bytes.get()?),
1483 FrameType::PathResponse => Frame::PathResponse(self.bytes.get()?),
1484 FrameType::NewConnectionId | FrameType::PathNewConnectionId => {
1485 let read_path = ty == FrameType::PathNewConnectionId;
1486 Frame::NewConnectionId(NewConnectionId::read(&mut self.bytes, read_path)?)
1487 }
1488 FrameType::Crypto => Frame::Crypto(Crypto {
1489 offset: self.bytes.get_var()?,
1490 data: self.take_len()?,
1491 }),
1492 FrameType::NewToken => Frame::NewToken(NewToken {
1493 token: self.take_len()?,
1494 }),
1495 FrameType::HandshakeDone => Frame::HandshakeDone,
1496 FrameType::AckFrequency => Frame::AckFrequency(AckFrequency {
1497 sequence: self.bytes.get()?,
1498 ack_eliciting_threshold: self.bytes.get()?,
1499 request_max_ack_delay: self.bytes.get()?,
1500 reordering_threshold: self.bytes.get()?,
1501 }),
1502 FrameType::ImmediateAck => Frame::ImmediateAck,
1503 FrameType::ObservedIpv4Addr | FrameType::ObservedIpv6Addr => {
1504 let is_ipv6 = ty == FrameType::ObservedIpv6Addr;
1505 let observed = ObservedAddr::read(&mut self.bytes, is_ipv6)?;
1506 Frame::ObservedAddr(observed)
1507 }
1508 FrameType::PathAbandon => Frame::PathAbandon(PathAbandon::decode(&mut self.bytes)?),
1509 FrameType::PathStatusAvailable => {
1510 Frame::PathStatusAvailable(PathStatusAvailable::decode(&mut self.bytes)?)
1511 }
1512 FrameType::PathStatusBackup => {
1513 Frame::PathStatusBackup(PathStatusBackup::decode(&mut self.bytes)?)
1514 }
1515 FrameType::MaxPathId => Frame::MaxPathId(MaxPathId::decode(&mut self.bytes)?),
1516 FrameType::PathsBlocked => Frame::PathsBlocked(PathsBlocked::decode(&mut self.bytes)?),
1517 FrameType::PathCidsBlocked => {
1518 Frame::PathCidsBlocked(PathCidsBlocked::decode(&mut self.bytes)?)
1519 }
1520 FrameType::AddIpv4Address | FrameType::AddIpv6Address => {
1521 let is_ipv6 = ty == FrameType::AddIpv6Address;
1522 let add_address = AddAddress::read(&mut self.bytes, is_ipv6)?;
1523 Frame::AddAddress(add_address)
1524 }
1525 FrameType::ReachOutAtIpv4 | FrameType::ReachOutAtIpv6 => {
1526 let is_ipv6 = ty == FrameType::ReachOutAtIpv6;
1527 let reach_out = ReachOut::read(&mut self.bytes, is_ipv6)?;
1528 Frame::ReachOut(reach_out)
1529 }
1530 FrameType::RemoveAddress => Frame::RemoveAddress(RemoveAddress::read(&mut self.bytes)?),
1531 FrameType::Stream(s) => Frame::Stream(Stream {
1532 id: self.bytes.get()?,
1533 offset: if s.off() { self.bytes.get_var()? } else { 0 },
1534 fin: s.fin(),
1535 data: if s.len() {
1536 self.take_len()?
1537 } else {
1538 self.take_remaining()
1539 },
1540 }),
1541 FrameType::Datagram(d) => Frame::Datagram(Datagram {
1542 data: if d.len() {
1543 self.take_len()?
1544 } else {
1545 self.take_remaining()
1546 },
1547 }),
1548 })
1549 }
1550
1551 fn take_remaining(&mut self) -> Bytes {
1552 mem::take(&mut self.bytes)
1553 }
1554}
1555
1556impl Iterator for Iter {
1557 type Item = Result<Frame, InvalidFrame>;
1558 fn next(&mut self) -> Option<Self::Item> {
1559 if !self.bytes.has_remaining() {
1560 return None;
1561 }
1562 match self.try_next() {
1563 Ok(x) => Some(Ok(x)),
1564 Err(e) => {
1565 self.bytes.clear();
1567 Some(Err(InvalidFrame {
1568 ty: self.last_ty,
1569 reason: e.reason(),
1570 }))
1571 }
1572 }
1573 }
1574}
1575
1576#[derive(Debug)]
1577pub(crate) struct InvalidFrame {
1578 pub(crate) ty: MaybeFrame,
1579 pub(crate) reason: &'static str,
1580}
1581
1582impl From<InvalidFrame> for TransportError {
1583 fn from(err: InvalidFrame) -> Self {
1584 let mut te = Self::FRAME_ENCODING_ERROR(err.reason);
1585 te.frame = err.ty;
1586 te
1587 }
1588}
1589
1590fn scan_ack_blocks(mut buf: &[u8], largest: u64, n: usize) -> Result<usize, IterErr> {
1592 let total_len = buf.remaining();
1593 let first_block = buf.get_var()?;
1594 let mut smallest = largest.checked_sub(first_block).ok_or(IterErr::Malformed)?;
1595 for _ in 0..n {
1596 let gap = buf.get_var()?;
1597 smallest = smallest.checked_sub(gap + 2).ok_or(IterErr::Malformed)?;
1598 let block = buf.get_var()?;
1599 smallest = smallest.checked_sub(block).ok_or(IterErr::Malformed)?;
1600 }
1601 Ok(total_len - buf.remaining())
1602}
1603
1604#[derive(Debug)]
1605enum IterErr {
1606 UnexpectedEnd,
1607 InvalidFrameId,
1608 Malformed,
1609}
1610
1611impl IterErr {
1612 fn reason(&self) -> &'static str {
1613 use IterErr::*;
1614 match *self {
1615 UnexpectedEnd => "unexpected end",
1616 InvalidFrameId => "invalid frame ID",
1617 Malformed => "malformed",
1618 }
1619 }
1620}
1621
1622impl From<UnexpectedEnd> for IterErr {
1623 fn from(_: UnexpectedEnd) -> Self {
1624 Self::UnexpectedEnd
1625 }
1626}
1627
1628#[derive(Debug, Clone)]
1629pub(crate) struct AckIter<'a> {
1630 largest: u64,
1631 data: &'a [u8],
1632}
1633
1634impl<'a> AckIter<'a> {
1635 fn new(largest: u64, data: &'a [u8]) -> Self {
1636 Self { largest, data }
1637 }
1638}
1639
1640impl Iterator for AckIter<'_> {
1641 type Item = RangeInclusive<u64>;
1642 fn next(&mut self) -> Option<RangeInclusive<u64>> {
1643 if !self.data.has_remaining() {
1644 return None;
1645 }
1646 let block = self.data.get_var().unwrap();
1647 let largest = self.largest;
1648 if let Ok(gap) = self.data.get_var() {
1649 self.largest -= block + gap + 2;
1650 }
1651 Some(largest - block..=largest)
1652 }
1653}
1654
1655#[allow(unreachable_pub)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1657#[derive(Debug, Copy, Clone, derive_more::Display)]
1658#[display("RESET_STREAM id: {id}")]
1659pub struct ResetStream {
1660 pub(crate) id: StreamId,
1661 pub(crate) error_code: VarInt,
1662 pub(crate) final_offset: VarInt,
1663}
1664
1665impl ResetStream {
1666 const fn get_type(&self) -> FrameType {
1667 FrameType::ResetStream
1668 }
1669}
1670
1671impl FrameStruct for ResetStream {
1672 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
1673}
1674
1675impl Encodable for ResetStream {
1676 fn encode<W: BufMut>(&self, out: &mut W) {
1677 out.write(FrameType::ResetStream); out.write(self.id); out.write(self.error_code); out.write(self.final_offset); }
1682}
1683
1684#[derive(Debug, Copy, Clone, derive_more::Display)]
1685#[display("STOP_SENDING id: {id}")]
1686pub(crate) struct StopSending {
1687 pub(crate) id: StreamId,
1688 pub(crate) error_code: VarInt,
1689}
1690
1691impl FrameStruct for StopSending {
1692 const SIZE_BOUND: usize = 1 + 8 + 8;
1693}
1694
1695impl StopSending {
1696 const fn get_type(&self) -> FrameType {
1697 FrameType::StopSending
1698 }
1699}
1700
1701impl Encodable for StopSending {
1702 fn encode<W: BufMut>(&self, out: &mut W) {
1703 out.write(FrameType::StopSending); out.write(self.id); out.write(self.error_code) }
1707}
1708
1709#[derive(Debug, Copy, Clone, PartialEq, Eq, derive_more::Display)]
1710#[display("{} {} seq: {sequence} id: {id}", self.get_type(), DisplayOption::new("path_id", path_id.as_ref()))]
1711pub(crate) struct NewConnectionId {
1712 pub(crate) path_id: Option<PathId>,
1713 pub(crate) sequence: u64,
1714 pub(crate) retire_prior_to: u64,
1715 pub(crate) id: ConnectionId,
1716 pub(crate) reset_token: ResetToken,
1717}
1718
1719impl NewConnectionId {
1720 pub(crate) const SIZE_BOUND: usize = {
1722 let type_len = FrameType::NewConnectionId.size();
1723 let seq_max_len = 8usize;
1724 let retire_prior_to_max_len = 8usize;
1725 let cid_len_len = 1;
1726 let cid_len = 160;
1727 let reset_token_len = 16;
1728 type_len + seq_max_len + retire_prior_to_max_len + cid_len_len + cid_len + reset_token_len
1729 };
1730
1731 pub(crate) const SIZE_BOUND_MULTIPATH: usize = {
1733 let type_len = FrameType::PathNewConnectionId.size();
1734 let path_id_len = VarInt::from_u32(u32::MAX).size();
1735 let seq_max_len = 8usize;
1736 let retire_prior_to_max_len = 8usize;
1737 let cid_len_len = 1;
1738 let cid_len = 160;
1739 let reset_token_len = 16;
1740 type_len
1741 + path_id_len
1742 + seq_max_len
1743 + retire_prior_to_max_len
1744 + cid_len_len
1745 + cid_len
1746 + reset_token_len
1747 };
1748
1749 const fn get_type(&self) -> FrameType {
1750 if self.path_id.is_some() {
1751 FrameType::PathNewConnectionId
1752 } else {
1753 FrameType::NewConnectionId
1754 }
1755 }
1756
1757 pub(crate) const fn size_bound(path_new_cid: bool, cid_len: usize) -> usize {
1761 let upper_bound = match path_new_cid {
1762 true => Self::SIZE_BOUND_MULTIPATH,
1763 false => Self::SIZE_BOUND,
1764 };
1765 upper_bound - 160 + cid_len
1767 }
1768
1769 fn read<R: Buf>(bytes: &mut R, read_path: bool) -> Result<Self, IterErr> {
1770 let path_id = if read_path { Some(bytes.get()?) } else { None };
1771 let sequence = bytes.get_var()?;
1772 let retire_prior_to = bytes.get_var()?;
1773 if retire_prior_to > sequence {
1774 return Err(IterErr::Malformed);
1775 }
1776 let length = bytes.get::<u8>()? as usize;
1777 if length > MAX_CID_SIZE || length == 0 {
1778 return Err(IterErr::Malformed);
1779 }
1780 if length > bytes.remaining() {
1781 return Err(IterErr::UnexpectedEnd);
1782 }
1783 let mut stage = [0; MAX_CID_SIZE];
1784 bytes.copy_to_slice(&mut stage[0..length]);
1785 let id = ConnectionId::new(&stage[..length]);
1786 if bytes.remaining() < 16 {
1787 return Err(IterErr::UnexpectedEnd);
1788 }
1789 let mut reset_token = [0; RESET_TOKEN_SIZE];
1790 bytes.copy_to_slice(&mut reset_token);
1791 Ok(Self {
1792 path_id,
1793 sequence,
1794 retire_prior_to,
1795 id,
1796 reset_token: reset_token.into(),
1797 })
1798 }
1799
1800 pub(crate) fn issued(&self) -> crate::shared::IssuedCid {
1801 crate::shared::IssuedCid {
1802 path_id: self.path_id.unwrap_or_default(),
1803 sequence: self.sequence,
1804 id: self.id,
1805 reset_token: self.reset_token,
1806 }
1807 }
1808}
1809
1810impl Encodable for NewConnectionId {
1811 fn encode<W: BufMut>(&self, out: &mut W) {
1812 out.write(self.get_type());
1813 if let Some(id) = self.path_id {
1814 out.write(id);
1815 }
1816 out.write_var(self.sequence);
1817 out.write_var(self.retire_prior_to);
1818 out.write(self.id.len() as u8);
1819 out.put_slice(&self.id);
1820 out.put_slice(&self.reset_token);
1821 }
1822}
1823
1824impl FrameStruct for NewConnectionId {
1825 const SIZE_BOUND: usize = 1 + 8 + 8 + 1 + MAX_CID_SIZE + RESET_TOKEN_SIZE;
1826}
1827
1828#[derive(Debug, Clone, derive_more::Display)]
1830#[display("DATAGRAM len: {}", data.len())]
1831pub struct Datagram {
1832 pub data: Bytes,
1834}
1835
1836impl FrameStruct for Datagram {
1837 const SIZE_BOUND: usize = 1 + 8;
1838}
1839
1840impl Datagram {
1841 pub(crate) fn size(&self, length: bool) -> usize {
1842 1 + if length {
1843 VarInt::from_u64(self.data.len() as u64).unwrap().size()
1844 } else {
1845 0
1846 } + self.data.len()
1847 }
1848
1849 const fn get_type(&self) -> FrameType {
1850 FrameType::Datagram(DatagramInfo(*DatagramInfo::VALUES.start() as u8))
1851 }
1852}
1853
1854impl Encodable for Datagram {
1855 fn encode<B: BufMut>(&self, out: &mut B) {
1856 const ENCODE_LEN: bool = true;
1858 out.write(FrameType::Datagram(DatagramInfo(
1859 *DatagramInfo::VALUES.start() as u8 | u8::from(ENCODE_LEN),
1860 ))); out.write(VarInt::from_u64(self.data.len() as u64).unwrap()); out.put_slice(&self.data);
1864 }
1865}
1866
1867#[derive(Debug, Copy, Clone, PartialEq, Eq, derive_more::Display)]
1868#[display("ACK_FREQUENCY max_ack_delay: {}µs", request_max_ack_delay.0)]
1869pub(crate) struct AckFrequency {
1870 pub(crate) sequence: VarInt,
1871 pub(crate) ack_eliciting_threshold: VarInt,
1872 pub(crate) request_max_ack_delay: VarInt,
1873 pub(crate) reordering_threshold: VarInt,
1874}
1875
1876impl AckFrequency {
1877 const fn get_type(&self) -> FrameType {
1878 FrameType::AckFrequency
1879 }
1880}
1881
1882impl Encodable for AckFrequency {
1883 fn encode<W: BufMut>(&self, buf: &mut W) {
1884 buf.write(FrameType::AckFrequency);
1885 buf.write(self.sequence);
1886 buf.write(self.ack_eliciting_threshold);
1887 buf.write(self.request_max_ack_delay);
1888 buf.write(self.reordering_threshold);
1889 }
1890}
1891
1892#[derive(Debug, PartialEq, Eq, Clone, derive_more::Display)]
1897#[display("{} seq_no: {seq_no} addr: {}", self.get_type(), self.socket_addr())]
1898pub(crate) struct ObservedAddr {
1899 pub(crate) seq_no: VarInt,
1901 pub(crate) ip: IpAddr,
1903 pub(crate) port: u16,
1905}
1906
1907impl ObservedAddr {
1908 pub(crate) fn new<N: Into<VarInt>>(remote: std::net::SocketAddr, seq_no: N) -> Self {
1909 Self {
1910 ip: remote.ip(),
1911 port: remote.port(),
1912 seq_no: seq_no.into(),
1913 }
1914 }
1915
1916 const fn get_type(&self) -> FrameType {
1918 if self.ip.is_ipv6() {
1919 FrameType::ObservedIpv6Addr
1920 } else {
1921 FrameType::ObservedIpv4Addr
1922 }
1923 }
1924
1925 pub(crate) fn size(&self) -> usize {
1927 let type_size = self.get_type().size();
1928 let req_id_bytes = self.seq_no.size();
1929 let ip_bytes = if self.ip.is_ipv6() { 16 } else { 4 };
1930 let port_bytes = 2;
1931 type_size + req_id_bytes + ip_bytes + port_bytes
1932 }
1933
1934 pub(crate) fn read<R: Buf>(bytes: &mut R, is_ipv6: bool) -> coding::Result<Self> {
1939 let seq_no = bytes.get()?;
1940 let ip = if is_ipv6 {
1941 IpAddr::V6(bytes.get()?)
1942 } else {
1943 IpAddr::V4(bytes.get()?)
1944 };
1945 let port = bytes.get()?;
1946 Ok(Self { seq_no, ip, port })
1947 }
1948
1949 pub(crate) fn socket_addr(&self) -> SocketAddr {
1951 (self.ip, self.port).into()
1952 }
1953}
1954
1955impl Encodable for ObservedAddr {
1956 fn encode<W: BufMut>(&self, buf: &mut W) {
1957 buf.write(self.get_type());
1958 buf.write(self.seq_no);
1959 match self.ip {
1960 IpAddr::V4(ipv4_addr) => {
1961 buf.write(ipv4_addr);
1962 }
1963 IpAddr::V6(ipv6_addr) => {
1964 buf.write(ipv6_addr);
1965 }
1966 }
1967 buf.write::<u16>(self.port);
1968 }
1969}
1970
1971#[derive(Debug, PartialEq, Eq, derive_more::Display)]
1974#[display("PATH_ABANDON path_id: {path_id}")]
1975pub(crate) struct PathAbandon {
1976 pub(crate) path_id: PathId,
1977 pub(crate) error_code: TransportErrorCode,
1978}
1979
1980impl PathAbandon {
1981 pub(crate) const SIZE_BOUND: usize = FrameType::PathAbandon.size() + 8 + 8;
1982
1983 const fn get_type(&self) -> FrameType {
1984 FrameType::PathAbandon
1985 }
1986}
1987
1988impl Encodable for PathAbandon {
1989 fn encode<W: BufMut>(&self, buf: &mut W) {
1990 buf.write(FrameType::PathAbandon);
1991 buf.write(self.path_id);
1992 buf.write(self.error_code);
1993 }
1994}
1995
1996impl Decodable for PathAbandon {
1997 fn decode<R: Buf>(bytes: &mut R) -> coding::Result<Self> {
1998 Ok(Self {
1999 path_id: bytes.get()?,
2000 error_code: bytes.get()?,
2001 })
2002 }
2003}
2004
2005#[derive(Debug, PartialEq, Eq, derive_more::Display)]
2006#[display("PATH_STATUS_AVAILABLE path_id: {path_id} seq_no: {status_seq_no}")]
2007pub(crate) struct PathStatusAvailable {
2008 pub(crate) path_id: PathId,
2009 pub(crate) status_seq_no: VarInt,
2010}
2011
2012impl PathStatusAvailable {
2013 const TYPE: FrameType = FrameType::PathStatusAvailable;
2014 pub(crate) const SIZE_BOUND: usize = FrameType::PathStatusAvailable.size() + 8 + 8;
2015
2016 const fn get_type(&self) -> FrameType {
2017 FrameType::PathStatusAvailable
2018 }
2019}
2020
2021impl Encodable for PathStatusAvailable {
2022 fn encode<W: BufMut>(&self, buf: &mut W) {
2023 buf.write(Self::TYPE);
2024 buf.write(self.path_id);
2025 buf.write(self.status_seq_no);
2026 }
2027}
2028
2029impl Decodable for PathStatusAvailable {
2030 fn decode<R: Buf>(bytes: &mut R) -> coding::Result<Self> {
2031 Ok(Self {
2032 path_id: bytes.get()?,
2033 status_seq_no: bytes.get()?,
2034 })
2035 }
2036}
2037
2038#[derive(Debug, PartialEq, Eq, derive_more::Display)]
2039#[display("PATH_STATUS_BACKUP path_id: {path_id} seq_no: {status_seq_no}")]
2040pub(crate) struct PathStatusBackup {
2041 pub(crate) path_id: PathId,
2042 pub(crate) status_seq_no: VarInt,
2043}
2044
2045impl PathStatusBackup {
2046 const TYPE: FrameType = FrameType::PathStatusBackup;
2047
2048 const fn get_type(&self) -> FrameType {
2049 FrameType::PathStatusBackup
2050 }
2051}
2052
2053impl Encodable for PathStatusBackup {
2054 fn encode<W: BufMut>(&self, buf: &mut W) {
2055 buf.write(Self::TYPE);
2056 buf.write(self.path_id);
2057 buf.write(self.status_seq_no);
2058 }
2059}
2060
2061impl Decodable for PathStatusBackup {
2062 fn decode<R: Buf>(bytes: &mut R) -> coding::Result<Self> {
2063 Ok(Self {
2064 path_id: bytes.get()?,
2065 status_seq_no: bytes.get()?,
2066 })
2067 }
2068}
2069
2070#[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord, derive_more::Display)]
2075#[display("{} seq_no: {seq_no} addr: {}", self.get_type(), self.socket_addr())]
2076pub(crate) struct AddAddress {
2077 pub(crate) seq_no: VarInt,
2080 pub(crate) ip: IpAddr,
2082 pub(crate) port: u16,
2084}
2085
2086#[allow(dead_code)]
2088impl AddAddress {
2089 pub(crate) const SIZE_BOUND: usize = Self {
2091 ip: IpAddr::V6(std::net::Ipv6Addr::LOCALHOST),
2092 port: u16::MAX,
2093 seq_no: VarInt::MAX,
2094 }
2095 .size();
2096
2097 pub(crate) const fn new((ip, port): (IpAddr, u16), seq_no: VarInt) -> Self {
2098 Self { ip, port, seq_no }
2099 }
2100
2101 const fn get_type(&self) -> FrameType {
2103 if self.ip.is_ipv6() {
2104 FrameType::AddIpv6Address
2105 } else {
2106 FrameType::AddIpv4Address
2107 }
2108 }
2109
2110 pub(crate) const fn size(&self) -> usize {
2112 let type_size = self.get_type().size();
2113 let seq_no_bytes = self.seq_no.size();
2114 let ip_bytes = if self.ip.is_ipv6() { 16 } else { 4 };
2115 let port_bytes = 2;
2116 type_size + seq_no_bytes + ip_bytes + port_bytes
2117 }
2118
2119 pub(crate) fn read<R: Buf>(bytes: &mut R, is_ipv6: bool) -> coding::Result<Self> {
2124 let seq_no = bytes.get()?;
2125 let ip = if is_ipv6 {
2126 IpAddr::V6(bytes.get()?)
2127 } else {
2128 IpAddr::V4(bytes.get()?)
2129 };
2130 let port = bytes.get()?;
2131 Ok(Self { seq_no, ip, port })
2132 }
2133
2134 pub(crate) fn socket_addr(&self) -> SocketAddr {
2136 self.ip_port().into()
2137 }
2138
2139 pub(crate) fn ip_port(&self) -> (IpAddr, u16) {
2140 (self.ip, self.port)
2141 }
2142}
2143
2144impl Encodable for AddAddress {
2145 fn encode<W: BufMut>(&self, buf: &mut W) {
2146 buf.write(self.get_type());
2147 buf.write(self.seq_no);
2148 match self.ip {
2149 IpAddr::V4(ipv4_addr) => {
2150 buf.write(ipv4_addr);
2151 }
2152 IpAddr::V6(ipv6_addr) => {
2153 buf.write(ipv6_addr);
2154 }
2155 }
2156 buf.write::<u16>(self.port);
2157 }
2158}
2159
2160#[derive(Debug, PartialEq, Eq, Clone, derive_more::Display)]
2163#[display("REACH_OUT round: {round} local_addr: {}", self.socket_addr())]
2164pub(crate) struct ReachOut {
2165 pub(crate) round: VarInt,
2167 pub(crate) ip: IpAddr,
2169 pub(crate) port: u16,
2171}
2172
2173#[allow(dead_code)]
2175impl ReachOut {
2176 pub(crate) const SIZE_BOUND: usize = Self {
2178 round: VarInt::MAX,
2179 ip: IpAddr::V6(std::net::Ipv6Addr::LOCALHOST),
2180 port: u16::MAX,
2181 }
2182 .size();
2183
2184 pub(crate) const fn new(round: VarInt, (ip, port): (IpAddr, u16)) -> Self {
2185 Self { round, ip, port }
2186 }
2187
2188 pub(crate) const fn get_type(&self) -> FrameType {
2190 if self.ip.is_ipv6() {
2191 FrameType::ReachOutAtIpv6
2192 } else {
2193 FrameType::ReachOutAtIpv4
2194 }
2195 }
2196
2197 pub(crate) const fn size(&self) -> usize {
2199 let type_size = self.get_type().size();
2200 let round_bytes = self.round.size();
2201 let ip_bytes = if self.ip.is_ipv6() { 16 } else { 4 };
2202 let port_bytes = 2;
2203 type_size + round_bytes + ip_bytes + port_bytes
2204 }
2205
2206 pub(crate) fn read<R: Buf>(bytes: &mut R, is_ipv6: bool) -> coding::Result<Self> {
2211 let round = bytes.get()?;
2212 let ip = if is_ipv6 {
2213 IpAddr::V6(bytes.get()?)
2214 } else {
2215 IpAddr::V4(bytes.get()?)
2216 };
2217 let port = bytes.get()?;
2218 Ok(Self { round, ip, port })
2219 }
2220
2221 pub(crate) fn socket_addr(&self) -> SocketAddr {
2223 (self.ip, self.port).into()
2224 }
2225}
2226
2227impl Encodable for ReachOut {
2228 fn encode<W: BufMut>(&self, buf: &mut W) {
2229 buf.write(self.get_type());
2230 buf.write(self.round);
2231 match self.ip {
2232 IpAddr::V4(ipv4_addr) => {
2233 buf.write(ipv4_addr);
2234 }
2235 IpAddr::V6(ipv6_addr) => {
2236 buf.write(ipv6_addr);
2237 }
2238 }
2239 buf.write::<u16>(self.port);
2240 }
2241}
2242
2243#[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord, derive_more::Display)]
2245#[display("REMOVE_ADDRESS seq_no: {seq_no}")]
2246pub(crate) struct RemoveAddress {
2247 pub(crate) seq_no: VarInt,
2249}
2250
2251#[allow(dead_code)]
2253impl RemoveAddress {
2254 pub(crate) const TYPE: FrameType = FrameType::RemoveAddress;
2256
2257 pub(crate) const SIZE_BOUND: usize = Self::new(VarInt::MAX).size();
2259
2260 pub(crate) const fn new(seq_no: VarInt) -> Self {
2261 Self { seq_no }
2262 }
2263
2264 pub(crate) const fn size(&self) -> usize {
2266 let type_size = Self::TYPE.size();
2267 let seq_no_bytes = self.seq_no.size();
2268 type_size + seq_no_bytes
2269 }
2270
2271 pub(crate) fn read<R: Buf>(bytes: &mut R) -> coding::Result<Self> {
2276 Ok(Self {
2277 seq_no: bytes.get()?,
2278 })
2279 }
2280
2281 const fn get_type(&self) -> FrameType {
2282 FrameType::RemoveAddress
2283 }
2284}
2285
2286impl Encodable for RemoveAddress {
2287 fn encode<W: BufMut>(&self, buf: &mut W) {
2288 buf.write(Self::TYPE);
2289 buf.write(self.seq_no);
2290 }
2291}
2292
2293struct DisplayOption<T: Display> {
2297 field_name: &'static str,
2298 op: Option<T>,
2299}
2300
2301impl<T: Display> DisplayOption<T> {
2302 fn new(field_name: &'static str, op: Option<T>) -> Self {
2303 Self { field_name, op }
2304 }
2305}
2306
2307impl<T: Display> Display for DisplayOption<T> {
2308 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2309 if let Some(x) = self.op.as_ref() {
2310 write!(f, "{}: {x}", self.field_name)
2311 } else {
2312 fmt::Result::Ok(())
2313 }
2314 }
2315}
2316
2317#[cfg(test)]
2318mod test {
2319 use super::*;
2320 use crate::coding::Encodable;
2321 use assert_matches::assert_matches;
2322
2323 #[test]
2324 fn frame_type() {
2325 assert_eq!(
2326 FrameType::try_from(FrameType::Padding.to_u64()),
2327 Ok(FrameType::Padding),
2328 );
2329
2330 assert_eq!(
2331 FrameType::try_from(FrameType::Datagram(DatagramInfo(0x30)).to_u64()),
2332 Ok(FrameType::Datagram(DatagramInfo(0x30))),
2333 );
2334
2335 assert_eq!(
2336 FrameType::try_from(FrameType::Stream(StreamInfo(0x08)).to_u64()),
2337 Ok(FrameType::Stream(StreamInfo(0x08))),
2338 );
2339 }
2340
2341 #[track_caller]
2342 fn frames(buf: Vec<u8>) -> Vec<Frame> {
2343 Iter::new(Bytes::from(buf))
2344 .unwrap()
2345 .collect::<Result<Vec<_>, _>>()
2346 .unwrap()
2347 }
2348
2349 #[test]
2350 fn ack_coding() {
2351 const PACKETS: &[u64] = &[1, 2, 3, 5, 10, 11, 14];
2352 let mut ranges = ArrayRangeSet::new();
2353 for &packet in PACKETS {
2354 ranges.insert(packet..packet + 1);
2355 }
2356 let mut buf = Vec::new();
2357 const ECN: EcnCounts = EcnCounts {
2358 ect0: 42,
2359 ect1: 24,
2360 ce: 12,
2361 };
2362 Ack::encoder(42, &ranges, Some(&ECN)).encode(&mut buf);
2363 let frames = frames(buf);
2364 assert_eq!(frames.len(), 1);
2365 match frames[0] {
2366 Frame::Ack(ref ack) => {
2367 let mut packets = ack.iter().flatten().collect::<Vec<_>>();
2368 packets.sort_unstable();
2369 assert_eq!(&packets[..], PACKETS);
2370 assert_eq!(ack.ecn, Some(ECN));
2371 }
2372 ref x => panic!("incorrect frame {x:?}"),
2373 }
2374 }
2375
2376 #[test]
2377 #[allow(clippy::range_plus_one)]
2378 fn path_ack_coding() {
2379 const PACKETS: &[u64] = &[1, 2, 3, 5, 10, 11, 14];
2380 let mut ranges = ArrayRangeSet::new();
2381 for &packet in PACKETS {
2382 ranges.insert(packet..packet + 1);
2383 }
2384 let mut buf = Vec::new();
2385 const ECN: EcnCounts = EcnCounts {
2386 ect0: 42,
2387 ect1: 24,
2388 ce: 12,
2389 };
2390 const PATH_ID: PathId = PathId::MAX;
2391 PathAck::encoder(PATH_ID, 42, &ranges, Some(&ECN)).encode(&mut buf);
2392 let frames = frames(buf);
2393 assert_eq!(frames.len(), 1);
2394 match frames[0] {
2395 Frame::PathAck(ref ack) => {
2396 assert_eq!(ack.path_id, PATH_ID);
2397 let mut packets = ack.into_iter().flatten().collect::<Vec<_>>();
2398 packets.sort_unstable();
2399 assert_eq!(&packets[..], PACKETS);
2400 assert_eq!(ack.ecn, Some(ECN));
2401 }
2402 ref x => panic!("incorrect frame {x:?}"),
2403 }
2404 }
2405
2406 #[test]
2407 fn ack_frequency_coding() {
2408 let mut buf = Vec::new();
2409 let original = AckFrequency {
2410 sequence: VarInt(42),
2411 ack_eliciting_threshold: VarInt(20),
2412 request_max_ack_delay: VarInt(50_000),
2413 reordering_threshold: VarInt(1),
2414 };
2415 original.encode(&mut buf);
2416 let frames = frames(buf);
2417 assert_eq!(frames.len(), 1);
2418 match &frames[0] {
2419 Frame::AckFrequency(decoded) => assert_eq!(decoded, &original),
2420 x => panic!("incorrect frame {x:?}"),
2421 }
2422 }
2423
2424 #[test]
2425 fn immediate_ack_coding() {
2426 let mut buf = Vec::new();
2427 FrameType::ImmediateAck.encode(&mut buf);
2428 let frames = frames(buf);
2429 assert_eq!(frames.len(), 1);
2430 assert_matches!(&frames[0], Frame::ImmediateAck);
2431 }
2432
2433 #[test]
2435 fn test_observed_addr_roundrip() {
2436 let observed_addr = ObservedAddr {
2437 seq_no: VarInt(42),
2438 ip: std::net::Ipv4Addr::LOCALHOST.into(),
2439 port: 4242,
2440 };
2441 let mut buf = Vec::with_capacity(observed_addr.size());
2442 observed_addr.encode(&mut buf);
2443
2444 assert_eq!(
2445 observed_addr.size(),
2446 buf.len(),
2447 "expected written bytes and actual size differ"
2448 );
2449
2450 let mut decoded = frames(buf);
2451 assert_eq!(decoded.len(), 1);
2452 match decoded.pop().expect("non empty") {
2453 Frame::ObservedAddr(decoded) => assert_eq!(decoded, observed_addr),
2454 x => panic!("incorrect frame {x:?}"),
2455 }
2456 }
2457
2458 #[test]
2459 fn test_path_abandon_roundtrip() {
2460 let abandon = PathAbandon {
2461 path_id: PathId(42),
2462 error_code: TransportErrorCode::NO_ERROR,
2463 };
2464 let mut buf = Vec::new();
2465 abandon.encode(&mut buf);
2466
2467 let mut decoded = frames(buf);
2468 assert_eq!(decoded.len(), 1);
2469 match decoded.pop().expect("non empty") {
2470 Frame::PathAbandon(decoded) => assert_eq!(decoded, abandon),
2471 x => panic!("incorrect frame {x:?}"),
2472 }
2473 }
2474
2475 #[test]
2476 fn test_path_status_available_roundtrip() {
2477 let path_status_available = PathStatusAvailable {
2478 path_id: PathId(42),
2479 status_seq_no: VarInt(73),
2480 };
2481 let mut buf = Vec::new();
2482 path_status_available.encode(&mut buf);
2483
2484 let mut decoded = frames(buf);
2485 assert_eq!(decoded.len(), 1);
2486 match decoded.pop().expect("non empty") {
2487 Frame::PathStatusAvailable(decoded) => assert_eq!(decoded, path_status_available),
2488 x => panic!("incorrect frame {x:?}"),
2489 }
2490 }
2491
2492 #[test]
2493 fn test_path_status_backup_roundtrip() {
2494 let path_status_backup = PathStatusBackup {
2495 path_id: PathId(42),
2496 status_seq_no: VarInt(73),
2497 };
2498 let mut buf = Vec::new();
2499 path_status_backup.encode(&mut buf);
2500
2501 let mut decoded = frames(buf);
2502 assert_eq!(decoded.len(), 1);
2503 match decoded.pop().expect("non empty") {
2504 Frame::PathStatusBackup(decoded) => assert_eq!(decoded, path_status_backup),
2505 x => panic!("incorrect frame {x:?}"),
2506 }
2507 }
2508
2509 #[test]
2510 fn test_path_new_connection_id_roundtrip() {
2511 let cid = NewConnectionId {
2512 path_id: Some(PathId(22)),
2513 sequence: 31,
2514 retire_prior_to: 13,
2515 id: ConnectionId::new(&[0xAB; 8]),
2516 reset_token: ResetToken::from([0xCD; crate::RESET_TOKEN_SIZE]),
2517 };
2518 let mut buf = Vec::new();
2519 cid.encode(&mut buf);
2520
2521 let mut decoded = frames(buf);
2522 assert_eq!(decoded.len(), 1);
2523 match decoded.pop().expect("non empty") {
2524 Frame::NewConnectionId(decoded) => assert_eq!(decoded, cid),
2525 x => panic!("incorrect frame {x:?}"),
2526 }
2527 }
2528
2529 #[test]
2530 fn test_path_retire_connection_id_roundtrip() {
2531 let retire_cid = RetireConnectionId {
2532 path_id: Some(PathId(22)),
2533 sequence: 31,
2534 };
2535 let mut buf = Vec::new();
2536 retire_cid.encode(&mut buf);
2537
2538 let mut decoded = frames(buf);
2539 assert_eq!(decoded.len(), 1);
2540 match decoded.pop().expect("non empty") {
2541 Frame::RetireConnectionId(decoded) => assert_eq!(decoded, retire_cid),
2542 x => panic!("incorrect frame {x:?}"),
2543 }
2544 }
2545
2546 #[test]
2547 fn test_paths_blocked_path_cids_blocked_roundtrip() {
2548 let mut buf = Vec::new();
2549
2550 let frame0 = PathsBlocked(PathId(22));
2551 frame0.encode(&mut buf);
2552 let frame1 = PathCidsBlocked {
2553 path_id: PathId(23),
2554 next_seq: VarInt(32),
2555 };
2556 frame1.encode(&mut buf);
2557
2558 let mut decoded = frames(buf);
2559 assert_eq!(decoded.len(), 2);
2560 match decoded.pop().expect("non empty") {
2561 Frame::PathCidsBlocked(decoded) => assert_eq!(decoded, frame1),
2562 x => panic!("incorrect frame {x:?}"),
2563 }
2564 match decoded.pop().expect("non empty") {
2565 Frame::PathsBlocked(decoded) => assert_eq!(decoded, frame0),
2566 x => panic!("incorrect frame {x:?}"),
2567 }
2568 }
2569
2570 #[test]
2572 fn test_add_address_roundrip() {
2573 let add_address = AddAddress {
2574 seq_no: VarInt(42),
2575 ip: std::net::Ipv4Addr::LOCALHOST.into(),
2576 port: 4242,
2577 };
2578 let mut buf = Vec::with_capacity(add_address.size());
2579 add_address.encode(&mut buf);
2580
2581 assert_eq!(
2582 add_address.size(),
2583 buf.len(),
2584 "expected written bytes and actual size differ"
2585 );
2586
2587 let mut decoded = frames(buf);
2588 assert_eq!(decoded.len(), 1);
2589 match decoded.pop().expect("non empty") {
2590 Frame::AddAddress(decoded) => assert_eq!(decoded, add_address),
2591 x => panic!("incorrect frame {x:?}"),
2592 }
2593 }
2594
2595 #[test]
2597 fn test_reach_out_roundrip() {
2598 let reach_out = ReachOut {
2599 round: VarInt(42),
2600 ip: std::net::Ipv6Addr::LOCALHOST.into(),
2601 port: 4242,
2602 };
2603 let mut buf = Vec::with_capacity(reach_out.size());
2604 reach_out.encode(&mut buf);
2605
2606 assert_eq!(
2607 reach_out.size(),
2608 buf.len(),
2609 "expected written bytes and actual size differ"
2610 );
2611
2612 let mut decoded = frames(buf);
2613 assert_eq!(decoded.len(), 1);
2614 match decoded.pop().expect("non empty") {
2615 Frame::ReachOut(decoded) => assert_eq!(decoded, reach_out),
2616 x => panic!("incorrect frame {x:?}"),
2617 }
2618 }
2619
2620 #[test]
2622 fn test_remove_address_roundrip() {
2623 let remove_addr = RemoveAddress::new(VarInt(10));
2624 let mut buf = Vec::with_capacity(remove_addr.size());
2625 remove_addr.encode(&mut buf);
2626
2627 assert_eq!(
2628 remove_addr.size(),
2629 buf.len(),
2630 "expected written bytes and actual size differ"
2631 );
2632
2633 let mut decoded = frames(buf);
2634 assert_eq!(decoded.len(), 1);
2635 match decoded.pop().expect("non empty") {
2636 Frame::RemoveAddress(decoded) => assert_eq!(decoded, remove_addr),
2637 x => panic!("incorrect frame {x:?}"),
2638 }
2639 }
2640}