mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-26 14:42:21 +00:00
BUG/MINOR: mux-quic: close all QCS before freeing QCC tasklet
QUIC MUX is freed via qcc_release(). This in turn liberate all the remaining QCS instances. For each one of them, their corresponding stream-desc is released via qc_stream_desc_release(). This last function may itself notifies QUIC MUX when new buffers are available. This is useful when QCS are closed individually without the whole connection. However, when the connection is closed through qcc_release(), this may cause issue as some elements of QUIC MUX are already freed. In 2.9.6, a bug was detected directly linked to this. Indeed, QCC instance may be woken up on stream-desc release. If called through qcc_release(), this is an issue because QCC tasklet is freed before QCS instances. However, this bug is not systematic and relies on prior conditions : in particular, QUIC MUX must be under Tx buffers exhaustion prior to the qcc_release() invocation. The current dev tree is not impacted by this bug, thanks to QUIC MUX refactoring. Indeed, notifying accross layers have changed and now stream-desc release notifies individual QCS instances instead of the QCC element, which is a safer mechanism. However, to simplify backport process, bugfix is introduced in the current dev tree as it does not have any impact. Note that a proper fix would be to set quic-conn MUX state to QC_MUX_RELEASED. However, it is not possible to call quic_close() without having releasing all stream-desc elements first. The simpler solution was chosen to prevent other breaking issues during backports. This should fix github issue #2494. It should be backported up to 2.6. Note that prior to 2.7 qcc_release() was named qc_release().
This commit is contained in:
parent
0d4273f04b
commit
bd384a359b
@ -2464,13 +2464,6 @@ static void qcc_release(struct qcc *qcc)
|
||||
qcc->task = NULL;
|
||||
}
|
||||
|
||||
tasklet_free(qcc->wait_event.tasklet);
|
||||
if (conn && qcc->wait_event.events) {
|
||||
conn->xprt->unsubscribe(conn, conn->xprt_ctx,
|
||||
qcc->wait_event.events,
|
||||
&qcc->wait_event);
|
||||
}
|
||||
|
||||
/* liberate remaining qcs instances */
|
||||
node = eb64_first(&qcc->streams_by_id);
|
||||
while (node) {
|
||||
@ -2479,6 +2472,13 @@ static void qcc_release(struct qcc *qcc)
|
||||
qcs_free(qcs);
|
||||
}
|
||||
|
||||
tasklet_free(qcc->wait_event.tasklet);
|
||||
if (conn && qcc->wait_event.events) {
|
||||
conn->xprt->unsubscribe(conn, conn->xprt_ctx,
|
||||
qcc->wait_event.events,
|
||||
&qcc->wait_event);
|
||||
}
|
||||
|
||||
while (!LIST_ISEMPTY(&qcc->lfctl.frms)) {
|
||||
struct quic_frame *frm = LIST_ELEM(qcc->lfctl.frms.n, struct quic_frame *, list);
|
||||
qc_frm_free(qcc->conn->handle.qc, &frm);
|
||||
|
Loading…
Reference in New Issue
Block a user