diff --git a/MediaBrowser.Common/Net/NetworkConstants.cs b/MediaBrowser.Common/Net/NetworkConstants.cs index b18058fa96..ccef5d2719 100644 --- a/MediaBrowser.Common/Net/NetworkConstants.cs +++ b/MediaBrowser.Common/Net/NetworkConstants.cs @@ -58,6 +58,11 @@ public static class NetworkConstants /// public static readonly IPNetwork IPv4RFC1918PrivateClassC = new IPNetwork(IPAddress.Parse("192.168.0.0"), 16); + /// + /// IPv4 Link-Local as defined in RFC 3927. + /// + public static readonly IPNetwork IPv4RFC3927LinkLocal = new IPNetwork(IPAddress.Parse("169.254.0.0"), 16); + /// /// IPv6 loopback as defined in RFC 4291. /// diff --git a/src/Jellyfin.Networking/Manager/NetworkManager.cs b/src/Jellyfin.Networking/Manager/NetworkManager.cs index 70790bb5b1..148b33fcbd 100644 --- a/src/Jellyfin.Networking/Manager/NetworkManager.cs +++ b/src/Jellyfin.Networking/Manager/NetworkManager.cs @@ -903,6 +903,17 @@ public class NetworkManager : INetworkManager, IDisposable return false; } + /// + /// Get if the IPAddress is Link-local. + /// + /// The IP Address. + /// Bool indicates if the address is link-local. + public bool IsLinkLocalAddress(IPAddress address) + { + ArgumentNullException.ThrowIfNull(address); + return NetworkConstants.IPv4RFC3927LinkLocal.Contains(address) || address.IsIPv6LinkLocal; + } + /// public bool IsInLocalNetwork(IPAddress address) { @@ -1084,7 +1095,11 @@ public class NetworkManager : INetworkManager, IDisposable private bool MatchesExternalInterface(IPAddress source, out string result) { // Get the first external interface address that isn't a loopback. - var extResult = _interfaces.Where(p => !IsInLocalNetwork(p.Address)).OrderBy(x => x.Index).ToArray(); + var extResult = _interfaces + .Where(p => !IsInLocalNetwork(p.Address)) + .Where(p => p.Address.AddressFamily.Equals(source.AddressFamily)) + .Where(p => !IsLinkLocalAddress(p.Address)) + .OrderBy(x => x.Index).ToArray(); // No external interface found if (extResult.Length == 0)