LCOV - code coverage report
Current view: top level - waltz/quic - fd_quic_pretty_print.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 393 0.0 %
Date: 2025-01-08 12:08:44 Functions: 0 32 0.0 %

          Line data    Source code
       1             : #pragma GCC diagnostic ignored "-Wtype-limits"
       2             : 
       3             : #include "templ/fd_quic_pretty_print.h"
       4             : #include "templ/fd_quic_templ.h"
       5             : #include "templ/fd_quic_frames_templ.h"
       6             : #include "templ/fd_quic_undefs.h"
       7             : #include "fd_quic_private.h"
       8             : #include "fd_quic_pretty_print.h"
       9             : 
      10             : /* Generate frame pretty-print */
      11             : 
      12             : #define FD_TEMPL_DEF_STRUCT_BEGIN(NAME)                                    \
      13             :   static ulong fd_quic_pretty_print_frame_##NAME(                          \
      14             :       fd_quic_##NAME##_t * frame,                                          \
      15             :       char **              out_buf,                                        \
      16             :       ulong *              out_buf_sz,                                     \
      17             :       uchar const * const  buf,                                            \
      18             :       ulong         const  buf_sz                                          \
      19           0 :   ) {                                                                      \
      20           0 :     uchar const *       p0 = buf;                                          \
      21           0 :     uchar const * const p1 = buf+buf_sz;                                   \
      22           0 :     ulong               rc;                                                \
      23           0 :                                                                            \
      24           0 :     rc = fd_quic_decode_##NAME( frame, p0, (ulong)(p1-p0) );               \
      25           0 :     if( FD_UNLIKELY( rc==FD_QUIC_PARSE_FAIL ) ) return FD_QUIC_PARSE_FAIL; \
      26           0 :     p0 += rc;                                                              \
      27           0 :                                                                            \
      28           0 :     fd_quic_pretty_print_struct_##NAME( out_buf, out_buf_sz, frame );      \
      29           0 :                                                                            \
      30           0 :     return (ulong)(p0-buf);                                                \
      31           0 :   }
      32             : #include "templ/fd_quic_dft.h"
      33             : #include "templ/fd_quic_frames_templ.h"
      34             : #include "templ/fd_quic_undefs.h"
      35             : 
      36             : #include "templ/fd_quic_frame.h"
      37             : 
      38             : 
      39             : #define safe_snprintf( out, sz, ... )               \
      40           0 :   (__extension__({                                  \
      41           0 :     int rtn = snprintf( (out), (sz), __VA_ARGS__ ); \
      42           0 :     if( rtn < 0 ) rtn = 0;                          \
      43           0 :     if( rtn > (int)(sz) ) rtn = (int)(sz);          \
      44           0 :     (ulong)rtn; }))
      45             : 
      46             : ulong
      47             : fd_quic_pretty_print_frame( char **           out_buf,
      48             :                             ulong *           out_buf_sz,
      49             :                             uchar const *     buf,
      50           0 :                             ulong             buf_sz ) {
      51           0 :   if( FD_UNLIKELY( buf_sz<1UL ) ) return FD_QUIC_PARSE_FAIL;
      52             : 
      53           0 :   uchar const * cur_buf = buf;
      54           0 :   uchar const * buf_end = buf + buf_sz;
      55             : 
      56           0 :   if( cur_buf[0] == 0x00 ) { /* handle padding separately */
      57           0 :     ulong padding_cnt = 0;
      58           0 :     while( cur_buf < buf_end && *cur_buf == 0x00 ) {
      59           0 :       padding_cnt++;
      60           0 :       cur_buf++;
      61           0 :     }
      62             : 
      63           0 :     ulong sz = safe_snprintf( *out_buf, *out_buf_sz, "\"frame_type\": \"0-padding\", \"count\": %lu, ", padding_cnt );
      64           0 :     *out_buf    += sz;
      65           0 :     *out_buf_sz -= sz;
      66             : 
      67           0 :     if( FD_UNLIKELY( cur_buf == buf_end ) ) return (ulong)( cur_buf - buf );
      68           0 :   }
      69             : 
      70             :   /* Frame ID is technically a varint but it's sufficient to look at the
      71             :      first byte. */
      72           0 :   uint id = cur_buf[0];
      73           0 :   if( FD_UNLIKELY( id >= FD_QUIC_FRAME_TYPE_CNT ) ) {
      74           0 :     ulong sz = safe_snprintf( *out_buf, *out_buf_sz, "\"frame_type\": \"%x-unknown\", ...", (uint)id );
      75           0 :     *out_buf    += sz;
      76           0 :     *out_buf_sz -= sz;
      77             : 
      78           0 :     return FD_QUIC_PARSE_FAIL;
      79           0 :   }
      80             : 
      81           0 :   ulong consumed = 0UL;
      82             : 
      83           0 :   union {
      84           0 : #define FD_TEMPL_DEF_STRUCT_BEGIN(NAME) fd_quic_##NAME##_t NAME;
      85           0 : #include "templ/fd_quic_dft.h"
      86           0 : #include "templ/fd_quic_frames_templ.h"
      87           0 : #include "templ/fd_quic_undefs.h"
      88           0 :   } data;
      89             : 
      90           0 :   memset( &data, 0, sizeof( data ) );
      91             : 
      92             :   /* tail call to frame handler */
      93           0 :   switch( id ) {
      94             : 
      95           0 : # define F(T,MID,NAME,...) \
      96           0 :     case T: { \
      97           0 :       ulong sz = safe_snprintf( *out_buf, *out_buf_sz, "\"frame_type\": \"%u\", ", (uint)id ); \
      98           0 :       *out_buf    += sz; \
      99           0 :       *out_buf_sz -= sz; \
     100           0 :       consumed = fd_quic_pretty_print_frame_##NAME##_frame( &data.NAME##_frame, out_buf, out_buf_sz, cur_buf, (ulong)( buf_end - cur_buf ) ); \
     101           0 :       break; \
     102           0 :     }
     103           0 :   FD_QUIC_FRAME_TYPES(F)
     104           0 : # undef F
     105             : 
     106           0 :   default:
     107             :     /* we're unable to consume more bytes, since this is invalid */
     108             :     /* TODO put error key in json */
     109           0 :     return FD_QUIC_PARSE_FAIL;
     110           0 :   }
     111             : 
     112           0 :   if( consumed == FD_QUIC_PARSE_FAIL ) return FD_QUIC_PARSE_FAIL;
     113             : 
     114             :   /* handle repeating blocks, etc. */
     115           0 :   cur_buf += consumed;
     116             : 
     117           0 :   switch( id ) {
     118           0 :     case 0x02:
     119           0 :     case 0x03:
     120           0 :     {
     121           0 :       ulong ack_range_count = data.ack_frame.ack_range_count;
     122             : 
     123             :       /* skip ack ranges */
     124           0 :       for( ulong j = 0UL; j < ack_range_count; ++j ) {
     125           0 :         fd_quic_ack_range_frag_t ack_range[1];
     126           0 :         ulong rc = fd_quic_decode_ack_range_frag( ack_range, cur_buf, (ulong)( buf_end - cur_buf ) );
     127           0 :         if( FD_UNLIKELY( rc == FD_QUIC_PARSE_FAIL ) ) {
     128           0 :           ulong out_sz = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"parse-ack-ranges\"" );
     129           0 :           *out_buf    += out_sz;
     130           0 :           *out_buf_sz -= out_sz;
     131           0 :           return FD_QUIC_PARSE_FAIL;
     132           0 :         }
     133             : 
     134           0 :         fd_quic_pretty_print_struct_ack_range_frag( out_buf, out_buf_sz, ack_range );
     135           0 :       }
     136             : 
     137           0 :       if( data.ack_frame.type & 1U ) {
     138           0 :         fd_quic_ecn_counts_frag_t ecn_counts[1] = {0};
     139           0 :         ulong rc = fd_quic_decode_ecn_counts_frag( ecn_counts, cur_buf, (ulong)( buf_end - cur_buf ) );
     140           0 :         if( rc == FD_QUIC_PARSE_FAIL ) {
     141           0 :           ulong out_sz = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"parse-ecn-counts\"" );
     142           0 :           *out_buf    += out_sz;
     143           0 :           *out_buf_sz -= out_sz;
     144           0 :           return FD_QUIC_PARSE_FAIL;
     145           0 :         }
     146             : 
     147           0 :         cur_buf += rc;
     148           0 :       }
     149             : 
     150           0 :       break;
     151           0 :     }
     152             : 
     153           0 :     case 0x06:
     154           0 :     {
     155           0 :       ulong out_sz = 0;
     156           0 :       ulong remain  = (ulong)( buf_end - cur_buf );
     157           0 :       ulong data_sz = data.crypto_frame.length;
     158           0 :       if( data_sz > remain ) {
     159           0 :         out_sz = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"overflow\", " );
     160           0 :         *out_buf    += out_sz;
     161           0 :         *out_buf_sz -= out_sz;
     162             : 
     163           0 :         return FD_QUIC_PARSE_FAIL;
     164           0 :       }
     165             : 
     166           0 :       out_sz = safe_snprintf( *out_buf, *out_buf_sz, "\"data\": [ " );
     167           0 :       *out_buf    += out_sz;
     168           0 :       *out_buf_sz -= out_sz;
     169             : 
     170           0 :       for( ulong j = 0; j < data_sz; ++j ) {
     171           0 :         out_sz = safe_snprintf( *out_buf, *out_buf_sz, "0x%02x, ", cur_buf[j] );
     172           0 :         *out_buf    += out_sz;
     173           0 :         *out_buf_sz -= out_sz;
     174           0 :       }
     175             : 
     176           0 :       out_sz = safe_snprintf( *out_buf, *out_buf_sz, "], " );
     177           0 :       *out_buf    += out_sz;
     178           0 :       *out_buf_sz -= out_sz;
     179             : 
     180           0 :       cur_buf  += data_sz;
     181             : 
     182           0 :       break;
     183           0 :     }
     184             : 
     185           0 :     case 0x08:
     186           0 :     case 0x09:
     187           0 :     case 0x0a:
     188           0 :     case 0x0b:
     189           0 :     case 0x0c:
     190           0 :     case 0x0d:
     191           0 :     case 0x0e:
     192           0 :     case 0x0f:
     193           0 :     {
     194           0 :       ulong remain = (ulong)( buf_end - cur_buf );
     195             : 
     196             :       /* stream */
     197             :       /* optional fields decoding */
     198           0 :       ulong offset      = 0;
     199           0 :       ulong stream_id   = 0;
     200           0 :       ulong data_sz     = remain;
     201           0 :       ulong fin         = 0;
     202             : 
     203           0 :       switch( id ) {
     204           0 : #       define _0(ELSE,...) ELSE
     205           0 : #       define _1(ELSE,...) __VA_ARGS__
     206           0 : #       define _CASE(OFF,LEN,FIN,NAME)           \
     207           0 :         case 8 + OFF(0,4) + LEN(0,2) + FIN(0,1): \
     208           0 :           OFF(,offset  = data.NAME.offset;)      \
     209           0 :           LEN(,data_sz = data.NAME.length;)      \
     210           0 :           FIN(,fin     = 1;)                     \
     211           0 :           stream_id   = data.NAME.stream_id;     \
     212           0 :           break;
     213           0 :         _CASE(_0,_0,_0,stream_8_frame)
     214           0 :         _CASE(_0,_0,_1,stream_8_frame)
     215           0 :         _CASE(_0,_1,_0,stream_a_frame)
     216           0 :         _CASE(_0,_1,_1,stream_a_frame)
     217           0 :         _CASE(_1,_0,_0,stream_c_frame)
     218           0 :         _CASE(_1,_0,_1,stream_c_frame)
     219           0 :         _CASE(_1,_1,_0,stream_e_frame)
     220           0 :         _CASE(_1,_1,_1,stream_e_frame)
     221           0 : #       undef _CASE
     222           0 : #       undef _1
     223           0 : #       undef _0
     224           0 :       }
     225             : 
     226           0 :       ulong stream_type = stream_id & 3UL;
     227             : 
     228           0 :       ulong out_sz = safe_snprintf(
     229           0 :                        *out_buf,
     230           0 :                        *out_buf_sz,
     231           0 :                        "\"stream_type\": %u, \"offset\": %lu, \"length\": %lu, \"fin\": %lu, ",
     232           0 :                        (uint)stream_type, offset, data_sz, fin );
     233           0 :       *out_buf    += out_sz;
     234           0 :       *out_buf_sz -= out_sz;
     235             : 
     236           0 :       if( data_sz > remain ) {
     237           0 :         out_sz = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"overflow\", " );
     238           0 :         *out_buf    += out_sz;
     239           0 :         *out_buf_sz -= out_sz;
     240             : 
     241           0 :         return FD_QUIC_PARSE_FAIL;
     242           0 :       }
     243             : 
     244           0 :       out_sz = safe_snprintf( *out_buf, *out_buf_sz, "\"data\": [ " );
     245           0 :       *out_buf    += out_sz;
     246           0 :       *out_buf_sz -= out_sz;
     247             : 
     248           0 :       for( ulong j = 0; j < data_sz; ++j ) {
     249           0 :         out_sz = safe_snprintf( *out_buf, *out_buf_sz, "0x%02x, ", cur_buf[j] );
     250           0 :         *out_buf    += out_sz;
     251           0 :         *out_buf_sz -= out_sz;
     252           0 :       }
     253             : 
     254           0 :       out_sz = safe_snprintf( *out_buf, *out_buf_sz, "], " );
     255           0 :       *out_buf    += out_sz;
     256           0 :       *out_buf_sz -= out_sz;
     257             : 
     258           0 :       cur_buf  += data_sz;
     259             : 
     260           0 :       break;
     261           0 :     }
     262             : 
     263           0 :     case 0x1c: /* connection close */
     264           0 :     {
     265             :       /* the conn_close_1_frame structure is different to conn_close_0_frame */
     266           0 :       ulong reason_phrase_length = data.conn_close_0_frame.reason_phrase_length;
     267           0 :       ulong remain               = (ulong)( buf_end - cur_buf );
     268           0 :       if( FD_UNLIKELY( reason_phrase_length > remain ) ) {
     269           0 :         ulong out_sz = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"overflow\", " );
     270           0 :         *out_buf    += out_sz;
     271           0 :         *out_buf_sz -= out_sz;
     272             : 
     273           0 :         return FD_QUIC_PARSE_FAIL;
     274           0 :       }
     275             : 
     276             :       /* TODO pretty print the reason phrase */
     277             : 
     278           0 :       cur_buf += reason_phrase_length;
     279             : 
     280           0 :       break;
     281           0 :     }
     282             : 
     283           0 :     case 0x1d: /* connection close */
     284           0 :     {
     285             :       /* the conn_close_1_frame structure is different to conn_close_0_frame */
     286           0 :       ulong reason_phrase_length = data.conn_close_1_frame.reason_phrase_length;
     287           0 :       ulong remain               = (ulong)( buf_end - cur_buf );
     288           0 :       if( FD_UNLIKELY( reason_phrase_length > remain ) ) {
     289           0 :         ulong out_sz = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"overflow\", " );
     290           0 :         *out_buf    += out_sz;
     291           0 :         *out_buf_sz -= out_sz;
     292             : 
     293           0 :         return FD_QUIC_PARSE_FAIL;
     294           0 :       }
     295             : 
     296             :       /* TODO pretty print the reason phrase */
     297             : 
     298           0 :       cur_buf += reason_phrase_length;
     299             : 
     300           0 :       break;
     301           0 :     }
     302           0 :   }
     303             : 
     304           0 :   return (ulong)( cur_buf - buf );
     305             : 
     306           0 : }
     307             : 
     308             : ulong
     309             : fd_quic_pretty_print_frames( char **           out_buf,
     310             :                              ulong *           out_buf_sz,
     311             :                              uchar const *     buf,
     312             :                              ulong             buf_sz );
     313             : 
     314             : 
     315             : ulong
     316             : fd_quic_pretty_print_quic_hdr_initial( char **        out_buf,
     317             :                                        ulong *        out_buf_sz,
     318             :                                        uchar const ** frame_ptr,
     319             :                                        ulong *        frame_sz,
     320             :                                        uchar const *  buf,
     321           0 :                                        ulong          buf_sz ) {
     322           0 :   ulong sz = safe_snprintf( *out_buf, *out_buf_sz, "\"hdr_type\": \"initial\", " );
     323           0 :   *out_buf    += sz;
     324           0 :   *out_buf_sz -= sz;
     325             : 
     326           0 :   fd_quic_initial_t initial[1] = {0};
     327           0 :   ulong rc = fd_quic_decode_initial( initial, buf, buf_sz );
     328           0 :   if( FD_UNLIKELY( rc == FD_QUIC_PARSE_FAIL ) ) {
     329           0 :     ulong sz = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"hdr_parse_failed\", " );
     330           0 :     *out_buf    += sz;
     331           0 :     *out_buf_sz -= sz;
     332             : 
     333           0 :     FD_LOG_HEXDUMP_ERR(( "hdr_parse_failed", buf, fd_ulong_min( 16, buf_sz ) ));
     334             : 
     335           0 :     return FD_QUIC_PARSE_FAIL;
     336           0 :   }
     337             : 
     338           0 :   ulong body_sz       = initial->len;  /* not a protected field */
     339           0 :   ulong pn_offset     = initial->pkt_num_pnoff;
     340           0 :   ulong pkt_number_sz = fd_quic_h0_pkt_num_len( buf[0] ) + 1u;
     341           0 :   ulong payload_off   = pn_offset + pkt_number_sz;
     342             : 
     343             :   /* now we have decrypted packet number */
     344           0 :   ulong pkt_number = fd_quic_pktnum_decode( buf+pn_offset, pkt_number_sz );
     345             : 
     346             :   /* write pkt_number_sz into initial, for tracing */
     347             :   /* note this is the raw packet number, which may have been truncated */
     348           0 :   initial->pkt_num = pkt_number;
     349             : 
     350           0 :   *frame_ptr   = buf + payload_off;
     351           0 :   *frame_sz    = body_sz - pkt_number_sz - FD_QUIC_CRYPTO_TAG_SZ; /* total size of all frames in packet */
     352             : 
     353           0 :   fd_quic_pretty_print_struct_initial( out_buf, out_buf_sz, initial );
     354             : 
     355           0 :   return payload_off;
     356           0 : }
     357             : 
     358             : 
     359             : ulong
     360             : fd_quic_pretty_print_quic_hdr_handshake( char **        out_buf,
     361             :                                          ulong *        out_buf_sz,
     362             :                                          uchar const ** frame_ptr,
     363             :                                          ulong *        frame_sz,
     364             :                                          uchar const *  buf,
     365           0 :                                          ulong          buf_sz ) {
     366           0 :   ulong sz = safe_snprintf( *out_buf, *out_buf_sz, "\"hdr_type\": \"handshake\", " );
     367           0 :   *out_buf    += sz;
     368           0 :   *out_buf_sz -= sz;
     369             : 
     370           0 :   fd_quic_handshake_t handshake[1] = {0};
     371           0 :   ulong rc = fd_quic_decode_handshake( handshake, buf, buf_sz );
     372           0 :   if( FD_UNLIKELY( rc == FD_QUIC_PARSE_FAIL ) ) {
     373           0 :     ulong sz = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"hdr_parse_failed\", " );
     374           0 :     *out_buf    += sz;
     375           0 :     *out_buf_sz -= sz;
     376             : 
     377           0 :     FD_LOG_HEXDUMP_ERR(( "hdr_parse_failed", buf, fd_ulong_min( 16, buf_sz ) ));
     378             : 
     379           0 :     return FD_QUIC_PARSE_FAIL;
     380           0 :   }
     381             : 
     382           0 :   ulong body_sz       = handshake->len;  /* not a protected field */
     383           0 :   ulong pn_offset     = handshake->pkt_num_pnoff;
     384           0 :   ulong pkt_number_sz = fd_quic_h0_pkt_num_len( buf[0] ) + 1u;
     385           0 :   ulong payload_off   = pn_offset + pkt_number_sz;
     386             : 
     387             :   /* now we have decrypted packet number */
     388           0 :   ulong pkt_number = fd_quic_pktnum_decode( buf+pn_offset, pkt_number_sz );
     389             : 
     390             :   /* write pkt_number_sz into handshake, for tracing */
     391             :   /* note this is the raw packet number, which may have been truncated */
     392           0 :   handshake->pkt_num = pkt_number;
     393             : 
     394           0 :   *frame_ptr   = buf + payload_off;
     395           0 :   *frame_sz    = body_sz - pkt_number_sz - FD_QUIC_CRYPTO_TAG_SZ; /* total size of all frames in packet */
     396             : 
     397           0 :   fd_quic_pretty_print_struct_handshake( out_buf, out_buf_sz, handshake );
     398             : 
     399           0 :   return payload_off;
     400           0 : }
     401             : 
     402             : 
     403             : ulong
     404             : fd_quic_pretty_print_quic_hdr_one_rtt( char **        out_buf,
     405             :                                        ulong *        out_buf_sz,
     406             :                                        uchar const ** frame_ptr,
     407             :                                        ulong *        frame_sz,
     408             :                                        uchar const *  buf,
     409           0 :                                        ulong          buf_sz ) {
     410           0 :   ulong sz = safe_snprintf( *out_buf, *out_buf_sz, "\"hdr_type\": \"1-rtt\", " );
     411           0 :   *out_buf    += sz;
     412           0 :   *out_buf_sz -= sz;
     413             : 
     414           0 :   fd_quic_one_rtt_t one_rtt[1] = {0};
     415             : 
     416             :   /* hidden field needed by decode function */
     417           0 :   one_rtt->dst_conn_id_len = 8;
     418             : 
     419           0 :   ulong rc = fd_quic_decode_one_rtt( one_rtt, buf, buf_sz );
     420           0 :   if( FD_UNLIKELY( rc == FD_QUIC_PARSE_FAIL ) ) {
     421           0 :     ulong sz = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"hdr_parse_failed\", " );
     422           0 :     *out_buf    += sz;
     423           0 :     *out_buf_sz -= sz;
     424             : 
     425           0 :     FD_LOG_HEXDUMP_ERR(( "hdr_parse_failed", buf, fd_ulong_min( 16, buf_sz ) ));
     426             : 
     427           0 :     return FD_QUIC_PARSE_FAIL;
     428           0 :   }
     429             : 
     430           0 :   ulong pn_offset     = one_rtt->pkt_num_pnoff;
     431           0 :   ulong pkt_number_sz = fd_quic_h0_pkt_num_len( buf[0] ) + 1u;
     432           0 :   ulong payload_off   = pn_offset + pkt_number_sz;
     433           0 :   ulong payload_sz    = buf_sz - pn_offset - pkt_number_sz; /* includes auth tag */
     434             : 
     435             :   /* now we have decrypted packet number */
     436           0 :   ulong pkt_number = fd_quic_pktnum_decode( buf+pn_offset, pkt_number_sz );
     437             : 
     438             :   /* write pkt_number_sz into one_rtt, for tracing */
     439             :   /* note this is the raw packet number, which may have been truncated */
     440           0 :   one_rtt->pkt_num = pkt_number;
     441             : 
     442           0 :   *frame_ptr   = buf + payload_off;
     443           0 :   *frame_sz    = payload_sz - FD_QUIC_CRYPTO_TAG_SZ; /* total size of all frames in packet */
     444             : 
     445           0 :   fd_quic_pretty_print_struct_one_rtt( out_buf, out_buf_sz, one_rtt );
     446             : 
     447           0 :   return payload_off;
     448           0 : }
     449             : 
     450             : 
     451             : ulong
     452             : fd_quic_pretty_print_quic_hdr( char **        out_buf,
     453             :                                ulong *        out_buf_sz,
     454             :                                uchar const ** frame_ptr,
     455             :                                ulong *        frame_sz,
     456             :                                uchar const *  buf,
     457           0 :                                ulong          buf_sz ) {
     458           0 :   ulong sz;
     459             : 
     460           0 :   uint first   = (uint)buf[0];
     461           0 :   uint is_long = first >> 7u;
     462             : 
     463           0 :   if( !is_long ) {
     464           0 :       return fd_quic_pretty_print_quic_hdr_one_rtt( out_buf, out_buf_sz, frame_ptr, frame_sz, buf, buf_sz );
     465           0 :   }
     466             : 
     467           0 :   uint long_type = ( first >> 4u ) & 0x03u;
     468             : 
     469           0 :   switch( long_type ) {
     470           0 :     case 0x00: /* initial */
     471           0 :       return fd_quic_pretty_print_quic_hdr_initial( out_buf, out_buf_sz, frame_ptr, frame_sz, buf, buf_sz );
     472           0 :     case 0x01: /* 0-rtt - unused */
     473           0 :       sz = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"0-rtt\", " );
     474           0 :       *out_buf    += sz;
     475           0 :       *out_buf_sz -= sz;
     476           0 :       return FD_QUIC_PARSE_FAIL;
     477           0 :     case 0x02: /* handshake */
     478           0 :       return fd_quic_pretty_print_quic_hdr_handshake( out_buf, out_buf_sz, frame_ptr, frame_sz, buf, buf_sz );
     479           0 :     case 0x03:
     480           0 :       sz = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"not-implemented-retry\", " );
     481           0 :       *out_buf    += sz;
     482           0 :       *out_buf_sz -= sz;
     483           0 :       return FD_QUIC_PARSE_FAIL;
     484           0 :   }
     485             : 
     486             :   /* long type is uint & 0x03u - yet gcc thinks this is reachable */
     487           0 :   return FD_QUIC_PARSE_FAIL;
     488           0 : }
     489             : 
     490             : 
     491             : /* 16 bytes allows for: xxx.xxx.xxx.xxx\0 */
     492           0 : #define IP4_TO_STR_BUF_SZ 16
     493             : static
     494             : char const *
     495           0 : ip4_to_str( char buf[IP4_TO_STR_BUF_SZ], uint ip4_addr ) {
     496             :   /* can't use sizeof(buf) here, as technically typeof(buf) is char* */
     497           0 :   ulong sz = safe_snprintf( buf, IP4_TO_STR_BUF_SZ, FD_IP4_ADDR_FMT, FD_IP4_ADDR_FMT_ARGS( ip4_addr ) );
     498             :   /* should not be possible */
     499           0 :   if( FD_UNLIKELY( sz >= IP4_TO_STR_BUF_SZ ) ) buf[IP4_TO_STR_BUF_SZ-1] = '\0';
     500           0 :   return buf;
     501           0 : }
     502             : 
     503             : 
     504             : ulong
     505             : fd_quic_pretty_print_quic_pkt( fd_quic_pretty_print_t * pretty_print,
     506             :                                ulong                    now,
     507             :                                uchar const *            buf,
     508             :                                ulong                    buf_sz,
     509             :                                char const *             flow,
     510             :                                uint                     ip4_saddr,
     511           0 :                                ushort                   udp_sport ) {
     512           0 :   (void)pretty_print;
     513           0 :   (void)now;
     514             : 
     515           0 :   char tmp_buf[16];
     516             : 
     517           0 :   if( buf == NULL ) return FD_QUIC_PARSE_FAIL;
     518             : 
     519           0 :   static FD_TL char pretty_print_buf[16384];
     520             : 
     521           0 :   memset( pretty_print_buf, 0, sizeof( pretty_print_buf ) );
     522             : 
     523           0 :   char * out_buf    = &pretty_print_buf[0];
     524           0 :   ulong  out_buf_sz = sizeof( pretty_print_buf ) - 1UL;
     525             : 
     526           0 :   uchar const * frame_ptr = NULL;
     527           0 :   ulong         frame_sz  = 0;
     528             : 
     529           0 :   ulong sz = safe_snprintf( out_buf, out_buf_sz, "{ \"type\": \"packet\", \"flow\": \"%s\", ", flow );
     530           0 :   out_buf    += sz;
     531           0 :   out_buf_sz -= sz;
     532             : 
     533           0 :   /* */ sz = safe_snprintf( out_buf, out_buf_sz, "\"src_ip_addr\": \"%s\", \"src_udp_port\": \"%u\", ",
     534           0 :                             ip4_to_str( tmp_buf, ip4_saddr ), fd_ushort_bswap( udp_sport ) );
     535           0 :   out_buf    += sz;
     536           0 :   out_buf_sz -= sz;
     537             : 
     538           0 :   ulong hdr_rc = fd_quic_pretty_print_quic_hdr( &out_buf,
     539           0 :                                                 &out_buf_sz,
     540           0 :                                                 &frame_ptr,
     541           0 :                                                 &frame_sz,
     542           0 :                                                 buf,
     543           0 :                                                 buf_sz );
     544           0 :   if( hdr_rc == FD_QUIC_PARSE_FAIL ) {
     545           0 :     sz = safe_snprintf( out_buf, out_buf_sz, "\"err\": \"parse_fail\" } " );
     546           0 :     out_buf    += sz;
     547           0 :     out_buf_sz -= sz;
     548             : 
     549           0 :     return FD_QUIC_PARSE_FAIL;
     550           0 :   }
     551             : 
     552           0 :   sz = safe_snprintf( out_buf, out_buf_sz, "\"frames\": [ " );
     553           0 :   out_buf    += sz;
     554           0 :   out_buf_sz -= sz;
     555             : 
     556           0 :   ulong rc = fd_quic_pretty_print_frames( &out_buf,
     557           0 :                                           &out_buf_sz,
     558           0 :                                           frame_ptr,
     559           0 :                                           frame_sz );
     560           0 :   if( rc == FD_QUIC_PARSE_FAIL ) {
     561           0 :     sz = safe_snprintf( out_buf, out_buf_sz, "], \"err\": \"parse_fail\" }, " );
     562           0 :     out_buf    += sz;
     563           0 :     out_buf_sz -= sz;
     564           0 :     printf( "\nTRACE: %s\n", pretty_print_buf );
     565           0 :     fflush( stdout );
     566           0 :     return FD_QUIC_PARSE_FAIL;
     567           0 :   }
     568             : 
     569           0 :   sz = safe_snprintf( out_buf, out_buf_sz, "] }, " );
     570           0 :   out_buf    += sz;
     571           0 :   out_buf_sz -= sz;
     572             : 
     573           0 :   for( ulong j = 0; j < (ulong)( out_buf - pretty_print_buf); ++j ) {
     574           0 :     if( pretty_print_buf[j] == '\0' ) pretty_print_buf[j] = '*';
     575           0 :   }
     576             : 
     577           0 :   printf( "TRACE: [ %s ]\n", pretty_print_buf );
     578             : 
     579           0 :   return rc;
     580           0 : }
     581             : 
     582             : ulong
     583             : fd_quic_pretty_print_frames( char **           out_buf,
     584             :                              ulong *           out_buf_sz,
     585             :                              uchar const *     buf,
     586           0 :                              ulong             buf_sz ) {
     587           0 :   uchar const * orig_buf = buf;
     588           0 :   ulong sz;
     589             : 
     590           0 :   while( buf_sz > 0 ) {
     591           0 :     sz          = safe_snprintf( *out_buf, *out_buf_sz, "{ \"type\": \"frame\", " );
     592           0 :     *out_buf    += sz;
     593           0 :     *out_buf_sz -= sz;
     594             : 
     595           0 :     ulong rc = fd_quic_pretty_print_frame( out_buf, out_buf_sz, buf, buf_sz );
     596           0 :     if( rc == FD_QUIC_PARSE_FAIL ) {
     597           0 :       sz          = safe_snprintf( *out_buf, *out_buf_sz, "\"err\": \"parse_fail\" }, " );
     598           0 :       *out_buf    += sz;
     599           0 :       *out_buf_sz -= sz;
     600           0 :       break;
     601           0 :     }
     602             : 
     603           0 :     sz          = safe_snprintf( *out_buf, *out_buf_sz, " }, " );
     604           0 :     *out_buf    += sz;
     605           0 :     *out_buf_sz -= sz;
     606             : 
     607           0 :     if( rc >= buf_sz ) break;
     608             : 
     609           0 :     buf    += rc;
     610           0 :     buf_sz -= rc;
     611           0 :   }
     612             : 
     613           0 :   return (ulong)( buf - orig_buf );
     614           0 : }

Generated by: LCOV version 1.14