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.
This commit is contained in:
Amaury Denoyelle 2025-07-08 10:31:46 +02:00
parent c5bcc3a21e
commit 558532fc57

View File

@ -328,12 +328,9 @@ static void qcc_refresh_timeout(struct qcc *qcc)
if (!LIST_ISEMPTY(&qcc->send_list) || !LIST_ISEMPTY(&qcc->tx.frms)) { if (!LIST_ISEMPTY(&qcc->send_list) || !LIST_ISEMPTY(&qcc->tx.frms)) {
TRACE_DEVEL("pending output data", QMUX_EV_QCC_WAKE, qcc->conn); TRACE_DEVEL("pending output data", QMUX_EV_QCC_WAKE, qcc->conn);
qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout); qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout);
task_queue(qcc->task);
goto leave;
} }
else if ((!LIST_ISEMPTY(&qcc->opening_list) || unlikely(!qcc->largest_bidi_r)) &&
if ((!LIST_ISEMPTY(&qcc->opening_list) || unlikely(!qcc->largest_bidi_r)) && qcc->app_st < QCC_APP_ST_SHUT) {
qcc->app_st < QCC_APP_ST_SHUT) {
int timeout = px->timeout.httpreq; int timeout = px->timeout.httpreq;
struct qcs *qcs = NULL; struct qcs *qcs = NULL;
int base_time; 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); 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); qcc->task->expire = tick_add_ifset(qcc->idle_start, timeout);
} }
}
}
/* If proxy soft-stop in progress and connection is /* If proxy soft-stop in progress and connection is inactive,
* inactive, close the connection immediately. If a * close the connection immediately. If a close-spread-time is
* close-spread-time is configured, randomly spread the * configured, randomly spread the timer over a closing window.
* 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)) && if (!tick_isset(qcc->task->expire) ||
!(global.tune.options & GTUNE_DISABLE_ACTIVE_CLOSE)) { tick_is_le(global.close_spread_end, qcc->task->expire)) {
/* Set an expire value shorter than the current value
/* Wake timeout task immediately if window already expired. */ * because the close spread window end comes earlier.
int remaining_window = tick_isset(global.close_spread_end) ? */
tick_remain(now_ms, global.close_spread_end) : 0; qcc->task->expire = tick_add(now_ms,
statistical_prng_range(remaining_window));
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);
}
} }
} }
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 /* fallback to default timeout if frontend specific undefined or for