Ver Fonte

add udp error handling

Luke Pulverenti há 8 anos atrás
pai
commit
25312d7d03

+ 2 - 21
Emby.Common.Implementations/Net/UdpSocket.cs

@@ -102,29 +102,10 @@ namespace Emby.Common.Implementations.Net
                     {
                         taskSource.TrySetException(ex);
                     }
-                    catch (ObjectDisposedException ex)
-                    {
-                        taskSource.TrySetException(ex);
-                    }
-                    catch (InvalidOperationException ex)
-                    {
-                        taskSource.TrySetException(ex);
-                    }
-                    catch (SecurityException ex)
-                    {
-                        taskSource.TrySetException(ex);
-                    }
+
                 }, null);
             }
-            catch (SocketException ex)
-            {
-                taskSource.TrySetException(ex);
-            }
-            catch (ObjectDisposedException ex)
-            {
-                taskSource.TrySetException(ex);
-            }
-            catch (SecurityException ex)
+            catch (Exception ex)
             {
                 taskSource.TrySetException(ex);
             }

+ 45 - 40
Emby.Common.Implementations/Networking/BaseNetworkManager.cs

@@ -22,7 +22,7 @@ namespace Emby.Common.Implementations.Networking
             Logger = logger;
         }
 
-		private List<IPAddress> _localIpAddresses;
+        private List<IPAddress> _localIpAddresses;
         private readonly object _localIpAddressSyncLock = new object();
 
         /// <summary>
@@ -51,24 +51,24 @@ namespace Emby.Common.Implementations.Networking
             return _localIpAddresses;
         }
 
-		private IEnumerable<IPAddress> GetLocalIpAddressesInternal()
+        private IEnumerable<IPAddress> GetLocalIpAddressesInternal()
         {
             var list = GetIPsDefault()
                 .ToList();
 
             if (list.Count == 0)
             {
-				list.AddRange(GetLocalIpAddressesFallback().Result);
+                list.AddRange(GetLocalIpAddressesFallback().Result);
             }
 
-			return list.Where(FilterIpAddress).DistinctBy(i => i.ToString());
+            return list.Where(FilterIpAddress).DistinctBy(i => i.ToString());
         }
 
-		private bool FilterIpAddress(IPAddress address)
+        private bool FilterIpAddress(IPAddress address)
         {
-			var addressString = address.ToString ();
+            var addressString = address.ToString();
 
-			if (addressString.StartsWith("169.", StringComparison.OrdinalIgnoreCase))
+            if (addressString.StartsWith("169.", StringComparison.OrdinalIgnoreCase))
             {
                 return false;
             }
@@ -156,12 +156,12 @@ namespace Emby.Common.Implementations.Networking
                 {
                     var prefix = addressString.Substring(0, lengthMatch);
 
-					if (GetLocalIpAddresses().Any(i => i.ToString().StartsWith(prefix, StringComparison.OrdinalIgnoreCase)))
+                    if (GetLocalIpAddresses().Any(i => i.ToString().StartsWith(prefix, StringComparison.OrdinalIgnoreCase)))
                     {
                         return true;
                     }
                 }
-            } 
+            }
             else if (resolveHost)
             {
                 Uri uri;
@@ -200,45 +200,50 @@ namespace Emby.Common.Implementations.Networking
             return Dns.GetHostAddressesAsync(hostName);
         }
 
