diff options
Diffstat (limited to 'MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs')
| -rw-r--r-- | MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs | 147 |
1 files changed, 89 insertions, 58 deletions
diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs index c27dfd68d..bc3dc360f 100644 --- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -7,6 +7,7 @@ using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Threading; +using MoreLinq; namespace MediaBrowser.Common.Implementations.Networking { @@ -31,14 +32,14 @@ namespace MediaBrowser.Common.Implementations.Networking } } - private volatile List<string> _localIpAddresses; + private volatile List<IPAddress> _localIpAddresses; private readonly object _localIpAddressSyncLock = new object(); /// <summary> /// Gets the machine's local ip address /// </summary> /// <returns>IPAddress.</returns> - public IEnumerable<string> GetLocalIpAddresses() + public IEnumerable<IPAddress> GetLocalIpAddresses() { if (_localIpAddresses == null) { @@ -58,25 +59,24 @@ namespace MediaBrowser.Common.Implementations.Networking return _localIpAddresses; } - private IEnumerable<string> GetLocalIpAddressesInternal() + private IEnumerable<IPAddress> GetLocalIpAddressesInternal() { var list = GetIPsDefault() - .Where(i => !IPAddress.IsLoopback(i)) - .Select(i => i.ToString()) - .Where(FilterIpAddress) .ToList(); - if (list.Count > 0) + if (list.Count == 0) { - return list; + list.AddRange(GetLocalIpAddressesFallback()); } - return GetLocalIpAddressesFallback().Where(FilterIpAddress); + return list.Where(FilterIpAddress).DistinctBy(i => i.ToString()); } - private bool FilterIpAddress(string address) + private bool FilterIpAddress(IPAddress address) { - if (address.StartsWith("169.", StringComparison.OrdinalIgnoreCase)) + var addressString = address.ToString (); + + if (addressString.StartsWith("169.", StringComparison.OrdinalIgnoreCase)) { return false; } @@ -84,8 +84,16 @@ namespace MediaBrowser.Common.Implementations.Networking return true; } - private bool IsInPrivateAddressSpace(string endpoint) + public bool IsInPrivateAddressSpace(string endpoint) { + if (string.Equals(endpoint, "::1", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + + // Handle ipv4 mapped to ipv6 + endpoint = endpoint.Replace("::ffff:", string.Empty); + // Private address space: // http://en.wikipedia.org/wiki/Private_network @@ -96,9 +104,6 @@ namespace MediaBrowser.Common.Implementations.Networking return - // If url was requested with computer name, we may see this - endpoint.IndexOf("::", StringComparison.OrdinalIgnoreCase) != -1 || - endpoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) || endpoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) || endpoint.StartsWith("10.", StringComparison.OrdinalIgnoreCase) || @@ -131,26 +136,41 @@ namespace MediaBrowser.Common.Implementations.Networking throw new ArgumentNullException("endpoint"); } - if (IsInPrivateAddressSpace(endpoint)) - { - return true; - } - - const int lengthMatch = 4; - - if (endpoint.Length >= lengthMatch) + IPAddress address; + if (IPAddress.TryParse(endpoint, out address)) { - var prefix = endpoint.Substring(0, lengthMatch); + var addressString = address.ToString(); - if (GetLocalIpAddresses() - .Any(i => i.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))) + int lengthMatch = 100; + if (address.AddressFamily == AddressFamily.InterNetwork) { - return true; + lengthMatch = 4; + if (IsInPrivateAddressSpace(addressString)) + { + return true; + } + } + else if (address.AddressFamily == AddressFamily.InterNetworkV6) + { + lengthMatch = 10; + if (IsInPrivateAddressSpace(endpoint)) + { + return true; + } } - } - IPAddress address; - if (resolveHost && !IPAddress.TryParse(endpoint, out address)) + // Should be even be doing this with ipv6? + if (addressString.Length >= lengthMatch) + { + var prefix = addressString.Substring(0, lengthMatch); + + if (GetLocalIpAddresses().Any(i => i.ToString().StartsWith(prefix, StringComparison.OrdinalIgnoreCase))) + { + return true; + } + } + } + else if (resolveHost) { Uri uri; if (Uri.TryCreate(endpoint, UriKind.RelativeOrAbsolute, out uri)) @@ -188,33 +208,45 @@ namespace MediaBrowser.Common.Implementations.Networking return Dns.GetHostAddresses(hostName); } - private IEnumerable<IPAddress> GetIPsDefault() - { - foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) - { - var props = adapter.GetIPProperties(); - var gateways = from ga in props.GatewayAddresses - where !ga.Address.Equals(IPAddress.Any) - select true; - - if (!gateways.Any()) - { - continue; - } - - foreach (var uni in props.UnicastAddresses) - { - var address = uni.Address; - if (address.AddressFamily != AddressFamily.InterNetwork) - { - continue; - } - yield return address; - } - } - } - - private IEnumerable<string> GetLocalIpAddressesFallback() + private List<IPAddress> GetIPsDefault() + { + NetworkInterface[] interfaces; + + try + { + interfaces = NetworkInterface.GetAllNetworkInterfaces(); + } + catch (Exception ex) + { + Logger.ErrorException("Error in GetAllNetworkInterfaces", ex); + return new List<IPAddress>(); + } + + return interfaces.SelectMany(network => { + + try + { + Logger.Debug("Querying interface: {0}. Type: {1}. Status: {2}", network.Name, network.NetworkInterfaceType, network.OperationalStatus); + + var properties = network.GetIPProperties(); + + return properties.UnicastAddresses + .Where(i => i.IsDnsEligible) + .Select(i => i.Address) + .Where(i => i.AddressFamily == AddressFamily.InterNetwork) + .ToList(); + } + catch (Exception ex) + { + Logger.ErrorException("Error querying network interface", ex); + return new List<IPAddress>(); + } + + }).DistinctBy(i => i.ToString()) + .ToList(); + } + + private IEnumerable<IPAddress> GetLocalIpAddressesFallback() { var host = Dns.GetHostEntry(Dns.GetHostName()); @@ -222,7 +254,6 @@ namespace MediaBrowser.Common.Implementations.Networking // It's not fool-proof so ultimately the consumer will have to examine them and decide return host.AddressList .Where(i => i.AddressFamily == AddressFamily.InterNetwork) - .Select(i => i.ToString()) .Reverse(); } |
