diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-02-11 20:30:20 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-02-11 20:30:20 +0100 |
commit | d48be90a0614700c075719ba9a8b24276af635a1 (patch) | |
tree | 45b1161172e6f2e9f387a797a516c94a68e20845 | |
parent | ce372826b3bb8d57c04df3708b634f7495a6a86d (diff) | |
download | gnutls-d48be90a0614700c075719ba9a8b24276af635a1.tar.gz |
use subsecond granularity for DTLS packet retransmissions.
-rw-r--r-- | lib/gnutls_dtls.c | 15 | ||||
-rw-r--r-- | lib/gnutls_dtls.h | 15 | ||||
-rw-r--r-- | lib/gnutls_int.h | 6 | ||||
-rw-r--r-- | lib/gnutls_state.c | 3 |
4 files changed, 24 insertions, 15 deletions
diff --git a/lib/gnutls_dtls.c b/lib/gnutls_dtls.c index 1dd3ccbbfc..465225201f 100644 --- a/lib/gnutls_dtls.c +++ b/lib/gnutls_dtls.c @@ -34,7 +34,7 @@ #include <gnutls_constate.h> #include <gnutls_state.h> #include <gnutls/dtls.h> - +#include <timespec.h> /* This function fragments and transmits a previously buffered * outgoing message. It accepts mtu_data which is a buffer to @@ -183,7 +183,9 @@ unsigned int timeout; &session->internals.handshake_send_buffer; mbuffer_st *cur; gnutls_handshake_description_t last_type = 0; - time_t now = gnutls_time (0); + struct timespec now; + + gettime(&now); /* If we have already sent a flight and we are operating in a * non blocking way, check if it is time to retransmit or just @@ -207,10 +209,8 @@ unsigned int timeout; { /* if no retransmission is required yet just return */ - if (1000*(now-session->internals.dtls.handshake_start_time) < - session->internals.dtls.actual_retrans_timeout_ms) + if (timespec_sub_ms(&now, &session->internals.dtls.handshake_start_time) < session->internals.dtls.actual_retrans_timeout_ms) { - session->internals.dtls.handshake_last_call = now; gnutls_assert(); goto nb_timeout; } @@ -227,7 +227,7 @@ unsigned int timeout; do { - if (1000*(now-session->internals.dtls.handshake_start_time) >= session->internals.dtls.total_timeout_ms) + if (timespec_sub_ms(&now, &session->internals.dtls.handshake_start_time) >= session->internals.dtls.total_timeout_ms) { ret = gnutls_assert_val(GNUTLS_E_TIMEDOUT); goto end_flight; @@ -251,7 +251,6 @@ unsigned int timeout; if (session->internals.dtls.flight_init == 0) { session->internals.dtls.flight_init = 1; - session->internals.dtls.handshake_last_call = now; RESET_TIMER; timeout = session->internals.dtls.actual_retrans_timeout_ms; @@ -304,7 +303,7 @@ unsigned int timeout; } } - now = gnutls_time (0); + gettime(&now); } while(ret == GNUTLS_E_TIMEDOUT); if (ret < 0) diff --git a/lib/gnutls_dtls.h b/lib/gnutls_dtls.h index 3c8754fa9d..95e63b8521 100644 --- a/lib/gnutls_dtls.h +++ b/lib/gnutls_dtls.h @@ -23,9 +23,11 @@ #ifndef DTLS_H # define DTLS_H +#include <config.h> #include "gnutls_int.h" #include "gnutls_buffers.h" #include "gnutls_mbuffers.h" +#include <timespec.h> int _dtls_transmit(gnutls_session_t session); int _dtls_retransmit(gnutls_session_t session); @@ -33,9 +35,18 @@ int _dtls_record_check(gnutls_session_t session, uint64 * _seq); #define MAX_DTLS_TIMEOUT 60000 +/* returns a-b in ms */ +inline static unsigned int timespec_sub_ms(struct timespec *a, struct timespec *b) +{ + return (a->tv_sec * 1000 + a->tv_nsec / (1000 * 1000) - + (b->tv_sec * 1000 + b->tv_nsec / (1000 * 1000))); +} + #define RETURN_DTLS_EAGAIN_OR_TIMEOUT(session) { \ - if (gnutls_time(0) - session->internals.dtls.handshake_start_time > \ - session->internals.dtls.total_timeout_ms/1000) \ + struct timespec now; \ + gettime(&now); \ + \ + if (timespec_sub_ms(&now, &session->internals.dtls.handshake_start_time) > session->internals.dtls.total_timeout_ms) \ return gnutls_assert_val(GNUTLS_E_TIMEDOUT); \ else \ { \ diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index d99354449a..578e355a8b 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -625,10 +625,8 @@ typedef struct /* non blocking stuff variables */ unsigned int blocking:1; - /* starting time of current handshake - seconds since epoch */ - time_t handshake_start_time; - /* time in seconds of the last handshake call */ - time_t handshake_last_call; + /* starting time of current handshake */ + struct timespec handshake_start_time; /* The actual retrans_timeout for the next message (e.g. doubled or so) */ diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index e5790dd7e7..3588d2e18a 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -46,6 +46,7 @@ #include <gnutls_extensions.h> #include <system.h> #include <gnutls/dtls.h> +#include <timespec.h> /* These should really be static, but src/tests.c calls them. Make them public functions? */ @@ -263,7 +264,7 @@ _gnutls_handshake_internal_state_init (gnutls_session_t session) session->internals.dtls.hsk_read_seq = 0; session->internals.dtls.hsk_write_seq = 0; - session->internals.dtls.handshake_start_time = gnutls_time(0); + gettime(&session->internals.dtls.handshake_start_time); } void |