From: Amaury Denoyelle Date: Wed, 3 May 2023 07:50:39 +0000 (+0200) Subject: MINOR: mux-quic: do not send STREAM frames if already subscribe X-Git-Tag: v2.8-dev12~70 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=04b2208aa0768bb7f69dc4a286e7e059409bdf09;p=thirdparty%2Fhaproxy.git MINOR: mux-quic: do not send STREAM frames if already subscribe Do not built STREAM frames if MUX is already subscribed for sending on lower layer. Indeed, this means that either socket currently encountered a transient error or congestion window is full. This change is an optimization which prevents to allocate and release a series of STREAM frames for nothing under congestion. Note that nothing is done for other frames (flow-control, RESET_STREAM and STOP_SENDING). Indeed, these frames are not restricted by flow control. However, this means that they will be allocated for nothing if send is blocked on a transient error. This should be backported up to 2.7. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index 6070b00882..297d2adaa5 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -1843,6 +1843,15 @@ static int _qc_send_qcs(struct qcs *qcs, struct list *frms) /* Build a new STREAM frame with buffer. */ if (qcs->tx.sent_offset != qcs->tx.offset || fin) { + /* Skip STREAM frame allocation if already subscribed for send. + * Happens on sendto transient error or network congestion. + */ + if (qcc->wait_event.events & SUB_RETRY_SEND) { + TRACE_DEVEL("already subscribed for sending", + QMUX_EV_QCS_SEND, qcc->conn, qcs); + goto err; + } + if (qcs_build_stream_frm(qcs, out, fin, frms) < 0) goto err; } @@ -1871,6 +1880,12 @@ static int qc_send(struct qcc *qcc) TRACE_ENTER(QMUX_EV_QCC_SEND, qcc->conn); + /* TODO if socket in transient error, sending should be temporarily + * disabled for all frames. However, checking for send subscription is + * not valid as this may be caused by a congestion error which only + * apply for STREAM frames. + */ + /* Check for locally detected connection error. */ if (qcc->flags & QC_CF_ERRL) { /* Prepare a CONNECTION_CLOSE if not already done. */