Skip to content

Commit d8b2992

Browse files
committed
dtls 1.3: allow rtx interval to be less than a second
1 parent eab58ae commit d8b2992

File tree

5 files changed

+96
-7
lines changed

5 files changed

+96
-7
lines changed

src/dtls13.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ typedef struct Dtls13RecordPlaintextHeader {
110110
supported. */
111111
#define DTLS13_UNIFIED_HEADER_SIZE 5
112112
#define DTLS13_MIN_CIPHERTEXT 16
113-
#define DTLS13_MIN_RTX_INTERVAL 1
113+
#ifndef DTLS13_MIN_RTX_INTERVAL
114+
#define DTLS13_MIN_RTX_INTERVAL 1000
115+
#endif
114116

115117
#ifndef NO_WOLFSSL_CLIENT
116118
WOLFSSL_METHOD* wolfDTLSv1_3_client_method_ex(void* heap)
@@ -1570,21 +1572,24 @@ static int Dtls13RtxSendBuffered(WOLFSSL* ssl)
15701572
int isLast;
15711573
int sendSz;
15721574
#ifndef NO_ASN_TIME
1575+
#ifdef WOLFSSL_32BIT_MILLI_TIME
15731576
word32 now;
1577+
#else
1578+
sword64 now;
1579+
#endif
15741580
#endif
15751581
int ret;
15761582

15771583
WOLFSSL_ENTER("Dtls13RtxSendBuffered");
15781584

15791585
#ifndef NO_ASN_TIME
1580-
now = LowResTimer();
1586+
now = TimeNowInMilliseconds();
15811587
if (now - ssl->dtls13Rtx.lastRtx < DTLS13_MIN_RTX_INTERVAL) {
15821588
#ifdef WOLFSSL_DEBUG_TLS
15831589
WOLFSSL_MSG("Avoid too fast retransmission");
15841590
#endif /* WOLFSSL_DEBUG_TLS */
15851591
return 0;
15861592
}
1587-
15881593
ssl->dtls13Rtx.lastRtx = now;
15891594
#endif
15901595

src/tls13.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,7 +1665,7 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
16651665
return ret;
16661666
}
16671667

1668-
#if (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
1668+
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) || defined(WOLFSSL_DTLS13)
16691669
#ifdef WOLFSSL_32BIT_MILLI_TIME
16701670
#ifndef NO_ASN_TIME
16711671
#if defined(USER_TICKS)
@@ -2264,7 +2264,7 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
22642264
*/
22652265
#endif /* !NO_ASN_TIME */
22662266
#endif /* WOLFSSL_32BIT_MILLI_TIME */
2267-
#endif /* HAVE_SESSION_TICKET || !NO_PSK */
2267+
#endif /* HAVE_SESSION_TICKET || !NO_PSK || WOLFSSL_DTLS13 */
22682268

