LCOV - code coverage report
Current view: top level - waltz/quic/templ - fd_quic_parsers.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 59 69 85.5 %
Date: 2024-11-13 11:58:15 Functions: 0 0 -

          Line data    Source code
       1             : // QUIC parsers
       2             : 
       3             : // TODO add platform optimized versions of these
       4             : // e.g. 32 bit unaligned fetch w/ byte swap on intel
       5    27328105 : #define FD_TEMPL_PARSE_IMPL_uchar(p) (                                 \
       6    27328105 :     ( (uchar)((p)[0]) ) )
       7          12 : #define FD_TEMPL_PARSE_IMPL_ushort(p) (                                \
       8          12 :     ( (ushort)((p)[0]) << (ushort)0x08 ) +                             \
       9          12 :     ( (ushort)((p)[1]) << (ushort)0x00 ) )
      10     3060741 : #define FD_TEMPL_PARSE_IMPL_uint(p) (                                  \
      11     3060741 :     (   (uint)((p)[0]) <<   (uint)0x18 ) +                             \
      12     3060741 :     (   (uint)((p)[1]) <<   (uint)0x10 ) +                             \
      13     3060741 :     (   (uint)((p)[2]) <<   (uint)0x08 ) +                             \
      14     3060741 :     (   (uint)((p)[3]) <<   (uint)0x00 ) )
      15             : #define FD_TEMPL_PARSE_IMPL_ulong(p) (                                 \
      16             :     (  (ulong)((p)[0]) <<  (ulong)0x38 ) +                             \
      17             :     (  (ulong)((p)[1]) <<  (ulong)0x30 ) +                             \
      18             :     (  (ulong)((p)[2]) <<  (ulong)0x28 ) +                             \
      19             :     (  (ulong)((p)[3]) <<  (ulong)0x20 ) +                             \
      20             :     (  (ulong)((p)[4]) <<  (ulong)0x18 ) +                             \
      21             :     (  (ulong)((p)[5]) <<  (ulong)0x10 ) +                             \
      22             :     (  (ulong)((p)[6]) <<  (ulong)0x08 ) +                             \
      23             :     (  (ulong)((p)[7]) <<  (ulong)0x00 ) )
      24             : 
      25             : /* assigns parsed value
      26             :    result is the size of the type */
      27             : #define FD_TEMPL_PARSE(TYPE,VAR,p) \
      28    30388894 :   ( ( (VAR) = (__typeof__((VAR)))FD_TEMPL_PARSE_IMPL_##TYPE((p)) ), sizeof(fd_quic_##TYPE) )
      29             : 
      30             : 
      31             : // returns bytes consumed
      32             : #define FD_TEMPL_DEF_STRUCT_BEGIN(NAME)                                \
      33             :   ulong fd_quic_decode_##NAME( fd_quic_##NAME##_t * FD_RESTRICT out,   \
      34             :                                uchar const *        FD_RESTRICT buf,   \
      35    66785409 :                                ulong                            sz ) { \
      36    66785409 :     (void)out; (void)buf; (void)sz;                                    \
      37    66785409 :     ulong cur_byte = 0;                                                \
      38    66785409 :     ulong tmp_len = 0; (void)tmp_len;                                  \
      39             :     // TODO check min size here
      40             : 
      41             : // consumes single aligned byte in input
      42             : #define FD_TEMPL_MBR_FRAME_TYPE(NAME,ID_LO,ID_HI)                      \
      43    45548885 :     out->NAME = buf[cur_byte];                                         \
      44    45548885 :     cur_byte++;
      45             : 
      46             : 
      47             : // consumes aligned bytes in input
      48             : #define FD_TEMPL_MBR_ELEM(NAME,TYPE)                                   \
      49    30388678 :     if( FD_UNLIKELY( cur_byte + sizeof(fd_quic_##TYPE) > sz ) )        \
      50    30388678 :       return FD_QUIC_PARSE_FAIL;                                       \
      51    30388678 :     cur_byte += FD_TEMPL_PARSE(TYPE,out->NAME,buf+cur_byte);
      52             : 
      53             : 
      54             : // always aligned
      55             : // packet numbers have special parsing, due to being protected by
      56             : // header protection
      57             : // stores the offset for packet processing
      58             : #define FD_TEMPL_MBR_ELEM_PKTNUM(NAME,TYPE)                            \
      59    18202432 :     if( FD_UNLIKELY( cur_byte >= sz ) ) return FD_QUIC_PARSE_FAIL;     \
      60    18202432 :     out->NAME##_pnoff = (unsigned)cur_byte;
      61             : 
      62             : 
      63             : // consumes varint
      64             : // always aligned
      65             : // most significant two bits represent the width of the int
      66             : // remaining bits are all data bits
      67             : #define FD_TEMPL_MBR_ELEM_VARINT(NAME,TYPE)                            \
      68    52064363 :   do {                                                                 \
      69    52064363 :     out->NAME = 0;                                                     \
      70    52064363 :     if( FD_UNLIKELY( cur_byte >= sz ) ) return FD_QUIC_PARSE_FAIL;     \
      71    52064363 :     uint msb2 = buf[cur_byte] >> 6u;                                   \
      72    52064018 :     uint vsz  = 1U<<msb2;                                              \
      73    52064018 :     if( FD_UNLIKELY( cur_byte+vsz > sz ) ) return FD_QUIC_PARSE_FAIL;  \
      74    52064018 :     out->NAME = (fd_quic_##TYPE)fd_quic_varint_decode( buf+cur_byte, msb2 ); \
      75    52063706 :     cur_byte += vsz;                                                   \
      76    52063706 :   } while(0);
      77             : 
      78             : 
      79             : // VAR currently assumed to be aligned bytes
      80             : // BITS_MIN and BITS_MAX are always divisible by 8
      81             : #define FD_TEMPL_MBR_ELEM_VAR(NAME,BITS_MIN,BITS_MAX,LEN_NAME)         \
      82    24312838 :     tmp_len = out->LEN_NAME;                                           \
      83    24312838 :     if( FD_UNLIKELY( ( tmp_len < (ulong)(BITS_MIN / 8) ) ||            \
      84    24312838 :                      ( tmp_len > (ulong)(BITS_MAX / 8) ) ) ) {         \
      85         996 :       return FD_QUIC_PARSE_FAIL;                                       \
      86         996 :     }                                                                  \
      87    24312838 :     if( FD_UNLIKELY( cur_byte + tmp_len > sz )) {                      \
      88         207 :       return FD_QUIC_PARSE_FAIL;                                       \
      89         207 :     }                                                                  \
      90   242676471 :     for( ulong j=0; j<tmp_len; ++j ) {                                 \
      91   218364836 :       out->NAME[j] = buf[cur_byte+j];                                  \
      92   218364836 :     }                                                                  \
      93    24311635 :     cur_byte += tmp_len;
      94             : 
      95             : 
      96             : // VAR currently assumed to be aligned bytes
      97             : // BITS_MIN and BITS_MAX are always divisible by 8
      98             : #define FD_TEMPL_MBR_ELEM_VAR_RAW(NAME,BITS_MIN,BITS_MAX,LEN_NAME)     \
      99           0 :     tmp_len = out->LEN_NAME;                                           \
     100           0 :     if( FD_UNLIKELY( ( tmp_len < (ulong)(BITS_MIN / 8) ) ||            \
     101           0 :                      ( tmp_len > (ulong)(BITS_MAX / 8) ) ) ) {         \
     102           0 :       return FD_QUIC_PARSE_FAIL;                                       \
     103           0 :     }                                                                  \
     104           0 :     if( FD_UNLIKELY( cur_byte + tmp_len > sz )) {                      \
     105           0 :       return FD_QUIC_PARSE_FAIL;                                       \
     106           0 :     }                                                                  \
     107           0 :     out->NAME = &buf[cur_byte];                                        \
     108           0 :     cur_byte += tmp_len;
     109             : 
     110             : 
     111             : /* ARRAY is an array of elements, each of the same size,
     112             :    with length implied by the packet size */
     113             : #define FD_TEMPL_MBR_ELEM_ARRAY(NAME,TYPE,BYTES_MIN,BYTES_MAX)         \
     114             :     tmp_len = sz - cur_byte;                                           \
     115             :     if( FD_UNLIKELY( tmp_len > BYTES_MAX ) )                           \
     116             :       tmp_len = BYTES_MAX;                                             \
     117             :     if( FD_UNLIKELY( tmp_len % sizeof(fd_quic_##TYPE) ) )              \
     118             :       return FD_QUIC_PARSE_FAIL;                                       \
     119             :     tmp_len /= sizeof(fd_quic_##TYPE);                                 \
     120             :     out->NAME##_len = (__typeof__(out->NAME##_len))tmp_len;            \
     121             :     for( ulong j=0; j<tmp_len; ++j ) {                                 \
     122             :       cur_byte += FD_TEMPL_PARSE(TYPE,out->NAME[j],buf+cur_byte);      \
     123             :     }
     124             : 
     125             : /* FIXED is an array of elements, each of the same size,
     126             :    with length constant */
     127             : #define FD_TEMPL_MBR_ELEM_FIXED(NAME,TYPE,BYTES)                       \
     128          18 :     if( FD_UNLIKELY( cur_byte+BYTES>sz ) ) return FD_QUIC_PARSE_FAIL;  \
     129          18 :     tmp_len = BYTES / sizeof(fd_quic_##TYPE);                          \
     130          18 :     if( FD_UNLIKELY( tmp_len * sizeof( fd_quic_##TYPE ) >              \
     131          18 :         sizeof( out->NAME ) ) ) return FD_QUIC_PARSE_FAIL;             \
     132         234 :     for( ulong j=0; j<tmp_len; ++j ) {                                 \
     133         216 :       cur_byte += FD_TEMPL_PARSE(TYPE,out->NAME[j],buf+cur_byte);      \
     134         216 :     }
     135             : 
     136             : #define FD_TEMPL_MBR_OPT(TYPE_NAME,NAME,MASK,...)   \
     137   126757251 :     do {                                            \
     138   126757251 :       _Bool cond = out->TYPE_NAME & (MASK);         \
     139   126757251 :       out->NAME##_opt = cond;                       \
     140   126757251 :       if( cond ) {                                  \
     141   157279994 :         __VA_ARGS__                                 \
     142    59343100 :       }                                             \
     143   126757251 :     } while(0);
     144             : 
     145             : 
     146             : // at end, return the number of bytes consumed
     147             : #define FD_TEMPL_DEF_STRUCT_END(NAME) \
     148    66752535 :     return cur_byte;                  \
     149    66783642 :   }
     150             : 
     151             : #include "fd_quic_dft.h"
     152             : 

Generated by: LCOV version 1.14