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