From cadb232e937040741103039c37f997d6fa6677e7 Mon Sep 17 00:00:00 2001 From: Emeric Brun Date: Tue, 11 Jul 2023 16:13:19 +0200 Subject: [PATCH] BUG/MEDIUM: quic: timestamp shared in token was using internal time clock The internal tick clock was used to export the timestamp int the token on retry packets. Doing this in cluster mode the nodes don't understand the timestamp from tokens generated by others. This patch re-work this using the the real current date (wall-clock time). Timestamp are also now considered in secondes instead of milleseconds. This patch should be backported until v2.6 --- include/haproxy/quic_conn-t.h | 2 +- src/quic_conn.c | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/haproxy/quic_conn-t.h b/include/haproxy/quic_conn-t.h index b5ca429c9..dea013d90 100644 --- a/include/haproxy/quic_conn-t.h +++ b/include/haproxy/quic_conn-t.h @@ -92,7 +92,7 @@ typedef unsigned long long ull; /* Salt length used to derive retry token secret */ #define QUIC_RETRY_TOKEN_SALTLEN 16 /* bytes */ /* Retry token duration */ -#define QUIC_RETRY_DURATION_MS 10000 +#define QUIC_RETRY_DURATION_SEC 10 /* Default Retry threshold */ #define QUIC_DFLT_RETRY_THRESHOLD 100 /* in connection openings */ /* Default limit of loss detection on a single frame. If exceeded, connection is closed. */ diff --git a/src/quic_conn.c b/src/quic_conn.c index a64b967f6..3edfef767 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -5389,6 +5389,7 @@ static int parse_retry_token(struct quic_conn *qc, int ret = 0; uint64_t odcid_len; uint32_t timestamp; + uint32_t now_sec = (uint32_t)date.tv_sec; TRACE_ENTER(QUIC_EV_CONN_LPKT, qc); @@ -5414,7 +5415,11 @@ static int parse_retry_token(struct quic_conn *qc, } timestamp = ntohl(read_u32(token + odcid_len)); - if (tick_is_expired(tick_add(timestamp, MS_TO_TICKS(QUIC_RETRY_DURATION_MS)), now_ms)) { + /* check if elapsed time is +/- QUIC_RETRY_DURATION_SEC + * to tolerate token generator is not perfectly time synced + */ + if ((uint32_t)(now_sec - timestamp) > QUIC_RETRY_DURATION_SEC && + (uint32_t)(timestamp - now_sec) > QUIC_RETRY_DURATION_SEC) { TRACE_ERROR("token has expired", QUIC_EV_CONN_LPKT, qc); goto leave; } @@ -6358,7 +6363,7 @@ static int quic_generate_retry_token(unsigned char *token, size_t len, size_t seclen = strlen(global.cluster_secret); EVP_CIPHER_CTX *ctx = NULL; const EVP_CIPHER *aead = EVP_aes_128_gcm(); - uint32_t timestamp = now_ms; + uint32_t timestamp = (uint32_t)date.tv_sec; TRACE_ENTER(QUIC_EV_CONN_TXPKT);