Path: blob/main/crypto/openssl/ssl/quic/quic_ackm.c
48261 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) packets;3334/*35* Mapping from packet numbers (uint64_t) to (OSSL_ACKM_TX_PKT *)36*37* Invariant: A packet is in this map if and only if it is in the linked38* list.39*/40LHASH_OF(OSSL_ACKM_TX_PKT) *map;4142/*43* The lowest packet number which may currently be added to the history list44* (inclusive). We do not allow packet numbers to be added to the history45* list non-monotonically, so packet numbers must be greater than or equal46* to this value.47*/48uint64_t watermark;4950/*51* Packet number of the highest packet info structure we have yet appended52* to the list. This is usually one less than watermark, except when we have53* not added any packet yet.54*/55uint64_t highest_sent;56};5758DEFINE_LHASH_OF_EX(OSSL_ACKM_TX_PKT);5960static unsigned long tx_pkt_info_hash(const OSSL_ACKM_TX_PKT *pkt)61{62/* Using low bits of the packet number as the hash should be enough */63return (unsigned long)pkt->pkt_num;64}6566static int tx_pkt_info_compare(const OSSL_ACKM_TX_PKT *a,67const OSSL_ACKM_TX_PKT *b)68{69if (a->pkt_num < b->pkt_num)70return -1;71if (a->pkt_num > b->pkt_num)72return 1;73return 0;74}7576static int77tx_pkt_history_init(struct tx_pkt_history_st *h)78{79ossl_list_tx_history_init(&h->packets);80h->watermark = 0;81h->highest_sent = 0;8283h->map = lh_OSSL_ACKM_TX_PKT_new(tx_pkt_info_hash, tx_pkt_info_compare);84if (h->map == NULL)85return 0;8687return 1;88}8990static void91tx_pkt_history_destroy(struct tx_pkt_history_st *h)92{93lh_OSSL_ACKM_TX_PKT_free(h->map);94h->map = NULL;95ossl_list_tx_history_init(&h->packets);96}9798static int99tx_pkt_history_add_actual(struct tx_pkt_history_st *h,100OSSL_ACKM_TX_PKT *pkt)101{102OSSL_ACKM_TX_PKT *existing;103104/*105* There should not be any existing packet with this number106* in our mapping.107*/108existing = lh_OSSL_ACKM_TX_PKT_retrieve(h->map, pkt);109if (!ossl_assert(existing == NULL))110return 0;111112/* Should not already be in a list. */113if (!ossl_assert(ossl_list_tx_history_next(pkt) == NULL114&& ossl_list_tx_history_prev(pkt) == NULL))115return 0;116117lh_OSSL_ACKM_TX_PKT_insert(h->map, pkt);118119ossl_list_tx_history_insert_tail(&h->packets, pkt);120return 1;121}122123/* Adds a packet information structure to the history list. */124static int125tx_pkt_history_add(struct tx_pkt_history_st *h,126OSSL_ACKM_TX_PKT *pkt)127{128if (!ossl_assert(pkt->pkt_num >= h->watermark))129return 0;130131if (tx_pkt_history_add_actual(h, pkt) < 1)132return 0;133134h->watermark = pkt->pkt_num + 1;135h->highest_sent = pkt->pkt_num;136return 1;137}138139/* Retrieve a packet information structure by packet number. */140static OSSL_ACKM_TX_PKT *141tx_pkt_history_by_pkt_num(struct tx_pkt_history_st *h, uint64_t pkt_num)142{143OSSL_ACKM_TX_PKT key;144145key.pkt_num = pkt_num;146147return lh_OSSL_ACKM_TX_PKT_retrieve(h->map, &key);148}149150/* Remove a packet information structure from the history log. */151static int152tx_pkt_history_remove(struct tx_pkt_history_st *h, uint64_t pkt_num)153{154OSSL_ACKM_TX_PKT key, *pkt;155key.pkt_num = pkt_num;156157pkt = tx_pkt_history_by_pkt_num(h, pkt_num);158if (pkt == NULL)159return 0;160161ossl_list_tx_history_remove(&h->packets, pkt);162lh_OSSL_ACKM_TX_PKT_delete(h->map, &key);163return 1;164}165166/*167* RX Packet Number Tracking168* *************************169*170* **Background.** The RX side of the ACK manager must track packets we have171* received for which we have to generate ACK frames. Broadly, this means we172* store a set of packet numbers which we have received but which we do not know173* for a fact that the transmitter knows we have received.174*175* This must handle various situations:176*177* 1. We receive a packet but have not sent an ACK yet, so the transmitter178* does not know whether we have received it or not yet.179*180* 2. We receive a packet and send an ACK which is lost. We do not181* immediately know that the ACK was lost and the transmitter does not know182* that we have received the packet.183*184* 3. We receive a packet and send an ACK which is received by the185* transmitter. The transmitter does not immediately respond with an ACK,186* or responds with an ACK which is lost. The transmitter knows that we187* have received the packet, but we do not know for sure that it knows,188* because the ACK we sent could have been lost.189*190* 4. We receive a packet and send an ACK which is received by the191* transmitter. The transmitter subsequently sends us an ACK which confirms192* its receipt of the ACK we sent, and we successfully receive that ACK, so193* we know that the transmitter knows, that we received the original194* packet.195*196* Only when we reach case (4) are we relieved of any need to track a given197* packet number we have received, because only in this case do we know for sure198* that the peer knows we have received the packet. Having reached case (4) we199* will never again need to generate an ACK containing the PN in question, but200* until we reach that point, we must keep track of the PN as not having been201* provably ACKed, as we may have to keep generating ACKs for the given PN not202* just until the transmitter receives one, but until we know that it has203* received one. This will be referred to herein as "provably ACKed".204*205* **Duplicate handling.** The above discusses the case where we have received a206* packet with a given PN but are at best unsure whether the sender knows we207* have received it or not. However, we must also handle the case where we have208* yet to receive a packet with a given PN in the first place. The reason for209* this is because of the requirement expressed by RFC 9000 s. 12.3:210*211* "A receiver MUST discard a newly unprotected packet unless it is certain212* that it has not processed another packet with the same packet number from213* the same packet number space."214*215* We must ensure we never process a duplicate PN. As such, each possible PN we216* can receive must exist in one of the following logical states:217*218* - We have never processed this PN before219* (so if we receive such a PN, it can be processed)220*221* - We have processed this PN but it has not yet been provably ACKed222* (and should therefore be in any future ACK frame generated;223* if we receive such a PN again, it must be ignored)224*225* - We have processed this PN and it has been provably ACKed226* (if we receive such a PN again, it must be ignored)227*228* However, if we were to track this state for every PN ever used in the history229* of a connection, the amount of state required would increase unboundedly as230* the connection goes on (for example, we would have to store a set of every PN231* ever received.)232*233* RFC 9000 s. 12.3 continues:234*235* "Endpoints that track all individual packets for the purposes of detecting236* duplicates are at risk of accumulating excessive state. The data required237* for detecting duplicates can be limited by maintaining a minimum packet238* number below which all packets are immediately dropped."239*240* Moreover, RFC 9000 s. 13.2.3 states that:241*242* "A receiver MUST retain an ACK Range unless it can ensure that it will not243* subsequently accept packets with numbers in that range. Maintaining a244* minimum packet number that increases as ranges are discarded is one way to245* achieve this with minimal state."246*247* This touches on a subtlety of the original requirement quoted above: the248* receiver MUST discard a packet unless it is certain that it has not processed249* another packet with the same PN. However, this does not forbid the receiver250* from also discarding some PNs even though it has not yet processed them. In251* other words, implementations must be conservative and err in the direction of252* assuming a packet is a duplicate, but it is acceptable for this to come at253* the cost of falsely identifying some packets as duplicates.254*255* This allows us to bound the amount of state we must keep, and we adopt the256* suggested strategy quoted above to do so. We define a watermark PN below257* which all PNs are in the same state. This watermark is only ever increased.258* Thus the PNs the state for which needs to be explicitly tracked is limited to259* only a small number of recent PNs, and all older PNs have an assumed state.260*261* Any given PN thus falls into one of the following states:262*263* - (A) The PN is above the watermark but we have not yet received it.264*265* If we receive such a PN, we should process it and record the PN as266* received.267*268* - (B) The PN is above the watermark and we have received it.269*270* The PN should be included in any future ACK frame we generate.271* If we receive such a PN again, we should ignore it.272*273* - (C) The PN is below the watermark.274*275* We do not know whether a packet with the given PN was received or276* not. To be safe, if we receive such a packet, it is not processed.277*278* Note that state (C) corresponds to both "we have processed this PN and it has279* been provably ACKed" logical state and a subset of the PNs in the "we have280* never processed this PN before" logical state (namely all PNs which were lost281* and never received, but which are not recent enough to be above the282* watermark). The reason we can merge these states and avoid tracking states283* for the PNs in this state is because the provably ACKed and never-received284* states are functionally identical in terms of how we need to handle them: we285* don't need to do anything for PNs in either of these states, so we don't have286* to care about PNs in this state nor do we have to care about distinguishing287* the two states for a given PN.288*289* Note that under this scheme provably ACKed PNs are by definition always below290* the watermark; therefore, it follows that when a PN becomes provably ACKed,291* the watermark must be immediately increased to exceed it (otherwise we would292* keep reporting it in future ACK frames).293*294* This is in line with RFC 9000 s. 13.2.4's suggested strategy on when295* to advance the watermark:296*297* "When a packet containing an ACK frame is sent, the Largest Acknowledged298* field in that frame can be saved. When a packet containing an ACK frame is299* acknowledged, the receiver can stop acknowledging packets less than or300* equal to the Largest Acknowledged field in the sent ACK frame."301*302* This is where our scheme's false positives arise. When a packet containing an303* ACK frame is itself ACK'd, PNs referenced in that ACK frame become provably304* acked, and the watermark is bumped accordingly. However, the Largest305* Acknowledged field does not imply that all lower PNs have been received,306* because there may be gaps expressed in the ranges of PNs expressed by that307* and previous ACK frames. Thus, some unreceived PNs may be moved below the308* watermark, and we may subsequently reject those PNs as possibly being309* duplicates even though we have not actually received those PNs. Since we bump310* the watermark when a PN becomes provably ACKed, it follows that an unreceived311* PN falls below the watermark (and thus becomes a false positive for the312* purposes of duplicate detection) when a higher-numbered PN becomes provably313* ACKed.314*315* Thus, when PN n becomes provably acked, any unreceived PNs in the range [0,316* n) will no longer be processed. Although datagrams may be reordered in the317* network, a PN we receive can only become provably ACKed after our own318* subsequently generated ACK frame is sent in a future TX packet, and then we319* receive another RX PN acknowledging that TX packet. This means that a given RX320* PN can only become provably ACKed at least 1 RTT after it is received; it is321* unlikely that any reordered datagrams will still be "in the network" (and not322* lost) by this time. If this does occur for whatever reason and a late PN is323* received, the packet will be discarded unprocessed and the PN is simply324* handled as though lost (a "written off" PN).325*326* **Data structure.** Our state for the RX handling side of the ACK manager, as327* discussed above, mainly comprises:328*329* a) a logical set of PNs, and330* b) a monotonically increasing PN counter (the watermark).331*332* For (a), we define a data structure which stores a logical set of PNs, which333* we use to keep track of which PNs we have received but which have not yet334* been provably ACKed, and thus will later need to generate an ACK frame for.335*336* The correspondence with the logical states discussed above is as follows. A337* PN is in state (C) if it is below the watermark; otherwise it is in state (B)338* if it is in the logical set of PNs, and in state (A) otherwise.339*340* Note that PNs are only removed from the PN set (when they become provably341* ACKed or written off) by virtue of advancement of the watermark. Removing PNs342* from the PN set any other way would be ambiguous as it would be343* indistinguishable from a PN we have not yet received and risk us processing a344* duplicate packet. In other words, for a given PN:345*346* - State (A) can transition to state (B) or (C)347* - State (B) can transition to state (C) only348* - State (C) is the terminal state349*350* We can query the logical set data structure for PNs which have been received351* but which have not been provably ACKed when we want to generate ACK frames.352* Since ACK frames can be lost and/or we might not know that the peer has353* successfully received them, we might generate multiple ACK frames covering a354* given PN until that PN becomes provably ACKed and we finally remove it from355* our set (by bumping the watermark) as no longer being our concern.356*357* The data structure used is the UINT_SET structure defined in uint_set.h,358* which is used as a PN set. We use the following operations of the structure:359*360* Insert Range: Used when we receive a new PN.361*362* Remove Range: Used when bumping the watermark.363*364* Query: Used to determine if a PN is in the set.365*366* **Possible duplicates.** A PN is considered a possible duplicate when either:367*368* a) its PN is already in the PN set (i.e. has already been received), or369* b) its PN is below the watermark (i.e. was provably ACKed or written off).370*371* A packet with a given PN is considered 'processable' when that PN is not372* considered a possible duplicate (see ossl_ackm_is_rx_pn_processable).373*374* **TX/RX interaction.** The watermark is bumped whenever an RX packet becomes375* provably ACKed. This occurs when an ACK frame is received by the TX side of376* the ACK manager; thus, there is necessary interaction between the TX and RX377* sides of the ACK manager.378*379* This is implemented as follows. When a packet is queued as sent in the TX380* side of the ACK manager, it may optionally have a Largest Acked value set on381* it. The user of the ACK manager should do this if the packet being382* transmitted contains an ACK frame, by setting the field to the Largest Acked383* field of that frame. Otherwise, this field should be set to QUIC_PN_INVALID.384* When a TX packet is eventually acknowledged which has this field set, it is385* used to update the state of the RX side of the ACK manager by bumping the386* watermark accordingly.387*/388struct rx_pkt_history_st {389UINT_SET set;390391/*392* Invariant: PNs below this are not in the set.393* Invariant: This is monotonic and only ever increases.394*/395QUIC_PN watermark;396};397398static int rx_pkt_history_bump_watermark(struct rx_pkt_history_st *h,399QUIC_PN watermark);400401static void rx_pkt_history_init(struct rx_pkt_history_st *h)402{403ossl_uint_set_init(&h->set);404h->watermark = 0;405}406407static void rx_pkt_history_destroy(struct rx_pkt_history_st *h)408{409ossl_uint_set_destroy(&h->set);410}411412/*413* Limit the number of ACK ranges we store to prevent resource consumption DoS414* attacks.415*/416#define MAX_RX_ACK_RANGES 32417418static void rx_pkt_history_trim_range_count(struct rx_pkt_history_st *h)419{420QUIC_PN highest = QUIC_PN_INVALID;421422while (ossl_list_uint_set_num(&h->set) > MAX_RX_ACK_RANGES) {423UINT_RANGE r = ossl_list_uint_set_head(&h->set)->range;424425highest = (highest == QUIC_PN_INVALID)426? r.end : ossl_quic_pn_max(highest, r.end);427428ossl_uint_set_remove(&h->set, &r);429}430431/*432* Bump watermark to cover all PNs we removed to avoid accidental433* reprocessing of packets.434*/435if (highest != QUIC_PN_INVALID)436rx_pkt_history_bump_watermark(h, highest + 1);437}438439static int rx_pkt_history_add_pn(struct rx_pkt_history_st *h,440QUIC_PN pn)441{442UINT_RANGE r;443444r.start = pn;445r.end = pn;446447if (pn < h->watermark)448return 1; /* consider this a success case */449450if (ossl_uint_set_insert(&h->set, &r) != 1)451return 0;452453rx_pkt_history_trim_range_count(h);454return 1;455}456457static int rx_pkt_history_bump_watermark(struct rx_pkt_history_st *h,458QUIC_PN watermark)459{460UINT_RANGE r;461462if (watermark <= h->watermark)463return 1;464465/* Remove existing PNs below the watermark. */466r.start = 0;467r.end = watermark - 1;468if (ossl_uint_set_remove(&h->set, &r) != 1)469return 0;470471h->watermark = watermark;472return 1;473}474475/*476* ACK Manager Implementation477* **************************478* Implementation of the ACK manager proper.479*/480481/* Constants used by the ACK manager; see RFC 9002. */482#define K_GRANULARITY (1 * OSSL_TIME_MS)483#define K_PKT_THRESHOLD 3484#define K_TIME_THRESHOLD_NUM 9485#define K_TIME_THRESHOLD_DEN 8486487/* The maximum number of times we allow PTO to be doubled. */488#define MAX_PTO_COUNT 16489490/* Default maximum amount of time to leave an ACK-eliciting packet un-ACK'd. */491#define DEFAULT_TX_MAX_ACK_DELAY ossl_ms2time(QUIC_DEFAULT_MAX_ACK_DELAY)492493struct ossl_ackm_st {494/* Our list of transmitted packets. Corresponds to RFC 9002 sent_packets. */495struct tx_pkt_history_st tx_history[QUIC_PN_SPACE_NUM];496497/* Our list of received PNs which are not yet provably acked. */498struct rx_pkt_history_st rx_history[QUIC_PN_SPACE_NUM];499500/* Polymorphic dependencies that we consume. */501OSSL_TIME (*now)(void *arg);502void *now_arg;503OSSL_STATM *statm;504const OSSL_CC_METHOD *cc_method;505OSSL_CC_DATA *cc_data;506507/* RFC 9002 variables. */508uint32_t pto_count;509QUIC_PN largest_acked_pkt[QUIC_PN_SPACE_NUM];510OSSL_TIME time_of_last_ack_eliciting_pkt[QUIC_PN_SPACE_NUM];511OSSL_TIME loss_time[QUIC_PN_SPACE_NUM];512OSSL_TIME loss_detection_deadline;513514/* Lowest PN which is still not known to be ACKed. */515QUIC_PN lowest_unacked_pkt[QUIC_PN_SPACE_NUM];516517/* Time at which we got our first RTT sample, or 0. */518OSSL_TIME first_rtt_sample;519520/*521* A packet's num_bytes are added to this if it is inflight,522* and removed again once ack'd/lost/discarded.523*/524uint64_t bytes_in_flight;525526/*527* A packet's num_bytes are added to this if it is both inflight and528* ack-eliciting, and removed again once ack'd/lost/discarded.529*/530uint64_t ack_eliciting_bytes_in_flight[QUIC_PN_SPACE_NUM];531532/* Count of ECN-CE events. */533uint64_t peer_ecnce[QUIC_PN_SPACE_NUM];534535/* Set to 1 when the handshake is confirmed. */536char handshake_confirmed;537538/* Set to 1 when attached to server channel */539char is_server;540541/* Set to 1 when the peer has completed address validation. */542char peer_completed_addr_validation;543544/* Set to 1 when a PN space has been discarded. */545char discarded[QUIC_PN_SPACE_NUM];546547/* Set to 1 when we think an ACK frame should be generated. */548char rx_ack_desired[QUIC_PN_SPACE_NUM];549550/* Set to 1 if an ACK frame has ever been generated. */551char rx_ack_generated[QUIC_PN_SPACE_NUM];552553/* Probe request counts for reporting to the user. */554OSSL_ACKM_PROBE_INFO pending_probe;555556/* Generated ACK frames for each PN space. */557OSSL_QUIC_FRAME_ACK ack[QUIC_PN_SPACE_NUM];558OSSL_QUIC_ACK_RANGE ack_ranges[QUIC_PN_SPACE_NUM][MAX_RX_ACK_RANGES];559560/* Other RX state. */561/* Largest PN we have RX'd. */562QUIC_PN rx_largest_pn[QUIC_PN_SPACE_NUM];563564/* Time at which the PN in rx_largest_pn was RX'd. */565OSSL_TIME rx_largest_time[QUIC_PN_SPACE_NUM];566567/*568* ECN event counters. Each time we receive a packet with a given ECN label,569* the corresponding ECN counter here is incremented.570*/571uint64_t rx_ect0[QUIC_PN_SPACE_NUM];572uint64_t rx_ect1[QUIC_PN_SPACE_NUM];573uint64_t rx_ecnce[QUIC_PN_SPACE_NUM];574575/*576* Number of ACK-eliciting packets since last ACK. We use this to defer577* emitting ACK frames until a threshold number of ACK-eliciting packets578* have been received.579*/580uint32_t rx_ack_eliciting_pkts_since_last_ack[QUIC_PN_SPACE_NUM];581582/*583* The ACK frame coalescing deadline at which we should flush any unsent ACK584* frames.585*/586OSSL_TIME rx_ack_flush_deadline[QUIC_PN_SPACE_NUM];587588/*589* The RX maximum ACK delay (the maximum amount of time our peer might590* wait to send us an ACK after receiving an ACK-eliciting packet).591*/592OSSL_TIME rx_max_ack_delay;593594/*595* The TX maximum ACK delay (the maximum amount of time we allow ourselves596* to wait before generating an ACK after receiving an ACK-eliciting597* packet).598*/599OSSL_TIME tx_max_ack_delay;600601/* Callbacks for deadline updates. */602void (*loss_detection_deadline_cb)(OSSL_TIME deadline, void *arg);603void *loss_detection_deadline_cb_arg;604605void (*ack_deadline_cb)(OSSL_TIME deadline, int pkt_space, void *arg);606void *ack_deadline_cb_arg;607};608609static ossl_inline uint32_t min_u32(uint32_t x, uint32_t y)610{611return x < y ? x : y;612}613614/*615* Get TX history for a given packet number space. Must not have been616* discarded.617*/618static struct tx_pkt_history_st *get_tx_history(OSSL_ACKM *ackm, int pkt_space)619{620assert(!ackm->discarded[pkt_space]);621622return &ackm->tx_history[pkt_space];623}624625/*626* Get RX history for a given packet number space. Must not have been627* discarded.628*/629static struct rx_pkt_history_st *get_rx_history(OSSL_ACKM *ackm, int pkt_space)630{631assert(!ackm->discarded[pkt_space]);632633return &ackm->rx_history[pkt_space];634}635636/* Does the newly-acknowledged list contain any ack-eliciting packet? */637static int ack_includes_ack_eliciting(OSSL_ACKM_TX_PKT *pkt)638{639for (; pkt != NULL; pkt = pkt->anext)640if (pkt->is_ack_eliciting)641return 1;642643return 0;644}645646/* Return number of ACK-eliciting bytes in flight across all PN spaces. */647static uint64_t ackm_ack_eliciting_bytes_in_flight(OSSL_ACKM *ackm)648{649int i;650uint64_t total = 0;651652for (i = 0; i < QUIC_PN_SPACE_NUM; ++i)653total += ackm->ack_eliciting_bytes_in_flight[i];654655return total;656}657658/* Return 1 if the range contains the given PN. */659static int range_contains(const OSSL_QUIC_ACK_RANGE *range, QUIC_PN pn)660{661return pn >= range->start && pn <= range->end;662}663664/*665* Given a logical representation of an ACK frame 'ack', create a singly-linked666* list of the newly ACK'd frames; that is, of frames which are matched by the667* list of PN ranges contained in the ACK frame. The packet structures in the668* list returned are removed from the TX history list. Returns a pointer to the669* list head (or NULL) if empty.670*/671static OSSL_ACKM_TX_PKT *ackm_detect_and_remove_newly_acked_pkts(OSSL_ACKM *ackm,672const OSSL_QUIC_FRAME_ACK *ack,673int pkt_space)674{675OSSL_ACKM_TX_PKT *acked_pkts = NULL, **fixup = &acked_pkts, *pkt, *pprev;676struct tx_pkt_history_st *h;677size_t ridx = 0;678679assert(ack->num_ack_ranges > 0);680681/*682* Our history list is a list of packets sorted in ascending order683* by packet number.684*685* ack->ack_ranges is a list of packet number ranges in descending order.686*687* Walk through our history list from the end in order to efficiently detect688* membership in the specified ack ranges. As an optimization, we use our689* hashtable to try and skip to the first matching packet. This may fail if690* the ACK ranges given include nonexistent packets.691*/692h = get_tx_history(ackm, pkt_space);693694pkt = tx_pkt_history_by_pkt_num(h, ack->ack_ranges[0].end);695if (pkt == NULL)696pkt = ossl_list_tx_history_tail(&h->packets);697698for (; pkt != NULL; pkt = pprev) {699/*700* Save prev value as it will be zeroed if we remove the packet from the701* history list below.702*/703pprev = ossl_list_tx_history_prev(pkt);704705for (;; ++ridx) {706if (ridx >= ack->num_ack_ranges) {707/*708* We have exhausted all ranges so stop here, even if there are709* more packets to look at.710*/711goto stop;712}713714if (range_contains(&ack->ack_ranges[ridx], pkt->pkt_num)) {715/* We have matched this range. */716tx_pkt_history_remove(h, pkt->pkt_num);717718*fixup = pkt;719fixup = &pkt->anext;720*fixup = NULL;721break;722} else if (pkt->pkt_num > ack->ack_ranges[ridx].end) {723/*724* We have not reached this range yet in our list, so do not725* advance ridx.726*/727break;728} else {729/*730* We have moved beyond this range, so advance to the next range731* and try matching again.732*/733assert(pkt->pkt_num < ack->ack_ranges[ridx].start);734continue;735}736}737}738stop:739740return acked_pkts;741}742743/*744* Create a singly-linked list of newly detected-lost packets in the given745* packet number space. Returns the head of the list or NULL if no packets were746* detected lost. The packets in the list are removed from the TX history list.747*/748static OSSL_ACKM_TX_PKT *ackm_detect_and_remove_lost_pkts(OSSL_ACKM *ackm,749int pkt_space)750{751OSSL_ACKM_TX_PKT *lost_pkts = NULL, **fixup = &lost_pkts, *pkt, *pnext;752OSSL_TIME loss_delay, lost_send_time, now;753OSSL_RTT_INFO rtt;754struct tx_pkt_history_st *h;755756assert(ackm->largest_acked_pkt[pkt_space] != QUIC_PN_INVALID);757758ossl_statm_get_rtt_info(ackm->statm, &rtt);759760ackm->loss_time[pkt_space] = ossl_time_zero();761762loss_delay = ossl_time_multiply(ossl_time_max(rtt.latest_rtt,763rtt.smoothed_rtt),764K_TIME_THRESHOLD_NUM);765loss_delay = ossl_time_divide(loss_delay, K_TIME_THRESHOLD_DEN);766767/* Minimum time of K_GRANULARITY before packets are deemed lost. */768loss_delay = ossl_time_max(loss_delay, ossl_ticks2time(K_GRANULARITY));769770/* Packets sent before this time are deemed lost. */771now = ackm->now(ackm->now_arg);772lost_send_time = ossl_time_subtract(now, loss_delay);773774h = get_tx_history(ackm, pkt_space);775pkt = ossl_list_tx_history_head(&h->packets);776777for (; pkt != NULL; pkt = pnext) {778assert(pkt_space == pkt->pkt_space);779780/*781* Save prev value as it will be zeroed if we remove the packet from the782* history list below.783*/784pnext = ossl_list_tx_history_next(pkt);785786if (pkt->pkt_num > ackm->largest_acked_pkt[pkt_space])787continue;788789/*790* Mark packet as lost, or set time when it should be marked.791*/792if (ossl_time_compare(pkt->time, lost_send_time) <= 0793|| ackm->largest_acked_pkt[pkt_space]794>= pkt->pkt_num + K_PKT_THRESHOLD) {795tx_pkt_history_remove(h, pkt->pkt_num);796797*fixup = pkt;798fixup = &pkt->lnext;799*fixup = NULL;800} else {801if (ossl_time_is_zero(ackm->loss_time[pkt_space]))802ackm->loss_time[pkt_space] =803ossl_time_add(pkt->time, loss_delay);804else805ackm->loss_time[pkt_space] =806ossl_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 &&866(ackm->handshake_confirmed == 1 || ackm->is_server == 1))867continue;868869if (i == QUIC_PN_SPACE_APP) {870/* Skip application data until handshake confirmed. */871if (!ackm->handshake_confirmed)872break;873874/* Include max_ack_delay and backoff for app data. */875if (!ossl_time_is_infinite(ackm->rx_max_ack_delay)) {876uint64_t factor877= (uint64_t)1 << min_u32(ackm->pto_count, MAX_PTO_COUNT);878879duration880= ossl_time_add(duration,881ossl_time_multiply(ackm->rx_max_ack_delay,882factor));883}884}885886/*887* Only re-arm timer if stack has sent at least one ACK eliciting frame.888* If stack has sent no ACK eliciting frame at given encryption level then889* particular timer is zero and we must not attempt to set it. Timer keeps890* time since epoch (Jan 1 1970) and we must not set timer to past.891*/892if (!ossl_time_is_zero(ackm->time_of_last_ack_eliciting_pkt[i])) {893t = ossl_time_add(ackm->time_of_last_ack_eliciting_pkt[i], duration);894if (ossl_time_compare(t, pto_timeout) < 0) {895pto_timeout = t;896pto_space = i;897}898}899}900901*space = pto_space;902return pto_timeout;903}904905static void ackm_set_loss_detection_timer_actual(OSSL_ACKM *ackm,906OSSL_TIME deadline)907{908ackm->loss_detection_deadline = deadline;909910if (ackm->loss_detection_deadline_cb != NULL)911ackm->loss_detection_deadline_cb(deadline,912ackm->loss_detection_deadline_cb_arg);913}914915static int ackm_set_loss_detection_timer(OSSL_ACKM *ackm)916{917int space;918OSSL_TIME earliest_loss_time, timeout;919920earliest_loss_time = ackm_get_loss_time_and_space(ackm, &space);921if (!ossl_time_is_zero(earliest_loss_time)) {922/* Time threshold loss detection. */923ackm_set_loss_detection_timer_actual(ackm, earliest_loss_time);924return 1;925}926927if (ackm_ack_eliciting_bytes_in_flight(ackm) == 0928&& ackm->peer_completed_addr_validation) {929/*930* Nothing to detect lost, so no timer is set. However, the client931* needs to arm the timer if the server might be blocked by the932* anti-amplification limit.933*/934ackm_set_loss_detection_timer_actual(ackm, ossl_time_zero());935return 1;936}937938timeout = ackm_get_pto_time_and_space(ackm, &space);939ackm_set_loss_detection_timer_actual(ackm, timeout);940return 1;941}942943static int ackm_in_persistent_congestion(OSSL_ACKM *ackm,944const OSSL_ACKM_TX_PKT *lpkt)945{946/* TODO(QUIC FUTURE): Persistent congestion not currently implemented. */947return 0;948}949950static void ackm_on_pkts_lost(OSSL_ACKM *ackm, int pkt_space,951const OSSL_ACKM_TX_PKT *lpkt, int pseudo)952{953const OSSL_ACKM_TX_PKT *p, *pnext;954OSSL_RTT_INFO rtt;955QUIC_PN largest_pn_lost = 0;956OSSL_CC_LOSS_INFO loss_info = {0};957uint32_t flags = 0;958959for (p = lpkt; p != NULL; p = pnext) {960pnext = p->lnext;961962if (p->is_inflight) {963ackm->bytes_in_flight -= p->num_bytes;964if (p->is_ack_eliciting)965ackm->ack_eliciting_bytes_in_flight[p->pkt_space]966-= p->num_bytes;967968if (p->pkt_num > largest_pn_lost)969largest_pn_lost = p->pkt_num;970971if (!pseudo) {972/*973* If this is pseudo-loss (e.g. during connection retry) we do not974* inform the CC as it is not a real loss and not reflective of975* network conditions.976*/977loss_info.tx_time = p->time;978loss_info.tx_size = p->num_bytes;979980ackm->cc_method->on_data_lost(ackm->cc_data, &loss_info);981}982}983984p->on_lost(p->cb_arg);985}986987/*988* Persistent congestion can only be considered if we have gotten at least989* one RTT sample.990*/991ossl_statm_get_rtt_info(ackm->statm, &rtt);992if (!ossl_time_is_zero(ackm->first_rtt_sample)993&& ackm_in_persistent_congestion(ackm, lpkt))994flags |= OSSL_CC_LOST_FLAG_PERSISTENT_CONGESTION;995996ackm->cc_method->on_data_lost_finished(ackm->cc_data, flags);997}998999static void ackm_on_pkts_acked(OSSL_ACKM *ackm, const OSSL_ACKM_TX_PKT *apkt)1000{1001const OSSL_ACKM_TX_PKT *anext;1002QUIC_PN last_pn_acked = 0;1003OSSL_CC_ACK_INFO ainfo = {0};10041005for (; apkt != NULL; apkt = anext) {1006if (apkt->is_inflight) {1007ackm->bytes_in_flight -= apkt->num_bytes;1008if (apkt->is_ack_eliciting)1009ackm->ack_eliciting_bytes_in_flight[apkt->pkt_space]1010-= apkt->num_bytes;10111012if (apkt->pkt_num > last_pn_acked)1013last_pn_acked = apkt->pkt_num;10141015if (apkt->largest_acked != QUIC_PN_INVALID)1016/*1017* This can fail, but it is monotonic; worst case we try again1018* next time.1019*/1020rx_pkt_history_bump_watermark(get_rx_history(ackm,1021apkt->pkt_space),1022apkt->largest_acked + 1);1023}10241025ainfo.tx_time = apkt->time;1026ainfo.tx_size = apkt->num_bytes;10271028anext = apkt->anext;1029apkt->on_acked(apkt->cb_arg); /* may free apkt */10301031if (apkt->is_inflight)1032ackm->cc_method->on_data_acked(ackm->cc_data, &ainfo);1033}1034}10351036OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg),1037void *now_arg,1038OSSL_STATM *statm,1039const OSSL_CC_METHOD *cc_method,1040OSSL_CC_DATA *cc_data,1041int is_server)1042{1043OSSL_ACKM *ackm;1044int i;10451046ackm = OPENSSL_zalloc(sizeof(OSSL_ACKM));1047if (ackm == NULL)1048return NULL;10491050for (i = 0; i < (int)OSSL_NELEM(ackm->tx_history); ++i) {1051ackm->largest_acked_pkt[i] = QUIC_PN_INVALID;1052ackm->rx_ack_flush_deadline[i] = ossl_time_infinite();1053if (tx_pkt_history_init(&ackm->tx_history[i]) < 1)1054goto err;1055}10561057for (i = 0; i < (int)OSSL_NELEM(ackm->rx_history); ++i)1058rx_pkt_history_init(&ackm->rx_history[i]);10591060ackm->now = now;1061ackm->now_arg = now_arg;1062ackm->statm = statm;1063ackm->cc_method = cc_method;1064ackm->cc_data = cc_data;1065ackm->is_server = (char)is_server;10661067ackm->rx_max_ack_delay = ossl_ms2time(QUIC_DEFAULT_MAX_ACK_DELAY);1068ackm->tx_max_ack_delay = DEFAULT_TX_MAX_ACK_DELAY;10691070return ackm;10711072err:1073while (--i >= 0)1074tx_pkt_history_destroy(&ackm->tx_history[i]);10751076OPENSSL_free(ackm);1077return NULL;1078}10791080void ossl_ackm_free(OSSL_ACKM *ackm)1081{1082size_t i;10831084if (ackm == NULL)1085return;10861087for (i = 0; i < OSSL_NELEM(ackm->tx_history); ++i)1088if (!ackm->discarded[i]) {1089tx_pkt_history_destroy(&ackm->tx_history[i]);1090rx_pkt_history_destroy(&ackm->rx_history[i]);1091}10921093OPENSSL_free(ackm);1094}10951096int ossl_ackm_on_tx_packet(OSSL_ACKM *ackm, OSSL_ACKM_TX_PKT *pkt)1097{1098struct tx_pkt_history_st *h = get_tx_history(ackm, pkt->pkt_space);10991100/* Time must be set and not move backwards. */1101if (ossl_time_is_zero(pkt->time)1102|| ossl_time_compare(ackm->time_of_last_ack_eliciting_pkt[pkt->pkt_space],1103pkt->time) > 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 &&1204ack_includes_ack_eliciting(na_pkts)) {1205OSSL_TIME now = ackm->now(ackm->now_arg), ack_delay;1206if (ossl_time_is_zero(ackm->first_rtt_sample))1207ackm->first_rtt_sample = now;12081209/* Enforce maximum ACK delay. */1210ack_delay = ack->delay_time;1211if (ackm->handshake_confirmed)1212ack_delay = ossl_time_min(ack_delay, ackm->rx_max_ack_delay);12131214ossl_statm_update_rtt(ackm->statm, ack_delay,1215ossl_time_subtract(now, na_pkts->time));1216}12171218/*1219* Process ECN information if present.1220*1221* We deliberately do most ECN processing in the ACKM rather than the1222* congestion controller to avoid having to give the congestion controller1223* access to ACKM internal state.1224*/1225if (ack->ecn_present)1226ackm_process_ecn(ackm, ack, pkt_space);12271228/* Handle inferred loss. */1229lost_pkts = ackm_detect_and_remove_lost_pkts(ackm, pkt_space);1230if (lost_pkts != NULL)1231ackm_on_pkts_lost(ackm, pkt_space, lost_pkts, /*pseudo=*/0);12321233ackm_on_pkts_acked(ackm, na_pkts);12341235/*1236* Reset pto_count unless the client is unsure if the server validated the1237* client's address.1238*/1239if (ackm->peer_completed_addr_validation)1240ackm->pto_count = 0;12411242ackm_set_loss_detection_timer(ackm);1243return 1;1244}12451246int ossl_ackm_on_pkt_space_discarded(OSSL_ACKM *ackm, int pkt_space)1247{1248OSSL_ACKM_TX_PKT *pkt, *pnext;1249uint64_t num_bytes_invalidated = 0;12501251if (ackm->discarded[pkt_space])1252return 0;12531254if (pkt_space == QUIC_PN_SPACE_HANDSHAKE)1255ackm->peer_completed_addr_validation = 1;12561257for (pkt = ossl_list_tx_history_head(&get_tx_history(ackm, pkt_space)->packets);1258pkt != NULL; pkt = pnext) {1259pnext = ossl_list_tx_history_next(pkt);1260if (pkt->is_inflight) {1261ackm->bytes_in_flight -= pkt->num_bytes;1262num_bytes_invalidated += pkt->num_bytes;1263}12641265pkt->on_discarded(pkt->cb_arg); /* may free pkt */1266}12671268tx_pkt_history_destroy(&ackm->tx_history[pkt_space]);1269rx_pkt_history_destroy(&ackm->rx_history[pkt_space]);12701271if (num_bytes_invalidated > 0)1272ackm->cc_method->on_data_invalidated(ackm->cc_data,1273num_bytes_invalidated);12741275ackm->time_of_last_ack_eliciting_pkt[pkt_space] = ossl_time_zero();1276ackm->loss_time[pkt_space] = ossl_time_zero();1277ackm->pto_count = 0;1278ackm->discarded[pkt_space] = 1;1279ackm->ack_eliciting_bytes_in_flight[pkt_space] = 0;1280ackm_set_loss_detection_timer(ackm);1281return 1;1282}12831284int ossl_ackm_on_handshake_confirmed(OSSL_ACKM *ackm)1285{1286ackm->handshake_confirmed = 1;1287ackm->peer_completed_addr_validation = 1;1288ackm_set_loss_detection_timer(ackm);1289return 1;1290}12911292static void ackm_queue_probe_anti_deadlock_handshake(OSSL_ACKM *ackm)1293{1294++ackm->pending_probe.anti_deadlock_handshake;1295}12961297static void ackm_queue_probe_anti_deadlock_initial(OSSL_ACKM *ackm)1298{1299++ackm->pending_probe.anti_deadlock_initial;1300}13011302static void ackm_queue_probe(OSSL_ACKM *ackm, int pkt_space)1303{1304/*1305* TODO(QUIC FUTURE): We are allowed to send either one or two probe1306* packets here.1307* Determine a strategy for when we should send two probe packets.1308*/1309++ackm->pending_probe.pto[pkt_space];1310}13111312int ossl_ackm_on_timeout(OSSL_ACKM *ackm)1313{1314int pkt_space;1315OSSL_TIME earliest_loss_time;1316OSSL_ACKM_TX_PKT *lost_pkts;13171318earliest_loss_time = ackm_get_loss_time_and_space(ackm, &pkt_space);1319if (!ossl_time_is_zero(earliest_loss_time)) {1320/* Time threshold loss detection. */1321lost_pkts = ackm_detect_and_remove_lost_pkts(ackm, pkt_space);1322if (lost_pkts != NULL)1323ackm_on_pkts_lost(ackm, pkt_space, lost_pkts, /*pseudo=*/0);1324ackm_set_loss_detection_timer(ackm);1325return 1;1326}13271328if (ackm_ack_eliciting_bytes_in_flight(ackm) == 0) {1329assert(!ackm->peer_completed_addr_validation);1330/*1331* Client sends an anti-deadlock packet: Initial is padded to earn more1332* anti-amplification credit. A handshake packet proves address1333* ownership.1334*/1335if (ackm->discarded[QUIC_PN_SPACE_INITIAL])1336ackm_queue_probe_anti_deadlock_handshake(ackm);1337else1338ackm_queue_probe_anti_deadlock_initial(ackm);1339} else {1340/*1341* PTO. The user of the ACKM should send new data if available, else1342* retransmit old data, or if neither is available, send a single PING1343* frame.1344*/1345ackm_get_pto_time_and_space(ackm, &pkt_space);1346ackm_queue_probe(ackm, pkt_space);1347}13481349++ackm->pto_count;1350ackm_set_loss_detection_timer(ackm);1351return 1;1352}13531354OSSL_TIME ossl_ackm_get_loss_detection_deadline(OSSL_ACKM *ackm)1355{1356return ackm->loss_detection_deadline;1357}13581359OSSL_ACKM_PROBE_INFO *ossl_ackm_get0_probe_request(OSSL_ACKM *ackm)1360{1361return &ackm->pending_probe;1362}13631364int ossl_ackm_get_largest_unacked(OSSL_ACKM *ackm, int pkt_space, QUIC_PN *pn)1365{1366struct tx_pkt_history_st *h;1367OSSL_ACKM_TX_PKT *p;13681369h = get_tx_history(ackm, pkt_space);1370p = ossl_list_tx_history_tail(&h->packets);1371if (p != NULL) {1372*pn = p->pkt_num;1373return 1;1374}13751376return 0;1377}13781379/* Number of ACK-eliciting packets RX'd before we always emit an ACK. */1380#define PKTS_BEFORE_ACK 213811382/*1383* Return 1 if emission of an ACK frame is currently desired.1384*1385* This occurs when one or more of the following conditions occurs:1386*1387* - We have flagged that we want to send an ACK frame1388* (for example, due to the packet threshold count being exceeded), or1389*1390* - We have exceeded the ACK flush deadline, meaning that1391* we have received at least one ACK-eliciting packet, but held off on1392* sending an ACK frame immediately in the hope that more ACK-eliciting1393* packets might come in, but not enough did and we are now requesting1394* transmission of an ACK frame anyway.1395*1396*/1397int ossl_ackm_is_ack_desired(OSSL_ACKM *ackm, int pkt_space)1398{1399return ackm->rx_ack_desired[pkt_space]1400|| (!ossl_time_is_infinite(ackm->rx_ack_flush_deadline[pkt_space])1401&& ossl_time_compare(ackm->now(ackm->now_arg),1402ackm->rx_ack_flush_deadline[pkt_space]) >= 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 =1645ossl_time_subtract(now, ackm->rx_largest_time[pkt_space]);1646else1647ack->delay_time = ossl_time_zero();16481649ack->ect0 = ackm->rx_ect0[pkt_space];1650ack->ect1 = ackm->rx_ect1[pkt_space];1651ack->ecnce = ackm->rx_ecnce[pkt_space];1652ack->ecn_present = 1;16531654ackm->rx_ack_eliciting_pkts_since_last_ack[pkt_space] = 0;16551656ackm->rx_ack_generated[pkt_space] = 1;1657ackm->rx_ack_desired[pkt_space] = 0;1658ackm_set_flush_deadline(ackm, pkt_space, ossl_time_infinite());1659return ack;1660}166116621663OSSL_TIME ossl_ackm_get_ack_deadline(OSSL_ACKM *ackm, int pkt_space)1664{1665if (ackm->rx_ack_desired[pkt_space])1666/* Already desired, deadline is now. */1667return ossl_time_zero();16681669return ackm->rx_ack_flush_deadline[pkt_space];1670}16711672int ossl_ackm_is_rx_pn_processable(OSSL_ACKM *ackm, QUIC_PN pn, int pkt_space)1673{1674struct rx_pkt_history_st *h = get_rx_history(ackm, pkt_space);16751676return pn >= h->watermark && ossl_uint_set_query(&h->set, pn) == 0;1677}16781679void ossl_ackm_set_loss_detection_deadline_callback(OSSL_ACKM *ackm,1680void (*fn)(OSSL_TIME deadline,1681void *arg),1682void *arg)1683{1684ackm->loss_detection_deadline_cb = fn;1685ackm->loss_detection_deadline_cb_arg = arg;1686}16871688void ossl_ackm_set_ack_deadline_callback(OSSL_ACKM *ackm,1689void (*fn)(OSSL_TIME deadline,1690int pkt_space,1691void *arg),1692void *arg)1693{1694ackm->ack_deadline_cb = fn;1695ackm->ack_deadline_cb_arg = arg;1696}16971698int ossl_ackm_mark_packet_pseudo_lost(OSSL_ACKM *ackm,1699int pkt_space, QUIC_PN pn)1700{1701struct tx_pkt_history_st *h = get_tx_history(ackm, pkt_space);1702OSSL_ACKM_TX_PKT *pkt;17031704pkt = tx_pkt_history_by_pkt_num(h, pn);1705if (pkt == NULL)1706return 0;17071708tx_pkt_history_remove(h, pkt->pkt_num);1709pkt->lnext = NULL;1710ackm_on_pkts_lost(ackm, pkt_space, pkt, /*pseudo=*/1);1711return 1;1712}17131714OSSL_TIME ossl_ackm_get_pto_duration(OSSL_ACKM *ackm)1715{1716OSSL_TIME duration;1717OSSL_RTT_INFO rtt;17181719ossl_statm_get_rtt_info(ackm->statm, &rtt);17201721duration = ossl_time_add(rtt.smoothed_rtt,1722ossl_time_max(ossl_time_multiply(rtt.rtt_variance, 4),1723ossl_ticks2time(K_GRANULARITY)));1724if (!ossl_time_is_infinite(ackm->rx_max_ack_delay))1725duration = ossl_time_add(duration, ackm->rx_max_ack_delay);17261727return duration;1728}17291730QUIC_PN ossl_ackm_get_largest_acked(OSSL_ACKM *ackm, int pkt_space)1731{1732return ackm->largest_acked_pkt[pkt_space];1733}17341735void ossl_ackm_set_rx_max_ack_delay(OSSL_ACKM *ackm, OSSL_TIME rx_max_ack_delay)1736{1737ackm->rx_max_ack_delay = rx_max_ack_delay;1738}17391740void ossl_ackm_set_tx_max_ack_delay(OSSL_ACKM *ackm, OSSL_TIME tx_max_ack_delay)1741{1742ackm->tx_max_ack_delay = tx_max_ack_delay;1743}174417451746