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
(cherry picked from commit cadb232e937040741103039c37f997d6fa6677e7)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/include/haproxy/quic_conn-t.h b/include/haproxy/quic_conn-t.h
index 58a3334..7a99013 100644
--- a/include/haproxy/quic_conn-t.h
+++ b/include/haproxy/quic_conn-t.h
@@ -92,7 +92,7 @@
/* 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 ecb4845..2b7e220 100644
--- a/src/quic_conn.c
+++ b/src/quic_conn.c
@@ -5459,6 +5459,7 @@
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);
@@ -5484,7 +5485,11 @@
}
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;
}
@@ -6402,7 +6407,7 @@
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);