Line data Source code
1 : #ifndef HEADER_fd_src_waltz_quic_fd_quic_pkt_meta_h 2 : #define HEADER_fd_src_waltz_quic_fd_quic_pkt_meta_h 3 : 4 : #include "fd_quic_common.h" 5 : 6 : typedef struct fd_quic_pkt_meta fd_quic_pkt_meta_t; 7 : typedef struct fd_quic_pkt_meta_list fd_quic_pkt_meta_list_t; 8 : typedef struct fd_quic_pkt_meta_pool fd_quic_pkt_meta_pool_t; 9 : 10 : /* TODO convert to a union with various types of metadata overlaid */ 11 : 12 : /* fd_quic_pkt_meta_var used for tracking max_data, max_stream_data and 13 : * max_streams 14 : * 15 : * type: FD_QUIC_PKT_META_TYPE_STREAM_DATA 16 : * FD_QUIC_PKT_META_TYPE_OTHER 17 : * flags: FD_QUIC_PKT_META_FLAGS_* 18 : * value: max_data number of bytes 19 : * max_stream_data number of bytes 20 : * max_streams number of streams 21 : */ 22 : union fd_quic_pkt_meta_key { 23 : union { 24 12721018 : #define FD_QUIC_PKT_META_STREAM_MASK ((1UL<<62UL)-1UL) 25 : ulong stream_id; 26 : struct { 27 : ulong flags:62; 28 : ulong type:2; 29 0 : #define FD_QUIC_PKT_META_TYPE_OTHER 0UL 30 12721018 : #define FD_QUIC_PKT_META_TYPE_STREAM_DATA 1UL 31 : }; 32 : #define FD_QUIC_PKT_META_KEY( TYPE, FLAGS, STREAM_ID ) \ 33 12727137 : ((fd_quic_pkt_meta_key_t) \ 34 12727137 : { .stream_id = ( ( (ulong)(STREAM_ID) ) | \ 35 12727137 : ( (ulong)(TYPE) << 62UL ) | \ 36 12727137 : ( (ulong)(FLAGS) ) ) } ) 37 : /* FD_QUIC_PKT_META_STREAM_ID 38 : * This is used to extract the stream_id, since some of the bits are used 39 : * for "type". 40 : * The more natural way "stream_id:62" caused compilation warnings and ugly 41 : * work-arounds */ 42 12721018 : #define FD_QUIC_PKT_META_STREAM_ID( KEY ) ( (KEY).stream_id & FD_QUIC_PKT_META_STREAM_MASK ) 43 : }; 44 : }; 45 : typedef union fd_quic_pkt_meta_key fd_quic_pkt_meta_key_t; 46 : 47 : struct fd_quic_pkt_meta_var { 48 : fd_quic_pkt_meta_key_t key; 49 : union { 50 : ulong value; 51 : fd_quic_range_t range; 52 : }; 53 : }; 54 : typedef struct fd_quic_pkt_meta_var fd_quic_pkt_meta_var_t; 55 : 56 : /* the max number of pkt_meta_var entries in pkt_meta 57 : this limits the number of max_data, max_stream_data and max_streams 58 : allowed in a single quic packet */ 59 12727227 : #define FD_QUIC_PKT_META_VAR_MAX 16 60 : 61 : /* fd_quic_pkt_meta 62 : 63 : tracks the metadata of data sent to the peer 64 : used when acks arrive to determine what is being acked specifically */ 65 : struct fd_quic_pkt_meta { 66 : /* stores metadata about what was sent in the identified packet */ 67 : ulong pkt_number; /* packet number (in pn_space) */ 68 : uchar enc_level; /* encryption level of packet */ 69 : uchar pn_space; /* packet number space (derived from enc_level) */ 70 : uchar var_sz; /* number of populated entries in var */ 71 : 72 : /* does/should the referenced packet contain: 73 : FD_QUIC_PKT_META_FLAGS_HS_DATA handshake data 74 : FD_QUIC_PKT_META_FLAGS_STREAM stream data 75 : FD_QUIC_PKT_META_FLAGS_HS_DONE handshake-done frame 76 : FD_QUIC_PKT_META_FLAGS_MAX_DATA max_data frame 77 : FD_QUIC_PKT_META_FLAGS_MAX_STREAMS_UNIDIR max_streams frame (unidir) 78 : FD_QUIC_PKT_META_FLAGS_CLOSE close frame 79 : FD_QUIC_PKT_META_FLAGS_PING set to send a PING frame 80 : 81 : some of these flags are mutually exclusive */ 82 : uint flags; /* flags */ 83 12775159 : # define FD_QUIC_PKT_META_FLAGS_HS_DATA (1u<<0u) 84 25478233 : # define FD_QUIC_PKT_META_FLAGS_STREAM (1u<<1u) 85 27114120 : # define FD_QUIC_PKT_META_FLAGS_HS_DONE (1u<<2u) 86 12751096 : # define FD_QUIC_PKT_META_FLAGS_MAX_DATA (1u<<3u) 87 27108105 : # define FD_QUIC_PKT_META_FLAGS_MAX_STREAMS_UNIDIR (1u<<5u) 88 12105 : # define FD_QUIC_PKT_META_FLAGS_CLOSE (1u<<8u) 89 : fd_quic_range_t range; /* CRYPTO data range; FIXME use pkt_meta var instead */ 90 : ulong stream_id; /* if this contains stream data, 91 : the stream id, else zero */ 92 : 93 : ulong expiry; /* time pkt_meta expires... this is the time the 94 : ack is expected by */ 95 : 96 : fd_quic_pkt_meta_var_t var[FD_QUIC_PKT_META_VAR_MAX]; 97 : 98 : fd_quic_pkt_meta_t * next; /* next in current list */ 99 : }; 100 : 101 : 102 : struct fd_quic_pkt_meta_list { 103 : fd_quic_pkt_meta_t * head; 104 : fd_quic_pkt_meta_t * tail; 105 : }; 106 : 107 : 108 : struct fd_quic_pkt_meta_pool { 109 : fd_quic_pkt_meta_list_t free; /* free pkt_meta */ 110 : 111 : /* one of each of these for each enc_level */ 112 : fd_quic_pkt_meta_list_t sent_pkt_meta[4]; /* sent pkt_meta */ 113 : }; 114 : 115 : 116 : 117 : FD_PROTOTYPES_BEGIN 118 : 119 : /* initialize pool with existing array of pkt_meta */ 120 : void 121 : fd_quic_pkt_meta_pool_init( fd_quic_pkt_meta_pool_t * pool, 122 : fd_quic_pkt_meta_t * pkt_meta_array, 123 : ulong pkt_meta_array_sz ); 124 : 125 : /* pop from front of list */ 126 : fd_quic_pkt_meta_t * 127 : fd_quic_pkt_meta_pop_front( fd_quic_pkt_meta_list_t * list ); 128 : 129 : 130 : /* push onto front of list */ 131 : void 132 : fd_quic_pkt_meta_push_front( fd_quic_pkt_meta_list_t * list, 133 : fd_quic_pkt_meta_t * pkt_meta ); 134 : 135 : /* push onto back of list */ 136 : void 137 : fd_quic_pkt_meta_push_back( fd_quic_pkt_meta_list_t * list, 138 : fd_quic_pkt_meta_t * pkt_meta ); 139 : 140 : /* remove from list 141 : requires the prior element */ 142 : void 143 : fd_quic_pkt_meta_remove( fd_quic_pkt_meta_list_t * list, 144 : fd_quic_pkt_meta_t * pkt_meta_prior, 145 : fd_quic_pkt_meta_t * pkt_meta ); 146 : 147 : 148 : /* allocate a pkt_meta 149 : obtains a free pkt_meta from the free list, and returns it 150 : returns NULL if none is available */ 151 : fd_quic_pkt_meta_t * 152 : fd_quic_pkt_meta_allocate( fd_quic_pkt_meta_pool_t * pool ); 153 : 154 : 155 : /* free a pkt_meta 156 : returns a pkt_meta to the free list, ready to be allocated again */ 157 : void 158 : fd_quic_pkt_meta_deallocate( fd_quic_pkt_meta_pool_t * pool, 159 : fd_quic_pkt_meta_t * pkt_meta ); 160 : 161 : FD_PROTOTYPES_END 162 : 163 : #endif // HEADER_fd_src_waltz_quic_fd_quic_pkt_meta_h 164 :