LCOV - code coverage report
Current view: top level - waltz/quic/templ - fd_quic_parse_util.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 66 74 89.2 %
Date: 2025-01-08 12:08:44 Functions: 25 238 10.5 %

          Line data    Source code
       1             : #ifndef FD_QUIC_WALTZ_QUIC_TEMPL_FD_QUIC_PARSE_UTIL_H
       2             : #define FD_QUIC_WALTZ_QUIC_TEMPL_FD_QUIC_PARSE_UTIL_H
       3             : 
       4             : #include <stddef.h>
       5             : 
       6             : #include "../fd_quic_common.h"
       7             : #include "../../../util/bits/fd_bits.h"
       8             : 
       9             : static inline uint
      10 17010432480 : fd_quic_varint_min_sz_unsafe( ulong val ) {
      11 17010432480 :   int sz_class = fd_uint_find_msb( (uint)fd_ulong_find_msb( val|0x3fUL ) + 2 ) - 2;
      12 17010432480 :   return 1U<<sz_class;
      13 17010432480 : }
      14             : 
      15             : static inline uint
      16 16911530070 : fd_quic_varint_min_sz( ulong val ) {
      17 16911530070 :   return fd_quic_varint_min_sz_unsafe( fd_ulong_min( val, 0x3fffffffffffffffUL ) );
      18 16911530070 : }
      19             : 
      20             : static inline uint
      21             : fd_quic_varint_encode( uchar out[8],
      22    98902410 :                        ulong val ) {
      23             :   /* max out at 0x3fffffffffffffffUL */
      24    98902410 :   val = fd_ulong_min( val, 0x3fffffffffffffffUL );
      25             : 
      26             :   /* input byte pattern:
      27             :      - sz 1: aa 00 00 00 00 00 00 00
      28             :      - sz 2: aa bb 00 00 00 00 00 00
      29             :      - sz 4: aa bb cc dd 00 00 00 00
      30             :      - sz 8: aa bb cc dd ee ff ff gg */
      31             : 
      32    98902410 :   uint sz = fd_quic_varint_min_sz_unsafe( val );
      33             : 
      34             :   /* shifted byte pattern
      35             :      - sz 1: 00 00 00 00 00 00 00 aa
      36             :      - sz 2: 00 00 00 00 00 00 aa bb
      37             :      - sz 4: 00 00 00 00 aa bb cc dd
      38             :      - sz 8: aa bb cc dd ee ff ff gg */
      39             : 
      40    98902410 :   ulong shifted = val << ( 8 * ( 8 - sz ) );
      41             : 
      42             :   /* swapped byte pattern
      43             :      - sz 1: aa 00 00 00 00 00 00 00
      44             :      - sz 2: bb aa 00 00 00 00 00 00
      45             :      - sz 4: dd cc bb aa 00 00 00 00
      46             :      - sz 8: gg ff ee dd cc bb aa 00 */
      47             : 
      48    98902410 :   ulong encoded = fd_ulong_bswap( shifted );
      49             : 
      50             :   /* set length indication */
      51             : 
      52    98902410 :   encoded &= 0xffffffffffffff3fUL;
      53    98902410 :   encoded |= ((ulong)fd_uint_find_msb( sz ))<<6;
      54             : 
      55    98902410 :   FD_STORE( ulong, out, encoded );
      56    98902410 :   return sz;
      57    98902410 : }
      58             : 
      59             : 
      60             : /* encode a VARINT "val" into "buf" of size "buf_sz"
      61             :    buf must be a mutable uchar pointer, and will be updated to point to
      62             :      the remaining buffer
      63             :    buf_sz must be a mutable integer and will be reduced by the number of
      64             :      bytes written
      65             :    bounds are checked before writing into buf */
      66             : #define FD_QUIC_ENCODE_VARINT(buf,buf_sz,val)                 \
      67      349203 :   do {                                                        \
      68      349203 :     if( FD_UNLIKELY( buf_sz<8 ) ) return FD_QUIC_ENCODE_FAIL; \
      69      349203 :     uint sz = fd_quic_varint_encode( buf, (val) );            \
      70      349203 :     buf += sz; buf_sz -= sz;                                  \
      71      349203 :   } while(0);
      72             : 
      73             : /* fd_quic_h0_hdr_form extract the 'Header Form' bit, the first bit of a QUIC v1 packet.
      74             :    Returns 1 if the packet is a long header packet, 0 if the packet is a short header packet.
      75             :    Does not require decryption of the packet header. */
      76             : static inline uchar
      77    14367974 : fd_quic_h0_hdr_form( uchar hdr ) {
      78    14367974 :   return hdr>>7;
      79    14367974 : }
      80             : 
      81             : /* fd_quic_h0_long_packet_type extracts the 'Long Packet Type' from
      82             :    the first byte of a QUIC v1 long header packet.  Returns FD_QUIC_PKTTYPE_V1_{...}
      83             :    in range [0,4).  Does not require decryption of the packet header. */
      84             : static inline uchar
      85       27867 : fd_quic_h0_long_packet_type( uchar hdr ) {
      86       27867 :   return (hdr>>4)&3;
      87       27867 : }
      88             : 
      89             : static inline uchar
      90    75410624 : fd_quic_h0_pkt_num_len( uint h0 ) {
      91    75410624 :   return (uchar)( h0 & 0x03 );
      92    75410624 : }
      93             : 
      94             : static inline uchar
      95       12114 : fd_quic_initial_h0( uint pkt_num_len /* [0,3] */ ) {
      96       12114 :   return (uchar)( 0xc0 | pkt_num_len );
      97       12114 : }
      98             : 
      99             : static inline uchar
     100       12030 : fd_quic_handshake_h0( uint pkt_num_len /* [0,3] */ ) {
     101       12030 :   return (uchar)( 0xe0 | pkt_num_len );
     102       12030 : }
     103             : 
     104             : static inline uchar
     105             : fd_quic_one_rtt_h0( uint spin_bit,   /* [0,1] */
     106             :                     uint key_phase,  /* [0,1] */
     107    14338955 :                     uint pkt_num_len /* [0,3] */ ) {
     108    14338955 :   return (uchar)( 0x40 | (spin_bit<<5) | (key_phase<<2) | pkt_num_len );
     109    14338955 : }
     110             : 
     111             : static inline uint
     112           0 : fd_quic_one_rtt_spin_bit( uint h0 ) {
     113           0 :   return (uint)( (h0>>5) & 1 );
     114           0 : }
     115             : 
     116             : static inline uint
     117    14326856 : fd_quic_one_rtt_key_phase( uint h0 ) {
     118    14326856 :   return (uint)( (h0>>2) & 1 );
     119    14326856 : }
     120             : 
     121             : static inline uchar
     122             : fd_quic_stream_type( uint has_off,
     123             :                      uint has_len,
     124           0 :                      uint fin ) {
     125           0 :   return (uchar)( 0x08 + (has_off<<2) + (has_len<<1) + fin );
     126           0 : }
     127             : 
     128             : __attribute__((used)) static ulong
     129             : fd_quic_varint_decode( uchar const * buf,
     130   190647203 :                        uint          msb2 ) {
     131   190647203 :   switch( msb2 ) {
     132         324 :   case 3:
     133         324 :     return __builtin_bswap64( FD_LOAD( ulong,  buf ) ) & 0x3fffffffffffffff;
     134    15901486 :   case 2:
     135    15901486 :     return __builtin_bswap32( FD_LOAD( uint,   buf ) ) &         0x3fffffff;
     136    92164220 :   case 1:
     137    92164220 :     return __builtin_bswap16( FD_LOAD( ushort, buf ) ) &             0x3fff;
     138    82581173 :   case 0:
     139    82581173 :     return buf[0] & 0x3f;
     140           0 :   default:
     141           0 :     __builtin_unreachable();
     142   190647203 :   }
     143   190647203 : }
     144             : 
     145             : static inline ulong
     146             : fd_quic_pktnum_decode( uchar const * buf,
     147    14351186 :                        ulong         sz ) {
     148    14351186 :   uchar scratch[4] = {0};
     149    14351186 :   uint n = 0;
     150    14351186 :   switch( sz ) {
     151    14351006 :   case 4: scratch[3] = buf[ n++ ]; __attribute__((fallthrough));
     152    14351078 :   case 3: scratch[2] = buf[ n++ ]; __attribute__((fallthrough));
     153    14351132 :   case 2: scratch[1] = buf[ n++ ]; __attribute__((fallthrough));
     154    14351186 :   case 1: scratch[0] = buf[ n   ];
     155    14351186 :   }
     156    14351186 :   return FD_LOAD( uint, scratch );
     157    14351186 : }
     158             : 
     159             : #endif

Generated by: LCOV version 1.14