diff --git a/src/libraries/System.Net.NameResolution/src/System/Net/Dns.cs b/src/libraries/System.Net.NameResolution/src/System/Net/Dns.cs index 62a389ffe4ba5b..1f3068700f237c 100644 --- a/src/libraries/System.Net.NameResolution/src/System/Net/Dns.cs +++ b/src/libraries/System.Net.NameResolution/src/System/Net/Dns.cs @@ -432,6 +432,18 @@ private static object GetHostEntryOrAddressesCore(string hostName, bool justAddr object result; try { + if (MatchesReservedName(hostName, "invalid")) + { + LogSpecialUse(hostName); + throw new SocketException((int)SocketError.HostNotFound); + } + + if (MatchesReservedName(hostName, "localhost")) + { + LogSpecialUse(hostName); + return GetLoopbacksForAddressFamily(addressFamily); + } + SocketError errorCode = NameResolutionPal.TryGetAddrInfo(hostName, justAddresses, addressFamily, out string? newHostName, out string[] aliases, out IPAddress[] addresses, out int nativeErrorCode); if (errorCode != SocketError.Success) @@ -702,6 +714,33 @@ private static void ValidateHostName(string hostName) } } + private static IPAddress[] GetLoopbacksForAddressFamily(AddressFamily addressFamily) + { + bool ipv4Enabled = SocketProtocolSupportPal.OSSupportsIPv4; + bool ipv6Enabled = SocketProtocolSupportPal.OSSupportsIPv6; + + return addressFamily switch + { + AddressFamily.InterNetwork when ipv4Enabled => new[] { IPAddress.Loopback }, + AddressFamily.InterNetworkV6 when ipv6Enabled => new[] { IPAddress.IPv6Loopback }, + AddressFamily.Unspecified when ipv4Enabled && ipv6Enabled => new[] { IPAddress.Loopback, IPAddress.IPv6Loopback }, + AddressFamily.Unspecified when ipv4Enabled => new[] { IPAddress.Loopback }, + AddressFamily.Unspecified when ipv6Enabled => new[] { IPAddress.IPv6Loopback }, + _ => Array.Empty(), + }; + } + + private static bool MatchesReservedName(string name, string reservedName) + { + return name.Equals(reservedName, StringComparison.OrdinalIgnoreCase) || + name.EndsWith("." + reservedName, StringComparison.OrdinalIgnoreCase); + } + + private static void LogSpecialUse(string hostName) + { + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(hostName, $"Special-use domain intercepted before calling OS resolver: {hostName}"); + } + private static bool LogFailure(object hostNameOrAddress, in NameResolutionActivity activity, Exception exception) { NameResolutionTelemetry.Log.AfterResolution(hostNameOrAddress, activity, answer: null, exception: exception);