← Commit list

73a05428d4

Stefan Eissing
Stefan Eissing
2026-08-04
SUCCESS Duration: 420s

Subject

dnscache: use Curl_peer in resolve and dnscache operations

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/asyn-ares.c+21 -93
@@ -208,19 +208,6 @@ void Curl_async_ares_destroy(struct Curl_easy *data,
ares_destroy(ares->channel);
ares->channel = NULL;
}
- if(ares->res_A) {
- Curl_freeaddrinfo(ares->res_A);
- ares->res_A = NULL;
- }
- if(ares->res_AAAA) {
- Curl_freeaddrinfo(ares->res_AAAA);
- ares->res_AAAA = NULL;
- }
-#ifdef USE_HTTPSRR
- curlx_safefree(ares->https_name);
- Curl_httpsrr_destroy(ares->hinfo);
- ares->hinfo = NULL;
-#endif
}
CURLcode Curl_async_pollset(struct Curl_easy *data,
@@ -276,8 +263,8 @@ CURLcode Curl_async_take_result(struct Curl_easy *data,
if(CURL_DNSQ_IS_ADDR(async->dns_queries)) {
dns = Curl_dnsc_mk_addr2(data, async->dns_queries,
- &ares->res_AAAA, &ares->res_A,
- async->hostname, async->port);
+ &async->ai_AAAA, &async->ai_A,
+ async->peer);
if(!dns) {
result = CURLE_OUT_OF_MEMORY;
goto out;
@@ -286,8 +273,7 @@ CURLcode Curl_async_take_result(struct Curl_easy *data,
#ifdef HTTPSRR_WORKS
if(!dns && (async->dns_queries & CURL_DNSQ_HTTPS)) {
- dns = Curl_dnsc_mk_https(data, &ares->hinfo,
- async->hostname, async->port);
+ dns = Curl_dnsc_mk_https(data, &async->httpsrr, async->peer);
if(!dns) {
result = CURLE_OUT_OF_MEMORY;
goto out;
@@ -349,67 +335,6 @@ static timediff_t async_ares_poll_timeout(struct async_ares_ctx *ares,
return 1000;
}
-static const struct Curl_addrinfo *async_ares_get_ai(
- const struct Curl_addrinfo *ai,
- int ai_family,
- unsigned int index)
-{
- unsigned int i = 0;
- for(i = 0; ai; ai = ai->ai_next) {
- if(ai->ai_family == ai_family) {
- if(i == index)
- return ai;
- ++i;
- }
- }
- return NULL;
-}
-
-const struct Curl_addrinfo *Curl_async_get_ai(struct Curl_easy *data,
- struct Curl_resolv_async *async,
- int ai_family,
- unsigned int index)
-{
- struct async_ares_ctx *ares = &async->ares;
-
- (void)data;
- switch(ai_family) {
- case AF_INET:
- if(ares->res_A)
- return async_ares_get_ai(ares->res_A, ai_family, index);
- break;
- case AF_INET6:
- if(ares->res_AAAA)
- return async_ares_get_ai(ares->res_AAAA, ai_family, index);
- break;
- default:
- break;
- }
- return NULL;
-}
-
-#ifdef USE_HTTPSRR
-const struct Curl_https_rrinfo *Curl_async_get_https(
- struct Curl_easy *data,
- struct Curl_resolv_async *async)
-{
- if(Curl_async_knows_https(data, async))
- return async->ares.hinfo;
- return NULL;
-}
-
-bool Curl_async_knows_https(struct Curl_easy *data,
- struct Curl_resolv_async *async)
-{
- (void)data;
- if(async->dns_queries & CURL_DNSQ_HTTPS)
- return ((async->dns_responses & CURL_DNSQ_HTTPS) ||
- !async->queries_ongoing);
- return TRUE; /* we know it will never come */
-}
-
-#endif /* USE_HTTPSRR */
-
/*
* Curl_async_await()
*
@@ -566,7 +491,7 @@ static void async_ares_A_cb(void *user_data, int status, int timeouts,
async->done = !async->queries_ongoing;
if(status == ARES_SUCCESS) {
ares->ares_status = ARES_SUCCESS;
- ares->res_A = async_ares_node2addr(ares_ai->nodes);
+ async->ai_A = async_ares_node2addr(ares_ai->nodes);
ares_freeaddrinfo(ares_ai);
}
else {
@@ -593,7 +518,7 @@ static void async_ares_AAAA_cb(void *user_data, int status, int timeouts,
async->done = !async->queries_ongoing;
if(status == ARES_SUCCESS) {
ares->ares_status = ARES_SUCCESS;
- ares->res_AAAA = async_ares_node2addr(ares_ai->nodes);
+ async->ai_AAAA = async_ares_node2addr(ares_ai->nodes);
ares_freeaddrinfo(ares_ai);
}
else {
@@ -625,7 +550,7 @@ static void async_ares_rr_done(void *user_data, ares_status_t status,
ares->transient_err = TRUE;
if((ARES_SUCCESS != status) || !dnsrec)
return;
- ares->result = Curl_httpsrr_from_ares(dnsrec, &ares->hinfo);
+ ares->result = Curl_httpsrr_from_ares(dnsrec, &async->httpsrr);
}
#endif /* USE_HTTPSRR */
@@ -664,7 +589,7 @@ CURLcode Curl_async_getaddrinfo(struct Curl_easy *data,
}
#endif
- curl_msnprintf(service, sizeof(service), "%d", async->port);
+ curl_msnprintf(service, sizeof(service), "%d", async->peer->port);
socktype =
(Curl_conn_get_transport(data, data->conn) == TRNSPRT_TCP) ?
SOCK_STREAM : SOCK_DGRAM;
@@ -674,12 +599,13 @@ CURLcode Curl_async_getaddrinfo(struct Curl_easy *data,
struct ares_addrinfo_hints hints;
memset(&hints, 0, sizeof(hints));
- CURL_TRC_DNS(data, "[AAAA] ares: query records for %s", async->hostname);
+ CURL_TRC_DNS(data, "[AAAA] ares: query records for %s",
+ async->peer->hostname);
hints.ai_family = PF_INET6;
hints.ai_socktype = socktype;
hints.ai_flags = ARES_AI_NUMERICSERV;
async->queries_ongoing++;
- ares_getaddrinfo(ares->channel, async->hostname,
+ ares_getaddrinfo(ares->channel, async->peer->hostname,
service, &hints, async_ares_AAAA_cb, async);
}
#endif /* CURLRES_IPV6 */
@@ -688,31 +614,33 @@ CURLcode Curl_async_getaddrinfo(struct Curl_easy *data,
struct ares_addrinfo_hints hints;
memset(&hints, 0, sizeof(hints));
- CURL_TRC_DNS(data, "[A] ares: query records for %s", async->hostname);
+ CURL_TRC_DNS(data, "[A] ares: query records for %s",
+ async->peer->hostname);
hints.ai_family = PF_INET;
hints.ai_socktype = socktype;
hints.ai_flags = ARES_AI_NUMERICSERV;
async->queries_ongoing++;
- ares_getaddrinfo(ares->channel, async->hostname,
+ ares_getaddrinfo(ares->channel, async->peer->hostname,
service, &hints, async_ares_A_cb, async);
}
#ifdef USE_HTTPSRR
if(async->dns_queries & CURL_DNSQ_HTTPS) {
- ares->https_name = NULL;
- if(async->port != 443) {
- ares->https_name = curl_maprintf("_%d._https.%s",
- async->port, async->hostname);
- if(!ares->https_name)
+ char *https_name = NULL;
+ if(async->peer->port != 443) {
+ https_name = curl_maprintf("_%u._https.%s",
+ async->peer->port, async->peer->hostname);
+ if(!https_name)
return CURLE_OUT_OF_MEMORY;
}
CURL_TRC_DNS(data, "[HTTPS] ares: query records for %s",
- ares->https_name ? ares->https_name : async->hostname);
+ https_name ? https_name : async->peer->hostname);
async->queries_ongoing++;
ares_query_dnsrec(ares->channel,
- ares->https_name ? ares->https_name : async->hostname,
+ https_name ? https_name : async->peer->hostname,
ARES_CLASS_IN, ARES_REC_TYPE_HTTPS,
async_ares_rr_done, async, NULL);
+ curlx_free(https_name);
}
#endif /* USE_HTTPSRR */
lib/asyn-base.c+11 -1
@@ -43,8 +43,10 @@
#include "urldata.h"
#include "connect.h"
+#include "curl_addrinfo.h"
#include "curl_trc.h"
#include "hostip.h"
+#include "httpsrr.h"
#include "multiif.h"
#include "progress.h"
#include "select.h"
@@ -238,6 +240,14 @@ void Curl_async_destroy(struct Curl_easy *data,
#ifndef CURL_DISABLE_DOH
Curl_doh_cleanup(data, async);
#endif
+ if(async->ai_A)
+ Curl_freeaddrinfo(async->ai_A);
+ if(async->ai_AAAA)
+ Curl_freeaddrinfo(async->ai_AAAA);
+#ifdef USE_HTTPSRR
+ Curl_httpsrr_destroy(async->httpsrr);
+#endif
+ Curl_peer_unlink(&async->peer);
curlx_safefree(async);
}
}
@@ -258,7 +268,7 @@ CURLcode Curl_async_failed(struct Curl_easy *data,
if(async->dns_queries & (CURL_DNSQ_A|CURL_DNSQ_AAAA))
failf(data, "Could not resolve %s: %s%s%s%s",
- host_or_proxy, async->hostname,
+ host_or_proxy, async->peer->hostname,
detail ? " (" : "", detail ? detail : "", detail ? ")" : "");
return result;
}
lib/asyn-thrdd.c+48 -119
@@ -209,48 +209,54 @@ static void async_thrdd_rr_done(void *user_data, ares_status_t status,
async->queries_ongoing--;
async->done = !async->queries_ongoing;
if((ARES_SUCCESS == status) && dnsrec)
- async->result = Curl_httpsrr_from_ares(dnsrec, &thrdd->rr.hinfo);
+ async->result = Curl_httpsrr_from_ares(dnsrec, &async->httpsrr);
}
static CURLcode async_rr_start(struct Curl_easy *data,
struct Curl_resolv_async *async)
{
struct async_thrdd_ctx *thrdd = &async->thrdd;
+ char *https_name = NULL;
int status;
- char *rrname = NULL;
+ CURLcode result = CURLE_OK;
DEBUGASSERT(!thrdd->rr.channel);
- if(async->port != 443) {
- rrname = curl_maprintf("_%d_.https.%s", async->port, async->hostname);
- if(!rrname)
- return CURLE_OUT_OF_MEMORY;
+ if(async->peer->port != 443) {
+ https_name = curl_maprintf("_%u._https.%s",
+ async->peer->port, async->peer->hostname);
+ if(!https_name) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
}
status = ares_init_options(&thrdd->rr.channel, NULL, 0);
if(status != ARES_SUCCESS) {
thrdd->rr.channel = NULL;
- curlx_free(rrname);
- return CURLE_FAILED_INIT;
+ result = CURLE_FAILED_INIT;
+ goto out;
}
#ifdef DEBUGBUILD
if(getenv("CURL_DNS_SERVER")) {
const char *servers = getenv("CURL_DNS_SERVER");
status = ares_set_servers_ports_csv(thrdd->rr.channel, servers);
if(status) {
- curlx_free(rrname);
- return CURLE_FAILED_INIT;
+ result = CURLE_FAILED_INIT;
+ goto out;
}
}
#endif
- thrdd->rr.https_name = rrname;
async->queries_ongoing++;
ares_query_dnsrec(thrdd->rr.channel,
- rrname ? rrname : async->hostname, ARES_CLASS_IN,
- ARES_REC_TYPE_HTTPS,
+ https_name ? https_name : async->peer->hostname,
+ ARES_CLASS_IN, ARES_REC_TYPE_HTTPS,
async_thrdd_rr_done, async, NULL);
- CURL_TRC_DNS(data, "[HTTPS-RR] initiated request for %s",
- rrname ? rrname : async->hostname);
- return CURLE_OK;
+ CURL_TRC_DNS(data, "[HTTPS] query records for %s",
+ https_name ? https_name : async->peer->hostname);
+
+out:
+ curlx_free(https_name);
+ return result;
}
#endif
@@ -290,15 +296,9 @@ void Curl_async_thrdd_destroy(struct Curl_easy *data,
ares_destroy(async->thrdd.rr.channel);
async->thrdd.rr.channel = NULL;
}
- curlx_safefree(async->thrdd.rr.https_name);
- Curl_httpsrr_destroy(async->thrdd.rr.hinfo);
#endif
- async_thrdd_item_destroy(async->thrdd.inc_A);
- async->thrdd.inc_A = NULL;
async_thrdd_item_destroy(async->thrdd.res_A);
async->thrdd.res_A = NULL;
- async_thrdd_item_destroy(async->thrdd.inc_AAAA);
- async->thrdd.inc_AAAA = NULL;
async_thrdd_item_destroy(async->thrdd.res_AAAA);
async->thrdd.res_AAAA = NULL;
}
@@ -569,11 +569,11 @@ void Curl_async_thrdd_multi_process(struct Curl_multi *multi)
if(data)
async = Curl_async_get(data, item->resolv_id);
if(async) {
- struct async_thrdd_item **pdest = &async->thrdd.inc_A;
+ struct async_thrdd_item **pdest = &async->thrdd.res_A;
#ifdef CURLRES_IPV6
if(item->dns_queries & CURL_DNSQ_AAAA)
- pdest = &async->thrdd.inc_AAAA;
+ pdest = &async->thrdd.res_AAAA;
#endif
if(!*pdest) {
*pdest = item;
@@ -607,7 +607,7 @@ static CURLcode async_thrdd_query(struct Curl_easy *data,
CURLcode result;
item = async_thrdd_item_create(data, async->id, dns_queries,
- async->hostname, async->port,
+ async->peer->hostname, async->peer->port,
async->transport);
if(!item) {
result = CURLE_OUT_OF_MEMORY;
@@ -676,7 +676,7 @@ out:
if(result)
CURL_TRC_DNS(data, "error queueing query %s:%d -> %d",
- async->hostname, async->port, (int)result);
+ async->peer->hostname, async->peer->port, (int)result);
return result;
}
@@ -772,33 +772,31 @@ static CURLcode async_thrdd_check_done(struct Curl_easy *data,
struct async_thrdd_ctx *thrdd = &async->thrdd;
(void)data;
- if(thrdd->inc_A) {
- thrdd->res_A = thrdd->inc_A;
- thrdd->inc_A = NULL;
+ if(thrdd->res_A && !thrdd->processed_A) {
VERBOSE(async_thrdd_report_item(data, thrdd->res_A));
+ /* move addrinfos to the async result member */
async->dns_responses |= thrdd->res_A->dns_queries;
+ async->ai_A = thrdd->res_A->res;
+ thrdd->res_A->res = NULL;
+ thrdd->processed_A = TRUE;
}
- if(thrdd->inc_AAAA) {
- if(thrdd->res_AAAA) {
- DEBUGASSERT(0); /* should not happen */
- return CURLE_FAILED_INIT;
- }
+ if(thrdd->res_AAAA && !thrdd->processed_AAAA) {
#if defined(USE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
/* do we accept the incoming AAAA response? */
- if(!(thrdd->inc_AAAA->dns_queries & CURL_DNSQ_A) &&
- async_thrdd_item_missing_scope(data, thrdd->inc_AAAA)) {
+ if(!(thrdd->res_AAAA->dns_queries & CURL_DNSQ_A) &&
+ async_thrdd_item_missing_scope(data, thrdd->res_AAAA)) {
/* We queried "only" AF_INET6. This may be problematic when the
* result has ipv6 link-local addresses and did not give
* any scope id for it. glibc has a long outstanding bug
* <https://sourceware.org/bugzilla/show_bug.cgi?id=14413>
* that gives scope ids only on AF_UNSPEC queries. */
- struct async_thrdd_item *item = thrdd->inc_AAAA;
+ struct async_thrdd_item *item = thrdd->res_AAAA;
CURLcode result;
/* Reuse the item and queue it again, this time with added
* CURL_DNSQ_A which resolves using AF_UNSPEC. */
- thrdd->inc_AAAA = NULL;
+ thrdd->res_AAAA = NULL;
item->dns_queries |= CURL_DNSQ_A;
if(item->res) {
Curl_freeaddrinfo(item->res);
@@ -819,12 +817,14 @@ static CURLcode async_thrdd_check_done(struct Curl_easy *data,
}
/* accepting the AAAA result, strip it of any AF_INET entries,
* as we might have resolved it with AF_UNSPEC. */
- async_thrdd_item_strip_results(thrdd->inc_AAAA, AF_INET);
+ async_thrdd_item_strip_results(thrdd->res_AAAA, AF_INET);
#endif /* USE_IPV6 && HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID */
- thrdd->res_AAAA = thrdd->inc_AAAA;
- thrdd->inc_AAAA = NULL;
VERBOSE(async_thrdd_report_item(data, thrdd->res_AAAA));
+ /* move addrinfos to the async result member */
async->dns_responses |= thrdd->res_AAAA->dns_queries;
+ async->ai_AAAA = thrdd->res_AAAA->res;
+ thrdd->res_AAAA->res = NULL;
+ thrdd->processed_AAAA = TRUE;
}
if(async->queries_ongoing)
@@ -872,9 +872,9 @@ CURLcode Curl_async_take_result(struct Curl_easy *data,
const uint8_t ip_queries =
async->dns_queries & (CURL_DNSQ_A | CURL_DNSQ_AAAA);
bool negative = (async->dns_responses & ip_queries) == ip_queries;
- if(thrdd->res_A && (thrdd->res_A->res || !thrdd->res_A->negative))
+ if(thrdd->res_A && (async->ai_A || !thrdd->res_A->negative))
negative = FALSE;
- if(thrdd->res_AAAA && (thrdd->res_AAAA->res || !thrdd->res_AAAA->negative))
+ if(thrdd->res_AAAA && (async->ai_AAAA || !thrdd->res_AAAA->negative))
negative = FALSE;
if(!thrdd->res_A && !thrdd->res_AAAA)
negative = FALSE;
@@ -886,13 +886,9 @@ CURLcode Curl_async_take_result(struct Curl_easy *data,
goto out;
}
- if((thrdd->res_A && thrdd->res_A->res) ||
- (thrdd->res_AAAA && thrdd->res_AAAA->res)) {
+ if(async->ai_A || async->ai_AAAA) {
dns = Curl_dnsc_mk_addr2(
- data, async->dns_queries,
- thrdd->res_A ? &thrdd->res_A->res : NULL,
- thrdd->res_AAAA ? &thrdd->res_AAAA->res : NULL,
- async->hostname, async->port);
+ data, async->dns_queries, &async->ai_A, &async->ai_AAAA, async->peer);
if(!dns) {
result = CURLE_OUT_OF_MEMORY;
goto out;
@@ -901,9 +897,8 @@ CURLcode Curl_async_take_result(struct Curl_easy *data,
#ifdef USE_HTTPSRR_ARES
if(!dns && thrdd->rr.channel) {
- Curl_httpsrr_trace(data, thrdd->rr.hinfo);
- dns = Curl_dnsc_mk_https(data, &thrdd->rr.hinfo,
- async->hostname, async->port);
+ Curl_httpsrr_trace(data, async->httpsrr);
+ dns = Curl_dnsc_mk_https(data, &async->httpsrr, async->peer);
if(!dns) {
result = CURLE_OUT_OF_MEMORY;
goto out;
@@ -928,75 +923,9 @@ out:
(result != CURLE_COULDNT_RESOLVE_HOST) &&
(result != CURLE_COULDNT_RESOLVE_PROXY)) {
CURL_TRC_DNS(data, "Error %d resolving %s:%d",
- (int)result, async->hostname, async->port);
+ (int)result, async->peer->hostname, async->peer->port);
}
return result;
}
-static const struct Curl_addrinfo *async_thrdd_get_ai(
- const struct Curl_addrinfo *ai,
- int ai_family, unsigned int index)
-{
- unsigned int i = 0;
- for(i = 0; ai; ai = ai->ai_next) {
- if(ai->ai_family == ai_family) {
- if(i == index)
- return ai;
- ++i;
- }
- }
- return NULL;
-}
-
-const struct Curl_addrinfo *Curl_async_get_ai(struct Curl_easy *data,
- struct Curl_resolv_async *async,
- int ai_family,
- unsigned int index)
-{
- struct async_thrdd_ctx *thrdd = &async->thrdd;
-
- (void)data;
- switch(ai_family) {
- case AF_INET:
- if(thrdd->res_A)
- return async_thrdd_get_ai(thrdd->res_A->res, ai_family, index);
- break;
-#ifdef USE_IPV6
- case AF_INET6:
- if(thrdd->res_AAAA)
- return async_thrdd_get_ai(thrdd->res_AAAA->res, ai_family, index);
- break;
-#endif
- default:
- break;
- }
- return NULL;
-}
-
-#ifdef USE_HTTPSRR
-const struct Curl_https_rrinfo *Curl_async_get_https(
- struct Curl_easy *data,
- struct Curl_resolv_async *async)
-{
-#ifdef USE_HTTPSRR_ARES
- if(Curl_async_knows_https(data, async))
- return async->thrdd.rr.hinfo;
-#else
- (void)data;
- (void)async;
-#endif
- return NULL;
-}
-
-bool Curl_async_knows_https(struct Curl_easy *data,
- struct Curl_resolv_async *async)
-{
- (void)data;
- if(async->dns_queries & CURL_DNSQ_HTTPS)
- return ((async->dns_responses & CURL_DNSQ_HTTPS) || async->done);
- return TRUE; /* we know it will never come */
-}
-
-#endif /* USE_HTTPSRR */
-
#endif /* USE_RESOLV_THREADED */
lib/asyn.h+8 -24
@@ -82,15 +82,7 @@ void Curl_async_global_cleanup(void);
CURLcode Curl_async_getaddrinfo(struct Curl_easy *data,
struct Curl_resolv_async *async);
-const struct Curl_addrinfo *Curl_async_get_ai(struct Curl_easy *data,
- struct Curl_resolv_async *async,
- int ai_family,
- unsigned int index);
-
#ifdef USE_HTTPSRR
-const struct Curl_https_rrinfo *Curl_async_get_https(
- struct Curl_easy *data,
- struct Curl_resolv_async *async);
bool Curl_async_knows_https(struct Curl_easy *data,
struct Curl_resolv_async *async);
#endif /* USE_HTTPSRR */
@@ -114,15 +106,8 @@ int Curl_ares_perform(ares_channel channel, timediff_t timeout_ms);
/* async resolving implementation using c-ares alone */
struct async_ares_ctx {
ares_channel channel;
- struct Curl_addrinfo *res_A;
- struct Curl_addrinfo *res_AAAA;
int ares_status; /* ARES_SUCCESS, ARES_ENOTFOUND, etc. */
CURLcode result; /* CURLE_OK or error handling response */
- struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
-#ifdef USE_HTTPSRR
- char *https_name;
- struct Curl_https_rrinfo *hinfo;
-#endif
BIT(transient_err); /* an A/AAAA query failed without the resolver
answering that the name does not exist */
};
@@ -140,17 +125,15 @@ struct async_thrdd_item;
/* Context for threaded resolver */
struct async_thrdd_ctx {
- struct async_thrdd_item *inc_A; /* IPv4 incoming result */
struct async_thrdd_item *res_A; /* IPv4 final result */
- struct async_thrdd_item *inc_AAAA; /* IPv6 incoming result */
struct async_thrdd_item *res_AAAA; /* IPv6 final result */
#if defined(USE_HTTPSRR) && defined(USE_ARES)
struct {
ares_channel channel;
- char *https_name;
- struct Curl_https_rrinfo *hinfo;
} rr;
#endif
+ BIT(processed_A);
+ BIT(processed_AAAA);
};
void Curl_async_thrdd_shutdown(struct Curl_easy *data,
@@ -216,11 +199,9 @@ CURLcode Curl_async_pollset(struct Curl_easy *data,
/* convert these functions if an asynch resolver is not used */
#define Curl_async_global_init() CURLE_OK
#define Curl_async_global_cleanup() Curl_nop_stmt
-#define Curl_async_get_ai(a, b, c, d) NULL
#define Curl_async_await(a, b, c) CURLE_COULDNT_RESOLVE_HOST
#define Curl_async_take_result(x, y, z) CURLE_COULDNT_RESOLVE_HOST
#define Curl_async_pollset(x, y, z) CURLE_OK
-#define Curl_async_get_https(x, y) NULL
#define Curl_async_knows_https(x, y) TRUE
#endif /* !CURLRES_ASYNCH */
@@ -232,6 +213,12 @@ CURLcode Curl_async_pollset(struct Curl_easy *data,
struct Curl_resolv_async {
struct Curl_resolv_async *next;
+ struct Curl_peer *peer;
+ struct Curl_addrinfo *ai_A;
+ struct Curl_addrinfo *ai_AAAA;
+#ifdef USE_HTTPSRR
+ struct Curl_https_rrinfo *httpsrr;
+#endif
#ifdef USE_RESOLV_ARES
struct async_ares_ctx ares;
#elif defined(USE_RESOLV_THREADED)
@@ -246,8 +233,6 @@ struct Curl_resolv_async {
CURLcode result;
uint32_t poll_interval;
uint32_t id; /* unique id per easy handle of the resolve operation */
- /* what is being resolved */
- uint16_t port;
uint8_t dns_queries; /* what queries are being performed */
uint8_t dns_responses; /* what queries had responses so far. */
uint8_t transport;
@@ -261,7 +246,6 @@ struct Curl_resolv_async {
exist. Only such failures may be cached as
negative entries, not transient or local
resolver failures. */
- char hostname[1];
};
timediff_t Curl_async_timeleft_ms(struct Curl_easy *data,
lib/cf-dns.c+11 -26
@@ -567,30 +567,6 @@ CURLcode Curl_conn_dns_addr_result(struct connectdata *conn,
return CURLE_FAILED_INIT; /* no one is resolving */
}
-static const struct Curl_addrinfo *cf_dns_get_nth_ai(
- struct Curl_cfilter *cf,
- const struct Curl_addrinfo *ai,
- int ai_family, unsigned int index)
-{
- struct cf_dns_ctx *ctx = cf->ctx;
- unsigned int i = 0;
-
- if((ai_family == AF_INET) && !(ctx->dns_queries & CURL_DNSQ_A))
- return NULL;
-#ifdef USE_IPV6
- if((ai_family == AF_INET6) && !(ctx->dns_queries & CURL_DNSQ_AAAA))
- return NULL;
-#endif
- for(i = 0; ai; ai = ai->ai_next) {
- if(ai->ai_family == ai_family) {
- if(i == index)
- return ai;
- ++i;
- }
- }
- return NULL;
-}
-
/* Return the addrinfo at `index` for the given `family` from the
* first "resolve" filter at the connection. If the DNS resolving is
* not done yet or if no address for the family exists, returns NULL.
@@ -613,8 +589,17 @@ const struct Curl_addrinfo *Curl_conn_dns_get_ai(struct Curl_easy *data,
index, peer->hostname, peer->port, ai_family, !!ctx->dns);
if(ctx->resolv_result)
return NULL;
- else if(ctx->dns)
- return cf_dns_get_nth_ai(cf, ctx->dns->addr, ai_family, index);
+ else if(ctx->dns) {
+ /* A cached DNS entry may contain address families that we
+ * here never queried for. We want to give no results for those. */
+ if((ai_family == AF_INET) && !(ctx->dns_queries & CURL_DNSQ_A))
+ return NULL;
+#ifdef USE_IPV6
+ if((ai_family == AF_INET6) && !(ctx->dns_queries & CURL_DNSQ_AAAA))
+ return NULL;
+#endif
+ return Curl_addrinfo_get(ctx->dns->addr, ai_family, index);
+ }
else
return Curl_resolv_get_ai(data, ctx->resolv_id, ai_family, index);
}
lib/curl_addrinfo.c+15 -0
@@ -79,6 +79,21 @@ void Curl_freeaddrinfo(struct Curl_addrinfo *cahead)
}
}
+struct Curl_addrinfo *Curl_addrinfo_get(struct Curl_addrinfo *ai,
+ int ai_family,
+ unsigned int n)
+{
+ unsigned int i;
+ for(i = 0; ai; ai = ai->ai_next) {
+ if(ai->ai_family == ai_family) {
+ if(i == n)
+ return ai;
+ ++i;
+ }
+ }
+ return NULL;
+}
+
#ifdef HAVE_GETADDRINFO
/*
* Curl_getaddrinfo_ex()
lib/curl_addrinfo.h+5 -0
@@ -62,6 +62,11 @@ struct Curl_addrinfo {
void Curl_freeaddrinfo(struct Curl_addrinfo *cahead);
+/* Get the n-th addrinfo of family ai_family. */
+struct Curl_addrinfo *Curl_addrinfo_get(struct Curl_addrinfo *ai,
+ int ai_family,
+ unsigned int n);
+
#ifdef HAVE_GETADDRINFO
int Curl_getaddrinfo_ex(const char *nodename,
const char *servname,
lib/dnscache.c+163 -121
@@ -60,32 +60,58 @@
#define MAX_DNS_CACHE_SIZE 29999
-static void dnscache_entry_free(struct Curl_dns_entry *dns)
+struct dnsc_id {
+ struct Curl_str name;
+ uint16_t port;
+ char type;
+};
+
+static void dnsc_peer2id(struct dnsc_id *pid, char type,
+ struct Curl_peer *peer)
{
- Curl_freeaddrinfo(dns->addr);
-#ifdef USE_HTTPSRR
- Curl_httpsrr_destroy(dns->hinfo);
-#endif
- curlx_free(dns);
+ curlx_str_assign(&pid->name, peer->hostname, strlen(peer->hostname));
+ pid->port = peer->port;
+ pid->type = type;
+}
+
+static void dnsc_str2id(struct dnsc_id *pid, char type,
+ struct Curl_str *name, uint16_t port)
+{
+ pid->name = *name;
+ pid->port = port;
+ pid->type = type;
}
+struct dnsc_key {
+ char data[MAX_HOSTCACHE_LEN];
+ size_t len;
+};
+
/*
* Create a hostcache id string for the provided host + port, to be used by
* the DNS caching. Without alloc. Return length of the id string.
*/
-static size_t create_dnscache_id(char type, const char *name,
- size_t nlen, /* 0 or actual name length */
- uint16_t port,
- char *buf, size_t buflen)
-{
- size_t len = nlen ? nlen : strlen(name);
- DEBUGASSERT(buflen >= MAX_HOSTCACHE_LEN);
- if(len > (buflen - 8))
- len = buflen - 8;
+static void dnsc_id2key(struct dnsc_key *key, struct dnsc_id *id)
+{
+ size_t namelen = curlx_strlen(&id->name);
+ if(namelen > (sizeof(key->data) - 8))
+ namelen = sizeof(key->data) - 8;
/* store and lower case the name */
- buf[0] = type;
- Curl_strntolower(buf + 1, name, len);
- return curl_msnprintf(&buf[len + 1], 7, ":%u", port) + len + 1;
+ key->data[0] = id->type;
+ Curl_strntolower(key->data + 1, curlx_str(&id->name), namelen);
+ /* include the terminating 0 in key length */
+ key->len = namelen + 2 +
+ curl_msnprintf(&key->data[namelen + 1], 7, ":%u", id->port);
+}
+
+
+static void dnscache_entry_free(struct Curl_dns_entry *dns)
+{
+ Curl_freeaddrinfo(dns->addr);
+#ifdef USE_HTTPSRR
+ Curl_httpsrr_destroy(dns->hinfo);
+#endif
+ curlx_free(dns);
}
struct dnscache_prune_data {
@@ -211,35 +237,36 @@ void Curl_dnscache_clear(struct Curl_easy *data)
static CURLcode fetch_addr(struct Curl_easy *data,
struct Curl_dnscache *dnscache,
uint8_t dns_queries,
- const char *hostname,
- uint16_t port,
+ struct Curl_peer *peer,
struct Curl_dns_entry **pdns)
{
struct Curl_dns_entry *dns = NULL;
- char entry_id[MAX_HOSTCACHE_LEN];
- size_t entry_len;
- char entry_type = CURL_DNSQ_IS_ADDR(dns_queries) ?
- CURL_DNST_ADDR : CURL_DNST_HTTPS;
+ struct dnsc_id id;
+ struct dnsc_key key;
+ char type = CURL_DNSQ_IS_ADDR(dns_queries) ?
+ CURL_DNST_ADDR : CURL_DNST_HTTPS;
CURLcode result = CURLE_OK;
*pdns = NULL;
if(!dnscache)
return CURLE_OK;
- /* Create an entry id, based upon the hostname and port */
- entry_len = create_dnscache_id(entry_type, hostname, 0, port,
- entry_id, sizeof(entry_id));
+ dnsc_peer2id(&id, type, peer);
+ dnsc_id2key(&key, &id);
/* See if it is already in our dns cache */
- dns = Curl_hash_pick(&dnscache->entries, entry_id, entry_len + 1);
+ dns = Curl_hash_pick(&dnscache->entries, key.data, key.len);
/* No entry found in cache, check if we might have a wildcard entry */
- if(!dns && data->state.wildcard_resolve && CURL_DNSQ_IS_ADDR(dns_queries)) {
- entry_len = create_dnscache_id(CURL_DNST_ADDR, "*", 1, port,
- entry_id, sizeof(entry_id));
+ if(!dns && (type == CURL_DNST_ADDR) && data->state.wildcard_resolve) {
+ struct Curl_str wildname;
+
+ curlx_str_assign(&wildname, "*", 1);
+ dnsc_str2id(&id, CURL_DNST_ADDR, &wildname, peer->port);
+ dnsc_id2key(&key, &id);
/* See if it is already in our dns cache */
- dns = Curl_hash_pick(&dnscache->entries, entry_id, entry_len + 1);
+ dns = Curl_hash_pick(&dnscache->entries, key.data, key.len);
}
if(dns && (data->set.dns_cache_timeout_ms != -1)) {
@@ -253,7 +280,7 @@ static CURLcode fetch_addr(struct Curl_easy *data,
if(dnscache_entry_is_stale(&user, dns)) {
infof(data, "Hostname in DNS cache was stale, zapped");
dns = NULL; /* the memory deallocation is being handled by the hash */
- Curl_hash_delete(&dnscache->entries, entry_id, entry_len + 1);
+ Curl_hash_delete(&dnscache->entries, key.data, key.len);
}
}
@@ -297,8 +324,7 @@ static CURLcode fetch_addr(struct Curl_easy *data,
*/
CURLcode Curl_dnscache_get(struct Curl_easy *data,
uint8_t dns_queries,
- const char *hostname,
- uint16_t port,
+ struct Curl_peer *peer,
struct Curl_dns_entry **pentry)
{
struct Curl_dnscache *dnscache = dnscache_get(data);
@@ -306,7 +332,7 @@ CURLcode Curl_dnscache_get(struct Curl_easy *data,
CURLcode result = CURLE_OK;
dnscache_lock(data, dnscache);
- result = fetch_addr(data, dnscache, dns_queries, hostname, port, &dns);
+ result = fetch_addr(data, dnscache, dns_queries, peer, &dns);
if(!result && dns)
dns->refcount++; /* we pass out a reference */
else if(result) {
@@ -316,7 +342,7 @@ CURLcode Curl_dnscache_get(struct Curl_easy *data,
dnscache_unlock(data, dnscache);
CURL_TRC_DNS(data, "cache lookup %s:%u queries=%s -> %d %sfound",
- hostname, port, Curl_resolv_query_str(dns_queries),
+ peer->hostname, peer->port, Curl_resolv_query_str(dns_queries),
(int)result, dns ? "" : "not ");
*pentry = dns;
return result;
@@ -414,24 +440,23 @@ static bool dnscache_ai_has_family(struct Curl_addrinfo *ai,
return FALSE;
}
-static struct Curl_dns_entry *dnsc_entry_create(
- struct Curl_easy *data,
- const char *hostname,
- size_t hostlen,
- uint16_t port,
- bool permanent)
+static struct Curl_dns_entry *dnsc_entry_create(struct Curl_easy *data,
+ struct dnsc_id *pid,
+ bool permanent)
{
struct Curl_dns_entry *dns = NULL;
/* Create a new cache entry, struct already has the hostname NUL */
- dns = curlx_calloc(1, sizeof(struct Curl_dns_entry) + hostlen);
+ dns = curlx_calloc(1, sizeof(struct Curl_dns_entry) +
+ curlx_strlen(&pid->name));
if(!dns)
goto out;
dns->refcount = 1; /* the cache has the first reference */
- dns->port = port;
- if(hostlen)
- memcpy(dns->hostname, hostname, hostlen);
+ dns->hostlen = curlx_strlen(&pid->name);
+ dns->port = pid->port;
+ if(dns->hostlen)
+ memcpy(dns->hostname, curlx_str(&pid->name), dns->hostlen);
if(permanent) {
dns->timestamp.tv_sec = 0; /* an entry that never goes stale */
@@ -515,26 +540,30 @@ out:
}
struct Curl_dns_entry *Curl_dnsc_mk_addr(struct Curl_easy *data,
- uint8_t dns_queries,
- struct Curl_addrinfo **paddr,
- const char *hostname,
- uint16_t port)
+ uint8_t dns_queries,
+ struct Curl_addrinfo **paddr,
+ struct Curl_peer *peer)
{
- struct Curl_dns_entry *dns = dnsc_entry_create(
- data, hostname, hostname ? strlen(hostname) : 0, port, FALSE);
+ struct dnsc_id id;
+ struct Curl_dns_entry *dns;
+
+ dnsc_peer2id(&id, CURL_DNST_ADDR, peer);
+ dns = dnsc_entry_create(data, &id, FALSE);
dns = dnsc_entry_assign_addr(data, dns, dns_queries, paddr, NULL);
return dns;
}
struct Curl_dns_entry *Curl_dnsc_mk_addr2(struct Curl_easy *data,
- uint8_t dns_queries,
- struct Curl_addrinfo **paddr1,
- struct Curl_addrinfo **paddr2,
- const char *hostname,
- uint16_t port)
-{
- struct Curl_dns_entry *dns = dnsc_entry_create(
- data, hostname, hostname ? strlen(hostname) : 0, port, FALSE);
+ uint8_t dns_queries,
+ struct Curl_addrinfo **paddr1,
+ struct Curl_addrinfo **paddr2,
+ struct Curl_peer *peer)
+{
+ struct dnsc_id id;
+ struct Curl_dns_entry *dns;
+
+ dnsc_peer2id(&id, CURL_DNST_ADDR, peer);
+ dns = dnsc_entry_create(data, &id, FALSE);
dns = dnsc_entry_assign_addr(data, dns, dns_queries, paddr1, paddr2);
return dns;
}
@@ -570,11 +599,13 @@ out:
struct Curl_dns_entry *Curl_dnsc_mk_https(struct Curl_easy *data,
struct Curl_https_rrinfo **phinfo,
- const char *hostname,
- uint16_t port)
+ struct Curl_peer *peer)
{
- struct Curl_dns_entry *dns = dnsc_entry_create(
- data, hostname, hostname ? strlen(hostname) : 0, port, FALSE);
+ struct dnsc_id id;
+ struct Curl_dns_entry *dns;
+
+ dnsc_peer2id(&id, CURL_DNST_HTTPS, peer);
+ dns = dnsc_entry_create(data, &id, FALSE);
dns = dnsc_entry_assign_https(dns, phinfo);
return dns;
}
@@ -582,28 +613,20 @@ struct Curl_dns_entry *Curl_dnsc_mk_https(struct Curl_easy *data,
static struct Curl_dns_entry *dnsc_add_https(struct Curl_easy *data,
struct Curl_dnscache *dnscache,
struct Curl_https_rrinfo **phinfo,
- const char *hostname,
- size_t hlen,
- uint16_t port,
+ struct dnsc_id *id,
bool permanent)
{
- char entry_id[MAX_HOSTCACHE_LEN];
- size_t entry_len;
struct Curl_dns_entry *dns, *dns2;
+ struct dnsc_key key;
- dns = dnsc_entry_create(data, hostname, hostname ? strlen(hostname) : 0,
- port, permanent);
+ dns = dnsc_entry_create(data, id, permanent);
dns = dnsc_entry_assign_https(dns, phinfo);
if(!dns)
return NULL;
- /* Create an entry id, based upon the hostname and port */
- entry_len = create_dnscache_id(CURL_DNST_HTTPS, hostname, hlen, port,
- entry_id, sizeof(entry_id));
-
/* Store the resolved data in our DNS cache. */
- dns2 = Curl_hash_add(&dnscache->entries, entry_id, entry_len + 1,
- (void *)dns);
+ dnsc_id2key(&key, id);
+ dns2 = Curl_hash_add(&dnscache->entries, key.data, key.len, (void *)dns);
if(!dns2) {
dnscache_entry_free(dns);
return NULL;
@@ -620,28 +643,51 @@ static struct Curl_dns_entry *dnsc_add_addr(struct Curl_easy *data,
struct Curl_dnscache *dnscache,
uint8_t dns_queries,
struct Curl_addrinfo **paddr,
- const char *hostname,
- size_t hlen,
- uint16_t port,
+ struct dnsc_id *id,
+ struct dnsc_key *key,
bool permanent)
{
- char entry_id[MAX_HOSTCACHE_LEN];
- size_t entry_len;
struct Curl_dns_entry *dns;
struct Curl_dns_entry *dns2;
- dns = dnsc_entry_create(data, hostname, hlen, port, permanent);
+ dns = dnsc_entry_create(data, id, permanent);
+ dns = dnsc_entry_assign_addr(data, dns, dns_queries, paddr, NULL);
+ if(!dns)
+ return NULL;
+
+ /* Store the resolved data in our DNS cache. */
+ dns2 = Curl_hash_add(&dnscache->entries, key->data, key->len, (void *)dns);
+ if(!dns2) {
+ dnscache_entry_free(dns);
+ return NULL;
+ }
+
+ dns = dns2;
+ dns->refcount++; /* mark entry as in-use */
+ return dns;
+}
+
+static struct Curl_dns_entry *
+dnsc_add_peer_addr(struct Curl_easy *data,
+ struct Curl_dnscache *dnscache,
+ uint8_t dns_queries,
+ struct Curl_addrinfo **paddr,
+ struct dnsc_id *id,
+ bool permanent)
+{
+ struct Curl_dns_entry *dns;
+ struct Curl_dns_entry *dns2;
+ struct dnsc_key key;
+
+ dns = dnsc_entry_create(data, id, permanent);
dns = dnsc_entry_assign_addr(data, dns, dns_queries, paddr, NULL);
if(!dns)
return NULL;
- /* Create an entry id, based upon the hostname and port */
- entry_len = create_dnscache_id(CURL_DNST_ADDR, hostname, hlen, port,
- entry_id, sizeof(entry_id));
/* Store the resolved data in our DNS cache. */
- dns2 = Curl_hash_add(&dnscache->entries, entry_id, entry_len + 1,
- (void *)dns);
+ dnsc_id2key(&key, id);
+ dns2 = Curl_hash_add(&dnscache->entries, key.data, key.len, (void *)dns);
if(!dns2) {
dnscache_entry_free(dns);
return NULL;
@@ -656,21 +702,22 @@ CURLcode Curl_dnscache_add(struct Curl_easy *data,
struct Curl_dns_entry *entry)
{
struct Curl_dnscache *dnscache = dnscache_get(data);
- char id[MAX_HOSTCACHE_LEN];
- size_t idlen;
+ struct Curl_str name;
+ struct dnsc_id id;
+ struct dnsc_key key;
if(!dnscache)
return CURLE_FAILED_INIT;
if(!entry || (entry->type == CURL_DNST_INIT))
return CURLE_BAD_FUNCTION_ARGUMENT;
- /* Create an entry id, based upon the hostname and port */
- idlen = create_dnscache_id(entry->type, entry->hostname, 0, entry->port,
- id, sizeof(id));
+ curlx_str_assign(&name, entry->hostname, entry->hostlen);
+ dnsc_str2id(&id, entry->type, &name, entry->port);
+ dnsc_id2key(&key, &id);
/* Store the resolved data in our DNS cache and up ref count */
dnscache_lock(data, dnscache);
- if(!Curl_hash_add(&dnscache->entries, id, idlen + 1, (void *)entry)) {
+ if(!Curl_hash_add(&dnscache->entries, key.data, key.len, (void *)entry)) {
dnscache_unlock(data, dnscache);
return CURLE_OUT_OF_MEMORY;
}
@@ -684,11 +731,11 @@ CURLcode Curl_dnscache_add(struct Curl_easy *data,
CURLcode Curl_dnscache_add_negative(struct Curl_easy *data,
uint8_t dns_queries,
- const char *host,
- uint16_t port)
+ struct Curl_peer *peer)
{
struct Curl_dnscache *dnscache = dnscache_get(data);
struct Curl_dns_entry *dns = NULL;
+ struct dnsc_id id;
CURLcode result = CURLE_OK;
DEBUGASSERT(dnscache);
@@ -699,15 +746,15 @@ CURLcode Curl_dnscache_add_negative(struct Curl_easy *data,
if(dns_queries & CURL_DNSQ_ADDR) {
/* put this new host in the cache */
- dns = dnsc_add_addr(data, dnscache, dns_queries, NULL,
- host, strlen(host), port, FALSE);
+ dnsc_peer2id(&id, CURL_DNST_ADDR, peer);
+ dns = dnsc_add_peer_addr(data, dnscache, dns_queries, NULL, &id, FALSE);
if(!dns)
result = CURLE_OUT_OF_MEMORY;
}
#ifdef USE_HTTPSRR
else if(dns_queries == CURL_DNSQ_HTTPS) {
- dns = dnsc_add_https(data, dnscache, NULL,
- host, strlen(host), port, FALSE);
+ dnsc_peer2id(&id, CURL_DNST_HTTPS, peer);
+ dns = dnsc_add_https(data, dnscache, NULL, &id, FALSE);
if(!dns)
result = CURLE_OUT_OF_MEMORY;
}
@@ -722,7 +769,8 @@ CURLcode Curl_dnscache_add_negative(struct Curl_easy *data,
* entry alive: */
dns->refcount--;
CURL_TRC_DNS(data, "cache negative name resolve for %s:%d type=%s",
- host, port, Curl_resolv_query_str(dns_queries));
+ peer->hostname, peer->port,
+ Curl_resolv_query_str(dns_queries));
}
dnscache_unlock(data, dnscache);
return result;
@@ -777,6 +825,8 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
{
struct Curl_dnscache *dnscache = dnscache_get(data);
struct curl_slist *hostp;
+ struct dnsc_id id;
+ struct dnsc_key key;
if(!dnscache)
return CURLE_FAILED_INIT;
@@ -785,14 +835,12 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
data->state.wildcard_resolve = FALSE;
for(hostp = data->state.resolve; hostp; hostp = hostp->next) {
- char entry_id[MAX_HOSTCACHE_LEN];
const char *host = hostp->data;
struct Curl_str source;
if(!host)
continue;
if(*host == '-') {
curl_off_t num = 0;
- size_t entry_len;
host++;
if(!curlx_str_single(&host, '[')) {
if(curlx_str_until(&host, &source, MAX_IPADR_LEN, ']') ||
@@ -809,19 +857,17 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
if(!curlx_str_number(&host, &num, 0xffff)) {
/* Create an entry id, based upon the hostname and port */
- entry_len = create_dnscache_id(CURL_DNST_ADDR, curlx_str(&source),
- curlx_strlen(&source), (uint16_t)num,
- entry_id, sizeof(entry_id));
+ dnsc_str2id(&id, CURL_DNST_ADDR, &source, (uint16_t)num);
+ dnsc_id2key(&key, &id);
dnscache_lock(data, dnscache);
/* delete entry, ignore if it did not exist */
- Curl_hash_delete(&dnscache->entries, entry_id, entry_len + 1);
+ Curl_hash_delete(&dnscache->entries, key.data, key.len);
dnscache_unlock(data, dnscache);
}
}
else {
struct Curl_dns_entry *dns;
struct Curl_addrinfo *head = NULL, *tail = NULL;
- size_t entry_len;
char address[64];
curl_off_t tmpofft = 0;
uint16_t port = 0;
@@ -913,15 +959,12 @@ err:
return CURLE_SETOPT_OPTION_SYNTAX;
}
- /* Create an entry id, based upon the hostname and port */
- entry_len = create_dnscache_id(CURL_DNST_ADDR,
- curlx_str(&source), curlx_strlen(&source),
- port, entry_id, sizeof(entry_id));
-
+ dnsc_str2id(&id, CURL_DNST_ADDR, &source, port);
+ dnsc_id2key(&key, &id);
dnscache_lock(data, dnscache);
/* See if it is already in our dns cache */
- dns = Curl_hash_pick(&dnscache->entries, entry_id, entry_len + 1);
+ dns = Curl_hash_pick(&dnscache->entries, key.data, key.len);
if(dns) {
infof(data, "RESOLVE %.*s:%u - old addresses discarded",
@@ -938,13 +981,12 @@ err:
4. when adding a non-permanent entry, we want it to get a "fresh"
timeout that starts _now_. */
- Curl_hash_delete(&dnscache->entries, entry_id, entry_len + 1);
+ Curl_hash_delete(&dnscache->entries, key.data, key.len);
}
/* put this new host in the cache, override all address queries */
- dns = dnsc_add_addr(data, dnscache, CURL_DNSQ_ADDR,
- &head, curlx_str(&source),
- curlx_strlen(&source), port, permanent);
+ dns = dnsc_add_addr(data, dnscache, CURL_DNSQ_ADDR, &head,
+ &id, &key, permanent);
if(dns)
/* release the returned reference; the cache itself will keep the
* entry alive: */
@@ -956,8 +998,8 @@ err:
return CURLE_OUT_OF_MEMORY;
infof(data, "[DNS] added %.*s:%u:%s to cache%s",
- (int)curlx_strlen(&source), curlx_str(&source), port, addresses,
- permanent ? "" : " (non-permanent)");
+ (int)curlx_strlen(&id.name), curlx_str(&id.name), id.port,
+ addresses, permanent ? "" : " (non-permanent)");
/* Wildcard hostname */
if(curlx_str_casecompare(&source, "*")) {
lib/dnscache.h+7 -10
@@ -35,6 +35,7 @@ struct connectdata;
struct easy_pollset;
struct Curl_https_rrinfo;
struct Curl_multi;
+struct Curl_peer;
#define CURL_DNST_INIT '\0'
#define CURL_DNST_ADDR 'A'
@@ -47,6 +48,7 @@ struct Curl_dns_entry {
#endif
/* timestamp == 0 -- permanent CURLOPT_RESOLVE entry (does not time out) */
struct curltime timestamp;
+ size_t hostlen;
/* reference counter, entry is freed on reaching 0 */
uint32_t refcount;
/* hostname port number that resolved to addr. */
@@ -70,21 +72,18 @@ struct Curl_dns_entry {
struct Curl_dns_entry *Curl_dnsc_mk_addr(struct Curl_easy *data,
uint8_t dns_queries,
struct Curl_addrinfo **paddr,
- const char *hostname,
- uint16_t port);
+ struct Curl_peer *peer);
struct Curl_dns_entry *Curl_dnsc_mk_addr2(struct Curl_easy *data,
uint8_t dns_queries,
struct Curl_addrinfo **paddr1,
struct Curl_addrinfo **paddr2,
- const char *hostname,
- uint16_t port);
+ struct Curl_peer *peer);
#ifdef USE_HTTPSRR
struct Curl_dns_entry *Curl_dnsc_mk_https(struct Curl_easy *data,
struct Curl_https_rrinfo **phinfo,
- const char *hostname,
- uint16_t port);
+ struct Curl_peer *peer);
#endif /* USE_HTTPSRR */
/* unlink a dns entry, frees all resources if it was the last reference.
@@ -119,8 +118,7 @@ void Curl_dnscache_clear(struct Curl_easy *data);
*/
CURLcode Curl_dnscache_get(struct Curl_easy *data,
uint8_t dns_queries,
- const char *hostname,
- uint16_t port,
+ struct Curl_peer *peer,
struct Curl_dns_entry **pentry);
/*
@@ -134,8 +132,7 @@ CURLcode Curl_dnscache_add(struct Curl_easy *data,
* it could not be resolved. */
CURLcode Curl_dnscache_add_negative(struct Curl_easy *data,
uint8_t dns_queries,
- const char *host,
- uint16_t port);
+ struct Curl_peer *peer);
/*
* Populate the cache with specified entries from CURLOPT_RESOLVE.
lib/doh.c+13 -16
@@ -463,7 +463,7 @@ CURLcode Curl_doh(struct Curl_easy *data,
size_t i;
DEBUGASSERT(!async->doh);
- DEBUGASSERT(async->hostname[0]);
+ DEBUGASSERT(async->peer->hostname[0]);
if(async->doh) {
DEBUGASSERT(0); /* should not happen */
Curl_doh_cleanup(data, async);
@@ -479,13 +479,10 @@ CURLcode Curl_doh(struct Curl_easy *data,
curlx_dyn_init(&dohp->probe_resp[i].body, DYN_DOH_RESPONSE);
}
- dohp->host = async->hostname;
- dohp->port = async->port;
-
/* create IPv4 DoH request */
if(async->dns_queries & CURL_DNSQ_A) {
result = doh_probe_run(data, CURL_DNS_TYPE_A,
- async->hostname, data->set.str[STRING_DOH],
+ async->peer->hostname, data->set.str[STRING_DOH],
data->multi, async->id,
&dohp->probe_resp[DOH_SLOT_IPV4].probe_mid);
if(result)
@@ -497,7 +494,7 @@ CURLcode Curl_doh(struct Curl_easy *data,
if(async->dns_queries & CURL_DNSQ_AAAA) {
/* create IPv6 DoH request */
result = doh_probe_run(data, CURL_DNS_TYPE_AAAA,
- async->hostname, data->set.str[STRING_DOH],
+ async->peer->hostname, data->set.str[STRING_DOH],
data->multi, async->id,
&dohp->probe_resp[DOH_SLOT_IPV6].probe_mid);
if(result)
@@ -509,13 +506,14 @@ CURLcode Curl_doh(struct Curl_easy *data,
#ifdef USE_HTTPSRR
if(async->dns_queries & CURL_DNSQ_HTTPS) {
char *qname = NULL;
- if(async->port != PORT_HTTPS) {
- qname = curl_maprintf("_%d._https.%s", async->port, async->hostname);
+ if(async->peer->port != PORT_HTTPS) {
+ qname = curl_maprintf("_%u._https.%s",
+ async->peer->port, async->peer->hostname);
if(!qname)
goto error;
}
result = doh_probe_run(data, CURL_DNS_TYPE_HTTPS,
- qname ? qname : async->hostname,
+ qname ? qname : async->peer->hostname,
data->set.str[STRING_DOH], data->multi,
async->id,
&dohp->probe_resp[DOH_SLOT_HTTPS_RR].probe_mid);
@@ -1209,7 +1207,7 @@ CURLcode Curl_doh_take_result(struct Curl_easy *data,
if(CURL_DNSQ_IS_ADDR(async->dns_queries) &&
dohp->probe_resp[DOH_SLOT_IPV4].probe_mid == UINT32_MAX &&
dohp->probe_resp[DOH_SLOT_IPV6].probe_mid == UINT32_MAX) {
- failf(data, "Could not DoH-resolve: %s", dohp->host);
+ failf(data, "Could not DoH-resolve: %s", async->peer->hostname);
return async->for_proxy ?
CURLE_COULDNT_RESOLVE_PROXY : CURLE_COULDNT_RESOLVE_HOST;
}
@@ -1240,7 +1238,7 @@ CURLcode Curl_doh_take_result(struct Curl_easy *data,
CURL_TRC_DNS(data, "[%s] [DoH] error: %s type %s for %s",
Curl_resolv_query_str(async->dns_queries),
doh_strerror(rc[slot]),
- doh_type2name(p->dnstype), dohp->host);
+ doh_type2name(p->dnstype), async->peer->hostname);
}
} /* next slot */
@@ -1250,11 +1248,11 @@ CURLcode Curl_doh_take_result(struct Curl_easy *data,
struct Curl_addrinfo *ai;
if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_doh)) {
- CURL_TRC_DNS(data, "hostname: %s", dohp->host);
+ CURL_TRC_DNS(data, "hostname: %s", async->peer->hostname);
doh_show(data, &de);
}
- result = doh2ai(&de, dohp->host, dohp->port, &ai);
+ result = doh2ai(&de, async->peer->hostname, async->peer->port, &ai);
if(result) {
/* a decoded response without any usable address, e.g. only
CNAME records, is an authoritative "no data" answer */
@@ -1264,8 +1262,7 @@ CURLcode Curl_doh_take_result(struct Curl_easy *data,
}
/* we got a response, create a dns entry. */
- dns = Curl_dnsc_mk_addr(data, async->dns_queries,
- &ai, dohp->host, dohp->port);
+ dns = Curl_dnsc_mk_addr(data, async->dns_queries, &ai, async->peer);
if(!dns) {
result = CURLE_OUT_OF_MEMORY;
goto error;
@@ -1297,7 +1294,7 @@ CURLcode Curl_doh_take_result(struct Curl_easy *data,
infof(data, "Some HTTPS RR to process");
}
Curl_httpsrr_trace(data, hrr);
- dns = Curl_dnsc_mk_https(data, &hrr, async->hostname, async->port);
+ dns = Curl_dnsc_mk_https(data, &hrr, async->peer);
if(!dns) {
result = CURLE_OUT_OF_MEMORY;
goto error;
lib/doh.h+0 -2
@@ -110,8 +110,6 @@ struct doh_response {
struct doh_probes {
struct doh_response probe_resp[DOH_SLOT_COUNT];
unsigned int pending; /* still outstanding probes */
- uint16_t port;
- const char *host;
};
/*
lib/hostip.c+93 -89
@@ -342,11 +342,11 @@ static bool tailmatch(const char *full, size_t flen,
}
static CURLcode hostip_resolv_failed(struct Curl_easy *data,
- const char *hostname,
+ struct Curl_peer *peer,
bool for_proxy)
{
failf(data, "Could not resolve %s: %s",
- for_proxy ? "proxy" : "host", hostname);
+ for_proxy ? "proxy" : "host", peer->hostname);
return RESOLV_FAIL(for_proxy);
}
@@ -383,14 +383,12 @@ CURLcode Curl_resolv_announce_start(struct Curl_easy *data,
static struct Curl_resolv_async *hostip_async_new(struct Curl_easy *data,
uint8_t dns_queries,
- const char *hostname,
- uint16_t port,
+ struct Curl_peer *peer,
uint8_t transport,
bool for_proxy,
timediff_t timeout_ms)
{
struct Curl_resolv_async *async;
- size_t hostlen = strlen(hostname);
if(!data->multi) {
DEBUGASSERT(0);
@@ -398,7 +396,7 @@ static struct Curl_resolv_async *hostip_async_new(struct Curl_easy *data,
}
/* struct size already includes the NUL for hostname */
- async = curlx_calloc(1, sizeof(*async) + hostlen);
+ async = curlx_calloc(1, sizeof(*async));
if(!async)
return NULL;
@@ -412,18 +410,15 @@ static struct Curl_resolv_async *hostip_async_new(struct Curl_easy *data,
else
data->multi->last_resolv_id++;
async->id = data->multi->last_resolv_id;
+ Curl_peer_link(&async->peer, peer);
async->dns_queries = dns_queries;
- async->port = port;
async->transport = transport;
async->for_proxy = for_proxy;
async->start = *Curl_pgrs_now(data);
async->timeout_ms = timeout_ms;
- if(hostlen) {
- memcpy(async->hostname, hostname, hostlen);
- async->is_ipaddr = Curl_is_ipaddr(async->hostname);
- if(async->is_ipaddr)
- async->is_ipv4addr = Curl_is_ipv4addr(async->hostname);
- }
+ async->is_ipaddr = Curl_is_ipaddr(peer->hostname);
+ if(async->is_ipaddr)
+ async->is_ipv4addr = Curl_is_ipv4addr(peer->hostname);
return async;
}
@@ -450,7 +445,8 @@ static CURLcode hostip_resolv_take_result(struct Curl_easy *data,
"ongoing=%d for %s:%d",
Curl_resolv_query_str(async->dns_queries),
Curl_resolv_query_str(async->dns_responses),
- async->queries_ongoing, async->hostname, async->port);
+ async->queries_ongoing,
+ async->peer->hostname, async->peer->port);
result = CURLE_OK;
}
else if(IS_RESOLV_FAIL(result)) {
@@ -461,12 +457,12 @@ static CURLcode hostip_resolv_take_result(struct Curl_easy *data,
is so it does not get treated as one. */
CURL_TRC_DNS(data, "[%s] resolve error %d for %s:%u",
Curl_resolv_query_str(async->dns_queries),
- (int)result, async->hostname, async->port);
+ (int)result, async->peer->hostname, async->peer->port);
}
else {
CURL_TRC_DNS(data, "[%s] resolve complete for %s:%u",
Curl_resolv_query_str(async->dns_queries),
- async->hostname, async->port);
+ async->peer->hostname, async->peer->port);
DEBUGASSERT(*pdns);
}
@@ -504,16 +500,18 @@ const struct Curl_addrinfo *Curl_resolv_get_ai(struct Curl_easy *data,
unsigned int index)
{
struct Curl_resolv_async *async = Curl_async_get(data, resolv_id);
- (void)index;
- if(!async)
- return NULL;
- if((ai_family == AF_INET) && !(async->dns_queries & CURL_DNSQ_A))
+ if(!async || !CURL_DNSQ_IS_ADDR(async->dns_queries))
return NULL;
+ switch(ai_family) {
+ case AF_INET:
+ return Curl_addrinfo_get(async->ai_A, ai_family, index);
#ifdef USE_IPV6
- if((ai_family == AF_INET6) && !(async->dns_queries & CURL_DNSQ_AAAA))
- return NULL;
+ case AF_INET6:
+ return Curl_addrinfo_get(async->ai_AAAA, ai_family, index);
#endif
- return Curl_async_get_ai(data, async, ai_family, index);
+ default:
+ return NULL;
+ }
}
#ifdef USE_HTTPSRR
@@ -532,19 +530,22 @@ CURLcode Curl_resolv_https(struct Curl_easy *data,
const struct Curl_https_rrinfo *
Curl_resolv_get_https(struct Curl_easy *data, uint32_t resolv_id)
{
- struct Curl_resolv_async *async = Curl_async_get(data, resolv_id);
- if(!async)
+ struct Curl_resolv_async *async;
+ if(!Curl_resolv_knows_https(data, resolv_id))
return NULL;
- return Curl_async_get_https(data, async);
+ async = Curl_async_get(data, resolv_id);
+ return async ? async->httpsrr : NULL;
}
bool Curl_resolv_knows_https(struct Curl_easy *data, uint32_t resolv_id)
{
struct Curl_resolv_async *async = Curl_async_get(data, resolv_id);
- if(!async)
- return TRUE;
- return Curl_async_knows_https(data, async);
+ if(async && (async->dns_queries & CURL_DNSQ_HTTPS))
+ return ((async->dns_responses & CURL_DNSQ_HTTPS) ||
+ !async->queries_ongoing);
+ return TRUE; /* we know it will never come */
}
+
#endif /* USE_HTTPSRR */
#endif /* USE_CURL_ASYNC */
@@ -555,8 +556,7 @@ bool Curl_resolv_knows_https(struct Curl_easy *data, uint32_t resolv_id)
that must not be cached as negative entries. */
static CURLcode hostip_resolv_start(struct Curl_easy *data,
uint8_t dns_queries,
- const char *hostname,
- uint16_t port,
+ struct Curl_peer *peer,
uint8_t transport,
bool for_proxy,
timediff_t timeout_ms,
@@ -582,40 +582,40 @@ static CURLcode hostip_resolv_start(struct Curl_easy *data,
/* Check for "known" things to resolve ourselves. */
if(addr_queries) {
#ifndef USE_RESOLVE_ON_IPS
- if(Curl_is_ipaddr(hostname)) {
+ if(Curl_is_ipaddr(peer->hostname)) {
/* test655 verifies that the announce is done, even though there
* is no real resolving. So, keep doing this. */
result = Curl_resolv_announce_start(data, NULL);
if(result)
goto out;
/* shortcut literal IP addresses, if we are not told to resolve them. */
- result = Curl_str2addr(hostname, port, &addr);
+ result = Curl_str2addr(peer->hostname, peer->port, &addr);
goto out;
}
#endif
- hostname_len = strlen(hostname);
- if(curl_strequal(hostname, "localhost") ||
- curl_strequal(hostname, "localhost.") ||
- tailmatch(hostname, hostname_len, STRCONST(".localhost")) ||
- tailmatch(hostname, hostname_len, STRCONST(".localhost."))) {
+ hostname_len = strlen(peer->hostname);
+ if(curl_strequal(peer->hostname, "localhost") ||
+ curl_strequal(peer->hostname, "localhost.") ||
+ tailmatch(peer->hostname, hostname_len, STRCONST(".localhost")) ||
+ tailmatch(peer->hostname, hostname_len, STRCONST(".localhost."))) {
result = Curl_resolv_announce_start(data, NULL);
if(result)
goto out;
- addr = get_localhost(port, hostname);
+ addr = get_localhost(peer->port, peer->hostname);
if(!addr)
result = CURLE_OUT_OF_MEMORY;
goto out;
}
}
#ifndef CURL_DISABLE_DOH
- if(!Curl_is_ipaddr(hostname) && allowDOH && data->set.doh) {
+ if(!Curl_is_ipaddr(peer->hostname) && allowDOH && data->set.doh) {
result = Curl_resolv_announce_start(data, NULL);
if(result)
goto out;
if(!async) {
- async = hostip_async_new(data, dns_queries, hostname, port,
- transport, for_proxy, timeout_ms);
+ async = hostip_async_new(data, dns_queries, peer, transport,
+ for_proxy, timeout_ms);
if(!async) {
result = CURLE_OUT_OF_MEMORY;
goto out;
@@ -637,8 +637,8 @@ static CURLcode hostip_resolv_start(struct Curl_easy *data,
#ifdef CURLRES_ASYNCH
(void)addr;
if(!async) {
- async = hostip_async_new(data, dns_queries, hostname, port,
- transport, for_proxy, timeout_ms);
+ async = hostip_async_new(data, dns_queries, peer, transport,
+ for_proxy, timeout_ms);
if(!async) {
result = CURLE_OUT_OF_MEMORY;
goto out;
@@ -657,7 +657,8 @@ static CURLcode hostip_resolv_start(struct Curl_easy *data,
result = Curl_resolv_announce_start(data, NULL);
if(result)
goto out;
- addr = Curl_sync_getaddrinfo(data, dns_queries, hostname, port, transport);
+ addr = Curl_sync_getaddrinfo(data, dns_queries, peer->hostname, peer->port,
+ transport);
if(!addr) {
result = RESOLV_FAIL(for_proxy);
/* the synchronous resolvers do not tell a transient failure from
@@ -671,7 +672,7 @@ out:
if(addr) {
/* we got a response, create a dns entry, add to cache, return */
DEBUGASSERT(!*pdns);
- *pdns = Curl_dnsc_mk_addr(data, dns_queries, &addr, hostname, port);
+ *pdns = Curl_dnsc_mk_addr(data, dns_queries, &addr, peer);
if(!*pdns)
result = CURLE_OUT_OF_MEMORY;
}
@@ -701,8 +702,7 @@ out:
static CURLcode hostip_resolv(struct Curl_easy *data,
uint8_t dns_queries,
- const char *hostname,
- uint16_t port,
+ struct Curl_peer *peer,
uint8_t transport,
bool for_proxy,
timediff_t timeout_ms,
@@ -724,40 +724,40 @@ static CURLcode hostip_resolv(struct Curl_easy *data,
#endif
/* We should intentionally error and not resolve .onion TLDs */
- hostname_len = strlen(hostname);
+ hostname_len = strlen(peer->hostname);
DEBUGASSERT(hostname_len);
if(hostname_len >= 7 &&
- (curl_strequal(&hostname[hostname_len - 6], ".onion") ||
- curl_strequal(&hostname[hostname_len - 7], ".onion."))) {
+ (curl_strequal(&peer->hostname[hostname_len - 6], ".onion") ||
+ curl_strequal(&peer->hostname[hostname_len - 7], ".onion."))) {
failf(data, "Not resolving .onion address (RFC 7686)");
goto out;
}
#ifdef DEBUGBUILD
CURL_TRC_DNS(data, "[%s] hostip_resolv(%s:%u)",
- Curl_resolv_query_str(dns_queries), hostname, port);
+ Curl_resolv_query_str(dns_queries), peer->hostname, peer->port);
if((CURL_DNSQ_IS_ADDR(dns_queries) == CURL_DNSQ_AAAA) &&
getenv("CURL_DBG_RESOLV_FAIL_IPV6")) {
infof(data, "DEBUG fail ipv6 resolve");
- result = hostip_resolv_failed(data, hostname, for_proxy);
+ result = hostip_resolv_failed(data, peer, for_proxy);
goto out;
}
#endif
/* Let's check our DNS cache first */
- result = Curl_dnscache_get(data, dns_queries, hostname, port, pdns);
+ result = Curl_dnscache_get(data, dns_queries, peer, pdns);
if(*pdns) {
- infof(data, "Hostname %s was found in DNS cache", hostname);
+ infof(data, "Hostname %s was found in DNS cache", peer->hostname);
result = CURLE_OK;
}
else if(result) {
infof(data, "Negative DNS entry");
- result = hostip_resolv_failed(data, hostname, for_proxy);
+ result = hostip_resolv_failed(data, peer, for_proxy);
}
else {
/* No luck, we need to start resolving. */
cache_dns = TRUE;
- result = hostip_resolv_start(data, dns_queries, hostname, port,
- transport, for_proxy, timeout_ms, allowDOH,
+ result = hostip_resolv_start(data, dns_queries, peer, transport,
+ for_proxy, timeout_ms, allowDOH,
presolv_id, pdns, &negative);
CURL_TRC_DNS(data, "[%s] hostip_resolv started -> %d",
Curl_resolv_query_str(dns_queries), (int)result);
@@ -768,12 +768,13 @@ out:
Curl_dns_entry_unlink(data, pdns);
if(IS_RESOLV_FAIL(result)) {
if(cache_dns && negative)
- Curl_dnscache_add_negative(data, dns_queries, hostname, port);
+ Curl_dnscache_add_negative(data, dns_queries, peer);
if(dns_queries & (CURL_DNSQ_A|CURL_DNSQ_AAAA))
- failf(data, "Could not resolve: %s:%u", hostname, port);
+ failf(data, "Could not resolve: %s:%u", peer->hostname, peer->port);
}
else {
- failf(data, "Error %d resolving %s:%u", (int)result, hostname, port);
+ failf(data, "Error %d resolving %s:%u",
+ (int)result, peer->hostname, peer->port);
}
}
else if(cache_dns && *pdns) {
@@ -792,13 +793,19 @@ CURLcode Curl_resolv_blocking(struct Curl_easy *data,
uint8_t transport,
struct Curl_dns_entry **pdns)
{
+ struct Curl_peer *peer = NULL;
CURLcode result;
uint32_t resolv_id;
+
DEBUGASSERT(hostname && *hostname);
*pdns = NULL;
+
+ result = Curl_peer_create(data, data->conn->scheme, hostname, port, &peer);
+ if(result)
+ goto out;
+
/* We cannot do a blocking resolve using DoH currently */
- result = hostip_resolv(data, dns_queries,
- hostname, port, transport, FALSE, 0, FALSE,
+ result = hostip_resolv(data, dns_queries, peer, transport, FALSE, 0, FALSE,
&resolv_id, pdns);
switch(result) {
case CURLE_OK:
@@ -814,6 +821,9 @@ CURLcode Curl_resolv_blocking(struct Curl_easy *data,
default:
break;
}
+
+out:
+ Curl_peer_unlink(&peer);
return result;
}
@@ -831,8 +841,7 @@ CURL_NORETURN static void alarmfunc(int sig)
static CURLcode resolv_alarm_timeout(struct Curl_easy *data,
uint8_t dns_queries,
- const char *hostname,
- uint16_t port,
+ struct Curl_peer *peer,
uint8_t transport,
bool for_proxy,
timediff_t timeout_ms,
@@ -852,7 +861,7 @@ static CURLcode resolv_alarm_timeout(struct Curl_easy *data,
volatile unsigned int prev_alarm = 0;
CURLcode result;
- DEBUGASSERT(hostname && *hostname);
+ DEBUGASSERT(peer->hostname && *peer->hostname);
DEBUGASSERT(timeout_ms > 0);
DEBUGASSERT(!data->set.no_signal);
#ifndef CURL_DISABLE_DOH
@@ -913,7 +922,7 @@ static CURLcode resolv_alarm_timeout(struct Curl_easy *data,
/* Perform the actual name resolution. This might be interrupted by an
* alarm if it takes too long. */
- result = hostip_resolv(data, dns_queries, hostname, port, transport,
+ result = hostip_resolv(data, dns_queries, peer, transport,
for_proxy, timeout_ms, FALSE, presolv_id, entry);
clean_up:
@@ -967,27 +976,26 @@ clean_up:
#ifdef USE_UNIX_SOCKETS
static CURLcode resolv_unix(struct Curl_easy *data,
- const char *unix_path,
- bool abstract_path,
+ struct Curl_peer *peer,
struct Curl_dns_entry **pdns)
{
struct Curl_addrinfo *addr;
CURLcode result;
- DEBUGASSERT(unix_path);
+ DEBUGASSERT(peer->unix_socket);
*pdns = NULL;
- result = Curl_unix2addr(unix_path, abstract_path, &addr);
+ result = Curl_unix2addr(peer->hostname, (bool)peer->abstract_uds, &addr);
if(result) {
if(result == CURLE_TOO_LARGE) {
/* Long paths are not supported for now */
- failf(data, "Unix socket path too long: '%s'", unix_path);
+ failf(data, "Unix socket path too long: '%s'", peer->hostname);
result = CURLE_COULDNT_RESOLVE_HOST;
}
return result;
}
- *pdns = Curl_dnsc_mk_addr(data, 0, &addr, NULL, 0);
+ *pdns = Curl_dnsc_mk_addr(data, 0, &addr, peer);
return *pdns ? CURLE_OK : CURLE_OUT_OF_MEMORY;
}
#endif /* USE_UNIX_SOCKETS */
@@ -1032,10 +1040,10 @@ CURLcode Curl_resolv(struct Curl_easy *data,
#ifdef USE_UNIX_SOCKETS
if((dns_queries & CURL_DNSQ_ADDR) && peer->unix_socket)
- return resolv_unix(data, peer->hostname, (bool)peer->abstract_uds, pdns);
+ return resolv_unix(data, peer, pdns);
#else
if(peer->unix_socket)
- return hostip_resolv_failed(data, peer->hostname, for_proxy);
+ return hostip_resolv_failed(data, peer, for_proxy);
#endif
#ifdef USE_ALARM_TIMEOUT
@@ -1045,10 +1053,8 @@ CURLcode Curl_resolv(struct Curl_easy *data,
timeout_ms = 0;
}
if(timeout_ms && !Curl_doh_wanted(data)) {
- return resolv_alarm_timeout(data, dns_queries,
- peer->hostname, peer->port,
- transport, for_proxy, timeout_ms,
- presolv_id, pdns);
+ return resolv_alarm_timeout(data, dns_queries, peer, transport,
+ for_proxy, timeout_ms, presolv_id, pdns);
}
}
#endif /* !USE_ALARM_TIMEOUT */
@@ -1058,9 +1064,8 @@ CURLcode Curl_resolv(struct Curl_easy *data,
infof(data, "timeout on name lookup is not supported");
#endif
- return hostip_resolv(data, dns_queries, peer->hostname, peer->port,
- transport, for_proxy, timeout_ms, TRUE, presolv_id,
- pdns);
+ return hostip_resolv(data, dns_queries, peer, transport,
+ for_proxy, timeout_ms, TRUE, presolv_id, pdns);
}
#ifdef USE_CURL_ASYNC
@@ -1087,11 +1092,10 @@ CURLcode Curl_resolv_take_result(struct Curl_easy *data, uint32_t resolv_id,
return CURLE_FAILED_INIT;
/* check if we have the name resolved by now (from someone else) */
- result = Curl_dnscache_get(data, async->dns_queries,
- async->hostname, async->port, pdns);
+ result = Curl_dnscache_get(data, async->dns_queries, async->peer, pdns);
if(*pdns) {
/* Tell a possibly async resolver we no longer need the results. */
- infof(data, "Hostname '%s' was found in DNS cache", async->hostname);
+ infof(data, "Hostname '%s' was found in DNS cache", async->peer->hostname);
Curl_async_shutdown(data, async);
return CURLE_OK;
}
@@ -1115,14 +1119,14 @@ CURLcode Curl_resolv_take_result(struct Curl_easy *data, uint32_t resolv_id,
nothing about the name and would poison the cache for every
transfer using it. */
if(async->negative_answer)
- Curl_dnscache_add_negative(data, async->dns_queries,
- async->hostname, async->port);
+ Curl_dnscache_add_negative(data, async->dns_queries, async->peer);
if(async->dns_queries & (CURL_DNSQ_A|CURL_DNSQ_AAAA))
- failf(data, "Could not resolve: %s:%u", async->hostname, async->port);
+ failf(data, "Could not resolve: %s:%u",
+ async->peer->hostname, async->peer->port);
}
else if(result) {
failf(data, "Error %d resolving %s:%u",
- (int)result, async->hostname, async->port);
+ (int)result, async->peer->hostname, async->peer->port);
}
return result;
}