From 83efd209c01256461b072f7cada28689b03feabc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Vladim=C3=ADr=20=C4=8Cun=C3=A1t?= Date: Tue, 24 May 2022 09:02:53 +0200 Subject: [PATCH] lib/selection: improve IPv6 avoidance if broken 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 | 1 + lib/selection.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 5541f924e..6c0888517 100644 --- 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 -------- diff --git a/lib/selection.c b/lib/selection.c index 07cf2ee84..a418fc045 100644 --- a/lib/selection.c +++ b/lib/selection.c @@ -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 -- 2.47.3