Skip to content

Conversation

@icing
Copy link
Contributor

@icing icing commented Jul 30, 2025

When CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS expires, start the next ip connect attempt, but keep all ongoing attempts alive.

Separate happy-eyeballs connection filter into own source files.

@github-actions github-actions bot added the tests label Jul 30, 2025
@icing icing force-pushed the ip-eyeballing-improve branch from a019e47 to 49db114 Compare July 30, 2025 15:23
@bagder
Copy link
Member

bagder commented Jul 30, 2025

I love it!

When `CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS` expires, start the next
ip connect attempt, but keep all ongoing attempts alive.

Separate happy-eyeballs connection filter into own source files.
@icing icing force-pushed the ip-eyeballing-improve branch from e4b2831 to 95e09ee Compare July 31, 2025 08:24
@icing icing marked this pull request as ready for review July 31, 2025 12:42
@icing icing requested a review from bagder July 31, 2025 12:42
@bagder bagder closed this in af69c9d Aug 1, 2025
@dscho
Copy link
Contributor

dscho commented Sep 29, 2025

Hmm. I am experiencing some difficulties in Microsoft Git with this change, and reverting this PR "fixes" it.

The problem is that curl_multi_timeout() (when being called in a test that intentionally tries to access a non-existing server by connecting to http://127.0.0.1:5799/ when nobody is listening on that port) changed behavior. Previously, it kept returning a timeout of -1. Now, the timeout is instead first set to 200ms (or 199ms, sometimes). The next two calls return 300 seconds (i.e. not milliseconds), and the next three calls repeat that sequence, causing my test case to fail for different reasons than the expected one.

Is this by design? I could understand if the six attempts would now cause 200ms * 5 = one second of extra delay, but not an extra delay that had not been there before of more than 20 minutes.

FWIW when I tried to debug this, I saw that the 300 seconds come from the Curl_timeleft() call in the new cf_ip_ballers_run() call, which returns essentially the DEFAULT_CONNECT_TIMEOUT. The stack trace when that happens looks like this:

#0  cf_ip_ballers_run (bs=0x27752d8, cf=0x2775390, data=0x2772900, connected=0x5ff687) at cf-ip-happy.c:498
#1  0x00007ffb9c34bf1a in is_connected (cf=0x2775390, data=0x2772900, connected=0x5ff687) at cf-ip-happy.c:625
#2  0x00007ffb9c34c511 in cf_ip_happy_connect (cf=0x2775390, data=0x2772900, done=0x5ff687) at cf-ip-happy.c:758
#3  0x00007ffb9c35149a in Curl_conn_cf_connect (cf=0x2775390, data=0x2772900, done=0x5ff687) at cfilters.c:413
#4  0x00007ffb9c355c7d in cf_setup_connect (cf=0x27750a0, data=0x2772900, done=0x5ff687) at connect.c:387
#5  0x00007ffb9c3518b2 in Curl_conn_connect (data=0x2772900, sockindex=0, blocking=false, done=0x5ff687) at cfilters.c:498
#6  0x00007ffb9c397268 in multi_runsingle (multi=0xfb8410, nowp=0x5ff710, data=0x2772900) at multi.c:2429
#7  0x00007ffb9c397ccd in curl_multi_perform (m=0xfb8410, running_handles=0x5ff794) at multi.c:2758

This amount is then dutifully added to the splay list, from where curl_multi_timeout() obtains it.

Is this a bug, or do I now have to call cURL's API in a different way to get back the previous behavior?

@icing
Copy link
Contributor Author

icing commented Sep 29, 2025

Could you open a new issue for this? I think I understand to what you are referring to, but since this PR is closed, any fix of this would work better with a separate issue.

@dscho
Copy link
Contributor

dscho commented Sep 29, 2025

Could you open a new issue for this? I think I understand to what you are referring to, but since this PR is closed, any fix of this would work better with a separate issue.

@icing done: #18767

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

3 participants