Home | History | Annotate | Line # | Download | only in quic
      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 
     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 */
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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