Skip to content

Commit f05ebc0

Browse files
committed
Apply connect_timeout to TLS handshake
SSL_connect() blocks indefinitely when connecting with TLS to a non-TLS server. Apply the connect_timeout as a socket timeout around the SSL_connect() call for blocking connections. Signed-off-by: Björn Svensson <bjorn.a.svensson@est.tech>
1 parent b9285b5 commit f05ebc0

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

src/tls.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,23 @@ static int valkeyTLSConnect(valkeyContext *c, SSL *ssl) {
376376

377377
ERR_clear_error();
378378

379+
/* Apply connect_timeout to the TLS handshake. */
380+
if ((c->flags & VALKEY_BLOCK) && c->connect_timeout != NULL) {
381+
c->funcs->set_timeout(c, *c->connect_timeout);
382+
}
383+
379384
int rv = SSL_connect(rssl->ssl);
385+
386+
/* Restore the command_timeout. */
387+
if ((c->flags & VALKEY_BLOCK) && c->connect_timeout != NULL) {
388+
if (c->command_timeout != NULL) {
389+
c->funcs->set_timeout(c, *c->command_timeout);
390+
} else {
391+
struct timeval tv_zero = {0, 0};
392+
c->funcs->set_timeout(c, tv_zero);
393+
}
394+
}
395+
380396
if (rv == 1) {
381397
c->funcs = &valkeyContextTLSFuncs;
382398
c->privctx = rssl;

tests/client_test.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2676,6 +2676,36 @@ static void sharded_pubsub_test(struct config cfg) {
26762676
}
26772677
#endif /* VALKEY_TEST_ASYNC */
26782678

2679+
#ifdef VALKEY_TEST_TLS
2680+
/* Test that a TLS handshake to a non-TLS server times out using
2681+
* connect_timeout rather than hanging indefinitely. */
2682+
static void test_tls_handshake_timeout(struct config config) {
2683+
test("TLS handshake to non-TLS port times out with connect_timeout: ");
2684+
2685+
#ifndef _WIN32
2686+
/* Abort the test after 5 seconds. */
2687+
unsigned int old_alarm = alarm(5);
2688+
#endif
2689+
2690+
struct timeval tv = {0, 100000}; /* 100ms */
2691+
valkeyOptions opt = {0};
2692+
VALKEY_OPTIONS_SET_TCP(&opt, config.tcp.host, config.tcp.port); /* TCP */
2693+
opt.connect_timeout = &tv;
2694+
/* No command timeout set. */
2695+
2696+
valkeyContext *c = valkeyConnectWithOptions(&opt);
2697+
assert(c != NULL && c->err == 0);
2698+
2699+
int rc = valkeyInitiateTLSWithContext(c, _tls_ctx);
2700+
test_cond(rc == VALKEY_ERR && c->err != 0);
2701+
valkeyFree(c);
2702+
2703+
#ifndef _WIN32
2704+
alarm(old_alarm); /* Reset any alarm. */
2705+
#endif
2706+
}
2707+
#endif /* VALKEY_TEST_TLS */
2708+
26792709
int main(int argc, char **argv) {
26802710
struct config cfg = {
26812711
.tcp = {
@@ -2840,6 +2870,7 @@ int main(int argc, char **argv) {
28402870
test_blocking_io_errors(cfg);
28412871
test_invalid_timeout_errors(cfg);
28422872
test_append_formatted_commands(cfg);
2873+
test_tls_handshake_timeout(cfg);
28432874
if (throughput)
28442875
test_throughput(cfg);
28452876

0 commit comments

Comments
 (0)