gusarov / river

Tunelling & proxy connectivity
Apache License 2.0
10 stars 3 forks source link

Happy Eyeballs #4

Open gusarov opened 4 years ago

gusarov commented 4 years ago

Implement Happy Eyeballs to fallback from IPv6 if it is not supported by the next party. IETF promotes that IPv6 should be the preference when choosing among 2 addresses. But the next party (your ISP) might not support it. So: 1) on a IPv6 enabled machine you can receive AAAA dns entry for www.google.com but if you continue with IPv6 over SOCKS it might fail on a proxy server side if proxy's ISP is not supporting IPv6. 2) if you are connecting private machine it might have local IPv4 which is unreachable by proxy, while reachable by IPv6. To facilitate this, there should be Happy Eyeballs or similar implementation: Happy Eyeballs attempts to establish connection with both algorithms simultaneously. If IPv6 succeeded, it proceeds with IPv6 otherwise falls back to IPv4.

For the PROXY server in the middle this have one more option: proceed with Domain Name instead. This one also should be considered for better connectivity

gusarov commented 4 years ago

This is mostly for Socks5ClientStream

            var targetIsIp = IPAddress.TryParse(targetHost, out var ip);
            if (!targetIsIp) // if targetHost is IP - just use IP
            {
                var dns = Dns.GetHostAddresses(targetHost);
                var ipv4 = dns.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork);
                var ipv6 = dns.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetworkV6);

                ip = ipv4 ?? ipv6; // have to take ipv4 first because ipv6 is not working most of the times and HappyEyeballs is not possible via socks due to single connection
            }

For ShadowSocks it is even harder, because protocol does not acknowledge proper connection