diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c index 31912da400..a4a7464285 100644 --- a/lib/asyn-ares.c +++ b/lib/asyn-ares.c @@ -310,7 +310,7 @@ CURLcode Curl_async_take_result(struct Curl_easy *data, const char *msg = NULL; if(ares->ares_status != ARES_SUCCESS) msg = ares_strerror(ares->ares_status); - result = Curl_resolver_error(data, msg); + result = Curl_async_failed(data, async, msg); } CURL_TRC_DNS(data, "ares: is_resolved() result=%d, dns=%sfound", diff --git a/lib/asyn-base.c b/lib/asyn-base.c index 9e400a914b..62cb0effe4 100644 --- a/lib/asyn-base.c +++ b/lib/asyn-base.c @@ -242,4 +242,24 @@ void Curl_async_destroy(struct Curl_easy *data, } } +CURLcode Curl_async_failed(struct Curl_easy *data, + struct Curl_resolv_async *async, + const char *detail) +{ + const char *host_or_proxy = "host"; + CURLcode result = CURLE_COULDNT_RESOLVE_HOST; + +#ifndef CURL_DISABLE_PROXY + if(async->for_proxy) { + host_or_proxy = "proxy"; + result = CURLE_COULDNT_RESOLVE_PROXY; + } +#endif + + failf(data, "Could not resolve %s: %s%s%s%s", + host_or_proxy, async->hostname, + detail ? " (" : "", detail ? detail : "", detail ? ")" : ""); + return result; +} + #endif /* USE_CURL_ASYNC */ diff --git a/lib/asyn-thrdd.c b/lib/asyn-thrdd.c index ce61ed64b6..90f055c2a1 100644 --- a/lib/asyn-thrdd.c +++ b/lib/asyn-thrdd.c @@ -751,7 +751,7 @@ out: Curl_dns_entry_unlink(data, &dns); Curl_async_thrdd_shutdown(data, async); if(!result && !*pdns) - result = Curl_resolver_error(data, NULL); + result = Curl_async_failed(data, async, NULL); if(result && (result != CURLE_COULDNT_RESOLVE_HOST) && (result != CURLE_COULDNT_RESOLVE_PROXY)) { diff --git a/lib/asyn.h b/lib/asyn.h index 8c1bd8fd6b..ed50933654 100644 --- a/lib/asyn.h +++ b/lib/asyn.h @@ -248,6 +248,7 @@ struct Curl_resolv_async { uint8_t queries_ongoing; BIT(is_ipaddr); BIT(is_ipv4addr); + BIT(for_proxy); BIT(done); BIT(shutdown); char hostname[1]; @@ -264,6 +265,10 @@ void Curl_async_shutdown(struct Curl_easy *data, void Curl_async_destroy(struct Curl_easy *data, struct Curl_resolv_async *async); +CURLcode Curl_async_failed(struct Curl_easy *data, + struct Curl_resolv_async *async, + const char *detail); + #else /* !USE_CURL_ASYNC */ #define Curl_async_shutdown(x, y) Curl_nop_stmt #endif /* USE_CURL_ASYNC */ diff --git a/lib/cf-dns.c b/lib/cf-dns.c index 54ac0eebe8..e763b8ed38 100644 --- a/lib/cf-dns.c +++ b/lib/cf-dns.c @@ -46,6 +46,7 @@ struct cf_dns_ctx { BIT(announced); BIT(abstract_unix_socket); BIT(complete_resolve); + BIT(for_proxy); char hostname[1]; }; @@ -54,6 +55,7 @@ static struct cf_dns_ctx *cf_dns_ctx_create(struct Curl_easy *data, const char *hostname, uint16_t port, uint8_t transport, bool abstract_unix_socket, + bool for_proxy, bool complete_resolve, struct Curl_dns_entry *dns) { @@ -68,6 +70,7 @@ static struct cf_dns_ctx *cf_dns_ctx_create(struct Curl_easy *data, 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; @@ -196,7 +199,8 @@ static CURLcode cf_dns_start(struct Curl_cfilter *cf, #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); @@ -394,6 +398,7 @@ static CURLcode cf_dns_create(struct Curl_cfilter **pcf, uint16_t port, uint8_t transport, bool abstract_unix_socket, + bool for_proxy, bool complete_resolve, struct Curl_dns_entry *dns) { @@ -403,7 +408,8 @@ static CURLcode cf_dns_create(struct Curl_cfilter **pcf, (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; @@ -430,7 +436,7 @@ static CURLcode cf_dns_conn_create(struct Curl_cfilter **pcf, 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 { @@ -444,13 +450,12 @@ static CURLcode cf_dns_conn_create(struct Curl_cfilter **pcf, #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) { @@ -469,7 +474,8 @@ static CURLcode cf_dns_conn_create(struct Curl_cfilter **pcf, } 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. @@ -494,7 +500,7 @@ CURLcode Curl_cf_dns_add(struct Curl_easy *data, 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); @@ -526,7 +532,7 @@ CURLcode Curl_cf_dns_insert_after(struct Curl_cfilter *cf_at, result = cf_dns_create(&cf, data, dns_queries, hostname, port, transport, - FALSE, complete_resolve, NULL); + FALSE, FALSE, complete_resolve, NULL); if(result) return result; diff --git a/lib/cf-ip-happy.c b/lib/cf-ip-happy.c index 3064612d52..f67273e489 100644 --- a/lib/cf-ip-happy.c +++ b/lib/cf-ip-happy.c @@ -673,8 +673,7 @@ static CURLcode is_connected(struct Curl_cfilter *cf, if(!result) return CURLE_OK; - - { + else { const char *hostname, *proxy_name = NULL; char viamsg[160]; #ifndef CURL_DISABLE_PROXY @@ -712,14 +711,14 @@ static CURLcode is_connected(struct Curl_cfilter *cf, curlx_ptimediff_ms(Curl_pgrs_now(data), &data->progress.t_startsingle), curl_easy_strerror(result)); - } #ifdef SOCKETIMEDOUT - if(SOCKETIMEDOUT == data->state.os_errno) - result = CURLE_OPERATION_TIMEDOUT; + if(SOCKETIMEDOUT == data->state.os_errno) + result = CURLE_OPERATION_TIMEDOUT; #endif - return result; + return result; + } } #define IP_HE_MAX_CONCURRENT_ATTEMPTS 6 diff --git a/lib/connect.c b/lib/connect.c index 3ec404df87..3d1aec1f70 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -602,7 +602,7 @@ const char *Curl_conn_get_unix_path(struct connectdata *conn) const char *unix_path = conn->unix_domain_socket; #ifndef CURL_DISABLE_PROXY - if(!unix_path && CONN_IS_PROXIED(conn) && conn->socks_proxy.host.name && + if(!unix_path && conn->bits.proxy && conn->socks_proxy.host.name && !strncmp(UNIX_SOCKET_PREFIX "/", conn->socks_proxy.host.name, sizeof(UNIX_SOCKET_PREFIX))) unix_path = conn->socks_proxy.host.name + sizeof(UNIX_SOCKET_PREFIX) - 1; diff --git a/lib/doh.c b/lib/doh.c index a4340b1a2a..30441358ca 100644 --- a/lib/doh.c +++ b/lib/doh.c @@ -1230,8 +1230,8 @@ CURLcode Curl_doh_take_result(struct Curl_easy *data, if(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); - return CONN_IS_PROXIED(data->conn) ? CURLE_COULDNT_RESOLVE_PROXY : - CURLE_COULDNT_RESOLVE_HOST; + return async->for_proxy ? + CURLE_COULDNT_RESOLVE_PROXY : CURLE_COULDNT_RESOLVE_HOST; } else if(!dohp->pending) { DOHcode rc[DOH_SLOT_COUNT]; @@ -1301,8 +1301,8 @@ CURLcode Curl_doh_take_result(struct Curl_easy *data, *pdns = dns; } /* address processing done */ else { - result = CONN_IS_PROXIED(data->conn) ? CURLE_COULDNT_RESOLVE_PROXY : - CURLE_COULDNT_RESOLVE_HOST; + result = async->for_proxy ? + CURLE_COULDNT_RESOLVE_PROXY : CURLE_COULDNT_RESOLVE_HOST; } } /* !dohp->pending */ diff --git a/lib/hostip.c b/lib/hostip.c index e547a8e450..0eae6b9fb7 100644 --- a/lib/hostip.c +++ b/lib/hostip.c @@ -74,6 +74,12 @@ #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. */ @@ -339,6 +345,15 @@ static bool tailmatch(const char *full, size_t flen, 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) { @@ -368,11 +383,13 @@ CURLcode Curl_resolv_announce_start(struct Curl_easy *data, } #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; @@ -401,6 +418,7 @@ static struct Curl_resolv_async *hostip_async_new(struct Curl_easy *data, 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) { @@ -439,8 +457,7 @@ static CURLcode hostip_resolv_take_result(struct Curl_easy *data, 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", @@ -522,6 +539,7 @@ static CURLcode hostip_resolv_start(struct Curl_easy *data, const char *hostname, uint16_t port, uint8_t transport, + bool for_proxy, timediff_t timeout_ms, bool allowDOH, uint32_t *presolv_id, @@ -573,7 +591,7 @@ static CURLcode hostip_resolv_start(struct Curl_easy *data, 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; @@ -588,7 +606,7 @@ static CURLcode hostip_resolv_start(struct Curl_easy *data, /* 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; } @@ -596,7 +614,7 @@ static CURLcode hostip_resolv_start(struct Curl_easy *data, (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; @@ -617,7 +635,7 @@ static CURLcode hostip_resolv_start(struct Curl_easy *data, 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: @@ -657,13 +675,14 @@ static CURLcode hostip_resolv(struct Curl_easy *data, 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 */ @@ -690,7 +709,7 @@ static CURLcode hostip_resolv(struct Curl_easy *data, 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 @@ -702,21 +721,20 @@ static CURLcode hostip_resolv(struct Curl_easy *data, } 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); @@ -747,7 +765,7 @@ CURLcode Curl_resolv_blocking(struct Curl_easy *data, *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: @@ -786,6 +804,7 @@ static CURLcode resolv_alarm_timeout(struct Curl_easy *data, 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) @@ -865,7 +884,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, - timeout_ms, FALSE, presolv_id, entry); + for_proxy, timeout_ms, FALSE, presolv_id, entry); clean_up: if(!prev_alarm) @@ -934,14 +953,14 @@ clean_up: * 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) @@ -963,7 +982,7 @@ CURLcode Curl_resolv(struct Curl_easy *data, } 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 */ @@ -973,7 +992,7 @@ CURLcode Curl_resolv(struct Curl_easy *data, #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 @@ -1010,7 +1029,7 @@ CURLcode Curl_resolv_take_result(struct Curl_easy *data, uint32_t resolv_id, } 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); @@ -1021,8 +1040,7 @@ CURLcode Curl_resolv_take_result(struct Curl_easy *data, uint32_t resolv_id, 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); @@ -1085,31 +1103,6 @@ void Curl_resolv_destroy_all(struct Curl_easy *data) #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, diff --git a/lib/hostip.h b/lib/hostip.h index 368883b8e7..780fb4dc13 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -100,6 +100,7 @@ CURLcode Curl_resolv(struct Curl_easy *data, 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); @@ -170,8 +171,6 @@ bool Curl_resolv_knows_https(struct Curl_easy *data, uint32_t resolv_id); #define Curl_resolv_destroy(x, y) Curl_nop_stmt #endif /* USE_CURL_ASYNC */ -CURLcode Curl_resolver_error(struct Curl_easy *data, const char *detail); - #ifdef CURLRES_SYNCH /* * Curl_sync_getaddrinfo() is the non-async low-level name resolve API. diff --git a/lib/url.c b/lib/url.c index 61d29bdbd7..5fe68033d9 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1989,15 +1989,13 @@ static CURLcode parse_proxy(struct Curl_easy *data, goto error; } -#ifdef USE_SSL - if(!Curl_ssl_supports(data, SSLSUPP_HTTPS_PROXY)) -#endif - if(IS_HTTPS_PROXY(proxytype)) { - failf(data, "Unsupported proxy \'%s\', libcurl is built without the " - "HTTPS-proxy support.", proxy); - result = CURLE_NOT_BUILT_IN; - goto error; - } + if(IS_HTTPS_PROXY(proxytype) && + !Curl_ssl_supports(data, SSLSUPP_HTTPS_PROXY)) { + failf(data, "Unsupported proxy \'%s\', libcurl is built without the " + "HTTPS-proxy support.", proxy); + result = CURLE_NOT_BUILT_IN; + goto error; + } sockstype = proxytype == CURLPROXY_SOCKS5_HOSTNAME || diff --git a/lib/urldata.h b/lib/urldata.h index 70f70a7bc1..f35bfee053 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -240,12 +240,6 @@ typedef enum { GSS_AUTHSUCC } curlnegotiate; -#ifdef CURL_DISABLE_PROXY -#define CONN_IS_PROXIED(x) 0 -#else -#define CONN_IS_PROXIED(x) (x)->bits.proxy -#endif - /* * Boolean values that concerns this connection. */