Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -235,23 +235,13 @@ public async Task DnsGetHostAddresses_LocalhostSubdomain_ReturnsLoopback(string
{
// The subdomain goes to OS resolver first. If it fails (likely on most systems),
// it falls back to resolving plain "localhost", which should return loopback addresses.
// On Android/Apple mobile platforms the OS resolver may return non-loopback addresses
// for *.localhost.
bool requireLoopback = !PlatformDetection.IsAppleMobile && !PlatformDetection.IsAndroid;

IPAddress[] addresses = Dns.GetHostAddresses(hostName);
Assert.True(addresses.Length >= 1, "Expected at least one address");
if (requireLoopback)
{
Assert.All(addresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(addresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));

addresses = await Dns.GetHostAddressesAsync(hostName);
Assert.True(addresses.Length >= 1, "Expected at least one address");
if (requireLoopback)
{
Assert.All(addresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(addresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}

// RFC 6761: "*.localhost" subdomains should respect AddressFamily parameter.
Expand Down Expand Up @@ -291,35 +281,24 @@ public async Task DnsGetHostAddresses_LocalhostSubdomain_RespectsAddressFamily(A
// 1. The OS resolver is tried first for subdomains
// 2. The OS may return different results (e.g., both IPv4+IPv6 vs IPv4 only)
// 3. Different systems configure localhost differently
// On Android and Apple mobile the OS resolver may return non-loopback addresses
// for both plain "localhost" and "*.localhost" (e.g. link-local IPv6 or
// multicast DNS results), so we only require any address to be returned there.
[Fact]
public async Task DnsGetHostAddresses_LocalhostAndSubdomain_BothReturnLoopback()
{
bool requireLoopback = !PlatformDetection.IsAppleMobile && !PlatformDetection.IsAndroid;

IPAddress[] localhostAddresses = Dns.GetHostAddresses("localhost");
IPAddress[] subdomainAddresses = Dns.GetHostAddresses("foo.localhost");

Assert.True(localhostAddresses.Length >= 1);
Assert.True(subdomainAddresses.Length >= 1);
if (requireLoopback)
{
Assert.All(localhostAddresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
Assert.All(subdomainAddresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(localhostAddresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
Assert.All(subdomainAddresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));

localhostAddresses = await Dns.GetHostAddressesAsync("localhost");
subdomainAddresses = await Dns.GetHostAddressesAsync("bar.localhost");

Assert.True(localhostAddresses.Length >= 1);
Assert.True(subdomainAddresses.Length >= 1);
if (requireLoopback)
{
Assert.All(localhostAddresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
Assert.All(subdomainAddresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(localhostAddresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
Assert.All(subdomainAddresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}

// RFC 6761: Localhost subdomains with trailing dot should work (e.g., "foo.localhost.")
Expand All @@ -328,21 +307,13 @@ public async Task DnsGetHostAddresses_LocalhostAndSubdomain_BothReturnLoopback()
[InlineData("bar.test.localhost.")]
public async Task DnsGetHostAddresses_LocalhostSubdomainWithTrailingDot_ReturnsLoopback(string hostName)
{
bool requireLoopback = !PlatformDetection.IsAppleMobile && !PlatformDetection.IsAndroid;

IPAddress[] addresses = Dns.GetHostAddresses(hostName);
Assert.True(addresses.Length >= 1, "Expected at least one address");
if (requireLoopback)
{
Assert.All(addresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(addresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));

addresses = await Dns.GetHostAddressesAsync(hostName);
Assert.True(addresses.Length >= 1, "Expected at least one address");
if (requireLoopback)
{
Assert.All(addresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(addresses, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}

// RFC 6761: Ensure names that look similar but are not reserved are still resolved via OS.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,23 +357,13 @@ public async Task DnsGetHostEntry_LocalhostSubdomain_ReturnsLoopback(string host
{
// The subdomain goes to OS resolver first. If it fails (likely on most systems),
// it falls back to resolving plain "localhost", which should return loopback addresses.
// On Android/Apple mobile platforms the OS resolver may return non-loopback addresses
// for *.localhost.
bool requireLoopback = !PlatformDetection.IsAppleMobile && !PlatformDetection.IsAndroid;

IPHostEntry entry = Dns.GetHostEntry(hostName);
Assert.True(entry.AddressList.Length >= 1, "Expected at least one address");
if (requireLoopback)
{
Assert.All(entry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(entry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));

entry = await Dns.GetHostEntryAsync(hostName);
Assert.True(entry.AddressList.Length >= 1, "Expected at least one address");
if (requireLoopback)
{
Assert.All(entry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(entry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}

// RFC 6761: Ensure names that look similar but are not reserved are still resolved via OS.
Expand Down Expand Up @@ -456,35 +446,24 @@ public async Task DnsGetHostEntry_LocalhostSubdomain_RespectsAddressFamily(Addre
// 1. The OS resolver is tried first for subdomains
// 2. The OS may return different results (e.g., both IPv4+IPv6 vs IPv4 only)
// 3. Different systems configure localhost differently
// On Android and Apple mobile the OS resolver may return non-loopback addresses
// for both plain "localhost" and "*.localhost" (e.g. link-local IPv6 or
// multicast DNS results), so we only require any address to be returned there.
[Fact]
public async Task DnsGetHostEntry_LocalhostAndSubdomain_BothReturnLoopback()
{
bool requireLoopback = !PlatformDetection.IsAppleMobile && !PlatformDetection.IsAndroid;

IPHostEntry localhostEntry = Dns.GetHostEntry("localhost");
IPHostEntry subdomainEntry = Dns.GetHostEntry("foo.localhost");

Assert.True(localhostEntry.AddressList.Length >= 1);
Assert.True(subdomainEntry.AddressList.Length >= 1);
if (requireLoopback)
{
Assert.All(localhostEntry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
Assert.All(subdomainEntry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(localhostEntry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
Assert.All(subdomainEntry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));

localhostEntry = await Dns.GetHostEntryAsync("localhost");
subdomainEntry = await Dns.GetHostEntryAsync("bar.localhost");

Assert.True(localhostEntry.AddressList.Length >= 1);
Assert.True(subdomainEntry.AddressList.Length >= 1);
if (requireLoopback)
{
Assert.All(localhostEntry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
Assert.All(subdomainEntry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(localhostEntry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
Assert.All(subdomainEntry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}

// RFC 6761: Localhost subdomains with trailing dot should work (e.g., "foo.localhost.")
Expand All @@ -494,21 +473,13 @@ public async Task DnsGetHostEntry_LocalhostAndSubdomain_BothReturnLoopback()
[InlineData("bar.test.localhost.")]
public async Task DnsGetHostEntry_LocalhostSubdomainWithTrailingDot_ReturnsLoopback(string hostName)
{
bool requireLoopback = !PlatformDetection.IsAppleMobile && !PlatformDetection.IsAndroid;

IPHostEntry entry = Dns.GetHostEntry(hostName);
Assert.True(entry.AddressList.Length >= 1, "Expected at least one address");
if (requireLoopback)
{
Assert.All(entry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(entry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));

entry = await Dns.GetHostEntryAsync(hostName);
Assert.True(entry.AddressList.Length >= 1, "Expected at least one address");
if (requireLoopback)
{
Assert.All(entry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}
Assert.All(entry.AddressList, addr => Assert.True(IPAddress.IsLoopback(addr), $"Expected loopback address but got: {addr}"));
}

[Fact]
Expand Down
Loading