]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
hostip: Make Curl_ipv6works function independent of getaddrinfo
authorJay Satiro <raysatiro@yahoo.com>
Tue, 3 Aug 2021 07:03:00 +0000 (03:03 -0400)
committerJay Satiro <raysatiro@yahoo.com>
Tue, 10 Aug 2021 07:29:49 +0000 (03:29 -0400)
- 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

lib/hostip.c
lib/hostip.h
lib/hostip6.c

index 30ce509267980ef359e0316925e4160a0362ef4d..bb110dee5dde4c852c6228a5e22e8163da98fa76 100644 (file)
@@ -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 */
index 28f3b840187e4d959a90a65b3494e37a42fe5d6c..67a688aebdc0193fad03de337288ce74da8fa5b8 100644 (file)
@@ -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.
  */
index 943cdd261c100b0b9b94200bce8479d05e3da7ac..e2777c73d46dc8509cea5d9354aeb142d18673fe 100644 (file)
 #include "curl_memory.h"
 #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.