fixing protocol
other stuff too
This commit is contained in:
parent
4e89dcab07
commit
6cfb66a2b3
15 changed files with 116 additions and 176 deletions
25
protocol.md
25
protocol.md
|
@ -1,12 +1,3 @@
|
|||
<style type="text/css">
|
||||
.right { text-align: right; }
|
||||
.center { text-align: center; }
|
||||
.left { text-align: left; }
|
||||
table { margin-right: 8px; }
|
||||
td { text-align: center; }
|
||||
.flex { display: flex; flex-wrap: wrap; }
|
||||
</style>
|
||||
|
||||
# PROTOCOL DEFINITION
|
||||
|
||||
Messages communicated between the client and server follow the same format, but have different meanings depending on which end is the recipient. A message's intent is determined by its packet ID, a unique identifier that tells the client or server how it should react to the received message. A message id that incites bidirectional communication between the client and server should typically be associated with the same message id on the client as on the server, so as to avoid confusion.
|
||||
|
@ -46,7 +37,7 @@ A packet ID may have a specific "direction" of communication, in that an endpoin
|
|||
|
||||
#### Server to Client
|
||||
|
||||
<div class="flex">
|
||||
<div style="display: flex; flex-wrap: wrap;">
|
||||
<!--
|
||||
<table class="float">
|
||||
<thead>
|
||||
|
@ -86,7 +77,7 @@ A packet ID may have a specific "direction" of communication, in that an endpoin
|
|||
</tr>
|
||||
</table>
|
||||
-->
|
||||
<table>
|
||||
<table style="margin-right: 8px; margin-bottom: 8px;">
|
||||
<thead>
|
||||
<th colspan="100" class="center">
|
||||
ID 0: Key Exchange<br />
|
||||
|
@ -115,7 +106,7 @@ A packet ID may have a specific "direction" of communication, in that an endpoin
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<table style="margin-right: 8px; margin-bottom: 8px;">
|
||||
<thead>
|
||||
<th colspan="100" class="center">
|
||||
ID 1: Login Attempt<br />
|
||||
|
@ -144,7 +135,7 @@ A packet ID may have a specific "direction" of communication, in that an endpoin
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<table style="margin-right: 8px; margin-bottom: 8px;">
|
||||
<thead>
|
||||
<th colspan="100" class="center">
|
||||
ID 2: Registration Attempt<br />
|
||||
|
@ -176,8 +167,8 @@ A packet ID may have a specific "direction" of communication, in that an endpoin
|
|||
|
||||
#### Client to Server
|
||||
|
||||
<div class="flex">
|
||||
<table>
|
||||
<div style="display: flex; flex-wrap: wrap;">
|
||||
<table style="margin-right: 8px; margin-bottom: 8px;">
|
||||
<thead>
|
||||
<th colspan="100" class="center">
|
||||
ID 0: Key Exchange<br />
|
||||
|
@ -196,7 +187,7 @@ A packet ID may have a specific "direction" of communication, in that an endpoin
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<table style="margin-right: 8px; margin-bottom: 8px;">
|
||||
<thead>
|
||||
<th colspan="100" class="center">
|
||||
ID 1: Login Attempt<br />
|
||||
|
@ -225,7 +216,7 @@ A packet ID may have a specific "direction" of communication, in that an endpoin
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<table style="margin-right: 8px; margin-bottom: 8px;">
|
||||
<thead>
|
||||
<th colspan="100" class="center">
|
||||
ID 2: Registration Attempt<br />
|
||||
|
|
|
@ -11,16 +11,28 @@ namespace CircleScape.Encryption {
|
|||
private BigInteger Secret;
|
||||
public BigInteger Generator { get; private set; } = 2;
|
||||
public BigInteger Modulus { get; private set; }
|
||||
public BigInteger PrivateKey { get; private set; } = BigInteger.MinusOne;
|
||||
public BigInteger PrivateKey { get; private set; } = BigInteger.Zero;
|
||||
public bool Succeeded {
|
||||
get => !PrivateKey.IsZero;
|
||||
}
|
||||
|
||||
public KeyExchange() {
|
||||
Secret = RNG.NextPrime(512 / 8);
|
||||
Modulus = RNG.NextPrime(512 / 8);
|
||||
}
|
||||
|
||||
public Packet GenerateInitialPacket() {
|
||||
public Packet GenerateRequestPacket() {
|
||||
return new Packet(Packet.kId.KeyExchange, Generator.ToHexString(), Modulus.ToHexString(), BigInteger.ModPow(Generator, Secret, Modulus).ToHexString());
|
||||
}
|
||||
|
||||
return
|
||||
public BigInteger ParseResponsePacket(Packet packet) {
|
||||
if(packet.Id == Packet.kId.KeyExchange && packet.RegionCount != 1)
|
||||
return -1;
|
||||
|
||||
if(!BigInteger.TryParse(packet[0], out BigInteger ClientKey))
|
||||
return -1;
|
||||
|
||||
return (PrivateKey = BigInteger.ModPow(ClientKey, Secret, Modulus));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,7 @@ namespace Kneesocks {
|
|||
}
|
||||
}
|
||||
internal bool IsIdNull {
|
||||
get {
|
||||
return _Id == null;
|
||||
}
|
||||
get => _Id == null;
|
||||
}
|
||||
|
||||
private TcpClient Socket = null;
|
||||
|
@ -47,9 +45,7 @@ namespace Kneesocks {
|
|||
private DateTime LastPing;
|
||||
private bool AwaitingPingResponse = false;
|
||||
private TimeSpan TimeSinceLastPing {
|
||||
get {
|
||||
return DateTime.UtcNow - LastPing;
|
||||
}
|
||||
get => DateTime.UtcNow - LastPing;
|
||||
}
|
||||
|
||||
internal bool OutsidePool = false;
|
||||
|
@ -322,13 +318,9 @@ namespace Kneesocks {
|
|||
}
|
||||
}
|
||||
|
||||
public void RemoveFromPool() {
|
||||
OutsidePool = true;
|
||||
}
|
||||
public void RemoveFromPool() => OutsidePool = true;
|
||||
|
||||
public void Disconnect(string reason = null) {
|
||||
Disconnect(Frame.kClosingReason.Normal, reason);
|
||||
}
|
||||
public void Disconnect(string reason = null) => Disconnect(Frame.kClosingReason.Normal, reason);
|
||||
|
||||
public void Disconnect(Frame.kClosingReason status, string reason = null) {
|
||||
Disconnected = true;
|
||||
|
|
|
@ -50,9 +50,7 @@ namespace Kneesocks {
|
|||
|
||||
private int _BodyLength = 0;
|
||||
public int BodyLength {
|
||||
get {
|
||||
return Content == null ? _BodyLength : Content.Length;
|
||||
}
|
||||
get => Content == null ? _BodyLength : Content.Length;
|
||||
}
|
||||
|
||||
public byte[] Content { get; set; } = null;
|
||||
|
|
|
@ -31,9 +31,7 @@ namespace Kneesocks {
|
|||
}
|
||||
public kStatusCode? StatusCode { get; private set; } = null;
|
||||
protected string StatusCodeText {
|
||||
get {
|
||||
return Enum.GetName(typeof(kStatusCode), StatusCode).Replace('_', ' ');
|
||||
}
|
||||
get => Enum.GetName(typeof(kStatusCode), StatusCode).Replace('_', ' ');
|
||||
}
|
||||
|
||||
private Dictionary<string, string> Headers =
|
||||
|
@ -90,13 +88,10 @@ namespace Kneesocks {
|
|||
return shake;
|
||||
}
|
||||
|
||||
public static Handshake DenyRequest(kStatusCode statusCode = kStatusCode.Bad_Request, string message = "Handshake failed.") {
|
||||
return new Handshake(statusCode, message);
|
||||
}
|
||||
public static Handshake DenyRequest(kStatusCode statusCode = kStatusCode.Bad_Request, string message = "Handshake failed.")
|
||||
=> new Handshake(statusCode, message);
|
||||
|
||||
public byte[] ToBytes() {
|
||||
return ToString().GetBytes();
|
||||
}
|
||||
public byte[] ToBytes() => ToString().GetBytes();
|
||||
|
||||
public override string ToString() {
|
||||
if(IsRequest)
|
||||
|
@ -114,9 +109,7 @@ namespace Kneesocks {
|
|||
return raw += "\r\n";
|
||||
}
|
||||
|
||||
public bool HasHeader(string name) {
|
||||
return Headers.ContainsKey(name);
|
||||
}
|
||||
public bool HasHeader(string name) => Headers.ContainsKey(name);
|
||||
|
||||
public string GetHeader(string name) {
|
||||
if(Headers.ContainsKey(name))
|
||||
|
|
|
@ -50,9 +50,7 @@ namespace Kneesocks {
|
|||
}
|
||||
}
|
||||
|
||||
public bool HasConnection(UInt64 id) {
|
||||
return Connections.ContainsKey(id);
|
||||
}
|
||||
public bool HasConnection(UInt64 id) => Connections.ContainsKey(id);
|
||||
|
||||
private void IndexConnection(T connection) {
|
||||
lock(Connections) {
|
||||
|
|
|
@ -23,9 +23,7 @@ namespace Kneesocks {
|
|||
}
|
||||
|
||||
public TimeSpan ElapsedReadTime {
|
||||
get {
|
||||
return DateTime.UtcNow - StartTime;
|
||||
}
|
||||
get => DateTime.UtcNow - StartTime;
|
||||
}
|
||||
|
||||
private byte[] CheckBuffer() {
|
||||
|
|
|
@ -33,18 +33,13 @@ namespace Kneesocks {
|
|||
}
|
||||
|
||||
public int Count {
|
||||
get {
|
||||
return Clients.Count;
|
||||
}
|
||||
get => Clients.Count;
|
||||
}
|
||||
|
||||
internal void StopThread() {
|
||||
Running = false;
|
||||
}
|
||||
internal void StopThread() => Running = false;
|
||||
|
||||
private bool CheckIfConnected(T client) {
|
||||
return !client.Disconnected && !client.OutsidePool;
|
||||
}
|
||||
private bool CheckIfConnected(T client)
|
||||
=> !client.Disconnected && !client.OutsidePool;
|
||||
|
||||
public void ManageStack() {
|
||||
while(Running && (Count > 0 || RunWithNoClients)) {
|
||||
|
|
|
@ -23,18 +23,15 @@ namespace Square {
|
|||
}
|
||||
|
||||
public static class ByteArrayExtensions {
|
||||
public static string Base64Encode(this byte[] bytes) {
|
||||
return Convert.ToBase64String(bytes);
|
||||
}
|
||||
public static string Base64Encode(this byte[] bytes)
|
||||
=> Convert.ToBase64String(bytes);
|
||||
|
||||
public static string ToHexString(this byte[] bytes) {
|
||||
return BitConverter.ToString(bytes).Replace("-", "");
|
||||
}
|
||||
public static string ToHexString(this byte[] bytes)
|
||||
=> BitConverter.ToString(bytes).Replace("-", "");
|
||||
|
||||
public static string GetString(this byte[] bytes, bool isUtf8 = true) {
|
||||
return isUtf8 ? Encoding.UTF8.GetString(bytes)
|
||||
public static string GetString(this byte[] bytes, bool isUtf8 = true)
|
||||
=> isUtf8 ? Encoding.UTF8.GetString(bytes)
|
||||
: Encoding.ASCII.GetString(bytes);
|
||||
}
|
||||
|
||||
public static byte[] HostToNetworkOrder(this byte[] bytes) {
|
||||
if(BitConverter.IsLittleEndian)
|
||||
|
@ -50,36 +47,28 @@ namespace Square {
|
|||
return bytes;
|
||||
}
|
||||
|
||||
public static Single UnpackFloat(this byte[] bytes) {
|
||||
return BitConverter.ToSingle(bytes.NetworkToHostOrder(), 0);
|
||||
}
|
||||
public static Single UnpackFloat(this byte[] bytes)
|
||||
=> BitConverter.ToSingle(bytes.NetworkToHostOrder(), 0);
|
||||
|
||||
public static Double UnpackDouble(this byte[] bytes) {
|
||||
return BitConverter.ToDouble(bytes.NetworkToHostOrder(), 0);
|
||||
}
|
||||
public static Double UnpackDouble(this byte[] bytes)
|
||||
=> BitConverter.ToDouble(bytes.NetworkToHostOrder(), 0);
|
||||
|
||||
public static Int16 UnpackInt16(this byte[] bytes) {
|
||||
return BitConverter.ToInt16(bytes.NetworkToHostOrder(), 0);
|
||||
}
|
||||
public static Int16 UnpackInt16(this byte[] bytes)
|
||||
=> BitConverter.ToInt16(bytes.NetworkToHostOrder(), 0);
|
||||
|
||||
public static UInt16 UnpackUInt16(this byte[] bytes) {
|
||||
return BitConverter.ToUInt16(bytes.NetworkToHostOrder(), 0);
|
||||
}
|
||||
public static UInt16 UnpackUInt16(this byte[] bytes)
|
||||
=> BitConverter.ToUInt16(bytes.NetworkToHostOrder(), 0);
|
||||
|
||||
public static Int32 UnpackInt32(this byte[] bytes) {
|
||||
return BitConverter.ToInt32(bytes.NetworkToHostOrder(), 0);
|
||||
}
|
||||
public static Int32 UnpackInt32(this byte[] bytes)
|
||||
=> BitConverter.ToInt32(bytes.NetworkToHostOrder(), 0);
|
||||
|
||||
public static UInt32 UnpackUInt32(this byte[] bytes) {
|
||||
return BitConverter.ToUInt32(bytes.NetworkToHostOrder(), 0);
|
||||
}
|
||||
public static UInt32 UnpackUInt32(this byte[] bytes)
|
||||
=> BitConverter.ToUInt32(bytes.NetworkToHostOrder(), 0);
|
||||
|
||||
public static Int64 UnpackInt64(this byte[] bytes) {
|
||||
return BitConverter.ToInt64(bytes.NetworkToHostOrder(), 0);
|
||||
}
|
||||
public static Int64 UnpackInt64(this byte[] bytes)
|
||||
=> BitConverter.ToInt64(bytes.NetworkToHostOrder(), 0);
|
||||
|
||||
public static UInt64 UnpackUInt64(this byte[] bytes) {
|
||||
return BitConverter.ToUInt64(bytes.NetworkToHostOrder(), 0);
|
||||
}
|
||||
public static UInt64 UnpackUInt64(this byte[] bytes)
|
||||
=> BitConverter.ToUInt64(bytes.NetworkToHostOrder(), 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,8 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Square {
|
||||
public static class CryptoExtensions {
|
||||
public static byte[] SHA1(this string str) {
|
||||
return Encoding.UTF8.GetBytes(str).SHA1();
|
||||
}
|
||||
public static byte[] SHA1(this string str)
|
||||
=> Encoding.UTF8.GetBytes(str).SHA1();
|
||||
|
||||
public static byte[] SHA1(this byte[] bytes) {
|
||||
using(var hasher = new SHA1CryptoServiceProvider()) {
|
||||
|
@ -17,9 +16,8 @@ namespace Square {
|
|||
}
|
||||
}
|
||||
|
||||
public static byte[] MD5(this string str) {
|
||||
return Encoding.UTF8.GetBytes(str).MD5();
|
||||
}
|
||||
public static byte[] MD5(this string str)
|
||||
=> Encoding.UTF8.GetBytes(str).MD5();
|
||||
|
||||
public static byte[] MD5(this byte[] bytes) {
|
||||
using(var hasher = new MD5CryptoServiceProvider()) {
|
||||
|
|
|
@ -8,37 +8,29 @@ using System.Globalization;
|
|||
|
||||
namespace Square {
|
||||
public static class NumericExtensions {
|
||||
public static byte[] Pack(this Single value) {
|
||||
return BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
}
|
||||
public static byte[] Pack(this Single value)
|
||||
=> BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
|
||||
public static byte[] Pack(this Double value) {
|
||||
return BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
}
|
||||
public static byte[] Pack(this Double value)
|
||||
=> BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
|
||||
public static byte[] Pack(this Int16 value) {
|
||||
return BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
}
|
||||
public static byte[] Pack(this Int16 value)
|
||||
=> BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
|
||||
public static byte[] Pack(this UInt16 value) {
|
||||
return BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
}
|
||||
public static byte[] Pack(this UInt16 value)
|
||||
=> BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
|
||||
public static byte[] Pack(this Int32 value) {
|
||||
return BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
}
|
||||
public static byte[] Pack(this Int32 value)
|
||||
=> BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
|
||||
public static byte[] Pack(this UInt32 value) {
|
||||
return BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
}
|
||||
public static byte[] Pack(this UInt32 value)
|
||||
=> BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
|
||||
public static byte[] Pack(this Int64 value) {
|
||||
return BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
}
|
||||
public static byte[] Pack(this Int64 value)
|
||||
=> BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
|
||||
public static byte[] Pack(this UInt64 value) {
|
||||
return BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
}
|
||||
public static byte[] Pack(this UInt64 value)
|
||||
=> BitConverter.GetBytes(value).HostToNetworkOrder();
|
||||
|
||||
public static bool IsDivisibleBy(this BigInteger value, BigInteger dividend) {
|
||||
if(value.IsZero) return false;
|
||||
|
@ -63,12 +55,10 @@ namespace Square {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static string ToHexString(this BigInteger value) {
|
||||
return value.ToString("X").ToLower();
|
||||
}
|
||||
public static string ToHexString(this BigInteger value)
|
||||
=> value.ToString("X").ToLower();
|
||||
|
||||
public static BigInteger HexStringToBigInt(this string value) {
|
||||
return BigInteger.Parse(value, NumberStyles.HexNumber);
|
||||
}
|
||||
public static BigInteger HexStringToBigInt(this string value)
|
||||
=> BigInteger.Parse(value, NumberStyles.HexNumber);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,8 +67,7 @@ namespace Square {
|
|||
return minValue + (randomNumber % delta);
|
||||
}
|
||||
|
||||
public static BigInteger NextBigInt(int byteCount) {
|
||||
return BigInteger.Abs(new BigInteger(NextBytes(byteCount)));
|
||||
}
|
||||
public static BigInteger NextBigInt(int byteCount)
|
||||
=> BigInteger.Abs(new BigInteger(NextBytes(byteCount)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,15 +6,13 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Square {
|
||||
public static class StringExtensions {
|
||||
public static byte[] GetBytes(this string str, bool isUtf8 = true) {
|
||||
return isUtf8 ? Encoding.UTF8.GetBytes(str)
|
||||
public static byte[] GetBytes(this string str, bool isUtf8 = true)
|
||||
=> isUtf8 ? Encoding.UTF8.GetBytes(str)
|
||||
: Encoding.ASCII.GetBytes(str);
|
||||
}
|
||||
|
||||
public static int ByteLength(this string str, bool isUtf8 = true) {
|
||||
return isUtf8 ? Encoding.UTF8.GetByteCount(str)
|
||||
public static int ByteLength(this string str, bool isUtf8 = true)
|
||||
=> isUtf8 ? Encoding.UTF8.GetByteCount(str)
|
||||
: Encoding.ASCII.GetByteCount(str);
|
||||
}
|
||||
|
||||
public static string Base64Encode(this string str, bool isUtf8 = true) {
|
||||
var raw =
|
||||
|
@ -29,8 +27,7 @@ namespace Square {
|
|||
: Encoding.ASCII.GetString(raw);
|
||||
}
|
||||
|
||||
public static byte[] Base64DecodeRaw(this string str) {
|
||||
return Convert.FromBase64String(str);
|
||||
}
|
||||
public static byte[] Base64DecodeRaw(this string str)
|
||||
=> Convert.FromBase64String(str);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,9 +14,7 @@ namespace CircleScape {
|
|||
}
|
||||
|
||||
private static Packet ErrorPacket {
|
||||
get {
|
||||
return new Packet { IsLegal = false };
|
||||
}
|
||||
get => new Packet { IsLegal = false };
|
||||
}
|
||||
|
||||
public static Packet FromRaw(byte[] raw) {
|
||||
|
@ -68,11 +66,11 @@ namespace CircleScape {
|
|||
public kId Id { get; private set; } = kId.KeyExchange;
|
||||
public bool IsLegal { get; private set; } = true;
|
||||
public int RegionCount {
|
||||
get {
|
||||
return Regions.Count;
|
||||
}
|
||||
get => Regions.Count;
|
||||
}
|
||||
|
||||
private Packet() { }
|
||||
|
||||
public Packet(kId id, params object[] regions) {
|
||||
Id = id;
|
||||
|
||||
|
@ -85,9 +83,7 @@ namespace CircleScape {
|
|||
}
|
||||
|
||||
public Region this[int i] {
|
||||
get {
|
||||
return new Region(Regions[i]);
|
||||
}
|
||||
get => new Region(Regions[i]);
|
||||
}
|
||||
|
||||
public byte[] GetBytes() {
|
||||
|
@ -112,18 +108,15 @@ namespace CircleScape {
|
|||
|
||||
return header.Concat(body).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
class Region {
|
||||
public class Region {
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
public Region(byte[] data) {
|
||||
Data = data;
|
||||
}
|
||||
|
||||
public static implicit operator byte[](Region region) {
|
||||
return region.Data;
|
||||
}
|
||||
public static implicit operator byte[] (Region region) => region.Data;
|
||||
|
||||
public static implicit operator string(Region region) {
|
||||
try {
|
||||
|
@ -133,4 +126,5 @@ namespace CircleScape {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,14 +11,10 @@ namespace CircleScape {
|
|||
private static Pool<PendingConnection> PendingConnectionsPool;
|
||||
private static Pool<ActiveConnection> ActiveConnectionsPool;
|
||||
public static Pool<PendingConnection> Pending {
|
||||
get {
|
||||
return PendingConnectionsPool;
|
||||
}
|
||||
get => PendingConnectionsPool;
|
||||
}
|
||||
public static Pool<ActiveConnection> Active {
|
||||
get {
|
||||
return ActiveConnectionsPool;
|
||||
}
|
||||
get => ActiveConnectionsPool;
|
||||
}
|
||||
|
||||
static PoolManager() {
|
||||
|
|
Loading…
Reference in a new issue