1 | /*
|
---|
2 | * Copyright 2023-2024 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 | #include <openssl/bio.h>
|
---|
11 | #include "../ssl_local.h"
|
---|
12 | #include "internal/quic_wire_pkt.h"
|
---|
13 |
|
---|
14 | static const char *packet_type(int type)
|
---|
15 | {
|
---|
16 | switch (type) {
|
---|
17 | case QUIC_PKT_TYPE_INITIAL:
|
---|
18 | return "Initial";
|
---|
19 |
|
---|
20 | case QUIC_PKT_TYPE_0RTT:
|
---|
21 | return "0RTT";
|
---|
22 |
|
---|
23 | case QUIC_PKT_TYPE_HANDSHAKE:
|
---|
24 | return "Handshake";
|
---|
25 |
|
---|
26 | case QUIC_PKT_TYPE_RETRY:
|
---|
27 | return "Retry";
|
---|
28 |
|
---|
29 | case QUIC_PKT_TYPE_1RTT:
|
---|
30 | return "1RTT";
|
---|
31 |
|
---|
32 | case QUIC_PKT_TYPE_VERSION_NEG:
|
---|
33 | return "VersionNeg";
|
---|
34 |
|
---|
35 | default:
|
---|
36 | return "Unknown";
|
---|
37 | }
|
---|
38 | }
|
---|
39 |
|
---|
40 | /* Print a non-NUL terminated string to BIO */
|
---|
41 | static void put_str(BIO *bio, char *str, size_t slen)
|
---|
42 | {
|
---|
43 | size_t i;
|
---|
44 |
|
---|
45 | for (i = 0; i < slen; i++)
|
---|
46 | BIO_printf(bio, "%c", str[i]);
|
---|
47 | }
|
---|
48 |
|
---|
49 | static void put_data(BIO *bio, const uint8_t *data, size_t datalen)
|
---|
50 | {
|
---|
51 | size_t i;
|
---|
52 |
|
---|
53 | for (i = 0; i < datalen; i++)
|
---|
54 | BIO_printf(bio, "%02x", data[i]);
|
---|
55 | }
|
---|
56 |
|
---|
57 | static void put_conn_id(BIO *bio, QUIC_CONN_ID *id)
|
---|
58 | {
|
---|
59 | if (id->id_len == 0) {
|
---|
60 | BIO_puts(bio, "<zero length id>");
|
---|
61 | return;
|
---|
62 | }
|
---|
63 |
|
---|
64 | BIO_puts(bio, "0x");
|
---|
65 | put_data(bio, id->id, id->id_len);
|
---|
66 | }
|
---|
67 |
|
---|
68 | static void put_token(BIO *bio, const uint8_t *token, size_t token_len)
|
---|
69 | {
|
---|
70 | if (token_len == 0)
|
---|
71 | BIO_puts(bio, "<zero length token>");
|
---|
72 | else
|
---|
73 | put_data(bio, token, token_len);
|
---|
74 | }
|
---|
75 |
|
---|
76 | static int frame_ack(BIO *bio, PACKET *pkt)
|
---|
77 | {
|
---|
78 | OSSL_QUIC_FRAME_ACK ack;
|
---|
79 | OSSL_QUIC_ACK_RANGE *ack_ranges = NULL;
|
---|
80 | uint64_t total_ranges = 0;
|
---|
81 | uint64_t i;
|
---|
82 | int ret = 0;
|
---|
83 |
|
---|
84 | if (!ossl_quic_wire_peek_frame_ack_num_ranges(pkt, &total_ranges)
|
---|
85 | /* In case sizeof(uint64_t) > sizeof(size_t) */
|
---|
86 | || total_ranges > SIZE_MAX / sizeof(ack_ranges[0])
|
---|
87 | || (ack_ranges = OPENSSL_zalloc(sizeof(ack_ranges[0])
|
---|
88 | * (size_t)total_ranges)) == NULL)
|
---|
89 | return ret;
|
---|
90 |
|
---|
91 | ack.ack_ranges = ack_ranges;
|
---|
92 | ack.num_ack_ranges = (size_t)total_ranges;
|
---|
93 |
|
---|
94 | /* Ack delay exponent is 0, so we can get the raw delay time below */
|
---|
95 | if (!ossl_quic_wire_decode_frame_ack(pkt, 0, &ack, NULL))
|
---|
96 | goto end;
|
---|
97 |
|
---|
98 | BIO_printf(bio, " Largest acked: %llu\n",
|
---|
99 | (unsigned long long)ack.ack_ranges[0].end);
|
---|
100 | BIO_printf(bio, " Ack delay (raw) %llu\n",
|
---|
101 | (unsigned long long)ossl_time2ticks(ack.delay_time));
|
---|
102 | BIO_printf(bio, " Ack range count: %llu\n",
|
---|
103 | (unsigned long long)total_ranges - 1);
|
---|
104 | BIO_printf(bio, " First ack range: %llu\n",
|
---|
105 | (unsigned long long)(ack.ack_ranges[0].end
|
---|
106 | - ack.ack_ranges[0].start));
|
---|
107 | for (i = 1; i < total_ranges; i++) {
|
---|
108 | BIO_printf(bio, " Gap: %llu\n",
|
---|
109 | (unsigned long long)(ack.ack_ranges[i - 1].start
|
---|
110 | - ack.ack_ranges[i].end - 2));
|
---|
111 | BIO_printf(bio, " Ack range len: %llu\n",
|
---|
112 | (unsigned long long)(ack.ack_ranges[i].end
|
---|
113 | - ack.ack_ranges[i].start));
|
---|
114 | }
|
---|
115 |
|
---|
116 | ret = 1;
|
---|
117 | end:
|
---|
118 | OPENSSL_free(ack_ranges);
|
---|
119 | return ret;
|
---|
120 | }
|
---|
121 |
|
---|
122 | static int frame_reset_stream(BIO *bio, PACKET *pkt)
|
---|
123 | {
|
---|
124 | OSSL_QUIC_FRAME_RESET_STREAM frame_data;
|
---|
125 |
|
---|
126 | if (!ossl_quic_wire_decode_frame_reset_stream(pkt, &frame_data))
|
---|
127 | return 0;
|
---|
128 |
|
---|
129 | BIO_printf(bio, " Stream id: %llu\n",
|
---|
130 | (unsigned long long)frame_data.stream_id);
|
---|
131 | BIO_printf(bio, " App Protocol Error Code: %llu\n",
|
---|
132 | (unsigned long long)frame_data.app_error_code);
|
---|
133 | BIO_printf(bio, " Final size: %llu\n",
|
---|
134 | (unsigned long long)frame_data.final_size);
|
---|
135 |
|
---|
136 | return 1;
|
---|
137 | }
|
---|
138 |
|
---|
139 | static int frame_stop_sending(BIO *bio, PACKET *pkt)
|
---|
140 | {
|
---|
141 | OSSL_QUIC_FRAME_STOP_SENDING frame_data;
|
---|
142 |
|
---|
143 | if (!ossl_quic_wire_decode_frame_stop_sending(pkt, &frame_data))
|
---|
144 | return 0;
|
---|
145 |
|
---|
146 | BIO_printf(bio, " Stream id: %llu\n",
|
---|
147 | (unsigned long long)frame_data.stream_id);
|
---|
148 | BIO_printf(bio, " App Protocol Error Code: %llu\n",
|
---|
149 | (unsigned long long)frame_data.app_error_code);
|
---|
150 |
|
---|
151 | return 1;
|
---|
152 | }
|
---|
153 |
|
---|
154 | static int frame_crypto(BIO *bio, PACKET *pkt)
|
---|
155 | {
|
---|
156 | OSSL_QUIC_FRAME_CRYPTO frame_data;
|
---|
157 |
|
---|
158 | if (!ossl_quic_wire_decode_frame_crypto(pkt, 1, &frame_data))
|
---|
159 | return 0;
|
---|
160 |
|
---|
161 | BIO_printf(bio, " Offset: %llu\n", (unsigned long long)frame_data.offset);
|
---|
162 | BIO_printf(bio, " Len: %llu\n", (unsigned long long)frame_data.len);
|
---|
163 |
|
---|
164 | return 1;
|
---|
165 | }
|
---|
166 |
|
---|
167 | static int frame_new_token(BIO *bio, PACKET *pkt)
|
---|
168 | {
|
---|
169 | const uint8_t *token;
|
---|
170 | size_t token_len;
|
---|
171 |
|
---|
172 | if (!ossl_quic_wire_decode_frame_new_token(pkt, &token, &token_len))
|
---|
173 | return 0;
|
---|
174 |
|
---|
175 | BIO_puts(bio, " Token: ");
|
---|
176 | put_token(bio, token, token_len);
|
---|
177 | BIO_puts(bio, "\n");
|
---|
178 |
|
---|
179 | return 1;
|
---|
180 | }
|
---|
181 |
|
---|
182 | static int frame_stream(BIO *bio, PACKET *pkt, uint64_t frame_type)
|
---|
183 | {
|
---|
184 |
|
---|
185 | OSSL_QUIC_FRAME_STREAM frame_data;
|
---|
186 |
|
---|
187 | BIO_puts(bio, "Stream");
|
---|
188 | switch(frame_type) {
|
---|
189 | case OSSL_QUIC_FRAME_TYPE_STREAM:
|
---|
190 | BIO_puts(bio, "\n");
|
---|
191 | break;
|
---|
192 |
|
---|
193 | case OSSL_QUIC_FRAME_TYPE_STREAM_FIN:
|
---|
194 | BIO_puts(bio, " (Fin)\n");
|
---|
195 | break;
|
---|
196 |
|
---|
197 | case OSSL_QUIC_FRAME_TYPE_STREAM_LEN:
|
---|
198 | BIO_puts(bio, " (Len)\n");
|
---|
199 | break;
|
---|
200 |
|
---|
201 | case OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN:
|
---|
202 | BIO_puts(bio, " (Len, Fin)\n");
|
---|
203 | break;
|
---|
204 |
|
---|
205 | case OSSL_QUIC_FRAME_TYPE_STREAM_OFF:
|
---|
206 | BIO_puts(bio, " (Off)\n");
|
---|
207 | break;
|
---|
208 |
|
---|
209 | case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN:
|
---|
210 | BIO_puts(bio, " (Off, Fin)\n");
|
---|
211 | break;
|
---|
212 |
|
---|
213 | case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN:
|
---|
214 | BIO_puts(bio, " (Off, Len)\n");
|
---|
215 | break;
|
---|
216 |
|
---|
217 | case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN:
|
---|
218 | BIO_puts(bio, " (Off, Len, Fin)\n");
|
---|
219 | break;
|
---|
220 |
|
---|
221 | default:
|
---|
222 | return 0;
|
---|
223 | }
|
---|
224 |
|
---|
225 | if (!ossl_quic_wire_decode_frame_stream(pkt, 1, &frame_data))
|
---|
226 | return 0;
|
---|
227 |
|
---|
228 | BIO_printf(bio, " Stream id: %llu\n",
|
---|
229 | (unsigned long long)frame_data.stream_id);
|
---|
230 | BIO_printf(bio, " Offset: %llu\n",
|
---|
231 | (unsigned long long)frame_data.offset);
|
---|
232 | /*
|
---|
233 | * It would be nice to find a way of passing the implicit length through
|
---|
234 | * to the msg_callback. But this is not currently possible.
|
---|
235 | */
|
---|
236 | if (frame_data.has_explicit_len)
|
---|
237 | BIO_printf(bio, " Len: %llu\n", (unsigned long long)frame_data.len);
|
---|
238 | else
|
---|
239 | BIO_puts(bio, " Len: <implicit length>\n");
|
---|
240 |
|
---|
241 | return 1;
|
---|
242 | }
|
---|
243 |
|
---|
244 | static int frame_max_data(BIO *bio, PACKET *pkt)
|
---|
245 | {
|
---|
246 | uint64_t max_data = 0;
|
---|
247 |
|
---|
248 | if (!ossl_quic_wire_decode_frame_max_data(pkt, &max_data))
|
---|
249 | return 0;
|
---|
250 |
|
---|
251 | BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data);
|
---|
252 |
|
---|
253 | return 1;
|
---|
254 | }
|
---|
255 |
|
---|
256 | static int frame_max_stream_data(BIO *bio, PACKET *pkt)
|
---|
257 | {
|
---|
258 | uint64_t stream_id = 0;
|
---|
259 | uint64_t max_stream_data = 0;
|
---|
260 |
|
---|
261 | if (!ossl_quic_wire_decode_frame_max_stream_data(pkt, &stream_id,
|
---|
262 | &max_stream_data))
|
---|
263 | return 0;
|
---|
264 |
|
---|
265 | BIO_printf(bio, " Max Stream Data: %llu\n",
|
---|
266 | (unsigned long long)max_stream_data);
|
---|
267 |
|
---|
268 | return 1;
|
---|
269 | }
|
---|
270 |
|
---|
271 | static int frame_max_streams(BIO *bio, PACKET *pkt)
|
---|
272 | {
|
---|
273 | uint64_t max_streams = 0;
|
---|
274 |
|
---|
275 | if (!ossl_quic_wire_decode_frame_max_streams(pkt, &max_streams))
|
---|
276 | return 0;
|
---|
277 |
|
---|
278 | BIO_printf(bio, " Max Streams: %llu\n", (unsigned long long)max_streams);
|
---|
279 |
|
---|
280 | return 1;
|
---|
281 | }
|
---|
282 |
|
---|
283 | static int frame_data_blocked(BIO *bio, PACKET *pkt)
|
---|
284 | {
|
---|
285 | uint64_t max_data = 0;
|
---|
286 |
|
---|
287 | if (!ossl_quic_wire_decode_frame_data_blocked(pkt, &max_data))
|
---|
288 | return 0;
|
---|
289 |
|
---|
290 | BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data);
|
---|
291 |
|
---|
292 | return 1;
|
---|
293 | }
|
---|
294 |
|
---|
295 | static int frame_stream_data_blocked(BIO *bio, PACKET *pkt)
|
---|
296 | {
|
---|
297 | uint64_t stream_id = 0;
|
---|
298 | uint64_t max_data = 0;
|
---|
299 |
|
---|
300 | if (!ossl_quic_wire_decode_frame_stream_data_blocked(pkt, &stream_id,
|
---|
301 | &max_data))
|
---|
302 | return 0;
|
---|
303 |
|
---|
304 | BIO_printf(bio, " Stream id: %llu\n", (unsigned long long)stream_id);
|
---|
305 | BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data);
|
---|
306 |
|
---|
307 | return 1;
|
---|
308 | }
|
---|
309 |
|
---|
310 | static int frame_streams_blocked(BIO *bio, PACKET *pkt)
|
---|
311 | {
|
---|
312 | uint64_t max_data = 0;
|
---|
313 |
|
---|
314 | if (!ossl_quic_wire_decode_frame_streams_blocked(pkt, &max_data))
|
---|
315 | return 0;
|
---|
316 |
|
---|
317 | BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data);
|
---|
318 |
|
---|
319 | return 1;
|
---|
320 | }
|
---|
321 |
|
---|
322 | static int frame_new_conn_id(BIO *bio, PACKET *pkt)
|
---|
323 | {
|
---|
324 | OSSL_QUIC_FRAME_NEW_CONN_ID frame_data;
|
---|
325 |
|
---|
326 | if (!ossl_quic_wire_decode_frame_new_conn_id(pkt, &frame_data))
|
---|
327 | return 0;
|
---|
328 |
|
---|
329 | BIO_printf(bio, " Sequence Number: %llu\n",
|
---|
330 | (unsigned long long)frame_data.seq_num);
|
---|
331 | BIO_printf(bio, " Retire prior to: %llu\n",
|
---|
332 | (unsigned long long)frame_data.retire_prior_to);
|
---|
333 | BIO_puts(bio, " Connection id: ");
|
---|
334 | put_conn_id(bio, &frame_data.conn_id);
|
---|
335 | BIO_puts(bio, "\n Stateless Reset Token: ");
|
---|
336 | put_data(bio, frame_data.stateless_reset.token,
|
---|
337 | sizeof(frame_data.stateless_reset.token));
|
---|
338 | BIO_puts(bio, "\n");
|
---|
339 |
|
---|
340 | return 1;
|
---|
341 | }
|
---|
342 |
|
---|
343 | static int frame_retire_conn_id(BIO *bio, PACKET *pkt)
|
---|
344 | {
|
---|
345 | uint64_t seq_num;
|
---|
346 |
|
---|
347 | if (!ossl_quic_wire_decode_frame_retire_conn_id(pkt, &seq_num))
|
---|
348 | return 0;
|
---|
349 |
|
---|
350 | BIO_printf(bio, " Sequence Number: %llu\n", (unsigned long long)seq_num);
|
---|
351 |
|
---|
352 | return 1;
|
---|
353 | }
|
---|
354 |
|
---|
355 | static int frame_path_challenge(BIO *bio, PACKET *pkt)
|
---|
356 | {
|
---|
357 | uint64_t data = 0;
|
---|
358 |
|
---|
359 | if (!ossl_quic_wire_decode_frame_path_challenge(pkt, &data))
|
---|
360 | return 0;
|
---|
361 |
|
---|
362 | BIO_printf(bio, " Data: %016llx\n", (unsigned long long)data);
|
---|
363 |
|
---|
364 | return 1;
|
---|
365 | }
|
---|
366 |
|
---|
367 | static int frame_path_response(BIO *bio, PACKET *pkt)
|
---|
368 | {
|
---|
369 | uint64_t data = 0;
|
---|
370 |
|
---|
371 | if (!ossl_quic_wire_decode_frame_path_response(pkt, &data))
|
---|
372 | return 0;
|
---|
373 |
|
---|
374 | BIO_printf(bio, " Data: %016llx\n", (unsigned long long)data);
|
---|
375 |
|
---|
376 | return 1;
|
---|
377 | }
|
---|
378 |
|
---|
379 | static int frame_conn_closed(BIO *bio, PACKET *pkt)
|
---|
380 | {
|
---|
381 | OSSL_QUIC_FRAME_CONN_CLOSE frame_data;
|
---|
382 |
|
---|
383 | if (!ossl_quic_wire_decode_frame_conn_close(pkt, &frame_data))
|
---|
384 | return 0;
|
---|
385 |
|
---|
386 | BIO_printf(bio, " Error Code: %llu\n",
|
---|
387 | (unsigned long long)frame_data.error_code);
|
---|
388 | BIO_puts(bio, " Reason: ");
|
---|
389 | put_str(bio, frame_data.reason, frame_data.reason_len);
|
---|
390 | BIO_puts(bio, "\n");
|
---|
391 |
|
---|
392 | return 1;
|
---|
393 | }
|
---|
394 |
|
---|
395 | static int trace_frame_data(BIO *bio, PACKET *pkt)
|
---|
396 | {
|
---|
397 | uint64_t frame_type;
|
---|
398 |
|
---|
399 | if (!ossl_quic_wire_peek_frame_header(pkt, &frame_type, NULL))
|
---|
400 | return 0;
|
---|
401 |
|
---|
402 | switch (frame_type) {
|
---|
403 | case OSSL_QUIC_FRAME_TYPE_PING:
|
---|
404 | BIO_puts(bio, "Ping\n");
|
---|
405 | if (!ossl_quic_wire_decode_frame_ping(pkt))
|
---|
406 | return 0;
|
---|
407 | break;
|
---|
408 |
|
---|
409 | case OSSL_QUIC_FRAME_TYPE_PADDING:
|
---|
410 | BIO_puts(bio, "Padding\n");
|
---|
411 | ossl_quic_wire_decode_padding(pkt);
|
---|
412 | break;
|
---|
413 |
|
---|
414 | case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN:
|
---|
415 | case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN:
|
---|
416 | BIO_puts(bio, "Ack ");
|
---|
417 | if (frame_type == OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN)
|
---|
418 | BIO_puts(bio, " (with ECN)\n");
|
---|
419 | else
|
---|
420 | BIO_puts(bio, " (without ECN)\n");
|
---|
421 | if (!frame_ack(bio, pkt))
|
---|
422 | return 0;
|
---|
423 | break;
|
---|
424 |
|
---|
425 | case OSSL_QUIC_FRAME_TYPE_RESET_STREAM:
|
---|
426 | BIO_puts(bio, "Reset stream\n");
|
---|
427 | if (!frame_reset_stream(bio, pkt))
|
---|
428 | return 0;
|
---|
429 | break;
|
---|
430 |
|
---|
431 | case OSSL_QUIC_FRAME_TYPE_STOP_SENDING:
|
---|
432 | BIO_puts(bio, "Stop sending\n");
|
---|
433 | if (!frame_stop_sending(bio, pkt))
|
---|
434 | return 0;
|
---|
435 | break;
|
---|
436 |
|
---|
437 | case OSSL_QUIC_FRAME_TYPE_CRYPTO:
|
---|
438 | BIO_puts(bio, "Crypto\n");
|
---|
439 | if (!frame_crypto(bio, pkt))
|
---|
440 | return 0;
|
---|
441 | break;
|
---|
442 |
|
---|
443 | case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN:
|
---|
444 | BIO_puts(bio, "New token\n");
|
---|
445 | if (!frame_new_token(bio, pkt))
|
---|
446 | return 0;
|
---|
447 | break;
|
---|
448 |
|
---|
449 | case OSSL_QUIC_FRAME_TYPE_STREAM:
|
---|
450 | case OSSL_QUIC_FRAME_TYPE_STREAM_FIN:
|
---|
451 | case OSSL_QUIC_FRAME_TYPE_STREAM_LEN:
|
---|
452 | case OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN:
|
---|
453 | case OSSL_QUIC_FRAME_TYPE_STREAM_OFF:
|
---|
454 | case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN:
|
---|
455 | case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN:
|
---|
456 | case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN:
|
---|
457 | /* frame_stream() prints the frame type string */
|
---|
458 | if (!frame_stream(bio, pkt, frame_type))
|
---|
459 | return 0;
|
---|
460 | break;
|
---|
461 |
|
---|
462 | case OSSL_QUIC_FRAME_TYPE_MAX_DATA:
|
---|
463 | BIO_puts(bio, "Max data\n");
|
---|
464 | if (!frame_max_data(bio, pkt))
|
---|
465 | return 0;
|
---|
466 | break;
|
---|
467 |
|
---|
468 | case OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA:
|
---|
469 | BIO_puts(bio, "Max stream data\n");
|
---|
470 | if (!frame_max_stream_data(bio, pkt))
|
---|
471 | return 0;
|
---|
472 | break;
|
---|
473 |
|
---|
474 | case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI:
|
---|
475 | case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI:
|
---|
476 | BIO_puts(bio, "Max streams ");
|
---|
477 | if (frame_type == OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI)
|
---|
478 | BIO_puts(bio, " (Bidi)\n");
|
---|
479 | else
|
---|
480 | BIO_puts(bio, " (Uni)\n");
|
---|
481 | if (!frame_max_streams(bio, pkt))
|
---|
482 | return 0;
|
---|
483 | break;
|
---|
484 |
|
---|
485 | case OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED:
|
---|
486 | BIO_puts(bio, "Data blocked\n");
|
---|
487 | if (!frame_data_blocked(bio, pkt))
|
---|
488 | return 0;
|
---|
489 | break;
|
---|
490 |
|
---|
491 | case OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED:
|
---|
492 | BIO_puts(bio, "Stream data blocked\n");
|
---|
493 | if (!frame_stream_data_blocked(bio, pkt))
|
---|
494 | return 0;
|
---|
495 | break;
|
---|
496 |
|
---|
497 | case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI:
|
---|
498 | case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI:
|
---|
499 | BIO_puts(bio, "Streams blocked");
|
---|
500 | if (frame_type == OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI)
|
---|
501 | BIO_puts(bio, " (Bidi)\n");
|
---|
502 | else
|
---|
503 | BIO_puts(bio, " (Uni)\n");
|
---|
504 | if (!frame_streams_blocked(bio, pkt))
|
---|
505 | return 0;
|
---|
506 | break;
|
---|
507 |
|
---|
508 | case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID:
|
---|
509 | BIO_puts(bio, "New conn id\n");
|
---|
510 | if (!frame_new_conn_id(bio, pkt))
|
---|
511 | return 0;
|
---|
512 | break;
|
---|
513 |
|
---|
514 | case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID:
|
---|
515 | BIO_puts(bio, "Retire conn id\n");
|
---|
516 | if (!frame_retire_conn_id(bio, pkt))
|
---|
517 | return 0;
|
---|
518 | break;
|
---|
519 |
|
---|
520 | case OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE:
|
---|
521 | BIO_puts(bio, "Path challenge\n");
|
---|
522 | if (!frame_path_challenge(bio, pkt))
|
---|
523 | return 0;
|
---|
524 | break;
|
---|
525 |
|
---|
526 | case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE:
|
---|
527 | BIO_puts(bio, "Path response\n");
|
---|
528 | if (!frame_path_response(bio, pkt))
|
---|
529 | return 0;
|
---|
530 | break;
|
---|
531 |
|
---|
532 | case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP:
|
---|
533 | case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT:
|
---|
534 | BIO_puts(bio, "Connection close");
|
---|
535 | if (frame_type == OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP)
|
---|
536 | BIO_puts(bio, " (app)\n");
|
---|
537 | else
|
---|
538 | BIO_puts(bio, " (transport)\n");
|
---|
539 | if (!frame_conn_closed(bio, pkt))
|
---|
540 | return 0;
|
---|
541 | break;
|
---|
542 |
|
---|
543 | case OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE:
|
---|
544 | BIO_puts(bio, "Handshake done\n");
|
---|
545 | if (!ossl_quic_wire_decode_frame_handshake_done(pkt))
|
---|
546 | return 0;
|
---|
547 | break;
|
---|
548 |
|
---|
549 | default:
|
---|
550 | return 0;
|
---|
551 | }
|
---|
552 |
|
---|
553 | if (PACKET_remaining(pkt) != 0)
|
---|
554 | BIO_puts(bio, " <unexpected trailing frame data skipped>\n");
|
---|
555 |
|
---|
556 | return 1;
|
---|
557 | }
|
---|
558 |
|
---|
559 | int ossl_quic_trace(int write_p, int version, int content_type,
|
---|
560 | const void *buf, size_t msglen, SSL *ssl, void *arg)
|
---|
561 | {
|
---|
562 | BIO *bio = arg;
|
---|
563 | PACKET pkt;
|
---|
564 |
|
---|
565 | switch (content_type) {
|
---|
566 | case SSL3_RT_QUIC_DATAGRAM:
|
---|
567 | BIO_puts(bio, write_p ? "Sent" : "Received");
|
---|
568 | /*
|
---|
569 | * Unfortunately there is no way of receiving auxiliary information
|
---|
570 | * about the datagram through the msg_callback API such as the peer
|
---|
571 | * address
|
---|
572 | */
|
---|
573 | BIO_printf(bio, " Datagram\n Length: %zu\n", msglen);
|
---|
574 | break;
|
---|
575 |
|
---|
576 | case SSL3_RT_QUIC_PACKET:
|
---|
577 | {
|
---|
578 | QUIC_PKT_HDR hdr;
|
---|
579 | size_t i;
|
---|
580 |
|
---|
581 | if (!PACKET_buf_init(&pkt, buf, msglen))
|
---|
582 | return 0;
|
---|
583 | /* Decode the packet header */
|
---|
584 | /*
|
---|
585 | * TODO(QUIC SERVER): We need to query the short connection id len
|
---|
586 | * here, e.g. via some API SSL_get_short_conn_id_len()
|
---|
587 | */
|
---|
588 | if (ossl_quic_wire_decode_pkt_hdr(&pkt, 0, 0, 1, &hdr, NULL) != 1)
|
---|
589 | return 0;
|
---|
590 |
|
---|
591 | BIO_puts(bio, write_p ? "Sent" : "Received");
|
---|
592 | BIO_puts(bio, " Packet\n");
|
---|
593 | BIO_printf(bio, " Packet Type: %s\n", packet_type(hdr.type));
|
---|
594 | if (hdr.type != QUIC_PKT_TYPE_1RTT)
|
---|
595 | BIO_printf(bio, " Version: 0x%08lx\n",
|
---|
596 | (unsigned long)hdr.version);
|
---|
597 | BIO_puts(bio, " Destination Conn Id: ");
|
---|
598 | put_conn_id(bio, &hdr.dst_conn_id);
|
---|
599 | BIO_puts(bio, "\n");
|
---|
600 | if (hdr.type != QUIC_PKT_TYPE_1RTT) {
|
---|
601 | BIO_puts(bio, " Source Conn Id: ");
|
---|
602 | put_conn_id(bio, &hdr.src_conn_id);
|
---|
603 | BIO_puts(bio, "\n");
|
---|
604 | }
|
---|
605 | BIO_printf(bio, " Payload length: %zu\n", hdr.len);
|
---|
606 | if (hdr.type == QUIC_PKT_TYPE_INITIAL) {
|
---|
607 | BIO_puts(bio, " Token: ");
|
---|
608 | put_token(bio, hdr.token, hdr.token_len);
|
---|
609 | BIO_puts(bio, "\n");
|
---|
610 | }
|
---|
611 | if (hdr.type != QUIC_PKT_TYPE_VERSION_NEG
|
---|
612 | && hdr.type != QUIC_PKT_TYPE_RETRY) {
|
---|
613 | BIO_puts(bio, " Packet Number: 0x");
|
---|
614 | /* Will always be at least 1 byte */
|
---|
615 | for (i = 0; i < hdr.pn_len; i++)
|
---|
616 | BIO_printf(bio, "%02x", hdr.pn[i]);
|
---|
617 | BIO_puts(bio, "\n");
|
---|
618 | }
|
---|
619 | break;
|
---|
620 | }
|
---|
621 |
|
---|
622 | case SSL3_RT_QUIC_FRAME_PADDING:
|
---|
623 | case SSL3_RT_QUIC_FRAME_FULL:
|
---|
624 | case SSL3_RT_QUIC_FRAME_HEADER:
|
---|
625 | {
|
---|
626 | BIO_puts(bio, write_p ? "Sent" : "Received");
|
---|
627 | BIO_puts(bio, " Frame: ");
|
---|
628 |
|
---|
629 | if (!PACKET_buf_init(&pkt, buf, msglen))
|
---|
630 | return 0;
|
---|
631 | if (!trace_frame_data(bio, &pkt)) {
|
---|
632 | BIO_puts(bio, " <error processing frame data>\n");
|
---|
633 | return 0;
|
---|
634 | }
|
---|
635 | }
|
---|
636 | break;
|
---|
637 |
|
---|
638 | default:
|
---|
639 | /* Unrecognised content_type. We defer to SSL_trace */
|
---|
640 | return 0;
|
---|
641 | }
|
---|
642 |
|
---|
643 | return 1;
|
---|
644 | }
|
---|