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