public async Task <IPEndPoint> ResolveAsync(string endpoint, int port, IpVersion ipVersion = IpVersion.IpV4, CancellationToken token = default(CancellationToken)) { string cacheKey = $"{endpoint}:{port}:{ipVersion}"; if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort) { throw new ArgumentOutOfRangeException(nameof(port)); } if (cache.HasKey(cacheKey)) { return(cache.Get <IPEndPoint>(cacheKey)); } var addressFamily = ipVersion.HasFlag(IpVersion.IpV4) ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6; token.ThrowIfCancellationRequested(); IPEndPoint ipEndpoint; var ipAddress = TryGetIpAddress(endpoint); if (ipAddress != null) { ipEndpoint = new IPEndPoint(ipAddress, port); cache.Add(cacheKey, ipEndpoint, TimeSpan.FromMinutes(60)); return(ipEndpoint); } try { #if NET40 var allAddresses = Dns.GetHostAddresses(endpoint); #else var allAddresses = await Dns.GetHostAddressesAsync(endpoint); #endif var firstAddressInFamily = allAddresses.FirstOrDefault(x => x.AddressFamily == addressFamily); if (firstAddressInFamily != null) { ipEndpoint = new IPEndPoint(firstAddressInFamily, port); cache.Add(cacheKey, ipEndpoint, TimeSpan.FromMinutes(60)); return(ipEndpoint); } if (addressFamily == AddressFamily.InterNetwork && ipVersion.HasFlag(IpVersion.IpV6)) { ipEndpoint = await ResolveAsync(endpoint, port, IpVersion.IpV6, token); if (ipEndpoint != null) { cache.Add(cacheKey, ipEndpoint, TimeSpan.FromMinutes(60)); return(ipEndpoint); } } var firstAddress = allAddresses.FirstOrDefault(); if (firstAddress == null) { return(null); } switch (firstAddress.AddressFamily) { case AddressFamily.InterNetwork: #if NET40 ipEndpoint = new IPEndPoint(firstAddress, port); #else ipEndpoint = new IPEndPoint(firstAddress.MapToIPv6(), port); #endif break; case AddressFamily.InterNetworkV6: #if NET40 ipEndpoint = new IPEndPoint(firstAddress, port); #else ipEndpoint = new IPEndPoint(firstAddress.MapToIPv4(), port); #endif break; default: return(null); } cache.Add(cacheKey, ipEndpoint, TimeSpan.FromMinutes(60)); return(ipEndpoint); } catch { return(null); } }