aboutsummaryrefslogtreecommitdiff
path: root/lib/hostip.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hostip.c')
-rw-r--r--lib/hostip.c115
1 files changed, 104 insertions, 11 deletions
diff --git a/lib/hostip.c b/lib/hostip.c
index 3cd9a65c5..4f44d348f 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -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,
@@ -521,7 +533,7 @@ static struct Curl_addrinfo *get_localhost6(int port, const char *name)
struct sockaddr_in6 sa6;
unsigned char ipv6[16];
unsigned short port16 = (unsigned short)(port & 0xffff);
- ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1);
+ ca = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1);
if(!ca)
return NULL;
@@ -568,7 +580,7 @@ static struct Curl_addrinfo *get_localhost(int port, const char *name)
return NULL;
memcpy(&sa.sin_addr, &ipv4, sizeof(ipv4));
- ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1);
+ ca = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1);
if(!ca)
return NULL;
ca->ai_flags = 0;
@@ -742,16 +754,22 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
#ifndef USE_RESOLVE_ON_IPS
/* First check if this is an IPv4 address string */
- if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+ if(Curl_inet_pton(AF_INET, hostname, &in) > 0) {
/* This is a dotted IP address 123.123.123.123-style */
addr = Curl_ip2addr(AF_INET, &in, hostname, port);
+ if(!addr)
+ return CURLRESOLV_ERROR;
+ }
#ifdef ENABLE_IPV6
- if(!addr) {
+ else {
struct in6_addr in6;
/* check if this is an IPv6 address string */
- if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
+ if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0) {
/* This is an IPv6 address literal */
addr = Curl_ip2addr(AF_INET6, &in6, hostname, port);
+ if(!addr)
+ return CURLRESOLV_ERROR;
+ }
}
#endif /* ENABLE_IPV6 */
@@ -823,8 +841,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);
+ }
}
}
@@ -839,7 +859,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
* execution. This effectively causes the remainder of the application to run
* within a signal handler which is nonportable and could lead to problems.
*/
-static
+CURL_NORETURN static
void alarmfunc(int sig)
{
(void)sig;
@@ -1269,9 +1289,11 @@ err:
Curl_freeaddrinfo(head);
return CURLE_OUT_OF_MEMORY;
}
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
infof(data, "Added %.*s:%d:%s to DNS cache%s",
(int)hlen, host_begin, port, addresses,
permanent ? "" : " (non-permanent)");
+#endif
/* Wildcard hostname */
if((hlen == 1) && (host_begin[0] == '*')) {
@@ -1285,18 +1307,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,