- Add fast-server-permil and fast-server-num options.

- Deprecate low-rtt and low-rtt-permil options.


git-svn-id: file:///svn/unbound/trunk@4938 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Ralph Dolmans 2018-10-08 16:03:46 +00:00
parent 2d28fba3bf
commit 02bd3e2ff1
11 changed files with 3415 additions and 3312 deletions

View file

@ -1,3 +1,7 @@
8 October 2018: Ralph
- Add fast-server-permil and fast-server-num options.
- Deprecate low-rtt and low-rtt-permil options.
8 October 2018: Wouter
- Squelch log of failed to tcp initiate after TCP Fastopen failure.

View file

@ -757,12 +757,12 @@ server:
# Limit the number of connections simultaneous from a netblock
# tcp-connection-limit: 192.0.2.0/24 12
# what is considered a low rtt (ping time for upstream server), in msec
# low-rtt: 45
# select low rtt this many times out of 1000. 0 means the fast server
# select is disabled. prefetches are not sped up.
# low-rtt-permil: 0
# select from the fastest servers this many times out of 1000. 0 means
# the fast server select is disabled. prefetches are not sped up.
# fast-server-permil: 0
# the number of servers that will be used in the fast server selection.
# fast-server-num: 4
# Specific options for ipsecmod. unbound needs to be configured with
# --enable-ipsecmod for these to take effect.
#

View file

@ -1391,22 +1391,20 @@ This can make ordinary queries complete (if repeatedly queried for),
and enter the cache, whilst also mitigating the traffic flow by the
factor given.
.TP 5
.B low\-rtt: \fI<msec time>
Set the time in millisecond that is considere a low ping time for fast
server selection with the low\-rtt\-permil option, that turns this on or off.
The default is 45 msec, a number from IPv6 quick response documents.
.B fast\-server\-permil: \fI<number>
Specify how many times out of 1000 to pick from the set of fastest servers.
0 turns the feature off. A value of 900 would pick from the fastest
servers 90 percent of the time, and would perform normal exploration of random
servers for the remaining time. When prefetch is enabled (or serve\-expired),
such prefetches are not sped up, because there is no one waiting for it, and it
presents a good moment to perform server exploration. The
\fBfast\-server\-num\fR option can be used to specify the size of the fastest
servers set. The default for fast\-server\-permil is 0.
.TP 5
.B low\-rtt\-permil: \fI<number>
Specify how many times out of 1000 to pick the fast server from the low
rtt band. 0 turns the feature off. A value of 900 would pick the fast
server when such fast servers are available 90 percent of the time, and
the remaining time perform normal exploration of random servers.
When prefetch is enabled (or serve\-expired), such prefetches are not
sped up, because there is no one waiting for it, and it presents a good
moment to perform server exploration. The low\-rtt option can be used
to specify which servers are picked for fast server selection, servers
with a ping roundtrip time below that value are considered.
The default for low\-rtt\-permil is 0.
.B fast\-server\-num: \fI<number>
Set the number of servers that should be used for fast server selection. Only
use the fastest specified number of servers with the fast\-server\-permil
option, that turns this on or off. The default is to use the fastest 4 servers.
.SS "Remote Control Options"
In the
.B remote\-control:

View file

