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 pub const DATA_FRAME_TYPE_ID: u64 = 0x0;
17 pub const HEADERS_FRAME_TYPE_ID: u64 = 0x1;
18 pub const CANCEL_PUSH_FRAME_TYPE_ID: u64 = 0x3;
19 pub const SETTINGS_FRAME_TYPE_ID: u64 = 0x4;
20 pub const PUSH_PROMISE_FRAME_TYPE_ID: u64 = 0x5;
21 pub const GOAWAY_FRAME_TYPE_ID: u64 = 0x7;
22 pub const MAX_PUSH_FRAME_TYPE_ID: u64 = 0xD;
23 pub const PRIORITY_UPDATE_FRAME_REQUEST_TYPE_ID: u64 = 0xF0700;
24 pub const PRIORITY_UPDATE_FRAME_PUSH_TYPE_ID: u64 = 0xF0701;
25 pub const SETTINGS_QPACK_MAX_TABLE_CAPACITY: u64 = 0x1;
26 pub const SETTINGS_MAX_FIELD_SECTION_SIZE: u64 = 0x6;
27 pub const SETTINGS_QPACK_BLOCKED_STREAMS: u64 = 0x7;
28 pub const SETTINGS_ENABLE_CONNECT_PROTOCOL: u64 = 0x8;
29 pub const SETTINGS_H3_DATAGRAM_00: u64 = 0x276;
30 pub const SETTINGS_H3_DATAGRAM: u64 = 0x33;
31 // Permit between 16 maximally-encoded and 128 minimally-encoded SETTINGS.
32 const MAX_SETTINGS_PAYLOAD_SIZE: usize = 256;
33 
34 #[derive(Clone)]
35 pub struct Frame {
36     ty: u64,
37     len: u64,
38     payload: Payload,
39 }
40 
41 #[derive(Clone)]
42 pub enum Payload {
43     /// HEADERS frame payload.
44     Headers(Headers),
45     /// DATA frame payload.
46     Data(Data),
47     /// SETTINGS frame payload.
48     Settings(Settings),
49     /// CancelPush frame payload.
50     CancelPush(CancelPush),
51     /// PushPromise frame payload.
52     PushPromise(PushPromise),
53     /// GOAWAY frame payload.
54     Goaway(GoAway),
55     /// MaxPushId frame payload.
56     MaxPushId(MaxPushId),
57     /// Unknown frame payload.
58     Unknown(Unknown),
59 }
60 
61 #[derive(Clone)]
62 pub struct Headers {
63     headers: Vec<u8>,
64     parts: Parts,
65 }
66 
67 #[derive(Clone)]
68 pub struct Data {
69     data: Vec<u8>,
70 }
71 
72 #[derive(Clone)]
73 pub struct Settings {
74     max_field_section_size: Option<u64>,
75     qpack_max_table_capacity: Option<u64>,
76     qpack_blocked_streams: Option<u64>,
77     connect_protocol_enabled: Option<u64>,
78     h3_datagram: Option<u64>,
79     raw: Option<Vec<(u64, u64)>>,
80 }
81 
82 #[derive(Clone)]
83 pub struct CancelPush {
84     push_id: u64,
85 }
86 
87 #[derive(Clone)]
88 pub struct PushPromise {
89     push_id: u64,
90     headers: Vec<u8>,
91 }
92 
93 #[derive(Clone)]
94 pub struct GoAway {
95     id: u64,
96 }
97 
98 pub struct MaxPushId {
99     push_id: u64,
100 }
101 
102 pub struct Unknown {
103     raw_type: u64,
104     len: u64,
105 }
106 
107 impl Frame {
new(ty: u64, len: u64, payload: Payload) -> Self108     pub fn new(ty: u64, len: u64, payload: Payload) -> Self {
109         Frame { ty, len, payload }
110     }
111 
frame_type(&self) -> &u64112     pub fn frame_type(&self) -> &u64 {
113         &self.ty
114     }
115 
frame_len(&self) -> &u64116     pub fn frame_len(&self) -> &u64 {
117         &self.len
118     }
119 
payload(&self) -> &Payload120     pub fn payload(&self) -> &Payload {
121         &self.payload
122     }
123 
payload_mut(&mut self) -> &mut Payload124     pub(crate) fn payload_mut(&mut self) -> &mut Payload {
125         &mut self.payload
126     }
127 }
128 
129 // settings结构体相当于quiche中setting结构体
130 impl Settings {
131     /// Creates a new Settings instance containing the provided settings.
new() -> Self132     pub fn new() -> Self {
133         Settings {
134             max_field_section_size: None,
135             qpack_max_table_capacity: None,
136             qpack_blocked_streams: None,
137             connect_protocol_enabled: None,
138             h3_datagram: None,
139             raw: None,
140         }
141     }
142 
143     /// SETTINGS_HEADER_TABLE_SIZE (0x01) setting.
max_fied_section_size(mut self, size: u64) -> Self144     pub fn max_fied_section_size(mut self, size: u64) -> Self {
145         self.max_field_section_size = Some(size);
146         self
147     }
148 
149     /// SETTINGS_ENABLE_PUSH (0x02) setting.
qpack_max_table_capacity(mut self, size: u64) -> Self150     pub fn qpack_max_table_capacity(mut self, size: u64) -> Self {
151         self.qpack_max_table_capacity = Some(size);
152         self
153     }
154 
155     /// SETTINGS_MAX_FRAME_SIZE (0x05) setting.
qpack_block_stream(mut self, size: u64) -> Self156     pub fn qpack_block_stream(mut self, size: u64) -> Self {
157         self.qpack_blocked_streams = Some(size);
158         self
159     }
160 
161     /// SETTINGS_MAX_HEADER_LIST_SIZE (0x06) setting.
connect_protocol_enabled(mut self, size: u64) -> Self162     pub fn connect_protocol_enabled(mut self, size: u64) -> Self {
163         self.connect_protocol_enabled = Some(size);
164         self
165     }
166 
h3_datagram(mut self, size: u64) -> Self167     pub fn h3_datagram(mut self, size: u64) -> Self {
168         self.h3_datagram = Some(size);
169         self
170     }
171 
172     /// SETTINGS_HEADER_TABLE_SIZE (0x01) setting.
get_max_fied_section_size(&self) -> &Option<u64>173     pub fn get_max_fied_section_size(&self) -> &Option<u64> {
174         &self.max_field_section_size
175     }
176 
177     /// SETTINGS_ENABLE_PUSH (0x02) setting.
get_qpack_max_table_capacity(&self) -> &Option<u64>178     pub fn get_qpack_max_table_capacity(&self) -> &Option<u64> {
179         &self.qpack_max_table_capacity
180     }
181 
182     /// SETTINGS_MAX_FRAME_SIZE (0x05) setting.
get_qpack_block_stream(&self) -> &Option<u64>183     pub fn get_qpack_block_stream(&self) -> &Option<u64> {
184         &self.qpack_blocked_streams
185     }
186 
187     /// SETTINGS_MAX_HEADER_LIST_SIZE (0x06) setting.
get_connect_protocol_enabled(&self) -> &Option<u64>188     pub fn get_connect_protocol_enabled(&self) -> &Option<u64> {
189         &self.connect_protocol_enabled
190     }
191 
get_h3_datagram(&self) -> &Option<u64>192     pub fn get_h3_datagram(&self) -> &Option<u64> {
193         &self.h3_datagram
194     }
195 }
196 
197 impl Data {
198     /// Creates a new Data instance containing the provided data.
new(data: Vec<u8>) -> Self199     pub fn new(data: Vec<u8>) -> Self {
200         Data { data }
201     }
202 
203     /// Return the `Vec` that contains the data payload.
data(&self) -> &Vec<u8>204     pub fn data(&self) -> &Vec<u8> {
205         &self.data
206     }
207 }
208 
209 impl CancelPush {
210     /// Creates a new CancelPush instance from the provided Parts.
new(id: u64) -> Self211     pub fn new(id: u64) -> Self {
212         CancelPush { push_id: id }
213     }
214 
get_push_id(&self) -> &u64215     pub fn get_push_id(&self) -> &u64 {
216         &self.push_id
217     }
218 }
219 
220 impl Headers {
221     /// Creates a new Headers instance from the provided Parts.
new(parts: Parts) -> Self222     pub fn new(parts: Parts) -> Self {
223         Headers {
224             headers: vec![0; 16383],
225             parts,
226         }
227     }
228 
229     /// Returns pseudo headers and other headers
get_headers(&self) -> &Vec<u8>230     pub fn get_headers(&self) -> &Vec<u8> {
231         &self.headers
232     }
233 
get_part(&self) -> Parts234     pub fn get_part(&self) -> Parts {
235         self.parts.clone()
236     }
237 }
238 
239 impl PushPromise {
240     /// Creates a new PushPromise instance from the provided Parts.
new(push_id: u64, header: Vec<u8>) -> Self241     pub fn new(push_id: u64, header: Vec<u8>) -> Self {
242         PushPromise {
243             push_id,
244             headers: header,
245         }
246     }
247 
get_push_id(&self) -> u64248     pub fn get_push_id(&self) -> u64 {
249         self.push_id
250     }
251 
252     /// Returns a copy of the internal parts of the Headers.
get_headers(&self) -> &Vec<u8>253     pub(crate) fn get_headers(&self) -> &Vec<u8> {
254         &self.headers.clone()
255     }
256 }
257 
258 impl GoAway {
259     /// Creates a new GoAway instance from the provided Parts.
new(id: u64) -> Self260     pub fn new(id: u64) -> Self {
261         GoAway { id }
262     }
263 
get_id(&self) -> &u64264     pub fn get_id(&self) -> &u64 {
265         &self.id
266     }
267 }
268 
269 impl MaxPushId {
270     /// Creates a new MaxPushId instance from the provided Parts.
new(push_id: u64) -> Self271     pub fn new(push_id: u64) -> Self {
272         MaxPushId { push_id }
273     }
274 
get_id(&self) -> &u64275     pub fn get_id(&self) -> &u64 {
276         &self.push_id
277     }
278 }
279