VirtualBox

source: vbox/trunk/src/libs/openssl-3.3.2/ssl/quic/quic_trace.c@ 108358

最後變更 在這個檔案從108358是 108206,由 vboxsync 提交於 5 週 前

openssl-3.3.2: Exported all files to OSE and removed .scm-settings ​bugref:10757

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 17.9 KB
 
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
14static 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 */
41static 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
49static 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
57static 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
68static 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
76static 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;
117end:
118 OPENSSL_free(ack_ranges);
119 return ret;
120}
121
122static 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
139static 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
154static 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
167static 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
182static 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
244static 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
256static 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
271static 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
283static 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
295static 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
310static 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
322static 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
343static 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
355static 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
367static 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
379static 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
395static 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
559int 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}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette