]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
resolve: make forced IPv4 resolve only use A queries
authorDmitry Karpov <dkarpov@roku.com>
Mon, 19 Sep 2022 20:59:35 +0000 (13:59 -0700)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 20 Sep 2022 13:43:27 +0000 (15:43 +0200)
This protects IPv4-only transfers from undesired bad IPv6-related side
effects and make IPv4 transfers in dual-stack libcurl behave the same
way as in IPv4 single-stack libcurl.

Closes #9540

lib/asyn-ares.c
lib/asyn-thread.c
lib/doh.c
lib/hostip.c
lib/hostip6.c

index dff671b4de68737439d0cc5259c4babb33508f10..1f3965541eed13a08c3c013dc797da3d918ac100 100644 (file)
@@ -781,7 +781,8 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
 #ifdef CURLRES_IPV6
       if(Curl_ipv6works(data))
         /* The stack seems to be IPv6-enabled */
-        pf = PF_UNSPEC;
+        if(data->conn->ip_version != CURL_IPRESOLVE_V4)
+          pf = PF_UNSPEC;
 #endif /* CURLRES_IPV6 */
       hints.ai_family = pf;
       hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
@@ -794,7 +795,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
 #else
 
 #ifdef HAVE_CARES_IPV6
-    if(Curl_ipv6works(data)) {
+    if(Curl_ipv6works(data) && data->conn->ip_version != CURL_IPRESOLVE_V4) {
       /* The stack seems to be IPv6-enabled */
       res->num_pending = 2;
 
index 1ab1e977b56604f9a4f84fee6001b40b25068263..68fddf0b22d28f34c1119cdae9333bdf8d55041d 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))
+  if(Curl_ipv6works(data) && data->conn->ip_version != CURL_IPRESOLVE_V4)
     /* The stack seems to be IPv6-enabled */
     pf = PF_UNSPEC;
 #endif /* CURLRES_IPV6 */
index 087258d93079d8dc7ae259c389dfdd3f2cb57ec9..29399772b115a359d9b12f170fe63b2322cb63b8 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)) {
+  if(Curl_ipv6works(data) && conn->ip_version != CURL_IPRESOLVE_V4) {
     /* create IPv6 DoH request */
     result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V6],
                       DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH],
index d08d4daec8518a4a0bfb9706ebb5e465ee121aa0..ec27602dc90c2a9b577266d32a6df799d251474b 100644 (file)
@@ -297,6 +297,29 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data,
     }
   }
 
+  /* See if the returned entry matches the required resolve mode */
+  if(dns && data->conn->ip_version != CURL_IPRESOLVE_WHATEVER) {
+    int pf = PF_INET;
+    bool found = false;
+    struct Curl_addrinfo *addr = dns->addr;
+
+    if(data->conn->ip_version == CURL_IPRESOLVE_V6)
+      pf = PF_INET6;
+
+    while(addr) {
+      if(addr->ai_family == pf) {
+        found = true;
+        break;
+      }
+      addr = addr->ai_next;
+    }
+
+    if(!found) {
+      infof(data, "Hostname in DNS cache doesn't have needed family, zapped");
+      dns = NULL; /* the memory deallocation is being handled by the hash */
+      Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
+    }
+  }
   return dns;
 }
 
index f1b36afb284b444c70dd31c14f675791f6fda50a..4e8e916ce7f74320505e5fe714853bcf727647b2 100644 (file)
@@ -117,7 +117,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
 
   *waitp = 0; /* synchronous response only */
 
-  if(Curl_ipv6works(data))
+  if(Curl_ipv6works(data) && data->conn->ip_version != CURL_IPRESOLVE_V4)
     /* The stack seems to be IPv6-enabled */
     pf = PF_UNSPEC;