Merge pull request #1524 from Bond-009/ipaddress

Remove IpAddressInfo and IpEndPointInfo classes
This commit is contained in:
dkanada 2019-07-27 17:50:17 -07:00 committed by GitHub
commit 85b277b872
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 265 additions and 444 deletions

View File

@ -1,4 +1,5 @@
using System;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Emby.Dlna.PlayTo;
@ -247,7 +248,7 @@ namespace Emby.Dlna.Main
foreach (var address in addresses)
{
if (address.AddressFamily == IpAddressFamily.InterNetworkV6)
if (address.AddressFamily == AddressFamily.InterNetworkV6)
{
// Not support IPv6 right now
continue;

View File

@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Extensions;
@ -14,7 +15,6 @@ using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Session;
using Microsoft.Extensions.Logging;
@ -172,7 +172,7 @@ namespace Emby.Dlna.PlayTo
_sessionManager.UpdateDeviceName(sessionInfo.Id, deviceName);
string serverAddress;
if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Any))
if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IPAddress.Any) || info.LocalIpAddress.Equals(IPAddress.IPv6Any))
{
serverAddress = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
}

View File

@ -7,6 +7,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
@ -1546,14 +1547,32 @@ namespace Emby.Server.Implementations
return null;
}
public string GetLocalApiUrl(IpAddressInfo ipAddress)
/// <summary>
/// Removes the scope id from IPv6 addresses.
/// </summary>
/// <param name="address">The IPv6 address.</param>
/// <returns>The IPv6 address without the scope id.</returns>
private string RemoveScopeId(string address)
{
if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6)
var index = address.IndexOf('%');
if (index == -1)
{
return GetLocalApiUrl("[" + ipAddress.Address + "]");
return address;
}
return GetLocalApiUrl(ipAddress.Address);
return address.Substring(0, index);
}
public string GetLocalApiUrl(IPAddress ipAddress)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
var str = RemoveScopeId(ipAddress.ToString());
return GetLocalApiUrl("[" + str + "]");
}
return GetLocalApiUrl(ipAddress.ToString());
}
public string GetLocalApiUrl(string host)
@ -1564,19 +1583,22 @@ namespace Emby.Server.Implementations
host,
HttpsPort.ToString(CultureInfo.InvariantCulture));
}
return string.Format("http://{0}:{1}",
host,
HttpPort.ToString(CultureInfo.InvariantCulture));
}
public string GetWanApiUrl(IpAddressInfo ipAddress)
public string GetWanApiUrl(IPAddress ipAddress)
{
if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6)
if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
return GetWanApiUrl("[" + ipAddress.Address + "]");
var str = RemoveScopeId(ipAddress.ToString());
return GetWanApiUrl("[" + str + "]");
}
return GetWanApiUrl(ipAddress.Address);
return GetWanApiUrl(ipAddress.ToString());
}
public string GetWanApiUrl(string host)
@ -1587,17 +1609,18 @@ namespace Emby.Server.Implementations
host,
ServerConfigurationManager.Configuration.PublicHttpsPort.ToString(CultureInfo.InvariantCulture));
}
return string.Format("http://{0}:{1}",
host,
ServerConfigurationManager.Configuration.PublicPort.ToString(CultureInfo.InvariantCulture));
}
public Task<List<IpAddressInfo>> GetLocalIpAddresses(CancellationToken cancellationToken)
public Task<List<IPAddress>> GetLocalIpAddresses(CancellationToken cancellationToken)
{
return GetLocalIpAddressesInternal(true, 0, cancellationToken);
}
private async Task<List<IpAddressInfo>> GetLocalIpAddressesInternal(bool allowLoopback, int limit, CancellationToken cancellationToken)
private async Task<List<IPAddress>> GetLocalIpAddressesInternal(bool allowLoopback, int limit, CancellationToken cancellationToken)
{
var addresses = ServerConfigurationManager
.Configuration
@ -1611,13 +1634,13 @@ namespace Emby.Server.Implementations
addresses.AddRange(NetworkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces));
}
var resultList = new List<IpAddressInfo>();
var resultList = new List<IPAddress>();
foreach (var address in addresses)
{
if (!allowLoopback)
{
if (address.Equals(IpAddressInfo.Loopback) || address.Equals(IpAddressInfo.IPv6Loopback))
if (address.Equals(IPAddress.Loopback) || address.Equals(IPAddress.IPv6Loopback))
{
continue;
}
@ -1638,7 +1661,7 @@ namespace Emby.Server.Implementations
return resultList;
}
private IpAddressInfo NormalizeConfiguredLocalAddress(string address)
private IPAddress NormalizeConfiguredLocalAddress(string address)
{
var index = address.Trim('/').IndexOf('/');
@ -1647,7 +1670,7 @@ namespace Emby.Server.Implementations
address = address.Substring(index + 1);
}
if (NetworkManager.TryParseIpAddress(address.Trim('/'), out IpAddressInfo result))
if (IPAddress.TryParse(address.Trim('/'), out IPAddress result))
{
return result;
}
@ -1657,10 +1680,10 @@ namespace Emby.Server.Implementations
private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
private async Task<bool> IsIpAddressValidAsync(IpAddressInfo address, CancellationToken cancellationToken)
private async Task<bool> IsIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken)
{
if (address.Equals(IpAddressInfo.Loopback) ||
address.Equals(IpAddressInfo.IPv6Loopback))
if (address.Equals(IPAddress.Loopback) ||
address.Equals(IPAddress.IPv6Loopback))
{
return true;
}

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
@ -11,7 +12,6 @@ using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@ -20,7 +20,6 @@ using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
@ -259,7 +258,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
using (var manager = new HdHomerunManager(_socketFactory, Logger))
{
// Legacy HdHomeruns are IPv4 only
var ipInfo = _networkManager.ParseIpAddress(uri.Host);
var ipInfo = IPAddress.Parse(uri.Host);
for (int i = 0; i < model.TunerCount; ++i)
{
@ -675,13 +674,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
// Need a way to set the Receive timeout on the socket otherwise this might never timeout?
try
{
await udpClient.SendToAsync(discBytes, 0, discBytes.Length, new IpEndPointInfo(new IpAddressInfo("255.255.255.255", IpAddressFamily.InterNetwork), 65001), cancellationToken);
await udpClient.SendToAsync(discBytes, 0, discBytes.Length, new IPEndPoint(IPAddress.Parse("255.255.255.255"), 65001), cancellationToken);
var receiveBuffer = new byte[8192];
while (!cancellationToken.IsCancellationRequested)
{
var response = await udpClient.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, cancellationToken).ConfigureAwait(false);
var deviceIp = response.RemoteEndPoint.IpAddress.Address;
var deviceIp = response.RemoteEndPoint.Address.ToString();
// check to make sure we have enough bytes received to be a valid message and make sure the 2nd byte is the discover reply byte
if (response.ReceivedBytes > 13 && response.Buffer[1] == 3)

View File

@ -89,7 +89,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private uint? _lockkey = null;
private int _activeTuner = -1;
private readonly ISocketFactory _socketFactory;
private IpAddressInfo _remoteIp;
private IPAddress _remoteIp;
private ILogger _logger;
private ISocket _currentTcpSocket;
@ -114,7 +114,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
}
public async Task<bool> CheckTunerAvailability(IpAddressInfo remoteIp, int tuner, CancellationToken cancellationToken)
public async Task<bool> CheckTunerAvailability(IPAddress remoteIp, int tuner, CancellationToken cancellationToken)
{
using (var socket = _socketFactory.CreateTcpSocket(remoteIp, HdHomeRunPort))
{
@ -122,9 +122,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
}
private static async Task<bool> CheckTunerAvailability(ISocket socket, IpAddressInfo remoteIp, int tuner, CancellationToken cancellationToken)
private static async Task<bool> CheckTunerAvailability(ISocket socket, IPAddress remoteIp, int tuner, CancellationToken cancellationToken)
{
var ipEndPoint = new IpEndPointInfo(remoteIp, HdHomeRunPort);
var ipEndPoint = new IPEndPoint(remoteIp, HdHomeRunPort);
var lockkeyMsg = CreateGetMessage(tuner, "lockkey");
await socket.SendToAsync(lockkeyMsg, 0, lockkeyMsg.Length, ipEndPoint, cancellationToken);
@ -137,7 +137,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return string.Equals(returnVal, "none", StringComparison.OrdinalIgnoreCase);
}
public async Task StartStreaming(IpAddressInfo remoteIp, IPAddress localIp, int localPort, IHdHomerunChannelCommands commands, int numTuners, CancellationToken cancellationToken)
public async Task StartStreaming(IPAddress remoteIp, IPAddress localIp, int localPort, IHdHomerunChannelCommands commands, int numTuners, CancellationToken cancellationToken)
{
_remoteIp = remoteIp;
@ -154,7 +154,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var lockKeyValue = _lockkey.Value;
var ipEndPoint = new IpEndPointInfo(_remoteIp, HdHomeRunPort);
var ipEndPoint = new IPEndPoint(_remoteIp, HdHomeRunPort);
for (int i = 0; i < numTuners; ++i)
{
@ -217,7 +217,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
foreach (Tuple<string, string> command in commandList)
{
var channelMsg = CreateSetMessage(_activeTuner, command.Item1, command.Item2, _lockkey);
await tcpClient.SendToAsync(channelMsg, 0, channelMsg.Length, new IpEndPointInfo(_remoteIp, HdHomeRunPort), cancellationToken).ConfigureAwait(false);
await tcpClient.SendToAsync(channelMsg, 0, channelMsg.Length, new IPEndPoint(_remoteIp, HdHomeRunPort), cancellationToken).ConfigureAwait(false);
var response = await tcpClient.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, cancellationToken).ConfigureAwait(false);
// parse response to make sure it worked
if (!ParseReturnMessage(response.Buffer, response.ReceivedBytes, out string returnVal))
@ -242,7 +242,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
_logger.LogInformation("HdHomerunManager.ReleaseLockkey {0}", lockKeyValue);
var ipEndPoint = new IpEndPointInfo(_remoteIp, HdHomeRunPort);
var ipEndPoint = new IPEndPoint(_remoteIp, HdHomeRunPort);
var releaseTarget = CreateSetMessage(_activeTuner, "target", "none", lockKeyValue);
await tcpClient.SendToAsync(releaseTarget, 0, releaseTarget.Length, ipEndPoint, CancellationToken.None).ConfigureAwait(false);

View File

@ -25,7 +25,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private readonly int _numTuners;
private readonly INetworkManager _networkManager;
public HdHomerunUdpStream(MediaSourceInfo mediaSource, TunerHostInfo tunerHostInfo, string originalStreamId, IHdHomerunChannelCommands channelCommands, int numTuners, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, MediaBrowser.Model.Net.ISocketFactory socketFactory, INetworkManager networkManager)
public HdHomerunUdpStream(
MediaSourceInfo mediaSource,
TunerHostInfo tunerHostInfo,
string originalStreamId,
IHdHomerunChannelCommands channelCommands,
int numTuners,
IFileSystem fileSystem,
IHttpClient httpClient,
ILogger logger,
IServerApplicationPaths appPaths,
IServerApplicationHost appHost,
MediaBrowser.Model.Net.ISocketFactory socketFactory,
INetworkManager networkManager)
: base(mediaSource, tunerHostInfo, fileSystem, logger, appPaths)
{
_appHost = appHost;
@ -58,7 +70,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
Logger.LogInformation("Opening HDHR UDP Live stream from {host}", uri.Host);
var remoteAddress = IPAddress.Parse(uri.Host);
var embyRemoteAddress = _networkManager.ParseIpAddress(uri.Host);
IPAddress localAddress = null;
using (var tcpSocket = CreateSocket(remoteAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
@ -81,7 +92,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
try
{
// send url to start streaming
await hdHomerunManager.StartStreaming(embyRemoteAddress, localAddress, localPort, _channelCommands, _numTuners, openCancellationToken).ConfigureAwait(false);
await hdHomerunManager.StartStreaming(remoteAddress, localAddress, localPort, _channelCommands, _numTuners, openCancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{

View File

@ -16,14 +16,14 @@ namespace Emby.Server.Implementations.Net
// but that wasn't really the point so kept to YAGNI principal for now, even if the
// interfaces are a bit ugly, specific and make assumptions.
public ISocket CreateTcpSocket(IpAddressInfo remoteAddress, int remotePort)
public ISocket CreateTcpSocket(IPAddress remoteAddress, int remotePort)
{
if (remotePort < 0)
{
throw new ArgumentException("remotePort cannot be less than zero.", nameof(remotePort));
}
var addressFamily = remoteAddress.AddressFamily == IpAddressFamily.InterNetwork
var addressFamily = remoteAddress.AddressFamily == AddressFamily.InterNetwork
? AddressFamily.InterNetwork
: AddressFamily.InterNetworkV6;
@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.Net
try
{
return new UdpSocket(retVal, new IpEndPointInfo(remoteAddress, remotePort));
return new UdpSocket(retVal, new IPEndPoint(remoteAddress, remotePort));
}
catch
{
@ -102,7 +102,7 @@ namespace Emby.Server.Implementations.Net
/// Creates a new UDP acceptSocket that is a member of the SSDP multicast local admin group and binds it to the specified local port.
/// </summary>
/// <returns>An implementation of the <see cref="ISocket"/> interface used by RSSDP components to perform acceptSocket operations.</returns>
public ISocket CreateSsdpUdpSocket(IpAddressInfo localIpAddress, int localPort)
public ISocket CreateSsdpUdpSocket(IPAddress localIpAddress, int localPort)
{
if (localPort < 0)
{
@ -115,10 +115,8 @@ namespace Emby.Server.Implementations.Net
retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4);
var localIp = NetworkManager.ToIPAddress(localIpAddress);
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIp));
return new UdpSocket(retVal, localPort, localIp);
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIpAddress));
return new UdpSocket(retVal, localPort, localIpAddress);
}
catch
{

View File

@ -19,7 +19,7 @@ namespace Emby.Server.Implementations.Net
public Socket Socket => _socket;
public IpAddressInfo LocalIPAddress { get; }
public IPAddress LocalIPAddress { get; }
private readonly SocketAsyncEventArgs _receiveSocketAsyncEventArgs = new SocketAsyncEventArgs()
{
@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.Net
_socket = socket;
_localPort = localPort;
LocalIPAddress = NetworkManager.ToIpAddressInfo(ip);
LocalIPAddress = ip;
_socket.Bind(new IPEndPoint(ip, _localPort));
@ -71,7 +71,7 @@ namespace Emby.Server.Implementations.Net
{
Buffer = e.Buffer,
ReceivedBytes = e.BytesTransferred,
RemoteEndPoint = ToIpEndPointInfo(e.RemoteEndPoint as IPEndPoint),
RemoteEndPoint = e.RemoteEndPoint as IPEndPoint,
LocalIPAddress = LocalIPAddress
});
}
@ -100,12 +100,12 @@ namespace Emby.Server.Implementations.Net
}
}
public UdpSocket(Socket socket, IpEndPointInfo endPoint)
public UdpSocket(Socket socket, IPEndPoint endPoint)
{
if (socket == null) throw new ArgumentNullException(nameof(socket));
_socket = socket;
_socket.Connect(NetworkManager.ToIPEndPoint(endPoint));
_socket.Connect(endPoint);
InitReceiveSocketAsyncEventArgs();
}
@ -140,7 +140,7 @@ namespace Emby.Server.Implementations.Net
return new SocketReceiveResult
{
ReceivedBytes = receivedBytes,
RemoteEndPoint = ToIpEndPointInfo((IPEndPoint)remoteEndPoint),
RemoteEndPoint = (IPEndPoint)remoteEndPoint,
Buffer = buffer,
LocalIPAddress = LocalIPAddress
};
@ -191,7 +191,7 @@ namespace Emby.Server.Implementations.Net
return ReceiveAsync(buffer, 0, buffer.Length, cancellationToken);
}
public Task SendToAsync(byte[] buffer, int offset, int size, IpEndPointInfo endPoint, CancellationToken cancellationToken)
public Task SendToAsync(byte[] buffer, int offset, int size, IPEndPoint endPoint, CancellationToken cancellationToken)
{
ThrowIfDisposed();
@ -227,13 +227,11 @@ namespace Emby.Server.Implementations.Net
return taskCompletion.Task;
}
public IAsyncResult BeginSendTo(byte[] buffer, int offset, int size, IpEndPointInfo endPoint, AsyncCallback callback, object state)
public IAsyncResult BeginSendTo(byte[] buffer, int offset, int size, IPEndPoint endPoint, AsyncCallback callback, object state)
{
ThrowIfDisposed();
var ipEndPoint = NetworkManager.ToIPEndPoint(endPoint);
return _socket.BeginSendTo(buffer, offset, size, SocketFlags.None, ipEndPoint, callback, state);
return _socket.BeginSendTo(buffer, offset, size, SocketFlags.None, endPoint, callback, state);
}
public int EndSendTo(IAsyncResult result)
@ -268,15 +266,5 @@ namespace Emby.Server.Implementations.Net
_disposed = true;
}
private static IpEndPointInfo ToIpEndPointInfo(IPEndPoint endpoint)
{
if (endpoint == null)
{
return null;
}
return NetworkManager.ToIpEndPointInfo(endpoint);
}
}
}

View File

@ -9,55 +9,38 @@ using System.Threading.Tasks;
using MediaBrowser.Common.Net;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.System;
using Microsoft.Extensions.Logging;
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
namespace Emby.Server.Implementations.Networking
{
public class NetworkManager : INetworkManager
{
protected ILogger Logger { get; private set; }
private readonly ILogger _logger;
public event EventHandler NetworkChanged;
public Func<string[]> LocalSubnetsFn { get; set; }
private IPAddress[] _localIpAddresses;
private readonly object _localIpAddressSyncLock = new object();
public NetworkManager(ILoggerFactory loggerFactory)
public NetworkManager(ILogger<NetworkManager> logger)
{
Logger = loggerFactory.CreateLogger(nameof(NetworkManager));
_logger = logger;
// In FreeBSD these events cause a crash
if (OperatingSystem.Id != OperatingSystemId.BSD)
{
try
{
NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;
}
catch (Exception ex)
{
Logger.LogError(ex, "Error binding to NetworkAddressChanged event");
}
try
{
NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
}
catch (Exception ex)
{
Logger.LogError(ex, "Error binding to NetworkChange_NetworkAvailabilityChanged event");
}
}
NetworkChange.NetworkAddressChanged += OnNetworkAddressChanged;
NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged;
}
private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
public Func<string[]> LocalSubnetsFn { get; set; }
public event EventHandler NetworkChanged;
private void OnNetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
{
Logger.LogDebug("NetworkAvailabilityChanged");
_logger.LogDebug("NetworkAvailabilityChanged");
OnNetworkChanged();
}
private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
private void OnNetworkAddressChanged(object sender, EventArgs e)
{
Logger.LogDebug("NetworkAddressChanged");
_logger.LogDebug("NetworkAddressChanged");
OnNetworkChanged();
}
@ -68,39 +51,35 @@ namespace Emby.Server.Implementations.Networking
_localIpAddresses = null;
_macAddresses = null;
}
if (NetworkChanged != null)
{
NetworkChanged(this, EventArgs.Empty);
}
}
private IpAddressInfo[] _localIpAddresses;
private readonly object _localIpAddressSyncLock = new object();
public IpAddressInfo[] GetLocalIpAddresses(bool ignoreVirtualInterface = true)
public IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface = true)
{
lock (_localIpAddressSyncLock)
{
if (_localIpAddresses == null)
{
var addresses = GetLocalIpAddressesInternal(ignoreVirtualInterface).Result.Select(ToIpAddressInfo).ToArray();
var addresses = GetLocalIpAddressesInternal(ignoreVirtualInterface).ToArray();
_localIpAddresses = addresses;
return addresses;
}
return _localIpAddresses;
}
}
private async Task<List<IPAddress>> GetLocalIpAddressesInternal(bool ignoreVirtualInterface)
private List<IPAddress> GetLocalIpAddressesInternal(bool ignoreVirtualInterface)
{
var list = GetIPsDefault(ignoreVirtualInterface)
.ToList();
var list = GetIPsDefault(ignoreVirtualInterface).ToList();
if (list.Count == 0)
{
list.AddRange(await GetLocalIpAddressesFallback().ConfigureAwait(false));
list = GetLocalIpAddressesFallback().GetAwaiter().GetResult().ToList();
}
var listClone = list.ToList();
@ -351,13 +330,13 @@ namespace Emby.Server.Implementations.Networking
try
{
var host = uri.DnsSafeHost;
Logger.LogDebug("Resolving host {0}", host);
_logger.LogDebug("Resolving host {0}", host);
address = GetIpAddresses(host).Result.FirstOrDefault();
if (address != null)
{
Logger.LogDebug("{0} resolved to {1}", host, address);
_logger.LogDebug("{0} resolved to {1}", host, address);
return IsInLocalNetworkInternal(address.ToString(), false);
}
@ -368,7 +347,7 @@ namespace Emby.Server.Implementations.Networking
}
catch (Exception ex)
{
Logger.LogError(ex, "Error resolving hostname");
_logger.LogError(ex, "Error resolving hostname");
}
}
}
@ -381,56 +360,41 @@ namespace Emby.Server.Implementations.Networking
return Dns.GetHostAddressesAsync(hostName);
}
private List<IPAddress> GetIPsDefault(bool ignoreVirtualInterface)
private IEnumerable<IPAddress> GetIPsDefault(bool ignoreVirtualInterface)
{
NetworkInterface[] interfaces;
IEnumerable<NetworkInterface> interfaces;
try
{
var validStatuses = new[] { OperationalStatus.Up, OperationalStatus.Unknown };
interfaces = NetworkInterface.GetAllNetworkInterfaces()
.Where(i => validStatuses.Contains(i.OperationalStatus))
.ToArray();
.Where(x => x.OperationalStatus == OperationalStatus.Up
|| x.OperationalStatus == OperationalStatus.Unknown);
}
catch (Exception ex)
catch (NetworkInformationException ex)
{
Logger.LogError(ex, "Error in GetAllNetworkInterfaces");
return new List<IPAddress>();
_logger.LogError(ex, "Error in GetAllNetworkInterfaces");
return Enumerable.Empty<IPAddress>();
}
return interfaces.SelectMany(network =>
{
var ipProperties = network.GetIPProperties();
try
// Try to exclude virtual adapters
// http://stackoverflow.com/questions/8089685/c-sharp-finding-my-machines-local-ip-address-and-not-the-vms
var addr = ipProperties.GatewayAddresses.FirstOrDefault();
if (addr == null
|| (ignoreVirtualInterface
&& (addr.Address.Equals(IPAddress.Any) || addr.Address.Equals(IPAddress.IPv6Any))))
{
// suppress logging because it might be causing nas device wake up
//logger.LogDebug("Querying interface: {0}. Type: {1}. Status: {2}", network.Name, network.NetworkInterfaceType, network.OperationalStatus);
var ipProperties = network.GetIPProperties();
// Try to exclude virtual adapters
// http://stackoverflow.com/questions/8089685/c-sharp-finding-my-machines-local-ip-address-and-not-the-vms
var addr = ipProperties.GatewayAddresses.FirstOrDefault();
if (addr == null || ignoreVirtualInterface && string.Equals(addr.Address.ToString(), "0.0.0.0", StringComparison.OrdinalIgnoreCase))
{
return new List<IPAddress>();
}
return ipProperties.UnicastAddresses
.Select(i => i.Address)
.Where(i => i.AddressFamily == AddressFamily.InterNetwork || i.AddressFamily == AddressFamily.InterNetworkV6)
.ToList();
}
catch (Exception ex)
{
Logger.LogError(ex, "Error querying network interface");
return new List<IPAddress>();
return Enumerable.Empty<IPAddress>();
}
return ipProperties.UnicastAddresses
.Select(i => i.Address)
.Where(i => i.AddressFamily == AddressFamily.InterNetwork || i.AddressFamily == AddressFamily.InterNetworkV6);
}).GroupBy(i => i.ToString())
.Select(x => x.First())
.ToList();
.Select(x => x.First());
}
private static async Task<IEnumerable<IPAddress>> GetLocalIpAddressesFallback()
@ -612,32 +576,10 @@ namespace Emby.Server.Implementations.Networking
return hosts[0];
}
public IpAddressInfo ParseIpAddress(string ipAddress)
public bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask)
{
if (TryParseIpAddress(ipAddress, out var info))
{
return info;
}
throw new ArgumentException("Invalid ip address: " + ipAddress);
}
public bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo)
{
if (IPAddress.TryParse(ipAddress, out var address))
{
ipAddressInfo = ToIpAddressInfo(address);
return true;
}
ipAddressInfo = null;
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));
IPAddress network1 = GetNetworkAddress(address1, subnetMask);
IPAddress network2 = GetNetworkAddress(address2, subnetMask);
return network1.Equals(network2);
}
@ -656,13 +598,13 @@ namespace Emby.Server.Implementations.Networking
{
broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i]));
}
return new IPAddress(broadcastAddress);
}
public IpAddressInfo GetLocalIpSubnetMask(IpAddressInfo address)
public IPAddress GetLocalIpSubnetMask(IPAddress address)
{
NetworkInterface[] interfaces;
IPAddress ipaddress = ToIPAddress(address);
try
{
@ -674,7 +616,7 @@ namespace Emby.Server.Implementations.Networking
}
catch (Exception ex)
{
Logger.LogError(ex, "Error in GetAllNetworkInterfaces");
_logger.LogError(ex, "Error in GetAllNetworkInterfaces");
return null;
}
@ -684,85 +626,17 @@ namespace Emby.Server.Implementations.Networking
{
foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
{
if (ip.Address.Equals(ipaddress) && ip.IPv4Mask != null)
if (ip.Address.Equals(address) && ip.IPv4Mask != null)
{
return ToIpAddressInfo(ip.IPv4Mask);
return ip.IPv4Mask;
}
}
}
}
return null;
}
public static IpEndPointInfo ToIpEndPointInfo(IPEndPoint endpoint)
{
if (endpoint == null)
{
return null;
}
return new IpEndPointInfo(ToIpAddressInfo(endpoint.Address), endpoint.Port);
}
public static IPEndPoint ToIPEndPoint(IpEndPointInfo endpoint)
{
if (endpoint == null)
{
return null;
}
return new IPEndPoint(ToIPAddress(endpoint.IpAddress), endpoint.Port);
}
public static IPAddress ToIPAddress(IpAddressInfo address)
{
if (address.Equals(IpAddressInfo.Any))
{
return IPAddress.Any;
}
if (address.Equals(IpAddressInfo.IPv6Any))
{
return IPAddress.IPv6Any;
}
if (address.Equals(IpAddressInfo.Loopback))
{
return IPAddress.Loopback;
}
if (address.Equals(IpAddressInfo.IPv6Loopback))
{
return IPAddress.IPv6Loopback;
}
return IPAddress.Parse(address.Address);
}
public static IpAddressInfo ToIpAddressInfo(IPAddress address)
{
if (address.Equals(IPAddress.Any))
{
return IpAddressInfo.Any;
}
if (address.Equals(IPAddress.IPv6Any))
{
return IpAddressInfo.IPv6Any;
}
if (address.Equals(IPAddress.Loopback))
{
return IpAddressInfo.Loopback;
}
if (address.Equals(IPAddress.IPv6Loopback))
{
return IpAddressInfo.IPv6Loopback;
}
return new IpAddressInfo(address.ToString(), address.AddressFamily == AddressFamily.InterNetworkV6 ? IpAddressFamily.InterNetworkV6 : IpAddressFamily.InterNetwork);
}
public async Task<IpAddressInfo[]> GetHostAddressesAsync(string host)
{
var addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false);
return addresses.Select(ToIpAddressInfo).ToArray();
}
/// <summary>
/// Gets the network shares.
/// </summary>

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@ -25,7 +26,7 @@ namespace Emby.Server.Implementations.Udp
private bool _isDisposed;
private readonly List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>> _responders = new List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>>();
private readonly List<Tuple<string, bool, Func<string, IPEndPoint, Encoding, CancellationToken, Task>>> _responders = new List<Tuple<string, bool, Func<string, IPEndPoint, Encoding, CancellationToken, Task>>>();
private readonly IServerApplicationHost _appHost;
private readonly IJsonSerializer _json;
@ -43,9 +44,9 @@ namespace Emby.Server.Implementations.Udp
AddMessageResponder("who is JellyfinServer?", true, RespondToV2Message);
}
private void AddMessageResponder(string message, bool isSubstring, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task> responder)
private void AddMessageResponder(string message, bool isSubstring, Func<string, IPEndPoint, Encoding, CancellationToken, Task> responder)
{
_responders.Add(new Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>(message, isSubstring, responder));
_responders.Add(new Tuple<string, bool, Func<string, IPEndPoint, Encoding, CancellationToken, Task>>(message, isSubstring, responder));
}
/// <summary>
@ -83,7 +84,7 @@ namespace Emby.Server.Implementations.Udp
}
}
private Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding)
private Tuple<string, Tuple<string, bool, Func<string, IPEndPoint, Encoding, CancellationToken, Task>>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding)
{
var text = encoding.GetString(buffer, 0, bytesReceived);
var responder = _responders.FirstOrDefault(i =>
@ -99,10 +100,10 @@ namespace Emby.Server.Implementations.Udp
{
return null;
}
return new Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>>(text, responder);
return new Tuple<string, Tuple<string, bool, Func<string, IPEndPoint, Encoding, CancellationToken, Task>>>(text, responder);
}
private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding, CancellationToken cancellationToken)
private async Task RespondToV2Message(string messageText, IPEndPoint endpoint, Encoding encoding, CancellationToken cancellationToken)
{
var parts = messageText.Split('|');
@ -254,7 +255,7 @@ namespace Emby.Server.Implementations.Udp
}
}
public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint, CancellationToken cancellationToken)
public async Task SendAsync(byte[] bytes, IPEndPoint remoteEndPoint, CancellationToken cancellationToken)
{
if (_isDisposed)
{

View File

@ -143,7 +143,7 @@ namespace Jellyfin.Server
options,
new ManagedFileSystem(_loggerFactory.CreateLogger<ManagedFileSystem>(), appPaths),
new NullImageEncoder(),
new NetworkManager(_loggerFactory),
new NetworkManager(_loggerFactory.CreateLogger<NetworkManager>()),
appConfig))
{
await appHost.InitAsync(new ServiceCollection()).ConfigureAwait(false);

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
@ -53,17 +54,12 @@ namespace MediaBrowser.Common.Net
/// <returns><c>true</c> if [is in local network] [the specified endpoint]; otherwise, <c>false</c>.</returns>
bool IsInLocalNetwork(string endpoint);
IpAddressInfo[] GetLocalIpAddresses(bool ignoreVirtualInterface);
IpAddressInfo ParseIpAddress(string ipAddress);
bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo);
Task<IpAddressInfo[]> GetHostAddressesAsync(string host);
IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface);
bool IsAddressInSubnets(string addressString, string[] subnets);
bool IsInSameSubnet(IpAddressInfo address1, IpAddressInfo address2, IpAddressInfo subnetMask);
IpAddressInfo GetLocalIpSubnetMask(IpAddressInfo address);
bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask);
IPAddress GetLocalIpSubnetMask(IPAddress address);
}
}