-		private List<IPAddress> GetIPsDefault()
-		{
-			NetworkInterface[] interfaces;
+        private List<IPAddress> GetIPsDefault()
+        {
+            NetworkInterface[] interfaces;
 
-			try
-			{
-				interfaces = NetworkInterface.GetAllNetworkInterfaces();
-			}
-			catch (Exception ex)
-			{
-				Logger.ErrorException("Error in GetAllNetworkInterfaces", ex);
-				return new List<IPAddress>();
-			}
+            try
+            {
+                var validStatuses = new[] { OperationalStatus.Up, OperationalStatus.Unknown };
 
-			return interfaces.SelectMany(network => {
+                interfaces = NetworkInterface.GetAllNetworkInterfaces()
+                    .Where(i => validStatuses.Contains(i.OperationalStatus))
+                    .ToArray();
+            }
+            catch (Exception ex)
+            {
+                Logger.ErrorException("Error in GetAllNetworkInterfaces", ex);
+                return new List<IPAddress>();
+            }
+
+            return interfaces.SelectMany(network =>
+            {
 
-				try
-				{
+                try
+                {
                     Logger.Debug("Querying interface: {0}. Type: {1}. Status: {2}", network.Name, network.NetworkInterfaceType, network.OperationalStatus);
 
-					var properties = network.GetIPProperties();
+                    var properties = network.GetIPProperties();
 
-					return properties.UnicastAddresses
+                    return properties.UnicastAddresses
                         .Where(i => i.IsDnsEligible)
                         .Select(i => i.Address)
                         .Where(i => i.AddressFamily == AddressFamily.InterNetwork)
-						.ToList();
-				}
-				catch (Exception ex)
-				{
-					Logger.ErrorException("Error querying network interface", ex);
-					return new List<IPAddress>();
-				}
-
-			}).DistinctBy(i => i.ToString())
-				.ToList();
-		}
-
-		private async Task<IEnumerable<IPAddress>> GetLocalIpAddressesFallback()
+                        .ToList();
+                }
+                catch (Exception ex)
+                {
+                    Logger.ErrorException("Error querying network interface", ex);
+                    return new List<IPAddress>();
+                }
+
+            }).DistinctBy(i => i.ToString())
+                .ToList();
+        }
+
+        private async Task<IEnumerable<IPAddress>> GetLocalIpAddressesFallback()
         {
             var host = await Dns.GetHostEntryAsync(Dns.GetHostName()).ConfigureAwait(false);
 
@@ -310,7 +315,7 @@ namespace Emby.Common.Implementations.Networking
             string[] values = endpointstring.Split(new char[] { ':' });
             IPAddress ipaddy;
             int port = -1;
-          
+
             //check if we have an IPv6 or ports
             if (values.Length <= 2) // ipv4 or hostname
             {

+ 8 - 3
Emby.Dlna/Main/DlnaEntryPoint.cs

@@ -240,6 +240,8 @@ namespace Emby.Dlna.Main
 
             var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList();
 
+            var udn = CreateUuid(_appHost.SystemId);
+
             foreach (var address in addresses)
             {
                 //if (IPAddress.IsLoopback(address))
@@ -250,8 +252,6 @@ namespace Emby.Dlna.Main
 
                 var addressString = address.ToString();
 
-                var udn = CreateUuid(addressString);
-
                 var fullService = "urn:schemas-upnp-org:device:MediaServer:1";
 
                 _logger.Info("Registering publisher for {0} on {1}", fullService, addressString);
@@ -299,7 +299,12 @@ namespace Emby.Dlna.Main
 
         private string CreateUuid(string text)
         {
-            return text.GetMD5().ToString("N");
+            Guid guid;
+            if (!Guid.TryParse(text, out guid))
+            {
+                guid = text.GetMD5();
+            }
+            return guid.ToString("N");
         }
 
         private void SetProperies(SsdpDevice device, string fullDeviceType)

+ 1 - 1
Emby.Dlna/Service/BaseControlHandler.cs

@@ -228,7 +228,7 @@ namespace Emby.Dlna.Service
             var headers = string.Join(", ", request.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
             builder.AppendFormat("Headers: {0}", headers);
             builder.AppendLine();
-            builder.Append(request.InputXml);
+            //builder.Append(request.InputXml);
 
             Logger.LogMultiline("Control request", LogSeverity.Debug, builder);
         }

+ 10 - 2
Emby.Server.Implementations/Security/MBLicenseFile.cs

@@ -124,9 +124,17 @@ namespace Emby.Server.Implementations.Security
                 //the rest of the lines should be pairs of features and timestamps
                 for (var i = 2; i < contents.Length; i = i + 2)
                 {
-                    var feat = Guid.Parse(contents[i]);
+                    var line = contents[i];
+                    if (string.IsNullOrWhiteSpace(line))
+                    {
+                        continue;
+                    }
 
-                    SetUpdateRecord(feat, new DateTime(Convert.ToInt64(contents[i + 1])));
+                    Guid feat;
+                    if (Guid.TryParse(line, out feat))
+                    {
+                        SetUpdateRecord(feat, new DateTime(Convert.ToInt64(contents[i + 1])));
+                    }
                 }
             }
         }

+ 21 - 30
RSSDP/SsdpCommunicationsServer.cs

@@ -78,17 +78,6 @@ namespace Rssdp.Infrastructure
         {
         }
 
-        /// <summary>
-        /// Partial constructor.
-        /// </summary>
-        /// <param name="socketFactory">An implementation of the <see cref="ISocketFactory"/> interface that can be used to make new unicast and multicast sockets. Cannot be null.</param>
-        /// <param name="localPort">The specific local port to use for all sockets created by this instance. Specify zero to indicate the system should choose a free port itself.</param>
-        /// <exception cref="System.ArgumentNullException">The <paramref name="socketFactory"/> argument is null.</exception>
-        public SsdpCommunicationsServer(ISocketFactory socketFactory, int localPort)
-            : this(socketFactory, localPort, SsdpConstants.SsdpDefaultMulticastTimeToLive)
-        {
-        }
-
         /// <summary>
         /// Full constructor.
         /// </summary>
@@ -170,7 +159,12 @@ namespace Rssdp.Infrastructure
             EnsureSendSocketCreated();
 
             // SSDP spec recommends sending messages multiple times (not more than 3) to account for possible packet loss over UDP.
-            await Repeat(SsdpConstants.UdpResendCount, TimeSpan.FromMilliseconds(100), () => SendMessageIfSocketNotDisposed(messageData, destination)).ConfigureAwait(false);
+            for (var i = 0; i < SsdpConstants.UdpResendCount; i++)
+            {
+                await SendMessageIfSocketNotDisposed(messageData, destination).ConfigureAwait(false);
+
+                await Task.Delay(100).ConfigureAwait(false);
+            }
         }
 
         /// <summary>
