diff --git a/Emby.Common.Implementations/Net/SocketFactory.cs b/Emby.Common.Implementations/Net/SocketFactory.cs
index 3a2cea12a7..6f0ff29961 100644
--- a/Emby.Common.Implementations/Net/SocketFactory.cs
+++ b/Emby.Common.Implementations/Net/SocketFactory.cs
@@ -37,22 +37,46 @@ namespace Emby.Common.Implementations.Net
#region ISocketFactory Members
///
- /// Creates a new UDP socket that is a member of the SSDP multicast local admin group and binds it to the specified local port.
+ /// Creates a new UDP socket and binds it to the specified local port.
///
/// An integer specifying the local port to bind the socket to.
- /// An implementation of the interface used by RSSDP components to perform socket operations.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The purpose of this method is to create and returns a disposable result, it is up to the caller to dispose it when they are done with it.")]
public IUdpSocket CreateUdpSocket(int localPort)
{
if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort");
+ var retVal = new Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp);
+ try
+ {
+ retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+ return new UdpSocket(retVal, localPort, _LocalIP);
+ }
+ catch
+ {
+ if (retVal != null)
+ retVal.Dispose();
+
+ throw;
+ }
+ }
+
+ ///
+ /// Creates a new UDP socket that is a member of the SSDP multicast local admin group and binds it to the specified local port.
+ ///
+ /// An integer specifying the local port to bind the socket to.
+ /// An implementation of the interface used by RSSDP components to perform socket operations.
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The purpose of this method is to create and returns a disposable result, it is up to the caller to dispose it when they are done with it.")]
+ public IUdpSocket CreateSsdpUdpSocket(int localPort)
+ {
+ if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort");
+
var retVal = new Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp);
try
{
retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4);
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), _LocalIP));
- return new UdpSocket(retVal, localPort, _LocalIP.ToString());
+ return new UdpSocket(retVal, localPort, _LocalIP);
}
catch
{
@@ -97,7 +121,7 @@ namespace Emby.Common.Implementations.Net
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), _LocalIP));
retVal.MulticastLoopback = true;
- return new UdpSocket(retVal, localPort, _LocalIP.ToString());
+ return new UdpSocket(retVal, localPort, _LocalIP);
}
catch
{
diff --git a/Emby.Common.Implementations/Net/UdpSocket.cs b/Emby.Common.Implementations/Net/UdpSocket.cs
index 86ce9c83be..997d3f25fa 100644
--- a/Emby.Common.Implementations/Net/UdpSocket.cs
+++ b/Emby.Common.Implementations/Net/UdpSocket.cs
@@ -24,19 +24,13 @@ namespace Emby.Common.Implementations.Net
#region Constructors
- public UdpSocket(System.Net.Sockets.Socket socket, int localPort, string ipAddress)
+ public UdpSocket(System.Net.Sockets.Socket socket, int localPort, IPAddress ip)
{
if (socket == null) throw new ArgumentNullException("socket");
_Socket = socket;
_LocalPort = localPort;
- IPAddress ip = null;
- if (String.IsNullOrEmpty(ipAddress))
- ip = IPAddress.Any;
- else
- ip = IPAddress.Parse(ipAddress);
-
_Socket.Bind(new IPEndPoint(ip, _LocalPort));
if (_LocalPort == 0)
_LocalPort = (_Socket.LocalEndPoint as IPEndPoint).Port;
@@ -46,11 +40,11 @@ namespace Emby.Common.Implementations.Net
#region IUdpSocket Members
- public Task ReceiveAsync()
+ public Task ReceiveAsync()
{
ThrowIfDisposed();
- var tcs = new TaskCompletionSource();
+ var tcs = new TaskCompletionSource();
System.Net.EndPoint receivedFromEndPoint = new IPEndPoint(IPAddress.Any, 0);
var state = new AsyncReceiveState(_Socket, receivedFromEndPoint);
@@ -74,22 +68,30 @@ namespace Emby.Common.Implementations.Net
return tcs.Task;
}
- public Task SendTo(byte[] messageData, IpEndPointInfo endPoint)
+ public Task SendAsync(byte[] buffer, int size, IpEndPointInfo endPoint)
{
ThrowIfDisposed();
- if (messageData == null) throw new ArgumentNullException("messageData");
+ if (buffer == null) throw new ArgumentNullException("messageData");
if (endPoint == null) throw new ArgumentNullException("endPoint");
#if NETSTANDARD1_6
- _Socket.SendTo(messageData, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port));
+
+ if (size != buffer.Length)
+ {
+ byte[] copy = new byte[size];
+ Buffer.BlockCopy(buffer, 0, copy, 0, size);
+ buffer = copy;
+ }
+
+ _Socket.SendTo(buffer, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port));
return Task.FromResult(true);
#else
var taskSource = new TaskCompletionSource();
try
{
- _Socket.BeginSendTo(messageData, 0, messageData.Length, SocketFlags.None, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port), result =>
+ _Socket.BeginSendTo(buffer, 0, size, SocketFlags.None, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port), result =>
{
try
{
@@ -160,11 +162,11 @@ namespace Emby.Common.Implementations.Net
var ipEndPoint = state.EndPoint as IPEndPoint;
state.TaskCompletionSource.SetResult(
- new ReceivedUdpData()
+ new SocketReceiveResult()
{
Buffer = state.Buffer,
ReceivedBytes = bytesRead,
- ReceivedFrom = ToIpEndPointInfo(ipEndPoint)
+ RemoteEndPoint = ToIpEndPointInfo(ipEndPoint)
}
);
}
@@ -215,11 +217,11 @@ namespace Emby.Common.Implementations.Net
var ipEndPoint = state.EndPoint as IPEndPoint;
state.TaskCompletionSource.SetResult(
- new ReceivedUdpData()
+ new SocketReceiveResult
{
Buffer = state.Buffer,
ReceivedBytes = bytesRead,
- ReceivedFrom = ToIpEndPointInfo(ipEndPoint)
+ RemoteEndPoint = ToIpEndPointInfo(ipEndPoint)
}
);
}
@@ -258,7 +260,7 @@ namespace Emby.Common.Implementations.Net
public System.Net.Sockets.Socket Socket { get; private set; }
- public TaskCompletionSource TaskCompletionSource { get; set; }
+ public TaskCompletionSource TaskCompletionSource { get; set; }
}
diff --git a/Emby.Common.Implementations/Networking/BaseNetworkManager.cs b/Emby.Common.Implementations/Networking/BaseNetworkManager.cs
index bab340e27d..d1c299dc96 100644
--- a/Emby.Common.Implementations/Networking/BaseNetworkManager.cs
+++ b/Emby.Common.Implementations/Networking/BaseNetworkManager.cs
@@ -8,6 +8,7 @@ using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading.Tasks;
using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.Net;
namespace Emby.Common.Implementations.Networking
{
@@ -382,5 +383,35 @@ namespace Emby.Common.Implementations.Networking
return hosts[0];
}
+
+ public IpAddressInfo ParseIpAddress(string ipAddress)
+ {
+ IpAddressInfo info;
+ if (TryParseIpAddress(ipAddress, out info))
+ {
+ return info;
+ }
+
+ throw new ArgumentException("Invalid ip address: " + ipAddress);
+ }
+
+ public bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo)
+ {
+ IPAddress address;
+ if (IPAddress.TryParse(ipAddress, out address))
+ {
+
+ ipAddressInfo = new IpAddressInfo
+ {
+ Address = address.ToString(),
+ IsIpv6 = address.AddressFamily == AddressFamily.InterNetworkV6
+ };
+
+ return true;
+ }
+
+ ipAddressInfo = null;
+ return false;
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectData.cs b/Emby.Server.Implementations/Connect/ConnectData.cs
similarity index 95%
rename from MediaBrowser.Server.Implementations/Connect/ConnectData.cs
rename to Emby.Server.Implementations/Connect/ConnectData.cs
index 5ec0bea22c..41b89ce52b 100644
--- a/MediaBrowser.Server.Implementations/Connect/ConnectData.cs
+++ b/Emby.Server.Implementations/Connect/ConnectData.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-namespace MediaBrowser.Server.Implementations.Connect
+namespace Emby.Server.Implementations.Connect
{
public class ConnectData
{
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/Emby.Server.Implementations/Connect/ConnectEntryPoint.cs
similarity index 88%
rename from MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs
rename to Emby.Server.Implementations/Connect/ConnectEntryPoint.cs
index 565eeb259b..d7574d466c 100644
--- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs
+++ b/Emby.Server.Implementations/Connect/ConnectEntryPoint.cs
@@ -7,16 +7,12 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
using System;
using System.IO;
-using System.Net;
-using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Threading;
-namespace MediaBrowser.Server.Implementations.Connect
+namespace Emby.Server.Implementations.Connect
{
public class ConnectEntryPoint : IServerEntryPoint
{
@@ -59,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.Connect
private async void TimerCallback(object state)
{
- IPAddress validIpAddress = null;
+ IpAddressInfo validIpAddress = null;
foreach (var ipLookupUrl in _ipLookups)
{
@@ -68,7 +64,7 @@ namespace MediaBrowser.Server.Implementations.Connect
validIpAddress = await GetIpAddress(ipLookupUrl).ConfigureAwait(false);
// Try to find the ipv4 address, if present
- if (validIpAddress.AddressFamily == AddressFamily.InterNetwork)
+ if (!validIpAddress.IsIpv6)
{
break;
}
@@ -83,7 +79,7 @@ namespace MediaBrowser.Server.Implementations.Connect
}
// If this produced an ipv6 address, try again
- if (validIpAddress != null && validIpAddress.AddressFamily == AddressFamily.InterNetworkV6)
+ if (validIpAddress != null && validIpAddress.IsIpv6)
{
foreach (var ipLookupUrl in _ipLookups)
{
@@ -92,7 +88,7 @@ namespace MediaBrowser.Server.Implementations.Connect
var newAddress = await GetIpAddress(ipLookupUrl, true).ConfigureAwait(false);
// Try to find the ipv4 address, if present
- if (newAddress.AddressFamily == AddressFamily.InterNetwork)
+ if (!newAddress.IsIpv6)
{
validIpAddress = newAddress;
break;
@@ -115,7 +111,7 @@ namespace MediaBrowser.Server.Implementations.Connect
}
}
- private async Task GetIpAddress(string lookupUrl, bool preferIpv4 = false)
+ private async Task GetIpAddress(string lookupUrl, bool preferIpv4 = false)
{
// Sometimes whatismyipaddress might fail, but it won't do us any good having users raise alarms over it.
var logErrors = false;
@@ -140,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.Connect
{
var addressString = await reader.ReadToEndAsync().ConfigureAwait(false);
- return IPAddress.Parse(addressString);
+ return _networkManager.ParseIpAddress(addressString);
}
}
}
@@ -150,7 +146,7 @@ namespace MediaBrowser.Server.Implementations.Connect
get { return Path.Combine(_appPaths.DataPath, "wan.txt"); }
}
- private void CacheAddress(IPAddress address)
+ private void CacheAddress(IpAddressInfo address)
{
var path = CacheFilePath;
@@ -174,9 +170,9 @@ namespace MediaBrowser.Server.Implementations.Connect
try
{
var endpoint = _fileSystem.ReadAllText(path, Encoding.UTF8);
- IPAddress ipAddress;
+ IpAddressInfo ipAddress;
- if (IPAddress.TryParse(endpoint, out ipAddress))
+ if (_networkManager.TryParseIpAddress(endpoint, out ipAddress))
{
((ConnectManager)_connectManager).OnWanAddressResolved(ipAddress);
}
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/Emby.Server.Implementations/Connect/ConnectManager.cs
similarity index 99%
rename from MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
rename to Emby.Server.Implementations/Connect/ConnectManager.cs
index 27bbfbe82d..6c2ac40c32 100644
--- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
+++ b/Emby.Server.Implementations/Connect/ConnectManager.cs
@@ -19,16 +19,13 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
-using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.IO;
using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.IO;
-namespace MediaBrowser.Server.Implementations.Connect
+namespace Emby.Server.Implementations.Connect
{
public class ConnectManager : IConnectManager
{
@@ -57,7 +54,7 @@ namespace MediaBrowser.Server.Implementations.Connect
get { return _data.AccessKey; }
}
- private IPAddress DiscoveredWanIpAddress { get; set; }
+ private IpAddressInfo DiscoveredWanIpAddress { get; set; }
public string WanIpAddress
{
@@ -77,7 +74,7 @@ namespace MediaBrowser.Server.Implementations.Connect
if (string.IsNullOrWhiteSpace(address) && DiscoveredWanIpAddress != null)
{
- if (DiscoveredWanIpAddress.AddressFamily == AddressFamily.InterNetworkV6)
+ if (DiscoveredWanIpAddress.IsIpv6)
{
address = "[" + DiscoveredWanIpAddress + "]";
}
@@ -148,7 +145,7 @@ namespace MediaBrowser.Server.Implementations.Connect
_config.ConfigurationUpdated += _config_ConfigurationUpdated;
}
- internal void OnWanAddressResolved(IPAddress address)
+ internal void OnWanAddressResolved(IpAddressInfo address)
{
DiscoveredWanIpAddress = address;
diff --git a/MediaBrowser.Server.Implementations/Connect/Responses.cs b/Emby.Server.Implementations/Connect/Responses.cs
similarity index 98%
rename from MediaBrowser.Server.Implementations/Connect/Responses.cs
rename to Emby.Server.Implementations/Connect/Responses.cs
index f865278294..87cb6cdf93 100644
--- a/MediaBrowser.Server.Implementations/Connect/Responses.cs
+++ b/Emby.Server.Implementations/Connect/Responses.cs
@@ -1,7 +1,7 @@
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Connect;
-namespace MediaBrowser.Server.Implementations.Connect
+namespace Emby.Server.Implementations.Connect
{
public class ServerRegistrationResponse
{
diff --git a/MediaBrowser.Server.Implementations/Connect/Validator.cs b/Emby.Server.Implementations/Connect/Validator.cs
similarity index 94%
rename from MediaBrowser.Server.Implementations/Connect/Validator.cs
rename to Emby.Server.Implementations/Connect/Validator.cs
index 8cdfc4a6b3..5c94fa71c7 100644
--- a/MediaBrowser.Server.Implementations/Connect/Validator.cs
+++ b/Emby.Server.Implementations/Connect/Validator.cs
@@ -1,6 +1,6 @@
using System.Text.RegularExpressions;
-namespace MediaBrowser.Server.Implementations.Connect
+namespace Emby.Server.Implementations.Connect
{
public static class Validator
{
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 4a27ddb745..8d13d206ac 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -43,6 +43,11 @@
+
+
+
+
+
@@ -51,6 +56,7 @@
+
@@ -68,6 +74,7 @@
+
@@ -159,6 +166,7 @@
+
@@ -217,6 +225,7 @@
+
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
similarity index 73%
rename from MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
rename to Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
index 1febcdd402..df5a7c985d 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
+++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
@@ -1,12 +1,12 @@
using System;
-using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
-using MediaBrowser.Server.Implementations.Udp;
+using Emby.Server.Implementations.Udp;
+using MediaBrowser.Model.Net;
-namespace MediaBrowser.Server.Implementations.EntryPoints
+namespace Emby.Server.Implementations.EntryPoints
{
///
/// Class UdpServerEntryPoint
@@ -23,10 +23,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
/// The _logger
///
private readonly ILogger _logger;
- ///
- /// The _network manager
- ///
- private readonly INetworkManager _networkManager;
+ private readonly ISocketFactory _socketFactory;
private readonly IServerApplicationHost _appHost;
private readonly IJsonSerializer _json;
@@ -35,16 +32,12 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
///
/// Initializes a new instance of the class.
///
- /// The logger.
- /// The network manager.
- /// The application host.
- /// The json.
- public UdpServerEntryPoint(ILogger logger, INetworkManager networkManager, IServerApplicationHost appHost, IJsonSerializer json)
+ public UdpServerEntryPoint(ILogger logger, IServerApplicationHost appHost, IJsonSerializer json, ISocketFactory socketFactory)
{
_logger = logger;
- _networkManager = networkManager;
_appHost = appHost;
_json = json;
+ _socketFactory = socketFactory;
}
///
@@ -52,7 +45,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
///
public void Run()
{
- var udpServer = new UdpServer(_logger, _networkManager, _appHost, _json);
+ var udpServer = new UdpServer(_logger, _appHost, _json, _socketFactory);
try
{
diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/Emby.Server.Implementations/IO/FileRefresher.cs
similarity index 97%
rename from MediaBrowser.Server.Implementations/IO/FileRefresher.cs
rename to Emby.Server.Implementations/IO/FileRefresher.cs
index 2742e1a268..295ecc4651 100644
--- a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
+++ b/Emby.Server.Implementations/IO/FileRefresher.cs
@@ -16,7 +16,7 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Threading;
-namespace MediaBrowser.Server.Implementations.IO
+namespace Emby.Server.Implementations.IO
{
public class FileRefresher : IDisposable
{
@@ -226,11 +226,11 @@ namespace MediaBrowser.Server.Implementations.IO
private bool IsFileLocked(string path)
{
- if (Environment.OSVersion.Platform != PlatformID.Win32NT)
- {
- // Causing lockups on linux
- return false;
- }
+ //if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+ //{
+ // // Causing lockups on linux
+ // return false;
+ //}
try
{
diff --git a/MediaBrowser.Server.Implementations/Security/EncryptionManager.cs b/Emby.Server.Implementations/Security/EncryptionManager.cs
similarity index 93%
rename from MediaBrowser.Server.Implementations/Security/EncryptionManager.cs
rename to Emby.Server.Implementations/Security/EncryptionManager.cs
index cd9b9651ec..271b0bbdb5 100644
--- a/MediaBrowser.Server.Implementations/Security/EncryptionManager.cs
+++ b/Emby.Server.Implementations/Security/EncryptionManager.cs
@@ -2,7 +2,7 @@
using System;
using System.Text;
-namespace MediaBrowser.Server.Implementations.Security
+namespace Emby.Server.Implementations.Security
{
public class EncryptionManager : IEncryptionManager
{
@@ -45,7 +45,7 @@ namespace MediaBrowser.Server.Implementations.Security
// Yes, this isn't good, but ProtectedData in mono is throwing exceptions, so use this for now
var bytes = Convert.FromBase64String(value);
- return Encoding.UTF8.GetString(bytes);
+ return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs b/Emby.Server.Implementations/Udp/UdpServer.cs
similarity index 53%
rename from MediaBrowser.Server.Implementations/Udp/UdpServer.cs
rename to Emby.Server.Implementations/Udp/UdpServer.cs
index c2082f0d2a..c15e0ee41b 100644
--- a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs
+++ b/Emby.Server.Implementations/Udp/UdpServer.cs
@@ -1,18 +1,16 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller;
+using MediaBrowser.Controller;
using MediaBrowser.Model.ApiClient;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Net;
-using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
-using Emby.Common.Implementations.Networking;
+using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Net;
-namespace MediaBrowser.Server.Implementations.Udp
+namespace Emby.Server.Implementations.Udp
{
///
/// Provides a Udp Server
@@ -24,14 +22,9 @@ namespace MediaBrowser.Server.Implementations.Udp
///
private readonly ILogger _logger;
- ///
- /// The _network manager
- ///
- private readonly INetworkManager _networkManager;
-
private bool _isDisposed;
- private readonly List>> _responders = new List>>();
+ private readonly List>> _responders = new List>>();
private readonly IServerApplicationHost _appHost;
private readonly IJsonSerializer _json;
@@ -39,46 +32,43 @@ namespace MediaBrowser.Server.Implementations.Udp
///
/// Initializes a new instance of the class.
///
- /// The logger.
- /// The network manager.
- /// The application host.
- /// The json.
- public UdpServer(ILogger logger, INetworkManager networkManager, IServerApplicationHost appHost, IJsonSerializer json)
+ public UdpServer(ILogger logger, IServerApplicationHost appHost, IJsonSerializer json, ISocketFactory socketFactory)
{
_logger = logger;
- _networkManager = networkManager;
_appHost = appHost;
_json = json;
+ _socketFactory = socketFactory;
AddMessageResponder("who is EmbyServer?", true, RespondToV2Message);
AddMessageResponder("who is MediaBrowserServer_v2?", false, RespondToV2Message);
}
- private void AddMessageResponder(string message, bool isSubstring, Func responder)
+ private void AddMessageResponder(string message, bool isSubstring, Func responder)
{
- _responders.Add(new Tuple>(message, isSubstring, responder));
+ _responders.Add(new Tuple>(message, isSubstring, responder));
}
///
/// Raises the event.
///
- /// The instance containing the event data.
- private async void OnMessageReceived(UdpMessageReceivedEventArgs e)
+ private async void OnMessageReceived(GenericEventArgs e)
{
+ var message = e.Argument;
+
var encoding = Encoding.UTF8;
- var responder = GetResponder(e.Bytes, encoding);
+ var responder = GetResponder(message.Buffer, message.ReceivedBytes, encoding);
if (responder == null)
{
encoding = Encoding.Unicode;
- responder = GetResponder(e.Bytes, encoding);
+ responder = GetResponder(message.Buffer, message.ReceivedBytes, encoding);
}
if (responder != null)
{
try
{
- await responder.Item2.Item3(responder.Item1, e.RemoteEndPoint, encoding).ConfigureAwait(false);
+ await responder.Item2.Item3(responder.Item1, message.RemoteEndPoint, encoding).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -87,9 +77,9 @@ namespace MediaBrowser.Server.Implementations.Udp
}
}
- private Tuple>> GetResponder(byte[] bytes, Encoding encoding)
+ private Tuple>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding)
{
- var text = encoding.GetString(bytes);
+ var text = encoding.GetString(buffer, 0, bytesReceived);
var responder = _responders.FirstOrDefault(i =>
{
if (i.Item2)
@@ -103,10 +93,10 @@ namespace MediaBrowser.Server.Implementations.Udp
{
return null;
}
- return new Tuple>>(text, responder);
+ return new Tuple>>(text, responder);
}
- private async Task RespondToV2Message(string messageText, string endpoint, Encoding encoding)
+ private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding)
{
var parts = messageText.Split('|');
@@ -122,7 +112,7 @@ namespace MediaBrowser.Server.Implementations.Udp
};
await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint).ConfigureAwait(false);
-
+
if (parts.Length > 1)
{
_appHost.EnableLoopback(parts[1]);
@@ -137,7 +127,8 @@ namespace MediaBrowser.Server.Implementations.Udp
///
/// The _udp client
///
- private UdpClient _udpClient;
+ private IUdpSocket _udpClient;
+ private readonly ISocketFactory _socketFactory;
///
/// Starts the specified port.
@@ -145,9 +136,7 @@ namespace MediaBrowser.Server.Implementations.Udp
/// The port.
public void Start(int port)
{
- _udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, port));
-
- _udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+ _udpClient = _socketFactory.CreateUdpSocket(port);
Task.Run(() => StartListening());
}
@@ -158,56 +147,36 @@ namespace MediaBrowser.Server.Implementations.Udp
{
try
{
- var result = await GetResult().ConfigureAwait(false);
+ var result = await _udpClient.ReceiveAsync().ConfigureAwait(false);
OnMessageReceived(result);
}
catch (ObjectDisposedException)
{
- break;
}
catch (Exception ex)
{
- _logger.ErrorException("Error in StartListening", ex);
+ _logger.ErrorException("Error receiving udp message", ex);
}
}
}
- private Task GetResult()
- {
- try
- {
- return _udpClient.ReceiveAsync();
- }
- catch (ObjectDisposedException)
- {
- return Task.FromResult(new UdpReceiveResult(new byte[] { }, new IPEndPoint(IPAddress.Any, 0)));
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error receiving udp message", ex);
- return Task.FromResult(new UdpReceiveResult(new byte[] { }, new IPEndPoint(IPAddress.Any, 0)));
- }
- }
-
///
/// Called when [message received].
///
/// The message.
- private void OnMessageReceived(UdpReceiveResult message)
+ private void OnMessageReceived(SocketReceiveResult message)
{
if (message.RemoteEndPoint.Port == 0)
{
return;
}
- var bytes = message.Buffer;
try
{
- OnMessageReceived(new UdpMessageReceivedEventArgs
+ OnMessageReceived(new GenericEventArgs
{
- Bytes = bytes,
- RemoteEndPoint = message.RemoteEndPoint.ToString()
+ Argument = message
});
}
catch (Exception ex)
@@ -234,7 +203,7 @@ namespace MediaBrowser.Server.Implementations.Udp
if (_udpClient != null)
{
- _udpClient.Close();
+ _udpClient.Dispose();
}
}
@@ -250,71 +219,21 @@ namespace MediaBrowser.Server.Implementations.Udp
}
}
- ///
- /// Sends the async.
- ///
- /// The data.
- /// The ip address.
- /// The port.
- /// Task{System.Int32}.
- /// data
- public Task SendAsync(string data, string ipAddress, int port)
- {
- return SendAsync(Encoding.UTF8.GetBytes(data), ipAddress, port);
- }
-
- ///
- /// Sends the async.
- ///
- /// The bytes.
- /// The ip address.
- /// The port.
- /// Task{System.Int32}.
- /// bytes
- public Task SendAsync(byte[] bytes, string ipAddress, int port)
+ public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint)
{
if (bytes == null)
{
throw new ArgumentNullException("bytes");
}
- if (string.IsNullOrEmpty(ipAddress))
- {
- throw new ArgumentNullException("ipAddress");
- }
-
- return _udpClient.SendAsync(bytes, bytes.Length, ipAddress, port);
- }
-
- ///
- /// Sends the async.
- ///
- /// The bytes.
- /// The remote end point.
- /// Task.
- ///
- /// bytes
- /// or
- /// remoteEndPoint
- ///
- public async Task SendAsync(byte[] bytes, string remoteEndPoint)
- {
- if (bytes == null)
- {
- throw new ArgumentNullException("bytes");
- }
-
- if (string.IsNullOrEmpty(remoteEndPoint))
+ if (remoteEndPoint == null)
{
throw new ArgumentNullException("remoteEndPoint");
}
try
{
- // Need to do this until Common will compile with this method
- var nativeNetworkManager = (BaseNetworkManager) _networkManager;
-
- await _udpClient.SendAsync(bytes, bytes.Length, nativeNetworkManager.Parse(remoteEndPoint)).ConfigureAwait(false);
+ await _udpClient.SendAsync(bytes, bytes.Length, remoteEndPoint).ConfigureAwait(false);
_logger.Info("Udp message sent to {0}", remoteEndPoint);
}
diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs
index 0a565f6701..fe60c7ebfa 100644
--- a/MediaBrowser.Common/Net/INetworkManager.cs
+++ b/MediaBrowser.Common/Net/INetworkManager.cs
@@ -46,6 +46,10 @@ namespace MediaBrowser.Common.Net
/// true if [is in local network] [the specified endpoint]; otherwise, false.
bool IsInLocalNetwork(string endpoint);
+ IpAddressInfo ParseIpAddress(string ipAddress);
+
+ bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo);
+
///
/// Generates a self signed certificate at the locatation specified by .
///
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 03bbafe60a..c85b215f2c 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -140,7 +140,7 @@
-
+
diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs
index c0e0440c25..3f1ddf84f9 100644
--- a/MediaBrowser.Model/Net/ISocketFactory.cs
+++ b/MediaBrowser.Model/Net/ISocketFactory.cs
@@ -14,13 +14,18 @@ namespace MediaBrowser.Model.Net
/// A implementation.
IUdpSocket CreateUdpSocket(int localPort);
- ///
- /// Createa a new multicast socket using the specified multicast IP address, multicast time to live and local port.
- ///
- /// The multicast IP address to bind to.
- /// The multicast time to live value. Actually a maximum number of network hops for UDP packets.
- /// The local port to bind to.
- /// A implementation.
- IUdpSocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort);
+ ///
+ /// Createa a new unicast socket using the specified local port number.
+ ///
+ IUdpSocket CreateSsdpUdpSocket(int localPort);
+
+ ///
+ /// Createa a new multicast socket using the specified multicast IP address, multicast time to live and local port.
+ ///
+ /// The multicast IP address to bind to.
+ /// The multicast time to live value. Actually a maximum number of network hops for UDP packets.
+ /// The local port to bind to.
+ /// A implementation.
+ IUdpSocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort);
}
}
diff --git a/MediaBrowser.Model/Net/IUdpSocket.cs b/MediaBrowser.Model/Net/IUdpSocket.cs
index cbeb8a995f..ef090e010c 100644
--- a/MediaBrowser.Model/Net/IUdpSocket.cs
+++ b/MediaBrowser.Model/Net/IUdpSocket.cs
@@ -15,13 +15,11 @@ namespace MediaBrowser.Model.Net
/// Waits for and returns the next UDP message sent to this socket (uni or multicast).
///
///
- Task ReceiveAsync();
+ Task ReceiveAsync();
///
/// Sends a UDP message to a particular end point (uni or multicast).
///
- /// The data to send.
- /// The providing the address and port to send to.
- Task SendTo(byte[] messageData, IpEndPointInfo endPoint);
+ Task SendAsync(byte[] buffer, int bytes, IpEndPointInfo endPoint);
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Model/Net/ReceivedUdpData.cs b/MediaBrowser.Model/Net/SocketReceiveResult.cs
similarity index 83%
rename from MediaBrowser.Model/Net/ReceivedUdpData.cs
rename to MediaBrowser.Model/Net/SocketReceiveResult.cs
index 1fdb22c930..0a2d04ad39 100644
--- a/MediaBrowser.Model/Net/ReceivedUdpData.cs
+++ b/MediaBrowser.Model/Net/SocketReceiveResult.cs
@@ -4,7 +4,7 @@ namespace MediaBrowser.Model.Net
///
/// Used by the sockets wrapper to hold raw data received from a UDP socket.
///
- public sealed class ReceivedUdpData
+ public sealed class SocketReceiveResult
{
///
/// The buffer to place received data into.
@@ -19,6 +19,6 @@ namespace MediaBrowser.Model.Net
///
/// The the data was received from.
///
- public IpEndPointInfo ReceivedFrom { get; set; }
+ public IpEndPointInfo RemoteEndPoint { get; set; }
}
}
diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
index 20d89d2eb1..5619348543 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
@@ -1,13 +1,13 @@
using System.Collections.Specialized;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Logging;
-using MediaBrowser.Server.Implementations.Logging;
using SocketHttpListener.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Emby.Server.Implementations.HttpServer;
+using Emby.Server.Implementations.Logging;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Services;
diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
index 49cb1e75f4..34fc85e7b1 100644
--- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
+++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
@@ -10,13 +10,14 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using Emby.Server.Implementations.IO;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller;
using MediaBrowser.Controller.IO;
+using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Threading;
-using Microsoft.Win32;
namespace MediaBrowser.Server.Implementations.IO
{
@@ -142,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.IO
///
/// Initializes a new instance of the class.
///
- public LibraryMonitor(ILogManager logManager, ITaskManager taskManager, ILibraryManager libraryManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ITimerFactory timerFactory)
+ public LibraryMonitor(ILogManager logManager, ITaskManager taskManager, ILibraryManager libraryManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ITimerFactory timerFactory, ISystemEvents systemEvents)
{
if (taskManager == null)
{
@@ -156,15 +157,10 @@ namespace MediaBrowser.Server.Implementations.IO
_fileSystem = fileSystem;
_timerFactory = timerFactory;
- SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
+ systemEvents.Resume += _systemEvents_Resume;
}
- ///
- /// Handles the PowerModeChanged event of the SystemEvents control.
- ///
- /// The source of the event.
- /// The instance containing the event data.
- void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
+ private void _systemEvents_Resume(object sender, EventArgs e)
{
Restart();
}
diff --git a/MediaBrowser.Server.Implementations/Logging/PatternsLogger.cs b/MediaBrowser.Server.Implementations/Logging/PatternsLogger.cs
deleted file mode 100644
index 00b6cc5a8b..0000000000
--- a/MediaBrowser.Server.Implementations/Logging/PatternsLogger.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using Patterns.Logging;
-using System;
-
-namespace MediaBrowser.Server.Implementations.Logging
-{
- public class PatternsLogger : ILogger
- {
- private readonly Model.Logging.ILogger _logger;
-
- public PatternsLogger()
- : this(new Model.Logging.NullLogger())
- {
- }
-
- public PatternsLogger(Model.Logging.ILogger logger)
- {
- _logger = logger;
- }
-
- public void Debug(string message, params object[] paramList)
- {
- _logger.Debug(message, paramList);
- }
-
- public void Error(string message, params object[] paramList)
- {
- _logger.Error(message, paramList);
- }
-
- public void ErrorException(string message, Exception exception, params object[] paramList)
- {
- _logger.ErrorException(message, exception, paramList);
- }
-
- public void Fatal(string message, params object[] paramList)
- {
- _logger.Fatal(message, paramList);
- }
-
- public void FatalException(string message, Exception exception, params object[] paramList)
- {
- _logger.FatalException(message, exception, paramList);
- }
-
- public void Info(string message, params object[] paramList)
- {
- _logger.Info(message, paramList);
- }
-
- public void Warn(string message, params object[] paramList)
- {
- _logger.Warn(message, paramList);
- }
-
- public void Log(LogSeverity severity, string message, params object[] paramList)
- {
- }
-
- public void LogMultiline(string message, LogSeverity severity, System.Text.StringBuilder additionalContent)
- {
- }
- }
-}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index d6223c4655..066ee8e306 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -113,15 +113,9 @@
-
-
-
-
-
-
@@ -140,7 +134,6 @@
-
@@ -166,7 +159,6 @@
-
@@ -180,15 +172,12 @@
-
-
-
diff --git a/MediaBrowser.Server.Implementations/Udp/UdpMessageReceivedEventArgs.cs b/MediaBrowser.Server.Implementations/Udp/UdpMessageReceivedEventArgs.cs
deleted file mode 100644
index 5c83a13007..0000000000
--- a/MediaBrowser.Server.Implementations/Udp/UdpMessageReceivedEventArgs.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-
-namespace MediaBrowser.Server.Implementations.Udp
-{
- ///
- /// Class UdpMessageReceivedEventArgs
- ///
- public class UdpMessageReceivedEventArgs : EventArgs
- {
- ///
- /// Gets or sets the bytes.
- ///
- /// The bytes.
- public byte[] Bytes { get; set; }
- ///
- /// Gets or sets the remote end point.
- ///
- /// The remote end point.
- public string RemoteEndPoint { get; set; }
- }
-}
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index 5f609de27a..79f7b5f051 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -51,12 +51,9 @@ using MediaBrowser.Providers.Subtitles;
using MediaBrowser.Server.Implementations;
using MediaBrowser.Server.Implementations.Activity;
using MediaBrowser.Server.Implementations.Configuration;
-using MediaBrowser.Server.Implementations.Connect;
using MediaBrowser.Server.Implementations.Devices;
-using MediaBrowser.Server.Implementations.EntryPoints;
using MediaBrowser.Server.Implementations.HttpServer;
using MediaBrowser.Server.Implementations.IO;
-using MediaBrowser.Server.Implementations.LiveTv;
using MediaBrowser.Server.Implementations.Localization;
using MediaBrowser.Server.Implementations.Notifications;
using MediaBrowser.Server.Implementations.Persistence;
@@ -102,8 +99,10 @@ using Emby.Dlna.Ssdp;
using Emby.Server.Implementations.Activity;
using Emby.Server.Implementations.Channels;
using Emby.Server.Implementations.Collections;
+using Emby.Server.Implementations.Connect;
using Emby.Server.Implementations.Devices;
using Emby.Server.Implementations.Dto;
+using Emby.Server.Implementations.EntryPoints;
using Emby.Server.Implementations.FileOrganization;
using Emby.Server.Implementations.HttpServer.Security;
using Emby.Server.Implementations.Library;
@@ -593,7 +592,7 @@ namespace MediaBrowser.Server.Startup.Common
var musicManager = new MusicManager(LibraryManager);
RegisterSingleInstance(new MusicManager(LibraryManager));
- LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, TimerFactory);
+ LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, TimerFactory, SystemEvents);
RegisterSingleInstance(LibraryMonitor);
ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer, MemoryStreamProvider);
diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs
index 64278fe4e5..dadb1bff4b 100644
--- a/RSSDP/SsdpCommunicationsServer.cs
+++ b/RSSDP/SsdpCommunicationsServer.cs
@@ -260,7 +260,7 @@ namespace Rssdp.Infrastructure
var socket = _SendSocket;
if (socket != null)
{
- await _SendSocket.SendTo(messageData, destination).ConfigureAwait(false);
+ await _SendSocket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false);
}
else
{
@@ -290,7 +290,7 @@ namespace Rssdp.Infrastructure
private IUdpSocket CreateSocketAndListenForResponsesAsync()
{
- _SendSocket = _SocketFactory.CreateUdpSocket(_LocalPort);
+ _SendSocket = _SocketFactory.CreateSsdpUdpSocket(_LocalPort);
ListenToSocket(_SendSocket);
@@ -316,7 +316,7 @@ namespace Rssdp.Infrastructure
// Strange cannot convert compiler error here if I don't explicitly
// assign or cast to Action first. Assignment is easier to read,
// so went with that.
- Action processWork = () => ProcessMessage(System.Text.UTF8Encoding.UTF8.GetString(result.Buffer, 0, result.ReceivedBytes), result.ReceivedFrom);
+ Action processWork = () => ProcessMessage(System.Text.UTF8Encoding.UTF8.GetString(result.Buffer, 0, result.ReceivedBytes), result.RemoteEndPoint);
var processTask = Task.Run(processWork);
}
}