diff options
author | dartraiden <wowemuh@gmail.com> | 2021-07-29 03:58:47 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2021-07-29 04:00:29 +0300 |
commit | fe19d22eaddb5383337114ab7a611d781de24b59 (patch) | |
tree | 618312785cafc338b2f3369184ef17364c20e6ec /libs/libcurl/src/hostip.c | |
parent | d60a8d0c45ea7903274c570f523b7775125f4e89 (diff) |
libcurl: update to 7.78
Diffstat (limited to 'libs/libcurl/src/hostip.c')
-rw-r--r-- | libs/libcurl/src/hostip.c | 146 |
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); |