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
SOCKS problem with 8.7.0+ #13455
Comments
No, there is no such thing. That's a wild guess that cannot be correct. Also, I could reproduce this problem even with all the curl_multi_remove_handle() and curl_easy_cleanup() calls removed from the reproducer code. In my testing in reproducing this issue, doing SOCKS5 seems shaky in 8.6.0 as well, compared to not using the proxy. Thus, I don't think 8.6.0 had this working correctly either, only that perhaps 8.7.x made it more visible. I have not yet figured out what the problem is. The symptom is timed out transfers that otherwise would not timeout. |
I'm glad you reproduced the problem. Some additional notes: |
I suspect I don't reproduce the problem you report. If you can see the same problem with HTTPS proxy, then you see something completely different. They use very different code paths. Can you clarify exactly how the transfers fail? Does transfer 2-6 always fail once the first one is completed? I figured out the reason why some of my proxy connections timed out: But when connecting directly to a host, without a proxy, curl does happy eyeballs which tries both IPv6 and IPv4 and thus the failed IPv6 attempt is not visible. |
Test results, there will be 10-20% normal downloads. Problematic tests, 80% are 5 remaining tasks caught in a loop. Other times, sometimes it's 2 caught in a loop, sometimes it's 3... |
I found a way to download 100% properly. Task-1, even if it downloads the allocated data size, it doesn't disconnect and still downloads all the data. The other tasks then don't get stuck in a loop. That means the code that triggers this is, task-1 |
Come again? What do you mean that you do or don't do with the first transfer? |
According to the example of 10-at-a-time.html, if you use 6 chunks to download, the main thread needs to create these 6 tasks at once after getting the "content-length" (assuming the file size is 6): task-1 Range=bytes=0-1 Note that here task-1 has a normal task size. The way I used it, I skipped the process of getting the "content-length" in the main thread, and created only one task, with "Range=bytes=0-" set in task-1. task-1 headerfunction => get content-length loop 5 This means that task-1 will download all the data (6) and I have to actively terminate it after it finishes downloading the specified content write_callback_function(){ And I found that task-1 write_callback_function() return 0 causes the other 5 tasks to get stuck in a loop. So the way to download 100% normally is to not actively end it and let task-1 download all the data (6). |
10-at-a-time.c is a single-threaded example, so referring to its thread as "the main thread" is a bit incongruous since there is no other thread. It sounds like you've converted that example into a multithreaded program. Improper use of multithreading in libcurl is a frequent source of problems. Did you abide by everything in https://curl.se/libcurl/c/threadsafe.html when you converted the example? |
It was my poor choice of words. I'm not using multithreading. You can interpret the improper "threads" here as: |
Are you abiding by the restrictions in what libcurl functions are allowed to be called within libcurl callbacks?
|
I can't understand what "limitations" you're talking about, but I'm not operating the curl api in write_callback_function() other than using RtlMoveMemory() to read the data. Regarding task-1's header_callback_function, it also doesn't manipulate the curl api, it just creates 5 task objects with task information. In the multi loop{}, these objects are added to multi, consistent with '10-at-a-time.c'. |
I'm just guessing at what your program does. If you posted the code, it would
help inform whether there is a problem in it.
|
Unless someone explicitly says they need the AutoHotkey code, I can't provide it. |
I've summarized the current problem as follows: |
I think maybe the odd terms in use makes it hard to speak the same language. curl performs transfers. You can do multiple transfers with it. They are not multi-tasking. By your description it sounds as if you add new transfers from within a callback, which sounds odd. libcurl tries to forbid that. So are you? And again: you say repeatedly that "the other transfers fail", but I want to know more specifically and exactly how they fail. Details! You say you do six transfers. Can you describe exactly what each transfer does? |
I searched all my statements and did not find the word "transfers". If you look carefully, you will find it: |
I don't know C at all, but I modified 10-at-a-time.c as a schematic. If you're still confused, close this issue, it's not worth the effort.
|
That's exactly the problem: you refer to them as tasks but they are not tasks. They are transfers. Your code refers to a |
AutoHotkey can attach data when creating callbacks." The "this" variable is just to record the task_size and nothing else. Like this new example
|
I'm sorry but none of this brings me any closer to understanding the issue. I don't understand your program. I don't even know how the transfers fail. I can't reproduce the problem. |
Ok, thanks for the reply. I'm sure you didn't forget to use the SOCKS5 proxy in your test and you must have triggered the "return 0" in your test. I don't have any more information to provide, so it looks like I'm giving meaningless issues, so please ignore the problem. |
I did this
When 8.7.0 was released, I noticed that my script for updating mpv's was failing. It uses curl_multi and downloads the mpv.zip file in 6 chunks. It seems that some EASY task is stuck in an infinite loop. The script had been working fine for years before.
I didn't have the energy to find out why at the time, so I fell back to 8.6.0.
When 8.7.1 was released I tested it again and still had the problem.
Until now, I tried to find out why.
First of all it should be noted that I am not a programmer, I just use AutoHotkey to call libcurl.dll. I tested libcurl.dll from two sources
https://curl.se/windows/
https://community.chocolatey.org/packages/curl
I tested still chunked downloads and the script was modified from this example:
https://curl.se/libcurl/c/10-at-a-time.html
I can only access the Internets properly with a vps.
I have to set the proxy to socks5://127.0.0.1:5000 to access google.
Test file:
https://dl.google.com/drive-file-stream/GoogleDriveSetup.exe
8.7.1 - Test results for libcurl.dll:
Using curl_easy can download normally.
Using curl_multi * 6-split the above problem occurs.
I changed the download file to an address that I can download normally, but still using socks5://127.0.0.1:5000
Using curl_easy downloads fine.
Using curl_multi * 6-split downloads fine.
The conclusion I've come to is that after one of curl_multi's sub-easy tasks finishes, calling curl_multi_remove_handle() or curl_easy_cleanup() destroys the proxy settings of the other sub-easy tasks that are still running. So google files that must be downloaded using a proxy are constantly trying to download. These 6 EASY, except for the different Range-bytes data, have exactly the same mission information. This may also be the reason why one mission ends and the agents for the other missions are corrupted. I used curl_easy_getinfo(CURLINFO_USED_PROXY ) to look at the tasks with broken proxies, and the returned value is still 1.
And files that can be downloaded normally have no effect (or even finish downloading faster) when the proxy is disabled
Unless the developer has such a complex network environment, this problem is hard to detect.
Of course, I'm not sure if it's some new update feature I'm missing, but I double checked the changelog and couldn't find anything about it.
I expected the following
Consistent with the behavior of 8.6.
curl/libcurl version
8.7.0+
operating system
win-10 64bit
The text was updated successfully, but these errors were encountered: