]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: quic: timestamp shared in token was using internal time clock
authorEmeric Brun <ebrun@haproxy.com>
Tue, 11 Jul 2023 14:13:19 +0000 (16:13 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 12 Jul 2023 12:32:01 +0000 (14:32 +0200)
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
src/quic_conn.c

index b5ca429c97e23b04ff2dc6f995d186a996b18343..dea013d904254f5d2a3bb086459d730af60918eb 100644 (file)
@@ -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. */
index a64b967f64528d0eb57c205db6d31b351c9a7e7e..3edfef767211016fc272963f00fe4251aeb03711 100644 (file)
@@ -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);