소스 검색

Updating to NetCollection 1.03

Jim Cartlidge 4 년 전
부모
커밋
bbe2400b59

+ 1 - 2
Jellyfin.Networking/Jellyfin.Networking.csproj

@@ -28,8 +28,7 @@
     <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.7" />
     <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.7" />
     <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="3.1.7" />
-    <PackageReference Include="Mono.Nat" Version="3.0.0" />
-    <PackageReference Include="NetworkCollection" Version="1.0.1" />
+    <PackageReference Include="NetworkCollection" Version="1.0.3" />
   </ItemGroup>
 
   <ItemGroup>

+ 98 - 52
Jellyfin.Networking/Manager/NetworkManager.cs

@@ -12,6 +12,7 @@ using MediaBrowser.Model.Configuration;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.Logging;
 using NetworkCollection;
+using NetworkCollection.Udp;
 
 namespace Jellyfin.Networking.Manager
 {
@@ -125,29 +126,19 @@ namespace Jellyfin.Networking.Manager
         public event EventHandler? NetworkChanged;
 
         /// <summary>
-        /// Gets the unique network location signature, which is updated on every network change.
+        /// Gets or sets a value indicating whether testing is taking place.
         /// </summary>
-        public static string NetworkLocationSignature { get; internal set; } = Guid.NewGuid().ToString();
+        public static string MockNetworkSettings { get; set; } = string.Empty;
 
         /// <summary>
-        /// Gets a value indicating whether IP6 is enabled.
+        /// Gets or sets a value indicating whether IP6 is enabled.
         /// </summary>
-        public static bool IsIP6Enabled { get; internal set; }
+        public bool IsIP6Enabled { get; set; }
 
         /// <summary>
-        /// Gets a value indicating whether IP4 is enabled.
+        /// Gets or sets a value indicating whether IP4 is enabled.
         /// </summary>
-        public static bool IsIP4Enabled { get; internal set; } = true;
-
-        /// <summary>
-        /// Gets a value indicating whether is multi-socket binding available.
-        /// </summary>
-        public static bool EnableMultiSocketBinding { get; internal set; } = true;
-
-        /// <summary>
-        /// Gets the number of times the network address has changed.
-        /// </summary>
-        public static int NetworkChangeCount { get; internal set; } = 1;
+        public bool IsIP4Enabled { get; set; }
 
         /// <inheritdoc/>
         public NetCollection RemoteAddressFilter { get; private set; }
@@ -271,7 +262,7 @@ namespace Jellyfin.Networking.Manager
         }
 
         /// <inheritdoc/>
