> I guess this refers to the changing of Curl_ipv6works() to store the state in > the multi handle as compared to the previous take where the state was stored > globally. Done in 0b030a5b232bd9fc, shipped since 7.69.0.
When the state was stored globally, there were other quite serious issues with that approach. 1. There were multithreading issues. 2. In some setups on embedded systems, the Curl_ipv6works() might be called too early as part of curl_global_init, when some system network parameters were set later, and falsely report that IPv6 doesn't work. I observed this behavior on my systems, and it was a pain to work around. So, I think that it was the right decision to move the "IPv6 check"as part of the multi handle initialization. > I'm betting that this problem can be fixed without adding a new callback, > especially one that goes against the way libcurl works, namely that callbacks > are used to change behaviour during a transfer. 1. How? We can't just modify the Curl_ipv6works() to work equally good with ALL possible kernels and network configuration scenarios. 2. There are "transfer" callbacks (the ones that you are referring) which change transfer behavior, but there are "system" callbacks (like memory management functions) which change system behavior. I propose to add one "system" callback in addition to memory management ones - so it is not " against the way libcurl works ". > > Since you're calling it a regression, then where did that regression > occur? I think I explained it several times already but let me try again. Regression happens when curl application code is migrated from IPv4-only libcurl to dual-stack libcurl. For some kernel configurations and network conditions connection establishment for cases when IPv6 doesn't work in dual-stack libcurl may take ~30ms more. It occurred for all resolve modes: IPv4, IPv6 and AUTO. Daniel's PR fixed it for IPv4 mode, for all the other modes the problem remains because Curl_ipv6works() is still called for these cases. In other words, if IPv6 doesn't work then the AUTO mode in dual-stack libcurl may have a connection delay caused by Curl_ipv6works() vs the AUTO mode in single-stack libcurl. > Was it in libcurl or in the kernel? Maybe this problem needs to > be solved elsewhere. It is a regression in libcurl (dual-stack vs single stack) because there is no obligation for kernels to fail IPv6 socket creation calls immediately with 0ms delay when they have some problems with IPv6. And even if there was such obligation, there can be bugs in kernel code, which curl application developer just has no way to fix. > An application that can "just use an atomic variable" can also "just set an > easy option" and get the exact same effect, right? No, it can't get the same effect via "just set an easy option". For example, transfer sets the resolve mode as "AUTO" (which is the default option) and it does want to use dual-stack when it is available. So, this option will remain the same no matter whether "IPv6 works" or not. Under the hood, libcurl calls a "system" level (not a transfer level) function Curl_ipv6works() to decide whether it can actually go with IPv6 for the AUTO and IPv6 modes. So, checking if "IPv6 works" is below the transfer level and the transfer will be performed based on that "system" information. For me, the "IPv6 works" check is the same "system" level functionality as memory management callbacks - that's why I propose to have it as a global "system" callback. > This suggestion reads to me like a work-around for you not wanting to change > code in the place that would afix the problem, > but you rather propose and add a new public libcurl function call so that you > can do the change elsewhere in your app. > Generally, having two ways to do the same thing is bad. That's right. I don't think that it is possible to change the Curl_ipv6works() implementation that it will work the same way with zero delays for ALL possible kernels/network configurations. And it is not possible to change all kernels where some curl application may run to make Curl_ipv6works() return false with 0ms delay when there are some issues with IPv6 on kernel levels. And because "IPv6 works" will always be needed for IPv6-related modes, there should be a way to customize the default Curl_ipv6works() behavior, which can be achieved via "system" global callbacks. I just gave example of using "atomic global variable" because in my case, I have "out-of-band" mechanism to detect whether IPv6 works on my systems and set a global variable to be used in the "IP works" system callback. But it is just an example of how the problems with Curl_ipv6works() can be worked around, and other developers can implement something else. Once there is a way to specify the "IP works" callback, it will provide a flexibility to handle problems with default Curl_ipv6works() using different ways -best for some specific application. > You can consider another approach for this - add new global function > curl_global_setopt. It would better fit how libcurl works now. This new > function should be called after curl_global_init/curl_global_init_mem and before any other libcurl calls. No, global options are not going to help here. Each transfer can select any mode: IPv4, IPv6 or AUTO - no matter whether it comes from local and global options. And for IPv6 or AUTO modes, the Curl_ipv6works() will always be called with potential connection or connection failure delays. And as I mentioned above, because it is not feasible to fix IPv6-related issues causing the delays in all possible kernels where some curl application may be running, there is a need for workaround which the system "IPv6 works" callback can provide. Thanks, Dmitry Karpov -----Original Message----- From: curl-library <curl-library-boun...@lists.haxx.se> On Behalf Of Daniel Stenberg via curl-library Sent: Thursday, September 22, 2022 8:33 AM To: Daniel F via curl-library <curl-library@lists.haxx.se> Cc: Daniel Stenberg <dan...@haxx.se> Subject: Re: [EXTERNAL] Re: Feature request: provide ability to set a global callback function telling libcurl if IPv6 works on the system On Thu, 22 Sep 2022, Daniel F via curl-library wrote: > Yes, this can cause problems. One way to address this is to document > it somewhere, unfortunately people still would be able to write bad > code and complain here that something does not work. So better > approach would be to pass all these global options to curl_global_init_opts > function: I think the even better way is to resist adding global options! -- / daniel.haxx.se | Commercial curl support up to 24x7 is available! | Private help, bug fixes, support, ports, new features | https://curl.se/support.html -- Unsubscribe: https://lists.haxx.se/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.html -- Unsubscribe: https://lists.haxx.se/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.html