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 13553787 : #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 13553787 : #define FD_QUIC_PKT_META_TYPE_STREAM_DATA 1UL 31 : }; 32 : #define FD_QUIC_PKT_META_KEY( TYPE, FLAGS, STREAM_ID ) \ 33 13560005 : ((fd_quic_pkt_meta_key_t) \ 34 13560005 : { .stream_id = ( ( (ulong)(STREAM_ID) ) | \ 35 13560005 : ( (ulong)(TYPE) << 62UL ) | \ 36 13560005 : ( (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 13553787 : #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 13560005 : #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 13607928 : # define FD_QUIC_PKT_META_FLAGS_HS_DATA (1u<<0u) 84 27143870 : # define FD_QUIC_PKT_META_FLAGS_STREAM (1u<<1u) 85 13589880 : # define FD_QUIC_PKT_META_FLAGS_HS_DONE (1u<<2u) 86 13583865 : # define FD_QUIC_PKT_META_FLAGS_MAX_DATA (1u<<3u) 87 27429826 : # define FD_QUIC_PKT_META_FLAGS_MAX_STREAMS_UNIDIR (1u<<4u) 88 12105 : # define FD_QUIC_PKT_META_FLAGS_CLOSE (1u<<5u) 89 13583865 : # define FD_QUIC_PKT_META_FLAGS_PING (1u<<6u) 90 : fd_quic_range_t range; /* CRYPTO data range; FIXME use pkt_meta var instead */ 91 : ulong stream_id; /* if this contains stream data, 92 : the stream id, else zero */ 93 : 94 : ulong tx_time; /* transmit time */ 95 : ulong expiry; /* time pkt_meta expires... this is the time the 96 : ack is expected by */ 97 : 98 : fd_quic_pkt_meta_var_t var[FD_QUIC_PKT_META_VAR_MAX]; 99 : 100 : fd_quic_pkt_meta_t * next; /* next in current list */ 101 : }; 102 : 103 : 104 : struct fd_quic_pkt_meta_list { 105 : fd_quic_pkt_meta_t * head; 106 : fd_quic_pkt_meta_t * tail; 107 : }; 108 : 109 : 110 : struct fd_quic_pkt_meta_pool { 111 : fd_quic_pkt_meta_list_t free; /* free pkt_meta */ 112 : 113 : /* one of each of these for each enc_level */ 114 : fd_quic_pkt_meta_list_t sent_pkt_meta[4]; /* sent pkt_meta */ 115 : }; 116 : 117 : 118 : 119 : FD_PROTOTYPES_BEGIN 120 : 121 : /* initialize pool with existing array of pkt_meta */ 122 : void 123 : fd_quic_pkt_meta_pool_init( fd_quic_pkt_meta_pool_t * pool, 124 : fd_quic_pkt_meta_t * pkt_meta_array, 125 : ulong pkt_meta_array_sz ); 126 : 127 : /* pop from front of list */ 128 : fd_quic_pkt_meta_t * 129 : fd_quic_pkt_meta_pop_front( fd_quic_pkt_meta_list_t * list ); 130 : 131 : 132 : /* push onto front of list */ 133 : void 134 : fd_quic_pkt_meta_push_front( fd_quic_pkt_meta_list_t * list, 135 : fd_quic_pkt_meta_t * pkt_meta ); 136 : 137 : /* push onto back of list */ 138 : void 139 : fd_quic_pkt_meta_push_back( fd_quic_pkt_meta_list_t * list, 140 : fd_quic_pkt_meta_t * pkt_meta ); 141 : 142 : /* remove from list 143 : requires the prior element */ 144 : void 145 : fd_quic_pkt_meta_remove( fd_quic_pkt_meta_list_t * list, 146 : fd_quic_pkt_meta_t * pkt_meta_prior, 147 : fd_quic_pkt_meta_t * pkt_meta ); 148 : 149 : 150 : /* allocate a pkt_meta 151 : obtains a free pkt_meta from the free list, and returns it 152 : returns NULL if none is available */ 153 : fd_quic_pkt_meta_t * 154 : fd_quic_pkt_meta_allocate( fd_quic_pkt_meta_pool_t * pool ); 155 : 156 : 157 : /* free a pkt_meta 158 : returns a pkt_meta to the free list, ready to be allocated again */ 159 : void 160 : fd_quic_pkt_meta_deallocate( fd_quic_pkt_meta_pool_t * pool, 161 : fd_quic_pkt_meta_t * pkt_meta ); 162 : 163 : FD_PROTOTYPES_END 164 : 165 : #endif // HEADER_fd_src_waltz_quic_fd_quic_pkt_meta_h 166 :