-
Bug
-
Resolution: Unresolved
-
Not Evaluated
-
None
-
6.8.3
-
None
-
neon-user-20250925-0744.iso
Steps to reproduce:
1. Modify /etc/resolv.conf to set DNS to 114.114.114.114
2. Execute: sudo ip6tables -A INPUT -s 2400:3200:1300::1a7 -j DROP
3. Run the demo
When the demo uses HTTP, it returns normally:
QString urlStr = 'http://appstore.uniontech.com';
When changed to:
QString urlStr = 'https://appstore.uniontech.com';
It takes 30 seconds to revert to IPv4 (verifiable with a timer, e.g. set timer to 40).
1. The timing of parallel link selection in HTTPS scenarios presents issues: the decision point for selecting one link over another occurs after the TCP connection is established, at which point the corresponding link is chosen and the other link is closed. However, HTTPS (HTTP over SSL) introduces an additional TLS phase, meaning that after the TCP connection is established, a TLS handshake follows. If the IPv6 TCP connection is halted during this phase, Should issues arise during the TLS phase, it becomes blocked at IPv6 and cannot proceed. Consequently, it waits until the configured timeout period (30 seconds as specified in the source code) before reverting to IPv4. This results in a perceived delay when switching back to IPv4. In contrast, HTTP lacks a TLS phase, enabling rapid parallel selection/reversion at the TCP layer and thus faster transition to IPv4.
2. During testing, HTTPS consistently fails to enter the `q_connected_abstract_socket` function (this is the callback after 'TCP connected'). Failure to enter indicates TCP never established the connection, caused by the command directly disabling IPv6). Under certain configurations, HTTPS utilises HTTP/2 with activeChannelCount=1 by default. startNetworkLayerStateLookup() initiates only one connection (AnyIPProtocol) in the single-channel branch, failing to simultaneously establish both IPv4 and IPv6 connections. If DNS returns an AAAA record, the single-channel approach will likely attempt IPv6 first. Should the system disable/block IPv6, TCP will remain stuck in the connection phase, preventing this function from being invoked. Subsequent modifications—such as the parallel determination deferred to `encrypted()`—will then prove ineffective.
HTTP avoids this issue because:
HTTP operates over HTTP/1.1, which defaults to multi-channel operation. In dual-stack environments, it initiates IPv6 and IPv4 connections in parallel (with a 300ms interval). Should IPv6 stall, IPv4 swiftly takes over, enabling the `connected` state to be triggered promptly.
Approach: Under the HTTPS model, force both channels to start concurrently (even though HTTP/2 defaults to one channel), maintaining the 300ms interval; defer determining the ‘link selection within the parallel strategy’ until TLS encryption is complete (encrypted). This ensures that even if IPv6 stalls at any stage of TCP/TLS, IPv4 will be swiftly activated to take over, thereby avoiding prolonged waiting periods.
For Gerrit Dashboard: QTBUG-140556 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
679505,3 | network: Optimize HTTPS Happy Eyeballs to avoid long stalls | dev | qt/qtbase | Status: NEW | 0 | 0 |