]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
connect: stop halving the remaining timeout when less than 600 ms left
authorDaniel Stenberg <daniel@haxx.se>
Fri, 18 Aug 2023 11:41:16 +0000 (13:41 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 29 Aug 2023 08:43:26 +0000 (10:43 +0200)
When curl wants to connect to a host, it always has a TIMEOUT. The
maximum time it is allowed to spend until a connect is confirmed.

curl will try to connect to each of the IP adresses returned for the
host. Two loops, one for each IP family.

During the connect loop, while curl has more than one IP address left to
try within a single address family, curl has traditionally allowed (time
left/2) for *this* connect attempt. This, to not get stuck on the
initial addresses in case the timeout but still allow later addresses to
get attempted.

This has the downside that when users set a very short timeout and the
host has a large number of IP addresses, the effective result might be
that every attempt gets a little too short time.

This change stop doing the divided-by-two if the total time left is
below a threshold. This threshold is 600 milliseconds.

Closes #11693

lib/connect.c

index 98a733ee7fb58bf968aac85c8590a3d1f0667c01..d652be8ae23d60c2d025b4bc6abae6d0effb1f7f 100644 (file)
@@ -381,6 +381,11 @@ struct cf_he_ctx {
   struct curltime started;
 };
 
+/* when there are more than one IP address left to use, this macro returns how
+   much of the given timeout to spend on *this* attempt */
+#define TIMEOUT_LARGE 600
+#define USETIME(ms) ((ms > TIMEOUT_LARGE) ? (ms / 2) : ms)
+
 static CURLcode eyeballer_new(struct eyeballer **pballer,
                               cf_ip_connect_create *cf_create,
                               const struct Curl_addrinfo *addr,
@@ -408,7 +413,7 @@ static CURLcode eyeballer_new(struct eyeballer **pballer,
   baller->primary = primary;
   baller->delay_ms = delay_ms;
   baller->timeoutms = addr_next_match(baller->addr, baller->ai_family)?
-                        timeout_ms / 2 : timeout_ms;
+    USETIME(timeout_ms) : timeout_ms;
   baller->timeout_id = timeout_id;
   baller->result = CURLE_COULDNT_CONNECT;
 
@@ -501,7 +506,7 @@ static CURLcode baller_start(struct Curl_cfilter *cf,
   while(baller->addr) {
     baller->started = Curl_now();
     baller->timeoutms = addr_next_match(baller->addr, baller->ai_family) ?
-                         timeoutms / 2 : timeoutms;
+      USETIME(timeoutms) : timeoutms;
     baller_initiate(cf, data, baller);
     if(!baller->result)
       break;