async-thrdd: use thread queue for resolving

Use a thread queue and pool for asnyc threaded DNS resolves.
Add pytest test_21_* for verification.

Add `CURLMOPT_RESOLVE_THREADS_MAX` to allow applications to
resize the thread pool used.

Add `CURLMOPT_QUICK_EXIT` to allow applications to skip thread
joins when cleaning up a multi handle. Multi handles in
`curl_easy_perform()` inherit this from `CURLOPT_QUICK_EXIT`.

Add several debug environment variables for testing.

Closes #20936
This commit is contained in:
Stefan Eissing 2026-03-24 12:50:53 +01:00 committed by Daniel Stenberg
parent 507e7be573
commit 39036c9021
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
31 changed files with 998 additions and 614 deletions

View file

@ -530,7 +530,8 @@ CURLcode Curl_parse_interface(const char *input,
#ifndef CURL_DISABLE_BINDLOCAL
static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
curl_socket_t sockfd, int af, unsigned int scope)
curl_socket_t sockfd, int af, unsigned int scope,
uint8_t transport)
{
struct Curl_sockaddr_storage sa;
struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */
@ -648,7 +649,7 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
ip_version = CURL_IPRESOLVE_V6;
#endif
(void)Curl_resolv_blocking(data, host, 80, ip_version, &h);
(void)Curl_resolv_blocking(data, host, 80, ip_version, transport, &h);
if(h) {
int h_af = h->addr->ai_family;
/* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */
@ -1143,7 +1144,8 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
#endif
) {
result = bindlocal(data, cf->conn, ctx->sock, ctx->addr.family,
Curl_ipv6_scope(&ctx->addr.curl_sa_addr));
Curl_ipv6_scope(&ctx->addr.curl_sa_addr),
ctx->transport);
if(result) {
if(result == CURLE_UNSUPPORTED_PROTOCOL) {
/* The address family is not supported on this interface.