From 248894690c4b669a1187f1a21551d7b00491b3d5 Mon Sep 17 00:00:00 2001 From: dramforever Date: Sun, 14 Sep 2025 05:39:19 +0800 Subject: [PATCH] libstore: Raise default connect-timeout to 15 secs This allows the weird network or DNS server fallback mechanism inside glibc to work, and prevents a "Resolving timed out after 5000 milliseconds" error. Read on for details. The DNS request stuff (dns-hosts) in glibc uses this fallback procedure to minimize network RTT in the ideal case while dealing with ill-behaving networks and DNS servers gracefully (see resolv.conf(5)): - Use sendmmsg() to send UDP DNS requests for IPv4 and IPv6 in parallel - If that times out (meaning that none or only one of the responses have been received), send the requests one by one, waiting for the response before sending the next request ("single-request") - If that still times out, try to use a different socket (hence different address) for each request ("single-request-reopen") The default timeout inside glibc is 5 seconds. Therefore, setting connect-timeout, and therefore CURLOPT_CONNECTTIMEOUT to 5 seconds prevents the single-request fallback, and setting it to even 10 seconds prevents the single-request-reopen fallback as well. The fallback decision is saved by glibc, but only thread-locally, and libcurl starts a new thread for getaddrinfo() for each connection. Therefore for every connection the fallback starts from sendmmsg() all over again. And since these are considered to have timed out by libcurl, even though getaddrinfo() might return a successful result, it is not cached in libcurl. While a user could tweak these with resolv.conf(5) options (e.g. using networking.resolvconf.extraOptions in NixOS), and indeed that is probably needed to avoid annoying delays, it still means that the default connect-timeout of 5 is too low. Raise it to give fallback a chance. (cherry picked from commit 7295034362a2655d9e916db6dd3e1f89b393ed94) --- src/libstore/include/nix/store/filetransfer.hh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libstore/include/nix/store/filetransfer.hh b/src/libstore/include/nix/store/filetransfer.hh index 8ff0de5ef..3a341910a 100644 --- a/src/libstore/include/nix/store/filetransfer.hh +++ b/src/libstore/include/nix/store/filetransfer.hh @@ -30,9 +30,17 @@ struct FileTransferSettings : Config )", {"binary-caches-parallel-connections"}}; + /* Do not set this too low. On glibc, getaddrinfo() contains fallback code + paths that deal with ill-behaved DNS servers. Setting this too low + prevents some fallbacks from occurring. + + See description of options timeout, single-request, single-request-reopen + in resolv.conf(5). Also see https://github.com/NixOS/nix/pull/13985 for + details on the interaction between getaddrinfo(3) behavior and libcurl + CURLOPT_CONNECTTIMEOUT. */ Setting connectTimeout{ this, - 5, + 15, "connect-timeout", R"( The timeout (in seconds) for establishing connections in the