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 34175269 : #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 4405726 : #define FD_QUIC_PKT_META_TYPE_OTHER 0UL 30 34175269 : #define FD_QUIC_PKT_META_TYPE_STREAM_DATA 1UL 31 : }; 32 : #define FD_QUIC_PKT_META_KEY( TYPE, FLAGS, STREAM_ID ) \ 33 17090693 : ((fd_quic_pkt_meta_key_t) \ 34 17090693 : { .stream_id = ( ( (ulong)(STREAM_ID) ) | \ 35 17090693 : ( (ulong)(TYPE) << 62UL ) | \ 36 17090693 : ( (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 34175269 : #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 19363805 : #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; /* the packet number */ 68 : uchar enc_level; /* every packet is sent at a specific 69 : enc_level */ 70 : uchar pn_space; /* packet number space (must be consistent 71 : with enc_level) */ 72 : uchar var_sz; /* number of populated entries in var */ 73 : 74 : /* does/should the referenced packet contain: 75 : FD_QUIC_PKT_META_FLAGS_HS_DATA handshake data 76 : FD_QUIC_PKT_META_FLAGS_STREAM stream data 77 : FD_QUIC_PKT_META_FLAGS_HS_DONE handshake-done frame 78 : FD_QUIC_PKT_META_FLAGS_MAX_DATA max_data frame 79 : FD_QUIC_PKT_META_FLAGS_MAX_STREAMS_UNIDIR max_streams frame (unidir) 80 : FD_QUIC_PKT_META_FLAGS_CLOSE close frame 81 : FD_QUIC_PKT_META_FLAGS_KEY_UPDATE indicates key update was in effect 82 : FD_QUIC_PKT_META_FLAGS_KEY_PHASE set only if key_phase was set in the short-header 83 : FD_QUIC_PKT_META_FLAGS_PING set to send a PING frame 84 : 85 : some of these flags are mutually exclusive */ 86 : uint flags; /* flags */ 87 18530476 : # define FD_QUIC_PKT_META_FLAGS_HS_DATA (1u<<0u) 88 55009631 : # define FD_QUIC_PKT_META_FLAGS_STREAM (1u<<1u) 89 37924950 : # define FD_QUIC_PKT_META_FLAGS_HS_DONE (1u<<2u) 90 21845844 : # define FD_QUIC_PKT_META_FLAGS_MAX_DATA (1u<<3u) 91 37918938 : # define FD_QUIC_PKT_META_FLAGS_MAX_STREAMS_UNIDIR (1u<<5u) 92 338109 : # define FD_QUIC_PKT_META_FLAGS_CLOSE (1u<<8u) 93 11069674 : # define FD_QUIC_PKT_META_FLAGS_KEY_UPDATE (1u<<9u) 94 11069674 : # define FD_QUIC_PKT_META_FLAGS_KEY_PHASE (1u<<10u) 95 : fd_quic_range_t range; /* range of bytes referred to by this meta */ 96 : /* stream data or crypto data */ 97 : /* we currently do not put both in the same packet */ 98 : ulong stream_id; /* if this contains stream data, 99 : the stream id, else zero */ 100 : 101 : ulong expiry; /* time pkt_meta expires... this is the time the 102 : ack is expected by */ 103 : 104 : fd_quic_pkt_meta_var_t var[FD_QUIC_PKT_META_VAR_MAX]; 105 : 106 : fd_quic_pkt_meta_t * next; /* next in current list */ 107 : }; 108 : 109 : 110 : struct fd_quic_pkt_meta_list { 111 : fd_quic_pkt_meta_t * head; 112 : fd_quic_pkt_meta_t * tail; 113 : }; 114 : 115 : 116 : struct fd_quic_pkt_meta_pool { 117 : fd_quic_pkt_meta_list_t free; /* free pkt_meta */ 118 : 119 : /* one of each of these for each enc_level */ 120 : fd_quic_pkt_meta_list_t sent_pkt_meta[4]; /* sent pkt_meta */ 121 : }; 122 : 123 : 124 : 125 : FD_PROTOTYPES_BEGIN 126 : 127 : /* initialize pool with existing array of pkt_meta */ 128 : void 129 : fd_quic_pkt_meta_pool_init( fd_quic_pkt_meta_pool_t * pool, 130 : fd_quic_pkt_meta_t * pkt_meta_array, 131 : ulong pkt_meta_array_sz ); 132 : 133 : /* pop from front of list */ 134 : fd_quic_pkt_meta_t * 135 : fd_quic_pkt_meta_pop_front( fd_quic_pkt_meta_list_t * list ); 136 : 137 : 138 : /* push onto front of list */ 139 : void 140 : fd_quic_pkt_meta_push_front( fd_quic_pkt_meta_list_t * list, 141 : fd_quic_pkt_meta_t * pkt_meta ); 142 : 143 : /* push onto back of list */ 144 : void 145 : fd_quic_pkt_meta_push_back( fd_quic_pkt_meta_list_t * list, 146 : fd_quic_pkt_meta_t * pkt_meta ); 147 : 148 : /* remove from list 149 : requires the prior element */ 150 : void 151 : fd_quic_pkt_meta_remove( fd_quic_pkt_meta_list_t * list, 152 : fd_quic_pkt_meta_t * pkt_meta_prior, 153 : fd_quic_pkt_meta_t * pkt_meta ); 154 : 155 : 156 : /* allocate a pkt_meta 157 : obtains a free pkt_meta from the free list, and returns it 158 : returns NULL if none is available */ 159 : fd_quic_pkt_meta_t * 160 : fd_quic_pkt_meta_allocate( fd_quic_pkt_meta_pool_t * pool ); 161 : 162 : 163 : /* free a pkt_meta 164 : returns a pkt_meta to the free list, ready to be allocated again */ 165 : void 166 : fd_quic_pkt_meta_deallocate( fd_quic_pkt_meta_pool_t * pool, 167 : fd_quic_pkt_meta_t * pkt_meta ); 168 : 169 : FD_PROTOTYPES_END 170 : 171 : #endif // HEADER_fd_src_waltz_quic_fd_quic_pkt_meta_h 172 :