From: Stefan Eissing Date: Thu, 7 Aug 2025 08:32:14 +0000 (+0200) Subject: ares: destroy channel on shutdown X-Git-Tag: curl-8_16_0~221 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c1372df2e2fa93d4435aeb50d068643b53194000;p=thirdparty%2Fcurl.git 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 --- diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c index 375f1a6eb6..815d7ab57f 100644 --- a/lib/asyn-ares.c +++ b/lib/asyn-ares.c @@ -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.