Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add max-query-restarts option #461

Merged
merged 5 commits into from Dec 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/unbound.conf.5.in
Expand Up @@ -1780,6 +1780,11 @@ option can be used multiple times. The most specific match will be used.
EDNS0 option code for the \fIedns\-client\-string\fR option, from 0 to 65535.
A value from the `Reserved for Local/Experimental` range (65001-65534) should
be used. Default is 65001.
.TP 5
.B max\-query\-restarts: \fI<number>
Set the maximum number of times a query is allowed to restart upon encountering
a CNAME record. If a query encounters more than the specified number of CNAME
records before resolving, unbound will reply with SERVFAIL. Default is 8.
.SS "Remote Control Options"
In the
.B remote\-control:
Expand Down
2 changes: 2 additions & 0 deletions iterator/iter_utils.c
Expand Up @@ -176,7 +176,9 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
}
iter_env->supports_ipv6 = cfg->do_ip6;
iter_env->supports_ipv4 = cfg->do_ip4;
iter_env->max_query_restarts = cfg->max_query_restarts;
iter_env->outbound_msg_retry = cfg->outbound_msg_retry;

return 1;
}

Expand Down
2 changes: 1 addition & 1 deletion iterator/iterator.c
Expand Up @@ -1291,7 +1291,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,

/* We enforce a maximum number of query restarts. This is primarily a
* cheap way to prevent CNAME loops. */
if(iq->query_restart_count > MAX_RESTART_COUNT) {
if(iq->query_restart_count > ie->max_query_restarts) {
verbose(VERB_QUERY, "request has exceeded the maximum number"
" of query restarts with %d", iq->query_restart_count);
errinf(qstate, "request has exceeded the maximum number "
Expand Down
2 changes: 2 additions & 0 deletions iterator/iterator.h
Expand Up @@ -138,6 +138,8 @@ struct iter_env {
/** number of queries that have been ratelimited */
size_t num_queries_ratelimited;

/** max number of query restarts to limit length of CNAME chain */
size_t max_query_restarts;
/** number of retries on outgoing queries */
int outbound_msg_retry;
};
Expand Down
3 changes: 3 additions & 0 deletions util/config_file.c
Expand Up @@ -354,6 +354,7 @@ config_create(void)
cfg->pad_responses_block_size = 468; /* from RFC8467 */
cfg->pad_queries = 1;
cfg->pad_queries_block_size = 128; /* from RFC8467 */
cfg->max_query_restarts = MAX_RESTART_COUNT;
#ifdef USE_IPSECMOD
cfg->ipsecmod_enabled = 1;
cfg->ipsecmod_ignore_bogus = 0;
Expand Down Expand Up @@ -774,6 +775,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_SIZET_NONZERO("pad-responses-block-size:", pad_responses_block_size)
else S_YNO("pad-queries:", pad_queries)
else S_SIZET_NONZERO("pad-queries-block-size:", pad_queries_block_size)
else S_SIZET_NONZERO("max-query-restarts:", max_query_restarts)
#ifdef USE_IPSECMOD
else S_YNO("ipsecmod-enabled:", ipsecmod_enabled)
else S_YNO("ipsecmod-ignore-bogus:", ipsecmod_ignore_bogus)
Expand Down Expand Up @@ -1241,6 +1243,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "pad-queries", pad_queries)
else O_DEC(opt, "pad-queries-block-size", pad_queries_block_size)
else O_LS2(opt, "edns-client-strings", edns_client_strings)
else O_DEC(opt, "max-query-restarts", max_query_restarts)
#ifdef USE_IPSECMOD
else O_YNO(opt, "ipsecmod-enabled", ipsecmod_enabled)
else O_YNO(opt, "ipsecmod-ignore-bogus", ipsecmod_ignore_bogus)
Expand Down
3 changes: 3 additions & 0 deletions util/config_file.h
Expand Up @@ -640,6 +640,9 @@ struct config_file {
/** block size with which to pad encrypted queries (default: 128) */
size_t pad_queries_block_size;

/** max number of query restarts. Determines max number of CNAME chain (default: 8) */
size_t max_query_restarts;

/** IPsec module */
#ifdef USE_IPSECMOD
/** false to bypass the IPsec module */
Expand Down
1 change: 1 addition & 0 deletions util/configlexer.lex
Expand Up @@ -531,6 +531,7 @@ pad-responses{COLON} { YDVAR(1, VAR_PAD_RESPONSES) }
pad-responses-block-size{COLON} { YDVAR(1, VAR_PAD_RESPONSES_BLOCK_SIZE) }
pad-queries{COLON} { YDVAR(1, VAR_PAD_QUERIES) }
pad-queries-block-size{COLON} { YDVAR(1, VAR_PAD_QUERIES_BLOCK_SIZE) }
max-query-restarts{COLON} { YDVAR(1, VAR_MAX_QUERY_RESTARTS) }
ipsecmod-enabled{COLON} { YDVAR(1, VAR_IPSECMOD_ENABLED) }
ipsecmod-ignore-bogus{COLON} { YDVAR(1, VAR_IPSECMOD_IGNORE_BOGUS) }
ipsecmod-hook{COLON} { YDVAR(1, VAR_IPSECMOD_HOOK) }
Expand Down
11 changes: 11 additions & 0 deletions util/configparser.y
Expand Up @@ -169,6 +169,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_DNSCRYPT_NONCE_CACHE_SLABS
%token VAR_PAD_RESPONSES VAR_PAD_RESPONSES_BLOCK_SIZE
%token VAR_PAD_QUERIES VAR_PAD_QUERIES_BLOCK_SIZE
%token VAR_MAX_QUERY_RESTARTS
%token VAR_IPSECMOD_ENABLED VAR_IPSECMOD_HOOK VAR_IPSECMOD_IGNORE_BOGUS
%token VAR_IPSECMOD_MAX_TTL VAR_IPSECMOD_WHITELIST VAR_IPSECMOD_STRICT
%token VAR_CACHEDB VAR_CACHEDB_BACKEND VAR_CACHEDB_SECRETSEED
Expand Down Expand Up @@ -289,6 +290,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_qname_minimisation_strict |
server_pad_responses | server_pad_responses_block_size |
server_pad_queries | server_pad_queries_block_size |
server_max_query_restarts |
server_serve_expired |
server_serve_expired_ttl | server_serve_expired_ttl_reset |
server_serve_expired_reply_ttl | server_serve_expired_client_timeout |
Expand Down Expand Up @@ -2635,6 +2637,15 @@ server_pad_queries_block_size: VAR_PAD_QUERIES_BLOCK_SIZE STRING_ARG
free($2);
}
;
server_max_query_restarts: VAR_MAX_QUERY_RESTARTS STRING_ARG
{
OUTYY(("P(server_max_query_restarts:%s)\n", $2));
if(atoi($2) == 0)
yyerror("number expected");
else cfg_parser->cfg->max_query_restarts = atoi($2);
free($2);
}
;
server_ipsecmod_enabled: VAR_IPSECMOD_ENABLED STRING_ARG
{
#ifdef USE_IPSECMOD
Expand Down