1 /* 2 * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include "internal/quic_stream_map.h" 11 #include "internal/nelem.h" 12 13 /* 14 * QUIC Stream Map 15 * =============== 16 */ 17 DEFINE_LHASH_OF_EX(QUIC_STREAM); 18 19 static void shutdown_flush_done(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs); 20 21 /* Circular list management. */ 22 static void list_insert_tail(QUIC_STREAM_LIST_NODE *l, 23 QUIC_STREAM_LIST_NODE *n) 24 { 25 /* Must not be in list. */ 26 assert(n->prev == NULL && n->next == NULL 27 && l->prev != NULL && l->next != NULL); 28 29 n->prev = l->prev; 30 n->prev->next = n; 31 l->prev = n; 32 n->next = l; 33 } 34 35 static void list_remove(QUIC_STREAM_LIST_NODE *l, 36 QUIC_STREAM_LIST_NODE *n) 37 { 38 assert(n->prev != NULL && n->next != NULL 39 && n->prev != n && n->next != n); 40 41 n->prev->next = n->next; 42 n->next->prev = n->prev; 43 n->next = n->prev = NULL; 44 } 45 46 static QUIC_STREAM *list_next(QUIC_STREAM_LIST_NODE *l, QUIC_STREAM_LIST_NODE *n, 47 size_t off) 48 { 49 assert(n->prev != NULL && n->next != NULL 50 && (n == l || (n->prev != n && n->next != n)) 51 && l->prev != NULL && l->next != NULL); 52 53 n = n->next; 54 55 if (n == l) 56 n = n->next; 57 if (n == l) 58 return NULL; 59 60 assert(n != NULL); 61 62 return (QUIC_STREAM *)(((char *)n) - off); 63 } 64 65 #define active_next(l, s) list_next((l), &(s)->active_node, \ 66 offsetof(QUIC_STREAM, active_node)) 67 #define accept_next(l, s) list_next((l), &(s)->accept_node, \ 68 offsetof(QUIC_STREAM, accept_node)) 69 #define accept_head(l) list_next((l), (l), \ 70 offsetof(QUIC_STREAM, accept_node)) 71 #define ready_for_gc_head(l) list_next((l), (l), \ 72 offsetof(QUIC_STREAM, ready_for_gc_node)) 73 74 static unsigned long hash_stream(const QUIC_STREAM *s) 75 { 76 return (unsigned long)s->id; 77 } 78 79 static int cmp_stream(const QUIC_STREAM *a, const QUIC_STREAM *b) 80 { 81 if (a->id < b->id) 82 return -1; 83 if (a->id > b->id) 84 return 1; 85 return 0; 86 } 87 88 int ossl_quic_stream_map_init(QUIC_STREAM_MAP *qsm, 89 uint64_t (*get_stream_limit_cb)(int uni, void *arg), 90 void *get_stream_limit_cb_arg, 91 QUIC_RXFC *max_streams_bidi_rxfc, 92 QUIC_RXFC *max_streams_uni_rxfc, 93 int is_server) 94 { 95 qsm->map = lh_QUIC_STREAM_new(hash_stream, cmp_stream); 96 qsm->active_list.prev = qsm->active_list.next = &qsm->active_list; 97 qsm->accept_list.prev = qsm->accept_list.next = &qsm->accept_list; 98 qsm->ready_for_gc_list.prev = qsm->ready_for_gc_list.next 99 = &qsm->ready_for_gc_list; 100 qsm->rr_stepping = 1; 101 qsm->rr_counter = 0; 102 qsm->rr_cur = NULL; 103 104 qsm->num_accept_bidi = 0; 105 qsm->num_accept_uni = 0; 106 qsm->num_shutdown_flush = 0; 107 108 qsm->get_stream_limit_cb = get_stream_limit_cb; 109 qsm->get_stream_limit_cb_arg = get_stream_limit_cb_arg; 110 qsm->max_streams_bidi_rxfc = max_streams_bidi_rxfc; 111 qsm->max_streams_uni_rxfc = max_streams_uni_rxfc; 112 qsm->is_server = is_server; 113 return 1; 114 } 115 116 static void release_each(QUIC_STREAM *stream, void *arg) 117 { 118 QUIC_STREAM_MAP *qsm = arg; 119 120 ossl_quic_stream_map_release(qsm, stream); 121 } 122 123 void ossl_quic_stream_map_cleanup(QUIC_STREAM_MAP *qsm) 124 { 125 lh_QUIC_STREAM_set_down_load(qsm->map, 0); 126 ossl_quic_stream_map_visit(qsm, release_each, qsm); 127 128 lh_QUIC_STREAM_free(qsm->map); 129 qsm->map = NULL; 130 } 131 132 void ossl_quic_stream_map_visit(QUIC_STREAM_MAP *qsm, 133 void (*visit_cb)(QUIC_STREAM *stream, void *arg), 134 void *visit_cb_arg) 135 { 136 lh_QUIC_STREAM_doall_arg(qsm->map, visit_cb, visit_cb_arg); 137 } 138 139 QUIC_STREAM *ossl_quic_stream_map_alloc(QUIC_STREAM_MAP *qsm, 140 uint64_t stream_id, 141 int type) 142 { 143 QUIC_STREAM *s; 144 QUIC_STREAM key; 145 146 key.id = stream_id; 147 148 s = lh_QUIC_STREAM_retrieve(qsm->map, &key); 149 if (s != NULL) 150 return NULL; 151 152 s = OPENSSL_zalloc(sizeof(*s)); 153 if (s == NULL) 154 return NULL; 155 156 s->id = stream_id; 157 s->type = type; 158 s->as_server = qsm->is_server; 159 s->send_state = (ossl_quic_stream_is_local_init(s) 160 || ossl_quic_stream_is_bidi(s)) 161 ? QUIC_SSTREAM_STATE_READY 162 : QUIC_SSTREAM_STATE_NONE; 163 s->recv_state = (!ossl_quic_stream_is_local_init(s) 164 || ossl_quic_stream_is_bidi(s)) 165 ? QUIC_RSTREAM_STATE_RECV 166 : QUIC_RSTREAM_STATE_NONE; 167 168 s->send_final_size = UINT64_MAX; 169 170 lh_QUIC_STREAM_insert(qsm->map, s); 171 return s; 172 } 173 174 void ossl_quic_stream_map_release(QUIC_STREAM_MAP *qsm, QUIC_STREAM *stream) 175 { 176 if (stream == NULL) 177 return; 178 179 if (stream->active_node.next != NULL) 180 list_remove(&qsm->active_list, &stream->active_node); 181 if (stream->accept_node.next != NULL) 182 list_remove(&qsm->accept_list, &stream->accept_node); 183 if (stream->ready_for_gc_node.next != NULL) 184 list_remove(&qsm->ready_for_gc_list, &stream->ready_for_gc_node); 185 186 ossl_quic_sstream_free(stream->sstream); 187 stream->sstream = NULL; 188 189 ossl_quic_rstream_free(stream->rstream); 190 stream->rstream = NULL; 191 192 lh_QUIC_STREAM_delete(qsm->map, stream); 193 OPENSSL_free(stream); 194 } 195 196 QUIC_STREAM *ossl_quic_stream_map_get_by_id(QUIC_STREAM_MAP *qsm, 197 uint64_t stream_id) 198 { 199 QUIC_STREAM key; 200 201 key.id = stream_id; 202 203 return lh_QUIC_STREAM_retrieve(qsm->map, &key); 204 } 205 206 static void stream_map_mark_active(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) 207 { 208 if (s->active) 209 return; 210 211 list_insert_tail(&qsm->active_list, &s->active_node); 212 213 if (qsm->rr_cur == NULL) 214 qsm->rr_cur = s; 215 216 s->active = 1; 217 } 218 219 static void stream_map_mark_inactive(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) 220 { 221 if (!s->active) 222 return; 223 224 if (qsm->rr_cur == s) 225 qsm->rr_cur = active_next(&qsm->active_list, s); 226 if (qsm->rr_cur == s) 227 qsm->rr_cur = NULL; 228 229 list_remove(&qsm->active_list, &s->active_node); 230 231 s->active = 0; 232 } 233 234 void ossl_quic_stream_map_set_rr_stepping(QUIC_STREAM_MAP *qsm, size_t stepping) 235 { 236 qsm->rr_stepping = stepping; 237 qsm->rr_counter = 0; 238 } 239 240 static int stream_has_data_to_send(QUIC_STREAM *s) 241 { 242 OSSL_QUIC_FRAME_STREAM shdr; 243 OSSL_QTX_IOVEC iov[2]; 244 size_t num_iov; 245 uint64_t fc_credit, fc_swm, fc_limit; 246 247 switch (s->send_state) { 248 case QUIC_SSTREAM_STATE_READY: 249 case QUIC_SSTREAM_STATE_SEND: 250 case QUIC_SSTREAM_STATE_DATA_SENT: 251 /* 252 * We can still have data to send in DATA_SENT due to retransmissions, 253 * etc. 254 */ 255 break; 256 default: 257 return 0; /* Nothing to send. */ 258 } 259 260 /* 261 * We cannot determine if we have data to send simply by checking if 262 * ossl_quic_txfc_get_credit() is zero, because we may also have older 263 * stream data we need to retransmit. The SSTREAM returns older data first, 264 * so we do a simple comparison of the next chunk the SSTREAM wants to send 265 * against the TXFC CWM. 266 */ 267 num_iov = OSSL_NELEM(iov); 268 if (!ossl_quic_sstream_get_stream_frame(s->sstream, 0, &shdr, iov, 269 &num_iov)) 270 return 0; 271 272 fc_credit = ossl_quic_txfc_get_credit(&s->txfc, 0); 273 fc_swm = ossl_quic_txfc_get_swm(&s->txfc); 274 fc_limit = fc_swm + fc_credit; 275 276 return (shdr.is_fin && shdr.len == 0) || shdr.offset < fc_limit; 277 } 278 279 static ossl_unused int qsm_send_part_permits_gc(const QUIC_STREAM *qs) 280 { 281 switch (qs->send_state) { 282 case QUIC_SSTREAM_STATE_NONE: 283 case QUIC_SSTREAM_STATE_DATA_RECVD: 284 case QUIC_SSTREAM_STATE_RESET_RECVD: 285 return 1; 286 default: 287 return 0; 288 } 289 } 290 291 static int qsm_ready_for_gc(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs) 292 { 293 int recv_stream_fully_drained = 0; /* TODO(QUIC FUTURE): Optimisation */ 294 295 /* 296 * If sstream has no FIN, we auto-reset it at marked-for-deletion time, so 297 * we don't need to worry about that here. 298 */ 299 assert(!qs->deleted 300 || !ossl_quic_stream_has_send(qs) 301 || ossl_quic_stream_send_is_reset(qs) 302 || ossl_quic_stream_send_get_final_size(qs, NULL)); 303 304 return qs->deleted 305 && (!ossl_quic_stream_has_recv(qs) 306 || recv_stream_fully_drained 307 || qs->acked_stop_sending) 308 && (!ossl_quic_stream_has_send(qs) 309 || qs->send_state == QUIC_SSTREAM_STATE_DATA_RECVD 310 || qs->send_state == QUIC_SSTREAM_STATE_RESET_RECVD); 311 } 312 313 int ossl_quic_stream_map_is_local_allowed_by_stream_limit(QUIC_STREAM_MAP *qsm, 314 uint64_t stream_ordinal, 315 int is_uni) 316 { 317 uint64_t stream_limit; 318 319 if (qsm->get_stream_limit_cb == NULL) 320 return 1; 321 322 stream_limit = qsm->get_stream_limit_cb(is_uni, qsm->get_stream_limit_cb_arg); 323 return stream_ordinal < stream_limit; 324 } 325 326 void ossl_quic_stream_map_update_state(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) 327 { 328 int should_be_active, allowed_by_stream_limit = 1; 329 330 if (ossl_quic_stream_is_server_init(s) == qsm->is_server) { 331 int is_uni = !ossl_quic_stream_is_bidi(s); 332 uint64_t stream_ordinal = s->id >> 2; 333 334 allowed_by_stream_limit 335 = ossl_quic_stream_map_is_local_allowed_by_stream_limit(qsm, 336 stream_ordinal, 337 is_uni); 338 } 339 340 if (s->send_state == QUIC_SSTREAM_STATE_DATA_SENT 341 && ossl_quic_sstream_is_totally_acked(s->sstream)) 342 ossl_quic_stream_map_notify_totally_acked(qsm, s); 343 else if (s->shutdown_flush 344 && s->send_state == QUIC_SSTREAM_STATE_SEND 345 && ossl_quic_sstream_is_totally_acked(s->sstream)) 346 shutdown_flush_done(qsm, s); 347 348 if (!s->ready_for_gc) { 349 s->ready_for_gc = qsm_ready_for_gc(qsm, s); 350 if (s->ready_for_gc) 351 list_insert_tail(&qsm->ready_for_gc_list, &s->ready_for_gc_node); 352 } 353 354 should_be_active 355 = allowed_by_stream_limit 356 && !s->ready_for_gc 357 && ((ossl_quic_stream_has_recv(s) 358 && !ossl_quic_stream_recv_is_reset(s) 359 && (s->recv_state == QUIC_RSTREAM_STATE_RECV 360 && (s->want_max_stream_data 361 || ossl_quic_rxfc_has_cwm_changed(&s->rxfc, 0)))) 362 || s->want_stop_sending 363 || s->want_reset_stream 364 || (!s->peer_stop_sending && stream_has_data_to_send(s))); 365 366 if (should_be_active) 367 stream_map_mark_active(qsm, s); 368 else 369 stream_map_mark_inactive(qsm, s); 370 } 371 372 /* 373 * Stream Send Part State Management 374 * ================================= 375 */ 376 377 int ossl_quic_stream_map_ensure_send_part_id(QUIC_STREAM_MAP *qsm, 378 QUIC_STREAM *qs) 379 { 380 switch (qs->send_state) { 381 case QUIC_SSTREAM_STATE_NONE: 382 /* Stream without send part - caller error. */ 383 return 0; 384 385 case QUIC_SSTREAM_STATE_READY: 386 /* 387 * We always allocate a stream ID upfront, so we don't need to do it 388 * here. 389 */ 390 qs->send_state = QUIC_SSTREAM_STATE_SEND; 391 return 1; 392 393 default: 394 /* Nothing to do. */ 395 return 1; 396 } 397 } 398 399 int ossl_quic_stream_map_notify_all_data_sent(QUIC_STREAM_MAP *qsm, 400 QUIC_STREAM *qs) 401 { 402 switch (qs->send_state) { 403 default: 404 /* Wrong state - caller error. */ 405 case QUIC_SSTREAM_STATE_NONE: 406 /* Stream without send part - caller error. */ 407 return 0; 408 409 case QUIC_SSTREAM_STATE_SEND: 410 if (!ossl_quic_sstream_get_final_size(qs->sstream, &qs->send_final_size)) 411 return 0; 412 413 qs->send_state = QUIC_SSTREAM_STATE_DATA_SENT; 414 return 1; 415 } 416 } 417 418 static void shutdown_flush_done(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs) 419 { 420 if (!qs->shutdown_flush) 421 return; 422 423 assert(qsm->num_shutdown_flush > 0); 424 qs->shutdown_flush = 0; 425 --qsm->num_shutdown_flush; 426 } 427 428 int ossl_quic_stream_map_notify_totally_acked(QUIC_STREAM_MAP *qsm, 429 QUIC_STREAM *qs) 430 { 431 switch (qs->send_state) { 432 default: 433 /* Wrong state - caller error. */ 434 case QUIC_SSTREAM_STATE_NONE: 435 /* Stream without send part - caller error. */ 436 return 0; 437 438 case QUIC_SSTREAM_STATE_DATA_SENT: 439 qs->send_state = QUIC_SSTREAM_STATE_DATA_RECVD; 440 /* 441 * Remember final size in case SSL_get_stream_write_state() 442 * gets called. 443 */ 444 qs->have_final_size = ossl_quic_sstream_get_final_size(qs->sstream, 445 NULL); 446 447 /* We no longer need a QUIC_SSTREAM in this state. */ 448 ossl_quic_sstream_free(qs->sstream); 449 qs->sstream = NULL; 450 451 shutdown_flush_done(qsm, qs); 452 return 1; 453 } 454 } 455 456 int ossl_quic_stream_map_reset_stream_send_part(QUIC_STREAM_MAP *qsm, 457 QUIC_STREAM *qs, 458 uint64_t aec) 459 { 460 switch (qs->send_state) { 461 default: 462 case QUIC_SSTREAM_STATE_NONE: 463 /* 464 * RESET_STREAM pertains to sending part only, so we cannot reset a 465 * receive-only stream. 466 */ 467 case QUIC_SSTREAM_STATE_DATA_RECVD: 468 /* 469 * RFC 9000 s. 3.3: A sender MUST NOT [...] send RESET_STREAM from a 470 * terminal state. If the stream has already finished normally and the 471 * peer has acknowledged this, we cannot reset it. 472 */ 473 return 0; 474 475 case QUIC_SSTREAM_STATE_READY: 476 if (!ossl_quic_stream_map_ensure_send_part_id(qsm, qs)) 477 return 0; 478 479 /* FALLTHROUGH */ 480 case QUIC_SSTREAM_STATE_SEND: 481 /* 482 * If we already have a final size (e.g. because we are coming from 483 * DATA_SENT), we have to be consistent with that, so don't change it. 484 * If we don't already have a final size, determine a final size value. 485 * This is the value which we will end up using for a RESET_STREAM frame 486 * for flow control purposes. We could send the stream size (total 487 * number of bytes appended to QUIC_SSTREAM by the application), but it 488 * is in our interest to exclude any bytes we have not actually 489 * transmitted yet, to avoid unnecessarily consuming flow control 490 * credit. We can get this from the TXFC. 491 */ 492 qs->send_final_size = ossl_quic_txfc_get_swm(&qs->txfc); 493 494 /* FALLTHROUGH */ 495 case QUIC_SSTREAM_STATE_DATA_SENT: 496 qs->reset_stream_aec = aec; 497 qs->want_reset_stream = 1; 498 qs->send_state = QUIC_SSTREAM_STATE_RESET_SENT; 499 500 ossl_quic_sstream_free(qs->sstream); 501 qs->sstream = NULL; 502 503 shutdown_flush_done(qsm, qs); 504 ossl_quic_stream_map_update_state(qsm, qs); 505 return 1; 506 507 case QUIC_SSTREAM_STATE_RESET_SENT: 508 case QUIC_SSTREAM_STATE_RESET_RECVD: 509 /* 510 * Idempotent - no-op. In any case, do not send RESET_STREAM again - as 511 * mentioned, we must not send it from a terminal state. 512 */ 513 return 1; 514 } 515 } 516 517 int ossl_quic_stream_map_notify_reset_stream_acked(QUIC_STREAM_MAP *qsm, 518 QUIC_STREAM *qs) 519 { 520 switch (qs->send_state) { 521 default: 522 /* Wrong state - caller error. */ 523 case QUIC_SSTREAM_STATE_NONE: 524 /* Stream without send part - caller error. */ 525 return 0; 526 527 case QUIC_SSTREAM_STATE_RESET_SENT: 528 qs->send_state = QUIC_SSTREAM_STATE_RESET_RECVD; 529 return 1; 530 531 case QUIC_SSTREAM_STATE_RESET_RECVD: 532 /* Already in the correct state. */ 533 return 1; 534 } 535 } 536 537 /* 538 * Stream Receive Part State Management 539 * ==================================== 540 */ 541 542 int ossl_quic_stream_map_notify_size_known_recv_part(QUIC_STREAM_MAP *qsm, 543 QUIC_STREAM *qs, 544 uint64_t final_size) 545 { 546 switch (qs->recv_state) { 547 default: 548 /* Wrong state - caller error. */ 549 case QUIC_RSTREAM_STATE_NONE: 550 /* Stream without receive part - caller error. */ 551 return 0; 552 553 case QUIC_RSTREAM_STATE_RECV: 554 qs->recv_state = QUIC_RSTREAM_STATE_SIZE_KNOWN; 555 return 1; 556 } 557 } 558 559 int ossl_quic_stream_map_notify_totally_received(QUIC_STREAM_MAP *qsm, 560 QUIC_STREAM *qs) 561 { 562 switch (qs->recv_state) { 563 default: 564 /* Wrong state - caller error. */ 565 case QUIC_RSTREAM_STATE_NONE: 566 /* Stream without receive part - caller error. */ 567 return 0; 568 569 case QUIC_RSTREAM_STATE_SIZE_KNOWN: 570 qs->recv_state = QUIC_RSTREAM_STATE_DATA_RECVD; 571 qs->want_stop_sending = 0; 572 return 1; 573 } 574 } 575 576 int ossl_quic_stream_map_notify_totally_read(QUIC_STREAM_MAP *qsm, 577 QUIC_STREAM *qs) 578 { 579 switch (qs->recv_state) { 580 default: 581 /* Wrong state - caller error. */ 582 case QUIC_RSTREAM_STATE_NONE: 583 /* Stream without receive part - caller error. */ 584 return 0; 585 586 case QUIC_RSTREAM_STATE_DATA_RECVD: 587 qs->recv_state = QUIC_RSTREAM_STATE_DATA_READ; 588 589 /* QUIC_RSTREAM is no longer needed */ 590 ossl_quic_rstream_free(qs->rstream); 591 qs->rstream = NULL; 592 return 1; 593 } 594 } 595 596 int ossl_quic_stream_map_notify_reset_recv_part(QUIC_STREAM_MAP *qsm, 597 QUIC_STREAM *qs, 598 uint64_t app_error_code, 599 uint64_t final_size) 600 { 601 uint64_t prev_final_size; 602 603 switch (qs->recv_state) { 604 default: 605 case QUIC_RSTREAM_STATE_NONE: 606 /* Stream without receive part - caller error. */ 607 return 0; 608 609 case QUIC_RSTREAM_STATE_RECV: 610 case QUIC_RSTREAM_STATE_SIZE_KNOWN: 611 case QUIC_RSTREAM_STATE_DATA_RECVD: 612 if (ossl_quic_stream_recv_get_final_size(qs, &prev_final_size) 613 && prev_final_size != final_size) 614 /* Cannot change previous final size. */ 615 return 0; 616 617 qs->recv_state = QUIC_RSTREAM_STATE_RESET_RECVD; 618 qs->peer_reset_stream_aec = app_error_code; 619 620 /* RFC 9000 s. 3.3: No point sending STOP_SENDING if already reset. */ 621 qs->want_stop_sending = 0; 622 623 /* QUIC_RSTREAM is no longer needed */ 624 ossl_quic_rstream_free(qs->rstream); 625 qs->rstream = NULL; 626 627 ossl_quic_stream_map_update_state(qsm, qs); 628 return 1; 629 630 case QUIC_RSTREAM_STATE_DATA_READ: 631 /* 632 * If we already retired the FIN to the application this is moot 633 * - just ignore. 634 */ 635 case QUIC_RSTREAM_STATE_RESET_RECVD: 636 case QUIC_RSTREAM_STATE_RESET_READ: 637 /* Could be a reordered/retransmitted frame - just ignore. */ 638 return 1; 639 } 640 } 641 642 int ossl_quic_stream_map_notify_app_read_reset_recv_part(QUIC_STREAM_MAP *qsm, 643 QUIC_STREAM *qs) 644 { 645 switch (qs->recv_state) { 646 default: 647 /* Wrong state - caller error. */ 648 case QUIC_RSTREAM_STATE_NONE: 649 /* Stream without receive part - caller error. */ 650 return 0; 651 652 case QUIC_RSTREAM_STATE_RESET_RECVD: 653 qs->recv_state = QUIC_RSTREAM_STATE_RESET_READ; 654 return 1; 655 } 656 } 657 658 int ossl_quic_stream_map_stop_sending_recv_part(QUIC_STREAM_MAP *qsm, 659 QUIC_STREAM *qs, 660 uint64_t aec) 661 { 662 if (qs->stop_sending) 663 return 0; 664 665 switch (qs->recv_state) { 666 default: 667 case QUIC_RSTREAM_STATE_NONE: 668 /* Send-only stream, so this makes no sense. */ 669 case QUIC_RSTREAM_STATE_DATA_RECVD: 670 case QUIC_RSTREAM_STATE_DATA_READ: 671 /* 672 * Not really any point in STOP_SENDING if we already received all data. 673 */ 674 case QUIC_RSTREAM_STATE_RESET_RECVD: 675 case QUIC_RSTREAM_STATE_RESET_READ: 676 /* 677 * RFC 9000 s. 3.5: "STOP_SENDING SHOULD only be sent for a stream that 678 * has not been reset by the peer." 679 * 680 * No point in STOP_SENDING if the peer already reset their send part. 681 */ 682 return 0; 683 684 case QUIC_RSTREAM_STATE_RECV: 685 case QUIC_RSTREAM_STATE_SIZE_KNOWN: 686 /* 687 * RFC 9000 s. 3.5: "If the stream is in the Recv or Size Known state, 688 * the transport SHOULD signal this by sending a STOP_SENDING frame to 689 * prompt closure of the stream in the opposite direction." 690 * 691 * Note that it does make sense to send STOP_SENDING for a receive part 692 * of a stream which has a known size (because we have received a FIN) 693 * but which still has other (previous) stream data yet to be received. 694 */ 695 break; 696 } 697 698 qs->stop_sending = 1; 699 qs->stop_sending_aec = aec; 700 return ossl_quic_stream_map_schedule_stop_sending(qsm, qs); 701 } 702 703 /* Called to mark STOP_SENDING for generation, or regeneration after loss. */ 704 int ossl_quic_stream_map_schedule_stop_sending(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs) 705 { 706 if (!qs->stop_sending) 707 return 0; 708 709 /* 710 * Ignore the call as a no-op if already scheduled, or in a state 711 * where it makes no sense to send STOP_SENDING. 712 */ 713 if (qs->want_stop_sending) 714 return 1; 715 716 switch (qs->recv_state) { 717 default: 718 return 1; /* ignore */ 719 case QUIC_RSTREAM_STATE_RECV: 720 case QUIC_RSTREAM_STATE_SIZE_KNOWN: 721 /* 722 * RFC 9000 s. 3.5: "An endpoint is expected to send another 723 * STOP_SENDING frame if a packet containing a previous STOP_SENDING is 724 * lost. However, once either all stream data or a RESET_STREAM frame 725 * has been received for the stream -- that is, the stream is in any 726 * state other than "Recv" or "Size Known" -- sending a STOP_SENDING 727 * frame is unnecessary." 728 */ 729 break; 730 } 731 732 qs->want_stop_sending = 1; 733 ossl_quic_stream_map_update_state(qsm, qs); 734 return 1; 735 } 736 737 QUIC_STREAM *ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP *qsm) 738 { 739 return accept_head(&qsm->accept_list); 740 } 741 742 void ossl_quic_stream_map_push_accept_queue(QUIC_STREAM_MAP *qsm, 743 QUIC_STREAM *s) 744 { 745 list_insert_tail(&qsm->accept_list, &s->accept_node); 746 if (ossl_quic_stream_is_bidi(s)) 747 ++qsm->num_accept_bidi; 748 else 749 ++qsm->num_accept_uni; 750 } 751 752 static QUIC_RXFC *qsm_get_max_streams_rxfc(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) 753 { 754 return ossl_quic_stream_is_bidi(s) 755 ? qsm->max_streams_bidi_rxfc 756 : qsm->max_streams_uni_rxfc; 757 } 758 759 void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP *qsm, 760 QUIC_STREAM *s, 761 OSSL_TIME rtt) 762 { 763 QUIC_RXFC *max_streams_rxfc; 764 765 list_remove(&qsm->accept_list, &s->accept_node); 766 if (ossl_quic_stream_is_bidi(s)) 767 --qsm->num_accept_bidi; 768 else 769 --qsm->num_accept_uni; 770 771 if ((max_streams_rxfc = qsm_get_max_streams_rxfc(qsm, s)) != NULL) 772 (void)ossl_quic_rxfc_on_retire(max_streams_rxfc, 1, rtt); 773 } 774 775 size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm, int is_uni) 776 { 777 return is_uni ? qsm->num_accept_uni : qsm->num_accept_bidi; 778 } 779 780 size_t ossl_quic_stream_map_get_total_accept_queue_len(QUIC_STREAM_MAP *qsm) 781 { 782 return ossl_quic_stream_map_get_accept_queue_len(qsm, /*is_uni=*/0) 783 + ossl_quic_stream_map_get_accept_queue_len(qsm, /*is_uni=*/1); 784 } 785 786 void ossl_quic_stream_map_gc(QUIC_STREAM_MAP *qsm) 787 { 788 QUIC_STREAM *qs; 789 790 while ((qs = ready_for_gc_head(&qsm->ready_for_gc_list)) != NULL) { 791 ossl_quic_stream_map_release(qsm, qs); 792 } 793 } 794 795 static int eligible_for_shutdown_flush(QUIC_STREAM *qs) 796 { 797 /* 798 * We only care about servicing the send part of a stream (if any) during 799 * shutdown flush. We make sure we flush a stream if it is either 800 * non-terminated or was terminated normally such as via 801 * SSL_stream_conclude. A stream which was terminated via a reset is not 802 * flushed, and we will have thrown away the send buffer in that case 803 * anyway. 804 */ 805 switch (qs->send_state) { 806 case QUIC_SSTREAM_STATE_SEND: 807 case QUIC_SSTREAM_STATE_DATA_SENT: 808 return !ossl_quic_sstream_is_totally_acked(qs->sstream); 809 default: 810 return 0; 811 } 812 } 813 814 static void begin_shutdown_flush_each(QUIC_STREAM *qs, void *arg) 815 { 816 QUIC_STREAM_MAP *qsm = arg; 817 818 if (!eligible_for_shutdown_flush(qs) || qs->shutdown_flush) 819 return; 820 821 qs->shutdown_flush = 1; 822 ++qsm->num_shutdown_flush; 823 } 824 825 void ossl_quic_stream_map_begin_shutdown_flush(QUIC_STREAM_MAP *qsm) 826 { 827 qsm->num_shutdown_flush = 0; 828 829 ossl_quic_stream_map_visit(qsm, begin_shutdown_flush_each, qsm); 830 } 831 832 int ossl_quic_stream_map_is_shutdown_flush_finished(QUIC_STREAM_MAP *qsm) 833 { 834 return qsm->num_shutdown_flush == 0; 835 } 836 837 /* 838 * QUIC Stream Iterator 839 * ==================== 840 */ 841 void ossl_quic_stream_iter_init(QUIC_STREAM_ITER *it, QUIC_STREAM_MAP *qsm, 842 int advance_rr) 843 { 844 it->qsm = qsm; 845 it->stream = it->first_stream = qsm->rr_cur; 846 if (advance_rr && it->stream != NULL 847 && ++qsm->rr_counter >= qsm->rr_stepping) { 848 qsm->rr_counter = 0; 849 qsm->rr_cur = active_next(&qsm->active_list, qsm->rr_cur); 850 } 851 } 852 853 void ossl_quic_stream_iter_next(QUIC_STREAM_ITER *it) 854 { 855 if (it->stream == NULL) 856 return; 857 858 it->stream = active_next(&it->qsm->active_list, it->stream); 859 if (it->stream == it->first_stream) 860 it->stream = NULL; 861 } 862