From: Frédéric Lécaille Date: Fri, 28 Jan 2022 20:43:48 +0000 (+0100) Subject: MINOR: quic: Do not try to accept a connection more than one time X-Git-Tag: v2.6-dev1~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91f083a365b56cbfa993281031b6b9c66eba278a;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/include/haproxy/xprt_quic-t.h b/include/haproxy/xprt_quic-t.h index 157d81d456..0f1004fd84 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 5533b01d5e..087a65dedb 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