]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
hostip: lazily wait to figure out if IPv6 works until needed
authorDaniel Stenberg <daniel@haxx.se>
Wed, 21 Sep 2022 06:52:57 +0000 (08:52 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 22 Sep 2022 07:47:59 +0000 (09:47 +0200)
The check may take many milliseconds, so now it is performed once the
value is first needed. Also, this change makes sure that the value is
not used if the resolve is set to be IPv4-only.

Closes #9553

lib/asyn-ares.c
lib/asyn-thread.c
lib/doh.c
lib/hostip.c
lib/hostip6.c
lib/multi.c
lib/multihandle.h

index 1f3965541eed13a08c3c013dc797da3d918ac100..cbc0e2ea77c9057831cce964fd24acabe94d15ef 100644 (file)
@@ -779,10 +779,9 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
       int pf = PF_INET;
       memset(&hints, 0, sizeof(hints));
 #ifdef CURLRES_IPV6
-      if(Curl_ipv6works(data))
+      if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data))
         /* The stack seems to be IPv6-enabled */
-        if(data->conn->ip_version != CURL_IPRESOLVE_V4)
-          pf = PF_UNSPEC;
+        pf = PF_UNSPEC;
 #endif /* CURLRES_IPV6 */
       hints.ai_family = pf;
       hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
@@ -795,7 +794,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
 #else
 
 #ifdef HAVE_CARES_IPV6
-    if(Curl_ipv6works(data) && data->conn->ip_version != CURL_IPRESOLVE_V4) {
+    if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) {
       /* The stack seems to be IPv6-enabled */
       res->num_pending = 2;
 
index 68fddf0b22d28f34c1119cdae9333bdf8d55041d..8b375eb5ee8924217e191964b61e9a6772ee314f 100644 (file)
@@ -707,7 +707,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
   *waitp = 0; /* default to synchronous response */
 
 #ifdef CURLRES_IPV6
-  if(Curl_ipv6works(data) && data->conn->ip_version != CURL_IPRESOLVE_V4)
+  if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data))
     /* The stack seems to be IPv6-enabled */
     pf = PF_UNSPEC;
 #endif /* CURLRES_IPV6 */
index 29399772b115a359d9b12f170fe63b2322cb63b8..3b1d5d60ef860f5ae240629e82128fd221a2f973 100644 (file)
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -396,7 +396,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
     goto error;
   dohp->pending++;
 
-  if(Curl_ipv6works(data) && conn->ip_version != CURL_IPRESOLVE_V4) {
+  if((conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) {
     /* create IPv6 DoH request */
     result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V6],
                       DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH],
index ec27602dc90c2a9b577266d32a6df799d251474b..0eb565a2e536c27c8fc18995e16e3799b0a9901d 100644 (file)
@@ -569,7 +569,11 @@ bool Curl_ipv6works(struct Curl_easy *data)
        have the info kept for fast re-use */
     DEBUGASSERT(data);
     DEBUGASSERT(data->multi);
-    return data->multi->ipv6_works;
+    if(data->multi->ipv6_up == IPV6_UNKNOWN) {
+      bool works = Curl_ipv6works(NULL);
+      data->multi->ipv6_up = works ? IPV6_WORKS : IPV6_DEAD;
+    }
+    return data->multi->ipv6_up == IPV6_WORKS;
   }
   else {
     int ipv6_works = -1;
index 4e8e916ce7f74320505e5fe714853bcf727647b2..c62c254c7224dda9234603a098dce5fd2a058f3a 100644 (file)
@@ -117,7 +117,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
 
   *waitp = 0; /* synchronous response only */
 
-  if(Curl_ipv6works(data) && data->conn->ip_version != CURL_IPRESOLVE_V4)
+  if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data))
     /* The stack seems to be IPv6-enabled */
     pf = PF_UNSPEC;
 
index 01b27f77081574e91c817fe11f1547572854e09f..d9d7d8c0a341547a992801d712d18da52476c9ee 100644 (file)
@@ -417,7 +417,6 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
   /* -1 means it not set by user, use the default value */
   multi->maxconnects = -1;
   multi->max_concurrent_streams = 100;
-  multi->ipv6_works = Curl_ipv6works(NULL);
 
 #ifdef USE_WINSOCK
   multi->wsa_event = WSACreateEvent();
index 76a67a89a06b3db8d5a9f657e192dcb14add62d4..a997784ea3772b70c2f9f9cdc5760e87e7ee8123 100644 (file)
@@ -150,11 +150,13 @@ struct Curl_multi {
                                    0 is used for read, 1 is used for write */
 #endif
 #endif
-  /* multiplexing wanted */
-  bool multiplexing;
-  bool recheckstate; /* see Curl_multi_connchanged */
+#define IPV6_UNKNOWN 0
+#define IPV6_DEAD    1
+#define IPV6_WORKS   2
+  unsigned char ipv6_up;       /* IPV6_* defined */
+  bool multiplexing;           /* multiplexing wanted */
+  bool recheckstate;           /* see Curl_multi_connchanged */
   bool in_callback;            /* true while executing a callback */
-  bool ipv6_works;
 #ifdef USE_OPENSSL
   bool ssl_seeded;
 #endif