1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
25392f7a3SLiteSpeed Tech/*
35392f7a3SLiteSpeed Tech * lsquic_trans_params.h -- Transport parameters types and functions.
45392f7a3SLiteSpeed Tech */
55392f7a3SLiteSpeed Tech
65392f7a3SLiteSpeed Tech#ifndef LSQUIC_TRANS_PARAMS_H
75392f7a3SLiteSpeed Tech#define LSQUIC_TRANS_PARAMS_H 1
85392f7a3SLiteSpeed Tech
91bdb91d1SDmitri Tikhonov/* Transport parameters are grouped by the type of their values: numeric,
101bdb91d1SDmitri Tikhonov * empty, and custom.
111bdb91d1SDmitri Tikhonov *
121bdb91d1SDmitri Tikhonov * The enum values are arbitrary.  The literal transport parameter ID
131bdb91d1SDmitri Tikhonov * *values* (e.g. 0x1057 for loss bits) are not exposed by the API.
141bdb91d1SDmitri Tikhonov */
155392f7a3SLiteSpeed Techenum transport_param_id
165392f7a3SLiteSpeed Tech{
171bdb91d1SDmitri Tikhonov    /*
181bdb91d1SDmitri Tikhonov     * Numeric transport parameters that have default values:
191bdb91d1SDmitri Tikhonov     */
201bdb91d1SDmitri Tikhonov    TPI_MAX_IDLE_TIMEOUT,
21fb73393fSDmitri Tikhonov    TPI_MAX_UDP_PAYLOAD_SIZE,
221bdb91d1SDmitri Tikhonov    TPI_INIT_MAX_DATA,
231bdb91d1SDmitri Tikhonov    TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL,
241bdb91d1SDmitri Tikhonov    TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE,
251bdb91d1SDmitri Tikhonov    TPI_INIT_MAX_STREAM_DATA_UNI,
261bdb91d1SDmitri Tikhonov    TPI_INIT_MAX_STREAMS_BIDI,
271bdb91d1SDmitri Tikhonov    TPI_INIT_MAX_STREAMS_UNI,
281bdb91d1SDmitri Tikhonov    TPI_ACK_DELAY_EXPONENT,
291bdb91d1SDmitri Tikhonov    TPI_MAX_ACK_DELAY,
301bdb91d1SDmitri Tikhonov    TPI_ACTIVE_CONNECTION_ID_LIMIT,         MAX_NUM_WITH_DEF_TPI = TPI_ACTIVE_CONNECTION_ID_LIMIT,
311bdb91d1SDmitri Tikhonov
321bdb91d1SDmitri Tikhonov    /*
331bdb91d1SDmitri Tikhonov     * Numeric transport parameters without default values:
341bdb91d1SDmitri Tikhonov     */
35feca77f5SDmitri Tikhonov    TPI_MIN_ACK_DELAY,
36f38b395aSDmitri Tikhonov    /* The _02 version of MIN_ACK_DELAY is to support -02 version of the
37f38b395aSDmitri Tikhonov     * draft.  Functionally, it's exactly the same as -01, but without the
38f38b395aSDmitri Tikhonov     * extra enum there is no easy way to keep encoding and decoding simple.
39f38b395aSDmitri Tikhonov     * Because we support both, we don't care which one the peer selects.
40f38b395aSDmitri Tikhonov     * If the peer, like us, also sends both, we *assume* that the two
41f38b395aSDmitri Tikhonov     * versions of the transport parameter carry the same values.
42f38b395aSDmitri Tikhonov     */
43f38b395aSDmitri Tikhonov    TPI_MIN_ACK_DELAY_02,
4449f1f4f6SDmitri Tikhonov    TPI_TIMESTAMPS,
45b1a7c3f9SDmitri Tikhonov    TPI_MAX_DATAGRAM_FRAME_SIZE,
461bdb91d1SDmitri Tikhonov    TPI_LOSS_BITS,                          MAX_NUMERIC_TPI = TPI_LOSS_BITS,
475392f7a3SLiteSpeed Tech
481bdb91d1SDmitri Tikhonov    /*
491bdb91d1SDmitri Tikhonov     * Empty transport parameters:
501bdb91d1SDmitri Tikhonov     */
51692a9102SDmitri Tikhonov    TPI_GREASE_QUIC_BIT,
521bdb91d1SDmitri Tikhonov    TPI_DISABLE_ACTIVE_MIGRATION,           MAX_EMPTY_TPI = TPI_DISABLE_ACTIVE_MIGRATION,
531bdb91d1SDmitri Tikhonov
541bdb91d1SDmitri Tikhonov    /*
551bdb91d1SDmitri Tikhonov     * Custom handlers:
561bdb91d1SDmitri Tikhonov     */
571bdb91d1SDmitri Tikhonov    TPI_PREFERRED_ADDRESS,
58fb73393fSDmitri Tikhonov        /* CIDs must be in a contiguous range for tp_cids array to work */
59fb73393fSDmitri Tikhonov#define FIRST_TP_CID TPI_ORIGINAL_DEST_CID
60fb73393fSDmitri Tikhonov    TPI_ORIGINAL_DEST_CID,
61fb73393fSDmitri Tikhonov    TPI_INITIAL_SOURCE_CID,
62fb73393fSDmitri Tikhonov#define LAST_TP_CID TPI_RETRY_SOURCE_CID
63fb73393fSDmitri Tikhonov    TPI_RETRY_SOURCE_CID,
6403e6b668SDmitri Tikhonov#if LSQUIC_TEST_QUANTUM_READINESS
651bdb91d1SDmitri Tikhonov    TPI_QUANTUM_READINESS,
6603e6b668SDmitri Tikhonov#endif
671bdb91d1SDmitri Tikhonov    TPI_STATELESS_RESET_TOKEN,              LAST_TPI = TPI_STATELESS_RESET_TOKEN
685392f7a3SLiteSpeed Tech};
695392f7a3SLiteSpeed Tech
70fb73393fSDmitri Tikhonov#define TP_CID_IDX(tpi_) ((tpi_) - FIRST_TP_CID)
71fb73393fSDmitri Tikhonov
721bdb91d1SDmitri Tikhonov
735392f7a3SLiteSpeed Techstruct transport_params
745392f7a3SLiteSpeed Tech{
751bdb91d1SDmitri Tikhonov    /* Which transport parameters values are set: */
761bdb91d1SDmitri Tikhonov    unsigned                tp_set;
771bdb91d1SDmitri Tikhonov
781bdb91d1SDmitri Tikhonov    /* Which transport parameters were present (set by the decoder): */
791bdb91d1SDmitri Tikhonov    unsigned                tp_decoded;
801bdb91d1SDmitri Tikhonov
811bdb91d1SDmitri Tikhonov    uint64_t                tp_numerics[MAX_NUMERIC_TPI + 1];
821bdb91d1SDmitri Tikhonov
831bdb91d1SDmitri Tikhonov#define tp_init_max_stream_data_bidi_local  tp_numerics[TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL]
841bdb91d1SDmitri Tikhonov#define tp_init_max_stream_data_bidi_remote tp_numerics[TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE]
851bdb91d1SDmitri Tikhonov#define tp_init_max_stream_data_uni         tp_numerics[TPI_INIT_MAX_STREAM_DATA_UNI]
861bdb91d1SDmitri Tikhonov#define tp_init_max_data                    tp_numerics[TPI_INIT_MAX_DATA]
871bdb91d1SDmitri Tikhonov#define tp_max_idle_timeout                 tp_numerics[TPI_MAX_IDLE_TIMEOUT]
881bdb91d1SDmitri Tikhonov#define tp_init_max_streams_bidi            tp_numerics[TPI_INIT_MAX_STREAMS_BIDI]
891bdb91d1SDmitri Tikhonov#define tp_init_max_streams_uni             tp_numerics[TPI_INIT_MAX_STREAMS_UNI]
90fb73393fSDmitri Tikhonov#define tp_max_udp_payload_size             tp_numerics[TPI_MAX_UDP_PAYLOAD_SIZE]
911bdb91d1SDmitri Tikhonov#define tp_ack_delay_exponent               tp_numerics[TPI_ACK_DELAY_EXPONENT]
921bdb91d1SDmitri Tikhonov#define tp_max_ack_delay                    tp_numerics[TPI_MAX_ACK_DELAY]
931bdb91d1SDmitri Tikhonov#define tp_active_connection_id_limit       tp_numerics[TPI_ACTIVE_CONNECTION_ID_LIMIT]
941bdb91d1SDmitri Tikhonov#define tp_loss_bits                        tp_numerics[TPI_LOSS_BITS]
951bdb91d1SDmitri Tikhonov
965392f7a3SLiteSpeed Tech    uint8_t     tp_stateless_reset_token[IQUIC_SRESET_TOKEN_SZ];
975392f7a3SLiteSpeed Tech    struct {
985392f7a3SLiteSpeed Tech        uint8_t         ipv4_addr[4];
995392f7a3SLiteSpeed Tech        uint16_t        ipv4_port;
1005392f7a3SLiteSpeed Tech        uint8_t         ipv6_addr[16];
1015392f7a3SLiteSpeed Tech        uint16_t        ipv6_port;
1025392f7a3SLiteSpeed Tech        lsquic_cid_t    cid;
1035392f7a3SLiteSpeed Tech        uint8_t         srst[IQUIC_SRESET_TOKEN_SZ];
1045392f7a3SLiteSpeed Tech    }           tp_preferred_address;
105fb73393fSDmitri Tikhonov    lsquic_cid_t    tp_cids[3];
106fb73393fSDmitri Tikhonov#define tp_original_dest_cid tp_cids[TP_CID_IDX(TPI_ORIGINAL_DEST_CID)]
107fb73393fSDmitri Tikhonov#define tp_initial_source_cid tp_cids[TP_CID_IDX(TPI_INITIAL_SOURCE_CID)]
108fb73393fSDmitri Tikhonov#define tp_retry_source_cid tp_cids[TP_CID_IDX(TPI_RETRY_SOURCE_CID)]
1095392f7a3SLiteSpeed Tech};
1105392f7a3SLiteSpeed Tech
111fb73393fSDmitri Tikhonov#define MAX_TP_STR_SZ ((LAST_TPI + 1) *                                     \
112fb73393fSDmitri Tikhonov    (34 /* longest entry in tt2str */ + 2 /* semicolon */ + 2 /* colon */)  \
113fb73393fSDmitri Tikhonov  + INET_ADDRSTRLEN + INET6_ADDRSTRLEN + 5 /* Port */ * 2                   \
114fb73393fSDmitri Tikhonov  + MAX_CID_LEN * 2 * 4 /* there are four CIDs */                           \
115fb73393fSDmitri Tikhonov  + 11 * (MAX_NUMERIC_TPI + 1)                                              \
116fb73393fSDmitri Tikhonov  + IQUIC_SRESET_TOKEN_SZ * 2 * 2 /* there are two reset tokens */)
117fb73393fSDmitri Tikhonov
118fb73393fSDmitri Tikhonov#define TP_DEF_MAX_UDP_PAYLOAD_SIZE 65527
1195392f7a3SLiteSpeed Tech#define TP_DEF_ACK_DELAY_EXP 3
1205392f7a3SLiteSpeed Tech#define TP_DEF_INIT_MAX_STREAMS_UNI 0
1215392f7a3SLiteSpeed Tech#define TP_DEF_INIT_MAX_STREAMS_BIDI 0
1225392f7a3SLiteSpeed Tech#define TP_DEF_INIT_MAX_DATA 0
12392f6e17bSDmitri Tikhonov#define TP_DEF_DISABLE_ACTIVE_MIGRATION 0
1245392f7a3SLiteSpeed Tech#define TP_DEF_INIT_MAX_STREAM_DATA_BIDI_LOCAL 0
1255392f7a3SLiteSpeed Tech#define TP_DEF_INIT_MAX_STREAM_DATA_BIDI_REMOTE 0
1265392f7a3SLiteSpeed Tech#define TP_DEF_INIT_MAX_STREAM_DATA_UNI 0
1279fc12041SDmitri Tikhonov#define TP_DEF_MAX_IDLE_TIMEOUT 0
128f38b395aSDmitri Tikhonov#define TP_DEF_MAX_ACK_DELAY 25u
1299fc12041SDmitri Tikhonov#define TP_DEF_ACTIVE_CONNECTION_ID_LIMIT 2
1305392f7a3SLiteSpeed Tech
13110e0dad8SGeorge Wang/* [draft-ietf-quic-transport-34], Section 18.2 */
13210e0dad8SGeorge Wang#define TP_MAX_ACK_DELAY_EXP 20
13310e0dad8SGeorge Wang
1345392f7a3SLiteSpeed Tech/* [draft-ietf-quic-transport-18], Section 18.1 */
1355392f7a3SLiteSpeed Tech#define TP_MAX_MAX_ACK_DELAY ((1u << 14) - 1)
1365392f7a3SLiteSpeed Tech
1375392f7a3SLiteSpeed Tech#define TP_DEFAULT_VALUES                                                             \
1381bdb91d1SDmitri Tikhonov    .tp_set = ((1 << (MAX_NUM_WITH_DEF_TPI + 1)) - 1),                                \
1395392f7a3SLiteSpeed Tech    .tp_active_connection_id_limit        =  TP_DEF_ACTIVE_CONNECTION_ID_LIMIT,       \
1409fc12041SDmitri Tikhonov    .tp_max_idle_timeout                  =  TP_DEF_MAX_IDLE_TIMEOUT,                 \
1415392f7a3SLiteSpeed Tech    .tp_max_ack_delay                     =  TP_DEF_MAX_ACK_DELAY,                    \
142fb73393fSDmitri Tikhonov    .tp_max_udp_payload_size              =  TP_DEF_MAX_UDP_PAYLOAD_SIZE,             \
1435392f7a3SLiteSpeed Tech    .tp_ack_delay_exponent                =  TP_DEF_ACK_DELAY_EXP,                    \
1445392f7a3SLiteSpeed Tech    .tp_init_max_streams_bidi             =  TP_DEF_INIT_MAX_STREAMS_BIDI,            \
1455392f7a3SLiteSpeed Tech    .tp_init_max_streams_uni              =  TP_DEF_INIT_MAX_STREAMS_UNI,             \
1465392f7a3SLiteSpeed Tech    .tp_init_max_data                     =  TP_DEF_INIT_MAX_DATA,                    \
1475392f7a3SLiteSpeed Tech    .tp_init_max_stream_data_bidi_local   =  TP_DEF_INIT_MAX_STREAM_DATA_BIDI_LOCAL,  \
1485392f7a3SLiteSpeed Tech    .tp_init_max_stream_data_bidi_remote  =  TP_DEF_INIT_MAX_STREAM_DATA_BIDI_REMOTE, \
1495392f7a3SLiteSpeed Tech    .tp_init_max_stream_data_uni          =  TP_DEF_INIT_MAX_STREAM_DATA_UNI
1505392f7a3SLiteSpeed Tech
1515392f7a3SLiteSpeed Tech#define TP_INITIALIZER() (struct transport_params) { TP_DEFAULT_VALUES }
1525392f7a3SLiteSpeed Tech
1535392f7a3SLiteSpeed Techint
1541bdb91d1SDmitri Tikhonovlsquic_tp_encode (const struct transport_params *, int is_server,
155fb3e20e0SDmitri Tikhonov                  unsigned char *const buf, size_t bufsz);
1565392f7a3SLiteSpeed Tech
1575392f7a3SLiteSpeed Techint
158fb3e20e0SDmitri Tikhonovlsquic_tp_decode (const unsigned char *const buf, size_t bufsz,
1595392f7a3SLiteSpeed Tech    /* This argument specifies whose transport parameters we are parsing.  If
1605392f7a3SLiteSpeed Tech     * true, we are parsing parameters sent by the server; if false, we are
1615392f7a3SLiteSpeed Tech     * parsing parameteres sent by the client.
1625392f7a3SLiteSpeed Tech     */
1635392f7a3SLiteSpeed Tech                  int is_server,
1645392f7a3SLiteSpeed Tech                  struct transport_params *);
1655392f7a3SLiteSpeed Tech
166fb73393fSDmitri Tikhonovvoid
167fb73393fSDmitri Tikhonovlsquic_tp_to_str (const struct transport_params *params, char *buf, size_t sz);
168fb73393fSDmitri Tikhonov
169bc520ef7SDmitri Tikhonovint
170fb73393fSDmitri Tikhonovlsquic_tp_encode_27 (const struct transport_params *, int is_server,
171fb3e20e0SDmitri Tikhonov                  unsigned char *const buf, size_t bufsz);
172bc520ef7SDmitri Tikhonov
173bc520ef7SDmitri Tikhonovint
174fb3e20e0SDmitri Tikhonovlsquic_tp_decode_27 (const unsigned char *const buf, size_t bufsz,
175fb73393fSDmitri Tikhonov                  int is_server,
176fb73393fSDmitri Tikhonov                  struct transport_params *);
177bc520ef7SDmitri Tikhonov
1785392f7a3SLiteSpeed Techvoid
179fb73393fSDmitri Tikhonovlsquic_tp_to_str_27 (const struct transport_params *params, char *buf, size_t sz);
1805392f7a3SLiteSpeed Tech
1811bdb91d1SDmitri Tikhonovint
1821bdb91d1SDmitri Tikhonovlsquic_tp_has_pref_ipv4 (const struct transport_params *);
1831bdb91d1SDmitri Tikhonov
1841bdb91d1SDmitri Tikhonovint
1851bdb91d1SDmitri Tikhonovlsquic_tp_has_pref_ipv6 (const struct transport_params *);
1861bdb91d1SDmitri Tikhonov
187fb73393fSDmitri Tikhonovextern const char * const lsquic_tpi2str[LAST_TPI + 1];
188fb73393fSDmitri Tikhonov
18949f1f4f6SDmitri Tikhonov/* From [draft-huitema-quic-ts-03] */
19049f1f4f6SDmitri Tikhonov#define TS_WANT_THEM            1
19149f1f4f6SDmitri Tikhonov#define TS_GENERATE_THEM        2
19249f1f4f6SDmitri Tikhonov
193b1a7c3f9SDmitri Tikhonov#if LSQUIC_TEST_QUANTUM_READINESS
194b1a7c3f9SDmitri Tikhonovsize_t
195b1a7c3f9SDmitri Tikhonovlsquic_tp_get_quantum_sz (void);
196b1a7c3f9SDmitri Tikhonov#endif
197b1a7c3f9SDmitri Tikhonov
19804f8f447SDmitri Tikhonov#define SERVER_0RTT_TPS                                              (0 \
19904f8f447SDmitri Tikhonov    /* [draft-ietf-quic-transport-31] Section 7.4.1: */                 \
20004f8f447SDmitri Tikhonov    | (1 << TPI_ACTIVE_CONNECTION_ID_LIMIT)                             \
20104f8f447SDmitri Tikhonov    | (1 << TPI_INIT_MAX_DATA)                                          \
20204f8f447SDmitri Tikhonov    | (1 << TPI_INIT_MAX_STREAMS_UNI)                                   \
20304f8f447SDmitri Tikhonov    | (1 << TPI_INIT_MAX_STREAMS_BIDI)                                  \
20404f8f447SDmitri Tikhonov    | (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_LOCAL)                        \
20504f8f447SDmitri Tikhonov    | (1 << TPI_INIT_MAX_STREAM_DATA_BIDI_REMOTE)                       \
20604f8f447SDmitri Tikhonov    | (1 << TPI_INIT_MAX_STREAM_DATA_UNI)                               \
20704f8f447SDmitri Tikhonov    | (1 << TPI_MAX_IDLE_TIMEOUT)                                       \
20804f8f447SDmitri Tikhonov    | (1 << TPI_MAX_UDP_PAYLOAD_SIZE)                                   \
20904f8f447SDmitri Tikhonov    | (1 << TPI_DISABLE_ACTIVE_MIGRATION)                               \
21004f8f447SDmitri Tikhonov    /* Not including TPI_LOSS_BITS, see                              */ \
21104f8f447SDmitri Tikhonov    /* draft-ferrieuxhamchaoui-quic-lossbits-03, Section 5.1         */ \
21204f8f447SDmitri Tikhonov    /* [draft-ietf-quic-datagram-01] Section 3:                      */ \
21304f8f447SDmitri Tikhonov    | (1 << TPI_MAX_DATAGRAM_FRAME_SIZE)                                \
21404f8f447SDmitri Tikhonov    /* [draft-iyengar-quic-delayed-ack-01] does not specfiy, store:  */ \
21504f8f447SDmitri Tikhonov    | (1 << TPI_MIN_ACK_DELAY)                                          \
216f38b395aSDmitri Tikhonov    /* [draft-iyengar-quic-delayed-ack-02] does not specfiy, store:  */ \
217f38b395aSDmitri Tikhonov    | (1 << TPI_MIN_ACK_DELAY_02)                                       \
21804f8f447SDmitri Tikhonov    /* [draft-huitema-quic-ts-03] does not specfiy, store:           */ \
21904f8f447SDmitri Tikhonov    | (1 << TPI_TIMESTAMPS)                                             \
22004f8f447SDmitri Tikhonov)
22104f8f447SDmitri Tikhonov
222f38b395aSDmitri Tikhonov/* We always send the minimum ACK delay as 10ms; it is not configurable.
223f38b395aSDmitri Tikhonov * There is nothing special about this particular value, except that it
224f38b395aSDmitri Tikhonov * is not "too small" -- that is, it's within an order of magnitude from
225f38b395aSDmitri Tikhonov * the maximum ACK delay of 25ms.  10ms seems like a safe lower bound for
226f38b395aSDmitri Tikhonov * the ACK delay without performing more research.
227f38b395aSDmitri Tikhonov */
228f38b395aSDmitri Tikhonov#define TP_MIN_ACK_DELAY 10000u
229f38b395aSDmitri Tikhonov
2305392f7a3SLiteSpeed Tech#endif
231