@ -282,10 +282,13 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
static int
iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
uint8_t* name, size_t namelen, uint16_t qtype, time_t now,
struct delegpt* dp, int* best_rtt, struct sock_list* blacklist)
struct delegpt* dp, int* best_rtt, struct sock_list* blacklist,
int* num_suitable_results)
{
int got_it = 0;
struct delegpt_addr* a;
*num_suitable_results = 0;
if(dp->bogus)
return 0; /* NS bogus, all bogus, nothing found */
for(a=dp->result_list; a; a = a->next_result) {
@ -301,11 +304,57 @@ iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
} else if(a->sel_rtt < *best_rtt) {
*best_rtt = a->sel_rtt;
}
(*num_suitable_results)++;
}
}
return got_it;
}
/** compare two rtts, return -1, 0 or 1 */
static int
rtt_compare(const void* x, const void* y)
{
if(*(int*)x == *(int*)y)
return 0;
if(*(int*)x > *(int*)y)
return 1;
return -1;
}
/** get RTT for the Nth fastest server */
static int
nth_rtt(struct delegpt_addr* result_list, int num_results, int n)
{
int rtt_band, i;
int* rtt_list, *rtt_index;
if(num_results < 1 || n >= num_results) {
return -1;
}
rtt_list = calloc(num_results, sizeof(int));
if(!rtt_list) {
log_err("malloc failure: allocating rtt_list");
return -1;
}
rtt_index = rtt_list;
for(i=0; i<num_results && result_list; i++) {
if(result_list->sel_rtt != -1) {
*rtt_index = result_list->sel_rtt;
rtt_index++;
}
result_list=result_list->next_result;
}
qsort(rtt_list, num_results, sizeof(*rtt_list), rtt_compare);
log_assert(n > 0);
rtt_band = rtt_list[n-1];
free(rtt_list);
return rtt_band;
}
/** filter the address list, putting best targets at front,
* returns number of best targets (or 0, no suitable targets) */
static int
@ -314,12 +363,13 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
struct delegpt* dp, int* selected_rtt, int open_target,
struct sock_list* blacklist, time_t prefetch)
{
int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND;
int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND,
num_results, nth;
struct delegpt_addr* a, *n, *prev=NULL;
/* fillup sel_rtt and find best rtt in the bunch */
got_num = iter_fill_rtt(iter_env, env, name, namelen, qtype, now, dp,
&low_rtt, blacklist);
&low_rtt, blacklist, &num_results);
if(got_num == 0)
return 0;
if(low_rtt >= USEFUL_SERVER_TOP_TIMEOUT &&
@ -329,14 +379,19 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
return 0 to force the caller to fetch more */
}
if(env->cfg->low_rtt_permil != 0 && prefetch == 0 &&
low_rtt < env->cfg->low_rtt &&
ub_random_max(env->rnd, 1000) < env->cfg->low_rtt_permil) {
if(env->cfg->fast_server_permil != 0 && prefetch == 0 &&
num_results > env->cfg->fast_server_num &&
ub_random_max(env->rnd, 1000) < env->cfg->fast_server_permil) {
/* the query is not prefetch, but for a downstream client,
* there is a low_rtt (fast) server. We choose that x% of the
* time */
/* pick rtt numbers from 0..LOWBAND_RTT */
rtt_band = env->cfg->low_rtt - low_rtt;
* there are more servers available then the fastest N we want
* to choose from. Limit our choice to the fastest servers. */
nth = nth_rtt(dp->result_list, num_results,
env->cfg->fast_server_num);
if(nth > 0) {
rtt_band = nth - low_rtt;
if(rtt_band > RTT_BAND)
rtt_band = RTT_BAND;
}
}
got_num = 0;

View file

@ -167,8 +167,8 @@ config_create(void)
if(!(cfg->logfile = strdup(""))) goto error_exit;
if(!(cfg->pidfile = strdup(PIDFILE))) goto error_exit;
if(!(cfg->target_fetch_policy = strdup("3 2 1 0 0"))) goto error_exit;
cfg->low_rtt_permil = 0;
cfg->low_rtt = 45;
cfg->fast_server_permil = 0;
cfg->fast_server_num = 4;
cfg->donotqueryaddrs = NULL;
cfg->donotquery_localhost = 1;
cfg->root_hints = NULL;
@ -642,9 +642,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_POW2("ratelimit-slabs:", ratelimit_slabs)
else S_NUMBER_OR_ZERO("ip-ratelimit-factor:", ip_ratelimit_factor)
else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor)
else S_NUMBER_OR_ZERO("low-rtt:", low_rtt)
else S_NUMBER_OR_ZERO("low-rtt-pct:", low_rtt_permil)
else S_NUMBER_OR_ZERO("low-rtt-permil:", low_rtt_permil)
else S_NUMBER_NONZERO("fast-server-num:", fast_server_num)
else S_NUMBER_OR_ZERO("fast-server-permil:", fast_server_permil)
else S_YNO("qname-minimisation:", qname_minimisation)
else S_YNO("qname-minimisation-strict:", qname_minimisation_strict)
#ifdef USE_IPSECMOD
@ -1036,9 +1035,8 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_LS2(opt, "ratelimit-below-domain", ratelimit_below_domain)
else O_DEC(opt, "ip-ratelimit-factor", ip_ratelimit_factor)
else O_DEC(opt, "ratelimit-factor", ratelimit_factor)
else O_DEC(opt, "low-rtt", low_rtt)
else O_DEC(opt, "low-rtt-pct", low_rtt_permil)
else O_DEC(opt, "low-rtt-permil", low_rtt_permil)
else O_DEC(opt, "fast-server-num", fast_server_num)
else O_DEC(opt, "fast-server-permil", fast_server_permil)
else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min)
else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max)
else O_YNO(opt, "qname-minimisation", qname_minimisation)

View file

