ares: destroy channel on shutdown

When we cancel async resolv operations, we have kept an existing ares
channel open. This seems unreliable as reported in #18216.

To get reliable behaviour, always destroy the ares channel on async
shutdown and create a new one on demand.

Fixes #18216
Reported-by: devgs on github
Closes #18217
This commit is contained in:
Stefan Eissing 2025-08-07 10:32:14 +02:00 committed by Daniel Stenberg
parent 3b40128b0f
commit c1372df2e2
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2

View file

@ -237,26 +237,6 @@ CURLcode Curl_async_get_impl(struct Curl_easy *data, void **impl)
return result;
}
static void async_ares_cleanup(struct Curl_easy *data);
void Curl_async_ares_shutdown(struct Curl_easy *data)
{
struct async_ares_ctx *ares = &data->state.async.ares;
if(ares->channel)
ares_cancel(ares->channel);
async_ares_cleanup(data);
}
void Curl_async_ares_destroy(struct Curl_easy *data)
{
struct async_ares_ctx *ares = &data->state.async.ares;
Curl_async_ares_shutdown(data);
if(ares->channel) {
ares_destroy(ares->channel);
ares->channel = NULL;
}
}
/*
* async_ares_cleanup() cleans up async resolver data.
*/
@ -272,6 +252,26 @@ static void async_ares_cleanup(struct Curl_easy *data)
#endif
}
void Curl_async_ares_shutdown(struct Curl_easy *data)
{
/* c-ares has a method to "cancel" operations on a channel, but
* as reported in #18216, this does not totally reset the channel
* and ares may get stuck.
* We need to destroy the channel and on demand create a new
* one to avoid that. */
Curl_async_ares_destroy(data);
}
void Curl_async_ares_destroy(struct Curl_easy *data)
{
struct async_ares_ctx *ares = &data->state.async.ares;
if(ares->channel) {
ares_destroy(ares->channel);
ares->channel = NULL;
}
async_ares_cleanup(data);
}
/*
* Curl_async_pollset() is called when someone from the outside world
* (using curl_multi_fdset()) wants to get our fd_set setup.