Fix for multiple ip's in the same subnet per interface.

This commit is contained in:
BaronGreenback 2021-03-09 00:07:21 +00:00
parent e858e5f0b8
commit a031f7e410
3 changed files with 25 additions and 19 deletions

View File

@ -157,15 +157,16 @@ namespace Jellyfin.Networking.Manager
/// Creates a new network collection. /// Creates a new network collection.
/// </summary> /// </summary>
/// <param name="source">Items to assign the collection, or null.</param> /// <param name="source">Items to assign the collection, or null.</param>
/// <param name="unique"><c>True</c> if subnets that overlap should be merged (default).</param>
/// <returns>The collection created.</returns> /// <returns>The collection created.</returns>
public static Collection<IPObject> CreateCollection(IEnumerable<IPObject>? source = null) public static Collection<IPObject> CreateCollection(IEnumerable<IPObject>? source = null, bool unique = true)
{ {
var result = new Collection<IPObject>(); var result = new Collection<IPObject>();
if (source != null) if (source != null)
{ {
foreach (var item in source) foreach (var item in source)
{ {
result.AddItem(item); result.AddItem(item, unique);
} }
} }
@ -386,10 +387,12 @@ namespace Jellyfin.Networking.Manager
} }
// Get the first LAN interface address that isn't a loopback. // Get the first LAN interface address that isn't a loopback.
var interfaces = CreateCollection(_interfaceAddresses var interfaces = CreateCollection(
_interfaceAddresses
.Exclude(_bindExclusions) .Exclude(_bindExclusions)
.Where(IsInLocalNetwork) .Where(IsInLocalNetwork)
.OrderBy(p => p.Tag)); .OrderBy(p => p.Tag),
false);
if (interfaces.Count > 0) if (interfaces.Count > 0)
{ {
@ -429,11 +432,11 @@ namespace Jellyfin.Networking.Manager
if (_bindExclusions.Count > 0) if (_bindExclusions.Count > 0)
{ {
// Return all the internal interfaces except the ones excluded. // Return all the internal interfaces except the ones excluded.
return CreateCollection(_internalInterfaces.Where(p => !_bindExclusions.ContainsAddress(p))); return CreateCollection(_internalInterfaces.Where(p => !_bindExclusions.ContainsAddress(p)), false);
} }
// No bind address, so return all internal interfaces. // No bind address, so return all internal interfaces.
return CreateCollection(_internalInterfaces.Where(p => !p.IsLoopback())); return CreateCollection(_internalInterfaces.Where(p => !p.IsLoopback()), false);
} }
return new Collection<IPObject>(_bindAddresses); return new Collection<IPObject>(_bindAddresses);
@ -555,7 +558,7 @@ namespace Jellyfin.Networking.Manager
&& ((IsIP4Enabled && iface.Address.AddressFamily == AddressFamily.InterNetwork) && ((IsIP4Enabled && iface.Address.AddressFamily == AddressFamily.InterNetwork)
|| (IsIP6Enabled && iface.Address.AddressFamily == AddressFamily.InterNetworkV6))) || (IsIP6Enabled && iface.Address.AddressFamily == AddressFamily.InterNetworkV6)))
{ {
result.AddItem(iface); result.AddItem(iface, false);
} }
} }
@ -599,8 +602,8 @@ namespace Jellyfin.Networking.Manager
var address = IPNetAddress.Parse(parts[0]); var address = IPNetAddress.Parse(parts[0]);
var index = int.Parse(parts[1], CultureInfo.InvariantCulture); var index = int.Parse(parts[1], CultureInfo.InvariantCulture);
address.Tag = index; address.Tag = index;
_interfaceAddresses.AddItem(address); _interfaceAddresses.AddItem(address, false);
_interfaceNames.Add(parts[2], Math.Abs(index)); _interfaceNames[parts[2]] = Math.Abs(index);
} }
} }
@ -977,7 +980,7 @@ namespace Jellyfin.Networking.Manager
{ {
_logger.LogDebug("Using LAN interface addresses as user provided no LAN details."); _logger.LogDebug("Using LAN interface addresses as user provided no LAN details.");
// Internal interfaces must be private and not excluded. // Internal interfaces must be private and not excluded.
_internalInterfaces = CreateCollection(_interfaceAddresses.Where(i => IsPrivateAddressRange(i) && !_excludedSubnets.ContainsAddress(i))); _internalInterfaces = CreateCollection(_interfaceAddresses.Where(i => IsPrivateAddressRange(i) && !_excludedSubnets.ContainsAddress(i)), false);
// Subnets are the same as the calculated internal interface. // Subnets are the same as the calculated internal interface.
_lanSubnets = new Collection<IPObject>(); _lanSubnets = new Collection<IPObject>();
@ -1012,7 +1015,7 @@ namespace Jellyfin.Networking.Manager
} }
// Internal interfaces must be private, not excluded and part of the LocalNetworkSubnet. // Internal interfaces must be private, not excluded and part of the LocalNetworkSubnet.
_internalInterfaces = CreateCollection(_interfaceAddresses.Where(i => IsInLocalNetwork(i))); _internalInterfaces = CreateCollection(_interfaceAddresses.Where(i => IsInLocalNetwork(i)), false);
} }
_logger.LogInformation("Defined LAN addresses : {0}", _lanSubnets.AsString()); _logger.LogInformation("Defined LAN addresses : {0}", _lanSubnets.AsString());
@ -1071,7 +1074,7 @@ namespace Jellyfin.Networking.Manager
nw.Tag *= -1; nw.Tag *= -1;
} }
_interfaceAddresses.AddItem(nw); _interfaceAddresses.AddItem(nw, false);
// Store interface name so we can use the name in Collections. // Store interface name so we can use the name in Collections.
_interfaceNames[adapter.Description.ToLower(CultureInfo.InvariantCulture)] = tag; _interfaceNames[adapter.Description.ToLower(CultureInfo.InvariantCulture)] = tag;
@ -1092,7 +1095,7 @@ namespace Jellyfin.Networking.Manager
nw.Tag *= -1; nw.Tag *= -1;
} }
_interfaceAddresses.AddItem(nw); _interfaceAddresses.AddItem(nw, false);
// Store interface name so we can use the name in Collections. // Store interface name so we can use the name in Collections.
_interfaceNames[adapter.Description.ToLower(CultureInfo.InvariantCulture)] = tag; _interfaceNames[adapter.Description.ToLower(CultureInfo.InvariantCulture)] = tag;
@ -1126,10 +1129,10 @@ namespace Jellyfin.Networking.Manager
{ {
_logger.LogWarning("No interfaces information available. Using loopback."); _logger.LogWarning("No interfaces information available. Using loopback.");
// Last ditch attempt - use loopback address. // Last ditch attempt - use loopback address.
_interfaceAddresses.AddItem(IPNetAddress.IP4Loopback); _interfaceAddresses.AddItem(IPNetAddress.IP4Loopback, false);
if (IsIP6Enabled) if (IsIP6Enabled)
{ {
_interfaceAddresses.AddItem(IPNetAddress.IP6Loopback); _interfaceAddresses.AddItem(IPNetAddress.IP6Loopback, false);
} }
} }
} }

