SOCKS FINALLY DONE
HOLY SHIT
This commit is contained in:
parent
c8d100da96
commit
132e272580
9 changed files with 194 additions and 59 deletions
|
@ -18,6 +18,9 @@ namespace CircleScape {
|
||||||
|
|
||||||
// logic processing loop
|
// logic processing loop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
server.Stop();
|
||||||
|
PoolManager.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,9 @@ using System.IO;
|
||||||
|
|
||||||
namespace Kneesocks {
|
namespace Kneesocks {
|
||||||
public class Connection {
|
public class Connection {
|
||||||
public UInt64? _Id = null;
|
private bool Initialized = false;
|
||||||
|
|
||||||
|
private UInt64? _Id = null;
|
||||||
public UInt64 Id {
|
public UInt64 Id {
|
||||||
get {
|
get {
|
||||||
if(_Id == null)
|
if(_Id == null)
|
||||||
|
@ -22,9 +24,14 @@ namespace Kneesocks {
|
||||||
_Id = value;
|
_Id = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
internal bool IsIdNull {
|
||||||
|
get {
|
||||||
|
return _Id == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private TcpClient Socket;
|
private TcpClient Socket = null;
|
||||||
private NetworkStream Stream;
|
private NetworkStream Stream = null;
|
||||||
|
|
||||||
ReadBuffer Buffer;
|
ReadBuffer Buffer;
|
||||||
private byte[] FirstTwoBytes = null;
|
private byte[] FirstTwoBytes = null;
|
||||||
|
@ -32,27 +39,54 @@ namespace Kneesocks {
|
||||||
private byte[] FrameHeader = null;
|
private byte[] FrameHeader = null;
|
||||||
private List<Frame> ReceiveFrameBuffer = new List<Frame>();
|
private List<Frame> ReceiveFrameBuffer = new List<Frame>();
|
||||||
private List<Frame> SendFrameBuffer = new List<Frame>();
|
private List<Frame> SendFrameBuffer = new List<Frame>();
|
||||||
|
private const int MaximumSendFrameSize = 0xFFFFF;
|
||||||
|
|
||||||
|
private Random Random = new Random();
|
||||||
|
|
||||||
|
protected const int PingInterval = 30;
|
||||||
|
protected const int TimeoutInterval = 120;
|
||||||
|
private byte[] PingData = Encoding.ASCII.GetBytes("woomy!");
|
||||||
private DateTime LastPing;
|
private DateTime LastPing;
|
||||||
|
private bool AwaitingPingResponse = false;
|
||||||
|
private TimeSpan TimeSinceLastPing {
|
||||||
|
get {
|
||||||
|
return DateTime.UtcNow - LastPing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool OutsidePool = false;
|
||||||
public bool Disconnected { get; private set; } = false;
|
public bool Disconnected { get; private set; } = false;
|
||||||
public string DisconnectReason { get; private set; } = null;
|
public string DisconnectReason { get; private set; } = null;
|
||||||
|
|
||||||
public bool Handshaked { get; private set; } = false;
|
public bool Handshaked { get; private set; } = false;
|
||||||
public Handshake ClientHandshake { get; private set; } = null;
|
public Handshake ClientHandshake { get; private set; } = null;
|
||||||
|
|
||||||
public Connection(TcpClient sock) {
|
public void Initialize(TcpClient sock) {
|
||||||
|
if(Initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
Socket = sock;
|
Socket = sock;
|
||||||
Socket.ReceiveTimeout = 1;
|
Socket.ReceiveTimeout = 1;
|
||||||
Stream = sock.GetStream();
|
Stream = sock.GetStream();
|
||||||
Buffer = new ReadBuffer(Stream);
|
Buffer = new ReadBuffer(Stream);
|
||||||
|
|
||||||
|
Initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Connection(UInt64 id, TcpClient sock) : this(sock) {
|
public void Initialize(UInt64 id, TcpClient sock) {
|
||||||
|
if(Initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Initialize(sock);
|
||||||
Id = id;
|
Id = id;
|
||||||
|
|
||||||
|
Initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Connection(Connection conn, bool preserveId = true) {
|
public void Initialize(Connection conn, bool preserveId = false) {
|
||||||
|
if(Initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
if(preserveId)
|
if(preserveId)
|
||||||
_Id = conn._Id;
|
_Id = conn._Id;
|
||||||
|
|
||||||
|
@ -65,22 +99,25 @@ namespace Kneesocks {
|
||||||
FrameHeader = conn.FrameHeader;
|
FrameHeader = conn.FrameHeader;
|
||||||
ReceiveFrameBuffer = conn.ReceiveFrameBuffer;
|
ReceiveFrameBuffer = conn.ReceiveFrameBuffer;
|
||||||
|
|
||||||
|
LastPing = conn.LastPing;
|
||||||
|
|
||||||
Disconnected = conn.Disconnected;
|
Disconnected = conn.Disconnected;
|
||||||
DisconnectReason = conn.DisconnectReason;
|
DisconnectReason = conn.DisconnectReason;
|
||||||
|
|
||||||
Handshaked = conn.Handshaked;
|
Handshaked = conn.Handshaked;
|
||||||
ClientHandshake = conn.ClientHandshake;
|
ClientHandshake = conn.ClientHandshake;
|
||||||
|
|
||||||
|
Initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int MaximumFrameSize = 0xFFFFF;
|
|
||||||
private void _Send(byte[] message, bool isFinal = true, bool singleFrame = false, bool first = false) {
|
private void _Send(byte[] message, bool isFinal = true, bool singleFrame = false, bool first = false) {
|
||||||
int frameCount = singleFrame ? 0 : (message.Length / MaximumFrameSize);
|
int frameCount = singleFrame ? 0 : (message.Length / MaximumSendFrameSize);
|
||||||
for(var i = 0; i <= frameCount; ++i) {
|
for(var i = 0; i <= frameCount; ++i) {
|
||||||
SendFrameBuffer.Add(new Frame {
|
SendFrameBuffer.Add(new Frame {
|
||||||
IsFinal = (i == frameCount && isFinal) ? true : false,
|
IsFinal = (i == frameCount && isFinal) ? true : false,
|
||||||
IsMasked = false,
|
IsMasked = false,
|
||||||
Opcode = (i == 0 || (singleFrame && first)) ? Frame.kOpcode.BinaryFrame : Frame.kOpcode.Continuation,
|
Opcode = (i == 0 || (singleFrame && first)) ? Frame.kOpcode.BinaryFrame : Frame.kOpcode.Continuation,
|
||||||
Content = message.Subset(i * (MaximumFrameSize + 1), MaximumFrameSize)
|
Content = message.Subset(i * (MaximumSendFrameSize + 1), MaximumSendFrameSize)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,15 +133,15 @@ namespace Kneesocks {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool firstRead = true;
|
bool firstRead = true;
|
||||||
byte[] byteBuffer = new byte[MaximumFrameSize];
|
byte[] byteBuffer = new byte[MaximumSendFrameSize];
|
||||||
while(true) {
|
while(true) {
|
||||||
var bytesRead = stream.Read(byteBuffer, 0, MaximumFrameSize);
|
var bytesRead = stream.Read(byteBuffer, 0, MaximumSendFrameSize);
|
||||||
|
|
||||||
if(stream.Position == stream.Length) {
|
if(stream.Position == stream.Length) {
|
||||||
_Send(bytesRead == MaximumFrameSize ? byteBuffer : byteBuffer.Take(bytesRead).ToArray(), true, true, firstRead);
|
_Send(bytesRead == MaximumSendFrameSize ? byteBuffer : byteBuffer.Take(bytesRead).ToArray(), true, true, firstRead);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
_Send(bytesRead == MaximumFrameSize ? byteBuffer : byteBuffer.Take(bytesRead).ToArray(), false, true, firstRead);
|
_Send(bytesRead == MaximumSendFrameSize ? byteBuffer : byteBuffer.Take(bytesRead).ToArray(), false, true, firstRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
firstRead = false;
|
firstRead = false;
|
||||||
|
@ -133,9 +170,25 @@ namespace Kneesocks {
|
||||||
buffer = buffer == null ? Buffer.AttemptRead(terminator)
|
buffer = buffer == null ? Buffer.AttemptRead(terminator)
|
||||||
: buffer;
|
: buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Parse() {
|
internal void Parse() {
|
||||||
if(Handshaked) {
|
if(Handshaked) {
|
||||||
|
if(!Buffer.IsReading) {
|
||||||
|
if(TimeSinceLastPing.Seconds > TimeoutInterval) {
|
||||||
|
Disconnect(Frame.kClosingReason.Normal, "Ping response timed out.");
|
||||||
|
} else if(TimeSinceLastPing.Seconds > PingInterval && !AwaitingPingResponse) {
|
||||||
|
var frameBytes = new Frame {
|
||||||
|
IsFinal = true,
|
||||||
|
IsMasked = false,
|
||||||
|
Opcode = Frame.kOpcode.Ping,
|
||||||
|
Content = PingData
|
||||||
|
}.GetBytes();
|
||||||
|
|
||||||
|
Stream.Write(frameBytes, 0, frameBytes.Length);
|
||||||
|
AwaitingPingResponse = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lock(SendFrameBuffer) {
|
lock(SendFrameBuffer) {
|
||||||
if(SendFrameBuffer.Count > 0) {
|
if(SendFrameBuffer.Count > 0) {
|
||||||
foreach(var frame in SendFrameBuffer) {
|
foreach(var frame in SendFrameBuffer) {
|
||||||
|
@ -172,6 +225,7 @@ namespace Kneesocks {
|
||||||
Stream.Write(response, 0, response.Length);
|
Stream.Write(response, 0, response.Length);
|
||||||
ClientHandshake = request;
|
ClientHandshake = request;
|
||||||
Handshaked = true;
|
Handshaked = true;
|
||||||
|
|
||||||
LastPing = DateTime.UtcNow;
|
LastPing = DateTime.UtcNow;
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
Disconnect(Frame.kClosingReason.ProtocolError, e.Message);
|
Disconnect(Frame.kClosingReason.ProtocolError, e.Message);
|
||||||
|
@ -238,7 +292,8 @@ namespace Kneesocks {
|
||||||
if(tempFrame.IsFinal) {
|
if(tempFrame.IsFinal) {
|
||||||
switch(tempFrame.Opcode) {
|
switch(tempFrame.Opcode) {
|
||||||
case Frame.kOpcode.Ping:
|
case Frame.kOpcode.Ping:
|
||||||
LastPing = DateTime.Now;
|
LastPing = DateTime.UtcNow;
|
||||||
|
AwaitingPingResponse = false;
|
||||||
|
|
||||||
tempFrame.Opcode = Frame.kOpcode.Pong;
|
tempFrame.Opcode = Frame.kOpcode.Pong;
|
||||||
var pingBuffer = tempFrame.GetBytes();
|
var pingBuffer = tempFrame.GetBytes();
|
||||||
|
@ -246,24 +301,33 @@ namespace Kneesocks {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Frame.kOpcode.Pong:
|
case Frame.kOpcode.Pong:
|
||||||
LastPing = DateTime.Now;
|
LastPing = DateTime.UtcNow;
|
||||||
|
AwaitingPingResponse = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Frame.kOpcode.Close:
|
case Frame.kOpcode.Close:
|
||||||
Disconnect(Frame.kClosingReason.Normal, "Connection closed.");
|
Disconnect(Frame.kClosingReason.Normal, "Connection closed.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Frame.kOpcode.BinaryFrame:
|
||||||
|
case Frame.kOpcode.TextFrame:
|
||||||
|
case Frame.kOpcode.Continuation:
|
||||||
|
byte[] byteBuffer = new byte[0];
|
||||||
|
foreach(var frame in ReceiveFrameBuffer)
|
||||||
|
byteBuffer = byteBuffer.Concat(frame.Content).ToArray();
|
||||||
|
|
||||||
|
ReceiveFrameBuffer = new List<Frame>();
|
||||||
|
OnReceive(byteBuffer);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] byteBuffer = new byte[0];
|
|
||||||
foreach(var frame in ReceiveFrameBuffer)
|
|
||||||
byteBuffer = byteBuffer.Concat(frame.Content).ToArray();
|
|
||||||
|
|
||||||
ReceiveFrameBuffer = new List<Frame>();
|
|
||||||
OnReceive(byteBuffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemoveFromPool() {
|
||||||
|
OutsidePool = true;
|
||||||
|
}
|
||||||
|
|
||||||
public void Disconnect(string reason = null) {
|
public void Disconnect(string reason = null) {
|
||||||
Disconnect(Frame.kClosingReason.Normal, reason);
|
Disconnect(Frame.kClosingReason.Normal, reason);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace Kneesocks {
|
||||||
// 0 means never redistribute
|
// 0 means never redistribute
|
||||||
public int Tolerance { get; set; } = 0;
|
public int Tolerance { get; set; } = 0;
|
||||||
|
|
||||||
|
private bool Disposed = false;
|
||||||
private int _fullThreadCount;
|
private int _fullThreadCount;
|
||||||
private volatile bool updateFullThreadCount = true;
|
private volatile bool updateFullThreadCount = true;
|
||||||
|
|
||||||
|
@ -41,42 +42,59 @@ namespace Kneesocks {
|
||||||
CreateThread(runWithNoClients: true);
|
CreateThread(runWithNoClients: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IndexConnection(UInt64 id, T connection) {
|
public T this[UInt64 id] {
|
||||||
lock(Connections) {
|
get {
|
||||||
if(id == 0)
|
if(HasConnection(id))
|
||||||
id = (ulong)Interlocked.Increment(ref InternalCounter);
|
return Connections[id];
|
||||||
|
else return null;
|
||||||
connection.Id = id;
|
|
||||||
Connections.Add(id, connection);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvalidateConnection(UInt64 id) {
|
public bool HasConnection(UInt64 id) {
|
||||||
|
return Connections.ContainsKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IndexConnection(T connection) {
|
||||||
|
lock(Connections) {
|
||||||
|
if(connection.IsIdNull)
|
||||||
|
connection.Id = (ulong)Interlocked.Increment(ref InternalCounter);
|
||||||
|
|
||||||
|
Connections.Add(connection.Id, connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void InvalidateConnection(UInt64 id) {
|
||||||
lock(Connections) {
|
lock(Connections) {
|
||||||
Connections.Remove(id);
|
Connections.Remove(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Broadcast(byte[] message) {
|
public void Broadcast(byte[] message) {
|
||||||
|
if(Disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
lock(Connections) {
|
lock(Connections) {
|
||||||
foreach(var conn in Connections)
|
foreach(var conn in Connections)
|
||||||
conn.Value.Send(message);
|
conn.Value.Send(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddConnection(T connection, UInt64 id = 0) {
|
public bool AddConnection(T connection) {
|
||||||
|
if(Disposed)
|
||||||
|
return false;
|
||||||
|
|
||||||
lock(Threads) {
|
lock(Threads) {
|
||||||
foreach(var thread in Threads) {
|
foreach(var thread in Threads) {
|
||||||
if(thread.Stack.Count < FullThreadSize) {
|
if(thread.Stack.Count < FullThreadSize) {
|
||||||
thread.Stack.AddClient(connection);
|
thread.Stack.AddClient(connection);
|
||||||
IndexConnection(id, connection);
|
IndexConnection(connection);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MaxCount == 0 || Threads.Count < MaxCount) {
|
if(MaxCount == 0 || Threads.Count < MaxCount) {
|
||||||
CreateThread(connection);
|
CreateThread(connection);
|
||||||
IndexConnection(id, connection);
|
IndexConnection(connection);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +102,7 @@ namespace Kneesocks {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvalidateThread(Stack<T> stackRef) {
|
internal void InvalidateThread(Stack<T> stackRef) {
|
||||||
lock(Threads) {
|
lock(Threads) {
|
||||||
var ctx = Threads.FirstOrDefault(x => Object.ReferenceEquals(x.Stack, stackRef));
|
var ctx = Threads.FirstOrDefault(x => Object.ReferenceEquals(x.Stack, stackRef));
|
||||||
if(ctx != null) {
|
if(ctx != null) {
|
||||||
|
@ -120,6 +138,37 @@ namespace Kneesocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
if(Disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Disposed = true;
|
||||||
|
|
||||||
|
lock(Threads) {
|
||||||
|
foreach(var thread in Threads)
|
||||||
|
thread.Stack.StopThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
lock(Threads) {
|
||||||
|
if(Threads.Count == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lock(Connections) {
|
||||||
|
foreach(var conn in Connections) {
|
||||||
|
conn.Value.Disconnect(Frame.kClosingReason.Normal, "Server shutting down.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~Pool() {
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
class ThreadContext {
|
class ThreadContext {
|
||||||
public Thread Thread { get; set; }
|
public Thread Thread { get; set; }
|
||||||
public Stack<T> Stack { get; set; }
|
public Stack<T> Stack { get; set; }
|
||||||
|
|
|
@ -7,11 +7,11 @@ using System.Net.Sockets;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace Kneesocks {
|
namespace Kneesocks {
|
||||||
public class Server<T> where T : Connection {
|
public class Server<T> where T : Connection, new() {
|
||||||
private TcpListener Socket;
|
private TcpListener Socket;
|
||||||
private Thread Listener = null;
|
private Thread Listener = null;
|
||||||
private Pool<T> ConnectionPool = null;
|
private Pool<T> ConnectionPool = null;
|
||||||
private bool Started = false;
|
public bool Started { get; private set; } = false;
|
||||||
public UInt16 Port { get; private set; }
|
public UInt16 Port { get; private set; }
|
||||||
|
|
||||||
public Server(UInt16 port, Pool<T> pool) {
|
public Server(UInt16 port, Pool<T> pool) {
|
||||||
|
@ -39,8 +39,11 @@ namespace Kneesocks {
|
||||||
Socket.Start();
|
Socket.Start();
|
||||||
|
|
||||||
while(Started) {
|
while(Started) {
|
||||||
if(Socket.Pending())
|
if(Socket.Pending()) {
|
||||||
ConnectionPool.AddConnection((T)new Connection(Socket.AcceptTcpClient()));
|
var templatedConnection = new T();
|
||||||
|
templatedConnection.Initialize(Socket.AcceptTcpClient());
|
||||||
|
ConnectionPool.AddConnection(templatedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,14 @@ using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Kneesocks {
|
namespace Kneesocks {
|
||||||
public class Stack<T> where T : Connection {
|
internal class Stack<T> where T : Connection {
|
||||||
private Pool<T> PoolRef = null;
|
private Pool<T> PoolRef = null;
|
||||||
private List<T> Clients = new List<T>();
|
private List<T> Clients = new List<T>();
|
||||||
private bool RunWithNoClients = false;
|
private bool RunWithNoClients = false;
|
||||||
private bool Running = true;
|
private bool Running = true;
|
||||||
|
|
||||||
|
public bool Finished { get; private set; } = false;
|
||||||
|
|
||||||
public Stack(Pool<T> poolRef, T initialConnection = null) {
|
public Stack(Pool<T> poolRef, T initialConnection = null) {
|
||||||
PoolRef = poolRef;
|
PoolRef = poolRef;
|
||||||
if(initialConnection != null)
|
if(initialConnection != null)
|
||||||
|
@ -36,31 +38,26 @@ namespace Kneesocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopThread() {
|
internal void StopThread() {
|
||||||
Running = false;
|
Running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Finished { get; private set; }
|
private bool CheckIfConnected(T client) {
|
||||||
|
return !client.Disconnected && !client.OutsidePool;
|
||||||
public bool UnlistConnection(Connection connection) {
|
|
||||||
lock(Clients) {
|
|
||||||
foreach(var conn in Clients) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// USED FOR THREADING -- DO NOT CALL
|
|
||||||
public void ManageStack() {
|
public void ManageStack() {
|
||||||
while(Running && (Count > 0 || RunWithNoClients)) {
|
while(Running && (Count > 0 || RunWithNoClients)) {
|
||||||
lock(Clients) {
|
lock(Clients) {
|
||||||
for(var i = Count - 1; i >= 0 && Running; --i) {
|
for(var i = Count - 1; i >= 0 && Running; --i) {
|
||||||
var client = Clients[i];
|
var client = Clients[i];
|
||||||
var connected = !client.Disconnected;
|
var connected = CheckIfConnected(client);
|
||||||
|
|
||||||
if(connected) {
|
if(connected) {
|
||||||
try {
|
try {
|
||||||
client.Parse();
|
client.Parse();
|
||||||
|
if(CheckIfConnected(client))
|
||||||
|
connected = false;
|
||||||
} catch {
|
} catch {
|
||||||
connected = false;
|
connected = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace Square {
|
||||||
return BitConverter.ToString(bytes).Replace("-", "");
|
return BitConverter.ToString(bytes).Replace("-", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ToString(this byte[] bytes, bool isUtf8 = true) {
|
public static string GetString(this byte[] bytes, bool isUtf8 = true) {
|
||||||
return isUtf8 ? Encoding.UTF8.GetString(bytes)
|
return isUtf8 ? Encoding.UTF8.GetString(bytes)
|
||||||
: Encoding.ASCII.GetString(bytes);
|
: Encoding.ASCII.GetString(bytes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace CircleScape {
|
namespace CircleScape {
|
||||||
class ActiveConnection : Kneesocks.Connection {
|
class ActiveConnection : Kneesocks.Connection {
|
||||||
public ActiveConnection(UInt32 id, TcpClient sock) : base(id, sock) { }
|
|
||||||
public ActiveConnection(PendingConnection conn) : base(conn) { }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,25 @@ using System.Linq;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Square;
|
||||||
|
using Kneesocks;
|
||||||
|
|
||||||
namespace CircleScape {
|
namespace CircleScape {
|
||||||
class PendingConnection : Kneesocks.Connection {
|
class PendingConnection : Connection {
|
||||||
public PendingConnection(UInt32 id, TcpClient sock) : base(id, sock) { }
|
private DateTime ConnectionOpened;
|
||||||
|
|
||||||
|
protected override void OnOpen() {
|
||||||
|
ConnectionOpened = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnParse() {
|
||||||
|
if((DateTime.UtcNow - ConnectionOpened).Seconds > 60) {
|
||||||
|
Disconnect(Frame.kClosingReason.ProtocolError, "Logon request timed out.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnReceive(byte[] data) {
|
||||||
|
Console.WriteLine(Id + " says " + data.GetString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,5 +32,10 @@ namespace CircleScape {
|
||||||
|
|
||||||
ActiveConnectionsPool = new Pool<ActiveConnection>();
|
ActiveConnectionsPool = new Pool<ActiveConnection>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Dispose() {
|
||||||
|
PendingConnectionsPool.Dispose();
|
||||||
|
ActiveConnectionsPool.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue