mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] [PATCH] resolvconf: Set minimum timeout value to 1
@ 2025-02-24 21:04 roblabla
  2025-02-26  7:42 ` Quentin Rameau
  0 siblings, 1 reply; 3+ messages in thread
From: roblabla @ 2025-02-24 21:04 UTC (permalink / raw)
  To: musl; +Cc: roblabla

/etc/resolv.conf has an option to configure the timeout, in seconds,
that the DNS resolution must wait before considering that resolution to
have failed. While there is no documentation about what happens when
that value contains a 0 or negative value, some machines appear to have
it configured this way.

Previously, when resolv.conf contained a timeout value of 0, musl would
fail to do any DNS resolution. More precisely, __res_msend_rc wouldn't
even try to send a single query out, as the bulk of the work is done in
a loop that checks for timeout expiration. With the timeout set to 0,
we wouldn't even enter this loop, and thus never send a single DNS
request. This would manifest in user programs as API such as getaddrinfo
returning a TRY_AGAIN error in h_errno.

Other language runtimes seem more foolproof against this kind of
misconfiguration, mostly by considering a 0 or negative timeout value to
simply mean 1. For example:

- In glibc, we can see the timeout is automatically increased to 1 in
  the function responsible for handling this timeout:
  https://github.com/bminor/glibc/blob/glibc-2.41/resolv/res_send.c#L945-L949
- In go, when parsing the resolv.conf file, it sets the timeout value to
  1 if it was lower than that:
  https://github.com/golang/go/blob/go1.24.0/src/net/dnsconfig_unix.go#L89-L91

This commit makes musl take this approach. Upon parsing the timeout
value, if it encounters a value below or equal to 0, it simply raises it
back to 1 second. This allows MUSL program to run on machines that are
misconfigured in this way, matching the behavior of both glibc and go.
---
 src/network/resolvconf.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/network/resolvconf.c b/src/network/resolvconf.c
index ceabf080..5735165a 100644
--- a/src/network/resolvconf.c
+++ b/src/network/resolvconf.c
@@ -55,7 +55,15 @@ int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
 			if (p && (isdigit(p[8]) || p[8]=='.')) {
 				p += 8;
 				unsigned long x = strtoul(p, &z, 10);
-				if (z != p) conf->timeout = x > 60 ? 60 : x;
+				if (z != p) {
+					/* Setting a timeout to 0 would result in a non-functional
+					 * DNS resolution. Both glibc and go default to 1 when x is
+					 * set to 0, let's follow suit.
+					 */
+					if (x < 1) x = 1;
+					if (x > 60) x = 60;
+					conf->timeout = x;
+				}
 			}
 			continue;
 		}

base-commit: 1880359b54ff7dd9f5016002bfdae4b136007dde
-- 
2.47.2


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [musl] [PATCH] resolvconf: Set minimum timeout value to 1
  2025-02-24 21:04 [musl] [PATCH] resolvconf: Set minimum timeout value to 1 roblabla
@ 2025-02-26  7:42 ` Quentin Rameau
  2025-02-26 10:31   ` roblabla
  0 siblings, 1 reply; 3+ messages in thread
From: Quentin Rameau @ 2025-02-26  7:42 UTC (permalink / raw)
  To: musl

Hi,

> /etc/resolv.conf has an option to configure the timeout, in seconds,
> that the DNS resolution must wait before considering that resolution to
> have failed. While there is no documentation about what happens when
> that value contains a 0 or negative value, some machines appear to have
> it configured this way.

The question is what was the user intent when setting timeout to 0
or a negative value.
Surely that wouldn't be having a timeout of 1,
because they would have put a timeout of 1.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [musl] [PATCH] resolvconf: Set minimum timeout value to 1
  2025-02-26  7:42 ` Quentin Rameau
@ 2025-02-26 10:31   ` roblabla
  0 siblings, 0 replies; 3+ messages in thread
From: roblabla @ 2025-02-26 10:31 UTC (permalink / raw)
  To: musl

> The question is what was the user intent when setting timeout to 0
> or a negative value.
> Surely that wouldn't be having a timeout of 1,
> because they would have put a timeout of 1.

I was able to trace this practice to a (I think misguided) stackoverflow answer[0], which claims that

> The effect is that the resolver asks the number of nameservers without waiting and returns the first response. It should be used only when your first server in the resolv.conf is overloaded. But normally it has no effect, because the dns responses are quick. 

This is, of course, not really true (glibc will act as if a timeout of 1 was specified - it will still wait a second for the answer of the first nameserver, before asking the next one), and anyways a moot point in musl since it asks all nameservers in parallel instead of one after the other.

So my best guess is that people are setting the timeout to 0 to workaround a faulty/laggy first nameserver in their resolv.conf causing undue lag in their glibc-based apps.


[0]: https://unix.stackexchange.com/questions/120623/what-is-the-effect-of-setting-the-timeout-value-to-0-in-etc-resolv-conf

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-02-26 10:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-24 21:04 [musl] [PATCH] resolvconf: Set minimum timeout value to 1 roblabla
2025-02-26  7:42 ` Quentin Rameau
2025-02-26 10:31   ` roblabla

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).