hostip: show the list of IPs when resolving is done

Getting 'curl.se' today then gets this verbose output which might help
debugging connectivity related matters.

* Host curl.se:80 was resolved.
* IPv6: 2a04:4e42::347, 2a04:4e42:200::347, 2a04:4e42:400::347,
  2a04:4e42:600::347, 2a04:4e42:800::347, 2a04:4e42:a00::347,
  2a04:4e42:c00::347, 2a04:4e42:e00::347
* IPv4: 151.101.193.91, 151.101.1.91, 151.101.65.91, 151.101.129.91

Co-authored-by: Jay Satiro
Closes #12145
This commit is contained in:
Daniel Stenberg 2023-10-17 17:01:52 +02:00
parent 276ffedec2
commit b651aba096
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 94 additions and 5 deletions

View File

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

View File

@ -64,6 +64,10 @@ struct Curl_dns_entry {
time_t timestamp;
/* use-counter, use Curl_resolv_unlock to release reference */
long inuse;
/* hostname port number that resolved to addr. */
int hostport;
/* hostname that resolved to addr. may be NULL (unix domain sockets). */
char hostname[1];
};
bool Curl_host_is_ipnum(const char *hostname);