Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up`Dns.GetHostEntryAsync` returning odd results #405
Comments
This comment has been minimized.
This comment has been minimized.
So runtime/src/libraries/System.Net.NameResolution/src/System/Net/Dns.cs Lines 396 to 405 in 4f9ae42 Is there some way to avoid this? I just want the PTR record, I don't care about if the forward lookup matches.
|
This comment has been minimized.
This comment has been minimized.
Here's my example code where I copied and pasted the using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace DnsTest
{
class Program
{
static async Task Main(string[] args)
{
await Task.WhenAll(
Lookup("118.127.7.26"),
Lookup("203.26.198.8"),
Lookup("141.0.104.145")
);
}
static async Task Lookup(string ip)
{
var result = await Dns.GetHostEntryAsync(ip);
Console.WriteLine($"{ip} Dns.GetHostEntryAsync = {result.HostName}");
var result2 = TryGetNameInfo(IPAddress.Parse(ip), out var socketError, out var nativeErrorCode);
Console.WriteLine($"{ip} TryGetNameInfo = {result2}");
}
public static unsafe string TryGetNameInfo(IPAddress addr, out SocketError socketError, out int nativeErrorCode)
{
byte* buffer = stackalloc byte[Interop.Sys.NI_MAXHOST + 1 /*for null*/];
byte isIPv6;
int rawAddressLength;
if (addr.AddressFamily == AddressFamily.InterNetwork)
{
isIPv6 = 0;
rawAddressLength = IPAddressParserStatics.IPv4AddressBytes;
}
else
{
isIPv6 = 1;
rawAddressLength = IPAddressParserStatics.IPv6AddressBytes;
}
byte* rawAddress = stackalloc byte[rawAddressLength];
addr.TryWriteBytes(new Span<byte>(rawAddress, rawAddressLength), out int bytesWritten);
Debug.Assert(bytesWritten == rawAddressLength);
int error = Interop.Sys.GetNameInfo(
rawAddress,
(uint)rawAddressLength,
isIPv6,
buffer,
Interop.Sys.NI_MAXHOST,
null,
0,
Interop.Sys.GetNameInfoFlags.NI_NAMEREQD);
socketError = GetSocketErrorForNativeError(error);
nativeErrorCode = error;
return socketError == SocketError.Success ? Marshal.PtrToStringAnsi((IntPtr)buffer) : null;
}
private static SocketError GetSocketErrorForNativeError(int error)
{
switch (error)
{
case 0:
return SocketError.Success;
case (int)Interop.Sys.GetAddrInfoErrorFlags.EAI_AGAIN:
return SocketError.TryAgain;
case (int)Interop.Sys.GetAddrInfoErrorFlags.EAI_BADFLAGS:
case (int)Interop.Sys.GetAddrInfoErrorFlags.EAI_BADARG:
return SocketError.InvalidArgument;
case (int)Interop.Sys.GetAddrInfoErrorFlags.EAI_FAIL:
return SocketError.NoRecovery;
case (int)Interop.Sys.GetAddrInfoErrorFlags.EAI_FAMILY:
return SocketError.AddressFamilyNotSupported;
case (int)Interop.Sys.GetAddrInfoErrorFlags.EAI_NONAME:
return SocketError.HostNotFound;
case (int)Interop.Sys.GetAddrInfoErrorFlags.EAI_MEMORY:
throw new OutOfMemoryException();
default:
Debug.Fail("Unexpected error: " + error.ToString());
return SocketError.SocketError;
}
}
}
internal static partial class Interop
{
internal static partial class Sys
{
internal const int NI_MAXHOST = 1025;
[Flags]
internal enum GetNameInfoFlags : int
{
NI_NAMEREQD = 0x1,
NI_NUMERICHOST = 0x2,
}
internal enum GetAddrInfoErrorFlags : int
{
EAI_AGAIN = 1, // Temporary failure in name resolution.
EAI_BADFLAGS = 2, // Invalid value for `ai_flags' field.
EAI_FAIL = 3, // Non-recoverable failure in name resolution.
EAI_FAMILY = 4, // 'ai_family' not supported.
EAI_NONAME = 5, // NAME or SERVICE is unknown.
EAI_BADARG = 6, // One or more input arguments were invalid.
EAI_NOMORE = 7, // No more entries are present in the list.
EAI_MEMORY = 8, // Out of memory.
}
[DllImport("System.Native", EntryPoint = "SystemNative_GetNameInfo")] // Libraries.SystemNative
internal static extern unsafe int GetNameInfo(
byte* address,
uint addressLength,
byte isIpv6,
byte* host,
uint hostLength,
byte* service,
uint serviceLength,
GetNameInfoFlags flags);
}
}
internal static class IPAddressParserStatics
{
public const int IPv4AddressBytes = 4;
public const int IPv6AddressBytes = 16;
public const int IPv6AddressShorts = IPv6AddressBytes / 2;
}
}
Output when I run it:
So |
This comment has been minimized.
This comment has been minimized.
The |
This comment has been minimized.
This comment has been minimized.
Turns out the issue is that I have a wildcard subdomain (so
I found this interesting section in the
So what the Linux DNS resolver was doing was concatenating Adding
to |
Dns.GetHostEntryAsync
is returning weird results for me. Calling it on several IPs such as118.127.7.26
,203.26.198.8
and141.0.104.145
are returning my server's domain name as theHostName
value, rather than the proper reverse DNS of the IP address. Thehost
command on the server does return the correct values though:How can I debug this? How does the DNS resolution in the framework work?