Exemple #1
0
 public virtual void Connect()
 {
     if (ServerSide)
     {
         throw new SystemException("Serverside socket cannot connect to a remote peer!");
     }
     NetSupport.DoStateCheck(IsAlive || (eventListener != null && eventListener.IsAlive), false);
     Connection = new Socket(SocketType.Stream, ProtocolType.Tcp);
     Connection.Connect(target, Port);
     Running       = true;
     eventListener = new Thread(() =>
     {
         bool cryptoEstablished = false;
         int mLen          = 0;
         Queue <byte> ibuf = new Queue <byte>();
         byte[] buffer     = new byte[bufSize];
         while (Running)
         {
             if (SyncListener(ref cryptoEstablished, ref mLen, out bool _, ibuf, buffer))
             {
                 break;
             }
         }
         if (ibuf.Count != 0)
         {
             Console.WriteLine("Client socket closed with unread data!");
         }
     })
     {
         Priority = ThreadPriority.Highest,
         Name     = $"NetClient-${target}:${Port}"
     };
     eventListener.Start();
 }
Exemple #2
0
        /// <summary>
        /// Disconnect from server
        /// </summary>
        /// <returns></returns>
        public virtual async Task <object> Disconnect()
        {
            NetSupport.DoStateCheck(IsAlive, true);
            Running = false;


            return(await new TaskFactory().StartNew <object>(() => { eventListener.Join(); return null; }));
        }
Exemple #3
0
        internal NetClient(Socket sock, RSA crypto, OnMessageRecieved handler, OnClientConnect onConn)
            : this(null, ((IPEndPoint)sock.RemoteEndPoint).Address, (short)((IPEndPoint)sock.RemoteEndPoint).Port, handler, onConn, -1)
        {
            decrypt    = crypto;
            Connection = sock;
            Running    = true;
            ServerSide = true;

            // Initiate crypto-handshake by sending public keys
            Connection.Send(NetSupport.WithHeader(crypto.Serialize()));
        }
Exemple #4
0
 public virtual void Send(byte[] message)
 {
     NetSupport.DoStateCheck(IsAlive, true);
     lock (messageBuffer) messageBuffer.Enqueue(Crypto.Encrypt(NetSupport.WithHeader(message)));
 }
Exemple #5
0
        protected internal bool SyncListener(ref bool cryptoEstablished, ref int mLen, out bool acceptedData, Queue <byte> ibuf, byte[] buffer)
        {
            if (cryptoEstablished)
            {
                lock (messageBuffer)
                {
                    foreach (byte[] message in messageBuffer)
                    {
                        Connection.Send(NetSupport.WithHeader(message));
                    }
                    messageBuffer.Clear();
                }
            }
            if (acceptedData = Connection.Available > 0)
            {
                int read = Connection.Receive(buffer);
                ibuf.EnqueueAll(buffer, 0, read);
            }
            if (mLen == 0 && ibuf.Count >= 4)
            {
                mLen = Support.ReadInt(ibuf.Dequeue(4), 0);
            }
            if (mLen != 0 && ibuf.Count >= mLen)
            {
                // Got a full message. Parse!
                byte[] message = ibuf.Dequeue(mLen);

                if (!cryptoEstablished)
                {
                    if (ServerSide)
                    {
                        try
                        {
                            if (Crypto == null)
                            {
                                Crypto = Rijndael128.Deserialize(decrypt.Decrypt(message), out int _);
                            }
                            else
                            {
                                CBC = new PCBC(Crypto, decrypt.Decrypt(message));
                            }
                        }
                        catch (Exception) {
                            Console.WriteLine("A fatal error ocurrd when attempting to establish a secure channel! Stopping...");
                            Thread.Sleep(5000);
                            Environment.Exit(-1);
                        }
                    }
                    else
                    {
                        // Reconstruct RSA object from remote public keys and use it to encrypt our serialized AES key/iv
                        RSA asymm = RSA.Deserialize(message, out int _);
                        Connection.Send(NetSupport.WithHeader(asymm.Encrypt(Crypto.Serialize())));
                        Connection.Send(NetSupport.WithHeader(asymm.Encrypt(CBC.IV)));
                    }
                    if (CBC != null)
                    {
                        cryptoEstablished = true;
                        onConn(this);
                    }
                }
                else
                {
                    // Decrypt the incoming message
                    byte[] read = Crypto.Decrypt(message);

                    // Read the decrypted message length
                    int mlenInner = Support.ReadInt(read, 0);

                    // Send the message to the handler and get a response
                    string response = handler(read.SubArray(4, 4 + mlenInner).ToUTF8String(), out bool live);

                    // Send the response (if given one) and drop the connection if the handler tells us to
                    if (response != null)
                    {
                        Connection.Send(NetSupport.WithHeader(Crypto.Encrypt(NetSupport.WithHeader(response.ToUTF8Bytes()))));
                    }
                    if (!live)
                    {
                        Running = false;
                        try
                        {
                            Connection.Close();
                        }
                        catch (Exception) { }
                        return(true);
                    }
                }

                // Reset expexted message length
                mLen = 0;
            }
            return(false);
        }