Standardize bind IPs in ssdp and dlnahost (#82)

This commit is contained in:
disgustipated 2024-10-26 14:00:16 -04:00 committed by GitHub
parent 6907e25a18
commit b89cee0af3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 37 deletions

View File

@ -3,6 +3,7 @@
using System;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Threading;
@ -245,8 +246,12 @@ public sealed class DlnaHost : IHostedService, IDisposable
// Only get bind addresses in LAN
// IPv6 is currently unsupported
var validInterfaces = _networkManager.GetInternalBindAddresses()
var validInterfaces = _networkManager.GetInternalBindAddresses()
.Where(x => x.Address is not null)
.Where(x => x.AddressFamily != AddressFamily.InterNetworkV6)
.Where(x => x.AddressFamily == AddressFamily.InterNetwork)
.Where(x => x.SupportsMulticast)
.Where(x => !x.Address.Equals(IPAddress.Loopback))
.ToList();
var httpBindPort = _appHost.HttpPort;

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;
@ -233,6 +234,19 @@ namespace Rssdp.Infrastructure
}
}
public IEnumerable<IPData> GetBindIPs()
{
var iplist = _networkManager.GetInternalBindAddresses()
.Where(x => x.Address is not null)
.Where(x => x.AddressFamily != AddressFamily.InterNetworkV6)
.Where(x => x.AddressFamily == AddressFamily.InterNetwork)
.Where(x => x.SupportsMulticast)
.Where(x => !x.Address.Equals(IPAddress.Loopback))
.ToList();
return iplist;
}
public Task SendMulticastMessage(string message, IPAddress fromlocalIPAddress, CancellationToken cancellationToken)
{
return SendMulticastMessage(message, SsdpConstants.UdpResendCount, fromlocalIPAddress, cancellationToken);
@ -343,24 +357,19 @@ namespace Rssdp.Infrastructure
var sockets = new List<Socket>();
var multicastGroupAddress = IPAddress.Parse(SsdpConstants.MulticastLocalAdminAddress);
// IPv6 is currently unsupported
var validInterfaces = _networkManager.GetInternalBindAddresses()
.Where(x => x.Address is not null)
.Where(x => x.SupportsMulticast)
.Where(x => x.AddressFamily == AddressFamily.InterNetwork)
.DistinctBy(x => x.Index);
var validInterfaces = GetBindIPs();
foreach (var intf in validInterfaces)
{
try
{
var socket = CreateUdpMulticastSocket(multicastGroupAddress, intf, _MulticastTtl, SsdpConstants.MulticastPort);
_ = ListenToSocketInternal(socket);
_ = ListenToSocketInternal(socket, intf);
sockets.Add(socket);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to create SSDP UDP multicast socket for {0} on interface {1} (index {2})", intf.Address, intf.Name, intf.Index);
_logger.LogError(ex, "Failed to create SSDP UDP multicast socket for {0} on interface {1} (index {2})", intf, intf.Name, intf.Index);
}
}
@ -370,37 +379,26 @@ namespace Rssdp.Infrastructure
private List<Socket> CreateSendSockets()
{
var sockets = new List<Socket>();
// IPv6 is currently unsupported
var validInterfaces = _networkManager.GetInternalBindAddresses()
.Where(x => x.Address is not null)
.Where(x => x.SupportsMulticast)
.Where(x => x.AddressFamily == AddressFamily.InterNetwork);
if (OperatingSystem.IsMacOS())
{
// Manually remove loopback on macOS due to https://github.com/dotnet/runtime/issues/24340
validInterfaces = validInterfaces.Where(x => !x.Address.Equals(IPAddress.Loopback));
}
var validInterfaces = GetBindIPs();
foreach (var intf in validInterfaces)
{
try
{
var socket = CreateSsdpUdpSocket(intf, _LocalPort);
_ = ListenToSocketInternal(socket);
_ = ListenToSocketInternal(socket, intf);
sockets.Add(socket);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to create SSDP UDP sender socket for {0} on interface {1} (index {2})", intf.Address, intf.Name, intf.Index);
_logger.LogError(ex, "Failed to create SSDP UDP sender socket for {0} on interface {1} (index {2})", intf, intf.Name, intf.Index);
}
}
return sockets;
}
private async Task ListenToSocketInternal(Socket socket)
private async Task ListenToSocketInternal(Socket socket, IPData listenIP)
{
var cancelled = false;
var receiveBuffer = new byte[8192];
@ -414,23 +412,11 @@ namespace Rssdp.Infrastructure
if (result.ReceivedBytes > 0)
{
var remoteEndpoint = (IPEndPoint)result.RemoteEndPoint;
var allBindInterfaces = _networkManager.GetAllBindInterfaces();
IPData localEndpointAdapter;
if (allBindInterfaces.Count == 1
&& (allBindInterfaces[0].Address.Equals(IPAddress.Any)
|| allBindInterfaces[0].Address.Equals(IPAddress.IPv6Any)))
{
localEndpointAdapter = allBindInterfaces[0];
}
else
{
localEndpointAdapter = allBindInterfaces.First(a => a.Index == result.PacketInformation.Interface);
}
ProcessMessage(
Encoding.UTF8.GetString(receiveBuffer, 0, result.ReceivedBytes),
remoteEndpoint,
localEndpointAdapter.Address);
listenIP.Address);
}
}
catch (ObjectDisposedException)