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.*/
upstream->total_responses+=upstream->responses_received;
upstream->total_timeouts+=upstream->responses_timeouts;
/* Pick up the auth state if it is of interest*/
if (upstream->tls_auth_state != GETDNS_AUTH_NONE)
upstream->past_tls_auth_state = upstream->tls_auth_state;
/* Need the last auth state when using session resumption*/
upstream->last_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
DEBUG_DAEMON("%s %s : Conn closed: Conn stats - Resp=%d,Timeouts=%d,Auth=%s,Keepalive(ms)=%d\n",
STUB_DEBUG_DAEMON, upstream->addr_str,
(int)upstream->responses_received, (int)upstream->responses_timeouts,
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,
(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_shutdowns, (int)upstream->conn_backoffs);
#endif
@ -908,6 +909,8 @@ upstream_init(getdns_upstream *upstream,
upstream->tls_hs_state = GETDNS_HS_NONE;
upstream->tls_auth_name[0] = '\0';
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->loop = NULL;
(void) getdns_eventloop_event_init(

View File

@ -147,7 +147,8 @@ typedef struct getdns_upstream {
size_t conn_backoffs;
size_t total_responses;
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. */
getdns_conn_state_t conn_state;
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);
(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;
}
@ -995,6 +1009,9 @@ tls_do_handshake(getdns_upstream *upstream)
upstream->tls_hs_state = GETDNS_HS_DONE;
upstream->conn_state = GETDNS_CONN_OPEN;
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",
STUB_DEBUG_SETUP_TLS, __FUNCTION__, upstream->fd, upstream->tls_auth_state,
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.*/
if (netreq->tls_auth_min != GETDNS_AUTHENTICATION_REQUIRED)
return 1;
return ((upstream->past_tls_auth_state == GETDNS_AUTH_OK ||
upstream->past_tls_auth_state == GETDNS_AUTH_NONE) ? 1 : 0);
return ((upstream->best_tls_auth_state == GETDNS_AUTH_OK ||
upstream->best_tls_auth_state == GETDNS_AUTH_NONE) ? 1 : 0);
}
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
will be better communicated to the user when we have better error codes*/
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);
if (upstream_valid(&upstreams->upstreams[i], transport, netreq)) {
upstream = &upstreams->upstreams[i];
@ -1744,8 +1761,6 @@ upstream_connect(getdns_upstream *upstream, getdns_transport_list_t transport,
close(fd);
return -1;
}
if (upstream->tls_session != NULL)
SSL_set_session(upstream->tls_obj, upstream->tls_session);
upstream->tls_hs_state = GETDNS_HS_WRITE;
}
upstream->conn_state = GETDNS_CONN_SETUP;