mirror of
https://github.com/curl/curl.git
synced 2024-11-27 05:50:21 +08:00
doh: fix cleanup
When removing an easy handle that had DoH sub-easy handles going, those were not removed from the multi handle. Their memory was reclaimed on curl_easy_cleanup() of the owning handle, but multi still had them in their list. Add `Curl_doh_close()` and `Curl_doh_cleanup()` as common point for handling the DoH resource management. Use the `multi` present in the doh handles (if so), for removal, as the `data->multi` might already have been NULLed at this time. Reported-by: 罗朝辉 Fixes #14207 Closes #14212
This commit is contained in:
parent
5eba0a4b37
commit
d8696dc8c0
42
lib/doh.c
42
lib/doh.c
@ -400,7 +400,6 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
|
||||
int *waitp)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
int slot;
|
||||
struct dohdata *dohp;
|
||||
struct connectdata *conn = data->conn;
|
||||
#ifdef USE_HTTPSRR
|
||||
@ -484,13 +483,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
|
||||
return NULL;
|
||||
|
||||
error:
|
||||
curl_slist_free_all(dohp->headers);
|
||||
data->req.doh->headers = NULL;
|
||||
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
||||
(void)curl_multi_remove_handle(data->multi, dohp->probe[slot].easy);
|
||||
Curl_close(&dohp->probe[slot].easy);
|
||||
}
|
||||
Curl_safefree(data->req.doh);
|
||||
Curl_doh_cleanup(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1325,10 +1318,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
struct dohentry de;
|
||||
int slot;
|
||||
/* remove DoH handles from multi handle and close them */
|
||||
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
||||
curl_multi_remove_handle(data->multi, dohp->probe[slot].easy);
|
||||
Curl_close(&dohp->probe[slot].easy);
|
||||
}
|
||||
Curl_doh_close(data);
|
||||
/* parse the responses, create the struct and return it! */
|
||||
de_init(&de);
|
||||
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
||||
@ -1415,4 +1405,32 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_doh_close(struct Curl_easy *data)
|
||||
{
|
||||
struct dohdata *doh = data->req.doh;
|
||||
if(doh) {
|
||||
size_t slot;
|
||||
for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
|
||||
if(!doh->probe[slot].easy)
|
||||
continue;
|
||||
/* data->multi might already be reset at this time */
|
||||
if(doh->probe[slot].easy->multi)
|
||||
curl_multi_remove_handle(doh->probe[slot].easy->multi,
|
||||
doh->probe[slot].easy);
|
||||
Curl_close(&doh->probe[slot].easy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_doh_cleanup(struct Curl_easy *data)
|
||||
{
|
||||
struct dohdata *doh = data->req.doh;
|
||||
if(doh) {
|
||||
Curl_doh_close(data);
|
||||
curl_slist_free_all(doh->headers);
|
||||
data->req.doh->headers = NULL;
|
||||
Curl_safefree(data->req.doh);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_DOH */
|
||||
|
@ -140,6 +140,8 @@ struct dohentry {
|
||||
#endif
|
||||
};
|
||||
|
||||
void Curl_doh_close(struct Curl_easy *data);
|
||||
void Curl_doh_cleanup(struct Curl_easy *data);
|
||||
|
||||
#ifdef UNITTESTS
|
||||
UNITTEST DOHcode doh_encode(const char *host,
|
||||
|
@ -2799,6 +2799,9 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
|
||||
/* First remove all remaining easy handles */
|
||||
data = multi->easyp;
|
||||
while(data) {
|
||||
if(!GOOD_EASY_HANDLE(data))
|
||||
return CURLM_BAD_HANDLE;
|
||||
|
||||
nextdata = data->next;
|
||||
if(!data->state.done && data->conn)
|
||||
/* if DONE was never called for this handle */
|
||||
|
@ -116,10 +116,7 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data)
|
||||
Curl_bufq_reset(&req->sendbuf);
|
||||
|
||||
#ifndef CURL_DISABLE_DOH
|
||||
if(req->doh) {
|
||||
Curl_close(&req->doh->probe[0].easy);
|
||||
Curl_close(&req->doh->probe[1].easy);
|
||||
}
|
||||
Curl_doh_close(data);
|
||||
#endif
|
||||
/* Can no longer memset() this struct as we need to keep some state */
|
||||
req->size = -1;
|
||||
@ -173,14 +170,7 @@ void Curl_req_free(struct SingleRequest *req, struct Curl_easy *data)
|
||||
Curl_client_cleanup(data);
|
||||
|
||||
#ifndef CURL_DISABLE_DOH
|
||||
if(req->doh) {
|
||||
Curl_close(&req->doh->probe[0].easy);
|
||||
Curl_close(&req->doh->probe[1].easy);
|
||||
Curl_dyn_free(&req->doh->probe[0].serverdoh);
|
||||
Curl_dyn_free(&req->doh->probe[1].serverdoh);
|
||||
curl_slist_free_all(req->doh->headers);
|
||||
Curl_safefree(req->doh);
|
||||
}
|
||||
Curl_doh_cleanup(data);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user