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