mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-04 09:22:09 +01:00
Fix UDP Auto-Discovery returning IPv6 for cross-subnet IPv4 requests
Fixes #15898 When a UDP discovery request is relayed from a different IPv4 subnet, GetBindAddress() now correctly returns an IPv4 address instead of incorrectly falling back to ::1. Changes: - Loopback fallback now prefers address family matching the source IP - Interface fallback now prefers interfaces matching source address family - Added test case for cross-subnet IPv4 request scenario
This commit is contained in:
@@ -164,6 +164,7 @@
|
||||
- [XVicarious](https://github.com/XVicarious)
|
||||
- [YouKnowBlom](https://github.com/YouKnowBlom)
|
||||
- [ZachPhelan](https://github.com/ZachPhelan)
|
||||
- [ZeusCraft10](https://github.com/ZeusCraft10)
|
||||
- [KristupasSavickas](https://github.com/KristupasSavickas)
|
||||
- [Pusta](https://github.com/pusta)
|
||||
- [nielsvanvelzen](https://github.com/nielsvanvelzen)
|
||||
|
||||
@@ -875,7 +875,20 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||
if (availableInterfaces.Count == 0)
|
||||
{
|
||||
// There isn't any others, so we'll use the loopback.
|
||||
result = IsIPv4Enabled && !IsIPv6Enabled ? "127.0.0.1" : "::1";
|
||||
// Prefer loopback address matching the source's address family
|
||||
if (source is not null && source.AddressFamily == AddressFamily.InterNetwork && IsIPv4Enabled)
|
||||
{
|
||||
result = "127.0.0.1";
|
||||
}
|
||||
else if (source is not null && source.AddressFamily == AddressFamily.InterNetworkV6 && IsIPv6Enabled)
|
||||
{
|
||||
result = "::1";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = IsIPv4Enabled ? "127.0.0.1" : "::1";
|
||||
}
|
||||
|
||||
_logger.LogWarning("{Source}: Only loopback {Result} returned, using that as bind address.", source, result);
|
||||
return result;
|
||||
}
|
||||
@@ -900,9 +913,19 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to first available interface
|
||||
// Fallback to an interface matching the source's address family, or first available
|
||||
var preferredInterface = availableInterfaces
|
||||
.FirstOrDefault(x => x.Address.AddressFamily == source.AddressFamily);
|
||||
|
||||
if (preferredInterface is not null)
|
||||
{
|
||||
result = NetworkUtils.FormatIPString(preferredInterface.Address);
|
||||
_logger.LogDebug("{Source}: No matching subnet found, using interface with matching address family: {Result}", source, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = NetworkUtils.FormatIPString(availableInterfaces[0].Address);
|
||||
_logger.LogDebug("{Source}: No matching interfaces found, using preferred interface as bind address: {Result}", source, result);
|
||||
_logger.LogDebug("{Source}: No matching interfaces found, using first available interface as bind address: {Result}", source, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -377,6 +377,8 @@ namespace Jellyfin.Networking.Tests
|
||||
[InlineData("192.168.1.208/24,-16,eth16|10.0.0.1/24,10,eth7", "192.168.1.0/24", "10.0.0.1", "192.168.1.209", "10.0.0.1")] // LAN not bound, so return external.
|
||||
[InlineData("192.168.1.208/24,-16,eth16|10.0.0.1/24,10,eth7", "192.168.1.0/24", "192.168.1.208,10.0.0.1", "8.8.8.8", "10.0.0.1")] // return external bind address
|
||||
[InlineData("192.168.1.208/24,-16,eth16|10.0.0.1/24,10,eth7", "192.168.1.0/24", "192.168.1.208,10.0.0.1", "192.168.1.210", "192.168.1.208")] // return LAN bind address
|
||||
// Cross-subnet IPv4 request should return IPv4, not IPv6 (Issue #15898)
|
||||
[InlineData("192.168.1.208/24,-16,eth16|fd00::1/64,10,eth7", "192.168.1.0/24", "", "192.168.2.100", "192.168.1.208")]
|
||||
public void GetBindInterface_ValidSourceGiven_Success(string interfaces, string lan, string bind, string source, string result)
|
||||
{
|
||||
var conf = new NetworkConfiguration
|
||||
|
||||
Reference in New Issue
Block a user