]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/selection: improve IPv6 avoidance if broken
authorVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 24 May 2022 07:02:53 +0000 (09:02 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 9 Jun 2022 07:16:49 +0000 (09:16 +0200)
It was still possible to get into a deadlock here.
https://forum.turris.cz/t/not-connecting-to-applications-like-discord/17111/7
If A records for a NS fell out of cache but AAAA remained,
with probability 1-\epsilon we'd choose an AAAA address
even if IPv6 was considered broken.

I looked at *the whole* no6 strategy again, and I do think that
there are no such holes anymore.  A few percent attempts will still
go over IPv6 even if it's considered broken, but that sounds OK-ish.

NEWS
lib/selection.c

diff --git a/NEWS b/NEWS
index 5541f924e45342cca2a962dd90b56a4b95ebfa7b..6c08885177e17ee4a1bf68a9406fe4c442664e1a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Improvements
 - daemon/tls: disable TLS resumption via tickets for TLS <= 1.2 (#742, !1295)
 - daemon/http: DoH now responds with proper HTTP codes (#728, !1279)
 - renumber module: allow rewriting subnet to a single IP (!1302)
+- nameserver selection algorithm: improve IPv6 avoidance if broken (!1298)
 
 Bugfixes
 --------
index 07cf2ee84a1afe0c15d1a5ac5788a3a0fc337b64..a418fc045cc04933714cdb70ac081ca4c2aac5f6 100644 (file)
@@ -440,7 +440,9 @@ struct kr_transport *select_transport(const struct choice choices[], int choices
        const struct choice *best = select_best(choices, choices_len);
        const struct choice *chosen;
 
-       const bool explore = choices_len == 0 || kr_rand_coin(EPSILON_NOMIN, EPSILON_DENOM);
+       const bool explore = choices_len == 0 || kr_rand_coin(EPSILON_NOMIN, EPSILON_DENOM)
+               /* We may need to explore to get at least one A record. */
+               || (no6_is_bad() && best->address.ip.sa_family == AF_INET6);
        if (explore) {
                /* "EXPLORE":
                 * randomly choose some option