From: Lennart Poettering Date: Thu, 26 Jun 2025 21:04:07 +0000 (+0200) Subject: resolved: when determining error to return, prefer "conclusive" over "inconclusive... X-Git-Tag: v258-rc1~237 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=635b42edd9e8c3fc6ac9d43ebfd2800fc08c6b13;p=thirdparty%2Fsystemd.git resolved: when determining error to return, prefer "conclusive" over "inconclusive" errors When asked to look something up, and all scopes we contact fail we need to pick a suitable error code for the failure, and given that we look up things on multiple scopes we might have multiple errors to choose from. So far we simply picked the error from the last scope in the list, which hence would be pretty arbitrary. Let's tweak this a bit, and if we have multiple errors to choose from, let's prefer "conclusive" failures over "inconclusive" ones. The "inconclusive" ones in this sense are the ones where we didn't even issue a request, but couldn't even do that because we had no server, no network or things like that. The "conclusive" ones are the errors we got from a server, that hence a "real" in a way. This addresses the confusion described in #37969. For LLMNR lookups we generally refuse looking up A addresses via IPv6 and AAAA via IPv4. This generates a DNS_TRANSACTION_NO_SERVERS error, which we would then return for one type of lookup but not for the other, because the IPv6 scope is generally created after the IPv4 one, and hence so far won. Fixes: #37969 --- diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index dee771bb447..305399dfe8b 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -1157,8 +1157,14 @@ void dns_query_ready(DnsQuery *q) { break; default: - /* Any kind of failure */ - bad = c; + /* Any kind of failure: save the most recent error, as long as we never saved one + * before or our current one is "conclusive" in the sense that we definitely did a + * lookup, and thus have a real answer (which might be a failure, but is still *some* + * answer). */ + + if (!bad || !IN_SET(state, DNS_TRANSACTION_NO_SERVERS, DNS_TRANSACTION_NETWORK_DOWN, DNS_TRANSACTION_NO_SOURCE)) + bad = c; + break; } }