Remove IpAddressInfo and IpEndPointInfo classes

pull/1524/head
Bond_009 5 years ago
parent e8028de4d7
commit ddd1a282ea

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

@ -1,5 +1,6 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Net;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Extensions;
@ -14,7 +15,6 @@ using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Events; using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Session; using MediaBrowser.Model.Session;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -172,7 +172,7 @@ namespace Emby.Dlna.PlayTo
_sessionManager.UpdateDeviceName(sessionInfo.Id, deviceName); _sessionManager.UpdateDeviceName(sessionInfo.Id, deviceName);
string serverAddress; 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); serverAddress = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
} }

@ -7,6 +7,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Sockets;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
@ -1546,14 +1547,22 @@ namespace Emby.Server.Implementations
return null; return null;
} }
public string GetLocalApiUrl(IpAddressInfo ipAddress) public string GetLocalApiUrl(IPAddress ipAddress)
{ {
if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6) if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{ {
return GetLocalApiUrl("[" + ipAddress.Address + "]"); // Remove the scope id from IPv6 addresses
var str = ipAddress.ToString();
var index = str.IndexOf('%');
if (index != -1)
{
str = str.Substring(0, index);
}
return GetLocalApiUrl("[" + str + "]");
} }
return GetLocalApiUrl(ipAddress.Address); return GetLocalApiUrl(ipAddress.ToString());
} }
public string GetLocalApiUrl(string host) public string GetLocalApiUrl(string host)
@ -1564,19 +1573,28 @@ namespace Emby.Server.Implementations
host, host,
HttpsPort.ToString(CultureInfo.InvariantCulture)); HttpsPort.ToString(CultureInfo.InvariantCulture));
} }
return string.Format("http://{0}:{1}", return string.Format("http://{0}:{1}",
host, host,
HttpPort.ToString(CultureInfo.InvariantCulture)); 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 + "]"); // Remove the scope id from IPv6 addresses
var str = ipAddress.ToString();
var index = str.IndexOf('%');
if (index != -1)
{
str = str.Substring(0, index);
}
return GetWanApiUrl("[" + str + "]");
} }
return GetWanApiUrl(ipAddress.Address); return GetWanApiUrl(ipAddress.ToString());
} }
public string GetWanApiUrl(string host) public string GetWanApiUrl(string host)
@ -1587,17 +1605,18 @@ namespace Emby.Server.Implementations
host, host,
ServerConfigurationManager.Configuration.PublicHttpsPort.ToString(CultureInfo.InvariantCulture)); ServerConfigurationManager.Configuration.PublicHttpsPort.ToString(CultureInfo.InvariantCulture));
} }
return string.Format("http://{0}:{1}", return string.Format("http://{0}:{1}",
host, host,
ServerConfigurationManager.Configuration.PublicPort.ToString(CultureInfo.InvariantCulture)); 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); 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 var addresses = ServerConfigurationManager
.Configuration .Configuration
@ -1611,13 +1630,13 @@ namespace Emby.Server.Implementations
addresses.AddRange(NetworkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces)); addresses.AddRange(NetworkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces));
} }
var resultList = new List<IpAddressInfo>(); var resultList = new List<IPAddress>();
foreach (var address in addresses) foreach (var address in addresses)
{ {
if (!allowLoopback) if (!allowLoopback)
{ {
if (address.Equals(IpAddressInfo.Loopback) || address.Equals(IpAddressInfo.IPv6Loopback)) if (address.Equals(IPAddress.Loopback) || address.Equals(IPAddress.IPv6Loopback))
{ {
continue; continue;
} }
@ -1638,7 +1657,7 @@ namespace Emby.Server.Implementations
return resultList; return resultList;
} }
private IpAddressInfo NormalizeConfiguredLocalAddress(string address) private IPAddress NormalizeConfiguredLocalAddress(string address)
{ {
var index = address.Trim('/').IndexOf('/'); var index = address.Trim('/').IndexOf('/');
@ -1647,7 +1666,7 @@ namespace Emby.Server.Implementations
address = address.Substring(index + 1); address = address.Substring(index + 1);
} }
if (NetworkManager.TryParseIpAddress(address.Trim('/'), out IpAddressInfo result)) if (IPAddress.TryParse(address.Trim('/'), out IPAddress result))
{ {
return result; return result;
} }
@ -1657,10 +1676,10 @@ namespace Emby.Server.Implementations
private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase); 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) || if (address.Equals(IPAddress.Loopback) ||
address.Equals(IpAddressInfo.IPv6Loopback)) address.Equals(IPAddress.IPv6Loopback))
{ {
return true; return true;
} }

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
@ -11,7 +12,6 @@ using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
@ -20,7 +20,6 @@ using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Net; using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun 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)) using (var manager = new HdHomerunManager(_socketFactory, Logger))
{ {
// Legacy HdHomeruns are IPv4 only // 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) 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? // Need a way to set the Receive timeout on the socket otherwise this might never timeout?
try 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]; var receiveBuffer = new byte[8192];
while (!cancellationToken.IsCancellationRequested) while (!cancellationToken.IsCancellationRequested)
{ {
var response = await udpClient.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, cancellationToken).ConfigureAwait(false); 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 // 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) if (response.ReceivedBytes > 13 && response.Buffer[1] == 3)

@ -89,7 +89,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private uint? _lockkey = null; private uint? _lockkey = null;
private int _activeTuner = -1; private int _activeTuner = -1;
private readonly ISocketFactory _socketFactory; private readonly ISocketFactory _socketFactory;
private IpAddressInfo _remoteIp; private IPAddress _remoteIp;
private ILogger _logger; private ILogger _logger;
private ISocket _currentTcpSocket; 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)) 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"); var lockkeyMsg = CreateGetMessage(tuner, "lockkey");
await socket.SendToAsync(lockkeyMsg, 0, lockkeyMsg.Length, ipEndPoint, cancellationToken); 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); 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; _remoteIp = remoteIp;
@ -154,7 +154,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var lockKeyValue = _lockkey.Value; var lockKeyValue = _lockkey.Value;
var ipEndPoint = new IpEndPointInfo(_remoteIp, HdHomeRunPort); var ipEndPoint = new IPEndPoint(_remoteIp, HdHomeRunPort);
for (int i = 0; i < numTuners; ++i) 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) foreach (Tuple<string, string> command in commandList)
{ {
var channelMsg = CreateSetMessage(_activeTuner, command.Item1, command.Item2, _lockkey); 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); var response = await tcpClient.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, cancellationToken).ConfigureAwait(false);
// parse response to make sure it worked // parse response to make sure it worked
if (!ParseReturnMessage(response.Buffer, response.ReceivedBytes, out string returnVal)) 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); _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); var releaseTarget = CreateSetMessage(_activeTuner, "target", "none", lockKeyValue);
await tcpClient.SendToAsync(releaseTarget, 0, releaseTarget.Length, ipEndPoint, CancellationToken.None).ConfigureAwait(false); await tcpClient.SendToAsync(releaseTarget, 0, releaseTarget.Length, ipEndPoint, CancellationToken.None).ConfigureAwait(false);

