-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DOH] Since v8.5.0, a change in API behavior causes curl_multi_poll() or curl_multi_perform() to return error code #14414
Comments
Instead of trying to figure out what your code actually does, I decided to write a (simpler) version in plain C and it just works. Any idea what differences there are between them? #include <stdio.h>
#include <string.h>
/* curl stuff */
#include <curl/curl.h>
/*
* Simply download an HTTP file.
*/
int main(void)
{
CURL *http_handle;
CURLM *multi_handle;
int still_running = 1; /* keep number of running handles */
curl_global_init(CURL_GLOBAL_DEFAULT);
http_handle = curl_easy_init();
curl_easy_setopt(http_handle, CURLOPT_URL, "https://httpbin.org/delay/5");
curl_easy_setopt(http_handle, CURLOPT_DOH_URL, "https://1.1.1.1/dns-query");
/* init a multi stack */
multi_handle = curl_multi_init();
/* add the individual transfers */
curl_multi_add_handle(multi_handle, http_handle);
do {
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
if(!mc)
/* wait for activity, timeout or "nothing" */
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
if(mc) {
fprintf(stderr, "curl_multi_poll() failed, code %d.\n", (int)mc);
break;
}
} while(still_running);
curl_multi_remove_handle(multi_handle, http_handle);
curl_easy_cleanup(http_handle);
curl_multi_cleanup(multi_handle);
curl_global_cleanup();
return 0;
} |
@bagder Thank you for your response and for taking the time to write sample code. I would like to share more test results. This issue only occurs when DOH is enabled and curl_multi_remove_handle() is called to remove handles during the execution of curl. This problem started appearing from version v8.5.0. The test program is simplified from the product code (which works with versions v7.68.0 to v8.4.0). It primarily implements two features: setting up DOH and canceling requests.
Based on the program run and version test results, I speculate that this is likely related to some changes in DoH in v8.5.0. I hope the information provided will be helpful. |
I did some fixes in regard to DoH handle cleanup in #14212. Maybe there is more lurking? |
The commit should be in 8.9.1. Maybe there is a code path that it has not covered? The error indicates that there is an easy handle found that is no longer valid, e.g. was released. The question is what kind of handle it is. If you build libcurl yourself, maybe you could extend the GOOD_EASY_HANDLE check to give some more information if the memory had not been overwritten yet. |
I enabled both File:
Please note the different test results for the different versions.
|
So, my current thinking is that you app does abort transfers which have DoH request ongoing and the cleanup of those is not handled properly:
Sounds reasonable? |
@icing I think your reasoning makes sense. This issue only happens when canceling an ongoing DoH request. |
@luozhaohui thanks for your patience. I made #14499 to manage the dependencies between a transfer and its DoH requests better. I am not sure this will fix the issue you observer, but I would be interested if this changes anything in your setup. |
I am very happy to hear that! |
`data->id` is unique in *most* situations, but not in all. If a libcurl application uses more than one connection cache, they will overlap. This is a rare situations, but libcurl apps do crazy things. However, for informative things, like tracing, `data->id` is superior, since it assigns new ids in curl's serial curl_easy_perform() use. Introduce `data->mid` which is a unique identifer inside one multi instance, assigned on multi_add_handle() and cleared on multi_remove_handle(). Use the `mid` in DoH operations and also in h2/h3 stream hashes. Reported-by: 罗朝辉 Fixes #14414 Closes #14499
I did this
Note
I'm not entirely sure if this is a bug or an improvement. However, since curl_multi_poll() returns error code 12: Unrecoverable error in select/poll work thread exiting, I can't determine if cURL's internal state is valid and if it should continue working. Therefore, I'm reporting this as an issue for now.
If this isn't a bug, could you please advise on how to proceed when curl_multi_poll() returns error code 12? Thank you very much.
Test Program
I expected the following
Below are test reports using different versions of curl.
v8.3.0 & v8.4.0(EXPECTED)
This is the
expected
test result.v8.5.0 & v8.6.0 &v8.7.1(NOT EXPECTED)
This is
NOT
the expected test result.v8.8.0 & v8.9.1(NOT EXPECTED)
This is
NOT
the expected test result.curl/libcurl version
operating system
Darwin Kernel Version 23.3.0: Wed Dec 20 21:28:58 PST 2023; root:xnu-10002.81.5~7/RELEASE_X86_64 x86_64
The text was updated successfully, but these errors were encountered: