Skip to content

Commit

Permalink
connect: stop halving the remaining timeout when less than N ms left
Browse files Browse the repository at this point in the history
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 proposes that we stop doing the divided-by-two if the total
time left is below a threshold. This threshold is 600 milliseconds in
this initial commit.

To discuss:

A) a good/bad idea?
B) what's the threshold?
C) is there instead a better fix to do?
  • Loading branch information
bagder committed Aug 18, 2023
1 parent 98483a8 commit b3e7c2c
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions lib/connect.c
Expand Up @@ -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,
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit b3e7c2c

Please sign in to comment.