View File

@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.System;
namespace MediaBrowser.Controller
@ -59,7 +59,7 @@ namespace MediaBrowser.Controller
/// Gets the local ip address.
/// </summary>
/// <value>The local ip address.</value>
Task<List<IpAddressInfo>> GetLocalIpAddresses(CancellationToken cancellationToken);
Task<List<IPAddress>> GetLocalIpAddresses(CancellationToken cancellationToken);
/// <summary>
/// Gets the local API URL.
@ -77,7 +77,7 @@ namespace MediaBrowser.Controller
/// <summary>
/// Gets the local API URL.
/// </summary>
string GetLocalApiUrl(IpAddressInfo address);
string GetLocalApiUrl(IPAddress address);
void LaunchUrl(string url);

View File

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Model.Net;
using System.Net;
namespace MediaBrowser.Model.Dlna
{
@ -8,7 +8,7 @@ namespace MediaBrowser.Model.Dlna
{
public Uri Location { get; set; }
public Dictionary<string, string> Headers { get; set; }
public IpAddressInfo LocalIpAddress { get; set; }
public IPAddress LocalIpAddress { get; set; }
public int LocalPort { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
@ -9,7 +10,7 @@ namespace MediaBrowser.Model.Net
/// </summary>
public interface ISocket : IDisposable
{
IpAddressInfo LocalIPAddress { get; }
IPAddress LocalIPAddress { get; }
Task<SocketReceiveResult> ReceiveAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken);
@ -21,6 +22,6 @@ namespace MediaBrowser.Model.Net
/// <summary>
/// Sends a UDP message to a particular end point (uni or multicast).
/// </summary>
Task SendToAsync(byte[] buffer, int offset, int bytes, IpEndPointInfo endPoint, CancellationToken cancellationToken);
Task SendToAsync(byte[] buffer, int offset, int bytes, IPEndPoint endPoint, CancellationToken cancellationToken);
}
}

View File

@ -1,4 +1,5 @@
using System.IO;
using System.Net;
namespace MediaBrowser.Model.Net
{
@ -8,7 +9,7 @@ namespace MediaBrowser.Model.Net
public interface ISocketFactory
{
/// <summary>
/// Createa a new unicast socket using the specified local port number.
/// Creates a new unicast socket using the specified local port number.
/// </summary>
/// <param name="localPort">The local port to bind to.</param>
/// <returns>A <see cref="ISocket"/> implementation.</returns>
@ -16,15 +17,15 @@ namespace MediaBrowser.Model.Net
ISocket CreateUdpBroadcastSocket(int localPort);
ISocket CreateTcpSocket(IpAddressInfo remoteAddress, int remotePort);
ISocket CreateTcpSocket(IPAddress remoteAddress, int remotePort);
/// <summary>
/// Createa a new unicast socket using the specified local port number.
/// Creates a new unicast socket using the specified local port number.
/// </summary>
ISocket CreateSsdpUdpSocket(IpAddressInfo localIp, int localPort);
ISocket CreateSsdpUdpSocket(IPAddress localIp, int localPort);
/// <summary>
/// Createa a new multicast socket using the specified multicast IP address, multicast time to live and local port.
/// Creates a new multicast socket using the specified multicast IP address, multicast time to live and local port.
/// </summary>
/// <param name="ipAddress">The multicast IP address to bind to.</param>
/// <param name="multicastTimeToLive">The multicast time to live value. Actually a maximum number of network hops for UDP packets.</param>

View File

@ -1,38 +0,0 @@
using System;
namespace MediaBrowser.Model.Net
{
public class IpAddressInfo
{
public static IpAddressInfo Any = new IpAddressInfo("0.0.0.0", IpAddressFamily.InterNetwork);
public static IpAddressInfo IPv6Any = new IpAddressInfo("00000000000000000000", IpAddressFamily.InterNetworkV6);
public static IpAddressInfo Loopback = new IpAddressInfo("127.0.0.1", IpAddressFamily.InterNetwork);
public static IpAddressInfo IPv6Loopback = new IpAddressInfo("::1", IpAddressFamily.InterNetworkV6);
public string Address { get; set; }
public IpAddressInfo SubnetMask { get; set; }
public IpAddressFamily AddressFamily { get; set; }
public IpAddressInfo(string address, IpAddressFamily addressFamily)
{
Address = address;
AddressFamily = addressFamily;
}
public bool Equals(IpAddressInfo address)
{
return string.Equals(address.Address, Address, StringComparison.OrdinalIgnoreCase);
}
public override string ToString()
{
return Address;
}
}
public enum IpAddressFamily
{
InterNetwork,
InterNetworkV6
}
}

View File

@ -1,29 +0,0 @@
using System.Globalization;
namespace MediaBrowser.Model.Net
{
public class IpEndPointInfo
{
public IpAddressInfo IpAddress { get; set; }
public int Port { get; set; }
public IpEndPointInfo()
{
}
public IpEndPointInfo(IpAddressInfo address, int port)
{
IpAddress = address;
Port = port;
}
public override string ToString()
{
var ipAddresString = IpAddress == null ? string.Empty : IpAddress.ToString();
return ipAddresString + ":" + Port.ToString(CultureInfo.InvariantCulture);
}
}
}

View File

@ -1,3 +1,5 @@
using System.Net;
namespace MediaBrowser.Model.Net
{
/// <summary>
@ -18,7 +20,7 @@ namespace MediaBrowser.Model.Net
/// <summary>
/// The <see cref="IpEndPointInfo"/> the data was received from.
/// </summary>
public IpEndPointInfo RemoteEndPoint { get; set; }
public IpAddressInfo LocalIPAddress { get; set; }
public IPEndPoint RemoteEndPoint { get; set; }
public IPAddress LocalIPAddress { get; set; }
}
}

View File

@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
using System.Net;
namespace Rssdp
{
@ -11,12 +8,12 @@ namespace Rssdp
/// </summary>
public sealed class DeviceAvailableEventArgs : EventArgs
{
public IpAddressInfo LocalIpAddress { get; set; }
public IPAddress LocalIpAddress { get; set; }
#region Fields
private readonly DiscoveredSsdpDevice _DiscoveredDevice;
private readonly bool _IsNewlyDiscovered;
private readonly bool _IsNewlyDiscovered;
#endregion
@ -29,34 +26,34 @@ namespace Rssdp
/// <param name="isNewlyDiscovered">A boolean value indicating whether or not this device came from the cache. See <see cref="IsNewlyDiscovered"/> for more detail.</param>
/// <exception cref="ArgumentNullException">Thrown if the <paramref name="discoveredDevice"/> parameter is null.</exception>
public DeviceAvailableEventArgs(DiscoveredSsdpDevice discoveredDevice, bool isNewlyDiscovered)
{
if (discoveredDevice == null) throw new ArgumentNullException(nameof(discoveredDevice));
{
if (discoveredDevice == null) throw new ArgumentNullException(nameof(discoveredDevice));
_DiscoveredDevice = discoveredDevice;
_IsNewlyDiscovered = isNewlyDiscovered;
}
_DiscoveredDevice = discoveredDevice;
_IsNewlyDiscovered = isNewlyDiscovered;
}
#endregion
#endregion
#region Public Properties
#region Public Properties
/// <summary>
/// Returns true if the device was discovered due to an alive notification, or a search and was not already in the cache. Returns false if the item came from the cache but matched the current search request.
/// </summary>
public bool IsNewlyDiscovered
{
get { return _IsNewlyDiscovered; }
}
/// <summary>
/// Returns true if the device was discovered due to an alive notification, or a search and was not already in the cache. Returns false if the item came from the cache but matched the current search request.
/// </summary>
public bool IsNewlyDiscovered
{
get { return _IsNewlyDiscovered; }
}
/// <summary>
/// A reference to a <see cref="DiscoveredSsdpDevice"/> instance containing the discovered details and allowing access to the full device description.
/// </summary>
public DiscoveredSsdpDevice DiscoveredDevice
{
get { return _DiscoveredDevice; }
}
{
get { return _DiscoveredDevice; }
}
#endregion
}
}
#endregion
}
}

