diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
index 8159be6340..46f8806573 100644
--- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
+++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
@@ -24,14 +24,32 @@ namespace MediaBrowser.Common.Implementations.Networking
/// IPAddress.
public IEnumerable GetLocalIpAddresses()
{
- var list = GetIPsDefault().Where(i => !IPAddress.IsLoopback(i)).Select(i => i.ToString()).ToList();
+ var list = GetIPsDefault()
+ .Where(i => !IPAddress.IsLoopback(i))
+ .Select(i => i.ToString())
+ .ToList();
- if (list.Count > 0)
+ try
{
- return list;
+ var listFromDns = Dns.GetHostAddresses(Dns.GetHostName())
+ .Where(i => i.AddressFamily == AddressFamily.InterNetwork)
+ .Where(i => !IPAddress.IsLoopback(i))
+ .Select(i => i.ToString())
+ .ToList();
+
+ if (listFromDns.Count > 0)
+ {
+ return listFromDns
+ .OrderBy(i => (list.Contains(i, StringComparer.OrdinalIgnoreCase) ? 0 : 1))
+ .ToList();
+ }
}
+ catch
+ {
- return GetLocalIpAddressesFallback();
+ }
+
+ return list;
}
public bool IsInLocalNetwork(string endpoint)
diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs
index a48860b7eb..d1a9b386cc 100644
--- a/MediaBrowser.Controller/IServerApplicationHost.cs
+++ b/MediaBrowser.Controller/IServerApplicationHost.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common;
+using System.Collections.Generic;
+using MediaBrowser.Common;
using MediaBrowser.Model.System;
using System;
@@ -46,5 +47,11 @@ namespace MediaBrowser.Controller
///
/// The name of the friendly.
string FriendlyName { get; }
+
+ ///
+ /// Gets the HTTP server ip addresses.
+ ///
+ /// The HTTP server ip addresses.
+ IEnumerable HttpServerIpAddresses { get; }
}
}
diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
index 4d3e2272a9..1d88eca032 100644
--- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
+++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
@@ -111,7 +111,7 @@ namespace MediaBrowser.Dlna.Main
_ssdpHandler.Start();
- _deviceDiscovery = new DeviceDiscovery(_logger, _config, _httpClient, _ssdpHandler, _network);
+ _deviceDiscovery = new DeviceDiscovery(_logger, _config, _ssdpHandler, _appHost);
_deviceDiscovery.Start();
}
diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
index 56877d82d4..adc2d731ac 100644
--- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
+++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Common.Events;
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Logging;
using System;
@@ -21,21 +22,19 @@ namespace MediaBrowser.Dlna.Ssdp
private readonly IServerConfigurationManager _config;
private readonly SsdpHandler _ssdpHandler;
private readonly CancellationTokenSource _tokenSource;
- private readonly IHttpClient _httpClient;
- private readonly INetworkManager _networkManager;
+ private readonly IServerApplicationHost _appHost;
public event EventHandler DeviceDiscovered;
public event EventHandler DeviceLeft;
- public DeviceDiscovery(ILogger logger, IServerConfigurationManager config, IHttpClient httpClient, SsdpHandler ssdpHandler, INetworkManager networkManager)
+ public DeviceDiscovery(ILogger logger, IServerConfigurationManager config, SsdpHandler ssdpHandler, IServerApplicationHost appHost)
{
_tokenSource = new CancellationTokenSource();
_logger = logger;
_config = config;
- _httpClient = httpClient;
_ssdpHandler = ssdpHandler;
- _networkManager = networkManager;
+ _appHost = appHost;
}
public void Start()
@@ -48,21 +47,21 @@ namespace MediaBrowser.Dlna.Ssdp
if (!network.SupportsMulticast || OperationalStatus.Up != network.OperationalStatus || !network.GetIPProperties().MulticastAddresses.Any())
continue;
-
+
var ipV4 = network.GetIPProperties().GetIPv4Properties();
if (null == ipV4)
continue;
- var localIp = network.GetIPProperties().UnicastAddresses
+ var localIps = network.GetIPProperties().UnicastAddresses
.Where(i => i.Address.AddressFamily == AddressFamily.InterNetwork)
.Select(i => i.Address)
- .FirstOrDefault();
+ .ToList();
- if (localIp != null)
+ foreach (var localIp in localIps)
{
try
{
- CreateListener(localIp, ipV4.Index);
+ CreateListener(localIp);
}
catch (Exception e)
{
@@ -71,7 +70,7 @@ namespace MediaBrowser.Dlna.Ssdp
}
}
}
-
+
void _ssdpHandler_MessageReceived(object sender, SsdpMessageEventArgs e)
{
string nts;
@@ -87,9 +86,9 @@ namespace MediaBrowser.Dlna.Ssdp
try
{
- var ip = _networkManager.GetLocalIpAddresses().FirstOrDefault();
+ var ip = _appHost.HttpServerIpAddresses.FirstOrDefault();
- if (ip != null)
+ if (!string.IsNullOrWhiteSpace(ip))
{
e.LocalIp = IPAddress.Parse(ip);
TryCreateDevice(e);
@@ -116,19 +115,17 @@ namespace MediaBrowser.Dlna.Ssdp
return new List();
}
}
- private void CreateListener(IPAddress localIp, int networkInterfaceIndex)
+ private void CreateListener(IPAddress localIp)
{
Task.Factory.StartNew(async (o) =>
{
try
{
- var socket = GetMulticastSocket(networkInterfaceIndex);
-
var endPoint = new IPEndPoint(localIp, 1900);
- socket.Bind(endPoint);
+ var socket = GetMulticastSocket(localIp, endPoint);
- _logger.Info("Creating SSDP listener on {0}, network interface index {1}", localIp, networkInterfaceIndex);
+ _logger.Info("Creating SSDP listener on {0}", localIp);
var receiveBuffer = new byte[64000];
@@ -188,12 +185,15 @@ namespace MediaBrowser.Dlna.Ssdp
}
- private Socket GetMulticastSocket(int networkInterfaceIndex)
+ private Socket GetMulticastSocket(IPAddress localIpAddress, EndPoint localEndpoint)
{
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
- socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), networkInterfaceIndex));
+ socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIpAddress));
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4);
+
+ socket.Bind(localEndpoint);
+
return socket;
}
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
index 15d1eea6d9..d88a04063a 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -14,7 +14,6 @@ using ServiceStack.Host.HttpListener;
using ServiceStack.Logging;
using ServiceStack.Web;
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -40,15 +39,26 @@ namespace MediaBrowser.Server.Implementations.HttpServer
public event EventHandler WebSocketConnected;
- private readonly ConcurrentDictionary _localEndPoints = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase);
-
+ private readonly List _localEndpoints = new List();
+
+ private readonly ReaderWriterLockSlim _localEndpointLock = new ReaderWriterLockSlim();
+
///
/// Gets the local end points.
///
/// The local end points.
public IEnumerable LocalEndPoints
{
- get { return _listener == null ? new List() : _localEndPoints.Keys.ToList(); }
+ get
+ {
+ _localEndpointLock.EnterReadLock();
+
+ var list = _localEndpoints.ToList();
+
+ _localEndpointLock.ExitReadLock();
+
+ return list;
+ }
}
public HttpListenerHost(IApplicationHost applicationHost, ILogManager logManager, string serviceName, string handlerPath, string defaultRedirectPath, params Assembly[] assembliesWithServices)
@@ -156,7 +166,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer
private void OnRequestReceived(string localEndPoint)
{
- _localEndPoints.GetOrAdd(localEndPoint, localEndPoint);
+ if (_localEndpointLock.TryEnterWriteLock(100))
+ {
+ var list = _localEndpoints.ToList();
+
+ list.Remove(localEndPoint);
+ list.Insert(0, localEndPoint);
+
+ _localEndpointLock.ExitWriteLock();
+ }
}
///
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index 25d410bfc7..e05ae9fa16 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -950,17 +950,8 @@ namespace MediaBrowser.ServerApplication
/// System.String.
private string GetLocalIpAddress()
{
- var localAddresses = NetworkManager.GetLocalIpAddresses().ToList();
-
- // Cross-check the local ip addresses with addresses that have been received on with the http server
- var matchedAddress = HttpServer.LocalEndPoints
- .ToList()
- .Select(i => i.Split(':').FirstOrDefault())
- .Where(i => !string.IsNullOrEmpty(i))
- .FirstOrDefault(i => localAddresses.Contains(i, StringComparer.OrdinalIgnoreCase));
-
// Return the first matched address, if found, or the first known local address
- var address = matchedAddress ?? localAddresses.FirstOrDefault();
+ var address = HttpServerIpAddresses.FirstOrDefault();
if (!string.IsNullOrWhiteSpace(address))
{
@@ -972,6 +963,37 @@ namespace MediaBrowser.ServerApplication
return address;
}
+ public IEnumerable HttpServerIpAddresses
+ {
+ get
+ {
+ var localAddresses = NetworkManager.GetLocalIpAddresses()
+ .ToList();
+
+ if (localAddresses.Count < 2)
+ {
+ return localAddresses;
+ }
+
+ var httpServerAddresses = HttpServer.LocalEndPoints
+ .Select(i => i.Split(':').FirstOrDefault())
+ .Where(i => !string.IsNullOrEmpty(i))
+ .ToList();
+
+ // Cross-check the local ip addresses with addresses that have been received on with the http server
+ var matchedAddresses = httpServerAddresses
+ .Where(i => localAddresses.Contains(i, StringComparer.OrdinalIgnoreCase))
+ .ToList();
+
+ if (matchedAddresses.Count == 0)
+ {
+ return localAddresses.Take(1);
+ }
+
+ return matchedAddresses;
+ }
+ }
+
public string FriendlyName
{
get