BIT(announced);
BIT(abstract_unix_socket);
BIT(complete_resolve);
+ BIT(for_proxy);
char hostname[1];
};
const char *hostname,
uint16_t port, uint8_t transport,
bool abstract_unix_socket,
+ bool for_proxy,
bool complete_resolve,
struct Curl_dns_entry *dns)
{
ctx->dns_queries = dns_queries;
ctx->transport = transport;
ctx->abstract_unix_socket = abstract_unix_socket;
+ ctx->for_proxy = for_proxy;
ctx->complete_resolve = complete_resolve;
ctx->dns = Curl_dns_entry_link(data, dns);
ctx->started = !!ctx->dns;
#endif
result = Curl_resolv(data, ctx->dns_queries,
ctx->hostname, ctx->port, ctx->transport,
- timeout_ms, &ctx->resolv_id, pdns);
+ (bool)ctx->for_proxy, timeout_ms,
+ &ctx->resolv_id, pdns);
DEBUGASSERT(!result || !*pdns);
if(!result) { /* resolved right away, either sync or from dnscache */
DEBUGASSERT(*pdns);
uint16_t port,
uint8_t transport,
bool abstract_unix_socket,
+ bool for_proxy,
bool complete_resolve,
struct Curl_dns_entry *dns)
{
(void)data;
ctx = cf_dns_ctx_create(data, dns_queries, hostname, port, transport,
- abstract_unix_socket, complete_resolve, dns);
+ abstract_unix_socket, for_proxy,
+ complete_resolve, dns);
if(!ctx) {
result = CURLE_OUT_OF_MEMORY;
goto out;
struct connectdata *conn = data->conn;
const char *hostname = NULL;
uint16_t port = 0;
- bool abstract_unix_socket = FALSE;
+ bool abstract_unix_socket = FALSE, for_proxy = FALSE;
#ifdef USE_UNIX_SOCKETS
{
#endif
#ifndef CURL_DISABLE_PROXY
- if(!hostname && CONN_IS_PROXIED(conn)) {
- struct hostname *ehost;
- ehost = conn->bits.socksproxy ? &conn->socks_proxy.host :
- &conn->http_proxy.host;
- hostname = ehost->name;
- port = conn->bits.socksproxy ? conn->socks_proxy.port :
- conn->http_proxy.port;
+ if(!hostname && conn->bits.proxy) {
+ for_proxy = TRUE;
+ hostname = conn->bits.socksproxy ?
+ conn->socks_proxy.host.name : conn->http_proxy.host.name;
+ port = conn->bits.socksproxy ?
+ conn->socks_proxy.port : conn->http_proxy.port;
}
#endif
if(!hostname) {
}
return cf_dns_create(pcf, data, dns_queries,
hostname, port, transport,
- abstract_unix_socket, complete_resolve, dns);
+ abstract_unix_socket, for_proxy,
+ complete_resolve, dns);
}
/* Adds a "resolv" filter at the top of the connection's filter chain.
else if(dns) {
result = cf_dns_create(&cf, data, dns_queries,
dns->hostname, dns->port, transport,
- FALSE, FALSE, dns);
+ FALSE, FALSE, FALSE, dns);
}
else {
DEBUGASSERT(0);
result = cf_dns_create(&cf, data, dns_queries,
hostname, port, transport,
- FALSE, complete_resolve, NULL);
+ FALSE, FALSE, complete_resolve, NULL);
if(result)
return result;
#define MAX_DNS_CACHE_SIZE 29999
+#define RESOLV_FAIL(for_proxy) \
+ ((for_proxy) ? CURLE_COULDNT_RESOLVE_PROXY : CURLE_COULDNT_RESOLVE_HOST)
+
+#define IS_RESOLV_FAIL(result) \
+ (((result) == CURLE_COULDNT_RESOLVE_HOST) || \
+ ((result) == CURLE_COULDNT_RESOLVE_PROXY))
/*
* ipv6works() returns TRUE if IPv6 seems to work.
*/
return curl_strnequal(part, &full[flen - plen], plen);
}
+static CURLcode hostip_resolv_failed(struct Curl_easy *data,
+ const char *hostname,
+ bool for_proxy)
+{
+ failf(data, "Could not resolve %s: %s",
+ for_proxy ? "proxy" : "host", hostname);
+ return RESOLV_FAIL(for_proxy);
+}
+
static bool can_resolve_dns_queries(struct Curl_easy *data,
uint8_t dns_queries)
{
}
#ifdef USE_CURL_ASYNC
+
static struct Curl_resolv_async *hostip_async_new(struct Curl_easy *data,
uint8_t dns_queries,
const char *hostname,
uint16_t port,
uint8_t transport,
+ bool for_proxy,
timediff_t timeout_ms)
{
struct Curl_resolv_async *async;
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) {
result = CURLE_OK;
}
else if(result) {
- CURL_TRC_DNS(data, "result error %d", result);
- Curl_resolver_error(data, NULL);
+ result = Curl_async_failed(data, async, NULL);
}
else {
CURL_TRC_DNS(data, "resolve complete for %s:%u",
const char *hostname,
uint16_t port,
uint8_t transport,
+ bool for_proxy,
timediff_t timeout_ms,
bool allowDOH,
uint32_t *presolv_id,
goto out;
if(!async) {
async = hostip_async_new(data, dns_queries, hostname, port,
- transport, timeout_ms);
+ transport, for_proxy, timeout_ms);
if(!async) {
result = CURLE_OUT_OF_MEMORY;
goto out;
/* Can we provide the requested IP specifics in resolving? */
if(!can_resolve_dns_queries(data, dns_queries)) {
- result = CURLE_COULDNT_RESOLVE_HOST;
+ result = RESOLV_FAIL(for_proxy);
goto out;
}
(void)addr;
if(!async) {
async = hostip_async_new(data, dns_queries, hostname, port,
- transport, timeout_ms);
+ transport, for_proxy, timeout_ms);
if(!async) {
result = CURLE_OUT_OF_MEMORY;
goto out;
goto out;
addr = Curl_sync_getaddrinfo(data, dns_queries, hostname, port, transport);
if(!addr)
- result = CURLE_COULDNT_RESOLVE_HOST;
+ result = RESOLV_FAIL(for_proxy);
#endif
out:
const char *hostname,
uint16_t port,
uint8_t transport,
+ bool for_proxy,
timediff_t timeout_ms,
bool allowDOH,
uint32_t *presolv_id,
struct Curl_dns_entry **pdns)
{
size_t hostname_len;
- CURLcode result = CURLE_COULDNT_RESOLVE_HOST;
+ CURLcode result = RESOLV_FAIL(for_proxy);
bool cache_dns = FALSE;
(void)timeout_ms; /* not used in all ifdefs */
if((CURL_DNSQ_IP(dns_queries) == CURL_DNSQ_AAAA) &&
getenv("CURL_DBG_RESOLV_FAIL_IPV6")) {
infof(data, "DEBUG fail ipv6 resolve");
- result = Curl_resolver_error(data, NULL);
+ result = hostip_resolv_failed(data, hostname, for_proxy);
goto out;
}
#endif
}
else if(result) {
infof(data, "Negative DNS entry");
- result = Curl_resolver_error(data, NULL);
+ result = hostip_resolv_failed(data, hostname, for_proxy);
}
else {
/* No luck, we need to start resolving. */
cache_dns = TRUE;
result = hostip_resolv_start(data, dns_queries, hostname, port,
- transport, timeout_ms, allowDOH,
+ transport, for_proxy, timeout_ms, allowDOH,
presolv_id, pdns);
}
out:
if(result && (result != CURLE_AGAIN)) {
Curl_dns_entry_unlink(data, pdns);
- if((result == CURLE_COULDNT_RESOLVE_HOST) ||
- (result == CURLE_COULDNT_RESOLVE_PROXY)) {
+ if(IS_RESOLV_FAIL(result)) {
if(cache_dns)
Curl_dnscache_add_negative(data, dns_queries, hostname, port);
failf(data, "Could not resolve: %s:%u", hostname, port);
*pdns = NULL;
/* We cannot do a blocking resolve using DoH currently */
result = hostip_resolv(data, dns_queries,
- hostname, port, transport, 0, FALSE,
+ hostname, port, transport, FALSE, 0, FALSE,
&resolv_id, pdns);
switch(result) {
case CURLE_OK:
const char *hostname,
uint16_t port,
uint8_t transport,
+ bool for_proxy,
timediff_t timeout_ms,
uint32_t *presolv_id,
struct Curl_dns_entry **entry)
/* 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,
- timeout_ms, FALSE, presolv_id, entry);
+ for_proxy, timeout_ms, FALSE, presolv_id, entry);
clean_up:
if(!prev_alarm)
* Return codes:
* CURLE_OK = success, *pdns set to non-NULL
* CURLE_AGAIN = resolving in progress, *pdns == NULL
- * CURLE_COULDNT_RESOLVE_HOST = error, *pdns == NULL
- * CURLE_OPERATION_TIMEDOUT = timeout expired, *pdns == NULL
+ * any other CURLcode error, *pdns == NULL
*/
CURLcode Curl_resolv(struct Curl_easy *data,
uint8_t dns_queries,
const char *hostname,
uint16_t port,
uint8_t transport,
+ bool for_proxy,
timediff_t timeout_ms,
uint32_t *presolv_id,
struct Curl_dns_entry **pdns)
}
if(timeout_ms && !Curl_doh_wanted(data)) {
return resolv_alarm_timeout(data, dns_queries, hostname, port, transport,
- timeout_ms, presolv_id, pdns);
+ for_proxy, timeout_ms, presolv_id, pdns);
}
#endif /* !USE_ALARM_TIMEOUT */
#endif
return hostip_resolv(data, dns_queries, hostname, port, transport,
- timeout_ms, TRUE, presolv_id, pdns);
+ for_proxy, timeout_ms, TRUE, presolv_id, pdns);
}
#ifdef USE_CURL_ASYNC
}
else if(result) {
Curl_async_shutdown(data, async);
- return Curl_resolver_error(data, NULL);
+ return Curl_async_failed(data, async, NULL);
}
result = hostip_resolv_take_result(data, async, pdns);
if(result)
Curl_dns_entry_unlink(data, pdns);
}
- else if((result == CURLE_COULDNT_RESOLVE_HOST) ||
- (result == CURLE_COULDNT_RESOLVE_PROXY)) {
+ else if(IS_RESOLV_FAIL(result)) {
Curl_dnscache_add_negative(data, async->dns_queries,
async->hostname, async->port);
failf(data, "Could not resolve: %s:%u", async->hostname, async->port);
#endif /* USE_CURL_ASYNC */
-/*
- * Curl_resolver_error() calls failf() with the appropriate message after a
- * resolve error
- */
-CURLcode Curl_resolver_error(struct Curl_easy *data, const char *detail)
-{
- struct connectdata *conn = data->conn;
- const char *host_or_proxy = "host";
- const char *name = conn->host.dispname;
- CURLcode result = CURLE_COULDNT_RESOLVE_HOST;
-
-#ifndef CURL_DISABLE_PROXY
- if(conn->bits.proxy) {
- host_or_proxy = "proxy";
- result = CURLE_COULDNT_RESOLVE_PROXY;
- name = conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
- conn->http_proxy.host.dispname;
- }
-#endif
-
- failf(data, "Could not resolve %s: %s%s%s%s", host_or_proxy, name,
- detail ? " (" : "", detail ? detail : "", detail ? ")" : "");
- return result;
-}
-
#ifdef USE_UNIX_SOCKETS
CURLcode Curl_resolv_unix(struct Curl_easy *data,
const char *unix_path,