View File

@ -1,7 +1,7 @@
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
namespace Rssdp.Infrastructure
{
@ -40,13 +40,13 @@ namespace Rssdp.Infrastructure
/// <summary>
/// Sends a message to a particular address (uni or multicast) and port.
/// </summary>
Task SendMessage(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken);
Task SendMessage(byte[] messageData, IPEndPoint destination, IPAddress fromLocalIpAddress, CancellationToken cancellationToken);
/// <summary>
/// Sends a message to the SSDP multicast address and port.
/// </summary>
Task SendMulticastMessage(string message, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken);
Task SendMulticastMessage(string message, int sendCount, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken);
Task SendMulticastMessage(string message, IPAddress fromLocalIpAddress, CancellationToken cancellationToken);
Task SendMulticastMessage(string message, int sendCount, IPAddress fromLocalIpAddress, CancellationToken cancellationToken);
#endregion

View File

@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
namespace Rssdp.Infrastructure
{
@ -16,18 +12,18 @@ namespace Rssdp.Infrastructure
#region Fields
private readonly HttpRequestMessage _Message;
private readonly IpEndPointInfo _ReceivedFrom;
private readonly IPEndPoint _ReceivedFrom;
#endregion
public IpAddressInfo LocalIpAddress { get; private set; }
public IPAddress LocalIpAddress { get; private set; }
#region Constructors
/// <summary>
/// Full constructor.
/// </summary>
public RequestReceivedEventArgs(HttpRequestMessage message, IpEndPointInfo receivedFrom, IpAddressInfo localIpAddress)
public RequestReceivedEventArgs(HttpRequestMessage message, IPEndPoint receivedFrom, IPAddress localIpAddress)
{
_Message = message;
_ReceivedFrom = receivedFrom;
@ -49,7 +45,7 @@ namespace Rssdp.Infrastructure
/// <summary>
/// The <see cref="UdpEndPoint"/> the request came from.
/// </summary>
public IpEndPointInfo ReceivedFrom
public IPEndPoint ReceivedFrom
{
get { return _ReceivedFrom; }
}

View File

@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
namespace Rssdp.Infrastructure
{
@ -14,12 +10,12 @@ namespace Rssdp.Infrastructure
public sealed class ResponseReceivedEventArgs : EventArgs
{
public IpAddressInfo LocalIpAddress { get; set; }
public IPAddress LocalIpAddress { get; set; }
#region Fields
private readonly HttpResponseMessage _Message;
private readonly IpEndPointInfo _ReceivedFrom;
private readonly IPEndPoint _ReceivedFrom;
#endregion
@ -28,7 +24,7 @@ namespace Rssdp.Infrastructure
/// <summary>
/// Full constructor.
/// </summary>
public ResponseReceivedEventArgs(HttpResponseMessage message, IpEndPointInfo receivedFrom)
public ResponseReceivedEventArgs(HttpResponseMessage message, IPEndPoint receivedFrom)
{
_Message = message;
_ReceivedFrom = receivedFrom;
@ -49,7 +45,7 @@ namespace Rssdp.Infrastructure
/// <summary>
/// The <see cref="UdpEndPoint"/> the response came from.
/// </summary>
public IpEndPointInfo ReceivedFrom
public IPEndPoint ReceivedFrom
{
get { return _ReceivedFrom; }
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Text;
@ -163,7 +164,7 @@ namespace Rssdp.Infrastructure
/// <summary>
/// Sends a message to a particular address (uni or multicast) and port.
/// </summary>
public async Task SendMessage(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken)
public async Task SendMessage(byte[] messageData, IPEndPoint destination, IPAddress fromLocalIpAddress, CancellationToken cancellationToken)
{
if (messageData == null) throw new ArgumentNullException(nameof(messageData));
@ -186,7 +187,7 @@ namespace Rssdp.Infrastructure
}
}
private async Task SendFromSocket(ISocket socket, byte[] messageData, IpEndPointInfo destination, CancellationToken cancellationToken)
private async Task SendFromSocket(ISocket socket, byte[] messageData, IPEndPoint destination, CancellationToken cancellationToken)
{
try
{
@ -206,7 +207,7 @@ namespace Rssdp.Infrastructure
}
}
private List<ISocket> GetSendSockets(IpAddressInfo fromLocalIpAddress, IpEndPointInfo destination)
private List<ISocket> GetSendSockets(IPAddress fromLocalIpAddress, IPEndPoint destination)
{
EnsureSendSocketCreated();
@ -215,24 +216,24 @@ namespace Rssdp.Infrastructure
var sockets = _sendSockets.Where(i => i.LocalIPAddress.AddressFamily == fromLocalIpAddress.AddressFamily);
// Send from the Any socket and the socket with the matching address
if (fromLocalIpAddress.AddressFamily == IpAddressFamily.InterNetwork)
if (fromLocalIpAddress.AddressFamily == AddressFamily.InterNetwork)
{
sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || fromLocalIpAddress.Equals(i.LocalIPAddress));
sockets = sockets.Where(i => i.LocalIPAddress.Equals(IPAddress.Any) || fromLocalIpAddress.Equals(i.LocalIPAddress));
// If sending to the loopback address, filter the socket list as well
if (destination.IpAddress.Equals(IpAddressInfo.Loopback))
if (destination.Address.Equals(IPAddress.Loopback))
{
sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || i.LocalIPAddress.Equals(IpAddressInfo.Loopback));
sockets = sockets.Where(i => i.LocalIPAddress.Equals(IPAddress.Any) || i.LocalIPAddress.Equals(IPAddress.Loopback));
}
}
else if (fromLocalIpAddress.AddressFamily == IpAddressFamily.InterNetworkV6)
else if (fromLocalIpAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.IPv6Any) || fromLocalIpAddress.Equals(i.LocalIPAddress));
sockets = sockets.Where(i => i.LocalIPAddress.Equals(IPAddress.IPv6Any) || fromLocalIpAddress.Equals(i.LocalIPAddress));
// If sending to the loopback address, filter the socket list as well
if (destination.IpAddress.Equals(IpAddressInfo.IPv6Loopback))
if (destination.Address.Equals(IPAddress.IPv6Loopback))
{
sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.IPv6Any) || i.LocalIPAddress.Equals(IpAddressInfo.IPv6Loopback));
sockets = sockets.Where(i => i.LocalIPAddress.Equals(IPAddress.IPv6Any) || i.LocalIPAddress.Equals(IPAddress.IPv6Loopback));
}
}
@ -240,7 +241,7 @@ namespace Rssdp.Infrastructure
}
}
public Task SendMulticastMessage(string message, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken)
public Task SendMulticastMessage(string message, IPAddress fromLocalIpAddress, CancellationToken cancellationToken)
{
return SendMulticastMessage(message, SsdpConstants.UdpResendCount, fromLocalIpAddress, cancellationToken);
}
@ -248,7 +249,7 @@ namespace Rssdp.Infrastructure
/// <summary>
/// Sends a message to the SSDP multicast address and port.
/// </summary>
public async Task SendMulticastMessage(string message, int sendCount, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken)
public async Task SendMulticastMessage(string message, int sendCount, IPAddress fromLocalIpAddress, CancellationToken cancellationToken)
{
if (message == null) throw new ArgumentNullException(nameof(message));
@ -263,12 +264,13 @@ namespace Rssdp.Infrastructure
// SSDP spec recommends sending messages multiple times (not more than 3) to account for possible packet loss over UDP.
for (var i = 0; i < sendCount; i++)
{
await SendMessageIfSocketNotDisposed(messageData, new IpEndPointInfo
{
IpAddress = new IpAddressInfo(SsdpConstants.MulticastLocalAdminAddress, IpAddressFamily.InterNetwork),
Port = SsdpConstants.MulticastPort
}, fromLocalIpAddress, cancellationToken).ConfigureAwait(false);
await SendMessageIfSocketNotDisposed(
messageData,
new IPEndPoint(
IPAddress.Parse(SsdpConstants.MulticastLocalAdminAddress),
SsdpConstants.MulticastPort),
fromLocalIpAddress,
cancellationToken).ConfigureAwait(false);
await Task.Delay(100, cancellationToken).ConfigureAwait(false);
}
@ -336,7 +338,7 @@ namespace Rssdp.Infrastructure
#region Private Methods
private Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken)
private Task SendMessageIfSocketNotDisposed(byte[] messageData, IPEndPoint destination, IPAddress fromLocalIpAddress, CancellationToken cancellationToken)
{
var sockets = _sendSockets;
if (sockets != null)
@ -364,13 +366,13 @@ namespace Rssdp.Infrastructure
{
var sockets = new List<ISocket>();
sockets.Add(_SocketFactory.CreateSsdpUdpSocket(IpAddressInfo.Any, _LocalPort));
sockets.Add(_SocketFactory.CreateSsdpUdpSocket(IPAddress.Any, _LocalPort));
if (_enableMultiSocketBinding)
{
foreach (var address in _networkManager.GetLocalIpAddresses(_config.Configuration.IgnoreVirtualInterfaces))
{
if (address.AddressFamily == IpAddressFamily.InterNetworkV6)
if (address.AddressFamily == AddressFamily.InterNetworkV6)
{
// Not support IPv6 right now
continue;
@ -439,7 +441,7 @@ namespace Rssdp.Infrastructure
}
}
private void ProcessMessage(string data, IpEndPointInfo endPoint, IpAddressInfo receivedOnLocalIpAddress)
private void ProcessMessage(string data, IPEndPoint endPoint, IPAddress receivedOnLocalIpAddress)
{
// Responses start with the HTTP version, prefixed with HTTP/ while
// requests start with a method which can vary and might be one we haven't
@ -481,7 +483,7 @@ namespace Rssdp.Infrastructure
}
}
private void OnRequestReceived(HttpRequestMessage data, IpEndPointInfo remoteEndPoint, IpAddressInfo receivedOnLocalIpAddress)
private void OnRequestReceived(HttpRequestMessage data, IPEndPoint remoteEndPoint, IPAddress receivedOnLocalIpAddress)
{
//SSDP specification says only * is currently used but other uri's might
//be implemented in the future and should be ignored unless understood.
@ -496,7 +498,7 @@ namespace Rssdp.Infrastructure
handlers(this, new RequestReceivedEventArgs(data, remoteEndPoint, receivedOnLocalIpAddress));
}
private void OnResponseReceived(HttpResponseMessage data, IpEndPointInfo endPoint, IpAddressInfo localIpAddress)
private void OnResponseReceived(HttpResponseMessage data, IPEndPoint endPoint, IPAddress localIpAddress)
{
var handlers = this.ResponseReceived;
if (handlers != null)

View File

@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Rssdp.Infrastructure;
namespace Rssdp

View File

@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
namespace Rssdp.Infrastructure
{
@ -213,7 +210,7 @@ namespace Rssdp.Infrastructure
/// Raises the <see cref="DeviceAvailable"/> event.
/// </summary>
/// <seealso cref="DeviceAvailable"/>
protected virtual void OnDeviceAvailable(DiscoveredSsdpDevice device, bool isNewDevice, IpAddressInfo localIpAddress)
protected virtual void OnDeviceAvailable(DiscoveredSsdpDevice device, bool isNewDevice, IPAddress localIpAddress)
{
if (this.IsDisposed) return;
@ -295,7 +292,7 @@ namespace Rssdp.Infrastructure
#region Discovery/Device Add
private void AddOrUpdateDiscoveredDevice(DiscoveredSsdpDevice device, IpAddressInfo localIpAddress)
private void AddOrUpdateDiscoveredDevice(DiscoveredSsdpDevice device, IPAddress localIpAddress)
{
bool isNewDevice = false;
lock (_Devices)
@ -316,7 +313,7 @@ namespace Rssdp.Infrastructure
DeviceFound(device, isNewDevice, localIpAddress);
}
private void DeviceFound(DiscoveredSsdpDevice device, bool isNewDevice, IpAddressInfo localIpAddress)
private void DeviceFound(DiscoveredSsdpDevice device, bool isNewDevice, IPAddress localIpAddress)
{
if (!NotificationTypeMatchesFilter(device)) return;
@ -357,7 +354,7 @@ namespace Rssdp.Infrastructure
return _CommunicationsServer.SendMulticastMessage(message, null, cancellationToken);
}
private void ProcessSearchResponseMessage(HttpResponseMessage message, IpAddressInfo localIpAddress)
private void ProcessSearchResponseMessage(HttpResponseMessage message, IPAddress localIpAddress)
{
if (!message.IsSuccessStatusCode) return;
@ -378,7 +375,7 @@ namespace Rssdp.Infrastructure
}
}
private void ProcessNotificationMessage(HttpRequestMessage message, IpAddressInfo localIpAddress)
private void ProcessNotificationMessage(HttpRequestMessage message, IPAddress localIpAddress)
{
if (String.Compare(message.Method.Method, "Notify", StringComparison.OrdinalIgnoreCase) != 0) return;
@ -389,7 +386,7 @@ namespace Rssdp.Infrastructure
ProcessByeByeNotification(message);
}
private void ProcessAliveNotification(HttpRequestMessage message, IpAddressInfo localIpAddress)
private void ProcessAliveNotification(HttpRequestMessage message, IPAddress localIpAddress)
{
var location = GetFirstHeaderUriValue("Location", message);
if (location != null)

View File

@ -2,13 +2,10 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
using MediaBrowser.Common.Net;
using Rssdp;
namespace Rssdp.Infrastructure
{
@ -199,7 +196,12 @@ namespace Rssdp.Infrastructure
}
}
private void ProcessSearchRequest(string mx, string searchTarget, IpEndPointInfo remoteEndPoint, IpAddressInfo receivedOnlocalIpAddress, CancellationToken cancellationToken)
private void ProcessSearchRequest(
string mx,
string searchTarget,
IPEndPoint remoteEndPoint,
IPAddress receivedOnlocalIpAddress,
CancellationToken cancellationToken)
{
if (String.IsNullOrEmpty(searchTarget))
{
@ -258,7 +260,7 @@ namespace Rssdp.Infrastructure
foreach (var device in deviceList)
{
if (!_sendOnlyMatchedHost ||
_networkManager.IsInSameSubnet(device.ToRootDevice().Address, remoteEndPoint.IpAddress, device.ToRootDevice().SubnetMask))
_networkManager.IsInSameSubnet(device.ToRootDevice().Address, remoteEndPoint.Address, device.ToRootDevice().SubnetMask))
{
SendDeviceSearchResponses(device, remoteEndPoint, receivedOnlocalIpAddress, cancellationToken);
}
@ -276,7 +278,11 @@ namespace Rssdp.Infrastructure
return _Devices.Union(_Devices.SelectManyRecursive<SsdpDevice>((d) => d.Devices));
}
private void SendDeviceSearchResponses(SsdpDevice device, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress, CancellationToken cancellationToken)
private void SendDeviceSearchResponses(
SsdpDevice device,
IPEndPoint endPoint,
IPAddress receivedOnlocalIpAddress,
CancellationToken cancellationToken)
{
bool isRootDevice = (device as SsdpRootDevice) != null;
if (isRootDevice)
@ -296,7 +302,13 @@ namespace Rssdp.Infrastructure
return String.Format("{0}::{1}", udn, fullDeviceType);
}
private async void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress, CancellationToken cancellationToken)
private async void SendSearchResponse(
string searchTarget,
SsdpDevice device,
string uniqueServiceName,
IPEndPoint endPoint,
IPAddress receivedOnlocalIpAddress,
CancellationToken cancellationToken)
{
var rootDevice = device.ToRootDevice();
@ -333,7 +345,7 @@ namespace Rssdp.Infrastructure
//WriteTrace(String.Format("Sent search response to " + endPoint.ToString()), device);
}
private bool IsDuplicateSearchRequest(string searchTarget, IpEndPointInfo endPoint)
private bool IsDuplicateSearchRequest(string searchTarget, IPEndPoint endPoint)
{
var isDuplicateRequest = false;
@ -556,7 +568,7 @@ namespace Rssdp.Infrastructure
private class SearchRequest
{
public IpEndPointInfo EndPoint { get; set; }
public IPEndPoint EndPoint { get; set; }
public DateTime Received { get; set; }
public string SearchTarget { get; set; }

View File

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Rssdp.Infrastructure;
using MediaBrowser.Model.Net;
using System.Net;
namespace Rssdp
{
@ -56,12 +52,12 @@ namespace Rssdp
/// <summary>
/// Gets or sets the Address used to check if the received message from same interface with this device/tree. Required.
/// </summary>
public IpAddressInfo Address { get; set; }
public IPAddress Address { get; set; }
/// <summary>
/// Gets or sets the SubnetMask used to check if the received message from same interface with this device/tree. Required.
/// </summary>
public IpAddressInfo SubnetMask { get; set; }
public IPAddress SubnetMask { get; set; }
/// <summary>
/// The base URL to use for all relative url's provided in other propertise (and those of child devices). Optional.