mirror of https://github.com/getdnsapi/getdns.git
Merge pull request #265 from saradickinson/feature/new_settings
Feature/new settings
This commit is contained in:
commit
52e3d2e1b0
|
@ -73,6 +73,9 @@ static struct const_info consts_info[] = {
|
|||
{ 619, "GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE", GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE_TEXT },
|
||||
{ 620, "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE_TEXT },
|
||||
{ 621, "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", GETDNS_CONTEXT_CODE_PUBKEY_PINSET_TEXT },
|
||||
{ 622, "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS_TEXT },
|
||||
{ 623, "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT },
|
||||
{ 624, "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT },
|
||||
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
|
||||
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
|
||||
{ 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT },
|
||||
|
@ -157,9 +160,12 @@ static struct const_name_info consts_name_info[] = {
|
|||
{ "GETDNS_CONTEXT_CODE_NAMESPACES", 600 },
|
||||
{ "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", 621 },
|
||||
{ "GETDNS_CONTEXT_CODE_RESOLUTION_TYPE", 601 },
|
||||
{ "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", 622 },
|
||||
{ "GETDNS_CONTEXT_CODE_SUFFIX", 608 },
|
||||
{ "GETDNS_CONTEXT_CODE_TIMEOUT", 616 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION", 618 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", 623 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", 624 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 },
|
||||
{ "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", 603 },
|
||||
{ "GETDNS_DNSSEC_BOGUS", 401 },
|
||||
|
|
123
src/context.c
123
src/context.c
|
@ -89,9 +89,6 @@ typedef unsigned short in_port_t;
|
|||
#define GETDNS_STR_PORT_ZERO "0"
|
||||
#define GETDNS_STR_PORT_DNS "53"
|
||||
#define GETDNS_STR_PORT_DNS_OVER_TLS "853"
|
||||
/* How long to wait in seconds before re-trying a connection based backed-off
|
||||
upstream. Using 1 hour for all transports - based on RFC7858 value for for TLS.*/
|
||||
#define BACKOFF_RETRY 3600
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
static pthread_mutex_t ssl_init_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
@ -657,6 +654,9 @@ upstreams_create(getdns_context *context, size_t size)
|
|||
r->referenced = 1;
|
||||
r->count = 0;
|
||||
r->current_udp = 0;
|
||||
r->current_stateful = 0;
|
||||
r->tls_backoff_time = context->tls_backoff_time;
|
||||
r->tls_connection_retries = context->tls_connection_retries;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -731,17 +731,17 @@ _getdns_upstream_shutdown(getdns_upstream *upstream)
|
|||
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 : Transport=%s - Resp=%d,Timeouts=%d,Auth=%s,Keepalive(ms)=%d\n",
|
||||
DEBUG_DAEMON("%s %-40s : Conn closed : Transport=%s - Resp=%d,Timeouts=%d,Auth=%s,Keepalive(ms)=%d\n",
|
||||
STUB_DEBUG_DAEMON, upstream->addr_str,
|
||||
(upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"),
|
||||
(int)upstream->responses_received, (int)upstream->responses_timeouts,
|
||||
_getdns_auth_str(upstream->tls_auth_state), (int)upstream->keepalive_timeout);
|
||||
DEBUG_DAEMON("%s %s : Upstream stats: Transport=%s - Resp=%d,Timeouts=%d,Best_auth=%s\n",
|
||||
DEBUG_DAEMON("%s %-40s : Upstream stats: Transport=%s - Resp=%d,Timeouts=%d,Best_auth=%s\n",
|
||||
STUB_DEBUG_DAEMON, upstream->addr_str,
|
||||
(upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"),
|
||||
(int)upstream->total_responses, (int)upstream->total_timeouts,
|
||||
_getdns_auth_str(upstream->best_tls_auth_state));
|
||||
DEBUG_DAEMON("%s %s : Upstream stats: Transport=%s - Conns=%d,Conn_fails=%d,Conn_shutdowns=%d,Backoffs=%d\n",
|
||||
DEBUG_DAEMON("%s %-40s : Upstream stats: Transport=%s - Conns=%d,Conn_fails=%d,Conn_shutdowns=%d,Backoffs=%d\n",
|
||||
STUB_DEBUG_DAEMON, upstream->addr_str,
|
||||
(upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"),
|
||||
(int)upstream->conn_completed, (int)upstream->conn_setup_failed,
|
||||
|
@ -753,16 +753,16 @@ _getdns_upstream_shutdown(getdns_upstream *upstream)
|
|||
Leave choice between working upstreams to the stub.
|
||||
This back-off should be time based for TLS according to RFC7858. For now,
|
||||
use the same basis if we simply can't get TCP service either.*/
|
||||
|
||||
uint16_t conn_retries = upstream->upstreams->tls_connection_retries;
|
||||
/* [TLS1]TODO: This arbitrary logic at the moment - review and improve!*/
|
||||
if (upstream->conn_setup_failed >= GETDNS_CONN_ATTEMPTS ||
|
||||
(upstream->conn_shutdowns >= GETDNS_CONN_ATTEMPTS*GETDNS_TRANSPORT_FAIL_MULT
|
||||
&& upstream->total_responses == 0) ||
|
||||
(upstream->conn_completed >= GETDNS_CONN_ATTEMPTS &&
|
||||
if (upstream->conn_setup_failed >= conn_retries
|
||||
|| (upstream->conn_shutdowns >= conn_retries*GETDNS_TRANSPORT_FAIL_MULT
|
||||
&& upstream->total_responses == 0)
|
||||
|| (upstream->conn_completed >= conn_retries &&
|
||||
upstream->total_responses == 0 &&
|
||||
upstream->total_timeouts > GETDNS_TRANSPORT_FAIL_MULT)) {
|
||||
upstream->conn_state = GETDNS_CONN_BACKOFF;
|
||||
upstream->conn_retry_time = time(NULL) + BACKOFF_RETRY;
|
||||
upstream->conn_retry_time = time(NULL) + upstream->upstreams->tls_backoff_time;
|
||||
upstream->total_responses = 0;
|
||||
upstream->total_timeouts = 0;
|
||||
upstream->conn_completed = 0;
|
||||
|
@ -770,7 +770,7 @@ _getdns_upstream_shutdown(getdns_upstream *upstream)
|
|||
upstream->conn_shutdowns = 0;
|
||||
upstream->conn_backoffs++;
|
||||
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
||||
DEBUG_DAEMON("%s %s : !Backing off this upstream - Will retry as new upstream at %s",
|
||||
DEBUG_DAEMON("%s %-40s : !Backing off this upstream - Will retry as new upstream at %s",
|
||||
STUB_DEBUG_DAEMON, upstream->addr_str,
|
||||
asctime(gmtime(&upstream->conn_retry_time)));
|
||||
#endif
|
||||
|
@ -1480,6 +1480,9 @@ getdns_context_create_with_extended_memory_functions(
|
|||
goto error;
|
||||
result->tls_auth = GETDNS_AUTHENTICATION_NONE;
|
||||
result->tls_auth_min = GETDNS_AUTHENTICATION_NONE;
|
||||
result->round_robin_upstreams = 0;
|
||||
result->tls_backoff_time = 3600;
|
||||
result->tls_connection_retries = 2;
|
||||
result->limit_outstanding_queries = 0;
|
||||
|
||||
/* unbound context is initialized here */
|
||||
|
@ -2096,6 +2099,62 @@ getdns_context_set_tls_authentication(getdns_context *context,
|
|||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_context_set_tls_authentication_list */
|
||||
|
||||
/*
|
||||
* getdns_context_set_round_robin_upstreams
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_round_robin_upstreams(getdns_context *context, uint8_t value)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
/* only allow 0 or 1 */
|
||||
if (value != 0 && value != 1) {
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
}
|
||||
|
||||
context->round_robin_upstreams = value;
|
||||
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS);
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_context_set_round_robin_upstreams */
|
||||
|
||||
/*
|
||||
* getdns_context_set_tls_backoff_time
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_tls_backoff_time(getdns_context *context, uint16_t value)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
/* Value is in seconds. Should we have a lower limit? 1 second?*/
|
||||
context->tls_backoff_time = value;
|
||||
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME);
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_context_set_tls_backoff_time */
|
||||
|
||||
/*
|
||||
* getdns_context_set_tls_connection_retries
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_tls_connection_retries(getdns_context *context, uint16_t value)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
/* Should we put a sensible upper limit on this? 10?*/
|
||||
// if (value > 10) {
|
||||
// return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
// }
|
||||
|
||||
context->tls_connection_retries = value;
|
||||
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES);
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_context_set_tls_connection retries */
|
||||
|
||||
#ifdef HAVE_LIBUNBOUND
|
||||
static void
|
||||
set_ub_limit_outstanding_queries(getdns_context* context, uint16_t value) {
|
||||
|
@ -3532,7 +3591,13 @@ _get_context_settings(getdns_context* context)
|
|||
|| getdns_dict_set_int(result, "append_name",
|
||||
context->append_name)
|
||||
|| getdns_dict_set_int(result, "tls_authentication",
|
||||
context->tls_auth))
|
||||
context->tls_auth)
|
||||
|| getdns_dict_set_int(result, "round_robin_upstreams",
|
||||
context->round_robin_upstreams)
|
||||
|| getdns_dict_set_int(result, "tls_backoff_time",
|
||||
context->tls_backoff_time)
|
||||
|| getdns_dict_set_int(result, "tls_connection_retries",
|
||||
context->tls_connection_retries))
|
||||
goto error;
|
||||
|
||||
/* list fields */
|
||||
|
@ -3828,6 +3893,33 @@ getdns_context_get_tls_authentication(getdns_context *context,
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_round_robin_upstreams(getdns_context *context,
|
||||
uint8_t* value) {
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
*value = context->round_robin_upstreams;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_backoff_time(getdns_context *context,
|
||||
uint16_t* value) {
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
*value = context->tls_backoff_time;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_connection_retries(getdns_context *context,
|
||||
uint16_t* value) {
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
*value = context->tls_connection_retries;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_limit_outstanding_queries(getdns_context *context,
|
||||
uint16_t* value) {
|
||||
|
@ -4223,6 +4315,9 @@ _getdns_context_config_setting(getdns_context *context,
|
|||
|
||||
CONTEXT_SETTING_INT(edns_client_subnet_private)
|
||||
CONTEXT_SETTING_INT(tls_authentication)
|
||||
CONTEXT_SETTING_INT(round_robin_upstreams)
|
||||
CONTEXT_SETTING_INT(tls_backoff_time)
|
||||
CONTEXT_SETTING_INT(tls_connection_retries)
|
||||
CONTEXT_SETTING_INT(tls_query_padding_blocksize)
|
||||
|
||||
/**************************************/
|
||||
|
|
|
@ -220,6 +220,9 @@ typedef struct getdns_upstreams {
|
|||
size_t referenced;
|
||||
size_t count;
|
||||
size_t current_udp;
|
||||
size_t current_stateful;
|
||||
uint16_t tls_backoff_time;
|
||||
uint16_t tls_connection_retries;
|
||||
getdns_upstream upstreams[];
|
||||
} getdns_upstreams;
|
||||
|
||||
|
@ -251,6 +254,9 @@ struct getdns_context {
|
|||
uint32_t dnssec_allowed_skew;
|
||||
getdns_tls_authentication_t tls_auth; /* What user requested for TLS*/
|
||||
getdns_tls_authentication_t tls_auth_min; /* Derived minimum auth allowed*/
|
||||
uint8_t round_robin_upstreams;
|
||||
uint16_t tls_backoff_time;
|
||||
uint16_t tls_connection_retries;
|
||||
|
||||
getdns_transport_list_t *dns_transports;
|
||||
size_t dns_transport_count;
|
||||
|
|
|
@ -76,6 +76,12 @@ extern "C" {
|
|||
#define GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE_TEXT "Change related to getdns_context_set_tls_query_padding_blocksize"
|
||||
#define GETDNS_CONTEXT_CODE_PUBKEY_PINSET 621
|
||||
#define GETDNS_CONTEXT_CODE_PUBKEY_PINSET_TEXT "Change related to getdns_context_set_pubkey_pinset"
|
||||
#define GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS 622
|
||||
#define GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS_TEXT "Change related to getdns_context_set_pubkey_pinset"
|
||||
#define GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME 623
|
||||
#define GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT "Change related to getdns_context_set_pubkey_pinset"
|
||||
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES 624
|
||||
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT "Change related to getdns_context_set_pubkey_pinset"
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
@ -265,6 +271,15 @@ getdns_return_t
|
|||
getdns_context_set_tls_authentication(
|
||||
getdns_context *context, getdns_tls_authentication_t value);
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_round_robin_upstreams(getdns_context *context, uint8_t value);
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_tls_backoff_time(getdns_context *context, uint16_t value);
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_tls_connection_retries(getdns_context *context, uint16_t value);
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_edns_client_subnet_private(getdns_context *context, uint8_t value);
|
||||
|
||||
|
@ -356,6 +371,18 @@ getdns_return_t
|
|||
getdns_context_get_tls_authentication(getdns_context *context,
|
||||
getdns_tls_authentication_t* value);
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_round_robin_upstreams(getdns_context *context,
|
||||
uint8_t* value);
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_backoff_time(getdns_context *context,
|
||||
uint16_t* value);
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_tls_connection_retries(getdns_context *context,
|
||||
uint16_t* value);
|
||||
|
||||
/**
|
||||
* Get the currently registered callback function and user defined argument
|
||||
* for context changes.
|
||||
|
|
|
@ -26,9 +26,12 @@ getdns_context_get_limit_outstanding_queries
|
|||
getdns_context_get_namespaces
|
||||
getdns_context_get_num_pending_requests
|
||||
getdns_context_get_resolution_type
|
||||
getdns_context_get_round_robin_upstreams
|
||||
getdns_context_get_suffix
|
||||
getdns_context_get_timeout
|
||||
getdns_context_get_tls_authentication
|
||||
getdns_context_get_tls_backoff_time
|
||||
getdns_context_get_tls_connection_retries
|
||||
getdns_context_get_tls_query_padding_blocksize
|
||||
getdns_context_get_update_callback
|
||||
getdns_context_get_upstream_recursive_servers
|
||||
|
@ -56,9 +59,12 @@ getdns_context_set_memory_functions
|
|||
getdns_context_set_namespaces
|
||||
getdns_context_set_resolution_type
|
||||
getdns_context_set_return_dnssec_status
|
||||
getdns_context_set_round_robin_upstreams
|
||||
getdns_context_set_suffix
|
||||
getdns_context_set_timeout
|
||||
getdns_context_set_tls_authentication
|
||||
getdns_context_set_tls_backoff_time
|
||||
getdns_context_set_tls_connection_retries
|
||||
getdns_context_set_tls_query_padding_blocksize
|
||||
getdns_context_set_update_callback
|
||||
getdns_context_set_upstream_recursive_servers
|
||||
|
|
92
src/stub.c
92
src/stub.c
|
@ -594,7 +594,7 @@ stub_timeout_cb(void *userarg)
|
|||
netreq->upstream->udp_timeouts++;
|
||||
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
||||
if (netreq->upstream->udp_timeouts % 100 == 0)
|
||||
DEBUG_DAEMON("%s %s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n",
|
||||
DEBUG_DAEMON("%s %-40s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n",
|
||||
STUB_DEBUG_DAEMON, netreq->upstream->addr_str,
|
||||
(int)netreq->upstream->udp_responses, (int)netreq->upstream->udp_timeouts);
|
||||
#endif
|
||||
|
@ -873,7 +873,7 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|||
#endif
|
||||
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
||||
if (!preverify_ok && !upstream->tls_fallback_ok)
|
||||
DEBUG_DAEMON("%s %s : Conn failed : Transport=TLS - *Failure* - (%d) \"%s\"\n",
|
||||
DEBUG_DAEMON("%s %-40s : Verify failed : Transport=TLS - *Failure* - (%d) \"%s\"\n",
|
||||
STUB_DEBUG_DAEMON, upstream->addr_str, err,
|
||||
X509_verify_cert_error_string(err));
|
||||
#endif
|
||||
|
@ -910,7 +910,7 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|||
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd);
|
||||
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
||||
else
|
||||
DEBUG_DAEMON("%s %s : Conn failed : Transport=TLS - *Failure* - Pinset validation failure\n",
|
||||
DEBUG_DAEMON("%s %-40s : Conn failed : Transport=TLS - *Failure* - Pinset validation failure\n",
|
||||
STUB_DEBUG_DAEMON, upstream->addr_str);
|
||||
#endif
|
||||
} else {
|
||||
|
@ -923,6 +923,10 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|||
preverify_ok = 1;
|
||||
DEBUG_STUB("%s %-35s: FD: %d, Allowing self-signed (%d) cert since pins match\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd, err);
|
||||
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
||||
DEBUG_DAEMON("%s %-40s : Verify passed : Transport=TLS - Allowing self-signed cert since pins match\n",
|
||||
STUB_DEBUG_DAEMON, upstream->addr_str);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1369,14 +1373,20 @@ stub_udp_read_cb(void *userarg)
|
|||
return;
|
||||
}
|
||||
netreq->response_len = read;
|
||||
dnsreq->upstreams->current_udp = 0;
|
||||
if (!dnsreq->context->round_robin_upstreams)
|
||||
dnsreq->upstreams->current_udp = 0;
|
||||
else {
|
||||
dnsreq->upstreams->current_udp+=GETDNS_UPSTREAM_TRANSPORTS;
|
||||
if (dnsreq->upstreams->current_udp >= dnsreq->upstreams->count)
|
||||
dnsreq->upstreams->current_udp = 0;
|
||||
}
|
||||
netreq->debug_end_time = _getdns_get_time_as_uintt64();
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||
upstream->udp_responses++;
|
||||
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
||||
if (upstream->udp_responses == 1 ||
|
||||
upstream->udp_responses % 100 == 0)
|
||||
DEBUG_DAEMON("%s %s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n",
|
||||
DEBUG_DAEMON("%s %-40s : Upstream stats: Transport=UDP - Resp=%d,Timeouts=%d\n",
|
||||
STUB_DEBUG_DAEMON, upstream->addr_str,
|
||||
(int)upstream->udp_responses, (int)upstream->udp_timeouts);
|
||||
#endif
|
||||
|
@ -1611,7 +1621,7 @@ upstream_write_cb(void *userarg)
|
|||
/* Cleaning up after connection or auth check failure. Need to fallback. */
|
||||
stub_cleanup(netreq);
|
||||
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
||||
DEBUG_DAEMON("%s %s : Conn closed : Transport=%s - *Failure*\n",
|
||||
DEBUG_DAEMON("%s %-40s : Conn closed : Transport=%s - *Failure*\n",
|
||||
STUB_DEBUG_DAEMON, upstream->addr_str,
|
||||
(upstream->transport == GETDNS_TRANSPORT_TLS ? "TLS" : "TCP"));
|
||||
#endif
|
||||
|
@ -1662,7 +1672,8 @@ upstream_working_ok(getdns_upstream *upstream)
|
|||
{
|
||||
/* [TLS1]TODO: This arbitrary logic at the moment - review and improve!*/
|
||||
return (upstream->responses_timeouts >
|
||||
upstream->responses_received*GETDNS_CONN_ATTEMPTS ? 0 : 1);
|
||||
upstream->responses_received*
|
||||
upstream->upstreams->tls_connection_retries ? 0 : 1);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1675,6 +1686,17 @@ upstream_active(getdns_upstream *upstream)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
upstream_usable(getdns_upstream *upstream)
|
||||
{
|
||||
if ((upstream->conn_state == GETDNS_CONN_CLOSED ||
|
||||
upstream->conn_state == GETDNS_CONN_SETUP ||
|
||||
upstream->conn_state == GETDNS_CONN_OPEN) &&
|
||||
upstream->keepalive_shutdown == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
upstream_auth_status_ok(getdns_upstream *upstream, getdns_network_req *netreq) {
|
||||
if (netreq->tls_auth_min != GETDNS_AUTHENTICATION_REQUIRED)
|
||||
|
@ -1695,10 +1717,16 @@ upstream_valid(getdns_upstream *upstream,
|
|||
getdns_transport_list_t transport,
|
||||
getdns_network_req *netreq)
|
||||
{
|
||||
if (upstream->transport != transport || upstream->conn_state != GETDNS_CONN_CLOSED)
|
||||
if (!(upstream->transport == transport && upstream_usable(upstream)))
|
||||
return 0;
|
||||
if (transport == GETDNS_TRANSPORT_TCP)
|
||||
return 1;
|
||||
if (upstream->conn_state == GETDNS_CONN_OPEN) {
|
||||
if (!upstream_auth_status_ok(upstream, netreq))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
/* 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;
|
||||
|
@ -1731,7 +1759,7 @@ upstream_select_stateful(getdns_network_req *netreq, getdns_transport_list_t tra
|
|||
getdns_upstreams *upstreams = netreq->owner->upstreams;
|
||||
size_t i;
|
||||
time_t now = time(NULL);
|
||||
|
||||
|
||||
if (!upstreams->count)
|
||||
return NULL;
|
||||
|
||||
|
@ -1741,37 +1769,55 @@ upstream_select_stateful(getdns_network_req *netreq, getdns_transport_list_t tra
|
|||
upstreams->upstreams[i].conn_retry_time < now) {
|
||||
upstreams->upstreams[i].conn_state = GETDNS_CONN_CLOSED;
|
||||
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
||||
DEBUG_DAEMON("%s %s : Re-instating upstream\n",
|
||||
DEBUG_DAEMON("%s %-40s : Re-instating upstream\n",
|
||||
STUB_DEBUG_DAEMON, upstreams->upstreams[i].addr_str);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* First find if an open upstream has the correct properties and use that*/
|
||||
for (i = 0; i < upstreams->count; i++) {
|
||||
if (upstream_valid_and_open(&upstreams->upstreams[i], transport, netreq))
|
||||
return &upstreams->upstreams[i];
|
||||
if (netreq->owner->context->round_robin_upstreams == 0) {
|
||||
/* First find if an open upstream has the correct properties and use that*/
|
||||
for (i = 0; i < upstreams->count; i++) {
|
||||
if (upstream_valid_and_open(&upstreams->upstreams[i], transport, netreq))
|
||||
return &upstreams->upstreams[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* OK - we will have to open one. Choose the first one that has the best stats
|
||||
and the right properties, but because we completely back off failed
|
||||
/* OK - Find the next one to use. First check we have at least one valid
|
||||
upstream because we completely back off failed
|
||||
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++) {
|
||||
i = upstreams->current_stateful;
|
||||
do {
|
||||
DEBUG_STUB("%s %-35s: Testing upstreams %d %d\n", STUB_DEBUG_SETUP,
|
||||
__FUNC__, (int)i, (int)upstreams->upstreams[i].conn_state);
|
||||
if (upstream_valid(&upstreams->upstreams[i], transport, netreq)) {
|
||||
upstream = &upstreams->upstreams[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
if (i >= upstreams->count)
|
||||
i = 0;
|
||||
} while (i != upstreams->current_stateful);
|
||||
if (!upstream)
|
||||
return NULL;
|
||||
for (i++; i < upstreams->count; i++) {
|
||||
if (upstream_valid(&upstreams->upstreams[i], transport, netreq) &&
|
||||
upstream_stats(&upstreams->upstreams[i]) > upstream_stats(upstream))
|
||||
upstream = &upstreams->upstreams[i];
|
||||
|
||||
/* Now select the specific upstream */
|
||||
if (netreq->owner->context->round_robin_upstreams == 0) {
|
||||
/* Base the decision on the stats, noting we will have started from 0*/
|
||||
for (i++; i < upstreams->count; i++) {
|
||||
if (upstream_valid(&upstreams->upstreams[i], transport, netreq) &&
|
||||
upstream_stats(&upstreams->upstreams[i]) > upstream_stats(upstream))
|
||||
upstream = &upstreams->upstreams[i];
|
||||
}
|
||||
} else {
|
||||
/* Simplistic, but always just pick the first one, incrementing the current.
|
||||
Note we are not distinguishing TCP/TLS here....*/
|
||||
upstreams->current_stateful+=GETDNS_UPSTREAM_TRANSPORTS;
|
||||
if (upstreams->current_stateful >= upstreams->count)
|
||||
upstreams->current_stateful = 0;
|
||||
}
|
||||
|
||||
return upstream;
|
||||
}
|
||||
|
||||
|
@ -1856,7 +1902,7 @@ upstream_connect(getdns_upstream *upstream, getdns_transport_list_t transport,
|
|||
}
|
||||
upstream->conn_state = GETDNS_CONN_SETUP;
|
||||
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
||||
DEBUG_DAEMON("%s %s : Conn init : Transport=%s - Profile=%s\n", STUB_DEBUG_DAEMON,
|
||||
DEBUG_DAEMON("%s %-40s : Conn init : Transport=%s - Profile=%s\n", STUB_DEBUG_DAEMON,
|
||||
upstream->addr_str, transport == GETDNS_TRANSPORT_TLS ? "TLS":"TCP",
|
||||
dnsreq->context->tls_auth_min == GETDNS_AUTHENTICATION_NONE ? "Opportunistic":"Strict");
|
||||
#endif
|
||||
|
|
|
@ -434,6 +434,29 @@
|
|||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (getdns_context_set_context_update_callback_23)
|
||||
{
|
||||
/*
|
||||
* value is NULL
|
||||
* expect: GETDNS_RETURN_INVALID_PARAMETER
|
||||
*/
|
||||
|
||||
struct getdns_context *context = NULL;
|
||||
CONTEXT_CREATE(TRUE);
|
||||
|
||||
ASSERT_RC(getdns_context_set_context_update_callback(context, update_callbackfn),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_context_update_callback()");
|
||||
|
||||
expected_changed_item = GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS;
|
||||
|
||||
ASSERT_RC(getdns_context_set_round_robin_upstreams(context, 1),
|
||||
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_timeout()");
|
||||
|
||||
CONTEXT_DESTROY;
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *
|
||||
getdns_context_set_context_update_callback_suite (void)
|
||||
|
@ -462,6 +485,7 @@
|
|||
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_20);
|
||||
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_21);
|
||||
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_22);
|
||||
tcase_add_test(tc_pos, getdns_context_set_context_update_callback_23);
|
||||
suite_add_tcase(s, tc_pos);
|
||||
|
||||
return s;
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
{ resolution_type: GETDNS_RESOLUTION_STUB
|
||||
, dns_transport_list: [ GETDNS_TRANSPORT_TLS ]
|
||||
, tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
|
||||
, tls_query_padding_blocksize: 256
|
||||
, edns_client_subnet_private : 1
|
||||
, listen_addresses: [ 127.0.0.1, 0::1 ]
|
||||
, idle_timeout: 10000
|
||||
, round_robin_upstreams: 1
|
||||
, upstream_recursive_servers:
|
||||
[ { address_data: 145.100.185.15
|
||||
, tls_auth_name: "dnsovertls.sinodun.com"
|
||||
|
@ -56,9 +62,4 @@
|
|||
} ]
|
||||
}
|
||||
]
|
||||
, tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
|
||||
, tls_query_padding_blocksize: 256
|
||||
, edns_client_subnet_private : 1
|
||||
, listen_addresses: [ 127.0.0.1, 0::1 ]
|
||||
, idle_timeout: 10000
|
||||
}
|
||||
|
|
|
@ -124,7 +124,6 @@ struct getdns_upstream;
|
|||
|
||||
#define GETDNS_TRANSPORTS_MAX 3
|
||||
#define GETDNS_UPSTREAM_TRANSPORTS 2
|
||||
#define GETDNS_CONN_ATTEMPTS 2
|
||||
#define GETDNS_TRANSPORT_FAIL_MULT 5
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue