mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-14 07:24:32 +00:00
BUG/MEDIUM: quic: ensure quic-conn survives to the MUX
Rationalize the lifetime of the quic-conn regarding with the MUX. The quic-conn must not be freed if the MUX is still allocated. This simplify the MUX code when accessing the quic-conn and removed possible segfaults. To implement this, if the quic-conn timer expired, the quic-conn is released only if the MUX is not allocated. Else, the quic-conn is flagged with QUIC_FL_CONN_EXP_TIMER. The MUX is then responsible to call quic_close() which will free the flagged quic-conn.
This commit is contained in:
parent
59bf255806
commit
db71e3bd09
@ -664,6 +664,7 @@ enum qc_mux_state {
|
||||
#define QUIC_FL_CONN_LISTENER (1U << 3)
|
||||
#define QUIC_FL_CONN_ACCEPT_REGISTERED (1U << 4)
|
||||
#define QUIC_FL_CONN_IDLE_TIMER_RESTARTED_AFTER_READ (1U << 6)
|
||||
#define QUIC_FL_CONN_EXP_TIMER (1U << 28) /* timer has expired, quic-conn can be freed */
|
||||
#define QUIC_FL_CONN_CLOSING (1U << 29)
|
||||
#define QUIC_FL_CONN_DRAINING (1U << 30)
|
||||
#define QUIC_FL_CONN_IMMEDIATE_CLOSE (1U << 31)
|
||||
|
@ -3802,6 +3802,9 @@ static void quic_conn_release(struct quic_conn *qc)
|
||||
struct eb64_node *node;
|
||||
struct quic_tls_ctx *app_tls_ctx;
|
||||
|
||||
/* We must not free the quic-conn if the MUX is still allocated. */
|
||||
BUG_ON(qc->mux_state == QC_MUX_READY);
|
||||
|
||||
/* free remaining stream descriptors */
|
||||
node = eb64_first(&qc->streams_by_id);
|
||||
while (node) {
|
||||
@ -3866,6 +3869,13 @@ void quic_close(struct connection *conn, void *xprt_ctx)
|
||||
/* Next application data can be dropped. */
|
||||
qc->mux_state = QC_MUX_RELEASED;
|
||||
|
||||
/* If the quic-conn timer has already expired free the quic-conn. */
|
||||
if (qc->flags & QUIC_FL_CONN_EXP_TIMER) {
|
||||
quic_conn_release(qc);
|
||||
TRACE_LEAVE(QUIC_EV_CONN_CLOSE);
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE_LEAVE(QUIC_EV_CONN_CLOSE, qc);
|
||||
}
|
||||
|
||||
@ -4107,7 +4117,16 @@ static struct task *qc_idle_timer_task(struct task *t, void *ctx, unsigned int s
|
||||
{
|
||||
struct quic_conn *qc = ctx;
|
||||
|
||||
quic_conn_release(qc);
|
||||
/* If the MUX is still alive, keep the quic-conn. The MUX is
|
||||
* responsible to call quic_close to release it.
|
||||
*/
|
||||
qc->flags |= QUIC_FL_CONN_EXP_TIMER;
|
||||
if (qc->mux_state != QC_MUX_READY)
|
||||
quic_conn_release(qc);
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user