Maintained by: NLnet Labs

[Unbound-users] Resolve failures when using forwarders that do recursion

Florian Riehm
Sun Dec 8 18:00:01 CET 2013


On 11/26/13 00:42, Florian Riehm wrote:
>>>
>>> If we turn the infra-cache off, Unbound will use its standard 376ms timeout and
>>> the situation may get even worse.
>>>
>>> Does it maybe make sense to add a new configuration parameter that allows to set
>>> a custom timeout value when using forwarders? In the case of that poor
>>> unbound.host
>>> we would set that timeout to be ~ 1500ms or something like that.
>>> It may be per-server or global value, and should be used only for requests
>>> to "upstream" servers.
>>>

Hi,

Please have a look to the attached patch.
It adds a new config option 'infra-cache-min-rtt' which makes the former
constant value of RTT_MIN_TIMEOUT adjustable. This gives the user the
opportunity to choose a reasonable retransmit timeout value.

I have tested different scenarios with forwarders inside my local network and
with google dns forwarders. Values about 1000 ms seems to be fine.
Inside lan 1500 ms works a little bit better. I haven't seen timeouts anymore
with this value.
If using google dns it could be neccessary to decrease the value to 750 ms
to compensate packet loss.

I would be glad if you could commit my patch.

Thanks.

Florian



Index: doc/unbound.conf.5.in
===================================================================
--- doc/unbound.conf.5.in	(revision 3036)
+++ doc/unbound.conf.5.in	(working copy)
@@ -286,6 +286,11 @@ by threads. Must be set to a power of 2.
 .B infra\-cache\-numhosts: \fI<number>
 Number of hosts for which information is cached. Default is 10000.
 .TP
+.B infra\-cache\-min\-rtt: \fI<msec>
+Lower limit for dynamic retransmit timeout calculation in infrastructure
+cache. Default is 50 milliseconds. Increase this value if using forwarders
+needing more time to do recursive name resolution.
+.TP
 .B do\-ip4: \fI<yes or no>
 Enable or disable whether ip4 queries are answered or issued. Default is yes.
 .TP
Index: util/config_file.c
===================================================================
--- util/config_file.c	(revision 3036)
+++ util/config_file.c	(working copy)
@@ -55,6 +55,7 @@
 #include "util/regional.h"
 #include "util/fptr_wlist.h"
 #include "util/data/dname.h"
+#include "util/rtt.h"
 #include "ldns/wire2str.h"
 #include "ldns/parseutil.h"
 #ifdef HAVE_GLOB_H
@@ -138,6 +139,7 @@ config_create(void)
 	cfg->prefetch_key = 0;
 	cfg->infra_cache_slabs = 4;
 	cfg->infra_cache_numhosts = 10000;
+	cfg->infra_cache_min_rtt = 50;
 	if(!(cfg->outgoing_avail_ports = (int*)calloc(65536, sizeof(int))))
 		goto error_exit;
 	init_outgoing_availports(cfg->outgoing_avail_ports, 65536);
