1use std::{
2 fmt::{self, Write},
3 mem,
4 net::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, UnexpectedEnd},
15 range_set::ArrayRangeSet,
16 shared::{ConnectionId, EcnCodepoint},
17};
18
19#[cfg(feature = "arbitrary")]
20use arbitrary::Arbitrary;
21
22#[derive(Copy, Clone, Eq, PartialEq)]
24pub struct FrameType(u64);
25
26impl FrameType {
27 fn stream(self) -> Option<StreamInfo> {
28 if STREAM_TYS.contains(&self.0) {
29 Some(StreamInfo(self.0 as u8))
30 } else {
31 None
32 }
33 }
34 fn datagram(self) -> Option<DatagramInfo> {
35 if DATAGRAM_TYS.contains(&self.0) {
36 Some(DatagramInfo(self.0 as u8))
37 } else {
38 None
39 }
40 }
41}
42
43impl coding::Codec for FrameType {
44 fn decode<B: Buf>(buf: &mut B) -> coding::Result<Self> {
45 Ok(Self(buf.get_var()?))
46 }
47 fn encode<B: BufMut>(&self, buf: &mut B) {
48 buf.write_var(self.0);
49 }
50}
51
52pub(crate) trait FrameStruct {
53 const SIZE_BOUND: usize;
55}
56
57macro_rules! frame_types {
58 {$($name:ident = $val:expr,)*} => {
59 impl FrameType {
60 $(pub(crate) const $name: FrameType = FrameType($val);)*
61 }
62
63 impl fmt::Debug for FrameType {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 match self.0 {
66 $($val => f.write_str(stringify!($name)),)*
67 _ => write!(f, "Type({:02x})", self.0)
68 }
69 }
70 }
71
72 impl fmt::Display for FrameType {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 match self.0 {
75 $($val => f.write_str(stringify!($name)),)*
76 x if STREAM_TYS.contains(&x) => f.write_str("STREAM"),
77 x if DATAGRAM_TYS.contains(&x) => f.write_str("DATAGRAM"),
78 _ => write!(f, "<unknown {:02x}>", self.0),
79 }
80 }
81 }
82 }
83}
84
85#[derive(Debug, Copy, Clone, Eq, PartialEq)]
86struct StreamInfo(u8);
87
88impl StreamInfo {
89 fn fin(self) -> bool {
90 self.0 & 0x01 != 0
91 }
92 fn len(self) -> bool {
93 self.0 & 0x02 != 0
94 }
95 fn off(self) -> bool {
96 self.0 & 0x04 != 0
97 }
98}
99
100#[derive(Debug, Copy, Clone, Eq, PartialEq)]
101struct DatagramInfo(u8);
102
103impl DatagramInfo {
104 fn len(self) -> bool {
105 self.0 & 0x01 != 0
106 }
107}
108
109frame_types! {
110 PADDING = 0x00,
111 PING = 0x01,
112 ACK = 0x02,
113 ACK_ECN = 0x03,
114 RESET_STREAM = 0x04,
115 STOP_SENDING = 0x05,
116 CRYPTO = 0x06,
117 NEW_TOKEN = 0x07,
118 MAX_DATA = 0x10,
120 MAX_STREAM_DATA = 0x11,
121 MAX_STREAMS_BIDI = 0x12,
122 MAX_STREAMS_UNI = 0x13,
123 DATA_BLOCKED = 0x14,
124 STREAM_DATA_BLOCKED = 0x15,
125 STREAMS_BLOCKED_BIDI = 0x16,
126 STREAMS_BLOCKED_UNI = 0x17,
127 NEW_CONNECTION_ID = 0x18,
128 RETIRE_CONNECTION_ID = 0x19,
129 PATH_CHALLENGE = 0x1a,
130 PATH_RESPONSE = 0x1b,
131 CONNECTION_CLOSE = 0x1c,
132 APPLICATION_CLOSE = 0x1d,
133 HANDSHAKE_DONE = 0x1e,
134 ACK_FREQUENCY = 0xaf,
136 IMMEDIATE_ACK = 0x1f,
137 ADD_ADDRESS = 0x40,
139 PUNCH_ME_NOW = 0x41,
140 REMOVE_ADDRESS = 0x42,
141 OBSERVED_ADDRESS = 0x43,
143 }
145
146const STREAM_TYS: RangeInclusive<u64> = RangeInclusive::new(0x08, 0x0f);
147const DATAGRAM_TYS: RangeInclusive<u64> = RangeInclusive::new(0x30, 0x31);
148
149#[derive(Debug)]
150pub(crate) enum Frame {
151 Padding,
152 Ping,
153 Ack(Ack),
154 ResetStream(ResetStream),
155 StopSending(StopSending),
156 Crypto(Crypto),
157 NewToken(NewToken),
158 Stream(Stream),
159 MaxData(VarInt),
160 MaxStreamData { id: StreamId, offset: u64 },
161 MaxStreams { dir: Dir, count: u64 },
162 DataBlocked { offset: u64 },
163 StreamDataBlocked { id: StreamId, offset: u64 },
164 StreamsBlocked { dir: Dir, limit: u64 },
165 NewConnectionId(NewConnectionId),
166 RetireConnectionId { sequence: u64 },
167 PathChallenge(u64),
168 PathResponse(u64),
169 Close(Close),
170 Datagram(Datagram),
171 AckFrequency(AckFrequency),
172 ImmediateAck,
173 HandshakeDone,
174 AddAddress(AddAddress),
175 PunchMeNow(PunchMeNow),
176 RemoveAddress(RemoveAddress),
177 ObservedAddress(ObservedAddress),
178}
179
180impl Frame {
181 pub(crate) fn ty(&self) -> FrameType {
182 use Frame::*;
183 match *self {
184 Padding => FrameType::PADDING,
185 ResetStream(_) => FrameType::RESET_STREAM,
186 Close(self::Close::Connection(_)) => FrameType::CONNECTION_CLOSE,
187 Close(self::Close::Application(_)) => FrameType::APPLICATION_CLOSE,
188 MaxData(_) => FrameType::MAX_DATA,
189 MaxStreamData { .. } => FrameType::MAX_STREAM_DATA,
190 MaxStreams { dir: Dir::Bi, .. } => FrameType::MAX_STREAMS_BIDI,
191 MaxStreams { dir: Dir::Uni, .. } => FrameType::MAX_STREAMS_UNI,
192 Ping => FrameType::PING,
193 DataBlocked { .. } => FrameType::DATA_BLOCKED,
194 StreamDataBlocked { .. } => FrameType::STREAM_DATA_BLOCKED,
195 StreamsBlocked { dir: Dir::Bi, .. } => FrameType::STREAMS_BLOCKED_BIDI,
196 StreamsBlocked { dir: Dir::Uni, .. } => FrameType::STREAMS_BLOCKED_UNI,
197 StopSending { .. } => FrameType::STOP_SENDING,
198 RetireConnectionId { .. } => FrameType::RETIRE_CONNECTION_ID,
199 Ack(_) => FrameType::ACK,
200 Stream(ref x) => {
201 let mut ty = *STREAM_TYS.start();
202 if x.fin {
203 ty |= 0x01;
204 }
205 if x.offset != 0 {
206 ty |= 0x04;
207 }
208 FrameType(ty)
209 }
210 PathChallenge(_) => FrameType::PATH_CHALLENGE,
211 PathResponse(_) => FrameType::PATH_RESPONSE,
212 NewConnectionId { .. } => FrameType::NEW_CONNECTION_ID,
213 Crypto(_) => FrameType::CRYPTO,
214 NewToken(_) => FrameType::NEW_TOKEN,
215 Datagram(_) => FrameType(*DATAGRAM_TYS.start()),
216 AckFrequency(_) => FrameType::ACK_FREQUENCY,
217 ImmediateAck => FrameType::IMMEDIATE_ACK,
218 HandshakeDone => FrameType::HANDSHAKE_DONE,
219 AddAddress(_) => FrameType::ADD_ADDRESS,
220 PunchMeNow(_) => FrameType::PUNCH_ME_NOW,
221 RemoveAddress(_) => FrameType::REMOVE_ADDRESS,
222 ObservedAddress(_) => FrameType::OBSERVED_ADDRESS,
223 }
224 }
225
226 pub(crate) fn is_ack_eliciting(&self) -> bool {
227 !matches!(*self, Self::Ack(_) | Self::Padding | Self::Close(_))
228 }
229}
230
231#[derive(Clone, Debug)]
232pub enum Close {
233 Connection(ConnectionClose),
234 Application(ApplicationClose),
235}
236
237impl Close {
238 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
239 match *self {
240 Self::Connection(ref x) => x.encode(out, max_len),
241 Self::Application(ref x) => x.encode(out, max_len),
242 }
243 }
244
245 pub(crate) fn is_transport_layer(&self) -> bool {
246 matches!(*self, Self::Connection(_))
247 }
248}
249
250impl From<TransportError> for Close {
251 fn from(x: TransportError) -> Self {
252 Self::Connection(x.into())
253 }
254}
255impl From<ConnectionClose> for Close {
256 fn from(x: ConnectionClose) -> Self {
257 Self::Connection(x)
258 }
259}
260impl From<ApplicationClose> for Close {
261 fn from(x: ApplicationClose) -> Self {
262 Self::Application(x)
263 }
264}
265
266#[derive(Debug, Clone, PartialEq, Eq)]
268pub struct ConnectionClose {
269 pub error_code: TransportErrorCode,
271 pub frame_type: Option<FrameType>,
273 pub reason: Bytes,
275}
276
277impl fmt::Display for ConnectionClose {
278 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
279 self.error_code.fmt(f)?;
280 if !self.reason.as_ref().is_empty() {
281 f.write_str(": ")?;
282 f.write_str(&String::from_utf8_lossy(&self.reason))?;
283 }
284 Ok(())
285 }
286}
287
288impl From<TransportError> for ConnectionClose {
289 fn from(x: TransportError) -> Self {
290 Self {
291 error_code: x.code,
292 frame_type: x.frame,
293 reason: x.reason.into(),
294 }
295 }
296}
297
298impl FrameStruct for ConnectionClose {
299 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
300}
301
302impl ConnectionClose {
303 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
304 out.write(FrameType::CONNECTION_CLOSE); out.write(self.error_code); let ty = self.frame_type.map_or(0, |x| x.0);
307 out.write_var(ty); let max_len = max_len
309 - 3
310 - VarInt::from_u64(ty).unwrap().size()
311 - VarInt::from_u64(self.reason.len() as u64).unwrap().size();
312 let actual_len = self.reason.len().min(max_len);
313 out.write_var(actual_len as u64); out.put_slice(&self.reason[0..actual_len]); }
316}
317
318#[derive(Debug, Clone, PartialEq, Eq)]
320pub struct ApplicationClose {
321 pub error_code: VarInt,
323 pub reason: Bytes,
325}
326
327impl fmt::Display for ApplicationClose {
328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329 if !self.reason.as_ref().is_empty() {
330 f.write_str(&String::from_utf8_lossy(&self.reason))?;
331 f.write_str(" (code ")?;
332 self.error_code.fmt(f)?;
333 f.write_str(")")?;
334 } else {
335 self.error_code.fmt(f)?;
336 }
337 Ok(())
338 }
339}
340
341impl FrameStruct for ApplicationClose {
342 const SIZE_BOUND: usize = 1 + 8 + 8;
343}
344
345impl ApplicationClose {
346 pub(crate) fn encode<W: BufMut>(&self, out: &mut W, max_len: usize) {
347 out.write(FrameType::APPLICATION_CLOSE); out.write(self.error_code); let max_len = max_len - 3 - VarInt::from_u64(self.reason.len() as u64).unwrap().size();
350 let actual_len = self.reason.len().min(max_len);
351 out.write_var(actual_len as u64); out.put_slice(&self.reason[0..actual_len]); }
354}
355
356#[derive(Clone, Eq, PartialEq)]
357pub struct Ack {
358 pub largest: u64,
359 pub delay: u64,
360 pub additional: Bytes,
361 pub ecn: Option<EcnCounts>,
362}
363
364impl fmt::Debug for Ack {
365 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
366 let mut ranges = "[".to_string();
367 let mut first = true;
368 for range in self.iter() {
369 if !first {
370 ranges.push(',');
371 }
372 write!(ranges, "{range:?}").unwrap();
373 first = false;
374 }
375 ranges.push(']');
376
377 f.debug_struct("Ack")
378 .field("largest", &self.largest)
379 .field("delay", &self.delay)
380 .field("ecn", &self.ecn)
381 .field("ranges", &ranges)
382 .finish()
383 }
384}
385
386impl<'a> IntoIterator for &'a Ack {
387 type Item = RangeInclusive<u64>;
388 type IntoIter = AckIter<'a>;
389
390 fn into_iter(self) -> AckIter<'a> {
391 AckIter::new(self.largest, &self.additional[..])
392 }
393}
394
395impl Ack {
396 pub fn encode<W: BufMut>(
397 delay: u64,
398 ranges: &ArrayRangeSet,
399 ecn: Option<&EcnCounts>,
400 buf: &mut W,
401 ) {
402 let mut rest = ranges.iter().rev();
403 let first = rest.next().unwrap();
404 let largest = first.end - 1;
405 let first_size = first.end - first.start;
406 buf.write(if ecn.is_some() {
407 FrameType::ACK_ECN
408 } else {
409 FrameType::ACK
410 });
411 buf.write_var(largest);
412 buf.write_var(delay);
413 buf.write_var(ranges.len() as u64 - 1);
414 buf.write_var(first_size - 1);
415 let mut prev = first.start;
416 for block in rest {
417 let size = block.end - block.start;
418 buf.write_var(prev - block.end - 1);
419 buf.write_var(size - 1);
420 prev = block.start;
421 }
422 if let Some(x) = ecn {
423 x.encode(buf)
424 }
425 }
426
427 pub fn iter(&self) -> AckIter<'_> {
428 self.into_iter()
429 }
430}
431
432#[derive(Debug, Copy, Clone, Eq, PartialEq)]
433pub struct EcnCounts {
434 pub ect0: u64,
435 pub ect1: u64,
436 pub ce: u64,
437}
438
439impl std::ops::AddAssign<EcnCodepoint> for EcnCounts {
440 fn add_assign(&mut self, rhs: EcnCodepoint) {
441 match rhs {
442 EcnCodepoint::Ect0 => {
443 self.ect0 += 1;
444 }
445 EcnCodepoint::Ect1 => {
446 self.ect1 += 1;
447 }
448 EcnCodepoint::Ce => {
449 self.ce += 1;
450 }
451 }
452 }
453}
454
455impl EcnCounts {
456 pub const ZERO: Self = Self {
457 ect0: 0,
458 ect1: 0,
459 ce: 0,
460 };
461
462 pub fn encode<W: BufMut>(&self, out: &mut W) {
463 out.write_var(self.ect0);
464 out.write_var(self.ect1);
465 out.write_var(self.ce);
466 }
467}
468
469#[derive(Debug, Clone)]
470pub(crate) struct Stream {
471 pub(crate) id: StreamId,
472 pub(crate) offset: u64,
473 pub(crate) fin: bool,
474 pub(crate) data: Bytes,
475}
476
477impl FrameStruct for Stream {
478 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
479}
480
481#[derive(Debug, Clone)]
483pub(crate) struct StreamMeta {
484 pub(crate) id: StreamId,
485 pub(crate) offsets: Range<u64>,
486 pub(crate) fin: bool,
487}
488
489impl Default for StreamMeta {
491 fn default() -> Self {
492 Self {
493 id: StreamId(0),
494 offsets: 0..0,
495 fin: false,
496 }
497 }
498}
499
500impl StreamMeta {
501 pub(crate) fn encode<W: BufMut>(&self, length: bool, out: &mut W) {
502 let mut ty = *STREAM_TYS.start();
503 if self.offsets.start != 0 {
504 ty |= 0x04;
505 }
506 if length {
507 ty |= 0x02;
508 }
509 if self.fin {
510 ty |= 0x01;
511 }
512 out.write_var(ty); out.write(self.id); if self.offsets.start != 0 {
515 out.write_var(self.offsets.start); }
517 if length {
518 out.write_var(self.offsets.end - self.offsets.start); }
520 }
521}
522
523pub(crate) type StreamMetaVec = TinyVec<[StreamMeta; 1]>;
525
526#[derive(Debug, Clone)]
527pub(crate) struct Crypto {
528 pub(crate) offset: u64,
529 pub(crate) data: Bytes,
530}
531
532impl Crypto {
533 pub(crate) const SIZE_BOUND: usize = 17;
534
535 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
536 out.write(FrameType::CRYPTO);
537 out.write_var(self.offset);
538 out.write_var(self.data.len() as u64);
539 out.put_slice(&self.data);
540 }
541}
542
543#[derive(Debug, Clone)]
544pub(crate) struct NewToken {
545 pub(crate) token: Bytes,
546}
547
548impl NewToken {
549 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
550 out.write(FrameType::NEW_TOKEN);
551 out.write_var(self.token.len() as u64);
552 out.put_slice(&self.token);
553 }
554
555 pub(crate) fn size(&self) -> usize {
556 1 + VarInt::from_u64(self.token.len() as u64).unwrap().size() + self.token.len()
557 }
558}
559
560pub(crate) struct Iter {
561 bytes: Bytes,
562 last_ty: Option<FrameType>,
563}
564
565impl Iter {
566 pub(crate) fn new(payload: Bytes) -> Result<Self, TransportError> {
567 if payload.is_empty() {
568 return Err(TransportError::PROTOCOL_VIOLATION(
572 "packet payload is empty",
573 ));
574 }
575
576 Ok(Self {
577 bytes: payload,
578 last_ty: None,
579 })
580 }
581
582 fn take_len(&mut self) -> Result<Bytes, UnexpectedEnd> {
583 let len = self.bytes.get_var()?;
584 if len > self.bytes.remaining() as u64 {
585 return Err(UnexpectedEnd);
586 }
587 Ok(self.bytes.split_to(len as usize))
588 }
589
590 fn try_next(&mut self) -> Result<Frame, IterErr> {
591 let ty = self.bytes.get::<FrameType>()?;
592 self.last_ty = Some(ty);
593 Ok(match ty {
594 FrameType::PADDING => Frame::Padding,
595 FrameType::RESET_STREAM => Frame::ResetStream(ResetStream {
596 id: self.bytes.get()?,
597 error_code: self.bytes.get()?,
598 final_offset: self.bytes.get()?,
599 }),
600 FrameType::CONNECTION_CLOSE => Frame::Close(Close::Connection(ConnectionClose {
601 error_code: self.bytes.get()?,
602 frame_type: {
603 let x = self.bytes.get_var()?;
604 if x == 0 { None } else { Some(FrameType(x)) }
605 },
606 reason: self.take_len()?,
607 })),
608 FrameType::APPLICATION_CLOSE => Frame::Close(Close::Application(ApplicationClose {
609 error_code: self.bytes.get()?,
610 reason: self.take_len()?,
611 })),
612 FrameType::MAX_DATA => Frame::MaxData(self.bytes.get()?),
613 FrameType::MAX_STREAM_DATA => Frame::MaxStreamData {
614 id: self.bytes.get()?,
615 offset: self.bytes.get_var()?,
616 },
617 FrameType::MAX_STREAMS_BIDI => Frame::MaxStreams {
618 dir: Dir::Bi,
619 count: self.bytes.get_var()?,
620 },
621 FrameType::MAX_STREAMS_UNI => Frame::MaxStreams {
622 dir: Dir::Uni,
623 count: self.bytes.get_var()?,
624 },
625 FrameType::PING => Frame::Ping,
626 FrameType::DATA_BLOCKED => Frame::DataBlocked {
627 offset: self.bytes.get_var()?,
628 },
629 FrameType::STREAM_DATA_BLOCKED => Frame::StreamDataBlocked {
630 id: self.bytes.get()?,
631 offset: self.bytes.get_var()?,
632 },
633 FrameType::STREAMS_BLOCKED_BIDI => Frame::StreamsBlocked {
634 dir: Dir::Bi,
635 limit: self.bytes.get_var()?,
636 },
637 FrameType::STREAMS_BLOCKED_UNI => Frame::StreamsBlocked {
638 dir: Dir::Uni,
639 limit: self.bytes.get_var()?,
640 },
641 FrameType::STOP_SENDING => Frame::StopSending(StopSending {
642 id: self.bytes.get()?,
643 error_code: self.bytes.get()?,
644 }),
645 FrameType::RETIRE_CONNECTION_ID => Frame::RetireConnectionId {
646 sequence: self.bytes.get_var()?,
647 },
648 FrameType::ACK | FrameType::ACK_ECN => {
649 let largest = self.bytes.get_var()?;
650 let delay = self.bytes.get_var()?;
651 let extra_blocks = self.bytes.get_var()? as usize;
652 let n = scan_ack_blocks(&self.bytes, largest, extra_blocks)?;
653 Frame::Ack(Ack {
654 delay,
655 largest,
656 additional: self.bytes.split_to(n),
657 ecn: if ty != FrameType::ACK_ECN {
658 None
659 } else {
660 Some(EcnCounts {
661 ect0: self.bytes.get_var()?,
662 ect1: self.bytes.get_var()?,
663 ce: self.bytes.get_var()?,
664 })
665 },
666 })
667 }
668 FrameType::PATH_CHALLENGE => Frame::PathChallenge(self.bytes.get()?),
669 FrameType::PATH_RESPONSE => Frame::PathResponse(self.bytes.get()?),
670 FrameType::NEW_CONNECTION_ID => {
671 let sequence = self.bytes.get_var()?;
672 let retire_prior_to = self.bytes.get_var()?;
673 if retire_prior_to > sequence {
674 return Err(IterErr::Malformed);
675 }
676 let length = self.bytes.get::<u8>()? as usize;
677 if length > MAX_CID_SIZE || length == 0 {
678 return Err(IterErr::Malformed);
679 }
680 if length > self.bytes.remaining() {
681 return Err(IterErr::UnexpectedEnd);
682 }
683 let mut stage = [0; MAX_CID_SIZE];
684 self.bytes.copy_to_slice(&mut stage[0..length]);
685 let id = ConnectionId::new(&stage[..length]);
686 if self.bytes.remaining() < 16 {
687 return Err(IterErr::UnexpectedEnd);
688 }
689 let mut reset_token = [0; RESET_TOKEN_SIZE];
690 self.bytes.copy_to_slice(&mut reset_token);
691 Frame::NewConnectionId(NewConnectionId {
692 sequence,
693 retire_prior_to,
694 id,
695 reset_token: reset_token.into(),
696 })
697 }
698 FrameType::CRYPTO => Frame::Crypto(Crypto {
699 offset: self.bytes.get_var()?,
700 data: self.take_len()?,
701 }),
702 FrameType::NEW_TOKEN => Frame::NewToken(NewToken {
703 token: self.take_len()?,
704 }),
705 FrameType::HANDSHAKE_DONE => Frame::HandshakeDone,
706 FrameType::ACK_FREQUENCY => Frame::AckFrequency(AckFrequency {
707 sequence: self.bytes.get()?,
708 ack_eliciting_threshold: self.bytes.get()?,
709 request_max_ack_delay: self.bytes.get()?,
710 reordering_threshold: self.bytes.get()?,
711 }),
712 FrameType::IMMEDIATE_ACK => Frame::ImmediateAck,
713 FrameType::ADD_ADDRESS => Frame::AddAddress(AddAddress::decode(&mut self.bytes)?),
714 FrameType::PUNCH_ME_NOW => Frame::PunchMeNow(PunchMeNow::decode(&mut self.bytes)?),
715 FrameType::REMOVE_ADDRESS => {
716 Frame::RemoveAddress(RemoveAddress::decode(&mut self.bytes)?)
717 }
718 FrameType::OBSERVED_ADDRESS => {
719 Frame::ObservedAddress(ObservedAddress::decode(&mut self.bytes)?)
720 }
721 _ => {
722 if let Some(s) = ty.stream() {
723 Frame::Stream(Stream {
724 id: self.bytes.get()?,
725 offset: if s.off() { self.bytes.get_var()? } else { 0 },
726 fin: s.fin(),
727 data: if s.len() {
728 self.take_len()?
729 } else {
730 self.take_remaining()
731 },
732 })
733 } else if let Some(d) = ty.datagram() {
734 Frame::Datagram(Datagram {
735 data: if d.len() {
736 self.take_len()?
737 } else {
738 self.take_remaining()
739 },
740 })
741 } else {
742 return Err(IterErr::InvalidFrameId);
743 }
744 }
745 })
746 }
747
748 fn take_remaining(&mut self) -> Bytes {
749 mem::take(&mut self.bytes)
750 }
751}
752
753impl Iterator for Iter {
754 type Item = Result<Frame, InvalidFrame>;
755 fn next(&mut self) -> Option<Self::Item> {
756 if !self.bytes.has_remaining() {
757 return None;
758 }
759 match self.try_next() {
760 Ok(x) => Some(Ok(x)),
761 Err(e) => {
762 self.bytes.clear();
764 Some(Err(InvalidFrame {
765 ty: self.last_ty,
766 reason: e.reason(),
767 }))
768 }
769 }
770 }
771}
772
773#[derive(Debug)]
774pub(crate) struct InvalidFrame {
775 pub(crate) ty: Option<FrameType>,
776 pub(crate) reason: &'static str,
777}
778
779impl From<InvalidFrame> for TransportError {
780 fn from(err: InvalidFrame) -> Self {
781 let mut te = Self::FRAME_ENCODING_ERROR(err.reason);
782 te.frame = err.ty;
783 te
784 }
785}
786
787fn scan_ack_blocks(mut buf: &[u8], largest: u64, n: usize) -> Result<usize, IterErr> {
789 let total_len = buf.remaining();
790 let first_block = buf.get_var()?;
791 let mut smallest = largest.checked_sub(first_block).ok_or(IterErr::Malformed)?;
792 for _ in 0..n {
793 let gap = buf.get_var()?;
794 smallest = smallest.checked_sub(gap + 2).ok_or(IterErr::Malformed)?;
795 let block = buf.get_var()?;
796 smallest = smallest.checked_sub(block).ok_or(IterErr::Malformed)?;
797 }
798 Ok(total_len - buf.remaining())
799}
800
801enum IterErr {
802 UnexpectedEnd,
803 InvalidFrameId,
804 Malformed,
805}
806
807impl IterErr {
808 fn reason(&self) -> &'static str {
809 use IterErr::*;
810 match *self {
811 UnexpectedEnd => "unexpected end",
812 InvalidFrameId => "invalid frame ID",
813 Malformed => "malformed",
814 }
815 }
816}
817
818impl From<UnexpectedEnd> for IterErr {
819 fn from(_: UnexpectedEnd) -> Self {
820 Self::UnexpectedEnd
821 }
822}
823
824#[derive(Debug, Clone)]
825pub struct AckIter<'a> {
826 largest: u64,
827 data: &'a [u8],
828}
829
830impl<'a> AckIter<'a> {
831 fn new(largest: u64, data: &'a [u8]) -> Self {
832 Self { largest, data }
833 }
834}
835
836impl Iterator for AckIter<'_> {
837 type Item = RangeInclusive<u64>;
838 fn next(&mut self) -> Option<RangeInclusive<u64>> {
839 if !self.data.has_remaining() {
840 return None;
841 }
842 let block = self.data.get_var().unwrap();
843 let largest = self.largest;
844 if let Ok(gap) = self.data.get_var() {
845 self.largest -= block + gap + 2;
846 }
847 Some(largest - block..=largest)
848 }
849}
850
851#[allow(unreachable_pub)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
853#[derive(Debug, Copy, Clone)]
854pub struct ResetStream {
855 pub(crate) id: StreamId,
856 pub(crate) error_code: VarInt,
857 pub(crate) final_offset: VarInt,
858}
859
860impl FrameStruct for ResetStream {
861 const SIZE_BOUND: usize = 1 + 8 + 8 + 8;
862}
863
864impl ResetStream {
865 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
866 out.write(FrameType::RESET_STREAM); out.write(self.id); out.write(self.error_code); out.write(self.final_offset); }
871}
872
873#[derive(Debug, Copy, Clone)]
874pub(crate) struct StopSending {
875 pub(crate) id: StreamId,
876 pub(crate) error_code: VarInt,
877}
878
879impl FrameStruct for StopSending {
880 const SIZE_BOUND: usize = 1 + 8 + 8;
881}
882
883impl StopSending {
884 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
885 out.write(FrameType::STOP_SENDING); out.write(self.id); out.write(self.error_code) }
889}
890
891#[derive(Debug, Copy, Clone)]
892pub(crate) struct NewConnectionId {
893 pub(crate) sequence: u64,
894 pub(crate) retire_prior_to: u64,
895 pub(crate) id: ConnectionId,
896 pub(crate) reset_token: ResetToken,
897}
898
899impl NewConnectionId {
900 pub(crate) fn encode<W: BufMut>(&self, out: &mut W) {
901 out.write(FrameType::NEW_CONNECTION_ID);
902 out.write_var(self.sequence);
903 out.write_var(self.retire_prior_to);
904 out.write(self.id.len() as u8);
905 out.put_slice(&self.id);
906 out.put_slice(&self.reset_token);
907 }
908}
909
910pub(crate) const RETIRE_CONNECTION_ID_SIZE_BOUND: usize = 9;
912
913#[derive(Debug, Clone)]
915pub struct Datagram {
916 pub data: Bytes,
918}
919
920impl FrameStruct for Datagram {
921 const SIZE_BOUND: usize = 1 + 8;
922}
923
924impl Datagram {
925 pub(crate) fn encode(&self, length: bool, out: &mut Vec<u8>) {
926 out.write(FrameType(*DATAGRAM_TYS.start() | u64::from(length))); if length {
928 out.write(VarInt::from_u64(self.data.len() as u64).unwrap()); }
931 out.extend_from_slice(&self.data);
932 }
933
934 pub(crate) fn size(&self, length: bool) -> usize {
935 1 + if length {
936 VarInt::from_u64(self.data.len() as u64).unwrap().size()
937 } else {
938 0
939 } + self.data.len()
940 }
941}
942
943#[derive(Debug, Copy, Clone, PartialEq, Eq)]
944pub(crate) struct AckFrequency {
945 pub(crate) sequence: VarInt,
946 pub(crate) ack_eliciting_threshold: VarInt,
947 pub(crate) request_max_ack_delay: VarInt,
948 pub(crate) reordering_threshold: VarInt,
949}
950
951impl AckFrequency {
952 pub(crate) fn encode<W: BufMut>(&self, buf: &mut W) {
953 buf.write(FrameType::ACK_FREQUENCY);
954 buf.write(self.sequence);
955 buf.write(self.ack_eliciting_threshold);
956 buf.write(self.request_max_ack_delay);
957 buf.write(self.reordering_threshold);
958 }
959}
960
961#[derive(Debug, Clone, PartialEq, Eq)]
963pub(crate) struct AddAddress {
964 pub(crate) sequence: VarInt,
966 pub(crate) address: SocketAddr,
968 pub(crate) priority: VarInt,
970}
971
972impl AddAddress {
973 pub(crate) fn encode<W: BufMut>(&self, buf: &mut W) {
974 buf.write(FrameType::ADD_ADDRESS);
975 buf.write(self.sequence);
976 buf.write(self.priority);
977
978 match self.address {
979 SocketAddr::V4(addr) => {
980 buf.put_u8(4); buf.put_slice(&addr.ip().octets());
982 buf.put_u16(addr.port());
983 }
984 SocketAddr::V6(addr) => {
985 buf.put_u8(6); buf.put_slice(&addr.ip().octets());
987 buf.put_u16(addr.port());
988 buf.put_u32(addr.flowinfo());
989 buf.put_u32(addr.scope_id());
990 }
991 }
992 }
993
994 pub(crate) fn decode<R: Buf>(r: &mut R) -> Result<Self, UnexpectedEnd> {
995 let sequence = r.get()?;
996 let priority = r.get()?;
997 let ip_version = r.get::<u8>()?;
998
999 let address = match ip_version {
1000 4 => {
1001 let mut octets = [0u8; 4];
1002 r.copy_to_slice(&mut octets);
1003 let port = r.get::<u16>()?;
1004 SocketAddr::V4(std::net::SocketAddrV4::new(
1005 std::net::Ipv4Addr::from(octets),
1006 port,
1007 ))
1008 }
1009 6 => {
1010 let mut octets = [0u8; 16];
1011 r.copy_to_slice(&mut octets);
1012 let port = r.get::<u16>()?;
1013 let flowinfo = r.get::<u32>()?;
1014 let scope_id = r.get::<u32>()?;
1015 SocketAddr::V6(std::net::SocketAddrV6::new(
1016 std::net::Ipv6Addr::from(octets),
1017 port,
1018 flowinfo,
1019 scope_id,
1020 ))
1021 }
1022 _ => return Err(UnexpectedEnd),
1023 };
1024
1025 Ok(Self {
1026 sequence,
1027 address,
1028 priority,
1029 })
1030 }
1031}
1032
1033impl FrameStruct for AddAddress {
1034 const SIZE_BOUND: usize = 1 + 9 + 9 + 1 + 16 + 2 + 4 + 4; }
1036
1037#[derive(Debug, Clone, PartialEq, Eq)]
1039pub(crate) struct PunchMeNow {
1040 pub(crate) round: VarInt,
1042 pub(crate) target_sequence: VarInt,
1044 pub(crate) local_address: SocketAddr,
1046 pub(crate) target_peer_id: Option<[u8; 32]>,
1049}
1050
1051impl PunchMeNow {
1052 pub(crate) fn encode<W: BufMut>(&self, buf: &mut W) {
1053 buf.write(FrameType::PUNCH_ME_NOW);
1054 buf.write(self.round);
1055 buf.write(self.target_sequence);
1056
1057 match self.local_address {
1058 SocketAddr::V4(addr) => {
1059 buf.put_u8(4); buf.put_slice(&addr.ip().octets());
1061 buf.put_u16(addr.port());
1062 }
1063 SocketAddr::V6(addr) => {
1064 buf.put_u8(6); buf.put_slice(&addr.ip().octets());
1066 buf.put_u16(addr.port());
1067 buf.put_u32(addr.flowinfo());
1068 buf.put_u32(addr.scope_id());
1069 }
1070 }
1071
1072 match &self.target_peer_id {
1074 Some(peer_id) => {
1075 buf.put_u8(1); buf.put_slice(peer_id);
1077 }
1078 None => {
1079 buf.put_u8(0); }
1081 }
1082 }
1083
1084 pub(crate) fn decode<R: Buf>(r: &mut R) -> Result<Self, UnexpectedEnd> {
1085 let round = r.get()?;
1086 let target_sequence = r.get()?;
1087 let ip_version = r.get::<u8>()?;
1088
1089 let local_address = match ip_version {
1090 4 => {
1091 let mut octets = [0u8; 4];
1092 r.copy_to_slice(&mut octets);
1093 let port = r.get::<u16>()?;
1094 SocketAddr::V4(std::net::SocketAddrV4::new(
1095 std::net::Ipv4Addr::from(octets),
1096 port,
1097 ))
1098 }
1099 6 => {
1100 let mut octets = [0u8; 16];
1101 r.copy_to_slice(&mut octets);
1102 let port = r.get::<u16>()?;
1103 let flowinfo = r.get::<u32>()?;
1104 let scope_id = r.get::<u32>()?;
1105 SocketAddr::V6(std::net::SocketAddrV6::new(
1106 std::net::Ipv6Addr::from(octets),
1107 port,
1108 flowinfo,
1109 scope_id,
1110 ))
1111 }
1112 _ => return Err(UnexpectedEnd),
1113 };
1114
1115 let target_peer_id = if r.remaining() > 0 {
1117 let has_peer_id = r.get::<u8>()?;
1118 if has_peer_id == 1 {
1119 let mut peer_id = [0u8; 32];
1120 r.copy_to_slice(&mut peer_id);
1121 Some(peer_id)
1122 } else {
1123 None
1124 }
1125 } else {
1126 None
1127 };
1128
1129 Ok(Self {
1130 round,
1131 target_sequence,
1132 local_address,
1133 target_peer_id,
1134 })
1135 }
1136}
1137
1138impl FrameStruct for PunchMeNow {
1139 const SIZE_BOUND: usize = 1 + 9 + 9 + 1 + 16 + 2 + 4 + 4 + 1 + 32; }
1141
1142#[derive(Debug, Clone, PartialEq, Eq)]
1144pub(crate) struct RemoveAddress {
1145 pub(crate) sequence: VarInt,
1147}
1148
1149impl RemoveAddress {
1150 pub(crate) fn encode<W: BufMut>(&self, buf: &mut W) {
1151 buf.write(FrameType::REMOVE_ADDRESS);
1152 buf.write(self.sequence);
1153 }
1154
1155 pub(crate) fn decode<R: Buf>(r: &mut R) -> Result<Self, UnexpectedEnd> {
1156 let sequence = r.get()?;
1157 Ok(Self { sequence })
1158 }
1159}
1160
1161impl FrameStruct for RemoveAddress {
1162 const SIZE_BOUND: usize = 1 + 9; }
1164
1165#[derive(Debug, Clone, PartialEq, Eq)]
1168pub(crate) struct ObservedAddress {
1169 pub(crate) address: SocketAddr,
1171}
1172
1173impl ObservedAddress {
1174 pub(crate) fn encode<W: BufMut>(&self, buf: &mut W) {
1175 buf.write(FrameType::OBSERVED_ADDRESS);
1176
1177 match self.address {
1178 SocketAddr::V4(addr) => {
1179 buf.put_u8(4); buf.put_slice(&addr.ip().octets());
1181 buf.put_u16(addr.port());
1182 }
1183 SocketAddr::V6(addr) => {
1184 buf.put_u8(6); buf.put_slice(&addr.ip().octets());
1186 buf.put_u16(addr.port());
1187 }
1188 }
1189 }
1190
1191 pub(crate) fn decode<R: Buf>(r: &mut R) -> Result<Self, UnexpectedEnd> {
1192 let ip_version = r.get::<u8>()?;
1193 let address = match ip_version {
1194 4 => {
1195 if r.remaining() < 6 {
1196 return Err(UnexpectedEnd);
1197 }
1198 let mut octets = [0u8; 4];
1199 r.copy_to_slice(&mut octets);
1200 let port = r.get::<u16>()?;
1201 SocketAddr::new(octets.into(), port)
1202 }
1203 6 => {
1204 if r.remaining() < 18 {
1205 return Err(UnexpectedEnd);
1206 }
1207 let mut octets = [0u8; 16];
1208 r.copy_to_slice(&mut octets);
1209 let port = r.get::<u16>()?;
1210 SocketAddr::new(octets.into(), port)
1211 }
1212 _ => return Err(UnexpectedEnd),
1213 };
1214
1215 Ok(Self { address })
1216 }
1217}
1218
1219impl FrameStruct for ObservedAddress {
1220 const SIZE_BOUND: usize = 1 + 1 + 16 + 2; }
1222
1223#[cfg(test)]
1224mod test {
1225 use super::*;
1226 use crate::coding::Codec;
1227 use assert_matches::assert_matches;
1228
1229 fn frames(buf: Vec<u8>) -> Vec<Frame> {
1230 Iter::new(Bytes::from(buf))
1231 .unwrap()
1232 .collect::<Result<Vec<_>, _>>()
1233 .unwrap()
1234 }
1235
1236 #[test]
1237 fn ack_coding() {
1238 const PACKETS: &[u64] = &[1, 2, 3, 5, 10, 11, 14];
1239 let mut ranges = ArrayRangeSet::new();
1240 for &packet in PACKETS {
1241 ranges.insert(packet..packet + 1);
1242 }
1243 let mut buf = Vec::new();
1244 const ECN: EcnCounts = EcnCounts {
1245 ect0: 42,
1246 ect1: 24,
1247 ce: 12,
1248 };
1249 Ack::encode(42, &ranges, Some(&ECN), &mut buf);
1250 let frames = frames(buf);
1251 assert_eq!(frames.len(), 1);
1252 match frames[0] {
1253 Frame::Ack(ref ack) => {
1254 let mut packets = ack.iter().flatten().collect::<Vec<_>>();
1255 packets.sort_unstable();
1256 assert_eq!(&packets[..], PACKETS);
1257 assert_eq!(ack.ecn, Some(ECN));
1258 }
1259 ref x => panic!("incorrect frame {x:?}"),
1260 }
1261 }
1262
1263 #[test]
1264 fn ack_frequency_coding() {
1265 let mut buf = Vec::new();
1266 let original = AckFrequency {
1267 sequence: VarInt(42),
1268 ack_eliciting_threshold: VarInt(20),
1269 request_max_ack_delay: VarInt(50_000),
1270 reordering_threshold: VarInt(1),
1271 };
1272 original.encode(&mut buf);
1273 let frames = frames(buf);
1274 assert_eq!(frames.len(), 1);
1275 match &frames[0] {
1276 Frame::AckFrequency(decoded) => assert_eq!(decoded, &original),
1277 x => panic!("incorrect frame {x:?}"),
1278 }
1279 }
1280
1281 #[test]
1282 fn immediate_ack_coding() {
1283 let mut buf = Vec::new();
1284 FrameType::IMMEDIATE_ACK.encode(&mut buf);
1285 let frames = frames(buf);
1286 assert_eq!(frames.len(), 1);
1287 assert_matches!(&frames[0], Frame::ImmediateAck);
1288 }
1289
1290 #[test]
1291 fn add_address_ipv4_coding() {
1292 let mut buf = Vec::new();
1293 let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
1294 let original = AddAddress {
1295 sequence: VarInt(42),
1296 address: addr,
1297 priority: VarInt(100),
1298 };
1299 original.encode(&mut buf);
1300 let frames = frames(buf);
1301 assert_eq!(frames.len(), 1);
1302 match &frames[0] {
1303 Frame::AddAddress(decoded) => {
1304 assert_eq!(decoded.sequence, original.sequence);
1305 assert_eq!(decoded.address, original.address);
1306 assert_eq!(decoded.priority, original.priority);
1307 }
1308 x => panic!("incorrect frame {x:?}"),
1309 }
1310 }
1311
1312 #[test]
1313 fn add_address_ipv6_coding() {
1314 let mut buf = Vec::new();
1315 let addr = SocketAddr::from(([0, 0, 0, 0, 0, 0, 0, 1], 8080));
1316 let original = AddAddress {
1317 sequence: VarInt(123),
1318 address: addr,
1319 priority: VarInt(200),
1320 };
1321 original.encode(&mut buf);
1322 let frames = frames(buf);
1323 assert_eq!(frames.len(), 1);
1324 match &frames[0] {
1325 Frame::AddAddress(decoded) => {
1326 assert_eq!(decoded.sequence, original.sequence);
1327 assert_eq!(decoded.address, original.address);
1328 assert_eq!(decoded.priority, original.priority);
1329 }
1330 x => panic!("incorrect frame {x:?}"),
1331 }
1332 }
1333
1334 #[test]
1335 fn punch_me_now_ipv4_coding() {
1336 let mut buf = Vec::new();
1337 let addr = SocketAddr::from(([192, 168, 1, 1], 9000));
1338 let original = PunchMeNow {
1339 round: VarInt(1),
1340 target_sequence: VarInt(42),
1341 local_address: addr,
1342 target_peer_id: None,
1343 };
1344 original.encode(&mut buf);
1345 let frames = frames(buf);
1346 assert_eq!(frames.len(), 1);
1347 match &frames[0] {
1348 Frame::PunchMeNow(decoded) => {
1349 assert_eq!(decoded.round, original.round);
1350 assert_eq!(decoded.target_sequence, original.target_sequence);
1351 assert_eq!(decoded.local_address, original.local_address);
1352 }
1353 x => panic!("incorrect frame {x:?}"),
1354 }
1355 }
1356
1357 #[test]
1358 fn punch_me_now_ipv6_coding() {
1359 let mut buf = Vec::new();
1360 let addr = SocketAddr::from(([0xfe80, 0, 0, 0, 0, 0, 0, 1], 9000));
1361 let original = PunchMeNow {
1362 round: VarInt(2),
1363 target_sequence: VarInt(100),
1364 local_address: addr,
1365 target_peer_id: None,
1366 };
1367 original.encode(&mut buf);
1368 let frames = frames(buf);
1369 assert_eq!(frames.len(), 1);
1370 match &frames[0] {
1371 Frame::PunchMeNow(decoded) => {
1372 assert_eq!(decoded.round, original.round);
1373 assert_eq!(decoded.target_sequence, original.target_sequence);
1374 assert_eq!(decoded.local_address, original.local_address);
1375 }
1376 x => panic!("incorrect frame {x:?}"),
1377 }
1378 }
1379
1380 #[test]
1381 fn remove_address_coding() {
1382 let mut buf = Vec::new();
1383 let original = RemoveAddress {
1384 sequence: VarInt(42),
1385 };
1386 original.encode(&mut buf);
1387 let frames = frames(buf);
1388 assert_eq!(frames.len(), 1);
1389 match &frames[0] {
1390 Frame::RemoveAddress(decoded) => {
1391 assert_eq!(decoded.sequence, original.sequence);
1392 }
1393 x => panic!("incorrect frame {x:?}"),
1394 }
1395 }
1396
1397 #[test]
1398 fn nat_traversal_frame_size_bounds() {
1399 let mut buf = Vec::new();
1401
1402 let addr = AddAddress {
1404 sequence: VarInt::MAX,
1405 address: SocketAddr::from(([0xffff; 8], 65535)),
1406 priority: VarInt::MAX,
1407 };
1408 addr.encode(&mut buf);
1409 assert!(buf.len() <= AddAddress::SIZE_BOUND);
1410 buf.clear();
1411
1412 let punch = PunchMeNow {
1414 round: VarInt::MAX,
1415 target_sequence: VarInt::MAX,
1416 local_address: SocketAddr::from(([0xffff; 8], 65535)),
1417 target_peer_id: Some([0xff; 32]),
1418 };
1419 punch.encode(&mut buf);
1420 assert!(buf.len() <= PunchMeNow::SIZE_BOUND);
1421 buf.clear();
1422
1423 let remove = RemoveAddress {
1425 sequence: VarInt::MAX,
1426 };
1427 remove.encode(&mut buf);
1428 assert!(buf.len() <= RemoveAddress::SIZE_BOUND);
1429 }
1430
1431 #[test]
1432 fn punch_me_now_with_target_peer_id() {
1433 let mut buf = Vec::new();
1434 let target_peer_id = [0x42; 32]; let addr = SocketAddr::from(([192, 168, 1, 100], 12345));
1436 let original = PunchMeNow {
1437 round: VarInt(5),
1438 target_sequence: VarInt(999),
1439 local_address: addr,
1440 target_peer_id: Some(target_peer_id),
1441 };
1442 original.encode(&mut buf);
1443 let frames = frames(buf);
1444 assert_eq!(frames.len(), 1);
1445 match &frames[0] {
1446 Frame::PunchMeNow(decoded) => {
1447 assert_eq!(decoded.round, original.round);
1448 assert_eq!(decoded.target_sequence, original.target_sequence);
1449 assert_eq!(decoded.local_address, original.local_address);
1450 assert_eq!(decoded.target_peer_id, Some(target_peer_id));
1451 }
1452 x => panic!("incorrect frame {x:?}"),
1453 }
1454 }
1455
1456 #[test]
1457 fn nat_traversal_frame_edge_cases() {
1458 let mut buf = Vec::new();
1460
1461 let min_addr = AddAddress {
1463 sequence: VarInt(0),
1464 address: SocketAddr::from(([0, 0, 0, 0], 0)),
1465 priority: VarInt(0),
1466 };
1467 min_addr.encode(&mut buf);
1468 let frames1 = frames(buf.clone());
1469 assert_eq!(frames1.len(), 1);
1470 buf.clear();
1471
1472 let min_punch = PunchMeNow {
1474 round: VarInt(0),
1475 target_sequence: VarInt(0),
1476 local_address: SocketAddr::from(([0, 0, 0, 0], 0)),
1477 target_peer_id: None,
1478 };
1479 min_punch.encode(&mut buf);
1480 let frames2 = frames(buf.clone());
1481 assert_eq!(frames2.len(), 1);
1482 buf.clear();
1483
1484 let min_remove = RemoveAddress {
1486 sequence: VarInt(0),
1487 };
1488 min_remove.encode(&mut buf);
1489 let frames3 = frames(buf);
1490 assert_eq!(frames3.len(), 1);
1491 }
1492
1493 #[test]
1494 fn nat_traversal_frame_boundary_values() {
1495 let mut buf = Vec::new();
1497
1498 let boundary_values = [
1500 VarInt(0),
1501 VarInt(63), VarInt(64), VarInt(16383), VarInt(16384), VarInt(1073741823), VarInt(1073741824), ];
1508
1509 for &sequence in &boundary_values {
1510 for &priority in &boundary_values {
1511 let addr = AddAddress {
1512 sequence,
1513 address: SocketAddr::from(([127, 0, 0, 1], 8080)),
1514 priority,
1515 };
1516 addr.encode(&mut buf);
1517 let parsed_frames = frames(buf.clone());
1518 assert_eq!(parsed_frames.len(), 1);
1519 match &parsed_frames[0] {
1520 Frame::AddAddress(decoded) => {
1521 assert_eq!(decoded.sequence, sequence);
1522 assert_eq!(decoded.priority, priority);
1523 }
1524 x => panic!("incorrect frame {x:?}"),
1525 }
1526 buf.clear();
1527 }
1528 }
1529 }
1530
1531 #[test]
1532 fn nat_traversal_frame_error_handling() {
1533 let malformed_frames = vec![
1535 vec![0x40], vec![0x41], vec![0x42], vec![0x40, 0x01], vec![0x40, 0x01, 0x04], vec![0x41, 0x01], vec![0x41, 0x01, 0x02], vec![0x40, 0x01, 0x99, 0x01, 0x02, 0x03, 0x04], ];
1551
1552 for malformed in malformed_frames {
1553 let result = Iter::new(Bytes::from(malformed)).unwrap().next();
1554 if let Some(frame_result) = result {
1555 match frame_result {
1558 Ok(_) => {} Err(_) => {} }
1561 }
1562 }
1563 }
1564
1565 #[test]
1566 fn nat_traversal_frame_roundtrip_consistency() {
1567 let add_test_cases = vec![
1571 AddAddress {
1572 sequence: VarInt(42),
1573 address: SocketAddr::from(([127, 0, 0, 1], 8080)),
1574 priority: VarInt(100),
1575 },
1576 AddAddress {
1577 sequence: VarInt(1000),
1578 address: SocketAddr::from(([0, 0, 0, 0, 0, 0, 0, 1], 443)),
1579 priority: VarInt(255),
1580 },
1581 ];
1582
1583 for original_add in add_test_cases {
1584 let mut buf = Vec::new();
1585 original_add.encode(&mut buf);
1586
1587 let decoded_frames = frames(buf);
1588 assert_eq!(decoded_frames.len(), 1);
1589
1590 match &decoded_frames[0] {
1591 Frame::AddAddress(decoded) => {
1592 assert_eq!(original_add.sequence, decoded.sequence);
1593 assert_eq!(original_add.address, decoded.address);
1594 assert_eq!(original_add.priority, decoded.priority);
1595 }
1596 _ => panic!("Expected AddAddress frame"),
1597 }
1598 }
1599
1600 let punch_test_cases = vec![
1602 PunchMeNow {
1603 round: VarInt(1),
1604 target_sequence: VarInt(42),
1605 local_address: SocketAddr::from(([192, 168, 1, 1], 9000)),
1606 target_peer_id: None,
1607 },
1608 PunchMeNow {
1609 round: VarInt(10),
1610 target_sequence: VarInt(500),
1611 local_address: SocketAddr::from(([2001, 0xdb8, 0, 0, 0, 0, 0, 1], 12345)),
1612 target_peer_id: Some([0xaa; 32]),
1613 },
1614 ];
1615
1616 for original_punch in punch_test_cases {
1617 let mut buf = Vec::new();
1618 original_punch.encode(&mut buf);
1619
1620 let decoded_frames = frames(buf);
1621 assert_eq!(decoded_frames.len(), 1);
1622
1623 match &decoded_frames[0] {
1624 Frame::PunchMeNow(decoded) => {
1625 assert_eq!(original_punch.round, decoded.round);
1626 assert_eq!(original_punch.target_sequence, decoded.target_sequence);
1627 assert_eq!(original_punch.local_address, decoded.local_address);
1628 assert_eq!(original_punch.target_peer_id, decoded.target_peer_id);
1629 }
1630 _ => panic!("Expected PunchMeNow frame"),
1631 }
1632 }
1633
1634 let remove_test_cases = vec![
1636 RemoveAddress {
1637 sequence: VarInt(123),
1638 },
1639 RemoveAddress {
1640 sequence: VarInt(0),
1641 },
1642 ];
1643
1644 for original_remove in remove_test_cases {
1645 let mut buf = Vec::new();
1646 original_remove.encode(&mut buf);
1647
1648 let decoded_frames = frames(buf);
1649 assert_eq!(decoded_frames.len(), 1);
1650
1651 match &decoded_frames[0] {
1652 Frame::RemoveAddress(decoded) => {
1653 assert_eq!(original_remove.sequence, decoded.sequence);
1654 }
1655 _ => panic!("Expected RemoveAddress frame"),
1656 }
1657 }
1658 }
1659
1660 #[test]
1661 fn nat_traversal_frame_type_constants() {
1662 assert_eq!(FrameType::ADD_ADDRESS.0, 0x40);
1664 assert_eq!(FrameType::PUNCH_ME_NOW.0, 0x41);
1665 assert_eq!(FrameType::REMOVE_ADDRESS.0, 0x42);
1666 }
1667
1668 #[test]
1669 fn observed_address_frame_encoding() {
1670 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1671
1672 let ipv4_cases = vec![
1674 ObservedAddress {
1675 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 8080),
1676 },
1677 ObservedAddress {
1678 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 443),
1679 },
1680 ObservedAddress {
1681 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 65535),
1682 },
1683 ];
1684
1685 for original in ipv4_cases {
1686 let mut buf = Vec::new();
1687 original.encode(&mut buf);
1688
1689 let decoded_frames = frames(buf);
1690 assert_eq!(decoded_frames.len(), 1);
1691
1692 match &decoded_frames[0] {
1693 Frame::ObservedAddress(decoded) => {
1694 assert_eq!(original.address, decoded.address);
1695 }
1696 _ => panic!("Expected ObservedAddress frame"),
1697 }
1698 }
1699
1700 let ipv6_cases = vec![
1702 ObservedAddress {
1703 address: SocketAddr::new(
1704 IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)),
1705 8080,
1706 ),
1707 },
1708 ObservedAddress {
1709 address: SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 443),
1710 },
1711 ObservedAddress {
1712 address: SocketAddr::new(
1713 IpAddr::V6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)),
1714 65535,
1715 ),
1716 },
1717 ];
1718
1719 for original in ipv6_cases {
1720 let mut buf = Vec::new();
1721 original.encode(&mut buf);
1722
1723 let decoded_frames = frames(buf);
1724 assert_eq!(decoded_frames.len(), 1);
1725
1726 match &decoded_frames[0] {
1727 Frame::ObservedAddress(decoded) => {
1728 assert_eq!(original.address, decoded.address);
1729 }
1730 _ => panic!("Expected ObservedAddress frame"),
1731 }
1732 }
1733 }
1734
1735 #[test]
1736 fn observed_address_malformed_frames() {
1737 use bytes::BufMut;
1738
1739 let mut buf = Vec::new();
1741 buf.put_u8(FrameType::OBSERVED_ADDRESS.0 as u8);
1742 buf.put_u8(5); buf.put_slice(&[192, 168, 1, 1]);
1744 buf.put_u16(8080);
1745
1746 let result = Iter::new(Bytes::from(buf));
1747 assert!(result.is_ok());
1748 let mut iter = result.unwrap();
1749 let frame_result = iter.next();
1750 assert!(frame_result.is_some());
1751 assert!(frame_result.unwrap().is_err());
1752
1753 let mut buf = Vec::new();
1755 buf.put_u8(FrameType::OBSERVED_ADDRESS.0 as u8);
1756 buf.put_u8(4); buf.put_slice(&[192, 168]); let result = Iter::new(Bytes::from(buf));
1760 assert!(result.is_ok());
1761 let mut iter = result.unwrap();
1762 let frame_result = iter.next();
1763 assert!(frame_result.is_some());
1764 assert!(frame_result.unwrap().is_err());
1765
1766 let mut buf = Vec::new();
1768 buf.put_u8(FrameType::OBSERVED_ADDRESS.0 as u8);
1769 buf.put_u8(6); buf.put_slice(&[0x20, 0x01, 0x0d, 0xb8]); let result = Iter::new(Bytes::from(buf));
1773 assert!(result.is_ok());
1774 let mut iter = result.unwrap();
1775 let frame_result = iter.next();
1776 assert!(frame_result.is_some());
1777 assert!(frame_result.unwrap().is_err());
1778 }
1779
1780 #[test]
1781 fn observed_address_frame_type_constant() {
1782 assert_eq!(FrameType::OBSERVED_ADDRESS.0, 0x43);
1784 }
1785
1786 #[test]
1787 fn observed_address_frame_serialization_edge_cases() {
1788 use bytes::BufMut;
1789 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1790
1791 let frame_port_0 = ObservedAddress {
1793 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 0),
1794 };
1795 let mut buf = Vec::new();
1796 frame_port_0.encode(&mut buf);
1797 let decoded_frames = frames(buf);
1798 assert_eq!(decoded_frames.len(), 1);
1799 match &decoded_frames[0] {
1800 Frame::ObservedAddress(decoded) => {
1801 assert_eq!(frame_port_0.address, decoded.address);
1802 assert_eq!(decoded.address.port(), 0);
1803 }
1804 _ => panic!("Expected ObservedAddress frame"),
1805 }
1806
1807 let frame_max_port = ObservedAddress {
1809 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 65535),
1810 };
1811 let mut buf = Vec::new();
1812 frame_max_port.encode(&mut buf);
1813 let decoded_frames = frames(buf);
1814 assert_eq!(decoded_frames.len(), 1);
1815 match &decoded_frames[0] {
1816 Frame::ObservedAddress(decoded) => {
1817 assert_eq!(frame_max_port.address, decoded.address);
1818 assert_eq!(decoded.address.port(), 65535);
1819 }
1820 _ => panic!("Expected ObservedAddress frame"),
1821 }
1822
1823 let unspecified_v4 = ObservedAddress {
1825 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 8080),
1826 };
1827 let mut buf = Vec::new();
1828 unspecified_v4.encode(&mut buf);
1829 let decoded_frames = frames(buf);
1830 assert_eq!(decoded_frames.len(), 1);
1831 match &decoded_frames[0] {
1832 Frame::ObservedAddress(decoded) => {
1833 assert_eq!(unspecified_v4.address, decoded.address);
1834 assert_eq!(decoded.address.ip(), IpAddr::V4(Ipv4Addr::UNSPECIFIED));
1835 }
1836 _ => panic!("Expected ObservedAddress frame"),
1837 }
1838
1839 let unspecified_v6 = ObservedAddress {
1840 address: SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 443),
1841 };
1842 let mut buf = Vec::new();
1843 unspecified_v6.encode(&mut buf);
1844 let decoded_frames = frames(buf);
1845 assert_eq!(decoded_frames.len(), 1);
1846 match &decoded_frames[0] {
1847 Frame::ObservedAddress(decoded) => {
1848 assert_eq!(unspecified_v6.address, decoded.address);
1849 assert_eq!(decoded.address.ip(), IpAddr::V6(Ipv6Addr::UNSPECIFIED));
1850 }
1851 _ => panic!("Expected ObservedAddress frame"),
1852 }
1853 }
1854
1855 #[test]
1856 fn observed_address_frame_size_compliance() {
1857 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1858
1859 let test_addresses = vec![
1861 ObservedAddress {
1862 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 8080),
1863 },
1864 ObservedAddress {
1865 address: SocketAddr::new(
1866 IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)),
1867 443,
1868 ),
1869 },
1870 ];
1871
1872 for frame in test_addresses {
1873 let mut buf = Vec::new();
1874 frame.encode(&mut buf);
1875
1876 match frame.address.ip() {
1880 IpAddr::V4(_) => {
1881 assert!(buf.len() >= 8 && buf.len() <= 9, "IPv4 frame size {} out of expected range", buf.len());
1882 }
1883 IpAddr::V6(_) => {
1884 assert!(buf.len() >= 20 && buf.len() <= 21, "IPv6 frame size {} out of expected range", buf.len());
1885 }
1886 }
1887 }
1888 }
1889
1890 #[test]
1891 fn observed_address_multiple_frames_in_packet() {
1892 use crate::coding::BufMutExt;
1893 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
1894
1895 let observed1 = ObservedAddress {
1897 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 1234),
1898 };
1899 let observed2 = ObservedAddress {
1900 address: SocketAddr::new(
1901 IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 2)),
1902 5678,
1903 ),
1904 };
1905
1906 let mut buf = Vec::new();
1907 observed1.encode(&mut buf);
1909 buf.write(FrameType::PING);
1911 observed2.encode(&mut buf);
1913 buf.push(0); let decoded_frames = frames(buf);
1917 assert_eq!(decoded_frames.len(), 4);
1918
1919 match &decoded_frames[0] {
1921 Frame::ObservedAddress(dec) => {
1922 assert_eq!(observed1.address, dec.address);
1923 }
1924 _ => panic!("Expected ObservedAddress at position 0"),
1925 }
1926
1927 match &decoded_frames[1] {
1928 Frame::Ping => {}
1929 _ => panic!("Expected Ping at position 1"),
1930 }
1931
1932 match &decoded_frames[2] {
1933 Frame::ObservedAddress(dec) => {
1934 assert_eq!(observed2.address, dec.address);
1935 }
1936 _ => panic!("Expected ObservedAddress at position 2"),
1937 }
1938
1939 match &decoded_frames[3] {
1940 Frame::Padding => {}
1941 _ => panic!("Expected Padding at position 3"),
1942 }
1943 }
1944
1945 #[test]
1946 fn observed_address_frame_error_recovery() {
1947 use bytes::BufMut;
1948
1949 let mut buf = Vec::new();
1951
1952 buf.put_u8(FrameType::PING.0 as u8);
1954
1955 buf.put_u8(FrameType::OBSERVED_ADDRESS.0 as u8);
1957 buf.put_u8(99); buf.put_slice(&[192, 168, 1, 1]);
1959 buf.put_u16(8080);
1960
1961 buf.put_u8(FrameType::PING.0 as u8);
1963
1964 let result = Iter::new(Bytes::from(buf));
1965 assert!(result.is_ok());
1966 let mut iter = result.unwrap();
1967
1968 let frame1 = iter.next();
1970 assert!(frame1.is_some());
1971 assert!(frame1.unwrap().is_ok());
1972
1973 let frame2 = iter.next();
1975 assert!(frame2.is_some());
1976 assert!(frame2.unwrap().is_err());
1977
1978 let frame3 = iter.next();
1980 assert!(frame3.is_none());
1981 }
1982
1983 #[test]
1984 fn observed_address_frame_varint_encoding() {
1985 use std::net::{IpAddr, Ipv4Addr};
1986
1987 let frame = ObservedAddress {
1989 address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 80),
1990 };
1991
1992 let mut buf = Vec::new();
1993 frame.encode(&mut buf);
1994
1995 assert_eq!(buf[0], 64); assert_eq!(buf[1], 67); }
2023
2024 mod comprehensive_tests {
2026 include!("frame/tests.rs");
2027 }
2028}