]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
QUIC ACKM: Add support for psuedo-loss
authorHugo Landau <hlandau@openssl.org>
Mon, 31 Oct 2022 13:32:34 +0000 (13:32 +0000)
committerHugo Landau <hlandau@openssl.org>
Fri, 13 Jan 2023 13:20:08 +0000 (13:20 +0000)
This is required to support retries during connection establishment.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19703)

include/internal/quic_ackm.h
ssl/quic/quic_ackm.c

index 6c8b0c5a466cdb68874d5c4c3c0acc21aefe4312..866213cb73091556a8d95bdac6f939999ac1d3dc 100644 (file)
@@ -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
index 0a9e55881a356c3c8cb8bc9296a0637187442abe..54298b54c41f64923d3933c0c4335ebd9d5a1aa2 100644 (file)
@@ -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;
+}