22692269
/* Add record layer header to message.
22702270
*

tests/api/test_dtls.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2489,3 +2489,80 @@ int test_dtls_mtu_split_messages(void)
24892489
return TEST_SKIPPED;
24902490
#endif
24912491
}
2492+
2493+
/* Test DTLS 1.3 minimum retransmission interval. This test calls
2494+
* wolfSSL_dtls_got_timeout() to simulate timeouts and verify that
2495+
* retransmissions are spaced at least DTLS13_MIN_RTX_INTERVAL apart.
2496+
*/
2497+
int test_dtls13_min_rtx_interval(void)
2498+
{
2499+
EXPECT_DECLS;
2500+
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
2501+
defined(WOLFSSL_DTLS13) && !defined(DTLS13_MIN_RTX_INTERVAL) && \
2502+
!defined(NO_ASN_TIME)
2503+
/* We don't want to test when DTLS13_MIN_RTX_INTERVAL is defined because
2504+
* it may be too low to trigger reliably in a test. The default value is
2505+
* 1 second which is sufficient for testing here. */
2506+
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
2507+
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
2508+
struct test_memio_ctx test_ctx;
2509+
int c_msg_count = 0;
2510+
2511+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
2512+
2513+
/* Setup DTLS 1.3 contexts */
2514+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
2515+
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
2516+
2517+
/* CH0 */
2518+
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
2519+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), SSL_ERROR_WANT_READ);
2520+
2521+
/* HRR */
2522+
ExpectIntEQ(wolfSSL_accept(ssl_s), -1);
2523+
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), SSL_ERROR_WANT_READ);
2524+
2525+
/* CH1 */
2526+
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
2527+
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), SSL_ERROR_WANT_READ);
2528+
2529+
/* SH ... FINISHED */
2530+
ExpectIntEQ(wolfSSL_accept(ssl_s), -1);
2531+
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), SSL_ERROR_WANT_READ);
2532+
2533+
/* We should have SH ... FINISHED messages in the buffer */
2534+
ExpectIntGE(test_ctx.c_msg_count, 2);
2535+
2536+
/* Drop everything */
2537+
test_memio_clear_buffer(&test_ctx, 1);
2538+
2539+
/* First timeout. This one should trigger a retransmission */
2540+
if (wolfSSL_dtls13_use_quick_timeout(ssl_s))
2541+
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), WOLFSSL_SUCCESS);
2542+
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), WOLFSSL_SUCCESS);
2543+
/* Save the message count to make sure no new messages are sent */
2544+
ExpectIntGE(c_msg_count = test_ctx.c_msg_count, 2);
2545+
2546+
/* Second timeout. This one should not trigger a retransmission */
2547+
if (wolfSSL_dtls13_use_quick_timeout(ssl_s))
2548+
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), WOLFSSL_SUCCESS);
2549+
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), WOLFSSL_SUCCESS);
2550+
/* This is the critical check. The message count should not increase
2551+
* after the second timeout. DTLS13_MIN_RTX_INTERVAL should have blocked
2552+
* retransmission here. */
2553+
ExpectIntEQ(c_msg_count, test_ctx.c_msg_count);
2554+
2555+
/* Now complete the handshake. We didn't clear the first retransmission
2556+
* so the handshake should proceed without issues. */
2557+
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
2558+
2559+
/* Cleanup */
2560+
wolfSSL_free(ssl_c);
2561+
wolfSSL_CTX_free(ctx_c);
2562+
wolfSSL_free(ssl_s);
2563+
wolfSSL_CTX_free(ctx_s);
2564+
return EXPECT_RESULT();
2565+
#else
2566+
return TEST_SKIPPED;
2567+
#endif
2568+
}

tests/api/test_dtls.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ int test_dtls_memio_wolfio(void);
4949
int test_dtls_memio_wolfio_stateless(void);
5050
int test_dtls_mtu_fragment_headroom(void);
5151
int test_dtls_mtu_split_messages(void);
52+
int test_dtls13_min_rtx_interval(void);
5253

5354
#define TEST_DTLS_DECLS \
5455
TEST_DECL_GROUP("dtls", test_dtls12_basic_connection_id), \
@@ -77,5 +78,6 @@ int test_dtls_mtu_split_messages(void);
7778
TEST_DECL_GROUP("dtls", test_dtls_memio_wolfio), \
7879
TEST_DECL_GROUP("dtls", test_dtls_mtu_fragment_headroom), \
7980
TEST_DECL_GROUP("dtls", test_dtls_mtu_split_messages), \
80-
TEST_DECL_GROUP("dtls", test_dtls_memio_wolfio_stateless)
81+
TEST_DECL_GROUP("dtls", test_dtls_memio_wolfio_stateless), \
82+
TEST_DECL_GROUP("dtls", test_dtls13_min_rtx_interval)
8183
#endif /* TESTS_API_DTLS_H */

wolfssl/internal.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5773,7 +5773,11 @@ typedef struct Dtls13Rtx {
57735773
Dtls13RtxRecord *rtxRecords;
57745774
Dtls13RtxRecord **rtxRecordTailPtr;
57755775
Dtls13RecordNumber *seenRecords;
5776+
#ifdef WOLFSSL_32BIT_MILLI_TIME
57765777
word32 lastRtx;
5778+
#else
5779+
sword64 lastRtx;
5780+
#endif
57775781
byte triggeredRtxs; /* Unused? */
57785782
byte sendAcks;
57795783
byte retransmit;
@@ -6825,7 +6829,8 @@ WOLFSSL_LOCAL word32 MacSize(const WOLFSSL* ssl);
68256829

68266830
WOLFSSL_LOCAL void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out);
68276831

6828-
#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
6832+
#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || \
6833+
!defined(NO_PSK) || defined(WOLFSSL_DTLS13))
68296834
#ifdef WOLFSSL_32BIT_MILLI_TIME
68306835
WOLFSSL_LOCAL word32 TimeNowInMilliseconds(void);
68316836
#else

0 commit comments

Comments
 (0)