Skip to content

Commit

Permalink
Deal with DoT servers that take long to connect to
Browse files Browse the repository at this point in the history
(because they might be under attack)
  • Loading branch information
wtoorop committed Feb 21, 2020
1 parent dadddb0 commit d7099f6
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,7 @@ upstream_init(getdns_upstream *upstream,

/* For sharing a socket to this upstream with TCP */
upstream->fd = -1;
upstream->expires = 0;
upstream->tls_obj = NULL;
upstream->tls_session = NULL;
upstream->tls_cipher_list = NULL;
Expand Down
5 changes: 4 additions & 1 deletion src/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,10 @@ typedef struct getdns_upstream {
_getdns_tls_session* tls_session;
getdns_tls_hs_state_t tls_hs_state;
getdns_auth_state_t tls_auth_state;

uint64_t expires; /* Expire time of waiting netreqs.
* This is how long a handshake may
* take.
*/
/* TLS settings */
char *tls_cipher_list;
char *tls_ciphersuites;
Expand Down
26 changes: 21 additions & 5 deletions src/stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@
#define STUB_TCP_ERROR -2

/* Don't currently have access to the context whilst doing handshake */
#define TIMEOUT_TLS 2500
#define MIN_TLS_HS_TIMEOUT 2500
#define MAX_TLS_HS_TIMEOUT 7500
/* Arbritray number of message for EDNS keepalive resend*/
#define EDNS_KEEPALIVE_RESEND 5

Expand Down Expand Up @@ -981,21 +982,31 @@ tls_do_handshake(getdns_upstream *upstream)
int r;
while ((r = _getdns_tls_connection_do_handshake(upstream->tls_obj)) != GETDNS_RETURN_GOOD)
{
uint64_t timeout_tls = _getdns_ms_until_expiry(upstream->expires);

if (timeout_tls < MIN_TLS_HS_TIMEOUT)
timeout_tls = MIN_TLS_HS_TIMEOUT;
else if (timeout_tls > MAX_TLS_HS_TIMEOUT)
timeout_tls = MAX_TLS_HS_TIMEOUT;

DEBUG_STUB("%s %-35s: FD: %d, do_handshake -> %d (timeout: %d)\n",
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd, r, (int)timeout_tls);

switch (r) {
case GETDNS_RETURN_TLS_WANT_READ:
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
upstream->event.read_cb = upstream_read_cb;
upstream->event.write_cb = NULL;
GETDNS_SCHEDULE_EVENT(upstream->loop,
upstream->fd, TIMEOUT_TLS, &upstream->event);
upstream->fd, timeout_tls, &upstream->event);
upstream->tls_hs_state = GETDNS_HS_READ;
return STUB_TCP_RETRY;
case GETDNS_RETURN_TLS_WANT_WRITE:
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
upstream->event.read_cb = NULL;
upstream->event.write_cb = upstream_write_cb;
GETDNS_SCHEDULE_EVENT(upstream->loop,
upstream->fd, TIMEOUT_TLS, &upstream->event);
upstream->fd, timeout_tls, &upstream->event);
upstream->tls_hs_state = GETDNS_HS_WRITE;
return STUB_TCP_RETRY;
default:
Expand Down Expand Up @@ -1199,7 +1210,12 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp,
_getdns_tls_connection* tls_obj = upstream->tls_obj;
uint16_t padding_sz;

int q = tls_connected(upstream);
int q;

if (netreq->owner->expires > upstream->expires)
upstream->expires = netreq->owner->expires;

q = tls_connected(upstream);
if (q != 0)
return q;
/* This is the case where the upstream is connected but it isn't an authenticated
Expand Down Expand Up @@ -2226,7 +2242,7 @@ upstream_schedule_netreq(getdns_upstream *upstream, getdns_network_req *netreq)
/* Set a timeout on the upstream so we can catch failed setup*/
upstream->event.timeout_cb = upstream_setup_timeout_cb;
GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd,
_getdns_ms_until_expiry(netreq->owner->expires)/2,
_getdns_ms_until_expiry(netreq->owner->expires)/5*4,
&upstream->event);
#if defined(HAVE_DECL_TCP_FASTOPEN) && HAVE_DECL_TCP_FASTOPEN \
&& !(defined(HAVE_DECL_TCP_FASTOPEN_CONNECT) && HAVE_DECL_TCP_FASTOPEN_CONNECT) \
Expand Down

0 comments on commit d7099f6

Please sign in to comment.