diff --git a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs
index e710eb3c76..df420f48a2 100644
--- a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs
+++ b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs
@@ -99,8 +99,7 @@ namespace Jellyfin.Networking.Configuration
public bool UPnPCreateHttpPortMap { get; set; }
///
- /// Gets or sets the UDPPortRange
- /// Gets or sets client udp port range.
+ /// Gets or sets the UDPPortRange.
///
public string UDPPortRange { get; set; } = string.Empty;
@@ -115,8 +114,8 @@ namespace Jellyfin.Networking.Configuration
public bool EnableIPV4 { get; set; } = true;
///
- /// Gets or sets a value indicating whether detailed ssdp logs are sent to the console/log.
- /// "Emby.Dlna": "Debug" must be set in logging.default.json for this property to work.
+ /// Gets or sets a value indicating whether detailed SSDP logs are sent to the console/log.
+ /// "Emby.Dlna": "Debug" must be set in logging.default.json for this property to have any effect.
///
public bool EnableSSDPTracing { get; set; }
@@ -143,7 +142,6 @@ namespace Jellyfin.Networking.Configuration
public bool IgnoreVirtualInterfaces { get; set; } = true;
///
- /// Gets or sets the VirtualInterfaceNames
/// Gets or sets a value indicating the interfaces that should be ignored. The list can be comma separated. .
///
public string VirtualInterfaceNames { get; set; } = "vEthernet*";
diff --git a/Jellyfin.Networking/Manager/NetworkManager.cs b/Jellyfin.Networking/Manager/NetworkManager.cs
index 00711f1620..515ae669a1 100644
--- a/Jellyfin.Networking/Manager/NetworkManager.cs
+++ b/Jellyfin.Networking/Manager/NetworkManager.cs
@@ -182,7 +182,7 @@ namespace Jellyfin.Networking.Manager
public IReadOnlyCollection GetMacAddresses()
{
// Populated in construction - so always has values.
- return _macAddresses.AsReadOnly();
+ return _macAddresses;
}
///
@@ -378,7 +378,7 @@ namespace Jellyfin.Networking.Manager
}
}
- _logger.LogDebug("GetBindInterface: Source: {0}, External: {1}:", haveSource, isExternal);
+ _logger.LogDebug("GetBindInterface: Source: {HaveSource}, External: {IsExternal}:", haveSource, isExternal);
// No preference given, so move on to bind addresses.
if (MatchesBindInterface(source, isExternal, out string result))
@@ -408,20 +408,20 @@ namespace Jellyfin.Networking.Manager
if (intf.Contains(source))
{
result = FormatIP6String(intf.Address);
- _logger.LogDebug("{0}: GetBindInterface: Has source, matched best internal interface on range. {1}", source, result);
+ _logger.LogDebug("{Source}: GetBindInterface: Has source, matched best internal interface on range. {Result}", source, result);
return result;
}
}
}
result = FormatIP6String(interfaces.First().Address);
- _logger.LogDebug("{0}: GetBindInterface: Matched first internal interface. {1}", source, result);
+ _logger.LogDebug("{Source}: GetBindInterface: Matched first internal interface. {Result}", source, result);
return result;
}
// There isn't any others, so we'll use the loopback.
result = IsIP6Enabled ? "::" : "127.0.0.1";
- _logger.LogWarning("{0}: GetBindInterface: Loopback return.", source, result);
+ _logger.LogWarning("{Source}: GetBindInterface: Loopback {Result} returned.", source, result);
return result;
}
@@ -552,7 +552,7 @@ namespace Jellyfin.Networking.Manager
{
result = new Collection();
- _logger.LogInformation("Interface {0} used in settings. Using its interface addresses.", token);
+ _logger.LogInformation("Interface {Token} used in settings. Using its interface addresses.", token);
// Replace interface tags with the interface IP's.
foreach (IPNetAddress iface in _interfaceAddresses)
@@ -575,7 +575,7 @@ namespace Jellyfin.Networking.Manager
/// Reloads all settings and re-initialises the instance.
///
/// The to use.
- public void UpdateSettings(NetworkConfiguration configuration)
+ public void UpdateSettings(object configuration)
{
NetworkConfiguration config = (NetworkConfiguration)configuration ?? throw new ArgumentNullException(nameof(configuration));
@@ -740,7 +740,7 @@ namespace Jellyfin.Networking.Manager
// Null check required here for automated testing.
if (IsInterface(token, out int index))
{
- _logger.LogInformation("Interface {0} used in settings. Using its interface addresses.", token);
+ _logger.LogInformation("Interface {Token} used in settings. Using its interface addresses.", token);
// Replace interface tags with the interface IP's.
foreach (IPNetAddress iface in _interfaceAddresses)
@@ -780,7 +780,7 @@ namespace Jellyfin.Networking.Manager
}
else
{
- _logger.LogDebug("Invalid or unknown network {0}.", token);
+ _logger.LogDebug("Invalid or unknown network {Token}.", token);
}
}
@@ -867,7 +867,7 @@ namespace Jellyfin.Networking.Manager
var parts = entry.Split('=');
if (parts.Length != 2)
{
- _logger.LogError("Unable to parse bind override. {0}", entry);
+ _logger.LogError("Unable to parse bind override: {Entry}", entry);
}
else
{
@@ -893,7 +893,7 @@ namespace Jellyfin.Networking.Manager
}
else
{
- _logger.LogError("Unable to parse bind ip address. {0}", parts[1]);
+ _logger.LogError("Unable to parse bind ip address. {Parts}", parts[1]);
}
}
}
@@ -905,30 +905,35 @@ namespace Jellyfin.Networking.Manager
///
private void InitialiseBind(NetworkConfiguration config)
{
- string[] lanAddresses = config.LocalNetworkAddresses;
-
- // TODO: remove when bug fixed: https://github.com/jellyfin/jellyfin-web/issues/1334
-
- if (lanAddresses.Length == 1 && lanAddresses[0].IndexOf(',', StringComparison.OrdinalIgnoreCase) != -1)
+ lock (_intLock)
{
- lanAddresses = lanAddresses[0].Split(',');
+ string[] lanAddresses = config.LocalNetworkAddresses;
+
+ // TODO: remove when bug fixed: https://github.com/jellyfin/jellyfin-web/issues/1334
+
+ if (lanAddresses.Length == 1 && lanAddresses[0].IndexOf(',', StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ lanAddresses = lanAddresses[0].Split(',');
+ }
+
+ // TODO: end fix: https://github.com/jellyfin/jellyfin-web/issues/1334
+
+ // Add virtual machine interface names to the list of bind exclusions, so that they are auto-excluded.
+ if (config.IgnoreVirtualInterfaces)
+ {
+ var virtualInterfaceNames = config.VirtualInterfaceNames.Split(',');
+ var newList = new string[lanAddresses.Length + virtualInterfaceNames.Length];
+ Array.Copy(lanAddresses, newList, lanAddresses.Length);
+ Array.Copy(virtualInterfaceNames, 0, newList, lanAddresses.Length, virtualInterfaceNames.Length);
+ lanAddresses = newList;
+ }
+
+ // Read and parse bind addresses and exclusions, removing ones that don't exist.
+ _bindAddresses = CreateIPCollection(lanAddresses).Union(_interfaceAddresses);
+ _bindExclusions = CreateIPCollection(lanAddresses, true).Union(_interfaceAddresses);
+ _logger.LogInformation("Using bind addresses: {0}", _bindAddresses.AsString());
+ _logger.LogInformation("Using bind exclusions: {0}", _bindExclusions.AsString());
}
-
- // TODO: end fix: https://github.com/jellyfin/jellyfin-web/issues/1334
-
- // Add virtual machine interface names to the list of bind exclusions, so that they are auto-excluded.
- if (config.IgnoreVirtualInterfaces)
- {
- var newList = lanAddresses.ToList();
- newList.AddRange(config.VirtualInterfaceNames.Split(',').ToList());
- lanAddresses = newList.ToArray();
- }
-
- // Read and parse bind addresses and exclusions, removing ones that don't exist.
- _bindAddresses = CreateIPCollection(lanAddresses).Union(_interfaceAddresses);
- _bindExclusions = CreateIPCollection(lanAddresses, true).Union(_interfaceAddresses);
- _logger.LogInformation("Using bind addresses: {0}", _bindAddresses.AsString());
- _logger.LogInformation("Using bind exclusions: {0}", _bindExclusions.AsString());
}
///
@@ -936,7 +941,10 @@ namespace Jellyfin.Networking.Manager
///
private void InitialiseRemote(NetworkConfiguration config)
{
- RemoteAddressFilter = CreateIPCollection(config.RemoteIPFilter);
+ lock (_intLock)
+ {
+ RemoteAddressFilter = CreateIPCollection(config.RemoteIPFilter);
+ }
}
///
@@ -959,7 +967,8 @@ namespace Jellyfin.Networking.Manager
// If no LAN addresses are specified - all private subnets are deemed to be the LAN
_usingPrivateAddresses = _lanSubnets.Count == 0;
- // NOTE: The order of the commands in this statement matters.
+ // NOTE: The order of the commands generating the collection in this statement matters.
+ // Altering the order will cause the collections to be created incorrectly.
if (_usingPrivateAddresses)
{
_logger.LogDebug("Using LAN interface addresses as user provided no LAN details.");
@@ -1020,6 +1029,7 @@ namespace Jellyfin.Networking.Manager
_interfaceNames.Clear();
_interfaceAddresses.Clear();
+ _macAddresses.Clear();
try
{
@@ -1051,7 +1061,7 @@ namespace Jellyfin.Networking.Manager
};
int tag = nw.Tag;
- if ((ipProperties.GatewayAddresses.Count > 0) && !nw.IsLoopback())
+ if (ipProperties.GatewayAddresses.Count > 0 && !nw.IsLoopback())
{
// -ve Tags signify the interface has a gateway.
nw.Tag *= -1;
@@ -1072,7 +1082,7 @@ namespace Jellyfin.Networking.Manager
};
int tag = nw.Tag;
- if ((ipProperties.GatewayAddresses.Count > 0) && !nw.IsLoopback())
+ if (ipProperties.GatewayAddresses.Count > 0 && !nw.IsLoopback())
{
// -ve Tags signify the interface has a gateway.
nw.Tag *= -1;
@@ -1087,9 +1097,10 @@ namespace Jellyfin.Networking.Manager
}
}
#pragma warning disable CA1031 // Do not catch general exception types
- catch
+ catch (Exception ex)
{
// Ignore error, and attempt to continue.
+ _logger.LogError(ex, "Error encountered parsing interfaces.");
}
#pragma warning restore CA1031 // Do not catch general exception types
}
@@ -1100,8 +1111,7 @@ namespace Jellyfin.Networking.Manager
// If for some reason we don't have an interface info, resolve our DNS name.
if (_interfaceAddresses.Count == 0)
{
- _logger.LogWarning("No interfaces information available. Using loopback.");
-
+ _logger.LogError("No interfaces information available. Resolving DNS name.");
IPHost host = new IPHost(Dns.GetHostName());
foreach (var a in host.GetAddresses())
{
@@ -1110,7 +1120,7 @@ namespace Jellyfin.Networking.Manager
if (_interfaceAddresses.Count == 0)
{
- _logger.LogError("No interfaces information available. Resolving DNS name.");
+ _logger.LogWarning("No interfaces information available. Using loopback.");
// Last ditch attempt - use loopback address.
_interfaceAddresses.AddItem(IPNetAddress.IP4Loopback);
if (IsIP6Enabled)
@@ -1131,11 +1141,11 @@ namespace Jellyfin.Networking.Manager
/// Attempts to match the source against a user defined bind interface.
///
/// IP source address to use.
- /// True if the source is in the external subnet.
+ /// True if the source is in the external subnet.
/// The published server url that matches the source address.
/// The resultant port, if one exists.
/// true if a match is found, false otherwise.
- private bool MatchesPublishedServerUrl(IPObject source, bool isExternal, out string bindPreference, out int? port)
+ private bool MatchesPublishedServerUrl(IPObject source, bool isInExternalSubnet, out string bindPreference, out int? port)
{
bindPreference = string.Empty;
port = null;
@@ -1144,12 +1154,12 @@ namespace Jellyfin.Networking.Manager
foreach (var addr in _publishedServerUrls)
{
// Remaining. Match anything.
- if (addr.Key.Equals(IPAddress.Broadcast))
+ if (addr.Key.Address.Equals(IPAddress.Broadcast))
{
bindPreference = addr.Value;
break;
}
- else if ((addr.Key.Equals(IPAddress.Any) || addr.Key.Equals(IPAddress.IPv6Any)) && isExternal)
+ else if ((addr.Key.Address.Equals(IPAddress.Any) || addr.Key.Address.Equals(IPAddress.IPv6Any)) && isInExternalSubnet)
{
// External.
bindPreference = addr.Value;
@@ -1163,38 +1173,38 @@ namespace Jellyfin.Networking.Manager
}
}
- if (!string.IsNullOrEmpty(bindPreference))
+ if (string.IsNullOrEmpty(bindPreference))
{
- // Has it got a port defined?
- var parts = bindPreference.Split(':');
- if (parts.Length > 1)
- {
- if (int.TryParse(parts[1], out int p))
- {
- bindPreference = parts[0];
- port = p;
- }
- }
-
- return true;
+ return false;
}
- return false;
+ // Has it got a port defined?
+ var parts = bindPreference.Split(':');
+ if (parts.Length > 1)
+ {
+ if (int.TryParse(parts[1], out int p))
+ {
+ bindPreference = parts[0];
+ port = p;
+ }
+ }
+
+ return true;
}
///
/// Attempts to match the source against a user defined bind interface.
///
/// IP source address to use.
- /// True if the source is in the external subnet.
+ /// True if the source is in the external subnet.
/// The result, if a match is found.
/// true if a match is found, false otherwise.
- private bool MatchesBindInterface(IPObject source, bool isExternal, out string result)
+ private bool MatchesBindInterface(IPObject source, bool isInExternalSubnet, out string result)
{
result = string.Empty;
- var nc = _bindAddresses.Exclude(_bindExclusions);
+ var addresses = _bindAddresses.Exclude(_bindExclusions);
- int count = nc.Count;
+ int count = addresses.Count;
if (count == 1 && (_bindAddresses[0].Equals(IPAddress.Any) || _bindAddresses[0].Equals(IPAddress.IPv6Any)))
{
// Ignore IPAny addresses.
@@ -1205,26 +1215,34 @@ namespace Jellyfin.Networking.Manager
{
// Check to see if any of the bind interfaces are in the same subnet.
- Collection bindResult;
IPAddress? defaultGateway = null;
- IPAddress? bindAddress;
+ IPAddress? bindAddress = null;
- if (isExternal)
+ if (isInExternalSubnet)
{
// Find all external bind addresses. Store the default gateway, but check to see if there is a better match first.
- bindResult = CreateCollection(nc
- .Where(p => !IsInLocalNetwork(p))
- .OrderBy(p => p.Tag));
- defaultGateway = bindResult.FirstOrDefault()?.Address;
- bindAddress = bindResult
- .Where(p => p.Contains(source))
- .OrderBy(p => p.Tag)
- .FirstOrDefault()?.Address;
+ foreach (var addr in addresses.OrderBy(p => p.Tag))
+ {
+ if (defaultGateway == null && !IsInLocalNetwork(addr))
+ {
+ defaultGateway = addr.Address;
+ }
+
+ if (bindAddress == null && addr.Contains(source))
+ {
+ bindAddress = addr.Address;
+ }
+
+ if (defaultGateway != null && bindAddress != null)
+ {
+ break;
+ }
+ }
}
else
{
// Look for the best internal address.
- bindAddress = nc
+ bindAddress = addresses
.Where(p => IsInLocalNetwork(p) && (p.Contains(source) || p.Equals(IPAddress.None)))
.OrderBy(p => p.Tag)
.FirstOrDefault()?.Address;
@@ -1233,23 +1251,23 @@ namespace Jellyfin.Networking.Manager
if (bindAddress != null)
{
result = FormatIP6String(bindAddress);
- _logger.LogDebug("{0}: GetBindInterface: Has source, found a match bind interface subnets. {1}", source, result);
+ _logger.LogDebug("{Source}: GetBindInterface: Has source, found a match bind interface subnets. {Result}", source, result);
return true;
}
- if (isExternal && defaultGateway != null)
+ if (isInExternalSubnet && defaultGateway != null)
{
result = FormatIP6String(defaultGateway);
- _logger.LogDebug("{0}: GetBindInterface: Using first user defined external interface. {1}", source, result);
+ _logger.LogDebug("{Source}: GetBindInterface: Using first user defined external interface. {Result}", source, result);
return true;
}
- result = FormatIP6String(nc.First().Address);
- _logger.LogDebug("{0}: GetBindInterface: Selected first user defined interface. {1}", source, result);
+ result = FormatIP6String(addresses[0].Address);
+ _logger.LogDebug("{Source}: GetBindInterface: Selected first user defined interface. {Result}", source, result);
- if (isExternal)
+ if (isInExternalSubnet)
{
- _logger.LogWarning("{0}: External request received, however, only an internal interface bind found.", source);
+ _logger.LogWarning("{Source}: External request received, however, only an internal interface bind found.", source);
}
return true;
@@ -1268,12 +1286,12 @@ namespace Jellyfin.Networking.Manager
{
result = string.Empty;
// Get the first WAN interface address that isn't a loopback.
- var extResult = CreateCollection(_interfaceAddresses
+ var extResult = _interfaceAddresses
.Exclude(_bindExclusions)
.Where(p => !IsInLocalNetwork(p))
- .OrderBy(p => p.Tag));
+ .OrderBy(p => p.Tag);
- if (extResult.Count > 0)
+ if (extResult.Any())
{
// Does the request originate in one of the interface subnets?
// (For systems with multiple internal network cards, and multiple subnets)
@@ -1282,19 +1300,19 @@ namespace Jellyfin.Networking.Manager
if (!IsInLocalNetwork(intf) && intf.Contains(source))
{
result = FormatIP6String(intf.Address);
- _logger.LogDebug("{0}: GetBindInterface: Selected best external on interface on range. {1}", source, result);
+ _logger.LogDebug("{Source}: GetBindInterface: Selected best external on interface on range. {Result}", source, result);
return true;
}
}
result = FormatIP6String(extResult.First().Address);
- _logger.LogDebug("{0}: GetBindInterface: Selected first external interface. {0}", source, result);
+ _logger.LogDebug("{Source}: GetBindInterface: Selected first external interface. {Result}", source, result);
return true;
}
// Have to return something, so return an internal address
- _logger.LogWarning("{0}: External request received, however, no WAN interface found.", source);
+ _logger.LogWarning("{Source}: External request received, however, no WAN interface found.", source);
return false;
}
}
diff --git a/MediaBrowser.Common/Net/IPHost.cs b/MediaBrowser.Common/Net/IPHost.cs
index f9e1568efc..4cede9ab16 100644
--- a/MediaBrowser.Common/Net/IPHost.cs
+++ b/MediaBrowser.Common/Net/IPHost.cs
@@ -1,5 +1,6 @@
#nullable enable
using System;
+using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
@@ -13,6 +14,11 @@ namespace MediaBrowser.Common.Net
///
public class IPHost : IPObject
{
+ ///
+ /// Gets or sets timeout value before resolve required, in minutes.
+ ///
+ public const int Timeout = 30;
+
///
/// Represents an IPHost that has no value.
///
@@ -21,7 +27,7 @@ namespace MediaBrowser.Common.Net
///
/// Time when last resolved in ticks.
///
- private long _lastResolved;
+ private DateTime? _lastResolved = null;
///
/// Gets the IP Addresses, attempting to resolve the name, if there are none.
@@ -83,15 +89,9 @@ namespace MediaBrowser.Common.Net
{
// Not implemented, as a host object can only have a prefix length of 128 (IPv6) or 32 (IPv4) prefix length,
// which is automatically determined by it's IP type. Anything else is meaningless.
- throw new NotImplementedException("The prefix length on a host cannot be set.");
}
}
- ///
- /// Gets or sets timeout value before resolve required, in minutes.
- ///
- public byte Timeout { get; set; } = 30;
-
///
/// Gets a value indicating whether the address has a value.
///
@@ -395,15 +395,15 @@ namespace MediaBrowser.Common.Net
private bool ResolveHost()
{
// When was the last time we resolved?
- if (_lastResolved == 0)
+ if (_lastResolved == null)
{
- _lastResolved = DateTime.UtcNow.Ticks;
+ _lastResolved = DateTime.UtcNow;
}
- // If we haven't resolved before, or out timer has run out...
- if ((_addresses.Length == 0 && !Resolved) || (TimeSpan.FromTicks(DateTime.UtcNow.Ticks - _lastResolved).TotalMinutes > Timeout))
+ // If we haven't resolved before, or our timer has run out...
+ if ((_addresses.Length == 0 && !Resolved) || (DateTime.UtcNow > _lastResolved?.AddMinutes(Timeout)))
{
- _lastResolved = DateTime.UtcNow.Ticks;
+ _lastResolved = DateTime.UtcNow;
ResolveHostInternal().GetAwaiter().GetResult();
Resolved = true;
}
@@ -433,9 +433,10 @@ namespace MediaBrowser.Common.Net
IPHostEntry ip = await Dns.GetHostEntryAsync(HostName).ConfigureAwait(false);
_addresses = ip.AddressList;
}
- catch (SocketException)
+ catch (SocketException ex)
{
- // Ignore socket errors, as the result value will just be an empty array.
+ // Log and then ignore socket errors, as the result value will just be an empty array.
+ Debug.WriteLine("GetHostEntryAsync failed with {Message}.", ex.Message);
}
}
}
diff --git a/MediaBrowser.Common/Net/IPNetAddress.cs b/MediaBrowser.Common/Net/IPNetAddress.cs
index 0d28c35cb8..a6f5fe4b37 100644
--- a/MediaBrowser.Common/Net/IPNetAddress.cs
+++ b/MediaBrowser.Common/Net/IPNetAddress.cs
@@ -18,17 +18,17 @@ namespace MediaBrowser.Common.Net
///
/// IPv4 multicast address.
///
- public static readonly IPAddress MulticastIPv4 = IPAddress.Parse("239.255.255.250");
+ public static readonly IPAddress SSDPMulticastIPv4 = IPAddress.Parse("239.255.255.250");
///
/// IPv6 local link multicast address.
///
- public static readonly IPAddress MulticastIPv6LinkLocal = IPAddress.Parse("ff02::C");
+ public static readonly IPAddress SSDPMulticastIPv6LinkLocal = IPAddress.Parse("ff02::C");
///
/// IPv6 site local multicast address.
///
- public static readonly IPAddress MulticastIPv6SiteLocal = IPAddress.Parse("ff05::C");
+ public static readonly IPAddress SSDPMulticastIPv6SiteLocal = IPAddress.Parse("ff05::C");
///
/// IP4Loopback address host.
@@ -235,7 +235,7 @@ namespace MediaBrowser.Common.Net
///
/// Returns a textual representation of this object.
///
- /// Set to true, if the subnet is to be included as part of the address.
+ /// Set to true, if the subnet is to be excluded as part of the address.
/// String representation of this object.
public string ToString(bool shortVersion)
{
diff --git a/MediaBrowser.Common/Net/IPObject.cs b/MediaBrowser.Common/Net/IPObject.cs
index d18ac98933..69cd57f8ae 100644
--- a/MediaBrowser.Common/Net/IPObject.cs
+++ b/MediaBrowser.Common/Net/IPObject.cs
@@ -86,7 +86,9 @@ namespace MediaBrowser.Common.Net
// prefix length value. eg. /16 on a 4 octet ip4 address (192.168.2.240) will result in the 2 and the 240 being zeroed out.
// Where there is not an exact boundary (eg /23), mod is used to calculate how many bits of this value are to be kept.
- byte[] addressBytes = address.GetAddressBytes();
+ // GetAddressBytes
+ Span addressBytes = stackalloc byte[address.AddressFamily == AddressFamily.InterNetwork ? 4 : 16];
+ address.TryWriteBytes(addressBytes, out _);
int div = prefixLength / 8;
int mod = prefixLength % 8;
@@ -170,14 +172,16 @@ namespace MediaBrowser.Common.Net
if (!address.Equals(IPAddress.None))
{
+ if (address.IsIPv4MappedToIPv6)
+ {
+ address = address.MapToIPv4();
+ }
+
if (address.AddressFamily == AddressFamily.InterNetwork)
{
- if (address.IsIPv4MappedToIPv6)
- {
- address = address.MapToIPv4();
- }
-
- byte[] octet = address.GetAddressBytes();
+ // GetAddressBytes
+ Span octet = stackalloc byte[4];
+ address.TryWriteBytes(octet, out _);
return (octet[0] == 10)
|| (octet[0] == 172 && octet[1] >= 16 && octet[1] <= 31) // RFC1918
@@ -186,7 +190,10 @@ namespace MediaBrowser.Common.Net
}
else
{
- byte[] octet = address.GetAddressBytes();
+ // GetAddressBytes
+ Span octet = stackalloc byte[16];
+ address.TryWriteBytes(octet, out _);
+
uint word = (uint)(octet[0] << 8) + octet[1];
return (word >= 0xfe80 && word <= 0xfebf) // fe80::/10 :Local link.
@@ -223,7 +230,9 @@ namespace MediaBrowser.Common.Net
return false;
}
- byte[] octet = address.GetAddressBytes();
+ // GetAddressBytes
+ Span octet = stackalloc byte[16];
+ address.TryWriteBytes(octet, out _);
uint word = (uint)(octet[0] << 8) + octet[1];
return word >= 0xfe80 && word <= 0xfebf; // fe80::/10 :Local link.
@@ -261,7 +270,9 @@ namespace MediaBrowser.Common.Net
byte cidrnet = 0;
if (!mask.Equals(IPAddress.Any))
{
- byte[] bytes = mask.GetAddressBytes();
+ // GetAddressBytes
+ Span bytes = stackalloc byte[mask.AddressFamily == AddressFamily.InterNetwork ? 4 : 16];
+ mask.TryWriteBytes(bytes, out _);
var zeroed = false;
for (var i = 0; i < bytes.Length; i++)