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