@@ -2489,3 +2489,81 @@ 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+ * This tests relies on timing of the retransmission logic so it may be
2497+ * flaky on very slow systems.
2498+ */
2499+ int test_dtls13_min_rtx_interval (void )
2500+ {
2501+ EXPECT_DECLS ;
2502+ #if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES ) && \
2503+ defined(WOLFSSL_DTLS13 ) && !defined(DTLS13_MIN_RTX_INTERVAL ) && \
2504+ !defined(NO_ASN_TIME )
2505+ /* We don't want to test when DTLS13_MIN_RTX_INTERVAL is defined because
2506+ * it may be too low to trigger reliably in a test. The default value is
2507+ * 1 second which is sufficient for testing here. */
2508+ WOLFSSL_CTX * ctx_c = NULL , * ctx_s = NULL ;
2509+ WOLFSSL * ssl_c = NULL , * ssl_s = NULL ;
2510+ struct test_memio_ctx test_ctx ;
2511+ int c_msg_count = 0 ;
2512+
2513+ XMEMSET (& test_ctx , 0 , sizeof (test_ctx ));
2514+
2515+ /* Setup DTLS 1.3 contexts */
2516+ ExpectIntEQ (test_memio_setup (& test_ctx , & ctx_c , & ctx_s , & ssl_c , & ssl_s ,
2517+ wolfDTLSv1_3_client_method , wolfDTLSv1_3_server_method ), 0 );
2518+
2519+ /* CH0 */
2520+ ExpectIntEQ (wolfSSL_connect (ssl_c ), -1 );
2521+ ExpectIntEQ (wolfSSL_get_error (ssl_c , -1 ), SSL_ERROR_WANT_READ );
2522+
2523+ /* HRR */
2524+ ExpectIntEQ (wolfSSL_accept (ssl_s ), -1 );
2525+ ExpectIntEQ (wolfSSL_get_error (ssl_s , -1 ), SSL_ERROR_WANT_READ );
2526+
2527+ /* CH1 */
2528+ ExpectIntEQ (wolfSSL_connect (ssl_c ), -1 );
2529+ ExpectIntEQ (wolfSSL_get_error (ssl_c , -1 ), SSL_ERROR_WANT_READ );
2530+
2531+ /* SH ... FINISHED */
2532+ ExpectIntEQ (wolfSSL_accept (ssl_s ), -1 );
2533+ ExpectIntEQ (wolfSSL_get_error (ssl_s , -1 ), SSL_ERROR_WANT_READ );
2534+
2535+ /* We should have SH ... FINISHED messages in the buffer */
2536+ ExpectIntGE (test_ctx .c_msg_count , 2 );
2537+
2538+ /* Drop everything */
2539+ test_memio_clear_buffer (& test_ctx , 1 );
2540+
2541+ /* First timeout. This one should trigger a retransmission */
2542+ if (wolfSSL_dtls13_use_quick_timeout (ssl_s ))
2543+ ExpectIntEQ (wolfSSL_dtls_got_timeout (ssl_s ), WOLFSSL_SUCCESS );
2544+ ExpectIntEQ (wolfSSL_dtls_got_timeout (ssl_s ), WOLFSSL_SUCCESS );
2545+ /* Save the message count to make sure no new messages are sent */
2546+ ExpectIntGE (test_ctx .c_msg_count , 2 );
2547+ c_msg_count = test_ctx .c_msg_count ;
2548+
2549+ /* Second timeout. This one should not trigger a retransmission */
2550+ if (wolfSSL_dtls13_use_quick_timeout (ssl_s ))
2551+ ExpectIntEQ (wolfSSL_dtls_got_timeout (ssl_s ), WOLFSSL_SUCCESS );
2552+ ExpectIntEQ (wolfSSL_dtls_got_timeout (ssl_s ), WOLFSSL_SUCCESS );
2553+ /* This is the critical check. The message count should not increase
2554+ * after the second timeout. DTLS13_MIN_RTX_INTERVAL should have blocked
2555+ * retransmission here. */
2556+ ExpectIntEQ (c_msg_count , test_ctx .c_msg_count );
2557+
2558+ /* Now complete the handshake. We didn't clear the first retransmission
2559+ * so the handshake should proceed without issues. */
2560+ ExpectIntEQ (test_memio_do_handshake (ssl_c , ssl_s , 10 , NULL ), 0 );
2561+
2562+ /* Cleanup */
2563+ wolfSSL_free (ssl_c );
2564+ wolfSSL_CTX_free (ctx_c );
2565+ wolfSSL_free (ssl_s );
2566+ wolfSSL_CTX_free (ctx_s );
2567+ #endif
2568+ return EXPECT_RESULT ();
2569+ }
0 commit comments