Merge branch 'bugfix/auth_retry' into release/1.1.0-alpha3

This commit is contained in:
Willem Toorop 2016-10-25 11:09:07 +02:00
commit 24de66e6ce
3 changed files with 31 additions and 12 deletions

View File

@ -710,19 +710,20 @@ _getdns_upstream_shutdown(getdns_upstream *upstream)
/* Update total stats for the upstream.*/ /* Update total stats for the upstream.*/
upstream->total_responses+=upstream->responses_received; upstream->total_responses+=upstream->responses_received;
upstream->total_timeouts+=upstream->responses_timeouts; upstream->total_timeouts+=upstream->responses_timeouts;
/* Pick up the auth state if it is of interest*/ /* Need the last auth state when using session resumption*/
if (upstream->tls_auth_state != GETDNS_AUTH_NONE) upstream->last_tls_auth_state = upstream->tls_auth_state;
upstream->past_tls_auth_state = upstream->tls_auth_state; /* Keep track of the best auth state this upstream has had*/
if (upstream->tls_auth_state > upstream->best_tls_auth_state)
upstream->best_tls_auth_state = upstream->tls_auth_state;
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG #if defined(DAEMON_DEBUG) && DAEMON_DEBUG
DEBUG_DAEMON("%s %s : Conn closed: Conn stats - Resp=%d,Timeouts=%d,Auth=%s,Keepalive(ms)=%d\n", DEBUG_DAEMON("%s %s : Conn closed: Conn stats - Resp=%d,Timeouts=%d,Auth=%s,Keepalive(ms)=%d\n",
STUB_DEBUG_DAEMON, upstream->addr_str, STUB_DEBUG_DAEMON, upstream->addr_str,
(int)upstream->responses_received, (int)upstream->responses_timeouts, (int)upstream->responses_received, (int)upstream->responses_timeouts,
getdns_auth_str_array[upstream->tls_auth_state], (int)upstream->keepalive_timeout); getdns_auth_str_array[upstream->tls_auth_state], (int)upstream->keepalive_timeout);
DEBUG_DAEMON("%s %s : Upstream stats - Resp=%d,Timeouts=%d,Auth=%s,Conns=%d,Conn_fails=%d,Conn_shutdowns=%d,Backoffs=%d\n", DEBUG_DAEMON("%s %s : Upstream stats - Resp=%d,Timeouts=%d,Best_auth=%s,Conns=%d,Conn_fails=%d,Conn_shutdowns=%d,Backoffs=%d\n",
STUB_DEBUG_DAEMON, upstream->addr_str, STUB_DEBUG_DAEMON, upstream->addr_str,
(int)upstream->total_responses, (int)upstream->total_timeouts, (int)upstream->total_responses, (int)upstream->total_timeouts,
getdns_auth_str_array[upstream->tls_auth_state], getdns_auth_str_array[upstream->best_tls_auth_state],
(int)upstream->conn_completed, (int)upstream->conn_setup_failed, (int)upstream->conn_completed, (int)upstream->conn_setup_failed,
(int)upstream->conn_shutdowns, (int)upstream->conn_backoffs); (int)upstream->conn_shutdowns, (int)upstream->conn_backoffs);
#endif #endif
@ -908,6 +909,8 @@ upstream_init(getdns_upstream *upstream,
upstream->tls_hs_state = GETDNS_HS_NONE; upstream->tls_hs_state = GETDNS_HS_NONE;
upstream->tls_auth_name[0] = '\0'; upstream->tls_auth_name[0] = '\0';
upstream->tls_auth_state = GETDNS_AUTH_NONE; upstream->tls_auth_state = GETDNS_AUTH_NONE;
upstream->last_tls_auth_state = GETDNS_AUTH_NONE;
upstream->best_tls_auth_state = GETDNS_AUTH_NONE;
upstream->tls_pubkey_pinset = NULL; upstream->tls_pubkey_pinset = NULL;
upstream->loop = NULL; upstream->loop = NULL;
(void) getdns_eventloop_event_init( (void) getdns_eventloop_event_init(

View File

@ -147,7 +147,8 @@ typedef struct getdns_upstream {
size_t conn_backoffs; size_t conn_backoffs;
size_t total_responses; size_t total_responses;
size_t total_timeouts; size_t total_timeouts;
getdns_auth_state_t past_tls_auth_state; getdns_auth_state_t best_tls_auth_state;
getdns_auth_state_t last_tls_auth_state;
/* These are per connection. */ /* These are per connection. */
getdns_conn_state_t conn_state; getdns_conn_state_t conn_state;
size_t queries_sent; size_t queries_sent;

View File

@ -954,6 +954,20 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
SSL_set_connect_state(ssl); SSL_set_connect_state(ssl);
(void) SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); (void) SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
/* Session resumption. There are trade-offs here. Want to do it when
possible only if we have the right type of connection. Note a change
to the upstream auth info creates a new upstream so never re-uses.*/
if (upstream->tls_session != NULL) {
if ((upstream->tls_fallback_ok == 0 &&
upstream->last_tls_auth_state == GETDNS_AUTH_OK) ||
upstream->tls_fallback_ok == 1) {
SSL_set_session(ssl, upstream->tls_session);
DEBUG_STUB("%s %-35s: Attempting session re-use\n", STUB_DEBUG_SETUP_TLS,
__FUNCTION__);
}
}
return ssl; return ssl;
} }
@ -995,6 +1009,9 @@ tls_do_handshake(getdns_upstream *upstream)
upstream->tls_hs_state = GETDNS_HS_DONE; upstream->tls_hs_state = GETDNS_HS_DONE;
upstream->conn_state = GETDNS_CONN_OPEN; upstream->conn_state = GETDNS_CONN_OPEN;
upstream->conn_completed++; upstream->conn_completed++;
/* A re-used session is not verified so need to fix up state in that case */
if (SSL_session_reused(upstream->tls_obj))
upstream->tls_auth_state = upstream->last_tls_auth_state;
DEBUG_STUB("%s %-35s: FD: %d Handshake succeeded with auth state %d. Session is %s.\n", DEBUG_STUB("%s %-35s: FD: %d Handshake succeeded with auth state %d. Session is %s.\n",
STUB_DEBUG_SETUP_TLS, __FUNCTION__, upstream->fd, upstream->tls_auth_state, STUB_DEBUG_SETUP_TLS, __FUNCTION__, upstream->fd, upstream->tls_auth_state,
SSL_session_reused(upstream->tls_obj) ?"re-used":"new"); SSL_session_reused(upstream->tls_obj) ?"re-used":"new");
@ -1598,8 +1615,8 @@ upstream_valid(getdns_upstream *upstream,
/* We need to check past authentication history to see if this is usable for TLS.*/ /* We need to check past authentication history to see if this is usable for TLS.*/
if (netreq->tls_auth_min != GETDNS_AUTHENTICATION_REQUIRED) if (netreq->tls_auth_min != GETDNS_AUTHENTICATION_REQUIRED)
return 1; return 1;
return ((upstream->past_tls_auth_state == GETDNS_AUTH_OK || return ((upstream->best_tls_auth_state == GETDNS_AUTH_OK ||
upstream->past_tls_auth_state == GETDNS_AUTH_NONE) ? 1 : 0); upstream->best_tls_auth_state == GETDNS_AUTH_NONE) ? 1 : 0);
} }
static int static int
@ -1654,7 +1671,7 @@ upstream_select_stateful(getdns_network_req *netreq, getdns_transport_list_t tra
upstreams we may have no valid upstream at all (in contrast to UDP). This upstreams we may have no valid upstream at all (in contrast to UDP). This
will be better communicated to the user when we have better error codes*/ will be better communicated to the user when we have better error codes*/
for (i = 0; i < upstreams->count; i++) { for (i = 0; i < upstreams->count; i++) {
DEBUG_STUB("%s %-35s: Testing %d %d\n", STUB_DEBUG_SETUP, DEBUG_STUB("%s %-35s: Testing upstreams %d %d\n", STUB_DEBUG_SETUP,
__FUNCTION__, (int)i, (int)upstreams->upstreams[i].conn_state); __FUNCTION__, (int)i, (int)upstreams->upstreams[i].conn_state);
if (upstream_valid(&upstreams->upstreams[i], transport, netreq)) { if (upstream_valid(&upstreams->upstreams[i], transport, netreq)) {
upstream = &upstreams->upstreams[i]; upstream = &upstreams->upstreams[i];
@ -1744,8 +1761,6 @@ upstream_connect(getdns_upstream *upstream, getdns_transport_list_t transport,
close(fd); close(fd);
return -1; return -1;
} }
if (upstream->tls_session != NULL)
SSL_set_session(upstream->tls_obj, upstream->tls_session);
upstream->tls_hs_state = GETDNS_HS_WRITE; upstream->tls_hs_state = GETDNS_HS_WRITE;
} }
upstream->conn_state = GETDNS_CONN_SETUP; upstream->conn_state = GETDNS_CONN_SETUP;