summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Satiro <raysatiro@yahoo.com>2021-08-03 03:03:00 -0400
committerJay Satiro <raysatiro@yahoo.com>2021-08-10 03:29:49 -0400
commit16e9c8e9909fc12c3f9735f666b5a8c5af669e8b (patch)
treee745c87344895b2d53bc024787cd2dd1bd11e3bf
parent26f93cf0388c36b78fda93353f9b76068308bbd8 (diff)
downloadcurl-16e9c8e9909fc12c3f9735f666b5a8c5af669e8b.tar.gz
hostip: Make Curl_ipv6works function independent of getaddrinfo
- Do not assume IPv6 is not working when getaddrinfo is not present. The check to see if IPv6 actually works is now independent of whether there is any resolver that can potentially resolve a hostname to IPv6. Prior to this change if getaddrinfo() was not found at compile time then Curl_ipv6works() would be defined as a macro that returns FALSE. When getaddrinfo is not found then libcurl is built with CURLRES_IPV4 defined instead of CURLRES_IPV6, meaning that it cannot do IPv6 lookups in the traditional way. With this commit if libcurl is built with IPv6 support (ENABLE_IPV6) but without getaddrinfo (CURLRES_IPV6), and the IPv6 stack is actually working, then it is possible for libcurl to resolve IPv6 addresses by using DoH. Ref: https://github.com/curl/curl/issues/7483#issuecomment-890765378 Closes https://github.com/curl/curl/pull/7529
-rw-r--r--lib/hostip.c38
-rw-r--r--lib/hostip.h2
-rw-r--r--lib/hostip6.c28
3 files changed, 36 insertions, 32 deletions
diff --git a/lib/hostip.c b/lib/hostip.c
index 30ce50926..bb110dee5 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -533,6 +533,36 @@ static struct Curl_addrinfo *get_localhost(int port)
return ca;
}
+#ifdef ENABLE_IPV6
+/*
+ * Curl_ipv6works() returns TRUE if IPv6 seems to work.
+ */
+bool Curl_ipv6works(struct Curl_easy *data)
+{
+ if(data) {
+ /* the nature of most system is that IPv6 status doesn't come and go
+ during a program's lifetime so we only probe the first time and then we
+ have the info kept for fast re-use */
+ DEBUGASSERT(data);
+ DEBUGASSERT(data->multi);
+ return data->multi->ipv6_works;
+ }
+ else {
+ int ipv6_works = -1;
+ /* probe to see if we have a working IPv6 stack */
+ curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
+ if(s == CURL_SOCKET_BAD)
+ /* an IPv6 address was requested but we can't get/use one */
+ ipv6_works = 0;
+ else {
+ ipv6_works = 1;
+ sclose(s);
+ }
+ return (ipv6_works>0)?TRUE:FALSE;
+ }
+}
+#endif /* ENABLE_IPV6 */
+
/*
* Curl_host_is_ipnum() returns TRUE if the given string is a numerical IPv4
* (or IPv6 if supported) address.
@@ -674,9 +704,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
#endif /* !USE_RESOLVE_ON_IPS */
if(!addr) {
- /* Check what IP specifics the app has requested and if we can provide
- * it. If not, bail out. */
- if(!Curl_ipvalid(data, conn))
+ if(conn->ip_version == CURL_IPRESOLVE_V6 && !Curl_ipv6works(data))
return CURLRESOLV_ERROR;
if(strcasecompare(hostname, "localhost"))
@@ -684,6 +712,10 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
else if(allowDOH && data->set.doh && !ipnum)
addr = Curl_doh(data, hostname, port, &respwait);
else {
+ /* Check what IP specifics the app has requested and if we can provide
+ * it. If not, bail out. */
+ if(!Curl_ipvalid(data, conn))
+ return CURLRESOLV_ERROR;
/* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
non-zero value indicating that we need to wait for the response to
the resolve call */
diff --git a/lib/hostip.h b/lib/hostip.h
index 28f3b8401..67a688aeb 100644
--- a/lib/hostip.h
+++ b/lib/hostip.h
@@ -97,7 +97,7 @@ enum resolve_t Curl_resolv_timeout(struct Curl_easy *data,
struct Curl_dns_entry **dnsentry,
timediff_t timeoutms);
-#ifdef CURLRES_IPV6
+#ifdef ENABLE_IPV6
/*
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
*/
diff --git a/lib/hostip6.c b/lib/hostip6.c
index 943cdd261..e2777c73d 100644
--- a/lib/hostip6.c
+++ b/lib/hostip6.c
@@ -60,34 +60,6 @@
#include "memdebug.h"
/*
- * Curl_ipv6works() returns TRUE if IPv6 seems to work.
- */
-bool Curl_ipv6works(struct Curl_easy *data)
-{
- if(data) {
- /* the nature of most system is that IPv6 status doesn't come and go
- during a program's lifetime so we only probe the first time and then we
- have the info kept for fast re-use */
- DEBUGASSERT(data);
- DEBUGASSERT(data->multi);
- return data->multi->ipv6_works;
- }
- else {
- int ipv6_works = -1;
- /* probe to see if we have a working IPv6 stack */
- curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
- if(s == CURL_SOCKET_BAD)
- /* an IPv6 address was requested but we can't get/use one */
- ipv6_works = 0;
- else {
- ipv6_works = 1;
- sclose(s);
- }
- return (ipv6_works>0)?TRUE:FALSE;
- }
-}
-
-/*
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
* been set and returns TRUE if they are OK.
*/