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_txp.h" 11 #include "internal/quic_fifd.h" 12 #include "internal/quic_stream_map.h" 13 #include "internal/quic_error.h" 14 #include "internal/common.h" 15 #include <openssl/err.h> 16 17 #define MIN_CRYPTO_HDR_SIZE 3 18 19 #define MIN_FRAME_SIZE_HANDSHAKE_DONE 1 20 #define MIN_FRAME_SIZE_MAX_DATA 2 21 #define MIN_FRAME_SIZE_ACK 5 22 #define MIN_FRAME_SIZE_CRYPTO (MIN_CRYPTO_HDR_SIZE + 1) 23 #define MIN_FRAME_SIZE_STREAM 3 /* minimum useful size (for non-FIN) */ 24 #define MIN_FRAME_SIZE_MAX_STREAMS_BIDI 2 25 #define MIN_FRAME_SIZE_MAX_STREAMS_UNI 2 26 27 /* 28 * Packet Archetypes 29 * ================= 30 */ 31 32 /* Generate normal packets containing most frame types, subject to EL. */ 33 #define TX_PACKETISER_ARCHETYPE_NORMAL 0 34 35 /* 36 * A probe packet is different in that: 37 * - It bypasses CC, but *is* counted as in flight for purposes of CC; 38 * - It must be ACK-eliciting. 39 */ 40 #define TX_PACKETISER_ARCHETYPE_PROBE 1 41 42 /* 43 * An ACK-only packet is different in that: 44 * - It bypasses CC, and is considered a 'non-inflight' packet; 45 * - It may not contain anything other than an ACK frame, not even padding. 46 */ 47 #define TX_PACKETISER_ARCHETYPE_ACK_ONLY 2 48 49 #define TX_PACKETISER_ARCHETYPE_NUM 3 50 51 struct ossl_quic_tx_packetiser_st { 52 OSSL_QUIC_TX_PACKETISER_ARGS args; 53 54 /* 55 * Opaque initial token blob provided by caller. TXP frees using the 56 * callback when it is no longer needed. 57 */ 58 const unsigned char *initial_token; 59 size_t initial_token_len; 60 ossl_quic_initial_token_free_fn *initial_token_free_cb; 61 void *initial_token_free_cb_arg; 62 63 /* Subcomponents of the TXP that we own. */ 64 QUIC_FIFD fifd; /* QUIC Frame-in-Flight Dispatcher */ 65 66 /* Internal state. */ 67 uint64_t next_pn[QUIC_PN_SPACE_NUM]; /* Next PN to use in given PN space. */ 68 OSSL_TIME last_tx_time; /* Last time a packet was generated, or 0. */ 69 70 size_t unvalidated_credit; /* Limit of data we can send until validated */ 71 72 /* Internal state - frame (re)generation flags. */ 73 unsigned int want_handshake_done : 1; 74 unsigned int want_max_data : 1; 75 unsigned int want_max_streams_bidi : 1; 76 unsigned int want_max_streams_uni : 1; 77 78 /* Internal state - frame (re)generation flags - per PN space. */ 79 unsigned int want_ack : QUIC_PN_SPACE_NUM; 80 unsigned int force_ack_eliciting : QUIC_PN_SPACE_NUM; 81 82 /* 83 * Internal state - connection close terminal state. 84 * Once this is set, it is not unset unlike other want_ flags - we keep 85 * sending it in every packet. 86 */ 87 unsigned int want_conn_close : 1; 88 89 /* Has the handshake been completed? */ 90 unsigned int handshake_complete : 1; 91 92 OSSL_QUIC_FRAME_CONN_CLOSE conn_close_frame; 93 94 /* 95 * Counts of the number of bytes received and sent while in the closing 96 * state. 97 */ 98 uint64_t closing_bytes_recv; 99 uint64_t closing_bytes_xmit; 100 101 /* Internal state - packet assembly. */ 102 struct txp_el { 103 unsigned char *scratch; /* scratch buffer for packet assembly */ 104 size_t scratch_len; /* number of bytes allocated for scratch */ 105 OSSL_QTX_IOVEC *iovec; /* scratch iovec array for use with QTX */ 106 size_t alloc_iovec; /* size of iovec array */ 107 } el[QUIC_ENC_LEVEL_NUM]; 108 109 /* Message callback related arguments */ 110 ossl_msg_cb msg_callback; 111 void *msg_callback_arg; 112 SSL *msg_callback_ssl; 113 114 /* Callbacks. */ 115 void (*ack_tx_cb)(const OSSL_QUIC_FRAME_ACK *ack, 116 uint32_t pn_space, 117 void *arg); 118 void *ack_tx_cb_arg; 119 }; 120 121 /* 122 * The TX helper records state used while generating frames into packets. It 123 * enables serialization into the packet to be done "transactionally" where 124 * serialization of a frame can be rolled back if it fails midway (e.g. if it 125 * does not fit). 126 */ 127 struct tx_helper { 128 OSSL_QUIC_TX_PACKETISER *txp; 129 /* 130 * The Maximum Packet Payload Length in bytes. This is the amount of 131 * space we have to generate frames into. 132 */ 133 size_t max_ppl; 134 /* 135 * Number of bytes we have generated so far. 136 */ 137 size_t bytes_appended; 138 /* 139 * Number of scratch bytes in txp->scratch we have used so far. Some iovecs 140 * will reference this scratch buffer. When we need to use more of it (e.g. 141 * when we need to put frame headers somewhere), we append to the scratch 142 * buffer, resizing if necessary, and increase this accordingly. 143 */ 144 size_t scratch_bytes; 145 /* 146 * Bytes reserved in the MaxPPL budget. We keep this number of bytes spare 147 * until reserve_allowed is set to 1. Currently this is always at most 1, as 148 * a PING frame takes up one byte and this mechanism is only used to ensure 149 * we can encode a PING frame if we have been asked to ensure a packet is 150 * ACK-eliciting and we are unusure if we are going to add any other 151 * ACK-eliciting frames before we reach our MaxPPL budget. 152 */ 153 size_t reserve; 154 /* 155 * Number of iovecs we have currently appended. This is the number of 156 * entries valid in txp->iovec. 157 */ 158 size_t num_iovec; 159 /* The EL this TX helper is being used for. */ 160 uint32_t enc_level; 161 /* 162 * Whether we are allowed to make use of the reserve bytes in our MaxPPL 163 * budget. This is used to ensure we have room to append a PING frame later 164 * if we need to. Once we know we will not need to append a PING frame, this 165 * is set to 1. 166 */ 167 unsigned int reserve_allowed : 1; 168 /* 169 * Set to 1 if we have appended a STREAM frame with an implicit length. If 170 * this happens we should never append another frame after that frame as it 171 * cannot be validly encoded. This is just a safety check. 172 */ 173 unsigned int done_implicit : 1; 174 struct { 175 /* 176 * The fields in this structure are valid if active is set, which means 177 * that a serialization transaction is currently in progress. 178 */ 179 unsigned char *data; 180 WPACKET wpkt; 181 unsigned int active : 1; 182 } txn; 183 }; 184 185 static void tx_helper_rollback(struct tx_helper *h); 186 static int txp_el_ensure_iovec(struct txp_el *el, size_t num); 187 188 /* Initialises the TX helper. */ 189 static int tx_helper_init(struct tx_helper *h, OSSL_QUIC_TX_PACKETISER *txp, 190 uint32_t enc_level, size_t max_ppl, size_t reserve) 191 { 192 if (reserve > max_ppl) 193 return 0; 194 195 h->txp = txp; 196 h->enc_level = enc_level; 197 h->max_ppl = max_ppl; 198 h->reserve = reserve; 199 h->num_iovec = 0; 200 h->bytes_appended = 0; 201 h->scratch_bytes = 0; 202 h->reserve_allowed = 0; 203 h->done_implicit = 0; 204 h->txn.data = NULL; 205 h->txn.active = 0; 206 207 if (max_ppl > h->txp->el[enc_level].scratch_len) { 208 unsigned char *scratch; 209 210 scratch = OPENSSL_realloc(h->txp->el[enc_level].scratch, max_ppl); 211 if (scratch == NULL) 212 return 0; 213 214 h->txp->el[enc_level].scratch = scratch; 215 h->txp->el[enc_level].scratch_len = max_ppl; 216 } 217 218 return 1; 219 } 220 221 static void tx_helper_cleanup(struct tx_helper *h) 222 { 223 if (h->txn.active) 224 tx_helper_rollback(h); 225 226 h->txp = NULL; 227 } 228 229 static void tx_helper_unrestrict(struct tx_helper *h) 230 { 231 h->reserve_allowed = 1; 232 } 233 234 /* 235 * Append an extent of memory to the iovec list. The memory must remain 236 * allocated until we finish generating the packet and call the QTX. 237 * 238 * In general, the buffers passed to this function will be from one of two 239 * ranges: 240 * 241 * - Application data contained in stream buffers managed elsewhere 242 * in the QUIC stack; or 243 * 244 * - Control frame data appended into txp->scratch using tx_helper_begin and 245 * tx_helper_commit. 246 * 247 */ 248 static int tx_helper_append_iovec(struct tx_helper *h, 249 const unsigned char *buf, 250 size_t buf_len) 251 { 252 struct txp_el *el = &h->txp->el[h->enc_level]; 253 254 if (buf_len == 0) 255 return 1; 256 257 if (!ossl_assert(!h->done_implicit)) 258 return 0; 259 260 if (!txp_el_ensure_iovec(el, h->num_iovec + 1)) 261 return 0; 262 263 el->iovec[h->num_iovec].buf = buf; 264 el->iovec[h->num_iovec].buf_len = buf_len; 265 266 ++h->num_iovec; 267 h->bytes_appended += buf_len; 268 return 1; 269 } 270 271 /* 272 * How many more bytes of space do we have left in our plaintext packet payload? 273 */ 274 static size_t tx_helper_get_space_left(struct tx_helper *h) 275 { 276 return h->max_ppl 277 - (h->reserve_allowed ? 0 : h->reserve) - h->bytes_appended; 278 } 279 280 /* 281 * Begin a control frame serialization transaction. This allows the 282 * serialization of the control frame to be backed out if it turns out it won't 283 * fit. Write the control frame to the returned WPACKET. Ensure you always 284 * call tx_helper_rollback or tx_helper_commit (or tx_helper_cleanup). Returns 285 * NULL on failure. 286 */ 287 static WPACKET *tx_helper_begin(struct tx_helper *h) 288 { 289 size_t space_left, len; 290 unsigned char *data; 291 struct txp_el *el = &h->txp->el[h->enc_level]; 292 293 if (!ossl_assert(!h->txn.active)) 294 return NULL; 295 296 if (!ossl_assert(!h->done_implicit)) 297 return NULL; 298 299 data = (unsigned char *)el->scratch + h->scratch_bytes; 300 len = el->scratch_len - h->scratch_bytes; 301 302 space_left = tx_helper_get_space_left(h); 303 if (!ossl_assert(space_left <= len)) 304 return NULL; 305 306 if (!WPACKET_init_static_len(&h->txn.wpkt, data, len, 0)) 307 return NULL; 308 309 if (!WPACKET_set_max_size(&h->txn.wpkt, space_left)) { 310 WPACKET_cleanup(&h->txn.wpkt); 311 return NULL; 312 } 313 314 h->txn.data = data; 315 h->txn.active = 1; 316 return &h->txn.wpkt; 317 } 318 319 static void tx_helper_end(struct tx_helper *h, int success) 320 { 321 if (success) 322 WPACKET_finish(&h->txn.wpkt); 323 else 324 WPACKET_cleanup(&h->txn.wpkt); 325 326 h->txn.active = 0; 327 h->txn.data = NULL; 328 } 329 330 /* Abort a control frame serialization transaction. */ 331 static void tx_helper_rollback(struct tx_helper *h) 332 { 333 if (!h->txn.active) 334 return; 335 336 tx_helper_end(h, 0); 337 } 338 339 /* Commit a control frame. */ 340 static int tx_helper_commit(struct tx_helper *h) 341 { 342 size_t l = 0; 343 344 if (!h->txn.active) 345 return 0; 346 347 if (!WPACKET_get_total_written(&h->txn.wpkt, &l)) { 348 tx_helper_end(h, 0); 349 return 0; 350 } 351 352 if (!tx_helper_append_iovec(h, h->txn.data, l)) { 353 tx_helper_end(h, 0); 354 return 0; 355 } 356 357 if (h->txp->msg_callback != NULL && l > 0) { 358 uint64_t ftype; 359 int ctype = SSL3_RT_QUIC_FRAME_FULL; 360 PACKET pkt; 361 362 if (!PACKET_buf_init(&pkt, h->txn.data, l) 363 || !ossl_quic_wire_peek_frame_header(&pkt, &ftype, NULL)) { 364 tx_helper_end(h, 0); 365 return 0; 366 } 367 368 if (ftype == OSSL_QUIC_FRAME_TYPE_PADDING) 369 ctype = SSL3_RT_QUIC_FRAME_PADDING; 370 else if (OSSL_QUIC_FRAME_TYPE_IS_STREAM(ftype) 371 || ftype == OSSL_QUIC_FRAME_TYPE_CRYPTO) 372 ctype = SSL3_RT_QUIC_FRAME_HEADER; 373 374 h->txp->msg_callback(1, OSSL_QUIC1_VERSION, ctype, h->txn.data, l, 375 h->txp->msg_callback_ssl, 376 h->txp->msg_callback_arg); 377 } 378 379 h->scratch_bytes += l; 380 tx_helper_end(h, 1); 381 return 1; 382 } 383 384 struct archetype_data { 385 unsigned int allow_ack : 1; 386 unsigned int allow_ping : 1; 387 unsigned int allow_crypto : 1; 388 unsigned int allow_handshake_done : 1; 389 unsigned int allow_path_challenge : 1; 390 unsigned int allow_path_response : 1; 391 unsigned int allow_new_conn_id : 1; 392 unsigned int allow_retire_conn_id : 1; 393 unsigned int allow_stream_rel : 1; 394 unsigned int allow_conn_fc : 1; 395 unsigned int allow_conn_close : 1; 396 unsigned int allow_cfq_other : 1; 397 unsigned int allow_new_token : 1; 398 unsigned int allow_force_ack_eliciting : 1; 399 unsigned int allow_padding : 1; 400 unsigned int require_ack_eliciting : 1; 401 unsigned int bypass_cc : 1; 402 }; 403 404 struct txp_pkt_geom { 405 size_t cmpl, cmppl, hwm, pkt_overhead; 406 uint32_t archetype; 407 struct archetype_data adata; 408 }; 409 410 struct txp_pkt { 411 struct tx_helper h; 412 int h_valid; 413 QUIC_TXPIM_PKT *tpkt; 414 QUIC_STREAM *stream_head; 415 QUIC_PKT_HDR phdr; 416 struct txp_pkt_geom geom; 417 int force_pad; 418 }; 419 420 static QUIC_SSTREAM *get_sstream_by_id(uint64_t stream_id, uint32_t pn_space, 421 void *arg); 422 static void on_regen_notify(uint64_t frame_type, uint64_t stream_id, 423 QUIC_TXPIM_PKT *pkt, void *arg); 424 static void on_confirm_notify(uint64_t frame_type, uint64_t stream_id, 425 QUIC_TXPIM_PKT *pkt, void *arg); 426 static void on_sstream_updated(uint64_t stream_id, void *arg); 427 static int sstream_is_pending(QUIC_SSTREAM *sstream); 428 static int txp_should_try_staging(OSSL_QUIC_TX_PACKETISER *txp, 429 uint32_t enc_level, 430 uint32_t archetype, 431 uint64_t cc_limit, 432 uint32_t *conn_close_enc_level); 433 static size_t txp_determine_pn_len(OSSL_QUIC_TX_PACKETISER *txp); 434 static int txp_determine_ppl_from_pl(OSSL_QUIC_TX_PACKETISER *txp, 435 size_t pl, 436 uint32_t enc_level, 437 size_t hdr_len, 438 size_t *r); 439 static size_t txp_get_mdpl(OSSL_QUIC_TX_PACKETISER *txp); 440 static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, 441 struct txp_pkt *pkt, 442 int chosen_for_conn_close); 443 static int txp_pkt_init(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp, 444 uint32_t enc_level, uint32_t archetype, 445 size_t running_total); 446 static void txp_pkt_cleanup(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp); 447 static int txp_pkt_postgen_update_pkt_overhead(struct txp_pkt *pkt, 448 OSSL_QUIC_TX_PACKETISER *txp); 449 static int txp_pkt_append_padding(struct txp_pkt *pkt, 450 OSSL_QUIC_TX_PACKETISER *txp, size_t num_bytes); 451 static int txp_pkt_commit(OSSL_QUIC_TX_PACKETISER *txp, struct txp_pkt *pkt, 452 uint32_t archetype, int *txpim_pkt_reffed); 453 static uint32_t txp_determine_archetype(OSSL_QUIC_TX_PACKETISER *txp, 454 uint64_t cc_limit); 455 456 /** 457 * Sets the validated state of a QUIC TX packetiser. 458 * 459 * This function marks the provided QUIC TX packetiser as having its credit 460 * fully validated by setting its `unvalidated_credit` field to `SIZE_MAX`. 461 * 462 * @param txp A pointer to the OSSL_QUIC_TX_PACKETISER structure to update. 463 */ 464 void ossl_quic_tx_packetiser_set_validated(OSSL_QUIC_TX_PACKETISER *txp) 465 { 466 txp->unvalidated_credit = SIZE_MAX; 467 return; 468 } 469 470 /** 471 * Adds unvalidated credit to a QUIC TX packetiser. 472 * 473 * This function increases the unvalidated credit of the provided QUIC TX 474 * packetiser. If the current unvalidated credit is not `SIZE_MAX`, the 475 * function adds three times the specified `credit` value, ensuring it does 476 * not exceed the maximum allowable value (`SIZE_MAX - 1`). If the addition 477 * would cause an overflow, the unvalidated credit is capped at 478 * `SIZE_MAX - 1`. If the current unvalidated credit is already `SIZE_MAX`, 479 * the function does nothing. 480 * 481 * @param txp A pointer to the OSSL_QUIC_TX_PACKETISER structure to update. 482 * @param credit The amount of credit to add, multiplied by 3. 483 */ 484 void ossl_quic_tx_packetiser_add_unvalidated_credit(OSSL_QUIC_TX_PACKETISER *txp, 485 size_t credit) 486 { 487 if (txp->unvalidated_credit != SIZE_MAX) { 488 if ((SIZE_MAX - txp->unvalidated_credit) > (credit * 3)) 489 txp->unvalidated_credit += credit * 3; 490 else 491 txp->unvalidated_credit = SIZE_MAX - 1; 492 } 493 494 return; 495 } 496 497 /** 498 * Consumes unvalidated credit from a QUIC TX packetiser. 499 * 500 * This function decreases the unvalidated credit of the specified 501 * QUIC TX packetiser by the given `credit` value. If the unvalidated credit 502 * is set to `SIZE_MAX`, the function does nothing, as `SIZE_MAX` represents 503 * an unlimited credit state. 504 * 505 * @param txp A pointer to the OSSL_QUIC_TX_PACKETISER structure to update. 506 * @param credit The amount of credit to consume. 507 */ 508 void ossl_quic_tx_packetiser_consume_unvalidated_credit(OSSL_QUIC_TX_PACKETISER *txp, 509 size_t credit) 510 { 511 if (txp->unvalidated_credit != SIZE_MAX) { 512 if (txp->unvalidated_credit < credit) 513 txp->unvalidated_credit = 0; 514 else 515 txp->unvalidated_credit -= credit; 516 } 517 } 518 519 /** 520 * Checks if the QUIC TX packetiser has sufficient unvalidated credit. 521 * 522 * This function determines whether the unvalidated credit of the specified 523 * QUIC TX packetiser exceeds the required credit value (`req_credit`). 524 * If the unvalidated credit is greater than `req_credit`, the function 525 * returns 1 (true); otherwise, it returns 0 (false). 526 * 527 * @param txp A pointer to the OSSL_QUIC_TX_PACKETISER structure to check. 528 * @param req_credit The required credit value to compare against. 529 * 530 * @return 1 if the unvalidated credit exceeds `req_credit`, 0 otherwise. 531 */ 532 int ossl_quic_tx_packetiser_check_unvalidated_credit(OSSL_QUIC_TX_PACKETISER *txp, 533 size_t req_credit) 534 { 535 return (txp->unvalidated_credit > req_credit); 536 } 537 538 OSSL_QUIC_TX_PACKETISER *ossl_quic_tx_packetiser_new(const OSSL_QUIC_TX_PACKETISER_ARGS *args) 539 { 540 OSSL_QUIC_TX_PACKETISER *txp; 541 542 if (args == NULL 543 || args->qtx == NULL 544 || args->txpim == NULL 545 || args->cfq == NULL 546 || args->ackm == NULL 547 || args->qsm == NULL 548 || args->conn_txfc == NULL 549 || args->conn_rxfc == NULL 550 || args->max_streams_bidi_rxfc == NULL 551 || args->max_streams_uni_rxfc == NULL 552 || args->protocol_version == 0) { 553 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); 554 return NULL; 555 } 556 557 txp = OPENSSL_zalloc(sizeof(*txp)); 558 if (txp == NULL) 559 return NULL; 560 561 txp->args = *args; 562 txp->last_tx_time = ossl_time_zero(); 563 564 if (!ossl_quic_fifd_init(&txp->fifd, 565 txp->args.cfq, txp->args.ackm, txp->args.txpim, 566 get_sstream_by_id, txp, 567 on_regen_notify, txp, 568 on_confirm_notify, txp, 569 on_sstream_updated, txp, 570 args->get_qlog_cb, 571 args->get_qlog_cb_arg)) { 572 OPENSSL_free(txp); 573 return NULL; 574 } 575 576 return txp; 577 } 578 579 void ossl_quic_tx_packetiser_free(OSSL_QUIC_TX_PACKETISER *txp) 580 { 581 uint32_t enc_level; 582 583 if (txp == NULL) 584 return; 585 586 ossl_quic_tx_packetiser_set_initial_token(txp, NULL, 0, NULL, NULL); 587 ossl_quic_fifd_cleanup(&txp->fifd); 588 OPENSSL_free(txp->conn_close_frame.reason); 589 590 for (enc_level = QUIC_ENC_LEVEL_INITIAL; 591 enc_level < QUIC_ENC_LEVEL_NUM; 592 ++enc_level) { 593 OPENSSL_free(txp->el[enc_level].iovec); 594 OPENSSL_free(txp->el[enc_level].scratch); 595 } 596 597 OPENSSL_free(txp); 598 } 599 600 /* 601 * Determine if an Initial packet token length is reasonable based on the 602 * current MDPL, returning 1 if it is OK. 603 * 604 * The real PMTU to the peer could differ from our (pessimistic) understanding 605 * of the PMTU, therefore it is possible we could receive an Initial token from 606 * a server in a Retry packet which is bigger than the MDPL. In this case it is 607 * impossible for us ever to make forward progress and we need to error out 608 * and fail the connection attempt. 609 * 610 * The specific boundary condition is complex: for example, after the size of 611 * the Initial token, there are the Initial packet header overheads and then 612 * encryption/AEAD tag overheads. After that, the minimum room for frame data in 613 * order to guarantee forward progress must be guaranteed. For example, a crypto 614 * stream needs to always be able to serialize at least one byte in a CRYPTO 615 * frame in order to make forward progress. Because the offset field of a CRYPTO 616 * frame uses a variable-length integer, the number of bytes needed to ensure 617 * this also varies. 618 * 619 * Rather than trying to get this boundary condition check actually right, 620 * require a reasonable amount of slack to avoid pathological behaviours. (After 621 * all, transmitting a CRYPTO stream one byte at a time is probably not 622 * desirable anyway.) 623 * 624 * We choose 160 bytes as the required margin, which is double the rough 625 * estimation of the minimum we would require to guarantee forward progress 626 * under worst case packet overheads. 627 */ 628 #define TXP_REQUIRED_TOKEN_MARGIN 160 629 630 static int txp_check_token_len(size_t token_len, size_t mdpl) 631 { 632 if (token_len == 0) 633 return 1; 634 635 if (token_len >= mdpl) 636 return 0; 637 638 if (TXP_REQUIRED_TOKEN_MARGIN >= mdpl) 639 /* (should not be possible because MDPL must be at least 1200) */ 640 return 0; 641 642 if (token_len > mdpl - TXP_REQUIRED_TOKEN_MARGIN) 643 return 0; 644 645 return 1; 646 } 647 648 int ossl_quic_tx_packetiser_set_initial_token(OSSL_QUIC_TX_PACKETISER *txp, 649 const unsigned char *token, 650 size_t token_len, 651 ossl_quic_initial_token_free_fn *free_cb, 652 void *free_cb_arg) 653 { 654 if (!txp_check_token_len(token_len, txp_get_mdpl(txp))) 655 return 0; 656 657 if (txp->initial_token != NULL && txp->initial_token_free_cb != NULL) 658 txp->initial_token_free_cb(txp->initial_token, txp->initial_token_len, 659 txp->initial_token_free_cb_arg); 660 661 txp->initial_token = token; 662 txp->initial_token_len = token_len; 663 txp->initial_token_free_cb = free_cb; 664 txp->initial_token_free_cb_arg = free_cb_arg; 665 return 1; 666 } 667 668 int ossl_quic_tx_packetiser_set_protocol_version(OSSL_QUIC_TX_PACKETISER *txp, 669 uint32_t protocol_version) 670 { 671 txp->args.protocol_version = protocol_version; 672 return 1; 673 } 674 675 int ossl_quic_tx_packetiser_set_cur_dcid(OSSL_QUIC_TX_PACKETISER *txp, 676 const QUIC_CONN_ID *dcid) 677 { 678 if (dcid == NULL) { 679 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); 680 return 0; 681 } 682 683 txp->args.cur_dcid = *dcid; 684 return 1; 685 } 686 687 int ossl_quic_tx_packetiser_set_cur_scid(OSSL_QUIC_TX_PACKETISER *txp, 688 const QUIC_CONN_ID *scid) 689 { 690 if (scid == NULL) { 691 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); 692 return 0; 693 } 694 695 txp->args.cur_scid = *scid; 696 return 1; 697 } 698 699 /* Change the destination L4 address the TXP uses to send datagrams. */ 700 int ossl_quic_tx_packetiser_set_peer(OSSL_QUIC_TX_PACKETISER *txp, 701 const BIO_ADDR *peer) 702 { 703 if (peer == NULL) { 704 BIO_ADDR_clear(&txp->args.peer); 705 return 1; 706 } 707 708 return BIO_ADDR_copy(&txp->args.peer, peer); 709 } 710 711 void ossl_quic_tx_packetiser_set_ack_tx_cb(OSSL_QUIC_TX_PACKETISER *txp, 712 void (*cb)(const OSSL_QUIC_FRAME_ACK *ack, 713 uint32_t pn_space, 714 void *arg), 715 void *cb_arg) 716 { 717 txp->ack_tx_cb = cb; 718 txp->ack_tx_cb_arg = cb_arg; 719 } 720 721 void ossl_quic_tx_packetiser_set_qlog_cb(OSSL_QUIC_TX_PACKETISER *txp, 722 QLOG *(*get_qlog_cb)(void *arg), 723 void *get_qlog_cb_arg) 724 { 725 ossl_quic_fifd_set_qlog_cb(&txp->fifd, get_qlog_cb, get_qlog_cb_arg); 726 } 727 728 int ossl_quic_tx_packetiser_discard_enc_level(OSSL_QUIC_TX_PACKETISER *txp, 729 uint32_t enc_level) 730 { 731 if (enc_level >= QUIC_ENC_LEVEL_NUM) { 732 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); 733 return 0; 734 } 735 736 if (enc_level != QUIC_ENC_LEVEL_0RTT) 737 txp->args.crypto[ossl_quic_enc_level_to_pn_space(enc_level)] = NULL; 738 739 return 1; 740 } 741 742 void ossl_quic_tx_packetiser_notify_handshake_complete(OSSL_QUIC_TX_PACKETISER *txp) 743 { 744 txp->handshake_complete = 1; 745 } 746 747 void ossl_quic_tx_packetiser_schedule_handshake_done(OSSL_QUIC_TX_PACKETISER *txp) 748 { 749 txp->want_handshake_done = 1; 750 } 751 752 void ossl_quic_tx_packetiser_schedule_ack_eliciting(OSSL_QUIC_TX_PACKETISER *txp, 753 uint32_t pn_space) 754 { 755 txp->force_ack_eliciting |= (1UL << pn_space); 756 } 757 758 void ossl_quic_tx_packetiser_schedule_ack(OSSL_QUIC_TX_PACKETISER *txp, 759 uint32_t pn_space) 760 { 761 txp->want_ack |= (1UL << pn_space); 762 } 763 764 #define TXP_ERR_INTERNAL 0 /* Internal (e.g. alloc) error */ 765 #define TXP_ERR_SUCCESS 1 /* Success */ 766 #define TXP_ERR_SPACE 2 /* Not enough room for another packet */ 767 #define TXP_ERR_INPUT 3 /* Invalid/malformed input */ 768 769 /* 770 * Generates a datagram by polling the various ELs to determine if they want to 771 * generate any frames, and generating a datagram which coalesces packets for 772 * any ELs which do. 773 */ 774 int ossl_quic_tx_packetiser_generate(OSSL_QUIC_TX_PACKETISER *txp, 775 QUIC_TXP_STATUS *status) 776 { 777 /* 778 * Called to generate one or more datagrams, each containing one or more 779 * packets. 780 * 781 * There are some tricky things to note here: 782 * 783 * - The TXP is only concerned with generating encrypted packets; 784 * other packets use a different path. 785 * 786 * - Any datagram containing an Initial packet must have a payload length 787 * (DPL) of at least 1200 bytes. This padding need not necessarily be 788 * found in the Initial packet. 789 * 790 * - It is desirable to be able to coalesce an Initial packet 791 * with a Handshake packet. Since, before generating the Handshake 792 * packet, we do not know how long it will be, we cannot know the 793 * correct amount of padding to ensure a DPL of at least 1200 bytes. 794 * Thus this padding must added to the Handshake packet (or whatever 795 * packet is the last in the datagram). 796 * 797 * - However, at the time that we generate the Initial packet, 798 * we do not actually know for sure that we will be followed 799 * in the datagram by another packet. For example, suppose we have 800 * some queued data (e.g. crypto stream data for the HANDSHAKE EL) 801 * it looks like we will want to send on the HANDSHAKE EL. 802 * We could assume padding will be placed in the Handshake packet 803 * subsequently and avoid adding any padding to the Initial packet 804 * (which would leave no room for the Handshake packet in the 805 * datagram). 806 * 807 * However, this is not actually a safe assumption. Suppose that we 808 * are using a link with a MDPL of 1200 bytes, the minimum allowed by 809 * QUIC. Suppose that the Initial packet consumes 1195 bytes in total. 810 * Since it is not possible to fit a Handshake packet in just 5 bytes, 811 * upon trying to add a Handshake packet after generating the Initial 812 * packet, we will discover we have no room to fit it! This is not a 813 * problem in itself as another datagram can be sent subsequently, but 814 * it is a problem because we were counting to use that packet to hold 815 * the essential padding. But if we have already finished encrypting 816 * the Initial packet, we cannot go and add padding to it anymore. 817 * This leaves us stuck. 818 * 819 * Because of this, we have to plan multiple packets simultaneously, such 820 * that we can start generating a Handshake (or 0-RTT or 1-RTT, or so on) 821 * packet while still having the option to go back and add padding to the 822 * Initial packet if it turns out to be needed. 823 * 824 * Trying to predict ahead of time (e.g. during Initial packet generation) 825 * whether we will successfully generate a subsequent packet is fraught with 826 * error as it relies on a large number of variables: 827 * 828 * - Do we have room to fit a packet header? (Consider that due to 829 * variable-length integer encoding this is highly variable and can even 830 * depend on payload length due to a variable-length Length field.) 831 * 832 * - Can we fit even a single one of the frames we want to put in this 833 * packet in the packet? (Each frame type has a bespoke encoding. While 834 * our encodings of some frame types are adaptive based on the available 835 * room - e.g. STREAM frames - ultimately all frame types have some 836 * absolute minimum number of bytes to be successfully encoded. For 837 * example, if after an Initial packet there is enough room to encode 838 * only one byte of frame data, it is quite likely we can't send any of 839 * the frames we wanted to send.) While this is not strictly a problem 840 * because we could just fill the packet with padding frames, this is a 841 * pointless packet and is wasteful. 842 * 843 * Thus we adopt a multi-phase architecture: 844 * 845 * 1. Archetype Selection: Determine desired packet archetype. 846 * 847 * 2. Packet Staging: Generation of packet information and packet payload 848 * data (frame data) into staging areas. 849 * 850 * 3. Packet Adjustment: Adjustment of staged packets, adding padding to 851 * the staged packets if needed. 852 * 853 * 4. Commit: The packets are sent to the QTX and recorded as having been 854 * sent to the FIFM. 855 * 856 */ 857 int res = 0, rc; 858 uint32_t archetype, enc_level; 859 uint32_t conn_close_enc_level = QUIC_ENC_LEVEL_NUM; 860 struct txp_pkt pkt[QUIC_ENC_LEVEL_NUM]; 861 size_t pkts_done = 0; 862 uint64_t cc_limit = txp->args.cc_method->get_tx_allowance(txp->args.cc_data); 863 int need_padding = 0, txpim_pkt_reffed; 864 865 memset(status, 0, sizeof(*status)); 866 867 for (enc_level = QUIC_ENC_LEVEL_INITIAL; 868 enc_level < QUIC_ENC_LEVEL_NUM; 869 ++enc_level) 870 pkt[enc_level].h_valid = 0; 871 872 /* 873 * Should not be needed, but a sanity check in case anyone else has been 874 * using the QTX. 875 */ 876 ossl_qtx_finish_dgram(txp->args.qtx); 877 878 /* 1. Archetype Selection */ 879 archetype = txp_determine_archetype(txp, cc_limit); 880 881 /* 2. Packet Staging */ 882 for (enc_level = QUIC_ENC_LEVEL_INITIAL; 883 enc_level < QUIC_ENC_LEVEL_NUM; 884 ++enc_level) { 885 size_t running_total = (enc_level > QUIC_ENC_LEVEL_INITIAL) 886 ? pkt[enc_level - 1].geom.hwm 887 : 0; 888 889 pkt[enc_level].geom.hwm = running_total; 890 891 if (!txp_should_try_staging(txp, enc_level, archetype, cc_limit, 892 &conn_close_enc_level)) 893 continue; 894 895 if (!txp_pkt_init(&pkt[enc_level], txp, enc_level, archetype, 896 running_total)) 897 /* 898 * If this fails this is not a fatal error - it means the geometry 899 * planning determined there was not enough space for another 900 * packet. So just proceed with what we've already planned for. 901 */ 902 break; 903 904 rc = txp_generate_for_el(txp, &pkt[enc_level], 905 conn_close_enc_level == enc_level); 906 if (rc != TXP_ERR_SUCCESS) 907 goto out; 908 909 if (pkt[enc_level].force_pad) 910 /* 911 * txp_generate_for_el emitted a frame which forces packet padding. 912 */ 913 need_padding = 1; 914 915 pkt[enc_level].geom.hwm = running_total 916 + pkt[enc_level].h.bytes_appended 917 + pkt[enc_level].geom.pkt_overhead; 918 } 919 920 /* 3. Packet Adjustment */ 921 if (pkt[QUIC_ENC_LEVEL_INITIAL].h_valid 922 && pkt[QUIC_ENC_LEVEL_INITIAL].h.bytes_appended > 0) 923 /* 924 * We have an Initial packet in this datagram, so we need to make sure 925 * the total size of the datagram is adequate. 926 */ 927 need_padding = 1; 928 929 if (need_padding) { 930 size_t total_dgram_size = 0; 931 const size_t min_dpl = QUIC_MIN_INITIAL_DGRAM_LEN; 932 uint32_t pad_el = QUIC_ENC_LEVEL_NUM; 933 934 for (enc_level = QUIC_ENC_LEVEL_INITIAL; 935 enc_level < QUIC_ENC_LEVEL_NUM; 936 ++enc_level) 937 if (pkt[enc_level].h_valid && pkt[enc_level].h.bytes_appended > 0) { 938 if (pad_el == QUIC_ENC_LEVEL_NUM 939 /* 940 * We might not be able to add padding, for example if we 941 * are using the ACK_ONLY archetype. 942 */ 943 && pkt[enc_level].geom.adata.allow_padding 944 && !pkt[enc_level].h.done_implicit) 945 pad_el = enc_level; 946 947 txp_pkt_postgen_update_pkt_overhead(&pkt[enc_level], txp); 948 total_dgram_size += pkt[enc_level].geom.pkt_overhead 949 + pkt[enc_level].h.bytes_appended; 950 } 951 952 if (pad_el != QUIC_ENC_LEVEL_NUM && total_dgram_size < min_dpl) { 953 size_t deficit = min_dpl - total_dgram_size; 954 955 if (!txp_pkt_append_padding(&pkt[pad_el], txp, deficit)) 956 goto out; 957 958 total_dgram_size += deficit; 959 960 /* 961 * Padding frames make a packet ineligible for being a non-inflight 962 * packet. 963 */ 964 pkt[pad_el].tpkt->ackm_pkt.is_inflight = 1; 965 } 966 967 /* 968 * If we have failed to make a datagram of adequate size, for example 969 * because we have a padding requirement but are using the ACK_ONLY 970 * archetype (because we are CC limited), which precludes us from 971 * sending padding, give up on generating the datagram - there is 972 * nothing we can do. 973 */ 974 if (total_dgram_size < min_dpl) { 975 res = 1; 976 goto out; 977 } 978 } 979 980 /* 4. Commit */ 981 for (enc_level = QUIC_ENC_LEVEL_INITIAL; 982 enc_level < QUIC_ENC_LEVEL_NUM; 983 ++enc_level) { 984 985 if (!pkt[enc_level].h_valid) 986 /* Did not attempt to generate a packet for this EL. */ 987 continue; 988 989 if (pkt[enc_level].h.bytes_appended == 0) 990 /* Nothing was generated for this EL, so skip. */ 991 continue; 992 993 if (!ossl_quic_tx_packetiser_check_unvalidated_credit(txp, 994 pkt[enc_level].h.bytes_appended)) { 995 res = TXP_ERR_SPACE; 996 goto out; 997 } 998 ossl_quic_tx_packetiser_consume_unvalidated_credit(txp, pkt[enc_level].h.bytes_appended); 999 1000 rc = txp_pkt_commit(txp, &pkt[enc_level], archetype, 1001 &txpim_pkt_reffed); 1002 if (rc) { 1003 status->sent_ack_eliciting 1004 = status->sent_ack_eliciting 1005 || pkt[enc_level].tpkt->ackm_pkt.is_ack_eliciting; 1006 1007 if (enc_level == QUIC_ENC_LEVEL_HANDSHAKE) 1008 status->sent_handshake 1009 = (pkt[enc_level].h_valid 1010 && pkt[enc_level].h.bytes_appended > 0); 1011 } 1012 1013 if (txpim_pkt_reffed) 1014 pkt[enc_level].tpkt = NULL; /* don't free */ 1015 1016 if (!rc) 1017 goto out; 1018 1019 ++pkts_done; 1020 } 1021 1022 /* Flush & Cleanup */ 1023 res = 1; 1024 out: 1025 ossl_qtx_finish_dgram(txp->args.qtx); 1026 1027 for (enc_level = QUIC_ENC_LEVEL_INITIAL; 1028 enc_level < QUIC_ENC_LEVEL_NUM; 1029 ++enc_level) 1030 txp_pkt_cleanup(&pkt[enc_level], txp); 1031 1032 status->sent_pkt = pkts_done; 1033 1034 return res; 1035 } 1036 1037 static const struct archetype_data archetypes[QUIC_ENC_LEVEL_NUM][TX_PACKETISER_ARCHETYPE_NUM] = { 1038 /* EL 0(INITIAL) */ 1039 { 1040 /* EL 0(INITIAL) - Archetype 0(NORMAL) */ 1041 { 1042 /*allow_ack =*/1, 1043 /*allow_ping =*/1, 1044 /*allow_crypto =*/1, 1045 /*allow_handshake_done =*/0, 1046 /*allow_path_challenge =*/0, 1047 /*allow_path_response =*/0, 1048 /*allow_new_conn_id =*/0, 1049 /*allow_retire_conn_id =*/0, 1050 /*allow_stream_rel =*/0, 1051 /*allow_conn_fc =*/0, 1052 /*allow_conn_close =*/1, 1053 /*allow_cfq_other =*/0, 1054 /*allow_new_token =*/0, 1055 /*allow_force_ack_eliciting =*/1, 1056 /*allow_padding =*/1, 1057 /*require_ack_eliciting =*/0, 1058 /*bypass_cc =*/0, 1059 }, 1060 /* EL 0(INITIAL) - Archetype 1(PROBE) */ 1061 { 1062 /*allow_ack =*/1, 1063 /*allow_ping =*/1, 1064 /*allow_crypto =*/1, 1065 /*allow_handshake_done =*/0, 1066 /*allow_path_challenge =*/0, 1067 /*allow_path_response =*/0, 1068 /*allow_new_conn_id =*/0, 1069 /*allow_retire_conn_id =*/0, 1070 /*allow_stream_rel =*/0, 1071 /*allow_conn_fc =*/0, 1072 /*allow_conn_close =*/1, 1073 /*allow_cfq_other =*/0, 1074 /*allow_new_token =*/0, 1075 /*allow_force_ack_eliciting =*/1, 1076 /*allow_padding =*/1, 1077 /*require_ack_eliciting =*/1, 1078 /*bypass_cc =*/1, 1079 }, 1080 /* EL 0(INITIAL) - Archetype 2(ACK_ONLY) */ 1081 { 1082 /*allow_ack =*/1, 1083 /*allow_ping =*/0, 1084 /*allow_crypto =*/0, 1085 /*allow_handshake_done =*/0, 1086 /*allow_path_challenge =*/0, 1087 /*allow_path_response =*/0, 1088 /*allow_new_conn_id =*/0, 1089 /*allow_retire_conn_id =*/0, 1090 /*allow_stream_rel =*/0, 1091 /*allow_conn_fc =*/0, 1092 /*allow_conn_close =*/0, 1093 /*allow_cfq_other =*/0, 1094 /*allow_new_token =*/0, 1095 /*allow_force_ack_eliciting =*/1, 1096 /*allow_padding =*/0, 1097 /*require_ack_eliciting =*/0, 1098 /*bypass_cc =*/1, 1099 }, 1100 }, 1101 /* EL 1(0RTT) */ 1102 { 1103 /* EL 1(0RTT) - Archetype 0(NORMAL) */ 1104 { 1105 /*allow_ack =*/0, 1106 /*allow_ping =*/1, 1107 /*allow_crypto =*/0, 1108 /*allow_handshake_done =*/0, 1109 /*allow_path_challenge =*/0, 1110 /*allow_path_response =*/0, 1111 /*allow_new_conn_id =*/1, 1112 /*allow_retire_conn_id =*/1, 1113 /*allow_stream_rel =*/1, 1114 /*allow_conn_fc =*/1, 1115 /*allow_conn_close =*/1, 1116 /*allow_cfq_other =*/0, 1117 /*allow_new_token =*/0, 1118 /*allow_force_ack_eliciting =*/0, 1119 /*allow_padding =*/1, 1120 /*require_ack_eliciting =*/0, 1121 /*bypass_cc =*/0, 1122 }, 1123 /* EL 1(0RTT) - Archetype 1(PROBE) */ 1124 { 1125 /*allow_ack =*/0, 1126 /*allow_ping =*/1, 1127 /*allow_crypto =*/0, 1128 /*allow_handshake_done =*/0, 1129 /*allow_path_challenge =*/0, 1130 /*allow_path_response =*/0, 1131 /*allow_new_conn_id =*/1, 1132 /*allow_retire_conn_id =*/1, 1133 /*allow_stream_rel =*/1, 1134 /*allow_conn_fc =*/1, 1135 /*allow_conn_close =*/1, 1136 /*allow_cfq_other =*/0, 1137 /*allow_new_token =*/0, 1138 /*allow_force_ack_eliciting =*/0, 1139 /*allow_padding =*/1, 1140 /*require_ack_eliciting =*/1, 1141 /*bypass_cc =*/1, 1142 }, 1143 /* EL 1(0RTT) - Archetype 2(ACK_ONLY) */ 1144 { 1145 /*allow_ack =*/0, 1146 /*allow_ping =*/0, 1147 /*allow_crypto =*/0, 1148 /*allow_handshake_done =*/0, 1149 /*allow_path_challenge =*/0, 1150 /*allow_path_response =*/0, 1151 /*allow_new_conn_id =*/0, 1152 /*allow_retire_conn_id =*/0, 1153 /*allow_stream_rel =*/0, 1154 /*allow_conn_fc =*/0, 1155 /*allow_conn_close =*/0, 1156 /*allow_cfq_other =*/0, 1157 /*allow_new_token =*/0, 1158 /*allow_force_ack_eliciting =*/0, 1159 /*allow_padding =*/0, 1160 /*require_ack_eliciting =*/0, 1161 /*bypass_cc =*/1, 1162 }, 1163 }, 1164 /* EL (HANDSHAKE) */ 1165 { 1166 /* EL 2(HANDSHAKE) - Archetype 0(NORMAL) */ 1167 { 1168 /*allow_ack =*/1, 1169 /*allow_ping =*/1, 1170 /*allow_crypto =*/1, 1171 /*allow_handshake_done =*/0, 1172 /*allow_path_challenge =*/0, 1173 /*allow_path_response =*/0, 1174 /*allow_new_conn_id =*/0, 1175 /*allow_retire_conn_id =*/0, 1176 /*allow_stream_rel =*/0, 1177 /*allow_conn_fc =*/0, 1178 /*allow_conn_close =*/1, 1179 /*allow_cfq_other =*/0, 1180 /*allow_new_token =*/0, 1181 /*allow_force_ack_eliciting =*/1, 1182 /*allow_padding =*/1, 1183 /*require_ack_eliciting =*/0, 1184 /*bypass_cc =*/0, 1185 }, 1186 /* EL 2(HANDSHAKE) - Archetype 1(PROBE) */ 1187 { 1188 /*allow_ack =*/1, 1189 /*allow_ping =*/1, 1190 /*allow_crypto =*/1, 1191 /*allow_handshake_done =*/0, 1192 /*allow_path_challenge =*/0, 1193 /*allow_path_response =*/0, 1194 /*allow_new_conn_id =*/0, 1195 /*allow_retire_conn_id =*/0, 1196 /*allow_stream_rel =*/0, 1197 /*allow_conn_fc =*/0, 1198 /*allow_conn_close =*/1, 1199 /*allow_cfq_other =*/0, 1200 /*allow_new_token =*/0, 1201 /*allow_force_ack_eliciting =*/1, 1202 /*allow_padding =*/1, 1203 /*require_ack_eliciting =*/1, 1204 /*bypass_cc =*/1, 1205 }, 1206 /* EL 2(HANDSHAKE) - Archetype 2(ACK_ONLY) */ 1207 { 1208 /*allow_ack =*/1, 1209 /*allow_ping =*/0, 1210 /*allow_crypto =*/0, 1211 /*allow_handshake_done =*/0, 1212 /*allow_path_challenge =*/0, 1213 /*allow_path_response =*/0, 1214 /*allow_new_conn_id =*/0, 1215 /*allow_retire_conn_id =*/0, 1216 /*allow_stream_rel =*/0, 1217 /*allow_conn_fc =*/0, 1218 /*allow_conn_close =*/0, 1219 /*allow_cfq_other =*/0, 1220 /*allow_new_token =*/0, 1221 /*allow_force_ack_eliciting =*/1, 1222 /*allow_padding =*/0, 1223 /*require_ack_eliciting =*/0, 1224 /*bypass_cc =*/1, 1225 }, 1226 }, 1227 /* EL 3(1RTT) */ 1228 { 1229 /* EL 3(1RTT) - Archetype 0(NORMAL) */ 1230 { 1231 /*allow_ack =*/1, 1232 /*allow_ping =*/1, 1233 /*allow_crypto =*/1, 1234 /*allow_handshake_done =*/1, 1235 /*allow_path_challenge =*/0, 1236 /*allow_path_response =*/1, 1237 /*allow_new_conn_id =*/1, 1238 /*allow_retire_conn_id =*/1, 1239 /*allow_stream_rel =*/1, 1240 /*allow_conn_fc =*/1, 1241 /*allow_conn_close =*/1, 1242 /*allow_cfq_other =*/1, 1243 /*allow_new_token =*/1, 1244 /*allow_force_ack_eliciting =*/1, 1245 /*allow_padding =*/1, 1246 /*require_ack_eliciting =*/0, 1247 /*bypass_cc =*/0, 1248 }, 1249 /* EL 3(1RTT) - Archetype 1(PROBE) */ 1250 { 1251 /*allow_ack =*/1, 1252 /*allow_ping =*/1, 1253 /*allow_crypto =*/1, 1254 /*allow_handshake_done =*/1, 1255 /*allow_path_challenge =*/0, 1256 /*allow_path_response =*/1, 1257 /*allow_new_conn_id =*/1, 1258 /*allow_retire_conn_id =*/1, 1259 /*allow_stream_rel =*/1, 1260 /*allow_conn_fc =*/1, 1261 /*allow_conn_close =*/1, 1262 /*allow_cfq_other =*/1, 1263 /*allow_new_token =*/1, 1264 /*allow_force_ack_eliciting =*/1, 1265 /*allow_padding =*/1, 1266 /*require_ack_eliciting =*/1, 1267 /*bypass_cc =*/1, 1268 }, 1269 /* EL 3(1RTT) - Archetype 2(ACK_ONLY) */ 1270 { 1271 /*allow_ack =*/1, 1272 /*allow_ping =*/0, 1273 /*allow_crypto =*/0, 1274 /*allow_handshake_done =*/0, 1275 /*allow_path_challenge =*/0, 1276 /*allow_path_response =*/0, 1277 /*allow_new_conn_id =*/0, 1278 /*allow_retire_conn_id =*/0, 1279 /*allow_stream_rel =*/0, 1280 /*allow_conn_fc =*/0, 1281 /*allow_conn_close =*/0, 1282 /*allow_cfq_other =*/0, 1283 /*allow_new_token =*/0, 1284 /*allow_force_ack_eliciting =*/1, 1285 /*allow_padding =*/0, 1286 /*require_ack_eliciting =*/0, 1287 /*bypass_cc =*/1, 1288 } } 1289 }; 1290 1291 static int txp_get_archetype_data(uint32_t enc_level, 1292 uint32_t archetype, 1293 struct archetype_data *a) 1294 { 1295 if (enc_level >= QUIC_ENC_LEVEL_NUM 1296 || archetype >= TX_PACKETISER_ARCHETYPE_NUM) 1297 return 0; 1298 1299 /* No need to avoid copying this as it should not exceed one int in size. */ 1300 *a = archetypes[enc_level][archetype]; 1301 return 1; 1302 } 1303 1304 static int txp_determine_geometry(OSSL_QUIC_TX_PACKETISER *txp, 1305 uint32_t archetype, 1306 uint32_t enc_level, 1307 size_t running_total, 1308 QUIC_PKT_HDR *phdr, 1309 struct txp_pkt_geom *geom) 1310 { 1311 size_t mdpl, cmpl, hdr_len; 1312 1313 /* Get information about packet archetype. */ 1314 if (!txp_get_archetype_data(enc_level, archetype, &geom->adata)) 1315 return 0; 1316 1317 /* Assemble packet header. */ 1318 phdr->type = ossl_quic_enc_level_to_pkt_type(enc_level); 1319 phdr->spin_bit = 0; 1320 phdr->pn_len = txp_determine_pn_len(txp); 1321 phdr->partial = 0; 1322 phdr->fixed = 1; 1323 phdr->reserved = 0; 1324 phdr->version = txp->args.protocol_version; 1325 phdr->dst_conn_id = txp->args.cur_dcid; 1326 phdr->src_conn_id = txp->args.cur_scid; 1327 1328 /* 1329 * We need to know the length of the payload to get an accurate header 1330 * length for non-1RTT packets, because the Length field found in 1331 * Initial/Handshake/0-RTT packets uses a variable-length encoding. However, 1332 * we don't have a good idea of the length of our payload, because the 1333 * length of the payload depends on the room in the datagram after fitting 1334 * the header, which depends on the size of the header. 1335 * 1336 * In general, it does not matter if a packet is slightly shorter (because 1337 * e.g. we predicted use of a 2-byte length field, but ended up only needing 1338 * a 1-byte length field). However this does matter for Initial packets 1339 * which must be at least 1200 bytes, which is also the assumed default MTU; 1340 * therefore in many cases Initial packets will be padded to 1200 bytes, 1341 * which means if we overestimated the header size, we will be short by a 1342 * few bytes and the server will ignore the packet for being too short. In 1343 * this case, however, such packets always *will* be padded to meet 1200 1344 * bytes, which requires a 2-byte length field, so we don't actually need to 1345 * worry about this. Thus we estimate the header length assuming a 2-byte 1346 * length field here, which should in practice work well in all cases. 1347 */ 1348 phdr->len = OSSL_QUIC_VLINT_2B_MAX - phdr->pn_len; 1349 1350 if (enc_level == QUIC_ENC_LEVEL_INITIAL) { 1351 phdr->token = txp->initial_token; 1352 phdr->token_len = txp->initial_token_len; 1353 } else { 1354 phdr->token = NULL; 1355 phdr->token_len = 0; 1356 } 1357 1358 hdr_len = ossl_quic_wire_get_encoded_pkt_hdr_len(phdr->dst_conn_id.id_len, 1359 phdr); 1360 if (hdr_len == 0) 1361 return 0; 1362 1363 /* MDPL: Maximum datagram payload length. */ 1364 mdpl = txp_get_mdpl(txp); 1365 1366 /* 1367 * CMPL: Maximum encoded packet size we can put into this datagram given any 1368 * previous packets coalesced into it. 1369 */ 1370 if (running_total > mdpl) 1371 /* Should not be possible, but if it happens: */ 1372 cmpl = 0; 1373 else 1374 cmpl = mdpl - running_total; 1375 1376 /* CMPPL: Maximum amount we can put into the current packet payload */ 1377 if (!txp_determine_ppl_from_pl(txp, cmpl, enc_level, hdr_len, &geom->cmppl)) 1378 return 0; 1379 1380 geom->cmpl = cmpl; 1381 geom->pkt_overhead = cmpl - geom->cmppl; 1382 geom->archetype = archetype; 1383 return 1; 1384 } 1385 1386 static uint32_t txp_determine_archetype(OSSL_QUIC_TX_PACKETISER *txp, 1387 uint64_t cc_limit) 1388 { 1389 OSSL_ACKM_PROBE_INFO *probe_info 1390 = ossl_ackm_get0_probe_request(txp->args.ackm); 1391 uint32_t pn_space; 1392 1393 /* 1394 * If ACKM has requested probe generation (e.g. due to PTO), we generate a 1395 * Probe-archetype packet. Actually, we determine archetype on a 1396 * per-datagram basis, so if any EL wants a probe, do a pass in which 1397 * we try and generate a probe (if needed) for all ELs. 1398 */ 1399 if (probe_info->anti_deadlock_initial > 0 1400 || probe_info->anti_deadlock_handshake > 0) 1401 return TX_PACKETISER_ARCHETYPE_PROBE; 1402 1403 for (pn_space = QUIC_PN_SPACE_INITIAL; 1404 pn_space < QUIC_PN_SPACE_NUM; 1405 ++pn_space) 1406 if (probe_info->pto[pn_space] > 0) 1407 return TX_PACKETISER_ARCHETYPE_PROBE; 1408 1409 /* 1410 * If we are out of CC budget, we cannot send a normal packet, 1411 * but we can do an ACK-only packet (potentially, if we 1412 * want to send an ACK). 1413 */ 1414 if (cc_limit == 0) 1415 return TX_PACKETISER_ARCHETYPE_ACK_ONLY; 1416 1417 /* All other packets. */ 1418 return TX_PACKETISER_ARCHETYPE_NORMAL; 1419 } 1420 1421 static int txp_should_try_staging(OSSL_QUIC_TX_PACKETISER *txp, 1422 uint32_t enc_level, 1423 uint32_t archetype, 1424 uint64_t cc_limit, 1425 uint32_t *conn_close_enc_level) 1426 { 1427 struct archetype_data a; 1428 uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); 1429 QUIC_CFQ_ITEM *cfq_item; 1430 1431 if (!ossl_qtx_is_enc_level_provisioned(txp->args.qtx, enc_level)) 1432 return 0; 1433 1434 if (!txp_get_archetype_data(enc_level, archetype, &a)) 1435 return 0; 1436 1437 if (!a.bypass_cc && cc_limit == 0) 1438 /* CC not allowing us to send. */ 1439 return 0; 1440 1441 /* 1442 * We can produce CONNECTION_CLOSE frames on any EL in principle, which 1443 * means we need to choose which EL we would prefer to use. After a 1444 * connection is fully established we have only one provisioned EL and this 1445 * is a non-issue. Where multiple ELs are provisioned, it is possible the 1446 * peer does not have the keys for the EL yet, which suggests in general it 1447 * is preferable to use the lowest EL which is still provisioned. 1448 * 1449 * However (RFC 9000 s. 10.2.3 & 12.5) we are also required to not send 1450 * application CONNECTION_CLOSE frames in non-1-RTT ELs, so as to not 1451 * potentially leak application data on a connection which has yet to be 1452 * authenticated. Thus when we have an application CONNECTION_CLOSE frame 1453 * queued and need to send it on a non-1-RTT EL, we have to convert it 1454 * into a transport CONNECTION_CLOSE frame which contains no application 1455 * data. Since this loses information, it suggests we should use the 1-RTT 1456 * EL to avoid this if possible, even if a lower EL is also available. 1457 * 1458 * At the same time, just because we have the 1-RTT EL provisioned locally 1459 * does not necessarily mean the peer does, for example if a handshake 1460 * CRYPTO frame has been lost. It is fairly important that CONNECTION_CLOSE 1461 * is signalled in a way we know our peer can decrypt, as we stop processing 1462 * connection retransmission logic for real after connection close and 1463 * simply 'blindly' retransmit the same CONNECTION_CLOSE frame. 1464 * 1465 * This is not a major concern for clients, since if a client has a 1-RTT EL 1466 * provisioned the server is guaranteed to also have a 1-RTT EL provisioned. 1467 * 1468 * TODO(QUIC FUTURE): Revisit this when when have reached a decision on how 1469 * best to implement this 1470 */ 1471 if (*conn_close_enc_level > enc_level 1472 && *conn_close_enc_level != QUIC_ENC_LEVEL_1RTT) 1473 *conn_close_enc_level = enc_level; 1474 1475 /* Do we need to send a PTO probe? */ 1476 if (a.allow_force_ack_eliciting) { 1477 OSSL_ACKM_PROBE_INFO *probe_info 1478 = ossl_ackm_get0_probe_request(txp->args.ackm); 1479 1480 if ((enc_level == QUIC_ENC_LEVEL_INITIAL 1481 && probe_info->anti_deadlock_initial > 0) 1482 || (enc_level == QUIC_ENC_LEVEL_HANDSHAKE 1483 && probe_info->anti_deadlock_handshake > 0) 1484 || probe_info->pto[pn_space] > 0) 1485 return 1; 1486 } 1487 1488 /* Does the crypto stream for this EL want to produce anything? */ 1489 if (a.allow_crypto && sstream_is_pending(txp->args.crypto[pn_space])) 1490 return 1; 1491 1492 /* Does the ACKM for this PN space want to produce anything? */ 1493 if (a.allow_ack && (ossl_ackm_is_ack_desired(txp->args.ackm, pn_space) || (txp->want_ack & (1UL << pn_space)) != 0)) 1494 return 1; 1495 1496 /* Do we need to force emission of an ACK-eliciting packet? */ 1497 if (a.allow_force_ack_eliciting 1498 && (txp->force_ack_eliciting & (1UL << pn_space)) != 0) 1499 return 1; 1500 1501 /* Does the connection-level RXFC want to produce a frame? */ 1502 if (a.allow_conn_fc && (txp->want_max_data || ossl_quic_rxfc_has_cwm_changed(txp->args.conn_rxfc, 0))) 1503 return 1; 1504 1505 /* Do we want to produce a MAX_STREAMS frame? */ 1506 if (a.allow_conn_fc 1507 && (txp->want_max_streams_bidi 1508 || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_bidi_rxfc, 1509 0) 1510 || txp->want_max_streams_uni 1511 || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_uni_rxfc, 1512 0))) 1513 return 1; 1514 1515 /* Do we want to produce a HANDSHAKE_DONE frame? */ 1516 if (a.allow_handshake_done && txp->want_handshake_done) 1517 return 1; 1518 1519 /* Do we want to produce a CONNECTION_CLOSE frame? */ 1520 if (a.allow_conn_close && txp->want_conn_close && *conn_close_enc_level == enc_level) 1521 /* 1522 * This is a bit of a special case since CONNECTION_CLOSE can appear in 1523 * most packet types, and when we decide we want to send it this status 1524 * isn't tied to a specific EL. So if we want to send it, we send it 1525 * only on the lowest non-dropped EL. 1526 */ 1527 return 1; 1528 1529 /* Does the CFQ have any frames queued for this PN space? */ 1530 if (enc_level != QUIC_ENC_LEVEL_0RTT) 1531 for (cfq_item = ossl_quic_cfq_get_priority_head(txp->args.cfq, pn_space); 1532 cfq_item != NULL; 1533 cfq_item = ossl_quic_cfq_item_get_priority_next(cfq_item, pn_space)) { 1534 uint64_t frame_type = ossl_quic_cfq_item_get_frame_type(cfq_item); 1535 1536 switch (frame_type) { 1537 case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID: 1538 if (a.allow_new_conn_id) 1539 return 1; 1540 break; 1541 case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID: 1542 if (a.allow_retire_conn_id) 1543 return 1; 1544 break; 1545 case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN: 1546 if (a.allow_new_token) 1547 return 1; 1548 break; 1549 case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE: 1550 if (a.allow_path_response) 1551 return 1; 1552 break; 1553 default: 1554 if (a.allow_cfq_other) 1555 return 1; 1556 break; 1557 } 1558 } 1559 1560 if (a.allow_stream_rel && txp->handshake_complete) { 1561 QUIC_STREAM_ITER it; 1562 1563 /* If there are any active streams, 0/1-RTT wants to produce a packet. 1564 * Whether a stream is on the active list is required to be precise 1565 * (i.e., a stream is never on the active list if we cannot produce a 1566 * frame for it), and all stream-related frames are governed by 1567 * a.allow_stream_rel (i.e., if we can send one type of stream-related 1568 * frame, we can send any of them), so we don't need to inspect 1569 * individual streams on the active list, just confirm that the active 1570 * list is non-empty. 1571 */ 1572 ossl_quic_stream_iter_init(&it, txp->args.qsm, 0); 1573 if (it.stream != NULL) 1574 return 1; 1575 } 1576 1577 return 0; 1578 } 1579 1580 static int sstream_is_pending(QUIC_SSTREAM *sstream) 1581 { 1582 OSSL_QUIC_FRAME_STREAM hdr; 1583 OSSL_QTX_IOVEC iov[2]; 1584 size_t num_iov = OSSL_NELEM(iov); 1585 1586 return ossl_quic_sstream_get_stream_frame(sstream, 0, &hdr, iov, &num_iov); 1587 } 1588 1589 /* Determine how many bytes we should use for the encoded PN. */ 1590 static size_t txp_determine_pn_len(OSSL_QUIC_TX_PACKETISER *txp) 1591 { 1592 return 4; /* TODO(QUIC FUTURE) */ 1593 } 1594 1595 /* Determine plaintext packet payload length from payload length. */ 1596 static int txp_determine_ppl_from_pl(OSSL_QUIC_TX_PACKETISER *txp, 1597 size_t pl, 1598 uint32_t enc_level, 1599 size_t hdr_len, 1600 size_t *r) 1601 { 1602 if (pl < hdr_len) 1603 return 0; 1604 1605 pl -= hdr_len; 1606 1607 if (!ossl_qtx_calculate_plaintext_payload_len(txp->args.qtx, enc_level, 1608 pl, &pl)) 1609 return 0; 1610 1611 *r = pl; 1612 return 1; 1613 } 1614 1615 static size_t txp_get_mdpl(OSSL_QUIC_TX_PACKETISER *txp) 1616 { 1617 return ossl_qtx_get_mdpl(txp->args.qtx); 1618 } 1619 1620 static QUIC_SSTREAM *get_sstream_by_id(uint64_t stream_id, uint32_t pn_space, 1621 void *arg) 1622 { 1623 OSSL_QUIC_TX_PACKETISER *txp = arg; 1624 QUIC_STREAM *s; 1625 1626 if (stream_id == UINT64_MAX) 1627 return txp->args.crypto[pn_space]; 1628 1629 s = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); 1630 if (s == NULL) 1631 return NULL; 1632 1633 return s->sstream; 1634 } 1635 1636 static void on_regen_notify(uint64_t frame_type, uint64_t stream_id, 1637 QUIC_TXPIM_PKT *pkt, void *arg) 1638 { 1639 OSSL_QUIC_TX_PACKETISER *txp = arg; 1640 1641 switch (frame_type) { 1642 case OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE: 1643 txp->want_handshake_done = 1; 1644 break; 1645 case OSSL_QUIC_FRAME_TYPE_MAX_DATA: 1646 txp->want_max_data = 1; 1647 break; 1648 case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI: 1649 txp->want_max_streams_bidi = 1; 1650 break; 1651 case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI: 1652 txp->want_max_streams_uni = 1; 1653 break; 1654 case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN: 1655 txp->want_ack |= (1UL << pkt->ackm_pkt.pkt_space); 1656 break; 1657 case OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA: { 1658 QUIC_STREAM *s 1659 = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); 1660 1661 if (s == NULL) 1662 return; 1663 1664 s->want_max_stream_data = 1; 1665 ossl_quic_stream_map_update_state(txp->args.qsm, s); 1666 } break; 1667 case OSSL_QUIC_FRAME_TYPE_STOP_SENDING: { 1668 QUIC_STREAM *s 1669 = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); 1670 1671 if (s == NULL) 1672 return; 1673 1674 ossl_quic_stream_map_schedule_stop_sending(txp->args.qsm, s); 1675 } break; 1676 case OSSL_QUIC_FRAME_TYPE_RESET_STREAM: { 1677 QUIC_STREAM *s 1678 = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); 1679 1680 if (s == NULL) 1681 return; 1682 1683 s->want_reset_stream = 1; 1684 ossl_quic_stream_map_update_state(txp->args.qsm, s); 1685 } break; 1686 default: 1687 assert(0); 1688 break; 1689 } 1690 } 1691 1692 static int txp_need_ping(OSSL_QUIC_TX_PACKETISER *txp, 1693 uint32_t pn_space, 1694 const struct archetype_data *adata) 1695 { 1696 return adata->allow_ping 1697 && (adata->require_ack_eliciting 1698 || (txp->force_ack_eliciting & (1UL << pn_space)) != 0); 1699 } 1700 1701 static int txp_pkt_init(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp, 1702 uint32_t enc_level, uint32_t archetype, 1703 size_t running_total) 1704 { 1705 uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); 1706 1707 if (!txp_determine_geometry(txp, archetype, enc_level, 1708 running_total, &pkt->phdr, &pkt->geom)) 1709 return 0; 1710 1711 /* 1712 * Initialise TX helper. If we must be ACK eliciting, reserve 1 byte for 1713 * PING. 1714 */ 1715 if (!tx_helper_init(&pkt->h, txp, enc_level, 1716 pkt->geom.cmppl, 1717 txp_need_ping(txp, pn_space, &pkt->geom.adata) ? 1 : 0)) 1718 return 0; 1719 1720 pkt->h_valid = 1; 1721 pkt->tpkt = NULL; 1722 pkt->stream_head = NULL; 1723 pkt->force_pad = 0; 1724 return 1; 1725 } 1726 1727 static void txp_pkt_cleanup(struct txp_pkt *pkt, OSSL_QUIC_TX_PACKETISER *txp) 1728 { 1729 if (!pkt->h_valid) 1730 return; 1731 1732 tx_helper_cleanup(&pkt->h); 1733 pkt->h_valid = 0; 1734 1735 if (pkt->tpkt != NULL) { 1736 ossl_quic_txpim_pkt_release(txp->args.txpim, pkt->tpkt); 1737 pkt->tpkt = NULL; 1738 } 1739 } 1740 1741 static int txp_pkt_postgen_update_pkt_overhead(struct txp_pkt *pkt, 1742 OSSL_QUIC_TX_PACKETISER *txp) 1743 { 1744 /* 1745 * After we have staged and generated our packets, but before we commit 1746 * them, it is possible for the estimated packet overhead (packet header + 1747 * AEAD tag size) to shrink slightly because we generated a short packet 1748 * whose which can be represented in fewer bytes as a variable-length 1749 * integer than we were (pessimistically) budgeting for. We need to account 1750 * for this to ensure that we get our padding calculation exactly right. 1751 * 1752 * Update pkt_overhead to be accurate now that we know how much data is 1753 * going in a packet. 1754 */ 1755 size_t hdr_len, ciphertext_len; 1756 1757 if (pkt->h.enc_level == QUIC_ENC_LEVEL_INITIAL) 1758 /* 1759 * Don't update overheads for the INITIAL EL - we have not finished 1760 * appending padding to it and would potentially miscalculate the 1761 * correct padding if we now update the pkt_overhead field to switch to 1762 * e.g. a 1-byte length field in the packet header. Since we are padding 1763 * to QUIC_MIN_INITIAL_DGRAM_LEN which requires a 2-byte length field, 1764 * this is guaranteed to be moot anyway. See comment in 1765 * txp_determine_geometry for more information. 1766 */ 1767 return 1; 1768 1769 if (!ossl_qtx_calculate_ciphertext_payload_len(txp->args.qtx, pkt->h.enc_level, 1770 pkt->h.bytes_appended, 1771 &ciphertext_len)) 1772 return 0; 1773 1774 pkt->phdr.len = ciphertext_len; 1775 1776 hdr_len = ossl_quic_wire_get_encoded_pkt_hdr_len(pkt->phdr.dst_conn_id.id_len, 1777 &pkt->phdr); 1778 1779 pkt->geom.pkt_overhead = hdr_len + ciphertext_len - pkt->h.bytes_appended; 1780 return 1; 1781 } 1782 1783 static void on_confirm_notify(uint64_t frame_type, uint64_t stream_id, 1784 QUIC_TXPIM_PKT *pkt, void *arg) 1785 { 1786 OSSL_QUIC_TX_PACKETISER *txp = arg; 1787 1788 switch (frame_type) { 1789 case OSSL_QUIC_FRAME_TYPE_STOP_SENDING: { 1790 QUIC_STREAM *s 1791 = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); 1792 1793 if (s == NULL) 1794 return; 1795 1796 s->acked_stop_sending = 1; 1797 ossl_quic_stream_map_update_state(txp->args.qsm, s); 1798 } break; 1799 case OSSL_QUIC_FRAME_TYPE_RESET_STREAM: { 1800 QUIC_STREAM *s 1801 = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); 1802 1803 if (s == NULL) 1804 return; 1805 1806 /* 1807 * We must already be in RESET_SENT or RESET_RECVD if we are 1808 * here, so we don't need to check state here. 1809 */ 1810 ossl_quic_stream_map_notify_reset_stream_acked(txp->args.qsm, s); 1811 ossl_quic_stream_map_update_state(txp->args.qsm, s); 1812 } break; 1813 default: 1814 assert(0); 1815 break; 1816 } 1817 } 1818 1819 static int txp_pkt_append_padding(struct txp_pkt *pkt, 1820 OSSL_QUIC_TX_PACKETISER *txp, size_t num_bytes) 1821 { 1822 WPACKET *wpkt; 1823 1824 if (num_bytes == 0) 1825 return 1; 1826 1827 if (!ossl_assert(pkt->h_valid)) 1828 return 0; 1829 1830 if (!ossl_assert(pkt->tpkt != NULL)) 1831 return 0; 1832 1833 wpkt = tx_helper_begin(&pkt->h); 1834 if (wpkt == NULL) 1835 return 0; 1836 1837 if (!ossl_quic_wire_encode_padding(wpkt, num_bytes)) { 1838 tx_helper_rollback(&pkt->h); 1839 return 0; 1840 } 1841 1842 if (!tx_helper_commit(&pkt->h)) 1843 return 0; 1844 1845 pkt->tpkt->ackm_pkt.num_bytes += num_bytes; 1846 /* Cannot be non-inflight if we have a PADDING frame */ 1847 pkt->tpkt->ackm_pkt.is_inflight = 1; 1848 return 1; 1849 } 1850 1851 static void on_sstream_updated(uint64_t stream_id, void *arg) 1852 { 1853 OSSL_QUIC_TX_PACKETISER *txp = arg; 1854 QUIC_STREAM *s; 1855 1856 s = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); 1857 if (s == NULL) 1858 return; 1859 1860 ossl_quic_stream_map_update_state(txp->args.qsm, s); 1861 } 1862 1863 /* 1864 * Returns 1 if we can send that many bytes in closing state, 0 otherwise. 1865 * Also maintains the bytes sent state if it returns a success. 1866 */ 1867 static int try_commit_conn_close(OSSL_QUIC_TX_PACKETISER *txp, size_t n) 1868 { 1869 int res; 1870 1871 /* We can always send the first connection close frame */ 1872 if (txp->closing_bytes_recv == 0) 1873 return 1; 1874 1875 /* 1876 * RFC 9000 s. 10.2.1 Closing Connection State: 1877 * To avoid being used for an amplification attack, such 1878 * endpoints MUST limit the cumulative size of packets it sends 1879 * to three times the cumulative size of the packets that are 1880 * received and attributed to the connection. 1881 * and: 1882 * An endpoint in the closing state MUST either discard packets 1883 * received from an unvalidated address or limit the cumulative 1884 * size of packets it sends to an unvalidated address to three 1885 * times the size of packets it receives from that address. 1886 */ 1887 res = txp->closing_bytes_xmit + n <= txp->closing_bytes_recv * 3; 1888 1889 /* 1890 * Attribute the bytes to the connection, if we are allowed to send them 1891 * and this isn't the first closing frame. 1892 */ 1893 if (res && txp->closing_bytes_recv != 0) 1894 txp->closing_bytes_xmit += n; 1895 return res; 1896 } 1897 1898 void ossl_quic_tx_packetiser_record_received_closing_bytes( 1899 OSSL_QUIC_TX_PACKETISER *txp, size_t n) 1900 { 1901 txp->closing_bytes_recv += n; 1902 } 1903 1904 static int txp_generate_pre_token(OSSL_QUIC_TX_PACKETISER *txp, 1905 struct txp_pkt *pkt, 1906 int chosen_for_conn_close, 1907 int *can_be_non_inflight) 1908 { 1909 const uint32_t enc_level = pkt->h.enc_level; 1910 const uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); 1911 const struct archetype_data *a = &pkt->geom.adata; 1912 QUIC_TXPIM_PKT *tpkt = pkt->tpkt; 1913 struct tx_helper *h = &pkt->h; 1914 const OSSL_QUIC_FRAME_ACK *ack; 1915 OSSL_QUIC_FRAME_ACK ack2; 1916 1917 tpkt->ackm_pkt.largest_acked = QUIC_PN_INVALID; 1918 1919 /* ACK Frames (Regenerate) */ 1920 if (a->allow_ack 1921 && tx_helper_get_space_left(h) >= MIN_FRAME_SIZE_ACK 1922 && (((txp->want_ack & (1UL << pn_space)) != 0) 1923 || ossl_ackm_is_ack_desired(txp->args.ackm, pn_space)) 1924 && (ack = ossl_ackm_get_ack_frame(txp->args.ackm, pn_space)) != NULL) { 1925 WPACKET *wpkt = tx_helper_begin(h); 1926 1927 if (wpkt == NULL) 1928 return 0; 1929 1930 /* We do not currently support ECN */ 1931 ack2 = *ack; 1932 ack2.ecn_present = 0; 1933 1934 if (ossl_quic_wire_encode_frame_ack(wpkt, 1935 txp->args.ack_delay_exponent, 1936 &ack2)) { 1937 if (!tx_helper_commit(h)) 1938 return 0; 1939 1940 tpkt->had_ack_frame = 1; 1941 1942 if (ack->num_ack_ranges > 0) 1943 tpkt->ackm_pkt.largest_acked = ack->ack_ranges[0].end; 1944 1945 if (txp->ack_tx_cb != NULL) 1946 txp->ack_tx_cb(&ack2, pn_space, txp->ack_tx_cb_arg); 1947 } else { 1948 tx_helper_rollback(h); 1949 } 1950 } 1951 1952 /* CONNECTION_CLOSE Frames (Regenerate) */ 1953 if (a->allow_conn_close && txp->want_conn_close && chosen_for_conn_close) { 1954 WPACKET *wpkt = tx_helper_begin(h); 1955 OSSL_QUIC_FRAME_CONN_CLOSE f, *pf = &txp->conn_close_frame; 1956 size_t l; 1957 1958 if (wpkt == NULL) 1959 return 0; 1960 1961 /* 1962 * Application CONNECTION_CLOSE frames may only be sent in the 1963 * Application PN space, as otherwise they may be sent before a 1964 * connection is authenticated and leak application data. Therefore, if 1965 * we need to send a CONNECTION_CLOSE frame in another PN space and were 1966 * given an application CONNECTION_CLOSE frame, convert it into a 1967 * transport CONNECTION_CLOSE frame, removing any sensitive application 1968 * data. 1969 * 1970 * RFC 9000 s. 10.2.3: "A CONNECTION_CLOSE of type 0x1d MUST be replaced 1971 * by a CONNECTION_CLOSE of type 0x1c when sending the frame in Initial 1972 * or Handshake packets. Otherwise, information about the application 1973 * state might be revealed. Endpoints MUST clear the value of the Reason 1974 * Phrase field and SHOULD use the APPLICATION_ERROR code when 1975 * converting to a CONNECTION_CLOSE of type 0x1c." 1976 */ 1977 if (pn_space != QUIC_PN_SPACE_APP && pf->is_app) { 1978 pf = &f; 1979 pf->is_app = 0; 1980 pf->frame_type = 0; 1981 pf->error_code = OSSL_QUIC_ERR_APPLICATION_ERROR; 1982 pf->reason = NULL; 1983 pf->reason_len = 0; 1984 } 1985 1986 if (ossl_quic_wire_encode_frame_conn_close(wpkt, pf) 1987 && WPACKET_get_total_written(wpkt, &l) 1988 && try_commit_conn_close(txp, l)) { 1989 if (!tx_helper_commit(h)) 1990 return 0; 1991 1992 tpkt->had_conn_close = 1; 1993 *can_be_non_inflight = 0; 1994 } else { 1995 tx_helper_rollback(h); 1996 } 1997 } 1998 1999 return 1; 2000 } 2001 2002 static int try_len(size_t space_left, size_t orig_len, 2003 size_t base_hdr_len, size_t lenbytes, 2004 uint64_t maxn, size_t *hdr_len, size_t *payload_len) 2005 { 2006 size_t n; 2007 size_t maxn_ = maxn > SIZE_MAX ? SIZE_MAX : (size_t)maxn; 2008 2009 *hdr_len = base_hdr_len + lenbytes; 2010 2011 if (orig_len == 0 && space_left >= *hdr_len) { 2012 *payload_len = 0; 2013 return 1; 2014 } 2015 2016 n = orig_len; 2017 if (n > maxn_) 2018 n = maxn_; 2019 if (n + *hdr_len > space_left) 2020 n = (space_left >= *hdr_len) ? space_left - *hdr_len : 0; 2021 2022 *payload_len = n; 2023 return n > 0; 2024 } 2025 2026 static int determine_len(size_t space_left, size_t orig_len, 2027 size_t base_hdr_len, 2028 uint64_t *hlen, uint64_t *len) 2029 { 2030 int ok = 0; 2031 size_t chosen_payload_len = 0; 2032 size_t chosen_hdr_len = 0; 2033 size_t payload_len[4], hdr_len[4]; 2034 int i, valid[4] = { 0 }; 2035 2036 valid[0] = try_len(space_left, orig_len, base_hdr_len, 2037 1, OSSL_QUIC_VLINT_1B_MAX, 2038 &hdr_len[0], &payload_len[0]); 2039 valid[1] = try_len(space_left, orig_len, base_hdr_len, 2040 2, OSSL_QUIC_VLINT_2B_MAX, 2041 &hdr_len[1], &payload_len[1]); 2042 valid[2] = try_len(space_left, orig_len, base_hdr_len, 2043 4, OSSL_QUIC_VLINT_4B_MAX, 2044 &hdr_len[2], &payload_len[2]); 2045 valid[3] = try_len(space_left, orig_len, base_hdr_len, 2046 8, OSSL_QUIC_VLINT_8B_MAX, 2047 &hdr_len[3], &payload_len[3]); 2048 2049 for (i = OSSL_NELEM(valid) - 1; i >= 0; --i) 2050 if (valid[i] && payload_len[i] >= chosen_payload_len) { 2051 chosen_payload_len = payload_len[i]; 2052 chosen_hdr_len = hdr_len[i]; 2053 ok = 1; 2054 } 2055 2056 *hlen = chosen_hdr_len; 2057 *len = chosen_payload_len; 2058 return ok; 2059 } 2060 2061 /* 2062 * Given a CRYPTO frame header with accurate chdr->len and a budget 2063 * (space_left), try to find the optimal value of chdr->len to fill as much of 2064 * the budget as possible. This is slightly hairy because larger values of 2065 * chdr->len cause larger encoded sizes of the length field of the frame, which 2066 * in turn mean less space available for payload data. We check all possible 2067 * encodings and choose the optimal encoding. 2068 */ 2069 static int determine_crypto_len(struct tx_helper *h, 2070 OSSL_QUIC_FRAME_CRYPTO *chdr, 2071 size_t space_left, 2072 uint64_t *hlen, 2073 uint64_t *len) 2074 { 2075 size_t orig_len; 2076 size_t base_hdr_len; /* CRYPTO header length without length field */ 2077 2078 if (chdr->len > SIZE_MAX) 2079 return 0; 2080 2081 orig_len = (size_t)chdr->len; 2082 2083 chdr->len = 0; 2084 base_hdr_len = ossl_quic_wire_get_encoded_frame_len_crypto_hdr(chdr); 2085 chdr->len = orig_len; 2086 if (base_hdr_len == 0) 2087 return 0; 2088 2089 --base_hdr_len; 2090 2091 return determine_len(space_left, orig_len, base_hdr_len, hlen, len); 2092 } 2093 2094 static int determine_stream_len(struct tx_helper *h, 2095 OSSL_QUIC_FRAME_STREAM *shdr, 2096 size_t space_left, 2097 uint64_t *hlen, 2098 uint64_t *len) 2099 { 2100 size_t orig_len; 2101 size_t base_hdr_len; /* STREAM header length without length field */ 2102 2103 if (shdr->len > SIZE_MAX) 2104 return 0; 2105 2106 orig_len = (size_t)shdr->len; 2107 2108 shdr->len = 0; 2109 base_hdr_len = ossl_quic_wire_get_encoded_frame_len_stream_hdr(shdr); 2110 shdr->len = orig_len; 2111 if (base_hdr_len == 0) 2112 return 0; 2113 2114 if (shdr->has_explicit_len) 2115 --base_hdr_len; 2116 2117 return determine_len(space_left, orig_len, base_hdr_len, hlen, len); 2118 } 2119 2120 static int txp_generate_crypto_frames(OSSL_QUIC_TX_PACKETISER *txp, 2121 struct txp_pkt *pkt, 2122 int *have_ack_eliciting) 2123 { 2124 const uint32_t enc_level = pkt->h.enc_level; 2125 const uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); 2126 QUIC_TXPIM_PKT *tpkt = pkt->tpkt; 2127 struct tx_helper *h = &pkt->h; 2128 size_t num_stream_iovec; 2129 OSSL_QUIC_FRAME_STREAM shdr = { 0 }; 2130 OSSL_QUIC_FRAME_CRYPTO chdr = { 0 }; 2131 OSSL_QTX_IOVEC iov[2]; 2132 uint64_t hdr_bytes; 2133 WPACKET *wpkt; 2134 QUIC_TXPIM_CHUNK chunk = { 0 }; 2135 size_t i, space_left; 2136 2137 for (i = 0;; ++i) { 2138 space_left = tx_helper_get_space_left(h); 2139 2140 if (space_left < MIN_FRAME_SIZE_CRYPTO) 2141 return 1; /* no point trying */ 2142 2143 /* Do we have any CRYPTO data waiting? */ 2144 num_stream_iovec = OSSL_NELEM(iov); 2145 if (!ossl_quic_sstream_get_stream_frame(txp->args.crypto[pn_space], 2146 i, &shdr, iov, 2147 &num_stream_iovec)) 2148 return 1; /* nothing to do */ 2149 2150 /* Convert STREAM frame header to CRYPTO frame header */ 2151 chdr.offset = shdr.offset; 2152 chdr.len = shdr.len; 2153 2154 if (chdr.len == 0) 2155 return 1; /* nothing to do */ 2156 2157 /* Find best fit (header length, payload length) combination. */ 2158 if (!determine_crypto_len(h, &chdr, space_left, &hdr_bytes, 2159 &chdr.len)) 2160 return 1; /* can't fit anything */ 2161 2162 /* 2163 * Truncate IOVs to match our chosen length. 2164 * 2165 * The length cannot be more than SIZE_MAX because this length comes 2166 * from our send stream buffer. 2167 */ 2168 ossl_quic_sstream_adjust_iov((size_t)chdr.len, iov, num_stream_iovec); 2169 2170 /* 2171 * Ensure we have enough iovecs allocated (1 for the header, up to 2 for 2172 * the stream data.) 2173 */ 2174 if (!txp_el_ensure_iovec(&txp->el[enc_level], h->num_iovec + 3)) 2175 return 0; /* alloc error */ 2176 2177 /* Encode the header. */ 2178 wpkt = tx_helper_begin(h); 2179 if (wpkt == NULL) 2180 return 0; /* alloc error */ 2181 2182 if (!ossl_quic_wire_encode_frame_crypto_hdr(wpkt, &chdr)) { 2183 tx_helper_rollback(h); 2184 return 1; /* can't fit */ 2185 } 2186 2187 if (!tx_helper_commit(h)) 2188 return 0; /* alloc error */ 2189 2190 /* Add payload iovecs to the helper (infallible). */ 2191 for (i = 0; i < num_stream_iovec; ++i) 2192 tx_helper_append_iovec(h, iov[i].buf, iov[i].buf_len); 2193 2194 *have_ack_eliciting = 1; 2195 tx_helper_unrestrict(h); /* no longer need PING */ 2196 2197 /* Log chunk to TXPIM. */ 2198 chunk.stream_id = UINT64_MAX; /* crypto stream */ 2199 chunk.start = chdr.offset; 2200 chunk.end = chdr.offset + chdr.len - 1; 2201 chunk.has_fin = 0; /* Crypto stream never ends */ 2202 if (!ossl_quic_txpim_pkt_append_chunk(tpkt, &chunk)) 2203 return 0; /* alloc error */ 2204 } 2205 } 2206 2207 struct chunk_info { 2208 OSSL_QUIC_FRAME_STREAM shdr; 2209 uint64_t orig_len; 2210 OSSL_QTX_IOVEC iov[2]; 2211 size_t num_stream_iovec; 2212 int valid; 2213 }; 2214 2215 static int txp_plan_stream_chunk(OSSL_QUIC_TX_PACKETISER *txp, 2216 struct tx_helper *h, 2217 QUIC_SSTREAM *sstream, 2218 QUIC_TXFC *stream_txfc, 2219 size_t skip, 2220 struct chunk_info *chunk, 2221 uint64_t consumed) 2222 { 2223 uint64_t fc_credit, fc_swm, fc_limit; 2224 2225 chunk->num_stream_iovec = OSSL_NELEM(chunk->iov); 2226 chunk->valid = ossl_quic_sstream_get_stream_frame(sstream, skip, 2227 &chunk->shdr, 2228 chunk->iov, 2229 &chunk->num_stream_iovec); 2230 if (!chunk->valid) 2231 return 1; 2232 2233 if (!ossl_assert(chunk->shdr.len > 0 || chunk->shdr.is_fin)) 2234 /* Should only have 0-length chunk if FIN */ 2235 return 0; 2236 2237 chunk->orig_len = chunk->shdr.len; 2238 2239 /* Clamp according to connection and stream-level TXFC. */ 2240 fc_credit = ossl_quic_txfc_get_credit(stream_txfc, consumed); 2241 fc_swm = ossl_quic_txfc_get_swm(stream_txfc); 2242 fc_limit = fc_swm + fc_credit; 2243 2244 if (chunk->shdr.len > 0 && chunk->shdr.offset + chunk->shdr.len > fc_limit) { 2245 chunk->shdr.len = (fc_limit <= chunk->shdr.offset) 2246 ? 0 2247 : fc_limit - chunk->shdr.offset; 2248 chunk->shdr.is_fin = 0; 2249 } 2250 2251 if (chunk->shdr.len == 0 && !chunk->shdr.is_fin) { 2252 /* 2253 * Nothing to do due to TXFC. Since SSTREAM returns chunks in ascending 2254 * order of offset we don't need to check any later chunks, so stop 2255 * iterating here. 2256 */ 2257 chunk->valid = 0; 2258 return 1; 2259 } 2260 2261 return 1; 2262 } 2263 2264 /* 2265 * Returns 0 on fatal error (e.g. allocation failure), 1 on success. 2266 * *packet_full is set to 1 if there is no longer enough room for another STREAM 2267 * frame. 2268 */ 2269 static int txp_generate_stream_frames(OSSL_QUIC_TX_PACKETISER *txp, 2270 struct txp_pkt *pkt, 2271 uint64_t id, 2272 QUIC_SSTREAM *sstream, 2273 QUIC_TXFC *stream_txfc, 2274 QUIC_STREAM *next_stream, 2275 int *have_ack_eliciting, 2276 int *packet_full, 2277 uint64_t *new_credit_consumed, 2278 uint64_t conn_consumed) 2279 { 2280 int rc = 0; 2281 struct chunk_info chunks[2] = { 0 }; 2282 const uint32_t enc_level = pkt->h.enc_level; 2283 QUIC_TXPIM_PKT *tpkt = pkt->tpkt; 2284 struct tx_helper *h = &pkt->h; 2285 OSSL_QUIC_FRAME_STREAM *shdr; 2286 WPACKET *wpkt; 2287 QUIC_TXPIM_CHUNK chunk; 2288 size_t i, j, space_left; 2289 int can_fill_payload, use_explicit_len; 2290 int could_have_following_chunk; 2291 uint64_t orig_len; 2292 uint64_t hdr_len_implicit, payload_len_implicit; 2293 uint64_t hdr_len_explicit, payload_len_explicit; 2294 uint64_t fc_swm, fc_new_hwm; 2295 2296 fc_swm = ossl_quic_txfc_get_swm(stream_txfc); 2297 fc_new_hwm = fc_swm; 2298 2299 /* 2300 * Load the first two chunks if any offered by the send stream. We retrieve 2301 * the next chunk in advance so we can determine if we need to send any more 2302 * chunks from the same stream after this one, which is needed when 2303 * determining when we can use an implicit length in a STREAM frame. 2304 */ 2305 for (i = 0; i < 2; ++i) { 2306 if (!txp_plan_stream_chunk(txp, h, sstream, stream_txfc, i, &chunks[i], 2307 conn_consumed)) 2308 goto err; 2309 2310 if (i == 0 && !chunks[i].valid) { 2311 /* No chunks, nothing to do. */ 2312 rc = 1; 2313 goto err; 2314 } 2315 chunks[i].shdr.stream_id = id; 2316 } 2317 2318 for (i = 0;; ++i) { 2319 space_left = tx_helper_get_space_left(h); 2320 2321 if (!chunks[i % 2].valid) { 2322 /* Out of chunks; we're done. */ 2323 rc = 1; 2324 goto err; 2325 } 2326 2327 if (space_left < MIN_FRAME_SIZE_STREAM) { 2328 *packet_full = 1; 2329 rc = 1; 2330 goto err; 2331 } 2332 2333 if (!ossl_assert(!h->done_implicit)) 2334 /* 2335 * Logic below should have ensured we didn't append an 2336 * implicit-length unless we filled the packet or didn't have 2337 * another stream to handle, so this should not be possible. 2338 */ 2339 goto err; 2340 2341 shdr = &chunks[i % 2].shdr; 2342 orig_len = chunks[i % 2].orig_len; 2343 if (i > 0) 2344 /* Load next chunk for lookahead. */ 2345 if (!txp_plan_stream_chunk(txp, h, sstream, stream_txfc, i + 1, 2346 &chunks[(i + 1) % 2], conn_consumed)) 2347 goto err; 2348 2349 /* 2350 * Find best fit (header length, payload length) combination for if we 2351 * use an implicit length. 2352 */ 2353 shdr->has_explicit_len = 0; 2354 hdr_len_implicit = payload_len_implicit = 0; 2355 if (!determine_stream_len(h, shdr, space_left, 2356 &hdr_len_implicit, &payload_len_implicit)) { 2357 *packet_full = 1; 2358 rc = 1; 2359 goto err; /* can't fit anything */ 2360 } 2361 2362 /* 2363 * If there is a next stream, we don't use the implicit length so we can 2364 * add more STREAM frames after this one, unless there is enough data 2365 * for this STREAM frame to fill the packet. 2366 */ 2367 can_fill_payload = (hdr_len_implicit + payload_len_implicit 2368 >= space_left); 2369 2370 /* 2371 * Is there is a stream after this one, or another chunk pending 2372 * transmission in this stream? 2373 */ 2374 could_have_following_chunk 2375 = (next_stream != NULL || chunks[(i + 1) % 2].valid); 2376 2377 /* Choose between explicit or implicit length representations. */ 2378 use_explicit_len = !((can_fill_payload || !could_have_following_chunk) 2379 && !pkt->force_pad); 2380 2381 if (use_explicit_len) { 2382 /* 2383 * Find best fit (header length, payload length) combination for if 2384 * we use an explicit length. 2385 */ 2386 shdr->has_explicit_len = 1; 2387 hdr_len_explicit = payload_len_explicit = 0; 2388 if (!determine_stream_len(h, shdr, space_left, 2389 &hdr_len_explicit, &payload_len_explicit)) { 2390 *packet_full = 1; 2391 rc = 1; 2392 goto err; /* can't fit anything */ 2393 } 2394 2395 shdr->len = payload_len_explicit; 2396 } else { 2397 *packet_full = 1; 2398 shdr->has_explicit_len = 0; 2399 shdr->len = payload_len_implicit; 2400 } 2401 2402 /* If this is a FIN, don't keep filling the packet with more FINs. */ 2403 if (shdr->is_fin) 2404 chunks[(i + 1) % 2].valid = 0; 2405 2406 /* 2407 * We are now committed to our length (shdr->len can't change). 2408 * If we truncated the chunk, clear the FIN bit. 2409 */ 2410 if (shdr->len < orig_len) 2411 shdr->is_fin = 0; 2412 2413 /* Truncate IOVs to match our chosen length. */ 2414 ossl_quic_sstream_adjust_iov((size_t)shdr->len, chunks[i % 2].iov, 2415 chunks[i % 2].num_stream_iovec); 2416 2417 /* 2418 * Ensure we have enough iovecs allocated (1 for the header, up to 2 for 2419 * the stream data.) 2420 */ 2421 if (!txp_el_ensure_iovec(&txp->el[enc_level], h->num_iovec + 3)) 2422 goto err; /* alloc error */ 2423 2424 /* Encode the header. */ 2425 wpkt = tx_helper_begin(h); 2426 if (wpkt == NULL) 2427 goto err; /* alloc error */ 2428 2429 if (!ossl_assert(ossl_quic_wire_encode_frame_stream_hdr(wpkt, shdr))) { 2430 /* (Should not be possible.) */ 2431 tx_helper_rollback(h); 2432 *packet_full = 1; 2433 rc = 1; 2434 goto err; /* can't fit */ 2435 } 2436 2437 if (!tx_helper_commit(h)) 2438 goto err; /* alloc error */ 2439 2440 /* Add payload iovecs to the helper (infallible). */ 2441 for (j = 0; j < chunks[i % 2].num_stream_iovec; ++j) 2442 tx_helper_append_iovec(h, chunks[i % 2].iov[j].buf, 2443 chunks[i % 2].iov[j].buf_len); 2444 2445 *have_ack_eliciting = 1; 2446 tx_helper_unrestrict(h); /* no longer need PING */ 2447 if (!shdr->has_explicit_len) 2448 h->done_implicit = 1; 2449 2450 /* Log new TXFC credit which was consumed. */ 2451 if (shdr->len > 0 && shdr->offset + shdr->len > fc_new_hwm) 2452 fc_new_hwm = shdr->offset + shdr->len; 2453 2454 /* Log chunk to TXPIM. */ 2455 chunk.stream_id = shdr->stream_id; 2456 chunk.start = shdr->offset; 2457 chunk.end = shdr->offset + shdr->len - 1; 2458 chunk.has_fin = shdr->is_fin; 2459 chunk.has_stop_sending = 0; 2460 chunk.has_reset_stream = 0; 2461 if (!ossl_quic_txpim_pkt_append_chunk(tpkt, &chunk)) 2462 goto err; /* alloc error */ 2463 2464 if (shdr->len < orig_len) { 2465 /* 2466 * If we did not serialize all of this chunk we definitely do not 2467 * want to try the next chunk 2468 */ 2469 rc = 1; 2470 goto err; 2471 } 2472 } 2473 2474 err: 2475 *new_credit_consumed = fc_new_hwm - fc_swm; 2476 return rc; 2477 } 2478 2479 static void txp_enlink_tmp(QUIC_STREAM **tmp_head, QUIC_STREAM *stream) 2480 { 2481 stream->txp_next = *tmp_head; 2482 *tmp_head = stream; 2483 } 2484 2485 static int txp_generate_stream_related(OSSL_QUIC_TX_PACKETISER *txp, 2486 struct txp_pkt *pkt, 2487 int *have_ack_eliciting, 2488 QUIC_STREAM **tmp_head) 2489 { 2490 QUIC_STREAM_ITER it; 2491 WPACKET *wpkt; 2492 uint64_t cwm; 2493 QUIC_STREAM *stream, *snext; 2494 struct tx_helper *h = &pkt->h; 2495 uint64_t conn_consumed = 0; 2496 2497 for (ossl_quic_stream_iter_init(&it, txp->args.qsm, 1); 2498 it.stream != NULL;) { 2499 2500 stream = it.stream; 2501 ossl_quic_stream_iter_next(&it); 2502 snext = it.stream; 2503 2504 stream->txp_sent_fc = 0; 2505 stream->txp_sent_stop_sending = 0; 2506 stream->txp_sent_reset_stream = 0; 2507 stream->txp_blocked = 0; 2508 stream->txp_txfc_new_credit_consumed = 0; 2509 2510 /* Stream Abort Frames (STOP_SENDING, RESET_STREAM) */ 2511 if (stream->want_stop_sending) { 2512 OSSL_QUIC_FRAME_STOP_SENDING f; 2513 2514 wpkt = tx_helper_begin(h); 2515 if (wpkt == NULL) 2516 return 0; /* alloc error */ 2517 2518 f.stream_id = stream->id; 2519 f.app_error_code = stream->stop_sending_aec; 2520 if (!ossl_quic_wire_encode_frame_stop_sending(wpkt, &f)) { 2521 tx_helper_rollback(h); /* can't fit */ 2522 txp_enlink_tmp(tmp_head, stream); 2523 break; 2524 } 2525 2526 if (!tx_helper_commit(h)) 2527 return 0; /* alloc error */ 2528 2529 *have_ack_eliciting = 1; 2530 tx_helper_unrestrict(h); /* no longer need PING */ 2531 stream->txp_sent_stop_sending = 1; 2532 } 2533 2534 if (stream->want_reset_stream) { 2535 OSSL_QUIC_FRAME_RESET_STREAM f; 2536 2537 if (!ossl_assert(stream->send_state == QUIC_SSTREAM_STATE_RESET_SENT)) 2538 return 0; 2539 2540 wpkt = tx_helper_begin(h); 2541 if (wpkt == NULL) 2542 return 0; /* alloc error */ 2543 2544 f.stream_id = stream->id; 2545 f.app_error_code = stream->reset_stream_aec; 2546 if (!ossl_quic_stream_send_get_final_size(stream, &f.final_size)) 2547 return 0; /* should not be possible */ 2548 2549 if (!ossl_quic_wire_encode_frame_reset_stream(wpkt, &f)) { 2550 tx_helper_rollback(h); /* can't fit */ 2551 txp_enlink_tmp(tmp_head, stream); 2552 break; 2553 } 2554 2555 if (!tx_helper_commit(h)) 2556 return 0; /* alloc error */ 2557 2558 *have_ack_eliciting = 1; 2559 tx_helper_unrestrict(h); /* no longer need PING */ 2560 stream->txp_sent_reset_stream = 1; 2561 2562 /* 2563 * The final size of the stream as indicated by RESET_STREAM is used 2564 * to ensure a consistent view of flow control state by both 2565 * parties; if we happen to send a RESET_STREAM that consumes more 2566 * flow control credit, make sure we account for that. 2567 */ 2568 if (!ossl_assert(f.final_size <= ossl_quic_txfc_get_swm(&stream->txfc))) 2569 return 0; 2570 2571 stream->txp_txfc_new_credit_consumed 2572 = f.final_size - ossl_quic_txfc_get_swm(&stream->txfc); 2573 } 2574 2575 /* 2576 * Stream Flow Control Frames (MAX_STREAM_DATA) 2577 * 2578 * RFC 9000 s. 13.3: "An endpoint SHOULD stop sending MAX_STREAM_DATA 2579 * frames when the receiving part of the stream enters a "Size Known" or 2580 * "Reset Recvd" state." -- In practice, RECV is the only state 2581 * in which it makes sense to generate more MAX_STREAM_DATA frames. 2582 */ 2583 if (stream->recv_state == QUIC_RSTREAM_STATE_RECV 2584 && (stream->want_max_stream_data 2585 || ossl_quic_rxfc_has_cwm_changed(&stream->rxfc, 0))) { 2586 2587 wpkt = tx_helper_begin(h); 2588 if (wpkt == NULL) 2589 return 0; /* alloc error */ 2590 2591 cwm = ossl_quic_rxfc_get_cwm(&stream->rxfc); 2592 2593 if (!ossl_quic_wire_encode_frame_max_stream_data(wpkt, stream->id, 2594 cwm)) { 2595 tx_helper_rollback(h); /* can't fit */ 2596 txp_enlink_tmp(tmp_head, stream); 2597 break; 2598 } 2599 2600 if (!tx_helper_commit(h)) 2601 return 0; /* alloc error */ 2602 2603 *have_ack_eliciting = 1; 2604 tx_helper_unrestrict(h); /* no longer need PING */ 2605 stream->txp_sent_fc = 1; 2606 } 2607 2608 /* 2609 * Stream Data Frames (STREAM) 2610 * 2611 * RFC 9000 s. 3.3: A sender MUST NOT send a STREAM [...] frame for a 2612 * stream in the "Reset Sent" state [or any terminal state]. We don't 2613 * send any more STREAM frames if we are sending, have sent, or are 2614 * planning to send, RESET_STREAM. The other terminal state is Data 2615 * Recvd, but txp_generate_stream_frames() is guaranteed to generate 2616 * nothing in this case. 2617 */ 2618 if (ossl_quic_stream_has_send_buffer(stream) 2619 && !ossl_quic_stream_send_is_reset(stream)) { 2620 int packet_full = 0; 2621 2622 if (!ossl_assert(!stream->want_reset_stream)) 2623 return 0; 2624 2625 if (!txp_generate_stream_frames(txp, pkt, 2626 stream->id, stream->sstream, 2627 &stream->txfc, 2628 snext, 2629 have_ack_eliciting, 2630 &packet_full, 2631 &stream->txp_txfc_new_credit_consumed, 2632 conn_consumed)) { 2633 /* Fatal error (allocation, etc.) */ 2634 txp_enlink_tmp(tmp_head, stream); 2635 return 0; 2636 } 2637 conn_consumed += stream->txp_txfc_new_credit_consumed; 2638 2639 if (packet_full) { 2640 txp_enlink_tmp(tmp_head, stream); 2641 break; 2642 } 2643 } 2644 2645 txp_enlink_tmp(tmp_head, stream); 2646 } 2647 2648 return 1; 2649 } 2650 2651 static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, 2652 struct txp_pkt *pkt, 2653 int chosen_for_conn_close) 2654 { 2655 int rc = TXP_ERR_SUCCESS; 2656 const uint32_t enc_level = pkt->h.enc_level; 2657 const uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); 2658 int have_ack_eliciting = 0, done_pre_token = 0; 2659 const struct archetype_data a = pkt->geom.adata; 2660 /* 2661 * Cleared if we encode any non-ACK-eliciting frame type which rules out the 2662 * packet being a non-inflight frame. This means any non-ACK ACK-eliciting 2663 * frame, even PADDING frames. ACK eliciting frames always cause a packet to 2664 * become ineligible for non-inflight treatment so it is not necessary to 2665 * clear this in cases where have_ack_eliciting is set, as it is ignored in 2666 * that case. 2667 */ 2668 int can_be_non_inflight = 1; 2669 QUIC_CFQ_ITEM *cfq_item; 2670 QUIC_TXPIM_PKT *tpkt = NULL; 2671 struct tx_helper *h = &pkt->h; 2672 2673 /* Maximum PN reached? */ 2674 if (!ossl_quic_pn_valid(txp->next_pn[pn_space])) 2675 goto fatal_err; 2676 2677 if (!ossl_assert(pkt->tpkt == NULL)) 2678 goto fatal_err; 2679 2680 if ((pkt->tpkt = tpkt = ossl_quic_txpim_pkt_alloc(txp->args.txpim)) == NULL) 2681 goto fatal_err; 2682 2683 /* 2684 * Frame Serialization 2685 * =================== 2686 * 2687 * We now serialize frames into the packet in descending order of priority. 2688 */ 2689 2690 /* HANDSHAKE_DONE (Regenerate) */ 2691 if (a.allow_handshake_done && txp->want_handshake_done 2692 && tx_helper_get_space_left(h) >= MIN_FRAME_SIZE_HANDSHAKE_DONE) { 2693 WPACKET *wpkt = tx_helper_begin(h); 2694 2695 if (wpkt == NULL) 2696 goto fatal_err; 2697 2698 if (ossl_quic_wire_encode_frame_handshake_done(wpkt)) { 2699 tpkt->had_handshake_done_frame = 1; 2700 have_ack_eliciting = 1; 2701 2702 if (!tx_helper_commit(h)) 2703 goto fatal_err; 2704 2705 tx_helper_unrestrict(h); /* no longer need PING */ 2706 } else { 2707 tx_helper_rollback(h); 2708 } 2709 } 2710 2711 /* MAX_DATA (Regenerate) */ 2712 if (a.allow_conn_fc 2713 && (txp->want_max_data 2714 || ossl_quic_rxfc_has_cwm_changed(txp->args.conn_rxfc, 0)) 2715 && tx_helper_get_space_left(h) >= MIN_FRAME_SIZE_MAX_DATA) { 2716 WPACKET *wpkt = tx_helper_begin(h); 2717 uint64_t cwm = ossl_quic_rxfc_get_cwm(txp->args.conn_rxfc); 2718 2719 if (wpkt == NULL) 2720 goto fatal_err; 2721 2722 if (ossl_quic_wire_encode_frame_max_data(wpkt, cwm)) { 2723 tpkt->had_max_data_frame = 1; 2724 have_ack_eliciting = 1; 2725 2726 if (!tx_helper_commit(h)) 2727 goto fatal_err; 2728 2729 tx_helper_unrestrict(h); /* no longer need PING */ 2730 } else { 2731 tx_helper_rollback(h); 2732 } 2733 } 2734 2735 /* MAX_STREAMS_BIDI (Regenerate) */ 2736 if (a.allow_conn_fc 2737 && (txp->want_max_streams_bidi 2738 || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_bidi_rxfc, 0)) 2739 && tx_helper_get_space_left(h) >= MIN_FRAME_SIZE_MAX_STREAMS_BIDI) { 2740 WPACKET *wpkt = tx_helper_begin(h); 2741 uint64_t max_streams 2742 = ossl_quic_rxfc_get_cwm(txp->args.max_streams_bidi_rxfc); 2743 2744 if (wpkt == NULL) 2745 goto fatal_err; 2746 2747 if (ossl_quic_wire_encode_frame_max_streams(wpkt, /*is_uni=*/0, 2748 max_streams)) { 2749 tpkt->had_max_streams_bidi_frame = 1; 2750 have_ack_eliciting = 1; 2751 2752 if (!tx_helper_commit(h)) 2753 goto fatal_err; 2754 2755 tx_helper_unrestrict(h); /* no longer need PING */ 2756 } else { 2757 tx_helper_rollback(h); 2758 } 2759 } 2760 2761 /* MAX_STREAMS_UNI (Regenerate) */ 2762 if (a.allow_conn_fc 2763 && (txp->want_max_streams_uni 2764 || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_uni_rxfc, 0)) 2765 && tx_helper_get_space_left(h) >= MIN_FRAME_SIZE_MAX_STREAMS_UNI) { 2766 WPACKET *wpkt = tx_helper_begin(h); 2767 uint64_t max_streams 2768 = ossl_quic_rxfc_get_cwm(txp->args.max_streams_uni_rxfc); 2769 2770 if (wpkt == NULL) 2771 goto fatal_err; 2772 2773 if (ossl_quic_wire_encode_frame_max_streams(wpkt, /*is_uni=*/1, 2774 max_streams)) { 2775 tpkt->had_max_streams_uni_frame = 1; 2776 have_ack_eliciting = 1; 2777 2778 if (!tx_helper_commit(h)) 2779 goto fatal_err; 2780 2781 tx_helper_unrestrict(h); /* no longer need PING */ 2782 } else { 2783 tx_helper_rollback(h); 2784 } 2785 } 2786 2787 /* GCR Frames */ 2788 for (cfq_item = ossl_quic_cfq_get_priority_head(txp->args.cfq, pn_space); 2789 cfq_item != NULL; 2790 cfq_item = ossl_quic_cfq_item_get_priority_next(cfq_item, pn_space)) { 2791 uint64_t frame_type = ossl_quic_cfq_item_get_frame_type(cfq_item); 2792 const unsigned char *encoded = ossl_quic_cfq_item_get_encoded(cfq_item); 2793 size_t encoded_len = ossl_quic_cfq_item_get_encoded_len(cfq_item); 2794 2795 switch (frame_type) { 2796 case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID: 2797 if (!a.allow_new_conn_id) 2798 continue; 2799 break; 2800 case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID: 2801 if (!a.allow_retire_conn_id) 2802 continue; 2803 break; 2804 case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN: 2805 if (!a.allow_new_token) 2806 continue; 2807 2808 /* 2809 * NEW_TOKEN frames are handled via GCR, but some 2810 * Regenerate-strategy frames should come before them (namely 2811 * ACK, CONNECTION_CLOSE, PATH_CHALLENGE and PATH_RESPONSE). If 2812 * we find a NEW_TOKEN frame, do these now. If there are no 2813 * NEW_TOKEN frames in the GCR queue we will handle these below. 2814 */ 2815 if (!done_pre_token) 2816 if (txp_generate_pre_token(txp, pkt, 2817 chosen_for_conn_close, 2818 &can_be_non_inflight)) 2819 done_pre_token = 1; 2820 2821 break; 2822 case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE: 2823 if (!a.allow_path_response) 2824 continue; 2825 2826 /* 2827 * RFC 9000 s. 8.2.2: An endpoint MUST expand datagrams that 2828 * contain a PATH_RESPONSE frame to at least the smallest 2829 * allowed maximum datagram size of 1200 bytes. 2830 */ 2831 pkt->force_pad = 1; 2832 break; 2833 default: 2834 if (!a.allow_cfq_other) 2835 continue; 2836 break; 2837 } 2838 2839 /* 2840 * If the frame is too big, don't try to schedule any more GCR frames in 2841 * this packet rather than sending subsequent ones out of order. 2842 */ 2843 if (encoded_len > tx_helper_get_space_left(h)) 2844 break; 2845 2846 if (!tx_helper_append_iovec(h, encoded, encoded_len)) 2847 goto fatal_err; 2848 2849 ossl_quic_txpim_pkt_add_cfq_item(tpkt, cfq_item); 2850 2851 if (ossl_quic_frame_type_is_ack_eliciting(frame_type)) { 2852 have_ack_eliciting = 1; 2853 tx_helper_unrestrict(h); /* no longer need PING */ 2854 } 2855 } 2856 2857 /* 2858 * If we didn't generate ACK, CONNECTION_CLOSE, PATH_CHALLENGE or 2859 * PATH_RESPONSE (as desired) before, do so now. 2860 */ 2861 if (!done_pre_token) 2862 if (txp_generate_pre_token(txp, pkt, 2863 chosen_for_conn_close, 2864 &can_be_non_inflight)) 2865 done_pre_token = 1; 2866 2867 /* CRYPTO Frames */ 2868 if (a.allow_crypto) 2869 if (!txp_generate_crypto_frames(txp, pkt, &have_ack_eliciting)) 2870 goto fatal_err; 2871 2872 /* Stream-specific frames */ 2873 if (a.allow_stream_rel && txp->handshake_complete) 2874 if (!txp_generate_stream_related(txp, pkt, 2875 &have_ack_eliciting, 2876 &pkt->stream_head)) 2877 goto fatal_err; 2878 2879 /* PING */ 2880 tx_helper_unrestrict(h); 2881 2882 if (!have_ack_eliciting && txp_need_ping(txp, pn_space, &a)) { 2883 WPACKET *wpkt; 2884 2885 assert(h->reserve > 0); 2886 wpkt = tx_helper_begin(h); 2887 if (wpkt == NULL) 2888 goto fatal_err; 2889 2890 if (!ossl_quic_wire_encode_frame_ping(wpkt) 2891 || !tx_helper_commit(h)) 2892 /* 2893 * We treat a request to be ACK-eliciting as a requirement, so this 2894 * is an error. 2895 */ 2896 goto fatal_err; 2897 2898 have_ack_eliciting = 1; 2899 } 2900 2901 /* PADDING is added by ossl_quic_tx_packetiser_generate(). */ 2902 2903 /* 2904 * ACKM Data 2905 * ========= 2906 */ 2907 if (have_ack_eliciting) 2908 can_be_non_inflight = 0; 2909 2910 /* ACKM Data */ 2911 tpkt->ackm_pkt.num_bytes = h->bytes_appended + pkt->geom.pkt_overhead; 2912 tpkt->ackm_pkt.pkt_num = txp->next_pn[pn_space]; 2913 /* largest_acked is set in txp_generate_pre_token */ 2914 tpkt->ackm_pkt.pkt_space = pn_space; 2915 tpkt->ackm_pkt.is_inflight = !can_be_non_inflight; 2916 tpkt->ackm_pkt.is_ack_eliciting = have_ack_eliciting; 2917 tpkt->ackm_pkt.is_pto_probe = 0; 2918 tpkt->ackm_pkt.is_mtu_probe = 0; 2919 tpkt->ackm_pkt.time = txp->args.now(txp->args.now_arg); 2920 tpkt->pkt_type = pkt->phdr.type; 2921 2922 /* Done. */ 2923 return rc; 2924 2925 fatal_err: 2926 /* 2927 * Handler for fatal errors, i.e. errors causing us to abort the entire 2928 * packet rather than just one frame. Examples of such errors include 2929 * allocation errors. 2930 */ 2931 if (tpkt != NULL) { 2932 ossl_quic_txpim_pkt_release(txp->args.txpim, tpkt); 2933 pkt->tpkt = NULL; 2934 } 2935 return TXP_ERR_INTERNAL; 2936 } 2937 2938 /* 2939 * Commits and queues a packet for transmission. There is no backing out after 2940 * this. 2941 * 2942 * This: 2943 * 2944 * - Sends the packet to the QTX for encryption and transmission; 2945 * 2946 * - Records the packet as having been transmitted in FIFM. ACKM is informed, 2947 * etc. and the TXPIM record is filed. 2948 * 2949 * - Informs various subsystems of frames that were sent and clears frame 2950 * wanted flags so that we do not generate the same frames again. 2951 * 2952 * Assumptions: 2953 * 2954 * - pkt is a txp_pkt for the correct EL; 2955 * 2956 * - pkt->tpkt is valid; 2957 * 2958 * - pkt->tpkt->ackm_pkt has been fully filled in; 2959 * 2960 * - Stream chunk records have been appended to pkt->tpkt for STREAM and 2961 * CRYPTO frames, but not for RESET_STREAM or STOP_SENDING frames; 2962 * 2963 * - The chosen stream list for the packet can be fully walked from 2964 * pkt->stream_head using stream->txp_next; 2965 * 2966 * - pkt->has_ack_eliciting is set correctly. 2967 * 2968 */ 2969 static int txp_pkt_commit(OSSL_QUIC_TX_PACKETISER *txp, 2970 struct txp_pkt *pkt, 2971 uint32_t archetype, 2972 int *txpim_pkt_reffed) 2973 { 2974 int rc = 1; 2975 uint32_t enc_level = pkt->h.enc_level; 2976 uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); 2977 QUIC_TXPIM_PKT *tpkt = pkt->tpkt; 2978 QUIC_STREAM *stream; 2979 OSSL_QTX_PKT txpkt; 2980 struct archetype_data a; 2981 2982 *txpim_pkt_reffed = 0; 2983 2984 /* Cannot send a packet with an empty payload. */ 2985 if (pkt->h.bytes_appended == 0) 2986 return 0; 2987 2988 if (!txp_get_archetype_data(enc_level, archetype, &a)) 2989 return 0; 2990 2991 /* Packet Information for QTX */ 2992 txpkt.hdr = &pkt->phdr; 2993 txpkt.iovec = txp->el[enc_level].iovec; 2994 txpkt.num_iovec = pkt->h.num_iovec; 2995 txpkt.local = NULL; 2996 txpkt.peer = BIO_ADDR_family(&txp->args.peer) == AF_UNSPEC 2997 ? NULL 2998 : &txp->args.peer; 2999 txpkt.pn = txp->next_pn[pn_space]; 3000 txpkt.flags = OSSL_QTX_PKT_FLAG_COALESCE; /* always try to coalesce */ 3001 3002 /* Generate TXPIM chunks representing STOP_SENDING and RESET_STREAM frames. */ 3003 for (stream = pkt->stream_head; stream != NULL; stream = stream->txp_next) 3004 if (stream->txp_sent_stop_sending || stream->txp_sent_reset_stream) { 3005 /* Log STOP_SENDING/RESET_STREAM chunk to TXPIM. */ 3006 QUIC_TXPIM_CHUNK chunk; 3007 3008 chunk.stream_id = stream->id; 3009 chunk.start = UINT64_MAX; 3010 chunk.end = 0; 3011 chunk.has_fin = 0; 3012 chunk.has_stop_sending = stream->txp_sent_stop_sending; 3013 chunk.has_reset_stream = stream->txp_sent_reset_stream; 3014 if (!ossl_quic_txpim_pkt_append_chunk(tpkt, &chunk)) 3015 return 0; /* alloc error */ 3016 } 3017 3018 /* Dispatch to FIFD. */ 3019 if (!ossl_quic_fifd_pkt_commit(&txp->fifd, tpkt)) 3020 return 0; 3021 3022 /* 3023 * Transmission and Post-Packet Generation Bookkeeping 3024 * =================================================== 3025 * 3026 * No backing out anymore - at this point the ACKM has recorded the packet 3027 * as having been sent, so we need to increment our next PN counter, or 3028 * the ACKM will complain when we try to record a duplicate packet with 3029 * the same PN later. At this point actually sending the packet may still 3030 * fail. In this unlikely event it will simply be handled as though it 3031 * were a lost packet. 3032 */ 3033 ++txp->next_pn[pn_space]; 3034 *txpim_pkt_reffed = 1; 3035 3036 /* Send the packet. */ 3037 if (!ossl_qtx_write_pkt(txp->args.qtx, &txpkt)) 3038 return 0; 3039 3040 /* 3041 * Record FC and stream abort frames as sent; deactivate streams which no 3042 * longer have anything to do. 3043 */ 3044 for (stream = pkt->stream_head; stream != NULL; stream = stream->txp_next) { 3045 if (stream->txp_sent_fc) { 3046 stream->want_max_stream_data = 0; 3047 ossl_quic_rxfc_has_cwm_changed(&stream->rxfc, 1); 3048 } 3049 3050 if (stream->txp_sent_stop_sending) 3051 stream->want_stop_sending = 0; 3052 3053 if (stream->txp_sent_reset_stream) 3054 stream->want_reset_stream = 0; 3055 3056 if (stream->txp_txfc_new_credit_consumed > 0) { 3057 if (!ossl_assert(ossl_quic_txfc_consume_credit(&stream->txfc, 3058 stream->txp_txfc_new_credit_consumed))) 3059 /* 3060 * Should not be possible, but we should continue with our 3061 * bookkeeping as we have already committed the packet to the 3062 * FIFD. Just change the value we return. 3063 */ 3064 rc = 0; 3065 3066 stream->txp_txfc_new_credit_consumed = 0; 3067 } 3068 3069 /* 3070 * If we no longer need to generate any flow control (MAX_STREAM_DATA), 3071 * STOP_SENDING or RESET_STREAM frames, nor any STREAM frames (because 3072 * the stream is drained of data or TXFC-blocked), we can mark the 3073 * stream as inactive. 3074 */ 3075 ossl_quic_stream_map_update_state(txp->args.qsm, stream); 3076 3077 if (ossl_quic_stream_has_send_buffer(stream) 3078 && !ossl_quic_sstream_has_pending(stream->sstream) 3079 && ossl_quic_sstream_get_final_size(stream->sstream, NULL)) 3080 /* 3081 * Transition to DATA_SENT if stream has a final size and we have 3082 * sent all data. 3083 */ 3084 ossl_quic_stream_map_notify_all_data_sent(txp->args.qsm, stream); 3085 } 3086 3087 /* We have now sent the packet, so update state accordingly. */ 3088 if (tpkt->ackm_pkt.is_ack_eliciting) 3089 txp->force_ack_eliciting &= ~(1UL << pn_space); 3090 3091 if (tpkt->had_handshake_done_frame) 3092 txp->want_handshake_done = 0; 3093 3094 if (tpkt->had_max_data_frame) { 3095 txp->want_max_data = 0; 3096 ossl_quic_rxfc_has_cwm_changed(txp->args.conn_rxfc, 1); 3097 } 3098 3099 if (tpkt->had_max_streams_bidi_frame) { 3100 txp->want_max_streams_bidi = 0; 3101 ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_bidi_rxfc, 1); 3102 } 3103 3104 if (tpkt->had_max_streams_uni_frame) { 3105 txp->want_max_streams_uni = 0; 3106 ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_uni_rxfc, 1); 3107 } 3108 3109 if (tpkt->had_ack_frame) 3110 txp->want_ack &= ~(1UL << pn_space); 3111 3112 if (tpkt->had_conn_close) 3113 txp->want_conn_close = 0; 3114 3115 /* 3116 * Decrement probe request counts if we have sent a packet that meets 3117 * the requirement of a probe, namely being ACK-eliciting. 3118 */ 3119 if (tpkt->ackm_pkt.is_ack_eliciting) { 3120 OSSL_ACKM_PROBE_INFO *probe_info 3121 = ossl_ackm_get0_probe_request(txp->args.ackm); 3122 3123 if (enc_level == QUIC_ENC_LEVEL_INITIAL 3124 && probe_info->anti_deadlock_initial > 0) 3125 --probe_info->anti_deadlock_initial; 3126 3127 if (enc_level == QUIC_ENC_LEVEL_HANDSHAKE 3128 && probe_info->anti_deadlock_handshake > 0) 3129 --probe_info->anti_deadlock_handshake; 3130 3131 if (a.allow_force_ack_eliciting /* (i.e., not for 0-RTT) */ 3132 && probe_info->pto[pn_space] > 0) 3133 --probe_info->pto[pn_space]; 3134 } 3135 3136 ossl_quic_fifd_pkt_discard_unreliable(&txp->fifd, tpkt); 3137 3138 return rc; 3139 } 3140 3141 /* Ensure the iovec array is at least num elements long. */ 3142 static int txp_el_ensure_iovec(struct txp_el *el, size_t num) 3143 { 3144 OSSL_QTX_IOVEC *iovec; 3145 3146 if (el->alloc_iovec >= num) 3147 return 1; 3148 3149 num = el->alloc_iovec != 0 ? el->alloc_iovec * 2 : 8; 3150 3151 iovec = OPENSSL_realloc(el->iovec, sizeof(OSSL_QTX_IOVEC) * num); 3152 if (iovec == NULL) 3153 return 0; 3154 3155 el->iovec = iovec; 3156 el->alloc_iovec = num; 3157 return 1; 3158 } 3159 3160 int ossl_quic_tx_packetiser_schedule_conn_close(OSSL_QUIC_TX_PACKETISER *txp, 3161 const OSSL_QUIC_FRAME_CONN_CLOSE *f) 3162 { 3163 char *reason = NULL; 3164 size_t reason_len = f->reason_len; 3165 size_t max_reason_len = txp_get_mdpl(txp) / 2; 3166 3167 if (txp->want_conn_close) 3168 return 0; 3169 3170 /* 3171 * Arbitrarily limit the length of the reason length string to half of the 3172 * MDPL. 3173 */ 3174 if (reason_len > max_reason_len) 3175 reason_len = max_reason_len; 3176 3177 if (reason_len > 0) { 3178 reason = OPENSSL_memdup(f->reason, reason_len); 3179 if (reason == NULL) 3180 return 0; 3181 } 3182 3183 txp->conn_close_frame = *f; 3184 txp->conn_close_frame.reason = reason; 3185 txp->conn_close_frame.reason_len = reason_len; 3186 txp->want_conn_close = 1; 3187 return 1; 3188 } 3189 3190 void ossl_quic_tx_packetiser_set_msg_callback(OSSL_QUIC_TX_PACKETISER *txp, 3191 ossl_msg_cb msg_callback, 3192 SSL *msg_callback_ssl) 3193 { 3194 txp->msg_callback = msg_callback; 3195 txp->msg_callback_ssl = msg_callback_ssl; 3196 } 3197 3198 void ossl_quic_tx_packetiser_set_msg_callback_arg(OSSL_QUIC_TX_PACKETISER *txp, 3199 void *msg_callback_arg) 3200 { 3201 txp->msg_callback_arg = msg_callback_arg; 3202 } 3203 3204 QUIC_PN ossl_quic_tx_packetiser_get_next_pn(OSSL_QUIC_TX_PACKETISER *txp, 3205 uint32_t pn_space) 3206 { 3207 if (pn_space >= QUIC_PN_SPACE_NUM) 3208 return UINT64_MAX; 3209 3210 return txp->next_pn[pn_space]; 3211 } 3212 3213 OSSL_TIME ossl_quic_tx_packetiser_get_deadline(OSSL_QUIC_TX_PACKETISER *txp) 3214 { 3215 /* 3216 * TXP-specific deadline computations which rely on TXP innards. This is in 3217 * turn relied on by the QUIC_CHANNEL code to determine the channel event 3218 * handling deadline. 3219 */ 3220 OSSL_TIME deadline = ossl_time_infinite(); 3221 uint32_t enc_level, pn_space; 3222 3223 /* 3224 * ACK generation is not CC-gated - packets containing only ACKs are allowed 3225 * to bypass CC. We want to generate ACK frames even if we are currently 3226 * restricted by CC so the peer knows we have received data. The generate 3227 * call will take care of selecting the correct packet archetype. 3228 */ 3229 for (enc_level = QUIC_ENC_LEVEL_INITIAL; 3230 enc_level < QUIC_ENC_LEVEL_NUM; 3231 ++enc_level) 3232 if (ossl_qtx_is_enc_level_provisioned(txp->args.qtx, enc_level)) { 3233 pn_space = ossl_quic_enc_level_to_pn_space(enc_level); 3234 deadline = ossl_time_min(deadline, 3235 ossl_ackm_get_ack_deadline(txp->args.ackm, pn_space)); 3236 } 3237 3238 /* When will CC let us send more? */ 3239 if (txp->args.cc_method->get_tx_allowance(txp->args.cc_data) == 0) 3240 deadline = ossl_time_min(deadline, 3241 txp->args.cc_method->get_wakeup_deadline(txp->args.cc_data)); 3242 3243 return deadline; 3244 } 3245