Lines Matching +full:short +full:- +full:ping

2  * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.
23 #define MIN_FRAME_SIZE_STREAM 3 /* minimum useful size (for non-FIN) */
37 * - It bypasses CC, but *is* counted as in flight for purposes of CC;
38 * - It must be ACK-eliciting.
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.
64 QUIC_FIFD fifd; /* QUIC Frame-in-Flight Dispatcher */
72 /* Internal state - frame (re)generation flags. */
78 /* Internal state - frame (re)generation flags - per PN space. */
83 * Internal state - connection close terminal state.
84 * Once this is set, it is not unset unlike other want_ flags - we keep
101 /* Internal state - packet assembly. */
139 * Number of scratch bytes in txp->scratch we have used so far. Some iovecs
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.
156 * entries valid in txp->iovec.
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
195 h->txp = txp; in tx_helper_init()
196 h->enc_level = enc_level; in tx_helper_init()
197 h->max_ppl = max_ppl; in tx_helper_init()
198 h->reserve = reserve; in tx_helper_init()
199 h->num_iovec = 0; in tx_helper_init()
200 h->bytes_appended = 0; in tx_helper_init()
201 h->scratch_bytes = 0; in tx_helper_init()
202 h->reserve_allowed = 0; in tx_helper_init()
203 h->done_implicit = 0; in tx_helper_init()
204 h->txn.data = NULL; in tx_helper_init()
205 h->txn.active = 0; in tx_helper_init()
207 if (max_ppl > h->txp->el[enc_level].scratch_len) { in tx_helper_init()
210 scratch = OPENSSL_realloc(h->txp->el[enc_level].scratch, max_ppl); in tx_helper_init()
214 h->txp->el[enc_level].scratch = scratch; in tx_helper_init()
215 h->txp->el[enc_level].scratch_len = max_ppl; in tx_helper_init()
223 if (h->txn.active) in tx_helper_cleanup()
226 h->txp = NULL; in tx_helper_cleanup()
231 h->reserve_allowed = 1; in tx_helper_unrestrict()
241 * - Application data contained in stream buffers managed elsewhere
244 * - Control frame data appended into txp->scratch using tx_helper_begin and
252 struct txp_el *el = &h->txp->el[h->enc_level]; in tx_helper_append_iovec()
257 if (!ossl_assert(!h->done_implicit)) in tx_helper_append_iovec()
260 if (!txp_el_ensure_iovec(el, h->num_iovec + 1)) in tx_helper_append_iovec()
263 el->iovec[h->num_iovec].buf = buf; in tx_helper_append_iovec()
264 el->iovec[h->num_iovec].buf_len = buf_len; in tx_helper_append_iovec()
266 ++h->num_iovec; in tx_helper_append_iovec()
267 h->bytes_appended += buf_len; in tx_helper_append_iovec()
276 return h->max_ppl in tx_helper_get_space_left()
277 - (h->reserve_allowed ? 0 : h->reserve) - h->bytes_appended; in tx_helper_get_space_left()
291 struct txp_el *el = &h->txp->el[h->enc_level]; in tx_helper_begin()
293 if (!ossl_assert(!h->txn.active)) in tx_helper_begin()
296 if (!ossl_assert(!h->done_implicit)) in tx_helper_begin()
299 data = (unsigned char *)el->scratch + h->scratch_bytes; in tx_helper_begin()
300 len = el->scratch_len - h->scratch_bytes; in tx_helper_begin()
306 if (!WPACKET_init_static_len(&h->txn.wpkt, data, len, 0)) in tx_helper_begin()
309 if (!WPACKET_set_max_size(&h->txn.wpkt, space_left)) { in tx_helper_begin()
310 WPACKET_cleanup(&h->txn.wpkt); in tx_helper_begin()
314 h->txn.data = data; in tx_helper_begin()
315 h->txn.active = 1; in tx_helper_begin()
316 return &h->txn.wpkt; in tx_helper_begin()
322 WPACKET_finish(&h->txn.wpkt); in tx_helper_end()
324 WPACKET_cleanup(&h->txn.wpkt); in tx_helper_end()
326 h->txn.active = 0; in tx_helper_end()
327 h->txn.data = NULL; in tx_helper_end()
333 if (!h->txn.active) in tx_helper_rollback()
344 if (!h->txn.active) in tx_helper_commit()
347 if (!WPACKET_get_total_written(&h->txn.wpkt, &l)) { in tx_helper_commit()
352 if (!tx_helper_append_iovec(h, h->txn.data, l)) { in tx_helper_commit()
357 if (h->txp->msg_callback != NULL && l > 0) { in tx_helper_commit()
362 if (!PACKET_buf_init(&pkt, h->txn.data, l) in tx_helper_commit()
374 h->txp->msg_callback(1, OSSL_QUIC1_VERSION, ctype, h->txn.data, l, in tx_helper_commit()
375 h->txp->msg_callback_ssl, in tx_helper_commit()
376 h->txp->msg_callback_arg); in tx_helper_commit()
379 h->scratch_bytes += l; in tx_helper_commit()
466 txp->unvalidated_credit = SIZE_MAX; in ossl_quic_tx_packetiser_set_validated()
476 * not exceed the maximum allowable value (`SIZE_MAX - 1`). If the addition
478 * `SIZE_MAX - 1`. If the current unvalidated credit is already `SIZE_MAX`,
487 if (txp->unvalidated_credit != SIZE_MAX) { in ossl_quic_tx_packetiser_add_unvalidated_credit()
488 if ((SIZE_MAX - txp->unvalidated_credit) > (credit * 3)) in ossl_quic_tx_packetiser_add_unvalidated_credit()
489 txp->unvalidated_credit += credit * 3; in ossl_quic_tx_packetiser_add_unvalidated_credit()
491 txp->unvalidated_credit = SIZE_MAX - 1; in ossl_quic_tx_packetiser_add_unvalidated_credit()
511 if (txp->unvalidated_credit != SIZE_MAX) { in ossl_quic_tx_packetiser_consume_unvalidated_credit()
512 if (txp->unvalidated_credit < credit) in ossl_quic_tx_packetiser_consume_unvalidated_credit()
513 txp->unvalidated_credit = 0; in ossl_quic_tx_packetiser_consume_unvalidated_credit()
515 txp->unvalidated_credit -= credit; in ossl_quic_tx_packetiser_consume_unvalidated_credit()
535 return (txp->unvalidated_credit > req_credit); in ossl_quic_tx_packetiser_check_unvalidated_credit()
543 || args->qtx == NULL in ossl_quic_tx_packetiser_new()
544 || args->txpim == NULL in ossl_quic_tx_packetiser_new()
545 || args->cfq == NULL in ossl_quic_tx_packetiser_new()
546 || args->ackm == NULL in ossl_quic_tx_packetiser_new()
547 || args->qsm == NULL in ossl_quic_tx_packetiser_new()
548 || args->conn_txfc == NULL in ossl_quic_tx_packetiser_new()
549 || args->conn_rxfc == NULL in ossl_quic_tx_packetiser_new()
550 || args->max_streams_bidi_rxfc == NULL in ossl_quic_tx_packetiser_new()
551 || args->max_streams_uni_rxfc == NULL in ossl_quic_tx_packetiser_new()
552 || args->protocol_version == 0) { in ossl_quic_tx_packetiser_new()
561 txp->args = *args; in ossl_quic_tx_packetiser_new()
562 txp->last_tx_time = ossl_time_zero(); in ossl_quic_tx_packetiser_new()
564 if (!ossl_quic_fifd_init(&txp->fifd, in ossl_quic_tx_packetiser_new()
565 txp->args.cfq, txp->args.ackm, txp->args.txpim, in ossl_quic_tx_packetiser_new()
570 args->get_qlog_cb, in ossl_quic_tx_packetiser_new()
571 args->get_qlog_cb_arg)) { in ossl_quic_tx_packetiser_new()
587 ossl_quic_fifd_cleanup(&txp->fifd); in ossl_quic_tx_packetiser_free()
588 OPENSSL_free(txp->conn_close_frame.reason); in ossl_quic_tx_packetiser_free()
593 OPENSSL_free(txp->el[enc_level].iovec); in ossl_quic_tx_packetiser_free()
594 OPENSSL_free(txp->el[enc_level].scratch); in ossl_quic_tx_packetiser_free()
616 * frame uses a variable-length integer, the number of bytes needed to ensure
642 if (token_len > mdpl - TXP_REQUIRED_TOKEN_MARGIN) in txp_check_token_len()
657 if (txp->initial_token != NULL && txp->initial_token_free_cb != NULL) in ossl_quic_tx_packetiser_set_initial_token()
658 txp->initial_token_free_cb(txp->initial_token, txp->initial_token_len, in ossl_quic_tx_packetiser_set_initial_token()
659 txp->initial_token_free_cb_arg); in ossl_quic_tx_packetiser_set_initial_token()
661 txp->initial_token = token; in ossl_quic_tx_packetiser_set_initial_token()
662 txp->initial_token_len = token_len; in ossl_quic_tx_packetiser_set_initial_token()
663 txp->initial_token_free_cb = free_cb; in ossl_quic_tx_packetiser_set_initial_token()
664 txp->initial_token_free_cb_arg = free_cb_arg; in ossl_quic_tx_packetiser_set_initial_token()
671 txp->args.protocol_version = protocol_version; in ossl_quic_tx_packetiser_set_protocol_version()
683 txp->args.cur_dcid = *dcid; in ossl_quic_tx_packetiser_set_cur_dcid()
695 txp->args.cur_scid = *scid; in ossl_quic_tx_packetiser_set_cur_scid()
704 BIO_ADDR_clear(&txp->args.peer); in ossl_quic_tx_packetiser_set_peer()
708 return BIO_ADDR_copy(&txp->args.peer, peer); in ossl_quic_tx_packetiser_set_peer()
717 txp->ack_tx_cb = cb; in ossl_quic_tx_packetiser_set_ack_tx_cb()
718 txp->ack_tx_cb_arg = cb_arg; in ossl_quic_tx_packetiser_set_ack_tx_cb()
725 ossl_quic_fifd_set_qlog_cb(&txp->fifd, get_qlog_cb, get_qlog_cb_arg); in ossl_quic_tx_packetiser_set_qlog_cb()
738 txp->args.crypto[ossl_quic_enc_level_to_pn_space(enc_level)] = NULL; in ossl_quic_tx_packetiser_discard_enc_level()
745 txp->handshake_complete = 1; in ossl_quic_tx_packetiser_notify_handshake_complete()
750 txp->want_handshake_done = 1; in ossl_quic_tx_packetiser_schedule_handshake_done()
756 txp->force_ack_eliciting |= (1UL << pn_space); in ossl_quic_tx_packetiser_schedule_ack_eliciting()
762 txp->want_ack |= (1UL << pn_space); in ossl_quic_tx_packetiser_schedule_ack()
784 * - The TXP is only concerned with generating encrypted packets; in ossl_quic_tx_packetiser_generate()
787 * - Any datagram containing an Initial packet must have a payload length in ossl_quic_tx_packetiser_generate()
791 * - It is desirable to be able to coalesce an Initial packet in ossl_quic_tx_packetiser_generate()
798 * - However, at the time that we generate the Initial packet, in ossl_quic_tx_packetiser_generate()
821 * that we can start generating a Handshake (or 0-RTT or 1-RTT, or so on) in ossl_quic_tx_packetiser_generate()
829 * - Do we have room to fit a packet header? (Consider that due to in ossl_quic_tx_packetiser_generate()
830 * variable-length integer encoding this is highly variable and can even in ossl_quic_tx_packetiser_generate()
831 * depend on payload length due to a variable-length Length field.) in ossl_quic_tx_packetiser_generate()
833 * - Can we fit even a single one of the frames we want to put in this in ossl_quic_tx_packetiser_generate()
836 * room - e.g. STREAM frames - ultimately all frame types have some in ossl_quic_tx_packetiser_generate()
844 * Thus we adopt a multi-phase architecture: in ossl_quic_tx_packetiser_generate()
863 uint64_t cc_limit = txp->args.cc_method->get_tx_allowance(txp->args.cc_data); in ossl_quic_tx_packetiser_generate()
878 ossl_qtx_finish_dgram(txp->args.qtx); in ossl_quic_tx_packetiser_generate()
888 ? pkt[enc_level - 1].geom.hwm : 0; in ossl_quic_tx_packetiser_generate()
899 * If this fails this is not a fatal error - it means the geometry in ossl_quic_tx_packetiser_generate()
954 size_t deficit = min_dpl - total_dgram_size; in ossl_quic_tx_packetiser_generate()
962 * Padding frames make a packet ineligible for being a non-inflight in ossl_quic_tx_packetiser_generate()
965 pkt[pad_el].tpkt->ackm_pkt.is_inflight = 1; in ossl_quic_tx_packetiser_generate()
972 * sending padding, give up on generating the datagram - there is in ossl_quic_tx_packetiser_generate()
1004 status->sent_ack_eliciting in ossl_quic_tx_packetiser_generate()
1005 = status->sent_ack_eliciting in ossl_quic_tx_packetiser_generate()
1006 || pkt[enc_level].tpkt->ackm_pkt.is_ack_eliciting; in ossl_quic_tx_packetiser_generate()
1009 status->sent_handshake in ossl_quic_tx_packetiser_generate()
1027 ossl_qtx_finish_dgram(txp->args.qtx); in ossl_quic_tx_packetiser_generate()
1034 status->sent_pkt = pkts_done; in ossl_quic_tx_packetiser_generate()
1042 /* EL 0(INITIAL) - Archetype 0(NORMAL) */
1062 /* EL 0(INITIAL) - Archetype 1(PROBE) */
1082 /* EL 0(INITIAL) - Archetype 2(ACK_ONLY) */
1105 /* EL 1(0RTT) - Archetype 0(NORMAL) */
1125 /* EL 1(0RTT) - Archetype 1(PROBE) */
1145 /* EL 1(0RTT) - Archetype 2(ACK_ONLY) */
1168 /* EL 2(HANDSHAKE) - Archetype 0(NORMAL) */
1188 /* EL 2(HANDSHAKE) - Archetype 1(PROBE) */
1208 /* EL 2(HANDSHAKE) - Archetype 2(ACK_ONLY) */
1231 /* EL 3(1RTT) - Archetype 0(NORMAL) */
1251 /* EL 3(1RTT) - Archetype 1(PROBE) */
1271 /* EL 3(1RTT) - Archetype 2(ACK_ONLY) */
1317 if (!txp_get_archetype_data(enc_level, archetype, &geom->adata)) in txp_determine_geometry()
1321 phdr->type = ossl_quic_enc_level_to_pkt_type(enc_level); in txp_determine_geometry()
1322 phdr->spin_bit = 0; in txp_determine_geometry()
1323 phdr->pn_len = txp_determine_pn_len(txp); in txp_determine_geometry()
1324 phdr->partial = 0; in txp_determine_geometry()
1325 phdr->fixed = 1; in txp_determine_geometry()
1326 phdr->reserved = 0; in txp_determine_geometry()
1327 phdr->version = txp->args.protocol_version; in txp_determine_geometry()
1328 phdr->dst_conn_id = txp->args.cur_dcid; in txp_determine_geometry()
1329 phdr->src_conn_id = txp->args.cur_scid; in txp_determine_geometry()
1333 * length for non-1RTT packets, because the Length field found in in txp_determine_geometry()
1334 * Initial/Handshake/0-RTT packets uses a variable-length encoding. However, in txp_determine_geometry()
1340 * e.g. we predicted use of a 2-byte length field, but ended up only needing in txp_determine_geometry()
1341 * a 1-byte length field). However this does matter for Initial packets in txp_determine_geometry()
1344 * which means if we overestimated the header size, we will be short by a in txp_determine_geometry()
1345 * few bytes and the server will ignore the packet for being too short. In in txp_determine_geometry()
1347 * bytes, which requires a 2-byte length field, so we don't actually need to in txp_determine_geometry()
1348 * worry about this. Thus we estimate the header length assuming a 2-byte in txp_determine_geometry()
1351 phdr->len = OSSL_QUIC_VLINT_2B_MAX - phdr->pn_len; in txp_determine_geometry()
1354 phdr->token = txp->initial_token; in txp_determine_geometry()
1355 phdr->token_len = txp->initial_token_len; in txp_determine_geometry()
1357 phdr->token = NULL; in txp_determine_geometry()
1358 phdr->token_len = 0; in txp_determine_geometry()
1361 hdr_len = ossl_quic_wire_get_encoded_pkt_hdr_len(phdr->dst_conn_id.id_len, in txp_determine_geometry()
1377 cmpl = mdpl - running_total; in txp_determine_geometry()
1380 if (!txp_determine_ppl_from_pl(txp, cmpl, enc_level, hdr_len, &geom->cmppl)) in txp_determine_geometry()
1383 geom->cmpl = cmpl; in txp_determine_geometry()
1384 geom->pkt_overhead = cmpl - geom->cmppl; in txp_determine_geometry()
1385 geom->archetype = archetype; in txp_determine_geometry()
1393 = ossl_ackm_get0_probe_request(txp->args.ackm); in txp_determine_archetype()
1398 * Probe-archetype packet. Actually, we determine archetype on a in txp_determine_archetype()
1399 * per-datagram basis, so if any EL wants a probe, do a pass in which in txp_determine_archetype()
1402 if (probe_info->anti_deadlock_initial > 0 in txp_determine_archetype()
1403 || probe_info->anti_deadlock_handshake > 0) in txp_determine_archetype()
1409 if (probe_info->pto[pn_space] > 0) in txp_determine_archetype()
1414 * but we can do an ACK-only packet (potentially, if we in txp_determine_archetype()
1434 if (!ossl_qtx_is_enc_level_provisioned(txp->args.qtx, enc_level)) in txp_should_try_staging()
1448 * is a non-issue. Where multiple ELs are provisioned, it is possible the in txp_should_try_staging()
1453 * application CONNECTION_CLOSE frames in non-1-RTT ELs, so as to not in txp_should_try_staging()
1456 * queued and need to send it on a non-1-RTT EL, we have to convert it in txp_should_try_staging()
1458 * data. Since this loses information, it suggests we should use the 1-RTT in txp_should_try_staging()
1461 * At the same time, just because we have the 1-RTT EL provisioned locally in txp_should_try_staging()
1468 * This is not a major concern for clients, since if a client has a 1-RTT EL in txp_should_try_staging()
1469 * provisioned the server is guaranteed to also have a 1-RTT EL provisioned. in txp_should_try_staging()
1481 = ossl_ackm_get0_probe_request(txp->args.ackm); in txp_should_try_staging()
1484 && probe_info->anti_deadlock_initial > 0) in txp_should_try_staging()
1486 && probe_info->anti_deadlock_handshake > 0) in txp_should_try_staging()
1487 || probe_info->pto[pn_space] > 0) in txp_should_try_staging()
1492 if (a.allow_crypto && sstream_is_pending(txp->args.crypto[pn_space])) in txp_should_try_staging()
1496 if (a.allow_ack && (ossl_ackm_is_ack_desired(txp->args.ackm, pn_space) in txp_should_try_staging()
1497 || (txp->want_ack & (1UL << pn_space)) != 0)) in txp_should_try_staging()
1500 /* Do we need to force emission of an ACK-eliciting packet? */ in txp_should_try_staging()
1502 && (txp->force_ack_eliciting & (1UL << pn_space)) != 0) in txp_should_try_staging()
1505 /* Does the connection-level RXFC want to produce a frame? */ in txp_should_try_staging()
1506 if (a.allow_conn_fc && (txp->want_max_data in txp_should_try_staging()
1507 || ossl_quic_rxfc_has_cwm_changed(txp->args.conn_rxfc, 0))) in txp_should_try_staging()
1512 && (txp->want_max_streams_bidi in txp_should_try_staging()
1513 || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_bidi_rxfc, in txp_should_try_staging()
1515 || txp->want_max_streams_uni in txp_should_try_staging()
1516 || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_uni_rxfc, in txp_should_try_staging()
1521 if (a.allow_handshake_done && txp->want_handshake_done) in txp_should_try_staging()
1525 if (a.allow_conn_close && txp->want_conn_close && in txp_should_try_staging()
1531 * only on the lowest non-dropped EL. in txp_should_try_staging()
1537 for (cfq_item = ossl_quic_cfq_get_priority_head(txp->args.cfq, pn_space); in txp_should_try_staging()
1566 if (a.allow_stream_rel && txp->handshake_complete) { in txp_should_try_staging()
1569 /* If there are any active streams, 0/1-RTT wants to produce a packet. in txp_should_try_staging()
1572 * frame for it), and all stream-related frames are governed by in txp_should_try_staging()
1573 * a.allow_stream_rel (i.e., if we can send one type of stream-related in txp_should_try_staging()
1576 * list is non-empty. in txp_should_try_staging()
1578 ossl_quic_stream_iter_init(&it, txp->args.qsm, 0); in txp_should_try_staging()
1611 pl -= hdr_len; in txp_determine_ppl_from_pl()
1613 if (!ossl_qtx_calculate_plaintext_payload_len(txp->args.qtx, enc_level, in txp_determine_ppl_from_pl()
1623 return ossl_qtx_get_mdpl(txp->args.qtx); in txp_get_mdpl()
1633 return txp->args.crypto[pn_space]; in get_sstream_by_id()
1635 s = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); in get_sstream_by_id()
1639 return s->sstream; in get_sstream_by_id()
1649 txp->want_handshake_done = 1; in on_regen_notify()
1652 txp->want_max_data = 1; in on_regen_notify()
1655 txp->want_max_streams_bidi = 1; in on_regen_notify()
1658 txp->want_max_streams_uni = 1; in on_regen_notify()
1661 txp->want_ack |= (1UL << pkt->ackm_pkt.pkt_space); in on_regen_notify()
1666 = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); in on_regen_notify()
1671 s->want_max_stream_data = 1; in on_regen_notify()
1672 ossl_quic_stream_map_update_state(txp->args.qsm, s); in on_regen_notify()
1678 = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); in on_regen_notify()
1683 ossl_quic_stream_map_schedule_stop_sending(txp->args.qsm, s); in on_regen_notify()
1689 = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); in on_regen_notify()
1694 s->want_reset_stream = 1; in on_regen_notify()
1695 ossl_quic_stream_map_update_state(txp->args.qsm, s); in on_regen_notify()
1708 return adata->allow_ping in txp_need_ping()
1709 && (adata->require_ack_eliciting in txp_need_ping()
1710 || (txp->force_ack_eliciting & (1UL << pn_space)) != 0); in txp_need_ping()
1720 running_total, &pkt->phdr, &pkt->geom)) in txp_pkt_init()
1725 * PING. in txp_pkt_init()
1727 if (!tx_helper_init(&pkt->h, txp, enc_level, in txp_pkt_init()
1728 pkt->geom.cmppl, in txp_pkt_init()
1729 txp_need_ping(txp, pn_space, &pkt->geom.adata) ? 1 : 0)) in txp_pkt_init()
1732 pkt->h_valid = 1; in txp_pkt_init()
1733 pkt->tpkt = NULL; in txp_pkt_init()
1734 pkt->stream_head = NULL; in txp_pkt_init()
1735 pkt->force_pad = 0; in txp_pkt_init()
1741 if (!pkt->h_valid) in txp_pkt_cleanup()
1744 tx_helper_cleanup(&pkt->h); in txp_pkt_cleanup()
1745 pkt->h_valid = 0; in txp_pkt_cleanup()
1747 if (pkt->tpkt != NULL) { in txp_pkt_cleanup()
1748 ossl_quic_txpim_pkt_release(txp->args.txpim, pkt->tpkt); in txp_pkt_cleanup()
1749 pkt->tpkt = NULL; in txp_pkt_cleanup()
1759 * AEAD tag size) to shrink slightly because we generated a short packet in txp_pkt_postgen_update_pkt_overhead()
1760 * whose which can be represented in fewer bytes as a variable-length in txp_pkt_postgen_update_pkt_overhead()
1769 if (pkt->h.enc_level == QUIC_ENC_LEVEL_INITIAL) in txp_pkt_postgen_update_pkt_overhead()
1771 * Don't update overheads for the INITIAL EL - we have not finished in txp_pkt_postgen_update_pkt_overhead()
1774 * e.g. a 1-byte length field in the packet header. Since we are padding in txp_pkt_postgen_update_pkt_overhead()
1775 * to QUIC_MIN_INITIAL_DGRAM_LEN which requires a 2-byte length field, in txp_pkt_postgen_update_pkt_overhead()
1781 if (!ossl_qtx_calculate_ciphertext_payload_len(txp->args.qtx, pkt->h.enc_level, in txp_pkt_postgen_update_pkt_overhead()
1782 pkt->h.bytes_appended, in txp_pkt_postgen_update_pkt_overhead()
1786 pkt->phdr.len = ciphertext_len; in txp_pkt_postgen_update_pkt_overhead()
1788 hdr_len = ossl_quic_wire_get_encoded_pkt_hdr_len(pkt->phdr.dst_conn_id.id_len, in txp_pkt_postgen_update_pkt_overhead()
1789 &pkt->phdr); in txp_pkt_postgen_update_pkt_overhead()
1791 pkt->geom.pkt_overhead = hdr_len + ciphertext_len - pkt->h.bytes_appended; in txp_pkt_postgen_update_pkt_overhead()
1804 = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); in on_confirm_notify()
1809 s->acked_stop_sending = 1; in on_confirm_notify()
1810 ossl_quic_stream_map_update_state(txp->args.qsm, s); in on_confirm_notify()
1816 = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); in on_confirm_notify()
1825 ossl_quic_stream_map_notify_reset_stream_acked(txp->args.qsm, s); in on_confirm_notify()
1826 ossl_quic_stream_map_update_state(txp->args.qsm, s); in on_confirm_notify()
1843 if (!ossl_assert(pkt->h_valid)) in txp_pkt_append_padding()
1846 if (!ossl_assert(pkt->tpkt != NULL)) in txp_pkt_append_padding()
1849 wpkt = tx_helper_begin(&pkt->h); in txp_pkt_append_padding()
1854 tx_helper_rollback(&pkt->h); in txp_pkt_append_padding()
1858 if (!tx_helper_commit(&pkt->h)) in txp_pkt_append_padding()
1861 pkt->tpkt->ackm_pkt.num_bytes += num_bytes; in txp_pkt_append_padding()
1862 /* Cannot be non-inflight if we have a PADDING frame */ in txp_pkt_append_padding()
1863 pkt->tpkt->ackm_pkt.is_inflight = 1; in txp_pkt_append_padding()
1872 s = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id); in on_sstream_updated()
1876 ossl_quic_stream_map_update_state(txp->args.qsm, s); in on_sstream_updated()
1888 if (txp->closing_bytes_recv == 0) in try_commit_conn_close()
1903 res = txp->closing_bytes_xmit + n <= txp->closing_bytes_recv * 3; in try_commit_conn_close()
1909 if (res && txp->closing_bytes_recv != 0) in try_commit_conn_close()
1910 txp->closing_bytes_xmit += n; in try_commit_conn_close()
1917 txp->closing_bytes_recv += n; in ossl_quic_tx_packetiser_record_received_closing_bytes()
1925 const uint32_t enc_level = pkt->h.enc_level; in txp_generate_pre_token()
1927 const struct archetype_data *a = &pkt->geom.adata; in txp_generate_pre_token()
1928 QUIC_TXPIM_PKT *tpkt = pkt->tpkt; in txp_generate_pre_token()
1929 struct tx_helper *h = &pkt->h; in txp_generate_pre_token()
1933 tpkt->ackm_pkt.largest_acked = QUIC_PN_INVALID; in txp_generate_pre_token()
1936 if (a->allow_ack in txp_generate_pre_token()
1938 && (((txp->want_ack & (1UL << pn_space)) != 0) in txp_generate_pre_token()
1939 || ossl_ackm_is_ack_desired(txp->args.ackm, pn_space)) in txp_generate_pre_token()
1940 && (ack = ossl_ackm_get_ack_frame(txp->args.ackm, pn_space)) != NULL) { in txp_generate_pre_token()
1951 txp->args.ack_delay_exponent, in txp_generate_pre_token()
1956 tpkt->had_ack_frame = 1; in txp_generate_pre_token()
1958 if (ack->num_ack_ranges > 0) in txp_generate_pre_token()
1959 tpkt->ackm_pkt.largest_acked = ack->ack_ranges[0].end; in txp_generate_pre_token()
1961 if (txp->ack_tx_cb != NULL) in txp_generate_pre_token()
1962 txp->ack_tx_cb(&ack2, pn_space, txp->ack_tx_cb_arg); in txp_generate_pre_token()
1969 if (a->allow_conn_close && txp->want_conn_close && chosen_for_conn_close) { in txp_generate_pre_token()
1971 OSSL_QUIC_FRAME_CONN_CLOSE f, *pf = &txp->conn_close_frame; in txp_generate_pre_token()
1993 if (pn_space != QUIC_PN_SPACE_APP && pf->is_app) { in txp_generate_pre_token()
1995 pf->is_app = 0; in txp_generate_pre_token()
1996 pf->frame_type = 0; in txp_generate_pre_token()
1997 pf->error_code = OSSL_QUIC_ERR_APPLICATION_ERROR; in txp_generate_pre_token()
1998 pf->reason = NULL; in txp_generate_pre_token()
1999 pf->reason_len = 0; in txp_generate_pre_token()
2008 tpkt->had_conn_close = 1; in txp_generate_pre_token()
2036 n = (space_left >= *hdr_len) ? space_left - *hdr_len : 0; in try_len()
2065 for (i = OSSL_NELEM(valid) - 1; i >= 0; --i) in determine_len()
2078 * Given a CRYPTO frame header with accurate chdr->len and a budget
2079 * (space_left), try to find the optimal value of chdr->len to fill as much of
2081 * chdr->len cause larger encoded sizes of the length field of the frame, which
2094 if (chdr->len > SIZE_MAX) in determine_crypto_len()
2097 orig_len = (size_t)chdr->len; in determine_crypto_len()
2099 chdr->len = 0; in determine_crypto_len()
2101 chdr->len = orig_len; in determine_crypto_len()
2105 --base_hdr_len; in determine_crypto_len()
2119 if (shdr->len > SIZE_MAX) in determine_stream_len()
2122 orig_len = (size_t)shdr->len; in determine_stream_len()
2124 shdr->len = 0; in determine_stream_len()
2126 shdr->len = orig_len; in determine_stream_len()
2130 if (shdr->has_explicit_len) in determine_stream_len()
2131 --base_hdr_len; in determine_stream_len()
2140 const uint32_t enc_level = pkt->h.enc_level; in txp_generate_crypto_frames()
2142 QUIC_TXPIM_PKT *tpkt = pkt->tpkt; in txp_generate_crypto_frames()
2143 struct tx_helper *h = &pkt->h; in txp_generate_crypto_frames()
2161 if (!ossl_quic_sstream_get_stream_frame(txp->args.crypto[pn_space], in txp_generate_crypto_frames()
2190 if (!txp_el_ensure_iovec(&txp->el[enc_level], h->num_iovec + 3)) in txp_generate_crypto_frames()
2211 tx_helper_unrestrict(h); /* no longer need PING */ in txp_generate_crypto_frames()
2216 chunk.end = chdr.offset + chdr.len - 1; in txp_generate_crypto_frames()
2241 chunk->num_stream_iovec = OSSL_NELEM(chunk->iov); in txp_plan_stream_chunk()
2242 chunk->valid = ossl_quic_sstream_get_stream_frame(sstream, skip, in txp_plan_stream_chunk()
2243 &chunk->shdr, in txp_plan_stream_chunk()
2244 chunk->iov, in txp_plan_stream_chunk()
2245 &chunk->num_stream_iovec); in txp_plan_stream_chunk()
2246 if (!chunk->valid) in txp_plan_stream_chunk()
2249 if (!ossl_assert(chunk->shdr.len > 0 || chunk->shdr.is_fin)) in txp_plan_stream_chunk()
2250 /* Should only have 0-length chunk if FIN */ in txp_plan_stream_chunk()
2253 chunk->orig_len = chunk->shdr.len; in txp_plan_stream_chunk()
2255 /* Clamp according to connection and stream-level TXFC. */ in txp_plan_stream_chunk()
2260 if (chunk->shdr.len > 0 && chunk->shdr.offset + chunk->shdr.len > fc_limit) { in txp_plan_stream_chunk()
2261 chunk->shdr.len = (fc_limit <= chunk->shdr.offset) in txp_plan_stream_chunk()
2262 ? 0 : fc_limit - chunk->shdr.offset; in txp_plan_stream_chunk()
2263 chunk->shdr.is_fin = 0; in txp_plan_stream_chunk()
2266 if (chunk->shdr.len == 0 && !chunk->shdr.is_fin) { in txp_plan_stream_chunk()
2272 chunk->valid = 0; in txp_plan_stream_chunk()
2297 const uint32_t enc_level = pkt->h.enc_level; in txp_generate_stream_frames()
2298 QUIC_TXPIM_PKT *tpkt = pkt->tpkt; in txp_generate_stream_frames()
2299 struct tx_helper *h = &pkt->h; in txp_generate_stream_frames()
2348 if (!ossl_assert(!h->done_implicit)) in txp_generate_stream_frames()
2351 * implicit-length unless we filled the packet or didn't have in txp_generate_stream_frames()
2368 shdr->has_explicit_len = 0; in txp_generate_stream_frames()
2394 && !pkt->force_pad); in txp_generate_stream_frames()
2401 shdr->has_explicit_len = 1; in txp_generate_stream_frames()
2410 shdr->len = payload_len_explicit; in txp_generate_stream_frames()
2413 shdr->has_explicit_len = 0; in txp_generate_stream_frames()
2414 shdr->len = payload_len_implicit; in txp_generate_stream_frames()
2418 if (shdr->is_fin) in txp_generate_stream_frames()
2422 * We are now committed to our length (shdr->len can't change). in txp_generate_stream_frames()
2425 if (shdr->len < orig_len) in txp_generate_stream_frames()
2426 shdr->is_fin = 0; in txp_generate_stream_frames()
2429 ossl_quic_sstream_adjust_iov((size_t)shdr->len, chunks[i % 2].iov, in txp_generate_stream_frames()
2436 if (!txp_el_ensure_iovec(&txp->el[enc_level], h->num_iovec + 3)) in txp_generate_stream_frames()
2461 tx_helper_unrestrict(h); /* no longer need PING */ in txp_generate_stream_frames()
2462 if (!shdr->has_explicit_len) in txp_generate_stream_frames()
2463 h->done_implicit = 1; in txp_generate_stream_frames()
2466 if (shdr->len > 0 && shdr->offset + shdr->len > fc_new_hwm) in txp_generate_stream_frames()
2467 fc_new_hwm = shdr->offset + shdr->len; in txp_generate_stream_frames()
2470 chunk.stream_id = shdr->stream_id; in txp_generate_stream_frames()
2471 chunk.start = shdr->offset; in txp_generate_stream_frames()
2472 chunk.end = shdr->offset + shdr->len - 1; in txp_generate_stream_frames()
2473 chunk.has_fin = shdr->is_fin; in txp_generate_stream_frames()
2479 if (shdr->len < orig_len) { in txp_generate_stream_frames()
2490 *new_credit_consumed = fc_new_hwm - fc_swm; in txp_generate_stream_frames()
2496 stream->txp_next = *tmp_head; in txp_enlink_tmp()
2509 struct tx_helper *h = &pkt->h; in txp_generate_stream_related()
2512 for (ossl_quic_stream_iter_init(&it, txp->args.qsm, 1); in txp_generate_stream_related()
2519 stream->txp_sent_fc = 0; in txp_generate_stream_related()
2520 stream->txp_sent_stop_sending = 0; in txp_generate_stream_related()
2521 stream->txp_sent_reset_stream = 0; in txp_generate_stream_related()
2522 stream->txp_blocked = 0; in txp_generate_stream_related()
2523 stream->txp_txfc_new_credit_consumed = 0; in txp_generate_stream_related()
2526 if (stream->want_stop_sending) { in txp_generate_stream_related()
2533 f.stream_id = stream->id; in txp_generate_stream_related()
2534 f.app_error_code = stream->stop_sending_aec; in txp_generate_stream_related()
2545 tx_helper_unrestrict(h); /* no longer need PING */ in txp_generate_stream_related()
2546 stream->txp_sent_stop_sending = 1; in txp_generate_stream_related()
2549 if (stream->want_reset_stream) { in txp_generate_stream_related()
2552 if (!ossl_assert(stream->send_state == QUIC_SSTREAM_STATE_RESET_SENT)) in txp_generate_stream_related()
2559 f.stream_id = stream->id; in txp_generate_stream_related()
2560 f.app_error_code = stream->reset_stream_aec; in txp_generate_stream_related()
2574 tx_helper_unrestrict(h); /* no longer need PING */ in txp_generate_stream_related()
2575 stream->txp_sent_reset_stream = 1; in txp_generate_stream_related()
2583 if (!ossl_assert(f.final_size <= ossl_quic_txfc_get_swm(&stream->txfc))) in txp_generate_stream_related()
2586 stream->txp_txfc_new_credit_consumed in txp_generate_stream_related()
2587 = f.final_size - ossl_quic_txfc_get_swm(&stream->txfc); in txp_generate_stream_related()
2595 * "Reset Recvd" state." -- In practice, RECV is the only state in txp_generate_stream_related()
2598 if (stream->recv_state == QUIC_RSTREAM_STATE_RECV in txp_generate_stream_related()
2599 && (stream->want_max_stream_data in txp_generate_stream_related()
2600 || ossl_quic_rxfc_has_cwm_changed(&stream->rxfc, 0))) { in txp_generate_stream_related()
2606 cwm = ossl_quic_rxfc_get_cwm(&stream->rxfc); in txp_generate_stream_related()
2608 if (!ossl_quic_wire_encode_frame_max_stream_data(wpkt, stream->id, in txp_generate_stream_related()
2619 tx_helper_unrestrict(h); /* no longer need PING */ in txp_generate_stream_related()
2620 stream->txp_sent_fc = 1; in txp_generate_stream_related()
2637 if (!ossl_assert(!stream->want_reset_stream)) in txp_generate_stream_related()
2641 stream->id, stream->sstream, in txp_generate_stream_related()
2642 &stream->txfc, in txp_generate_stream_related()
2646 &stream->txp_txfc_new_credit_consumed, in txp_generate_stream_related()
2652 conn_consumed += stream->txp_txfc_new_credit_consumed; in txp_generate_stream_related()
2671 const uint32_t enc_level = pkt->h.enc_level; in txp_generate_for_el()
2674 const struct archetype_data a = pkt->geom.adata; in txp_generate_for_el()
2676 * Cleared if we encode any non-ACK-eliciting frame type which rules out the in txp_generate_for_el()
2677 * packet being a non-inflight frame. This means any non-ACK ACK-eliciting in txp_generate_for_el()
2679 * become ineligible for non-inflight treatment so it is not necessary to in txp_generate_for_el()
2686 struct tx_helper *h = &pkt->h; in txp_generate_for_el()
2689 if (!ossl_quic_pn_valid(txp->next_pn[pn_space])) in txp_generate_for_el()
2692 if (!ossl_assert(pkt->tpkt == NULL)) in txp_generate_for_el()
2695 if ((pkt->tpkt = tpkt = ossl_quic_txpim_pkt_alloc(txp->args.txpim)) == NULL) in txp_generate_for_el()
2706 if (a.allow_handshake_done && txp->want_handshake_done in txp_generate_for_el()
2714 tpkt->had_handshake_done_frame = 1; in txp_generate_for_el()
2720 tx_helper_unrestrict(h); /* no longer need PING */ in txp_generate_for_el()
2728 && (txp->want_max_data in txp_generate_for_el()
2729 || ossl_quic_rxfc_has_cwm_changed(txp->args.conn_rxfc, 0)) in txp_generate_for_el()
2732 uint64_t cwm = ossl_quic_rxfc_get_cwm(txp->args.conn_rxfc); in txp_generate_for_el()
2738 tpkt->had_max_data_frame = 1; in txp_generate_for_el()
2744 tx_helper_unrestrict(h); /* no longer need PING */ in txp_generate_for_el()
2752 && (txp->want_max_streams_bidi in txp_generate_for_el()
2753 || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_bidi_rxfc, 0)) in txp_generate_for_el()
2757 = ossl_quic_rxfc_get_cwm(txp->args.max_streams_bidi_rxfc); in txp_generate_for_el()
2764 tpkt->had_max_streams_bidi_frame = 1; in txp_generate_for_el()
2770 tx_helper_unrestrict(h); /* no longer need PING */ in txp_generate_for_el()
2778 && (txp->want_max_streams_uni in txp_generate_for_el()
2779 || ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_uni_rxfc, 0)) in txp_generate_for_el()
2783 = ossl_quic_rxfc_get_cwm(txp->args.max_streams_uni_rxfc); in txp_generate_for_el()
2790 tpkt->had_max_streams_uni_frame = 1; in txp_generate_for_el()
2796 tx_helper_unrestrict(h); /* no longer need PING */ in txp_generate_for_el()
2803 for (cfq_item = ossl_quic_cfq_get_priority_head(txp->args.cfq, pn_space); in txp_generate_for_el()
2825 * Regenerate-strategy frames should come before them (namely in txp_generate_for_el()
2846 pkt->force_pad = 1; in txp_generate_for_el()
2868 tx_helper_unrestrict(h); /* no longer need PING */ in txp_generate_for_el()
2887 /* Stream-specific frames */ in txp_generate_for_el()
2888 if (a.allow_stream_rel && txp->handshake_complete) in txp_generate_for_el()
2891 &pkt->stream_head)) in txp_generate_for_el()
2894 /* PING */ in txp_generate_for_el()
2900 assert(h->reserve > 0); in txp_generate_for_el()
2908 * We treat a request to be ACK-eliciting as a requirement, so this in txp_generate_for_el()
2926 tpkt->ackm_pkt.num_bytes = h->bytes_appended + pkt->geom.pkt_overhead; in txp_generate_for_el()
2927 tpkt->ackm_pkt.pkt_num = txp->next_pn[pn_space]; in txp_generate_for_el()
2929 tpkt->ackm_pkt.pkt_space = pn_space; in txp_generate_for_el()
2930 tpkt->ackm_pkt.is_inflight = !can_be_non_inflight; in txp_generate_for_el()
2931 tpkt->ackm_pkt.is_ack_eliciting = have_ack_eliciting; in txp_generate_for_el()
2932 tpkt->ackm_pkt.is_pto_probe = 0; in txp_generate_for_el()
2933 tpkt->ackm_pkt.is_mtu_probe = 0; in txp_generate_for_el()
2934 tpkt->ackm_pkt.time = txp->args.now(txp->args.now_arg); in txp_generate_for_el()
2935 tpkt->pkt_type = pkt->phdr.type; in txp_generate_for_el()
2947 ossl_quic_txpim_pkt_release(txp->args.txpim, tpkt); in txp_generate_for_el()
2948 pkt->tpkt = NULL; in txp_generate_for_el()
2959 * - Sends the packet to the QTX for encryption and transmission;
2961 * - Records the packet as having been transmitted in FIFM. ACKM is informed,
2964 * - Informs various subsystems of frames that were sent and clears frame
2969 * - pkt is a txp_pkt for the correct EL;
2971 * - pkt->tpkt is valid;
2973 * - pkt->tpkt->ackm_pkt has been fully filled in;
2975 * - Stream chunk records have been appended to pkt->tpkt for STREAM and
2978 * - The chosen stream list for the packet can be fully walked from
2979 * pkt->stream_head using stream->txp_next;
2981 * - pkt->has_ack_eliciting is set correctly.
2990 uint32_t enc_level = pkt->h.enc_level; in txp_pkt_commit()
2992 QUIC_TXPIM_PKT *tpkt = pkt->tpkt; in txp_pkt_commit()
3000 if (pkt->h.bytes_appended == 0) in txp_pkt_commit()
3007 txpkt.hdr = &pkt->phdr; in txp_pkt_commit()
3008 txpkt.iovec = txp->el[enc_level].iovec; in txp_pkt_commit()
3009 txpkt.num_iovec = pkt->h.num_iovec; in txp_pkt_commit()
3011 txpkt.peer = BIO_ADDR_family(&txp->args.peer) == AF_UNSPEC in txp_pkt_commit()
3012 ? NULL : &txp->args.peer; in txp_pkt_commit()
3013 txpkt.pn = txp->next_pn[pn_space]; in txp_pkt_commit()
3017 for (stream = pkt->stream_head; stream != NULL; stream = stream->txp_next) in txp_pkt_commit()
3018 if (stream->txp_sent_stop_sending || stream->txp_sent_reset_stream) { in txp_pkt_commit()
3022 chunk.stream_id = stream->id; in txp_pkt_commit()
3026 chunk.has_stop_sending = stream->txp_sent_stop_sending; in txp_pkt_commit()
3027 chunk.has_reset_stream = stream->txp_sent_reset_stream; in txp_pkt_commit()
3033 if (!ossl_quic_fifd_pkt_commit(&txp->fifd, tpkt)) in txp_pkt_commit()
3037 * Transmission and Post-Packet Generation Bookkeeping in txp_pkt_commit()
3040 * No backing out anymore - at this point the ACKM has recorded the packet in txp_pkt_commit()
3047 ++txp->next_pn[pn_space]; in txp_pkt_commit()
3051 if (!ossl_qtx_write_pkt(txp->args.qtx, &txpkt)) in txp_pkt_commit()
3058 for (stream = pkt->stream_head; stream != NULL; stream = stream->txp_next) { in txp_pkt_commit()
3059 if (stream->txp_sent_fc) { in txp_pkt_commit()
3060 stream->want_max_stream_data = 0; in txp_pkt_commit()
3061 ossl_quic_rxfc_has_cwm_changed(&stream->rxfc, 1); in txp_pkt_commit()
3064 if (stream->txp_sent_stop_sending) in txp_pkt_commit()
3065 stream->want_stop_sending = 0; in txp_pkt_commit()
3067 if (stream->txp_sent_reset_stream) in txp_pkt_commit()
3068 stream->want_reset_stream = 0; in txp_pkt_commit()
3070 if (stream->txp_txfc_new_credit_consumed > 0) { in txp_pkt_commit()
3071 if (!ossl_assert(ossl_quic_txfc_consume_credit(&stream->txfc, in txp_pkt_commit()
3072 stream->txp_txfc_new_credit_consumed))) in txp_pkt_commit()
3080 stream->txp_txfc_new_credit_consumed = 0; in txp_pkt_commit()
3086 * the stream is drained of data or TXFC-blocked), we can mark the in txp_pkt_commit()
3089 ossl_quic_stream_map_update_state(txp->args.qsm, stream); in txp_pkt_commit()
3092 && !ossl_quic_sstream_has_pending(stream->sstream) in txp_pkt_commit()
3093 && ossl_quic_sstream_get_final_size(stream->sstream, NULL)) in txp_pkt_commit()
3098 ossl_quic_stream_map_notify_all_data_sent(txp->args.qsm, stream); in txp_pkt_commit()
3102 if (tpkt->ackm_pkt.is_ack_eliciting) in txp_pkt_commit()
3103 txp->force_ack_eliciting &= ~(1UL << pn_space); in txp_pkt_commit()
3105 if (tpkt->had_handshake_done_frame) in txp_pkt_commit()
3106 txp->want_handshake_done = 0; in txp_pkt_commit()
3108 if (tpkt->had_max_data_frame) { in txp_pkt_commit()
3109 txp->want_max_data = 0; in txp_pkt_commit()
3110 ossl_quic_rxfc_has_cwm_changed(txp->args.conn_rxfc, 1); in txp_pkt_commit()
3113 if (tpkt->had_max_streams_bidi_frame) { in txp_pkt_commit()
3114 txp->want_max_streams_bidi = 0; in txp_pkt_commit()
3115 ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_bidi_rxfc, 1); in txp_pkt_commit()
3118 if (tpkt->had_max_streams_uni_frame) { in txp_pkt_commit()
3119 txp->want_max_streams_uni = 0; in txp_pkt_commit()
3120 ossl_quic_rxfc_has_cwm_changed(txp->args.max_streams_uni_rxfc, 1); in txp_pkt_commit()
3123 if (tpkt->had_ack_frame) in txp_pkt_commit()
3124 txp->want_ack &= ~(1UL << pn_space); in txp_pkt_commit()
3126 if (tpkt->had_conn_close) in txp_pkt_commit()
3127 txp->want_conn_close = 0; in txp_pkt_commit()
3131 * the requirement of a probe, namely being ACK-eliciting. in txp_pkt_commit()
3133 if (tpkt->ackm_pkt.is_ack_eliciting) { in txp_pkt_commit()
3135 = ossl_ackm_get0_probe_request(txp->args.ackm); in txp_pkt_commit()
3138 && probe_info->anti_deadlock_initial > 0) in txp_pkt_commit()
3139 --probe_info->anti_deadlock_initial; in txp_pkt_commit()
3142 && probe_info->anti_deadlock_handshake > 0) in txp_pkt_commit()
3143 --probe_info->anti_deadlock_handshake; in txp_pkt_commit()
3145 if (a.allow_force_ack_eliciting /* (i.e., not for 0-RTT) */ in txp_pkt_commit()
3146 && probe_info->pto[pn_space] > 0) in txp_pkt_commit()
3147 --probe_info->pto[pn_space]; in txp_pkt_commit()
3158 if (el->alloc_iovec >= num) in txp_el_ensure_iovec()
3161 num = el->alloc_iovec != 0 ? el->alloc_iovec * 2 : 8; in txp_el_ensure_iovec()
3163 iovec = OPENSSL_realloc(el->iovec, sizeof(OSSL_QTX_IOVEC) * num); in txp_el_ensure_iovec()
3167 el->iovec = iovec; in txp_el_ensure_iovec()
3168 el->alloc_iovec = num; in txp_el_ensure_iovec()
3176 size_t reason_len = f->reason_len; in ossl_quic_tx_packetiser_schedule_conn_close()
3179 if (txp->want_conn_close) in ossl_quic_tx_packetiser_schedule_conn_close()
3190 reason = OPENSSL_memdup(f->reason, reason_len); in ossl_quic_tx_packetiser_schedule_conn_close()
3195 txp->conn_close_frame = *f; in ossl_quic_tx_packetiser_schedule_conn_close()
3196 txp->conn_close_frame.reason = reason; in ossl_quic_tx_packetiser_schedule_conn_close()
3197 txp->conn_close_frame.reason_len = reason_len; in ossl_quic_tx_packetiser_schedule_conn_close()
3198 txp->want_conn_close = 1; in ossl_quic_tx_packetiser_schedule_conn_close()
3206 txp->msg_callback = msg_callback; in ossl_quic_tx_packetiser_set_msg_callback()
3207 txp->msg_callback_ssl = msg_callback_ssl; in ossl_quic_tx_packetiser_set_msg_callback()
3213 txp->msg_callback_arg = msg_callback_arg; in ossl_quic_tx_packetiser_set_msg_callback_arg()
3222 return txp->next_pn[pn_space]; in ossl_quic_tx_packetiser_get_next_pn()
3228 * TXP-specific deadline computations which rely on TXP innards. This is in in ossl_quic_tx_packetiser_get_deadline()
3236 * ACK generation is not CC-gated - packets containing only ACKs are allowed in ossl_quic_tx_packetiser_get_deadline()
3244 if (ossl_qtx_is_enc_level_provisioned(txp->args.qtx, enc_level)) { in ossl_quic_tx_packetiser_get_deadline()
3247 ossl_ackm_get_ack_deadline(txp->args.ackm, pn_space)); in ossl_quic_tx_packetiser_get_deadline()
3251 if (txp->args.cc_method->get_tx_allowance(txp->args.cc_data) == 0) in ossl_quic_tx_packetiser_get_deadline()
3253 txp->args.cc_method->get_wakeup_deadline(txp->args.cc_data)); in ossl_quic_tx_packetiser_get_deadline()