From 124bd4c2c03874f5b4de241e3d89ac95f6048b9a Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sat, 21 Nov 2020 12:59:14 +0000 Subject: Networking: 1 - Network Manager (#4124) * NetworkManager * Config file with additional options. * Update Jellyfin.Networking/Manager/INetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/INetworkManager.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Model/Configuration/ServerConfiguration.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Model/Configuration/ServerConfiguration.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Model/Configuration/ServerConfiguration.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Split function. * Update Jellyfin.Networking/Manager/INetworkManager.cs Co-authored-by: Cody Robibero * fixed iterations * Update Jellyfin.Networking.csproj * Update NetworkManager.cs * Updated to NetCollection 1.03. * Update ServerConfiguration.cs * Update StartupController.cs * Update INetworkManager.cs Removed public * Update INetworkManager.cs * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Claus Vium * Updated comment * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Claus Vium * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Claus Vium * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Claus Vium * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Claus Vium * Update Jellyfin.Networking/Manager/INetworkManager.cs Co-authored-by: Claus Vium * Remove mono code. Removed forced chromecast option * Inverted if * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Moved config into a separate container * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Changed sortedList to dictionary. * Update INetworkManager.cs Changed UpdateSettings param type * Update NetworkManager.cs * Update NetworkManager.cs * Update NetworkManager.cs * Update NetworkConfiguration.cs * Update INetworkManager.cs * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Claus Vium * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Claus Vium * Update MediaBrowser.Model/Configuration/ServerConfiguration.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Model/Configuration/ServerConfiguration.cs Co-authored-by: Cody Robibero * Updated changes github didn't update. * Fixed compilation. * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Removed read locking. * Update NetworkManager.cs Changed configuration event to NamedConfigurationUpdated * updated comment * removed whitespace * Updated NetCollection to 1.0.6 Updated DXCopAnalyser to 3.3.1 * removed NetCollection * Update NetworkManager.cs * Update NetworkExtensions.cs * Update NetworkExtensions.cs Removed function. * Update NetworkExtensions.cs * Update NetworkManager.cs Changed ToString() to AsString() as native collection formats incorrectly. * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update NetworkExtensions.cs * Update Jellyfin.Networking/Configuration/NetworkConfiguration.cs Co-authored-by: h1dden-da3m0n <33120068+h1dden-da3m0n@users.noreply.github.com> * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: h1dden-da3m0n <33120068+h1dden-da3m0n@users.noreply.github.com> * Update Jellyfin.Networking/Configuration/NetworkConfiguration.cs Co-authored-by: h1dden-da3m0n <33120068+h1dden-da3m0n@users.noreply.github.com> * Update Jellyfin.Networking/Configuration/NetworkConfiguration.cs Co-authored-by: h1dden-da3m0n <33120068+h1dden-da3m0n@users.noreply.github.com> * Update MediaBrowser.Common/Net/IPObject.cs Co-authored-by: h1dden-da3m0n <33120068+h1dden-da3m0n@users.noreply.github.com> * updated * Replaced NetCollection with Collection * Update MediaBrowser.Common/Net/NetworkExtensions.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Model/Configuration/PathSubstitution.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/NetworkExtensions.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPObject.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPObject.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPObject.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPHost.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPHost.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPHost.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPHost.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPHost.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPHost.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPHost.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPObject.cs Co-authored-by: Cody Robibero * Update MediaBrowser.Common/Net/IPObject.cs Co-authored-by: Cody Robibero * updated comments. * Updated comments / changes as suggested by @crobibero. * Split function as suggested * Fixed null ref. * Updated comment. * Updated cs to .net5 * Fixed issue with PublishedServerUrl * Fixes * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Claus Vium * Restored locking * optimisation * Added comment * updates. * updated. * updates * updated. * Update IPHost.cs * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Claus Vium * Update NetworkManager.cs * Removed whitespace. * Added debug logging * Added debug. * Update Jellyfin.Networking/Manager/NetworkManager.cs Co-authored-by: Bond-009 * Replaced GetAddressBytes Co-authored-by: Cody Robibero Co-authored-by: Claus Vium Co-authored-by: h1dden-da3m0n <33120068+h1dden-da3m0n@users.noreply.github.com> Co-authored-by: Bond-009 --- MediaBrowser.Common/Net/IPNetAddress.cs | 277 ++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 MediaBrowser.Common/Net/IPNetAddress.cs (limited to 'MediaBrowser.Common/Net/IPNetAddress.cs') diff --git a/MediaBrowser.Common/Net/IPNetAddress.cs b/MediaBrowser.Common/Net/IPNetAddress.cs new file mode 100644 index 000000000..a6f5fe4b3 --- /dev/null +++ b/MediaBrowser.Common/Net/IPNetAddress.cs @@ -0,0 +1,277 @@ +#nullable enable +using System; +using System.Net; +using System.Net.Sockets; + +namespace MediaBrowser.Common.Net +{ + /// + /// An object that holds and IP address and subnet mask. + /// + public class IPNetAddress : IPObject + { + /// + /// Represents an IPNetAddress that has no value. + /// + public static readonly IPNetAddress None = new IPNetAddress(IPAddress.None); + + /// + /// IPv4 multicast address. + /// + public static readonly IPAddress SSDPMulticastIPv4 = IPAddress.Parse("239.255.255.250"); + + /// + /// IPv6 local link multicast address. + /// + public static readonly IPAddress SSDPMulticastIPv6LinkLocal = IPAddress.Parse("ff02::C"); + + /// + /// IPv6 site local multicast address. + /// + public static readonly IPAddress SSDPMulticastIPv6SiteLocal = IPAddress.Parse("ff05::C"); + + /// + /// IP4Loopback address host. + /// + public static readonly IPNetAddress IP4Loopback = IPNetAddress.Parse("127.0.0.1/32"); + + /// + /// IP6Loopback address host. + /// + public static readonly IPNetAddress IP6Loopback = IPNetAddress.Parse("::1"); + + /// + /// Object's IP address. + /// + private IPAddress _address; + + /// + /// Initializes a new instance of the class. + /// + /// Address to assign. + public IPNetAddress(IPAddress address) + { + _address = address ?? throw new ArgumentNullException(nameof(address)); + PrefixLength = (byte)(address.AddressFamily == AddressFamily.InterNetwork ? 32 : 128); + } + + /// + /// Initializes a new instance of the class. + /// + /// IP Address. + /// Mask as a CIDR. + public IPNetAddress(IPAddress address, byte prefixLength) + { + if (address?.IsIPv4MappedToIPv6 ?? throw new ArgumentNullException(nameof(address))) + { + _address = address.MapToIPv4(); + } + else + { + _address = address; + } + + PrefixLength = prefixLength; + } + + /// + /// Gets or sets the object's IP address. + /// + public override IPAddress Address + { + get + { + return _address; + } + + set + { + _address = value ?? IPAddress.None; + } + } + + /// + public override byte PrefixLength { get; set; } + + /// + /// Try to parse the address and subnet strings into an IPNetAddress object. + /// + /// IP address to parse. Can be CIDR or X.X.X.X notation. + /// Resultant object. + /// True if the values parsed successfully. False if not, resulting in the IP being null. + public static bool TryParse(string addr, out IPNetAddress ip) + { + if (!string.IsNullOrEmpty(addr)) + { + addr = addr.Trim(); + + // Try to parse it as is. + if (IPAddress.TryParse(addr, out IPAddress? res)) + { + ip = new IPNetAddress(res); + return true; + } + + // Is it a network? + string[] tokens = addr.Split("/"); + + if (tokens.Length == 2) + { + tokens[0] = tokens[0].TrimEnd(); + tokens[1] = tokens[1].TrimStart(); + + if (IPAddress.TryParse(tokens[0], out res)) + { + // Is the subnet part a cidr? + if (byte.TryParse(tokens[1], out byte cidr)) + { + ip = new IPNetAddress(res, cidr); + return true; + } + + // Is the subnet in x.y.a.b form? + if (IPAddress.TryParse(tokens[1], out IPAddress? mask)) + { + ip = new IPNetAddress(res, MaskToCidr(mask)); + return true; + } + } + } + } + + ip = None; + return false; + } + + /// + /// Parses the string provided, throwing an exception if it is badly formed. + /// + /// String to parse. + /// IPNetAddress object. + public static IPNetAddress Parse(string addr) + { + if (TryParse(addr, out IPNetAddress o)) + { + return o; + } + + throw new ArgumentException("Unable to recognise object :" + addr); + } + + /// + public override bool Contains(IPAddress address) + { + if (address == null) + { + throw new ArgumentNullException(nameof(address)); + } + + if (address.IsIPv4MappedToIPv6) + { + address = address.MapToIPv4(); + } + + var altAddress = NetworkAddressOf(address, PrefixLength); + return NetworkAddress.Address.Equals(altAddress.Address) && NetworkAddress.PrefixLength >= altAddress.PrefixLength; + } + + /// + public override bool Contains(IPObject address) + { + if (address is IPHost addressObj && addressObj.HasAddress) + { + foreach (IPAddress addr in addressObj.GetAddresses()) + { + if (Contains(addr)) + { + return true; + } + } + } + else if (address is IPNetAddress netaddrObj) + { + // Have the same network address, but different subnets? + if (NetworkAddress.Address.Equals(netaddrObj.NetworkAddress.Address)) + { + return NetworkAddress.PrefixLength <= netaddrObj.PrefixLength; + } + + var altAddress = NetworkAddressOf(netaddrObj.Address, PrefixLength); + return NetworkAddress.Address.Equals(altAddress.Address); + } + + return false; + } + + /// + public override bool Equals(IPObject? other) + { + if (other is IPNetAddress otherObj && !Address.Equals(IPAddress.None) && !otherObj.Address.Equals(IPAddress.None)) + { + return Address.Equals(otherObj.Address) && + PrefixLength == otherObj.PrefixLength; + } + + return false; + } + + /// + public override bool Equals(IPAddress address) + { + if (address != null && !address.Equals(IPAddress.None) && !Address.Equals(IPAddress.None)) + { + return address.Equals(Address); + } + + return false; + } + + /// + public override string ToString() + { + return ToString(false); + } + + /// + /// Returns a textual representation of this object. + /// + /// Set to true, if the subnet is to be excluded as part of the address. + /// String representation of this object. + public string ToString(bool shortVersion) + { + if (!Address.Equals(IPAddress.None)) + { + if (Address.Equals(IPAddress.Any)) + { + return "Any IP4 Address"; + } + + if (Address.Equals(IPAddress.IPv6Any)) + { + return "Any IP6 Address"; + } + + if (Address.Equals(IPAddress.Broadcast)) + { + return "Any Address"; + } + + if (shortVersion) + { + return Address.ToString(); + } + + return $"{Address}/{PrefixLength}"; + } + + return string.Empty; + } + + /// + protected override IPObject CalculateNetworkAddress() + { + var value = NetworkAddressOf(_address, PrefixLength); + return new IPNetAddress(value.Address, value.PrefixLength); + } + } +} -- cgit v1.2.3