async: DoH improvements

Adds a "meta_hash" to each easy handle for keeping special data during
operations. All meta data set needs to add its destructor callback, so
that meta data gets destroyed properly when the easy handle is cleaned
up or reset.

Add data->master_mid for "sub" transfers that belong to a "master" easy
handle. When a "sub" transfer is done, the corresponding "master" can
add a callback to be invoked. Used in DoH name resolution.

DoH: use easy meta hash to add internal structs for DoH name resolution.
One in each in each probe easy handle. When probes are done, response
data is copied from the probe to the initiating easy.

This allows DoH using transfers and their probes to be cleaned up in any
sequence correctly.

Fold DoH cleanup into the Curl_async_shutdown() and Curl_async_destroy()
functions.

Closes #16384
This commit is contained in:
Stefan Eissing 2025-04-16 13:45:53 +02:00 committed by Daniel Stenberg
parent 8478365e29
commit 1ebd92d0fd
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
14 changed files with 357 additions and 138 deletions

View file

@ -727,6 +727,7 @@ CURLMcode curl_multi_remove_handle(CURLM *m, CURL *d)
data->multi = NULL; /* clear the association to this multi handle */
data->mid = -1;
data->master_mid = -1;
/* NOTE NOTE NOTE
We do not touch the easy handle here! */
@ -2507,9 +2508,24 @@ statemachine_end:
}
if(MSTATE_COMPLETED == data->mstate) {
if(data->set.fmultidone) {
/* signal via callback instead */
data->set.fmultidone(data, result);
if(data->master_mid >= 0) {
/* A sub transfer, not for msgsent to application */
struct Curl_easy *mdata;
CURL_TRC_M(data, "sub xfer done for master %" FMT_OFF_T,
data->master_mid);
mdata = Curl_multi_get_handle(multi, data->master_mid);
if(mdata) {
if(mdata->sub_xfer_done)
mdata->sub_xfer_done(mdata, data, result);
else
CURL_TRC_M(data, "master easy %" FMT_OFF_T
" without sub_xfer_done.", data->master_mid);
}
else {
CURL_TRC_M(data, "master easy %" FMT_OFF_T " already gone.",
data->master_mid);
}
}
else {
/* now fill in the Curl_message with this info */