summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2012-02-11 20:30:20 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2012-02-11 20:30:20 +0100
commitd48be90a0614700c075719ba9a8b24276af635a1 (patch)
tree45b1161172e6f2e9f387a797a516c94a68e20845
parentce372826b3bb8d57c04df3708b634f7495a6a86d (diff)
downloadgnutls-d48be90a0614700c075719ba9a8b24276af635a1.tar.gz
use subsecond granularity for DTLS packet retransmissions.
-rw-r--r--lib/gnutls_dtls.c15
-rw-r--r--lib/gnutls_dtls.h15
-rw-r--r--lib/gnutls_int.h6
-rw-r--r--lib/gnutls_state.c3
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