curl-library
Happy Eyeballs connection timeout
Date: Thu, 1 Oct 2015 11:22:58 +0000
Hi,
Would like to share results of connection timeout testing we did on libcurl 7.42.1 Happy Eyeballs and get your opinions on what the behaviour should be :
Test Description :
Attempt to connect to an FQDN "unhappyeyeballs.ipv6lab.com" which has both A and AAAA records, but neither of the IP addresses are reachable.
Set the libcurl CURLOPT_CONNECTTIMEOUT_MS = 10000 ( 10 seconds )
The observed timeout is 5200ms, shorter than expected
Curl Trace log :
[curlTraceCallback] - Curl debug message: Rebuilt URL to: unhappyeyeballs.ipv6lab.com /
[curlTraceCallback] - Curl debug message: Duplicating password for request http://unhappyeyeballs.ipv6lab.com/
[curlTraceCallback] - Curl debug message: Trying 1:1:1:1:1:1:1:1...
[curlTraceCallback] - Curl debug message: Trying 172.16.32.48...
[curlTraceCallback] - Curl debug message: After 5000ms connect time, move on!
[curlTraceCallback] - Curl debug message: connect to 1:1:1:1:1:1:1:1 port 80 failed: Connection timed out
[curlTraceCallback] - Curl debug message: After 2397ms connect time, move on!
[curlTraceCallback] - Curl debug message: connect to 172.16.32.48 port 80 failed: Connection timed out
[curlTraceCallback] - Curl debug message: Failed to connect to unhappyeyeballs.ipv6lab.com port 80: Connection timed out
[curlTraceCallback] - Curl debug message: Closing connection 0
Code Analysis :
I spend some time trying to understand the trace messages :
"After 5000ms connect time, move on!"
"After 2397ms connect time, move on!"
In connect.c, Curl_connecthost method, line 1159, the timeout_ms_per_addr is halved if there is more than 1 node in the tempaddr linked list before any connection attempt,
This will be case if there is both an A and AAAA record available for the FQDN
On line 829 within the Curl_is_connected method, the timeout_ms_per_addr is halved again when the first connection fails
Then I think we arrive at the timings seen because :
IPv6 conn->timeoutms_per_addr = 5000
IPv4 conn->timeoutms_per_addr = 5000-200 = 4800
when IPV6 connection fails :
IPV4 conn->timeoutms_per_addr = 4800/2 = 2400 ( due to the error handling logic on line 829 )
So :
IPv6 conn->timeoutms_per_addr = 5000 leads to the trace message "After 5000ms connect time, move on!" and
IPV4 conn->timeoutms_per_addr = 2400 leads to the trace message "After 2397ms connect time, move on!"
Since the IPV6 and IPV4 connections are done in parallel, I'm wondering if it is really necessary to half timeout on line 1159, perhaps reducing the timeout of the IPv4 attempt by HAPPY_EYEBALLS_TIMEOUT ( 200ms ) would be a good approach when there is more than one node in the tempaddr linked list.
Also I was wondering why the connection timeout is halved again on line 829 when the first connection fails ? Are there cases other than happy eyeballs where there is more than 1 address to attempt and it is appropriate to half the timeout ?
Appreciate your opinions on this
Thanks,
Will
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2015-10-01