@ -159,10 +159,11 @@ struct config_file {
/** the target fetch policy for the iterator */
char* target_fetch_policy;
/** percent*10, how many times in 1000 to pick low rtt destinations */
int low_rtt_permil;
/** what time in msec is a low rtt destination */
int low_rtt;
/** percent*10, how many times in 1000 to pick from the fastest
* destinations */
int fast_server_permil;
/** number of fastest server to select from */
int fast_server_num;
/** automatic interface for incoming messages. Uses ipv6 remapping,
* and recvmsg/sendmsg ancillary data to detect interfaces, boolean */

File diff suppressed because it is too large Load diff

View file

@ -441,8 +441,10 @@ ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) }
ip-ratelimit-factor{COLON} { YDVAR(1, VAR_IP_RATELIMIT_FACTOR) }
ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
low-rtt{COLON} { YDVAR(1, VAR_LOW_RTT) }
low-rtt-pct{COLON} { YDVAR(1, VAR_LOW_RTT_PERMIL) }
low-rtt-permil{COLON} { YDVAR(1, VAR_LOW_RTT_PERMIL) }
fast-server-num{COLON} { YDVAR(1, VAR_FAST_SERVER_NUM) }
low-rtt-pct{COLON} { YDVAR(1, VAR_FAST_SERVER_PERMIL) }
low-rtt-permil{COLON} { YDVAR(1, VAR_FAST_SERVER_PERMIL) }
fast-server-permil{COLON} { YDVAR(1, VAR_FAST_SERVER_PERMIL) }
response-ip-tag{COLON} { YDVAR(2, VAR_RESPONSE_IP_TAG) }
response-ip{COLON} { YDVAR(2, VAR_RESPONSE_IP) }
response-ip-data{COLON} { YDVAR(2, VAR_RESPONSE_IP_DATA) }

File diff suppressed because it is too large Load diff

View file

@ -290,12 +290,14 @@ extern int yydebug;
VAR_TLS_ADDITIONAL_PORT = 500,
VAR_LOW_RTT = 501,
VAR_LOW_RTT_PERMIL = 502,
VAR_ALLOW_NOTIFY = 503,
VAR_TLS_WIN_CERT = 504,
VAR_TCP_CONNECTION_LIMIT = 505,
VAR_FORWARD_NO_CACHE = 506,
VAR_STUB_NO_CACHE = 507,
VAR_LOG_SERVFAIL = 508
VAR_FAST_SERVER_PERMIL = 503,
VAR_FAST_SERVER_NUM = 504,
VAR_ALLOW_NOTIFY = 505,
VAR_TLS_WIN_CERT = 506,
VAR_TCP_CONNECTION_LIMIT = 507,
VAR_FORWARD_NO_CACHE = 508,
VAR_STUB_NO_CACHE = 509,
VAR_LOG_SERVFAIL = 510
};
#endif
/* Tokens. */
@ -544,12 +546,14 @@ extern int yydebug;
#define VAR_TLS_ADDITIONAL_PORT 500
#define VAR_LOW_RTT 501
#define VAR_LOW_RTT_PERMIL 502
#define VAR_ALLOW_NOTIFY 503
#define VAR_TLS_WIN_CERT 504
#define VAR_TCP_CONNECTION_LIMIT 505
#define VAR_FORWARD_NO_CACHE 506
#define VAR_STUB_NO_CACHE 507
#define VAR_LOG_SERVFAIL 508
#define VAR_FAST_SERVER_PERMIL 503
#define VAR_FAST_SERVER_NUM 504
#define VAR_ALLOW_NOTIFY 505
#define VAR_TLS_WIN_CERT 506
#define VAR_TCP_CONNECTION_LIMIT 507
#define VAR_FORWARD_NO_CACHE 508
#define VAR_STUB_NO_CACHE 509
#define VAR_LOG_SERVFAIL 510
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@ -560,7 +564,7 @@ union YYSTYPE
char* str;
#line 564 "util/configparser.h" /* yacc.c:1909 */
#line 568 "util/configparser.h" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;

View file

@ -159,6 +159,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
%token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
%token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
%token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL
@ -255,7 +256,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_ipsecmod_whitelist | server_ipsecmod_strict |
server_udp_upstream_without_downstream | server_aggressive_nsec |
server_tls_cert_bundle | server_tls_additional_port | server_low_rtt |
server_low_rtt_permil | server_tls_win_cert |
server_fast_server_permil | server_fast_server_num | server_tls_win_cert |
server_tcp_connection_limit | server_log_servfail
;
stubstart: VAR_STUB_ZONE
@ -1974,19 +1975,25 @@ server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG
;
server_low_rtt: VAR_LOW_RTT STRING_ARG
{
OUTYY(("P(server_low_rtt:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("number expected");
else cfg_parser->cfg->low_rtt = atoi($2);
OUTYY(("P(low-rtt option is deprecated, use fast-server-num instead)\n"));
free($2);
}
;
server_low_rtt_permil: VAR_LOW_RTT_PERMIL STRING_ARG
server_fast_server_num: VAR_FAST_SERVER_NUM STRING_ARG
{
OUTYY(("P(server_low_rtt_permil:%s)\n", $2));
OUTYY(("P(server_fast_server_num:%s)\n", $2));
if(atoi($2) <= 0)
yyerror("number expected");
else cfg_parser->cfg->fast_server_num = atoi($2);
free($2);
}
;
server_fast_server_permil: VAR_FAST_SERVER_PERMIL STRING_ARG
{
OUTYY(("P(server_fast_server_permil:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("number expected");
else cfg_parser->cfg->low_rtt_permil = atoi($2);
else cfg_parser->cfg->fast_server_permil = atoi($2);
free($2);
}
;