aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hostip.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hostip.c')
-rw-r--r--lib/hostip.c100
1 files changed, 59 insertions, 41 deletions
diff --git a/lib/hostip.c b/lib/hostip.c
index c0feb79f..dd5916e3 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -120,7 +120,7 @@ static void freednsentry(void *freethis);
/*
* Return # of addresses in a Curl_addrinfo struct
*/
-int Curl_num_addresses(const Curl_addrinfo *addr)
+int Curl_num_addresses(const struct Curl_addrinfo *addr)
{
int i = 0;
while(addr) {
@@ -131,39 +131,36 @@ int Curl_num_addresses(const Curl_addrinfo *addr)
}
/*
- * Curl_printable_address() returns a printable version of the 1st address
+ * 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
* bufsize bytes big.
*
- * If the conversion fails, it returns NULL.
+ * If the conversion fails, the target buffer is empty.
*/
-const char *
-Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
+void Curl_printable_address(const struct Curl_addrinfo *ai, char *buf,
+ size_t bufsize)
{
- const struct sockaddr_in *sa4;
- const struct in_addr *ipaddr4;
-#ifdef ENABLE_IPV6
- const struct sockaddr_in6 *sa6;
- const struct in6_addr *ipaddr6;
-#endif
+ DEBUGASSERT(bufsize);
+ buf[0] = 0;
switch(ai->ai_family) {
- case AF_INET:
- sa4 = (const void *)ai->ai_addr;
- ipaddr4 = &sa4->sin_addr;
- return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf,
- bufsize);
+ case AF_INET: {
+ const struct sockaddr_in *sa4 = (const void *)ai->ai_addr;
+ const struct in_addr *ipaddr4 = &sa4->sin_addr;
+ (void)Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf, bufsize);
+ break;
+ }
#ifdef ENABLE_IPV6
- case AF_INET6:
- sa6 = (const void *)ai->ai_addr;
- ipaddr6 = &sa6->sin6_addr;
- return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf,
- bufsize);
+ case AF_INET6: {
+ const struct sockaddr_in6 *sa6 = (const void *)ai->ai_addr;
+ const struct in6_addr *ipaddr6 = &sa6->sin6_addr;
+ (void)Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf, bufsize);
+ break;
+ }
#endif
- default:
- break;
+ default:
+ break;
}
- return NULL;
}
/*
@@ -337,7 +334,7 @@ Curl_fetch_addr(struct connectdata *conn,
#ifndef CURL_DISABLE_SHUFFLE_DNS
UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
- Curl_addrinfo **addr);
+ struct Curl_addrinfo **addr);
/*
* Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo'
* struct by re-linking its linked list.
@@ -351,13 +348,13 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
* @unittest: 1608
*/
UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
- Curl_addrinfo **addr)
+ struct Curl_addrinfo **addr)
{
CURLcode result = CURLE_OK;
const int num_addrs = Curl_num_addresses(*addr);
if(num_addrs > 1) {
- Curl_addrinfo **nodes;
+ struct Curl_addrinfo **nodes;
infof(data, "Shuffling %i addresses", num_addrs);
nodes = malloc(num_addrs*sizeof(*nodes));
@@ -376,7 +373,7 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
if(rnd) {
/* Fisher-Yates shuffle */
if(Curl_rand(data, (unsigned char *)rnd, rnd_size) == CURLE_OK) {
- Curl_addrinfo *swap_tmp;
+ struct Curl_addrinfo *swap_tmp;
for(i = num_addrs - 1; i > 0; i--) {
swap_tmp = nodes[rnd[i] % (i + 1)];
nodes[rnd[i] % (i + 1)] = nodes[i];
@@ -415,7 +412,7 @@ UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
*/
struct Curl_dns_entry *
Curl_cache_addr(struct Curl_easy *data,
- Curl_addrinfo *addr,
+ struct Curl_addrinfo *addr,
const char *hostname,
int port)
{
@@ -495,6 +492,7 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */
*entry = NULL;
+ conn->bits.doh = FALSE; /* default is not */
if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
@@ -513,11 +511,13 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
if(!dns) {
/* The entry was not in the cache. Resolve it to IP address */
- Curl_addrinfo *addr = NULL;
+ struct Curl_addrinfo *addr = NULL;
int respwait = 0;
-#ifndef USE_RESOLVE_ON_IPS
struct in_addr in;
+#ifndef USE_RESOLVE_ON_IPS
+ const
#endif
+ bool ipnum = FALSE;
/* notify the resolver start callback */
if(data->set.resolver_start) {
@@ -544,6 +544,22 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
addr = Curl_ip2addr(AF_INET6, &in6, hostname, port);
}
#endif /* ENABLE_IPV6 */
+
+#else /* if USE_RESOLVE_ON_IPS */
+ /* First check if this is an IPv4 address string */
+ if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+ /* This is a dotted IP address 123.123.123.123-style */
+ ipnum = TRUE;
+#ifdef ENABLE_IPV6
+ else {
+ struct in6_addr in6;
+ /* check if this is an IPv6 address string */
+ if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
+ /* This is an IPv6 address literal */
+ ipnum = TRUE;
+ }
+#endif /* ENABLE_IPV6 */
+
#endif /* !USE_RESOLVE_ON_IPS */
if(!addr) {
@@ -552,7 +568,7 @@ enum resolve_t Curl_resolv(struct connectdata *conn,
if(!Curl_ipvalid(conn))
return CURLRESOLV_ERROR;
- if(allowDOH && data->set.doh) {
+ if(allowDOH && data->set.doh && !ipnum) {
addr = Curl_doh(conn, hostname, port, &respwait);
}
else {
@@ -890,7 +906,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
}
else {
struct Curl_dns_entry *dns;
- Curl_addrinfo *head = NULL, *tail = NULL;
+ struct Curl_addrinfo *head = NULL, *tail = NULL;
size_t entry_len;
char address[64];
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -924,7 +940,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
while(*end_ptr) {
size_t alen;
- Curl_addrinfo *ai;
+ struct Curl_addrinfo *ai;
addr_begin = end_ptr + 1;
addr_end = strchr(addr_begin, ',');
@@ -1047,7 +1063,7 @@ CURLcode Curl_resolv_check(struct connectdata *conn,
(void)dns;
#endif
- if(conn->data->set.doh)
+ if(conn->bits.doh)
return Curl_doh_is_resolved(conn, dns);
return Curl_resolver_is_resolved(conn, dns);
}
@@ -1056,7 +1072,7 @@ int Curl_resolv_getsock(struct connectdata *conn,
curl_socket_t *socks)
{
#ifdef CURLRES_ASYNCH
- if(conn->data->set.doh)
+ if(conn->bits.doh)
/* nothing to wait for during DOH resolve, those handles have their own
sockets */
return GETSOCK_BLANK;
@@ -1085,10 +1101,12 @@ CURLcode Curl_once_resolved(struct connectdata *conn,
result = Curl_setup_conn(conn, protocol_done);
- if(result)
- /* We're not allowed to return failure with memory left allocated
- in the connectdata struct, free those here */
- Curl_disconnect(conn->data, conn, TRUE); /* close the connection */
-
+ if(result) {
+ struct Curl_easy *data = conn->data;
+ DEBUGASSERT(data);
+ Curl_detach_connnection(data);
+ Curl_conncache_remove_conn(data, conn, TRUE);
+ Curl_disconnect(data, conn, TRUE);
+ }
return result;
}