From 8230796a1b902bc436378d00fff19d54cdda46ed Mon Sep 17 00:00:00 2001 From: Malloc of Kuzkycyziklistan Date: Thu, 31 Aug 2017 15:59:57 -0500 Subject: [PATCH] the perplexed constable in old scroll obsidian h --- protocol.md | 86 ++++++++++++++++++++++++ server/Entrypoint.cs | 16 +++-- server/ServerList.cs | 24 +++++-- server/Socks/MasterUdpClient.cs | 8 ++- server/Socks/MasterUdpServer.cs | 65 +++++++++++++++--- server/Socks/Protocols/IntraMasterIds.cs | 8 ++- server/Socks/Protocols/Packet.cs | 3 +- 7 files changed, 187 insertions(+), 23 deletions(-) diff --git a/protocol.md b/protocol.md index 49244b9..8cd9cd6 100644 --- a/protocol.md +++ b/protocol.md @@ -87,6 +87,49 @@ Communication between the master server and clients will be done over a WebSocke + + + + + + + + + + + + + + +
+ ID 2: Positive ACK
+ Responder +
#RegionType
1Request Packet IDByte
+ + + + + + + + + + + + + + + + + + + + +
+ ID 3: Negative ACK
+ Responder +
#RegionType
1Request Packet IDByte
2Error MessageString
+ #### Slave to Master @@ -127,6 +170,49 @@ Communication between the master server and clients will be done over a WebSocke
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ID 2: Status Update
+ Blind Requester +
# (r)RegionType
1Server Count (n)Unsigned Byte
r > 1Iterated over n (0 ≤ in - 1)
2 + 4iServer IdPacked Unsigned Short
3 + 4iUser CountPacked Unsigned Short
4 + 4iIPv4 AddressBytes (4)
5 + 4iPortPacked Unsigned Short
+ ### Master/Client Packet IDs #### Master to Client diff --git a/server/Entrypoint.cs b/server/Entrypoint.cs index 35c8cf3..b0ea486 100644 --- a/server/Entrypoint.cs +++ b/server/Entrypoint.cs @@ -13,15 +13,17 @@ using Kneesocks; using MySql.Data.Entity; namespace SockScape { + static class ServerContext { + public static Dictionary> Servers { get; } + = new Dictionary>(); + public static Dictionary> Pools { get; } + = new Dictionary>(); + } + class Entrypoint { static void Main(string[] args) { var db = new DAL.ScapeDb(); - Dictionary servers - = new Dictionary(); - Dictionary> pools - = new Dictionary>(); - foreach(var server in Configuration.Servers) { var pool = new Pool { InitialCount = 3, @@ -33,8 +35,8 @@ namespace SockScape { var serverHandle = new Server((ushort)server["Port"], pool, server); - pools.Add(server["Id"], pool); - servers.Add(server["Id"], serverHandle); + ServerContext.Pools.Add(server["Id"], pool); + ServerContext.Servers.Add(server["Id"], serverHandle); serverHandle.Start(); } diff --git a/server/ServerList.cs b/server/ServerList.cs index f4e2836..13e7b5b 100644 --- a/server/ServerList.cs +++ b/server/ServerList.cs @@ -6,10 +6,26 @@ using System.Text; using System.Threading.Tasks; namespace SockScape { - static class ServerList { - public static Dictionary Servers { get; private set; } - = new Dictionary(); + class ServerList { + public static Dictionary Servers { get; } + = new Dictionary(); - + public Server this[int i] { + get => Servers.ContainsKey(i) ? Servers[i] : null; + set => Servers[i] = value; + } + + public bool HasId(int id) + => Servers.ContainsKey(id); + + public void Clear() + => Servers.Clear(); + } + + class Server { + public ushort Id { get; set; } + public ushort UserCount { get; set; } + public IPEndPoint Address { get; set; } + public IPEndPoint Owner { get; set; } } } diff --git a/server/Socks/MasterUdpClient.cs b/server/Socks/MasterUdpClient.cs index 1b7d1e1..9facb0f 100644 --- a/server/Socks/MasterUdpClient.cs +++ b/server/Socks/MasterUdpClient.cs @@ -16,12 +16,13 @@ namespace SockScape { private static UdpClient Sock; private static Thread ListeningThread; private static bool IsOpen; + private static DateTime LastMessage; public static void Initialize() { if(IsOpen || ListeningThread != null) return; - short port = (short)Configuration.General["Master Port"]; + ushort port = (ushort)Configuration.General["Master Port"]; Sock = new UdpClient(Configuration.General["Master Addr"], port); Key = new Key(); @@ -41,6 +42,11 @@ namespace SockScape { } } + public static void Send(byte[] message) { + Sock.Send(message, message.Length); + LastMessage = DateTime.Now; + } + public static void Close() { IsOpen = false; ListeningThread.Join(); diff --git a/server/Socks/MasterUdpServer.cs b/server/Socks/MasterUdpServer.cs index cd81e2b..756f6d0 100644 --- a/server/Socks/MasterUdpServer.cs +++ b/server/Socks/MasterUdpServer.cs @@ -13,6 +13,7 @@ namespace SockScape { static class MasterUdpServer { private static Dictionary Prospects; private static Dictionary Clients; + private static ServerList Servers; private static UdpClient Sock; private static Thread ListeningThread; @@ -22,8 +23,11 @@ namespace SockScape { if(IsOpen || ListeningThread != null) return; + Servers = new ServerList(); + Prospects = new Dictionary(); Clients = new Dictionary(); - short port = (short)Configuration.General["Master Port"]; + + ushort port = (ushort)Configuration.General["Master Port"]; Sock = new UdpClient(new IPEndPoint(IPAddress.Any, port)); IsOpen = true; @@ -31,10 +35,6 @@ namespace SockScape { ListeningThread.Start(); } - private static bool IsClientConnected(string client) { - return Clients.ContainsKey(client); - } - public static void Listener() { while(IsOpen) { IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0); @@ -42,29 +42,59 @@ namespace SockScape { var data = Sock.Receive(ref endPoint); var client = endPoint.ToString(); var encryptor = IsClientConnected(client) ? Clients[client].Encryptor : null; + if(data.Take(Packet.MagicNumber.Length).SequenceEqual(Packet.MagicNumber)) + encryptor = null; Packet packet = encryptor == null ? Packet.FromBytes(data) : Packet.FromBytes(encryptor.Parse(data)); + if(packet == null) + break; + + byte[] sendBuffer; switch((kIntraMasterId)packet.Id) { case kIntraMasterId.InitiationAttempt: if(packet.RegionCount != 1) break; if(packet[0] == Configuration.General["Master Secret"]) { - var request = - - var request = Key.GenerateRequestPacket().GetBytes(); - Sock.Send(request, request.Length, endPoint); + var key = new Key(); + Prospects[client] = new Client { + LastReceive = DateTime.Now, + Address = endPoint, + Key = key + }; + + sendBuffer = key.GenerateRequestPacket().GetBytes(); + Sock.Send(sendBuffer, sendBuffer.Length, endPoint); } break; + case kIntraMasterId.KeyExchange: + if(!IsProspectConnected(client)) + break; + + var privateKey = Prospects[client].Key.ParseResponsePacket(packet); + if(privateKey != -1) { + Prospects[client].Encryptor = new Cipher(privateKey); + Clients[client] = Prospects[client]; + Prospects.Remove(client); + } else + Prospects.Remove(client); + break; + + case kIntraMasterId.StatusUpdate: + if(!IsClientConnected(client) || packet.RegionCount < 1) + break; + break; } } + + Thread.Sleep(1); } } @@ -75,8 +105,25 @@ namespace SockScape { ListeningThread = null; Sock.Dispose(); } + + private static bool IsProspectConnected(string client) { + return Prospects.ContainsKey(client); + } + + private static bool IsClientConnected(string client) { + return Clients.ContainsKey(client); + } + + private static Packet PositiveAck(byte id) { + return new Packet((int)kIntraMasterAckId.PositiveAck, new { id }); + } + + private static Packet NegativeAck(byte id, string message) { + return new Packet((int)kIntraMasterAckId.NegativeAck, new { id, message }); + } class Client { + public IPEndPoint Address { get; set; } public DateTime LastReceive { get; set; } public Cipher Encryptor { get; set; } public Key Key { get; set; } diff --git a/server/Socks/Protocols/IntraMasterIds.cs b/server/Socks/Protocols/IntraMasterIds.cs index 2d24c58..3e952a1 100644 --- a/server/Socks/Protocols/IntraMasterIds.cs +++ b/server/Socks/Protocols/IntraMasterIds.cs @@ -7,6 +7,12 @@ using System.Threading.Tasks; namespace SockScape { public enum kIntraMasterId { InitiationAttempt = 0, - KeyExchange + KeyExchange, + StatusUpdate + } + + public enum kIntraMasterAckId { + PositiveAck = 1, + NegativeAck } } diff --git a/server/Socks/Protocols/Packet.cs b/server/Socks/Protocols/Packet.cs index 1c54f6c..55e7da3 100644 --- a/server/Socks/Protocols/Packet.cs +++ b/server/Socks/Protocols/Packet.cs @@ -7,7 +7,8 @@ using Glove; namespace SockScape { class Packet { - private static readonly byte[] MagicNumber = { 0xF0, 0x9F, 0xA6, 0x91 }; + // (squid) + public static readonly byte[] MagicNumber = { 0xF0, 0x9F, 0xA6, 0x91 }; public static Packet FromBytes(byte[] raw) { if(raw.Length < 7)