View File

@ -27,9 +27,10 @@ namespace MediaBrowser.Common.Net
/// </summary> /// </summary>
/// <param name="source">The <see cref="Collection{IPObject}"/>.</param> /// <param name="source">The <see cref="Collection{IPObject}"/>.</param>
/// <param name="item">Item to add.</param> /// <param name="item">Item to add.</param>
public static void AddItem(this Collection<IPObject> source, IPObject item) /// <param name="unique"><c>True</c> if subnets that overlap should be merged (default).</param>
public static void AddItem(this Collection<IPObject> source, IPObject item, bool unique = true)
{ {
if (!source.ContainsAddress(item)) if (!source.ContainsAddress(item) || !unique)
{ {
source.Add(item); source.Add(item);
} }

View File

@ -38,6 +38,8 @@ namespace Jellyfin.Networking.Tests
[InlineData("192.168.1.208/24,-16,vEthernet1|192.168.2.208/24,-16,vEthernet212|200.200.200.200/24,11,eth11", "192.168.1.0/24", "[]")] [InlineData("192.168.1.208/24,-16,vEthernet1|192.168.2.208/24,-16,vEthernet212|200.200.200.200/24,11,eth11", "192.168.1.0/24", "[]")]
// vEthernet1 and vEthernet212 should be excluded. // vEthernet1 and vEthernet212 should be excluded.
[InlineData("192.168.1.200/24,-20,vEthernet1|192.168.2.208/24,-16,vEthernet212|200.200.200.200/24,11,eth11", "192.168.1.0/24;200.200.200.200/24", "[200.200.200.200/24]")] [InlineData("192.168.1.200/24,-20,vEthernet1|192.168.2.208/24,-16,vEthernet212|200.200.200.200/24,11,eth11", "192.168.1.0/24;200.200.200.200/24", "[200.200.200.200/24]")]
// Overlapping interface,
[InlineData("192.168.1.110/24,-20,br0|192.168.1.10/24,-16,br0|200.200.200.200/24,11,eth11", "192.168.1.0/24", "[192.168.1.110/24,192.168.1.10/24]")]
public void IgnoreVirtualInterfaces(string interfaces, string lan, string value) public void IgnoreVirtualInterfaces(string interfaces, string lan, string value)
{ {
var conf = new NetworkConfiguration() var conf = new NetworkConfiguration()