summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Rühsen <tim.ruehsen@gmx.de>2018-12-04 17:15:02 +0100
committerTim Rühsen <tim.ruehsen@gmx.de>2018-12-06 16:13:00 +0100
commit3507f23cec212506da3c6836dbb159df4b41439f (patch)
treeff2f02ed31c2473c6fc795864ba98d758cce5c49
parent493723ee38cd817a60f25bb0bea505c80b22407c (diff)
downloadgnutls-3507f23cec212506da3c6836dbb159df4b41439f.tar.gz
Fix gnutls_handshake_set_timeout() for values < 1000tmp-fix-timeout
handshake-timeout.c now tests for <1000ms timeout and for >=1000ms timeout. The test duration decreased from 45s to 1.2s. Signed-off-by: Tim Rühsen <tim.ruehsen@gmx.de>
-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
-rw-r--r--tests/handshake-timeout.c38
5 files changed, 55 insertions, 26 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;
diff --git a/tests/handshake-timeout.c b/tests/handshake-timeout.c
index 52c21f69b4..92a398cce0 100644
--- a/tests/handshake-timeout.c
+++ b/tests/handshake-timeout.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#if defined(_WIN32)
@@ -61,7 +62,7 @@ static void client_log_func(int level, const char *str)
fprintf(stderr, "client|<%d>| %s", level, str);
}
-static void client(int fd, int wait)
+static void client(int fd, int tmo_ms)
{
int ret;
gnutls_anon_client_credentials_t anoncred;
@@ -79,7 +80,7 @@ static void client(int fd, int wait)
/* Initialize TLS session
*/
gnutls_init(&session, GNUTLS_CLIENT);
- gnutls_handshake_set_timeout(session, 20 * 1000);
+ gnutls_handshake_set_timeout(session, tmo_ms);
/* Use default priorities */
gnutls_priority_set_direct(session, "NORMAL:+ANON-ECDH:-VERS-ALL:+VERS-TLS1.2", NULL);
@@ -102,7 +103,7 @@ static void client(int fd, int wait)
gnutls_global_deinit();
if (ret < 0) {
- if (ret != GNUTLS_E_TIMEDOUT || wait == 0) {
+ if (ret != GNUTLS_E_TIMEDOUT || tmo_ms == 0) {
if (debug)
fail("client: unexpected error: %s\n",
gnutls_strerror(ret));
@@ -110,19 +111,19 @@ static void client(int fd, int wait)
}
if (debug)
success("client: expected timeout occurred\n");
- return;
} else {
- if (wait != 0) {
+ if (tmo_ms != 0) {
fail("client: handshake was completed unexpectedly\n");
gnutls_perror(ret);
exit(1);
}
}
+ shutdown(fd, SHUT_RDWR);
return;
}
-static void server(int fd, int wait)
+static void server(int fd, int tmo_ms)
{
int ret;
gnutls_session_t session;
@@ -150,8 +151,12 @@ static void server(int fd, int wait)
gnutls_transport_set_int(session, fd);
- if (wait) {
- sec_sleep(25);
+ if (tmo_ms) {
+ char buf[32];
+
+ // read until client closes connection
+ while (read(fd, buf, sizeof(buf)) > 0)
+ ;
} else {
do {
ret = gnutls_handshake(session);
@@ -167,14 +172,14 @@ static void server(int fd, int wait)
gnutls_global_deinit();
}
-static void start(int wait_flag)
+static void start(int tmo_ms)
{
int fd[2];
int ret;
pid_t child;
- if (debug && wait_flag)
- fprintf(stderr, "\nWill test timeout\n");
+ if (debug && tmo_ms)
+ fprintf(stderr, "\nWill test timeout %dms\n", tmo_ms);
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
if (ret < 0) {
@@ -193,14 +198,14 @@ static void start(int wait_flag)
int status = 0;
/* parent */
close(fd[1]);
- server(fd[0], wait_flag);
+ server(fd[0], tmo_ms);
close(fd[0]);
wait(&status);
check_wait_status(status);
} else {
close(fd[0]);
- client(fd[1], wait_flag);
+ client(fd[1], tmo_ms);
close(fd[1]);
exit(0);
}
@@ -219,8 +224,11 @@ void doit(void)
/* make sure that normal handshake occurs */
start(0);
- /* check the handshake with an expected timeout */
- start(1);
+ /* check the handshake with a 100ms timeout */
+ start(100);
+
+ /* check the handshake with a 1000ms timeout */
+ start(1000);
}
#endif /* _WIN32 */