@ -25,7 +25,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private readonly int _numTuners; private readonly int _numTuners;
private readonly INetworkManager _networkManager; 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) : base(mediaSource, tunerHostInfo, fileSystem, logger, appPaths)
{ {
_appHost = appHost; _appHost = appHost;
@ -58,7 +70,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
Logger.LogInformation("Opening HDHR UDP Live stream from {host}", uri.Host); Logger.LogInformation("Opening HDHR UDP Live stream from {host}", uri.Host);
var remoteAddress = IPAddress.Parse(uri.Host); var remoteAddress = IPAddress.Parse(uri.Host);
var embyRemoteAddress = _networkManager.ParseIpAddress(uri.Host);
IPAddress localAddress = null; IPAddress localAddress = null;
using (var tcpSocket = CreateSocket(remoteAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) using (var tcpSocket = CreateSocket(remoteAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{ {
@ -81,7 +92,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
try try
{ {
// send url to start streaming // 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) catch (Exception ex)
{ {

@ -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 // 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. // 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) if (remotePort < 0)
{ {
throw new ArgumentException("remotePort cannot be less than zero.", nameof(remotePort)); 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.InterNetwork
: AddressFamily.InterNetworkV6; : AddressFamily.InterNetworkV6;
@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.Net
try try
{ {
return new UdpSocket(retVal, new IpEndPointInfo(remoteAddress, remotePort)); return new UdpSocket(retVal, new IPEndPoint(remoteAddress, remotePort));
} }
catch 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. /// 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> /// </summary>
/// <returns>An implementation of the <see cref="ISocket"/> interface used by RSSDP components to perform acceptSocket operations.</returns> /// <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) if (localPort < 0)
{ {
@ -115,10 +115,8 @@ namespace Emby.Server.Implementations.Net
retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4); 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"), localIpAddress));
return new UdpSocket(retVal, localPort, localIpAddress);
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIp));
return new UdpSocket(retVal, localPort, localIp);
} }
catch catch
{ {

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

@ -9,55 +9,38 @@ using System.Threading.Tasks;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net; using MediaBrowser.Model.Net;
using MediaBrowser.Model.System;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
namespace Emby.Server.Implementations.Networking namespace Emby.Server.Implementations.Networking
{ {
public class NetworkManager : INetworkManager public class NetworkManager : INetworkManager
{ {
protected ILogger Logger { get; private set; } private readonly ILogger _logger;
public event EventHandler NetworkChanged; private IPAddress[] _localIpAddresses;
public Func<string[]> LocalSubnetsFn { get; set; } 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.NetworkAddressChanged += OnNetworkAddressChanged;
{ NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged;
NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
}
catch (Exception ex)
{
Logger.LogError(ex, "Error binding to NetworkChange_NetworkAvailabilityChanged event");
}
}
} }
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(); OnNetworkChanged();
} }
private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e) private void OnNetworkAddressChanged(object sender, EventArgs e)
{ {
Logger.LogDebug("NetworkAddressChanged"); _logger.LogDebug("NetworkAddressChanged");
OnNetworkChanged(); OnNetworkChanged();
} }
@ -68,39 +51,35 @@ namespace Emby.Server.Implementations.Networking
_localIpAddresses = null; _localIpAddresses = null;
_macAddresses = null; _macAddresses = null;
} }
if (NetworkChanged != null) if (NetworkChanged != null)
{ {
NetworkChanged(this, EventArgs.Empty); NetworkChanged(this, EventArgs.Empty);
} }
} }
private IpAddressInfo[] _localIpAddresses; public IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface = true)
private readonly object _localIpAddressSyncLock = new object();
public IpAddressInfo[] GetLocalIpAddresses(bool ignoreVirtualInterface = true)
{ {
lock (_localIpAddressSyncLock) lock (_localIpAddressSyncLock)
{ {
if (_localIpAddresses == null) if (_localIpAddresses == null)
{ {
var addresses = GetLocalIpAddressesInternal(ignoreVirtualInterface).Result.Select(ToIpAddressInfo).ToArray(); var addresses = GetLocalIpAddressesInternal(ignoreVirtualInterface).ToArray();
_localIpAddresses = addresses; _localIpAddresses = addresses;
return addresses;
} }
return _localIpAddresses; return _localIpAddresses;
} }
} }
private async Task<List<IPAddress>> GetLocalIpAddressesInternal(bool ignoreVirtualInterface) private List<IPAddress> GetLocalIpAddressesInternal(bool ignoreVirtualInterface)
{ {
var list = GetIPsDefault(ignoreVirtualInterface) var list = GetIPsDefault(ignoreVirtualInterface).ToList();
.ToList();
if (list.Count == 0) if (list.Count == 0)
{ {
list.AddRange(await GetLocalIpAddressesFallback().ConfigureAwait(false)); list = GetLocalIpAddressesFallback().GetAwaiter().GetResult().ToList();
} }
var listClone = list.ToList(); var listClone = list.ToList();
@ -351,13 +330,13 @@ namespace Emby.Server.Implementations.Networking
try try
{ {
var host = uri.DnsSafeHost; var host = uri.DnsSafeHost;
Logger.LogDebug("Resolving host {0}", host); _logger.LogDebug("Resolving host {0}", host);
address = GetIpAddresses(host).Result.FirstOrDefault(); address = GetIpAddresses(host).Result.FirstOrDefault();
if (address != null) if (address != null)
{ {
Logger.LogDebug("{0} resolved to {1}", host, address); _logger.LogDebug("{0} resolved to {1}", host, address);
return IsInLocalNetworkInternal(address.ToString(), false); return IsInLocalNetworkInternal(address.ToString(), false);
} }
@ -368,7 +347,7 @@ namespace Emby.Server.Implementations.Networking
} }
catch (Exception ex) 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); return Dns.GetHostAddressesAsync(hostName);
} }
private List<IPAddress> GetIPsDefault(bool ignoreVirtualInterface) private IEnumerable<IPAddress> GetIPsDefault(bool ignoreVirtualInterface)
{ {
NetworkInterface[] interfaces; IEnumerable<NetworkInterface> interfaces;
try try
{ {
var validStatuses = new[] { OperationalStatus.Up, OperationalStatus.Unknown };
interfaces = NetworkInterface.GetAllNetworkInterfaces() interfaces = NetworkInterface.GetAllNetworkInterfaces()
.Where(i => validStatuses.Contains(i.OperationalStatus)) .Where(x => x.OperationalStatus == OperationalStatus.Up
.ToArray(); || x.OperationalStatus == OperationalStatus.Unknown);
} }
catch (Exception ex) catch (NetworkInformationException ex)
{ {
Logger.LogError(ex, "Error in GetAllNetworkInterfaces"); _logger.LogError(ex, "Error in GetAllNetworkInterfaces");
return new List<IPAddress>(); return Enumerable.Empty<IPAddress>();
} }
return interfaces.SelectMany(network => 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
// suppress logging because it might be causing nas device wake up var addr = ipProperties.GatewayAddresses.FirstOrDefault();
//logger.LogDebug("Querying interface: {0}. Type: {1}. Status: {2}", network.Name, network.NetworkInterfaceType, network.OperationalStatus); if (addr == null
|| (ignoreVirtualInterface
var ipProperties = network.GetIPProperties(); && (addr.Address.Equals(IPAddress.Any) || addr.Address.Equals(IPAddress.IPv6Any))))
// 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 Enumerable.Empty<IPAddress>();
return new List<IPAddress>();
} }
return ipProperties.UnicastAddresses
.Select(i => i.Address)
.Where(i => i.AddressFamily == AddressFamily.InterNetwork || i.AddressFamily == AddressFamily.InterNetworkV6);
}).GroupBy(i => i.ToString()) }).GroupBy(i => i.ToString())
.Select(x => x.First()) .Select(x => x.First());
.ToList();
} }
private static async Task<IEnumerable<IPAddress>> GetLocalIpAddressesFallback() private static async Task<IEnumerable<IPAddress>> GetLocalIpAddressesFallback()
@ -612,32 +576,10 @@ namespace Emby.Server.Implementations.Networking
return hosts[0]; 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)) IPAddress network1 = GetNetworkAddress(address1, subnetMask);
{ IPAddress network2 = GetNetworkAddress(address2, subnetMask);
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));
return network1.Equals(network2); return network1.Equals(network2);
} }
@ -656,13 +598,13 @@ namespace Emby.Server.Implementations.Networking
{ {
broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i])); broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i]));
} }
return new IPAddress(broadcastAddress); return new IPAddress(broadcastAddress);
} }
public IpAddressInfo GetLocalIpSubnetMask(IpAddressInfo address) public IPAddress GetLocalIpSubnetMask(IPAddress address)
{ {
NetworkInterface[] interfaces; NetworkInterface[] interfaces;
IPAddress ipaddress = ToIPAddress(address);
try try
{ {
@ -674,7 +616,7 @@ namespace Emby.Server.Implementations.Networking
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.LogError(ex, "Error in GetAllNetworkInterfaces"); _logger.LogError(ex, "Error in GetAllNetworkInterfaces");
return null; return null;
} }
@ -684,83 +626,15 @@ namespace Emby.Server.Implementations.Networking
{ {
foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) 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) return null;
{
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> /// <summary>

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -25,7 +26,7 @@ namespace Emby.Server.Implementations.Udp
private bool _isDisposed; 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 IServerApplicationHost _appHost;
private readonly IJsonSerializer _json; private readonly IJsonSerializer _json;
@ -43,9 +44,9 @@ namespace Emby.Server.Implementations.Udp
AddMessageResponder("who is JellyfinServer?", true, RespondToV2Message); 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> /// <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 text = encoding.GetString(buffer, 0, bytesReceived);
var responder = _responders.FirstOrDefault(i => var responder = _responders.FirstOrDefault(i =>
@ -99,10 +100,10 @@ namespace Emby.Server.Implementations.Udp
{ {
return null; 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('|'); 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) if (_isDisposed)
{ {

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

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

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

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

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

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

@ -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
}
}

@ -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);
}
}
}

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

@ -1,8 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Net;
using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
namespace Rssdp namespace Rssdp
{ {
@ -11,12 +8,12 @@ namespace Rssdp
/// </summary> /// </summary>
public sealed class DeviceAvailableEventArgs : EventArgs public sealed class DeviceAvailableEventArgs : EventArgs
{ {
public IpAddressInfo LocalIpAddress { get; set; } public IPAddress LocalIpAddress { get; set; }
#region Fields #region Fields
private readonly DiscoveredSsdpDevice _DiscoveredDevice; private readonly DiscoveredSsdpDevice _DiscoveredDevice;
private readonly bool _IsNewlyDiscovered; private readonly bool _IsNewlyDiscovered;
#endregion #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> /// <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> /// <exception cref="ArgumentNullException">Thrown if the <paramref name="discoveredDevice"/> parameter is null.</exception>
public DeviceAvailableEventArgs(DiscoveredSsdpDevice discoveredDevice, bool isNewlyDiscovered) public DeviceAvailableEventArgs(DiscoveredSsdpDevice discoveredDevice, bool isNewlyDiscovered)
{ {
if (discoveredDevice == null) throw new ArgumentNullException(nameof(discoveredDevice)); if (discoveredDevice == null) throw new ArgumentNullException(nameof(discoveredDevice));
_DiscoveredDevice = discoveredDevice; _DiscoveredDevice = discoveredDevice;
_IsNewlyDiscovered = isNewlyDiscovered; _IsNewlyDiscovered = isNewlyDiscovered;
} }
#endregion #endregion
#region Public Properties #region Public Properties
/// <summary> /// <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. /// 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> /// </summary>
public bool IsNewlyDiscovered public bool IsNewlyDiscovered
{ {
get { return _IsNewlyDiscovered; } get { return _IsNewlyDiscovered; }
} }
/// <summary> /// <summary>
/// A reference to a <see cref="DiscoveredSsdpDevice"/> instance containing the discovered details and allowing access to the full device description. /// A reference to a <see cref="DiscoveredSsdpDevice"/> instance containing the discovered details and allowing access to the full device description.
/// </summary> /// </summary>
public DiscoveredSsdpDevice DiscoveredDevice public DiscoveredSsdpDevice DiscoveredDevice
{ {
get { return _DiscoveredDevice; } get { return _DiscoveredDevice; }
} }
#endregion #endregion
} }
} }

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

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

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

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
@ -163,7 +164,7 @@ namespace Rssdp.Infrastructure
/// <summary> /// <summary>
/// Sends a message to a particular address (uni or multicast) and port. /// Sends a message to a particular address (uni or multicast) and port.
/// </summary> /// </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)); 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 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(); EnsureSendSocketCreated();
@ -215,24 +216,24 @@ namespace Rssdp.Infrastructure
var sockets = _sendSockets.Where(i => i.LocalIPAddress.AddressFamily == fromLocalIpAddress.AddressFamily); var sockets = _sendSockets.Where(i => i.LocalIPAddress.AddressFamily == fromLocalIpAddress.AddressFamily);
// Send from the Any socket and the socket with the matching address // 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 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 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); return SendMulticastMessage(message, SsdpConstants.UdpResendCount, fromLocalIpAddress, cancellationToken);
} }
@ -248,7 +249,7 @@ namespace Rssdp.Infrastructure
/// <summary> /// <summary>
/// Sends a message to the SSDP multicast address and port. /// Sends a message to the SSDP multicast address and port.
/// </summary> /// </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)); 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. // 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++) for (var i = 0; i < sendCount; i++)
{ {
await SendMessageIfSocketNotDisposed(messageData, new IpEndPointInfo await SendMessageIfSocketNotDisposed(
{ messageData,
IpAddress = new IpAddressInfo(SsdpConstants.MulticastLocalAdminAddress, IpAddressFamily.InterNetwork), new IPEndPoint(
Port = SsdpConstants.MulticastPort IPAddress.Parse(SsdpConstants.MulticastLocalAdminAddress),
SsdpConstants.MulticastPort),
}, fromLocalIpAddress, cancellationToken).ConfigureAwait(false); fromLocalIpAddress,
cancellationToken).ConfigureAwait(false);
await Task.Delay(100, cancellationToken).ConfigureAwait(false); await Task.Delay(100, cancellationToken).ConfigureAwait(false);
} }
@ -336,7 +338,7 @@ namespace Rssdp.Infrastructure
#region Private Methods #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; var sockets = _sendSockets;
if (sockets != null) if (sockets != null)
@ -364,13 +366,13 @@ namespace Rssdp.Infrastructure
{ {
var sockets = new List<ISocket>(); var sockets = new List<ISocket>();
sockets.Add(_SocketFactory.CreateSsdpUdpSocket(IpAddressInfo.Any, _LocalPort)); sockets.Add(_SocketFactory.CreateSsdpUdpSocket(IPAddress.Any, _LocalPort));
if (_enableMultiSocketBinding) if (_enableMultiSocketBinding)
{ {
foreach (var address in _networkManager.GetLocalIpAddresses(_config.Configuration.IgnoreVirtualInterfaces)) foreach (var address in _networkManager.GetLocalIpAddresses(_config.Configuration.IgnoreVirtualInterfaces))
{ {
if (address.AddressFamily == IpAddressFamily.InterNetworkV6) if (address.AddressFamily == AddressFamily.InterNetworkV6)
{ {
// Not support IPv6 right now // Not support IPv6 right now
continue; 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 // 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 // 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 //SSDP specification says only * is currently used but other uri's might
//be implemented in the future and should be ignored unless understood. //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)); 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; var handlers = this.ResponseReceived;
if (handlers != null) if (handlers != null)

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

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

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

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

Loading…
Cancel
Save