DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
quic_tp.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file quic_tp.h
6 * @brief QUIC transport parameters (RFC 9000 sec 18) carried in the TLS quic_transport_parameters
7 * extension (RFC 9001 sec 8.2).
8 *
9 * Each endpoint states its transport limits (flow-control windows, stream limits, idle timeout, and
10 * the connection IDs used during the handshake) as a sequence of `ID (varint) | Length (varint) |
11 * Value` parameters. The server carries its parameters in the EncryptedExtensions message and reads
12 * the client's from the ClientHello. This module encodes the set a minimal server advertises and
13 * parses a peer's, applying the RFC 9000 sec 18.2 defaults and rejecting malformed or illegal values
14 * (bad varints, oversized connection IDs, a duplicated parameter, out-of-range limits).
15 *
16 * Pure, zero heap, host-tested (round-trip + the spec defaults + malformed-input rejection).
17 *
18 * @author Douglas Quigg (dstroy0)
19 * @date 2026
20 */
21
22#ifndef DETERMINISTICESPASYNCWEBSERVER_QUIC_TP_H
23#define DETERMINISTICESPASYNCWEBSERVER_QUIC_TP_H
24
25#include "ServerConfig.h"
26
27#if DETWS_ENABLE_HTTP3
28
29#include "network_drivers/presentation/http3/quic_packet.h" // QUIC_MAX_CID_LEN
30#include <stddef.h>
31#include <stdint.h>
32
33/** @brief Transport parameter identifiers (RFC 9000 sec 18.2 / Table 7). */
34struct QuicTp
35{
36 static constexpr uint8_t QUIC_TP_ORIGINAL_DCID = 0x00; ///< server: DCID of the client's first Initial
37 static constexpr uint8_t QUIC_TP_MAX_IDLE_TIMEOUT = 0x01; ///< varint, milliseconds (0 = disabled)
38 static constexpr uint8_t QUIC_TP_STATELESS_RESET_TOKEN = 0x02; ///< 16 bytes (server only)
39 static constexpr uint8_t QUIC_TP_MAX_UDP_PAYLOAD_SIZE = 0x03; ///< varint, default 65527, min 1200
40 static constexpr uint8_t QUIC_TP_INITIAL_MAX_DATA = 0x04; ///< varint, connection flow-control window
41 static constexpr uint8_t QUIC_TP_INITIAL_MAX_SD_BIDI_LOCAL = 0x05; ///< varint
42 static constexpr uint8_t QUIC_TP_INITIAL_MAX_SD_BIDI_REMOTE = 0x06; ///< varint
43 static constexpr uint8_t QUIC_TP_INITIAL_MAX_SD_UNI = 0x07; ///< varint
44 static constexpr uint8_t QUIC_TP_INITIAL_MAX_STREAMS_BIDI = 0x08; ///< varint
45 static constexpr uint8_t QUIC_TP_INITIAL_MAX_STREAMS_UNI = 0x09; ///< varint
46 static constexpr uint8_t QUIC_TP_ACK_DELAY_EXPONENT = 0x0a; ///< varint, default 3, max 20
47 static constexpr uint8_t QUIC_TP_MAX_ACK_DELAY = 0x0b; ///< varint, default 25, < 2^14
48 static constexpr uint8_t QUIC_TP_DISABLE_ACTIVE_MIGRATION = 0x0c; ///< zero-length flag
49 static constexpr uint8_t QUIC_TP_ACTIVE_CID_LIMIT = 0x0e; ///< varint, default 2, min 2
50 static constexpr uint8_t QUIC_TP_INITIAL_SCID = 0x0f; ///< SCID of this endpoint's first Initial
51 static constexpr uint8_t QUIC_TP_RETRY_SCID = 0x10; ///< server: SCID of a Retry it sent
52};
53
54/** @brief The transport parameters we encode / decode, with RFC 9000 sec 18.2 defaults applied. */
55struct QuicTransportParams
56{
57 bool has_original_dcid;
58 uint8_t original_dcid[QUIC_MAX_CID_LEN];
59 uint8_t original_dcid_len;
60 bool has_initial_scid;
61 uint8_t initial_scid[QUIC_MAX_CID_LEN];
62 uint8_t initial_scid_len;
63 bool has_retry_scid;
64 uint8_t retry_scid[QUIC_MAX_CID_LEN];
65 uint8_t retry_scid_len;
66
67 uint64_t max_idle_timeout; ///< default 0
68 uint64_t max_udp_payload_size; ///< default 65527
69 uint64_t initial_max_data; ///< default 0
70 uint64_t initial_max_sd_bidi_local; ///< default 0
71 uint64_t initial_max_sd_bidi_remote; ///< default 0
72 uint64_t initial_max_sd_uni; ///< default 0
73 uint64_t initial_max_streams_bidi; ///< default 0
74 uint64_t initial_max_streams_uni; ///< default 0
75 uint64_t ack_delay_exponent; ///< default 3
76 uint64_t max_ack_delay; ///< default 25 (ms)
77 uint64_t active_connection_id_limit; ///< default 2
78 bool disable_active_migration; ///< default false
79};
80
81/** @brief Fill @p tp with the RFC 9000 sec 18.2 default values (all connection IDs absent). */
82void quic_tp_defaults(QuicTransportParams *tp);
83
84/**
85 * @brief Encode the server's transport parameters into @p out.
86 *
87 * Emits, in ascending ID order: original_destination_connection_id and initial_source_connection_id
88 * (only if present), initial_max_data, the three initial_max_stream_data_* windows, the two
89 * initial_max_streams_* limits, max_idle_timeout, max_udp_payload_size, active_connection_id_limit,
90 * and disable_active_migration (only if set). @return bytes written, or 0 on overflow.
91 */
92size_t quic_tp_encode(const QuicTransportParams *tp, uint8_t *out, size_t cap);
93
94/**
95 * @brief Parse a peer's transport parameters (starting from the spec defaults).
96 *
97 * Walks ID/Length/Value triples, stores the parameters this module knows, and skips unknown IDs
98 * (forward compatibility / GREASE). @return false on a malformed encoding, an oversized connection
99 * ID, a duplicated known parameter, or an out-of-range value (RFC 9000 sec 18.2 limits):
100 * ack_delay_exponent > 20, max_ack_delay >= 2^14, max_udp_payload_size < 1200,
101 * active_connection_id_limit < 2, or a non-zero-length disable_active_migration.
102 */
103bool quic_tp_parse(const uint8_t *buf, size_t len, QuicTransportParams *tp);
104
105#endif // DETWS_ENABLE_HTTP3
106#endif // DETERMINISTICESPASYNCWEBSERVER_QUIC_TP_H
User-facing configuration for DeterministicESPAsyncWebServer.
QUIC packet headers and packet-number coding (RFC 9000 sec 17).