From: Amaury Denoyelle Date: Tue, 8 Jul 2025 08:31:46 +0000 (+0200) Subject: BUG/MINOR: mux-quic: ensure close-spread-time is properly applied X-Git-Tag: v3.3-dev4~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=558532fc57d8bd5bef83317586fbf1e34e689223;p=thirdparty%2Fhaproxy.git BUG/MINOR: mux-quic: ensure close-spread-time is properly applied If a connection remains on a proxy currently disabled or stopped, a special spread timeout is set if active close is configured. For QUIC MUX, this is set via qcc_refresh_timeout() as with all other timeout values. Fix this closing timeout setting : it is now used as an override to any other timeout that may have been chosen if calculated spread time is lower than the previously selected value. This is done for backend connections as well. This should be backported up to 2.6 after a period of observation. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index 5f10c23ab..97e006184 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -328,12 +328,9 @@ static void qcc_refresh_timeout(struct qcc *qcc) if (!LIST_ISEMPTY(&qcc->send_list) || !LIST_ISEMPTY(&qcc->tx.frms)) { TRACE_DEVEL("pending output data", QMUX_EV_QCC_WAKE, qcc->conn); qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout); - task_queue(qcc->task); - goto leave; } - - if ((!LIST_ISEMPTY(&qcc->opening_list) || unlikely(!qcc->largest_bidi_r)) && - qcc->app_st < QCC_APP_ST_SHUT) { + else if ((!LIST_ISEMPTY(&qcc->opening_list) || unlikely(!qcc->largest_bidi_r)) && + qcc->app_st < QCC_APP_ST_SHUT) { int timeout = px->timeout.httpreq; struct qcs *qcs = NULL; int base_time; @@ -361,42 +358,41 @@ static void qcc_refresh_timeout(struct qcc *qcc) TRACE_DEVEL("at least one request achieved but none currently in progress", QMUX_EV_QCC_WAKE, qcc->conn); qcc->task->expire = tick_add_ifset(qcc->idle_start, timeout); } + } + } - /* If proxy soft-stop in progress and connection is - * inactive, close the connection immediately. If a - * close-spread-time is configured, randomly spread the - * timer over a closing window. + /* If proxy soft-stop in progress and connection is inactive, + * close the connection immediately. If a close-spread-time is + * configured, randomly spread the timer over a closing window. + */ + if ((qcc->proxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) && + !(global.tune.options & GTUNE_DISABLE_ACTIVE_CLOSE)) { + + /* Wake timeout task immediately if window already expired. */ + int remaining_window = tick_isset(global.close_spread_end) ? + tick_remain(now_ms, global.close_spread_end) : 0; + + TRACE_DEVEL("proxy disabled, prepare connection soft-stop", QMUX_EV_QCC_WAKE, qcc->conn); + if (remaining_window) { + /* We don't need to reset the expire if it would + * already happen before the close window end. */ - if ((qcc->proxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) && - !(global.tune.options & GTUNE_DISABLE_ACTIVE_CLOSE)) { - - /* Wake timeout task immediately if window already expired. */ - int remaining_window = tick_isset(global.close_spread_end) ? - tick_remain(now_ms, global.close_spread_end) : 0; - - TRACE_DEVEL("proxy disabled, prepare connection soft-stop", QMUX_EV_QCC_WAKE, qcc->conn); - if (remaining_window) { - /* We don't need to reset the expire if it would - * already happen before the close window end. - */ - if (!tick_isset(qcc->task->expire) || - tick_is_le(global.close_spread_end, qcc->task->expire)) { - /* Set an expire value shorter than the current value - * because the close spread window end comes earlier. - */ - qcc->task->expire = tick_add(now_ms, - statistical_prng_range(remaining_window)); - } - } - else { - /* We are past the soft close window end, wake the timeout - * task up immediately. - */ - qcc->task->expire = tick_add(now_ms, 0); - task_wakeup(qcc->task, TASK_WOKEN_TIMER); - } + if (!tick_isset(qcc->task->expire) || + tick_is_le(global.close_spread_end, qcc->task->expire)) { + /* Set an expire value shorter than the current value + * because the close spread window end comes earlier. + */ + qcc->task->expire = tick_add(now_ms, + statistical_prng_range(remaining_window)); } } + else { + /* We are past the soft close window end, wake the timeout + * task up immediately. + */ + qcc->task->expire = tick_add(now_ms, 0); + task_wakeup(qcc->task, TASK_WOKEN_TIMER); + } } /* fallback to default timeout if frontend specific undefined or for