From cbd0e71c077e6233bcbc751f9a2f1ee742000ba3 Mon Sep 17 00:00:00 2001 From: Xu Fasheng Date: Fri, 22 Feb 2019 12:06:49 +0800 Subject: Send DLNA devices message to only the matched interface This will be the right way for multiple interfaces, or the client will receive all devices message with different IP addresses and could not detect which one could access. And provide one option DlnaOptions.SendOnlyMatchedHost to fallback to old behaviour if this commit missed something. --- .../Networking/NetworkManager.cs | 60 ++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'Emby.Server.Implementations/Networking') diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index b7a125f20..8696d1896 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -636,6 +636,66 @@ namespace Emby.Server.Implementations.Networking return false; } + public bool IsInSameSubnet(IpAddressInfo address1, IpAddressInfo address2, IpAddressInfo subnetMask) + { + IPAddress network1 = GetNetworkAddress(ToIPAddress(address1), ToIPAddress(subnetMask)); + IPAddress network2 = GetNetworkAddress(ToIPAddress(address2), ToIPAddress(subnetMask)); + return network1.Equals(network2); + } + + private IPAddress GetNetworkAddress(IPAddress address, IPAddress subnetMask) + { + byte[] ipAdressBytes = address.GetAddressBytes(); + byte[] subnetMaskBytes = subnetMask.GetAddressBytes(); + + if (ipAdressBytes.Length != subnetMaskBytes.Length) + { + throw new ArgumentException("Lengths of IP address and subnet mask do not match."); + } + + byte[] broadcastAddress = new byte[ipAdressBytes.Length]; + for (int i = 0; i < broadcastAddress.Length; i++) + { + broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i])); + } + return new IPAddress(broadcastAddress); + } + + public IpAddressInfo GetLocalIpSubnetMask(IpAddressInfo address) + { + NetworkInterface[] interfaces; + IPAddress ipaddress = ToIPAddress(address); + + try + { + var validStatuses = new[] { OperationalStatus.Up, OperationalStatus.Unknown }; + + interfaces = NetworkInterface.GetAllNetworkInterfaces() + .Where(i => validStatuses.Contains(i.OperationalStatus)) + .ToArray(); + } + catch (Exception ex) + { + Logger.LogError(ex, "Error in GetAllNetworkInterfaces"); + return null; + } + + foreach (NetworkInterface ni in interfaces) + { + if (ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null) + { + foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) + { + if (ip.Address.Equals(ipaddress) && ip.IPv4Mask != null) + { + return ToIpAddressInfo(ip.IPv4Mask); + } + } + } + } + return null; + } + public static IpEndPointInfo ToIpEndPointInfo(IPEndPoint endpoint) { if (endpoint == null) -- cgit v1.2.3