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