diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 60f32d778..9ff1d4f54 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -831,6 +831,13 @@ struct _ssl_context unsigned long time_limit; #endif +#if defined(POLARSSL_SSL_PROTO_DTLS) + uint32_t hs_timeout_min; /*!< initial value of the handshake + retransmission timeout */ + uint32_t hs_timeout_max; /*!< maximum value of the handshake + retransmission timeout */ +#endif + /* * Record layer (incoming data) */ @@ -1286,6 +1293,25 @@ void ssl_set_dtls_cookies( ssl_context *ssl, void ssl_set_dtls_anti_replay( ssl_context *ssl, char mode ); #endif /* POLARSSL_SSL_DTLS_ANTI_REPLAY */ +#if defined(POLARSSL_SSL_PROTO_DTLS) +/** + * \brief Set retransmit timeout values for the DTLS handshale. + * (DTLS only, no effect on TLS.) + * + * \param ssl SSL context + * \param min Initial timeout value in milliseconds. + * Default: 1000 (1 second). + * \param max Maximum timeout value in milliseconds. + * Default: 60000 (60 seconds). + * + * \note Default values are from RFC 6347 section 4.2.4.1. + * + * \note Higher values for initial timeout may increase average + * handshake latency. Lower values may increase the risk of + * network congestion by causing more retransmissions. + */ +void ssl_set_handshake_timeout( ssl_context *ssl, uint32_t min, uint32_t max ); +#endif /* POLARSSL_SSL_PROTO_DTLS */ /** * \brief Set the session cache callbacks (server-side only) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 308d87714..215f00554 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -117,16 +117,16 @@ static int ssl_double_retransmit_timeout( ssl_context *ssl ) { uint32_t new_timeout; - if( ssl->handshake->retransmit_timeout >= SSL_DTLS_TIMEOUT_DFL_MAX ) + if( ssl->handshake->retransmit_timeout >= ssl->hs_timeout_max ) return( -1 ); new_timeout = 2 * ssl->handshake->retransmit_timeout; /* Avoid arithmetic overflow and range overflow */ if( new_timeout < ssl->handshake->retransmit_timeout || - new_timeout > SSL_DTLS_TIMEOUT_DFL_MAX ) + new_timeout > ssl->hs_timeout_max ) { - new_timeout = SSL_DTLS_TIMEOUT_DFL_MAX; + new_timeout = ssl->hs_timeout_max; } ssl->handshake->retransmit_timeout = new_timeout; @@ -138,7 +138,7 @@ static int ssl_double_retransmit_timeout( ssl_context *ssl ) static void ssl_reset_retransmit_timeout( ssl_context *ssl ) { - ssl->handshake->retransmit_timeout = SSL_DTLS_TIMEOUT_DFL_MIN; + ssl->handshake->retransmit_timeout = ssl->hs_timeout_min; SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", ssl->handshake->retransmit_timeout ) ); } @@ -4535,7 +4535,7 @@ static int ssl_handshake_init( ssl_context *ssl ) #if defined(POLARSSL_SSL_PROTO_DTLS) ssl->handshake->alt_transform_out = ssl->transform_out; - ssl->handshake->retransmit_timeout = SSL_DTLS_TIMEOUT_DFL_MIN; + ssl->handshake->retransmit_timeout = ssl->hs_timeout_min; if( ssl->endpoint == SSL_IS_CLIENT ) ssl->handshake->retransmit_state = SSL_RETRANS_PREPARING; @@ -4647,6 +4647,11 @@ int ssl_init( ssl_context *ssl ) ssl->anti_replay = SSL_ANTI_REPLAY_ENABLED; #endif +#if defined(POLARSSL_SSL_PROTO_DTLS) + ssl->hs_timeout_min = SSL_DTLS_TIMEOUT_DFL_MIN; + ssl->hs_timeout_max = SSL_DTLS_TIMEOUT_DFL_MAX; +#endif + if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) return( ret ); @@ -4871,6 +4876,14 @@ void ssl_set_dtls_anti_replay( ssl_context *ssl, char mode ) } #endif +#if defined(POLARSSL_SSL_PROTO_DTLS) +void ssl_set_handshake_timeout( ssl_context *ssl, uint32_t min, uint32_t max ) +{ + ssl->hs_timeout_min = min; + ssl->hs_timeout_max = max; +} +#endif + void ssl_set_authmode( ssl_context *ssl, int authmode ) { ssl->authmode = authmode;