1 /* 2 * ngtcp2 3 * 4 * Copyright (c) 2017 ngtcp2 contributors 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 #ifndef NGTCP2_STRM_H 26 #define NGTCP2_STRM_H 27 28 #ifdef HAVE_CONFIG_H 29 # include <config.h> 30 #endif /* HAVE_CONFIG_H */ 31 32 #include <ngtcp2/ngtcp2.h> 33 34 #include "ngtcp2_rob.h" 35 #include "ngtcp2_map.h" 36 #include "ngtcp2_gaptr.h" 37 #include "ngtcp2_ksl.h" 38 #include "ngtcp2_pq.h" 39 40 typedef struct ngtcp2_frame_chain ngtcp2_frame_chain; 41 42 /* NGTCP2_STRM_FLAG_NONE indicates that no flag is set. */ 43 #define NGTCP2_STRM_FLAG_NONE 0x00u 44 /* NGTCP2_STRM_FLAG_SHUT_RD indicates that further reception of stream 45 data is not allowed. */ 46 #define NGTCP2_STRM_FLAG_SHUT_RD 0x01u 47 /* NGTCP2_STRM_FLAG_SHUT_WR indicates that further transmission of 48 stream data is not allowed. */ 49 #define NGTCP2_STRM_FLAG_SHUT_WR 0x02u 50 #define NGTCP2_STRM_FLAG_SHUT_RDWR \ 51 (NGTCP2_STRM_FLAG_SHUT_RD | NGTCP2_STRM_FLAG_SHUT_WR) 52 /* NGTCP2_STRM_FLAG_SENT_RST indicates that RST_STREAM is sent from 53 the local endpoint. In this case, NGTCP2_STRM_FLAG_SHUT_WR is also 54 set. */ 55 #define NGTCP2_STRM_FLAG_SENT_RST 0x04u 56 /* NGTCP2_STRM_FLAG_SENT_RST indicates that RST_STREAM is received 57 from the remote endpoint. In this case, NGTCP2_STRM_FLAG_SHUT_RD 58 is also set. */ 59 #define NGTCP2_STRM_FLAG_RECV_RST 0x08u 60 /* NGTCP2_STRM_FLAG_STOP_SENDING indicates that STOP_SENDING is sent 61 from the local endpoint. */ 62 #define NGTCP2_STRM_FLAG_STOP_SENDING 0x10u 63 /* NGTCP2_STRM_FLAG_RST_ACKED indicates that the outgoing RST_STREAM 64 is acknowledged by peer. */ 65 #define NGTCP2_STRM_FLAG_RST_ACKED 0x20u 66 /* NGTCP2_STRM_FLAG_FIN_ACKED indicates that a STREAM with FIN bit set 67 is acknowledged by a remote endpoint. */ 68 #define NGTCP2_STRM_FLAG_FIN_ACKED 0x40u 69 /* NGTCP2_STRM_FLAG_ANY_ACKED indicates that any portion of stream 70 data, including 0 length segment, is acknowledged. */ 71 #define NGTCP2_STRM_FLAG_ANY_ACKED 0x80u 72 /* NGTCP2_STRM_FLAG_APP_ERROR_CODE_SET indicates that app_error_code 73 field is set. This resolves the ambiguity that the initial 74 app_error_code value 0 might be a proper application error code. 75 In this case, without this flag, we are unable to distinguish 76 assigned value from unassigned one. */ 77 #define NGTCP2_STRM_FLAG_APP_ERROR_CODE_SET 0x100u 78 /* NGTCP2_STRM_FLAG_STREAM_STOP_SENDING_CALLED is set when 79 stream_stop_sending callback is called. */ 80 #define NGTCP2_STRM_FLAG_STREAM_STOP_SENDING_CALLED 0x200u 81 82 typedef struct ngtcp2_strm ngtcp2_strm; 83 84 struct ngtcp2_strm { 85 union { 86 struct { 87 ngtcp2_pq_entry pe; 88 uint64_t cycle; 89 ngtcp2_objalloc *frc_objalloc; 90 91 struct { 92 /* acked_offset tracks acknowledged outgoing data. */ 93 ngtcp2_gaptr *acked_offset; 94 /* cont_acked_offset is the offset that all data up to this offset 95 is acknowledged by a remote endpoint. It is used until the 96 remote endpoint acknowledges data in out-of-order. After that, 97 acked_offset is used instead. */ 98 uint64_t cont_acked_offset; 99 /* streamfrq contains STREAM frame for retransmission. The flow 100 control credits have been paid when they are transmitted first 101 time. There are no restriction regarding flow control for 102 retransmission. */ 103 ngtcp2_ksl *streamfrq; 104 /* offset is the next offset of outgoing data. In other words, it 105 is the number of bytes sent in this stream without 106 duplication. */ 107 uint64_t offset; 108 /* max_tx_offset is the maximum offset that local endpoint can 109 send for this stream. */ 110 uint64_t max_offset; 111 /* last_max_stream_data_ts is the timestamp when last 112 MAX_STREAM_DATA frame is sent. */ 113 ngtcp2_tstamp last_max_stream_data_ts; 114 /* loss_count is the number of packets that contain STREAM 115 frame for this stream and are declared to be lost. It may 116 include the spurious losses. It does not include a packet 117 whose contents have been reclaimed for PTO and which is 118 later declared to be lost. Those data are not blocked by 119 the flow control and will be sent immediately if no other 120 restrictions are applied. */ 121 size_t loss_count; 122 /* last_lost_pkt_num is the packet number of the packet that 123 is counted to loss_count. It is used to avoid to count 124 multiple STREAM frames in one lost packet. */ 125 int64_t last_lost_pkt_num; 126 } tx; 127 128 struct { 129 /* rob is the reorder buffer for incoming stream data. The data 130 received in out of order is buffered and sorted by its offset 131 in this object. */ 132 ngtcp2_rob *rob; 133 /* cont_offset is the largest offset of consecutive data. It is 134 used until the endpoint receives out-of-order data. After 135 that, rob is used to track the offset and data. */ 136 uint64_t cont_offset; 137 /* last_offset is the largest offset of stream data received for 138 this stream. */ 139 uint64_t last_offset; 140 /* max_offset is the maximum offset that remote endpoint can send 141 to this stream. */ 142 uint64_t max_offset; 143 /* unsent_max_offset is the maximum offset that remote endpoint 144 can send to this stream, and it is not notified to the remote 145 endpoint. unsent_max_offset >= max_offset must be hold. */ 146 uint64_t unsent_max_offset; 147 /* window is the stream-level flow control window size. */ 148 uint64_t window; 149 } rx; 150 151 const ngtcp2_mem *mem; 152 int64_t stream_id; 153 void *stream_user_data; 154 /* flags is bit-wise OR of zero or more of NGTCP2_STRM_FLAG_*. */ 155 uint32_t flags; 156 /* app_error_code is an error code the local endpoint sent in 157 RESET_STREAM or STOP_SENDING, or received from a remote endpoint 158 in RESET_STREAM or STOP_SENDING. First application error code is 159 chosen and when set, NGTCP2_STRM_FLAG_APP_ERROR_CODE_SET flag is 160 set in flags field. */ 161 uint64_t app_error_code; 162 }; 163 164 ngtcp2_opl_entry oplent; 165 }; 166 }; 167 168 /* 169 * ngtcp2_strm_init initializes |strm|. 170 */ 171 void ngtcp2_strm_init(ngtcp2_strm *strm, int64_t stream_id, uint32_t flags, 172 uint64_t max_rx_offset, uint64_t max_tx_offset, 173 void *stream_user_data, ngtcp2_objalloc *frc_objalloc, 174 const ngtcp2_mem *mem); 175 176 /* 177 * ngtcp2_strm_free deallocates memory allocated for |strm|. This 178 * function does not free the memory pointed by |strm| itself. 179 */ 180 void ngtcp2_strm_free(ngtcp2_strm *strm); 181 182 /* 183 * ngtcp2_strm_rx_offset returns the minimum offset of stream data 184 * which is not received yet. 185 */ 186 uint64_t ngtcp2_strm_rx_offset(ngtcp2_strm *strm); 187 188 /* 189 * ngtcp2_strm_recv_reordering handles reordered data. 190 * 191 * It returns 0 if it succeeds, or one of the following negative error 192 * codes: 193 * 194 * NGTCP2_ERR_NOMEM 195 * Out of memory 196 */ 197 int ngtcp2_strm_recv_reordering(ngtcp2_strm *strm, const uint8_t *data, 198 size_t datalen, uint64_t offset); 199 200 /* 201 * ngtcp2_strm_update_rx_offset tells that data up to offset bytes are 202 * received in order. 203 * 204 * NGTCP2_ERR_NOMEM 205 * Out of memory 206 */ 207 int ngtcp2_strm_update_rx_offset(ngtcp2_strm *strm, uint64_t offset); 208 209 /* 210 * ngtcp2_strm_shutdown shutdowns |strm|. |flags| should be 211 * NGTCP2_STRM_FLAG_SHUT_RD, and/or NGTCP2_STRM_FLAG_SHUT_WR. 212 */ 213 void ngtcp2_strm_shutdown(ngtcp2_strm *strm, uint32_t flags); 214 215 /* 216 * ngtcp2_strm_streamfrq_push pushes |frc| to streamfrq for 217 * retransmission. 218 * 219 * This function returns 0 if it succeeds, or one of the following 220 * negative error codes: 221 * 222 * NGTCP2_ERR_NOMEM 223 * Out of memory 224 */ 225 int ngtcp2_strm_streamfrq_push(ngtcp2_strm *strm, ngtcp2_frame_chain *frc); 226 227 /* 228 * ngtcp2_strm_streamfrq_pop pops the first ngtcp2_frame_chain and 229 * assigns it to |*pfrc|. This function splits into or merges several 230 * ngtcp2_frame_chain objects so that the returned ngtcp2_frame_chain 231 * has at most |left| data length. If there is no frames to send, 232 * this function returns 0 and |*pfrc| is NULL. 233 * 234 * This function returns 0 if it succeeds, or one of the following 235 * negative error codes: 236 * 237 * NGTCP2_ERR_NOMEM 238 * Out of memory 239 */ 240 int ngtcp2_strm_streamfrq_pop(ngtcp2_strm *strm, ngtcp2_frame_chain **pfrc, 241 size_t left); 242 243 /* 244 * ngtcp2_strm_streamfrq_unacked_offset returns the smallest offset of 245 * unacknowledged stream data held in strm->tx.streamfrq. 246 */ 247 uint64_t ngtcp2_strm_streamfrq_unacked_offset(ngtcp2_strm *strm); 248 249 /* 250 * ngtcp2_strm_streamfrq_top returns the first ngtcp2_frame_chain. 251 * The queue must not be empty. 252 */ 253 ngtcp2_frame_chain *ngtcp2_strm_streamfrq_top(ngtcp2_strm *strm); 254 255 /* 256 * ngtcp2_strm_streamfrq_empty returns nonzero if streamfrq is empty. 257 */ 258 int ngtcp2_strm_streamfrq_empty(ngtcp2_strm *strm); 259 260 /* 261 * ngtcp2_strm_streamfrq_clear removes all frames from streamfrq. 262 */ 263 void ngtcp2_strm_streamfrq_clear(ngtcp2_strm *strm); 264 265 /* 266 * ngtcp2_strm_is_tx_queued returns nonzero if |strm| is queued. 267 */ 268 int ngtcp2_strm_is_tx_queued(ngtcp2_strm *strm); 269 270 /* 271 * ngtcp2_strm_is_all_tx_data_acked returns nonzero if all outgoing 272 * data for |strm| which have sent so far have been acknowledged. 273 */ 274 int ngtcp2_strm_is_all_tx_data_acked(ngtcp2_strm *strm); 275 276 /* 277 * ngtcp2_strm_is_all_tx_data_fin_acked behaves like 278 * ngtcp2_strm_is_all_tx_data_acked, but it also requires that STREAM 279 * frame with fin bit set is acknowledged. 280 */ 281 int ngtcp2_strm_is_all_tx_data_fin_acked(ngtcp2_strm *strm); 282 283 /* 284 * ngtcp2_strm_get_unacked_range_after returns the range that is not 285 * acknowledged yet and intersects or comes after |offset|. 286 */ 287 ngtcp2_range ngtcp2_strm_get_unacked_range_after(ngtcp2_strm *strm, 288 uint64_t offset); 289 290 /* 291 * ngtcp2_strm_get_acked_offset returns offset, that is the data up to 292 * this offset have been acknowledged by a remote endpoint. It 293 * returns 0 if no data is acknowledged. 294 */ 295 uint64_t ngtcp2_strm_get_acked_offset(ngtcp2_strm *strm); 296 297 /* 298 * ngtcp2_strm_ack_data tells |strm| that the data [offset, 299 * offset+len) is acknowledged by a remote endpoint. 300 */ 301 int ngtcp2_strm_ack_data(ngtcp2_strm *strm, uint64_t offset, uint64_t len); 302 303 /* 304 * ngtcp2_strm_set_app_error_code sets |app_error_code| to |strm| and 305 * set NGTCP2_STRM_FLAG_APP_ERROR_CODE_SET flag. If the flag is 306 * already set, this function does nothing. 307 */ 308 void ngtcp2_strm_set_app_error_code(ngtcp2_strm *strm, uint64_t app_error_code); 309 310 #endif /* NGTCP2_STRM_H */ 311