Let AutoDiscoveryHost bind to all addresses

Signed-off-by: gnattu <gnattuoc@me.com>
pull/11504/head
gnattu 9 months ago
parent aaa42871ca
commit d919284b59

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
@ -11,7 +10,6 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Model.ApiClient; using MediaBrowser.Model.ApiClient;
using MediaBrowser.Model.Net;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -51,25 +49,6 @@ public sealed class AutoDiscoveryHost : BackgroundService
_networkManager = networkManager; _networkManager = networkManager;
} }
private static IPAddress GetBindAddress(IPData intf)
{
if (intf.AddressFamily == AddressFamily.InterNetwork)
{
if (OperatingSystem.IsLinux())
{
return NetworkUtils.GetBroadcastAddress(intf.Subnet);
}
if (OperatingSystem.IsMacOS())
{
// macOS kernel does not allow bind to 127:255:255:255
return IPAddress.IsLoopback(intf.Address) ? intf.Address : NetworkUtils.GetBroadcastAddress(intf.Subnet);
}
}
return intf.Address;
}
/// <inheritdoc /> /// <inheritdoc />
protected override async Task ExecuteAsync(CancellationToken stoppingToken) protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{ {
@ -80,17 +59,7 @@ public sealed class AutoDiscoveryHost : BackgroundService
} }
var udpServers = new List<Task>(); var udpServers = new List<Task>();
// Linux needs to bind to the broadcast addresses to receive broadcast traffic udpServers.Add(ListenForAutoDiscoveryMessage(IPAddress.Any, IPAddress.Any, stoppingToken));
if (OperatingSystem.IsLinux() && networkConfig.EnableIPv4)
{
udpServers.Add(ListenForAutoDiscoveryMessage(IPAddress.Broadcast, IPAddress.Broadcast, stoppingToken));
}
udpServers.AddRange(_networkManager.GetInternalBindAddresses()
.Select(intf => ListenForAutoDiscoveryMessage(
GetBindAddress(intf),
intf.Address,
stoppingToken)));
await Task.WhenAll(udpServers).ConfigureAwait(false); await Task.WhenAll(udpServers).ConfigureAwait(false);
} }
@ -110,7 +79,7 @@ public sealed class AutoDiscoveryHost : BackgroundService
var text = Encoding.UTF8.GetString(result.Buffer); var text = Encoding.UTF8.GetString(result.Buffer);
if (text.Contains("who is JellyfinServer?", StringComparison.OrdinalIgnoreCase)) if (text.Contains("who is JellyfinServer?", StringComparison.OrdinalIgnoreCase))
{ {
await RespondToV2Message(respondAddress, result.RemoteEndPoint, cancellationToken).ConfigureAwait(false); await RespondToV2Message(respondAddress, result.RemoteEndPoint, udpClient, cancellationToken).ConfigureAwait(false);
} }
} }
catch (SocketException ex) catch (SocketException ex)
@ -130,28 +99,48 @@ public sealed class AutoDiscoveryHost : BackgroundService
} }
} }
private async Task RespondToV2Message(IPAddress responderIp, IPEndPoint endpoint, CancellationToken cancellationToken) private async Task RespondToV2Message(IPAddress responderIp, IPEndPoint endpoint, UdpClient broadCastUdpClient, CancellationToken cancellationToken)
{ {
var localUrl = _appHost.GetSmartApiUrl(endpoint.Address); var localUrl = _appHost.GetSmartApiUrl(endpoint.Address);
if (string.IsNullOrEmpty(localUrl)) if (string.IsNullOrEmpty(localUrl))
{ {
_logger.LogWarning("Unable to respond to server discovery request because the local ip address could not be determined."); _logger.LogWarning("Unable to respond to server discovery request because the local ip address could not be determined");
return; return;
} }
var response = new ServerDiscoveryInfo(localUrl, _appHost.SystemId, _appHost.FriendlyName); var response = new ServerDiscoveryInfo(localUrl, _appHost.SystemId, _appHost.FriendlyName);
var listenerEndpoint = (IPEndPoint?)broadCastUdpClient.Client.LocalEndPoint;
var listenerIp = listenerEndpoint?.Address;
using var responder = new UdpClient(new IPEndPoint(responderIp, PortNumber)); // Reuse the UdpClient if listener IP equals to responder, otherwise create a new one and respond with that
try if (Equals(listenerIp, responderIp))
{ {
_logger.LogDebug("Sending AutoDiscovery response"); try
await responder {
.SendAsync(JsonSerializer.SerializeToUtf8Bytes(response).AsMemory(), endpoint, cancellationToken) _logger.LogDebug("Sending AutoDiscovery response");
.ConfigureAwait(false); await broadCastUdpClient
.SendAsync(JsonSerializer.SerializeToUtf8Bytes(response).AsMemory(), endpoint, cancellationToken)
.ConfigureAwait(false);
}
catch (SocketException ex)
{
_logger.LogError(ex, "Error sending response message");
}
} }
catch (SocketException ex) else
{ {
_logger.LogError(ex, "Error sending response message"); using var responder = new UdpClient(new IPEndPoint(responderIp, PortNumber));
try
{
_logger.LogDebug("Sending AutoDiscovery response");
await responder
.SendAsync(JsonSerializer.SerializeToUtf8Bytes(response).AsMemory(), endpoint, cancellationToken)
.ConfigureAwait(false);
}
catch (SocketException ex)
{
_logger.LogError(ex, "Error sending response message");
}
} }
} }
} }

Loading…
Cancel
Save