blob: 450fdd9965414017783f2f8af87f898b8145e53e [file] [log] [blame]
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001/*
2 * Copyright 2019 HAProxy Technologies, Frédéric Lécaille <flecaille@haproxy.com>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
Frédéric Lécaille8090b512020-11-30 16:19:22 +010010#include <import/eb64tree.h>
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +010011#include <haproxy/quic_frame.h>
12#include <haproxy/trace.h>
13#include <haproxy/xprt_quic.h>
14
15#define TRACE_SOURCE &trace_quic
16
17const char *quic_frame_type_string(enum quic_frame_type ft)
18{
19 switch (ft) {
20 case QUIC_FT_PADDING:
21 return "PADDING";
22 case QUIC_FT_PING:
23 return "PING";
24 case QUIC_FT_ACK:
25 return "ACK";
26 case QUIC_FT_ACK_ECN:
27 return "ACK_ENC";
28 case QUIC_FT_RESET_STREAM:
29 return "RESET_STREAM";
30 case QUIC_FT_STOP_SENDING:
31 return "STOP_SENDING";
32 case QUIC_FT_CRYPTO:
33 return "CRYPTO";
34 case QUIC_FT_NEW_TOKEN:
35 return "NEW_TOKEN";
36
37 case QUIC_FT_STREAM_8:
38 return "STREAM_8";
39 case QUIC_FT_STREAM_9:
40 return "STREAM_9";
41 case QUIC_FT_STREAM_A:
42 return "STREAM_A";
43 case QUIC_FT_STREAM_B:
44 return "STREAM_B";
45 case QUIC_FT_STREAM_C:
46 return "STREAM_C";
47 case QUIC_FT_STREAM_D:
48 return "STREAM_D";
49 case QUIC_FT_STREAM_E:
50 return "STREAM_E";
51 case QUIC_FT_STREAM_F:
52 return "STREAM_F";
53
54 case QUIC_FT_MAX_DATA:
55 return "MAX_DATA";
56 case QUIC_FT_MAX_STREAM_DATA:
57 return "MAX_STREAM_DATA";
58 case QUIC_FT_MAX_STREAMS_BIDI:
59 return "MAX_STREAMS_BIDI";
60 case QUIC_FT_MAX_STREAMS_UNI:
61 return "MAX_STREAMS_UNI";
62 case QUIC_FT_DATA_BLOCKED:
63 return "DATA_BLOCKED";
64 case QUIC_FT_STREAM_DATA_BLOCKED:
65 return "STREAM_DATA_BLOCKED";
66 case QUIC_FT_STREAMS_BLOCKED_BIDI:
67 return "STREAMS_BLOCKED_BIDI";
68 case QUIC_FT_STREAMS_BLOCKED_UNI:
69 return "STREAMS_BLOCKED_UNI";
70 case QUIC_FT_NEW_CONNECTION_ID:
71 return "NEW_CONNECTION_ID";
72 case QUIC_FT_RETIRE_CONNECTION_ID:
73 return "RETIRE_CONNECTION_ID";
74 case QUIC_FT_PATH_CHALLENGE:
75 return "PATH_CHALLENGE";
76 case QUIC_FT_PATH_RESPONSE:
77 return "PATH_RESPONSE";
78 case QUIC_FT_CONNECTION_CLOSE:
79 return "CONNECTION_CLOSE";
80 case QUIC_FT_CONNECTION_CLOSE_APP:
81 return "CONNECTION_CLOSE_APP";
82 case QUIC_FT_HANDSHAKE_DONE:
83 return "HANDSHAKE_DONE";
84 default:
85 return "UNKNOWN";
86 }
87}
88
89/* Encode <frm> PADDING frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +050090 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +010091 */
92static int quic_build_padding_frame(unsigned char **buf, const unsigned char *end,
93 struct quic_frame *frm, struct quic_conn *conn)
94{
95 struct quic_padding *padding = &frm->padding;
96
97 if (end - *buf < padding->len - 1)
98 return 0;
99
100 memset(*buf, 0, padding->len - 1);
101 *buf += padding->len - 1;
102
103 return 1;
104}
105
106/* Parse a PADDING frame from <buf> buffer with <end> as end into <frm> frame.
107 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
108 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100109static int quic_parse_padding_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100110 const unsigned char **buf, const unsigned char *end)
111{
112 const unsigned char *beg;
113 struct quic_padding *padding = &frm->padding;
114
115 beg = *buf;
116 padding->len = 1;
117 while (*buf < end && !**buf)
118 (*buf)++;
119 padding->len += *buf - beg;
120
121 return 1;
122}
123
124/* Encode a ACK frame into <buf> buffer.
125 * Always succeeds.
126 */
127static int quic_build_ping_frame(unsigned char **buf, const unsigned char *end,
128 struct quic_frame *frm, struct quic_conn *conn)
129{
130 /* No field */
131 return 1;
132}
133
134/* Parse a PADDING frame from <buf> buffer with <end> as end into <frm> frame.
135 * Always succeeds.
136 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100137static int quic_parse_ping_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100138 const unsigned char **buf, const unsigned char *end)
139{
140 /* No field */
141 return 1;
142}
143
144/* Encode a ACK frame.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500145 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100146 */
147static int quic_build_ack_frame(unsigned char **buf, const unsigned char *end,
148 struct quic_frame *frm, struct quic_conn *conn)
149{
150 struct quic_tx_ack *tx_ack = &frm->tx_ack;
Frédéric Lécaille8090b512020-11-30 16:19:22 +0100151 struct eb64_node *ar, *prev_ar;
152 struct quic_arng_node *ar_node, *prev_ar_node;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100153
Frédéric Lécaille8090b512020-11-30 16:19:22 +0100154 ar = eb64_last(&tx_ack->arngs->root);
155 ar_node = eb64_entry(&ar->node, struct quic_arng_node, first);
156 TRACE_PROTO("ack range", QUIC_EV_CONN_PRSAFRM,
157 conn->conn,, &ar_node->last, &ar_node->first.key);
158 if (!quic_enc_int(buf, end, ar_node->last) ||
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100159 !quic_enc_int(buf, end, tx_ack->ack_delay) ||
Frédéric Lécaille8090b512020-11-30 16:19:22 +0100160 !quic_enc_int(buf, end, tx_ack->arngs->sz - 1) ||
161 !quic_enc_int(buf, end, ar_node->last - ar_node->first.key))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100162 return 0;
163
Frédéric Lécaille8090b512020-11-30 16:19:22 +0100164 while ((prev_ar = eb64_prev(ar))) {
165 prev_ar_node = eb64_entry(&prev_ar->node, struct quic_arng_node, first);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100166 TRACE_PROTO("ack range", QUIC_EV_CONN_PRSAFRM, conn->conn,,
Frédéric Lécaille8090b512020-11-30 16:19:22 +0100167 &prev_ar_node->last, &prev_ar_node->first.key);
168 if (!quic_enc_int(buf, end, ar_node->first.key - prev_ar_node->last - 2) ||
169 !quic_enc_int(buf, end, prev_ar_node->last - prev_ar_node->first.key))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100170 return 0;
171
Frédéric Lécaille8090b512020-11-30 16:19:22 +0100172 ar = prev_ar;
173 ar_node = eb64_entry(&ar->node, struct quic_arng_node, first);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100174 }
175
176 return 1;
177}
178
179/* Parse an ACK frame header from <buf> buffer with <end> as end into <frm> frame.
180 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
181 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100182static int quic_parse_ack_frame_header(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100183 const unsigned char **buf, const unsigned char *end)
184{
185 int ret;
186 struct quic_ack *ack = &frm->ack;
187
188 ret = quic_dec_int(&ack->largest_ack, buf, end);
189 if (!ret)
190 return 0;
191
192 ret = quic_dec_int(&ack->ack_delay, buf, end);
193 if (!ret)
194 return 0;
195
196 ret = quic_dec_int(&ack->ack_range_num, buf, end);
197 if (!ret)
198 return 0;
199
200 ret = quic_dec_int(&ack->first_ack_range, buf, end);
201 if (!ret)
202 return 0;
203
204 return 1;
205}
206
207/* Encode a ACK_ECN frame.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500208 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100209 */
210static int quic_build_ack_ecn_frame(unsigned char **buf, const unsigned char *end,
211 struct quic_frame *frm, struct quic_conn *conn)
212{
213 struct quic_ack *ack = &frm->ack;
214
215 return quic_enc_int(buf, end, ack->largest_ack) &&
216 quic_enc_int(buf, end, ack->ack_delay) &&
217 quic_enc_int(buf, end, ack->first_ack_range) &&
218 quic_enc_int(buf, end, ack->ack_range_num);
219}
220
221/* Parse an ACK_ECN frame from <buf> buffer with <end> as end into <frm> frame.
222 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
223 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100224static int quic_parse_ack_ecn_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100225 const unsigned char **buf, const unsigned char *end)
226{
227 struct quic_ack *ack = &frm->ack;
228
229 return quic_dec_int(&ack->largest_ack, buf, end) &&
230 quic_dec_int(&ack->ack_delay, buf, end) &&
231 quic_dec_int(&ack->first_ack_range, buf, end) &&
232 quic_dec_int(&ack->ack_range_num, buf, end);
233}
234
235/* Encode a RESET_STREAM frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500236 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100237 */
238static int quic_build_reset_stream_frame(unsigned char **buf, const unsigned char *end,
239 struct quic_frame *frm, struct quic_conn *conn)
240{
241 struct quic_reset_stream *reset_stream = &frm->reset_stream;
242
243 return quic_enc_int(buf, end, reset_stream->id) &&
244 quic_enc_int(buf, end, reset_stream->app_error_code) &&
245 quic_enc_int(buf, end, reset_stream->final_size);
246}
247
248/* Parse a RESET_STREAM frame from <buf> buffer with <end> as end into <frm> frame.
249 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
250 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100251static int quic_parse_reset_stream_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100252 const unsigned char **buf, const unsigned char *end)
253{
254 struct quic_reset_stream *reset_stream = &frm->reset_stream;
255
256 return quic_dec_int(&reset_stream->id, buf, end) &&
257 quic_dec_int(&reset_stream->app_error_code, buf, end) &&
258 quic_dec_int(&reset_stream->final_size, buf, end);
259}
260
261/* Encode a STOP_SENDING frame.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500262 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100263 */
264static int quic_build_stop_sending_frame(unsigned char **buf, const unsigned char *end,
265 struct quic_frame *frm, struct quic_conn *conn)
266{
267 struct quic_stop_sending_frame *stop_sending_frame = &frm->stop_sending_frame;
268
269 return quic_enc_int(buf, end, stop_sending_frame->id) &&
270 quic_enc_int(buf, end, stop_sending_frame->app_error_code);
271}
272
273/* Parse a STOP_SENDING frame from <buf> buffer with <end> as end into <frm> frame.
274 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
275 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100276static int quic_parse_stop_sending_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100277 const unsigned char **buf, const unsigned char *end)
278{
279 struct quic_stop_sending_frame *stop_sending_frame = &frm->stop_sending_frame;
280
281 return quic_dec_int(&stop_sending_frame->id, buf, end) &&
282 quic_dec_int(&stop_sending_frame->app_error_code, buf, end);
283}
284
285/* Encode a CRYPTO frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500286 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100287 */
288static int quic_build_crypto_frame(unsigned char **buf, const unsigned char *end,
289 struct quic_frame *frm, struct quic_conn *conn)
290{
291 struct quic_crypto *crypto = &frm->crypto;
292 const struct quic_enc_level *qel = crypto->qel;
293 size_t offset, len;
294
295 if (!quic_enc_int(buf, end, crypto->offset) ||
296 !quic_enc_int(buf, end, crypto->len) || end - *buf < crypto->len)
297 return 0;
298
299 len = crypto->len;
300 offset = crypto->offset;
301 while (len) {
302 int idx;
303 size_t to_copy;
304 const unsigned char *data;
305
306 idx = offset >> QUIC_CRYPTO_BUF_SHIFT;
307 to_copy = qel->tx.crypto.bufs[idx]->sz - (offset & QUIC_CRYPTO_BUF_MASK);
308 if (to_copy > len)
309 to_copy = len;
310 data = qel->tx.crypto.bufs[idx]->data + (offset & QUIC_CRYPTO_BUF_MASK);
311 memcpy(*buf, data, to_copy);
312 *buf += to_copy;
313 offset += to_copy;
314 len -= to_copy;
315 }
316
317 return 1;
318}
319
320/* Parse a CRYPTO frame from <buf> buffer with <end> as end into <frm> frame.
321 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
322 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100323static int quic_parse_crypto_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100324 const unsigned char **buf, const unsigned char *end)
325{
326 struct quic_crypto *crypto = &frm->crypto;
327
328 if (!quic_dec_int(&crypto->offset, buf, end) ||
329 !quic_dec_int(&crypto->len, buf, end) || end - *buf < crypto->len)
330 return 0;
331
332 crypto->data = *buf;
333 *buf += crypto->len;
334
335 return 1;
336}
337
338/* Encode a NEW_TOKEN frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500339 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100340 */
341static int quic_build_new_token_frame(unsigned char **buf, const unsigned char *end,
342 struct quic_frame *frm, struct quic_conn *conn)
343{
344 struct quic_new_token *new_token = &frm->new_token;
345
346 if (!quic_enc_int(buf, end, new_token->len) || end - *buf < new_token->len)
347 return 0;
348
349 memcpy(*buf, new_token->data, new_token->len);
350
351 return 1;
352}
353
354/* Parse a NEW_TOKEN frame from <buf> buffer with <end> as end into <frm> frame.
355 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
356 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100357static int quic_parse_new_token_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100358 const unsigned char **buf, const unsigned char *end)
359{
360 struct quic_new_token *new_token = &frm->new_token;
361
362 if (!quic_dec_int(&new_token->len, buf, end) || end - *buf < new_token->len)
363 return 0;
364
365 new_token->data = *buf;
366 *buf += new_token->len;
367
368 return 1;
369}
370
371/* Encode a STREAM frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500372 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100373 */
374static int quic_build_stream_frame(unsigned char **buf, const unsigned char *end,
375 struct quic_frame *frm, struct quic_conn *conn)
376{
377 struct quic_stream *stream = &frm->stream;
378
379 if (!quic_enc_int(buf, end, stream->id) ||
Frédéric Lécaille242fb1b2020-12-31 12:45:38 +0100380 ((frm->type & QUIC_STREAM_FRAME_TYPE_OFF_BIT) && !quic_enc_int(buf, end, stream->offset)) ||
381 ((frm->type & QUIC_STREAM_FRAME_TYPE_LEN_BIT) &&
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100382 (!quic_enc_int(buf, end, stream->len) || end - *buf < stream->len)))
383 return 0;
384
385 memcpy(*buf, stream->data, stream->len);
386 *buf += stream->len;
387
388 return 1;
389}
390
391/* Parse a STREAM frame from <buf> buffer with <end> as end into <frm> frame.
392 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
393 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100394static int quic_parse_stream_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100395 const unsigned char **buf, const unsigned char *end)
396{
397 struct quic_stream *stream = &frm->stream;
398
Frédéric Lécaille129a3512020-12-31 10:57:04 +0100399 if (!quic_dec_int(&stream->id, buf, end))
400 return 0;
401
402 /* Offset parsing */
Frédéric Lécaille242fb1b2020-12-31 12:45:38 +0100403 if (!(frm->type & QUIC_STREAM_FRAME_TYPE_OFF_BIT)) {
Frédéric Lécaille129a3512020-12-31 10:57:04 +0100404 stream->offset = 0;
405 }
406 else if (!quic_dec_int(&stream->offset, buf, end))
407 return 0;
408
409 /* Length parsing */
Frédéric Lécaille242fb1b2020-12-31 12:45:38 +0100410 if (!(frm->type & QUIC_STREAM_FRAME_TYPE_LEN_BIT)) {
Frédéric Lécaille129a3512020-12-31 10:57:04 +0100411 stream->len = end - *buf;
412 }
413 else if (!quic_dec_int(&stream->len, buf, end) || end - *buf < stream->len)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100414 return 0;
415
416 stream->data = *buf;
417 *buf += stream->len;
418
419 return 1;
420}
421
422/* Encode a MAX_DATA frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500423 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100424 */
425static int quic_build_max_data_frame(unsigned char **buf, const unsigned char *end,
426 struct quic_frame *frm, struct quic_conn *conn)
427{
428 struct quic_max_data *max_data = &frm->max_data;
429
430 return quic_enc_int(buf, end, max_data->max_data);
431}
432
433/* Parse a MAX_DATA frame from <buf> buffer with <end> as end into <frm> frame.
434 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
435 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100436static int quic_parse_max_data_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100437 const unsigned char **buf, const unsigned char *end)
438{
439 struct quic_max_data *max_data = &frm->max_data;
440
441 return quic_dec_int(&max_data->max_data, buf, end);
442}
443
444/* Encode a MAX_STREAM_DATA frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500445 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100446 */
447static int quic_build_max_stream_data_frame(unsigned char **buf, const unsigned char *end,
448 struct quic_frame *frm, struct quic_conn *conn)
449{
450 struct quic_max_stream_data *max_stream_data = &frm->max_stream_data;
451
452 return quic_enc_int(buf, end, max_stream_data->id) &&
453 quic_enc_int(buf, end, max_stream_data->max_stream_data);
454}
455
456/* Parse a MAX_STREAM_DATA frame from <buf> buffer with <end> as end into <frm> frame.
457 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
458 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100459static int quic_parse_max_stream_data_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100460 const unsigned char **buf, const unsigned char *end)
461{
462 struct quic_max_stream_data *max_stream_data = &frm->max_stream_data;
463
464 return quic_dec_int(&max_stream_data->id, buf, end) &&
465 quic_dec_int(&max_stream_data->max_stream_data, buf, end);
466}
467
468/* Encode a MAX_STREAMS frame for bidirectional streams into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500469 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100470 */
471static int quic_build_max_streams_bidi_frame(unsigned char **buf, const unsigned char *end,
472 struct quic_frame *frm, struct quic_conn *conn)
473{
474 struct quic_max_streams *max_streams_bidi = &frm->max_streams_bidi;
475
476 return quic_enc_int(buf, end, max_streams_bidi->max_streams);
477}
478
479/* Parse a MAX_STREAMS frame for bidirectional streams from <buf> buffer with <end>
480 * as end into <frm> frame.
481 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
482 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100483static int quic_parse_max_streams_bidi_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100484 const unsigned char **buf, const unsigned char *end)
485{
486 struct quic_max_streams *max_streams_bidi = &frm->max_streams_bidi;
487
488 return quic_dec_int(&max_streams_bidi->max_streams, buf, end);
489}
490
491/* Encode a MAX_STREAMS frame for unidirectional streams into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500492 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100493 */
494static int quic_build_max_streams_uni_frame(unsigned char **buf, const unsigned char *end,
495 struct quic_frame *frm, struct quic_conn *conn)
496{
497 struct quic_max_streams *max_streams_uni = &frm->max_streams_uni;
498
499 return quic_enc_int(buf, end, max_streams_uni->max_streams);
500}
501
502/* Parse a MAX_STREAMS frame for undirectional streams from <buf> buffer with <end>
503 * as end into <frm> frame.
504 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
505 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100506static int quic_parse_max_streams_uni_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100507 const unsigned char **buf, const unsigned char *end)
508{
509 struct quic_max_streams *max_streams_uni = &frm->max_streams_uni;
510
511 return quic_dec_int(&max_streams_uni->max_streams, buf, end);
512}
513
514/* Encode a DATA_BLOCKED frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500515 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100516 */
517static int quic_build_data_blocked_frame(unsigned char **buf, const unsigned char *end,
518 struct quic_frame *frm, struct quic_conn *conn)
519{
520 struct quic_data_blocked *data_blocked = &frm->data_blocked;
521
522 return quic_enc_int(buf, end, data_blocked->limit);
523}
524
525/* Parse a DATA_BLOCKED frame from <buf> buffer with <end> as end into <frm> frame.
526 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
527 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100528static int quic_parse_data_blocked_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100529 const unsigned char **buf, const unsigned char *end)
530{
531 struct quic_data_blocked *data_blocked = &frm->data_blocked;
532
533 return quic_dec_int(&data_blocked->limit, buf, end);
534}
535
536/* Encode a STREAM_DATA_BLOCKED into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500537 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100538 */
539static int quic_build_stream_data_blocked_frame(unsigned char **buf, const unsigned char *end,
540 struct quic_frame *frm, struct quic_conn *conn)
541{
542 struct quic_stream_data_blocked *stream_data_blocked = &frm->stream_data_blocked;
543
544 return quic_enc_int(buf, end, stream_data_blocked->id) &&
545 quic_enc_int(buf, end, stream_data_blocked->limit);
546}
547
548/* Parse a STREAM_DATA_BLOCKED frame from <buf> buffer with <end> as end into <frm> frame.
549 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
550 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100551static int quic_parse_stream_data_blocked_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100552 const unsigned char **buf, const unsigned char *end)
553{
554 struct quic_stream_data_blocked *stream_data_blocked = &frm->stream_data_blocked;
555
556 return quic_dec_int(&stream_data_blocked->id, buf, end) &&
557 quic_dec_int(&stream_data_blocked->limit, buf, end);
558}
559
560/* Encode a STREAMS_BLOCKED frame for bidirectional streams into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500561 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100562 */
563static int quic_build_streams_blocked_bidi_frame(unsigned char **buf, const unsigned char *end,
564 struct quic_frame *frm, struct quic_conn *conn)
565{
566 struct quic_streams_blocked *streams_blocked_bidi = &frm->streams_blocked_bidi;
567
568 return quic_enc_int(buf, end, streams_blocked_bidi->limit);
569}
570
571/* Parse a STREAMS_BLOCKED frame for bidirectional streams from <buf> buffer with <end>
572 * as end into <frm> frame.
573 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
574 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100575static int quic_parse_streams_blocked_bidi_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100576 const unsigned char **buf, const unsigned char *end)
577{
578 struct quic_streams_blocked *streams_blocked_bidi = &frm->streams_blocked_bidi;
579
580 return quic_dec_int(&streams_blocked_bidi->limit, buf, end);
581}
582
583/* Encode a STREAMS_BLOCKED frame for unidirectional streams into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500584 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100585 */
586static int quic_build_streams_blocked_uni_frame(unsigned char **buf, const unsigned char *end,
587 struct quic_frame *frm, struct quic_conn *conn)
588{
589 struct quic_streams_blocked *streams_blocked_uni = &frm->streams_blocked_uni;
590
591 return quic_enc_int(buf, end, streams_blocked_uni->limit);
592}
593
594/* Parse a STREAMS_BLOCKED frame for unidirectional streams from <buf> buffer with <end>
595 * as end into <frm> frame.
596 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
597 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100598static int quic_parse_streams_blocked_uni_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100599 const unsigned char **buf, const unsigned char *end)
600{
601 struct quic_streams_blocked *streams_blocked_uni = &frm->streams_blocked_uni;
602
603 return quic_dec_int(&streams_blocked_uni->limit, buf, end);
604}
605
606/* Encode a NEW_CONNECTION_ID frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500607 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100608 */
609static int quic_build_new_connection_id_frame(unsigned char **buf, const unsigned char *end,
610 struct quic_frame *frm, struct quic_conn *conn)
611{
612 struct quic_new_connection_id *new_cid = &frm->new_connection_id;
613
614 if (!quic_enc_int(buf, end, new_cid->seq_num) ||
615 !quic_enc_int(buf, end, new_cid->retire_prior_to) ||
616 end - *buf < sizeof new_cid->cid.len + new_cid->cid.len + QUIC_STATELESS_RESET_TOKEN_LEN)
617 return 0;
618
619 *(*buf)++ = new_cid->cid.len;
620
621 if (new_cid->cid.len) {
622 memcpy(*buf, new_cid->cid.data, new_cid->cid.len);
623 *buf += new_cid->cid.len;
624 }
625 memcpy(*buf, new_cid->stateless_reset_token, QUIC_STATELESS_RESET_TOKEN_LEN);
626 *buf += QUIC_STATELESS_RESET_TOKEN_LEN;
627
628 return 1;
629}
630
631/* Parse a NEW_CONNECTION_ID frame from <buf> buffer with <end> as end into <frm> frame.
632 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
633 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100634static int quic_parse_new_connection_id_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100635 const unsigned char **buf, const unsigned char *end)
636{
637 struct quic_new_connection_id *new_cid = &frm->new_connection_id;
638
639 if (!quic_dec_int(&new_cid->seq_num, buf, end) ||
640 !quic_dec_int(&new_cid->retire_prior_to, buf, end) || end <= *buf)
641 return 0;
642
643 new_cid->cid.len = *(*buf)++;
644 if (end - *buf < new_cid->cid.len + QUIC_STATELESS_RESET_TOKEN_LEN)
645 return 0;
646
647 if (new_cid->cid.len) {
648 new_cid->cid.data = *buf;
649 *buf += new_cid->cid.len;
650 }
651 new_cid->stateless_reset_token = *buf;
652 *buf += QUIC_STATELESS_RESET_TOKEN_LEN;
653
654 return 1;
655}
656
657/* Encode a RETIRE_CONNECTION_ID frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500658 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100659 */
660static int quic_build_retire_connection_id_frame(unsigned char **buf, const unsigned char *end,
661 struct quic_frame *frm, struct quic_conn *conn)
662{
663 struct quic_retire_connection_id *retire_connection_id = &frm->retire_connection_id;
664
665 return quic_enc_int(buf, end, retire_connection_id->seq_num);
666}
667
668/* Parse a RETIRE_CONNECTION_ID frame from <buf> buffer with <end> as end into <frm> frame.
669 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
670 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100671static int quic_parse_retire_connection_id_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100672 const unsigned char **buf, const unsigned char *end)
673{
674 struct quic_retire_connection_id *retire_connection_id = &frm->retire_connection_id;
675
676 return quic_dec_int(&retire_connection_id->seq_num, buf, end);
677}
678
679/* Encode a PATH_CHALLENGE frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500680 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100681 */
682static int quic_build_path_challenge_frame(unsigned char **buf, const unsigned char *end,
683 struct quic_frame *frm, struct quic_conn *conn)
684{
685 struct quic_path_challenge *path_challenge = &frm->path_challenge;
686
687 if (end - *buf < sizeof path_challenge->data)
688 return 0;
689
690 memcpy(*buf, path_challenge->data, sizeof path_challenge->data);
691 *buf += sizeof path_challenge->data;
692
693 return 1;
694}
695
696/* Parse a PATH_CHALLENGE frame from <buf> buffer with <end> as end into <frm> frame.
697 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
698 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100699static int quic_parse_path_challenge_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100700 const unsigned char **buf, const unsigned char *end)
701{
702 struct quic_path_challenge *path_challenge = &frm->path_challenge;
703
704 if (end - *buf < sizeof path_challenge->data)
705 return 0;
706
707 memcpy(path_challenge->data, *buf, sizeof path_challenge->data);
708 *buf += sizeof path_challenge->data;
709
710 return 1;
711}
712
713
714/* Encode a PATH_RESPONSE frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500715 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100716 */
717static int quic_build_path_response_frame(unsigned char **buf, const unsigned char *end,
718 struct quic_frame *frm, struct quic_conn *conn)
719{
720 struct quic_path_challenge_response *path_challenge_response = &frm->path_challenge_response;
721
722 if (end - *buf < sizeof path_challenge_response->data)
723 return 0;
724
725 memcpy(*buf, path_challenge_response->data, sizeof path_challenge_response->data);
726 *buf += sizeof path_challenge_response->data;
727
728 return 1;
729}
730
731/* Parse a PATH_RESPONSE frame from <buf> buffer with <end> as end into <frm> frame.
732 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
733 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100734static int quic_parse_path_response_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100735 const unsigned char **buf, const unsigned char *end)
736{
737 struct quic_path_challenge_response *path_challenge_response = &frm->path_challenge_response;
738
739 if (end - *buf < sizeof path_challenge_response->data)
740 return 0;
741
742 memcpy(path_challenge_response->data, *buf, sizeof path_challenge_response->data);
743 *buf += sizeof path_challenge_response->data;
744
745 return 1;
746}
747
748/* Encode a CONNECTION_CLOSE frame at QUIC layer into <buf> buffer.
749 * Note there exist two types of CONNECTION_CLOSE frame, one for the application layer
750 * and another at QUIC layer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500751 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100752 */
753static int quic_build_connection_close_frame(unsigned char **buf, const unsigned char *end,
754 struct quic_frame *frm, struct quic_conn *conn)
755{
756 struct quic_connection_close *connection_close = &frm->connection_close;
757
758 if (!quic_enc_int(buf, end, connection_close->error_code) ||
759 !quic_enc_int(buf, end, connection_close->frame_type) ||
760 !quic_enc_int(buf, end, connection_close->reason_phrase_len) ||
761 end - *buf < connection_close->reason_phrase_len)
762 return 0;
763
764 memcpy(*buf, connection_close->reason_phrase, connection_close->reason_phrase_len);
765 *buf += connection_close->reason_phrase_len;
766
767 return 1;
768}
769
770/* Parse a CONNECTION_CLOSE frame at QUIC layer from <buf> buffer with <end> as end into <frm> frame.
771 * Note there exist two types of CONNECTION_CLOSE frame, one for the application layer
772 * and another at QUIC layer.
773 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
774 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100775static int quic_parse_connection_close_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100776 const unsigned char **buf, const unsigned char *end)
777{
778 struct quic_connection_close *connection_close = &frm->connection_close;
779
780 if (!quic_dec_int(&connection_close->error_code, buf, end) ||
781 !quic_dec_int(&connection_close->frame_type, buf, end) ||
782 !quic_dec_int(&connection_close->reason_phrase_len, buf, end) ||
783 end - *buf < connection_close->reason_phrase_len)
784 return 0;
785
786 if (connection_close->reason_phrase_len) {
787 memcpy(connection_close->reason_phrase, *buf, connection_close->reason_phrase_len);
788 *buf += connection_close->reason_phrase_len;
789 }
790
791 return 1;
792}
793
794/* Encode a CONNECTION_CLOSE frame at application layer into <buf> buffer.
795 * Note there exist two types of CONNECTION_CLOSE frame, one for application layer
796 * and another at QUIC layer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500797 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100798 */
799static int quic_build_connection_close_app_frame(unsigned char **buf, const unsigned char *end,
800 struct quic_frame *frm, struct quic_conn *conn)
801{
802 struct quic_connection_close_app *connection_close_app = &frm->connection_close_app;
803
804 if (!quic_enc_int(buf, end, connection_close_app->error_code) ||
805 !quic_enc_int(buf, end, connection_close_app->reason_phrase_len) ||
806 end - *buf < connection_close_app->reason_phrase_len)
807 return 0;
808
809 if (connection_close_app->reason_phrase_len) {
810 memcpy(*buf, connection_close_app->reason_phrase, connection_close_app->reason_phrase_len);
811 *buf += connection_close_app->reason_phrase_len;
812 }
813
814 return 1;
815}
816
817/* Parse a CONNECTION_CLOSE frame at QUIC layer from <buf> buffer with <end> as end into <frm> frame.
818 * Note there exist two types of CONNECTION_CLOSE frame, one for the application layer
819 * and another at QUIC layer.
820 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
821 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100822static int quic_parse_connection_close_app_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100823 const unsigned char **buf, const unsigned char *end)
824{
825 struct quic_connection_close_app *connection_close_app = &frm->connection_close_app;
826
827 if (!quic_dec_int(&connection_close_app->error_code, buf, end) ||
828 !quic_dec_int(&connection_close_app->reason_phrase_len, buf, end) ||
829 end - *buf < connection_close_app->reason_phrase_len)
830 return 0;
831
832 memcpy(connection_close_app->reason_phrase, *buf, connection_close_app->reason_phrase_len);
833 *buf += connection_close_app->reason_phrase_len;
834
835 return 1;
836}
837
838/* Encode a HANDSHAKE_DONE frame into <buf> buffer.
839 * Always succeeds.
840 */
841static int quic_build_handshake_done_frame(unsigned char **buf, const unsigned char *end,
842 struct quic_frame *frm, struct quic_conn *conn)
843{
844 /* No field */
845 return 1;
846}
847
848/* Parse a HANDSHAKE_DONE frame at QUIC layer from <buf> buffer with <end> as end into <frm> frame.
849 * Always succeed.
850 */
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100851static int quic_parse_handshake_done_frame(struct quic_frame *frm, struct quic_conn *qc,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100852 const unsigned char **buf, const unsigned char *end)
853{
854 /* No field */
855 return 1;
856}
857
858struct quic_frame_builder {
859 int (*func)(unsigned char **buf, const unsigned char *end,
860 struct quic_frame *frm, struct quic_conn *conn);
861 unsigned char flags;
862};
863
864struct quic_frame_builder quic_frame_builders[] = {
865 [QUIC_FT_PADDING] = { .func = quic_build_padding_frame, .flags = QUIC_FL_TX_PACKET_PADDING, },
866 [QUIC_FT_PING] = { .func = quic_build_ping_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
867 [QUIC_FT_ACK] = { .func = quic_build_ack_frame, .flags = 0, },
868 [QUIC_FT_ACK_ECN] = { .func = quic_build_ack_ecn_frame, .flags = 0, },
869 [QUIC_FT_RESET_STREAM] = { .func = quic_build_reset_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
870 [QUIC_FT_STOP_SENDING] = { .func = quic_build_stop_sending_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
871 [QUIC_FT_CRYPTO] = { .func = quic_build_crypto_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
872 [QUIC_FT_NEW_TOKEN] = { .func = quic_build_new_token_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
873 [QUIC_FT_STREAM_8] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
874 [QUIC_FT_STREAM_9] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
875 [QUIC_FT_STREAM_A] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
876 [QUIC_FT_STREAM_B] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
877 [QUIC_FT_STREAM_C] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
878 [QUIC_FT_STREAM_D] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
879 [QUIC_FT_STREAM_E] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
880 [QUIC_FT_STREAM_F] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
881 [QUIC_FT_MAX_DATA] = { .func = quic_build_max_data_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
882 [QUIC_FT_MAX_STREAM_DATA] = { .func = quic_build_max_stream_data_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
883 [QUIC_FT_MAX_STREAMS_BIDI] = { .func = quic_build_max_streams_bidi_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
884 [QUIC_FT_MAX_STREAMS_UNI] = { .func = quic_build_max_streams_uni_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
885 [QUIC_FT_DATA_BLOCKED] = { .func = quic_build_data_blocked_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
886 [QUIC_FT_STREAM_DATA_BLOCKED] = { .func = quic_build_stream_data_blocked_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
887 [QUIC_FT_STREAMS_BLOCKED_BIDI] = { .func = quic_build_streams_blocked_bidi_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
888 [QUIC_FT_STREAMS_BLOCKED_UNI] = { .func = quic_build_streams_blocked_uni_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
889 [QUIC_FT_NEW_CONNECTION_ID] = { .func = quic_build_new_connection_id_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
890 [QUIC_FT_RETIRE_CONNECTION_ID] = { .func = quic_build_retire_connection_id_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
891 [QUIC_FT_PATH_CHALLENGE] = { .func = quic_build_path_challenge_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
892 [QUIC_FT_PATH_RESPONSE] = { .func = quic_build_path_response_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
893 [QUIC_FT_CONNECTION_CLOSE] = { .func = quic_build_connection_close_frame, .flags = 0, },
894 [QUIC_FT_CONNECTION_CLOSE_APP] = { .func = quic_build_connection_close_app_frame, .flags = 0, },
895 [QUIC_FT_HANDSHAKE_DONE] = { .func = quic_build_handshake_done_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
896};
897
898struct quic_frame_parser {
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100899 int (*func)(struct quic_frame *frm, struct quic_conn *qc,
900 const unsigned char **buf, const unsigned char *end);
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100901 unsigned char flags;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100902 unsigned char mask;
903};
904
905struct quic_frame_parser quic_frame_parsers[] = {
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100906 [QUIC_FT_PADDING] = { .func = quic_parse_padding_frame, .flags = 0, .mask = QUIC_FT_PKT_TYPE_IH01_BITMASK, },
907 [QUIC_FT_PING] = { .func = quic_parse_ping_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE_IH01_BITMASK, },
908 [QUIC_FT_ACK] = { .func = quic_parse_ack_frame_header, .flags = 0, .mask = QUIC_FT_PKT_TYPE_IH_1_BITMASK, },
909 [QUIC_FT_ACK_ECN] = { .func = quic_parse_ack_ecn_frame, .flags = 0, .mask = QUIC_FT_PKT_TYPE_IH_1_BITMASK, },
910 [QUIC_FT_RESET_STREAM] = { .func = quic_parse_reset_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
911 [QUIC_FT_STOP_SENDING] = { .func = quic_parse_stop_sending_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
912 [QUIC_FT_CRYPTO] = { .func = quic_parse_crypto_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE_IH_1_BITMASK, },
913 [QUIC_FT_NEW_TOKEN] = { .func = quic_parse_new_token_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE____1_BITMASK, },
914 [QUIC_FT_STREAM_8] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
915 [QUIC_FT_STREAM_9] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
916 [QUIC_FT_STREAM_A] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
917 [QUIC_FT_STREAM_B] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
918 [QUIC_FT_STREAM_C] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
919 [QUIC_FT_STREAM_D] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
920 [QUIC_FT_STREAM_E] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
921 [QUIC_FT_STREAM_F] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
922 [QUIC_FT_MAX_DATA] = { .func = quic_parse_max_data_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
923 [QUIC_FT_MAX_STREAM_DATA] = { .func = quic_parse_max_stream_data_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
924 [QUIC_FT_MAX_STREAMS_BIDI] = { .func = quic_parse_max_streams_bidi_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
925 [QUIC_FT_MAX_STREAMS_UNI] = { .func = quic_parse_max_streams_uni_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
926 [QUIC_FT_DATA_BLOCKED] = { .func = quic_parse_data_blocked_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
927 [QUIC_FT_STREAM_DATA_BLOCKED] = { .func = quic_parse_stream_data_blocked_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
928 [QUIC_FT_STREAMS_BLOCKED_BIDI] = { .func = quic_parse_streams_blocked_bidi_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
929 [QUIC_FT_STREAMS_BLOCKED_UNI] = { .func = quic_parse_streams_blocked_uni_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
930 [QUIC_FT_NEW_CONNECTION_ID] = { .func = quic_parse_new_connection_id_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
931 [QUIC_FT_RETIRE_CONNECTION_ID] = { .func = quic_parse_retire_connection_id_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
932 [QUIC_FT_PATH_CHALLENGE] = { .func = quic_parse_path_challenge_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
933 [QUIC_FT_PATH_RESPONSE] = { .func = quic_parse_path_response_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
934 [QUIC_FT_CONNECTION_CLOSE] = { .func = quic_parse_connection_close_frame, .flags = 0, .mask = QUIC_FT_PKT_TYPE_IH01_BITMASK, },
935 [QUIC_FT_CONNECTION_CLOSE_APP] = { .func = quic_parse_connection_close_app_frame, .flags = 0, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
936 [QUIC_FT_HANDSHAKE_DONE] = { .func = quic_parse_handshake_done_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE____1_BITMASK, },
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100937};
938
939/* Decode a QUIC frame from <buf> buffer into <frm> frame.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500940 * Returns 1 if succeeded (enough data to parse the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100941 */
942int qc_parse_frm(struct quic_frame *frm, struct quic_rx_packet *pkt,
943 const unsigned char **buf, const unsigned char *end,
944 struct quic_conn *conn)
945{
946 struct quic_frame_parser *parser;
947
948 if (end <= *buf) {
949 TRACE_DEVEL("wrong frame", QUIC_EV_CONN_PRSFRM, conn->conn);
950 return 0;
951 }
952
953 frm->type = *(*buf)++;
954 if (frm->type > QUIC_FT_MAX) {
955 TRACE_DEVEL("wrong frame type", QUIC_EV_CONN_PRSFRM, conn->conn, frm);
956 return 0;
957 }
958
959 parser = &quic_frame_parsers[frm->type];
960 if (!(parser->mask & (1 << pkt->type))) {
961 TRACE_DEVEL("unauthorized frame", QUIC_EV_CONN_PRSFRM, conn->conn, frm);
962 return 0;
963 }
964
965 TRACE_PROTO("frame", QUIC_EV_CONN_PRSFRM, conn->conn, frm);
Frédéric Lécaille50044ad2020-12-29 11:42:08 +0100966 if (!parser->func(frm, conn, buf, end)) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100967 TRACE_DEVEL("parsing error", QUIC_EV_CONN_PRSFRM, conn->conn, frm);
968 return 0;
969 }
970
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100971 pkt->flags |= parser->flags;
972
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100973 return 1;
974}
975
976/* Encode <frm> QUIC frame into <buf> buffer.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500977 * Returns 1 if succeeded (enough room in <buf> to encode the frame), 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100978 */
979int qc_build_frm(unsigned char **buf, const unsigned char *end,
980 struct quic_frame *frm, struct quic_tx_packet *pkt,
981 struct quic_conn *conn)
982{
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100983 struct quic_frame_builder *builder;
984
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100985 if (end <= *buf) {
986 TRACE_DEVEL("not enough room", QUIC_EV_CONN_BFRM, conn->conn, frm);
987 return 0;
988 }
989
990 TRACE_PROTO("frame", QUIC_EV_CONN_BFRM, conn->conn, frm);
991 *(*buf)++ = frm->type;
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100992 builder = &quic_frame_builders[frm->type];
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100993 if (!quic_frame_builders[frm->type].func(buf, end, frm, conn)) {
994 TRACE_DEVEL("frame building error", QUIC_EV_CONN_BFRM, conn->conn, frm);
995 return 0;
996 }
997
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100998 pkt->flags |= builder[frm->type].flags;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100999
1000 return 1;
1001}
1002