mirror of https://github.com/Squidex/squidex.git
19 changed files with 176 additions and 47 deletions
@ -0,0 +1,130 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Net; |
||||
|
using System.Net.NetworkInformation; |
||||
|
using System.Net.Sockets; |
||||
|
using System.Threading.Tasks; |
||||
|
using Orleans.Runtime; |
||||
|
|
||||
|
namespace Squidex.Config.Orleans |
||||
|
{ |
||||
|
public static class ConfigUtilities |
||||
|
{ |
||||
|
public static IPAddress SiloAddress { get; } = GetBestIPAddressAsync().Result; |
||||
|
|
||||
|
private static Task<IPAddress> GetBestIPAddressAsync() |
||||
|
{ |
||||
|
return ResolveIPAddressAsync(Dns.GetHostName(), null, AddressFamily.InterNetwork); |
||||
|
} |
||||
|
|
||||
|
internal static async Task<IPAddress> ResolveIPAddressAsync(string addressOrHost, byte[] subnet, AddressFamily family) |
||||
|
{ |
||||
|
var loopback = family == AddressFamily.InterNetwork ? IPAddress.Loopback : IPAddress.IPv6Loopback; |
||||
|
|
||||
|
IList<IPAddress> nodeIps; |
||||
|
|
||||
|
if (string.IsNullOrEmpty(addressOrHost)) |
||||
|
{ |
||||
|
nodeIps = |
||||
|
NetworkInterface.GetAllNetworkInterfaces() |
||||
|
.SelectMany(i => i.GetIPProperties().UnicastAddresses) |
||||
|
.Select(a => a.Address) |
||||
|
.Where(a => a.AddressFamily == family && !IPAddress.IsLoopback(a)) |
||||
|
.ToList(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (addressOrHost.Equals("loopback", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
return loopback; |
||||
|
} |
||||
|
|
||||
|
if (IPAddress.TryParse(addressOrHost, out IPAddress address)) |
||||
|
{ |
||||
|
return address; |
||||
|
} |
||||
|
|
||||
|
nodeIps = await Dns.GetHostAddressesAsync(addressOrHost); |
||||
|
} |
||||
|
|
||||
|
var candidates = new List<IPAddress>(); |
||||
|
|
||||
|
foreach (var nodeIp in nodeIps.Where(x => x.AddressFamily == family)) |
||||
|
{ |
||||
|
if (subnet == null) |
||||
|
{ |
||||
|
candidates.Add(nodeIp); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var ip = nodeIp; |
||||
|
|
||||
|
if (subnet.Select((b, i) => ip.GetAddressBytes()[i] == b).All(x => x)) |
||||
|
{ |
||||
|
candidates.Add(nodeIp); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (candidates.Count > 0) |
||||
|
{ |
||||
|
return PickIPAddress(candidates); |
||||
|
} |
||||
|
|
||||
|
var subnetStr = Utils.EnumerableToString(subnet, null, ".", false); |
||||
|
|
||||
|
throw new ArgumentException($"Hostname '{addressOrHost}' with subnet {subnetStr} and family {family} is not a valid IP address or DNS name"); |
||||
|
} |
||||
|
|
||||
|
internal static IPAddress PickIPAddress(IReadOnlyList<IPAddress> candidates) |
||||
|
{ |
||||
|
IPAddress result = null; |
||||
|
|
||||
|
foreach (IPAddress address in candidates) |
||||
|
{ |
||||
|
if (result == null) |
||||
|
{ |
||||
|
result = address; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (CompareIPAddresses(address, result)) |
||||
|
{ |
||||
|
result = address; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
private static bool CompareIPAddresses(IPAddress lhs, IPAddress rhs) |
||||
|
{ |
||||
|
var lbytes = lhs.GetAddressBytes(); |
||||
|
var rbytes = rhs.GetAddressBytes(); |
||||
|
|
||||
|
if (lbytes.Length != rbytes.Length) |
||||
|
{ |
||||
|
return lbytes.Length < rbytes.Length; |
||||
|
} |
||||
|
|
||||
|
for (int i = 0; i < lbytes.Length; i++) |
||||
|
{ |
||||
|
if (lbytes[i] != rbytes[i]) |
||||
|
{ |
||||
|
return lbytes[i] < rbytes[i]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue