From fa4b82cc7cc556c03c652d40bd966ef3d4445592 Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Wed, 6 Sep 2017 08:30:00 +0200 Subject: add callback handler for setting DTLS timer interval Reviewed-by: Matt Caswell Reviewed-by: Bernd Edlinger (Merged from https://github.com/openssl/openssl/pull/4011) --- ssl/d1_lib.c | 49 +++++++++++++++++++++++++++++++++++++++++-------- ssl/ssl_locl.h | 6 +++++- 2 files changed, 46 insertions(+), 9 deletions(-) (limited to 'ssl') diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index d839e1a..a8ea097 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -161,6 +161,8 @@ int dtls1_clear(SSL *s) DTLS_RECORD_LAYER_clear(&s->rlayer); if (s->d1) { + DTLS_timer_cb timer_cb = s->d1->timer_cb; + buffered_messages = s->d1->buffered_messages; sent_messages = s->d1->sent_messages; mtu = s->d1->mtu; @@ -170,6 +172,9 @@ int dtls1_clear(SSL *s) memset(s->d1, 0, sizeof(*s->d1)); + /* Restore the timer callback from previous state */ + s->d1->timer_cb = timer_cb; + if (s->server) { s->d1->cookie_len = sizeof(s->d1->cookie); } @@ -236,6 +241,8 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) void dtls1_start_timer(SSL *s) { + unsigned int sec, usec; + #ifndef OPENSSL_NO_SCTP /* Disable timer for SCTP */ if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { @@ -244,16 +251,34 @@ void dtls1_start_timer(SSL *s) } #endif - /* If timer is not set, initialize duration with 1 second */ + /* + * If timer is not set, initialize duration with 1 second or + * a user-specified value if the timer callback is installed. + */ if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { - s->d1->timeout_duration = 1; + + if (s->d1->timer_cb != NULL) + s->d1->timeout_duration_us = s->d1->timer_cb(s, 0); + else + s->d1->timeout_duration_us = 1000000; } /* Set timeout to current time */ get_current_time(&(s->d1->next_timeout)); /* Add duration to current time */ - s->d1->next_timeout.tv_sec += s->d1->timeout_duration; + + sec = s->d1->timeout_duration_us / 1000000; + usec = s->d1->timeout_duration_us - (sec * 1000000); + + s->d1->next_timeout.tv_sec += sec; + s->d1->next_timeout.tv_usec += usec; + + if (s->d1->next_timeout.tv_usec >= 1000000) { + s->d1->next_timeout.tv_sec++; + s->d1->next_timeout.tv_usec -= 1000000; + } + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); } @@ -318,9 +343,9 @@ int dtls1_is_timer_expired(SSL *s) void dtls1_double_timeout(SSL *s) { - s->d1->timeout_duration *= 2; - if (s->d1->timeout_duration > 60) - s->d1->timeout_duration = 60; + s->d1->timeout_duration_us *= 2; + if (s->d1->timeout_duration_us > 60000000) + s->d1->timeout_duration_us = 60000000; dtls1_start_timer(s); } @@ -329,7 +354,7 @@ void dtls1_stop_timer(SSL *s) /* Reset everything */ memset(&s->d1->timeout, 0, sizeof(s->d1->timeout)); memset(&s->d1->next_timeout, 0, sizeof(s->d1->next_timeout)); - s->d1->timeout_duration = 1; + s->d1->timeout_duration_us = 1000000; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); /* Clear retransmission buffer */ @@ -367,7 +392,10 @@ int dtls1_handle_timeout(SSL *s) return 0; } - dtls1_double_timeout(s); + if (s->d1->timer_cb != NULL) + s->d1->timeout_duration_us = s->d1->timer_cb(s, s->d1->timeout_duration_us); + else + dtls1_double_timeout(s); if (dtls1_check_timeout_num(s) < 0) return -1; @@ -952,3 +980,8 @@ size_t DTLS_get_data_mtu(const SSL *s) return mtu; } + +void DTLS_set_timer_cb(SSL *s, DTLS_timer_cb cb) +{ + s->d1->timer_cb = cb; +} diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index a0127cf..59fba61 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1624,11 +1624,15 @@ typedef struct dtls1_state_st { */ struct timeval next_timeout; /* Timeout duration */ - unsigned short timeout_duration; + unsigned int timeout_duration_us; + unsigned int retransmitting; # ifndef OPENSSL_NO_SCTP int shutdown_received; # endif + + DTLS_timer_cb timer_cb; + } DTLS1_STATE; # ifndef OPENSSL_NO_EC -- cgit v1.1