From: Moritz Schneider Date: Wed, 12 Jun 2019 16:51:26 +0000 (+0200) Subject: Make outbound msg retry configurable X-Git-Tag: release-1.14.0rc1~51^2^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=79cc0490964f37c7e047d4552bdd3c96f72ed9ec;p=thirdparty%2Funbound.git Make outbound msg retry configurable --- diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index c7f8def61..83563dbf5 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -175,6 +175,7 @@ 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->outbound_msg_retry = cfg->outbound_msg_retry; return 1; } @@ -532,7 +533,7 @@ iter_server_selection(struct iter_env* iter_env, if(num == 1) { a = dp->result_list; - if(++a->attempts < OUTBOUND_MSG_RETRY) + if(++a->attempts < iter_env->outbound_msg_retry) return a; dp->result_list = a->next_result; return a; @@ -552,7 +553,7 @@ iter_server_selection(struct iter_env* iter_env, } if(!a) /* robustness */ return NULL; - if(++a->attempts < OUTBOUND_MSG_RETRY) + if(++a->attempts < iter_env->outbound_msg_retry) return a; /* remove it from the delegation point result list */ if(prev) @@ -1224,11 +1225,11 @@ iter_scrub_nxdomain(struct dns_msg* msg) msg->rep->an_numrrsets = 0; } -void iter_dec_attempts(struct delegpt* dp, int d) +void iter_dec_attempts(struct delegpt* dp, int d, size_t outbound_msg_retry) { struct delegpt_addr* a; for(a=dp->target_list; a; a = a->next_target) { - if(a->attempts >= OUTBOUND_MSG_RETRY) { + if(a->attempts >= outbound_msg_retry) { /* add back to result list */ a->next_result = dp->result_list; dp->result_list = a; @@ -1239,7 +1240,7 @@ void iter_dec_attempts(struct delegpt* dp, int d) } } -void iter_merge_retry_counts(struct delegpt* dp, struct delegpt* old) +void iter_merge_retry_counts(struct delegpt* dp, struct delegpt* old, size_t outbound_msg_retry) { struct delegpt_addr* a, *o, *prev; for(a=dp->target_list; a; a = a->next_target) { @@ -1253,7 +1254,7 @@ void iter_merge_retry_counts(struct delegpt* dp, struct delegpt* old) prev = NULL; a = dp->usable_list; while(a) { - if(a->attempts >= OUTBOUND_MSG_RETRY) { + if(a->attempts >= outbound_msg_retry) { log_addr(VERB_ALGO, "remove from usable list dp", &a->addr, a->addrlen); /* remove from result list */ diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h index f771930bb..1ad5d4216 100644 --- a/iterator/iter_utils.h +++ b/iterator/iter_utils.h @@ -345,16 +345,19 @@ void iter_scrub_nxdomain(struct dns_msg* msg); * Remove query attempts from all available ips. For 0x20. * @param dp: delegpt. * @param d: decrease. + * @param outbound_msg_retry: number of retries of outgoing queries */ -void iter_dec_attempts(struct delegpt* dp, int d); +void iter_dec_attempts(struct delegpt* dp, int d, size_t outbound_msg_retry); /** * Add retry counts from older delegpt to newer delegpt. * Does not waste time on timeout'd (or other failing) addresses. * @param dp: new delegationpoint. * @param old: old delegationpoint. + * @param outbound_msg_retry: number of retries of outgoing queries */ -void iter_merge_retry_counts(struct delegpt* dp, struct delegpt* old); +void iter_merge_retry_counts(struct delegpt* dp, struct delegpt* old, + size_t outbound_msg_retry); /** * See if a DS response (type ANSWER) is too low: a nodata answer with diff --git a/iterator/iterator.c b/iterator/iterator.c index c906c2714..0b6236ad2 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -2188,7 +2188,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, iq->minimise_count++; iq->minimise_timeout_count = 0; - iter_dec_attempts(iq->dp, 1); + iter_dec_attempts(iq->dp, 1, ie->outbound_msg_retry); /* Limit number of iterations for QNAMEs with more * than MAX_MINIMISE_COUNT labels. Send first MINIMISE_ONE_LAB @@ -2358,7 +2358,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, (int)iq->caps_server+1, (int)naddr*3); iq->response = iq->caps_response; iq->caps_fallback = 0; - iter_dec_attempts(iq->dp, 3); /* space for fallback */ + iter_dec_attempts(iq->dp, 3, ie->outbound_msg_retry); /* space for fallback */ iq->num_current_queries++; /* RespState decrements it*/ iq->referral_count++; /* make sure we don't loop */ iq->sent_count = 0; @@ -2445,7 +2445,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, (int)iq->caps_server+1); iq->response = iq->caps_response; iq->caps_fallback = 0; - iter_dec_attempts(iq->dp, 3); /* space for fallback */ + iter_dec_attempts(iq->dp, 3, ie->outbound_msg_retry); /* space for fallback */ iq->num_current_queries++; /* RespState decrements it*/ iq->referral_count++; /* make sure we don't loop */ iq->sent_count = 0; @@ -2570,7 +2570,7 @@ find_NS(struct reply_info* rep, size_t from, size_t to) */ static int processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - int id) + int id, size_t outbound_msg_retry) { int dnsseclame = 0; enum response_type type; @@ -2843,7 +2843,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, } if(iq->store_parent_NS && query_dname_compare(iq->dp->name, iq->store_parent_NS->name) == 0) - iter_merge_retry_counts(iq->dp, iq->store_parent_NS); + iter_merge_retry_counts(iq->dp, iq->store_parent_NS, outbound_msg_retry); delegpt_log(VERB_ALGO, iq->dp); /* Count this as a referral. */ iq->referral_count++; @@ -3538,7 +3538,8 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq, cont = processQueryTargets(qstate, iq, ie, id); break; case QUERY_RESP_STATE: - cont = processQueryResponse(qstate, iq, id); + cont = processQueryResponse( + qstate, iq, id, ie->outbound_msg_retry); break; case PRIME_RESP_STATE: cont = processPrimeResponse(qstate, id); @@ -3608,7 +3609,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq, iq->num_current_queries--; /* need fresh attempts for the 0x20 fallback, if * that was the cause for the failure */ - iter_dec_attempts(iq->dp, 3); + iter_dec_attempts(iq->dp, 3, ie->outbound_msg_retry); verbose(VERB_DETAIL, "Capsforid: timeouts, starting fallback"); goto handle_it; } diff --git a/iterator/iterator.h b/iterator/iterator.h index a2f1b5705..87281969c 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -89,8 +89,6 @@ extern int UNKNOWN_SERVER_NICENESS; * Equals RTT_MAX_TIMEOUT */ #define USEFUL_SERVER_TOP_TIMEOUT 120000 -/** number of retries on outgoing queries */ -#define OUTBOUND_MSG_RETRY 5 /** RTT band, within this amount from the best, servers are chosen randomly. * Chosen so that the UNKNOWN_SERVER_NICENESS falls within the band of a * fast server, this causes server exploration as a side benefit. msec. */ @@ -134,6 +132,9 @@ struct iter_env { lock_basic_type queries_ratelimit_lock; /** number of queries that have been ratelimited */ size_t num_queries_ratelimited; + + /** number of retries on outgoing queries */ + size_t outbound_msg_retry; }; /** diff --git a/util/config_file.c b/util/config_file.c index 9b60254d7..63797c8e7 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -299,6 +299,7 @@ config_create(void) cfg->ratelimit_size = 4*1024*1024; cfg->ratelimit_for_domain = NULL; cfg->ratelimit_below_domain = NULL; + cfg->outbound_msg_retry = 5; cfg->ip_ratelimit_factor = 10; cfg->ratelimit_factor = 10; cfg->qname_minimisation = 1; @@ -660,6 +661,7 @@ 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_SIZET_NONZERO("outbound-msg-retry", outbound_msg_retry) else S_SIZET_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) @@ -1066,6 +1068,7 @@ 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_UNS(opt, "outbound-msg-retry", outbound_msg_retry) 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) diff --git a/util/config_file.h b/util/config_file.h index 3cffdbff9..6c249eddc 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -511,6 +511,8 @@ struct config_file { struct config_str2list* ratelimit_below_domain; /** ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */ int ratelimit_factor; + /** number of retries on outgoing queries */ + size_t outbound_msg_retry; /** minimise outgoing QNAME and hide original QTYPE if possible */ int qname_minimisation; /** minimise QNAME in strict mode, minimise according to RFC. diff --git a/util/configlexer.lex b/util/configlexer.lex index 16b5bc547..df8a6d585 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -450,6 +450,7 @@ ratelimit-for-domain{COLON} { YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) } 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) } +outbound-msg-retry{COLON} { YDVAR(1, VAR_OUTBOUND_MSG_RETRY) } low-rtt{COLON} { YDVAR(1, VAR_LOW_RTT) } fast-server-num{COLON} { YDVAR(1, VAR_FAST_SERVER_NUM) } low-rtt-pct{COLON} { YDVAR(1, VAR_FAST_SERVER_PERMIL) } diff --git a/util/configparser.y b/util/configparser.y index e90b18442..2681e76b5 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -130,6 +130,7 @@ extern struct config_parser_state* cfg_parser; %token VAR_DISABLE_DNSSEC_LAME_CHECK %token VAR_IP_RATELIMIT VAR_IP_RATELIMIT_SLABS VAR_IP_RATELIMIT_SIZE %token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE +%token VAR_OUTBOUND_MSG_RETRY %token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN %token VAR_IP_RATELIMIT_FACTOR VAR_RATELIMIT_FACTOR %token VAR_SEND_CLIENT_SUBNET VAR_CLIENT_SUBNET_ZONE @@ -239,9 +240,9 @@ content_server: server_num_threads | server_verbosity | server_port | server_ip_ratelimit_size | server_ratelimit_size | server_ratelimit_for_domain | server_ratelimit_below_domain | server_ratelimit_factor | - server_ip_ratelimit_factor | server_send_client_subnet | - server_client_subnet_zone | server_client_subnet_always_forward | - server_client_subnet_opcode | + server_ip_ratelimit_factor | server_outbound_msg_retry | + server_send_client_subnet | server_client_subnet_zone | + server_client_subnet_always_forward | server_client_subnet_opcode | server_max_client_subnet_ipv4 | server_max_client_subnet_ipv6 | server_min_client_subnet_ipv4 | server_min_client_subnet_ipv6 | server_max_ecs_tree_size_ipv4 | server_max_ecs_tree_size_ipv6 | @@ -2116,6 +2117,15 @@ server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG free($2); } ; +server_outbound_msg_retry: VAR_OUTBOUND_MSG_RETRY STRING_ARG +{ + OUTYY(("P(server_outbound_msg_retry:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->outbound_msg_retry = atoi($2); + free($2); +} +; server_low_rtt: VAR_LOW_RTT STRING_ARG { OUTYY(("P(low-rtt option is deprecated, use fast-server-num instead)\n"));