diff --git a/include/haproxy/xprt_quic-t.h b/include/haproxy/xprt_quic-t.h index 157d81d45..0f1004fd8 100644 --- a/include/haproxy/xprt_quic-t.h +++ b/include/haproxy/xprt_quic-t.h @@ -657,6 +657,8 @@ enum qc_mux_state { #define QUIC_FL_POST_HANDSHAKE_FRAMES_BUILT (1U << 2) #define QUIC_FL_CONN_LISTENER (1U << 3) +#define QUIC_FL_ACCEPT_REGISTERED_BIT 4 +#define QUIC_FL_ACCEPT_REGISTERED (1U << QUIC_FL_ACCEPT_REGISTERED_BIT) #define QUIC_FL_CONN_IMMEDIATE_CLOSE (1U << 31) struct quic_conn { /* The quic_conn instance is refcounted as it can be used by threads diff --git a/src/quic_sock.c b/src/quic_sock.c index 5533b01d5..087a65ded 100644 --- a/src/quic_sock.c +++ b/src/quic_sock.c @@ -255,13 +255,19 @@ void quic_sock_fd_iocb(int fd) struct quic_accept_queue *quic_accept_queues; /* Install on the queue ready to be accepted. The queue task is then woken - * up. + * up. If accept is already scheduled or done, nothing is done. */ void quic_accept_push_qc(struct quic_conn *qc) { struct quic_accept_queue *queue = &quic_accept_queues[qc->tid]; struct li_per_thread *lthr = &qc->li->per_thr[qc->tid]; + /* early return if accept is already in progress/done for this + * connection + */ + if (HA_ATOMIC_BTS(&qc->flags, QUIC_FL_ACCEPT_REGISTERED_BIT)) + return; + BUG_ON(MT_LIST_INLIST(&qc->accept_list)); /* 1. insert the listener in the accept queue