Apply review suggestions

This commit is contained in:
Shadowghost 2022-10-14 10:25:57 +02:00
parent 7b90fcd053
commit 4aec41752f
5 changed files with 92 additions and 38 deletions

View File

@ -286,10 +286,10 @@ namespace Emby.Dlna.Main
// Only get bind addresses in LAN // Only get bind addresses in LAN
var bindAddresses = _networkManager var bindAddresses = _networkManager
.GetInternalBindAddresses() .GetInternalBindAddresses()
.Where(i => i.Address.AddressFamily == AddressFamily.InterNetwork .Where(i => i.Address.AddressFamily == AddressFamily.InterNetwork
|| (i.AddressFamily == AddressFamily.InterNetworkV6 && i.Address.ScopeId != 0)) || (i.AddressFamily == AddressFamily.InterNetworkV6 && i.Address.ScopeId != 0))
.ToList(); .ToList();
if (bindAddresses.Count == 0) if (bindAddresses.Count == 0)
{ {

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Net; using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jellyfin.Networking.Configuration; using Jellyfin.Networking.Configuration;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
@ -34,7 +35,7 @@ namespace Jellyfin.Networking.Manager
private readonly IConfigurationManager _configurationManager; private readonly IConfigurationManager _configurationManager;
private readonly object _eventFireLock; private readonly SemaphoreSlim _networkEvent;
/// <summary> /// <summary>
/// Holds the published server URLs and the IPs to use them on. /// Holds the published server URLs and the IPs to use them on.
@ -86,7 +87,7 @@ namespace Jellyfin.Networking.Manager
_interfaces = new List<IPData>(); _interfaces = new List<IPData>();
_macAddresses = new List<PhysicalAddress>(); _macAddresses = new List<PhysicalAddress>();
_publishedServerUrls = new Dictionary<IPData, string>(); _publishedServerUrls = new Dictionary<IPData, string>();
_eventFireLock = new object(); _networkEvent = new SemaphoreSlim(1, 1);
_remoteAddressFilter = new List<IPNetwork>(); _remoteAddressFilter = new List<IPNetwork>();
UpdateSettings(_configurationManager.GetNetworkConfiguration()); UpdateSettings(_configurationManager.GetNetworkConfiguration());
@ -143,7 +144,7 @@ namespace Jellyfin.Networking.Manager
private void OnNetworkAvailabilityChanged(object? sender, NetworkAvailabilityEventArgs e) private void OnNetworkAvailabilityChanged(object? sender, NetworkAvailabilityEventArgs e)
{ {
_logger.LogDebug("Network availability changed."); _logger.LogDebug("Network availability changed.");
OnNetworkChanged(); HandleNetworkChange();
} }
/// <summary> /// <summary>
@ -154,35 +155,34 @@ namespace Jellyfin.Networking.Manager
private void OnNetworkAddressChanged(object? sender, EventArgs e) private void OnNetworkAddressChanged(object? sender, EventArgs e)
{ {
_logger.LogDebug("Network address change detected."); _logger.LogDebug("Network address change detected.");
OnNetworkChanged(); HandleNetworkChange();
} }
/// <summary> /// <summary>
/// Triggers our event, and re-loads interface information. /// Triggers our event, and re-loads interface information.
/// </summary> /// </summary>
private void OnNetworkChanged() private void HandleNetworkChange()
{ {
lock (_eventFireLock) _networkEvent.Wait();
if (!_eventfire)
{ {
if (!_eventfire) _logger.LogDebug("Network Address Change Event.");
{ // As network events tend to fire one after the other only fire once every second.
_logger.LogDebug("Network Address Change Event."); _eventfire = true;
// As network events tend to fire one after the other only fire once every second. OnNetworkChange();
_eventfire = true;
OnNetworkChangeAsync().GetAwaiter().GetResult();
}
} }
_networkEvent.Release();
} }
/// <summary> /// <summary>
/// Async task that waits for 2 seconds before re-initialising the settings, as typically these events fire multiple times in succession. /// Waits for 2 seconds before re-initialising the settings, as typically these events fire multiple times in succession.
/// </summary> /// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> private void OnNetworkChange()
private async Task OnNetworkChangeAsync()
{ {
try try
{ {
await Task.Delay(2000).ConfigureAwait(false); Thread.Sleep(2000);
var networkConfig = _configurationManager.GetNetworkConfiguration(); var networkConfig = _configurationManager.GetNetworkConfiguration();
InitialiseLan(networkConfig); InitialiseLan(networkConfig);
InitialiseInterfaces(); InitialiseInterfaces();
@ -234,7 +234,7 @@ namespace Jellyfin.Networking.Manager
{ {
var interfaceObject = new IPData(info.Address, new IPNetwork(info.Address, info.PrefixLength), adapter.Name); var interfaceObject = new IPData(info.Address, new IPNetwork(info.Address, info.PrefixLength), adapter.Name);
interfaceObject.Index = ipProperties.GetIPv4Properties().Index; interfaceObject.Index = ipProperties.GetIPv4Properties().Index;
interfaceObject.Name = adapter.Name.ToLowerInvariant(); interfaceObject.Name = adapter.Name;
_interfaces.Add(interfaceObject); _interfaces.Add(interfaceObject);
} }
@ -242,7 +242,7 @@ namespace Jellyfin.Networking.Manager
{ {
var interfaceObject = new IPData(info.Address, new IPNetwork(info.Address, info.PrefixLength), adapter.Name); var interfaceObject = new IPData(info.Address, new IPNetwork(info.Address, info.PrefixLength), adapter.Name);
interfaceObject.Index = ipProperties.GetIPv6Properties().Index; interfaceObject.Index = ipProperties.GetIPv6Properties().Index;
interfaceObject.Name = adapter.Name.ToLowerInvariant(); interfaceObject.Name = adapter.Name;
_interfaces.Add(interfaceObject); _interfaces.Add(interfaceObject);
} }
@ -362,11 +362,10 @@ namespace Jellyfin.Networking.Manager
{ {
// Remove potentially exisiting * and split config string into prefixes // Remove potentially exisiting * and split config string into prefixes
var virtualInterfacePrefixes = config.VirtualInterfaceNames var virtualInterfacePrefixes = config.VirtualInterfaceNames
.Select(i => i.ToLowerInvariant() .Select(i => i.Replace("*", string.Empty, StringComparison.OrdinalIgnoreCase));
.Replace("*", string.Empty, StringComparison.OrdinalIgnoreCase));
// Check all interfaces for matches against the prefixes and remove them // Check all interfaces for matches against the prefixes and remove them
if (_interfaces.Count > 0 && virtualInterfacePrefixes.Any()) if (_interfaces.Count > 0)
{ {
foreach (var virtualInterfacePrefix in virtualInterfacePrefixes) foreach (var virtualInterfacePrefix in virtualInterfacePrefixes)
{ {
@ -548,6 +547,7 @@ namespace Jellyfin.Networking.Manager
_configurationManager.NamedConfigurationUpdated -= ConfigurationUpdated; _configurationManager.NamedConfigurationUpdated -= ConfigurationUpdated;
NetworkChange.NetworkAddressChanged -= OnNetworkAddressChanged; NetworkChange.NetworkAddressChanged -= OnNetworkAddressChanged;
NetworkChange.NetworkAvailabilityChanged -= OnNetworkAvailabilityChanged; NetworkChange.NetworkAvailabilityChanged -= OnNetworkAvailabilityChanged;
_networkEvent.Dispose();
} }
_disposed = true; _disposed = true;
@ -566,7 +566,7 @@ namespace Jellyfin.Networking.Manager
if (_interfaces != null) if (_interfaces != null)
{ {
// Match all interfaces starting with names starting with token // Match all interfaces starting with names starting with token
var matchedInterfaces = _interfaces.Where(s => s.Name.Equals(intf.ToLowerInvariant(), StringComparison.OrdinalIgnoreCase)).OrderBy(x => x.Index); var matchedInterfaces = _interfaces.Where(s => s.Name.Equals(intf, StringComparison.OrdinalIgnoreCase)).OrderBy(x => x.Index);
if (matchedInterfaces.Any()) if (matchedInterfaces.Any())
{ {
_logger.LogInformation("Interface {Token} used in settings. Using its interface addresses.", intf); _logger.LogInformation("Interface {Token} used in settings. Using its interface addresses.", intf);
@ -609,7 +609,7 @@ namespace Jellyfin.Networking.Manager
return false; return false;
} }
} }
else if (!_lanSubnets.Where(x => x.Contains(remoteIp)).Any()) else if (!_lanSubnets.Any(x => x.Contains(remoteIp)))
{ {
// Remote not enabled. So everyone should be LAN. // Remote not enabled. So everyone should be LAN.
return false; return false;
@ -875,10 +875,12 @@ namespace Jellyfin.Networking.Manager
bindPreference = string.Empty; bindPreference = string.Empty;
port = null; port = null;
var validPublishedServerUrls = _publishedServerUrls.Where(x => x.Key.Address.Equals(IPAddress.Any)).ToList(); var validPublishedServerUrls = _publishedServerUrls.Where(x => x.Key.Address.Equals(IPAddress.Any)
validPublishedServerUrls.AddRange(_publishedServerUrls.Where(x => x.Key.Address.Equals(IPAddress.IPv6Any))); || x.Key.Address.Equals(IPAddress.IPv6Any)
validPublishedServerUrls.AddRange(_publishedServerUrls.Where(x => x.Key.Subnet.Contains(source))); || x.Key.Subnet.Contains(source))
validPublishedServerUrls = validPublishedServerUrls.GroupBy(x => x.Key).Select(y => y.First()).ToList(); .GroupBy(x => x.Key)
.Select(y => y.First())
.ToList();
// Check for user override. // Check for user override.
foreach (var data in validPublishedServerUrls) foreach (var data in validPublishedServerUrls)

View File

@ -348,9 +348,9 @@ namespace Jellyfin.Server.Extensions
{ {
AddIpAddress(config, options, addr, addr.AddressFamily == AddressFamily.InterNetwork ? 32 : 128); AddIpAddress(config, options, addr, addr.AddressFamily == AddressFamily.InterNetwork ? 32 : 128);
} }
else if (NetworkExtensions.TryParseSubnets(new[] { allowedProxies[i] }, out var subnets)) else if (NetworkExtensions.TryParseSubnet(allowedProxies[i], out var subnet))
{ {
foreach (var subnet in subnets) if (subnet != null)
{ {
AddIpAddress(config, options, subnet.Prefix, subnet.PrefixLength); AddIpAddress(config, options, subnet.Prefix, subnet.PrefixLength);
} }

View File

@ -138,7 +138,7 @@ namespace MediaBrowser.Common.Net
/// <summary> /// <summary>
/// Try parsing an array of strings into subnets, respecting exclusions. /// Try parsing an array of strings into subnets, respecting exclusions.
/// </summary> /// </summary>
/// <param name="values">Input string to be parsed.</param> /// <param name="values">Input string array to be parsed.</param>
/// <param name="result">Collection of <see cref="IPNetwork"/>.</param> /// <param name="result">Collection of <see cref="IPNetwork"/>.</param>
/// <param name="negated">Boolean signaling if negated or not negated values should be parsed.</param> /// <param name="negated">Boolean signaling if negated or not negated values should be parsed.</param>
/// <returns><c>True</c> if parsing was successful.</returns> /// <returns><c>True</c> if parsing was successful.</returns>
@ -190,6 +190,58 @@ namespace MediaBrowser.Common.Net
return false; return false;
} }
/// <summary>
/// Try parsing a string into a subnet, respecting exclusions.
/// </summary>
/// <param name="value">Input string to be parsed.</param>
/// <param name="result">An <see cref="IPNetwork"/>.</param>
/// <param name="negated">Boolean signaling if negated or not negated values should be parsed.</param>
/// <returns><c>True</c> if parsing was successful.</returns>
public static bool TryParseSubnet(string value, out IPNetwork? result, bool negated = false)
{
result = null;
if (string.IsNullOrEmpty(value))
{
return false;
}
string[] v = value.Trim().Split("/");
var address = IPAddress.None;
if (negated && v[0].StartsWith('!'))
{
_ = IPAddress.TryParse(v[0][1..], out address);
}
else if (!negated)
{
_ = IPAddress.TryParse(v[0][0..], out address);
}
if (address != IPAddress.None && address != null)
{
if (int.TryParse(v[1], out var netmask))
{
result = new IPNetwork(address, netmask);
}
else if (address.AddressFamily == AddressFamily.InterNetwork)
{
result = new IPNetwork(address, 32);
}
else if (address.AddressFamily == AddressFamily.InterNetworkV6)
{
result = new IPNetwork(address, 128);
}
}
if (result != null)
{
return true;
}
return false;
}
/// <summary> /// <summary>
/// Attempts to parse a host string. /// Attempts to parse a host string.
/// </summary> /// </summary>

View File

@ -117,7 +117,7 @@ namespace Rssdp.Infrastructure
{ {
try try
{ {
_BroadcastListenSockets = ListenForBroadcastsAsync(); _BroadcastListenSockets = ListenForBroadcasts();
} }
catch (SocketException ex) catch (SocketException ex)
{ {
@ -333,7 +333,7 @@ namespace Rssdp.Infrastructure
return Task.CompletedTask; return Task.CompletedTask;
} }
private List<ISocket> ListenForBroadcastsAsync() private List<ISocket> ListenForBroadcasts()
{ {
var sockets = new List<ISocket>(); var sockets = new List<ISocket>();
if (_enableMultiSocketBinding) if (_enableMultiSocketBinding)
@ -352,7 +352,7 @@ namespace Rssdp.Infrastructure
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Error in ListenForBroadcastsAsync. IPAddress: {0}", address); _logger.LogError(ex, "Error in ListenForBroadcasts. IPAddress: {0}", address);
} }
} }
} }