hostip: lazily wait to figure out if IPv6 works until needed

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
This commit is contained in:
Daniel Stenberg 2022-09-21 08:52:57 +02:00
parent 7295e62c66
commit 46f3fe0e75
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
7 changed files with 17 additions and 13 deletions

View File

@ -779,9 +779,8 @@ 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;
#endif /* CURLRES_IPV6 */
hints.ai_family = pf;
@ -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;

View 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 */

View File

@ -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],

View 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;

View 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;

View 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();

View File

@ -150,11 +150,13 @@ struct Curl_multi {
0 is used for read, 1 is used for write */
#endif
#endif
/* multiplexing wanted */
bool multiplexing;
#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