1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use crate::h3::parts::Parts;
15 
16 /// Data Frame type code.
17 pub const DATA_FRAME_TYPE: u64 = 0x0;
18 /// HEADERS Frame type code.
19 pub const HEADERS_FRAME_TYPE: u64 = 0x1;
20 /// CANCEL_PUSH Frame type code.
21 pub const CANCEL_PUSH_FRAME_TYPE: u64 = 0x3;
22 /// SETTINGS Frame type code.
23 pub const SETTINGS_FRAME_TYPE: u64 = 0x4;
24 /// PUSH_PROMISE Frame type code.
25 pub const PUSH_PROMISE_FRAME_TYPE: u64 = 0x5;
26 /// GOAWAY Frame type code.
27 pub const GOAWAY_FRAME_TYPE: u64 = 0x7;
28 /// MAX_PUSH_ID Frame type code.
29 pub const MAX_PUSH_ID_FRAME_TYPE: u64 = 0xD;
30 /// SETTING_QPACK_MAX_TABLE_CAPACITY setting code.
31 pub const SETTING_QPACK_MAX_TABLE_CAPACITY: u64 = 0x1;
32 /// SETTING_MAX_FIELD_SECTION_SIZE setting code.
33 pub const SETTING_MAX_FIELD_SECTION_SIZE: u64 = 0x6;
34 /// SETTING_QPACK_BLOCKED_STREAMS setting code.
35 pub const SETTING_QPACK_BLOCKED_STREAMS: u64 = 0x7;
36 /// SETTING_ENABLE_CONNECT_PROTOCOL setting code.
37 pub const SETTING_ENABLE_CONNECT_PROTOCOL: u64 = 0x8;
38 /// SETTING_H3_DATAGRAM setting code.
39 pub const SETTING_H3_DATAGRAM: u64 = 0x33;
40 /// MAX_SETTING_PAYLOAD_SIZE setting code.
41 // Permit between 16 maximally-encoded and 128 minimally-encoded SETTINGS.
42 const MAX_SETTING_PAYLOAD_SIZE: usize = 256;
43 
44 /// Http3 frame definition.
45 #[derive(Clone, Debug)]
46 pub struct Frame {
47     ty: u64,
48     payload: Payload,
49 }
50 
51 /// Http3 frame payload.
52 #[derive(Clone, Debug)]
53 pub enum Payload {
54     /// HEADERS frame payload.
55     Headers(Headers),
56     /// DATA frame payload.
57     Data(Data),
58     /// SETTINGS frame payload.
59     Settings(Settings),
60     /// CancelPush frame payload.
61     CancelPush(CancelPush),
62     /// PushPromise frame payload.
63     PushPromise(PushPromise),
64     /// GOAWAY frame payload.
65     Goaway(GoAway),
66     /// MaxPushId frame payload.
67     MaxPushId(MaxPushId),
68     /// Unknown frame payload.
69     Unknown(Unknown),
70 }
71 
72 /// Http3 Headers frame payload, which also contains instructions to send when
73 /// decoding.
74 #[derive(Clone, Debug)]
75 pub struct Headers {
76     parts: Parts,
77     ins: Option<Vec<u8>>,
78 }
79 
80 /// Http3 Data frame payload, containing the body data.
81 #[derive(Clone, Debug)]
82 pub struct Data {
83     data: Vec<u8>,
84 }
85 
86 /// Http3 Settings frame payload.
87 #[derive(Clone, Default, Debug)]
88 pub struct Settings {
89     max_field_section_size: Option<u64>,
90     qpack_max_table_capacity: Option<u64>,
91     qpack_blocked_streams: Option<u64>,
92     connect_protocol_enabled: Option<u64>,
93     h3_datagram: Option<u64>,
94     additional: Option<Vec<(u64, u64)>>,
95 }
96 
97 /// Http3 CancelPush frame payload.
98 #[derive(Clone, Debug)]
99 pub struct CancelPush {
100     push_id: u64,
101 }
102 
103 /// Http3 PushPromise frame payload.
104 #[derive(Clone, Debug)]
105 pub struct PushPromise {
106     push_id: u64,
107     parts: Parts,
108     ins: Option<Vec<u8>>,
109 }
110 
111 /// Http3 GoAway frame payload.
112 #[derive(Clone, Debug)]
113 pub struct GoAway {
114     id: u64,
115 }
116 
117 /// Http3 MaxPushId frame payload.
118 #[derive(Clone, Debug)]
119 pub struct MaxPushId {
120     push_id: u64,
121 }
122 
123 /// Http3 Unknown frame payload.
124 #[derive(Clone, Debug)]
125 pub struct Unknown {
126     raw_type: u64,
127     len: u64,
128 }
129 
130 impl Frame {
131     /// Constructs a Frame with type and payload.
newnull132     pub fn new(ty: u64, payload: Payload) -> Self {
133         Frame { ty, payload }
134     }
135 
136     /// Gets frame type.
frame_typenull137     pub fn frame_type(&self) -> &u64 {
138         &self.ty
139     }
140 
141     /// Gets frame payload.
payloadnull142     pub fn payload(&self) -> &Payload {
143         &self.payload
144     }
145 
146     /// Gets a mutable frame payload of current frame.
147     pub(crate) fn payload_mut(&mut self) -> &mut Payload {
148         &mut self.payload
149     }
150 }
151 
152 impl Settings {
153     /// Sets SETTINGS_HEADER_TABLE_SIZE (0x01) setting.
set_max_field_section_sizenull154     pub fn set_max_field_section_size(&mut self, size: u64) {
155         self.max_field_section_size = Some(size)
156     }
157 
158     /// Sets SETTINGS_ENABLE_PUSH (0x02) setting.
set_qpack_max_table_capacitynull159     pub fn set_qpack_max_table_capacity(&mut self, size: u64) {
160         self.qpack_max_table_capacity = Some(size)
161     }
162 
163     /// Sets SETTINGS_MAX_FRAME_SIZE (0x05) setting.
set_qpack_block_streamnull164     pub fn set_qpack_block_stream(&mut self, size: u64) {
165         self.qpack_blocked_streams = Some(size)
166     }
167 
168     /// Sets SETTINGS_MAX_HEADER_LIST_SIZE (0x06) setting.
set_connect_protocol_enablednull169     pub fn set_connect_protocol_enabled(&mut self, size: u64) {
170         self.connect_protocol_enabled = Some(size)
171     }
172 
173     /// Sets SETTINGS_H3_DATAGRAM setting.
set_h3_datagramnull174     pub fn set_h3_datagram(&mut self, size: u64) {
175         self.h3_datagram = Some(size);
176     }
177 
178     /// Sets additional settings.
set_additionalnull179     pub fn set_additional(&mut self, addition: Vec<(u64, u64)>) {
180         self.additional = Some(addition)
181     }
182 
183     /// Gets SETTINGS_MAX_FIELD_SECTION_SIZE setting.
max_fied_section_sizenull184     pub fn max_fied_section_size(&self) -> Option<u64> {
185         self.max_field_section_size
186     }
187 
188     /// Gets SETTINGS_QPACK_MAX_TABLE_CAPACITY setting.
qpack_max_table_capacitynull189     pub fn qpack_max_table_capacity(&self) -> Option<u64> {
190         self.qpack_max_table_capacity
191     }
192 
193     /// Gets SETTINGS_QPACK_BLOCKED_STREAMS setting.
qpack_block_streamnull194     pub fn qpack_block_stream(&self) -> Option<u64> {
195         self.qpack_blocked_streams
196     }
197 
198     /// Gets SETTINGS_ENABLE_CONNECT_PROTOCOL setting.
connect_protocol_enablednull199     pub fn connect_protocol_enabled(&self) -> Option<u64> {
200         self.connect_protocol_enabled
201     }
202 
203     /// Gets SETTINGS_H3_DATAGRAM setting.
h3_datagramnull204     pub fn h3_datagram(&self) -> Option<u64> {
205         self.h3_datagram
206     }
207 
208     /// Gets additional settings.
additionalnull209     pub fn additional(&self) -> &Option<Vec<(u64, u64)>> {
210         &self.additional
211     }
212 }
213 
214 impl Data {
215     /// Creates a new Data instance containing the provided data.
newnull216     pub fn new(data: Vec<u8>) -> Self {
217         Data { data }
218     }
219 
220     /// Return the `Vec` that contains the data payload.
datanull221     pub fn data(&self) -> &Vec<u8> {
222         &self.data
223     }
224 }
225 
226 impl CancelPush {
227     /// Creates a new CancelPush instance from the provided Parts.
newnull228     pub fn new(id: u64) -> Self {
229         CancelPush { push_id: id }
230     }
231 
232     /// Gets push id of CancelPush payload.
get_push_idnull233     pub fn get_push_id(&self) -> &u64 {
234         &self.push_id
235     }
236 }
237 
238 impl Headers {
239     /// Creates a new Headers instance from the provided Parts.
newnull240     pub fn new(parts: Parts) -> Self {
241         Headers { parts, ins: None }
242     }
243 
244     /// Gets the instructions generated by qpack decoder after decoding headers
245     /// frame.
get_instructionnull246     pub fn get_instruction(&self) -> &Option<Vec<u8>> {
247         &self.ins
248     }
249 
250     /// Gets headers part of Headers frame payload.
get_partnull251     pub fn get_part(&self) -> Parts {
252         self.parts.clone()
253     }
254 
255     pub(crate) fn set_instruction(&mut self, buf: Vec<u8>) {
256         self.ins = Some(buf)
257     }
258 }
259 
260 impl PushPromise {
261     /// Creates a new PushPromise instance from the provided Parts.
newnull262     pub fn new(push_id: u64, parts: Parts) -> Self {
263         PushPromise {
264             push_id,
265             parts,
266             ins: None,
267         }
268     }
269 
270     /// Gets push id of PushPromise payload.
get_push_idnull271     pub fn get_push_id(&self) -> u64 {
272         self.push_id
273     }
274 
275     /// Returns a copy of the internal parts of the Headers.
276     pub(crate) fn get_parts(&self) -> &Parts {
277         &self.parts
278     }
279 
280     pub(crate) fn set_instruction(&mut self, buf: Vec<u8>) {
281         self.ins = Some(buf)
282     }
283 }
284 
285 impl GoAway {
286     /// Creates a new GoAway instance from the provided Parts.
newnull287     pub fn new(id: u64) -> Self {
288         GoAway { id }
289     }
290 
291     /// Gets go away stream id.
get_idnull292     pub fn get_id(&self) -> &u64 {
293         &self.id
294     }
295 }
296 
297 impl MaxPushId {
298     /// Creates a new MaxPushId instance from the provided Parts.
newnull299     pub fn new(push_id: u64) -> Self {
300         MaxPushId { push_id }
301     }
302 
303     /// Gets allowed max push stream id.
get_idnull304     pub fn get_id(&self) -> &u64 {
305         &self.push_id
306     }
307 }
308