You've already forked linux-packaging-mono
Imported Upstream version 5.16.0.100
Former-commit-id: 38faa55fb9669e35e7d8448b15c25dc447f25767
This commit is contained in:
parent
0a9828183b
commit
7d7f676260
4
external/corefx/src/System.Net.NameResolution/src/MatchingRefApiCompatBaseline.txt
vendored
Normal file
4
external/corefx/src/System.Net.NameResolution/src/MatchingRefApiCompatBaseline.txt
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
Compat issues with assembly System.Net.NameResolution:
|
||||
TypesMustExist : Type 'System.Net.Internals.ProtocolFamily' does not exist in the implementation but it does exist in the contract.
|
||||
TypesMustExist : Type 'System.Net.Internals.ProtocolType' does not exist in the implementation but it does exist in the contract.
|
||||
Total Issues: 2
|
@ -5,6 +5,7 @@
|
||||
<AssemblyName>System.Net.NameResolution</AssemblyName>
|
||||
<ProjectGuid>{1714448C-211E-48C1-8B7E-4EE667D336A1}</ProjectGuid>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<ILLinkClearInitLocals>true</ILLinkClearInitLocals>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='uap-Windows_NT-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='uap-Windows_NT-Release|AnyCPU'" />
|
||||
@ -46,15 +47,18 @@
|
||||
<Compile Include="$(CommonPath)\System\Net\IPEndPointStatics.cs">
|
||||
<Link>Common\System\Net\IPEndPointStatics.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\ByteOrder.cs">
|
||||
<Link>Common\System\Net\ByteOrder.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="System\Net\DnsResolveAsyncResult.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(TargetsWindows)' == 'true'">
|
||||
<Compile Include="System\Net\NameResolutionPal.Windows.cs" />
|
||||
<Compile Include="System\Net\NameResolutionPal.Win32.cs" Condition="'$(TargetGroup)' != 'uap'"/>
|
||||
<Compile Include="System\Net\NameResolutionPal.Uap.cs" Condition="'$(TargetGroup)' == 'uap'"/>
|
||||
<Compile Include="$(CommonPath)\System\Net\ContextAwareResult.Windows.cs">
|
||||
<Link>Common\System\Net\ContextAwareResult.Windows.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\IntPtrHelper.cs">
|
||||
<Link>Common\System\Net\IntPtrHelper.cs</Link>
|
||||
</Compile>
|
||||
<!-- Debug only -->
|
||||
<Compile Include="$(CommonPath)\System\Net\DebugSafeHandle.cs">
|
||||
<Link>Common\System\Net\DebugSafeHandle.cs</Link>
|
||||
@ -72,6 +76,9 @@
|
||||
<Compile Include="$(CommonPath)\System\Net\SocketProtocolSupportPal.Windows.cs">
|
||||
<Link>Common\System\Net\SocketProtocolSupportPal.Windows</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\SocketAddressPal.Windows.cs">
|
||||
<Link>Common\System\Net\SocketAddressPal.Windows</Link>
|
||||
</Compile>
|
||||
<!-- Interop -->
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Interop.Libraries.cs">
|
||||
<Link>Interop\Windows\Interop.Libraries.cs</Link>
|
||||
@ -87,13 +94,7 @@
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\Interop.closesocket.cs">
|
||||
<Link>Interop\Windows\Winsock\Interop.closesocket.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\Interop.gethostbyaddr.cs">
|
||||
<Link>Interop\Windows\Winsock\Interop.gethostbyaddr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\Interop.gethostbyname.cs">
|
||||
<Link>Interop\Windows\Winsock\Interop.gethostbyname.cs</Link>
|
||||
</Compile>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\Interop.gethostname.cs">
|
||||
<Link>Interop\Windows\Winsock\Interop.gethostname.cs</Link>
|
||||
</Compile>
|
||||
@ -118,12 +119,27 @@
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\SafeFreeAddrInfo.cs">
|
||||
<Link>Interop\Windows\Winsock\SafeFreeAddrInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\AddressInfoEx.cs">
|
||||
<Link>Interop\Windows\Winsock\AddressInfoEx.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\Interop.GetAddrInfoExW.cs">
|
||||
<Link>Interop\Windows\Winsock\Interop.GetAddrInfoExW.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs" Condition="'$(TargetGroup)' != 'uap'">
|
||||
<Link>Common\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Kernel32\Interop.GetProcAddress.cs" Condition="'$(TargetGroup)' != 'uap'">
|
||||
<Link>Interop\Windows\Kernel32\Interop.GetProcAddress.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Kernel32\Interop.LoadLibraryEx.cs" Condition="'$(TargetGroup)' != 'uap'">
|
||||
<Link>Interop\Windows\Kernel32\Interop.LoadLibraryEx.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Kernel32\Interop.FreeLibrary.cs">
|
||||
<Link>Interop\Windows\Kernel32\Interop.FreeLibrary.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(TargetsUnix)' == 'true' ">
|
||||
<Compile Include="System\Net\NameResolutionPal.Unix.cs" />
|
||||
<Compile Include="$(CommonPath)\System\Net\ByteOrder.cs">
|
||||
<Link>Common\System\Net\Internals\ByteOrder.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\ContextAwareResult.Unix.cs">
|
||||
<Link>Common\System\Net\ContextAwareResult.Unix.cs</Link>
|
||||
</Compile>
|
||||
@ -189,6 +205,7 @@
|
||||
<Reference Include="System.Security.Claims" />
|
||||
<Reference Include="System.Security.Principal.Windows" />
|
||||
<Reference Include="System.Threading" />
|
||||
<Reference Include="System.Threading.Overlapped" />
|
||||
<Reference Include="System.Threading.Tasks" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
|
@ -38,52 +38,31 @@ namespace System.Net
|
||||
{
|
||||
return NameResolutionUtilities.GetUnresolvedAnswer(address);
|
||||
}
|
||||
return InternalGetHostByName(hostName, false);
|
||||
return InternalGetHostByName(hostName);
|
||||
}
|
||||
|
||||
private static IPHostEntry InternalGetHostByName(string hostName, bool includeIPv6)
|
||||
private static void ValidateHostName(string hostName)
|
||||
{
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Enter(null, hostName);
|
||||
IPHostEntry ipHostEntry = null;
|
||||
|
||||
if (hostName.Length > MaxHostName // If 255 chars, the last one must be a dot.
|
||||
|| hostName.Length == MaxHostName && hostName[MaxHostName - 1] != '.')
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(hostName), SR.Format(SR.net_toolong,
|
||||
nameof(hostName), MaxHostName.ToString(NumberFormatInfo.CurrentInfo)));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// IPv6 Changes: IPv6 requires the use of getaddrinfo() rather
|
||||
// than the traditional IPv4 gethostbyaddr() / gethostbyname().
|
||||
// getaddrinfo() is also protocol independent in that it will also
|
||||
// resolve IPv4 names / addresses. As a result, it is the preferred
|
||||
// resolution mechanism on platforms that support it (Windows 5.1+).
|
||||
// If getaddrinfo() is unsupported, IPv6 resolution does not work.
|
||||
//
|
||||
// Consider : If IPv6 is disabled, we could detect IPv6 addresses
|
||||
// and throw an unsupported platform exception.
|
||||
//
|
||||
// Note : Whilst getaddrinfo is available on WinXP+, we only
|
||||
// use it if IPv6 is enabled (platform is part of that
|
||||
// decision). This is done to minimize the number of
|
||||
// possible tests that are needed.
|
||||
//
|
||||
if (includeIPv6 || SocketProtocolSupportPal.OSSupportsIPv6)
|
||||
private static IPHostEntry InternalGetHostByName(string hostName)
|
||||
{
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Enter(null, hostName);
|
||||
IPHostEntry ipHostEntry = null;
|
||||
|
||||
ValidateHostName(hostName);
|
||||
|
||||
int nativeErrorCode;
|
||||
SocketError errorCode = NameResolutionPal.TryGetAddrInfo(hostName, out ipHostEntry, out nativeErrorCode);
|
||||
if (errorCode != SocketError.Success)
|
||||
{
|
||||
//
|
||||
// IPv6 enabled: use getaddrinfo() to obtain DNS information.
|
||||
//
|
||||
int nativeErrorCode;
|
||||
SocketError errorCode = NameResolutionPal.TryGetAddrInfo(hostName, out ipHostEntry, out nativeErrorCode);
|
||||
if (errorCode != SocketError.Success)
|
||||
{
|
||||
throw SocketExceptionFactory.CreateSocketException(errorCode, nativeErrorCode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ipHostEntry = NameResolutionPal.GetHostByName(hostName);
|
||||
throw SocketExceptionFactory.CreateSocketException(errorCode, nativeErrorCode);
|
||||
}
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, ipHostEntry);
|
||||
@ -101,7 +80,7 @@ namespace System.Net
|
||||
throw new ArgumentNullException(nameof(address));
|
||||
}
|
||||
|
||||
IPHostEntry ipHostEntry = InternalGetHostByAddress(IPAddress.Parse(address), false);
|
||||
IPHostEntry ipHostEntry = InternalGetHostByAddress(IPAddress.Parse(address));
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, ipHostEntry);
|
||||
return ipHostEntry;
|
||||
@ -118,79 +97,51 @@ namespace System.Net
|
||||
throw new ArgumentNullException(nameof(address));
|
||||
}
|
||||
|
||||
IPHostEntry ipHostEntry = InternalGetHostByAddress(address, false);
|
||||
IPHostEntry ipHostEntry = InternalGetHostByAddress(address);
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, ipHostEntry);
|
||||
return ipHostEntry;
|
||||
} // GetHostByAddress
|
||||
|
||||
// Does internal IPAddress reverse and then forward lookups (for Legacy and current public methods).
|
||||
private static IPHostEntry InternalGetHostByAddress(IPAddress address, bool includeIPv6)
|
||||
private static IPHostEntry InternalGetHostByAddress(IPAddress address)
|
||||
{
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Info(null, address);
|
||||
|
||||
//
|
||||
// IPv6 Changes: We need to use the new getnameinfo / getaddrinfo functions
|
||||
// for resolution of IPv6 addresses.
|
||||
//
|
||||
|
||||
if (SocketProtocolSupportPal.OSSupportsIPv6 || includeIPv6)
|
||||
//
|
||||
// Try to get the data for the host from it's address
|
||||
//
|
||||
// We need to call getnameinfo first, because getaddrinfo w/ the ipaddress string
|
||||
// will only return that address and not the full list.
|
||||
|
||||
// Do a reverse lookup to get the host name.
|
||||
SocketError errorCode;
|
||||
int nativeErrorCode;
|
||||
string name = NameResolutionPal.TryGetNameInfo(address, out errorCode, out nativeErrorCode);
|
||||
if (errorCode == SocketError.Success)
|
||||
{
|
||||
//
|
||||
// Try to get the data for the host from it's address
|
||||
//
|
||||
// We need to call getnameinfo first, because getaddrinfo w/ the ipaddress string
|
||||
// will only return that address and not the full list.
|
||||
|
||||
// Do a reverse lookup to get the host name.
|
||||
SocketError errorCode;
|
||||
int nativeErrorCode;
|
||||
string name = NameResolutionPal.TryGetNameInfo(address, out errorCode, out nativeErrorCode);
|
||||
// Do the forward lookup to get the IPs for that host name
|
||||
IPHostEntry hostEntry;
|
||||
errorCode = NameResolutionPal.TryGetAddrInfo(name, out hostEntry, out nativeErrorCode);
|
||||
if (errorCode == SocketError.Success)
|
||||
{
|
||||
// Do the forward lookup to get the IPs for that host name
|
||||
IPHostEntry hostEntry;
|
||||
errorCode = NameResolutionPal.TryGetAddrInfo(name, out hostEntry, out nativeErrorCode);
|
||||
if (errorCode == SocketError.Success)
|
||||
{
|
||||
return hostEntry;
|
||||
}
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Error(null, SocketExceptionFactory.CreateSocketException(errorCode, nativeErrorCode));
|
||||
|
||||
// One of two things happened:
|
||||
// 1. There was a ptr record in dns, but not a corollary A/AAA record.
|
||||
// 2. The IP was a local (non-loopback) IP that resolved to a connection specific dns suffix.
|
||||
// - Workaround, Check "Use this connection's dns suffix in dns registration" on that network
|
||||
// adapter's advanced dns settings.
|
||||
|
||||
// Just return the resolved host name and no IPs.
|
||||
return hostEntry;
|
||||
}
|
||||
|
||||
throw SocketExceptionFactory.CreateSocketException(errorCode, nativeErrorCode);
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Error(null, SocketExceptionFactory.CreateSocketException(errorCode, nativeErrorCode));
|
||||
|
||||
// One of two things happened:
|
||||
// 1. There was a ptr record in dns, but not a corollary A/AAA record.
|
||||
// 2. The IP was a local (non-loopback) IP that resolved to a connection specific dns suffix.
|
||||
// - Workaround, Check "Use this connection's dns suffix in dns registration" on that network
|
||||
// adapter's advanced dns settings.
|
||||
|
||||
// Just return the resolved host name and no IPs.
|
||||
return hostEntry;
|
||||
}
|
||||
|
||||
//
|
||||
// If IPv6 is not enabled (maybe config switch) but we've been
|
||||
// given an IPv6 address then we need to bail out now.
|
||||
//
|
||||
else
|
||||
{
|
||||
if (address.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
{
|
||||
//
|
||||
// Protocol not supported
|
||||
//
|
||||
throw new SocketException((int)SocketError.ProtocolNotSupported);
|
||||
}
|
||||
//
|
||||
// Use gethostbyaddr() to try to resolve the IP address
|
||||
//
|
||||
// End IPv6 Changes
|
||||
//
|
||||
return NameResolutionPal.GetHostByAddr(address);
|
||||
}
|
||||
throw SocketExceptionFactory.CreateSocketException(errorCode, nativeErrorCode);
|
||||
|
||||
} // InternalGetHostByAddress
|
||||
|
||||
/*****************************************************************************
|
||||
@ -235,7 +186,7 @@ namespace System.Net
|
||||
{
|
||||
try
|
||||
{
|
||||
ipHostEntry = InternalGetHostByAddress(address, false);
|
||||
ipHostEntry = InternalGetHostByAddress(address);
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
@ -245,49 +196,26 @@ namespace System.Net
|
||||
}
|
||||
else
|
||||
{
|
||||
ipHostEntry = InternalGetHostByName(hostName, false);
|
||||
ipHostEntry = InternalGetHostByName(hostName);
|
||||
}
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, ipHostEntry);
|
||||
return ipHostEntry;
|
||||
}
|
||||
|
||||
private class ResolveAsyncResult : ContextAwareResult
|
||||
{
|
||||
// Forward lookup
|
||||
internal ResolveAsyncResult(string hostName, object myObject, bool includeIPv6, object myState, AsyncCallback myCallBack) :
|
||||
base(myObject, myState, myCallBack)
|
||||
{
|
||||
this.hostName = hostName;
|
||||
this.includeIPv6 = includeIPv6;
|
||||
}
|
||||
|
||||
// Reverse lookup
|
||||
internal ResolveAsyncResult(IPAddress address, object myObject, bool includeIPv6, object myState, AsyncCallback myCallBack) :
|
||||
base(myObject, myState, myCallBack)
|
||||
{
|
||||
this.includeIPv6 = includeIPv6;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
internal readonly string hostName;
|
||||
internal bool includeIPv6;
|
||||
internal IPAddress address;
|
||||
}
|
||||
|
||||
private static void ResolveCallback(object context)
|
||||
{
|
||||
ResolveAsyncResult result = (ResolveAsyncResult)context;
|
||||
DnsResolveAsyncResult result = (DnsResolveAsyncResult)context;
|
||||
IPHostEntry hostEntry;
|
||||
try
|
||||
{
|
||||
if (result.address != null)
|
||||
if (result.IpAddress != null)
|
||||
{
|
||||
hostEntry = InternalGetHostByAddress(result.address, result.includeIPv6);
|
||||
hostEntry = InternalGetHostByAddress(result.IpAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
hostEntry = InternalGetHostByName(result.hostName, result.includeIPv6);
|
||||
hostEntry = InternalGetHostByName(result.HostName);
|
||||
}
|
||||
}
|
||||
catch (OutOfMemoryException)
|
||||
@ -305,7 +233,7 @@ namespace System.Net
|
||||
|
||||
// Helpers for async GetHostByName, ResolveToAddresses, and Resolve - they're almost identical
|
||||
// If hostName is an IPString and justReturnParsedIP==true then no reverse lookup will be attempted, but the original address is returned.
|
||||
private static IAsyncResult HostResolutionBeginHelper(string hostName, bool justReturnParsedIp, bool includeIPv6, bool throwOnIIPAny, AsyncCallback requestCallback, object state)
|
||||
private static IAsyncResult HostResolutionBeginHelper(string hostName, bool justReturnParsedIp, bool throwOnIIPAny, AsyncCallback requestCallback, object state)
|
||||
{
|
||||
if (hostName == null)
|
||||
{
|
||||
@ -315,20 +243,20 @@ namespace System.Net
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Info(null, hostName);
|
||||
|
||||
// See if it's an IP Address.
|
||||
IPAddress address;
|
||||
ResolveAsyncResult asyncResult;
|
||||
if (IPAddress.TryParse(hostName, out address))
|
||||
IPAddress ipAddress;
|
||||
DnsResolveAsyncResult asyncResult;
|
||||
if (IPAddress.TryParse(hostName, out ipAddress))
|
||||
{
|
||||
if (throwOnIIPAny && (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any)))
|
||||
if (throwOnIIPAny && (ipAddress.Equals(IPAddress.Any) || ipAddress.Equals(IPAddress.IPv6Any)))
|
||||
{
|
||||
throw new ArgumentException(SR.net_invalid_ip_addr, nameof(hostName));
|
||||
}
|
||||
|
||||
asyncResult = new ResolveAsyncResult(address, null, includeIPv6, state, requestCallback);
|
||||
asyncResult = new DnsResolveAsyncResult(ipAddress, null, state, requestCallback);
|
||||
|
||||
if (justReturnParsedIp)
|
||||
{
|
||||
IPHostEntry hostEntry = NameResolutionUtilities.GetUnresolvedAnswer(address);
|
||||
IPHostEntry hostEntry = NameResolutionUtilities.GetUnresolvedAnswer(ipAddress);
|
||||
asyncResult.StartPostingAsyncOp(false);
|
||||
asyncResult.InvokeCallback(hostEntry);
|
||||
asyncResult.FinishPostingAsyncOp();
|
||||
@ -337,26 +265,36 @@ namespace System.Net
|
||||
}
|
||||
else
|
||||
{
|
||||
asyncResult = new ResolveAsyncResult(hostName, null, includeIPv6, state, requestCallback);
|
||||
asyncResult = new DnsResolveAsyncResult(hostName, null, state, requestCallback);
|
||||
}
|
||||
|
||||
// Set up the context, possibly flow.
|
||||
asyncResult.StartPostingAsyncOp(false);
|
||||
|
||||
// Start the resolve.
|
||||
Task.Factory.StartNew(
|
||||
s => ResolveCallback(s),
|
||||
asyncResult,
|
||||
CancellationToken.None,
|
||||
TaskCreationOptions.DenyChildAttach,
|
||||
TaskScheduler.Default);
|
||||
// If the OS supports it and 'hostName' is not an IP Address, resolve the name asynchronously
|
||||
// instead of calling the synchronous version in the ThreadPool.
|
||||
if (NameResolutionPal.SupportsGetAddrInfoAsync && ipAddress == null)
|
||||
{
|
||||
ValidateHostName(hostName);
|
||||
NameResolutionPal.GetAddrInfoAsync(asyncResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start the resolve.
|
||||
Task.Factory.StartNew(
|
||||
s => ResolveCallback(s),
|
||||
asyncResult,
|
||||
CancellationToken.None,
|
||||
TaskCreationOptions.DenyChildAttach,
|
||||
TaskScheduler.Default);
|
||||
}
|
||||
|
||||
// Finish the flowing, maybe it completed? This does nothing if we didn't initiate the flowing above.
|
||||
asyncResult.FinishPostingAsyncOp();
|
||||
return asyncResult;
|
||||
}
|
||||
|
||||
private static IAsyncResult HostResolutionBeginHelper(IPAddress address, bool flowContext, bool includeIPv6, AsyncCallback requestCallback, object state)
|
||||
private static IAsyncResult HostResolutionBeginHelper(IPAddress address, bool flowContext, AsyncCallback requestCallback, object state)
|
||||
{
|
||||
if (address == null)
|
||||
{
|
||||
@ -371,7 +309,7 @@ namespace System.Net
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Info(null, address);
|
||||
|
||||
// Set up the context, possibly flow.
|
||||
ResolveAsyncResult asyncResult = new ResolveAsyncResult(address, null, includeIPv6, state, requestCallback);
|
||||
DnsResolveAsyncResult asyncResult = new DnsResolveAsyncResult(address, null, state, requestCallback);
|
||||
if (flowContext)
|
||||
{
|
||||
asyncResult.StartPostingAsyncOp(false);
|
||||
@ -399,7 +337,7 @@ namespace System.Net
|
||||
{
|
||||
throw new ArgumentNullException(nameof(asyncResult));
|
||||
}
|
||||
ResolveAsyncResult castedResult = asyncResult as ResolveAsyncResult;
|
||||
DnsResolveAsyncResult castedResult = asyncResult as DnsResolveAsyncResult;
|
||||
if (castedResult == null)
|
||||
{
|
||||
throw new ArgumentException(SR.net_io_invalidasyncresult, nameof(asyncResult));
|
||||
@ -430,7 +368,7 @@ namespace System.Net
|
||||
|
||||
NameResolutionPal.EnsureSocketsAreInitialized();
|
||||
|
||||
IAsyncResult asyncResult = HostResolutionBeginHelper(hostName, true, true, false, requestCallback, stateObject);
|
||||
IAsyncResult asyncResult = HostResolutionBeginHelper(hostName, true, true, requestCallback, stateObject);
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, asyncResult);
|
||||
return asyncResult;
|
||||
@ -468,11 +406,11 @@ namespace System.Net
|
||||
throw new ArgumentException(SR.Format(SR.net_invalid_ip_addr, nameof(hostNameOrAddress)));
|
||||
}
|
||||
|
||||
ipHostEntry = InternalGetHostByAddress(address, true);
|
||||
ipHostEntry = InternalGetHostByAddress(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipHostEntry = InternalGetHostByName(hostNameOrAddress, true);
|
||||
ipHostEntry = InternalGetHostByName(hostNameOrAddress);
|
||||
}
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, ipHostEntry);
|
||||
@ -495,7 +433,7 @@ namespace System.Net
|
||||
throw new ArgumentException(SR.Format(SR.net_invalid_ip_addr, nameof(address)));
|
||||
}
|
||||
|
||||
IPHostEntry ipHostEntry = InternalGetHostByAddress(address, true);
|
||||
IPHostEntry ipHostEntry = InternalGetHostByAddress(address);
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, ipHostEntry);
|
||||
return ipHostEntry;
|
||||
@ -526,7 +464,7 @@ namespace System.Net
|
||||
{
|
||||
// InternalGetHostByName works with IP addresses (and avoids a reverse-lookup), but we need
|
||||
// explicit handling in order to do the ArgumentException and guarantee the behavior.
|
||||
addresses = InternalGetHostByName(hostNameOrAddress, true).AddressList;
|
||||
addresses = InternalGetHostByName(hostNameOrAddress).AddressList;
|
||||
}
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, addresses);
|
||||
@ -538,7 +476,7 @@ namespace System.Net
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Enter(null, hostNameOrAddress);
|
||||
NameResolutionPal.EnsureSocketsAreInitialized();
|
||||
|
||||
IAsyncResult asyncResult = HostResolutionBeginHelper(hostNameOrAddress, false, true, true, requestCallback, stateObject);
|
||||
IAsyncResult asyncResult = HostResolutionBeginHelper(hostNameOrAddress, false, true, requestCallback, stateObject);
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, asyncResult);
|
||||
return asyncResult;
|
||||
@ -550,7 +488,7 @@ namespace System.Net
|
||||
|
||||
NameResolutionPal.EnsureSocketsAreInitialized();
|
||||
|
||||
IAsyncResult asyncResult = HostResolutionBeginHelper(address, true, true, requestCallback, stateObject);
|
||||
IAsyncResult asyncResult = HostResolutionBeginHelper(address, true, requestCallback, stateObject);
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, asyncResult);
|
||||
return asyncResult;
|
||||
@ -570,7 +508,7 @@ namespace System.Net
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Enter(null, hostNameOrAddress);
|
||||
NameResolutionPal.EnsureSocketsAreInitialized();
|
||||
|
||||
IAsyncResult asyncResult = HostResolutionBeginHelper(hostNameOrAddress, true, true, true, requestCallback, state);
|
||||
IAsyncResult asyncResult = HostResolutionBeginHelper(hostNameOrAddress, true, true, requestCallback, state);
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, asyncResult);
|
||||
return asyncResult;
|
||||
@ -592,7 +530,7 @@ namespace System.Net
|
||||
|
||||
NameResolutionPal.EnsureSocketsAreInitialized();
|
||||
|
||||
IAsyncResult asyncResult = HostResolutionBeginHelper(hostName, false, false, false, requestCallback, stateObject);
|
||||
IAsyncResult asyncResult = HostResolutionBeginHelper(hostName, false, false, requestCallback, stateObject);
|
||||
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, asyncResult);
|
||||
return asyncResult;
|
||||
@ -611,7 +549,7 @@ namespace System.Net
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
IPAddress address = ((ResolveAsyncResult)asyncResult).address;
|
||||
IPAddress address = ((DnsResolveAsyncResult)asyncResult).IpAddress;
|
||||
if (address == null)
|
||||
throw; // BeginResolve was called with a HostName, not an IPAddress
|
||||
|
||||
|
26
external/corefx/src/System.Net.NameResolution/src/System/Net/DnsResolveAsyncResult.cs
vendored
Normal file
26
external/corefx/src/System.Net.NameResolution/src/System/Net/DnsResolveAsyncResult.cs
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace System.Net
|
||||
{
|
||||
internal sealed class DnsResolveAsyncResult : ContextAwareResult
|
||||
{
|
||||
internal string HostName { get; }
|
||||
internal IPAddress IpAddress { get; }
|
||||
|
||||
// Forward lookup
|
||||
internal DnsResolveAsyncResult(string hostName, object myObject, object myState, AsyncCallback myCallBack)
|
||||
: base(myObject, myState, myCallBack)
|
||||
{
|
||||
HostName = hostName;
|
||||
}
|
||||
|
||||
// Reverse lookup
|
||||
internal DnsResolveAsyncResult(IPAddress ipAddress, object myObject, object myState, AsyncCallback myCallBack)
|
||||
: base(myObject, myState, myCallBack)
|
||||
{
|
||||
IpAddress = ipAddress;
|
||||
}
|
||||
}
|
||||
}
|
11
external/corefx/src/System.Net.NameResolution/src/System/Net/NameResolutionPal.Uap.cs
vendored
Normal file
11
external/corefx/src/System.Net.NameResolution/src/System/Net/NameResolutionPal.Uap.cs
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace System.Net
|
||||
{
|
||||
internal static partial class NameResolutionPal
|
||||
{
|
||||
private static bool GetAddrInfoExSupportsOverlapped() => false;
|
||||
}
|
||||
}
|
@ -13,26 +13,8 @@ namespace System.Net
|
||||
{
|
||||
internal static partial class NameResolutionPal
|
||||
{
|
||||
private static SocketError GetSocketErrorForErrno(int errno)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case 0:
|
||||
return SocketError.Success;
|
||||
case (int)Interop.Sys.GetHostErrorCodes.HOST_NOT_FOUND:
|
||||
return SocketError.HostNotFound;
|
||||
case (int)Interop.Sys.GetHostErrorCodes.NO_DATA:
|
||||
return SocketError.NoData;
|
||||
case (int)Interop.Sys.GetHostErrorCodes.NO_RECOVERY:
|
||||
return SocketError.NoRecovery;
|
||||
case (int)Interop.Sys.GetHostErrorCodes.TRY_AGAIN:
|
||||
return SocketError.TryAgain;
|
||||
default:
|
||||
Debug.Fail("Unexpected errno: " + errno.ToString());
|
||||
return SocketError.SocketError;
|
||||
}
|
||||
}
|
||||
|
||||
public const bool SupportsGetAddrInfoAsync = false;
|
||||
|
||||
private static SocketError GetSocketErrorForNativeError(int error)
|
||||
{
|
||||
switch (error)
|
||||
@ -138,39 +120,7 @@ namespace System.Net
|
||||
Aliases = aliases
|
||||
};
|
||||
}
|
||||
|
||||
public static unsafe IPHostEntry GetHostByName(string hostName)
|
||||
{
|
||||
if (hostName == "")
|
||||
{
|
||||
// To match documented behavior on Windows, if an empty string is passed in, use the local host's name.
|
||||
hostName = Dns.GetHostName();
|
||||
}
|
||||
|
||||
Interop.Sys.HostEntry entry;
|
||||
int err = Interop.Sys.GetHostByName(hostName, &entry);
|
||||
if (err != 0)
|
||||
{
|
||||
throw SocketExceptionFactory.CreateSocketException(GetSocketErrorForErrno(err), err);
|
||||
}
|
||||
|
||||
return CreateIPHostEntry(entry);
|
||||
}
|
||||
|
||||
public static unsafe IPHostEntry GetHostByAddr(IPAddress addr)
|
||||
{
|
||||
// TODO #2891: Optimize this (or decide if this legacy code can be removed):
|
||||
Interop.Sys.IPAddress address = addr.GetNativeIPAddress();
|
||||
Interop.Sys.HostEntry entry;
|
||||
int err = Interop.Sys.GetHostByAddress(&address, &entry);
|
||||
if (err != 0)
|
||||
{
|
||||
throw SocketExceptionFactory.CreateSocketException(GetSocketErrorForErrno(err), err);
|
||||
}
|
||||
|
||||
return CreateIPHostEntry(entry);
|
||||
}
|
||||
|
||||
|
||||
public static unsafe SocketError TryGetAddrInfo(string name, out IPHostEntry hostinfo, out int nativeErrorCode)
|
||||
{
|
||||
if (name == "")
|
||||
@ -194,30 +144,45 @@ namespace System.Net
|
||||
return SocketError.Success;
|
||||
}
|
||||
|
||||
internal static void GetAddrInfoAsync(DnsResolveAsyncResult asyncResult)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public static unsafe string TryGetNameInfo(IPAddress addr, out SocketError socketError, out int nativeErrorCode)
|
||||
{
|
||||
byte* buffer = stackalloc byte[Interop.Sys.NI_MAXHOST + 1 /*for null*/];
|
||||
|
||||
// TODO #2891: Remove the copying step to improve performance. This requires a change in the contracts.
|
||||
byte[] addressBuffer = addr.GetAddressBytes();
|
||||
|
||||
int error;
|
||||
fixed (byte* rawAddress = &addressBuffer[0])
|
||||
byte isIPv6;
|
||||
int rawAddressLength;
|
||||
if (addr.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
error = Interop.Sys.GetNameInfo(
|
||||
rawAddress,
|
||||
unchecked((uint)addressBuffer.Length),
|
||||
addr.AddressFamily == AddressFamily.InterNetworkV6 ? (byte)1 : (byte)0,
|
||||
buffer,
|
||||
Interop.Sys.NI_MAXHOST,
|
||||
null,
|
||||
0,
|
||||
Interop.Sys.GetNameInfoFlags.NI_NAMEREQD);
|
||||
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 ? null : Marshal.PtrToStringAnsi((IntPtr)buffer);
|
||||
return socketError != SocketError.Success ? null : Marshal.PtrToStringAnsi((IntPtr)buffer);
|
||||
}
|
||||
|
||||
public static string GetHostName()
|
||||
|
24
external/corefx/src/System.Net.NameResolution/src/System/Net/NameResolutionPal.Win32.cs
vendored
Normal file
24
external/corefx/src/System.Net.NameResolution/src/System/Net/NameResolutionPal.Win32.cs
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace System.Net
|
||||
{
|
||||
internal static partial class NameResolutionPal
|
||||
{
|
||||
private static bool GetAddrInfoExSupportsOverlapped()
|
||||
{
|
||||
using (SafeLibraryHandle libHandle = Interop.Kernel32.LoadLibraryExW(Interop.Libraries.Ws2_32, IntPtr.Zero, Interop.Kernel32.LOAD_LIBRARY_SEARCH_SYSTEM32))
|
||||
{
|
||||
if (libHandle.IsInvalid)
|
||||
return false;
|
||||
|
||||
// We can't just check that 'GetAddrInfoEx' exists, because it existed before supporting overlapped.
|
||||
// The existence of 'GetAddrInfoExCancel' indicates that overlapped is supported.
|
||||
return Interop.Kernel32.GetProcAddress(libHandle, Interop.Winsock.GetAddrInfoExCancelFunctionName) != IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,19 +7,34 @@ using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using ProtocolFamily = System.Net.Internals.ProtocolFamily;
|
||||
|
||||
namespace System.Net
|
||||
{
|
||||
internal static class NameResolutionPal
|
||||
internal static partial class NameResolutionPal
|
||||
{
|
||||
//
|
||||
// used by GetHostName() to preallocate a buffer for the call to gethostname.
|
||||
//
|
||||
private const int HostNameBufferLength = 256;
|
||||
|
||||
private static bool s_initialized;
|
||||
private static readonly object s_initializedLock = new object();
|
||||
|
||||
private static readonly unsafe Interop.Winsock.LPLOOKUPSERVICE_COMPLETION_ROUTINE s_getAddrInfoExCallback = GetAddressInfoExCallback;
|
||||
private static bool s_getAddrInfoExSupported;
|
||||
|
||||
public static bool SupportsGetAddrInfoAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureSocketsAreInitialized();
|
||||
return s_getAddrInfoExSupported;
|
||||
}
|
||||
}
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
@ -99,7 +114,7 @@ namespace System.Net
|
||||
//
|
||||
// now get the next pointer in the array and start over
|
||||
//
|
||||
currentArrayElement = IntPtrHelper.Add(currentArrayElement, IntPtr.Size);
|
||||
currentArrayElement = currentArrayElement + IntPtr.Size;
|
||||
nativePointer = Marshal.ReadIntPtr(currentArrayElement);
|
||||
}
|
||||
|
||||
@ -132,7 +147,7 @@ namespace System.Net
|
||||
//
|
||||
// now get the next pointer in the array and start over
|
||||
//
|
||||
currentArrayElement = IntPtrHelper.Add(currentArrayElement, IntPtr.Size);
|
||||
currentArrayElement = currentArrayElement + IntPtr.Size;
|
||||
nativePointer = Marshal.ReadIntPtr(currentArrayElement);
|
||||
}
|
||||
|
||||
@ -141,62 +156,6 @@ namespace System.Net
|
||||
return HostEntry;
|
||||
} // NativeToHostEntry
|
||||
|
||||
public static IPHostEntry GetHostByName(string hostName)
|
||||
{
|
||||
//
|
||||
// IPv6 disabled: use gethostbyname() to obtain DNS information.
|
||||
//
|
||||
IntPtr nativePointer =
|
||||
Interop.Winsock.gethostbyname(
|
||||
hostName);
|
||||
|
||||
if (nativePointer == IntPtr.Zero)
|
||||
{
|
||||
// Need to do this first since if we wait the last error code might be overwritten.
|
||||
SocketException socketException = new SocketException();
|
||||
|
||||
IPAddress address;
|
||||
if (IPAddress.TryParse(hostName, out address))
|
||||
{
|
||||
IPHostEntry ipHostEntry = NameResolutionUtilities.GetUnresolvedAnswer(address);
|
||||
if (NetEventSource.IsEnabled) NetEventSource.Exit(null, ipHostEntry);
|
||||
return ipHostEntry;
|
||||
}
|
||||
|
||||
throw socketException;
|
||||
}
|
||||
|
||||
return NativeToHostEntry(nativePointer);
|
||||
}
|
||||
|
||||
public static IPHostEntry GetHostByAddr(IPAddress address)
|
||||
{
|
||||
// TODO #2891: Optimize this (or decide if this legacy code can be removed):
|
||||
#pragma warning disable CS0618 // Address is marked obsolete
|
||||
int addressAsInt = unchecked((int)address.Address);
|
||||
#pragma warning restore CS0618
|
||||
|
||||
#if BIGENDIAN
|
||||
// TODO #2891: above code needs testing for BIGENDIAN.
|
||||
|
||||
addressAsInt = (int)(((uint)addressAsInt << 24) | (((uint)addressAsInt & 0x0000FF00) << 8) |
|
||||
(((uint)addressAsInt >> 8) & 0x0000FF00) | ((uint)addressAsInt >> 24));
|
||||
#endif
|
||||
|
||||
IntPtr nativePointer =
|
||||
Interop.Winsock.gethostbyaddr(
|
||||
ref addressAsInt,
|
||||
sizeof(int),
|
||||
ProtocolFamily.InterNetwork);
|
||||
|
||||
if (nativePointer != IntPtr.Zero)
|
||||
{
|
||||
return NativeToHostEntry(nativePointer);
|
||||
}
|
||||
|
||||
throw new SocketException();
|
||||
}
|
||||
|
||||
public static unsafe SocketError TryGetAddrInfo(string name, out IPHostEntry hostinfo, out int nativeErrorCode)
|
||||
{
|
||||
//
|
||||
@ -232,7 +191,6 @@ namespace System.Net
|
||||
//
|
||||
while (pAddressInfo != null)
|
||||
{
|
||||
SocketAddress sockaddr;
|
||||
//
|
||||
// Retrieve the canonical name for the host - only appears in the first AddressInfo
|
||||
// entry in the returned array.
|
||||
@ -247,29 +205,17 @@ namespace System.Net
|
||||
// We also filter based on whether IPv6 is supported on the current
|
||||
// platform / machine.
|
||||
//
|
||||
if ((pAddressInfo->ai_family == AddressFamily.InterNetwork) || // Never filter v4
|
||||
(pAddressInfo->ai_family == AddressFamily.InterNetworkV6 && SocketProtocolSupportPal.OSSupportsIPv6))
|
||||
var socketAddress = new ReadOnlySpan<byte>(pAddressInfo->ai_addr, pAddressInfo->ai_addrlen);
|
||||
|
||||
if (pAddressInfo->ai_family == AddressFamily.InterNetwork)
|
||||
{
|
||||
sockaddr = new SocketAddress(pAddressInfo->ai_family, pAddressInfo->ai_addrlen);
|
||||
//
|
||||
// Push address data into the socket address buffer
|
||||
//
|
||||
for (int d = 0; d < pAddressInfo->ai_addrlen; d++)
|
||||
{
|
||||
sockaddr[d] = *(pAddressInfo->ai_addr + d);
|
||||
}
|
||||
//
|
||||
// NOTE: We need an IPAddress now, the only way to create it from a
|
||||
// SocketAddress is via IPEndPoint. This ought to be simpler.
|
||||
//
|
||||
if (pAddressInfo->ai_family == AddressFamily.InterNetwork)
|
||||
{
|
||||
addresses.Add(((IPEndPoint)IPEndPointStatics.Any.Create(sockaddr)).Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
addresses.Add(((IPEndPoint)IPEndPointStatics.IPv6Any.Create(sockaddr)).Address);
|
||||
}
|
||||
if (socketAddress.Length == SocketAddressPal.IPv4AddressSize)
|
||||
addresses.Add(CreateIPv4Address(socketAddress));
|
||||
}
|
||||
else if (pAddressInfo->ai_family == AddressFamily.InterNetworkV6 && SocketProtocolSupportPal.OSSupportsIPv6)
|
||||
{
|
||||
if (socketAddress.Length == SocketAddressPal.IPv6AddressSize)
|
||||
addresses.Add(CreateIPv6Address(socketAddress));
|
||||
}
|
||||
//
|
||||
// Next addressinfo entry
|
||||
@ -385,10 +331,193 @@ namespace System.Net
|
||||
throw new SocketException((int)errorCode);
|
||||
}
|
||||
|
||||
s_getAddrInfoExSupported = GetAddrInfoExSupportsOverlapped();
|
||||
|
||||
Volatile.Write(ref s_initialized, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void GetAddrInfoAsync(DnsResolveAsyncResult asyncResult)
|
||||
{
|
||||
GetAddrInfoExContext* context = GetAddrInfoExContext.AllocateContext();
|
||||
|
||||
try
|
||||
{
|
||||
var state = new GetAddrInfoExState(asyncResult);
|
||||
context->QueryStateHandle = state.CreateHandle();
|
||||
}
|
||||
catch
|
||||
{
|
||||
GetAddrInfoExContext.FreeContext(context);
|
||||
throw;
|
||||
}
|
||||
|
||||
AddressInfoEx hints = new AddressInfoEx();
|
||||
hints.ai_flags = AddressInfoHints.AI_CANONNAME;
|
||||
hints.ai_family = AddressFamily.Unspecified; // Gets all address families
|
||||
|
||||
SocketError errorCode =
|
||||
(SocketError)Interop.Winsock.GetAddrInfoExW(asyncResult.HostName, null, 0 /* NS_ALL*/, IntPtr.Zero, ref hints, out context->Result, IntPtr.Zero, ref context->Overlapped, s_getAddrInfoExCallback, out context->CancelHandle);
|
||||
|
||||
if (errorCode != SocketError.IOPending)
|
||||
ProcessResult(errorCode, context);
|
||||
}
|
||||
|
||||
private static unsafe void GetAddressInfoExCallback([In] int error, [In] int bytes, [In] NativeOverlapped* overlapped)
|
||||
{
|
||||
// Can be casted directly to GetAddrInfoExContext* because the overlapped is its first field
|
||||
GetAddrInfoExContext* context = (GetAddrInfoExContext*)overlapped;
|
||||
|
||||
ProcessResult((SocketError)error, context);
|
||||
}
|
||||
|
||||
private static unsafe void ProcessResult(SocketError errorCode, GetAddrInfoExContext* context)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetAddrInfoExState state = GetAddrInfoExState.FromHandleAndFree(context->QueryStateHandle);
|
||||
|
||||
if (errorCode != SocketError.Success)
|
||||
{
|
||||
state.CompleteAsyncResult(new SocketException((int)errorCode));
|
||||
return;
|
||||
}
|
||||
|
||||
AddressInfoEx* result = context->Result;
|
||||
string canonicalName = null;
|
||||
|
||||
List<IPAddress> addresses = new List<IPAddress>();
|
||||
|
||||
while (result != null)
|
||||
{
|
||||
if (canonicalName == null && result->ai_canonname != IntPtr.Zero)
|
||||
canonicalName = Marshal.PtrToStringUni(result->ai_canonname);
|
||||
|
||||
var socketAddress = new ReadOnlySpan<byte>(result->ai_addr, result->ai_addrlen);
|
||||
|
||||
if (result->ai_family == AddressFamily.InterNetwork)
|
||||
{
|
||||
if (socketAddress.Length == SocketAddressPal.IPv4AddressSize)
|
||||
addresses.Add(CreateIPv4Address(socketAddress));
|
||||
}
|
||||
else if (SocketProtocolSupportPal.OSSupportsIPv6 && result->ai_family == AddressFamily.InterNetworkV6)
|
||||
{
|
||||
if (socketAddress.Length == SocketAddressPal.IPv6AddressSize)
|
||||
addresses.Add(CreateIPv6Address(socketAddress));
|
||||
}
|
||||
|
||||
result = result->ai_next;
|
||||
}
|
||||
|
||||
if (canonicalName == null)
|
||||
canonicalName = state.HostName;
|
||||
|
||||
state.CompleteAsyncResult(new IPHostEntry
|
||||
{
|
||||
HostName = canonicalName,
|
||||
Aliases = Array.Empty<string>(),
|
||||
AddressList = addresses.ToArray()
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
GetAddrInfoExContext.FreeContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe IPAddress CreateIPv4Address(ReadOnlySpan<byte> socketAddress)
|
||||
{
|
||||
long address = (long)SocketAddressPal.GetIPv4Address(socketAddress) & 0x0FFFFFFFF;
|
||||
return new IPAddress(address);
|
||||
}
|
||||
|
||||
private static unsafe IPAddress CreateIPv6Address(ReadOnlySpan<byte> socketAddress)
|
||||
{
|
||||
Span<byte> address = stackalloc byte[IPAddressParserStatics.IPv6AddressBytes];
|
||||
uint scope;
|
||||
SocketAddressPal.GetIPv6Address(socketAddress, address, out scope);
|
||||
|
||||
return new IPAddress(address, (long)scope);
|
||||
}
|
||||
|
||||
#region GetAddrInfoAsync Helper Classes
|
||||
|
||||
//
|
||||
// Warning: If this ever ported to NETFX, AppDomain unloads needs to be handled
|
||||
// to protect against AppDomainUnloadException if there are pending operations.
|
||||
//
|
||||
|
||||
private sealed class GetAddrInfoExState
|
||||
{
|
||||
private DnsResolveAsyncResult _asyncResult;
|
||||
private object _result;
|
||||
|
||||
public string HostName => _asyncResult.HostName;
|
||||
|
||||
public GetAddrInfoExState(DnsResolveAsyncResult asyncResult)
|
||||
{
|
||||
_asyncResult = asyncResult;
|
||||
}
|
||||
|
||||
public void CompleteAsyncResult(object o)
|
||||
{
|
||||
// We don't want to expose the GetAddrInfoEx callback thread to user code.
|
||||
// The callback occurs in a native windows thread pool.
|
||||
|
||||
_result = o;
|
||||
|
||||
Task.Factory.StartNew(s =>
|
||||
{
|
||||
var self = (GetAddrInfoExState)s;
|
||||
self._asyncResult.InvokeCallback(self._result);
|
||||
}, this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
|
||||
}
|
||||
|
||||
public IntPtr CreateHandle()
|
||||
{
|
||||
GCHandle handle = GCHandle.Alloc(this, GCHandleType.Normal);
|
||||
return GCHandle.ToIntPtr(handle);
|
||||
}
|
||||
|
||||
public static GetAddrInfoExState FromHandleAndFree(IntPtr handle)
|
||||
{
|
||||
GCHandle gcHandle = GCHandle.FromIntPtr(handle);
|
||||
var state = (GetAddrInfoExState)gcHandle.Target;
|
||||
gcHandle.Free();
|
||||
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private unsafe struct GetAddrInfoExContext
|
||||
{
|
||||
private static readonly int Size = sizeof(GetAddrInfoExContext);
|
||||
|
||||
public NativeOverlapped Overlapped;
|
||||
public AddressInfoEx* Result;
|
||||
public IntPtr CancelHandle;
|
||||
public IntPtr QueryStateHandle;
|
||||
|
||||
public static GetAddrInfoExContext* AllocateContext()
|
||||
{
|
||||
var context = (GetAddrInfoExContext*)Marshal.AllocHGlobal(Size);
|
||||
*context = default;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
public static void FreeContext(GetAddrInfoExContext* context)
|
||||
{
|
||||
if (context->Result != null)
|
||||
Interop.Winsock.FreeAddrInfoEx(context->Result);
|
||||
|
||||
Marshal.FreeHGlobal((IntPtr)context);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,6 @@
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
netstandard-Windows_NT;
|
||||
netstandard-Unix;
|
||||
netcoreapp-Windows_NT;
|
||||
netcoreapp-Unix;
|
||||
</BuildConfigurations>
|
||||
|
91
external/corefx/src/System.Net.NameResolution/tests/PalTests/Fakes/FakeContextAwareResult.cs
vendored
Normal file
91
external/corefx/src/System.Net.NameResolution/tests/PalTests/Fakes/FakeContextAwareResult.cs
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Net
|
||||
{
|
||||
internal partial class ContextAwareResult : IAsyncResult
|
||||
{
|
||||
private AsyncCallback _callback;
|
||||
|
||||
private static Func<object> _resultFactory;
|
||||
|
||||
public static void FakeSetResultFactory(Func<object> resultFactory)
|
||||
{
|
||||
_resultFactory = resultFactory;
|
||||
}
|
||||
|
||||
public object AsyncState
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
internal bool EndCalled
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
internal object Result
|
||||
{
|
||||
get
|
||||
{
|
||||
return _resultFactory?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public WaitHandle AsyncWaitHandle
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public bool CompletedSynchronously
|
||||
{
|
||||
get
|
||||
{
|
||||
// Simulate sync completion:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCompleted
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
internal ContextAwareResult(object myObject, object myState, AsyncCallback myCallBack)
|
||||
{
|
||||
_callback = myCallBack;
|
||||
}
|
||||
|
||||
internal object StartPostingAsyncOp(bool lockCapture)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
internal bool FinishPostingAsyncOp()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void InvokeCallback(object result)
|
||||
{
|
||||
_callback.Invoke(this);
|
||||
}
|
||||
|
||||
internal void InternalWaitForCompletion() { }
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -22,87 +22,6 @@ namespace System.Net.NameResolution.PalTests
|
||||
Assert.NotNull(NameResolutionPal.GetHostName());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetHostByName_LocalHost()
|
||||
{
|
||||
IPHostEntry hostEntry = NameResolutionPal.GetHostByName("localhost");
|
||||
Assert.NotNull(hostEntry);
|
||||
Assert.NotNull(hostEntry.HostName);
|
||||
Assert.NotNull(hostEntry.AddressList);
|
||||
Assert.NotNull(hostEntry.Aliases);
|
||||
}
|
||||
|
||||
public static object[][] InvalidHostNames = new object[][] {
|
||||
new object[] { ":" },
|
||||
new object[] { "..." }
|
||||
};
|
||||
|
||||
[Theory, MemberData(nameof(InvalidHostNames))]
|
||||
public void GetHostByName_InvalidHostName_Throws(string hostName)
|
||||
{
|
||||
Assert.ThrowsAny<SocketException>(() => NameResolutionPal.GetHostByName(hostName));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetHostByName_HostName()
|
||||
{
|
||||
string hostName = NameResolutionPal.GetHostName();
|
||||
Assert.NotNull(hostName);
|
||||
|
||||
IPHostEntry hostEntry = NameResolutionPal.GetHostByName(hostName);
|
||||
Assert.NotNull(hostEntry);
|
||||
Assert.NotNull(hostEntry.HostName);
|
||||
Assert.NotNull(hostEntry.AddressList);
|
||||
Assert.NotNull(hostEntry.Aliases);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetHostByAddr_LocalHost()
|
||||
{
|
||||
Assert.NotNull(NameResolutionPal.GetHostByAddr(new IPAddress(0x0100007f)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetHostByName_LocalHost_GetHostByAddr()
|
||||
{
|
||||
IPHostEntry hostEntry1 = NameResolutionPal.GetHostByName("localhost");
|
||||
Assert.NotNull(hostEntry1);
|
||||
IPHostEntry hostEntry2 = NameResolutionPal.GetHostByAddr(hostEntry1.AddressList[0]);
|
||||
Assert.NotNull(hostEntry2);
|
||||
|
||||
IPAddress[] list1 = hostEntry1.AddressList;
|
||||
IPAddress[] list2 = hostEntry2.AddressList;
|
||||
|
||||
for (int i = 0; i < list1.Length; i++)
|
||||
{
|
||||
Assert.NotEqual(-1, Array.IndexOf(list2, list1[i]));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetHostByName_HostName_GetHostByAddr()
|
||||
{
|
||||
IPHostEntry hostEntry1 = NameResolutionPal.GetHostByName(System.Net.Test.Common.Configuration.Http.Http2Host);
|
||||
Assert.NotNull(hostEntry1);
|
||||
|
||||
IPAddress[] list1 = hostEntry1.AddressList;
|
||||
Assert.InRange(list1.Length, 1, Int32.MaxValue);
|
||||
|
||||
foreach (IPAddress addr1 in list1)
|
||||
{
|
||||
IPHostEntry hostEntry2 = NameResolutionPal.GetHostByAddr(addr1);
|
||||
Assert.NotNull(hostEntry2);
|
||||
|
||||
IPAddress[] list2 = hostEntry2.AddressList;
|
||||
Assert.InRange(list2.Length, 1, list1.Length);
|
||||
|
||||
foreach (IPAddress addr2 in list2)
|
||||
{
|
||||
Assert.NotEqual(-1, Array.IndexOf(list1, addr2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetAddrInfo_LocalHost()
|
||||
{
|
||||
@ -125,6 +44,13 @@ namespace System.Net.NameResolution.PalTests
|
||||
IPHostEntry hostEntry;
|
||||
int nativeErrorCode;
|
||||
SocketError error = NameResolutionPal.TryGetAddrInfo(hostName, out hostEntry, out nativeErrorCode);
|
||||
if (error == SocketError.HostNotFound && (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)))
|
||||
{
|
||||
// On Unix, we are not guaranteed to be able to resove the local host. The ability to do so depends on the
|
||||
// machine configurations, which varies by distro and is often inconsistent.
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.Equal(SocketError.Success, error);
|
||||
Assert.NotNull(hostEntry);
|
||||
Assert.NotNull(hostEntry.HostName);
|
||||
|
@ -10,10 +10,6 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Unix-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Unix-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Unix-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Windows_NT-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Windows_NT-Release|AnyCPU'" />
|
||||
<!-- Do not reference these assemblies from the TargetingPack since we are building part of the source code for tests. -->
|
||||
<ItemGroup>
|
||||
<TargetingPackExclusions Include="System.Net.NameResolution" />
|
||||
@ -24,6 +20,7 @@
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Fakes\FakeContextAwareResult.cs" />
|
||||
<Compile Include="NameResolutionPalTests.cs" />
|
||||
<Compile Include="Fakes\DebugThreadTracking.cs" />
|
||||
<Compile Include="Fakes\DnsFake.cs" />
|
||||
@ -34,6 +31,9 @@
|
||||
<Compile Include="..\..\src\System\Net\NameResolutionUtilities.cs">
|
||||
<Link>ProductionCode\System\Net\NameResolutionUtilities.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\System\Net\DnsResolveAsyncResult.cs">
|
||||
<Link>ProductionCode\System\Net\DnsResolveAsyncResult.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\Sockets\ProtocolType.cs" Condition="'$(OSGroup)' == 'Windows_NT'">
|
||||
<Link>Common\System\Net\Sockets\ProtocolType.cs</Link>
|
||||
</Compile>
|
||||
@ -52,20 +52,29 @@
|
||||
<Compile Include="$(CommonTestPath)\System\Net\Configuration.Http.cs">
|
||||
<Link>Common\System\Net\Configuration.Http.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\ByteOrder.cs">
|
||||
<Link>Common\System\Net\ByteOrder.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(TargetsWindows)' == 'true' ">
|
||||
<Compile Include="..\..\src\System\Net\NameResolutionPal.Windows.cs">
|
||||
<Link>ProductionCode\System\Net\NameResolutionPal.Windows.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\System\Net\NameResolutionPal.Uap.cs" Condition="'$(TargetGroup)' == 'uap'">
|
||||
<Link>ProductionCode\System\Net\NameResolutionPal.Uap.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\System\Net\NameResolutionPal.Win32.cs" Condition="'$(TargetGroup)' == 'netcoreapp'">
|
||||
<Link>ProductionCode\System\Net\NameResolutionPal.Win32.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\InternalException.cs">
|
||||
<Link>Common\System\Net\InternalException.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\IntPtrHelper.cs">
|
||||
<Link>Common\System\Net\IntPtrHelper.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\SocketProtocolSupportPal.Windows.cs">
|
||||
<Link>System\Net\SocketProtocolSupportPal.Windows</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\SocketAddressPal.Windows.cs">
|
||||
<Link>Common\System\Net\SocketAddressPal.Windows</Link>
|
||||
</Compile>
|
||||
<!-- Debug only -->
|
||||
<Compile Include="$(CommonPath)\System\Net\DebugSafeHandle.cs">
|
||||
<Link>Common\System\Net\DebugSafeHandle.cs</Link>
|
||||
@ -86,12 +95,6 @@
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\Interop.closesocket.cs">
|
||||
<Link>Interop\Windows\Winsock\Interop.closesocket.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\Interop.gethostbyaddr.cs">
|
||||
<Link>Interop\Windows\Winsock\Interop.gethostbyaddr.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\Interop.gethostbyname.cs">
|
||||
<Link>Interop\Windows\Winsock\Interop.gethostbyname.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\Interop.gethostname.cs">
|
||||
<Link>Interop\Windows\Winsock\Interop.gethostname.cs</Link>
|
||||
</Compile>
|
||||
@ -116,6 +119,24 @@
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\SafeFreeAddrInfo.cs">
|
||||
<Link>Interop\Windows\Winsock\SafeFreeAddrInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\AddressInfoEx.cs">
|
||||
<Link>Interop\Windows\Winsock\AddressInfoEx.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Winsock\Interop.GetAddrInfoExW.cs">
|
||||
<Link>Interop\Windows\Winsock\Interop.GetAddrInfoExW.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs">
|
||||
<Link>Common\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Kernel32\Interop.GetProcAddress.cs">
|
||||
<Link>Interop\Windows\Kernel32\Interop.GetProcAddress.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Kernel32\Interop.LoadLibraryEx.cs">
|
||||
<Link>Interop\Windows\Kernel32\Interop.LoadLibraryEx.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\Interop\Windows\Kernel32\Interop.FreeLibrary.cs">
|
||||
<Link>Interop\Windows\Kernel32\Interop.FreeLibrary.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(TargetsUnix)' == 'true' ">
|
||||
<Compile Include="$(CommonPath)\System\Net\SocketAddressPal.Unix.cs">
|
||||
@ -124,9 +145,6 @@
|
||||
<Compile Include="$(CommonPath)\Interop\Interop.CheckedAccess.cs">
|
||||
<Link>Common\System\Net\Internals\Interop.CheckedAccess.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\ByteOrder.cs">
|
||||
<Link>Common\System\Net\Internals\ByteOrder.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="$(CommonPath)\System\Net\InteropIPAddressExtensions.Unix.cs">
|
||||
<Link>Common\System\Net\InteropIPAddressExtensions.Unix.cs</Link>
|
||||
</Compile>
|
||||
|
@ -10,6 +10,8 @@ namespace System.Net
|
||||
{
|
||||
internal static class NameResolutionPal
|
||||
{
|
||||
public static bool SupportsGetAddrInfoAsync => false;
|
||||
|
||||
internal static int FakesEnsureSocketsAreInitializedCallCount
|
||||
{
|
||||
get;
|
||||
@ -49,6 +51,11 @@ namespace System.Net
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
internal static void GetAddrInfoAsync(DnsResolveAsyncResult asyncResult)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
internal static IPHostEntry GetHostByAddr(IPAddress address)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
@ -26,6 +26,9 @@
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\System\Net\DNS.cs">
|
||||
<Link>ProductionCode\System\Net\DNS.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\System\Net\DnsResolveAsyncResult.cs">
|
||||
<Link>ProductionCode\System\Net\DnsResolveAsyncResult.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
Reference in New Issue
Block a user