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 27103013 : #define fd_quic_buffer_used( buf ) ( (buf)->head - (buf)->tail ) 31 13549232 : #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 67767496 : # define FD_QUIC_STREAM_FLAGS_TX_FIN (1u<<0u) 45 67784359 : # define FD_QUIC_STREAM_FLAGS_UNSENT (1u<<3u) 46 27098302 : # define FD_QUIC_STREAM_FLAGS_DEAD (1u<<4u) 47 : 48 : # define FD_QUIC_STREAM_FLAGS_ACTION \ 49 54218360 : ( FD_QUIC_STREAM_FLAGS_TX_FIN | \ 50 54218360 : FD_QUIC_STREAM_FLAGS_UNSENT ) 51 : 52 : # define FD_QUIC_STREAM_ACTION(stream) \ 53 27115135 : (!!( (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 40662928 : # define FD_QUIC_STREAM_STATE_TX_FIN (1u<<0u) 68 27102938 : # define FD_QUIC_STREAM_STATE_RX_FIN (1u<<1u) 69 13549151 : # 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 : 86 : /* the largest acked value of rx_max_stream_data */ 87 : ulong rx_tot_data; /* the total number of bytes received on this stream */ 88 : 89 : /* last tx packet num with stream frame referring to this stream 90 : set to FD_QUIC_PKT_NUM_PENDING to indicate a new max_stream_data frame should be sent 91 : if we time out this packet (or possibly a later packet) we resend the frame 92 : and update this value */ 93 : ulong upd_pkt_number; 94 : 95 : /* doubly linked list with sentinel */ 96 : struct fd_quic_stream * next; 97 : struct fd_quic_stream * prev; 98 : 99 : /* TODO need a timeout on this data */ 100 : }; 101 : 102 : #define FD_QUIC_STREAM_LIST_LINK( LHS, RHS ) \ 103 192672538 : do { \ 104 192672538 : (LHS)->next = (RHS); \ 105 192672538 : (RHS)->prev = (LHS); \ 106 192672538 : } while(0) 107 : 108 : /* set up linked list sentinel 109 : sentinel just points to itself, at first */ 110 : #define FD_QUIC_STREAM_LIST_SENTINEL( stream ) \ 111 634002 : do { \ 112 634002 : FD_QUIC_STREAM_LIST_LINK( stream, stream ); \ 113 634002 : stream->sentinel = 1; \ 114 634002 : stream->stream_id = ~(0UL); \ 115 634002 : } while(0) 116 : 117 : /* initialize non-sentinel stream 118 : stream just points to itself, at first */ 119 : #define FD_QUIC_STREAM_LIST_INIT_STREAM( stream ) \ 120 14329130 : do { \ 121 14329130 : FD_QUIC_STREAM_LIST_LINK( stream, stream ); \ 122 14329130 : stream->sentinel = 0; \ 123 14329130 : } while(0) 124 : 125 : /* insert new_stream after stream in list */ 126 : #define FD_QUIC_STREAM_LIST_INSERT_AFTER( stream, new_stream ) \ 127 14329130 : do { \ 128 14329130 : fd_quic_stream_t * stream_next = (stream)->next; \ 129 14329130 : FD_QUIC_STREAM_LIST_LINK( stream, new_stream ); \ 130 14329130 : FD_QUIC_STREAM_LIST_LINK( new_stream, stream_next ); \ 131 14329130 : } while(0) 132 : 133 : /* insert new_stream before stream in list */ 134 : #define FD_QUIC_STREAM_LIST_INSERT_BEFORE( stream, new_stream ) \ 135 40650948 : do { \ 136 40650948 : fd_quic_stream_t * stream_prev = (stream)->prev; \ 137 40650948 : FD_QUIC_STREAM_LIST_LINK( new_stream, stream ); \ 138 40650948 : FD_QUIC_STREAM_LIST_LINK( stream_prev, new_stream ); \ 139 40650948 : } while(0) 140 : 141 : /* remove stream from list 142 : 143 : a stream pointing to itself is not in a list */ 144 : #define FD_QUIC_STREAM_LIST_REMOVE( stream ) \ 145 67749250 : do { \ 146 67749250 : fd_quic_stream_t * stream_prev = (stream)->prev; \ 147 67749250 : fd_quic_stream_t * stream_next = (stream)->next; \ 148 67749250 : FD_QUIC_STREAM_LIST_LINK( stream_prev, stream_next ); \ 149 67749250 : (stream)->next = (stream)->prev = stream; \ 150 67749250 : } while(0) 151 : 152 : /* stream map for use in fd_map_dynamic map */ 153 : struct fd_quic_stream_map { 154 : ulong stream_id; /* key */ 155 : uint hash; /* hash */ 156 : fd_quic_stream_t * stream; /* value */ 157 : }; 158 : 159 : FD_PROTOTYPES_BEGIN 160 : 161 : /* fd_quic_buffer_store 162 : store data into circular buffer */ 163 : void 164 : fd_quic_buffer_store( fd_quic_buffer_t * buf, 165 : uchar const * data, 166 : ulong data_sz ); 167 : 168 : /* fd_quic_buffer_load 169 : load data from circular buffer */ 170 : void 171 : fd_quic_buffer_load( fd_quic_buffer_t * buf, 172 : ulong offs, 173 : uchar * data, 174 : ulong data_sz ); 175 : 176 : /* returns the alignment of the fd_quic_stream_t */ 177 : FD_FN_CONST inline 178 : ulong 179 312 : fd_quic_stream_align( void ) { 180 312 : return 128ul; 181 312 : } 182 : 183 : /* returns the required footprint of fd_quic_stream_t 184 : 185 : args 186 : tx_buf_sz the size of the tx buffer */ 187 : FD_FN_CONST 188 : ulong 189 : fd_quic_stream_footprint( ulong tx_buf_sz ); 190 : 191 : /* returns a newly initialized stream 192 : 193 : args 194 : mem the memory aligned to fd_quic_stream_align, and at least fd_quic_stream_footprint 195 : bytes 196 : tx_buf_sz the size of the tx buffer */ 197 : fd_quic_stream_t * 198 : fd_quic_stream_new( void * mem, fd_quic_conn_t * conn, ulong tx_buf_sz ); 199 : 200 : /* delete a stream 201 : 202 : args 203 : stream the stream to free */ 204 : void 205 : fd_quic_stream_delete( fd_quic_stream_t * stream ); 206 : 207 : 208 : /* set stream context 209 : 210 : args 211 : stream the stream with which to associate the context 212 : context the user-defined context associated with the stream */ 213 : void 214 : fd_quic_stream_set_context( fd_quic_stream_t * stream, void * context ); 215 : 216 : 217 : /* get stream context 218 : 219 : args 220 : stream the stream from which to obtain the context 221 : 222 : returns 223 : context the user defined context associated with the stream */ 224 : void * 225 : fd_quic_stream_get_context( fd_quic_stream_t * stream ); 226 : 227 : 228 : FD_PROTOTYPES_END 229 : 230 : #endif /* HEADER_fd_src_waltz_quic_fd_quic_stream_h */