From 066db8ac7fcece0ab3420b6b6c03e420d22c7306 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Tue, 19 Jul 2022 21:28:04 +0200 Subject: Migrate NetworkManager and Tests to native .NET IP objects --- Jellyfin.Networking/Configuration/NetworkConfiguration.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'Jellyfin.Networking/Configuration/NetworkConfiguration.cs') diff --git a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs index 61db223d9..0ac55c986 100644 --- a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs +++ b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs @@ -113,12 +113,12 @@ namespace Jellyfin.Networking.Configuration public string UDPPortRange { get; set; } = string.Empty; /// - /// Gets or sets a value indicating whether gets or sets IPV6 capability. + /// Gets or sets a value indicating whether IPv6 is enabled or not. /// public bool EnableIPV6 { get; set; } /// - /// Gets or sets a value indicating whether gets or sets IPV4 capability. + /// Gets or sets a value indicating whether IPv6 is enabled or not. /// public bool EnableIPV4 { get; set; } = true; @@ -165,12 +165,6 @@ namespace Jellyfin.Networking.Configuration /// public bool EnableMultiSocketBinding { get; } = true; - /// - /// Gets or sets a value indicating whether all IPv6 interfaces should be treated as on the internal network. - /// Depending on the address range implemented ULA ranges might not be used. - /// - public bool TrustAllIP6Interfaces { get; set; } - /// /// Gets or sets the ports that HDHomerun uses. /// -- cgit v1.2.3 From 2281b8c997dff0fa148bf0f193b37664420aca3e Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Wed, 20 Jul 2022 14:29:30 +0200 Subject: Move away from using Collection, simplify code, add proper ordering --- Emby.Dlna/Main/DlnaEntryPoint.cs | 2 +- .../Configuration/NetworkConfiguration.cs | 4 +- Jellyfin.Networking/Manager/NetworkManager.cs | 54 +++++++++++----------- .../CreateNetworkConfiguration.cs | 2 +- MediaBrowser.Common/Net/INetworkManager.cs | 13 +++--- MediaBrowser.Common/Net/NetworkExtensions.cs | 6 +-- .../Jellyfin.Networking.Tests/NetworkParseTests.cs | 8 ++-- 7 files changed, 42 insertions(+), 47 deletions(-) (limited to 'Jellyfin.Networking/Configuration/NetworkConfiguration.cs') diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 7bc761b71..90c985a81 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -293,7 +293,7 @@ namespace Emby.Dlna.Main if (bindAddresses.Count == 0) { // No interfaces returned, so use loopback. - bindAddresses = _networkManager.GetLoopbacks(); + bindAddresses = _networkManager.GetLoopbacks().ToList(); } foreach (var address in bindAddresses) diff --git a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs index 0ac55c986..be8dc738d 100644 --- a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs +++ b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs @@ -151,9 +151,9 @@ namespace Jellyfin.Networking.Configuration public bool IgnoreVirtualInterfaces { get; set; } = true; /// - /// Gets or sets a value indicating the interfaces that should be ignored. The list can be comma separated. . + /// Gets or sets a value indicating the interface name prefixes that should be ignored. The list can be comma separated and values are case-insensitive. . /// - public string VirtualInterfaceNames { get; set; } = "vEthernet*"; + public string VirtualInterfaceNames { get; set; } = "veth"; /// /// Gets or sets the time (in seconds) between the pings of SSDP gateway monitor. diff --git a/Jellyfin.Networking/Manager/NetworkManager.cs b/Jellyfin.Networking/Manager/NetworkManager.cs index e9e3e1802..757b5994b 100644 --- a/Jellyfin.Networking/Manager/NetworkManager.cs +++ b/Jellyfin.Networking/Manager/NetworkManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Globalization; using System.Linq; using System.Net; @@ -47,7 +46,7 @@ namespace Jellyfin.Networking.Manager /// private readonly Dictionary _publishedServerUrls; - private Collection _remoteAddressFilter; + private List _remoteAddressFilter; /// /// Used to stop "event-racing conditions". @@ -58,12 +57,12 @@ namespace Jellyfin.Networking.Manager /// Unfiltered user defined LAN subnets () /// or internal interface network subnets if undefined by user. /// - private Collection _lanSubnets; + private List _lanSubnets; /// /// User defined list of subnets to excluded from the LAN. /// - private Collection _excludedSubnets; + private List _excludedSubnets; /// /// List of interfaces to bind to. @@ -95,7 +94,7 @@ namespace Jellyfin.Networking.Manager _macAddresses = new List(); _publishedServerUrls = new Dictionary(); _eventFireLock = new object(); - _remoteAddressFilter = new Collection(); + _remoteAddressFilter = new List(); UpdateSettings(_configurationManager.GetNetworkConfiguration()); @@ -225,8 +224,8 @@ namespace Jellyfin.Networking.Manager { try { - IPInterfaceProperties ipProperties = adapter.GetIPProperties(); - PhysicalAddress mac = adapter.GetPhysicalAddress(); + var ipProperties = adapter.GetIPProperties(); + var mac = adapter.GetPhysicalAddress(); // Populate MAC list if (adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback && PhysicalAddress.None.Equals(mac)) @@ -235,7 +234,7 @@ namespace Jellyfin.Networking.Manager } // Populate interface list - foreach (UnicastIPAddressInformation info in ipProperties.UnicastAddresses) + foreach (var info in ipProperties.UnicastAddresses) { if (IsIpv4Enabled && info.Address.AddressFamily == AddressFamily.InterNetwork) { @@ -364,8 +363,8 @@ namespace Jellyfin.Networking.Manager // Use explicit bind addresses if (config.LocalNetworkAddresses.Length > 0) { - _bindAddresses = config.LocalNetworkAddresses.Select(p => IPAddress.TryParse(p, out var address) - ? address + _bindAddresses = config.LocalNetworkAddresses.Select(p => IPAddress.TryParse(p, out var addresses) + ? addresses : (_interfaces.Where(x => x.Name.Equals(p, StringComparison.OrdinalIgnoreCase)).Select(x => x.Address).FirstOrDefault() ?? IPAddress.None)).ToList(); _bindAddresses.RemoveAll(x => x == IPAddress.None); } @@ -525,13 +524,11 @@ namespace Jellyfin.Networking.Manager var address = IPAddress.Parse(split[0]); var network = new IPNetwork(address, int.Parse(split[1], CultureInfo.InvariantCulture)); var index = int.Parse(parts[1], CultureInfo.InvariantCulture); - if (address.AddressFamily == AddressFamily.InterNetwork) + if (address.AddressFamily == AddressFamily.InterNetwork || address.AddressFamily == AddressFamily.InterNetworkV6) { - _interfaces.Add(new IPData(address, network, parts[2])); - } - else if (address.AddressFamily == AddressFamily.InterNetworkV6) - { - _interfaces.Add(new IPData(address, network, parts[2])); + var data = new IPData(address, network, parts[2]); + data.Index = index; + _interfaces.Add(data); } } } @@ -562,9 +559,9 @@ namespace Jellyfin.Networking.Manager } /// - public bool TryParseInterface(string intf, out Collection result) + public bool TryParseInterface(string intf, out List result) { - result = new Collection(); + result = new List(); if (string.IsNullOrEmpty(intf)) { return false; @@ -573,7 +570,7 @@ namespace Jellyfin.Networking.Manager if (_interfaces != null) { // Match all interfaces starting with names starting with token - var matchedInterfaces = _interfaces.Where(s => s.Name.Equals(intf.ToLowerInvariant(), StringComparison.OrdinalIgnoreCase)); + var matchedInterfaces = _interfaces.Where(s => s.Name.Equals(intf.ToLowerInvariant(), StringComparison.OrdinalIgnoreCase)).OrderBy(x => x.Index); if (matchedInterfaces.Any()) { _logger.LogInformation("Interface {Token} used in settings. Using its interface addresses.", intf); @@ -626,14 +623,14 @@ namespace Jellyfin.Networking.Manager } /// - public IReadOnlyCollection GetMacAddresses() + public IReadOnlyList GetMacAddresses() { // Populated in construction - so always has values. return _macAddresses; } /// - public List GetLoopbacks() + public IReadOnlyList GetLoopbacks() { var loopbackNetworks = new List(); if (IsIpv4Enabled) @@ -650,7 +647,7 @@ namespace Jellyfin.Networking.Manager } /// - public List GetAllBindInterfaces(bool individualInterfaces = false) + public IReadOnlyList GetAllBindInterfaces(bool individualInterfaces = false) { if (_bindAddresses.Count == 0) { @@ -816,7 +813,7 @@ namespace Jellyfin.Networking.Manager } /// - public List GetInternalBindAddresses() + public IReadOnlyList GetInternalBindAddresses() { if (_bindAddresses.Count == 0) { @@ -833,7 +830,8 @@ namespace Jellyfin.Networking.Manager // Select all local bind addresses return _interfaces.Where(x => _bindAddresses.Contains(x.Address)) .Where(x => IsInLocalNetwork(x.Address)) - .OrderBy(x => x.Index).ToList(); + .OrderBy(x => x.Index) + .ToList(); } /// @@ -892,7 +890,7 @@ namespace Jellyfin.Networking.Manager interfaces = interfaces.Where(x => IsInLocalNetwork(x.Address)).ToList(); } - foreach (var intf in _interfaces) + foreach (var intf in interfaces) { if (intf.Subnet.Contains(address)) { @@ -942,7 +940,7 @@ namespace Jellyfin.Networking.Manager foreach (var data in validPublishedServerUrls) { // Get address interface - var intf = _interfaces.FirstOrDefault(s => s.Subnet.Contains(data.Key.Address)); + var intf = _interfaces.OrderBy(x => x.Index).FirstOrDefault(s => s.Subnet.Contains(data.Key.Address)); // Remaining. Match anything. if (data.Key.Address.Equals(IPAddress.Broadcast)) @@ -1017,7 +1015,7 @@ namespace Jellyfin.Networking.Manager defaultGateway = addr; } - var intf = _interfaces.Where(x => x.Subnet.Contains(addr)).FirstOrDefault(); + var intf = _interfaces.Where(x => x.Subnet.Contains(addr)).OrderBy(x => x.Index).FirstOrDefault(); if (bindAddress == null && intf != null && intf.Subnet.Contains(source)) { @@ -1082,7 +1080,7 @@ namespace Jellyfin.Networking.Manager { result = string.Empty; // Get the first WAN interface address that isn't a loopback. - var extResult = _interfaces.Where(p => !IsInLocalNetwork(p.Address)); + var extResult = _interfaces.Where(p => !IsInLocalNetwork(p.Address)).OrderBy(x => x.Index); IPAddress? hasResult = null; // Does the request originate in one of the interface subnets? diff --git a/Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs b/Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs index ceeaa26e6..b67017281 100644 --- a/Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs +++ b/Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs @@ -114,7 +114,7 @@ public class CreateNetworkConfiguration : IMigrationRoutine public bool IgnoreVirtualInterfaces { get; set; } = true; - public string VirtualInterfaceNames { get; set; } = "veth*"; + public string VirtualInterfaceNames { get; set; } = "veth"; public string[] PublishedServerUriBySubnet { get; set; } = Array.Empty(); diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 9f4853557..bb0e2dcb3 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Net; using System.Net.NetworkInformation; using Microsoft.AspNetCore.Http; @@ -34,13 +33,13 @@ namespace MediaBrowser.Common.Net /// If all the interfaces are specified, and none are excluded, it returns zero items /// to represent any address. /// When false, return or for all interfaces. - List GetAllBindInterfaces(bool individualInterfaces = false); + IReadOnlyList GetAllBindInterfaces(bool individualInterfaces = false); /// - /// Returns a collection containing the loopback interfaces. + /// Returns a list containing the loopback interfaces. /// /// List{IPData}. - List GetLoopbacks(); + IReadOnlyList GetLoopbacks(); /// /// Retrieves the bind address to use in system url's. (Server Discovery, PlayTo, LiveTV, SystemInfo) @@ -97,7 +96,7 @@ namespace MediaBrowser.Common.Net /// Get a list of all the MAC addresses associated with active interfaces. /// /// List of MAC addresses. - IReadOnlyCollection GetMacAddresses(); + IReadOnlyList GetMacAddresses(); /// /// Returns true if the address is part of the user defined LAN. @@ -122,13 +121,13 @@ namespace MediaBrowser.Common.Net /// Interface name. /// Resultant object's ip addresses, if successful. /// Success of the operation. - bool TryParseInterface(string intf, out Collection? result); + bool TryParseInterface(string intf, out List? result); /// /// Returns all the internal Bind interface addresses. /// /// An internal list of interfaces addresses. - List GetInternalBindAddresses(); + IReadOnlyList GetInternalBindAddresses(); /// /// Checks to see if has access. diff --git a/MediaBrowser.Common/Net/NetworkExtensions.cs b/MediaBrowser.Common/Net/NetworkExtensions.cs index ae1e47ccc..316c2ebcd 100644 --- a/MediaBrowser.Common/Net/NetworkExtensions.cs +++ b/MediaBrowser.Common/Net/NetworkExtensions.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.HttpOverrides; using System; -using System.Collections.ObjectModel; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Net; using System.Net.Sockets; @@ -148,9 +148,9 @@ namespace MediaBrowser.Common.Net /// Collection of . /// Boolean signaling if negated or not negated values should be parsed. /// True if parsing was successful. - public static bool TryParseSubnets(string[] values, out Collection result, bool negated = false) + public static bool TryParseSubnets(string[] values, out List result, bool negated = false) { - result = new Collection(); + result = new List(); if (values == null || values.Length == 0) { diff --git a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs index 5b9739dd3..c45a9c9f5 100644 --- a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs +++ b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs @@ -1,5 +1,5 @@ using System; -using System.Collections.ObjectModel; +using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net; @@ -49,8 +49,6 @@ namespace Jellyfin.Networking.Tests { EnableIPV6 = true, EnableIPV4 = true, - IgnoreVirtualInterfaces = true, - VirtualInterfaceNames = "veth", LocalNetworkSubnets = lan?.Split(';') ?? throw new ArgumentNullException(nameof(lan)) }; @@ -208,7 +206,7 @@ namespace Jellyfin.Networking.Tests using var nm = new NetworkManager(GetMockConfig(conf), new NullLogger()); NetworkManager.MockNetworkSettings = string.Empty; - _ = nm.TryParseInterface(result, out Collection? resultObj); + _ = nm.TryParseInterface(result, out List? resultObj); // Check to see if dns resolution is working. If not, skip test. _ = NetworkExtensions.TryParseHost(source, out var host); @@ -277,7 +275,7 @@ namespace Jellyfin.Networking.Tests using var nm = new NetworkManager(GetMockConfig(conf), new NullLogger()); NetworkManager.MockNetworkSettings = string.Empty; - if (nm.TryParseInterface(result, out Collection? resultObj) && resultObj != null) + if (nm.TryParseInterface(result, out List? resultObj) && resultObj != null) { // Parse out IPAddresses so we can do a string comparison. (Ignore subnet masks). result = resultObj.First().Address.ToString(); -- cgit v1.2.3 From 8075cb4e99da4468d9474d1ad2e7668d96cd5224 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Wed, 20 Jul 2022 16:14:56 +0200 Subject: Cleanup and sort NetworkConfiguration --- .../Configuration/NetworkConfiguration.cs | 151 ++++++++++----------- 1 file changed, 73 insertions(+), 78 deletions(-) (limited to 'Jellyfin.Networking/Configuration/NetworkConfiguration.cs') diff --git a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs index be8dc738d..e9f6d597b 100644 --- a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs +++ b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs @@ -21,21 +21,6 @@ namespace Jellyfin.Networking.Configuration private string _baseUrl = string.Empty; - /// - /// Gets or sets a value indicating whether the server should force connections over HTTPS. - /// - public bool RequireHttps { get; set; } - - /// - /// Gets or sets the filesystem path of an X.509 certificate to use for SSL. - /// - public string CertificatePath { get; set; } = string.Empty; - - /// - /// Gets or sets the password required to access the X.509 certificate data in the file specified by . - /// - public string CertificatePassword { get; set; } = string.Empty; - /// /// Gets or sets a value used to specify the URL prefix that your Jellyfin instance can be accessed at. /// @@ -70,16 +55,28 @@ namespace Jellyfin.Networking.Configuration } /// - /// Gets or sets the public HTTPS port. + /// Gets or sets a value indicating whether to use HTTPS. /// - /// The public HTTPS port. - public int PublicHttpsPort { get; set; } = DefaultHttpsPort; + /// + /// In order for HTTPS to be used, in addition to setting this to true, valid values must also be + /// provided for and . + /// + public bool EnableHttps { get; set; } /// - /// Gets or sets the HTTP server port number. + /// Gets or sets a value indicating whether the server should force connections over HTTPS. /// - /// The HTTP server port number. - public int HttpServerPortNumber { get; set; } = DefaultHttpPort; + public bool RequireHttps { get; set; } + + /// + /// Gets or sets the filesystem path of an X.509 certificate to use for SSL. + /// + public string CertificatePath { get; set; } = string.Empty; + + /// + /// Gets or sets the password required to access the X.509 certificate data in the file specified by . + /// + public string CertificatePassword { get; set; } = string.Empty; /// /// Gets or sets the HTTPS server port number. @@ -88,13 +85,16 @@ namespace Jellyfin.Networking.Configuration public int HttpsPortNumber { get; set; } = DefaultHttpsPort; /// - /// Gets or sets a value indicating whether to use HTTPS. + /// Gets or sets the public HTTPS port. /// - /// - /// In order for HTTPS to be used, in addition to setting this to true, valid values must also be - /// provided for and . - /// - public bool EnableHttps { get; set; } + /// The public HTTPS port. + public int PublicHttpsPort { get; set; } = DefaultHttpsPort; + + /// + /// Gets or sets the HTTP server port number. + /// + /// The HTTP server port number. + public int HttpServerPortNumber { get; set; } = DefaultHttpPort; /// /// Gets or sets the public mapped port. @@ -108,14 +108,19 @@ namespace Jellyfin.Networking.Configuration public bool UPnPCreateHttpPortMap { get; set; } /// - /// Gets or sets the UDPPortRange. + /// Gets or sets a value indicating whether Autodiscovery is enabled. /// - public string UDPPortRange { get; set; } = string.Empty; + public bool AutoDiscovery { get; set; } = true; /// - /// Gets or sets a value indicating whether IPv6 is enabled or not. + /// Gets or sets a value indicating whether Autodiscovery tracing is enabled. /// - public bool EnableIPV6 { get; set; } + public bool AutoDiscoveryTracing { get; set; } + + /// + /// Gets or sets a value indicating whether to enable automatic port forwarding. + /// + public bool EnableUPnP { get; set; } /// /// Gets or sets a value indicating whether IPv6 is enabled or not. @@ -123,17 +128,34 @@ namespace Jellyfin.Networking.Configuration public bool EnableIPV4 { get; set; } = true; /// - /// Gets or sets a value indicating whether detailed SSDP logs are sent to the console/log. - /// "Emby.Dlna": "Debug" must be set in logging.default.json for this property to have any effect. + /// Gets or sets a value indicating whether IPv6 is enabled or not. /// - public bool EnableSSDPTracing { get; set; } + public bool EnableIPV6 { get; set; } /// - /// Gets or sets the SSDPTracingFilter - /// Gets or sets a value indicating whether an IP address is to be used to filter the detailed ssdp logs that are being sent to the console/log. - /// If the setting "Emby.Dlna": "Debug" msut be set in logging.default.json for this property to work. + /// Gets or sets a value indicating whether access outside of the LAN is permitted. /// - public string SSDPTracingFilter { get; set; } = string.Empty; + public bool EnableRemoteAccess { get; set; } = true; + + /// + /// Gets or sets the subnets that are deemed to make up the LAN. + /// + public string[] LocalNetworkSubnets { get; set; } = Array.Empty(); + + /// + /// Gets or sets the interface addresses which Jellyfin will bind to. If empty, all interfaces will be used. + /// + public string[] LocalNetworkAddresses { get; set; } = Array.Empty(); + + /// + /// Gets or sets the known proxies. If the proxy is a network, it's added to the KnownNetworks. + /// + public string[] KnownProxies { get; set; } = Array.Empty(); + + /// + /// Gets or sets the UDPPortRange. + /// + public string UDPPortRange { get; set; } = string.Empty; /// /// Gets or sets the number of times SSDP UDP messages are sent. @@ -156,19 +178,9 @@ namespace Jellyfin.Networking.Configuration public string VirtualInterfaceNames { get; set; } = "veth"; /// - /// Gets or sets the time (in seconds) between the pings of SSDP gateway monitor. - /// - public int GatewayMonitorPeriod { get; set; } = 60; - - /// - /// Gets a value indicating whether multi-socket binding is available. - /// - public bool EnableMultiSocketBinding { get; } = true; - - /// - /// Gets or sets the ports that HDHomerun uses. + /// Gets or sets a value indicating whether the published server uri is based on information in HTTP requests. /// - public string HDHomerunPortRange { get; set; } = string.Empty; + public bool EnablePublishedServerUriByRequest { get; set; } = false; /// /// Gets or sets the PublishedServerUriBySubnet @@ -177,14 +189,14 @@ namespace Jellyfin.Networking.Configuration public string[] PublishedServerUriBySubnet { get; set; } = Array.Empty(); /// - /// Gets or sets a value indicating whether Autodiscovery tracing is enabled. + /// Gets a value indicating whether multi-socket binding is available. /// - public bool AutoDiscoveryTracing { get; set; } + public bool EnableMultiSocketBinding { get; } = true; /// - /// Gets or sets a value indicating whether Autodiscovery is enabled. + /// Gets or sets the ports that HDHomerun uses. /// - public bool AutoDiscovery { get; set; } = true; + public string HDHomerunPortRange { get; set; } = string.Empty; /// /// Gets or sets the filter for remote IP connectivity. Used in conjuntion with . @@ -197,33 +209,16 @@ namespace Jellyfin.Networking.Configuration public bool IsRemoteIPFilterBlacklist { get; set; } /// - /// Gets or sets a value indicating whether to enable automatic port forwarding. - /// - public bool EnableUPnP { get; set; } - - /// - /// Gets or sets a value indicating whether access outside of the LAN is permitted. - /// - public bool EnableRemoteAccess { get; set; } = true; - - /// - /// Gets or sets the subnets that are deemed to make up the LAN. - /// - public string[] LocalNetworkSubnets { get; set; } = Array.Empty(); - - /// - /// Gets or sets the interface addresses which Jellyfin will bind to. If empty, all interfaces will be used. - /// - public string[] LocalNetworkAddresses { get; set; } = Array.Empty(); - - /// - /// Gets or sets the known proxies. If the proxy is a network, it's added to the KnownNetworks. + /// Gets or sets a value indicating whether detailed SSDP logs are sent to the console/log. + /// "Emby.Dlna": "Debug" must be set in logging.default.json for this property to have any effect. /// - public string[] KnownProxies { get; set; } = Array.Empty(); + public bool EnableSSDPTracing { get; set; } /// - /// Gets or sets a value indicating whether the published server uri is based on information in HTTP requests. + /// Gets or sets the SSDPTracingFilter + /// Gets or sets a value indicating whether an IP address is to be used to filter the detailed ssdp logs that are being sent to the console/log. + /// If the setting "Emby.Dlna": "Debug" msut be set in logging.default.json for this property to work. /// - public bool EnablePublishedServerUriByRequest { get; set; } = false; + public string SSDPTracingFilter { get; set; } = string.Empty; } } -- cgit v1.2.3 From b5c1d6129e394e40cd8a6bf338184edfe58c0ef4 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Thu, 21 Jul 2022 11:43:45 +0200 Subject: Remove more unused network configuration parameters --- .../Configuration/NetworkConfiguration.cs | 48 ---------------------- 1 file changed, 48 deletions(-) (limited to 'Jellyfin.Networking/Configuration/NetworkConfiguration.cs') diff --git a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs index e9f6d597b..642af7dda 100644 --- a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs +++ b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs @@ -102,21 +102,11 @@ namespace Jellyfin.Networking.Configuration /// The public mapped port. public int PublicPort { get; set; } = DefaultHttpPort; - /// - /// Gets or sets a value indicating whether the http port should be mapped as part of UPnP automatic port forwarding. - /// - public bool UPnPCreateHttpPortMap { get; set; } - /// /// Gets or sets a value indicating whether Autodiscovery is enabled. /// public bool AutoDiscovery { get; set; } = true; - /// - /// Gets or sets a value indicating whether Autodiscovery tracing is enabled. - /// - public bool AutoDiscoveryTracing { get; set; } - /// /// Gets or sets a value indicating whether to enable automatic port forwarding. /// @@ -152,21 +142,6 @@ namespace Jellyfin.Networking.Configuration /// public string[] KnownProxies { get; set; } = Array.Empty(); - /// - /// Gets or sets the UDPPortRange. - /// - public string UDPPortRange { get; set; } = string.Empty; - - /// - /// Gets or sets the number of times SSDP UDP messages are sent. - /// - public int UDPSendCount { get; set; } = 2; - - /// - /// Gets or sets the delay between each groups of SSDP messages (in ms). - /// - public int UDPSendDelay { get; set; } = 100; - /// /// Gets or sets a value indicating whether address names that match should be Ignore for the purposes of binding. /// @@ -188,16 +163,6 @@ namespace Jellyfin.Networking.Configuration /// public string[] PublishedServerUriBySubnet { get; set; } = Array.Empty(); - /// - /// Gets a value indicating whether multi-socket binding is available. - /// - public bool EnableMultiSocketBinding { get; } = true; - - /// - /// Gets or sets the ports that HDHomerun uses. - /// - public string HDHomerunPortRange { get; set; } = string.Empty; - /// /// Gets or sets the filter for remote IP connectivity. Used in conjuntion with . /// @@ -207,18 +172,5 @@ namespace Jellyfin.Networking.Configuration /// Gets or sets a value indicating whether contains a blacklist or a whitelist. Default is a whitelist. /// public bool IsRemoteIPFilterBlacklist { get; set; } - - /// - /// Gets or sets a value indicating whether detailed SSDP logs are sent to the console/log. - /// "Emby.Dlna": "Debug" must be set in logging.default.json for this property to have any effect. - /// - public bool EnableSSDPTracing { get; set; } - - /// - /// Gets or sets the SSDPTracingFilter - /// Gets or sets a value indicating whether an IP address is to be used to filter the detailed ssdp logs that are being sent to the console/log. - /// If the setting "Emby.Dlna": "Debug" msut be set in logging.default.json for this property to work. - /// - public string SSDPTracingFilter { get; set; } = string.Empty; } } -- cgit v1.2.3 From bd9a940fed129d99fe9ffedafec324e795549c90 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sat, 1 Oct 2022 20:00:35 +0200 Subject: Declare VirtualInterfaceNames as string array for consistency --- .../Configuration/NetworkConfiguration.cs | 2 +- Jellyfin.Networking/Manager/NetworkManager.cs | 31 +++++++++++++--------- .../CreateNetworkConfiguration.cs | 2 +- 3 files changed, 21 insertions(+), 14 deletions(-) (limited to 'Jellyfin.Networking/Configuration/NetworkConfiguration.cs') diff --git a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs index 642af7dda..f90419851 100644 --- a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs +++ b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs @@ -150,7 +150,7 @@ namespace Jellyfin.Networking.Configuration /// /// Gets or sets a value indicating the interface name prefixes that should be ignored. The list can be comma separated and values are case-insensitive. . /// - public string VirtualInterfaceNames { get; set; } = "veth"; + public string[] VirtualInterfaceNames { get; set; } = new string[] { "veth" }; /// /// Gets or sets a value indicating whether the published server uri is based on information in HTTP requests. diff --git a/Jellyfin.Networking/Manager/NetworkManager.cs b/Jellyfin.Networking/Manager/NetworkManager.cs index 0f8f1a36a..146340989 100644 --- a/Jellyfin.Networking/Manager/NetworkManager.cs +++ b/Jellyfin.Networking/Manager/NetworkManager.cs @@ -359,12 +359,11 @@ namespace Jellyfin.Networking.Manager { // Remove potentially exisiting * and split config string into prefixes var virtualInterfacePrefixes = config.VirtualInterfaceNames - .Replace("*", string.Empty, StringComparison.OrdinalIgnoreCase) - .ToLowerInvariant() - .Split(','); + .Select(i => i.ToLowerInvariant() + .Replace("*", string.Empty, StringComparison.OrdinalIgnoreCase)); // Check all interfaces for matches against the prefixes and remove them - if (_interfaces.Count > 0 && virtualInterfacePrefixes.Length > 0) + if (_interfaces.Count > 0 && virtualInterfacePrefixes.Any()) { foreach (var virtualInterfacePrefix in virtualInterfacePrefixes) { @@ -726,7 +725,15 @@ namespace Jellyfin.Networking.Manager if (MatchesPublishedServerUrl(source, isExternal, out string res, out port)) { - _logger.LogInformation("{Source}: Using BindAddress {Address}:{Port}", source, res, port); + if (port != null) + { + _logger.LogInformation("{Source}: Using BindAddress {Address}:{Port}", source, res, port); + } + else + { + _logger.LogInformation("{Source}: Using BindAddress {Address}", source, res); + } + return res; } @@ -756,7 +763,7 @@ namespace Jellyfin.Networking.Manager if (intf.Address.Equals(source)) { result = NetworkExtensions.FormatIpString(intf.Address); - _logger.LogDebug("{Source}: GetBindInterface: Has found matching interface. {Result}", source, result); + _logger.LogDebug("{Source}: GetBindInterface: Has found matching interface: {Result}", source, result); return result; } } @@ -768,14 +775,14 @@ namespace Jellyfin.Networking.Manager if (intf.Subnet.Contains(source)) { result = NetworkExtensions.FormatIpString(intf.Address); - _logger.LogDebug("{Source}: GetBindInterface: Has source, matched best internal interface on range. {Result}", source, result); + _logger.LogDebug("{Source}: GetBindInterface: Has source, matched best internal interface on range: {Result}", source, result); return result; } } } result = NetworkExtensions.FormatIpString(availableInterfaces.First().Address); - _logger.LogDebug("{Source}: GetBindInterface: Matched first internal interface. {Result}", source, result); + _logger.LogDebug("{Source}: GetBindInterface: Matched first internal interface: {Result}", source, result); return result; } @@ -956,7 +963,7 @@ namespace Jellyfin.Networking.Manager if (bindAddress != null) { result = NetworkExtensions.FormatIpString(bindAddress); - _logger.LogDebug("{Source}: GetBindInterface: Has source, found a matching external bind interface. {Result}", source, result); + _logger.LogDebug("{Source}: GetBindInterface: Has source, found a matching external bind interface: {Result}", source, result); return true; } } @@ -976,7 +983,7 @@ namespace Jellyfin.Networking.Manager if (bindAddress != null) { result = NetworkExtensions.FormatIpString(bindAddress); - _logger.LogWarning("{Source}: Request received, matching internal interface bind found. {Result}", source, result); + _logger.LogWarning("{Source}: Request received, matching internal interface bind found: {Result}", source, result); return true; } } @@ -1006,7 +1013,7 @@ namespace Jellyfin.Networking.Manager if (!IsInLocalNetwork(intf.Address) && intf.Subnet.Contains(source)) { result = NetworkExtensions.FormatIpString(intf.Address); - _logger.LogDebug("{Source}: GetBindInterface: Selected best external on interface on range. {Result}", source, result); + _logger.LogDebug("{Source}: GetBindInterface: Selected best external on interface on range: {Result}", source, result); return true; } } @@ -1014,7 +1021,7 @@ namespace Jellyfin.Networking.Manager if (hasResult != null) { result = NetworkExtensions.FormatIpString(hasResult); - _logger.LogDebug("{Source}: GetBindInterface: Selected first external interface. {Result}", source, result); + _logger.LogDebug("{Source}: GetBindInterface: Selected first external interface: {Result}", source, result); return true; } diff --git a/Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs b/Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs index b67017281..2c2715526 100644 --- a/Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs +++ b/Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs @@ -114,7 +114,7 @@ public class CreateNetworkConfiguration : IMigrationRoutine public bool IgnoreVirtualInterfaces { get; set; } = true; - public string VirtualInterfaceNames { get; set; } = "veth"; + public string[] VirtualInterfaceNames { get; set; } = new string[] { "veth" }; public string[] PublishedServerUriBySubnet { get; set; } = Array.Empty(); -- cgit v1.2.3 From 4eba16c6726564b159e395e188ec89f69d990e52 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Wed, 15 Feb 2023 22:34:44 +0100 Subject: Apply review suggestions --- .../EntryPoints/UdpServerEntryPoint.cs | 5 +- .../Configuration/NetworkConfiguration.cs | 4 +- .../NetworkConfigurationExtensions.cs | 2 +- Jellyfin.Networking/Manager/NetworkManager.cs | 101 ++++++++++++--------- .../Extensions/ApiServiceCollectionExtensions.cs | 2 +- MediaBrowser.Common/Net/INetworkManager.cs | 6 +- MediaBrowser.Common/Net/NetworkExtensions.cs | 67 ++++++-------- .../NetworkManagerTests.cs | 8 +- .../Jellyfin.Networking.Tests/NetworkParseTests.cs | 32 +++---- tests/Jellyfin.Server.Tests/ParseNetworkTests.cs | 8 +- 10 files changed, 117 insertions(+), 118 deletions(-) (limited to 'Jellyfin.Networking/Configuration/NetworkConfiguration.cs') diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index c2ffaf1bd..b5a33a735 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -102,7 +102,10 @@ namespace Emby.Server.Implementations.EntryPoints _udpServers.Add(new UdpServer(_logger, _appHost, _config, System.Net.IPAddress.Any, PortNumber)); } - _udpServers.ForEach(u => u.Start(_cancellationTokenSource.Token)); + foreach (var server in _udpServers) + { + server.Start(_cancellationTokenSource.Token); + } } catch (SocketException ex) { diff --git a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs index f90419851..f31d2bce2 100644 --- a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs +++ b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs @@ -115,12 +115,12 @@ namespace Jellyfin.Networking.Configuration /// /// Gets or sets a value indicating whether IPv6 is enabled or not. /// - public bool EnableIPV4 { get; set; } = true; + public bool EnableIPv4 { get; set; } = true; /// /// Gets or sets a value indicating whether IPv6 is enabled or not. /// - public bool EnableIPV6 { get; set; } + public bool EnableIPv6 { get; set; } /// /// Gets or sets a value indicating whether access outside of the LAN is permitted. diff --git a/Jellyfin.Networking/Configuration/NetworkConfigurationExtensions.cs b/Jellyfin.Networking/Configuration/NetworkConfigurationExtensions.cs index 8cbe398b0..3ba6bb8fc 100644 --- a/Jellyfin.Networking/Configuration/NetworkConfigurationExtensions.cs +++ b/Jellyfin.Networking/Configuration/NetworkConfigurationExtensions.cs @@ -14,7 +14,7 @@ namespace Jellyfin.Networking.Configuration /// The . public static NetworkConfiguration GetNetworkConfiguration(this IConfigurationManager config) { - return config.GetConfiguration("network"); + return config.GetConfiguration(NetworkConfigurationStore.StoreKey); } } } diff --git a/Jellyfin.Networking/Manager/NetworkManager.cs b/Jellyfin.Networking/Manager/NetworkManager.cs index ca9e9274f..5f82950fc 100644 --- a/Jellyfin.Networking/Manager/NetworkManager.cs +++ b/Jellyfin.Networking/Manager/NetworkManager.cs @@ -111,12 +111,12 @@ namespace Jellyfin.Networking.Manager /// /// Gets a value indicating whether IP4 is enabled. /// - public bool IsIpv4Enabled => _configurationManager.GetNetworkConfiguration().EnableIPV4; + public bool IsIPv4Enabled => _configurationManager.GetNetworkConfiguration().EnableIPv4; /// /// Gets a value indicating whether IP6 is enabled. /// - public bool IsIpv6Enabled => _configurationManager.GetNetworkConfiguration().EnableIPV6; + public bool IsIPv6Enabled => _configurationManager.GetNetworkConfiguration().EnableIPv6; /// /// Gets a value indicating whether is all IPv6 interfaces are trusted as internal. @@ -229,7 +229,7 @@ namespace Jellyfin.Networking.Manager // Populate interface list foreach (var info in ipProperties.UnicastAddresses) { - if (IsIpv4Enabled && info.Address.AddressFamily == AddressFamily.InterNetwork) + if (IsIPv4Enabled && info.Address.AddressFamily == AddressFamily.InterNetwork) { var interfaceObject = new IPData(info.Address, new IPNetwork(info.Address, info.PrefixLength), adapter.Name); interfaceObject.Index = ipProperties.GetIPv4Properties().Index; @@ -237,7 +237,7 @@ namespace Jellyfin.Networking.Manager _interfaces.Add(interfaceObject); } - else if (IsIpv6Enabled && info.Address.AddressFamily == AddressFamily.InterNetworkV6) + else if (IsIPv6Enabled && info.Address.AddressFamily == AddressFamily.InterNetworkV6) { var interfaceObject = new IPData(info.Address, new IPNetwork(info.Address, info.PrefixLength), adapter.Name); interfaceObject.Index = ipProperties.GetIPv6Properties().Index; @@ -268,12 +268,12 @@ namespace Jellyfin.Networking.Manager { _logger.LogWarning("No interface information available. Using loopback interface(s)."); - if (IsIpv4Enabled && !IsIpv6Enabled) + if (IsIPv4Enabled && !IsIPv6Enabled) { _interfaces.Add(new IPData(IPAddress.Loopback, new IPNetwork(IPAddress.Loopback, 8), "lo")); } - if (!IsIpv4Enabled && IsIpv6Enabled) + if (!IsIPv4Enabled && IsIPv6Enabled) { _interfaces.Add(new IPData(IPAddress.IPv6Loopback, new IPNetwork(IPAddress.IPv6Loopback, 128), "lo")); } @@ -311,14 +311,14 @@ namespace Jellyfin.Networking.Manager { _logger.LogDebug("Using LAN interface addresses as user provided no LAN details."); - if (IsIpv6Enabled) + if (IsIPv6Enabled) { _lanSubnets.Add(new IPNetwork(IPAddress.IPv6Loopback, 128)); // RFC 4291 (Loopback) _lanSubnets.Add(new IPNetwork(IPAddress.Parse("fe80::"), 10)); // RFC 4291 (Site local) _lanSubnets.Add(new IPNetwork(IPAddress.Parse("fc00::"), 7)); // RFC 4193 (Unique local) } - if (IsIpv4Enabled) + if (IsIPv4Enabled) { _lanSubnets.Add(new IPNetwork(IPAddress.Loopback, 8)); // RFC 5735 (Loopback) _lanSubnets.Add(new IPNetwork(IPAddress.Parse("10.0.0.0"), 8)); // RFC 1918 (private) @@ -382,13 +382,13 @@ namespace Jellyfin.Networking.Manager } // Remove all IPv4 interfaces if IPv4 is disabled - if (!IsIpv4Enabled) + if (!IsIPv4Enabled) { _interfaces.RemoveAll(x => x.AddressFamily == AddressFamily.InterNetwork); } // Remove all IPv6 interfaces if IPv6 is disabled - if (!IsIpv6Enabled) + if (!IsIPv6Enabled) { _interfaces.RemoveAll(x => x.AddressFamily == AddressFamily.InterNetworkV6); } @@ -470,7 +470,7 @@ namespace Jellyfin.Networking.Manager _publishedServerUrls[new IPData(lanPrefix, new IPNetwork(lanPrefix, lan.PrefixLength))] = replacement; } } - else if (NetworkExtensions.TryParseToSubnet(identifier, out var result) && result != null) + else if (NetworkExtensions.TryParseToSubnet(identifier, out var result) && result is not null) { var data = new IPData(result.Prefix, result); _publishedServerUrls[data] = replacement; @@ -492,7 +492,7 @@ namespace Jellyfin.Networking.Manager private void ConfigurationUpdated(object? sender, ConfigurationUpdateEventArgs evt) { - if (evt.Key.Equals("network", StringComparison.Ordinal)) + if (evt.Key.Equals(NetworkConfigurationStore.StoreKey, StringComparison.Ordinal)) { UpdateSettings((NetworkConfiguration)evt.NewConfiguration); } @@ -581,8 +581,8 @@ namespace Jellyfin.Networking.Manager // Use interface IP instead of name foreach (var iface in matchedInterfaces) { - if ((IsIpv4Enabled && iface.Address.AddressFamily == AddressFamily.InterNetwork) - || (IsIpv6Enabled && iface.Address.AddressFamily == AddressFamily.InterNetworkV6)) + if ((IsIPv4Enabled && iface.Address.AddressFamily == AddressFamily.InterNetwork) + || (IsIPv6Enabled && iface.Address.AddressFamily == AddressFamily.InterNetworkV6)) { result.Add(iface); } @@ -634,18 +634,18 @@ namespace Jellyfin.Networking.Manager /// public IReadOnlyList GetLoopbacks() { - if (!(IsIpv4Enabled && IsIpv4Enabled)) + if (!(IsIPv4Enabled && IsIPv4Enabled)) { return Array.Empty(); } var loopbackNetworks = new List(); - if (IsIpv4Enabled) + if (IsIPv4Enabled) { loopbackNetworks.Add(new IPData(IPAddress.Loopback, new IPNetwork(IPAddress.Loopback, 8), "lo")); } - if (IsIpv6Enabled) + if (IsIPv6Enabled) { loopbackNetworks.Add(new IPData(IPAddress.IPv6Loopback, new IPNetwork(IPAddress.IPv6Loopback, 128), "lo")); } @@ -674,16 +674,16 @@ namespace Jellyfin.Networking.Manager return result; } - if (IsIpv4Enabled && IsIpv6Enabled) + if (IsIPv4Enabled && IsIPv6Enabled) { // Kestrel source code shows it uses Sockets.DualMode - so this also covers IPAddress.Any by default result.Add(new IPData(IPAddress.IPv6Any, new IPNetwork(IPAddress.IPv6Any, 0))); } - else if (IsIpv4Enabled) + else if (IsIPv4Enabled) { result.Add(new IPData(IPAddress.Any, new IPNetwork(IPAddress.Any, 0))); } - else if (IsIpv6Enabled) + else if (IsIPv6Enabled) { // Cannot use IPv6Any as Kestrel will bind to IPv4 addresses too. foreach (var iface in _interfaces) @@ -701,7 +701,7 @@ namespace Jellyfin.Networking.Manager /// public string GetBindInterface(string source, out int? port) { - if (!NetworkExtensions.TryParseHost(source, out var addresses, IsIpv4Enabled, IsIpv6Enabled)) + if (!NetworkExtensions.TryParseHost(source, out var addresses, IsIPv4Enabled, IsIPv6Enabled)) { addresses = Array.Empty(); } @@ -726,14 +726,14 @@ namespace Jellyfin.Networking.Manager string result; - if (source != null) + if (source is not null) { - if (IsIpv4Enabled && !IsIpv6Enabled && source.AddressFamily == AddressFamily.InterNetworkV6) + if (IsIPv4Enabled && !IsIPv6Enabled && source.AddressFamily == AddressFamily.InterNetworkV6) { _logger.LogWarning("IPv6 is disabled in Jellyfin, but enabled in the OS. This may affect how the interface is selected."); } - if (!IsIpv4Enabled && IsIpv6Enabled && source.AddressFamily == AddressFamily.InterNetwork) + if (!IsIPv4Enabled && IsIPv6Enabled && source.AddressFamily == AddressFamily.InterNetwork) { _logger.LogWarning("IPv4 is disabled in Jellyfin, but enabled in the OS. This may affect how the interface is selected."); } @@ -759,6 +759,7 @@ namespace Jellyfin.Networking.Manager } // Get the first LAN interface address that's not excluded and not a loopback address. + // Get all available interfaces, prefer local interfaces var availableInterfaces = _interfaces.Where(x => !IPAddress.IsLoopback(x.Address)) .OrderByDescending(x => IsInLocalNetwork(x.Address)) .ThenBy(x => x.Index) @@ -766,6 +767,7 @@ namespace Jellyfin.Networking.Manager if (availableInterfaces.Count > 0) { + // If no source address is given, use the preferred (first) interface if (source is null) { result = NetworkExtensions.FormatIpString(availableInterfaces.First().Address); @@ -773,16 +775,6 @@ namespace Jellyfin.Networking.Manager return result; } - foreach (var intf in availableInterfaces) - { - if (intf.Address.Equals(source)) - { - result = NetworkExtensions.FormatIpString(intf.Address); - _logger.LogDebug("{Source}: Found matching interface to use as bind address: {Result}", source, result); - return result; - } - } - // Does the request originate in one of the interface subnets? // (For systems with multiple internal network cards, and multiple subnets) foreach (var intf in availableInterfaces) @@ -790,14 +782,19 @@ namespace Jellyfin.Networking.Manager if (intf.Subnet.Contains(source)) { result = NetworkExtensions.FormatIpString(intf.Address); - _logger.LogDebug("{Source}: Found internal interface with matching subnet, using it as bind address: {Result}", source, result); + _logger.LogDebug("{Source}: Found interface with matching subnet, using it as bind address: {Result}", source, result); return result; } } + + // Fallback to first available interface + result = NetworkExtensions.FormatIpString(availableInterfaces[0].Address); + _logger.LogDebug("{Source}: No matching interfaces found, using preferred interface as bind address: {Result}", source, result); + return result; } // There isn't any others, so we'll use the loopback. - result = IsIpv4Enabled && !IsIpv6Enabled ? "127.0.0.1" : "::1"; + result = IsIPv4Enabled && !IsIPv6Enabled ? "127.0.0.1" : "::1"; _logger.LogWarning("{Source}: Only loopback {Result} returned, using that as bind address.", source, result); return result; } @@ -819,12 +816,12 @@ namespace Jellyfin.Networking.Manager return IPAddress.IsLoopback(subnet.Prefix) || (_lanSubnets.Any(x => x.Contains(subnet.Prefix)) && !_excludedSubnets.Any(x => x.Contains(subnet.Prefix))); } - if (NetworkExtensions.TryParseHost(address, out var addresses, IsIpv4Enabled, IsIpv6Enabled)) + if (NetworkExtensions.TryParseHost(address, out var addresses, IsIPv4Enabled, IsIPv6Enabled)) { bool match = false; foreach (var ept in addresses) { - match |= IPAddress.IsLoopback(ept) || (_lanSubnets.Any(x => x.Contains(ept)) && !_excludedSubnets.Any(x => x.Contains(ept))); + match = match || IPAddress.IsLoopback(ept) || (_lanSubnets.Any(x => x.Contains(ept)) && !_excludedSubnets.Any(x => x.Contains(ept))); if (match) { @@ -860,15 +857,29 @@ namespace Jellyfin.Networking.Manager bool match = false; foreach (var lanSubnet in _lanSubnets) { - match |= lanSubnet.Contains(address); + match = lanSubnet.Contains(address); + + if (match) + { + break; + } + } + + if (!match) + { + return match; } foreach (var excludedSubnet in _excludedSubnets) { - match &= !excludedSubnet.Contains(address); + match = match && !excludedSubnet.Contains(address); + + if (!match) + { + break; + } } - NetworkExtensions.IsIPv6LinkLocal(address); return match; } @@ -905,7 +916,7 @@ namespace Jellyfin.Networking.Manager // Get address interface. var intf = _interfaces.OrderBy(x => x.Index).FirstOrDefault(x => data.Key.Subnet.Contains(x.Address)); - if (intf?.Address != null) + if (intf?.Address is not null) { // Match IP address. bindPreference = data.Value; @@ -930,7 +941,7 @@ namespace Jellyfin.Networking.Manager } } - if (port != null) + if (port is not null) { _logger.LogDebug("{Source}: Matching bind address override found: {Address}:{Port}", source, bindPreference, port); } @@ -981,7 +992,7 @@ namespace Jellyfin.Networking.Manager .Select(x => x.Address) .FirstOrDefault(); - if (bindAddress != null) + if (bindAddress is not null) { result = NetworkExtensions.FormatIpString(bindAddress); _logger.LogDebug("{Source}: External request received, matching external bind address found: {Result}", source, result); @@ -1001,7 +1012,7 @@ namespace Jellyfin.Networking.Manager .Select(x => x.Address) .FirstOrDefault(); - if (bindAddress != null) + if (bindAddress is not null) { result = NetworkExtensions.FormatIpString(bindAddress); _logger.LogDebug("{Source}: Internal request received, matching internal bind address found: {Result}", source, result); diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs index 5065fbdbb..71f23b788 100644 --- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs @@ -367,7 +367,7 @@ namespace Jellyfin.Server.Extensions private static void AddIpAddress(NetworkConfiguration config, ForwardedHeadersOptions options, IPAddress addr, int prefixLength) { - if ((!config.EnableIPV4 && addr.AddressFamily == AddressFamily.InterNetwork) || (!config.EnableIPV6 && addr.AddressFamily == AddressFamily.InterNetworkV6)) + if ((!config.EnableIPv4 && addr.AddressFamily == AddressFamily.InterNetwork) || (!config.EnableIPv6 && addr.AddressFamily == AddressFamily.InterNetworkV6)) { return; } diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index f0f16af78..5721b19ca 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -19,12 +19,12 @@ namespace MediaBrowser.Common.Net /// /// Gets a value indicating whether IPv4 is enabled. /// - bool IsIpv4Enabled { get; } + bool IsIPv4Enabled { get; } /// /// Gets a value indicating whether IPv6 is enabled. /// - bool IsIpv6Enabled { get; } + bool IsIPv6Enabled { get; } /// /// Calculates the list of interfaces to use for Kestrel. @@ -119,7 +119,7 @@ namespace MediaBrowser.Common.Net /// Interface name. /// Resulting object's IP addresses, if successful. /// Success of the operation. - bool TryParseInterface(string intf, out List? result); + bool TryParseInterface(string intf, out List result); /// /// Returns all internal (LAN) bind interface addresses. diff --git a/MediaBrowser.Common/Net/NetworkExtensions.cs b/MediaBrowser.Common/Net/NetworkExtensions.cs index 97f0abbb5..7c36081e6 100644 --- a/MediaBrowser.Common/Net/NetworkExtensions.cs +++ b/MediaBrowser.Common/Net/NetworkExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Net; using System.Net.Sockets; using System.Text.RegularExpressions; @@ -170,36 +171,9 @@ namespace MediaBrowser.Common.Net for (int a = 0; a < values.Length; a++) { - string[] v = values[a].Trim().Split("/"); - - var address = IPAddress.None; - if (negated && v[0].StartsWith('!')) - { - _ = IPAddress.TryParse(v[0][1..], out address); - } - else if (!negated) + if (TryParseToSubnet(values[a], out var innerResult, negated)) { - _ = IPAddress.TryParse(v[0][0..], out address); - } - - if (address != IPAddress.None && address is not null) - { - if (v.Length > 1 && int.TryParse(v[1], out var netmask)) - { - result.Add(new IPNetwork(address, netmask)); - } - else if (v.Length > 1 && IPAddress.TryParse(v[1], out var netmaskAddress)) - { - result.Add(new IPNetwork(address, NetworkExtensions.MaskToCidr(netmaskAddress))); - } - else if (address.AddressFamily == AddressFamily.InterNetwork) - { - result.Add(new IPNetwork(address, 32)); - } - else if (address.AddressFamily == AddressFamily.InterNetworkV6) - { - result.Add(new IPNetwork(address, 128)); - } + result.Add(innerResult); } } @@ -228,27 +202,32 @@ namespace MediaBrowser.Common.Net return false; } - string[] v = value.Trim().Split("/"); + var splitString = value.Trim().Split("/"); + var ipBlock = splitString[0]; var address = IPAddress.None; - if (negated && v[0].StartsWith('!')) + if (negated && ipBlock.StartsWith('!') && IPAddress.TryParse(ipBlock[1..], out var tmpAddress)) { - _ = IPAddress.TryParse(v[0][1..], out address); + address = tmpAddress; } - else if (!negated) + else if (!negated && IPAddress.TryParse(ipBlock, out tmpAddress)) { - _ = IPAddress.TryParse(v[0][0..], out address); + address = tmpAddress; } if (address != IPAddress.None && address is not null) { - if (v.Length > 1 && int.TryParse(v[1], out var netmask)) - { - result = new IPNetwork(address, netmask); - } - else if (v.Length > 1 && IPAddress.TryParse(v[1], out var netmaskAddress)) + if (splitString.Length > 1) { - result = new IPNetwork(address, NetworkExtensions.MaskToCidr(netmaskAddress)); + var subnetBlock = splitString[1]; + if (int.TryParse(subnetBlock, out var netmask)) + { + result = new IPNetwork(address, netmask); + } + else if (IPAddress.TryParse(subnetBlock, out var netmaskAddress)) + { + result = new IPNetwork(address, NetworkExtensions.MaskToCidr(netmaskAddress)); + } } else if (address.AddressFamily == AddressFamily.InterNetwork) { @@ -353,7 +332,13 @@ namespace MediaBrowser.Common.Net /// The broadcast address. public static IPAddress GetBroadcastAddress(IPNetwork network) { - uint ipAddress = BitConverter.ToUInt32(network.Prefix.GetAddressBytes(), 0); + var addressBytes = network.Prefix.GetAddressBytes(); + if (BitConverter.IsLittleEndian) + { + addressBytes.Reverse(); + } + + uint ipAddress = BitConverter.ToUInt32(addressBytes, 0); uint ipMaskV4 = BitConverter.ToUInt32(CidrToMask(network.PrefixLength, AddressFamily.InterNetwork).GetAddressBytes(), 0); uint broadCastIpAddress = ipAddress | ~ipMaskV4; diff --git a/tests/Jellyfin.Networking.Tests/NetworkManagerTests.cs b/tests/Jellyfin.Networking.Tests/NetworkManagerTests.cs index 61f913252..85226d430 100644 --- a/tests/Jellyfin.Networking.Tests/NetworkManagerTests.cs +++ b/tests/Jellyfin.Networking.Tests/NetworkManagerTests.cs @@ -23,8 +23,8 @@ namespace Jellyfin.Networking.Tests var ip = IPAddress.Parse(value); var conf = new NetworkConfiguration() { - EnableIPV6 = true, - EnableIPV4 = true, + EnableIPv6 = true, + EnableIPv4 = true, LocalNetworkSubnets = network.Split(',') }; @@ -50,8 +50,8 @@ namespace Jellyfin.Networking.Tests var ip = IPAddress.Parse(value); var conf = new NetworkConfiguration() { - EnableIPV6 = true, - EnableIPV4 = true, + EnableIPv6 = true, + EnableIPv4 = true, LocalNetworkSubnets = network.Split(',') }; diff --git a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs index 241d2314b..c493ce5ea 100644 --- a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs +++ b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs @@ -47,8 +47,8 @@ namespace Jellyfin.Networking.Tests { var conf = new NetworkConfiguration() { - EnableIPV6 = true, - EnableIPV4 = true, + EnableIPv6 = true, + EnableIPv4 = true, LocalNetworkSubnets = lan?.Split(';') ?? throw new ArgumentNullException(nameof(lan)) }; @@ -107,7 +107,7 @@ namespace Jellyfin.Networking.Tests [InlineData("10.128.240.50/30", "10.128.240.51")] [InlineData("10.128.240.50/255.255.255.252", "10.128.240.51")] [InlineData("127.0.0.1/8", "127.0.0.1")] - public void IpV4SubnetMaskMatchesValidIpAddress(string netMask, string ipAddress) + public void IPv4SubnetMaskMatchesValidIPAddress(string netMask, string ipAddress) { var ipa = IPAddress.Parse(ipAddress); Assert.True(NetworkExtensions.TryParseToSubnet(netMask, out var subnet) && subnet.Contains(IPAddress.Parse(ipAddress))); @@ -127,7 +127,7 @@ namespace Jellyfin.Networking.Tests [InlineData("10.128.240.50/30", "10.128.239.50")] [InlineData("10.128.240.50/30", "10.127.240.51")] [InlineData("10.128.240.50/255.255.255.252", "10.127.240.51")] - public void IpV4SubnetMaskDoesNotMatchInvalidIpAddress(string netMask, string ipAddress) + public void IPv4SubnetMaskDoesNotMatchInvalidIPAddress(string netMask, string ipAddress) { var ipa = IPAddress.Parse(ipAddress); Assert.False(NetworkExtensions.TryParseToSubnet(netMask, out var subnet) && subnet.Contains(IPAddress.Parse(ipAddress))); @@ -144,7 +144,7 @@ namespace Jellyfin.Networking.Tests [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:0001:0000:0000:0000")] [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0012:FFFF:FFFF:FFFF:FFF0")] [InlineData("2001:db8:abcd:0012::0/128", "2001:0DB8:ABCD:0012:0000:0000:0000:0000")] - public void IpV6SubnetMaskMatchesValidIpAddress(string netMask, string ipAddress) + public void IPv6SubnetMaskMatchesValidIPAddress(string netMask, string ipAddress) { Assert.True(NetworkExtensions.TryParseToSubnet(netMask, out var subnet) && subnet.Contains(IPAddress.Parse(ipAddress))); } @@ -155,7 +155,7 @@ namespace Jellyfin.Networking.Tests [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0013:0001:0000:0000:0000")] [InlineData("2001:db8:abcd:0012::0/64", "2001:0DB8:ABCD:0011:FFFF:FFFF:FFFF:FFF0")] [InlineData("2001:db8:abcd:0012::0/128", "2001:0DB8:ABCD:0012:0000:0000:0000:0001")] - public void IpV6SubnetMaskDoesNotMatchInvalidIpAddress(string netMask, string ipAddress) + public void IPv6SubnetMaskDoesNotMatchInvalidIPAddress(string netMask, string ipAddress) { Assert.False(NetworkExtensions.TryParseToSubnet(netMask, out var subnet) && subnet.Contains(IPAddress.Parse(ipAddress))); } @@ -194,8 +194,8 @@ namespace Jellyfin.Networking.Tests var conf = new NetworkConfiguration() { LocalNetworkAddresses = bindAddresses.Split(','), - EnableIPV6 = ipv6enabled, - EnableIPV4 = true + EnableIPv6 = ipv6enabled, + EnableIPv4 = true }; NetworkManager.MockNetworkSettings = "192.168.1.208/24,-16,eth16|200.200.200.200/24,11,eth11"; @@ -256,8 +256,8 @@ namespace Jellyfin.Networking.Tests { LocalNetworkSubnets = lan.Split(','), LocalNetworkAddresses = bindAddresses.Split(','), - EnableIPV6 = ipv6enabled, - EnableIPV4 = true, + EnableIPv6 = ipv6enabled, + EnableIPv4 = true, PublishedServerUriBySubnet = new string[] { publishedServers } }; @@ -281,13 +281,13 @@ namespace Jellyfin.Networking.Tests [InlineData("185.10.10.10", "185.10.10.10", false)] [InlineData("", "100.100.100.100", false)] - public void HasRemoteAccess_GivenWhitelist_AllowsOnlyIpsInWhitelist(string addresses, string remoteIp, bool denied) + public void HasRemoteAccess_GivenWhitelist_AllowsOnlyIPsInWhitelist(string addresses, string remoteIp, bool denied) { // Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. // If left blank, all remote addresses will be allowed. var conf = new NetworkConfiguration() { - EnableIPV4 = true, + EnableIPv4 = true, RemoteIPFilter = addresses.Split(','), IsRemoteIPFilterBlacklist = false }; @@ -301,13 +301,13 @@ namespace Jellyfin.Networking.Tests [InlineData("185.10.10.10", "185.10.10.10", true)] [InlineData("", "100.100.100.100", false)] - public void HasRemoteAccess_GivenBlacklist_BlacklistTheIps(string addresses, string remoteIp, bool denied) + public void HasRemoteAccess_GivenBlacklist_BlacklistTheIPs(string addresses, string remoteIp, bool denied) { // Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. // If left blank, all remote addresses will be allowed. var conf = new NetworkConfiguration() { - EnableIPV4 = true, + EnableIPv4 = true, RemoteIPFilter = addresses.Split(','), IsRemoteIPFilterBlacklist = true }; @@ -326,7 +326,7 @@ namespace Jellyfin.Networking.Tests { var conf = new NetworkConfiguration { - EnableIPV4 = true, + EnableIPv4 = true, LocalNetworkSubnets = lan.Split(','), LocalNetworkAddresses = bind.Split(',') }; @@ -350,7 +350,7 @@ namespace Jellyfin.Networking.Tests { var conf = new NetworkConfiguration { - EnableIPV4 = true, + EnableIPv4 = true, LocalNetworkSubnets = lan.Split(','), LocalNetworkAddresses = bind.Split(',') }; diff --git a/tests/Jellyfin.Server.Tests/ParseNetworkTests.cs b/tests/Jellyfin.Server.Tests/ParseNetworkTests.cs index 12a9beb9e..49516cccc 100644 --- a/tests/Jellyfin.Server.Tests/ParseNetworkTests.cs +++ b/tests/Jellyfin.Server.Tests/ParseNetworkTests.cs @@ -77,8 +77,8 @@ namespace Jellyfin.Server.Tests var settings = new NetworkConfiguration { - EnableIPV4 = ip4, - EnableIPV6 = ip6 + EnableIPv4 = ip4, + EnableIPv6 = ip6 }; ForwardedHeadersOptions options = new ForwardedHeadersOptions(); @@ -116,8 +116,8 @@ namespace Jellyfin.Server.Tests { var conf = new NetworkConfiguration() { - EnableIPV6 = true, - EnableIPV4 = true, + EnableIPv6 = true, + EnableIPv4 = true, }; return new NetworkManager(GetMockConfig(conf), new NullLogger()); -- cgit v1.2.3 From 32ac3b580c547f8b1923e242d0efd4816470fb45 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Mon, 3 Jul 2023 14:03:33 +0200 Subject: Rename additional values in NetworkConfiguration and add migration for all changed values --- Emby.Server.Implementations/ApplicationHost.cs | 8 +- .../EntryPoints/ExternalPortForwarding.cs | 8 +- .../Configuration/NetworkConfiguration.cs | 38 ++-- Jellyfin.Server/Migrations/MigrationRunner.cs | 3 +- .../MigrateNetworkConfiguration.cs | 195 +++++++++++++++++++++ 5 files changed, 224 insertions(+), 28 deletions(-) create mode 100644 Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs (limited to 'Jellyfin.Networking/Configuration/NetworkConfiguration.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 31f98a20c..8dc54ecfb 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -475,8 +475,8 @@ namespace Emby.Server.Implementations } var networkConfiguration = ConfigurationManager.GetNetworkConfiguration(); - HttpPort = networkConfiguration.HttpServerPortNumber; - HttpsPort = networkConfiguration.HttpsPortNumber; + HttpPort = networkConfiguration.ServerPortNumberHttp; + HttpsPort = networkConfiguration.ServerPortNumberHttps; // Safeguard against invalid configuration if (HttpPort == HttpsPort) @@ -785,8 +785,8 @@ namespace Emby.Server.Implementations if (HttpPort != 0 && HttpsPort != 0) { // Need to restart if ports have changed - if (networkConfiguration.HttpServerPortNumber != HttpPort - || networkConfiguration.HttpsPortNumber != HttpsPort) + if (networkConfiguration.ServerPortNumberHttp != HttpPort + || networkConfiguration.ServerPortNumberHttps != HttpsPort) { if (ConfigurationManager.Configuration.IsPortAuthorized) { diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 06e57ad12..6e23c5f46 100644 --- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -57,8 +57,8 @@ namespace Emby.Server.Implementations.EntryPoints return new StringBuilder(32) .Append(config.EnableUPnP).Append(Separator) - .Append(config.PublicPort).Append(Separator) - .Append(config.PublicHttpsPort).Append(Separator) + .Append(config.PublicPortHttp).Append(Separator) + .Append(config.PublicPortHttps).Append(Separator) .Append(_appHost.HttpPort).Append(Separator) .Append(_appHost.HttpsPort).Append(Separator) .Append(_appHost.ListenWithHttps).Append(Separator) @@ -146,11 +146,11 @@ namespace Emby.Server.Implementations.EntryPoints private IEnumerable CreatePortMaps(INatDevice device) { var config = _config.GetNetworkConfiguration(); - yield return CreatePortMap(device, _appHost.HttpPort, config.PublicPort); + yield return CreatePortMap(device, _appHost.HttpPort, config.PublicPortHttp); if (_appHost.ListenWithHttps) { - yield return CreatePortMap(device, _appHost.HttpsPort, config.PublicHttpsPort); + yield return CreatePortMap(device, _appHost.HttpsPort, config.PublicPortHttps); } } diff --git a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs index f31d2bce2..90c7718ce 100644 --- a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs +++ b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs @@ -10,12 +10,12 @@ namespace Jellyfin.Networking.Configuration public class NetworkConfiguration { /// - /// The default value for . + /// The default value for . /// public const int DefaultHttpPort = 8096; /// - /// The default value for and . + /// The default value for and . /// public const int DefaultHttpsPort = 8920; @@ -79,28 +79,28 @@ namespace Jellyfin.Networking.Configuration public string CertificatePassword { get; set; } = string.Empty; /// - /// Gets or sets the HTTPS server port number. + /// Gets or sets the HTTP server port number. /// - /// The HTTPS server port number. - public int HttpsPortNumber { get; set; } = DefaultHttpsPort; + /// The HTTP server port number. + public int ServerPortNumberHttp { get; set; } = DefaultHttpPort; /// - /// Gets or sets the public HTTPS port. + /// Gets or sets the HTTPS server port number. /// - /// The public HTTPS port. - public int PublicHttpsPort { get; set; } = DefaultHttpsPort; + /// The HTTPS server port number. + public int ServerPortNumberHttps { get; set; } = DefaultHttpsPort; /// - /// Gets or sets the HTTP server port number. + /// Gets or sets the public mapped port. /// - /// The HTTP server port number. - public int HttpServerPortNumber { get; set; } = DefaultHttpPort; + /// The public mapped port. + public int PublicPortHttp { get; set; } = DefaultHttpPort; /// - /// Gets or sets the public mapped port. + /// Gets or sets the public HTTPS port. /// - /// The public mapped port. - public int PublicPort { get; set; } = DefaultHttpPort; + /// The public HTTPS port. + public int PublicPortHttps { get; set; } = DefaultHttpsPort; /// /// Gets or sets a value indicating whether Autodiscovery is enabled. @@ -113,17 +113,17 @@ namespace Jellyfin.Networking.Configuration public bool EnableUPnP { get; set; } /// - /// Gets or sets a value indicating whether IPv6 is enabled or not. + /// Gets or sets a value indicating whether IPv6 is enabled. /// public bool EnableIPv4 { get; set; } = true; /// - /// Gets or sets a value indicating whether IPv6 is enabled or not. + /// Gets or sets a value indicating whether IPv6 is enabled. /// public bool EnableIPv6 { get; set; } /// - /// Gets or sets a value indicating whether access outside of the LAN is permitted. + /// Gets or sets a value indicating whether access from outside of the LAN is permitted. /// public bool EnableRemoteAccess { get; set; } = true; @@ -138,12 +138,12 @@ namespace Jellyfin.Networking.Configuration public string[] LocalNetworkAddresses { get; set; } = Array.Empty(); /// - /// Gets or sets the known proxies. If the proxy is a network, it's added to the KnownNetworks. + /// Gets or sets the known proxies. /// public string[] KnownProxies { get; set; } = Array.Empty(); /// - /// Gets or sets a value indicating whether address names that match should be Ignore for the purposes of binding. + /// Gets or sets a value indicating whether address names that match should be ignored for the purposes of binding. /// public bool IgnoreVirtualInterfaces { get; set; } = true; diff --git a/Jellyfin.Server/Migrations/MigrationRunner.cs b/Jellyfin.Server/Migrations/MigrationRunner.cs index abfdcd77d..33c02f41c 100644 --- a/Jellyfin.Server/Migrations/MigrationRunner.cs +++ b/Jellyfin.Server/Migrations/MigrationRunner.cs @@ -22,7 +22,8 @@ namespace Jellyfin.Server.Migrations private static readonly Type[] _preStartupMigrationTypes = { typeof(PreStartupRoutines.CreateNetworkConfiguration), - typeof(PreStartupRoutines.MigrateMusicBrainzTimeout) + typeof(PreStartupRoutines.MigrateMusicBrainzTimeout), + typeof(PreStartupRoutines.MigrateNetworkConfiguration) }; /// diff --git a/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs b/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs new file mode 100644 index 000000000..afcf5436c --- /dev/null +++ b/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs @@ -0,0 +1,195 @@ +using System; +using System.IO; +using System.Xml; +using System.Xml.Serialization; +using Emby.Server.Implementations; +using Jellyfin.Networking.Configuration; +using Microsoft.Extensions.Logging; + +namespace Jellyfin.Server.Migrations.PreStartupRoutines; + +/// +public class MigrateNetworkConfiguration : IMigrationRoutine +{ + private readonly ServerApplicationPaths _applicationPaths; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// An instance of . + /// An instance of the interface. + public MigrateNetworkConfiguration(ServerApplicationPaths applicationPaths, ILoggerFactory loggerFactory) + { + _applicationPaths = applicationPaths; + _logger = loggerFactory.CreateLogger(); + } + + /// + public Guid Id => Guid.Parse("4FB5C950-1991-11EE-9B4B-0800200C9A66"); + + /// + public string Name => nameof(MigrateNetworkConfiguration); + + /// + public bool PerformOnNewInstall => false; + + /// + public void Perform() + { + string path = Path.Combine(_applicationPaths.ConfigurationDirectoryPath, "network.xml"); + var oldNetworkConfigSerializer = new XmlSerializer(typeof(OldNetworkConfiguration), new XmlRootAttribute("NetworkConfiguration")); + using var xmlReader = XmlReader.Create(path); + var oldNetworkConfiguration = (OldNetworkConfiguration?)oldNetworkConfigSerializer.Deserialize(xmlReader); + + if (oldNetworkConfiguration is not null) + { + // Migrate network config values to new config schema + var networkConfiguration = new NetworkConfiguration(); + networkConfiguration.AutoDiscovery = oldNetworkConfiguration.AutoDiscovery; + networkConfiguration.BaseUrl = oldNetworkConfiguration.BaseUrl; + networkConfiguration.CertificatePassword = oldNetworkConfiguration.CertificatePassword; + networkConfiguration.CertificatePath = oldNetworkConfiguration.CertificatePath; + networkConfiguration.EnableHttps = oldNetworkConfiguration.EnableHttps; + networkConfiguration.EnableIPv4 = oldNetworkConfiguration.EnableIPV4; + networkConfiguration.EnableIPv6 = oldNetworkConfiguration.EnableIPV6; + networkConfiguration.EnablePublishedServerUriByRequest = oldNetworkConfiguration.EnablePublishedServerUriByRequest; + networkConfiguration.EnableRemoteAccess = oldNetworkConfiguration.EnableRemoteAccess; + networkConfiguration.EnableUPnP = oldNetworkConfiguration.EnableUPnP; + networkConfiguration.IgnoreVirtualInterfaces = oldNetworkConfiguration.IgnoreVirtualInterfaces; + networkConfiguration.IsRemoteIPFilterBlacklist = oldNetworkConfiguration.IsRemoteIPFilterBlacklist; + networkConfiguration.KnownProxies = oldNetworkConfiguration.KnownProxies; + networkConfiguration.LocalNetworkAddresses = oldNetworkConfiguration.LocalNetworkAddresses; + networkConfiguration.LocalNetworkSubnets = oldNetworkConfiguration.LocalNetworkSubnets; + networkConfiguration.PublicPortHttp = oldNetworkConfiguration.PublicPort; + networkConfiguration.PublicPortHttps = oldNetworkConfiguration.PublicHttpsPort; + networkConfiguration.PublishedServerUriBySubnet = oldNetworkConfiguration.PublishedServerUriBySubnet; + networkConfiguration.RemoteIPFilter = oldNetworkConfiguration.RemoteIPFilter; + networkConfiguration.RequireHttps = oldNetworkConfiguration.RequireHttps; + networkConfiguration.ServerPortNumberHttp = oldNetworkConfiguration.HttpServerPortNumber; + networkConfiguration.ServerPortNumberHttps = oldNetworkConfiguration.HttpsPortNumber; + + // Migrate old virtual interface name schema + var oldVirtualInterfaceNames = oldNetworkConfiguration.VirtualInterfaceNames; + if (oldVirtualInterfaceNames.Equals("vEthernet*", StringComparison.OrdinalIgnoreCase)) + { + networkConfiguration.VirtualInterfaceNames = new string[] { "veth" }; + } + else + { + networkConfiguration.VirtualInterfaceNames = oldVirtualInterfaceNames.Replace("*", string.Empty, StringComparison.OrdinalIgnoreCase).Split(','); + } + + var networkConfigSerializer = new XmlSerializer(typeof(NetworkConfiguration)); + var xmlWriterSettings = new XmlWriterSettings { Indent = true }; + using var xmlWriter = XmlWriter.Create(path, xmlWriterSettings); + networkConfigSerializer.Serialize(xmlWriter, networkConfiguration); + } + } + +#pragma warning disable + public sealed class OldNetworkConfiguration + { + public const int DefaultHttpPort = 8096; + + public const int DefaultHttpsPort = 8920; + + private string _baseUrl = string.Empty; + + public bool RequireHttps { get; set; } + + public string CertificatePath { get; set; } = string.Empty; + + public string CertificatePassword { get; set; } = string.Empty; + + public string BaseUrl + { + get => _baseUrl; + set + { + // Normalize the start of the string + if (string.IsNullOrWhiteSpace(value)) + { + // If baseUrl is empty, set an empty prefix string + _baseUrl = string.Empty; + return; + } + + if (value[0] != '/') + { + // If baseUrl was not configured with a leading slash, append one for consistency + value = "/" + value; + } + + // Normalize the end of the string + if (value[^1] == '/') + { + // If baseUrl was configured with a trailing slash, remove it for consistency + value = value.Remove(value.Length - 1); + } + + _baseUrl = value; + } + } + + public int PublicHttpsPort { get; set; } = DefaultHttpsPort; + + public int HttpServerPortNumber { get; set; } = DefaultHttpPort; + + public int HttpsPortNumber { get; set; } = DefaultHttpsPort; + + public bool EnableHttps { get; set; } + + public int PublicPort { get; set; } = DefaultHttpPort; + + public bool UPnPCreateHttpPortMap { get; set; } + + public string UDPPortRange { get; set; } = string.Empty; + + public bool EnableIPV6 { get; set; } + + public bool EnableIPV4 { get; set; } = true; + + public bool EnableSSDPTracing { get; set; } + + public string SSDPTracingFilter { get; set; } = string.Empty; + + public int UDPSendCount { get; set; } = 2; + + public int UDPSendDelay { get; set; } = 100; + + public bool IgnoreVirtualInterfaces { get; set; } = true; + + public string VirtualInterfaceNames { get; set; } = "vEthernet*"; + + public int GatewayMonitorPeriod { get; set; } = 60; + + public bool EnableMultiSocketBinding { get; } = true; + + public bool TrustAllIP6Interfaces { get; set; } + + public string HDHomerunPortRange { get; set; } = string.Empty; + + public string[] PublishedServerUriBySubnet { get; set; } = Array.Empty(); + + public bool AutoDiscoveryTracing { get; set; } + + public bool AutoDiscovery { get; set; } = true; + + public string[] RemoteIPFilter { get; set; } = Array.Empty(); + + public bool IsRemoteIPFilterBlacklist { get; set; } + + public bool EnableUPnP { get; set; } + + public bool EnableRemoteAccess { get; set; } = true; + + public string[] LocalNetworkSubnets { get; set; } = Array.Empty(); + + public string[] LocalNetworkAddresses { get; set; } = Array.Empty(); + public string[] KnownProxies { get; set; } = Array.Empty(); + + public bool EnablePublishedServerUriByRequest { get; set; } = false; + } +#pragma warning restore +} -- cgit v1.2.3 From e233a3b074d7696e4c05846aaf04434dafaf4031 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Mon, 3 Jul 2023 15:59:39 +0200 Subject: Apply review suggestions --- Emby.Server.Implementations/ApplicationHost.cs | 8 ++++---- .../EntryPoints/ExternalPortForwarding.cs | 8 ++++---- .../Configuration/NetworkConfiguration.cs | 24 +++++++++++----------- .../MigrateNetworkConfiguration.cs | 8 ++++---- 4 files changed, 24 insertions(+), 24 deletions(-) (limited to 'Jellyfin.Networking/Configuration/NetworkConfiguration.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 8dc54ecfb..dd90a8950 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -475,8 +475,8 @@ namespace Emby.Server.Implementations } var networkConfiguration = ConfigurationManager.GetNetworkConfiguration(); - HttpPort = networkConfiguration.ServerPortNumberHttp; - HttpsPort = networkConfiguration.ServerPortNumberHttps; + HttpPort = networkConfiguration.InternalHttpPort; + HttpsPort = networkConfiguration.InternalHttpsPort; // Safeguard against invalid configuration if (HttpPort == HttpsPort) @@ -785,8 +785,8 @@ namespace Emby.Server.Implementations if (HttpPort != 0 && HttpsPort != 0) { // Need to restart if ports have changed - if (networkConfiguration.ServerPortNumberHttp != HttpPort - || networkConfiguration.ServerPortNumberHttps != HttpsPort) + if (networkConfiguration.InternalHttpPort != HttpPort + || networkConfiguration.InternalHttpsPort != HttpsPort) { if (ConfigurationManager.Configuration.IsPortAuthorized) { diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 6e23c5f46..d6da597b8 100644 --- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -57,8 +57,8 @@ namespace Emby.Server.Implementations.EntryPoints return new StringBuilder(32) .Append(config.EnableUPnP).Append(Separator) - .Append(config.PublicPortHttp).Append(Separator) - .Append(config.PublicPortHttps).Append(Separator) + .Append(config.PublicHttpPort).Append(Separator) + .Append(config.PublicHttpsPort).Append(Separator) .Append(_appHost.HttpPort).Append(Separator) .Append(_appHost.HttpsPort).Append(Separator) .Append(_appHost.ListenWithHttps).Append(Separator) @@ -146,11 +146,11 @@ namespace Emby.Server.Implementations.EntryPoints private IEnumerable CreatePortMaps(INatDevice device) { var config = _config.GetNetworkConfiguration(); - yield return CreatePortMap(device, _appHost.HttpPort, config.PublicPortHttp); + yield return CreatePortMap(device, _appHost.HttpPort, config.PublicHttpPort); if (_appHost.ListenWithHttps) { - yield return CreatePortMap(device, _appHost.HttpsPort, config.PublicPortHttps); + yield return CreatePortMap(device, _appHost.HttpsPort, config.PublicHttpsPort); } } diff --git a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs index 90c7718ce..573c36be7 100644 --- a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs +++ b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs @@ -10,12 +10,12 @@ namespace Jellyfin.Networking.Configuration public class NetworkConfiguration { /// - /// The default value for . + /// The default value for . /// public const int DefaultHttpPort = 8096; /// - /// The default value for and . + /// The default value for and . /// public const int DefaultHttpsPort = 8920; @@ -79,28 +79,28 @@ namespace Jellyfin.Networking.Configuration public string CertificatePassword { get; set; } = string.Empty; /// - /// Gets or sets the HTTP server port number. + /// Gets or sets the internal HTTP server port. /// - /// The HTTP server port number. - public int ServerPortNumberHttp { get; set; } = DefaultHttpPort; + /// The HTTP server port. + public int InternalHttpPort { get; set; } = DefaultHttpPort; /// - /// Gets or sets the HTTPS server port number. + /// Gets or sets the internal HTTPS server port. /// - /// The HTTPS server port number. - public int ServerPortNumberHttps { get; set; } = DefaultHttpsPort; + /// The HTTPS server port. + public int InternalHttpsPort { get; set; } = DefaultHttpsPort; /// - /// Gets or sets the public mapped port. + /// Gets or sets the public HTTP port. /// - /// The public mapped port. - public int PublicPortHttp { get; set; } = DefaultHttpPort; + /// The public HTTP port. + public int PublicHttpPort { get; set; } = DefaultHttpPort; /// /// Gets or sets the public HTTPS port. /// /// The public HTTPS port. - public int PublicPortHttps { get; set; } = DefaultHttpsPort; + public int PublicHttpsPort { get; set; } = DefaultHttpsPort; /// /// Gets or sets a value indicating whether Autodiscovery is enabled. diff --git a/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs b/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs index afcf5436c..3b32e6043 100644 --- a/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs +++ b/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs @@ -57,17 +57,17 @@ public class MigrateNetworkConfiguration : IMigrationRoutine networkConfiguration.EnableRemoteAccess = oldNetworkConfiguration.EnableRemoteAccess; networkConfiguration.EnableUPnP = oldNetworkConfiguration.EnableUPnP; networkConfiguration.IgnoreVirtualInterfaces = oldNetworkConfiguration.IgnoreVirtualInterfaces; + networkConfiguration.InternalHttpPort = oldNetworkConfiguration.HttpServerPortNumber; + networkConfiguration.InternalHttpsPort = oldNetworkConfiguration.HttpsPortNumber; networkConfiguration.IsRemoteIPFilterBlacklist = oldNetworkConfiguration.IsRemoteIPFilterBlacklist; networkConfiguration.KnownProxies = oldNetworkConfiguration.KnownProxies; networkConfiguration.LocalNetworkAddresses = oldNetworkConfiguration.LocalNetworkAddresses; networkConfiguration.LocalNetworkSubnets = oldNetworkConfiguration.LocalNetworkSubnets; - networkConfiguration.PublicPortHttp = oldNetworkConfiguration.PublicPort; - networkConfiguration.PublicPortHttps = oldNetworkConfiguration.PublicHttpsPort; + networkConfiguration.PublicHttpPort = oldNetworkConfiguration.PublicPort; + networkConfiguration.PublicHttpsPort = oldNetworkConfiguration.PublicHttpsPort; networkConfiguration.PublishedServerUriBySubnet = oldNetworkConfiguration.PublishedServerUriBySubnet; networkConfiguration.RemoteIPFilter = oldNetworkConfiguration.RemoteIPFilter; networkConfiguration.RequireHttps = oldNetworkConfiguration.RequireHttps; - networkConfiguration.ServerPortNumberHttp = oldNetworkConfiguration.HttpServerPortNumber; - networkConfiguration.ServerPortNumberHttps = oldNetworkConfiguration.HttpsPortNumber; // Migrate old virtual interface name schema var oldVirtualInterfaceNames = oldNetworkConfiguration.VirtualInterfaceNames; -- cgit v1.2.3