Browse Source

cleaning

pull/123/head
notgiven688 3 years ago
parent
commit
59067f091a
4 changed files with 167 additions and 150 deletions
  1. +1
    -2
      server/Server/Fleck/Interfaces/ISocket.cs
  2. +0
    -1
      server/Server/Fleck/Interfaces/IWebSocketServer.cs
  3. +2
    -2
      server/Server/Fleck/SocketWrapper.cs
  4. +164
    -145
      server/Server/Fleck/WebSocketServer.cs

+ 1
- 2
server/Server/Fleck/Interfaces/ISocket.cs View File

@ -24,7 +24,6 @@
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
@ -40,7 +39,7 @@ namespace Fleck
bool NoDelay { get; set; }
EndPoint LocalEndPoint { get; }
Task Accept(Action<ISocket> callback, Action<Exception> error);
Task Accept(Action<ISocket> callback, Action<Exception> error);
Task Send(byte[] buffer, Action callback, Action<Exception> error);
Task<int> Receive(byte[] buffer, Action<int> callback, Action<Exception> error, int offset = 0);
Task Authenticate(X509Certificate2 certificate, SslProtocols enabledSslProtocols, Action callback, Action<Exception> error);

+ 0
- 1
server/Server/Fleck/Interfaces/IWebSocketServer.cs View File

@ -28,6 +28,5 @@ namespace Fleck
public interface IWebSocketServer : IDisposable
{
void Start(Action<IWebSocketConnection> config);
}
}

+ 2
- 2
server/Server/Fleck/SocketWrapper.cs View File

