Sfoglia il codice sorgente

update local address detection

Luke Pulverenti 9 anni fa
parent
commit
b46ef16ba8

+ 11 - 0
MediaBrowser.Api/System/SystemService.cs

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

+ 2 - 2
MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs

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

+ 3 - 1
MediaBrowser.Controller/IServerApplicationHost.cs

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

+ 0 - 6
MediaBrowser.Controller/Net/IHttpServer.cs

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

+ 25 - 19
MediaBrowser.Dlna/Main/DlnaEntryPoint.cs

@@ -43,19 +43,19 @@ namespace MediaBrowser.Dlna.Main
         private readonly List<string> _registeredServerIds = new List<string>();
         private readonly List<string> _registeredServerIds = new List<string>();
         private bool _dlnaServerStarted;
         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)
             ISsdpHandler ssdpHandler, IDeviceDiscovery deviceDiscovery)
         {
         {
             _config = config;
             _config = config;
@@ -148,14 +148,20 @@ 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 ();
-				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 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>
                 var services = new List<string>
                 {
                 {
@@ -166,8 +172,8 @@ namespace MediaBrowser.Dlna.Main
                     "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1",
                     "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1",
                     "uuid:" + guid.ToString("N")
                     "uuid:" + guid.ToString("N")
                 };
                 };
-                
-				_ssdpHandler.RegisterNotification(guid, uri, address, services);
+
+                _ssdpHandler.RegisterNotification(guid, uri, address, services);
 
 
                 _registeredServerIds.Add(guid.ToString("N"));
                 _registeredServerIds.Add(guid.ToString("N"));
             }
             }

+ 5 - 2
MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs

@@ -110,8 +110,11 @@ namespace MediaBrowser.Dlna.Ssdp
             {
             {
                 if (e.LocalEndPoint == null)
                 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)
                 if (e.LocalEndPoint != null)

+ 0 - 38
MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs

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

+ 49 - 23
MediaBrowser.Server.Startup.Common/ApplicationHost.cs

@@ -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
             get
             {
             {
-                return HttpServerIpAddresses.FirstOrDefault();
+                var localAddresses = NetworkManager.GetLocalIpAddresses()
+                    .Where(IsIpAddressValid)
+                    .ToList();
+
+                return localAddresses;
             }
             }
         }
         }
 
 
-        private IEnumerable<string> HttpServerIpAddresses
+        private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
+        private bool IsIpAddressValid(IPAddress address)
         {
         {
-            get
+            if (IPAddress.IsLoopback(address))
             {
             {
-                var localAddresses = NetworkManager.GetLocalIpAddresses()
-					.Select(i => i.ToString())
-                    .ToList();
+                return true;
+            }
 
 
-                var httpServerAddresses = HttpServer.LocalEndPoints
-                    .Select(i => i.Split(':').FirstOrDefault())
-                    .Where(i => !string.IsNullOrEmpty(i))
-                    .ToList();
+            var apiUrl = GetLocalApiUrl(address.ToString());
+            apiUrl += "/system/ping";
 
 
-                // 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();
+            bool cachedResult;
+            if (_validAddressResults.TryGetValue(apiUrl, out cachedResult))
+            {
+                return cachedResult;
+            }
 
 
-                if (matchedAddresses.Count == 0)
+            try
+            {
+                using (var response = HttpClient.SendAsync(new HttpRequestOptions
                 {
                 {
-                    return localAddresses;
-                }
+                    Url = apiUrl,
+                    BufferContent = false,
+                    LogErrorResponseBody = false,
+                    LogErrors = false
 
 
-                return matchedAddresses;
+                }, "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