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