Limit back_off value to avoid very long retry interval

This commit is contained in:
Robert Groenenberg 2018-02-26 16:41:13 +01:00 committed by Willem Toorop
parent d1aa3922fe
commit a0fb2c8424
5 changed files with 70 additions and 3 deletions

View File

@ -679,6 +679,7 @@ upstreams_create(getdns_context *context, size_t size)
r->count = 0;
r->current_udp = 0;
r->current_stateful = 0;
r->max_backoff_value = context->max_backoff_value;
r->tls_backoff_time = context->tls_backoff_time;
r->tls_connection_retries = context->tls_connection_retries;
r->log = context->log;
@ -1664,6 +1665,7 @@ getdns_context_create_with_extended_memory_functions(
result->tls_backoff_time = 3600;
result->tls_connection_retries = 2;
result->limit_outstanding_queries = 0;
result->max_backoff_value = 1000;
/* unbound context is initialized here */
/* Unbound needs SSL to be init'ed this early when TLS is used. However we
@ -2362,6 +2364,22 @@ getdns_context_set_round_robin_upstreams(getdns_context *context, uint8_t value)
return GETDNS_RETURN_GOOD;
} /* getdns_context_set_round_robin_upstreams */
/*
* getdns_context_set_max_backoff_value
*
*/
getdns_return_t
getdns_context_set_max_backoff_value(getdns_context *context, uint16_t value)
{
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
context->max_backoff_value = value;
dispatch_updated(context, GETDNS_CONTEXT_CODE_MAX_BACKOFF_VALUE);
return GETDNS_RETURN_GOOD;
} /* getdns_context_set_max_backoff_value */
/*
* getdns_context_set_tls_backoff_time
*
@ -3931,6 +3949,8 @@ _get_context_settings(getdns_context* context)
context->tls_auth)
|| getdns_dict_set_int(result, "round_robin_upstreams",
context->round_robin_upstreams)
|| getdns_dict_set_int(result, "max_backoff_value",
context->max_backoff_value)
|| getdns_dict_set_int(result, "tls_backoff_time",
context->tls_backoff_time)
|| getdns_dict_set_int(result, "tls_connection_retries",
@ -4378,6 +4398,15 @@ getdns_context_get_round_robin_upstreams(getdns_context *context,
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_get_max_backoff_value(getdns_context *context,
uint16_t* value) {
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
*value = context->max_backoff_value;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_get_tls_backoff_time(getdns_context *context,
uint16_t* value) {

View File

@ -263,6 +263,7 @@ typedef struct getdns_upstreams {
size_t count;
size_t current_udp;
size_t current_stateful;
uint16_t max_backoff_value;
uint16_t tls_backoff_time;
uint16_t tls_connection_retries;
getdns_log_config log;
@ -357,6 +358,7 @@ struct getdns_context {
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 max_backoff_value;
uint16_t tls_backoff_time;
uint16_t tls_connection_retries;

View File

@ -103,6 +103,9 @@ extern "C" {
#define GETDNS_CONTEXT_CODE_TLS_CURVES_LIST 634
#define GETDNS_CONTEXT_CODE_TLS_CURVES_LIST_TEXT "Change related to getdns_context_set_tls_curves_list"
#define GETDNS_CONTEXT_CODE_MAX_BACKOFF_VALUE 635
#define GETDNS_CONTEXT_CODE_MAX_BACKOFF_VALUE_TEXT "Change related to getdns_context_set_max_backoff_value"
/** @}
*/
@ -768,6 +771,19 @@ getdns_return_t
getdns_context_set_tls_curves_list(
getdns_context *context, const char *curves_list);
/**
* Set the maximum number of messages that can be sent to other upstreams
* before the upstream which has previously timed out will be tried again.
* @see getdns_context_get_max_backoff_value
* @param[in] context The context to configure
* @param[in[ value Number of messages sent to other upstreams before
* retrying the upstream which had timed out.
* @return GETDNS_RETURN_GOOD on success
* @return GETDNS_RETURN_INVALID_PARAMETER if context is null.
*/
getdns_return_t
getdns_context_set_max_backoff_value(getdns_context *context, uint16_t value);
/**
* Get the current resolution type setting from this context.
@ -1076,7 +1092,7 @@ getdns_context_get_tls_authentication(getdns_context *context,
/**
* Get whether the context is configured to round robin queries over the available
* upstreams.
* @see getdns_context_get_round_robin_upstreams
* @see getdns_context_set_round_robin_upstreams
* @param[in] context The context from which to get the setting
* @param[out] value 1 if the setting is on, 0 otherwise
* @return GETDNS_RETURN_GOOD when successful
@ -1303,6 +1319,19 @@ getdns_return_t
getdns_context_get_tls_curves_list(
getdns_context *context, const char **curves_list);
/**
* Get the maximum number of messages that can be sent to other upstreams
* before the upstream which has previously timed out will be tried again.
* @see getdns_context_set_max_backoff_value
* @param[in] context The context from which to get the setting
* @param[out] value Number of messages sent to other upstreams before
* retrying the upstream which had timed out.
* @return GETDNS_RETURN_GOOD on success
* @return GETDNS_RETURN_INVALID_PARAMETER if context is null.
*/
getdns_return_t
getdns_context_get_max_backoff_value(getdns_context *context,
uint16_t* value);
/** @}
*/

View File

@ -29,6 +29,7 @@ getdns_context_get_num_pending_requests
getdns_context_get_resolution_type
getdns_context_get_resolvconf
getdns_context_get_round_robin_upstreams
getdns_context_get_max_backoff_value
getdns_context_get_suffix
getdns_context_get_timeout
getdns_context_get_tls_authentication
@ -73,6 +74,7 @@ getdns_context_set_resolution_type
getdns_context_set_resolvconf
getdns_context_set_return_dnssec_status
getdns_context_set_round_robin_upstreams
getdns_context_set_max_backoff_value
getdns_context_set_suffix
getdns_context_set_timeout
getdns_context_set_tls_authentication

View File

@ -460,8 +460,13 @@ stub_next_upstream(getdns_network_req *netreq)
{
getdns_dns_req *dnsreq = netreq->owner;
if (! --netreq->upstream->to_retry)
netreq->upstream->to_retry = -(netreq->upstream->back_off *= 2);
if (! --netreq->upstream->to_retry) {
/* Limit back_off value to configured maximum */
if (netreq->upstream->back_off * 2 > dnsreq->context->max_backoff_value)
netreq->upstream->to_retry = -(dnsreq->context->max_backoff_value);
else
netreq->upstream->to_retry = -(netreq->upstream->back_off *= 2);
}
dnsreq->upstreams->current_udp+=GETDNS_UPSTREAM_TRANSPORTS;
if (dnsreq->upstreams->current_udp >= dnsreq->upstreams->count)