Files
DearFTP/DearFTP/Connection/StaticDataConnection.cs
2019-07-21 20:05:57 +02:00

113 lines
2.7 KiB
C#

using System.IO;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace DearFTP.Connection
{
class StaticDataConnection : IDataConnection
{
public const int Timeout = 10_000;
public Stream Stream { get; private set; }
public bool IsTlsProtected { get; private set; }
public int Port => ((IPEndPoint)_listener.LocalEndpoint).Port;
public bool IsAvailable
{
get
{
if (_acceptTask == null)
{
return false;
}
else if (_acceptTask.Wait(Timeout))
{
return true;
}
else
{
_acceptTask.Dispose();
_acceptTask = null;
return false;
}
}
}
private static TcpListener _listener;
private static Task _acceptTask;
private TcpClient _client;
public StaticDataConnection()
{
if (_listener == null)
{
_listener = new TcpListener(IPAddress.Any, FtpServer.Instance.Configuration.Server.ForceDataPort);
_listener.Start();
}
IsTlsProtected = false;
}
public void AcceptClient()
{
if (_acceptTask?.IsCompleted == false)
{
_acceptTask.Wait(Timeout);
_acceptTask.Dispose();
_acceptTask = null;
}
_acceptTask = _listener.AcceptTcpClientAsync().ContinueWith(t =>
{
_client = t.Result;
if (IsTlsProtected)
{
Stream = new SslStream(_client.GetStream(), false);
}
else
{
Stream = _client.GetStream();
}
});
}
public void Authenticate()
{
if (IsTlsProtected)
{
((SslStream)Stream).AuthenticateAsServer(FtpServer.Instance.Configuration.Tls.X509Certificate, false, true);
}
}
public void ActivateTls()
{
IsTlsProtected = true;
}
public void Close()
{
Stream.Close();
_client.Close();
}
public void Create()
{
// Nothing to create as the TcpListener is shared by all
}
public void DesactivateTls()
{
IsTlsProtected = false;
}
public static void Stop()
{
_listener?.Stop();
}
}
}