-        public NetCollection GetAllBindInterfaces()
+        public NetCollection GetAllBindInterfaces(bool individualInterfaces = false)
         {
             lock (_intLock)
             {
@@ -285,6 +276,11 @@ namespace Jellyfin.Networking.Manager
                         return _interfaceAddresses.Exclude(_bindExclusions);
                     }
 
+                    if (individualInterfaces)
+                    {
+                        return new NetCollection(_interfaceAddresses);
+                    }
+
                     // No bind address and no exclusions, so listen on all interfaces.
                     NetCollection result = new NetCollection();
 
@@ -311,12 +307,6 @@ namespace Jellyfin.Networking.Manager
         {
             if (!string.IsNullOrEmpty(source))
             {
-                if (string.Equals(source, "chromecast", StringComparison.OrdinalIgnoreCase))
-                {
-                    // Just assign a variable so has source = true;
-                    return GetBindInterface(IPNetAddress.IP4Loopback, out port);
-                }
-
                 if (IPHost.TryParse(source, out IPHost host))
                 {
                     return GetBindInterface(host, out port);
@@ -572,16 +562,18 @@ namespace Jellyfin.Networking.Manager
         }
 
         /// <inheritdoc/>
-        public bool TryParseInterface(string token, out IPNetAddress result)
+        public bool TryParseInterface(string token, out NetCollection? result)
         {
+            result = null;
             if (string.IsNullOrEmpty(token))
             {
-                result = IPNetAddress.None;
                 return false;
             }
 
             if (_interfaceNames != null && _interfaceNames.TryGetValue(token.ToLower(CultureInfo.InvariantCulture), out int index))
             {
+                result = new NetCollection();
+
                 _logger.LogInformation("Interface {0} used in settings. Using its interface addresses.", token);
 
                 // Replace interface tags with the interface IP's.
@@ -591,13 +583,14 @@ namespace Jellyfin.Networking.Manager
                         ((IsIP4Enabled && iface.Address.AddressFamily == AddressFamily.InterNetwork) ||
                          (IsIP6Enabled && iface.Address.AddressFamily == AddressFamily.InterNetworkV6)))
                     {
-                        result = iface;
-                        return true;
+                        result.Add(iface);
                     }
                 }
+
+                return true;
             }
 
-            return IPNetAddress.TryParse(token, out result);
+            return false;
         }
 
         /// <summary>
@@ -614,9 +607,27 @@ namespace Jellyfin.Networking.Manager
             IsIP4Enabled = Socket.OSSupportsIPv6 && config.EnableIPV4;
             IsIP6Enabled = Socket.OSSupportsIPv6 && config.EnableIPV6;
             TrustAllIP6Interfaces = config.TrustAllIP6Interfaces;
-            EnableMultiSocketBinding = config.EnableMultiSocketBinding;
+            UdpHelper.EnableMultiSocketBinding = config.EnableMultiSocketBinding;
+
+            if (string.IsNullOrEmpty(MockNetworkSettings))
+            {
+                InitialiseInterfaces();
+            }
+            else // Used in testing only.
+            {
+                // Format is <IPAddress>,<Index>,<Name>: <next interface>. Set index to -ve to simulate a gateway.
+                var interfaceList = MockNetworkSettings.Split(':');
+                foreach (var details in interfaceList)
+                {
+                    var parts = details.Split(',');
+                    var address = IPNetAddress.Parse(parts[0]);
+                    var index = int.Parse(parts[1], CultureInfo.InvariantCulture);
+                    address.Tag = index;
+                    _interfaceAddresses.Add(address);
+                    _interfaceNames.Add(parts[2], Math.Abs(index));
+                }
+            }
 
-            InitialiseInterfaces();
             InitialiseLAN(config);
             InitialiseBind(config);
             InitialiseRemote(config);
@@ -671,6 +682,40 @@ namespace Jellyfin.Networking.Manager
             return str;
         }
 
