Line data Source code
1 : #ifndef HEADER_fd_src_waltz_quic_templ_fd_quic_parse_util_h 2 : #define HEADER_fd_src_waltz_quic_templ_fd_quic_parse_util_h 3 : 4 : #include <stddef.h> 5 : 6 : #include "../fd_quic_common.h" 7 : #include "../../../util/log/fd_log.h" 8 : 9 : static inline uint 10 17067523335 : fd_quic_varint_min_sz_unsafe( ulong val ) { 11 17067523335 : int sz_class = fd_uint_find_msb( (uint)fd_ulong_find_msb( val|0x3fUL ) + 2 ) - 2; 12 17067523335 : return 1U<<sz_class; 13 17067523335 : } 14 : 15 : static inline uint 16 16911531336 : fd_quic_varint_min_sz( ulong val ) { 17 16911531336 : return fd_quic_varint_min_sz_unsafe( fd_ulong_min( val, 0x3fffffffffffffffUL ) ); 18 16911531336 : } 19 : 20 : static inline uint 21 : fd_quic_varint_encode( uchar out[8], 22 155991999 : ulong val ) { 23 : /* max out at 0x3fffffffffffffffUL */ 24 155991999 : 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 155991999 : 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 155991999 : 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 155991999 : ulong encoded = fd_ulong_bswap( shifted ); 49 : 50 : /* set length indication */ 51 : 52 155991999 : encoded &= 0xffffffffffffff3fUL; 53 155991999 : encoded |= ((ulong)fd_uint_find_msb( sz ))<<6; 54 : 55 155991999 : FD_STORE( ulong, out, encoded ); 56 155991999 : return sz; 57 155991999 : } 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 353679 : do { \ 68 353679 : if( FD_UNLIKELY( buf_sz<8 ) ) return FD_QUIC_ENCODE_FAIL; \ 69 353679 : uint sz = fd_quic_varint_encode( buf, (val) ); \ 70 353679 : buf += sz; buf_sz -= sz; \ 71 353679 : } 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 30929917 : fd_quic_h0_hdr_form( uchar hdr ) { 78 30929917 : return hdr>>7; 79 30929917 : } 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 34164 : fd_quic_h0_long_packet_type( uchar hdr ) { 86 34164 : return (hdr>>4)&3; 87 34164 : } 88 : 89 : static inline uchar 90 135718615 : fd_quic_h0_pkt_num_len( uint h0 ) { 91 135718615 : return (uchar)( h0 & 0x03 ); 92 135718615 : } 93 : 94 : static inline uchar 95 18300 : fd_quic_initial_h0( uint pkt_num_len /* [0,3] */ ) { 96 18300 : return (uchar)( 0xc0 | pkt_num_len ); 97 18300 : } 98 : 99 : static inline uchar 100 12141 : fd_quic_handshake_h0( uint pkt_num_len /* [0,3] */ ) { 101 12141 : return (uchar)( 0xe0 | pkt_num_len ); 102 12141 : } 103 : 104 : static inline uchar 105 : fd_quic_one_rtt_h0( uint spin_bit, /* [0,1] */ 106 : uint key_phase, /* [0,1] */ 107 30888802 : uint pkt_num_len /* [0,3] */ ) { 108 30888802 : return (uchar)( 0x40 | (spin_bit<<5) | (key_phase<<2) | pkt_num_len ); 109 30888802 : } 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 30882505 : fd_quic_one_rtt_key_phase( uint h0 ) { 118 30882505 : return (uint)( (h0>>2) & 1 ); 119 30882505 : } 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 309236532 : uint msb2 ) { 131 309236532 : switch( msb2 ) { 132 324 : case 3: 133 324 : return __builtin_bswap64( FD_LOAD( ulong, buf ) ) & 0x3fffffffffffffff; 134 31348102 : case 2: 135 31348102 : return __builtin_bswap32( FD_LOAD( uint, buf ) ) & 0x3fffffff; 136 153656544 : case 1: 137 153656544 : return __builtin_bswap16( FD_LOAD( ushort, buf ) ) & 0x3fff; 138 124231562 : case 0: 139 124231562 : return buf[0] & 0x3f; 140 0 : default: 141 0 : FD_LOG_CRIT(( "invalid msb2 %u", msb2 )); 142 309236532 : } 143 309236532 : } 144 : 145 : static inline ulong 146 : fd_quic_pktnum_decode( uchar const * buf, 147 30913129 : ulong sz ) { 148 30913129 : uchar scratch[4] = {0}; 149 30913129 : uint n = 0; 150 30913129 : switch( sz ) { 151 30912949 : case 4: scratch[3] = buf[ n++ ]; __attribute__((fallthrough)); 152 30913021 : case 3: scratch[2] = buf[ n++ ]; __attribute__((fallthrough)); 153 30913075 : case 2: scratch[1] = buf[ n++ ]; __attribute__((fallthrough)); 154 30913129 : case 1: scratch[0] = buf[ n ]; 155 30913129 : } 156 30913129 : return FD_LOAD( uint, scratch ); 157 30913129 : } 158 : 159 : #endif /* HEADER_fd_src_waltz_quic_templ_fd_quic_parse_util_h */