]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: quic: Unsent frame because of qc_build_frms()
authorFrédéric Lécaille <flecaille@haproxy.com>
Fri, 18 Mar 2022 16:49:29 +0000 (17:49 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 21 Mar 2022 10:29:40 +0000 (11:29 +0100)
There are non already identified rare cases where qc_build_frms() does not manage
to size frames to be encoded in a packet leading qc_build_frm() to fail to add
such frame to the packet to be built. In such cases we must move back such
frames to their origin frame list passed as parameter to qc_build_frms(): <frms>.
because they were added to the packet frame list (but not built). If this
this packet is not retransmitted, the frame is lost for ever! Furthermore we must
not modify the buffer.

src/xprt_quic.c

index 114fc569b8312e85a115c26e9bf089db86aa830f..b50af85b375d5fb755cd1b14830a246bbf0b0385 100644 (file)
@@ -5231,12 +5231,23 @@ static int qc_do_build_pkt(unsigned char *pos, const unsigned char *end,
        /* Ack-eliciting frames */
        if (!LIST_ISEMPTY(&frm_list)) {
                list_for_each_entry(cf, &frm_list, list) {
-                       if (!qc_build_frm(&pos, end, cf, pkt, qc)) {
+                       unsigned char *spos = pos;
+
+                       if (!qc_build_frm(&spos, end, cf, pkt, qc)) {
                                ssize_t room = end - pos;
                                TRACE_PROTO("Not enough room", QUIC_EV_CONN_HPKT,
                                            qc, NULL, NULL, &room);
+                               /* TODO: this should not have happened if qc_build_frms()
+                                * had correctly computed and sized the frames to be
+                                * added to this packet. Note that <cf> was added
+                                * from <frm_list> to <frms> list by qc_build_frms().
+                                */
+                               LIST_DELETE(&cf->list);
+                               LIST_INSERT(frms, &cf->list);
                                break;
                        }
+
+                       pos = spos;
                        quic_tx_packet_refinc(pkt);
                        cf->pkt = pkt;
                }