diff --git a/Directory.Packages.props b/Directory.Packages.props index aa622129ba..c85d0c0328 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -49,7 +49,6 @@ - @@ -88,4 +87,4 @@ - \ No newline at end of file + diff --git a/Jellyfin.Api/Controllers/StartupController.cs b/Jellyfin.Api/Controllers/StartupController.cs index 41b0858d19..a6bc84311f 100644 --- a/Jellyfin.Api/Controllers/StartupController.cs +++ b/Jellyfin.Api/Controllers/StartupController.cs @@ -93,7 +93,6 @@ public class StartupController : BaseJellyfinApiController { NetworkConfiguration settings = _config.GetNetworkConfiguration(); settings.EnableRemoteAccess = startupRemoteAccessDto.EnableRemoteAccess; - settings.EnableUPnP = startupRemoteAccessDto.EnableAutomaticPortMapping; _config.SaveConfiguration(NetworkConfigurationStore.StoreKey, settings); return NoContent(); } diff --git a/Jellyfin.Api/Models/StartupDtos/StartupRemoteAccessDto.cs b/Jellyfin.Api/Models/StartupDtos/StartupRemoteAccessDto.cs index 1ae2cad4b6..9c29e372cf 100644 --- a/Jellyfin.Api/Models/StartupDtos/StartupRemoteAccessDto.cs +++ b/Jellyfin.Api/Models/StartupDtos/StartupRemoteAccessDto.cs @@ -1,3 +1,4 @@ +using System; using System.ComponentModel.DataAnnotations; namespace Jellyfin.Api.Models.StartupDtos; @@ -17,5 +18,6 @@ public class StartupRemoteAccessDto /// Gets or sets a value indicating whether enable automatic port mapping. /// [Required] + [Obsolete("No longer supported")] public bool EnableAutomaticPortMapping { get; set; } } diff --git a/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs b/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs index 49960f4305..09b2921714 100644 --- a/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs +++ b/Jellyfin.Server/Migrations/PreStartupRoutines/MigrateNetworkConfiguration.cs @@ -1,3 +1,5 @@ +#pragma warning disable CS0618 // obsolete + using System; using System.IO; using System.Xml; diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index e9fb3e4c27..c686614699 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -129,7 +129,6 @@ namespace Jellyfin.Server services.AddHostedService(); services.AddHostedService(); - services.AddHostedService(); services.AddHostedService(); services.AddHostedService(); services.AddHostedService(); diff --git a/MediaBrowser.Common/Net/NetworkConfiguration.cs b/MediaBrowser.Common/Net/NetworkConfiguration.cs index 61a51c99e2..053357296d 100644 --- a/MediaBrowser.Common/Net/NetworkConfiguration.cs +++ b/MediaBrowser.Common/Net/NetworkConfiguration.cs @@ -110,6 +110,7 @@ public class NetworkConfiguration /// /// Gets or sets a value indicating whether to enable automatic port forwarding. /// + [Obsolete("No longer supported")] public bool EnableUPnP { get; set; } /// diff --git a/jellyfin.code-workspace b/jellyfin.code-workspace index 7882b38219..844c69dbc9 100644 --- a/jellyfin.code-workspace +++ b/jellyfin.code-workspace @@ -12,6 +12,6 @@ "**/jellyfin-web": true, "**/obj": true }, - "formatFiles.excludePattern": "**/node_modules,**/.vscode,**/dist/**,**/.chrome,ThirdParty,RSSDP,Mono.Nat,unRaid,debian" + "formatFiles.excludePattern": "**/node_modules,**/.vscode,**/dist/**,**/.chrome,ThirdParty,unRaid,debian" } } diff --git a/src/Jellyfin.Networking/Jellyfin.Networking.csproj b/src/Jellyfin.Networking/Jellyfin.Networking.csproj index 472cdb7ef5..1a146549de 100644 --- a/src/Jellyfin.Networking/Jellyfin.Networking.csproj +++ b/src/Jellyfin.Networking/Jellyfin.Networking.csproj @@ -14,7 +14,4 @@ - - - diff --git a/src/Jellyfin.Networking/PortForwardingHost.cs b/src/Jellyfin.Networking/PortForwardingHost.cs deleted file mode 100644 index d01343624e..0000000000 --- a/src/Jellyfin.Networking/PortForwardingHost.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Net; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Mono.Nat; - -namespace Jellyfin.Networking; - -/// -/// responsible for UPnP port forwarding. -/// -public sealed class PortForwardingHost : IHostedService, IDisposable -{ - private readonly IServerApplicationHost _appHost; - private readonly ILogger _logger; - private readonly IServerConfigurationManager _config; - private readonly ConcurrentDictionary _createdRules = new(); - - private Timer? _timer; - private string? _configIdentifier; - private bool _disposed; - - /// - /// Initializes a new instance of the class. - /// - /// The logger. - /// The application host. - /// The configuration manager. - public PortForwardingHost( - ILogger logger, - IServerApplicationHost appHost, - IServerConfigurationManager config) - { - _logger = logger; - _appHost = appHost; - _config = config; - } - - private string GetConfigIdentifier() - { - const char Separator = '|'; - var config = _config.GetNetworkConfiguration(); - - return new StringBuilder(32) - .Append(config.EnableUPnP).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) - .Append(config.EnableRemoteAccess).Append(Separator) - .ToString(); - } - - private void OnConfigurationUpdated(object? sender, EventArgs e) - { - var oldConfigIdentifier = _configIdentifier; - _configIdentifier = GetConfigIdentifier(); - - if (!string.Equals(_configIdentifier, oldConfigIdentifier, StringComparison.OrdinalIgnoreCase)) - { - Stop(); - Start(); - } - } - - /// - public Task StartAsync(CancellationToken cancellationToken) - { - Start(); - - _config.ConfigurationUpdated += OnConfigurationUpdated; - - return Task.CompletedTask; - } - - /// - public Task StopAsync(CancellationToken cancellationToken) - { - Stop(); - - return Task.CompletedTask; - } - - private void Start() - { - var config = _config.GetNetworkConfiguration(); - if (!config.EnableUPnP || !config.EnableRemoteAccess) - { - return; - } - - _logger.LogInformation("Starting NAT discovery"); - - NatUtility.DeviceFound += OnNatUtilityDeviceFound; - NatUtility.StartDiscovery(); - - _timer?.Dispose(); - _timer = new Timer(_ => _createdRules.Clear(), null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10)); - } - - private void Stop() - { - _logger.LogInformation("Stopping NAT discovery"); - - NatUtility.StopDiscovery(); - NatUtility.DeviceFound -= OnNatUtilityDeviceFound; - - _timer?.Dispose(); - _timer = null; - } - - private async void OnNatUtilityDeviceFound(object? sender, DeviceEventArgs e) - { - ObjectDisposedException.ThrowIf(_disposed, this); - - try - { - // On some systems the device discovered event seems to fire repeatedly - // This check will help ensure we're not trying to port map the same device over and over - if (!_createdRules.TryAdd(e.Device.DeviceEndpoint, 0)) - { - return; - } - - await Task.WhenAll(CreatePortMaps(e.Device)).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error creating port forwarding rules"); - } - } - - private IEnumerable CreatePortMaps(INatDevice device) - { - var config = _config.GetNetworkConfiguration(); - yield return CreatePortMap(device, _appHost.HttpPort, config.PublicHttpPort); - - if (_appHost.ListenWithHttps) - { - yield return CreatePortMap(device, _appHost.HttpsPort, config.PublicHttpsPort); - } - } - - private async Task CreatePortMap(INatDevice device, int privatePort, int publicPort) - { - _logger.LogDebug( - "Creating port map on local port {LocalPort} to public port {PublicPort} with device {DeviceEndpoint}", - privatePort, - publicPort, - device.DeviceEndpoint); - - try - { - var mapping = new Mapping(Protocol.Tcp, privatePort, publicPort, 0, _appHost.Name); - await device.CreatePortMapAsync(mapping).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.LogError( - ex, - "Error creating port map on local port {LocalPort} to public port {PublicPort} with device {DeviceEndpoint}.", - privatePort, - publicPort, - device.DeviceEndpoint); - } - } - - /// - public void Dispose() - { - if (_disposed) - { - return; - } - - _config.ConfigurationUpdated -= OnConfigurationUpdated; - - _timer?.Dispose(); - _timer = null; - - _disposed = true; - } -}