LCOV - code coverage report
Current view: top level - waltz/quic/templ - fd_quic_transport_params.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 228 228 100.0 %
Date: 2026-10-15 04:28:26 Functions: 1 50 2.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_waltz_quic_templ_fd_quic_transport_params_h
       2             : #define HEADER_fd_src_waltz_quic_templ_fd_quic_transport_params_h
       3             : 
       4             : #include "../../../util/fd_util_base.h"
       5             : #include <stdio.h>
       6             : 
       7             : // TODO set proper defaults, and delete DFT_UNKNOWN
       8             : #define DFT_UNKNOWN 0
       9             : 
      10             : /* QUIC VARINT bounds - RFC 9000 variable-length integers can encode up to 2^62-1 */
      11      194571 : #define FD_QUIC_VARINT_MAX ((1UL<<62)-1UL)
      12      194592 : #define FD_QUIC_VARINT_MIN 0UL
      13             : 
      14             : /* RFC 9000 Section 19.11: Stream count maximum cannot exceed 2^60, as it is not possible to encode stream IDs larger than 2^62-1. */
      15           6 : #define FD_QUIC_STREAM_COUNT_MAX (1UL<<60)
      16             : 
      17             : /* RFC 9000 Section 18.2: ack_delay_exponent values above 20 are invalid */
      18             : #define FD_QUIC_ACK_DELAY_EXPONENT_MAX 20UL
      19             : 
      20             : /* RFC 9000 Section 18.2: max_ack_delay values of 2^14 or greater are invalid */
      21             : #define FD_QUIC_MAX_ACK_DELAY_MAX ((1UL<<14)-1UL)
      22             : 
      23             : /* RFC 9000 Section 18.2: max_udp_payload_size minimum is 1200 */
      24             : #define FD_QUIC_MAX_UDP_PAYLOAD_SIZE_MIN 1200UL
      25             : 
      26             : /* RFC 9000 Section 18.2: The value of the active_connection_id_limit parameter MUST be at least 2 */
      27             : #define FD_QUIC_ACTIVE_CONNECTION_ID_LIMIT_MIN 2UL
      28             : 
      29             : //23456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789
      30             : //........1.........2.........3.........4.........5.........6.........7.........8.........9.........0.........
      31             : // Fields: NAME, ID, TYPE, DFT, DESC, MIN, MAX (MIN and MAX ignored except for VARINT types)
      32       18726 : #define FD_QUIC_TRANSPORT_PARAMS(X, ...)                                               \
      33       18726 : X( original_destination_connection_id,                                                 \
      34        6357 :   0x00,                                                                                \
      35        6357 :   CONN_ID,                                                                             \
      36        6357 :   DFT_UNKNOWN,                                                                         \
      37        6357 :   "This parameter is the value of the Destination Connection ID field from the "       \
      38        6357 :   "first Initial packet sent by the client; see Section 7.3. This transport "          \
      39        6357 :   "parameter is only sent by a server.",                                               \
      40        6357 :   0, 0,                                                                                \
      41       24522 :   __VA_ARGS__ )                                                                        \
      42       24522 : X( max_idle_timeout_ms,                                                                \
      43       24516 :   0x01,                                                                                \
      44       24516 :   VARINT,                                                                              \
      45       24516 :   DFT_UNKNOWN,                                                                         \
      46       24516 :   "The maximum idle timeout is a value in milliseconds that is encoded as an "         \
      47       24516 :   "integer; see (Section 10.1). Idle timeout is disabled when both endpoints omit "    \
      48       24516 :   "this transport parameter or specify a value of 0.",                                 \
      49       24516 :   FD_QUIC_VARINT_MIN, FD_QUIC_VARINT_MAX,                                              \
      50       24516 :   __VA_ARGS__ )                                                                        \
      51       12369 : X( stateless_reset_token,                                                              \
      52       12363 :   0x02,                                                                                \
      53       12363 :   TOKEN,                                                                               \
      54       12363 :   DFT_UNKNOWN,                                                                         \
      55       12363 :   "A stateless reset token is used in verifying a stateless reset; see Section "       \
      56       12363 :   "10.3. This parameter is a sequence of 16 bytes. This transport parameter MUST "     \
      57       12363 :   "NOT be sent by a client but MAY be sent by a server. A server that does not send "  \
      58       12363 :   "this transport parameter cannot use stateless reset (Section 10.3) for the "        \
      59       12363 :   "connection ID negotiated during the handshake.",                                    \
      60       12363 :   0, 0,                                                                                \
      61       24522 :   __VA_ARGS__ )                                                                        \
      62       24522 : X( max_udp_payload_size,                                                               \
      63       24510 :   0x03,                                                                                \
      64       24510 :   VARINT,                                                                              \
      65       24510 :   65527,                                                                               \
      66       24510 :   "The maximum UDP payload size parameter is an integer value that limits the size "   \
      67       24510 :   "of UDP payloads that the endpoint is willing to receive. UDP datagrams with "       \
      68       24510 :   "payloads larger than this limit are not likely to be processed by the receiver. "   \
      69       24510 :   "The default for this parameter is the maximum permitted UDP payload of 65527. "     \
      70       24510 :   "Values below 1200 are invalid.\n"                                                   \
      71       24510 :   "This limit does act as an additional constraint on datagram size in the same way "  \
      72       24510 :   "as the path MTU, but it is a property of the endpoint and not the path; see "       \
      73       24510 :   "Section 14. It is expected that this is the space an endpoint dedicates to "        \
      74       24510 :   "holding incoming packets.",                                                         \
      75       24510 :   FD_QUIC_MAX_UDP_PAYLOAD_SIZE_MIN, FD_QUIC_VARINT_MAX,                                             \
      76       24513 :   __VA_ARGS__ )                                                                        \
      77       24513 : X( initial_max_data,                                                                   \
      78       24507 :   0x04,                                                                                \
      79       24507 :   VARINT,                                                                              \
      80       24507 :   DFT_UNKNOWN,                                                                         \
      81       24507 :   "The initial maximum data parameter is an integer value that contains the initial "  \
      82       24507 :   "value for the maximum amount of data that can be sent on the connection. This is "  \
      83       24507 :   "equivalent to sending a MAX_DATA (Section 19.9) for the connection immediately "    \
      84       24507 :   "after completing the handshake.",                                                   \
      85       24507 :   FD_QUIC_VARINT_MIN, FD_QUIC_VARINT_MAX,                                              \
      86       24507 :   __VA_ARGS__ )                                                                        \
      87       12375 : X( initial_max_stream_data_bidi_local,                                                 \
      88       12369 :   0x05,                                                                                \
      89       12369 :   VARINT,                                                                              \
      90       12369 :   DFT_UNKNOWN,                                                                         \
      91       12369 :   "This parameter is an integer value specifying the initial flow control limit for "  \
      92       12369 :   "locally initiated bidirectional streams. This limit applies to newly created "      \
      93       12369 :   "bidirectional streams opened by the endpoint that sends the transport parameter. "  \
      94       12369 :   "In client transport parameters, this applies to streams with an identifier with "   \
      95       12369 :   "the least significant two bits set to 0x00; in server transport parameters, this "  \
      96       12369 :   "applies to streams with the least significant two bits set to 0x01.",               \
      97       12369 :   FD_QUIC_VARINT_MIN, FD_QUIC_VARINT_MAX,                                              \
      98       12375 :   __VA_ARGS__ )                                                                        \
      99       12375 : X( initial_max_stream_data_bidi_remote,                                                \
     100       12369 :   0x06,                                                                                \
     101       12369 :   VARINT,                                                                              \
     102       12369 :   DFT_UNKNOWN,                                                                         \
     103       12369 :   "This parameter is an integer value specifying the initial flow control limit for "  \
     104       12369 :   "peer-initiated bidirectional streams. This limit applies to newly created "         \
     105       12369 :   "bidirectional streams opened by the endpoint that receives the transport "          \
     106       12369 :   "parameter. In client transport parameters, this applies to streams with an "        \
     107       12369 :   "identifier with the least significant two bits set to 0x01; in server transport "   \
     108       12369 :   "parameters, this applies to streams with the least significant two bits set to "    \
     109       12369 :   "0x00.",                                                                             \
     110       12369 :   FD_QUIC_VARINT_MIN, FD_QUIC_VARINT_MAX,                                              \
     111       24513 :   __VA_ARGS__ )                                                                        \
     112       24513 : X( initial_max_stream_data_uni,                                                        \
     113       24507 :   0x07,                                                                                \
     114       24507 :   VARINT,                                                                              \
     115       24507 :   DFT_UNKNOWN,                                                                         \
     116       24507 :   "This parameter is an integer value specifying the initial flow control limit for "  \
     117       24507 :   "unidirectional streams. This limit applies to newly created unidirectional "        \
     118       24507 :   "streams opened by the endpoint that receives the transport parameter. In client "   \
     119       24507 :   "transport parameters, this applies to streams with an identifier with the least "   \
     120       24507 :   "significant two bits set to 0x03; in server transport parameters, this applies "    \
     121       24507 :   "to streams with the least significant two bits set to 0x02.",                       \
     122       24507 :   FD_QUIC_VARINT_MIN, FD_QUIC_VARINT_MAX,                                              \
     123       24525 :   __VA_ARGS__ )                                                                        \
     124       24525 : X( initial_max_streams_bidi,                                                           \
     125       24516 :   0x08,                                                                                \
     126       24516 :   VARINT,                                                                              \
     127       24516 :   DFT_UNKNOWN,                                                                         \
     128       24516 :   "The initial maximum bidirectional streams parameter is an integer value that "      \
     129       24516 :   "contains the initial maximum number of bidirectional streams the endpoint that "    \
     130       24516 :   "receives this transport parameter is permitted to initiate. If this parameter is "  \
     131       24516 :   "absent or zero, the peer cannot open bidirectional streams until a MAX_STREAMS "    \
     132       24516 :   "frame is sent. Setting this parameter is equivalent to sending a MAX_STREAMS "      \
     133       24516 :   "(Section 19.11) of the corresponding type with the same value.",                    \
     134       24516 :   FD_QUIC_VARINT_MIN, FD_QUIC_STREAM_COUNT_MAX,                                        \
     135       24519 :   __VA_ARGS__ )                                                                        \
     136       24519 : X( initial_max_streams_uni,                                                            \
     137       24510 :   0x09,                                                                                \
     138       24510 :   VARINT,                                                                              \
     139       24510 :   DFT_UNKNOWN,                                                                         \
     140       24510 :   "The initial maximum unidirectional streams parameter is an integer value that "     \
     141       24510 :   "contains the initial maximum number of unidirectional streams the endpoint that "   \
     142       24510 :   "receives this transport parameter is permitted to initiate. If this parameter is "  \
     143       24510 :   "absent or zero, the peer cannot open unidirectional streams until a MAX_STREAMS "   \
     144       24510 :   "frame is sent. Setting this parameter is equivalent to sending a MAX_STREAMS "      \
     145       24510 :   "(Section 19.11) of the corresponding type with the same value.",                    \
     146       24510 :   FD_QUIC_VARINT_MIN, FD_QUIC_STREAM_COUNT_MAX,                                        \
     147       24579 :   __VA_ARGS__ )                                                                        \
     148       24579 : X( ack_delay_exponent,                                                                 \
     149       24567 :   0x0a,                                                                                \
     150       24567 :   VARINT,                                                                              \
     151       24567 :   DFT_UNKNOWN,                                                                         \
     152       24567 :   "The acknowledgment delay exponent is an integer value indicating an exponent "      \
     153       24567 :   "used to decode the ACK Delay field in the ACK frame (Section 19.3). If this "       \
     154       24567 :   "value is absent, a default value of 3 is assumed (indicating a multiplier of 8).\n" \
     155       24567 :   "Values above 20 are invalid.",                                                      \
     156       24567 :   FD_QUIC_VARINT_MIN, FD_QUIC_ACK_DELAY_EXPONENT_MAX,                                  \
     157       24567 :   __VA_ARGS__ )                                                                        \
     158       24525 : X( max_ack_delay,                                                                      \
     159       24513 :   0x0b,                                                                                \
     160       24513 :   VARINT,                                                                              \
     161       24513 :   25,                                                                                  \
     162       24513 :   "The maximum acknowledgment delay is an integer value indicating the maximum "       \
     163       24513 :   "amount of time in milliseconds by which the endpoint will delay sending "           \
     164       24513 :   "acknowledgments. This value SHOULD include the receiver's expected delays in "      \
     165       24513 :   "alarms firing. For example, if a receiver sets a timer for 5ms and alarms "         \
     166       24513 :   "commonly fire up to 1ms late, then it should send a max_ack_delay of 6ms. If "      \
     167       24513 :   "this value is absent, a default of 25 milliseconds is assumed. Values of 2^14 or "  \
     168       24513 :   "greater are invalid.",                                                              \
     169       24513 :   FD_QUIC_VARINT_MIN, FD_QUIC_MAX_ACK_DELAY_MAX,                                       \
     170       24513 :   __VA_ARGS__ )                                                                        \
     171       24513 : X( disable_active_migration,                                                           \
     172       24507 :   0x0c,                                                                                \
     173       24507 :   ZERO_LENGTH,                                                                         \
     174       24507 :   DFT_UNKNOWN,                                                                         \
     175       24507 :   "The disable active migration transport parameter is included if the endpoint "      \
     176       24507 :   "does not support active connection migration (Section 9) on the address being "     \
     177       24507 :   "used during the handshake. An endpoint that receives this transport parameter "     \
     178       24507 :   "MUST NOT use a new local address when sending to the address that the peer used "   \
     179       24507 :   "during the handshake. This transport parameter does not prohibit connection "       \
     180       24507 :   "migration after a client has acted on a preferred_address transport parameter.\n"   \
     181       24507 :   "This parameter is a zero-length value.",                                            \
     182       24507 :   0, 0,                                                                                \
     183       24507 :   __VA_ARGS__ )                                                                        \
     184       12369 : X( preferred_address,                                                                  \
     185       12363 :   0x0d,                                                                                \
     186       12363 :   PREFERRED_ADDRESS,                                                                   \
     187       12363 :   DFT_UNKNOWN,                                                                         \
     188       12363 :   "The server's preferred address is used to effect a change in server address at "    \
     189       12363 :   "the end of the handshake, as described in Section 9.6. This transport parameter "   \
     190       12363 :   "is only sent by a server. Servers MAY choose to only send a preferred address of "  \
     191       12363 :   "one address family by sending an all-zero address and port (0.0.0.0:0 or [::]:0) "  \
     192       12363 :   "for the other family. IP addresses are encoded in network byte order.\n"            \
     193       12363 :   "The preferred_address transport parameter contains an address and port for both "   \
     194       12363 :   "IPv4 and IPv6. The four-byte IPv4 Address field is followed by the associated "     \
     195       12363 :   "two-byte IPv4 Port field. This is followed by a 16-byte IPv6 Address field and "    \
     196       12363 :   "two-byte IPv6 Port field. After address and port pairs, a Connection ID Length "    \
     197       12363 :   "field describes the length of the following Connection ID field. Finally, a "       \
     198       12363 :   "16-byte Stateless Reset Token field includes the stateless reset token "            \
     199       12363 :   "associated with the connection ID. The format of this transport parameter is "      \
     200       12363 :   "shown in Figure 22 below.",                                                         \
     201       12363 :   0, 0,                                                                                \
     202       12384 :   __VA_ARGS__ )                                                                        \
     203       12384 : X( active_connection_id_limit,                                                         \
     204       12372 :   0x0e,                                                                                \
     205       12372 :   VARINT,                                                                              \
     206       12372 :   2,                                                                                   \
     207       12372 :   "This is an integer value specifying the maximum number of connection IDs from "     \
     208       12372 :   "the peer that an endpoint is willing to store. This value includes the "            \
     209       12372 :   "connection ID received during the handshake, that received in the "                 \
     210       12372 :   "preferred_address transport parameter, and those received in NEW_CONNECTION_ID "    \
     211       12372 :   "frames. The value of the active_connection_id_limit parameter MUST be at least "    \
     212       12372 :   "2. An endpoint that receives a value less than 2 MUST close the connection with "   \
     213       12372 :   "an error of type TRANSPORT_PARAMETER_ERROR. If this transport parameter is "        \
     214       12372 :   "absent, a default of 2 is assumed. If an endpoint issues a zero-length "            \
     215       12372 :   "connection ID, it will never send a NEW_CONNECTION_ID frame and therefore "         \
     216       12372 :   "ignores the active_connection_id_limit value received from its peer.",              \
     217       12372 :   FD_QUIC_ACTIVE_CONNECTION_ID_LIMIT_MIN, FD_QUIC_VARINT_MAX,                          \
     218       24513 :   __VA_ARGS__ )                                                                        \
     219       24513 : X( initial_source_connection_id,                                                       \
     220       24507 :   0x0f,                                                                                \
     221       24507 :   CONN_ID,                                                                             \
     222       24507 :   DFT_UNKNOWN,                                                                         \
     223       24507 :   "This is the value that the endpoint included in the Source Connection ID field "    \
     224       24507 :   "of the first Initial packet it sends for the connection; see Section 7.3.",         \
     225       24507 :   0, 0,                                                                                \
     226       24507 :   __VA_ARGS__ )                                                                        \
     227       12375 : X( retry_source_connection_id,                                                         \
     228       12369 :   0x10,                                                                                \
     229       12369 :   CONN_ID,                                                                             \
     230       12369 :   DFT_UNKNOWN,                                                                         \
     231       12369 :   "This is the value that the server included in the Source Connection ID field of "   \
     232       12369 :   "a Retry packet; see Section 7.3. This transport parameter is only sent by a "       \
     233       12369 :   "server.",                                                                           \
     234       12369 :   0, 0,                                                                                \
     235       12372 :   __VA_ARGS__ )                                                                        \
     236       12372 : X( max_datagram_frame_size,                                                            \
     237       12366 :   0x20,                                                                                \
     238       12366 :   VARINT,                                                                              \
     239       12366 :   DFT_UNKNOWN,                                                                         \
     240       12366 :   "RFC 9221 maximum DATAGRAM frame size. Omitting this parameter disables DATAGRAM.",  \
     241       12366 :   FD_QUIC_VARINT_MIN, FD_QUIC_VARINT_MAX,                                              \
     242       12366 :   __VA_ARGS__ )
     243             : 
     244           3 : #define FD_QUIC_PREFERRED_ADDRESS_SZ_MAX (61)
     245             : 
     246             : void
     247             : fd_quic_dump_transport_param_desc( FILE * out );
     248             : 
     249             : // TODO verify max length on these - CONN_ID and TOKEN
     250             : // PREFERRED_ADDRESS is incomplete
     251             : #define FD_QUIC_MBR_TYPE_VARINT(NAME,TYPE)            \
     252             :   ulong  NAME;                                        \
     253             :   uchar  NAME##_present;
     254             : #define FD_QUIC_MBR_TYPE_CONN_ID(NAME,TYPE)           \
     255             :   uchar  NAME##_len;                                  \
     256             :   uchar  NAME[20];                                    \
     257             :   uchar  NAME##_present;
     258             : #define FD_QUIC_MBR_TYPE_ZERO_LENGTH(NAME,TYPE)       \
     259             :   uchar  NAME##_present;
     260             : #define FD_QUIC_MBR_TYPE_TOKEN(NAME,TYPE)             \
     261             :   uint   NAME##_len;                                  \
     262             :   uchar  NAME[16];                                    \
     263             :   uchar  NAME##_present;
     264             : #define FD_QUIC_MBR_TYPE_PREFERRED_ADDRESS(NAME,TYPE) \
     265             :   uint   NAME##_len;                                  \
     266             :   uchar  NAME[FD_QUIC_PREFERRED_ADDRESS_SZ_MAX];      \
     267             :   uchar  NAME##_present;
     268             : 
     269             : struct fd_quic_transport_params {
     270             : #define __( NAME, ID, TYPE, DFT, DESC, ... ) \
     271             :   FD_QUIC_MBR_TYPE_##TYPE(NAME,TYPE)
     272             :   FD_QUIC_TRANSPORT_PARAMS( __, _ )
     273             : #undef __
     274             : };
     275             : typedef struct fd_quic_transport_params fd_quic_transport_params_t;
     276             : 
     277             : #define FD_QUIC_TRANSPORT_PARAM_SET( TP, NAME, VALUE ) \
     278        2370 :   do { (TP)->NAME##_present = 1; (TP)->NAME = VALUE; } while(0);
     279             : #define FD_QUIC_TRANSPORT_PARAM_UNSET( TP, NAME ) \
     280             :   do { (TP)->NAME##_present = 0;                     } while(0);
     281             : 
     282             : /* parses the varint at *buf (capacity *buf_sz)
     283             :    advances the *buf and reduces *buf_sz by the number of bytes
     284             :    consumed */
     285             : static inline ulong
     286             : fd_quic_tp_parse_varint( uchar const ** buf,
     287      255918 :                          ulong *        buf_sz ) {
     288             : 
     289      255918 :   if( FD_UNLIKELY( *buf_sz == 0    ) ) return ~(ulong)0;
     290             : 
     291      255915 :   uint width = 1u << ( (uint)(*buf)[0] >> 6u );
     292      255915 :   if( FD_UNLIKELY( *buf_sz < width ) ) return ~(ulong)0;
     293             : 
     294      255915 :   ulong value = (ulong)( (*buf)[0] & 0x3f );
     295      255987 :   for( ulong j=1; j<width; ++j ) {
     296          72 :     value = ( value<<8UL ) + (ulong)(*buf)[j];
     297          72 :   }
     298             : 
     299      255915 :   *buf    += width;
     300      255915 :   *buf_sz -= width;
     301             : 
     302      255915 :   return value;
     303      255915 : }
     304             : 
     305             : /* parse the entire buffer into the supplied transport parameters
     306             : 
     307             :    unknown transport parameters are ignored as per spec
     308             : 
     309             :    returns
     310             :      0  success
     311             :      -1 failed to parse */
     312             : int
     313             : fd_quic_decode_transport_params( fd_quic_transport_params_t * params,
     314             :                                  uchar const *                buf,
     315             :                                  ulong                        buf_sz );
     316             : 
     317             : /* dump all transport parameters to stdout */
     318             : void
     319             : fd_quic_dump_transport_params( fd_quic_transport_params_t const * params,
     320             :                                FILE * out );
     321             : 
     322             : 
     323             : /* encode transport parameters into a buffer
     324             :    args
     325             :      buf           the buffer to write encoded transport params into
     326             :      buf_sz        the size of buffer buf
     327             :      params        the parameters to be encoded
     328             : 
     329             :    returns the number of bytes written */
     330             : ulong
     331             : fd_quic_encode_transport_params( uchar *                            buf,
     332             :                                  ulong                              buf_sz,
     333             :                                  fd_quic_transport_params_t const * params );
     334             : 
     335             : #endif /* HEADER_fd_src_waltz_quic_templ_fd_quic_transport_params_h */

Generated by: LCOV version 1.14