diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs
index a95fcb542..4faff8780 100644
--- a/MediaBrowser.Api/System/SystemService.cs
+++ b/MediaBrowser.Api/System/SystemService.cs
@@ -32,6 +32,12 @@ namespace MediaBrowser.Api.System
}
+ [Route("/System/Ping", "POST")]
+ public class PingSystem : IReturnVoid
+ {
+
+ }
+
///
/// Class RestartApplication
///
@@ -117,6 +123,11 @@ namespace MediaBrowser.Api.System
return ToOptimizedResult(result);
}
+ public void Post(PingSystem request)
+ {
+
+ }
+
public object Get(GetServerLogs request)
{
List files;
diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
index 789cde5fc..9b278b889 100644
--- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
+++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
@@ -69,7 +69,7 @@ namespace MediaBrowser.Common.Implementations.Networking
list.AddRange(GetLocalIpAddressesFallback());
}
- return list.Where(i => !IPAddress.IsLoopback(i)).Where(FilterIpAddress).DistinctBy(i => i.ToString());
+ return list.Where(FilterIpAddress).DistinctBy(i => i.ToString());
}
private bool FilterIpAddress(IPAddress address)
@@ -232,7 +232,7 @@ namespace MediaBrowser.Common.Implementations.Networking
return properties.UnicastAddresses
.Select(i => i.Address)
- .Where(i => i.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(i))
+ .Where(i => i.AddressFamily == AddressFamily.InterNetwork)
.ToList();
}
catch (Exception ex)
diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs
index 1b842a5f6..fb843d191 100644
--- a/MediaBrowser.Controller/IServerApplicationHost.cs
+++ b/MediaBrowser.Controller/IServerApplicationHost.cs
@@ -1,6 +1,8 @@
using MediaBrowser.Common;
using MediaBrowser.Model.System;
using System;
+using System.Collections.Generic;
+using System.Net;
namespace MediaBrowser.Controller
{
@@ -63,7 +65,7 @@ namespace MediaBrowser.Controller
/// Gets the local ip address.
///
/// The local ip address.
- string LocalIpAddress { get; }
+ List LocalIpAddresses { get; }
///
/// Gets the local API URL.
diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs
index 91da5fab2..97c5dd31b 100644
--- a/MediaBrowser.Controller/Net/IHttpServer.cs
+++ b/MediaBrowser.Controller/Net/IHttpServer.cs
@@ -28,12 +28,6 @@ namespace MediaBrowser.Controller.Net
/// the ssl certificate localtion on the file system.
void StartServer(IEnumerable urlPrefixes, string certificatePath);
- ///
- /// Gets the local end points.
- ///
- /// The local end points.
- IEnumerable LocalEndPoints { get; }
-
///
/// Stops this instance.
///
diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
index 37cca43eb..d79ef9eaf 100644
--- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
+++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
@@ -43,19 +43,19 @@ namespace MediaBrowser.Dlna.Main
private readonly List _registeredServerIds = new List();
private bool _dlnaServerStarted;
- public DlnaEntryPoint(IServerConfigurationManager config,
- ILogManager logManager,
- IServerApplicationHost appHost,
- INetworkManager network,
- ISessionManager sessionManager,
- IHttpClient httpClient,
- ILibraryManager libraryManager,
- IUserManager userManager,
- IDlnaManager dlnaManager,
- IImageProcessor imageProcessor,
- IUserDataManager userDataManager,
- ILocalizationManager localization,
- IMediaSourceManager mediaSourceManager,
+ public DlnaEntryPoint(IServerConfigurationManager config,
+ ILogManager logManager,
+ IServerApplicationHost appHost,
+ INetworkManager network,
+ ISessionManager sessionManager,
+ IHttpClient httpClient,
+ ILibraryManager libraryManager,
+ IUserManager userManager,
+ IDlnaManager dlnaManager,
+ IImageProcessor imageProcessor,
+ IUserDataManager userDataManager,
+ ILocalizationManager localization,
+ IMediaSourceManager mediaSourceManager,
ISsdpHandler ssdpHandler, IDeviceDiscovery deviceDiscovery)
{
_config = config;
@@ -148,14 +148,20 @@ namespace MediaBrowser.Dlna.Main
private void RegisterServerEndpoints()
{
- foreach (var address in _network.GetLocalIpAddresses())
+ foreach (var address in _appHost.LocalIpAddresses)
{
- var addressString = address.ToString ();
- var guid = addressString.GetMD5();
+ //if (IPAddress.IsLoopback(address))
+ //{
+ // // Should we allow this?
+ // continue;
+ //}
+
+ var addressString = address.ToString();
+ var guid = addressString.GetMD5();
var descriptorURI = "/dlna/" + guid.ToString("N") + "/description.xml";
- var uri = new Uri(_appHost.GetLocalApiUrl(addressString) + descriptorURI);
+ var uri = new Uri(_appHost.GetLocalApiUrl(addressString) + descriptorURI);
var services = new List
{
@@ -166,8 +172,8 @@ namespace MediaBrowser.Dlna.Main
"urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1",
"uuid:" + guid.ToString("N")
};
-
- _ssdpHandler.RegisterNotification(guid, uri, address, services);
+
+ _ssdpHandler.RegisterNotification(guid, uri, address, services);
_registeredServerIds.Add(guid.ToString("N"));
}
diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
index 457134913..279979550 100644
--- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
+++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
@@ -110,8 +110,11 @@ namespace MediaBrowser.Dlna.Ssdp
{
if (e.LocalEndPoint == null)
{
- var ip = _appHost.LocalIpAddress;
- e.LocalEndPoint = new IPEndPoint(IPAddress.Parse(ip), 0);
+ var ip = _appHost.LocalIpAddresses.FirstOrDefault(i => !IPAddress.IsLoopback(i));
+ if (ip != null)
+ {
+ e.LocalEndPoint = new IPEndPoint(ip, 0);
+ }
}
if (e.LocalEndPoint != null)
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
index 847982976..0283c1f7a 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -40,33 +40,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
public event EventHandler WebSocketConnected;
public event EventHandler WebSocketConnecting;
- private readonly List _localEndpoints = new List();
-
- private readonly ReaderWriterLockSlim _localEndpointLock = new ReaderWriterLockSlim();
-
public string CertificatePath { get; private set; }
private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager;
- ///
- /// Gets the local end points.
- ///
- /// The local end points.
- public IEnumerable LocalEndPoints
- {
- get
- {
- _localEndpointLock.EnterReadLock();
-
- var list = _localEndpoints.ToList();
-
- _localEndpointLock.ExitReadLock();
-
- return list;
- }
- }
-
public HttpListenerHost(IApplicationHost applicationHost,
ILogManager logManager,
IServerConfigurationManager config,
@@ -178,22 +156,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
private void OnRequestReceived(string localEndPoint)
{
- var ignore = _networkManager.IsInPrivateAddressSpace(localEndPoint);
-
- if (ignore)
- {
- return;
- }
-
- if (_localEndpointLock.TryEnterWriteLock(100))
- {
- var list = _localEndpoints;
-
- list.Remove(localEndPoint);
- list.Insert(0, localEndPoint);
-
- _localEndpointLock.ExitWriteLock();
- }
}
///
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index 2bdb138d7..a4760f3af 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -91,10 +91,12 @@ using MediaBrowser.Server.Startup.Common.Migrations;
using MediaBrowser.WebDashboard.Api;
using MediaBrowser.XbmcMetadata.Providers;
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Net;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
@@ -207,6 +209,7 @@ namespace MediaBrowser.Server.Startup.Common
private readonly string _remotePackageName;
internal INativeApp NativeApp { get; set; }
+ private Timer _ipAddressCacheTimer;
///
/// Initializes a new instance of the class.
@@ -230,6 +233,8 @@ namespace MediaBrowser.Server.Startup.Common
NativeApp = nativeApp;
SetBaseExceptionMessage();
+
+ _ipAddressCacheTimer = new Timer(OnCacheClearTimerFired, null, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(3));
}
private Version _version;
@@ -1116,14 +1121,14 @@ namespace MediaBrowser.Server.Startup.Common
try
{
// Return the first matched address, if found, or the first known local address
- var address = LocalIpAddress;
+ var address = LocalIpAddresses.FirstOrDefault(i => !IPAddress.IsLoopback(i));
- if (!string.IsNullOrWhiteSpace(address))
+ if (address != null)
{
- address = GetLocalApiUrl(address);
+ return GetLocalApiUrl(address.ToString());
}
- return address;
+ return null;
}
catch (Exception ex)
{
@@ -1141,41 +1146,62 @@ namespace MediaBrowser.Server.Startup.Common
HttpPort.ToString(CultureInfo.InvariantCulture));
}
- public string LocalIpAddress
- {
- get
- {
- return HttpServerIpAddresses.FirstOrDefault();
- }
- }
-
- private IEnumerable HttpServerIpAddresses
+ public List LocalIpAddresses
{
get
{
var localAddresses = NetworkManager.GetLocalIpAddresses()
- .Select(i => i.ToString())
+ .Where(IsIpAddressValid)
.ToList();
- 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;
- }
-
- return matchedAddresses;
+ return localAddresses;
}
}
+ private readonly ConcurrentDictionary _validAddressResults = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase);
+ private bool IsIpAddressValid(IPAddress address)
+ {
+ if (IPAddress.IsLoopback(address))
+ {
+ return true;
+ }
+
+ var apiUrl = GetLocalApiUrl(address.ToString());
+ apiUrl += "/system/ping";
+
+ bool cachedResult;
+ if (_validAddressResults.TryGetValue(apiUrl, out cachedResult))
+ {
+ return cachedResult;
+ }
+
+ try
+ {
+ using (var response = HttpClient.SendAsync(new HttpRequestOptions
+ {
+ Url = apiUrl,
+ BufferContent = false,
+ LogErrorResponseBody = false,
+ LogErrors = false
+
+ }, "POST").Result)
+ {
+ _validAddressResults.AddOrUpdate(apiUrl, true, (k, v) => true);
+ return true;
+ }
+ }
+ catch
+ {
+ _validAddressResults.AddOrUpdate(apiUrl, true, (k, v) => false);
+ return false;
+ }
+ }
+
+ private void OnCacheClearTimerFired(object state)
+ {
+ _validAddressResults.Clear();
+ }
+
public string FriendlyName
{
get