]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: quic_loss modifications to support BBR
authorFrederic Lecaille <flecaille@haproxy.com>
Tue, 22 Oct 2024 17:01:08 +0000 (19:01 +0200)
committerFrederic Lecaille <flecaille@haproxy.com>
Wed, 20 Nov 2024 16:34:22 +0000 (17:34 +0100)
qc_packet_loss_lookup() aim is to detect the packet losses. This is this function
which must called ->on_pkt_lost() BBR specific callback. It also set
<bytes_lost> passed parameter to the total number of bytes detected as lost upon
an ACK frame receipt for its caller.
Modify qc_release_lost_pkts() to call ->congestion_event() with the send time
from the newest packet detected as lost.
Modify qc_release_lost_pkts() to call ->slow_start() callback only if define
by the congestion control algorithm. This is not the case for BBR.

include/haproxy/quic_loss.h
src/quic_conn.c
src/quic_loss.c

index fc713ca07d02340aa18a1b49e9abfe89492dc98c..f6833de45ab938349ab57eae01e77ab8dca8b959 100644 (file)
@@ -85,7 +85,7 @@ struct quic_pktns *quic_pto_pktns(struct quic_conn *qc,
                                   unsigned int *pto);
 
 void qc_packet_loss_lookup(struct quic_pktns *pktns, struct quic_conn *qc,
-                           struct list *lost_pkts);
+                           struct list *lost_pkts, uint32_t *bytes_lost);
 int qc_release_lost_pkts(struct quic_conn *qc, struct quic_pktns *pktns,
                          struct list *pkts, uint64_t now_us);
 #endif /* USE_QUIC */
index c5c2a74ff6122412a803e73c6754282cf23e85b1..a0ff0c331a22909ae2268852eddd0a7a2a58f704 100644 (file)
@@ -931,7 +931,7 @@ struct task *qc_process_timer(struct task *task, void *ctx, unsigned int state)
        if (tick_isset(pktns->tx.loss_time)) {
                struct list lost_pkts = LIST_HEAD_INIT(lost_pkts);
 
-               qc_packet_loss_lookup(pktns, qc, &lost_pkts);
+               qc_packet_loss_lookup(pktns, qc, &lost_pkts, NULL);
                if (!LIST_ISEMPTY(&lost_pkts))
                    tasklet_wakeup(qc->wait_event.tasklet);
                if (qc_release_lost_pkts(qc, pktns, &lost_pkts, now_ms))
index e80757102c3c3bd829bf14655465024e40d91f4c..6cce844689e146dc3e76593980230fe9d464eddd 100644 (file)
@@ -1,5 +1,6 @@
 #include <import/eb64tree.h>
 
+#include <haproxy/quic_cc-t.h>
 #include <haproxy/quic_conn-t.h>
 #include <haproxy/quic_loss.h>
 #include <haproxy/quic_tls.h>
@@ -151,7 +152,7 @@ struct quic_pktns *quic_pto_pktns(struct quic_conn *qc,
  * Always succeeds.
  */
 void qc_packet_loss_lookup(struct quic_pktns *pktns, struct quic_conn *qc,
-                           struct list *lost_pkts)
+                           struct list *lost_pkts, uint32_t *bytes_lost)
 {
        struct eb_root *pkts;
        struct eb64_node *node;
@@ -213,8 +214,14 @@ void qc_packet_loss_lookup(struct quic_pktns *pktns, struct quic_conn *qc,
                        ql->nb_reordered_pkt++;
 
                if (tick_is_le(loss_time_limit, now_ms) || reordered) {
+                       struct quic_cc *cc = &qc->path->cc;
+
+                       if (cc->algo->on_pkt_lost)
+                               cc->algo->on_pkt_lost(cc, pkt, pkt->rs.lost);
                        eb64_delete(&pkt->pn_node);
                        LIST_APPEND(lost_pkts, &pkt->list);
+                       if (bytes_lost)
+                               *bytes_lost += pkt->len;
                        ql->nb_lost_pkt++;
                }
                else {
@@ -276,6 +283,7 @@ int qc_release_lost_pkts(struct quic_conn *qc, struct quic_pktns *pktns,
 
        if (!close) {
                if (newest_lost) {
+                       struct quic_cc *cc = &qc->path->cc;
                        /* Sent a congestion event to the controller */
                        struct quic_cc_event ev = { };
 
@@ -283,7 +291,9 @@ int qc_release_lost_pkts(struct quic_conn *qc, struct quic_pktns *pktns,
                        ev.loss.time_sent = newest_lost->time_sent;
                        ev.loss.count = tot_lost;
 
-                       quic_cc_event(&qc->path->cc, &ev);
+                       quic_cc_event(cc, &ev);
+                       if (cc->algo->congestion_event)
+                           cc->algo->congestion_event(cc, newest_lost->time_sent);
                }
 
                /* If an RTT have been already sampled, <rtt_min> has been set.
@@ -295,7 +305,8 @@ int qc_release_lost_pkts(struct quic_conn *qc, struct quic_pktns *pktns,
                        unsigned int period = newest_lost->time_sent - oldest_lost->time_sent;
 
                        if (quic_loss_persistent_congestion(&qc->path->loss, period,
-                                                           now_ms, qc->max_ack_delay))
+                                                           now_ms, qc->max_ack_delay) &&
+                           qc->path->cc.algo->slow_start)
                                qc->path->cc.algo->slow_start(&qc->path->cc);
                }
        }