1use crate::{
29 Buf,
30 BufError::{self},
31 BufMut, BufResult, Codec, Cursor,
32 ietf::quic::{HeaderForm, Version},
33 ietf::quicv1::VariableLengthInteger,
34};
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
43#[repr(u8)]
44pub enum FixedBit {
45 One = 1,
47 VersionNegotiationPacket = 0,
49}
50
51impl Codec for FixedBit {
52 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
53 let current_byte = writer.peek_u8().unwrap_or(0x00);
54 let bit_mask = (*self as u8) << 6;
55 let updated_byte = (current_byte & !0x40) | bit_mask;
56 writer.poke_u8(updated_byte)
57 }
58
59 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
60 let byte = reader.peek_u8()?;
61 match (byte & 0x40) >> 6 {
62 0 => Ok(Self::VersionNegotiationPacket),
63 _ => Ok(Self::One),
64 }
65 }
66}
67
68#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
74#[repr(u8)]
75pub enum LongHeaderPacketType {
76 Initial = 0x00,
78
79 ZeroRtt = 0x01,
81
82 Handshake = 0x02,
84
85 Retry = 0x03,
87}
88
89impl Codec for LongHeaderPacketType {
90 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
91 let current_byte = writer.peek_u8().unwrap_or(0x00);
92 let bit_mask = (*self as u8) << 4;
93 let updated_byte = (current_byte & !0x30) | bit_mask;
94 writer.poke_u8(updated_byte)
95 }
96
97 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
98 let value = (reader.peek_u8()? & 0x30) >> 4;
99 match value {
100 0 => Ok(Self::Initial),
101 1 => Ok(Self::ZeroRtt),
102 2 => Ok(Self::Handshake),
103 _ => Ok(Self::Retry),
104 }
105 }
106}
107
108#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
112pub struct ConnectionId {
113 length: u8,
115 bytes: [u8; Self::MAXIMAL_LENGTH],
117}
118
119impl ConnectionId {
120 pub const MAXIMAL_LENGTH: usize = 20;
122
123 pub fn new(connection_id: &[u8]) -> Option<Self> {
125 let length = connection_id.length();
126 if length > Self::MAXIMAL_LENGTH as usize {
127 return None;
128 }
129 let mut cid = [0u8; Self::MAXIMAL_LENGTH];
130 cid[..length].copy_from_slice(connection_id);
131 let length = length as u8;
132 Some(Self { length, bytes: cid })
133 }
134
135 pub fn into_inner(self) -> (u8, [u8; Self::MAXIMAL_LENGTH]) {
137 (self.length, self.bytes)
138 }
139
140 pub fn length(self) -> u8 {
142 self.length
143 }
144
145 pub fn bytes(self) -> [u8; Self::MAXIMAL_LENGTH] {
147 self.bytes
148 }
149}
150
151impl Codec for ConnectionId {
152 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
153 let (cil, ci) = self.into_inner();
154 cil.encode(writer, ())?;
155 writer.write_slice(&ci[..cil as usize])
156 }
157
158 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
159 let ci = &mut [0u8; Self::MAXIMAL_LENGTH];
160 let cil = u8::decode(reader, ())?;
161 reader.read_into(&mut ci[..cil as usize])?;
162 Ok(Self::new(&ci[..cil as usize]).ok_or(BufError::UnexpectedValue)?)
163 }
164}
165
166impl Codec<u8> for ConnectionId {
167 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: u8) -> BufResult<()> {
168 let (cil, ci) = self.into_inner();
169 writer.write_slice(&ci[..cil as usize])
170 }
171
172 fn decode<R: Buf>(reader: &mut Cursor<R>, cil: u8) -> BufResult<Self> {
173 let ci = &mut [0u8; Self::MAXIMAL_LENGTH];
174 reader.read_into(&mut ci[..cil as usize])?;
175 Ok(Self::new(&ci[..cil as usize]).ok_or(BufError::UnexpectedValue)?)
176 }
177}
178
179#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
185pub struct PacketNumberLength(pub u8);
186
187impl PacketNumberLength {
188 pub fn from_packet_number(packet_number: PacketNumber) -> BufResult<Self> {
190 let pn = packet_number.0.0;
192
193 if pn <= u8::MAX as u64 {
194 Ok(Self(0)) } else if pn <= u16::MAX as u64 {
196 Ok(Self(1)) } else if pn <= 0xFFFFFF {
198 Ok(Self(2)) } else {
200 Ok(Self(3)) }
202 }
203
204 pub fn byte_length(&self) -> u8 {
206 self.0 + 1
207 }
208}
209
210impl Codec for PacketNumberLength {
211 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
212 let current_byte = writer.peek_u8().unwrap_or(0x00);
213 let bit_mask = self.0 & 0x03;
214 let updated_byte = (current_byte & !0x03) | bit_mask;
215
216 writer.write_u8(updated_byte)
217 }
218
219 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
220 Ok(Self(reader.read_u8()? & 0x03))
221 }
222}
223
224#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
230pub struct PacketNumber(pub VariableLengthInteger);
231impl PacketNumber {
232 pub fn new(last_sent: PacketNumber) -> Self {
234 let mut last_sent = last_sent;
235 last_sent.0.0 += 1;
236 Self(last_sent.0)
237 }
238
239 pub fn length(&self) -> BufResult<PacketNumberLength> {
241 PacketNumberLength::from_packet_number(*self)
242 }
243}
244impl Codec<PacketNumberLength> for PacketNumber {
245 fn encode<W: BufMut>(
246 &self,
247 writer: &mut Cursor<W>,
248 length: PacketNumberLength,
249 ) -> BufResult<()> {
250 let pn = self.0.0;
251
252 match length.0 {
253 0 => writer.write_u8(pn as u8),
254 1 => writer.write_u16_be(pn as u16), 2 => {
256 writer.write_u8((pn >> 16) as u8)?;
258 writer.write_u8((pn >> 8) as u8)?;
259 writer.write_u8(pn as u8)
260 }
261 3 => writer.write_u32_be(pn as u32),
262 _ => Err(BufError::UnexpectedValue),
263 }
264 }
265
266 fn decode<R: Buf>(reader: &mut Cursor<R>, length: PacketNumberLength) -> BufResult<Self> {
267 let pn = match length.0 {
268 0 => reader.read_u8()? as u64,
269 1 => reader.read_u16_be()? as u64,
270 2 => {
271 let b1 = reader.read_u8()? as u64;
273 let b2 = reader.read_u8()? as u64;
274 let b3 = reader.read_u8()? as u64;
275 (b1 << 16) | (b2 << 8) | b3
276 }
277 3 => reader.read_u32_be()? as u64,
278 _ => return Err(BufError::UnexpectedValue),
279 };
280
281 Ok(Self(VariableLengthInteger(pn)))
282 }
283}
284
285#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
291pub struct Length(pub VariableLengthInteger);
292impl Length {
293 pub fn calculate(
295 packet_payload_length: usize,
296 packet_number_length: PacketNumberLength,
297 ) -> BufResult<Self> {
298 Ok(Self(VariableLengthInteger::new(
299 packet_payload_length as u64 + packet_number_length.0 as u64,
300 )?))
301 }
302}
303
304impl Codec for Length {
305 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
306 self.0.encode(writer, ())
307 }
308
309 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
310 Ok(Self(VariableLengthInteger::decode(reader, ())?))
311 }
312}
313
314#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
318pub struct RetryToken(pub Vec<u8>);
319
320impl Codec for RetryToken {
321 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
323 self.0.encode(writer, ())
324 }
325
326 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
328 let remaining = reader.remaining();
329 if remaining < 16 {
330 return Err(BufError::OutOfBounds);
331 }
332 let length = remaining - 16;
333 Ok(Self(Vec::decode(reader, length)?))
334 }
335}
336
337impl Codec<VariableLengthInteger> for RetryToken {
338 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: VariableLengthInteger) -> BufResult<()> {
340 self.0.encode(writer, ())
341 }
342
343 fn decode<R: Buf>(reader: &mut Cursor<R>, length: VariableLengthInteger) -> BufResult<Self> {
345 Ok(Self(Vec::decode(reader, length.0 as usize)?))
346 }
347}
348
349#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
351pub struct RetryIntegrityTag(pub [u8; 16]);
352
353impl Codec for RetryIntegrityTag {
354 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
355 writer.write_array(&self.0)
356 }
357
358 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
359 Ok(Self(reader.read_array::<16>()?))
360 }
361}
362
363#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
369#[repr(u8)]
370pub enum SpinBit {
371 Zero = 0,
373 One = 1,
375}
376
377impl SpinBit {
378 pub fn spin(&mut self) {
380 *self = match self {
381 SpinBit::Zero => SpinBit::One,
382 SpinBit::One => SpinBit::Zero,
383 }
384 }
385}
386
387impl Codec for SpinBit {
388 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
389 let current_byte = writer.peek_u8().unwrap_or(0x00);
390 let bit_mask = (*self as u8) << 5;
391 let updated_byte = (current_byte & !0b100000) | bit_mask;
392 writer.poke_u8(updated_byte)
393 }
394
395 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
396 let value = reader.peek_u8()? & 0b100000;
397 match value {
398 0 => Ok(Self::Zero),
399 _ => Ok(Self::One),
400 }
401 }
402}
403
404#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
410#[repr(u8)]
411pub enum KeyPhase {
412 Zero = 0,
414 One = 1,
416}
417
418impl Codec for KeyPhase {
419 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
420 let current_byte = writer.peek_u8().unwrap_or(0x00);
421 let bit_mask = (*self as u8) << 2;
422 let updated_byte = (current_byte & !0b100) | bit_mask;
423 writer.poke_u8(updated_byte)
424 }
425
426 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
427 let value = reader.peek_u8()? & 0b100;
428 match value {
429 0 => Ok(Self::Zero),
430 _ => Ok(Self::One),
431 }
432 }
433}
434
435#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
443pub struct InitialPacket {
444 pub version: Version,
446 pub destination_connection_id: ConnectionId,
448 pub source_connection_id: ConnectionId,
450 pub token: RetryToken,
452 pub packet_number: PacketNumber,
454 pub packet_payload: Vec<u8>,
456}
457
458impl InitialPacket {
459 pub const HEADER_FORM: HeaderForm = HeaderForm::LongHeader;
461 pub const FIXED_BIT: FixedBit = FixedBit::One;
463 pub const LONG_PACKET_TYPE: LongHeaderPacketType = LongHeaderPacketType::Initial;
465}
466
467impl Codec for InitialPacket {
468 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
469 Self::HEADER_FORM.encode(writer, ())?;
470 Self::FIXED_BIT.encode(writer, ())?;
471 Self::LONG_PACKET_TYPE.encode(writer, ())?;
472 let packet_number_length = self.packet_number.length()?;
473 packet_number_length.encode(writer, ())?;
474 self.version.encode(writer, ())?;
475 self.destination_connection_id.encode(writer, ())?;
476 self.source_connection_id.encode(writer, ())?;
477 VariableLengthInteger::new(self.token.0.len() as u64)?.encode(writer, ())?;
478 self.token.0.encode(writer, ())?;
479 Length::calculate(self.packet_payload.len(), packet_number_length)?.encode(writer, ())?;
480 self.packet_number.encode(writer, packet_number_length)?;
481 self.packet_payload.encode(writer, ())
482 }
483
484 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
485 if HeaderForm::decode(reader, ())? != Self::HEADER_FORM {
486 return Err(BufError::UnexpectedValue);
487 }
488 if FixedBit::decode(reader, ())? != Self::FIXED_BIT {
489 return Err(BufError::UnexpectedValue);
490 }
491 if LongHeaderPacketType::decode(reader, ())? != Self::LONG_PACKET_TYPE {
492 return Err(BufError::UnexpectedValue);
493 }
494 let packet_number_length = PacketNumberLength::decode(reader, ())?;
495 let version = Version::decode(reader, ())?;
496 let destination_connection_id = ConnectionId::decode(reader, ())?;
497 let source_connection_id = ConnectionId::decode(reader, ())?;
498 let token_length = VariableLengthInteger::decode(reader, ())?;
499 let token_bytes = &mut [0u8; 16];
500 reader.read_into(&mut token_bytes[..token_length.0 as usize])?;
501 let token = RetryToken((&token_bytes[..token_length.0 as usize]).to_vec());
502 let _length = VariableLengthInteger::decode(reader, ())?;
503 let packet_number = PacketNumber::decode(reader, packet_number_length)?;
504 let packet_payload = Vec::decode(reader, ())?;
505
506 Ok(Self {
507 version,
508 destination_connection_id,
509 source_connection_id,
510 token,
511 packet_number,
512 packet_payload,
513 })
514 }
515}
516
517#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
523pub struct ZeroRttPacket {
524 pub version: Version,
526 pub destination_connection_id: ConnectionId,
528 pub source_connection_id: ConnectionId,
530 pub packet_number: PacketNumber,
532 pub packet_payload: Vec<u8>,
534}
535
536impl ZeroRttPacket {
537 pub const HEADER_FORM: HeaderForm = HeaderForm::LongHeader;
539 pub const FIXED_BIT: FixedBit = FixedBit::One;
541 pub const LONG_PACKET_TYPE: LongHeaderPacketType = LongHeaderPacketType::ZeroRtt;
543}
544
545impl Codec for ZeroRttPacket {
546 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
547 Self::HEADER_FORM.encode(writer, ())?;
548 Self::FIXED_BIT.encode(writer, ())?;
549 Self::LONG_PACKET_TYPE.encode(writer, ())?;
550 let packet_number_length = self.packet_number.length()?;
551 packet_number_length.encode(writer, ())?;
552 self.version.encode(writer, ())?;
553 self.destination_connection_id.encode(writer, ())?;
554 self.source_connection_id.encode(writer, ())?;
555 Length::calculate(self.packet_payload.len(), packet_number_length)?.encode(writer, ())?;
556 self.packet_number.encode(writer, packet_number_length)?;
557 self.packet_payload.encode(writer, ())
558 }
559
560 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
561 if HeaderForm::decode(reader, ())? != Self::HEADER_FORM {
562 return Err(BufError::UnexpectedValue);
563 }
564 if FixedBit::decode(reader, ())? != Self::FIXED_BIT {
565 return Err(BufError::UnexpectedValue);
566 }
567 if LongHeaderPacketType::decode(reader, ())? != Self::LONG_PACKET_TYPE {
568 return Err(BufError::UnexpectedValue);
569 }
570 let packet_number_length = PacketNumberLength::decode(reader, ())?;
571 let version = Version::decode(reader, ())?;
572 let destination_connection_id = ConnectionId::decode(reader, ())?;
573 let source_connection_id = ConnectionId::decode(reader, ())?;
574 let _length = VariableLengthInteger::decode(reader, ())?;
575 let packet_number = PacketNumber::decode(reader, packet_number_length)?;
576 let packet_payload = Vec::decode(reader, ())?;
577
578 Ok(Self {
579 version,
580 destination_connection_id,
581 source_connection_id,
582 packet_number,
583 packet_payload,
584 })
585 }
586}
587
588#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
594pub struct HandshakePacket {
595 pub version: Version,
597 pub destination_connection_id: ConnectionId,
599 pub source_connection_id: ConnectionId,
601 pub packet_number: PacketNumber,
603 pub packet_payload: Vec<u8>,
605}
606
607impl HandshakePacket {
608 pub const HEADER_FORM: HeaderForm = HeaderForm::LongHeader;
610 pub const FIXED_BIT: FixedBit = FixedBit::One;
612 pub const LONG_PACKET_TYPE: LongHeaderPacketType = LongHeaderPacketType::Handshake;
614}
615
616impl Codec for HandshakePacket {
617 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
618 Self::HEADER_FORM.encode(writer, ())?;
619 Self::FIXED_BIT.encode(writer, ())?;
620 Self::LONG_PACKET_TYPE.encode(writer, ())?;
621 let packet_number_length = self.packet_number.length()?;
622 packet_number_length.encode(writer, ())?;
623 self.version.encode(writer, ())?;
624 self.destination_connection_id.encode(writer, ())?;
625 self.source_connection_id.encode(writer, ())?;
626 Length::calculate(self.packet_payload.len(), packet_number_length)?.encode(writer, ())?;
627 self.packet_number.encode(writer, packet_number_length)?;
628 self.packet_payload.encode(writer, ())
629 }
630
631 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
632 if HeaderForm::decode(reader, ())? != Self::HEADER_FORM {
633 return Err(BufError::UnexpectedValue);
634 }
635 if FixedBit::decode(reader, ())? != Self::FIXED_BIT {
636 return Err(BufError::UnexpectedValue);
637 }
638 if LongHeaderPacketType::decode(reader, ())? != Self::LONG_PACKET_TYPE {
639 return Err(BufError::UnexpectedValue);
640 }
641 let packet_number_length = PacketNumberLength::decode(reader, ())?;
642 let version = Version::decode(reader, ())?;
643 let destination_connection_id = ConnectionId::decode(reader, ())?;
644 let source_connection_id = ConnectionId::decode(reader, ())?;
645 let _length = VariableLengthInteger::decode(reader, ())?;
646 let packet_number = PacketNumber::decode(reader, packet_number_length)?;
647 let packet_payload = Vec::decode(reader, ())?;
648
649 Ok(Self {
650 version,
651 destination_connection_id,
652 source_connection_id,
653 packet_number,
654 packet_payload,
655 })
656 }
657}
658
659#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
666pub struct RetryPacket {
667 pub version: Version,
669 pub destination_connection_id: ConnectionId,
671 pub source_connection_id: ConnectionId,
673 pub retry_token: RetryToken,
675 pub retry_integrity_tag: RetryIntegrityTag,
677}
678
679impl RetryPacket {
680 pub const HEADER_FORM: HeaderForm = HeaderForm::LongHeader;
682 pub const FIXED_BIT: FixedBit = FixedBit::One;
684 pub const LONG_PACKET_TYPE: LongHeaderPacketType = LongHeaderPacketType::Retry;
686}
687
688impl Codec for RetryPacket {
689 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
690 Self::HEADER_FORM.encode(writer, ())?;
691 Self::FIXED_BIT.encode(writer, ())?;
692 Self::LONG_PACKET_TYPE.encode(writer, ())?;
693 writer.advance(1)?;
694 self.version.encode(writer, ())?;
695 self.destination_connection_id.encode(writer, ())?;
696 self.source_connection_id.encode(writer, ())?;
697 self.retry_token.encode(writer, ())?;
698 self.retry_integrity_tag.encode(writer, ())
699 }
700
701 fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
702 if HeaderForm::decode(reader, ())? != Self::HEADER_FORM {
703 return Err(BufError::UnexpectedValue);
704 }
705 if FixedBit::decode(reader, ())? != Self::FIXED_BIT {
706 return Err(BufError::UnexpectedValue);
707 }
708 if LongHeaderPacketType::decode(reader, ())? != Self::LONG_PACKET_TYPE {
709 return Err(BufError::UnexpectedValue);
710 }
711 reader.advance(1)?;
712 let version = Version::decode(reader, ())?;
713 let destination_connection_id = ConnectionId::decode(reader, ())?;
714 let source_connection_id = ConnectionId::decode(reader, ())?;
715 let mut left = Vec::decode(reader, ())?;
716 let length = left.len();
717 let (retry_token, _retry_integrity_tag) = left.split_at_mut_checked(length - 16).unwrap();
718 let retry_token = RetryToken(retry_token.to_vec());
719 let retry_integrity_tag = match _retry_integrity_tag.try_into() {
720 Ok(x) => x,
721 Err(_) => return Err(BufError::UnexpectedValue),
722 };
723 let retry_integrity_tag = RetryIntegrityTag(retry_integrity_tag);
724 Ok(Self {
725 version,
726 destination_connection_id,
727 source_connection_id,
728 retry_token,
729 retry_integrity_tag,
730 })
731 }
732}
733
734#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
740pub struct OneRttPacket {
741 pub spin_bit: SpinBit,
743 pub key_phase: KeyPhase,
745 pub destination_connection_id: ConnectionId,
747 pub packet_number: PacketNumber,
749 pub packet_payload: Vec<u8>,
751}
752
753impl OneRttPacket {
754 pub const HEADER_FORM: HeaderForm = HeaderForm::ShortHeader;
756 pub const FIXED_BIT: FixedBit = FixedBit::One;
758}
759
760impl Codec<u8> for OneRttPacket {
761 fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, dcid_length: u8) -> BufResult<()> {
762 Self::HEADER_FORM.encode(writer, ())?;
763 Self::FIXED_BIT.encode(writer, ())?;
764 self.spin_bit.encode(writer, ())?;
765 self.key_phase.encode(writer, ())?;
766 let packet_number_length = self.packet_number.length()?;
767 packet_number_length.encode(writer, ())?;
768 self.destination_connection_id.encode(writer, dcid_length)?;
769 self.packet_number.encode(writer, packet_number_length)?;
770 self.packet_payload.encode(writer, ())
771 }
772
773 fn decode<R: Buf>(reader: &mut Cursor<R>, dcid_length: u8) -> BufResult<Self> {
774 if HeaderForm::decode(reader, ())? != Self::HEADER_FORM {
775 return Err(BufError::UnexpectedValue);
776 }
777 if FixedBit::decode(reader, ())? != Self::FIXED_BIT {
778 return Err(BufError::UnexpectedValue);
779 }
780 let spin_bit = SpinBit::decode(reader, ())?;
781 let key_phase = KeyPhase::decode(reader, ())?;
782 let packet_number_length = PacketNumberLength::decode(reader, ())?;
783 let destination_connection_id = ConnectionId::decode(reader, dcid_length)?;
784 let packet_number = PacketNumber::decode(reader, packet_number_length)?;
785 let packet_payload = Vec::decode(reader, ())?;
786
787 Ok(Self {
788 spin_bit,
789 key_phase,
790 destination_connection_id,
791 packet_number,
792 packet_payload,
793 })
794 }
795}
796
797#[cfg(test)]
798mod tests {
799 use core::fmt::Debug;
800
801 use crate::{
802 Codec, Cursor,
803 ietf::quic::Version,
804 ietf::quicv1::{
805 ConnectionId, FixedBit, HandshakePacket, InitialPacket, KeyPhase, LongHeaderPacketType,
806 OneRttPacket, PacketNumber, PacketNumberLength, RetryIntegrityTag, RetryPacket,
807 RetryToken, SpinBit, VariableLengthInteger, ZeroRttPacket,
808 },
809 };
810
811 fn codec_roundtrip<T: Codec<C> + Debug + Eq, C: Copy>(
812 etalon_struct: T,
813 etalon_bytes: &[u8],
814 context: C,
815 ) {
816 let mut encoded_bytes = vec![];
817 {
818 let writer = &mut Cursor::new(&mut encoded_bytes);
819 etalon_struct.encode(writer, context).unwrap();
820 }
821 assert_eq!(etalon_bytes, &encoded_bytes);
822
823 let decoded_struct = {
824 let reader = &mut Cursor::new(&mut encoded_bytes);
825 T::decode(reader, context).unwrap()
826 };
827 assert_eq!(etalon_struct, decoded_struct);
828
829 encoded_bytes.fill(0x00);
830 {
831 let writer = &mut Cursor::new(&mut encoded_bytes);
832 decoded_struct.encode(writer, context).unwrap();
833 }
834 assert_eq!(etalon_bytes, &encoded_bytes);
835 }
836
837 #[test]
838 fn fixed_bit() {
839 let etalon_bytes = &[0b01000000];
840 let etalon_struct = FixedBit::One;
841 codec_roundtrip(etalon_struct, etalon_bytes, ());
842
843 let etalon_bytes = &[0b00000000];
844 let etalon_struct = FixedBit::VersionNegotiationPacket;
845 codec_roundtrip(etalon_struct, etalon_bytes, ());
846 }
847
848 #[test]
849 fn long_header_packet_type() {
850 let etalon_bytes = &[0b00000000];
851 let etalon_struct = LongHeaderPacketType::Initial;
852 codec_roundtrip(etalon_struct, etalon_bytes, ());
853
854 let etalon_bytes = &[0b00010000];
855 let etalon_struct = LongHeaderPacketType::ZeroRtt;
856 codec_roundtrip(etalon_struct, etalon_bytes, ());
857
858 let etalon_bytes = &[0b00100000];
859 let etalon_struct = LongHeaderPacketType::Handshake;
860 codec_roundtrip(etalon_struct, etalon_bytes, ());
861
862 let etalon_bytes = &[0b00110000];
863 let etalon_struct = LongHeaderPacketType::Retry;
864 codec_roundtrip(etalon_struct, etalon_bytes, ());
865 }
866
867 #[test]
868 fn connection_id() {
869 assert_eq!(ConnectionId::new(&[0x08; 21]), None);
870
871 let etalon_bytes = &[0x08; 9];
872 let etalon_struct = ConnectionId::new(&[0x08; 8]).unwrap();
873 codec_roundtrip(etalon_struct, etalon_bytes, ());
874
875 let etalon_bytes = &[0x010; 17];
876 let etalon_struct = ConnectionId::new(&[0x010; 16]).unwrap();
877 codec_roundtrip(etalon_struct, etalon_bytes, ());
878
879 let etalon_bytes = &[0x014; 21];
880 let etalon_struct = ConnectionId::new(&[0x014; 20]).unwrap();
881 codec_roundtrip(etalon_struct, etalon_bytes, ());
882 }
883
884 #[test]
885 fn packet_number_length() {
886 let etalon_bytes = &[0x00];
887 let etalon_struct = PacketNumberLength::from_packet_number(PacketNumber(
888 VariableLengthInteger::new(0).unwrap(),
889 ))
890 .unwrap();
891 codec_roundtrip(etalon_struct, etalon_bytes, ());
892 }
893
894 #[test]
895 fn packet_number() {
896 let etalon_bytes = &[0x00];
897 let etalon_struct = PacketNumber(VariableLengthInteger::new(0).unwrap());
898 codec_roundtrip(etalon_struct, etalon_bytes, etalon_struct.length().unwrap());
899 }
900
901 #[test]
902 fn token() {
903 let etalon_bytes = &[
904 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
905 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
907 0x00, 0x00, ];
909 let etalon_struct = RetryToken(vec![0x00; 16]);
910 {
911 let context = ();
912 let mut encoded_bytes = vec![];
913 {
914 let writer = &mut Cursor::new(&mut encoded_bytes);
915 etalon_struct.encode(writer, context).unwrap();
916 }
917 encoded_bytes.extend_from_slice(&[0x00; 16]);
918 assert_eq!(&etalon_bytes.to_vec(), &encoded_bytes);
919
920 let decoded_struct = {
921 let reader = &mut Cursor::new(&mut encoded_bytes);
922 RetryToken::decode(reader, context).unwrap()
923 };
924 assert_eq!(etalon_struct, decoded_struct);
925
926 encoded_bytes.fill(0x00);
927 {
928 let writer = &mut Cursor::new(&mut encoded_bytes);
929 decoded_struct.encode(writer, context).unwrap();
930 }
931 assert_eq!(&etalon_bytes.to_vec(), &encoded_bytes);
932 };
933
934 let etalon_bytes = &[
935 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
936 0x00, 0x00,
937 ];
938 let etalon_struct = RetryToken(vec![0x00; 16]);
939 codec_roundtrip(
940 etalon_struct,
941 etalon_bytes,
942 VariableLengthInteger::new_const(16),
943 );
944 }
945
946 #[test]
947 fn retry_integrity_tag() {
948 let etalon_bytes = &[0; 16];
949 let etalon_struct = RetryIntegrityTag([0; 16]);
950
951 codec_roundtrip(etalon_struct, etalon_bytes, ());
952 }
953
954 #[test]
955 fn spin_bit() {
956 let etalon_bytes = &[0b00000000];
957 let etalon_struct = SpinBit::Zero;
958 codec_roundtrip(etalon_struct, etalon_bytes, ());
959
960 let etalon_bytes = &[0b00100000];
961 let etalon_struct = SpinBit::One;
962 codec_roundtrip(etalon_struct, etalon_bytes, ());
963 }
964
965 #[test]
966 fn key_phase() {
967 let etalon_bytes = &[0b00000000];
968 let etalon_struct = KeyPhase::Zero;
969 codec_roundtrip(etalon_struct, etalon_bytes, ());
970
971 let etalon_bytes = &[0b100];
972 let etalon_struct = KeyPhase::One;
973 codec_roundtrip(etalon_struct, etalon_bytes, ());
974 }
975
976 #[test]
977 fn initial_packet() {
978 let etalon_struct = InitialPacket {
979 version: Version(1),
980 destination_connection_id: ConnectionId::new(&[0x82; 8]).unwrap(),
981 source_connection_id: ConnectionId::new(&[0x41; 8]).unwrap(),
982 token: RetryToken(vec![0]),
983 packet_number: PacketNumber(VariableLengthInteger::new(0).unwrap()),
984 packet_payload: vec![],
985 };
986
987 let etalon_bytes: &[u8] = &[
990 0xC0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
993 0x08, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x01, 0x00, 0x00, 0x00,
999 ];
1000
1001 codec_roundtrip(etalon_struct, etalon_bytes, ());
1002 }
1003
1004 #[test]
1005 fn zero_rtt_packet() {
1006 let etalon_struct = ZeroRttPacket {
1007 version: Version(1),
1008 destination_connection_id: ConnectionId::new(&[0x82; 8]).unwrap(),
1009 source_connection_id: ConnectionId::new(&[0x41; 8]).unwrap(),
1010 packet_number: PacketNumber(VariableLengthInteger::new(0).unwrap()),
1011 packet_payload: vec![],
1012 };
1013
1014 let etalon_bytes: &[u8] = &[
1016 0xD0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
1020 0x08, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1022 0x00, 0x00,
1025 ];
1026
1027 codec_roundtrip(etalon_struct, etalon_bytes, ());
1028 }
1029
1030 #[test]
1031 fn handshake_packet() {
1032 let etalon_struct = HandshakePacket {
1033 version: Version(1),
1034 destination_connection_id: ConnectionId::new(&[0x82; 8]).unwrap(),
1035 source_connection_id: ConnectionId::new(&[0x41; 8]).unwrap(),
1036 packet_number: PacketNumber(VariableLengthInteger::new(0).unwrap()),
1037 packet_payload: vec![],
1038 };
1039
1040 let etalon_bytes: &[u8] = &[
1042 0xE0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
1046 0x08, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
1048 0x00, 0x00, ];
1051
1052 codec_roundtrip(etalon_struct, etalon_bytes, ());
1053 }
1054
1055 #[test]
1056 fn retry_packet() {
1057 let etalon_struct = RetryPacket {
1058 version: Version(1),
1059 destination_connection_id: ConnectionId::new(&[0x82; 8]).unwrap(),
1060 source_connection_id: ConnectionId::new(&[0x41; 8]).unwrap(),
1061 retry_token: RetryToken(vec![0]),
1062 retry_integrity_tag: RetryIntegrityTag([0x55; 16]),
1063 };
1064
1065 let etalon_bytes: &[u8] = &[
1066 0xF0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
1070 0x08, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
1074 0x55, 0x55,
1075 ];
1076
1077 codec_roundtrip(etalon_struct, etalon_bytes, ());
1078 }
1079
1080 #[test]
1081 fn one_rtt_packet() {
1082 let etalon_struct = OneRttPacket {
1083 spin_bit: SpinBit::Zero,
1084 key_phase: KeyPhase::Zero,
1085 destination_connection_id: ConnectionId::new(&[0x82; 8]).unwrap(),
1086 packet_number: PacketNumber(VariableLengthInteger::new(0).unwrap()),
1087 packet_payload: vec![],
1088 };
1089
1090 let etalon_bytes: &[u8] = &[
1091 0b01000000, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x00, ];
1095
1096 codec_roundtrip(etalon_struct, etalon_bytes, 8);
1097 }
1098}