Use System.Net.IPNetwork
This commit is contained in:
parent
eb022c49cc
commit
99e0d46ad9
363
Emby.Dlna/Main/DlnaEntryPoint.cs
Normal file
363
Emby.Dlna/Main/DlnaEntryPoint.cs
Normal file
|
@ -0,0 +1,363 @@
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Emby.Dlna.PlayTo;
|
||||||
|
using Emby.Dlna.Ssdp;
|
||||||
|
using Jellyfin.Networking.Configuration;
|
||||||
|
using Jellyfin.Networking.Extensions;
|
||||||
|
using MediaBrowser.Common.Configuration;
|
||||||
|
using MediaBrowser.Common.Extensions;
|
||||||
|
using MediaBrowser.Common.Net;
|
||||||
|
using MediaBrowser.Controller;
|
||||||
|
using MediaBrowser.Controller.Configuration;
|
||||||
|
using MediaBrowser.Controller.Dlna;
|
||||||
|
using MediaBrowser.Controller.Drawing;
|
||||||
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
|
using MediaBrowser.Controller.Plugins;
|
||||||
|
using MediaBrowser.Controller.Session;
|
||||||
|
using MediaBrowser.Model.Dlna;
|
||||||
|
using MediaBrowser.Model.Globalization;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Rssdp;
|
||||||
|
using Rssdp.Infrastructure;
|
||||||
|
|
||||||
|
namespace Emby.Dlna.Main
|
||||||
|
{
|
||||||
|
public sealed class DlnaEntryPoint : IServerEntryPoint, IRunBeforeStartup
|
||||||
|
{
|
||||||
|
private readonly IServerConfigurationManager _config;
|
||||||
|
private readonly ILogger<DlnaEntryPoint> _logger;
|
||||||
|
private readonly IServerApplicationHost _appHost;
|
||||||
|
private readonly ISessionManager _sessionManager;
|
||||||
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
private readonly IUserManager _userManager;
|
||||||
|
private readonly IDlnaManager _dlnaManager;
|
||||||
|
private readonly IImageProcessor _imageProcessor;
|
||||||
|
private readonly IUserDataManager _userDataManager;
|
||||||
|
private readonly ILocalizationManager _localization;
|
||||||
|
private readonly IMediaSourceManager _mediaSourceManager;
|
||||||
|
private readonly IMediaEncoder _mediaEncoder;
|
||||||
|
private readonly IDeviceDiscovery _deviceDiscovery;
|
||||||
|
private readonly ISsdpCommunicationsServer _communicationsServer;
|
||||||
|
private readonly INetworkManager _networkManager;
|
||||||
|
private readonly object _syncLock = new();
|
||||||
|
private readonly bool _disabled;
|
||||||
|
|
||||||
|
private PlayToManager _manager;
|
||||||
|
private SsdpDevicePublisher _publisher;
|
||||||
|
|
||||||
|
private bool _disposed;
|
||||||
|
|
||||||
|
public DlnaEntryPoint(
|
||||||
|
IServerConfigurationManager config,
|
||||||
|
ILoggerFactory loggerFactory,
|
||||||
|
IServerApplicationHost appHost,
|
||||||
|
ISessionManager sessionManager,
|
||||||
|
IHttpClientFactory httpClientFactory,
|
||||||
|
ILibraryManager libraryManager,
|
||||||
|
IUserManager userManager,
|
||||||
|
IDlnaManager dlnaManager,
|
||||||
|
IImageProcessor imageProcessor,
|
||||||
|
IUserDataManager userDataManager,
|
||||||
|
ILocalizationManager localizationManager,
|
||||||
|
IMediaSourceManager mediaSourceManager,
|
||||||
|
IDeviceDiscovery deviceDiscovery,
|
||||||
|
IMediaEncoder mediaEncoder,
|
||||||
|
ISsdpCommunicationsServer communicationsServer,
|
||||||
|
INetworkManager networkManager)
|
||||||
|
{
|
||||||
|
_config = config;
|
||||||
|
_appHost = appHost;
|
||||||
|
_sessionManager = sessionManager;
|
||||||
|
_httpClientFactory = httpClientFactory;
|
||||||
|
_libraryManager = libraryManager;
|
||||||
|
_userManager = userManager;
|
||||||
|
_dlnaManager = dlnaManager;
|
||||||
|
_imageProcessor = imageProcessor;
|
||||||
|
_userDataManager = userDataManager;
|
||||||
|
_localization = localizationManager;
|
||||||
|
_mediaSourceManager = mediaSourceManager;
|
||||||
|
_deviceDiscovery = deviceDiscovery;
|
||||||
|
_mediaEncoder = mediaEncoder;
|
||||||
|
_communicationsServer = communicationsServer;
|
||||||
|
_networkManager = networkManager;
|
||||||
|
_logger = loggerFactory.CreateLogger<DlnaEntryPoint>();
|
||||||
|
|
||||||
|
var netConfig = config.GetConfiguration<NetworkConfiguration>(NetworkConfigurationStore.StoreKey);
|
||||||
|
_disabled = appHost.ListenWithHttps && netConfig.RequireHttps;
|
||||||
|
|
||||||
|
if (_disabled && _config.GetDlnaConfiguration().EnableServer)
|
||||||
|
{
|
||||||
|
_logger.LogError("The DLNA specification does not support HTTPS.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task RunAsync()
|
||||||
|
{
|
||||||
|
await ((DlnaManager)_dlnaManager).InitProfilesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (_disabled)
|
||||||
|
{
|
||||||
|
// No use starting as dlna won't work, as we're running purely on HTTPS.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReloadComponents();
|
||||||
|
|
||||||
|
_config.NamedConfigurationUpdated += OnNamedConfigurationUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnNamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e)
|
||||||
|
{
|
||||||
|
if (string.Equals(e.Key, "dlna", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
ReloadComponents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReloadComponents()
|
||||||
|
{
|
||||||
|
var options = _config.GetDlnaConfiguration();
|
||||||
|
StartDeviceDiscovery();
|
||||||
|
|
||||||
|
if (options.EnableServer)
|
||||||
|
{
|
||||||
|
StartDevicePublisher(options);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DisposeDevicePublisher();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.EnablePlayTo)
|
||||||
|
{
|
||||||
|
StartPlayToManager();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DisposePlayToManager();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartDeviceDiscovery()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
((DeviceDiscovery)_deviceDiscovery).Start(_communicationsServer);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error starting device discovery");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartDevicePublisher(Configuration.DlnaOptions options)
|
||||||
|
{
|
||||||
|
if (_publisher is not null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_publisher = new SsdpDevicePublisher(
|
||||||
|
_communicationsServer,
|
||||||
|
Environment.OSVersion.Platform.ToString(),
|
||||||
|
// Can not use VersionString here since that includes OS and version
|
||||||
|
Environment.OSVersion.Version.ToString(),
|
||||||
|
_config.GetDlnaConfiguration().SendOnlyMatchedHost)
|
||||||
|
{
|
||||||
|
LogFunction = (msg) => _logger.LogDebug("{Msg}", msg),
|
||||||
|
SupportPnpRootDevice = false
|
||||||
|
};
|
||||||
|
|
||||||
|
RegisterServerEndpoints();
|
||||||
|
|
||||||
|
if (options.BlastAliveMessages)
|
||||||
|
{
|
||||||
|
_publisher.StartSendingAliveNotifications(TimeSpan.FromSeconds(options.BlastAliveMessageIntervalSeconds));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error registering endpoint");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterServerEndpoints()
|
||||||
|
{
|
||||||
|
var udn = CreateUuid(_appHost.SystemId);
|
||||||
|
var descriptorUri = "/dlna/" + udn + "/description.xml";
|
||||||
|
|
||||||
|
// Only get bind addresses in LAN
|
||||||
|
// IPv6 is currently unsupported
|
||||||
|
var validInterfaces = _networkManager.GetInternalBindAddresses()
|
||||||
|
.Where(x => x.Address is not null)
|
||||||
|
.Where(x => x.AddressFamily != AddressFamily.InterNetworkV6)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (validInterfaces.Count == 0)
|
||||||
|
{
|
||||||
|
// No interfaces returned, fall back to loopback
|
||||||
|
validInterfaces = _networkManager.GetLoopbacks().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var intf in validInterfaces)
|
||||||
|
{
|
||||||
|
var fullService = "urn:schemas-upnp-org:device:MediaServer:1";
|
||||||
|
|
||||||
|
_logger.LogInformation("Registering publisher for {ResourceName} on {DeviceAddress}", fullService, intf.Address);
|
||||||
|
|
||||||
|
var uri = new UriBuilder(_appHost.GetApiUrlForLocalAccess(intf.Address, false) + descriptorUri);
|
||||||
|
|
||||||
|
var device = new SsdpRootDevice
|
||||||
|
{
|
||||||
|
CacheLifetime = TimeSpan.FromSeconds(1800), // How long SSDP clients can cache this info.
|
||||||
|
Location = uri.Uri, // Must point to the URL that serves your devices UPnP description document.
|
||||||
|
Address = intf.Address,
|
||||||
|
PrefixLength = NetworkExtensions.MaskToCidr(intf.Subnet.BaseAddress),
|
||||||
|
FriendlyName = "Jellyfin",
|
||||||
|
Manufacturer = "Jellyfin",
|
||||||
|
ModelName = "Jellyfin Server",
|
||||||
|
Uuid = udn
|
||||||
|
// This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
SetProperties(device, fullService);
|
||||||
|
_publisher.AddDevice(device);
|
||||||
|
|
||||||
|
var embeddedDevices = new[]
|
||||||
|
{
|
||||||
|
"urn:schemas-upnp-org:service:ContentDirectory:1",
|
||||||
|
"urn:schemas-upnp-org:service:ConnectionManager:1",
|
||||||
|
// "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1"
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var subDevice in embeddedDevices)
|
||||||
|
{
|
||||||
|
var embeddedDevice = new SsdpEmbeddedDevice
|
||||||
|
{
|
||||||
|
FriendlyName = device.FriendlyName,
|
||||||
|
Manufacturer = device.Manufacturer,
|
||||||
|
ModelName = device.ModelName,
|
||||||
|
Uuid = udn
|
||||||
|
// This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
SetProperties(embeddedDevice, subDevice);
|
||||||
|
device.AddDevice(embeddedDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string CreateUuid(string text)
|
||||||
|
{
|
||||||
|
if (!Guid.TryParse(text, out var guid))
|
||||||
|
{
|
||||||
|
guid = text.GetMD5();
|
||||||
|
}
|
||||||
|
|
||||||
|
return guid.ToString("D", CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetProperties(SsdpDevice device, string fullDeviceType)
|
||||||
|
{
|
||||||
|
var serviceParts = fullDeviceType
|
||||||
|
.Replace("urn:", string.Empty, StringComparison.OrdinalIgnoreCase)
|
||||||
|
.Replace(":1", string.Empty, StringComparison.OrdinalIgnoreCase)
|
||||||
|
.Split(':');
|
||||||
|
|
||||||
|
device.DeviceTypeNamespace = serviceParts[0].Replace('.', '-');
|
||||||
|
device.DeviceClass = serviceParts[1];
|
||||||
|
device.DeviceType = serviceParts[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartPlayToManager()
|
||||||
|
{
|
||||||
|
lock (_syncLock)
|
||||||
|
{
|
||||||
|
if (_manager is not null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_manager = new PlayToManager(
|
||||||
|
_logger,
|
||||||
|
_sessionManager,
|
||||||
|
_libraryManager,
|
||||||
|
_userManager,
|
||||||
|
_dlnaManager,
|
||||||
|
_appHost,
|
||||||
|
_imageProcessor,
|
||||||
|
_deviceDiscovery,
|
||||||
|
_httpClientFactory,
|
||||||
|
_userDataManager,
|
||||||
|
_localization,
|
||||||
|
_mediaSourceManager,
|
||||||
|
_mediaEncoder);
|
||||||
|
|
||||||
|
_manager.Start();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error starting PlayTo manager");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisposePlayToManager()
|
||||||
|
{
|
||||||
|
lock (_syncLock)
|
||||||
|
{
|
||||||
|
if (_manager is not null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Disposing PlayToManager");
|
||||||
|
_manager.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error disposing PlayTo manager");
|
||||||
|
}
|
||||||
|
|
||||||
|
_manager = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisposeDevicePublisher()
|
||||||
|
{
|
||||||
|
if (_publisher is not null)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Disposing SsdpDevicePublisher");
|
||||||
|
_publisher.Dispose();
|
||||||
|
_publisher = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisposeDevicePublisher();
|
||||||
|
DisposePlayToManager();
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,6 @@ using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
|
using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
|
||||||
|
@ -530,7 +529,7 @@ namespace Jellyfin.Networking.Manager
|
||||||
{
|
{
|
||||||
foreach (var lan in _lanSubnets)
|
foreach (var lan in _lanSubnets)
|
||||||
{
|
{
|
||||||
var lanPrefix = lan.Prefix;
|
var lanPrefix = lan.BaseAddress;
|
||||||
publishedServerUrls.Add(
|
publishedServerUrls.Add(
|
||||||
new PublishedServerUriOverride(
|
new PublishedServerUriOverride(
|
||||||
new IPData(lanPrefix, new IPNetwork(lanPrefix, lan.PrefixLength)),
|
new IPData(lanPrefix, new IPNetwork(lanPrefix, lan.PrefixLength)),
|
||||||
|
@ -541,7 +540,7 @@ namespace Jellyfin.Networking.Manager
|
||||||
}
|
}
|
||||||
else if (NetworkUtils.TryParseToSubnet(identifier, out var result) && result is not null)
|
else if (NetworkUtils.TryParseToSubnet(identifier, out var result) && result is not null)
|
||||||
{
|
{
|
||||||
var data = new IPData(result.Prefix, result);
|
var data = new IPData(result.BaseAddress, result);
|
||||||
publishedServerUrls.Add(
|
publishedServerUrls.Add(
|
||||||
new PublishedServerUriOverride(
|
new PublishedServerUriOverride(
|
||||||
data,
|
data,
|
||||||
|
@ -607,7 +606,7 @@ namespace Jellyfin.Networking.Manager
|
||||||
var parts = details.Split(',');
|
var parts = details.Split(',');
|
||||||
if (NetworkUtils.TryParseToSubnet(parts[0], out var subnet))
|
if (NetworkUtils.TryParseToSubnet(parts[0], out var subnet))
|
||||||
{
|
{
|
||||||
var address = subnet.Prefix;
|
var address = subnet.BaseAddress;
|
||||||
var index = int.Parse(parts[1], CultureInfo.InvariantCulture);
|
var index = int.Parse(parts[1], CultureInfo.InvariantCulture);
|
||||||
if (address.AddressFamily == AddressFamily.InterNetwork || address.AddressFamily == AddressFamily.InterNetworkV6)
|
if (address.AddressFamily == AddressFamily.InterNetwork || address.AddressFamily == AddressFamily.InterNetworkV6)
|
||||||
{
|
{
|
||||||
|
@ -881,7 +880,7 @@ namespace Jellyfin.Networking.Manager
|
||||||
{
|
{
|
||||||
if (NetworkUtils.TryParseToSubnet(address, out var subnet))
|
if (NetworkUtils.TryParseToSubnet(address, out var subnet))
|
||||||
{
|
{
|
||||||
return IPAddress.IsLoopback(subnet.Prefix) || (_lanSubnets.Any(x => x.Contains(subnet.Prefix)) && !_excludedSubnets.Any(x => x.Contains(subnet.Prefix)));
|
return IPAddress.IsLoopback(subnet.BaseAddress) || (_lanSubnets.Any(x => x.Contains(subnet.BaseAddress)) && !_excludedSubnets.Any(x => x.Contains(subnet.BaseAddress)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetworkUtils.TryParseHost(address, out var addresses, IsIPv4Enabled, IsIPv6Enabled))
|
if (NetworkUtils.TryParseHost(address, out var addresses, IsIPv4Enabled, IsIPv6Enabled))
|
||||||
|
@ -1112,12 +1111,12 @@ namespace Jellyfin.Networking.Manager
|
||||||
var logLevel = debug ? LogLevel.Debug : LogLevel.Information;
|
var logLevel = debug ? LogLevel.Debug : LogLevel.Information;
|
||||||
if (_logger.IsEnabled(logLevel))
|
if (_logger.IsEnabled(logLevel))
|
||||||
{
|
{
|
||||||
_logger.Log(logLevel, "Defined LAN addresses: {0}", _lanSubnets.Select(s => s.Prefix + "/" + s.PrefixLength));
|
_logger.Log(logLevel, "Defined LAN addresses: {0}", _lanSubnets.Select(s => s.BaseAddress + "/" + s.PrefixLength));
|
||||||
_logger.Log(logLevel, "Defined LAN exclusions: {0}", _excludedSubnets.Select(s => s.Prefix + "/" + s.PrefixLength));
|
_logger.Log(logLevel, "Defined LAN exclusions: {0}", _excludedSubnets.Select(s => s.BaseAddress + "/" + s.PrefixLength));
|
||||||
_logger.Log(logLevel, "Using LAN addresses: {0}", _lanSubnets.Where(s => !_excludedSubnets.Contains(s)).Select(s => s.Prefix + "/" + s.PrefixLength));
|
_logger.Log(logLevel, "Using LAN addresses: {0}", _lanSubnets.Where(s => !_excludedSubnets.Contains(s)).Select(s => s.BaseAddress + "/" + s.PrefixLength));
|
||||||
_logger.Log(logLevel, "Using bind addresses: {0}", _interfaces.OrderByDescending(x => x.AddressFamily == AddressFamily.InterNetwork).Select(x => x.Address));
|
_logger.Log(logLevel, "Using bind addresses: {0}", _interfaces.OrderByDescending(x => x.AddressFamily == AddressFamily.InterNetwork).Select(x => x.Address));
|
||||||
_logger.Log(logLevel, "Remote IP filter is {0}", config.IsRemoteIPFilterBlacklist ? "Blocklist" : "Allowlist");
|
_logger.Log(logLevel, "Remote IP filter is {0}", config.IsRemoteIPFilterBlacklist ? "Blocklist" : "Allowlist");
|
||||||
_logger.Log(logLevel, "Filter list: {0}", _remoteAddressFilter.Select(s => s.Prefix + "/" + s.PrefixLength));
|
_logger.Log(logLevel, "Filter list: {0}", _remoteAddressFilter.Select(s => s.BaseAddress + "/" + s.PrefixLength));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Cors.Infrastructure;
|
using Microsoft.AspNetCore.Cors.Infrastructure;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.OpenApi.Any;
|
using Microsoft.OpenApi.Any;
|
||||||
using Microsoft.OpenApi.Interfaces;
|
using Microsoft.OpenApi.Interfaces;
|
||||||
|
@ -280,7 +279,7 @@ namespace Jellyfin.Server.Extensions
|
||||||
{
|
{
|
||||||
if (subnet is not null)
|
if (subnet is not null)
|
||||||
{
|
{
|
||||||
AddIPAddress(config, options, subnet.Prefix, subnet.PrefixLength);
|
AddIPAddress(config, options, subnet.BaseAddress, subnet.PrefixLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (NetworkUtils.TryParseHost(allowedProxies[i], out var addresses, config.EnableIPv4, config.EnableIPv6))
|
else if (NetworkUtils.TryParseHost(allowedProxies[i], out var addresses, config.EnableIPv4, config.EnableIPv6))
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Net;
|
namespace MediaBrowser.Common.Net;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Jellyfin.Extensions;
|
using Jellyfin.Extensions;
|
||||||
|
using Jellyfin.Networking.Constants;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Net;
|
namespace MediaBrowser.Common.Net;
|
||||||
|
@ -335,7 +336,7 @@ public static partial class NetworkUtils
|
||||||
/// <returns>The broadcast address.</returns>
|
/// <returns>The broadcast address.</returns>
|
||||||
public static IPAddress GetBroadcastAddress(IPNetwork network)
|
public static IPAddress GetBroadcastAddress(IPNetwork network)
|
||||||
{
|
{
|
||||||
var addressBytes = network.Prefix.GetAddressBytes();
|
var addressBytes = network.BaseAddress.GetAddressBytes();
|
||||||
uint ipAddress = BitConverter.ToUInt32(addressBytes, 0);
|
uint ipAddress = BitConverter.ToUInt32(addressBytes, 0);
|
||||||
uint ipMaskV4 = BitConverter.ToUInt32(CidrToMask(network.PrefixLength, AddressFamily.InterNetwork).GetAddressBytes(), 0);
|
uint ipMaskV4 = BitConverter.ToUInt32(CidrToMask(network.PrefixLength, AddressFamily.InterNetwork).GetAddressBytes(), 0);
|
||||||
uint broadCastIPAddress = ipAddress | ~ipMaskV4;
|
uint broadCastIPAddress = ipAddress | ~ipMaskV4;
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.HttpOverrides" />
|
|
||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
|
||||||
<PackageReference Include="MimeTypes">
|
<PackageReference Include="MimeTypes">
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Model.Net;
|
namespace MediaBrowser.Model.Net;
|
||||||
|
|
||||||
|
@ -66,9 +65,9 @@ public class IPData
|
||||||
{
|
{
|
||||||
if (Address.Equals(IPAddress.None))
|
if (Address.Equals(IPAddress.None))
|
||||||
{
|
{
|
||||||
return Subnet.Prefix.AddressFamily.Equals(IPAddress.None)
|
return Subnet.BaseAddress.AddressFamily.Equals(IPAddress.None)
|
||||||
? AddressFamily.Unspecified
|
? AddressFamily.Unspecified
|
||||||
: Subnet.Prefix.AddressFamily;
|
: Subnet.BaseAddress.AddressFamily;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
<!-- TODO: Remove once we update SkiaSharp > 2.88.5 -->
|
||||||
|
<NoWarn>NU1903</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -6,7 +6,6 @@ using Jellyfin.Server.Extensions;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
@ -99,7 +98,7 @@ namespace Jellyfin.Server.Tests
|
||||||
Assert.Equal(knownNetworks.Length, options.KnownNetworks.Count);
|
Assert.Equal(knownNetworks.Length, options.KnownNetworks.Count);
|
||||||
foreach (var item in knownNetworks)
|
foreach (var item in knownNetworks)
|
||||||
{
|
{
|
||||||
Assert.NotNull(options.KnownNetworks.FirstOrDefault(x => x.Prefix.Equals(item.Prefix) && x.PrefixLength == item.PrefixLength));
|
Assert.NotNull(options.KnownNetworks.FirstOrDefault(x => x.BaseAddress.Equals(item.BaseAddress) && x.PrefixLength == item.PrefixLength));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user