Path: blob/main/crypto/openssl/ssl/quic/quic_ackm.c
108604 views
/*1* Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include "internal/quic_ackm.h"10#include "internal/uint_set.h"11#include "internal/common.h"12#include <assert.h>1314DEFINE_LIST_OF(tx_history, OSSL_ACKM_TX_PKT);1516/*17* TX Packet History18* *****************19*20* The TX Packet History object tracks information about packets which have been21* sent for which we later expect to receive an ACK. It is essentially a simple22* database keeping a list of packet information structures in packet number23* order which can also be looked up directly by packet number.24*25* We currently only allow packets to be appended to the list (i.e. the packet26* numbers of the packets appended to the list must monotonically increase), as27* we should not currently need more general functionality such as a sorted list28* insert.29*/30struct tx_pkt_history_st {31/* A linked list of all our packets. */32OSSL_LIST(tx_history)33packets;3435/*36* Mapping from packet numbers (uint64_t) to (OSSL_ACKM_TX_PKT *)37*38* Invariant: A packet is in this map if and only if it is in the linked39* list.40*/41LHASH_OF(OSSL_ACKM_TX_PKT) *map;4243/*44* The lowest packet number which may currently be added to the history list45* (inclusive). We do not allow packet numbers to be added to the history46* list non-monotonically, so packet numbers must be greater than or equal47* to this value.48*/49uint64_t watermark;5051/*52* Packet number of the highest packet info structure we have yet appended53* to the list. This is usually one less than watermark, except when we have54* not added any packet yet.55*/56uint64_t highest_sent;57};5859DEFINE_LHASH_OF_EX(OSSL_ACKM_TX_PKT);6061static unsigned long tx_pkt_info_hash(const OSSL_ACKM_TX_PKT *pkt)62{63/* Using low bits of the packet number as the hash should be enough */64return (unsigned long)pkt->pkt_num;65}6667static int tx_pkt_info_compare(const OSSL_ACKM_TX_PKT *a,68const OSSL_ACKM_TX_PKT *b)69{70if (a->pkt_num < b->pkt_num)71return -1;72if (a->pkt_num > b->pkt_num)73return 1;74return 0;75}7677static int78tx_pkt_history_init(struct tx_pkt_history_st *h)79{80ossl_list_tx_history_init(&h->packets);81h->watermark = 0;82h->highest_sent = 0;8384h->map = lh_OSSL_ACKM_TX_PKT_new(tx_pkt_info_hash, tx_pkt_info_compare);85if (h->map == NULL)86return 0;8788return 1;89}9091static void92tx_pkt_history_destroy(struct tx_pkt_history_st *h)93{94lh_OSSL_ACKM_TX_PKT_free(h->map);95h->map = NULL;96ossl_list_tx_history_init(&h->packets);97}9899static int100tx_pkt_history_add_actual(struct tx_pkt_history_st *h,101OSSL_ACKM_TX_PKT *pkt)102{103OSSL_ACKM_TX_PKT *existing;104105/*106* There should not be any existing packet with this number107* in our mapping.108*/109existing = lh_OSSL_ACKM_TX_PKT_retrieve(h->map, pkt);110if (!ossl_assert(existing == NULL))111return 0;112113/* Should not already be in a list. */114if (!ossl_assert(ossl_list_tx_history_next(pkt) == NULL115&& ossl_list_tx_history_prev(pkt) == NULL))116return 0;117118lh_OSSL_ACKM_TX_PKT_insert(h->map, pkt);119120ossl_list_tx_history_insert_tail(&h->packets, pkt);121return 1;122}123124/* Adds a packet information structure to the history list. */125static int126tx_pkt_history_add(struct tx_pkt_history_st *h,127OSSL_ACKM_TX_PKT *pkt)128{129if (!ossl_assert(pkt->pkt_num >= h->watermark))130return 0;131132if (tx_pkt_history_add_actual(h, pkt) < 1)133return 0;134135h->watermark = pkt->pkt_num + 1;136h->highest_sent = pkt->pkt_num;137return 1;138}139140/* Retrieve a packet information structure by packet number. */141static OSSL_ACKM_TX_PKT *142tx_pkt_history_by_pkt_num(struct tx_pkt_history_st *h, uint64_t pkt_num)143{144OSSL_ACKM_TX_PKT key;145146key.pkt_num = pkt_num;147148return lh_OSSL_ACKM_TX_PKT_retrieve(h->map, &key);149}150151/* Remove a packet information structure from the history log. */152static int153tx_pkt_history_remove(struct tx_pkt_history_st *h, uint64_t pkt_num)154{155OSSL_ACKM_TX_PKT key, *pkt;156key.pkt_num = pkt_num;157158pkt = tx_pkt_history_by_pkt_num(h, pkt_num);159if (pkt == NULL)160return 0;161162ossl_list_tx_history_remove(&h->packets, pkt);163lh_OSSL_ACKM_TX_PKT_delete(h->map, &key);164return 1;165}166167/*168* RX Packet Number Tracking169* *************************170*171* **Background.** The RX side of the ACK manager must track packets we have172* received for which we have to generate ACK frames. Broadly, this means we173* store a set of packet numbers which we have received but which we do not know174* for a fact that the transmitter knows we have received.175*176* This must handle various situations:177*178* 1. We receive a packet but have not sent an ACK yet, so the transmitter179* does not know whether we have received it or not yet.180*181* 2. We receive a packet and send an ACK which is lost. We do not182* immediately know that the ACK was lost and the transmitter does not know183* that we have received the packet.184*185* 3. We receive a packet and send an ACK which is received by the186* transmitter. The transmitter does not immediately respond with an ACK,187* or responds with an ACK which is lost. The transmitter knows that we188* have received the packet, but we do not know for sure that it knows,189* because the ACK we sent could have been lost.190*191* 4. We receive a packet and send an ACK which is received by the192* transmitter. The transmitter subsequently sends us an ACK which confirms193* its receipt of the ACK we sent, and we successfully receive that ACK, so194* we know that the transmitter knows, that we received the original195* packet.196*197* Only when we reach case (4) are we relieved of any need to track a given198* packet number we have received, because only in this case do we know for sure199* that the peer knows we have received the packet. Having reached case (4) we200* will never again need to generate an ACK containing the PN in question, but201* until we reach that point, we must keep track of the PN as not having been202* provably ACKed, as we may have to keep generating ACKs for the given PN not203* just until the transmitter receives one, but until we know that it has204* received one. This will be referred to herein as "provably ACKed".205*206* **Duplicate handling.** The above discusses the case where we have received a207* packet with a given PN but are at best unsure whether the sender knows we208* have received it or not. However, we must also handle the case where we have209* yet to receive a packet with a given PN in the first place. The reason for210* this is because of the requirement expressed by RFC 9000 s. 12.3:211*212* "A receiver MUST discard a newly unprotected packet unless it is certain213* that it has not processed another packet with the same packet number from214* the same packet number space."215*216* We must ensure we never process a duplicate PN. As such, each possible PN we217* can receive must exist in one of the following logical states:218*219* - We have never processed this PN before220* (so if we receive such a PN, it can be processed)221*222* - We have processed this PN but it has not yet been provably ACKed223* (and should therefore be in any future ACK frame generated;224* if we receive such a PN again, it must be ignored)225*226* - We have processed this PN and it has been provably ACKed227* (if we receive such a PN again, it must be ignored)228*229* However, if we were to track this state for every PN ever used in the history230* of a connection, the amount of state required would increase unboundedly as231* the connection goes on (for example, we would have to store a set of every PN232* ever received.)233*234* RFC 9000 s. 12.3 continues:235*236* "Endpoints that track all individual packets for the purposes of detecting237* duplicates are at risk of accumulating excessive state. The data required238* for detecting duplicates can be limited by maintaining a minimum packet239* number below which all packets are immediately dropped."240*241* Moreover, RFC 9000 s. 13.2.3 states that:242*243* "A receiver MUST retain an ACK Range unless it can ensure that it will not244* subsequently accept packets with numbers in that range. Maintaining a245* minimum packet number that increases as ranges are discarded is one way to246* achieve this with minimal state."247*248* This touches on a subtlety of the original requirement quoted above: the249* receiver MUST discard a packet unless it is certain that it has not processed250* another packet with the same PN. However, this does not forbid the receiver251* from also discarding some PNs even though it has not yet processed them. In252* other words, implementations must be conservative and err in the direction of253* assuming a packet is a duplicate, but it is acceptable for this to come at254* the cost of falsely identifying some packets as duplicates.255*256* This allows us to bound the amount of state we must keep, and we adopt the257* suggested strategy quoted above to do so. We define a watermark PN below258* which all PNs are in the same state. This watermark is only ever increased.259* Thus the PNs the state for which needs to be explicitly tracked is limited to260* only a small number of recent PNs, and all older PNs have an assumed state.261*262* Any given PN thus falls into one of the following states:263*264* - (A) The PN is above the watermark but we have not yet received it.265*266* If we receive such a PN, we should process it and record the PN as267* received.268*269* - (B) The PN is above the watermark and we have received it.270*271* The PN should be included in any future ACK frame we generate.272* If we receive such a PN again, we should ignore it.273*274* - (C) The PN is below the watermark.275*276* We do not know whether a packet with the given PN was received or277* not. To be safe, if we receive such a packet, it is not processed.278*279* Note that state (C) corresponds to both "we have processed this PN and it has280* been provably ACKed" logical state and a subset of the PNs in the "we have281* never processed this PN before" logical state (namely all PNs which were lost282* and never received, but which are not recent enough to be above the283* watermark). The reason we can merge these states and avoid tracking states284* for the PNs in this state is because the provably ACKed and never-received285* states are functionally identical in terms of how we need to handle them: we286* don't need to do anything for PNs in either of these states, so we don't have287* to care about PNs in this state nor do we have to care about distinguishing288* the two states for a given PN.289*290* Note that under this scheme provably ACKed PNs are by definition always below291* the watermark; therefore, it follows that when a PN becomes provably ACKed,292* the watermark must be immediately increased to exceed it (otherwise we would293* keep reporting it in future ACK frames).294*295* This is in line with RFC 9000 s. 13.2.4's suggested strategy on when296* to advance the watermark:297*298* "When a packet containing an ACK frame is sent, the Largest Acknowledged299* field in that frame can be saved. When a packet containing an ACK frame is300* acknowledged, the receiver can stop acknowledging packets less than or301* equal to the Largest Acknowledged field in the sent ACK frame."302*303* This is where our scheme's false positives arise. When a packet containing an304* ACK frame is itself ACK'd, PNs referenced in that ACK frame become provably305* acked, and the watermark is bumped accordingly. However, the Largest306* Acknowledged field does not imply that all lower PNs have been received,307* because there may be gaps expressed in the ranges of PNs expressed by that308* and previous ACK frames. Thus, some unreceived PNs may be moved below the309* watermark, and we may subsequently reject those PNs as possibly being310* duplicates even though we have not actually received those PNs. Since we bump311* the watermark when a PN becomes provably ACKed, it follows that an unreceived312* PN falls below the watermark (and thus becomes a false positive for the313* purposes of duplicate detection) when a higher-numbered PN becomes provably314* ACKed.315*316* Thus, when PN n becomes provably acked, any unreceived PNs in the range [0,317* n) will no longer be processed. Although datagrams may be reordered in the318* network, a PN we receive can only become provably ACKed after our own319* subsequently generated ACK frame is sent in a future TX packet, and then we320* receive another RX PN acknowledging that TX packet. This means that a given RX321* PN can only become provably ACKed at least 1 RTT after it is received; it is322* unlikely that any reordered datagrams will still be "in the network" (and not323* lost) by this time. If this does occur for whatever reason and a late PN is324* received, the packet will be discarded unprocessed and the PN is simply325* handled as though lost (a "written off" PN).326*327* **Data structure.** Our state for the RX handling side of the ACK manager, as328* discussed above, mainly comprises:329*330* a) a logical set of PNs, and331* b) a monotonically increasing PN counter (the watermark).332*333* For (a), we define a data structure which stores a logical set of PNs, which334* we use to keep track of which PNs we have received but which have not yet335* been provably ACKed, and thus will later need to generate an ACK frame for.336*337* The correspondence with the logical states discussed above is as follows. A338* PN is in state (C) if it is below the watermark; otherwise it is in state (B)339* if it is in the logical set of PNs, and in state (A) otherwise.340*341* Note that PNs are only removed from the PN set (when they become provably342* ACKed or written off) by virtue of advancement of the watermark. Removing PNs343* from the PN set any other way would be ambiguous as it would be344* indistinguishable from a PN we have not yet received and risk us processing a345* duplicate packet. In other words, for a given PN:346*347* - State (A) can transition to state (B) or (C)348* - State (B) can transition to state (C) only349* - State (C) is the terminal state350*351* We can query the logical set data structure for PNs which have been received352* but which have not been provably ACKed when we want to generate ACK frames.353* Since ACK frames can be lost and/or we might not know that the peer has354* successfully received them, we might generate multiple ACK frames covering a355* given PN until that PN becomes provably ACKed and we finally remove it from356* our set (by bumping the watermark) as no longer being our concern.357*358* The data structure used is the UINT_SET structure defined in uint_set.h,359* which is used as a PN set. We use the following operations of the structure:360*361* Insert Range: Used when we receive a new PN.362*363* Remove Range: Used when bumping the watermark.364*365* Query: Used to determine if a PN is in the set.366*367* **Possible duplicates.** A PN is considered a possible duplicate when either:368*369* a) its PN is already in the PN set (i.e. has already been received), or370* b) its PN is below the watermark (i.e. was provably ACKed or written off).371*372* A packet with a given PN is considered 'processable' when that PN is not373* considered a possible duplicate (see ossl_ackm_is_rx_pn_processable).374*375* **TX/RX interaction.** The watermark is bumped whenever an RX packet becomes376* provably ACKed. This occurs when an ACK frame is received by the TX side of377* the ACK manager; thus, there is necessary interaction between the TX and RX378* sides of the ACK manager.379*380* This is implemented as follows. When a packet is queued as sent in the TX381* side of the ACK manager, it may optionally have a Largest Acked value set on382* it. The user of the ACK manager should do this if the packet being383* transmitted contains an ACK frame, by setting the field to the Largest Acked384* field of that frame. Otherwise, this field should be set to QUIC_PN_INVALID.385* When a TX packet is eventually acknowledged which has this field set, it is386* used to update the state of the RX side of the ACK manager by bumping the387* watermark accordingly.388*/389struct rx_pkt_history_st {390UINT_SET set;391392/*393* Invariant: PNs below this are not in the set.394* Invariant: This is monotonic and only ever increases.395*/396QUIC_PN watermark;397};398399static int rx_pkt_history_bump_watermark(struct rx_pkt_history_st *h,400QUIC_PN watermark);401402static void rx_pkt_history_init(struct rx_pkt_history_st *h)403{404ossl_uint_set_init(&h->set);405h->watermark = 0;406}407408static void rx_pkt_history_destroy(struct rx_pkt_history_st *h)409{410ossl_uint_set_destroy(&h->set);411}412413/*414* Limit the number of ACK ranges we store to prevent resource consumption DoS415* attacks.416*/417#define MAX_RX_ACK_RANGES 32418419static void rx_pkt_history_trim_range_count(struct rx_pkt_history_st *h)420{421QUIC_PN highest = QUIC_PN_INVALID;422423while (ossl_list_uint_set_num(&h->set) > MAX_RX_ACK_RANGES) {424UINT_RANGE r = ossl_list_uint_set_head(&h->set)->range;425426highest = (highest == QUIC_PN_INVALID)427? r.end428: ossl_quic_pn_max(highest, r.end);429430ossl_uint_set_remove(&h->set, &r);431}432433/*434* Bump watermark to cover all PNs we removed to avoid accidental435* reprocessing of packets.436*/437if (highest != QUIC_PN_INVALID)438rx_pkt_history_bump_watermark(h, highest + 1);439}440441static int rx_pkt_history_add_pn(struct rx_pkt_history_st *h,442QUIC_PN pn)443{444UINT_RANGE r;445446r.start = pn;447r.end = pn;448449if (pn < h->watermark)450return 1; /* consider this a success case */451452if (ossl_uint_set_insert(&h->set, &r) != 1)453return 0;454455rx_pkt_history_trim_range_count(h);456return 1;457}458459static int rx_pkt_history_bump_watermark(struct rx_pkt_history_st *h,460QUIC_PN watermark)461{462UINT_RANGE r;463464if (watermark <= h->watermark)465return 1;466467/* Remove existing PNs below the watermark. */468r.start = 0;469r.end = watermark - 1;470if (ossl_uint_set_remove(&h->set, &r) != 1)471return 0;472473h->watermark = watermark;474return 1;475}476477/*478* ACK Manager Implementation479* **************************480* Implementation of the ACK manager proper.481*/482483/* Constants used by the ACK manager; see RFC 9002. */484#define K_GRANULARITY (1 * OSSL_TIME_MS)485#define K_PKT_THRESHOLD 3486#define K_TIME_THRESHOLD_NUM 9487#define K_TIME_THRESHOLD_DEN 8488489/* The maximum number of times we allow PTO to be doubled. */490#define MAX_PTO_COUNT 16491492/* Default maximum amount of time to leave an ACK-eliciting packet un-ACK'd. */493#define DEFAULT_TX_MAX_ACK_DELAY ossl_ms2time(QUIC_DEFAULT_MAX_ACK_DELAY)494495struct ossl_ackm_st {496/* Our list of transmitted packets. Corresponds to RFC 9002 sent_packets. */497struct tx_pkt_history_st tx_history[QUIC_PN_SPACE_NUM];498499/* Our list of received PNs which are not yet provably acked. */500struct rx_pkt_history_st rx_history[QUIC_PN_SPACE_NUM];501502/* Polymorphic dependencies that we consume. */503OSSL_TIME (*now)(void *arg);504void *now_arg;505OSSL_STATM *statm;506const OSSL_CC_METHOD *cc_method;507OSSL_CC_DATA *cc_data;508509/* RFC 9002 variables. */510uint32_t pto_count;511QUIC_PN largest_acked_pkt[QUIC_PN_SPACE_NUM];512OSSL_TIME time_of_last_ack_eliciting_pkt[QUIC_PN_SPACE_NUM];513OSSL_TIME loss_time[QUIC_PN_SPACE_NUM];514OSSL_TIME loss_detection_deadline;515516/* Lowest PN which is still not known to be ACKed. */517QUIC_PN lowest_unacked_pkt[QUIC_PN_SPACE_NUM];518519/* Time at which we got our first RTT sample, or 0. */520OSSL_TIME first_rtt_sample;521522/*523* A packet's num_bytes are added to this if it is inflight,524* and removed again once ack'd/lost/discarded.525*/526uint64_t bytes_in_flight;527528/*529* A packet's num_bytes are added to this if it is both inflight and530* ack-eliciting, and removed again once ack'd/lost/discarded.531*/532uint64_t ack_eliciting_bytes_in_flight[QUIC_PN_SPACE_NUM];533534/* Count of ECN-CE events. */535uint64_t peer_ecnce[QUIC_PN_SPACE_NUM];536537/* Set to 1 when the handshake is confirmed. */538char handshake_confirmed;539540/* Set to 1 when attached to server channel */541char is_server;542543/* Set to 1 when the peer has completed address validation. */544char peer_completed_addr_validation;545546/* Set to 1 when a PN space has been discarded. */547char discarded[QUIC_PN_SPACE_NUM];548549/* Set to 1 when we think an ACK frame should be generated. */550char rx_ack_desired[QUIC_PN_SPACE_NUM];551552/* Set to 1 if an ACK frame has ever been generated. */553char rx_ack_generated[QUIC_PN_SPACE_NUM];554555/* Probe request counts for reporting to the user. */556OSSL_ACKM_PROBE_INFO pending_probe;557558/* Generated ACK frames for each PN space. */559OSSL_QUIC_FRAME_ACK ack[QUIC_PN_SPACE_NUM];560OSSL_QUIC_ACK_RANGE ack_ranges[QUIC_PN_SPACE_NUM][MAX_RX_ACK_RANGES];561562/* Other RX state. */563/* Largest PN we have RX'd. */564QUIC_PN rx_largest_pn[QUIC_PN_SPACE_NUM];565566/* Time at which the PN in rx_largest_pn was RX'd. */567OSSL_TIME rx_largest_time[QUIC_PN_SPACE_NUM];568569/*570* ECN event counters. Each time we receive a packet with a given ECN label,571* the corresponding ECN counter here is incremented.572*/573uint64_t rx_ect0[QUIC_PN_SPACE_NUM];574uint64_t rx_ect1[QUIC_PN_SPACE_NUM];575uint64_t rx_ecnce[QUIC_PN_SPACE_NUM];576577/*578* Number of ACK-eliciting packets since last ACK. We use this to defer579* emitting ACK frames until a threshold number of ACK-eliciting packets580* have been received.581*/582uint32_t rx_ack_eliciting_pkts_since_last_ack[QUIC_PN_SPACE_NUM];583584/*585* The ACK frame coalescing deadline at which we should flush any unsent ACK586* frames.587*/588OSSL_TIME rx_ack_flush_deadline[QUIC_PN_SPACE_NUM];589590/*591* The RX maximum ACK delay (the maximum amount of time our peer might592* wait to send us an ACK after receiving an ACK-eliciting packet).593*/594OSSL_TIME rx_max_ack_delay;595596/*597* The TX maximum ACK delay (the maximum amount of time we allow ourselves598* to wait before generating an ACK after receiving an ACK-eliciting599* packet).600*/601OSSL_TIME tx_max_ack_delay;602603/* Callbacks for deadline updates. */604void (*loss_detection_deadline_cb)(OSSL_TIME deadline, void *arg);605void *loss_detection_deadline_cb_arg;606607void (*ack_deadline_cb)(OSSL_TIME deadline, int pkt_space, void *arg);608void *ack_deadline_cb_arg;609};610611static ossl_inline uint32_t min_u32(uint32_t x, uint32_t y)612{613return x < y ? x : y;614}615616/*617* Get TX history for a given packet number space. Must not have been618* discarded.619*/620static struct tx_pkt_history_st *get_tx_history(OSSL_ACKM *ackm, int pkt_space)621{622assert(!ackm->discarded[pkt_space]);623624return &ackm->tx_history[pkt_space];625}626627/*628* Get RX history for a given packet number space. Must not have been629* discarded.630*/631static struct rx_pkt_history_st *get_rx_history(OSSL_ACKM *ackm, int pkt_space)632{633assert(!ackm->discarded[pkt_space]);634635return &ackm->rx_history[pkt_space];636}637638/* Does the newly-acknowledged list contain any ack-eliciting packet? */639static int ack_includes_ack_eliciting(OSSL_ACKM_TX_PKT *pkt)640{641for (; pkt != NULL; pkt = pkt->anext)642if (pkt->is_ack_eliciting)643return 1;644645return 0;646}647648/* Return number of ACK-eliciting bytes in flight across all PN spaces. */649static uint64_t ackm_ack_eliciting_bytes_in_flight(OSSL_ACKM *ackm)650{651int i;652uint64_t total = 0;653654for (i = 0; i < QUIC_PN_SPACE_NUM; ++i)655total += ackm->ack_eliciting_bytes_in_flight[i];656657return total;658}659660/* Return 1 if the range contains the given PN. */661static int range_contains(const OSSL_QUIC_ACK_RANGE *range, QUIC_PN pn)662{663return pn >= range->start && pn <= range->end;664}665666/*667* Given a logical representation of an ACK frame 'ack', create a singly-linked668* list of the newly ACK'd frames; that is, of frames which are matched by the669* list of PN ranges contained in the ACK frame. The packet structures in the670* list returned are removed from the TX history list. Returns a pointer to the671* list head (or NULL) if empty.672*/673static OSSL_ACKM_TX_PKT *ackm_detect_and_remove_newly_acked_pkts(OSSL_ACKM *ackm,674const OSSL_QUIC_FRAME_ACK *ack,675int pkt_space)676{677OSSL_ACKM_TX_PKT *acked_pkts = NULL, **fixup = &acked_pkts, *pkt, *pprev;678struct tx_pkt_history_st *h;679size_t ridx = 0;680681assert(ack->num_ack_ranges > 0);682683/*684* Our history list is a list of packets sorted in ascending order685* by packet number.686*687* ack->ack_ranges is a list of packet number ranges in descending order.688*689* Walk through our history list from the end in order to efficiently detect690* membership in the specified ack ranges. As an optimization, we use our691* hashtable to try and skip to the first matching packet. This may fail if692* the ACK ranges given include nonexistent packets.693*/694h = get_tx_history(ackm, pkt_space);695696pkt = tx_pkt_history_by_pkt_num(h, ack->ack_ranges[0].end);697if (pkt == NULL)698pkt = ossl_list_tx_history_tail(&h->packets);699700for (; pkt != NULL; pkt = pprev) {701/*702* Save prev value as it will be zeroed if we remove the packet from the703* history list below.704*/705pprev = ossl_list_tx_history_prev(pkt);706707for (;; ++ridx) {708if (ridx >= ack->num_ack_ranges) {709/*710* We have exhausted all ranges so stop here, even if there are711* more packets to look at.712*/713goto stop;714}715716if (range_contains(&ack->ack_ranges[ridx], pkt->pkt_num)) {717/* We have matched this range. */718tx_pkt_history_remove(h, pkt->pkt_num);719720*fixup = pkt;721fixup = &pkt->anext;722*fixup = NULL;723break;724} else if (pkt->pkt_num > ack->ack_ranges[ridx].end) {725/*726* We have not reached this range yet in our list, so do not727* advance ridx.728*/729break;730} else {731/*732* We have moved beyond this range, so advance to the next range733* and try matching again.734*/735assert(pkt->pkt_num < ack->ack_ranges[ridx].start);736continue;737}738}739}740stop:741742return acked_pkts;743}744745/*746* Create a singly-linked list of newly detected-lost packets in the given747* packet number space. Returns the head of the list or NULL if no packets were748* detected lost. The packets in the list are removed from the TX history list.749*/750static OSSL_ACKM_TX_PKT *ackm_detect_and_remove_lost_pkts(OSSL_ACKM *ackm,751int pkt_space)752{753OSSL_ACKM_TX_PKT *lost_pkts = NULL, **fixup = &lost_pkts, *pkt, *pnext;754OSSL_TIME loss_delay, lost_send_time, now;755OSSL_RTT_INFO rtt;756struct tx_pkt_history_st *h;757758assert(ackm->largest_acked_pkt[pkt_space] != QUIC_PN_INVALID);759760ossl_statm_get_rtt_info(ackm->statm, &rtt);761762ackm->loss_time[pkt_space] = ossl_time_zero();763764loss_delay = ossl_time_multiply(ossl_time_max(rtt.latest_rtt,765rtt.smoothed_rtt),766K_TIME_THRESHOLD_NUM);767loss_delay = ossl_time_divide(loss_delay, K_TIME_THRESHOLD_DEN);768769/* Minimum time of K_GRANULARITY before packets are deemed lost. */770loss_delay = ossl_time_max(loss_delay, ossl_ticks2time(K_GRANULARITY));771772/* Packets sent before this time are deemed lost. */773now = ackm->now(ackm->now_arg);774lost_send_time = ossl_time_subtract(now, loss_delay);775776h = get_tx_history(ackm, pkt_space);777pkt = ossl_list_tx_history_head(&h->packets);778779for (; pkt != NULL; pkt = pnext) {780assert(pkt_space == pkt->pkt_space);781782/*783* Save prev value as it will be zeroed if we remove the packet from the784* history list below.785*/786pnext = ossl_list_tx_history_next(pkt);787788if (pkt->pkt_num > ackm->largest_acked_pkt[pkt_space])789continue;790791/*792* Mark packet as lost, or set time when it should be marked.793*/794if (ossl_time_compare(pkt->time, lost_send_time) <= 0795|| ackm->largest_acked_pkt[pkt_space]796>= pkt->pkt_num + K_PKT_THRESHOLD) {797tx_pkt_history_remove(h, pkt->pkt_num);798799*fixup = pkt;800fixup = &pkt->lnext;801*fixup = NULL;802} else {803if (ossl_time_is_zero(ackm->loss_time[pkt_space]))804ackm->loss_time[pkt_space] = ossl_time_add(pkt->time, loss_delay);805else806ackm->loss_time[pkt_space] = ossl_time_min(ackm->loss_time[pkt_space],807ossl_time_add(pkt->time, loss_delay));808}809}810811return lost_pkts;812}813814static OSSL_TIME ackm_get_loss_time_and_space(OSSL_ACKM *ackm, int *pspace)815{816OSSL_TIME time = ackm->loss_time[QUIC_PN_SPACE_INITIAL];817int i, space = QUIC_PN_SPACE_INITIAL;818819for (i = space + 1; i < QUIC_PN_SPACE_NUM; ++i)820if (ossl_time_is_zero(time)821|| ossl_time_compare(ackm->loss_time[i], time) == -1) {822time = ackm->loss_time[i];823space = i;824}825826*pspace = space;827return time;828}829830static OSSL_TIME ackm_get_pto_time_and_space(OSSL_ACKM *ackm, int *space)831{832OSSL_RTT_INFO rtt;833OSSL_TIME duration;834OSSL_TIME pto_timeout = ossl_time_infinite(), t;835int pto_space = QUIC_PN_SPACE_INITIAL, i;836837ossl_statm_get_rtt_info(ackm->statm, &rtt);838839duration840= ossl_time_add(rtt.smoothed_rtt,841ossl_time_max(ossl_time_multiply(rtt.rtt_variance, 4),842ossl_ticks2time(K_GRANULARITY)));843844duration845= ossl_time_multiply(duration,846(uint64_t)1 << min_u32(ackm->pto_count,847MAX_PTO_COUNT));848849/* Anti-deadlock PTO starts from the current time. */850if (ackm_ack_eliciting_bytes_in_flight(ackm) == 0) {851assert(!ackm->peer_completed_addr_validation);852853*space = ackm->discarded[QUIC_PN_SPACE_INITIAL]854? QUIC_PN_SPACE_HANDSHAKE855: QUIC_PN_SPACE_INITIAL;856return ossl_time_add(ackm->now(ackm->now_arg), duration);857}858859for (i = QUIC_PN_SPACE_INITIAL; i < QUIC_PN_SPACE_NUM; ++i) {860/*861* RFC 9002 section 6.2.2.1 keep probe timeout armed until862* handshake is confirmed (client sees HANDSHAKE_DONE message863* from server).864*/865if (ackm->ack_eliciting_bytes_in_flight[i] == 0 && (ackm->handshake_confirmed == 1 || ackm->is_server == 1))866continue;867868if (i == QUIC_PN_SPACE_APP) {869/* Skip application data until handshake confirmed. */870if (!ackm->handshake_confirmed)871break;872873/* Include max_ack_delay and backoff for app data. */874if (!ossl_time_is_infinite(ackm->rx_max_ack_delay)) {875uint64_t factor876= (uint64_t)1 << min_u32(ackm->pto_count, MAX_PTO_COUNT);877878duration879= ossl_time_add(duration,880ossl_time_multiply(ackm->rx_max_ack_delay,881factor));882}883}884885/*886* Only re-arm timer if stack has sent at least one ACK eliciting frame.887* If stack has sent no ACK eliciting frame at given encryption level then888* particular timer is zero and we must not attempt to set it. Timer keeps889* time since epoch (Jan 1 1970) and we must not set timer to past.890*/891if (!ossl_time_is_zero(ackm->time_of_last_ack_eliciting_pkt[i])) {892t = ossl_time_add(ackm->time_of_last_ack_eliciting_pkt[i], duration);893if (ossl_time_compare(t, pto_timeout) < 0) {894pto_timeout = t;895pto_space = i;896}897}898}899900*space = pto_space;901return pto_timeout;902}903904static void ackm_set_loss_detection_timer_actual(OSSL_ACKM *ackm,905OSSL_TIME deadline)906{907ackm->loss_detection_deadline = deadline;908909if (ackm->loss_detection_deadline_cb != NULL)910ackm->loss_detection_deadline_cb(deadline,911ackm->loss_detection_deadline_cb_arg);912}913914static int ackm_set_loss_detection_timer(OSSL_ACKM *ackm)915{916int space;917OSSL_TIME earliest_loss_time, timeout;918919earliest_loss_time = ackm_get_loss_time_and_space(ackm, &space);920if (!ossl_time_is_zero(earliest_loss_time)) {921/* Time threshold loss detection. */922ackm_set_loss_detection_timer_actual(ackm, earliest_loss_time);923return 1;924}925926if (ackm_ack_eliciting_bytes_in_flight(ackm) == 0927&& ackm->peer_completed_addr_validation) {928/*929* Nothing to detect lost, so no timer is set. However, the client930* needs to arm the timer if the server might be blocked by the931* anti-amplification limit.932*/933ackm_set_loss_detection_timer_actual(ackm, ossl_time_zero());934return 1;935}936937timeout = ackm_get_pto_time_and_space(ackm, &space);938ackm_set_loss_detection_timer_actual(ackm, timeout);939return 1;940}941942static int ackm_in_persistent_congestion(OSSL_ACKM *ackm,943const OSSL_ACKM_TX_PKT *lpkt)944{945/* TODO(QUIC FUTURE): Persistent congestion not currently implemented. */946return 0;947}948949static void ackm_on_pkts_lost(OSSL_ACKM *ackm, int pkt_space,950const OSSL_ACKM_TX_PKT *lpkt, int pseudo)951{952const OSSL_ACKM_TX_PKT *p, *pnext;953OSSL_RTT_INFO rtt;954QUIC_PN largest_pn_lost = 0;955OSSL_CC_LOSS_INFO loss_info = { 0 };956uint32_t flags = 0;957958for (p = lpkt; p != NULL; p = pnext) {959pnext = p->lnext;960961if (p->is_inflight) {962ackm->bytes_in_flight -= p->num_bytes;963if (p->is_ack_eliciting)964ackm->ack_eliciting_bytes_in_flight[p->pkt_space]965-= p->num_bytes;966967if (p->pkt_num > largest_pn_lost)968largest_pn_lost = p->pkt_num;969970if (!pseudo) {971/*972* If this is pseudo-loss (e.g. during connection retry) we do not973* inform the CC as it is not a real loss and not reflective of974* network conditions.975*/976loss_info.tx_time = p->time;977loss_info.tx_size = p->num_bytes;978979ackm->cc_method->on_data_lost(ackm->cc_data, &loss_info);980}981}982983p->on_lost(p->cb_arg);984}985986/*987* Persistent congestion can only be considered if we have gotten at least988* one RTT sample.989*/990ossl_statm_get_rtt_info(ackm->statm, &rtt);991if (!ossl_time_is_zero(ackm->first_rtt_sample)992&& ackm_in_persistent_congestion(ackm, lpkt))993flags |= OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION;994995ackm->cc_method->on_data_lost_finished(ackm->cc_data, flags);996}997998static void ackm_on_pkts_acked(OSSL_ACKM *ackm, const OSSL_ACKM_TX_PKT *apkt)999{1000const OSSL_ACKM_TX_PKT *anext;1001QUIC_PN last_pn_acked = 0;1002OSSL_CC_ACK_INFO ainfo = { 0 };10031004for (; apkt != NULL; apkt = anext) {1005if (apkt->is_inflight) {1006ackm->bytes_in_flight -= apkt->num_bytes;1007if (apkt->is_ack_eliciting)1008ackm->ack_eliciting_bytes_in_flight[apkt->pkt_space]1009-= apkt->num_bytes;10101011if (apkt->pkt_num > last_pn_acked)1012last_pn_acked = apkt->pkt_num;10131014if (apkt->largest_acked != QUIC_PN_INVALID)1015/*1016* This can fail, but it is monotonic; worst case we try again1017* next time.1018*/1019rx_pkt_history_bump_watermark(get_rx_history(ackm,1020apkt->pkt_space),1021apkt->largest_acked + 1);1022}10231024ainfo.tx_time = apkt->time;1025ainfo.tx_size = apkt->num_bytes;10261027anext = apkt->anext;1028apkt->on_acked(apkt->cb_arg); /* may free apkt */10291030if (apkt->is_inflight)1031ackm->cc_method->on_data_acked(ackm->cc_data, &ainfo);1032}1033}10341035OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg),1036void *now_arg,1037OSSL_STATM *statm,1038const OSSL_CC_METHOD *cc_method,1039OSSL_CC_DATA *cc_data,1040int is_server)1041{1042OSSL_ACKM *ackm;1043int i;10441045ackm = OPENSSL_zalloc(sizeof(OSSL_ACKM));1046if (ackm == NULL)1047return NULL;10481049for (i = 0; i < (int)OSSL_NELEM(ackm->tx_history); ++i) {1050ackm->largest_acked_pkt[i] = QUIC_PN_INVALID;1051ackm->rx_ack_flush_deadline[i] = ossl_time_infinite();1052if (tx_pkt_history_init(&ackm->tx_history[i]) < 1)1053goto err;1054}10551056for (i = 0; i < (int)OSSL_NELEM(ackm->rx_history); ++i)1057rx_pkt_history_init(&ackm->rx_history[i]);10581059ackm->now = now;1060ackm->now_arg = now_arg;1061ackm->statm = statm;1062ackm->cc_method = cc_method;1063ackm->cc_data = cc_data;1064ackm->is_server = (char)is_server;10651066ackm->rx_max_ack_delay = ossl_ms2time(QUIC_DEFAULT_MAX_ACK_DELAY);1067ackm->tx_max_ack_delay = DEFAULT_TX_MAX_ACK_DELAY;10681069return ackm;10701071err:1072while (--i >= 0)1073tx_pkt_history_destroy(&ackm->tx_history[i]);10741075OPENSSL_free(ackm);1076return NULL;1077}10781079void ossl_ackm_free(OSSL_ACKM *ackm)1080{1081size_t i;10821083if (ackm == NULL)1084return;10851086for (i = 0; i < OSSL_NELEM(ackm->tx_history); ++i)1087if (!ackm->discarded[i]) {1088tx_pkt_history_destroy(&ackm->tx_history[i]);1089rx_pkt_history_destroy(&ackm->rx_history[i]);1090}10911092OPENSSL_free(ackm);1093}10941095int ossl_ackm_on_tx_packet(OSSL_ACKM *ackm, OSSL_ACKM_TX_PKT *pkt)1096{1097struct tx_pkt_history_st *h = get_tx_history(ackm, pkt->pkt_space);10981099/* Time must be set and not move backwards. */1100if (ossl_time_is_zero(pkt->time)1101|| ossl_time_compare(ackm->time_of_last_ack_eliciting_pkt[pkt->pkt_space],1102pkt->time)1103> 0)1104return 0;11051106/* Must have non-zero number of bytes. */1107if (pkt->num_bytes == 0)1108return 0;11091110/* Does not make any sense for a non-in-flight packet to be ACK-eliciting. */1111if (!pkt->is_inflight && pkt->is_ack_eliciting)1112return 0;11131114if (tx_pkt_history_add(h, pkt) == 0)1115return 0;11161117if (pkt->is_inflight) {1118if (pkt->is_ack_eliciting) {1119ackm->time_of_last_ack_eliciting_pkt[pkt->pkt_space] = pkt->time;1120ackm->ack_eliciting_bytes_in_flight[pkt->pkt_space]1121+= pkt->num_bytes;1122}11231124ackm->bytes_in_flight += pkt->num_bytes;1125ackm_set_loss_detection_timer(ackm);11261127ackm->cc_method->on_data_sent(ackm->cc_data, pkt->num_bytes);1128}11291130return 1;1131}11321133int ossl_ackm_on_rx_datagram(OSSL_ACKM *ackm, size_t num_bytes)1134{1135/* No-op on the client. */1136return 1;1137}11381139static void ackm_process_ecn(OSSL_ACKM *ackm, const OSSL_QUIC_FRAME_ACK *ack,1140int pkt_space)1141{1142struct tx_pkt_history_st *h;1143OSSL_ACKM_TX_PKT *pkt;1144OSSL_CC_ECN_INFO ecn_info = { 0 };11451146/*1147* If the ECN-CE counter reported by the peer has increased, this could1148* be a new congestion event.1149*/1150if (ack->ecnce > ackm->peer_ecnce[pkt_space]) {1151ackm->peer_ecnce[pkt_space] = ack->ecnce;11521153h = get_tx_history(ackm, pkt_space);1154pkt = tx_pkt_history_by_pkt_num(h, ack->ack_ranges[0].end);1155if (pkt == NULL)1156return;11571158ecn_info.largest_acked_time = pkt->time;1159ackm->cc_method->on_ecn(ackm->cc_data, &ecn_info);1160}1161}11621163int ossl_ackm_on_rx_ack_frame(OSSL_ACKM *ackm, const OSSL_QUIC_FRAME_ACK *ack,1164int pkt_space, OSSL_TIME rx_time)1165{1166OSSL_ACKM_TX_PKT *na_pkts, *lost_pkts;1167int must_set_timer = 0;11681169if (ackm->largest_acked_pkt[pkt_space] == QUIC_PN_INVALID)1170ackm->largest_acked_pkt[pkt_space] = ack->ack_ranges[0].end;1171else1172ackm->largest_acked_pkt[pkt_space]1173= ossl_quic_pn_max(ackm->largest_acked_pkt[pkt_space],1174ack->ack_ranges[0].end);11751176/*1177* If we get an ACK in the handshake space, address validation is completed.1178* Make sure we update the timer, even if no packets were ACK'd.1179*/1180if (!ackm->peer_completed_addr_validation1181&& pkt_space == QUIC_PN_SPACE_HANDSHAKE) {1182ackm->peer_completed_addr_validation = 1;1183must_set_timer = 1;1184}11851186/*1187* Find packets that are newly acknowledged and remove them from the list.1188*/1189na_pkts = ackm_detect_and_remove_newly_acked_pkts(ackm, ack, pkt_space);1190if (na_pkts == NULL) {1191if (must_set_timer)1192ackm_set_loss_detection_timer(ackm);11931194return 1;1195}11961197/*1198* Update the RTT if the largest acknowledged is newly acked and at least1199* one ACK-eliciting packet was newly acked.1200*1201* First packet in the list is always the one with the largest PN.1202*/1203if (na_pkts->pkt_num == ack->ack_ranges[0].end && ack_includes_ack_eliciting(na_pkts)) {1204OSSL_TIME now = ackm->now(ackm->now_arg), ack_delay;1205if (ossl_time_is_zero(ackm->first_rtt_sample))1206ackm->first_rtt_sample = now;12071208/* Enforce maximum ACK delay. */1209ack_delay = ack->delay_time;1210if (ackm->handshake_confirmed)1211ack_delay = ossl_time_min(ack_delay, ackm->rx_max_ack_delay);12121213ossl_statm_update_rtt(ackm->statm, ack_delay,1214ossl_time_subtract(now, na_pkts->time));1215}12161217/*1218* Process ECN information if present.1219*1220* We deliberately do most ECN processing in the ACKM rather than the1221* congestion controller to avoid having to give the congestion controller1222* access to ACKM internal state.1223*/1224if (ack->ecn_present)1225ackm_process_ecn(ackm, ack, pkt_space);12261227/* Handle inferred loss. */1228lost_pkts = ackm_detect_and_remove_lost_pkts(ackm, pkt_space);1229if (lost_pkts != NULL)1230ackm_on_pkts_lost(ackm, pkt_space, lost_pkts, /*pseudo=*/0);12311232ackm_on_pkts_acked(ackm, na_pkts);12331234/*1235* Reset pto_count unless the client is unsure if the server validated the1236* client's address.1237*/1238if (ackm->peer_completed_addr_validation)1239ackm->pto_count = 0;12401241ackm_set_loss_detection_timer(ackm);1242return 1;1243}12441245int ossl_ackm_on_pkt_space_discarded(OSSL_ACKM *ackm, int pkt_space)1246{1247OSSL_ACKM_TX_PKT *pkt, *pnext;1248uint64_t num_bytes_invalidated = 0;12491250if (ackm->discarded[pkt_space])1251return 0;12521253if (pkt_space == QUIC_PN_SPACE_HANDSHAKE)1254ackm->peer_completed_addr_validation = 1;12551256for (pkt = ossl_list_tx_history_head(&get_tx_history(ackm, pkt_space)->packets);1257pkt != NULL; pkt = pnext) {1258pnext = ossl_list_tx_history_next(pkt);1259if (pkt->is_inflight) {1260ackm->bytes_in_flight -= pkt->num_bytes;1261num_bytes_invalidated += pkt->num_bytes;1262}12631264pkt->on_discarded(pkt->cb_arg); /* may free pkt */1265}12661267tx_pkt_history_destroy(&ackm->tx_history[pkt_space]);1268rx_pkt_history_destroy(&ackm->rx_history[pkt_space]);12691270if (num_bytes_invalidated > 0)1271ackm->cc_method->on_data_invalidated(ackm->cc_data,1272num_bytes_invalidated);12731274ackm->time_of_last_ack_eliciting_pkt[pkt_space] = ossl_time_zero();1275ackm->loss_time[pkt_space] = ossl_time_zero();1276ackm->pto_count = 0;1277ackm->discarded[pkt_space] = 1;1278ackm->ack_eliciting_bytes_in_flight[pkt_space] = 0;1279ackm_set_loss_detection_timer(ackm);1280return 1;1281}12821283int ossl_ackm_on_handshake_confirmed(OSSL_ACKM *ackm)1284{1285ackm->handshake_confirmed = 1;1286ackm->peer_completed_addr_validation = 1;1287ackm_set_loss_detection_timer(ackm);1288return 1;1289}12901291static void ackm_queue_probe_anti_deadlock_handshake(OSSL_ACKM *ackm)1292{1293++ackm->pending_probe.anti_deadlock_handshake;1294}12951296static void ackm_queue_probe_anti_deadlock_initial(OSSL_ACKM *ackm)1297{1298++ackm->pending_probe.anti_deadlock_initial;1299}13001301static void ackm_queue_probe(OSSL_ACKM *ackm, int pkt_space)1302{1303/*1304* TODO(QUIC FUTURE): We are allowed to send either one or two probe1305* packets here.1306* Determine a strategy for when we should send two probe packets.1307*/1308++ackm->pending_probe.pto[pkt_space];1309}13101311int ossl_ackm_on_timeout(OSSL_ACKM *ackm)1312{1313int pkt_space;1314OSSL_TIME earliest_loss_time;1315OSSL_ACKM_TX_PKT *lost_pkts;13161317earliest_loss_time = ackm_get_loss_time_and_space(ackm, &pkt_space);1318if (!ossl_time_is_zero(earliest_loss_time)) {1319/* Time threshold loss detection. */1320lost_pkts = ackm_detect_and_remove_lost_pkts(ackm, pkt_space);1321if (lost_pkts != NULL)1322ackm_on_pkts_lost(ackm, pkt_space, lost_pkts, /*pseudo=*/0);1323ackm_set_loss_detection_timer(ackm);1324return 1;1325}13261327if (ackm_ack_eliciting_bytes_in_flight(ackm) == 0) {1328assert(!ackm->peer_completed_addr_validation);1329/*1330* Client sends an anti-deadlock packet: Initial is padded to earn more1331* anti-amplification credit. A handshake packet proves address1332* ownership.1333*/1334if (ackm->discarded[QUIC_PN_SPACE_INITIAL])1335ackm_queue_probe_anti_deadlock_handshake(ackm);1336else1337ackm_queue_probe_anti_deadlock_initial(ackm);1338} else {1339/*1340* PTO. The user of the ACKM should send new data if available, else1341* retransmit old data, or if neither is available, send a single PING1342* frame.1343*/1344ackm_get_pto_time_and_space(ackm, &pkt_space);1345ackm_queue_probe(ackm, pkt_space);1346}13471348++ackm->pto_count;1349ackm_set_loss_detection_timer(ackm);1350return 1;1351}13521353OSSL_TIME ossl_ackm_get_loss_detection_deadline(OSSL_ACKM *ackm)1354{1355return ackm->loss_detection_deadline;1356}13571358OSSL_ACKM_PROBE_INFO *ossl_ackm_get0_probe_request(OSSL_ACKM *ackm)1359{1360return &ackm->pending_probe;1361}13621363int ossl_ackm_get_largest_unacked(OSSL_ACKM *ackm, int pkt_space, QUIC_PN *pn)1364{1365struct tx_pkt_history_st *h;1366OSSL_ACKM_TX_PKT *p;13671368h = get_tx_history(ackm, pkt_space);1369p = ossl_list_tx_history_tail(&h->packets);1370if (p != NULL) {1371*pn = p->pkt_num;1372return 1;1373}13741375return 0;1376}13771378/* Number of ACK-eliciting packets RX'd before we always emit an ACK. */1379#define PKTS_BEFORE_ACK 213801381/*1382* Return 1 if emission of an ACK frame is currently desired.1383*1384* This occurs when one or more of the following conditions occurs:1385*1386* - We have flagged that we want to send an ACK frame1387* (for example, due to the packet threshold count being exceeded), or1388*1389* - We have exceeded the ACK flush deadline, meaning that1390* we have received at least one ACK-eliciting packet, but held off on1391* sending an ACK frame immediately in the hope that more ACK-eliciting1392* packets might come in, but not enough did and we are now requesting1393* transmission of an ACK frame anyway.1394*1395*/1396int ossl_ackm_is_ack_desired(OSSL_ACKM *ackm, int pkt_space)1397{1398return ackm->rx_ack_desired[pkt_space]1399|| (!ossl_time_is_infinite(ackm->rx_ack_flush_deadline[pkt_space])1400&& ossl_time_compare(ackm->now(ackm->now_arg),1401ackm->rx_ack_flush_deadline[pkt_space])1402>= 0);1403}14041405/*1406* Returns 1 if an ACK frame matches a given packet number.1407*/1408static int ack_contains(const OSSL_QUIC_FRAME_ACK *ack, QUIC_PN pkt_num)1409{1410size_t i;14111412for (i = 0; i < ack->num_ack_ranges; ++i)1413if (range_contains(&ack->ack_ranges[i], pkt_num))1414return 1;14151416return 0;1417}14181419/*1420* Returns 1 iff a PN (which we have just received) was previously reported as1421* implied missing (by us, in an ACK frame we previously generated).1422*/1423static int ackm_is_missing(OSSL_ACKM *ackm, int pkt_space, QUIC_PN pkt_num)1424{1425/*1426* A PN is implied missing if it is not greater than the highest PN in our1427* generated ACK frame, but is not matched by the frame.1428*/1429return ackm->ack[pkt_space].num_ack_ranges > 01430&& pkt_num <= ackm->ack[pkt_space].ack_ranges[0].end1431&& !ack_contains(&ackm->ack[pkt_space], pkt_num);1432}14331434/*1435* Returns 1 iff our RX of a PN newly establishes the implication of missing1436* packets.1437*/1438static int ackm_has_newly_missing(OSSL_ACKM *ackm, int pkt_space)1439{1440struct rx_pkt_history_st *h;14411442h = get_rx_history(ackm, pkt_space);14431444if (ossl_list_uint_set_is_empty(&h->set))1445return 0;14461447/*1448* The second condition here establishes that the highest PN range in our RX1449* history comprises only a single PN. If there is more than one, then this1450* function will have returned 1 during a previous call to1451* ossl_ackm_on_rx_packet assuming the third condition below was met. Thus1452* we only return 1 when the missing PN condition is newly established.1453*1454* The third condition here establishes that the highest PN range in our RX1455* history is beyond (and does not border) the highest PN we have yet1456* reported in any ACK frame. Thus there is a gap of at least one PN between1457* the PNs we have ACK'd previously and the PN we have just received.1458*/1459return ackm->ack[pkt_space].num_ack_ranges > 01460&& ossl_list_uint_set_tail(&h->set)->range.start1461== ossl_list_uint_set_tail(&h->set)->range.end1462&& ossl_list_uint_set_tail(&h->set)->range.start1463> ackm->ack[pkt_space].ack_ranges[0].end + 1;1464}14651466static void ackm_set_flush_deadline(OSSL_ACKM *ackm, int pkt_space,1467OSSL_TIME deadline)1468{1469ackm->rx_ack_flush_deadline[pkt_space] = deadline;14701471if (ackm->ack_deadline_cb != NULL)1472ackm->ack_deadline_cb(ossl_ackm_get_ack_deadline(ackm, pkt_space),1473pkt_space, ackm->ack_deadline_cb_arg);1474}14751476/* Explicitly flags that we want to generate an ACK frame. */1477static void ackm_queue_ack(OSSL_ACKM *ackm, int pkt_space)1478{1479ackm->rx_ack_desired[pkt_space] = 1;14801481/* Cancel deadline. */1482ackm_set_flush_deadline(ackm, pkt_space, ossl_time_infinite());1483}14841485static void ackm_on_rx_ack_eliciting(OSSL_ACKM *ackm,1486OSSL_TIME rx_time, int pkt_space,1487int was_missing)1488{1489OSSL_TIME tx_max_ack_delay;14901491if (ackm->rx_ack_desired[pkt_space])1492/* ACK generation already requested so nothing to do. */1493return;14941495++ackm->rx_ack_eliciting_pkts_since_last_ack[pkt_space];14961497if (!ackm->rx_ack_generated[pkt_space]1498|| was_missing1499|| ackm->rx_ack_eliciting_pkts_since_last_ack[pkt_space]1500>= PKTS_BEFORE_ACK1501|| ackm_has_newly_missing(ackm, pkt_space)) {1502/*1503* Either:1504*1505* - We have never yet generated an ACK frame, meaning that this1506* is the first ever packet received, which we should always1507* acknowledge immediately, or1508*1509* - We previously reported the PN that we have just received as1510* missing in a previous ACK frame (meaning that we should report1511* the fact that we now have it to the peer immediately), or1512*1513* - We have exceeded the ACK-eliciting packet threshold count1514* for the purposes of ACK coalescing, so request transmission1515* of an ACK frame, or1516*1517* - The PN we just received and added to our PN RX history1518* newly implies one or more missing PNs, in which case we should1519* inform the peer by sending an ACK frame immediately.1520*1521* We do not test the ACK flush deadline here because it is tested1522* separately in ossl_ackm_is_ack_desired.1523*/1524ackm_queue_ack(ackm, pkt_space);1525return;1526}15271528/*1529* Not emitting an ACK yet.1530*1531* Update the ACK flush deadline.1532*1533* RFC 9000 s. 13.2.1: "An endpoint MUST acknowledge all ack-eliciting1534* Initial and Handshake packets immediately"; don't delay ACK generation if1535* we are using the Initial or Handshake PN spaces.1536*/1537tx_max_ack_delay = ackm->tx_max_ack_delay;1538if (pkt_space == QUIC_PN_SPACE_INITIAL1539|| pkt_space == QUIC_PN_SPACE_HANDSHAKE)1540tx_max_ack_delay = ossl_time_zero();15411542if (ossl_time_is_infinite(ackm->rx_ack_flush_deadline[pkt_space]))1543ackm_set_flush_deadline(ackm, pkt_space,1544ossl_time_add(rx_time, tx_max_ack_delay));1545else1546ackm_set_flush_deadline(ackm, pkt_space,1547ossl_time_min(ackm->rx_ack_flush_deadline[pkt_space],1548ossl_time_add(rx_time,1549tx_max_ack_delay)));1550}15511552int ossl_ackm_on_rx_packet(OSSL_ACKM *ackm, const OSSL_ACKM_RX_PKT *pkt)1553{1554struct rx_pkt_history_st *h = get_rx_history(ackm, pkt->pkt_space);1555int was_missing;15561557if (ossl_ackm_is_rx_pn_processable(ackm, pkt->pkt_num, pkt->pkt_space) != 1)1558/* PN has already been processed or written off, no-op. */1559return 1;15601561/*1562* Record the largest PN we have RX'd and the time we received it.1563* We use this to calculate the ACK delay field of ACK frames.1564*/1565if (pkt->pkt_num > ackm->rx_largest_pn[pkt->pkt_space]) {1566ackm->rx_largest_pn[pkt->pkt_space] = pkt->pkt_num;1567ackm->rx_largest_time[pkt->pkt_space] = pkt->time;1568}15691570/*1571* If the PN we just received was previously implied missing by virtue of1572* being omitted from a previous ACK frame generated, we skip any packet1573* count thresholds or coalescing delays and emit a new ACK frame1574* immediately.1575*/1576was_missing = ackm_is_missing(ackm, pkt->pkt_space, pkt->pkt_num);15771578/*1579* Add the packet number to our history list of PNs we have not yet provably1580* acked.1581*/1582if (rx_pkt_history_add_pn(h, pkt->pkt_num) != 1)1583return 0;15841585/*1586* Receiving this packet may or may not cause us to emit an ACK frame.1587* We may not emit an ACK frame yet if we have not yet received a threshold1588* number of packets.1589*/1590if (pkt->is_ack_eliciting)1591ackm_on_rx_ack_eliciting(ackm, pkt->time, pkt->pkt_space, was_missing);15921593/* Update the ECN counters according to which ECN signal we got, if any. */1594switch (pkt->ecn) {1595case OSSL_ACKM_ECN_ECT0:1596++ackm->rx_ect0[pkt->pkt_space];1597break;1598case OSSL_ACKM_ECN_ECT1:1599++ackm->rx_ect1[pkt->pkt_space];1600break;1601case OSSL_ACKM_ECN_ECNCE:1602++ackm->rx_ecnce[pkt->pkt_space];1603break;1604default:1605break;1606}16071608return 1;1609}16101611static void ackm_fill_rx_ack_ranges(OSSL_ACKM *ackm, int pkt_space,1612OSSL_QUIC_FRAME_ACK *ack)1613{1614struct rx_pkt_history_st *h = get_rx_history(ackm, pkt_space);1615UINT_SET_ITEM *x;1616size_t i = 0;16171618/*1619* Copy out ranges from the PN set, starting at the end, until we reach our1620* maximum number of ranges.1621*/1622for (x = ossl_list_uint_set_tail(&h->set);1623x != NULL && i < OSSL_NELEM(ackm->ack_ranges);1624x = ossl_list_uint_set_prev(x), ++i) {1625ackm->ack_ranges[pkt_space][i].start = x->range.start;1626ackm->ack_ranges[pkt_space][i].end = x->range.end;1627}16281629ack->ack_ranges = ackm->ack_ranges[pkt_space];1630ack->num_ack_ranges = i;1631}16321633const OSSL_QUIC_FRAME_ACK *ossl_ackm_get_ack_frame(OSSL_ACKM *ackm,1634int pkt_space)1635{1636OSSL_QUIC_FRAME_ACK *ack = &ackm->ack[pkt_space];1637OSSL_TIME now = ackm->now(ackm->now_arg);16381639ackm_fill_rx_ack_ranges(ackm, pkt_space, ack);16401641if (!ossl_time_is_zero(ackm->rx_largest_time[pkt_space])1642&& ossl_time_compare(now, ackm->rx_largest_time[pkt_space]) > 01643&& pkt_space == QUIC_PN_SPACE_APP)1644ack->delay_time = ossl_time_subtract(now, ackm->rx_largest_time[pkt_space]);1645else1646ack->delay_time = ossl_time_zero();16471648ack->ect0 = ackm->rx_ect0[pkt_space];1649ack->ect1 = ackm->rx_ect1[pkt_space];1650ack->ecnce = ackm->rx_ecnce[pkt_space];1651ack->ecn_present = 1;16521653ackm->rx_ack_eliciting_pkts_since_last_ack[pkt_space] = 0;16541655ackm->rx_ack_generated[pkt_space] = 1;1656ackm->rx_ack_desired[pkt_space] = 0;1657ackm_set_flush_deadline(ackm, pkt_space, ossl_time_infinite());1658return ack;1659}16601661OSSL_TIME ossl_ackm_get_ack_deadline(OSSL_ACKM *ackm, int pkt_space)1662{1663if (ackm->rx_ack_desired[pkt_space])1664/* Already desired, deadline is now. */1665return ossl_time_zero();16661667return ackm->rx_ack_flush_deadline[pkt_space];1668}16691670int ossl_ackm_is_rx_pn_processable(OSSL_ACKM *ackm, QUIC_PN pn, int pkt_space)1671{1672struct rx_pkt_history_st *h = get_rx_history(ackm, pkt_space);16731674return pn >= h->watermark && ossl_uint_set_query(&h->set, pn) == 0;1675}16761677void ossl_ackm_set_loss_detection_deadline_callback(OSSL_ACKM *ackm,1678void (*fn)(OSSL_TIME deadline,1679void *arg),1680void *arg)1681{1682ackm->loss_detection_deadline_cb = fn;1683ackm->loss_detection_deadline_cb_arg = arg;1684}16851686void ossl_ackm_set_ack_deadline_callback(OSSL_ACKM *ackm,1687void (*fn)(OSSL_TIME deadline,1688int pkt_space,1689void *arg),1690void *arg)1691{1692ackm->ack_deadline_cb = fn;1693ackm->ack_deadline_cb_arg = arg;1694}16951696int ossl_ackm_mark_packet_pseudo_lost(OSSL_ACKM *ackm,1697int pkt_space, QUIC_PN pn)1698{1699struct tx_pkt_history_st *h = get_tx_history(ackm, pkt_space);1700OSSL_ACKM_TX_PKT *pkt;17011702pkt = tx_pkt_history_by_pkt_num(h, pn);1703if (pkt == NULL)1704return 0;17051706tx_pkt_history_remove(h, pkt->pkt_num);1707pkt->lnext = NULL;1708ackm_on_pkts_lost(ackm, pkt_space, pkt, /*pseudo=*/1);1709return 1;1710}17111712OSSL_TIME ossl_ackm_get_pto_duration(OSSL_ACKM *ackm)1713{1714OSSL_TIME duration;1715OSSL_RTT_INFO rtt;17161717ossl_statm_get_rtt_info(ackm->statm, &rtt);17181719duration = ossl_time_add(rtt.smoothed_rtt,1720ossl_time_max(ossl_time_multiply(rtt.rtt_variance, 4),1721ossl_ticks2time(K_GRANULARITY)));1722if (!ossl_time_is_infinite(ackm->rx_max_ack_delay))1723duration = ossl_time_add(duration, ackm->rx_max_ack_delay);17241725return duration;1726}17271728QUIC_PN ossl_ackm_get_largest_acked(OSSL_ACKM *ackm, int pkt_space)1729{1730return ackm->largest_acked_pkt[pkt_space];1731}17321733void ossl_ackm_set_rx_max_ack_delay(OSSL_ACKM *ackm, OSSL_TIME rx_max_ack_delay)1734{1735ackm->rx_max_ack_delay = rx_max_ack_delay;1736}17371738void ossl_ackm_set_tx_max_ack_delay(OSSL_ACKM *ackm, OSSL_TIME tx_max_ack_delay)1739{1740ackm->tx_max_ack_delay = tx_max_ack_delay;1741}174217431744