> 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 <[email protected]> On Behalf Of Daniel
Stenberg via curl-library
Sent: Thursday, September 22, 2022 8:33 AM
To: Daniel F via curl-library <[email protected]>
Cc: Daniel Stenberg <[email protected]>
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