|
@@ -117,6 +117,13 @@
|
|
|
|
|
|
static void freednsentry(void *freethis);
|
|
|
|
|
|
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
|
|
+static void show_resolve_info(struct Curl_easy *data,
|
|
|
+ struct Curl_dns_entry *dns);
|
|
|
+#else
|
|
|
+#define show_resolve_info(x,y) Curl_nop_stmt
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* Curl_printable_address() stores a printable version of the 1st address
|
|
|
* given in the 'ai' argument. The result will be stored in the buf that is
|
|
@@ -481,9 +488,11 @@ Curl_cache_addr(struct Curl_easy *data,
|
|
|
return NULL;
|
|
|
}
|
|
|
#endif
|
|
|
+ if(!hostlen)
|
|
|
+ hostlen = strlen(hostname);
|
|
|
|
|
|
/* Create a new cache entry */
|
|
|
- dns = calloc(1, sizeof(struct Curl_dns_entry));
|
|
|
+ dns = calloc(1, sizeof(struct Curl_dns_entry) + hostlen);
|
|
|
if(!dns) {
|
|
|
return NULL;
|
|
|
}
|
|
@@ -497,6 +506,9 @@ Curl_cache_addr(struct Curl_easy *data,
|
|
|
time(&dns->timestamp);
|
|
|
if(dns->timestamp == 0)
|
|
|
dns->timestamp = 1; /* zero indicates permanent CURLOPT_RESOLVE entry */
|
|
|
+ dns->hostport = port;
|
|
|
+ if(hostlen)
|
|
|
+ memcpy(dns->hostname, hostname, hostlen);
|
|
|
|
|
|
/* Store the resolved data in our DNS cache. */
|
|
|
dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len + 1,
|
|
@@ -823,8 +835,10 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
|
|
|
if(!dns)
|
|
|
/* returned failure, bail out nicely */
|
|
|
Curl_freeaddrinfo(addr);
|
|
|
- else
|
|
|
+ else {
|
|
|
rc = CURLRESOLV_RESOLVED;
|
|
|
+ show_resolve_info(data, dns);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1285,18 +1299,89 @@ err:
|
|
|
return CURLE_OK;
|
|
|
}
|
|
|
|
|
|
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
|
|
+static void show_resolve_info(struct Curl_easy *data,
|
|
|
+ struct Curl_dns_entry *dns)
|
|
|
+{
|
|
|
+ struct Curl_addrinfo *a;
|
|
|
+ CURLcode result = CURLE_OK;
|
|
|
+#ifdef CURLRES_IPV6
|
|
|
+ struct dynbuf out[2];
|
|
|
+#else
|
|
|
+ struct dynbuf out[1];
|
|
|
+#endif
|
|
|
+ DEBUGASSERT(data);
|
|
|
+ DEBUGASSERT(dns);
|
|
|
+
|
|
|
+ if(!data->set.verbose ||
|
|
|
+ /* ignore no name or numerical IP addresses */
|
|
|
+ !dns->hostname[0] || Curl_host_is_ipnum(dns->hostname))
|
|
|
+ return;
|
|
|
+
|
|
|
+ a = dns->addr;
|
|
|
+
|
|
|
+ infof(data, "Host %s:%d was resolved.",
|
|
|
+ (dns->hostname[0] ? dns->hostname : "(none)"), dns->hostport);
|
|
|
+
|
|
|
+ Curl_dyn_init(&out[0], 1024);
|
|
|
+#ifdef CURLRES_IPV6
|
|
|
+ Curl_dyn_init(&out[1], 1024);
|
|
|
+#endif
|
|
|
+
|
|
|
+ while(a) {
|
|
|
+ if(
|
|
|
+#ifdef CURLRES_IPV6
|
|
|
+ (a->ai_family == PF_INET6) ||
|
|
|
+#endif
|
|
|
+ (a->ai_family == PF_INET)) {
|
|
|
+ char buf[MAX_IPADR_LEN];
|
|
|
+ struct dynbuf *d = &out[(a->ai_family != PF_INET)];
|
|
|
+ Curl_printable_address(a, buf, sizeof(buf));
|
|
|
+ if(Curl_dyn_len(d))
|
|
|
+ result = Curl_dyn_addn(d, ", ", 2);
|
|
|
+ if(!result)
|
|
|
+ result = Curl_dyn_add(d, buf);
|
|
|
+ if(result) {
|
|
|
+ infof(data, "too many IP, can't show");
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ a = a->ai_next;
|
|
|
+ }
|
|
|
+
|
|
|
+#ifdef CURLRES_IPV6
|
|
|
+ infof(data, "IPv6: %s",
|
|
|
+ (Curl_dyn_len(&out[1]) ? Curl_dyn_ptr(&out[1]) : "(none)"));
|
|
|
+#endif
|
|
|
+ infof(data, "IPv4: %s",
|
|
|
+ (Curl_dyn_len(&out[0]) ? Curl_dyn_ptr(&out[0]) : "(none)"));
|
|
|
+
|
|
|
+fail:
|
|
|
+ Curl_dyn_free(&out[0]);
|
|
|
+#ifdef CURLRES_IPV6
|
|
|
+ Curl_dyn_free(&out[1]);
|
|
|
+#endif
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
CURLcode Curl_resolv_check(struct Curl_easy *data,
|
|
|
struct Curl_dns_entry **dns)
|
|
|
{
|
|
|
+ CURLcode result;
|
|
|
#if defined(CURL_DISABLE_DOH) && !defined(CURLRES_ASYNCH)
|
|
|
(void)data;
|
|
|
(void)dns;
|
|
|
#endif
|
|
|
#ifndef CURL_DISABLE_DOH
|
|
|
- if(data->conn->bits.doh)
|
|
|
- return Curl_doh_is_resolved(data, dns);
|
|
|
+ if(data->conn->bits.doh) {
|
|
|
+ result = Curl_doh_is_resolved(data, dns);
|
|
|
+ }
|
|
|
+ else
|
|
|
#endif
|
|
|
- return Curl_resolver_is_resolved(data, dns);
|
|
|
+ result = Curl_resolver_is_resolved(data, dns);
|
|
|
+ if(*dns)
|
|
|
+ show_resolve_info(data, *dns);
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
int Curl_resolv_getsock(struct Curl_easy *data,
|