forked from sshnet/SSH.NET
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDnsAbstraction.cs
More file actions
110 lines (99 loc) · 4.67 KB
/
DnsAbstraction.cs
File metadata and controls
110 lines (99 loc) · 4.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using System;
using System.Net;
using System.Net.Sockets;
#if FEATURE_TAP
using System.Threading.Tasks;
#endif
#if FEATURE_DNS_SYNC
#elif FEATURE_DNS_APM
using Renci.SshNet.Common;
#elif FEATURE_DEVICEINFORMATION_APM
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.Phone.Net.NetworkInformation;
#elif FEATURE_DATAGRAMSOCKET
using System.Collections.Generic;
using Windows.Networking;
using Windows.Networking.Sockets;
#endif
namespace Renci.SshNet.Abstractions
{
internal static class DnsAbstraction
{
/// <summary>
/// Returns the Internet Protocol (IP) addresses for the specified host.
/// </summary>
/// <param name="hostNameOrAddress">The host name or IP address to resolve</param>
/// <returns>
/// An array of type <see cref="IPAddress"/> that holds the IP addresses for the host that
/// is specified by the <paramref name="hostNameOrAddress"/> parameter.
/// </returns>
/// <exception cref="ArgumentNullException"><paramref name="hostNameOrAddress"/> is <c>null</c>.</exception>
/// <exception cref="SocketException">An error is encountered when resolving <paramref name="hostNameOrAddress"/>.</exception>
public static IPAddress[] GetHostAddresses(string hostNameOrAddress)
{
// TODO Eliminate sync variant, and implement timeout
#if FEATURE_DNS_SYNC
return Dns.GetHostAddresses(hostNameOrAddress);
#elif FEATURE_DNS_APM
var asyncResult = Dns.BeginGetHostAddresses(hostNameOrAddress, null, null);
if (!asyncResult.AsyncWaitHandle.WaitOne(Session.InfiniteTimeSpan))
throw new SshOperationTimeoutException("Timeout resolving host name.");
return Dns.EndGetHostAddresses(asyncResult);
#else
IPAddress address;
if (IPAddress.TryParse(hostNameOrAddress, out address))
return new [] { address};
#if FEATURE_DEVICEINFORMATION_APM
var resolveCompleted = new ManualResetEvent(false);
NameResolutionResult nameResolutionResult = null;
DeviceNetworkInformation.ResolveHostNameAsync(new DnsEndPoint(hostNameOrAddress, 0), result =>
{
nameResolutionResult = result;
resolveCompleted.Set();
}, null);
// wait until address is resolved
resolveCompleted.WaitOne();
if (nameResolutionResult.NetworkErrorCode == NetworkError.Success)
{
var addresses = new List<IPAddress>(nameResolutionResult.IPEndPoints.Select(p => p.Address).Distinct());
return addresses.ToArray();
}
throw new SocketException((int)nameResolutionResult.NetworkErrorCode);
#elif FEATURE_DATAGRAMSOCKET
// TODO we may need to only return those IP addresses that are supported on the current system
// TODO http://wojciechkulik.pl/csharp/winrt-how-to-detect-supported-ip-versions
var endpointPairs = DatagramSocket.GetEndpointPairsAsync(new HostName(hostNameOrAddress), "").GetAwaiter().GetResult();
var addresses = new List<IPAddress>();
foreach (var endpointPair in endpointPairs)
{
if (endpointPair.RemoteHostName.Type == HostNameType.Ipv4 || endpointPair.RemoteHostName.Type == HostNameType.Ipv6)
addresses.Add(IPAddress.Parse(endpointPair.RemoteHostName.CanonicalName));
}
if (addresses.Count == 0)
throw new SocketException((int) System.Net.Sockets.SocketError.HostNotFound);
return addresses.ToArray();
#else
throw new NotSupportedException("Resolving hostname to IP address is not implemented.");
#endif // FEATURE_DEVICEINFORMATION_APM
#endif
}
#if FEATURE_TAP
/// <summary>
/// Returns the Internet Protocol (IP) addresses for the specified host.
/// </summary>
/// <param name="hostNameOrAddress">The host name or IP address to resolve</param>
/// <returns>
/// A task with result of an array of type <see cref="IPAddress"/> that holds the IP addresses for the host that
/// is specified by the <paramref name="hostNameOrAddress"/> parameter.
/// </returns>
/// <exception cref="ArgumentNullException"><paramref name="hostNameOrAddress"/> is <c>null</c>.</exception>
/// <exception cref="SocketException">An error is encountered when resolving <paramref name="hostNameOrAddress"/>.</exception>
public static Task<IPAddress[]> GetHostAddressesAsync(string hostNameOrAddress)
{
return Dns.GetHostAddressesAsync(hostNameOrAddress);
}
#endif
}
}