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>
/// Class RestartApplication
/// </summary>
@ -117,6 +123,11 @@ namespace MediaBrowser.Api.System
return ToOptimizedResult(result);
}
public void Post(PingSystem request)
{
}
public object Get(GetServerLogs request)
{
List<FileSystemMetadata> files;

View File

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

View File

@ -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.
/// </summary>
/// <value>The local ip address.</value>
string LocalIpAddress { get; }
List<IPAddress> LocalIpAddresses { get; }
/// <summary>
/// Gets the local API URL.

View File

@ -28,12 +28,6 @@ namespace MediaBrowser.Controller.Net
/// the ssl certificate localtion on the file system.</param>
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>
/// Stops this instance.
/// </summary>

View File

@ -43,19 +43,19 @@ namespace MediaBrowser.Dlna.Main
private readonly List<string> _registeredServerIds = new List<string>();
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<string>
{
@ -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"));
}

View File

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

View File

@ -40,33 +40,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
public event EventHandler<WebSocketConnectEventArgs> WebSocketConnected;
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; }
private readonly IServerConfigurationManager _config;
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,
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();
}
}
/// <summary>

View File

@ -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;
/// <summary>
/// Initializes a new instance of the <see cref="ApplicationHost" /> 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<string> HttpServerIpAddresses
public List<IPAddress> 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<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
{
get