From: Amaury Denoyelle Date: Wed, 5 Jun 2024 15:26:14 +0000 (+0200) Subject: OPTIM: quic: fill whole Tx buffer if needed X-Git-Tag: v3.1-dev1~35 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ab37b8692141cd2b5e6ac7328e79162106c70d58;p=thirdparty%2Fhaproxy.git OPTIM: quic: fill whole Tx buffer if needed Previously, packets encoding was stopped as soon as buffer room left is less than UDP MTU. This is suboptimal if the next packet would be smaller than that. To improve this, only check if there is at least enough room for the mandatory packet header. qc_build_pkt() would ensure there is thus responsible to return QC_BUILD_PKT_ERR_BUFROOM as soon as buffer left is insufficient to stop packets encoding. An extra check is added to ensure end pointer would never exceed buffer end. This should not have any significant impact on the performance. However, this renders the code intention clearer. --- diff --git a/src/quic_tx.c b/src/quic_tx.c index 84e9f3267f..a21e61d54f 100644 --- a/src/quic_tx.c +++ b/src/quic_tx.c @@ -532,8 +532,7 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf, * Each datagram is prepended with its length followed by the address * of the first packet in the datagram (QUIC_DGRAM_HEADLEN). */ - while ((!cc && b_contig_space(buf) >= (int)qc->path->mtu + QUIC_DGRAM_HEADLEN) || - (cc && b_contig_space(buf) >= QUIC_MIN_CC_PKTSIZE + QUIC_DGRAM_HEADLEN) || prv_pkt) { + while (b_contig_space(buf) > QUIC_DGRAM_HEADLEN || prv_pkt) { int err, probe, must_ack; enum quic_pkt_type pkt_type; struct quic_tx_packet *cur_pkt; @@ -562,18 +561,21 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf, break; } - if (!prv_pkt) { - /* Leave room for the datagram header */ + /* On starting a new datagram, calculate end max offset + * to stay under MTU limit. + */ + if (!first_pkt) { pos += QUIC_DGRAM_HEADLEN; - if (cc) { + if (cc) end = pos + QUIC_MIN_CC_PKTSIZE; - } - else if (!quic_peer_validated_addr(qc) && qc_is_listener(qc)) { + else if (!quic_peer_validated_addr(qc) && qc_is_listener(qc)) end = pos + QUIC_MIN(qc->path->mtu, quic_may_send_bytes(qc)); - } - else { + else end = pos + qc->path->mtu; - } + + /* Ensure end does not go beyond buffer */ + if (end > (unsigned char *)b_wrap(buf)) + end = (unsigned char *)b_wrap(buf); } /* RFC 9000 14.1 Initial datagram size