add udp error handling

This commit is contained in:
Luke Pulverenti 2016-11-04 19:57:21 -04:00
parent 67ad1db6b7
commit 25312d7d03
6 changed files with 85 additions and 95 deletions

View file

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

View file

@ -206,7 +206,11 @@ namespace Emby.Common.Implementations.Networking
try
{
interfaces = NetworkInterface.GetAllNetworkInterfaces();
var validStatuses = new[] { OperationalStatus.Up, OperationalStatus.Unknown };
interfaces = NetworkInterface.GetAllNetworkInterfaces()
.Where(i => validStatuses.Contains(i.OperationalStatus))
.ToArray();
}
catch (Exception ex)
{
@ -214,7 +218,8 @@ namespace Emby.Common.Implementations.Networking
return new List<IPAddress>();
}
return interfaces.SelectMany(network => {
return interfaces.SelectMany(network =>
{
try
{

View file

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

View file

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

View file

@ -124,12 +124,20 @@ 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;
}
Guid feat;
if (Guid.TryParse(line, out feat))
{
SetUpdateRecord(feat, new DateTime(Convert.ToInt64(contents[i + 1])));
}
}
}
}
public void Save()
{

View file

@ -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);
return _SendSocket.SendAsync(messageData, messageData.Length, destination);
}
else
{
ThrowIfDisposed();
}
}
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);
}
return Task.FromResult(true);
}
private IUdpSocket ListenForBroadcastsAsync()