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 101206257 : #define FD_TEMPL_PARSE_IMPL_uchar(p) ( \ 6 101206257 : ( (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 3058584 : #define FD_TEMPL_PARSE_IMPL_uint(p) ( \ 11 3058584 : ( (uint)((p)[0]) << (uint)0x18 ) + \ 12 3058584 : ( (uint)((p)[1]) << (uint)0x10 ) + \ 13 3058584 : ( (uint)((p)[2]) << (uint)0x08 ) + \ 14 3058584 : ( (uint)((p)[3]) << (uint)0x00 ) ) 15 15 : #define FD_TEMPL_PARSE_IMPL_ulong(p) ( \ 16 15 : ( (ulong)((p)[0]) << (ulong)0x38 ) + \ 17 15 : ( (ulong)((p)[1]) << (ulong)0x30 ) + \ 18 15 : ( (ulong)((p)[2]) << (ulong)0x28 ) + \ 19 15 : ( (ulong)((p)[3]) << (ulong)0x20 ) + \ 20 15 : ( (ulong)((p)[4]) << (ulong)0x18 ) + \ 21 15 : ( (ulong)((p)[5]) << (ulong)0x10 ) + \ 22 15 : ( (ulong)((p)[6]) << (ulong)0x08 ) + \ 23 15 : ( (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 104264916 : ( ( (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 95429385 : ulong sz ) { \ 36 95429385 : (void)out; (void)buf; (void)sz; \ 37 95429385 : ulong cur_byte = 0; \ 38 95429385 : 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 311688 : out->NAME = buf[cur_byte]; \ 44 311688 : cur_byte++; 45 : 46 : 47 : // consumes aligned bytes in input 48 : #define FD_TEMPL_MBR_ELEM(NAME,TYPE) \ 49 104264916 : if( FD_UNLIKELY( cur_byte + sizeof(fd_quic_##TYPE) > sz ) ) \ 50 104264916 : return FD_QUIC_PARSE_FAIL; \ 51 104264916 : 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 26229 : if( FD_UNLIKELY( cur_byte >= sz ) ) return FD_QUIC_PARSE_FAIL; \ 60 26229 : 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 185278320 : do { \ 69 185278320 : out->NAME = 0; \ 70 185278320 : if( FD_UNLIKELY( cur_byte >= sz ) ) return FD_QUIC_PARSE_FAIL; \ 71 185278320 : uint msb2 = buf[cur_byte] >> 6u; \ 72 185277993 : uint vsz = 1U<<msb2; \ 73 185277993 : if( FD_UNLIKELY( cur_byte+vsz > sz ) ) return FD_QUIC_PARSE_FAIL; \ 74 185277993 : out->NAME = (fd_quic_##TYPE)fd_quic_varint_decode( buf+cur_byte, msb2 ); \ 75 185277717 : cur_byte += vsz; \ 76 185277717 : } 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 6116943 : tmp_len = out->LEN_NAME; \ 82 6116943 : if( FD_UNLIKELY( tmp_len<(MIN) || tmp_len>(MAX) ) ) { \ 83 228 : return FD_QUIC_PARSE_FAIL; \ 84 228 : } \ 85 6116943 : if( FD_UNLIKELY( cur_byte + tmp_len > sz )) { \ 86 120 : return FD_QUIC_PARSE_FAIL; \ 87 120 : } \ 88 79051959 : for( ulong j=0; j<tmp_len; ++j ) { \ 89 72935364 : out->NAME[j] = buf[cur_byte+j]; \ 90 72935364 : } \ 91 6116595 : 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 15360 : tmp_len = out->LEN_NAME; \ 97 15360 : if( FD_UNLIKELY( tmp_len<(MIN) || tmp_len>(MAX) ) ) { \ 98 693 : return FD_QUIC_PARSE_FAIL; \ 99 693 : } \ 100 15360 : if( FD_UNLIKELY( cur_byte + tmp_len > sz )) { \ 101 87 : return FD_QUIC_PARSE_FAIL; \ 102 87 : } \ 103 14667 : out->NAME = &buf[cur_byte]; \ 104 14580 : 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 95415177 : return cur_byte; \ 116 95427717 : } 117 : 118 : #include "fd_quic_dft.h" 119 :