From: Wouter Wijngaards Date: Fri, 6 Jul 2018 14:40:35 +0000 (+0000) Subject: - Fix round robin for failed addresses with prefer-ip6: yes X-Git-Tag: release-1.8.0rc1~106 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e3c30beac726e0a7d712864929ac325e1f44ff4;p=thirdparty%2Funbound.git - Fix round robin for failed addresses with prefer-ip6: yes git-svn-id: file:///svn/unbound/trunk@4776 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 52ede2978..c4c1e1864 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -4,6 +4,7 @@ - iana port update. - Note RFC8162 support. SMIMEA record type can be read in by the zone record parser. + - Fix round robin for failed addresses with prefer-ip6: yes 4 July 2018: Wouter - Fix #4112: Fix that unbound-anchor -f /etc/resolv.conf will not pass diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index df66776ae..90c8cf114 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -378,17 +378,32 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env, int attempt = -1; /* filter to make sure addresses have less attempts on them than the first, to force round robin when all the IPv6 addresses fail */ + int num4ok = 0; /* number ip4 at low attempt count */ + int num4_lowrtt = 0; prev = NULL; a = dp->result_list; for(i = 0; i < got_num; i++) { swap_to_front = 0; - if(a->addr.ss_family != AF_INET6 && attempt == -1) + if(a->addr.ss_family != AF_INET6 && attempt == -1) { + /* if we only have ip4 at low attempt count, + * then ip6 is failing, and we need to + * select one of the remaining IPv4 addrs */ attempt = a->attempts; - if(a->addr.ss_family == AF_INET6 && - (attempt==-1 || a->attempts<=attempt)) { - got_num6++; - if(attempt == -1) + num4ok++; + num4_lowrtt = a->sel_rtt; + } else if(a->addr.ss_family != AF_INET6 && attempt == a->attempts) { + num4ok++; + if(num4_lowrtt == 0 || a->sel_rtt < num4_lowrtt) { + num4_lowrtt = a->sel_rtt; + } + } + if(a->addr.ss_family == AF_INET6) { + if(attempt == -1) { attempt = a->attempts; + } else if(a->attempts > attempt) { + break; + } + got_num6++; swap_to_front = 1; if(low_rtt6 == 0 || a->sel_rtt < low_rtt6) { low_rtt6 = a->sel_rtt; @@ -409,6 +424,9 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env, if(got_num6 > 0) { got_num = got_num6; *selected_rtt = low_rtt6; + } else if(num4ok > 0) { + got_num = num4ok; + *selected_rtt = num4_lowrtt; } } return got_num;