diff options
Diffstat (limited to 'Jellyfin.Networking/Manager/NetworkManager.cs')
| -rw-r--r-- | Jellyfin.Networking/Manager/NetworkManager.cs | 85 |
1 files changed, 64 insertions, 21 deletions
diff --git a/Jellyfin.Networking/Manager/NetworkManager.cs b/Jellyfin.Networking/Manager/NetworkManager.cs index 60b899519..785a058d3 100644 --- a/Jellyfin.Networking/Manager/NetworkManager.cs +++ b/Jellyfin.Networking/Manager/NetworkManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Net; @@ -284,14 +285,25 @@ namespace Jellyfin.Networking.Manager // No bind address and no exclusions, so listen on all interfaces. Collection<IPObject> result = new Collection<IPObject>(); - if (IsIP4Enabled) + if (IsIP6Enabled && IsIP4Enabled) + { + // Kestrel source code shows it uses Sockets.DualMode - so this also covers IPAddress.Any + result.AddItem(IPAddress.IPv6Any); + } + else if (IsIP4Enabled) { result.AddItem(IPAddress.Any); } - - if (IsIP6Enabled) + else if (IsIP6Enabled) { - result.AddItem(IPAddress.IPv6Any); + // Cannot use IPv6Any as Kestrel will bind to IPv4 addresses. + foreach (var iface in _interfaceAddresses) + { + if (iface.AddressFamily == AddressFamily.InterNetworkV6) + { + result.AddItem(iface.Address); + } + } } return result; @@ -387,7 +399,7 @@ namespace Jellyfin.Networking.Manager // Get the first LAN interface address that isn't a loopback. var interfaces = CreateCollection(_interfaceAddresses .Exclude(_bindExclusions) - .Where(p => IsInLocalNetwork(p)) + .Where(IsInLocalNetwork) .OrderBy(p => p.Tag)); if (interfaces.Count > 0) @@ -413,7 +425,7 @@ namespace Jellyfin.Networking.Manager } // There isn't any others, so we'll use the loopback. - result = IsIP6Enabled ? "::" : "127.0.0.1"; + result = IsIP6Enabled ? "::1" : "127.0.0.1"; _logger.LogWarning("{Source}: GetBindInterface: Loopback {Result} returned.", source, result); return result; } @@ -564,6 +576,29 @@ namespace Jellyfin.Networking.Manager return false; } + /// <inheritdoc/> + public bool HasRemoteAccess(IPAddress remoteIp) + { + var config = _configurationManager.GetNetworkConfiguration(); + if (config.EnableRemoteAccess) + { + // Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. + // If left blank, all remote addresses will be allowed. + if (RemoteAddressFilter.Count > 0 && !IsInLocalNetwork(remoteIp)) + { + // remoteAddressFilter is a whitelist or blacklist. + return RemoteAddressFilter.ContainsAddress(remoteIp) == !config.IsRemoteIPFilterBlacklist; + } + } + else if (!IsInLocalNetwork(remoteIp)) + { + // Remote not enabled. So everyone should be LAN. + return false; + } + + return true; + } + /// <summary> /// Reloads all settings and re-initialises the instance. /// </summary> @@ -591,7 +626,7 @@ namespace Jellyfin.Networking.Manager else // Used in testing only. { // Format is <IPAddress>,<Index>,<Name>: <next interface>. Set index to -ve to simulate a gateway. - var interfaceList = MockNetworkSettings.Split(':'); + var interfaceList = MockNetworkSettings.Split('|'); foreach (var details in interfaceList) { var parts = details.Split(','); @@ -691,11 +726,11 @@ namespace Jellyfin.Networking.Manager /// Checks the string to see if it matches any interface names. /// </summary> /// <param name="token">String to check.</param> - /// <param name="index">Interface index number.</param> + /// <param name="index">Interface index numbers that match.</param> /// <returns><c>true</c> if an interface name matches the token, <c>False</c> otherwise.</returns> - private bool IsInterface(string token, out int index) + private bool TryGetInterfaces(string token, [NotNullWhen(true)] out List<int>? index) { - index = -1; + index = null; // Is it the name of an interface (windows) eg, Wireless LAN adapter Wireless Network Connection 1. // Null check required here for automated testing. @@ -712,13 +747,13 @@ namespace Jellyfin.Networking.Manager if ((!partial && string.Equals(interfc, token, StringComparison.OrdinalIgnoreCase)) || (partial && interfc.StartsWith(token, true, CultureInfo.InvariantCulture))) { - index = interfcIndex; - return true; + index ??= new List<int>(); + index.Add(interfcIndex); } } } - return false; + return index != null; } /// <summary> @@ -730,14 +765,14 @@ namespace Jellyfin.Networking.Manager { // Is it the name of an interface (windows) eg, Wireless LAN adapter Wireless Network Connection 1. // Null check required here for automated testing. - if (IsInterface(token, out int index)) + if (TryGetInterfaces(token, out var indices)) { _logger.LogInformation("Interface {Token} used in settings. Using its interface addresses.", token); - // Replace interface tags with the interface IP's. + // Replace all the interface tags with the interface IP's. foreach (IPNetAddress iface in _interfaceAddresses) { - if (Math.Abs(iface.Tag) == index + if (indices.Contains(Math.Abs(iface.Tag)) && ((IsIP4Enabled && iface.Address.AddressFamily == AddressFamily.InterNetwork) || (IsIP6Enabled && iface.Address.AddressFamily == AddressFamily.InterNetworkV6))) { @@ -916,11 +951,19 @@ namespace Jellyfin.Networking.Manager // 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; + // each virtual interface name must be pre-pended with the exclusion symbol ! + var virtualInterfaceNames = config.VirtualInterfaceNames.Split(',').Select(p => "!" + p).ToArray(); + if (lanAddresses.Length > 0) + { + 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; + } + else + { + lanAddresses = virtualInterfaceNames; + } } // Read and parse bind addresses and exclusions, removing ones that don't exist. |
