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