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 101193744 : #define FD_TEMPL_PARSE_IMPL_uchar(p) ( \ 6 101193744 : ( (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 3058533 : #define FD_TEMPL_PARSE_IMPL_uint(p) ( \ 11 3058533 : ( (uint)((p)[0]) << (uint)0x18 ) + \ 12 3058533 : ( (uint)((p)[1]) << (uint)0x10 ) + \ 13 3058533 : ( (uint)((p)[2]) << (uint)0x08 ) + \ 14 3058533 : ( (uint)((p)[3]) << (uint)0x00 ) ) 15 3 : #define FD_TEMPL_PARSE_IMPL_ulong(p) ( \ 16 3 : ( (ulong)((p)[0]) << (ulong)0x38 ) + \ 17 3 : ( (ulong)((p)[1]) << (ulong)0x30 ) + \ 18 3 : ( (ulong)((p)[2]) << (ulong)0x28 ) + \ 19 3 : ( (ulong)((p)[3]) << (ulong)0x20 ) + \ 20 3 : ( (ulong)((p)[4]) << (ulong)0x18 ) + \ 21 3 : ( (ulong)((p)[5]) << (ulong)0x10 ) + \ 22 3 : ( (ulong)((p)[6]) << (ulong)0x08 ) + \ 23 3 : ( (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 104252328 : ( ( (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 98358321 : ulong sz ) { \ 36 98358321 : (void)out; (void)buf; (void)sz; \ 37 98358321 : ulong cur_byte = 0; \ 38 98358321 : 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 3253059 : out->NAME = buf[cur_byte]; \ 44 3253059 : cur_byte++; 45 : 46 : 47 : // consumes aligned bytes in input 48 : #define FD_TEMPL_MBR_ELEM(NAME,TYPE) \ 49 104252328 : if( FD_UNLIKELY( cur_byte + sizeof(fd_quic_##TYPE) > sz ) ) \ 50 104252328 : return FD_QUIC_PARSE_FAIL; \ 51 104252328 : 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 26202 : if( FD_UNLIKELY( cur_byte >= sz ) ) return FD_QUIC_PARSE_FAIL; \ 60 26202 : 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 190647806 : do { \ 69 190647806 : out->NAME = 0; \ 70 190647806 : if( FD_UNLIKELY( cur_byte >= sz ) ) return FD_QUIC_PARSE_FAIL; \ 71 190647806 : uint msb2 = buf[cur_byte] >> 6u; \ 72 190647479 : uint vsz = 1U<<msb2; \ 73 190647479 : if( FD_UNLIKELY( cur_byte+vsz > sz ) ) return FD_QUIC_PARSE_FAIL; \ 74 190647479 : out->NAME = (fd_quic_##TYPE)fd_quic_varint_decode( buf+cur_byte, msb2 ); \ 75 190647203 : cur_byte += vsz; \ 76 190647203 : } while(0); 77 : 78 : 79 : // VAR currently assumed to be aligned bytes 80 : #define FD_TEMPL_MBR_ELEM_VAR(NAME,MIN,MAX,LEN_NAME) \ 81 6116841 : tmp_len = out->LEN_NAME; \ 82 6116841 : if( FD_UNLIKELY( tmp_len<(MIN) || tmp_len>(MAX) ) ) { \ 83 228 : return FD_QUIC_PARSE_FAIL; \ 84 228 : } \ 85 6116841 : if( FD_UNLIKELY( cur_byte + tmp_len > sz )) { \ 86 120 : return FD_QUIC_PARSE_FAIL; \ 87 120 : } \ 88 79051041 : for( ulong j=0; j<tmp_len; ++j ) { \ 89 72934548 : out->NAME[j] = buf[cur_byte+j]; \ 90 72934548 : } \ 91 6116493 : cur_byte += tmp_len; 92 : 93 : 94 : // VAR currently assumed to be aligned bytes 95 : #define FD_TEMPL_MBR_ELEM_VAR_RAW(NAME,MIN,MAX,LEN_NAME) \ 96 15345 : tmp_len = out->LEN_NAME; \ 97 15345 : if( FD_UNLIKELY( tmp_len<(MIN) || tmp_len>(MAX) ) ) { \ 98 693 : return FD_QUIC_PARSE_FAIL; \ 99 693 : } \ 100 15345 : if( FD_UNLIKELY( cur_byte + tmp_len > sz )) { \ 101 87 : return FD_QUIC_PARSE_FAIL; \ 102 87 : } \ 103 14652 : out->NAME = &buf[cur_byte]; \ 104 14565 : cur_byte += tmp_len; 105 : 106 : 107 : #define FD_TEMPL_MBR_ELEM_RAW(NAME,BYTES) \ 108 18 : if( FD_UNLIKELY( cur_byte+(BYTES)>sz ) ) return FD_QUIC_PARSE_FAIL;\ 109 18 : memcpy( out->NAME, buf+cur_byte, (BYTES) ); \ 110 18 : cur_byte += (BYTES); 111 : 112 : 113 : // at end, return the number of bytes consumed 114 : #define FD_TEMPL_DEF_STRUCT_END(NAME) \ 115 96751274 : return cur_byte; \ 116 98356653 : } 117 : 118 : #include "fd_quic_dft.h" 119 :