Skip to content

Commit

Permalink
Fix direct connecting to IP addresses.
Browse files Browse the repository at this point in the history
Oops, I misinterpreted the functionality for Dns.GetHostEntryAsync. It does not just pass through IPs received.
  • Loading branch information
PJB3005 committed May 17, 2024
1 parent 2a9a5e3 commit 7338b9d
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions SS14.Launcher/HappyEyeballsHttp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ private static async ValueTask<Stream> OnConnect(
// I could find no other robust way to check "is there a chance in hell IPv6 works" other than "try it",
// so... try it we will.
var endPoint = context.DnsEndPoint;
var hostEntry = await Dns.GetHostEntryAsync(endPoint.Host, cancellationToken).ConfigureAwait(false);
if (hostEntry.AddressList.Length == 0)
var resolvedAddresses = await GetIpsForHost(endPoint, cancellationToken).ConfigureAwait(false);
if (resolvedAddresses.Length == 0)
throw new Exception($"Host {context.DnsEndPoint.Host} resolved to no IPs!");

// Sort as specified in the RFC, interleaving.
var ips = SortInterleaved(hostEntry.AddressList);
var ips = SortInterleaved(resolvedAddresses);

Debug.Assert(ips.Length > 0);

Expand Down Expand Up @@ -125,6 +125,15 @@ private static async Task<Socket> AttemptConnection(
}
}

private static async Task<IPAddress[]> GetIpsForHost(DnsEndPoint endPoint, CancellationToken cancel)
{
if (IPAddress.TryParse(endPoint.Host, out var ip))
return [ip];

var entry = await Dns.GetHostEntryAsync(endPoint.Host, cancel).ConfigureAwait(false);
return entry.AddressList;
}

private static IPAddress[] SortInterleaved(IPAddress[] addresses)
{
// Interleave returned addresses so that they are IPv6 -> IPv4 -> IPv6 -> IPv4.
Expand Down

0 comments on commit 7338b9d

Please sign in to comment.