When the idle timer expired with a still present mux, this task was not freed
and even requeued with a timer in the past.
Fix this issue calling task_destroy() in this case. As the task is freed,
its handler must return NULL setting local <t> variable to NULL in every cases.
Also ensure that this timer task is not armed again after having been released
with a <return> statement when this is the case from qc_idle_timer_do_rearm().
Must be backported as far as 2.6.
{
unsigned int expire;
+ /* It is possible the idle timer task has been already released. */
+ if (!qc->idle_timer_task)
+ return;
+
if (stopping && qc->flags & (QUIC_FL_CONN_CLOSING|QUIC_FL_CONN_DRAINING)) {
TRACE_PROTO("executing idle timer immediately on stopping", QUIC_EV_CONN_IDLE_TIMER, qc);
qc->ack_expire = TICK_ETERNITY;
if (qc->mux_state != QC_MUX_READY) {
quic_conn_release(qc);
qc = NULL;
- t = NULL;
}
+ else {
+ task_destroy(t);
+ qc->idle_timer_task = NULL;
+ }
+
+ t = NULL;
/* TODO if the quic-conn cannot be freed because of the MUX, we may at
* least clean some parts of it such as the tasklet.