blob: 7b320cee175638fa23226959032750f9d232f106 [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.
90 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
91 */
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 */
109static int quic_parse_padding_frame(struct quic_frame *frm,
110 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 */
137static int quic_parse_ping_frame(struct quic_frame *frm,
138 const unsigned char **buf, const unsigned char *end)
139{
140 /* No field */
141 return 1;
142}
143
144/* Encode a ACK frame.
145 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
146 */
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 */
182static int quic_parse_ack_frame_header(struct quic_frame *frm,
183 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.
208 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
209 */
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 */
224static int quic_parse_ack_ecn_frame(struct quic_frame *frm,
225 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.
236 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
237 */
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 */
251static int quic_parse_reset_stream_frame(struct quic_frame *frm,
252 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.
262 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
263 */
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 */
276static int quic_parse_stop_sending_frame(struct quic_frame *frm,
277 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.
286 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
287 */
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 */
323static int quic_parse_crypto_frame(struct quic_frame *frm,
324 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.
339 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
340 */
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 */
357static int quic_parse_new_token_frame(struct quic_frame *frm,
358 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.
372 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
373 */
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) ||
380 ((frm->type & QUIC_STREAM_FRAME_OFF_BIT) && !quic_enc_int(buf, end, stream->offset)) ||
381 ((frm->type & QUIC_STREAM_FRAME_LEN_BIT) &&
382 (!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 */
394static int quic_parse_stream_frame(struct quic_frame *frm,
395 const unsigned char **buf, const unsigned char *end)
396{
397 struct quic_stream *stream = &frm->stream;
398
399 if (!quic_dec_int(&stream->id, buf, end) ||
400 ((frm->type & QUIC_STREAM_FRAME_OFF_BIT) && !quic_dec_int(&stream->offset, buf, end)) ||
401 ((frm->type & QUIC_STREAM_FRAME_LEN_BIT) &&
402 (!quic_dec_int(&stream->len, buf, end) || end - *buf < stream->len)))
403 return 0;
404
405 stream->data = *buf;
406 *buf += stream->len;
407
408 return 1;
409}
410
411/* Encode a MAX_DATA frame into <buf> buffer.
412 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
413 */
414static int quic_build_max_data_frame(unsigned char **buf, const unsigned char *end,
415 struct quic_frame *frm, struct quic_conn *conn)
416{
417 struct quic_max_data *max_data = &frm->max_data;
418
419 return quic_enc_int(buf, end, max_data->max_data);
420}
421
422/* Parse a MAX_DATA frame from <buf> buffer with <end> as end into <frm> frame.
423 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
424 */
425static int quic_parse_max_data_frame(struct quic_frame *frm,
426 const unsigned char **buf, const unsigned char *end)
427{
428 struct quic_max_data *max_data = &frm->max_data;
429
430 return quic_dec_int(&max_data->max_data, buf, end);
431}
432
433/* Encode a MAX_STREAM_DATA frame into <buf> buffer.
434 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
435 */
436static int quic_build_max_stream_data_frame(unsigned char **buf, const unsigned char *end,
437 struct quic_frame *frm, struct quic_conn *conn)
438{
439 struct quic_max_stream_data *max_stream_data = &frm->max_stream_data;
440
441 return quic_enc_int(buf, end, max_stream_data->id) &&
442 quic_enc_int(buf, end, max_stream_data->max_stream_data);
443}
444
445/* Parse a MAX_STREAM_DATA frame from <buf> buffer with <end> as end into <frm> frame.
446 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
447 */
448static int quic_parse_max_stream_data_frame(struct quic_frame *frm,
449 const unsigned char **buf, const unsigned char *end)
450{
451 struct quic_max_stream_data *max_stream_data = &frm->max_stream_data;
452
453 return quic_dec_int(&max_stream_data->id, buf, end) &&
454 quic_dec_int(&max_stream_data->max_stream_data, buf, end);
455}
456
457/* Encode a MAX_STREAMS frame for bidirectional streams into <buf> buffer.
458 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
459 */
460static int quic_build_max_streams_bidi_frame(unsigned char **buf, const unsigned char *end,
461 struct quic_frame *frm, struct quic_conn *conn)
462{
463 struct quic_max_streams *max_streams_bidi = &frm->max_streams_bidi;
464
465 return quic_enc_int(buf, end, max_streams_bidi->max_streams);
466}
467
468/* Parse a MAX_STREAMS frame for bidirectional streams from <buf> buffer with <end>
469 * as end into <frm> frame.
470 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
471 */
472static int quic_parse_max_streams_bidi_frame(struct quic_frame *frm,
473 const unsigned char **buf, const unsigned char *end)
474{
475 struct quic_max_streams *max_streams_bidi = &frm->max_streams_bidi;
476
477 return quic_dec_int(&max_streams_bidi->max_streams, buf, end);
478}
479
480/* Encode a MAX_STREAMS frame for unidirectional streams into <buf> buffer.
481 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
482 */
483static int quic_build_max_streams_uni_frame(unsigned char **buf, const unsigned char *end,
484 struct quic_frame *frm, struct quic_conn *conn)
485{
486 struct quic_max_streams *max_streams_uni = &frm->max_streams_uni;
487
488 return quic_enc_int(buf, end, max_streams_uni->max_streams);
489}
490
491/* Parse a MAX_STREAMS frame for undirectional streams from <buf> buffer with <end>
492 * as end into <frm> frame.
493 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
494 */
495static int quic_parse_max_streams_uni_frame(struct quic_frame *frm,
496 const unsigned char **buf, const unsigned char *end)
497{
498 struct quic_max_streams *max_streams_uni = &frm->max_streams_uni;
499
500 return quic_dec_int(&max_streams_uni->max_streams, buf, end);
501}
502
503/* Encode a DATA_BLOCKED frame into <buf> buffer.
504 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
505 */
506static int quic_build_data_blocked_frame(unsigned char **buf, const unsigned char *end,
507 struct quic_frame *frm, struct quic_conn *conn)
508{
509 struct quic_data_blocked *data_blocked = &frm->data_blocked;
510
511 return quic_enc_int(buf, end, data_blocked->limit);
512}
513
514/* Parse a DATA_BLOCKED frame from <buf> buffer with <end> as end into <frm> frame.
515 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
516 */
517static int quic_parse_data_blocked_frame(struct quic_frame *frm,
518 const unsigned char **buf, const unsigned char *end)
519{
520 struct quic_data_blocked *data_blocked = &frm->data_blocked;
521
522 return quic_dec_int(&data_blocked->limit, buf, end);
523}
524
525/* Encode a STREAM_DATA_BLOCKED into <buf> buffer.
526 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
527 */
528static int quic_build_stream_data_blocked_frame(unsigned char **buf, const unsigned char *end,
529 struct quic_frame *frm, struct quic_conn *conn)
530{
531 struct quic_stream_data_blocked *stream_data_blocked = &frm->stream_data_blocked;
532
533 return quic_enc_int(buf, end, stream_data_blocked->id) &&
534 quic_enc_int(buf, end, stream_data_blocked->limit);
535}
536
537/* Parse a STREAM_DATA_BLOCKED frame from <buf> buffer with <end> as end into <frm> frame.
538 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
539 */
540static int quic_parse_stream_data_blocked_frame(struct quic_frame *frm,
541 const unsigned char **buf, const unsigned char *end)
542{
543 struct quic_stream_data_blocked *stream_data_blocked = &frm->stream_data_blocked;
544
545 return quic_dec_int(&stream_data_blocked->id, buf, end) &&
546 quic_dec_int(&stream_data_blocked->limit, buf, end);
547}
548
549/* Encode a STREAMS_BLOCKED frame for bidirectional streams into <buf> buffer.
550 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
551 */
552static int quic_build_streams_blocked_bidi_frame(unsigned char **buf, const unsigned char *end,
553 struct quic_frame *frm, struct quic_conn *conn)
554{
555 struct quic_streams_blocked *streams_blocked_bidi = &frm->streams_blocked_bidi;
556
557 return quic_enc_int(buf, end, streams_blocked_bidi->limit);
558}
559
560/* Parse a STREAMS_BLOCKED frame for bidirectional streams from <buf> buffer with <end>
561 * as end into <frm> frame.
562 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
563 */
564static int quic_parse_streams_blocked_bidi_frame(struct quic_frame *frm,
565 const unsigned char **buf, const unsigned char *end)
566{
567 struct quic_streams_blocked *streams_blocked_bidi = &frm->streams_blocked_bidi;
568
569 return quic_dec_int(&streams_blocked_bidi->limit, buf, end);
570}
571
572/* Encode a STREAMS_BLOCKED frame for unidirectional streams into <buf> buffer.
573 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
574 */
575static int quic_build_streams_blocked_uni_frame(unsigned char **buf, const unsigned char *end,
576 struct quic_frame *frm, struct quic_conn *conn)
577{
578 struct quic_streams_blocked *streams_blocked_uni = &frm->streams_blocked_uni;
579
580 return quic_enc_int(buf, end, streams_blocked_uni->limit);
581}
582
583/* Parse a STREAMS_BLOCKED frame for unidirectional streams from <buf> buffer with <end>
584 * as end into <frm> frame.
585 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
586 */
587static int quic_parse_streams_blocked_uni_frame(struct quic_frame *frm,
588 const unsigned char **buf, const unsigned char *end)
589{
590 struct quic_streams_blocked *streams_blocked_uni = &frm->streams_blocked_uni;
591
592 return quic_dec_int(&streams_blocked_uni->limit, buf, end);
593}
594
595/* Encode a NEW_CONNECTION_ID frame into <buf> buffer.
596 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
597 */
598static int quic_build_new_connection_id_frame(unsigned char **buf, const unsigned char *end,
599 struct quic_frame *frm, struct quic_conn *conn)
600{
601 struct quic_new_connection_id *new_cid = &frm->new_connection_id;
602
603 if (!quic_enc_int(buf, end, new_cid->seq_num) ||
604 !quic_enc_int(buf, end, new_cid->retire_prior_to) ||
605 end - *buf < sizeof new_cid->cid.len + new_cid->cid.len + QUIC_STATELESS_RESET_TOKEN_LEN)
606 return 0;
607
608 *(*buf)++ = new_cid->cid.len;
609
610 if (new_cid->cid.len) {
611 memcpy(*buf, new_cid->cid.data, new_cid->cid.len);
612 *buf += new_cid->cid.len;
613 }
614 memcpy(*buf, new_cid->stateless_reset_token, QUIC_STATELESS_RESET_TOKEN_LEN);
615 *buf += QUIC_STATELESS_RESET_TOKEN_LEN;
616
617 return 1;
618}
619
620/* Parse a NEW_CONNECTION_ID frame from <buf> buffer with <end> as end into <frm> frame.
621 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
622 */
623static int quic_parse_new_connection_id_frame(struct quic_frame *frm,
624 const unsigned char **buf, const unsigned char *end)
625{
626 struct quic_new_connection_id *new_cid = &frm->new_connection_id;
627
628 if (!quic_dec_int(&new_cid->seq_num, buf, end) ||
629 !quic_dec_int(&new_cid->retire_prior_to, buf, end) || end <= *buf)
630 return 0;
631
632 new_cid->cid.len = *(*buf)++;
633 if (end - *buf < new_cid->cid.len + QUIC_STATELESS_RESET_TOKEN_LEN)
634 return 0;
635
636 if (new_cid->cid.len) {
637 new_cid->cid.data = *buf;
638 *buf += new_cid->cid.len;
639 }
640 new_cid->stateless_reset_token = *buf;
641 *buf += QUIC_STATELESS_RESET_TOKEN_LEN;
642
643 return 1;
644}
645
646/* Encode a RETIRE_CONNECTION_ID frame into <buf> buffer.
647 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
648 */
649static int quic_build_retire_connection_id_frame(unsigned char **buf, const unsigned char *end,
650 struct quic_frame *frm, struct quic_conn *conn)
651{
652 struct quic_retire_connection_id *retire_connection_id = &frm->retire_connection_id;
653
654 return quic_enc_int(buf, end, retire_connection_id->seq_num);
655}
656
657/* Parse a RETIRE_CONNECTION_ID frame from <buf> buffer with <end> as end into <frm> frame.
658 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
659 */
660static int quic_parse_retire_connection_id_frame(struct quic_frame *frm,
661 const unsigned char **buf, const unsigned char *end)
662{
663 struct quic_retire_connection_id *retire_connection_id = &frm->retire_connection_id;
664
665 return quic_dec_int(&retire_connection_id->seq_num, buf, end);
666}
667
668/* Encode a PATH_CHALLENGE frame into <buf> buffer.
669 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
670 */
671static int quic_build_path_challenge_frame(unsigned char **buf, const unsigned char *end,
672 struct quic_frame *frm, struct quic_conn *conn)
673{
674 struct quic_path_challenge *path_challenge = &frm->path_challenge;
675
676 if (end - *buf < sizeof path_challenge->data)
677 return 0;
678
679 memcpy(*buf, path_challenge->data, sizeof path_challenge->data);
680 *buf += sizeof path_challenge->data;
681
682 return 1;
683}
684
685/* Parse a PATH_CHALLENGE frame from <buf> buffer with <end> as end into <frm> frame.
686 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
687 */
688static int quic_parse_path_challenge_frame(struct quic_frame *frm,
689 const unsigned char **buf, const unsigned char *end)
690{
691 struct quic_path_challenge *path_challenge = &frm->path_challenge;
692
693 if (end - *buf < sizeof path_challenge->data)
694 return 0;
695
696 memcpy(path_challenge->data, *buf, sizeof path_challenge->data);
697 *buf += sizeof path_challenge->data;
698
699 return 1;
700}
701
702
703/* Encode a PATH_RESPONSE frame into <buf> buffer.
704 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
705 */
706static int quic_build_path_response_frame(unsigned char **buf, const unsigned char *end,
707 struct quic_frame *frm, struct quic_conn *conn)
708{
709 struct quic_path_challenge_response *path_challenge_response = &frm->path_challenge_response;
710
711 if (end - *buf < sizeof path_challenge_response->data)
712 return 0;
713
714 memcpy(*buf, path_challenge_response->data, sizeof path_challenge_response->data);
715 *buf += sizeof path_challenge_response->data;
716
717 return 1;
718}
719
720/* Parse a PATH_RESPONSE frame from <buf> buffer with <end> as end into <frm> frame.
721 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
722 */
723static int quic_parse_path_response_frame(struct quic_frame *frm,
724 const unsigned char **buf, const unsigned char *end)
725{
726 struct quic_path_challenge_response *path_challenge_response = &frm->path_challenge_response;
727
728 if (end - *buf < sizeof path_challenge_response->data)
729 return 0;
730
731 memcpy(path_challenge_response->data, *buf, sizeof path_challenge_response->data);
732 *buf += sizeof path_challenge_response->data;
733
734 return 1;
735}
736
737/* Encode a CONNECTION_CLOSE frame at QUIC layer into <buf> buffer.
738 * Note there exist two types of CONNECTION_CLOSE frame, one for the application layer
739 * and another at QUIC layer.
740 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
741 */
742static int quic_build_connection_close_frame(unsigned char **buf, const unsigned char *end,
743 struct quic_frame *frm, struct quic_conn *conn)
744{
745 struct quic_connection_close *connection_close = &frm->connection_close;
746
747 if (!quic_enc_int(buf, end, connection_close->error_code) ||
748 !quic_enc_int(buf, end, connection_close->frame_type) ||
749 !quic_enc_int(buf, end, connection_close->reason_phrase_len) ||
750 end - *buf < connection_close->reason_phrase_len)
751 return 0;
752
753 memcpy(*buf, connection_close->reason_phrase, connection_close->reason_phrase_len);
754 *buf += connection_close->reason_phrase_len;
755
756 return 1;
757}
758
759/* Parse a CONNECTION_CLOSE frame at QUIC layer from <buf> buffer with <end> as end into <frm> frame.
760 * Note there exist two types of CONNECTION_CLOSE frame, one for the application layer
761 * and another at QUIC layer.
762 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
763 */
764static int quic_parse_connection_close_frame(struct quic_frame *frm,
765 const unsigned char **buf, const unsigned char *end)
766{
767 struct quic_connection_close *connection_close = &frm->connection_close;
768
769 if (!quic_dec_int(&connection_close->error_code, buf, end) ||
770 !quic_dec_int(&connection_close->frame_type, buf, end) ||
771 !quic_dec_int(&connection_close->reason_phrase_len, buf, end) ||
772 end - *buf < connection_close->reason_phrase_len)
773 return 0;
774
775 if (connection_close->reason_phrase_len) {
776 memcpy(connection_close->reason_phrase, *buf, connection_close->reason_phrase_len);
777 *buf += connection_close->reason_phrase_len;
778 }
779
780 return 1;
781}
782
783/* Encode a CONNECTION_CLOSE frame at application layer into <buf> buffer.
784 * Note there exist two types of CONNECTION_CLOSE frame, one for application layer
785 * and another at QUIC layer.
786 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
787 */
788static int quic_build_connection_close_app_frame(unsigned char **buf, const unsigned char *end,
789 struct quic_frame *frm, struct quic_conn *conn)
790{
791 struct quic_connection_close_app *connection_close_app = &frm->connection_close_app;
792
793 if (!quic_enc_int(buf, end, connection_close_app->error_code) ||
794 !quic_enc_int(buf, end, connection_close_app->reason_phrase_len) ||
795 end - *buf < connection_close_app->reason_phrase_len)
796 return 0;
797
798 if (connection_close_app->reason_phrase_len) {
799 memcpy(*buf, connection_close_app->reason_phrase, connection_close_app->reason_phrase_len);
800 *buf += connection_close_app->reason_phrase_len;
801 }
802
803 return 1;
804}
805
806/* Parse a CONNECTION_CLOSE frame at QUIC layer from <buf> buffer with <end> as end into <frm> frame.
807 * Note there exist two types of CONNECTION_CLOSE frame, one for the application layer
808 * and another at QUIC layer.
809 * Return 1 if succeeded (enough room to parse this frame), 0 if not.
810 */
811static int quic_parse_connection_close_app_frame(struct quic_frame *frm,
812 const unsigned char **buf, const unsigned char *end)
813{
814 struct quic_connection_close_app *connection_close_app = &frm->connection_close_app;
815
816 if (!quic_dec_int(&connection_close_app->error_code, buf, end) ||
817 !quic_dec_int(&connection_close_app->reason_phrase_len, buf, end) ||
818 end - *buf < connection_close_app->reason_phrase_len)
819 return 0;
820
821 memcpy(connection_close_app->reason_phrase, *buf, connection_close_app->reason_phrase_len);
822 *buf += connection_close_app->reason_phrase_len;
823
824 return 1;
825}
826
827/* Encode a HANDSHAKE_DONE frame into <buf> buffer.
828 * Always succeeds.
829 */
830static int quic_build_handshake_done_frame(unsigned char **buf, const unsigned char *end,
831 struct quic_frame *frm, struct quic_conn *conn)
832{
833 /* No field */
834 return 1;
835}
836
837/* Parse a HANDSHAKE_DONE frame at QUIC layer from <buf> buffer with <end> as end into <frm> frame.
838 * Always succeed.
839 */
840static int quic_parse_handshake_done_frame(struct quic_frame *frm,
841 const unsigned char **buf, const unsigned char *end)
842{
843 /* No field */
844 return 1;
845}
846
847struct quic_frame_builder {
848 int (*func)(unsigned char **buf, const unsigned char *end,
849 struct quic_frame *frm, struct quic_conn *conn);
850 unsigned char flags;
851};
852
853struct quic_frame_builder quic_frame_builders[] = {
854 [QUIC_FT_PADDING] = { .func = quic_build_padding_frame, .flags = QUIC_FL_TX_PACKET_PADDING, },
855 [QUIC_FT_PING] = { .func = quic_build_ping_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
856 [QUIC_FT_ACK] = { .func = quic_build_ack_frame, .flags = 0, },
857 [QUIC_FT_ACK_ECN] = { .func = quic_build_ack_ecn_frame, .flags = 0, },
858 [QUIC_FT_RESET_STREAM] = { .func = quic_build_reset_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
859 [QUIC_FT_STOP_SENDING] = { .func = quic_build_stop_sending_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
860 [QUIC_FT_CRYPTO] = { .func = quic_build_crypto_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
861 [QUIC_FT_NEW_TOKEN] = { .func = quic_build_new_token_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
862 [QUIC_FT_STREAM_8] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
863 [QUIC_FT_STREAM_9] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
864 [QUIC_FT_STREAM_A] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
865 [QUIC_FT_STREAM_B] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
866 [QUIC_FT_STREAM_C] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
867 [QUIC_FT_STREAM_D] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
868 [QUIC_FT_STREAM_E] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
869 [QUIC_FT_STREAM_F] = { .func = quic_build_stream_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
870 [QUIC_FT_MAX_DATA] = { .func = quic_build_max_data_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
871 [QUIC_FT_MAX_STREAM_DATA] = { .func = quic_build_max_stream_data_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
872 [QUIC_FT_MAX_STREAMS_BIDI] = { .func = quic_build_max_streams_bidi_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
873 [QUIC_FT_MAX_STREAMS_UNI] = { .func = quic_build_max_streams_uni_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
874 [QUIC_FT_DATA_BLOCKED] = { .func = quic_build_data_blocked_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
875 [QUIC_FT_STREAM_DATA_BLOCKED] = { .func = quic_build_stream_data_blocked_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
876 [QUIC_FT_STREAMS_BLOCKED_BIDI] = { .func = quic_build_streams_blocked_bidi_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
877 [QUIC_FT_STREAMS_BLOCKED_UNI] = { .func = quic_build_streams_blocked_uni_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
878 [QUIC_FT_NEW_CONNECTION_ID] = { .func = quic_build_new_connection_id_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
879 [QUIC_FT_RETIRE_CONNECTION_ID] = { .func = quic_build_retire_connection_id_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
880 [QUIC_FT_PATH_CHALLENGE] = { .func = quic_build_path_challenge_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
881 [QUIC_FT_PATH_RESPONSE] = { .func = quic_build_path_response_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
882 [QUIC_FT_CONNECTION_CLOSE] = { .func = quic_build_connection_close_frame, .flags = 0, },
883 [QUIC_FT_CONNECTION_CLOSE_APP] = { .func = quic_build_connection_close_app_frame, .flags = 0, },
884 [QUIC_FT_HANDSHAKE_DONE] = { .func = quic_build_handshake_done_frame, .flags = QUIC_FL_TX_PACKET_ACK_ELICITING, },
885};
886
887struct quic_frame_parser {
888 int (*func)(struct quic_frame *frm,
889 const unsigned char **, const unsigned char *);
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100890 unsigned char flags;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100891 unsigned char mask;
892};
893
894struct quic_frame_parser quic_frame_parsers[] = {
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100895 [QUIC_FT_PADDING] = { .func = quic_parse_padding_frame, .flags = 0, .mask = QUIC_FT_PKT_TYPE_IH01_BITMASK, },
896 [QUIC_FT_PING] = { .func = quic_parse_ping_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE_IH01_BITMASK, },
897 [QUIC_FT_ACK] = { .func = quic_parse_ack_frame_header, .flags = 0, .mask = QUIC_FT_PKT_TYPE_IH_1_BITMASK, },
898 [QUIC_FT_ACK_ECN] = { .func = quic_parse_ack_ecn_frame, .flags = 0, .mask = QUIC_FT_PKT_TYPE_IH_1_BITMASK, },
899 [QUIC_FT_RESET_STREAM] = { .func = quic_parse_reset_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
900 [QUIC_FT_STOP_SENDING] = { .func = quic_parse_stop_sending_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
901 [QUIC_FT_CRYPTO] = { .func = quic_parse_crypto_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE_IH_1_BITMASK, },
902 [QUIC_FT_NEW_TOKEN] = { .func = quic_parse_new_token_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE____1_BITMASK, },
903 [QUIC_FT_STREAM_8] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
904 [QUIC_FT_STREAM_9] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
905 [QUIC_FT_STREAM_A] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
906 [QUIC_FT_STREAM_B] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
907 [QUIC_FT_STREAM_C] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
908 [QUIC_FT_STREAM_D] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
909 [QUIC_FT_STREAM_E] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
910 [QUIC_FT_STREAM_F] = { .func = quic_parse_stream_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
911 [QUIC_FT_MAX_DATA] = { .func = quic_parse_max_data_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
912 [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, },
913 [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, },
914 [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, },
915 [QUIC_FT_DATA_BLOCKED] = { .func = quic_parse_data_blocked_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
916 [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, },
917 [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, },
918 [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, },
919 [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, },
920 [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, },
921 [QUIC_FT_PATH_CHALLENGE] = { .func = quic_parse_path_challenge_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
922 [QUIC_FT_PATH_RESPONSE] = { .func = quic_parse_path_response_frame, .flags = QUIC_FL_RX_PACKET_ACK_ELICITING, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
923 [QUIC_FT_CONNECTION_CLOSE] = { .func = quic_parse_connection_close_frame, .flags = 0, .mask = QUIC_FT_PKT_TYPE_IH01_BITMASK, },
924 [QUIC_FT_CONNECTION_CLOSE_APP] = { .func = quic_parse_connection_close_app_frame, .flags = 0, .mask = QUIC_FT_PKT_TYPE___01_BITMASK, },
925 [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 +0100926};
927
928/* Decode a QUIC frame from <buf> buffer into <frm> frame.
929 * Returns 1 if succeded (enough data to parse the frame), 0 if not.
930 */
931int qc_parse_frm(struct quic_frame *frm, struct quic_rx_packet *pkt,
932 const unsigned char **buf, const unsigned char *end,
933 struct quic_conn *conn)
934{
935 struct quic_frame_parser *parser;
936
937 if (end <= *buf) {
938 TRACE_DEVEL("wrong frame", QUIC_EV_CONN_PRSFRM, conn->conn);
939 return 0;
940 }
941
942 frm->type = *(*buf)++;
943 if (frm->type > QUIC_FT_MAX) {
944 TRACE_DEVEL("wrong frame type", QUIC_EV_CONN_PRSFRM, conn->conn, frm);
945 return 0;
946 }
947
948 parser = &quic_frame_parsers[frm->type];
949 if (!(parser->mask & (1 << pkt->type))) {
950 TRACE_DEVEL("unauthorized frame", QUIC_EV_CONN_PRSFRM, conn->conn, frm);
951 return 0;
952 }
953
954 TRACE_PROTO("frame", QUIC_EV_CONN_PRSFRM, conn->conn, frm);
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100955 if (!parser->func(frm, buf, end)) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100956 TRACE_DEVEL("parsing error", QUIC_EV_CONN_PRSFRM, conn->conn, frm);
957 return 0;
958 }
959
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100960 pkt->flags |= parser->flags;
961
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100962 return 1;
963}
964
965/* Encode <frm> QUIC frame into <buf> buffer.
966 * Returns 1 if succeded (enough room in <buf> to encode the frame), 0 if not.
967 */
968int qc_build_frm(unsigned char **buf, const unsigned char *end,
969 struct quic_frame *frm, struct quic_tx_packet *pkt,
970 struct quic_conn *conn)
971{
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100972 struct quic_frame_builder *builder;
973
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100974 if (end <= *buf) {
975 TRACE_DEVEL("not enough room", QUIC_EV_CONN_BFRM, conn->conn, frm);
976 return 0;
977 }
978
979 TRACE_PROTO("frame", QUIC_EV_CONN_BFRM, conn->conn, frm);
980 *(*buf)++ = frm->type;
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100981 builder = &quic_frame_builders[frm->type];
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100982 if (!quic_frame_builders[frm->type].func(buf, end, frm, conn)) {
983 TRACE_DEVEL("frame building error", QUIC_EV_CONN_BFRM, conn->conn, frm);
984 return 0;
985 }
986
Frédéric Lécaillef7fe9652020-12-09 14:56:18 +0100987 pkt->flags |= builder[frm->type].flags;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100988
989 return 1;
990}
991