@@ -373,6 +375,10 @@ int config_set_option(struct config_file* cfg, con
 	{ IS_NUMBER_OR_ZERO; cfg->max_ttl = atoi(val); MAX_TTL=(time_t)cfg->max_ttl;}
 	else if(strcmp(opt, "cache-min-ttl:") == 0)
 	{ IS_NUMBER_OR_ZERO; cfg->min_ttl = atoi(val); MIN_TTL=(time_t)cfg->min_ttl;}
+	else if(strcmp(opt, "infra-cache-min-rtt:") == 0) {
+	    IS_NUMBER_OR_ZERO; cfg->infra_cache_min_rtt = atoi(val);
+	    RTT_MIN_TIMEOUT=cfg->infra_cache_min_rtt;
+	}
 	else S_NUMBER_OR_ZERO("infra-host-ttl:", host_ttl)
 	else S_POW2("infra-cache-slabs:", infra_cache_slabs)
 	else S_SIZET_NONZERO("infra-cache-numhosts:", infra_cache_numhosts)
@@ -618,6 +624,7 @@ config_get_option(struct config_file* cfg, const c
 	else O_DEC(opt, "cache-min-ttl", min_ttl)
 	else O_DEC(opt, "infra-host-ttl", host_ttl)
 	else O_DEC(opt, "infra-cache-slabs", infra_cache_slabs)
+	else O_DEC(opt, "infra-cache-min-rtt", infra_cache_min_rtt)
 	else O_MEM(opt, "infra-cache-numhosts", infra_cache_numhosts)
 	else O_YNO(opt, "do-ip4", do_ip4)
 	else O_YNO(opt, "do-ip6", do_ip6)
@@ -1177,6 +1184,7 @@ config_apply(struct config_file* config)
 {
 	MAX_TTL = (time_t)config->max_ttl;
 	MIN_TTL = (time_t)config->min_ttl;
+	RTT_MIN_TIMEOUT = config->infra_cache_min_rtt;
 	EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;
 	MINIMAL_RESPONSES = config->minimal_responses;
 	RRSET_ROUNDROBIN = config->rrset_roundrobin;
Index: util/config_file.h
===================================================================
--- util/config_file.h	(revision 3036)
+++ util/config_file.h	(working copy)
@@ -119,6 +119,8 @@ struct config_file {
 	size_t infra_cache_slabs;
 	/** max number of hosts in the infra cache */
 	size_t infra_cache_numhosts;
+	/** min value for infra cache rtt */
+	int infra_cache_min_rtt;

 	/** the target fetch policy for the iterator */
 	char* target_fetch_policy;
Index: util/configlexer.lex
===================================================================
--- util/configlexer.lex	(revision 3036)
+++ util/configlexer.lex	(working copy)
@@ -245,6 +245,7 @@ infra-lame-ttl{COLON}		{ YDVAR(1, VAR_INFRA_LAME_T
 infra-cache-slabs{COLON}	{ YDVAR(1, VAR_INFRA_CACHE_SLABS) }
 infra-cache-numhosts{COLON}	{ YDVAR(1, VAR_INFRA_CACHE_NUMHOSTS) }
 infra-cache-lame-size{COLON}	{ YDVAR(1, VAR_INFRA_CACHE_LAME_SIZE) }
+infra-cache-min-rtt{COLON}	{ YDVAR(1, VAR_INFRA_CACHE_MIN_RTT) }
 num-queries-per-thread{COLON}	{ YDVAR(1, VAR_NUM_QUERIES_PER_THREAD) }
 jostle-timeout{COLON}		{ YDVAR(1, VAR_JOSTLE_TIMEOUT) }
 target-fetch-policy{COLON}	{ YDVAR(1, VAR_TARGET_FETCH_POLICY) }
Index: util/configparser.y
===================================================================
--- util/configparser.y	(revision 3036)
+++ util/configparser.y	(working copy)
@@ -105,7 +105,7 @@ extern struct config_parser_state* cfg_parser;
 %token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
 %token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
 %token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
-%token VAR_MAX_UDP_SIZE
+%token VAR_MAX_UDP_SIZE VAR_INFRA_CACHE_MIN_RTT

 %%
 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -162,7 +162,8 @@ content_server: server_num_threads | server_verbos
 	server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag |
 	server_log_queries | server_tcp_upstream | server_ssl_upstream |
 	server_ssl_service_key | server_ssl_service_pem | server_ssl_port |
-	server_minimal_responses | server_rrset_roundrobin | server_max_udp_size
+	server_minimal_responses | server_rrset_roundrobin |
+	server_max_udp_size | server_infra_cache_min_rtt
 	;
 stubstart: VAR_STUB_ZONE
 	{
@@ -726,6 +727,15 @@ server_infra_cache_slabs: VAR_INFRA_CACHE_SLABS ST
 		free($2);
 	}
 	;
+server_infra_cache_min_rtt: VAR_INFRA_CACHE_MIN_RTT STRING_ARG
+	{
+		OUTYY(("P(server_infra_cache_min_rtt:%s)\n", $2));
+		if(atoi($2) == 0 && strcmp($2, "0") != 0)
+			yyerror("number expected");
+		else cfg_parser->cfg->infra_cache_min_rtt = atoi($2);
+		free($2);
+	}
+	;
 server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG
 	{
 		OUTYY(("P(server_target_fetch_policy:%s)\n", $2));
Index: util/rtt.c
===================================================================
--- util/rtt.c	(revision 3036)
+++ util/rtt.c	(working copy)
@@ -42,6 +42,8 @@
 #include "config.h"
 #include "util/rtt.h"

+/* overwritten by config: infra_cache_min_rtt: */
+int RTT_MIN_TIMEOUT = 50;
 /** calculate RTO from rtt information */
 static int
 calc_rto(const struct rtt_info* rtt)
Index: util/rtt.h
===================================================================
--- util/rtt.h	(revision 3036)
+++ util/rtt.h	(working copy)
@@ -56,7 +56,7 @@ struct rtt_info {
 };

 /** min retransmit timeout value, in milliseconds */
-#define RTT_MIN_TIMEOUT	50
+extern int RTT_MIN_TIMEOUT;
 /** max retransmit timeout value, in milliseconds */
 #define RTT_MAX_TIMEOUT 120000