@@ -188,8 +182,17 @@ namespace Rssdp.Infrastructure
             EnsureSendSocketCreated();
 
             // SSDP spec recommends sending messages multiple times (not more than 3) to account for possible packet loss over UDP.
-            await Repeat(SsdpConstants.UdpResendCount, TimeSpan.FromMilliseconds(100),
-                () => SendMessageIfSocketNotDisposed(messageData, new IpEndPointInfo() { IpAddress = new IpAddressInfo { Address = SsdpConstants.MulticastLocalAdminAddress }, Port = SsdpConstants.MulticastPort })).ConfigureAwait(false);
+            for (var i = 0; i < SsdpConstants.UdpResendCount; i++)
+            {
+                await SendMessageIfSocketNotDisposed(messageData, new IpEndPointInfo
+                {
+                    IpAddress = new IpAddressInfo { Address = SsdpConstants.MulticastLocalAdminAddress },
+                    Port = SsdpConstants.MulticastPort
+
+                }).ConfigureAwait(false);
+
+                await Task.Delay(100).ConfigureAwait(false);
+            }
         }
 
         /// <summary>
@@ -255,28 +258,16 @@ namespace Rssdp.Infrastructure
 
         #region Private Methods
 
-        private async Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination)
+        private Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination)
         {
             var socket = _SendSocket;
             if (socket != null)
             {
-                await _SendSocket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false);
-            }
-            else
-            {
-                ThrowIfDisposed();
+                return _SendSocket.SendAsync(messageData, messageData.Length, destination);
             }
-        }
-
-        private static async Task Repeat(int repetitions, TimeSpan delay, Func<Task> work)
-        {
-            for (int cnt = 0; cnt < repetitions; cnt++)
-            {
-                await work().ConfigureAwait(false);
 
-                if (delay != TimeSpan.Zero)
-                    await Task.Delay(delay).ConfigureAwait(false);
-            }
+            ThrowIfDisposed();
+            return Task.FromResult(true);
         }
 
         private IUdpSocket ListenForBroadcastsAsync()