/src/openssl34/include/internal/quic_wire.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5 | | * this file except in compliance with the License. You can obtain a copy |
6 | | * in the file LICENSE in the source distribution or at |
7 | | * https://www.openssl.org/source/license.html |
8 | | */ |
9 | | |
10 | | #ifndef OSSL_INTERNAL_QUIC_WIRE_H |
11 | | #define OSSL_INTERNAL_QUIC_WIRE_H |
12 | | #pragma once |
13 | | |
14 | | #include "internal/e_os.h" |
15 | | #include "internal/time.h" |
16 | | #include "internal/quic_types.h" |
17 | | #include "internal/packet_quic.h" |
18 | | |
19 | | #ifndef OPENSSL_NO_QUIC |
20 | | |
21 | 500k | #define OSSL_QUIC_FRAME_TYPE_PADDING 0x00 |
22 | 4.53M | #define OSSL_QUIC_FRAME_TYPE_PING 0x01 |
23 | 14.1M | #define OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN 0x02 |
24 | 777k | #define OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN 0x03 |
25 | 26.2k | #define OSSL_QUIC_FRAME_TYPE_RESET_STREAM 0x04 |
26 | 213k | #define OSSL_QUIC_FRAME_TYPE_STOP_SENDING 0x05 |
27 | 672k | #define OSSL_QUIC_FRAME_TYPE_CRYPTO 0x06 |
28 | 5.52k | #define OSSL_QUIC_FRAME_TYPE_NEW_TOKEN 0x07 |
29 | 71.4k | #define OSSL_QUIC_FRAME_TYPE_MAX_DATA 0x10 |
30 | 46.8k | #define OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA 0x11 |
31 | 67.5k | #define OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI 0x12 |
32 | 53.3k | #define OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI 0x13 |
33 | 18.8k | #define OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED 0x14 |
34 | 10.2k | #define OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED 0x15 |
35 | 118k | #define OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI 0x16 |
36 | 43.6k | #define OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI 0x17 |
37 | 27.0k | #define OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID 0x18 |
38 | 1.27M | #define OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID 0x19 |
39 | 372k | #define OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE 0x1A |
40 | 218M | #define OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE 0x1B |
41 | 417k | #define OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT 0x1C |
42 | 365k | #define OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP 0x1D |
43 | 744k | #define OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE 0x1E |
44 | | |
45 | 123k | #define OSSL_QUIC_FRAME_FLAG_STREAM_FIN 0x01 |
46 | 127k | #define OSSL_QUIC_FRAME_FLAG_STREAM_LEN 0x02 |
47 | 135k | #define OSSL_QUIC_FRAME_FLAG_STREAM_OFF 0x04 |
48 | 67.6k | #define OSSL_QUIC_FRAME_FLAG_STREAM_MASK ((uint64_t)0x07) |
49 | | |
50 | | /* Low 3 bits of the type contain flags */ |
51 | 172k | #define OSSL_QUIC_FRAME_TYPE_STREAM 0x08 /* base ID */ |
52 | | #define OSSL_QUIC_FRAME_TYPE_STREAM_FIN \ |
53 | 5.73k | (OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_FIN) |
54 | | #define OSSL_QUIC_FRAME_TYPE_STREAM_LEN \ |
55 | 6.66k | (OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_LEN) |
56 | | #define OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN \ |
57 | 8.97k | (OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_LEN | OSSL_QUIC_FRAME_FLAG_STREAM_FIN) |
58 | | #define OSSL_QUIC_FRAME_TYPE_STREAM_OFF \ |
59 | 9.24k | (OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_OFF) |
60 | | #define OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN \ |
61 | 14.0k | (OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_OFF | OSSL_QUIC_FRAME_FLAG_STREAM_FIN) |
62 | | #define OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN \ |
63 | 14.4k | (OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_OFF | OSSL_QUIC_FRAME_FLAG_STREAM_LEN) |
64 | | #define OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN \ |
65 | 27.4k | (OSSL_QUIC_FRAME_TYPE_STREAM | OSSL_QUIC_FRAME_FLAG_STREAM_OFF | OSSL_QUIC_FRAME_FLAG_STREAM_LEN | OSSL_QUIC_FRAME_FLAG_STREAM_FIN) |
66 | | |
67 | | #define OSSL_QUIC_FRAME_TYPE_IS_STREAM(x) \ |
68 | 0 | (((x) & ~OSSL_QUIC_FRAME_FLAG_STREAM_MASK) == OSSL_QUIC_FRAME_TYPE_STREAM) |
69 | | #define OSSL_QUIC_FRAME_TYPE_IS_ACK(x) \ |
70 | | (((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN) |
71 | | #define OSSL_QUIC_FRAME_TYPE_IS_MAX_STREAMS(x) \ |
72 | | (((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI) |
73 | | #define OSSL_QUIC_FRAME_TYPE_IS_STREAMS_BLOCKED(x) \ |
74 | | (((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI) |
75 | | #define OSSL_QUIC_FRAME_TYPE_IS_CONN_CLOSE(x) \ |
76 | | (((x) & ~(uint64_t)1) == OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT) |
77 | | |
78 | | const char *ossl_quic_frame_type_to_string(uint64_t frame_type); |
79 | | |
80 | | static ossl_unused ossl_inline int |
81 | | ossl_quic_frame_type_is_ack_eliciting(uint64_t frame_type) |
82 | 249k | { |
83 | 249k | switch (frame_type) { |
84 | 0 | case OSSL_QUIC_FRAME_TYPE_PADDING: |
85 | 0 | case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN: |
86 | 0 | case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN: |
87 | 0 | case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT: |
88 | 0 | case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP: |
89 | 0 | return 0; |
90 | 249k | default: |
91 | 249k | return 1; |
92 | 249k | } |
93 | 249k | } Unexecuted instantiation: quic-rcidm.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: ssl_init.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_rcidm.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: s3_lib.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: s3_msg.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: ssl_cert.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: ssl_ciph.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: ssl_lib.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: ssl_mcnf.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: ssl_sess.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: t1_lib.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: tls13_enc.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: tls_depr.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: tls_srp.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_impl.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_method.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_port.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_record_rx.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_record_shared.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_record_tx.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_record_util.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_rstream.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_srtm.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_sstream.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_stream_map.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_thread_assist.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: rec_layer_s3.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: dtls_meth.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: tls1_meth.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: tls_common.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: tls_multib.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: tlsany_meth.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: extensions.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: extensions_clnt.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: extensions_cust.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: extensions_srvr.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: statem.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: statem_clnt.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: statem_dtls.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: statem_lib.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: statem_srvr.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: d1_lib.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: d1_srtp.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: methods.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: pqueue.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: s3_enc.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: ssl_asn1.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: ssl_conf.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: ssl_rsa.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: t1_enc.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: qlog_event_helpers.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_channel.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_engine.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_lcidm.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_rx_depack.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_tls.c:ossl_quic_frame_type_is_ack_eliciting quic_txp.c:ossl_quic_frame_type_is_ack_eliciting Line | Count | Source | 82 | 249k | { | 83 | 249k | switch (frame_type) { | 84 | 0 | case OSSL_QUIC_FRAME_TYPE_PADDING: | 85 | 0 | case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN: | 86 | 0 | case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN: | 87 | 0 | case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT: | 88 | 0 | case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP: | 89 | 0 | return 0; | 90 | 249k | default: | 91 | 249k | return 1; | 92 | 249k | } | 93 | 249k | } |
Unexecuted instantiation: quic_txpim.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_wire.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: rec_layer_d1.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: ssl3_meth.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: tls13_meth.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: d1_msg.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_ackm.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic_fifd.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic-client.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: ssl_txt.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic-srtm.c:ossl_quic_frame_type_is_ack_eliciting Unexecuted instantiation: quic-lcidm.c:ossl_quic_frame_type_is_ack_eliciting |
94 | | |
95 | | /* QUIC Transport Parameter Types */ |
96 | 8.26k | #define QUIC_TPARAM_ORIG_DCID 0x00 |
97 | 29.0k | #define QUIC_TPARAM_MAX_IDLE_TIMEOUT 0x01 |
98 | 19 | #define QUIC_TPARAM_STATELESS_RESET_TOKEN 0x02 |
99 | 28.2k | #define QUIC_TPARAM_MAX_UDP_PAYLOAD_SIZE 0x03 |
100 | 28.0k | #define QUIC_TPARAM_INITIAL_MAX_DATA 0x04 |
101 | 28.5k | #define QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL 0x05 |
102 | 28.6k | #define QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE 0x06 |
103 | 28.7k | #define QUIC_TPARAM_INITIAL_MAX_STREAM_DATA_UNI 0x07 |
104 | 28.6k | #define QUIC_TPARAM_INITIAL_MAX_STREAMS_BIDI 0x08 |
105 | 28.5k | #define QUIC_TPARAM_INITIAL_MAX_STREAMS_UNI 0x09 |
106 | 55 | #define QUIC_TPARAM_ACK_DELAY_EXP 0x0A |
107 | 228 | #define QUIC_TPARAM_MAX_ACK_DELAY 0x0B |
108 | 29.1k | #define QUIC_TPARAM_DISABLE_ACTIVE_MIGRATION 0x0C |
109 | 76 | #define QUIC_TPARAM_PREFERRED_ADDR 0x0D |
110 | 27.9k | #define QUIC_TPARAM_ACTIVE_CONN_ID_LIMIT 0x0E |
111 | 28.9k | #define QUIC_TPARAM_INITIAL_SCID 0x0F |
112 | 18 | #define QUIC_TPARAM_RETRY_SCID 0x10 |
113 | | |
114 | | /* |
115 | | * QUIC Frame Logical Representations |
116 | | * ================================== |
117 | | */ |
118 | | |
119 | | /* QUIC Frame: ACK */ |
120 | | typedef struct ossl_quic_ack_range_st { |
121 | | /* |
122 | | * Represents an inclusive range of packet numbers [start, end]. |
123 | | * start must be <= end. |
124 | | */ |
125 | | QUIC_PN start, end; |
126 | | } OSSL_QUIC_ACK_RANGE; |
127 | | |
128 | | typedef struct ossl_quic_frame_ack_st { |
129 | | /* |
130 | | * A sequence of packet number ranges [[start, end]...]. |
131 | | * |
132 | | * The ranges must be sorted in descending order, for example: |
133 | | * [ 95, 100] |
134 | | * [ 90, 92] |
135 | | * etc. |
136 | | * |
137 | | * As such, ack_ranges[0].end is always the highest packet number |
138 | | * being acknowledged and ack_ranges[num_ack_ranges-1].start is |
139 | | * always the lowest packet number being acknowledged. |
140 | | * |
141 | | * num_ack_ranges must be greater than zero, as an ACK frame must |
142 | | * acknowledge at least one packet number. |
143 | | */ |
144 | | OSSL_QUIC_ACK_RANGE *ack_ranges; |
145 | | size_t num_ack_ranges; |
146 | | |
147 | | OSSL_TIME delay_time; |
148 | | uint64_t ect0, ect1, ecnce; |
149 | | unsigned int ecn_present : 1; |
150 | | } OSSL_QUIC_FRAME_ACK; |
151 | | |
152 | | /* Returns 1 if the given frame contains the given PN. */ |
153 | | int ossl_quic_frame_ack_contains_pn(const OSSL_QUIC_FRAME_ACK *ack, QUIC_PN pn); |
154 | | |
155 | | /* QUIC Frame: STREAM */ |
156 | | typedef struct ossl_quic_frame_stream_st { |
157 | | uint64_t stream_id; /* Stream ID */ |
158 | | uint64_t offset; /* Logical offset in stream */ |
159 | | uint64_t len; /* Length of data in bytes */ |
160 | | const unsigned char *data; |
161 | | |
162 | | /* |
163 | | * On encode, this determines whether the len field should be encoded or |
164 | | * not. If zero, the len field is not encoded and it is assumed the frame |
165 | | * runs to the end of the packet. |
166 | | * |
167 | | * On decode, this determines whether the frame had an explicitly encoded |
168 | | * length. If not set, the frame runs to the end of the packet and len has |
169 | | * been set accordingly. |
170 | | */ |
171 | | unsigned int has_explicit_len : 1; |
172 | | |
173 | | /* 1 if this is the end of the stream */ |
174 | | unsigned int is_fin : 1; |
175 | | } OSSL_QUIC_FRAME_STREAM; |
176 | | |
177 | | /* QUIC Frame: CRYPTO */ |
178 | | typedef struct ossl_quic_frame_crypto_st { |
179 | | uint64_t offset; /* Logical offset in stream */ |
180 | | uint64_t len; /* Length of the data in bytes */ |
181 | | const unsigned char *data; |
182 | | } OSSL_QUIC_FRAME_CRYPTO; |
183 | | |
184 | | /* QUIC Frame: RESET_STREAM */ |
185 | | typedef struct ossl_quic_frame_reset_stream_st { |
186 | | uint64_t stream_id; |
187 | | uint64_t app_error_code; |
188 | | uint64_t final_size; |
189 | | } OSSL_QUIC_FRAME_RESET_STREAM; |
190 | | |
191 | | /* QUIC Frame: STOP_SENDING */ |
192 | | typedef struct ossl_quic_frame_stop_sending_st { |
193 | | uint64_t stream_id; |
194 | | uint64_t app_error_code; |
195 | | } OSSL_QUIC_FRAME_STOP_SENDING; |
196 | | |
197 | | /* QUIC Frame: NEW_CONNECTION_ID */ |
198 | | typedef struct ossl_quic_frame_new_conn_id_st { |
199 | | uint64_t seq_num; |
200 | | uint64_t retire_prior_to; |
201 | | QUIC_CONN_ID conn_id; |
202 | | QUIC_STATELESS_RESET_TOKEN stateless_reset; |
203 | | } OSSL_QUIC_FRAME_NEW_CONN_ID; |
204 | | |
205 | | /* QUIC Frame: CONNECTION_CLOSE */ |
206 | | typedef struct ossl_quic_frame_conn_close_st { |
207 | | unsigned int is_app : 1; /* 0: transport error, 1: app error */ |
208 | | uint64_t error_code; /* 62-bit transport or app error code */ |
209 | | uint64_t frame_type; /* transport errors only */ |
210 | | char *reason; /* UTF-8 string, not necessarily zero-terminated */ |
211 | | size_t reason_len; /* Length of reason in bytes */ |
212 | | } OSSL_QUIC_FRAME_CONN_CLOSE; |
213 | | |
214 | | /* |
215 | | * QUIC Wire Format Encoding |
216 | | * ========================= |
217 | | * |
218 | | * These functions return 1 on success and 0 on failure. |
219 | | */ |
220 | | |
221 | | /* |
222 | | * Encodes zero or more QUIC PADDING frames to the packet writer. Each PADDING |
223 | | * frame consumes one byte; num_bytes specifies the number of bytes of padding |
224 | | * to write. |
225 | | */ |
226 | | int ossl_quic_wire_encode_padding(WPACKET *pkt, size_t num_bytes); |
227 | | |
228 | | /* |
229 | | * Encodes a QUIC PING frame to the packet writer. This frame type takes |
230 | | * no arguments. |
231 | | */ |
232 | | int ossl_quic_wire_encode_frame_ping(WPACKET *pkt); |
233 | | |
234 | | /* |
235 | | * Encodes a QUIC ACK frame to the packet writer, given a logical representation |
236 | | * of the ACK frame. |
237 | | * |
238 | | * The ACK ranges passed must be sorted in descending order. |
239 | | * |
240 | | * The logical representation stores a list of packet number ranges. The wire |
241 | | * encoding is slightly different and stores the first range in the list |
242 | | * in a different manner. |
243 | | * |
244 | | * The ack_delay_exponent argument specifies the index of a power of two by |
245 | | * which the ack->ack_delay field is be divided. This exponent value must match |
246 | | * the value used when decoding. |
247 | | */ |
248 | | int ossl_quic_wire_encode_frame_ack(WPACKET *pkt, |
249 | | uint32_t ack_delay_exponent, |
250 | | const OSSL_QUIC_FRAME_ACK *ack); |
251 | | |
252 | | /* |
253 | | * Encodes a QUIC RESET_STREAM frame to the packet writer, given a logical |
254 | | * representation of the RESET_STREAM frame. |
255 | | */ |
256 | | int ossl_quic_wire_encode_frame_reset_stream(WPACKET *pkt, |
257 | | const OSSL_QUIC_FRAME_RESET_STREAM *f); |
258 | | |
259 | | /* |
260 | | * Encodes a QUIC STOP_SENDING frame to the packet writer, given a logical |
261 | | * representation of the STOP_SENDING frame. |
262 | | */ |
263 | | int ossl_quic_wire_encode_frame_stop_sending(WPACKET *pkt, |
264 | | const OSSL_QUIC_FRAME_STOP_SENDING *f); |
265 | | |
266 | | /* |
267 | | * Encodes a QUIC CRYPTO frame header to the packet writer. |
268 | | * |
269 | | * To create a well-formed frame, the data written using this function must be |
270 | | * immediately followed by f->len bytes of data. |
271 | | */ |
272 | | int ossl_quic_wire_encode_frame_crypto_hdr(WPACKET *hdr, |
273 | | const OSSL_QUIC_FRAME_CRYPTO *f); |
274 | | |
275 | | /* |
276 | | * Returns the number of bytes which will be required to encode the given |
277 | | * CRYPTO frame header. Does not include the payload bytes in the count. |
278 | | * Returns 0 if input is invalid. |
279 | | */ |
280 | | size_t ossl_quic_wire_get_encoded_frame_len_crypto_hdr(const OSSL_QUIC_FRAME_CRYPTO *f); |
281 | | |
282 | | /* |
283 | | * Encodes a QUIC CRYPTO frame to the packet writer. |
284 | | * |
285 | | * This function returns a pointer to a buffer of f->len bytes which the caller |
286 | | * should fill however it wishes. If f->data is non-NULL, it is automatically |
287 | | * copied to the target buffer, otherwise the caller must fill the returned |
288 | | * buffer. Returns NULL on failure. |
289 | | */ |
290 | | void *ossl_quic_wire_encode_frame_crypto(WPACKET *pkt, |
291 | | const OSSL_QUIC_FRAME_CRYPTO *f); |
292 | | |
293 | | /* |
294 | | * Encodes a QUIC NEW_TOKEN frame to the packet writer. |
295 | | */ |
296 | | int ossl_quic_wire_encode_frame_new_token(WPACKET *pkt, |
297 | | const unsigned char *token, |
298 | | size_t token_len); |
299 | | |
300 | | /* |
301 | | * Encodes a QUIC STREAM frame's header to the packet writer. The f->stream_id, |
302 | | * f->offset and f->len fields are the values for the respective Stream ID, |
303 | | * Offset and Length fields. |
304 | | * |
305 | | * If f->is_fin is non-zero, the frame is marked as the final frame in the |
306 | | * stream. |
307 | | * |
308 | | * If f->has_explicit_len is zerro, the frame is assumed to be the final frame |
309 | | * in the packet, which the caller is responsible for ensuring; the Length |
310 | | * field is then omitted. |
311 | | * |
312 | | * To create a well-formed frame, the data written using this function must be |
313 | | * immediately followed by f->len bytes of stream data. |
314 | | */ |
315 | | int ossl_quic_wire_encode_frame_stream_hdr(WPACKET *pkt, |
316 | | const OSSL_QUIC_FRAME_STREAM *f); |
317 | | |
318 | | /* |
319 | | * Returns the number of bytes which will be required to encode the given |
320 | | * STREAM frame header. Does not include the payload bytes in the count. |
321 | | * Returns 0 if input is invalid. |
322 | | */ |
323 | | size_t ossl_quic_wire_get_encoded_frame_len_stream_hdr(const OSSL_QUIC_FRAME_STREAM *f); |
324 | | |
325 | | /* |
326 | | * Functions similarly to ossl_quic_wire_encode_frame_stream_hdr, but it also |
327 | | * allocates space for f->len bytes of data after the header, creating a |
328 | | * well-formed QUIC STREAM frame in one call. |
329 | | * |
330 | | * A pointer to the bytes allocated for the framme payload is returned, |
331 | | * which the caller can fill however it wishes. If f->data is non-NULL, |
332 | | * it is automatically copied to the target buffer, otherwise the caller |
333 | | * must fill the returned buffer. Returns NULL on failure. |
334 | | */ |
335 | | void *ossl_quic_wire_encode_frame_stream(WPACKET *pkt, |
336 | | const OSSL_QUIC_FRAME_STREAM *f); |
337 | | |
338 | | /* |
339 | | * Encodes a QUIC MAX_DATA frame to the packet writer. |
340 | | */ |
341 | | int ossl_quic_wire_encode_frame_max_data(WPACKET *pkt, |
342 | | uint64_t max_data); |
343 | | |
344 | | /* |
345 | | * Encodes a QUIC MAX_STREAM_DATA frame to the packet writer. |
346 | | */ |
347 | | int ossl_quic_wire_encode_frame_max_stream_data(WPACKET *pkt, |
348 | | uint64_t stream_id, |
349 | | uint64_t max_data); |
350 | | |
351 | | /* |
352 | | * Encodes a QUIC MAX_STREAMS frame to the packet writer. |
353 | | * |
354 | | * If is_uni is 0, the count specifies the maximum number of |
355 | | * bidirectional streams; else it specifies the maximum number of unidirectional |
356 | | * streams. |
357 | | */ |
358 | | int ossl_quic_wire_encode_frame_max_streams(WPACKET *pkt, |
359 | | char is_uni, |
360 | | uint64_t max_streams); |
361 | | |
362 | | /* |
363 | | * Encodes a QUIC DATA_BLOCKED frame to the packet writer. |
364 | | */ |
365 | | int ossl_quic_wire_encode_frame_data_blocked(WPACKET *pkt, |
366 | | uint64_t max_data); |
367 | | |
368 | | /* |
369 | | * Encodes a QUIC STREAM_DATA_BLOCKED frame to the packet writer. |
370 | | */ |
371 | | int ossl_quic_wire_encode_frame_stream_data_blocked(WPACKET *pkt, |
372 | | uint64_t stream_id, |
373 | | uint64_t max_stream_data); |
374 | | /* |
375 | | * Encodes a QUIC STREAMS_BLOCKED frame to the packet writer. |
376 | | * |
377 | | * If is_uni is 0, the count specifies the maximum number of |
378 | | * bidirectional streams; else it specifies the maximum number of unidirectional |
379 | | * streams. |
380 | | */ |
381 | | int ossl_quic_wire_encode_frame_streams_blocked(WPACKET *pkt, |
382 | | char is_uni, |
383 | | uint64_t max_streams); |
384 | | |
385 | | /* |
386 | | * Encodes a QUIC NEW_CONNECTION_ID frame to the packet writer, given a logical |
387 | | * representation of the NEW_CONNECTION_ID frame. |
388 | | * |
389 | | * The buffer pointed to by the conn_id field must be valid for the duration of |
390 | | * the call. |
391 | | */ |
392 | | int ossl_quic_wire_encode_frame_new_conn_id(WPACKET *pkt, |
393 | | const OSSL_QUIC_FRAME_NEW_CONN_ID *f); |
394 | | |
395 | | /* |
396 | | * Encodes a QUIC RETIRE_CONNECTION_ID frame to the packet writer. |
397 | | */ |
398 | | int ossl_quic_wire_encode_frame_retire_conn_id(WPACKET *pkt, |
399 | | uint64_t seq_num); |
400 | | |
401 | | /* |
402 | | * Encodes a QUIC PATH_CHALLENGE frame to the packet writer. |
403 | | */ |
404 | | int ossl_quic_wire_encode_frame_path_challenge(WPACKET *pkt, |
405 | | uint64_t data); |
406 | | |
407 | | /* |
408 | | * Encodes a QUIC PATH_RESPONSE frame to the packet writer. |
409 | | */ |
410 | | int ossl_quic_wire_encode_frame_path_response(WPACKET *pkt, |
411 | | uint64_t data); |
412 | | |
413 | | /* |
414 | | * Encodes a QUIC CONNECTION_CLOSE frame to the packet writer, given a logical |
415 | | * representation of the CONNECTION_CLOSE frame. |
416 | | * |
417 | | * The reason field may be NULL, in which case no reason is encoded. If the |
418 | | * reason field is non-NULL, it must point to a valid UTF-8 string and |
419 | | * reason_len must be set to the length of the reason string in bytes. The |
420 | | * reason string need not be zero terminated. |
421 | | */ |
422 | | int ossl_quic_wire_encode_frame_conn_close(WPACKET *pkt, |
423 | | const OSSL_QUIC_FRAME_CONN_CLOSE *f); |
424 | | |
425 | | /* |
426 | | * Encodes a QUIC HANDSHAKE_DONE frame to the packet writer. This frame type |
427 | | * takes no arguiments. |
428 | | */ |
429 | | int ossl_quic_wire_encode_frame_handshake_done(WPACKET *pkt); |
430 | | |
431 | | /* |
432 | | * Encodes a QUIC transport parameter TLV with the given ID into the WPACKET. |
433 | | * The payload is an arbitrary buffer. |
434 | | * |
435 | | * If value is non-NULL, the value is copied into the packet. |
436 | | * If it is NULL, value_len bytes are allocated for the payload and the caller |
437 | | * should fill the buffer using the returned pointer. |
438 | | * |
439 | | * Returns a pointer to the start of the payload on success, or NULL on failure. |
440 | | */ |
441 | | unsigned char *ossl_quic_wire_encode_transport_param_bytes(WPACKET *pkt, |
442 | | uint64_t id, |
443 | | const unsigned char *value, |
444 | | size_t value_len); |
445 | | |
446 | | /* |
447 | | * Encodes a QUIC transport parameter TLV with the given ID into the WPACKET. |
448 | | * The payload is a QUIC variable-length integer with the given value. |
449 | | */ |
450 | | int ossl_quic_wire_encode_transport_param_int(WPACKET *pkt, |
451 | | uint64_t id, |
452 | | uint64_t value); |
453 | | |
454 | | /* |
455 | | * Encodes a QUIC transport parameter TLV with a given ID into the WPACKET. |
456 | | * The payload is a QUIC connection ID. |
457 | | */ |
458 | | int ossl_quic_wire_encode_transport_param_cid(WPACKET *wpkt, |
459 | | uint64_t id, |
460 | | const QUIC_CONN_ID *cid); |
461 | | |
462 | | /* |
463 | | * QUIC Wire Format Decoding |
464 | | * ========================= |
465 | | * |
466 | | * These functions return 1 on success or 0 for failure. Typical reasons |
467 | | * why these functions may fail include: |
468 | | * |
469 | | * - A frame decode function is called but the frame in the PACKET's buffer |
470 | | * is not of the correct type. |
471 | | * |
472 | | * - A variable-length field in the encoded frame appears to exceed the bounds |
473 | | * of the PACKET's buffer. |
474 | | * |
475 | | * These functions should be called with the PACKET pointing to the start of the |
476 | | * frame (including the initial type field), and consume an entire frame |
477 | | * including its type field. The expectation is that the caller will have |
478 | | * already discerned the frame type using ossl_quic_wire_peek_frame_header(). |
479 | | */ |
480 | | |
481 | | /* |
482 | | * Decodes the type field header of a QUIC frame (without advancing the current |
483 | | * position). This can be used to determine the frame type and determine which |
484 | | * frame decoding function to call. |
485 | | */ |
486 | | int ossl_quic_wire_peek_frame_header(PACKET *pkt, uint64_t *type, |
487 | | int *was_minimal); |
488 | | |
489 | | /* |
490 | | * Like ossl_quic_wire_peek_frame_header, but advances the current position |
491 | | * so that the type field is consumed. For advanced use only. |
492 | | */ |
493 | | int ossl_quic_wire_skip_frame_header(PACKET *pkt, uint64_t *type); |
494 | | |
495 | | /* |
496 | | * Determines how many ranges are needed to decode a QUIC ACK frame. |
497 | | * |
498 | | * The number of ranges which must be allocated before the call to |
499 | | * ossl_quic_wire_decode_frame_ack is written to *total_ranges. |
500 | | * |
501 | | * The PACKET is not advanced. |
502 | | */ |
503 | | int ossl_quic_wire_peek_frame_ack_num_ranges(const PACKET *pkt, |
504 | | uint64_t *total_ranges); |
505 | | |
506 | | /* |
507 | | * Decodes a QUIC ACK frame. The ack_ranges field of the passed structure should |
508 | | * point to a preallocated array of ACK ranges and the num_ack_ranges field |
509 | | * should specify the length of allocation. |
510 | | * |
511 | | * *total_ranges is written with the number of ranges in the decoded frame, |
512 | | * which may be greater than the number of ranges which were decoded (i.e. if |
513 | | * num_ack_ranges was too small to decode all ranges). |
514 | | * |
515 | | * On success, this function modifies the num_ack_ranges field to indicate the |
516 | | * number of ranges in the decoded frame. This is the number of entries in the |
517 | | * ACK ranges array written by this function; any additional entries are not |
518 | | * modified. |
519 | | * |
520 | | * If the number of ACK ranges in the decoded frame exceeds that in |
521 | | * num_ack_ranges, as many ACK ranges as possible are decoded into the range |
522 | | * array. The caller can use the value written to *total_ranges to detect this |
523 | | * condition, as *total_ranges will exceed num_ack_ranges. |
524 | | * |
525 | | * If ack is NULL, the frame is still decoded, but only *total_ranges is |
526 | | * written. This can be used to determine the number of ranges which must be |
527 | | * allocated. |
528 | | * |
529 | | * The ack_delay_exponent argument specifies the index of a power of two used to |
530 | | * decode the ack_delay field. This must match the ack_delay_exponent value used |
531 | | * to encode the frame. |
532 | | */ |
533 | | int ossl_quic_wire_decode_frame_ack(PACKET *pkt, |
534 | | uint32_t ack_delay_exponent, |
535 | | OSSL_QUIC_FRAME_ACK *ack, |
536 | | uint64_t *total_ranges); |
537 | | |
538 | | /* |
539 | | * Decodes a QUIC RESET_STREAM frame. |
540 | | */ |
541 | | int ossl_quic_wire_decode_frame_reset_stream(PACKET *pkt, |
542 | | OSSL_QUIC_FRAME_RESET_STREAM *f); |
543 | | |
544 | | /* |
545 | | * Decodes a QUIC STOP_SENDING frame. |
546 | | */ |
547 | | int ossl_quic_wire_decode_frame_stop_sending(PACKET *pkt, |
548 | | OSSL_QUIC_FRAME_STOP_SENDING *f); |
549 | | |
550 | | /* |
551 | | * Decodes a QUIC CRYPTO frame. |
552 | | * |
553 | | * f->data is set to point inside the packet buffer inside the PACKET, therefore |
554 | | * it is safe to access for as long as the packet buffer exists. If nodata is |
555 | | * set to 1 then reading the PACKET stops after the frame header and f->data is |
556 | | * set to NULL. |
557 | | */ |
558 | | int ossl_quic_wire_decode_frame_crypto(PACKET *pkt, int nodata, |
559 | | OSSL_QUIC_FRAME_CRYPTO *f); |
560 | | |
561 | | /* |
562 | | * Decodes a QUIC NEW_TOKEN frame. *token is written with a pointer to the token |
563 | | * bytes and *token_len is written with the length of the token in bytes. |
564 | | */ |
565 | | int ossl_quic_wire_decode_frame_new_token(PACKET *pkt, |
566 | | const unsigned char **token, |
567 | | size_t *token_len); |
568 | | |
569 | | /* |
570 | | * Decodes a QUIC STREAM frame. |
571 | | * |
572 | | * If nodata is set to 1 then reading the PACKET stops after the frame header |
573 | | * and f->data is set to NULL. In this case f->len will also be 0 in the event |
574 | | * that "has_explicit_len" is 0. |
575 | | * |
576 | | * If the frame did not contain an offset field, f->offset is set to 0, as the |
577 | | * absence of an offset field is equivalent to an offset of 0. |
578 | | * |
579 | | * If the frame contained a length field, f->has_explicit_len is set to 1 and |
580 | | * the length of the data is placed in f->len. This function ensures that the |
581 | | * length does not exceed the packet buffer, thus it is safe to access f->data. |
582 | | * |
583 | | * If the frame did not contain a length field, this means that the frame runs |
584 | | * until the end of the packet. This function sets f->has_explicit_len to zero, |
585 | | * and f->len to the amount of data remaining in the input buffer. Therefore, |
586 | | * this function should be used with a PACKET representing a single packet (and |
587 | | * not e.g. multiple packets). |
588 | | * |
589 | | * Note also that this means f->len is always valid after this function returns |
590 | | * successfully, regardless of the value of f->has_explicit_len. |
591 | | * |
592 | | * f->data points inside the packet buffer inside the PACKET, therefore it is |
593 | | * safe to access for as long as the packet buffer exists. |
594 | | * |
595 | | * f->is_fin is set according to whether the frame was marked as ending the |
596 | | * stream. |
597 | | */ |
598 | | int ossl_quic_wire_decode_frame_stream(PACKET *pkt, int nodata, |
599 | | OSSL_QUIC_FRAME_STREAM *f); |
600 | | |
601 | | /* |
602 | | * Decodes a QUIC MAX_DATA frame. The Maximum Data field is written to |
603 | | * *max_data. |
604 | | */ |
605 | | int ossl_quic_wire_decode_frame_max_data(PACKET *pkt, |
606 | | uint64_t *max_data); |
607 | | |
608 | | /* |
609 | | * Decodes a QUIC MAX_STREAM_DATA frame. The Stream ID is written to *stream_id |
610 | | * and Maximum Stream Data field is written to *max_stream_data. |
611 | | */ |
612 | | int ossl_quic_wire_decode_frame_max_stream_data(PACKET *pkt, |
613 | | uint64_t *stream_id, |
614 | | uint64_t *max_stream_data); |
615 | | /* |
616 | | * Decodes a QUIC MAX_STREAMS frame. The Maximum Streams field is written to |
617 | | * *max_streams. |
618 | | * |
619 | | * Whether the limit concerns bidirectional streams or unidirectional streams is |
620 | | * denoted by the frame type; the caller should examine the frame type to |
621 | | * determine this. |
622 | | */ |
623 | | int ossl_quic_wire_decode_frame_max_streams(PACKET *pkt, |
624 | | uint64_t *max_streams); |
625 | | |
626 | | /* |
627 | | * Decodes a QUIC DATA_BLOCKED frame. The Maximum Data field is written to |
628 | | * *max_data. |
629 | | */ |
630 | | int ossl_quic_wire_decode_frame_data_blocked(PACKET *pkt, |
631 | | uint64_t *max_data); |
632 | | |
633 | | /* |
634 | | * Decodes a QUIC STREAM_DATA_BLOCKED frame. The Stream ID and Maximum Stream |
635 | | * Data fields are written to *stream_id and *max_stream_data respectively. |
636 | | */ |
637 | | int ossl_quic_wire_decode_frame_stream_data_blocked(PACKET *pkt, |
638 | | uint64_t *stream_id, |
639 | | uint64_t *max_stream_data); |
640 | | |
641 | | /* |
642 | | * Decodes a QUIC STREAMS_BLOCKED frame. The Maximum Streams field is written to |
643 | | * *max_streams. |
644 | | * |
645 | | * Whether the limit concerns bidirectional streams or unidirectional streams is |
646 | | * denoted by the frame type; the caller should examine the frame type to |
647 | | * determine this. |
648 | | */ |
649 | | int ossl_quic_wire_decode_frame_streams_blocked(PACKET *pkt, |
650 | | uint64_t *max_streams); |
651 | | |
652 | | /* |
653 | | * Decodes a QUIC NEW_CONNECTION_ID frame. The logical representation of the |
654 | | * frame is written to *f. |
655 | | * |
656 | | * The conn_id field is set to point to the connection ID string inside the |
657 | | * packet buffer; it is therefore valid for as long as the PACKET's buffer is |
658 | | * valid. The conn_id_len field is set to the length of the connection ID string |
659 | | * in bytes. |
660 | | */ |
661 | | int ossl_quic_wire_decode_frame_new_conn_id(PACKET *pkt, |
662 | | OSSL_QUIC_FRAME_NEW_CONN_ID *f); |
663 | | |
664 | | /* |
665 | | * Decodes a QUIC RETIRE_CONNECTION_ID frame. The Sequence Number field |
666 | | * is written to *seq_num. |
667 | | */ |
668 | | int ossl_quic_wire_decode_frame_retire_conn_id(PACKET *pkt, |
669 | | uint64_t *seq_num); |
670 | | |
671 | | /* |
672 | | * Decodes a QUIC PATH_CHALLENGE frame. The Data field is written to *data. |
673 | | */ |
674 | | int ossl_quic_wire_decode_frame_path_challenge(PACKET *pkt, |
675 | | uint64_t *data); |
676 | | |
677 | | /* |
678 | | * Decodes a QUIC PATH_CHALLENGE frame. The Data field is written to *data. |
679 | | */ |
680 | | int ossl_quic_wire_decode_frame_path_response(PACKET *pkt, |
681 | | uint64_t *data); |
682 | | |
683 | | /* |
684 | | * Decodes a QUIC CONNECTION_CLOSE frame. The logical representation |
685 | | * of the frame is written to *f. |
686 | | * |
687 | | * The reason field is set to point to the UTF-8 reason string inside |
688 | | * the packet buffer; it is therefore valid for as long as the PACKET's |
689 | | * buffer is valid. The reason_len field is set to the length of the |
690 | | * reason string in bytes. |
691 | | * |
692 | | * IMPORTANT: The reason string is not zero-terminated. |
693 | | * |
694 | | * Returns 1 on success or 0 on failure. |
695 | | */ |
696 | | int ossl_quic_wire_decode_frame_conn_close(PACKET *pkt, |
697 | | OSSL_QUIC_FRAME_CONN_CLOSE *f); |
698 | | |
699 | | /* |
700 | | * Decodes one or more PADDING frames. PADDING frames have no arguments. |
701 | | * |
702 | | * Returns the number of PADDING frames decoded or 0 on error. |
703 | | */ |
704 | | size_t ossl_quic_wire_decode_padding(PACKET *pkt); |
705 | | |
706 | | /* |
707 | | * Decodes a PING frame. The frame has no arguments. |
708 | | */ |
709 | | int ossl_quic_wire_decode_frame_ping(PACKET *pkt); |
710 | | |
711 | | /* |
712 | | * Decodes a HANDSHAKE_DONE frame. The frame has no arguments. |
713 | | */ |
714 | | int ossl_quic_wire_decode_frame_handshake_done(PACKET *pkt); |
715 | | |
716 | | /* |
717 | | * Peeks at the ID of the next QUIC transport parameter TLV in the stream. |
718 | | * The ID is written to *id. |
719 | | */ |
720 | | int ossl_quic_wire_peek_transport_param(PACKET *pkt, uint64_t *id); |
721 | | |
722 | | /* |
723 | | * Decodes a QUIC transport parameter TLV. A pointer to the value buffer is |
724 | | * returned on success. This points inside the PACKET's buffer and is therefore |
725 | | * valid as long as the PACKET's buffer is valid. |
726 | | * |
727 | | * The transport parameter ID is written to *id (if non-NULL) and the length of |
728 | | * the payload in bytes is written to *len. |
729 | | * |
730 | | * Returns NULL on failure. |
731 | | */ |
732 | | const unsigned char *ossl_quic_wire_decode_transport_param_bytes(PACKET *pkt, |
733 | | uint64_t *id, |
734 | | size_t *len); |
735 | | |
736 | | /* |
737 | | * Decodes a QUIC transport parameter TLV containing a variable-length integer. |
738 | | * |
739 | | * The transport parameter ID is written to *id (if non-NULL) and the value is |
740 | | * written to *value. |
741 | | */ |
742 | | int ossl_quic_wire_decode_transport_param_int(PACKET *pkt, |
743 | | uint64_t *id, |
744 | | uint64_t *value); |
745 | | |
746 | | /* |
747 | | * Decodes a QUIC transport parameter TLV containing a connection ID. |
748 | | * |
749 | | * The transport parameter ID is written to *id (if non-NULL) and the value is |
750 | | * written to *value. |
751 | | */ |
752 | | int ossl_quic_wire_decode_transport_param_cid(PACKET *pkt, |
753 | | uint64_t *id, |
754 | | QUIC_CONN_ID *cid); |
755 | | |
756 | | /* |
757 | | * Decodes a QUIC transport parameter TLV containing a preferred_address. |
758 | | */ |
759 | | typedef struct quic_preferred_addr_st { |
760 | | uint16_t ipv4_port, ipv6_port; |
761 | | unsigned char ipv4[4], ipv6[16]; |
762 | | QUIC_STATELESS_RESET_TOKEN stateless_reset; |
763 | | QUIC_CONN_ID cid; |
764 | | } QUIC_PREFERRED_ADDR; |
765 | | |
766 | | int ossl_quic_wire_decode_transport_param_preferred_addr(PACKET *pkt, |
767 | | QUIC_PREFERRED_ADDR *p); |
768 | | |
769 | | #endif |
770 | | |
771 | | #endif |