DnsAbstraction.cs 4.8 KB

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