summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/gnutls_int.h4
-rw-r--r--lib/handshake.c19
-rw-r--r--lib/handshake.h17
-rw-r--r--lib/state.c3
4 files changed, 32 insertions, 11 deletions
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 50a9208346..cccc3d1a97 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -1303,7 +1303,9 @@ typedef struct {
/* starting time of current handshake */
struct timespec handshake_start_time;
- time_t handshake_endtime; /* end time in seconds */
+ /* end time of current handshake */
+ struct timespec handshake_endtime;
+
unsigned int handshake_timeout_ms; /* timeout in milliseconds */
unsigned int record_timeout_ms; /* timeout in milliseconds */
diff --git a/lib/handshake.c b/lib/handshake.c
index 5080756c28..d83a51c9bb 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -2737,6 +2737,10 @@ int gnutls_handshake(gnutls_session_t session)
}
if (STATE == STATE0) {
+ unsigned int tmo_ms;
+ struct timespec *end;
+ struct timespec *start;
+
/* first call */
if (session->internals.priorities == NULL ||
session->internals.priorities->cs.size == 0)
@@ -2752,10 +2756,17 @@ int gnutls_handshake(gnutls_session_t session)
session->internals.handshake_in_progress = 1;
session->internals.vc_status = -1;
gnutls_gettime(&session->internals.handshake_start_time);
- if (session->internals.handshake_timeout_ms &&
- session->internals.handshake_endtime == 0)
- session->internals.handshake_endtime = session->internals.handshake_start_time.tv_sec +
- session->internals.handshake_timeout_ms / 1000;
+
+ tmo_ms = session->internals.handshake_timeout_ms;
+ end = &session->internals.handshake_endtime;
+ start = &session->internals.handshake_start_time;
+
+ if (tmo_ms && end->tv_sec == 0 && end->tv_nsec == 0) {
+ end->tv_sec =
+ start->tv_sec + (start->tv_nsec + tmo_ms * 1000000LL) / 1000000000LL;
+ end->tv_nsec =
+ (start->tv_nsec + tmo_ms * 1000000LL) % 1000000000LL;
+ }
}
if (session->internals.recv_state == RECV_STATE_FALSE_START) {
diff --git a/lib/handshake.h b/lib/handshake.h
index a82263aad1..11c310f33c 100644
--- a/lib/handshake.h
+++ b/lib/handshake.h
@@ -112,16 +112,23 @@ int _gnutls13_handshake_hash_buffers_synth(gnutls_session_t session,
#define FAGAIN(target) (FINAL_STATE==target?1:0)
#define AGAIN2(state, target) (state==target?1:0)
+/* return the remaining time in ms */
inline static int handshake_remaining_time(gnutls_session_t session)
{
- if (session->internals.handshake_endtime) {
+ struct timespec *end = &session->internals.handshake_endtime;
+
+ if (end->tv_sec || end->tv_nsec) {
struct timespec now;
gnutls_gettime(&now);
- if (now.tv_sec < session->internals.handshake_endtime)
- return (session->internals.handshake_endtime -
- now.tv_sec) * 1000;
- else
+ if (now.tv_sec < end->tv_sec ||
+ (now.tv_sec == end->tv_sec && now.tv_nsec < end->tv_nsec))
+ {
+ long long now_ms = now.tv_sec * 1000LL + now.tv_nsec / 1000000;
+ long long end_ms = end->tv_sec * 1000LL + end->tv_nsec / 1000000;
+
+ return end_ms - now_ms;
+ } else
return gnutls_assert_val(GNUTLS_E_TIMEDOUT);
}
return 0;
diff --git a/lib/state.c b/lib/state.c
index a60544737a..392183c95f 100644
--- a/lib/state.c
+++ b/lib/state.c
@@ -430,7 +430,8 @@ void _gnutls_handshake_internal_state_clear(gnutls_session_t session)
_gnutls_epoch_gc(session);
- session->internals.handshake_endtime = 0;
+ session->internals.handshake_endtime.tv_sec = 0;
+ session->internals.handshake_endtime.tv_nsec = 0;
session->internals.handshake_in_progress = 0;
session->internals.tfo.connect_addrlen = 0;