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 : 8 : static inline uint 9 16995442056 : fd_quic_varint_min_sz( ulong val ) { 10 16995442056 : val = fd_ulong_min( val, 0x3fffffffffffffffUL ); 11 16995442056 : int sz_class = fd_uint_find_msb( (uint)fd_ulong_find_msb( val|0x3fUL ) + 2 ) - 2; 12 16995442056 : return 1U<<sz_class; 13 16995442056 : } 14 : 15 : static inline uint 16 : fd_quic_varint_encode( uchar out[8], 17 83912034 : ulong val ) { 18 : 19 : /* input byte pattern: 20 : - sz 1: aa 00 00 00 00 00 00 00 21 : - sz 2: aa bb 00 00 00 00 00 00 22 : - sz 4: aa bb cc dd 00 00 00 00 23 : - sz 8: aa bb cc dd ee ff ff gg */ 24 : 25 83912034 : uint sz = fd_quic_varint_min_sz( val ); 26 : 27 : /* shifted byte pattern 28 : - sz 1: 00 00 00 00 00 00 00 aa 29 : - sz 2: 00 00 00 00 00 00 aa bb 30 : - sz 4: 00 00 00 00 aa bb cc dd 31 : - sz 8: aa bb cc dd ee ff ff gg */ 32 : 33 83912034 : ulong shifted = val << ( 8 * ( 8 - sz ) ); 34 : 35 : /* swapped byte pattern 36 : - sz 1: aa 00 00 00 00 00 00 00 37 : - sz 2: bb aa 00 00 00 00 00 00 38 : - sz 4: dd cc bb aa 00 00 00 00 39 : - sz 8: gg ff ee dd cc bb aa 00 */ 40 : 41 83912034 : ulong encoded = fd_ulong_bswap( shifted ); 42 : 43 : /* set length indication */ 44 : 45 83912034 : encoded &= 0xffffffffffffff3fUL; 46 83912034 : encoded |= ((ulong)fd_uint_find_msb( sz ))<<6; 47 : 48 83912034 : FD_STORE( ulong, out, encoded ); 49 83912034 : return sz; 50 83912034 : } 51 : 52 : 53 : /* encode a VARINT "val" into "buf" of size "buf_sz" 54 : buf must be a mutable uchar pointer, and will be updated to point to 55 : the remaining buffer 56 : buf_sz must be a mutable integer and will be reduced by the number of 57 : bytes written 58 : bounds are checked before writing into buf */ 59 : #define FD_QUIC_ENCODE_VARINT(buf,buf_sz,val) \ 60 349029 : do { \ 61 349029 : if( FD_UNLIKELY( buf_sz<8 ) ) return FD_QUIC_ENCODE_FAIL; \ 62 349029 : uint sz = fd_quic_varint_encode( buf, (val) ); \ 63 349029 : buf += sz; buf_sz -= sz; \ 64 349029 : } while(0); 65 : 66 : /* fd_quic_h0_hdr_form extract the 'Header Form' bit, the first bit of a QUIC v1 packet. 67 : Returns 1 if the packet is a long header packet, 0 if the packet is a short header packet. 68 : Does not require decryption of the packet header. */ 69 : static inline uchar 70 18217240 : fd_quic_h0_hdr_form( uchar hdr ) { 71 18217240 : return hdr>>7; 72 18217240 : } 73 : 74 : /* fd_quic_h0_long_packet_type extracts the 'Long Packet Type' from 75 : the first byte of a QUIC v1 long header packet. Returns FD_QUIC_PKTTYPE_V1_{...} 76 : in range [0,4). Does not require decryption of the packet header. */ 77 : static inline uchar 78 28920 : fd_quic_h0_long_packet_type( uchar hdr ) { 79 28920 : return (hdr>>4)&3; 80 28920 : } 81 : 82 : static inline uchar 83 92017232 : fd_quic_h0_pkt_num_len( uint h0 ) { 84 92017232 : return (uchar)( h0 & 0x03 ); 85 92017232 : } 86 : 87 : static inline uchar 88 12852 : fd_quic_initial_h0( uint pkt_num_len /* [0,3] */ ) { 89 12852 : return (uchar)( 0xc0 | pkt_num_len ); 90 12852 : } 91 : 92 : static inline uchar 93 12186 : fd_quic_handshake_h0( uint pkt_num_len /* [0,3] */ ) { 94 12186 : return (uchar)( 0xe0 | pkt_num_len ); 95 12186 : } 96 : 97 : static inline uchar 98 : fd_quic_one_rtt_h0( uint spin_bit, /* [0,1] */ 99 : uint key_phase, /* [0,1] */ 100 19393871 : uint pkt_num_len /* [0,3] */ ) { 101 19393871 : return (uchar)( 0x40 | (spin_bit<<5) | (key_phase<<2) | pkt_num_len ); 102 19393871 : } 103 : 104 : __attribute__((used)) static ulong 105 : fd_quic_varint_decode( uchar const * buf, 106 77698652 : uint msb2 ) { 107 77698652 : switch( msb2 ) { 108 1067186 : case 3: 109 1067186 : return __builtin_bswap64( FD_LOAD( ulong, buf ) ) & 0x3fffffffffffffff; 110 21293855 : case 2: 111 21293855 : return __builtin_bswap32( FD_LOAD( uint, buf ) ) & 0x3fffffff; 112 37741452 : case 1: 113 37741452 : return __builtin_bswap16( FD_LOAD( ushort, buf ) ) & 0x3fff; 114 17596159 : case 0: 115 17596159 : return buf[0] & 0x3f; 116 0 : default: 117 0 : __builtin_unreachable(); 118 77698652 : } 119 77698652 : } 120 : 121 : static inline ulong 122 : fd_quic_pktnum_decode( uchar const * buf, 123 18201574 : ulong sz ) { 124 18201574 : uchar scratch[4] = {0}; 125 18201574 : uint n = 0; 126 18201574 : switch( sz ) { 127 18200077 : case 4: scratch[3] = buf[ n++ ]; __attribute__((fallthrough)); 128 18201106 : case 3: scratch[2] = buf[ n++ ]; __attribute__((fallthrough)); 129 18201292 : case 2: scratch[1] = buf[ n++ ]; __attribute__((fallthrough)); 130 18201574 : case 1: scratch[0] = buf[ n ]; 131 18201574 : } 132 18201574 : return FD_LOAD( uint, scratch ); 133 18201574 : } 134 : 135 : #endif