From e5d575686efb280af08c3fd307a649ed2a942ce3 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Mon, 31 Oct 2022 13:32:34 +0000 Subject: [PATCH] QUIC ACKM: Add support for psuedo-loss This is required to support retries during connection establishment. Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/19703) --- include/internal/quic_ackm.h | 12 ++++++++++++ ssl/quic/quic_ackm.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/include/internal/quic_ackm.h b/include/internal/quic_ackm.h index 6c8b0c5a466..866213cb730 100644 --- a/include/internal/quic_ackm.h +++ b/include/internal/quic_ackm.h @@ -213,4 +213,16 @@ int ossl_ackm_get_probe_request(OSSL_ACKM *ackm, int clear, int ossl_ackm_get_largest_unacked(OSSL_ACKM *ackm, int pkt_space, QUIC_PN *pn); +/* + * Forces the ACKM to consider a packet with the given PN in the given PN space + * as having been pseudo-lost. The main reason to use this is during a Retry, to + * force any resources sent in the first Initial packet to be resent. + * + * The lost callback is called for the packet, but the packet is NOT considered + * lost for congestion control purposes. Thus this is not exactly the same as a + * true loss situation. + */ +int ossl_ackm_mark_packet_pseudo_lost(OSSL_ACKM *ackm, + int pkt_space, QUIC_PN pn); + #endif diff --git a/ssl/quic/quic_ackm.c b/ssl/quic/quic_ackm.c index 0a9e55881a3..54298b54c41 100644 --- a/ssl/quic/quic_ackm.c +++ b/ssl/quic/quic_ackm.c @@ -916,7 +916,7 @@ static int ackm_in_persistent_congestion(OSSL_ACKM *ackm, } static void ackm_on_pkts_lost(OSSL_ACKM *ackm, int pkt_space, - const OSSL_ACKM_TX_PKT *lpkt) + const OSSL_ACKM_TX_PKT *lpkt, int pseudo) { const OSSL_ACKM_TX_PKT *p, *pnext; OSSL_RTT_INFO rtt; @@ -941,6 +941,14 @@ static void ackm_on_pkts_lost(OSSL_ACKM *ackm, int pkt_space, p->on_lost(p->cb_arg); } + if (pseudo) + /* + * If this is psuedo-loss (e.g. during connection retry) we do not + * inform the CC as it is not a real loss and not reflective of network + * conditions. + */ + return; + /* * Only consider lost packets with regards to congestion after getting an * RTT sample. @@ -1181,7 +1189,7 @@ int ossl_ackm_on_rx_ack_frame(OSSL_ACKM *ackm, const OSSL_QUIC_FRAME_ACK *ack, /* Handle inferred loss. */ lost_pkts = ackm_detect_and_remove_lost_pkts(ackm, pkt_space); if (lost_pkts != NULL) - ackm_on_pkts_lost(ackm, pkt_space, lost_pkts); + ackm_on_pkts_lost(ackm, pkt_space, lost_pkts, /*pseudo=*/0); ackm_on_pkts_acked(ackm, na_pkts); @@ -1268,7 +1276,7 @@ int ossl_ackm_on_timeout(OSSL_ACKM *ackm) /* Time threshold loss detection. */ lost_pkts = ackm_detect_and_remove_lost_pkts(ackm, pkt_space); assert(lost_pkts != NULL); - ackm_on_pkts_lost(ackm, pkt_space, lost_pkts); + ackm_on_pkts_lost(ackm, pkt_space, lost_pkts, /*pseudo=*/0); ackm_set_loss_detection_timer(ackm); return 1; } @@ -1639,3 +1647,19 @@ void ossl_ackm_set_ack_deadline_callback(OSSL_ACKM *ackm, ackm->ack_deadline_cb = fn; ackm->ack_deadline_cb_arg = arg; } + +int ossl_ackm_mark_packet_pseudo_lost(OSSL_ACKM *ackm, + int pkt_space, QUIC_PN pn) +{ + struct tx_pkt_history_st *h = get_tx_history(ackm, pkt_space); + OSSL_ACKM_TX_PKT *pkt; + + pkt = tx_pkt_history_by_pkt_num(h, pn); + if (pkt == NULL) + return 0; + + tx_pkt_history_remove(h, pkt->pkt_num); + pkt->lnext = NULL; + ackm_on_pkts_lost(ackm, pkt_space, pkt, /*pseudo=*/1); + return 1; +} -- 2.47.3