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 17005375798 : fd_quic_varint_min_sz_unsafe( ulong val ) { 11 17005375798 : int sz_class = fd_uint_find_msb( (uint)fd_ulong_find_msb( val|0x3fUL ) + 2 ) - 2; 12 17005375798 : return 1U<<sz_class; 13 17005375798 : } 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 93845728 : ulong val ) { 23 : /* max out at 0x3fffffffffffffffUL */ 24 93845728 : 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 93845728 : 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 93845728 : 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 93845728 : ulong encoded = fd_ulong_bswap( shifted ); 49 : 50 : /* set length indication */ 51 : 52 93845728 : encoded &= 0xffffffffffffff3fUL; 53 93845728 : encoded |= ((ulong)fd_uint_find_msb( sz ))<<6; 54 : 55 93845728 : FD_STORE( ulong, out, encoded ); 56 93845728 : return sz; 57 93845728 : } 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 13856926 : fd_quic_h0_hdr_form( uchar hdr ) { 78 13856926 : return hdr>>7; 79 13856926 : } 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 73366450 : fd_quic_h0_pkt_num_len( uint h0 ) { 91 73366450 : return (uchar)( h0 & 0x03 ); 92 73366450 : } 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 13827817 : uint pkt_num_len /* [0,3] */ ) { 108 13827817 : return (uchar)( 0x40 | (spin_bit<<5) | (key_phase<<2) | pkt_num_len ); 109 13827817 : } 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 13815808 : fd_quic_one_rtt_key_phase( uint h0 ) { 118 13815808 : return (uint)( (h0>>2) & 1 ); 119 13815808 : } 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 185909663 : uint msb2 ) { 131 185909663 : switch( msb2 ) { 132 324 : case 3: 133 324 : return __builtin_bswap64( FD_LOAD( ulong, buf ) ) & 0x3fffffffffffffff; 134 14056998 : case 2: 135 14056998 : return __builtin_bswap32( FD_LOAD( uint, buf ) ) & 0x3fffffff; 136 92465285 : case 1: 137 92465285 : return __builtin_bswap16( FD_LOAD( ushort, buf ) ) & 0x3fff; 138 79387056 : case 0: 139 79387056 : return buf[0] & 0x3f; 140 0 : default: 141 0 : __builtin_unreachable(); 142 185909663 : } 143 185909663 : } 144 : 145 : static inline ulong 146 : fd_quic_pktnum_decode( uchar const * buf, 147 13840138 : ulong sz ) { 148 13840138 : uchar scratch[4] = {0}; 149 13840138 : uint n = 0; 150 13840138 : switch( sz ) { 151 13839958 : case 4: scratch[3] = buf[ n++ ]; __attribute__((fallthrough)); 152 13840030 : case 3: scratch[2] = buf[ n++ ]; __attribute__((fallthrough)); 153 13840084 : case 2: scratch[1] = buf[ n++ ]; __attribute__((fallthrough)); 154 13840138 : case 1: scratch[0] = buf[ n ]; 155 13840138 : } 156 13840138 : return FD_LOAD( uint, scratch ); 157 13840138 : } 158 : 159 : #endif