]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: quic: Do not resend already acked frames
authorFrédéric Lécaille <flecaille@haproxy.com>
Thu, 2 Mar 2023 13:49:22 +0000 (14:49 +0100)
committerFrédéric Lécaille <flecaille@haproxy.com>
Fri, 3 Mar 2023 18:12:26 +0000 (19:12 +0100)
Some frames are marked as already acknowledged from duplicated packets
whose the original packet has been acknowledged. There is no need
to resend such packets or frames.

Implement qc_pkt_with_only_acked_frms() to detect packet with only
already acknowledged frames inside and use it from qc_prep_fast_retrans()
which selects the packet to be retransmitted.

Must be backported to 2.6 and 2.7.

src/quic_conn.c

index 7c2ee64921779febbe13910a2ed73d63a7958886..61acd72c38d52b25a09decc04aee94227c254b90 100644 (file)
@@ -2536,6 +2536,11 @@ static void qc_dup_pkt_frms(struct quic_conn *qc,
        list_for_each_entry_safe(frm, frmbak, pkt_frm_list, list) {
                struct quic_frame *dup_frm, *origin;
 
+               if (frm->flags & QUIC_FL_TX_FRAME_ACKED) {
+                       TRACE_DEVEL("already acknowledged frame", QUIC_EV_CONN_PRSAFRM, qc, frm);
+                       continue;
+               }
+
                switch (frm->type) {
                case QUIC_FT_STREAM_8 ... QUIC_FT_STREAM_F:
                {
@@ -2598,6 +2603,20 @@ static void qc_dup_pkt_frms(struct quic_conn *qc,
        TRACE_LEAVE(QUIC_EV_CONN_PRSAFRM, qc);
 }
 
+/* Boolean function which return 1 if <pkt> TX packet is only made of
+ * already acknowledged frame.
+ */
+static inline int qc_pkt_with_only_acked_frms(struct quic_tx_packet *pkt)
+{
+       struct quic_frame *frm;
+
+       list_for_each_entry(frm, &pkt->frms, list)
+               if (!(frm->flags & QUIC_FL_TX_FRAME_ACKED))
+                       return 0;
+
+       return 1;
+}
+
 /* Prepare a fast retransmission from <qel> encryption level */
 static void qc_prep_fast_retrans(struct quic_conn *qc,
                                  struct quic_enc_level *qel,
@@ -2622,9 +2641,10 @@ static void qc_prep_fast_retrans(struct quic_conn *qc,
                node = eb64_next(node);
                /* Skip the empty and coalesced packets */
                TRACE_PRINTF(TRACE_LEVEL_DEVELOPER, QUIC_EV_CONN_SPPKTS, qc, 0, 0, 0,
-                            "--> pn=%llu (%d %d)", (ull)p->pn_node.key,
-                            LIST_ISEMPTY(&p->frms), !!(p->flags & QUIC_FL_TX_PACKET_COALESCED));
-               if (!LIST_ISEMPTY(&p->frms)) {
+                            "--> pn=%llu (%d %d %d)", (ull)p->pn_node.key,
+                            LIST_ISEMPTY(&p->frms), !!(p->flags & QUIC_FL_TX_PACKET_COALESCED),
+                            qc_pkt_with_only_acked_frms(p));
+               if (!LIST_ISEMPTY(&p->frms) && !qc_pkt_with_only_acked_frms(p)) {
                        pkt = p;
                        break;
                }
@@ -2684,7 +2704,8 @@ static void qc_prep_hdshk_fast_retrans(struct quic_conn *qc,
                TRACE_PRINTF(TRACE_LEVEL_DEVELOPER, QUIC_EV_CONN_SPPKTS, qc, 0, 0, 0,
                             "--> pn=%llu (%d %d)", (ull)p->pn_node.key,
                             LIST_ISEMPTY(&p->frms), !!(p->flags & QUIC_FL_TX_PACKET_COALESCED));
-               if (!LIST_ISEMPTY(&p->frms) && !(p->flags & QUIC_FL_TX_PACKET_COALESCED)) {
+               if (!LIST_ISEMPTY(&p->frms) && !(p->flags & QUIC_FL_TX_PACKET_COALESCED) &&
+                   !qc_pkt_with_only_acked_frms(p)) {
                        pkt = p;
                        break;
                }