curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Re: Connection takes too long in dual-stack if IPv6 starting family is not available or blocked and has multiple addresses.

From: Daniel Stenberg via curl-library <curl-library_at_cool.haxx.se>
Date: Fri, 4 Jun 2021 15:35:18 +0200 (CEST)

On Thu, 3 Jun 2021, Dmitry Karpov via curl-library wrote:

> I am not sure if this is the right fix, but it helped to improve the
> connection phase time for such cases very dramatically and make it close to
> pure IPv4 connection times. My tests also didn't reveal any bad side effects
> of this change.

Thanks for this!

From my understanding of this issue, this problem happens because
Curl_is_connected() gets called after a while but not because of a timeout on
the socket but because of an error.

This makes 'rc' not contain zero so the conditional check if it should start
the other family for connecting doesn't run but instead it kicks off another
connect attempt to the next IPv6 address.

If this is correct, shouldn't we then be able to fix the issue by making sure
that we check the happy-eyeballs-timeout both for timeouts and for errors? To
me, that seems like a simpler take than your proposal.

I mean like this:

diff --git a/lib/connect.c b/lib/connect.c
index d9317f378..2c209fa56 100644
--- a/lib/connect.c
+++ b/lib/connect.c
_at__at_ -931,18 +931,10 _at__at_ CURLcode Curl_is_connected(struct Curl_easy *data,
           conn->timeoutms_per_addr[i]) {
          infof(data, "After %" CURL_FORMAT_TIMEDIFF_T
                "ms connect time, move on!\n", conn->timeoutms_per_addr[i]);
          error = ETIMEDOUT;
        }
-
- /* should we try another protocol family? */
- if(i == 0 && !conn->bits.parallel_connect &&
- (Curl_timediff(now, conn->connecttime) >=
- data->set.happy_eyeballs_timeout)) {
- conn->bits.parallel_connect = TRUE; /* starting now */
- trynextip(data, conn, sockindex, 1);
- }
      }
      else if(rc == CURL_CSELECT_OUT || conn->bits.tcp_fastopen) {
        if(verifyconnect(conn->tempsock[i], &error)) {
          /* we are connected with TCP, awesome! */

_at__at_ -1002,10 +994,20 _at__at_ CURLcode Curl_is_connected(struct Curl_easy *data,
             conn->tempsock[other] == CURL_SOCKET_BAD)
            /* the last attempt failed and no other sockets remain open */
            result = status;
        }
      }
+
+ if(!rc || error) {
+ /* should we try another protocol family? */
+ if(i == 0 && !conn->bits.parallel_connect &&
+ (Curl_timediff(now, conn->connecttime) >=
+ data->set.happy_eyeballs_timeout)) {
+ conn->bits.parallel_connect = TRUE; /* starting now */
+ trynextip(data, conn, sockindex, 1);
+ }
+ }
    }

    if(result &&
       (conn->tempsock[0] == CURL_SOCKET_BAD) &&
       (conn->tempsock[1] == CURL_SOCKET_BAD)) {


-- 
  / daniel.haxx.se
  | Commercial curl support up to 24x7 is available!
  | Private help, bug fixes, support, ports, new features
  | https://www.wolfssl.com/contact/
-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.se/mail/etiquette.html
Received on 2021-06-04