summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/hostip.c
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2021-07-29 03:58:47 +0300
committerdartraiden <wowemuh@gmail.com>2021-07-29 04:00:29 +0300
commitfe19d22eaddb5383337114ab7a611d781de24b59 (patch)
tree618312785cafc338b2f3369184ef17364c20e6ec /libs/libcurl/src/hostip.c
parentd60a8d0c45ea7903274c570f523b7775125f4e89 (diff)
libcurl: update to 7.78
Diffstat (limited to 'libs/libcurl/src/hostip.c')
-rw-r--r--libs/libcurl/src/hostip.c146
1 files changed, 121 insertions, 25 deletions
diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c
index e0e3cfc2cb..30ce509267 100644
--- a/libs/libcurl/src/hostip.c
+++ b/libs/libcurl/src/hostip.c
@@ -63,6 +63,7 @@
#include "multiif.h"
#include "doh.h"
#include "warnless.h"
+#include "strcase.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -289,7 +290,7 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data,
user.cache_timeout = data->set.dns_cache_timeout;
if(hostcache_timestamp_remove(&user, dns)) {
- infof(data, "Hostname in DNS cache was stale, zapped\n");
+ infof(data, "Hostname in DNS cache was stale, zapped");
dns = NULL; /* the memory deallocation is being handled by the hash */
Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
}
@@ -460,6 +461,97 @@ Curl_cache_addr(struct Curl_easy *data,
return dns;
}
+#ifdef ENABLE_IPV6
+/* return a static IPv6 resolve for 'localhost' */
+static struct Curl_addrinfo *get_localhost6(int port)
+{
+ struct Curl_addrinfo *ca;
+ const size_t ss_size = sizeof(struct sockaddr_in6);
+ const size_t hostlen = strlen("localhost");
+ 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);
+ if(!ca)
+ return NULL;
+
+ sa6.sin6_family = AF_INET6;
+ sa6.sin6_port = htons(port16);
+ sa6.sin6_flowinfo = 0;
+ sa6.sin6_scope_id = 0;
+ if(Curl_inet_pton(AF_INET6, "::1", ipv6) < 1)
+ return NULL;
+ memcpy(&sa6.sin6_addr, ipv6, sizeof(ipv6));
+
+ ca->ai_flags = 0;
+ ca->ai_family = AF_INET6;
+ ca->ai_socktype = SOCK_STREAM;
+ ca->ai_protocol = IPPROTO_TCP;
+ ca->ai_addrlen = (curl_socklen_t)ss_size;
+ ca->ai_next = NULL;
+ ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
+ memcpy(ca->ai_addr, &sa6, ss_size);
+ ca->ai_canonname = (char *)ca->ai_addr + ss_size;
+ strcpy(ca->ai_canonname, "localhost");
+ return ca;
+}
+#else
+#define get_localhost6(x) NULL
+#endif
+
+/* return a static IPv4 resolve for 'localhost' */
+static struct Curl_addrinfo *get_localhost(int port)
+{
+ struct Curl_addrinfo *ca;
+ const size_t ss_size = sizeof(struct sockaddr_in);
+ const size_t hostlen = strlen("localhost");
+ struct sockaddr_in sa;
+ unsigned int ipv4;
+ unsigned short port16 = (unsigned short)(port & 0xffff);
+ ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1);
+ if(!ca)
+ return NULL;
+
+ /* memset to clear the sa.sin_zero field */
+ memset(&sa, 0, sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons(port16);
+ if(Curl_inet_pton(AF_INET, "127.0.0.1", (char *)&ipv4) < 1)
+ return NULL;
+ memcpy(&sa.sin_addr, &ipv4, sizeof(ipv4));
+
+ ca->ai_flags = 0;
+ ca->ai_family = AF_INET;
+ ca->ai_socktype = SOCK_STREAM;
+ ca->ai_protocol = IPPROTO_TCP;
+ ca->ai_addrlen = (curl_socklen_t)ss_size;
+ ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
+ memcpy(ca->ai_addr, &sa, ss_size);
+ ca->ai_canonname = (char *)ca->ai_addr + ss_size;
+ strcpy(ca->ai_canonname, "localhost");
+ ca->ai_next = get_localhost6(port);
+ return ca;
+}
+
+/*
+ * Curl_host_is_ipnum() returns TRUE if the given string is a numerical IPv4
+ * (or IPv6 if supported) address.
+ */
+bool Curl_host_is_ipnum(const char *hostname)
+{
+ struct in_addr in;
+#ifdef ENABLE_IPV6
+ struct in6_addr in6;
+#endif
+ if(Curl_inet_pton(AF_INET, hostname, &in) > 0
+#ifdef ENABLE_IPV6
+ || Curl_inet_pton(AF_INET6, hostname, &in6) > 0
+#endif
+ )
+ return TRUE;
+ return FALSE;
+}
+
/*
* Curl_resolv() is the main name resolve function within libcurl. It resolves
* a name and returns a pointer to the entry in the 'entry' argument (if one
@@ -487,7 +579,6 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
CURLcode result;
enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */
struct connectdata *conn = data->conn;
-
*entry = NULL;
conn->bits.doh = FALSE; /* default is not */
@@ -497,7 +588,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
dns = fetch_addr(data, hostname, port);
if(dns) {
- infof(data, "Hostname %s was found in DNS cache\n", hostname);
+ infof(data, "Hostname %s was found in DNS cache", hostname);
dns->inuse++; /* we use it! */
rc = CURLRESOLV_RESOLVED;
}
@@ -534,16 +625,20 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
}
#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES)
- /*
- * The automagic conversion from IPv4 literals to IPv6 literals only works
- * if the SCDynamicStoreCopyProxies system function gets called first. As
- * Curl currently doesn't support system-wide HTTP proxies, we therefore
- * don't use any value this function might return.
- *
- * This function is only available on a macOS and is not needed for
- * IPv4-only builds, hence the conditions above.
- */
- SCDynamicStoreCopyProxies(NULL);
+ {
+ /*
+ * The automagic conversion from IPv4 literals to IPv6 literals only
+ * works if the SCDynamicStoreCopyProxies system function gets called
+ * first. As Curl currently doesn't support system-wide HTTP proxies, we
+ * therefore don't use any value this function might return.
+ *
+ * This function is only available on a macOS and is not needed for
+ * IPv4-only builds, hence the conditions above.
+ */
+ CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL);
+ if(dict)
+ CFRelease(dict);
+ }
#endif
#ifndef USE_RESOLVE_ON_IPS
@@ -584,9 +679,10 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
if(!Curl_ipvalid(data, conn))
return CURLRESOLV_ERROR;
- if(allowDOH && data->set.doh && !ipnum) {
+ if(strcasecompare(hostname, "localhost"))
+ addr = get_localhost(port);
+ else if(allowDOH && data->set.doh && !ipnum)
addr = Curl_doh(data, hostname, port, &respwait);
- }
else {
/* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
non-zero value indicating that we need to wait for the response to
@@ -757,7 +853,7 @@ enum resolve_t Curl_resolv_timeout(struct Curl_easy *data,
#else
#ifndef CURLRES_ASYNCH
if(timeoutms)
- infof(data, "timeout on name lookup is not supported\n");
+ infof(data, "timeout on name lookup is not supported");
#else
(void)timeoutms; /* timeoutms not used with an async resolver */
#endif
@@ -895,7 +991,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
size_t entry_len;
if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) {
- infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'!\n",
+ infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'",
hostp->data);
continue;
}
@@ -984,7 +1080,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
#ifndef ENABLE_IPV6
if(strchr(address, ':')) {
- infof(data, "Ignoring resolve address '%s', missing IPv6 support.\n",
+ infof(data, "Ignoring resolve address '%s', missing IPv6 support.",
address);
continue;
}
@@ -992,7 +1088,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
ai = Curl_str2addr(address, port);
if(!ai) {
- infof(data, "Resolve address '%s' found illegal!\n", address);
+ infof(data, "Resolve address '%s' found illegal!", address);
goto err;
}
@@ -1011,10 +1107,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
error = false;
err:
if(error) {
- infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n",
+ failf(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!",
hostp->data);
Curl_freeaddrinfo(head);
- continue;
+ return CURLE_SETOPT_OPTION_SYNTAX;
}
/* Create an entry id, based upon the hostname and port */
@@ -1028,7 +1124,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
if(dns) {
- infof(data, "RESOLVE %s:%d is - old addresses discarded!\n",
+ infof(data, "RESOLVE %s:%d is - old addresses discarded!",
hostname, port);
/* delete old entry, there are two reasons for this
1. old entry may have different addresses.
@@ -1061,12 +1157,12 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
Curl_freeaddrinfo(head);
return CURLE_OUT_OF_MEMORY;
}
- infof(data, "Added %s:%d:%s to DNS cache%s\n",
+ infof(data, "Added %s:%d:%s to DNS cache%s",
hostname, port, addresses, permanent ? "" : " (non-permanent)");
/* Wildcard hostname */
if(hostname[0] == '*' && hostname[1] == '\0') {
- infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks\n",
+ infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks",
hostname, port);
data->state.wildcard_resolve = true;
}
@@ -1094,7 +1190,7 @@ int Curl_resolv_getsock(struct Curl_easy *data,
{
#ifdef CURLRES_ASYNCH
if(data->conn->bits.doh)
- /* nothing to wait for during DOH resolve, those handles have their own
+ /* nothing to wait for during DoH resolve, those handles have their own
sockets */
return GETSOCK_BLANK;
return Curl_resolver_getsock(data, socks);