update local address detection

This commit is contained in:
Luke Pulverenti 2015-12-28 22:39:38 -05:00
parent 971808f38f
commit b46ef16ba8
8 changed files with 102 additions and 98 deletions

View File

@ -32,6 +32,12 @@ namespace MediaBrowser.Api.System
} }
[Route("/System/Ping", "POST")]
public class PingSystem : IReturnVoid
{
}
/// <summary> /// <summary>
/// Class RestartApplication /// Class RestartApplication
/// </summary> /// </summary>
@ -117,6 +123,11 @@ namespace MediaBrowser.Api.System
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }
public void Post(PingSystem request)
{
}
public object Get(GetServerLogs request) public object Get(GetServerLogs request)
{ {
List<FileSystemMetadata> files; List<FileSystemMetadata> files;

View File

@ -69,7 +69,7 @@ namespace MediaBrowser.Common.Implementations.Networking
list.AddRange(GetLocalIpAddressesFallback()); 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) private bool FilterIpAddress(IPAddress address)
@ -232,7 +232,7 @@ namespace MediaBrowser.Common.Implementations.Networking
return properties.UnicastAddresses return properties.UnicastAddresses
.Select(i => i.Address) .Select(i => i.Address)
.Where(i => i.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(i)) .Where(i => i.AddressFamily == AddressFamily.InterNetwork)
.ToList(); .ToList();
} }
catch (Exception ex) catch (Exception ex)

View File

@ -1,6 +1,8 @@
using MediaBrowser.Common; using MediaBrowser.Common;
using MediaBrowser.Model.System; using MediaBrowser.Model.System;
using System; using System;
using System.Collections.Generic;
using System.Net;
namespace MediaBrowser.Controller namespace MediaBrowser.Controller
{ {
@ -63,7 +65,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>
string LocalIpAddress { get; } List<IPAddress> LocalIpAddresses { get; }
/// <summary> /// <summary>
/// Gets the local API URL. /// Gets the local API URL.

View File

@ -28,12 +28,6 @@ namespace MediaBrowser.Controller.Net
/// the ssl certificate localtion on the file system.</param> /// the ssl certificate localtion on the file system.</param>
void StartServer(IEnumerable<string> urlPrefixes, string certificatePath); void StartServer(IEnumerable<string> urlPrefixes, string certificatePath);
/// <summary>
/// Gets the local end points.
/// </summary>
/// <value>The local end points.</value>
IEnumerable<string> LocalEndPoints { get; }
/// <summary> /// <summary>
/// Stops this instance. /// Stops this instance.
/// </summary> /// </summary>

View File

@ -148,9 +148,15 @@ namespace MediaBrowser.Dlna.Main
private void RegisterServerEndpoints() private void RegisterServerEndpoints()
{ {
foreach (var address in _network.GetLocalIpAddresses()) foreach (var address in _appHost.LocalIpAddresses)
{ {
var addressString = address.ToString (); //if (IPAddress.IsLoopback(address))
//{
// // Should we allow this?
// continue;
//}
var addressString = address.ToString();
var guid = addressString.GetMD5(); var guid = addressString.GetMD5();
var descriptorURI = "/dlna/" + guid.ToString("N") + "/description.xml"; var descriptorURI = "/dlna/" + guid.ToString("N") + "/description.xml";

View File

@ -110,8 +110,11 @@ namespace MediaBrowser.Dlna.Ssdp
{ {
if (e.LocalEndPoint == null) if (e.LocalEndPoint == null)
{ {
var ip = _appHost.LocalIpAddress; var ip = _appHost.LocalIpAddresses.FirstOrDefault(i => !IPAddress.IsLoopback(i));
e.LocalEndPoint = new IPEndPoint(IPAddress.Parse(ip), 0); if (ip != null)
{
e.LocalEndPoint = new IPEndPoint(ip, 0);
}
} }
if (e.LocalEndPoint != null) if (e.LocalEndPoint != null)

View File

@ -40,33 +40,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
public event EventHandler<WebSocketConnectEventArgs> WebSocketConnected; public event EventHandler<WebSocketConnectEventArgs> WebSocketConnected;
public event EventHandler<WebSocketConnectingEventArgs> WebSocketConnecting; public event EventHandler<WebSocketConnectingEventArgs> WebSocketConnecting;
private readonly List<string> _localEndpoints = new List<string>();
private readonly ReaderWriterLockSlim _localEndpointLock = new ReaderWriterLockSlim();
public string CertificatePath { get; private set; } public string CertificatePath { get; private set; }
private readonly IServerConfigurationManager _config; private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager; private readonly INetworkManager _networkManager;
/// <summary>
/// Gets the local end points.
/// </summary>
/// <value>The local end points.</value>
public IEnumerable<string> LocalEndPoints
{
get
{
_localEndpointLock.EnterReadLock();
var list = _localEndpoints.ToList();
_localEndpointLock.ExitReadLock();
return list;
}
}
public HttpListenerHost(IApplicationHost applicationHost, public HttpListenerHost(IApplicationHost applicationHost,
ILogManager logManager, ILogManager logManager,
IServerConfigurationManager config, IServerConfigurationManager config,
@ -178,22 +156,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
private void OnRequestReceived(string localEndPoint) 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();
}
} }
/// <summary> /// <summary>

View File

@ -91,10 +91,12 @@ using MediaBrowser.Server.Startup.Common.Migrations;
using MediaBrowser.WebDashboard.Api; using MediaBrowser.WebDashboard.Api;
using MediaBrowser.XbmcMetadata.Providers; using MediaBrowser.XbmcMetadata.Providers;
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -207,6 +209,7 @@ namespace MediaBrowser.Server.Startup.Common
private readonly string _remotePackageName; private readonly string _remotePackageName;
internal INativeApp NativeApp { get; set; } internal INativeApp NativeApp { get; set; }
private Timer _ipAddressCacheTimer;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ApplicationHost" /> class. /// Initializes a new instance of the <see cref="ApplicationHost" /> class.
@ -230,6 +233,8 @@ namespace MediaBrowser.Server.Startup.Common
NativeApp = nativeApp; NativeApp = nativeApp;
SetBaseExceptionMessage(); SetBaseExceptionMessage();
_ipAddressCacheTimer = new Timer(OnCacheClearTimerFired, null, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(3));
} }
private Version _version; private Version _version;
@ -1116,14 +1121,14 @@ namespace MediaBrowser.Server.Startup.Common
try try
{ {
// Return the first matched address, if found, or the first known local address // 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) catch (Exception ex)
{ {
@ -1141,39 +1146,60 @@ namespace MediaBrowser.Server.Startup.Common
HttpPort.ToString(CultureInfo.InvariantCulture)); HttpPort.ToString(CultureInfo.InvariantCulture));
} }
public string LocalIpAddress public List<IPAddress> LocalIpAddresses
{
get
{
return HttpServerIpAddresses.FirstOrDefault();
}
}
private IEnumerable<string> HttpServerIpAddresses
{ {
get get
{ {
var localAddresses = NetworkManager.GetLocalIpAddresses() var localAddresses = NetworkManager.GetLocalIpAddresses()
.Select(i => i.ToString()) .Where(IsIpAddressValid)
.ToList(); .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 localAddresses;
} }
return matchedAddresses;
} }
private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(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 public string FriendlyName