From d3083c9df93e489d3c030c1f97fbd4ca5a545dfe Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Thu, 1 Dec 2022 16:20:06 +0100 Subject: [PATCH] MINOR: quic: reconnect quic-conn socket on address migration UDP addresses may change over time for a QUIC connection. When using quic-conn owned socket, we have to detect address change to break the bind/connect association on the socket. For the moment, on change detected, QUIC connection socket is closed and a new one is opened. In the future, we may improve this by trying to keep the original socket and reexecute only bind/connect syscalls. This change is part of quic-conn owned socket implementation. It may be backported to 2.7 after a period of observation. --- include/haproxy/quic_sock.h | 2 +- src/quic_conn.c | 12 +++++++++++- src/quic_sock.c | 9 +++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/include/haproxy/quic_sock.h b/include/haproxy/quic_sock.h index f7b0eb5eb..55ea170a1 100644 --- a/include/haproxy/quic_sock.h +++ b/include/haproxy/quic_sock.h @@ -63,7 +63,7 @@ static inline char qc_test_fd(struct quic_conn *qc) void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src, const struct sockaddr_storage *dst); -void qc_release_fd(struct quic_conn *qc); +void qc_release_fd(struct quic_conn *qc, int reinit); void quic_accept_push_qc(struct quic_conn *qc); diff --git a/src/quic_conn.c b/src/quic_conn.c index f86ad4b2a..0fc2f5eb9 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -4960,7 +4960,7 @@ void quic_conn_release(struct quic_conn *qc) BUG_ON(qc->mux_state == QC_MUX_READY); /* Close quic-conn socket fd. */ - qc_release_fd(qc); + qc_release_fd(qc, 0); /* in the unlikely (but possible) case the connection was just added to * the accept_list we must delete it from there. @@ -6369,6 +6369,16 @@ static int qc_handle_conn_migration(struct quic_conn *qc, * peer's address, unless it has previously validated that address. */ + /* Update quic-conn owned socket if in used. + * TODO try to reuse it instead of closing and opening a new one. + */ + if (qc_test_fd(qc)) { + /* TODO try to reuse socket instead of closing it and opening a new one. */ + TRACE_STATE("Connection migration detected, allocate a new connection socket", QUIC_EV_CONN_LPKT, qc); + qc_release_fd(qc, 1); + qc_alloc_fd(qc, local_addr, peer_addr); + } + qc->local_addr = *local_addr; qc->peer_addr = *peer_addr; HA_ATOMIC_INC(&qc->prx_counters->conn_migration_done); diff --git a/src/quic_sock.c b/src/quic_sock.c index 284c9614d..cbd5e77d6 100644 --- a/src/quic_sock.c +++ b/src/quic_sock.c @@ -748,12 +748,17 @@ void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src, close(fd); } -/* Release socket file-descriptor specific for QUIC connection . */ -void qc_release_fd(struct quic_conn *qc) +/* Release socket file-descriptor specific for QUIC connection . Set + * if socket should be reinitialized after address migration. + */ +void qc_release_fd(struct quic_conn *qc, int reinit) { if (qc_test_fd(qc)) { fd_delete(qc->fd); qc->fd = DEAD_FD_MAGIC; + + if (reinit) + qc_init_fd(qc); } }