Line data Source code
1 : #ifndef HEADER_fd_src_waltz_quic_fd_quic_stream_h 2 : #define HEADER_fd_src_waltz_quic_fd_quic_stream_h 3 : 4 : #include "fd_quic_common.h" 5 : #include "../../util/fd_util.h" 6 : 7 184831095 : #define FD_QUIC_STREAM_ID_UNUSED (~0ul) 8 : 9 : /* Forward declarations */ 10 : 11 : typedef struct fd_quic_conn fd_quic_conn_t; 12 : typedef struct fd_quic_stream fd_quic_stream_t; 13 : typedef struct fd_quic_stream_map fd_quic_stream_map_t; 14 : 15 : /* fd_quic_buffer_t is a circular buffer */ 16 : 17 : struct fd_quic_buffer { 18 : uchar * buf; 19 : ulong cap; /* capacity of buffer; assert fd_ulong_is_pow2 */ 20 : 21 : /* offsets to beginning of stream 22 : should be masked before being used to access buf data */ 23 : ulong head; /* first unused byte of stream */ 24 : ulong tail; /* first byte of used range */ 25 : }; 26 : typedef struct fd_quic_buffer fd_quic_buffer_t; 27 : 28 : 29 : /* buffer helper functions 30 : fd_quic_buffer_used returns bytes used in buffer 31 : fd_quic_buffer_avail returns bytes available in buffer */ 32 25637097 : #define fd_quic_buffer_used( buf ) ( (buf)->head - (buf)->tail ) 33 8552527 : #define fd_quic_buffer_avail( buf ) ( (buf)->cap - fd_quic_buffer_used(buf) ) 34 : 35 : struct fd_quic_stream { 36 : fd_quic_conn_t * conn; 37 : 38 : ulong stream_id; /* all 1's indicates an unused stream object */ 39 : void * context; /* user context for callbacks */ 40 : 41 : fd_quic_buffer_t tx_buf; /* transmit buffer */ 42 : uchar * tx_ack; /* ack - 1 bit per byte of tx_buf */ 43 : ulong tx_sent; /* stream offset of first unsent byte of tx_buf */ 44 : 45 : uint stream_flags; /* flags representing elements that require action */ 46 68383022 : # define FD_QUIC_STREAM_FLAGS_TX_FIN (1u<<0u) 47 76927275 : # define FD_QUIC_STREAM_FLAGS_UNSENT (1u<<3u) 48 50909067 : # define FD_QUIC_STREAM_FLAGS_DEAD (1u<<4u) 49 : 50 : # define FD_QUIC_STREAM_FLAGS_ACTION \ 51 34193380 : ( FD_QUIC_STREAM_FLAGS_TX_FIN | \ 52 34193380 : FD_QUIC_STREAM_FLAGS_UNSENT ) 53 : 54 : # define FD_QUIC_STREAM_ACTION(stream) \ 55 34193380 : (!!( (stream)->stream_flags & FD_QUIC_STREAM_FLAGS_ACTION )) 56 : 57 : 58 : uint sentinel; /* does this stream represent a sentinel? */ 59 : 60 : /* stream state 61 : mask made up of the following: 62 : FD_QUIC_STREAM_STATE_UNUSED Stream is not yet used 63 : FD_QUIC_STREAM_STATE_TX_FIN TX is finished 64 : FD_QUIC_STREAM_STATE_RX_FIN Size known 65 : FD_QUIC_STREAM_STATE_DEAD stream is dead and waiting to be 66 : reclaimed, or is in stream_pool */ 67 : uint state; 68 : # define FD_QUIC_STREAM_STATE_DEAD 0u 69 76435863 : # define FD_QUIC_STREAM_STATE_TX_FIN (1u<<0u) 70 25685022 : # define FD_QUIC_STREAM_STATE_RX_FIN (1u<<1u) 71 76016772 : # define FD_QUIC_STREAM_STATE_UNUSED (1u<<2u) 72 : 73 0 : # define FD_QUIC_DEFAULT_INITIAL_RX_MAX_STREAM_DATA 1280 // IPv6 minimum MTU 74 : 75 : uint list_memb; /* list membership */ 76 0 : # define FD_QUIC_STREAM_LIST_MEMB_NONE 0 77 : # define FD_QUIC_STREAM_LIST_MEMB_UNUSED 1 78 : # define FD_QUIC_STREAM_LIST_MEMB_USED 2 79 : # define FD_QUIC_STREAM_LIST_MEMB_SEND 3 80 : 81 : /* flow control */ 82 : ulong tx_max_stream_data; /* the limit on the number of bytes we are allowed to send 83 : to the peer on this stream 84 : this includes bytes implied by offsets that have not 85 : been received yet */ 86 : ulong tx_tot_data; /* the total number of bytes transmitted on this stream */ 87 : ulong tx_last_byte; /* the index of the last byte of the stream 88 : valid only if FD_QUIC_STREAM_FLAGS_TX_FIN set */ 89 : 90 : /* the largest acked value of rx_max_stream_data */ 91 : ulong rx_tot_data; /* the total number of bytes received on this stream */ 92 : 93 : /* last tx packet num with max_stream_data frame referring to this stream 94 : set to next_pkt_number to indicate a new max_stream_data frame should be sent 95 : if we time out this packet (or possibly a later packet) we resend the frame 96 : and update this value */ 97 : ulong upd_pkt_number; 98 : 99 : /* doubly linked list with sentinel */ 100 : struct fd_quic_stream * next; 101 : struct fd_quic_stream * prev; 102 : 103 : /* TODO need a timeout on this data */ 104 : }; 105 : 106 : #define FD_QUIC_STREAM_LIST_LINK( LHS, RHS ) \ 107 471462214 : do { \ 108 471462214 : (LHS)->next = (RHS); \ 109 471462214 : (RHS)->prev = (LHS); \ 110 471462214 : } while(0) 111 : 112 : /* set up linked list sentinel 113 : sentinel just points to itself, at first */ 114 : #define FD_QUIC_STREAM_LIST_SENTINEL( stream ) \ 115 636069 : do { \ 116 636069 : FD_QUIC_STREAM_LIST_LINK( stream, stream ); \ 117 636069 : stream->sentinel = 1; \ 118 636069 : stream->stream_id = ~(0UL); \ 119 636069 : } while(0) 120 : 121 : /* initialize non-sentinel stream 122 : stream just points to itself, at first */ 123 : #define FD_QUIC_STREAM_LIST_INIT_STREAM( stream ) \ 124 43703612 : do { \ 125 43703612 : FD_QUIC_STREAM_LIST_LINK( stream, stream ); \ 126 43703612 : stream->sentinel = 0; \ 127 43703612 : } while(0) 128 : 129 : /* insert new_stream after stream in list */ 130 : #define FD_QUIC_STREAM_LIST_INSERT_AFTER( stream, new_stream ) \ 131 43703612 : do { \ 132 43703612 : fd_quic_stream_t * stream_next = (stream)->next; \ 133 43703612 : FD_QUIC_STREAM_LIST_LINK( stream, new_stream ); \ 134 43703612 : FD_QUIC_STREAM_LIST_LINK( new_stream, stream_next ); \ 135 43703612 : } while(0) 136 : 137 : /* insert new_stream before stream in list */ 138 : #define FD_QUIC_STREAM_LIST_INSERT_BEFORE( stream, new_stream ) \ 139 85032697 : do { \ 140 85032697 : fd_quic_stream_t * stream_prev = (stream)->prev; \ 141 85032697 : FD_QUIC_STREAM_LIST_LINK( new_stream, stream ); \ 142 85032697 : FD_QUIC_STREAM_LIST_LINK( stream_prev, new_stream ); \ 143 85032697 : } while(0) 144 : 145 : /* remove stream from list 146 : 147 : a stream pointing to itself is not in a list */ 148 : #define FD_QUIC_STREAM_LIST_REMOVE( stream ) \ 149 169649915 : do { \ 150 169649915 : fd_quic_stream_t * stream_prev = (stream)->prev; \ 151 169649915 : fd_quic_stream_t * stream_next = (stream)->next; \ 152 169649915 : FD_QUIC_STREAM_LIST_LINK( stream_prev, stream_next ); \ 153 169649915 : (stream)->next = (stream)->prev = stream; \ 154 169649915 : } while(0) 155 : 156 : 157 : 158 : /* stream map for use in fd_map_dynamic map */ 159 : struct fd_quic_stream_map { 160 : ulong stream_id; /* key */ 161 : uint hash; /* hash */ 162 : fd_quic_stream_t * stream; /* value */ 163 : }; 164 : 165 : FD_PROTOTYPES_BEGIN 166 : 167 : /* fd_quic_buffer_store 168 : store data into circular buffer */ 169 : void 170 : fd_quic_buffer_store( fd_quic_buffer_t * buf, 171 : uchar const * data, 172 : ulong data_sz ); 173 : 174 : /* fd_quic_buffer_load 175 : load data from circular buffer */ 176 : void 177 : fd_quic_buffer_load( fd_quic_buffer_t * buf, 178 : ulong offs, 179 : uchar * data, 180 : ulong data_sz ); 181 : 182 : /* returns the alignment of the fd_quic_stream_t */ 183 : FD_FN_CONST inline 184 : ulong 185 327291 : fd_quic_stream_align( void ) { 186 327291 : return 128ul; 187 327291 : } 188 : 189 : /* returns the required footprint of fd_quic_stream_t 190 : 191 : args 192 : tx_buf_sz the size of the tx buffer */ 193 : FD_FN_CONST 194 : ulong 195 : fd_quic_stream_footprint( ulong tx_buf_sz ); 196 : 197 : /* returns a newly initialized stream 198 : 199 : args 200 : mem the memory aligned to fd_quic_stream_align, and at least fd_quic_stream_footprint 201 : bytes 202 : tx_buf_sz the size of the tx buffer */ 203 : fd_quic_stream_t * 204 : fd_quic_stream_new( void * mem, fd_quic_conn_t * conn, ulong tx_buf_sz ); 205 : 206 : /* delete a stream 207 : 208 : args 209 : stream the stream to free */ 210 : void 211 : fd_quic_stream_delete( fd_quic_stream_t * stream ); 212 : 213 : 214 : /* set stream context 215 : 216 : args 217 : stream the stream with which to associate the context 218 : context the user-defined context associated with the stream */ 219 : void 220 : fd_quic_stream_set_context( fd_quic_stream_t * stream, void * context ); 221 : 222 : 223 : /* get stream context 224 : 225 : args 226 : stream the stream from which to obtain the context 227 : 228 : returns 229 : context the user defined context associated with the stream */ 230 : void * 231 : fd_quic_stream_get_context( fd_quic_stream_t * stream ); 232 : 233 : 234 : FD_PROTOTYPES_END 235 : 236 : #endif /* HEADER_fd_src_waltz_quic_fd_quic_stream_h */