|
|
@ -1,6 +1,4 @@
|
|
|
|
using System;
|
|
|
|
using System;
|
|
|
|
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 +9,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 +48,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)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -79,23 +57,10 @@ public sealed class AutoDiscoveryHost : BackgroundService
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var udpServers = new List<Task>();
|
|
|
|
await ListenForAutoDiscoveryMessage(IPAddress.Any, stoppingToken).ConfigureAwait(false);
|
|
|
|
// Linux needs to bind to the broadcast addresses to receive broadcast traffic
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task ListenForAutoDiscoveryMessage(IPAddress listenAddress, IPAddress respondAddress, CancellationToken cancellationToken)
|
|
|
|
private async Task ListenForAutoDiscoveryMessage(IPAddress listenAddress, CancellationToken cancellationToken)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
try
|
|
|
|
try
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -110,7 +75,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(result.RemoteEndPoint, udpClient, cancellationToken).ConfigureAwait(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (SocketException ex)
|
|
|
|
catch (SocketException ex)
|
|
|
@ -130,22 +95,20 @@ public sealed class AutoDiscoveryHost : BackgroundService
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task RespondToV2Message(IPAddress responderIp, IPEndPoint endpoint, CancellationToken cancellationToken)
|
|
|
|
private async Task RespondToV2Message(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);
|
|
|
|
|
|
|
|
|
|
|
|
using var responder = new UdpClient(new IPEndPoint(responderIp, PortNumber));
|
|
|
|
|
|
|
|
try
|
|
|
|
try
|
|
|
|
{
|
|
|
|
{
|
|
|
|
_logger.LogDebug("Sending AutoDiscovery response");
|
|
|
|
_logger.LogDebug("Sending AutoDiscovery response");
|
|
|
|
await responder
|
|
|
|
await broadCastUdpClient
|
|
|
|
.SendAsync(JsonSerializer.SerializeToUtf8Bytes(response).AsMemory(), endpoint, cancellationToken)
|
|
|
|
.SendAsync(JsonSerializer.SerializeToUtf8Bytes(response).AsMemory(), endpoint, cancellationToken)
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
.ConfigureAwait(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|