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