From 32ac3b580c547f8b1923e242d0efd4816470fb45 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Mon, 3 Jul 2023 14:03:33 +0200 Subject: [PATCH] Rename additional values in NetworkConfiguration and add migration for all changed values --- .../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 diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 31f98a20ca..8dc54ecfb2 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 06e57ad127..6e23c5f46d 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 f31d2bce2d..90c7718ce2 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 abfdcd77d5..33c02f41c6 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 0000000000..afcf5436c2 --- /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 +}