From 91f083a365b56cbfa993281031b6b9c66eba278a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Fri, 28 Jan 2022 21:43:48 +0100 Subject: [PATCH] MINOR: quic: Do not try to accept a connection more than one time We add a new flag to mark a connection as already enqueued for acception. This is useful for 0-RTT session where a connection is first enqueued for acception as soon as 0-RTT RX secrets could be derived. Then as for any other connection, we could accept one more time this connection after handshake completion which lead to very bad side effects. Thank you to Amaury for this nice patch. --- include/haproxy/xprt_quic-t.h | 2 ++ src/quic_sock.c | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) 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