diff --git a/Jellyfin.Networking/Manager/NetworkManager.cs b/Jellyfin.Networking/Manager/NetworkManager.cs
index dd90a5b516..f0f95f5fc8 100644
--- a/Jellyfin.Networking/Manager/NetworkManager.cs
+++ b/Jellyfin.Networking/Manager/NetworkManager.cs
@@ -26,11 +26,6 @@ namespace Jellyfin.Networking.Manager
///
private readonly object _initLock;
- ///
- /// List of all interface MAC addresses.
- ///
- private readonly List _macAddresses;
-
private readonly ILogger _logger;
private readonly IConfigurationManager _configurationManager;
@@ -40,30 +35,35 @@ namespace Jellyfin.Networking.Manager
///
/// Holds the published server URLs and the IPs to use them on.
///
- private readonly Dictionary _publishedServerUrls;
+ private IReadOnlyDictionary _publishedServerUrls;
- private List _remoteAddressFilter;
+ private IReadOnlyList _remoteAddressFilter;
///
/// Used to stop "event-racing conditions".
///
private bool _eventfire;
+ ///
+ /// List of all interface MAC addresses.
+ ///
+ private IReadOnlyList _macAddresses;
+
///
/// Dictionary containing interface addresses and their subnets.
///
- private List _interfaces;
+ private IReadOnlyList _interfaces;
///
/// Unfiltered user defined LAN subnets ()
/// or internal interface network subnets if undefined by user.
///
- private List _lanSubnets;
+ private IReadOnlyList _lanSubnets;
///
/// User defined list of subnets to excluded from the LAN.
///
- private List _excludedSubnets;
+ private IReadOnlyList _excludedSubnets;
///
/// True if this object is disposed.
@@ -127,7 +127,7 @@ namespace Jellyfin.Networking.Manager
///
/// Gets the Published server override list.
///
- public Dictionary PublishedServerUrls => _publishedServerUrls;
+ public IReadOnlyDictionary PublishedServerUrls => _publishedServerUrls;
///
public void Dispose()
@@ -206,8 +206,8 @@ namespace Jellyfin.Networking.Manager
{
_logger.LogDebug("Refreshing interfaces.");
- _interfaces.Clear();
- _macAddresses.Clear();
+ var interfaces = new List();
+ var macAddresses = new List();
try
{
@@ -224,7 +224,7 @@ namespace Jellyfin.Networking.Manager
// Populate MAC list
if (adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback && PhysicalAddress.None.Equals(mac))
{
- _macAddresses.Add(mac);
+ macAddresses.Add(mac);
}
// Populate interface list
@@ -236,7 +236,7 @@ namespace Jellyfin.Networking.Manager
interfaceObject.Index = ipProperties.GetIPv4Properties().Index;
interfaceObject.Name = adapter.Name;
- _interfaces.Add(interfaceObject);
+ interfaces.Add(interfaceObject);
}
else if (IsIPv6Enabled && info.Address.AddressFamily == AddressFamily.InterNetworkV6)
{
@@ -244,7 +244,7 @@ namespace Jellyfin.Networking.Manager
interfaceObject.Index = ipProperties.GetIPv6Properties().Index;
interfaceObject.Name = adapter.Name;
- _interfaces.Add(interfaceObject);
+ interfaces.Add(interfaceObject);
}
}
}
@@ -265,23 +265,26 @@ namespace Jellyfin.Networking.Manager
}
// If no interfaces are found, fallback to loopback interfaces.
- if (_interfaces.Count == 0)
+ if (interfaces.Count == 0)
{
_logger.LogWarning("No interface information available. Using loopback interface(s).");
if (IsIPv4Enabled && !IsIPv6Enabled)
{
- _interfaces.Add(new IPData(IPAddress.Loopback, new IPNetwork(IPAddress.Loopback, 8), "lo"));
+ interfaces.Add(new IPData(IPAddress.Loopback, new IPNetwork(IPAddress.Loopback, 8), "lo"));
}
if (!IsIPv4Enabled && IsIPv6Enabled)
{
- _interfaces.Add(new IPData(IPAddress.IPv6Loopback, new IPNetwork(IPAddress.IPv6Loopback, 128), "lo"));
+ interfaces.Add(new IPData(IPAddress.IPv6Loopback, new IPNetwork(IPAddress.IPv6Loopback, 128), "lo"));
}
}
- _logger.LogDebug("Discovered {NumberOfInterfaces} interfaces.", _interfaces.Count);
- _logger.LogDebug("Interfaces addresses: {Addresses}", _interfaces.OrderByDescending(s => s.AddressFamily == AddressFamily.InterNetwork).Select(s => s.Address.ToString()));
+ _logger.LogDebug("Discovered {NumberOfInterfaces} interfaces.", interfaces.Count);
+ _logger.LogDebug("Interfaces addresses: {Addresses}", interfaces.OrderByDescending(s => s.AddressFamily == AddressFamily.InterNetwork).Select(s => s.Address.ToString()));
+
+ _macAddresses = macAddresses;
+ _interfaces = interfaces;
}
}
@@ -297,37 +300,38 @@ namespace Jellyfin.Networking.Manager
// Get configuration options
var subnets = config.LocalNetworkSubnets;
- if (!NetworkExtensions.TryParseToSubnets(subnets, out _lanSubnets, false))
- {
- _lanSubnets.Clear();
- }
-
- if (!NetworkExtensions.TryParseToSubnets(subnets, out _excludedSubnets, true))
- {
- _excludedSubnets.Clear();
- }
-
// If no LAN addresses are specified, all private subnets and Loopback are deemed to be the LAN
- if (_lanSubnets.Count == 0)
+ if (!NetworkExtensions.TryParseToSubnets(subnets, out var lanSubnets, false) || lanSubnets.Count == 0)
{
_logger.LogDebug("Using LAN interface addresses as user provided no LAN details.");
+ var fallbackLanSubnets = new List();
if (IsIPv6Enabled)
{
- _lanSubnets.Add(new IPNetwork(IPAddress.IPv6Loopback, 128)); // RFC 4291 (Loopback)
- _lanSubnets.Add(new IPNetwork(IPAddress.Parse("fe80::"), 10)); // RFC 4291 (Site local)
- _lanSubnets.Add(new IPNetwork(IPAddress.Parse("fc00::"), 7)); // RFC 4193 (Unique local)
+ fallbackLanSubnets.Add(new IPNetwork(IPAddress.IPv6Loopback, 128)); // RFC 4291 (Loopback)
+ fallbackLanSubnets.Add(new IPNetwork(IPAddress.Parse("fe80::"), 10)); // RFC 4291 (Site local)
+ fallbackLanSubnets.Add(new IPNetwork(IPAddress.Parse("fc00::"), 7)); // RFC 4193 (Unique local)
}
if (IsIPv4Enabled)
{
- _lanSubnets.Add(new IPNetwork(IPAddress.Loopback, 8)); // RFC 5735 (Loopback)
- _lanSubnets.Add(new IPNetwork(IPAddress.Parse("10.0.0.0"), 8)); // RFC 1918 (private)
- _lanSubnets.Add(new IPNetwork(IPAddress.Parse("172.16.0.0"), 12)); // RFC 1918 (private)
- _lanSubnets.Add(new IPNetwork(IPAddress.Parse("192.168.0.0"), 16)); // RFC 1918 (private)
+ fallbackLanSubnets.Add(new IPNetwork(IPAddress.Loopback, 8)); // RFC 5735 (Loopback)
+ fallbackLanSubnets.Add(new IPNetwork(IPAddress.Parse("10.0.0.0"), 8)); // RFC 1918 (private)
+ fallbackLanSubnets.Add(new IPNetwork(IPAddress.Parse("172.16.0.0"), 12)); // RFC 1918 (private)
+ fallbackLanSubnets.Add(new IPNetwork(IPAddress.Parse("192.168.0.0"), 16)); // RFC 1918 (private)
}
+
+ _lanSubnets = fallbackLanSubnets;
+ }
+ else
+ {
+ _lanSubnets = lanSubnets;
}
+ _excludedSubnets = NetworkExtensions.TryParseToSubnets(subnets, out var excludedSubnets, true)
+ ? excludedSubnets
+ : new List();
+
_logger.LogInformation("Defined LAN addresses: {0}", _lanSubnets.Select(s => s.Prefix + "/" + s.PrefixLength));
_logger.LogInformation("Defined LAN exclusions: {0}", _excludedSubnets.Select(s => s.Prefix + "/" + s.PrefixLength));
_logger.LogInformation("Using LAN addresses: {0}", _lanSubnets.Where(s => !_excludedSubnets.Contains(s)).Select(s => s.Prefix + "/" + s.PrefixLength));
@@ -342,26 +346,27 @@ namespace Jellyfin.Networking.Manager
lock (_initLock)
{
// Respect explicit bind addresses
+ var interfaces = _interfaces.ToList();
var localNetworkAddresses = config.LocalNetworkAddresses;
if (localNetworkAddresses.Length > 0 && !string.IsNullOrWhiteSpace(localNetworkAddresses[0]))
{
var bindAddresses = localNetworkAddresses.Select(p => NetworkExtensions.TryParseToSubnet(p, out var network)
? network.Prefix
- : (_interfaces.Where(x => x.Name.Equals(p, StringComparison.OrdinalIgnoreCase))
+ : (interfaces.Where(x => x.Name.Equals(p, StringComparison.OrdinalIgnoreCase))
.Select(x => x.Address)
.FirstOrDefault() ?? IPAddress.None))
.Where(x => x != IPAddress.None)
.ToHashSet();
- _interfaces = _interfaces.Where(x => bindAddresses.Contains(x.Address)).ToList();
+ interfaces = interfaces.Where(x => bindAddresses.Contains(x.Address)).ToList();
if (bindAddresses.Contains(IPAddress.Loopback))
{
- _interfaces.Add(new IPData(IPAddress.Loopback, new IPNetwork(IPAddress.Loopback, 8), "lo"));
+ interfaces.Add(new IPData(IPAddress.Loopback, new IPNetwork(IPAddress.Loopback, 8), "lo"));
}
if (bindAddresses.Contains(IPAddress.IPv6Loopback))
{
- _interfaces.Add(new IPData(IPAddress.IPv6Loopback, new IPNetwork(IPAddress.IPv6Loopback, 128), "lo"));
+ interfaces.Add(new IPData(IPAddress.IPv6Loopback, new IPNetwork(IPAddress.IPv6Loopback, 128), "lo"));
}
}
@@ -377,7 +382,7 @@ namespace Jellyfin.Networking.Manager
{
foreach (var virtualInterfacePrefix in virtualInterfacePrefixes)
{
- _interfaces.RemoveAll(x => x.Name.StartsWith(virtualInterfacePrefix, StringComparison.OrdinalIgnoreCase));
+ interfaces.RemoveAll(x => x.Name.StartsWith(virtualInterfacePrefix, StringComparison.OrdinalIgnoreCase));
}
}
}
@@ -385,16 +390,17 @@ namespace Jellyfin.Networking.Manager
// Remove all IPv4 interfaces if IPv4 is disabled
if (!IsIPv4Enabled)
{
- _interfaces.RemoveAll(x => x.AddressFamily == AddressFamily.InterNetwork);
+ interfaces.RemoveAll(x => x.AddressFamily == AddressFamily.InterNetwork);
}
// Remove all IPv6 interfaces if IPv6 is disabled
if (!IsIPv6Enabled)
{
- _interfaces.RemoveAll(x => x.AddressFamily == AddressFamily.InterNetworkV6);
+ interfaces.RemoveAll(x => x.AddressFamily == AddressFamily.InterNetworkV6);
}
- _logger.LogInformation("Using bind addresses: {0}", _interfaces.OrderByDescending(x => x.AddressFamily == AddressFamily.InterNetwork).Select(x => x.Address));
+ _logger.LogInformation("Using bind addresses: {0}", interfaces.OrderByDescending(x => x.AddressFamily == AddressFamily.InterNetwork).Select(x => x.Address));
+ _interfaces = interfaces;
}
}
@@ -410,10 +416,11 @@ namespace Jellyfin.Networking.Manager
if (remoteIPFilter.Any() && !string.IsNullOrWhiteSpace(remoteIPFilter.First()))
{
// Parse all IPs with netmask to a subnet
+ var remoteAddressFilter = new List();
var remoteFilteredSubnets = remoteIPFilter.Where(x => x.Contains('/', StringComparison.OrdinalIgnoreCase)).ToArray();
- if (!NetworkExtensions.TryParseToSubnets(remoteFilteredSubnets, out _remoteAddressFilter, false))
+ if (NetworkExtensions.TryParseToSubnets(remoteFilteredSubnets, out var remoteAddressFilterResult, false))
{
- _remoteAddressFilter.Clear();
+ remoteAddressFilter = remoteAddressFilterResult.ToList();
}
// Parse everything else as an IP and construct subnet with a single IP
@@ -422,9 +429,11 @@ namespace Jellyfin.Networking.Manager
{
if (IPAddress.TryParse(ip, out var ipp))
{
- _remoteAddressFilter.Add(new IPNetwork(ipp, ipp.AddressFamily == AddressFamily.InterNetwork ? 32 : 128));
+ remoteAddressFilter.Add(new IPNetwork(ipp, ipp.AddressFamily == AddressFamily.InterNetwork ? 32 : 128));
}
}
+
+ _remoteAddressFilter = remoteAddressFilter;
}
}
}
@@ -440,8 +449,8 @@ namespace Jellyfin.Networking.Manager
{
lock (_initLock)
{
- _publishedServerUrls.Clear();
- string[] overrides = config.PublishedServerUriBySubnet;
+ var publishedServerUrls = new Dictionary();
+ var overrides = config.PublishedServerUriBySubnet;
foreach (var entry in overrides)
{
@@ -456,31 +465,31 @@ namespace Jellyfin.Networking.Manager
var identifier = parts[0];
if (string.Equals(identifier, "all", StringComparison.OrdinalIgnoreCase))
{
- _publishedServerUrls[new IPData(IPAddress.Broadcast, null)] = replacement;
+ publishedServerUrls[new IPData(IPAddress.Broadcast, null)] = replacement;
}
else if (string.Equals(identifier, "external", StringComparison.OrdinalIgnoreCase))
{
- _publishedServerUrls[new IPData(IPAddress.Any, new IPNetwork(IPAddress.Any, 0))] = replacement;
- _publishedServerUrls[new IPData(IPAddress.IPv6Any, new IPNetwork(IPAddress.IPv6Any, 0))] = replacement;
+ publishedServerUrls[new IPData(IPAddress.Any, new IPNetwork(IPAddress.Any, 0))] = replacement;
+ publishedServerUrls[new IPData(IPAddress.IPv6Any, new IPNetwork(IPAddress.IPv6Any, 0))] = replacement;
}
else if (string.Equals(identifier, "internal", StringComparison.OrdinalIgnoreCase))
{
foreach (var lan in _lanSubnets)
{
var lanPrefix = lan.Prefix;
- _publishedServerUrls[new IPData(lanPrefix, new IPNetwork(lanPrefix, lan.PrefixLength))] = replacement;
+ publishedServerUrls[new IPData(lanPrefix, new IPNetwork(lanPrefix, lan.PrefixLength))] = replacement;
}
}
else if (NetworkExtensions.TryParseToSubnet(identifier, out var result) && result is not null)
{
var data = new IPData(result.Prefix, result);
- _publishedServerUrls[data] = replacement;
+ publishedServerUrls[data] = replacement;
}
else if (TryParseInterface(identifier, out var ifaces))
{
foreach (var iface in ifaces)
{
- _publishedServerUrls[iface] = replacement;
+ publishedServerUrls[iface] = replacement;
}
}
else
@@ -488,6 +497,8 @@ namespace Jellyfin.Networking.Manager
_logger.LogError("Unable to parse bind override: {Entry}", entry);
}
}
+
+ _publishedServerUrls = publishedServerUrls;
}
}
@@ -520,6 +531,7 @@ namespace Jellyfin.Networking.Manager
{
// Format is ,,: . Set index to -ve to simulate a gateway.
var interfaceList = MockNetworkSettings.Split('|');
+ var interfaces = new List();
foreach (var details in interfaceList)
{
var parts = details.Split(',');
@@ -531,7 +543,7 @@ namespace Jellyfin.Networking.Manager
{
var data = new IPData(address, subnet, parts[2]);
data.Index = index;
- _interfaces.Add(data);
+ interfaces.Add(data);
}
}
else
@@ -539,6 +551,8 @@ namespace Jellyfin.Networking.Manager
_logger.LogWarning("Could not parse mock interface settings: {Part}", details);
}
}
+
+ _interfaces = interfaces;
}
EnforceBindSettings(config);
@@ -565,11 +579,12 @@ namespace Jellyfin.Networking.Manager
}
///
- public bool TryParseInterface(string intf, out List result)
+ public bool TryParseInterface(string intf, out IReadOnlyList result)
{
- result = new List();
+ var resultList = new List();
if (string.IsNullOrEmpty(intf) || _interfaces is null)
{
+ result = resultList.AsReadOnly();
return false;
}
@@ -585,13 +600,15 @@ namespace Jellyfin.Networking.Manager
if ((IsIPv4Enabled && iface.Address.AddressFamily == AddressFamily.InterNetwork)
|| (IsIPv6Enabled && iface.Address.AddressFamily == AddressFamily.InterNetworkV6))
{
- result.Add(iface);
+ resultList.Add(iface);
}
}
+ result = resultList.AsReadOnly();
return true;
}
+ result = resultList.AsReadOnly();
return false;
}
diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs
index 1a3176b581..a92b751f2a 100644
--- a/MediaBrowser.Common/Net/INetworkManager.cs
+++ b/MediaBrowser.Common/Net/INetworkManager.cs
@@ -30,7 +30,7 @@ namespace MediaBrowser.Common.Net
///
/// Calculates the list of interfaces to use for Kestrel.
///
- /// A List{IPData} object containing all the interfaces to bind.
+ /// A IReadOnlyList{IPData} object containing all the interfaces to bind.
/// If all the interfaces are specified, and none are excluded, it returns zero items
/// to represent any address.
/// When false, return or for all interfaces.
@@ -39,7 +39,7 @@ namespace MediaBrowser.Common.Net
///
/// Returns a list containing the loopback interfaces.
///
- /// List{IPData}.
+ /// IReadOnlyList{IPData}.
IReadOnlyList GetLoopbacks();
///
@@ -120,7 +120,7 @@ namespace MediaBrowser.Common.Net
/// Interface name.
/// Resulting object's IP addresses, if successful.
/// Success of the operation.
- bool TryParseInterface(string intf, out List result);
+ bool TryParseInterface(string intf, out IReadOnlyList result);
///
/// Returns all internal (LAN) bind interface addresses.
diff --git a/MediaBrowser.Common/Net/NetworkExtensions.cs b/MediaBrowser.Common/Net/NetworkExtensions.cs
index cef4a5d965..227f0483f4 100644
--- a/MediaBrowser.Common/Net/NetworkExtensions.cs
+++ b/MediaBrowser.Common/Net/NetworkExtensions.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;
+using Jellyfin.Extensions;
using Microsoft.AspNetCore.HttpOverrides;
namespace MediaBrowser.Common.Net
@@ -193,71 +194,64 @@ namespace MediaBrowser.Common.Net
/// An .
/// Boolean signaling if negated or not negated values should be parsed.
/// True if parsing was successful.
- public static bool TryParseToSubnet(string value, out IPNetwork result, bool negated = false)
+ public static bool TryParseToSubnet(ReadOnlySpan value, out IPNetwork result, bool negated = false)
{
result = new IPNetwork(IPAddress.None, 32);
-
- if (string.IsNullOrEmpty(value))
- {
- return false;
- }
-
- var splitString = value.Trim().Split("/");
- var ipBlock = splitString[0];
-
- var address = IPAddress.None;
- if (negated && ipBlock.StartsWith('!') && IPAddress.TryParse(ipBlock[1..], out var tmpAddress))
- {
- address = tmpAddress;
- }
- else if (!negated && IPAddress.TryParse(ipBlock, out tmpAddress))
+ var splitString = value.Trim().Split('/');
+ if (splitString.MoveNext())
{
- address = tmpAddress;
- }
+ var ipBlock = splitString.Current;
+ var address = IPAddress.None;
+ if (negated && ipBlock.StartsWith("!") && IPAddress.TryParse(ipBlock[1..], out var tmpAddress))
+ {
+ address = tmpAddress;
+ }
+ else if (!negated && IPAddress.TryParse(ipBlock, out tmpAddress))
+ {
+ address = tmpAddress;
+ }
- if (address != IPAddress.None && address is not null)
- {
- if (splitString.Length > 1)
+ if (address != IPAddress.None)
{
- var subnetBlock = splitString[1];
- if (int.TryParse(subnetBlock, out var netmask))
+ if (splitString.MoveNext())
{
- result = new IPNetwork(address, netmask);
+ var subnetBlock = splitString.Current;
+ if (int.TryParse(subnetBlock, out var netmask))
+ {
+ result = new IPNetwork(address, netmask);
+ }
+ else if (IPAddress.TryParse(subnetBlock, out var netmaskAddress))
+ {
+ result = new IPNetwork(address, NetworkExtensions.MaskToCidr(netmaskAddress));
+ }
}
- else if (IPAddress.TryParse(subnetBlock, out var netmaskAddress))
+ else if (address.AddressFamily == AddressFamily.InterNetwork)
{
- result = new IPNetwork(address, NetworkExtensions.MaskToCidr(netmaskAddress));
+ result = new IPNetwork(address, 32);
+ }
+ else if (address.AddressFamily == AddressFamily.InterNetworkV6)
+ {
+ result = new IPNetwork(address, 128);
}
- }
- else if (address.AddressFamily == AddressFamily.InterNetwork)
- {
- result = new IPNetwork(address, 32);
- }
- else if (address.AddressFamily == AddressFamily.InterNetworkV6)
- {
- result = new IPNetwork(address, 128);
- }
- }
- if (!result.Prefix.Equals(IPAddress.None))
- {
- return true;
+ return true;
+ }
}
return false;
}
///
- /// Attempts to parse a host string.
+ /// Attempts to parse a host span.
///
/// Host name to parse.
- /// Object representing the string, if it has successfully been parsed.
+ /// Object representing the span, if it has successfully been parsed.
/// true if IPv4 is enabled.
/// true if IPv6 is enabled.
/// true if the parsing is successful, false if not.
- public static bool TryParseHost(string host, [NotNullWhen(true)] out IPAddress[] addresses, bool isIPv4Enabled = true, bool isIPv6Enabled = false)
+ public static bool TryParseHost(ReadOnlySpan host, [NotNullWhen(true)] out IPAddress[] addresses, bool isIPv4Enabled = true, bool isIPv6Enabled = false)
{
- if (string.IsNullOrWhiteSpace(host))
+ if (host.IsEmpty)
{
addresses = Array.Empty();
return false;
@@ -268,19 +262,24 @@ namespace MediaBrowser.Common.Net
// See if it's an IPv6 with port address e.g. [::1] or [::1]:120.
if (host[0] == '[')
{
- int i = host.IndexOf(']', StringComparison.Ordinal);
+ int i = host.IndexOf("]", StringComparison.Ordinal);
if (i != -1)
{
- return TryParseHost(host.Remove(i)[1..], out addresses);
+ return TryParseHost(host[1..(i - 1)], out addresses);
}
addresses = Array.Empty();
return false;
}
- var hosts = host.Split(':');
+ var hosts = new List();
+ var splitSpan = host.Split(':');
+ while (splitSpan.MoveNext())
+ {
+ hosts.Add(splitSpan.Current.ToString());
+ }
- if (hosts.Length <= 2)
+ if (hosts.Count <= 2)
{
// Is hostname or hostname:port
if (_fqdnRegex.IsMatch(hosts[0]))
@@ -315,10 +314,14 @@ namespace MediaBrowser.Common.Net
return true;
}
}
- else if (hosts.Length <= 9 && IPAddress.TryParse(host.Split('/')[0], out var address)) // 8 octets + port
+ else if (hosts.Count <= 9) // 8 octets + port
{
- addresses = new[] { address };
- return true;
+ splitSpan = host.Split('/');
+ if (splitSpan.MoveNext() && IPAddress.TryParse(splitSpan.Current, out var address))
+ {
+ addresses = new[] { address };
+ return true;
+ }
}
addresses = Array.Empty();
diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs
index 5b8916d021..0dce6c3bfa 100644
--- a/RSSDP/SsdpCommunicationsServer.cs
+++ b/RSSDP/SsdpCommunicationsServer.cs
@@ -428,7 +428,7 @@ namespace Rssdp.Infrastructure
if (result.ReceivedBytes > 0)
{
var remoteEndpoint = (IPEndPoint)result.RemoteEndPoint;
- var localEndpointAdapter = _networkManager.GetAllBindInterfaces().Where(a => a.Index == result.PacketInformation.Interface).First();
+ var localEndpointAdapter = _networkManager.GetAllBindInterfaces().First(a => a.Index == result.PacketInformation.Interface);
ProcessMessage(
UTF8Encoding.UTF8.GetString(receiveBuffer, 0, result.ReceivedBytes),
diff --git a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs
index d51ce19d75..8b7df0470d 100644
--- a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs
+++ b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs
@@ -203,7 +203,7 @@ namespace Jellyfin.Networking.Tests
using var nm = new NetworkManager(GetMockConfig(conf), new NullLogger());
NetworkManager.MockNetworkSettings = string.Empty;
- _ = nm.TryParseInterface(result, out List? resultObj);
+ _ = nm.TryParseInterface(result, out IReadOnlyList? resultObj);
// Check to see if dns resolution is working. If not, skip test.
_ = NetworkExtensions.TryParseHost(source, out var host);
@@ -266,7 +266,7 @@ namespace Jellyfin.Networking.Tests
using var nm = new NetworkManager(GetMockConfig(conf), new NullLogger());
NetworkManager.MockNetworkSettings = string.Empty;
- if (nm.TryParseInterface(result, out List? resultObj) && resultObj is not null)
+ if (nm.TryParseInterface(result, out IReadOnlyList? resultObj) && resultObj is not null)
{
// Parse out IPAddresses so we can do a string comparison (ignore subnet masks).
result = resultObj.First().Address.ToString();