mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-04-18 19:25:00 -04:00
Remove the ability to auto port forward (#13222)
This commit is contained in:
parent
cc284afb47
commit
b318f33599
9 changed files with 7 additions and 200 deletions
|
@ -49,7 +49,6 @@
|
|||
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.1" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||
<PackageVersion Include="MimeTypes" Version="2.5.2" />
|
||||
<PackageVersion Include="Mono.Nat" Version="3.0.4" />
|
||||
<PackageVersion Include="Moq" Version="4.18.4" />
|
||||
<PackageVersion Include="NEbml" Version="0.11.0" />
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
/// </summary>
|
||||
[Required]
|
||||
[Obsolete("No longer supported")]
|
||||
public bool EnableAutomaticPortMapping { get; set; }
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#pragma warning disable CS0618 // obsolete
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
|
|
|
@ -129,7 +129,6 @@ namespace Jellyfin.Server
|
|||
|
||||
services.AddHostedService<RecordingsHost>();
|
||||
services.AddHostedService<AutoDiscoveryHost>();
|
||||
services.AddHostedService<PortForwardingHost>();
|
||||
services.AddHostedService<NfoUserDataSaver>();
|
||||
services.AddHostedService<LibraryChangedNotifier>();
|
||||
services.AddHostedService<UserDataChangeNotifier>();
|
||||
|
|
|
@ -110,6 +110,7 @@ public class NetworkConfiguration
|
|||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to enable automatic port forwarding.
|
||||
/// </summary>
|
||||
[Obsolete("No longer supported")]
|
||||
public bool EnableUPnP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,4 @@
|
|||
<ProjectReference Include="..\..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mono.Nat" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="IHostedService"/> responsible for UPnP port forwarding.
|
||||
/// </summary>
|
||||
public sealed class PortForwardingHost : IHostedService, IDisposable
|
||||
{
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly ILogger<PortForwardingHost> _logger;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly ConcurrentDictionary<IPEndPoint, byte> _createdRules = new();
|
||||
|
||||
private Timer? _timer;
|
||||
private string? _configIdentifier;
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PortForwardingHost"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="appHost">The application host.</param>
|
||||
/// <param name="config">The configuration manager.</param>
|
||||
public PortForwardingHost(
|
||||
ILogger<PortForwardingHost> 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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Start();
|
||||
|
||||
_config.ConfigurationUpdated += OnConfigurationUpdated;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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<Task> 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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_config.ConfigurationUpdated -= OnConfigurationUpdated;
|
||||
|
||||
_timer?.Dispose();
|
||||
_timer = null;
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue