1use std::io;
2
3use quik_util::*;
4
5use crate::common::{ConnectionId, PacketNumber, VarInt};
6use crate::crypto::Crypto;
7pub enum Packet<'a> {
10 VersionNegotiation(VersionNegotiation),
11 Initial(Initial<'a>),
12 ZeroRTT(ZeroRTT),
13 Handshake(Handshake),
14 Retry(Retry<'a>),
15 OneRtt(OneRtt),
16}
17
18pub struct VersionNegotiation {
19 pub src_cid: ConnectionId,
20 pub dst_cid: ConnectionId,
21 pub supported_versions: Vec<u32>,
23}
24
25pub struct Initial<'a> {
26 pub src_cid: ConnectionId,
27 pub dst_cid: ConnectionId,
28 pub version: u32,
29
30 pub token: &'a [u8],
31 pub packet_number: u32,
33}
34
35pub struct ZeroRTT {
36 pub src_cid: ConnectionId,
37 pub dst_cid: ConnectionId,
38 pub version: u32,
39
40 pub packet_number: u32,
42}
43
44pub struct Handshake {
45 pub src_cid: ConnectionId,
46 pub dst_cid: ConnectionId,
47 pub version: u32,
48
49 pub packet_number: u32,
51}
52
53pub struct Retry<'a> {
54 pub src_cid: ConnectionId,
55 pub dst_cid: ConnectionId,
56 pub version: u32,
57
58 pub retry_token: &'a [u8],
59 pub retry_integrity_tag: u128,
60}
61
62pub struct OneRtt {
64 pub dst_cid: ConnectionId,
65 pub spin: u8,
66 pub key_phase: u8,
67
68 pub packet_number: u32,
70}
71
72pub enum RemainingBuf {
73 Decrypted(Vec<u8>),
74 None,
76}
77
78impl<'a> Packet<'a> {
79 pub async fn parse(
80 crypto: &impl Crypto,
81 mut data: &'a [u8],
82 ) -> Result<(Packet<'a>, RemainingBuf)> {
83 let first_byte = data.read_u8()?;
84 if first_byte >> 7 != 0 {
86 let packet_type = (first_byte >> 4) & 0b11;
92 let packet_number_length_encoded = first_byte & 0b11;
95 let packet_number_length = 1 + packet_number_length_encoded as usize;
96
97 let version = data.read_u32::<NetworkEndian>()?;
98 let dst_cid = ConnectionId::parse(&mut data)?;
99 let src_cid = ConnectionId::parse(&mut data)?;
100
101 if version == 0 {
102 let (versions_bytes, _remainder) = data.as_chunks::<4>();
106 let versions = versions_bytes
107 .iter()
108 .map(|b| (&b[..]).read_u32::<NetworkEndian>())
109 .collect::<io::Result<Vec<u32>>>()?;
110 let packet = Packet::VersionNegotiation(VersionNegotiation {
113 src_cid,
114 dst_cid: dst_cid.clone(),
115 supported_versions: versions,
116 });
117 return Ok((packet, RemainingBuf::None));
118 }
119 match packet_type {
120 0b00 => {
121 let token_length = VarInt::parse(&mut data)?;
125 let token = data.slice(token_length.into())?;
126 let length = VarInt::parse(&mut data)?; let packet_number = PacketNumber::parse(&mut data, packet_number_length)?;
128
129 let packet = Packet::Initial(Initial {
130 src_cid,
131 dst_cid: dst_cid.clone(),
132 version,
133 token,
134 packet_number,
135 });
136 let payload = crypto
137 .decrypt_initial_data(dst_cid, version, false, &mut data)
138 .await?;
139 Ok((packet, RemainingBuf::Decrypted(payload)))
140 }
141 0b01 => {
142 let length = VarInt::parse(&mut data)?; let packet_number = PacketNumber::parse(&mut data, packet_number_length)?;
147 let payload = data.to_vec(); let packet = Packet::ZeroRTT(ZeroRTT {
150 src_cid,
151 dst_cid: dst_cid.clone(),
152 version,
153 packet_number,
154 });
155 Ok((packet, RemainingBuf::Decrypted(payload)))
156 }
157 0b10 => {
158 let length = VarInt::parse(&mut data)?; let packet_number = PacketNumber::parse(&mut data, packet_number_length)?;
163 let payload = data.to_vec(); let packet = Packet::Handshake(Handshake {
166 src_cid,
167 dst_cid: dst_cid.clone(),
168 version,
169 packet_number,
170 });
171 Ok((packet, RemainingBuf::Decrypted(payload)))
172 }
173 0b11 => {
174 let (retry_token, retry_integrity_tag) = data
179 .split_last_chunk::<16>() .ok_or_else(|| "Packet too short for Retry Token")?;
181 let retry_integrity_tag =
182 (&retry_integrity_tag[..]).read_u128::<NetworkEndian>()?;
183
184 let packet = Packet::Retry(Retry {
185 src_cid,
186 dst_cid: dst_cid.clone(),
187 version,
188 retry_token,
189 retry_integrity_tag,
190 });
191 Ok((packet, RemainingBuf::None))
192 }
193 _ => unreachable!(),
194 }
195 } else {
196 let spin = (first_byte >> 5) & 1;
202 let key_phase = (first_byte >> 2) & 1;
205 let packet_number_length_encoded = first_byte & 0b11;
207 let packet_number_length = 1 + packet_number_length_encoded as usize;
208 let dst_cid = ConnectionId::parse(&mut data)?;
209
210 let packet_number = PacketNumber::parse(&mut data, packet_number_length)?;
213 let payload = data.to_vec(); let packet = Packet::OneRtt(OneRtt {
216 dst_cid: dst_cid.clone(),
217 packet_number,
218 spin,
219 key_phase,
220 });
221 Ok((packet, RemainingBuf::Decrypted(payload)))
222 }
223 }
224}