+        /// <summary>
+        /// Checks the string to see if it matches any interface names.
+        /// </summary>
+        /// <param name="token">String to check.</param>
+        /// <param name="index">Interface index number.</param>
+        /// <returns>True if an interface name matches the token.</returns>
+        private bool IsInterface(string token, out int index)
+        {
+            index = -1;
+
+            // Is it the name of an interface (windows) eg, Wireless LAN adapter Wireless Network Connection 1.
+            // Null check required here for automated testing.
+            if (_interfaceNames != null && token.Length > 1)
+            {
+                bool partial = token[^1] == '*';
+                if (partial)
+                {
+                    token = token[0..^1];
+                }
+
+                foreach ((string interfc, int interfcIndex) in _interfaceNames)
+                {
+                    if ((!partial && string.Equals(interfc, token, StringComparison.OrdinalIgnoreCase)) ||
+                       (partial && interfc.StartsWith(token, true, CultureInfo.InvariantCulture)))
+                    {
+                        index = interfcIndex;
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
         /// <summary>
         /// Parses strings into the collection, replacing any interface references.
         /// </summary>
@@ -680,7 +725,7 @@ namespace Jellyfin.Networking.Manager
         {
             // Is it the name of an interface (windows) eg, Wireless LAN adapter Wireless Network Connection 1.
             // Null check required here for automated testing.
-            if (_interfaceNames != null && _interfaceNames.TryGetValue(token.ToLower(CultureInfo.InvariantCulture), out int index))
+            if (IsInterface(token, out int index))
             {
                 _logger.LogInformation("Interface {0} used in settings. Using its interface addresses.", token);
 
@@ -774,14 +819,6 @@ namespace Jellyfin.Networking.Manager
         /// </summary>
         private void OnNetworkChanged()
         {
-            // As per UPnP Device Architecture v1.0 Annex A - IPv6 Support.
-            NetworkLocationSignature = Guid.NewGuid().ToString();
-            NetworkChangeCount++;
-            if (NetworkChangeCount > 99)
-            {
-                NetworkChangeCount = 1;
-            }
-
             if (!_eventfire)
             {
                 _logger.LogDebug("Network Address Change Event.");
@@ -800,20 +837,14 @@ namespace Jellyfin.Networking.Manager
         /// </summary>
         private void InitialiseOverrides(ServerConfiguration config)
         {
-            string[] overrides = config.PublishedServerUriBySubnet;
-            if (overrides == null)
-            {
-                lock (_intLock)
-                {
-                    _publishedServerUrls.Clear();
-                }
-
-                return;
-            }
-
             lock (_intLock)
             {
                 _publishedServerUrls.Clear();
+                string[] overrides = config.PublishedServerUriBySubnet;
+                if (overrides == null)
+                {
+                    return;
+                }
 
                 foreach (var entry in overrides)
                 {
@@ -833,9 +864,16 @@ namespace Jellyfin.Networking.Manager
                         {
                             _publishedServerUrls[new IPNetAddress(IPAddress.Any)] = replacement;
                         }
-                        else if (TryParseInterface(parts[0], out IPNetAddress address))
+                        else if (TryParseInterface(parts[0], out NetCollection? addresses) && addresses != null)
+                        {
+                            foreach (IPNetAddress na in addresses)
+                            {
+                                _publishedServerUrls[na] = replacement;
+                            }
+                        }
+                        else if (IPNetAddress.TryParse(parts[0], out IPNetAddress result))
                         {
-                            _publishedServerUrls[address] = replacement;
+                            _publishedServerUrls[result] = replacement;
                         }
                         else
                         {
@@ -859,6 +897,14 @@ namespace Jellyfin.Networking.Manager
 
             // TODO: end fix.
 
+            // Add virtual machine interface names to the list of bind exclusions, so that they are auto-excluded.
+            if (config.IgnoreVirtualInterfaces)
+            {
+                var newList = ba.ToList();
+                newList.AddRange(config.VirtualInterfaceNames.Split(',').ToList());
+                ba = newList.ToArray();
+            }
+
             // Read and parse bind addresses and exclusions, removing ones that don't exist.
             _bindAddresses = CreateIPCollection(ba).Union(_interfaceAddresses);
             _bindExclusions = CreateIPCollection(ba, true).Union(_interfaceAddresses);

+ 14 - 3
MediaBrowser.Common/Net/INetworkManager.cs

@@ -34,13 +34,24 @@ namespace MediaBrowser.Common.Net
         /// </summary>
         NetCollection RemoteAddressFilter { get; }
 
+        /// <summary>
+        /// Gets or sets a value indicating whether iP6 is enabled.
+        /// </summary>
+        public bool IsIP6Enabled { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether iP4 is enabled.
+        /// </summary>
+        public bool IsIP4Enabled { get; set; }
+
         /// <summary>
         /// Calculates the list of interfaces to use for Kestrel.
         /// </summary>
         /// <returns>A NetCollection object containing all the interfaces to bind.
         /// If all the interfaces are specified, and none are excluded, it returns zero items
         /// to represent any address.</returns>
-        NetCollection GetAllBindInterfaces();
+        /// <param name="individualInterfaces">When false, return <see cref="IPAddress.Any"/> or <see cref="IPAddress.IPv6Any"/> for all interfaces.</param>
+        NetCollection GetAllBindInterfaces(bool individualInterfaces = false);
 
         /// <summary>
         /// Returns a collection containing the loopback interfaces.
@@ -166,9 +177,9 @@ namespace MediaBrowser.Common.Net
         /// eg. "eth1", or "TP-LINK Wireless USB Adapter".
         /// </summary>
         /// <param name="token">Token to parse.</param>
-        /// <param name="result">Resultant object if successful.</param>
+        /// <param name="result">Resultant object's ip addresses, if successful.</param>
         /// <returns>Success of the operation.</returns>
-        bool TryParseInterface(string token, out IPNetAddress result);
+        bool TryParseInterface(string token, out NetCollection? result);
 
         /// <summary>
         /// Parses an array of strings into a NetCollection.

+ 15 - 8
MediaBrowser.Model/Configuration/ServerConfiguration.cs

@@ -1,4 +1,4 @@
-#nullable disable
+#nullable enable
 #pragma warning disable CS1591
 #pragma warning disable CA1819
 
@@ -111,7 +111,7 @@ namespace MediaBrowser.Model.Configuration
 
         /// <summary>
         /// Gets or sets a value indicating whether detailed ssdp logs are sent to the console/log.
-        /// If the setting "Emby.Dlna": "Debug" msut be set in logging.default.json for this property to work.
+        /// "Emby.Dlna": "Debug" must be set in logging.default.json for this property to work.
         /// </summary>
         public bool EnableSSDPTracing { get; set; } = false;
 
@@ -131,13 +131,23 @@ namespace MediaBrowser.Model.Configuration
         /// </summary>
         public int UDPSendDelay { get; set; } = 100;
 
+        /// <summary>
+        /// Gets or sets a value indicating whether address names that match <see cref="VirtualInterfaceNames"/> should be Ignore for the purposes of binding.
+        /// </summary>
+        public bool IgnoreVirtualInterfaces { get; set; } = true;
+
+        /// <summary>
+        /// Gets or sets a value indicating the interfaces that should be ignored. The list can be comma separated. <seealso cref="IgnoreVirtualInterfaces"/>.
+        /// </summary>
+        public string VirtualInterfaceNames { get; set; } = "vEthernet*";
+
         /// <summary>
         /// Gets or sets the time (in seconds) between the pings of SSDP gateway monitor.
         /// </summary>
         public int GatewayMonitorPeriod { get; set; } = 60;
 
         /// <summary>
-        /// Gets a value indicating whether is multi-socket binding available.
+        /// Gets a value indicating whether multi-socket binding is available.
         /// </summary>
         public bool EnableMultiSocketBinding { get; } = true;
 
@@ -158,7 +168,7 @@ namespace MediaBrowser.Model.Configuration
         public string[] PublishedServerUriBySubnet { get; set; } = Array.Empty<string>();
 
         /// <summary>
-        /// Gets or sets a value indicating whether gets or sets Autodiscovery tracing.
+        /// Gets or sets a value indicating whether Autodiscovery tracing is enabled.
         /// </summary>
         public bool AutoDiscoveryTracing { get; set; } = false;
 
@@ -216,9 +226,7 @@ namespace MediaBrowser.Model.Configuration
         /// Gets or sets a value indicating whether quick connect is available for use on this server.
         /// </summary>
         public bool QuickConnectAvailable { get; set; } = false;
-
-        public bool AutoRunWebApp { get; set; } = true;
-
+       
         /// <summary>
         /// Gets or sets a value indicating whether access outside of the LAN is permitted.
         /// </summary>
@@ -419,6 +427,5 @@ namespace MediaBrowser.Model.Configuration
         /// Gets or sets the known proxies.
         /// </summary>
         public string[] KnownProxies { get; set; } = Array.Empty<string>();
-
     }
 }