@ -175,8 +175,8 @@ namespace Fleck
return null;
}
}
public Task Accept(Action<ISocket> callback, Action<Exception> error)
public Task Accept(Action<ISocket> callback, Action<Exception> error)
{
Func<IAsyncResult, ISocket> end = r => _tokenSource.Token.IsCancellationRequested ? null : new SocketWrapper(_socket.EndAccept(r));
var task = _taskFactory.FromAsync(_socket.BeginAccept, end, null);

+ 164
- 145
server/Server/Fleck/WebSocketServer.cs View File

@ -24,49 +24,57 @@
#define __MonoCS__
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.AccessControl;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Collections.Generic;
using System.Security.Authentication;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using System.Threading;
using Fleck.Helpers;
namespace Fleck {
public class WebSocketServer : IWebSocketServer {
using System.Collections;
using System.Text;
using System.Text.RegularExpressions;
using System.Security;
using System.Runtime.InteropServices;
using System.IO;
using System.Security.Principal;
using System.Security.AccessControl;
using System.Diagnostics;
using System.Reflection;
namespace Fleck
{
public class WebSocketServer : IWebSocketServer
{
private readonly string _scheme;
private readonly IPAddress _locationIP;
private Action<IWebSocketConnection> _config;
private const int BytesPerLong = 4; // 32 / 8
private const int BitsPerByte = 8;
private const int BytesPerLong = 4; // 32 / 8
private const int BitsPerByte = 8;
public WebSocketServer (string location) {
var uri = new Uri (location);
public WebSocketServer(string location)
{
var uri = new Uri(location);
Port = uri.Port;
Location = location;
_locationIP = ParseIPAddress (uri);
_locationIP = ParseIPAddress(uri);
_scheme = uri.Scheme;
var socket = new Socket (_locationIP.AddressFamily, SocketType.Stream, ProtocolType.IP);
if (!MonoHelper.IsRunningOnMono ()) {
#if __MonoCS__
#else
socket.SetSocketOption (SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
#endif
var socket = new Socket(_locationIP.AddressFamily, SocketType.Stream, ProtocolType.IP);
if(!MonoHelper.IsRunningOnMono()){
#if __MonoCS__
#else
socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
#endif
}
ListenerSocket = new SocketWrapper (socket);
ListenerSocket = new SocketWrapper(socket);
SupportedSubProtocols = new string[0];
}
@ -76,166 +84,177 @@ namespace Fleck {
public X509Certificate2 Certificate { get; set; }
public SslProtocols EnabledSslProtocols { get; set; }
public IEnumerable<string> SupportedSubProtocols { get; set; }
public bool RestartAfterListenError { get; set; }
public bool RestartAfterListenError {get; set; }
public bool IsSecure {
public bool IsSecure
{
get { return _scheme == "wss" && Certificate != null; }
}
public void Dispose () {
ListenerSocket.Dispose ();
public void Dispose()
{
ListenerSocket.Dispose();
}
private IPAddress ParseIPAddress (Uri uri) {
private IPAddress ParseIPAddress(Uri uri)
{
string ipStr = uri.Host;
if (ipStr == "0.0.0.0") {
if (ipStr == "0.0.0.0" ){
return IPAddress.Any;
} else if (ipStr == "[0000:0000:0000:0000:0000:0000:0000:0000]") {
}else if(ipStr == "[0000:0000:0000:0000:0000:0000:0000:0000]")
{
return IPAddress.IPv6Any;
} else {
try {
return IPAddress.Parse (ipStr);
return IPAddress.Parse(ipStr);
} catch (Exception ex) {
throw new FormatException ("Failed to parse the IP address part of the location. Please make sure you specify a valid IP address. Use 0.0.0.0 or [::] to listen on all interfaces.", ex);
throw new FormatException("Failed to parse the IP address part of the location. Please make sure you specify a valid IP address. Use 0.0.0.0 or [::] to listen on all interfaces.", ex);
}
}
}
public void Start (Action<IWebSocketConnection> config) {
var ipLocal = new IPEndPoint (_locationIP, Port);
ListenerSocket.Bind (ipLocal);
ListenerSocket.Listen (100);
Port = ((IPEndPoint) ListenerSocket.LocalEndPoint).Port;
FleckLog.Info (string.Format ("Server started at {0} (actual port {1})", Location, Port));
if (_scheme == "wss") {
if (Certificate == null) {
FleckLog.Error ("Scheme cannot be 'wss' without a Certificate");
public void Start(Action<IWebSocketConnection> config)
{
var ipLocal = new IPEndPoint(_locationIP, Port);
ListenerSocket.Bind(ipLocal);
ListenerSocket.Listen(100);
Port = ((IPEndPoint)ListenerSocket.LocalEndPoint).Port;
FleckLog.Info(string.Format("Server started at {0} (actual port {1})", Location, Port));
if (_scheme == "wss")
{
if (Certificate == null)
{
FleckLog.Error("Scheme cannot be 'wss' without a Certificate");
return;
}
if (EnabledSslProtocols == SslProtocols.None) {
EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
if (EnabledSslProtocols == SslProtocols.None)
{
EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
//EnabledSslProtocols = SslProtocols.Tls; // changed by wmp
FleckLog.Debug ("Using default TLS 1.0 security protocol.");
FleckLog.Debug("Using default TLS 1.0 security protocol.");
}
}
ListenForClients ();
ListenForClients();
_config = config;
}
private void TryRestart()
private void TryRestart ()
{
FleckLog.Info("Listener socket restarting");
try
{
ListenerSocket.Dispose();
var socket = new Socket(_locationIP.AddressFamily, SocketType.Stream, ProtocolType.IP);
ListenerSocket = new SocketWrapper(socket);
Start(_config);
FleckLog.Info("Listener socket restarted");
}
catch (Exception ex)
{
FleckLog.Error("Listener socket could not be restarted", ex);
FleckLog.Info ("Listener socket restarting");
try {
ListenerSocket.Dispose ();
var socket = new Socket (_locationIP.AddressFamily, SocketType.Stream, ProtocolType.IP);
ListenerSocket = new SocketWrapper (socket);
Start (_config);
FleckLog.Info ("Listener socket restarted");
} catch (Exception ex) {
FleckLog.Error ("Listener socket could not be restarted", ex);
}
}
private void ListenForClients()
private void ListenForClients ()
{
ManualResetEvent acceptDone = new ManualResetEvent(false);
bool running = true;
Task.Run(() => {
while (running)
{
acceptDone.Reset();
var task = ListenerSocket.Accept(
s => {
running = (s != null);
acceptDone.Set();
OnClientConnect(s);
},
e => {
FleckLog.Error("Error while listening for new clients", e);
if (RestartAfterListenError) TryRestart();
running = false; acceptDone.Set();
}
);
task.ContinueWith((t) => FleckLog.Warn("Error during client connect", t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
acceptDone.WaitOne();
}
});
ManualResetEvent acceptDone = new ManualResetEvent (false);
bool running = true;
Task.Run (() => {
while (running) {
acceptDone.Reset ();
var task = ListenerSocket.Accept(
s => {
running = (s != null);
acceptDone.Set ();
OnClientConnect (s); },
e => { FleckLog.Error ("Error while listening for new clients", e);
if (RestartAfterListenError) TryRestart ();
running = false; acceptDone.Set (); }
);
task.ContinueWith((t) => FleckLog.Warn ("Error during client connect", t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
acceptDone.WaitOne ();
}
});
}
private void OnClientConnect (ISocket clientSocket) {
private void OnClientConnect(ISocket clientSocket)
{
if (clientSocket == null) return; // socket closed
// experimental removed by wmp
// experimental removed by wmp
//FleckLog.Debug(String.Format("Client connected from {0}:{1}", clientSocket.RemoteIpAddress, clientSocket.RemotePort.ToString()));
//Console.WriteLine(String.Format("Client connected from {0}:{1}", clientSocket.RemoteIpAddress, clientSocket.RemotePort.ToString()));
string rep = string.Empty;
bool failed = false;
try {
rep = clientSocket.RemoteIpAddress;
Console.WriteLine ("Connecting: " + rep);
} catch {
Console.WriteLine ("Started but IP not available.");
failed = true;
}
//ListenForClients ();
if (failed) {
try { clientSocket.Close (); } catch { }
try { clientSocket.Stream.Close (); } catch { }
try { clientSocket.Dispose (); } catch { }
return;
}
//Console.WriteLine(String.Format("Client connected from {0}:{1}", clientSocket.RemoteIpAddress, clientSocket.RemotePort.ToString()));
string rep = string.Empty;
bool failed = false;
try {
rep = clientSocket.RemoteIpAddress;
Console.WriteLine("Connecting: " + rep);
}
catch{
Console.WriteLine ("Started but IP not available.");
failed = true;
}
ListenForClients();
if (failed) {
try{ clientSocket.Close (); }catch{}
try{ clientSocket.Stream.Close();}catch{}
try{ clientSocket.Dispose ();}catch{}
return;
}
WebSocketConnection connection = null;
connection = new WebSocketConnection (
connection = new WebSocketConnection(
clientSocket,
_config,
bytes => RequestParser.Parse (bytes, _scheme),
r => HandlerFactory.BuildHandler (r,
s => connection.OnMessage (s),
connection.Close,
b => connection.OnBinary (b),
b => connection.OnPing (b),
b => connection.OnPong (b)),
s => SubProtocolNegotiator.Negotiate (SupportedSubProtocols, s));
if (IsSecure) {
FleckLog.Debug ("Authenticating Secure Connection");
bytes => RequestParser.Parse(bytes, _scheme),
r => HandlerFactory.BuildHandler(r,
s => connection.OnMessage(s),
connection.Close,
b => connection.OnBinary(b),
b => connection.OnPing(b),
b => connection.OnPong(b)),
s => SubProtocolNegotiator.Negotiate(SupportedSubProtocols, s));
if (IsSecure)
{
FleckLog.Debug("Authenticating Secure Connection");
clientSocket
.Authenticate (Certificate,
EnabledSslProtocols,
() => {
Console.WriteLine ("Authenticated {0}", rep);
Server.Firewall.Update (rep, Server.Firewall.UpdateEntry.AuthSuccess);
connection.StartReceiving ();
}, e => {
FleckLog.Warn ("Failed to Authenticate " + rep, e);
// here we could add connection.Close() ! wmp
Server.Firewall.Update (rep, Server.Firewall.UpdateEntry.AuthFailure);
connection.Close ();
});
} else {
Server.Firewall.Update (rep, Server.Firewall.UpdateEntry.AuthSuccess);
.Authenticate(Certificate,
EnabledSslProtocols,
() =>
{
Console.WriteLine("Authenticated {0}", rep);
Server.Firewall.Update(rep, Server.Firewall.UpdateEntry.AuthSuccess);
connection.StartReceiving();
}
,e =>
{
FleckLog.Warn("Failed to Authenticate " + rep, e);
// here we could add connection.Close() ! wmp
Server.Firewall.Update(rep, Server.Firewall.UpdateEntry.AuthFailure);
connection.Close();
});
}
else
{
Server.Firewall.Update(rep, Server.Firewall.UpdateEntry.AuthSuccess);
connection.StartReceiving ();
connection.StartReceiving();
}
}
}

Loading…
Cancel
Save