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