public SystemPacket(Header header, IMessage message, ushort ConnectionId, OperationalSocket OpSocket)
 {
     this.Header = header;
     this.Message = message;
     this.ConnectionId = ConnectionId;
     this.OpSocket = OpSocket;
 }
        /// <summary>
        /// Send data to the established connection
        /// </summary>
        /// <param name="Message">The data to send</param>
        /// <param name="Header">The Header to use for adding additional information</param>
        /// <param name="feature">The Feature that has been used for this Message</param>
        /// <param name="OpSocket">The OperationalSocket that has been used for this Message</param>
        internal int SendMessage(IMessage Message, Header Header, Feature feature = null, OperationalSocket OpSocket = null)
        {
            lock (SendLock)
            {
                if (!Connected)
                    return -1;

                if (Message == null)
                    throw new ArgumentException("Message cannot be null");
                if (Header == null)
                    throw new ArgumentException("Header cannot be null");

                ushort HeaderId = OpSocket != null ? OpSocket.Headers.GetHeaderId(Header) : Headers.GetHeaderId(Header);
                byte[] SerializedHeader = Header.Serialize(Header);

                uint messageId = OpSocket != null ? OpSocket.MessageHandler.GetMessageId(Message.GetType()) : messageHandler.GetMessageId(Message.GetType());

                if (SerializedHeader.Length >= MAX_PACKET_SIZE)
                    throw new ArgumentException("Header length cannot be greater then " + MAX_PAYLOAD);

                using (MemoryStream outStream = new MemoryStream())
                using (PayloadWriter pw = new PayloadWriter(outStream))
                {
                    pw.WriteBytes(new byte[HEADER_SIZE], 0, HEADER_SIZE); //reserve space

                    pw.WriteBytes(SerializedHeader);
                    pw.WriteUInteger(messageId);

                    int packetSize = messageHandler.EncryptMessage(this, Message, outStream);

                    if (pw.Length > MAX_PACKET_SIZE)
                        throw new OverflowException("Message size cannot be greater then " + MAX_PACKET_SIZE);

                    int PayloadLength = pw.Length - Connection.HEADER_SIZE;
                    byte CurPacketId = 0;
                    int FeatureId = feature != null ? feature.GetFeatureId() : -1;
                    ushort ConnectionId = OpSocket != null ? OpSocket.ConnectionId : (ushort)0;

                    byte checksum = 0;
                    checksum += (byte)PayloadLength;
                    checksum += CurPacketId;
                    checksum += (byte)ConnectionId;
                    checksum += (byte)HeaderId;
                    checksum += (byte)FeatureId;

                    pw.Position = 0;
                    pw.WriteThreeByteInteger(PayloadLength); //length
                    pw.WriteByte(CurPacketId); //cur packet id
                    pw.WriteUShort(ConnectionId); //Connection Id
                    pw.WriteUShort(HeaderId); //Header Id
                    pw.WriteByte(checksum);
                    pw.WriteInteger(FeatureId);

                    //encrypt the header
                    lock (HeaderEncryption)
                    {
                        HeaderEncryption.Encrypt(pw.GetBuffer(), 0, HEADER_SIZE);

                        byte[] temp = pw.GetBuffer();
                        headerConfuser.Obfuscate(ref temp, 0);
                    }

                    int SendNum = 0;

                    try
                    {
                        for (int i = 0; i < outStream.Length;)
                        {
                            int len = i + 65535 < outStream.Length ? 65535 : (int)outStream.Length - i;
                            Handle.Send(outStream.GetBuffer(), i, len, SocketFlags.None);
                            i += len;
                            SendNum += len;
                        }
                    }
                    catch (Exception ex)
                    {
                        Disconnect();
                        return -1;
                    }

                    SysLogger.Log("Send " + outStream.Length, SysLogType.Network);

                    PacketsOut++;
                    DataOut += (ulong)outStream.Length;
                    this.LastPacketSendSW = Stopwatch.StartNew();
                    return SendNum;
                }

                /*using (OptimizedPayloadStream ms = new OptimizedPayloadStream(SerializedHeader, HeaderId, feature, OpSocket))
                {
                    ms.Write(BitConverter.GetBytes(messageId), 0, 4);

                    MemoryStream stream = ms.PayloadFrames[ms.PayloadFrames.Count - 1];

                    int ReservedPos = (int)stream.Position;
                    ms.Write(new byte[3], 0, 3); //reserve space

                    ms.WritingMessage = true;
                    Serializer.Serialize(ms, Message);
                    ms.WritingMessage = false;

                    using (PayloadWriter pw = new PayloadWriter(new MemoryStream(stream.GetBuffer())))
                    {
                        pw.Position = ReservedPos; //skip MessageId data
                        pw.WriteThreeByteInteger(ms.MessageLength);//Reserved Space + MessageId = 7
                    }
                    ms.Commit(this);

                    for (int i = 0; i < ms.PayloadFrames.Count; i++)
                    {
                        stream = ms.PayloadFrames[i];

                        lock (HeaderEncryption)
                        {
                            HeaderEncryption.Encrypt(stream.GetBuffer(), 0, HEADER_SIZE);

                            byte[] temp = stream.GetBuffer();
                            headerConfuser.Obfuscate(ref temp, 0);
                        }
                        //lock (PayloadEncryption)
                        //{
                        //    PayloadEncryption.Encrypt(stream.GetBuffer(), HEADER_SIZE, (int)stream.Length - HEADER_SIZE);
                        //}

                        Handle.Send(stream.GetBuffer(), 0, (int)stream.Length, SocketFlags.None);
                    }
                }*/
            }
        }
 public override void ProcessPayload(SecureSocketProtocol3.SSPClient client, OperationalSocket OpSocket)
 {
 }
 public override void onOperationalSocket_Connected(OperationalSocket OPSocket)
 {
 }
 public override void onOperationalSocket_BeforeConnect(OperationalSocket OPSocket)
 {
 }
 public override void onOperationalSocket_Disconnected(OperationalSocket OPSocket, DisconnectReason Reason)
 {
 }
 internal bool RegisteredOperationalSocket(OperationalSocket opSocket)
 {
     lock (Connection.RegisteredOperationalSockets)
     {
         return Connection.RegisteredOperationalSockets.ContainsKey(opSocket.GetIdentifier());
     }
 }
 public void RegisterOperationalSocket(OperationalSocket opSocket)
 {
     lock (Connection.RegisteredOperationalSockets)
     {
         if (Connection.RegisteredOperationalSockets.ContainsKey(opSocket.GetIdentifier()))
             throw new Exception("This operational socket is already registered, conflict?");
         Connection.RegisteredOperationalSockets.Add(opSocket.GetIdentifier(), opSocket.GetType());
     }
 }
 public abstract void onOperationalSocket_Disconnected(OperationalSocket OPSocket, DisconnectReason Reason);
 public abstract void onOperationalSocket_Connected(OperationalSocket OPSocket);
 public abstract void onOperationalSocket_BeforeConnect(OperationalSocket OPSocket);
Example #12
0
        /// <summary>
        /// Send data to the established connection
        /// </summary>
        /// <param name="Message">The data to send</param>
        /// <param name="Header">The Header to use for adding additional information</param>
        /// <param name="feature">The Feature that has been used for this Message</param>
        /// <param name="OpSocket">The OperationalSocket that has been used for this Message</param>
        internal int SendMessage(IMessage Message, Header Header, Feature feature = null, OperationalSocket OpSocket = null)
        {
            lock (SendLock)
            {
                if (!Connected)
                {
                    return(-1);
                }

                if (Message == null)
                {
                    throw new ArgumentException("Message cannot be null");
                }
                if (Header == null)
                {
                    throw new ArgumentException("Header cannot be null");
                }

                ushort HeaderId = OpSocket != null?OpSocket.Headers.GetHeaderId(Header) : Headers.GetHeaderId(Header);

                byte[] SerializedHeader = Header.Serialize(Header);

                uint messageId = OpSocket != null?OpSocket.MessageHandler.GetMessageId(Message.GetType()) : messageHandler.GetMessageId(Message.GetType());

                if (SerializedHeader.Length >= MAX_PACKET_SIZE)
                {
                    throw new ArgumentException("Header length cannot be greater then " + MAX_PAYLOAD);
                }

                using (MemoryStream outStream = new MemoryStream())
                    using (PayloadWriter pw = new PayloadWriter(outStream))
                    {
                        pw.WriteBytes(new byte[HEADER_SIZE], 0, HEADER_SIZE); //reserve space

                        pw.WriteBytes(SerializedHeader);
                        pw.WriteUInteger(messageId);

                        int packetSize = messageHandler.EncryptMessage(this, Message, outStream);

                        if (pw.Length > MAX_PACKET_SIZE)
                        {
                            throw new OverflowException("Message size cannot be greater then " + MAX_PACKET_SIZE);
                        }

                        int  PayloadLength = pw.Length - Connection.HEADER_SIZE;
                        byte CurPacketId   = 0;
                        int  FeatureId     = feature != null?feature.GetFeatureId() : -1;

                        ushort ConnectionId = OpSocket != null ? OpSocket.ConnectionId : (ushort)0;

                        byte checksum = 0;
                        checksum += (byte)PayloadLength;
                        checksum += CurPacketId;
                        checksum += (byte)ConnectionId;
                        checksum += (byte)HeaderId;
                        checksum += (byte)FeatureId;

                        pw.Position = 0;
                        pw.WriteThreeByteInteger(PayloadLength); //length
                        pw.WriteByte(CurPacketId);               //cur packet id
                        pw.WriteUShort(ConnectionId);            //Connection Id
                        pw.WriteUShort(HeaderId);                //Header Id
                        pw.WriteByte(checksum);
                        pw.WriteInteger(FeatureId);

                        //encrypt the header
                        lock (HeaderEncryption)
                        {
                            HeaderEncryption.Encrypt(pw.GetBuffer(), 0, HEADER_SIZE);

                            byte[] temp = pw.GetBuffer();
                            headerConfuser.Obfuscate(ref temp, 0);
                        }

                        int SendNum = 0;

                        try
                        {
                            for (int i = 0; i < outStream.Length;)
                            {
                                int len = i + 65535 < outStream.Length ? 65535 : (int)outStream.Length - i;
                                Handle.Send(outStream.GetBuffer(), i, len, SocketFlags.None);
                                i       += len;
                                SendNum += len;
                            }
                        }
                        catch (Exception ex)
                        {
                            Disconnect();
                            return(-1);
                        }

                        SysLogger.Log("Send " + outStream.Length, SysLogType.Network);

                        PacketsOut++;
                        DataOut += (ulong)outStream.Length;
                        this.LastPacketSendSW = Stopwatch.StartNew();
                        return(SendNum);
                    }


                /*using (OptimizedPayloadStream ms = new OptimizedPayloadStream(SerializedHeader, HeaderId, feature, OpSocket))
                 * {
                 *  ms.Write(BitConverter.GetBytes(messageId), 0, 4);
                 *
                 *  MemoryStream stream = ms.PayloadFrames[ms.PayloadFrames.Count - 1];
                 *
                 *  int ReservedPos = (int)stream.Position;
                 *  ms.Write(new byte[3], 0, 3); //reserve space
                 *
                 *  ms.WritingMessage = true;
                 *  Serializer.Serialize(ms, Message);
                 *  ms.WritingMessage = false;
                 *
                 *  using (PayloadWriter pw = new PayloadWriter(new MemoryStream(stream.GetBuffer())))
                 *  {
                 *      pw.Position = ReservedPos; //skip MessageId data
                 *      pw.WriteThreeByteInteger(ms.MessageLength);//Reserved Space + MessageId = 7
                 *  }
                 *  ms.Commit(this);
                 *
                 *  for (int i = 0; i < ms.PayloadFrames.Count; i++)
                 *  {
                 *      stream = ms.PayloadFrames[i];
                 *
                 *      lock (HeaderEncryption)
                 *      {
                 *          HeaderEncryption.Encrypt(stream.GetBuffer(), 0, HEADER_SIZE);
                 *
                 *          byte[] temp = stream.GetBuffer();
                 *          headerConfuser.Obfuscate(ref temp, 0);
                 *      }
                 *      //lock (PayloadEncryption)
                 *      //{
                 *      //    PayloadEncryption.Encrypt(stream.GetBuffer(), HEADER_SIZE, (int)stream.Length - HEADER_SIZE);
                 *      //}
                 *
                 *      Handle.Send(stream.GetBuffer(), 0, (int)stream.Length, SocketFlags.None);
                 *  }
                 * }*/
            }
        }
Example #13
0
        private void AynsReceive(IAsyncResult result)
        {
            int BytesTransferred = -1;

            try
            {
                BytesTransferred = Handle.EndReceive(result);

                SysLogger.Log("Received " + BytesTransferred, SysLogType.Network);

                if (BytesTransferred <= 0)
                {
                    Disconnect();
                    return;
                }
            }
            catch (Exception ex)
            {
                SysLogger.Log(ex.Message, SysLogType.Error);
                Disconnect();
                return;
            }

            try
            {
                //let's check the certificate
                if (Client.Server != null && Client.Server.serverProperties != null)
                {
                    if (Client.ConnectionTime > Client.Server.serverProperties.ClientTimeConnected)
                    {
                        //we need to wait till the time is right
                        Disconnect();
                        return;
                    }
                }

                this.LastPacketRecvSW = Stopwatch.StartNew();
                ReadableDataLen      += BytesTransferred;
                DataIn += (ulong)BytesTransferred;
                bool Process = true;

                while (Process)
                {
                    if (ReceiveState == ReceiveType.Header)
                    {
                        Process = ReadableDataLen >= HEADER_SIZE;
                        if (ReadableDataLen >= HEADER_SIZE)
                        {
                            lock (HeaderEncryption)
                            {
                                headerConfuser.Deobfuscate(ref Buffer, ReadOffset);
                                HeaderEncryption.Decrypt(Buffer, ReadOffset, HEADER_SIZE);
                            }

                            using (PayloadReader pr = new PayloadReader(Buffer))
                            {
                                pr.Position    = ReadOffset;
                                PayloadLen     = pr.ReadThreeByteInteger();
                                CurPacketId    = pr.ReadByte();
                                ConnectionId   = pr.ReadUShort();
                                HeaderId       = pr.ReadUShort();
                                HeaderChecksum = pr.ReadByte();
                                FeatureId      = pr.ReadInteger();
                            }

                            byte ReChecksum = 0; //re-calculate the checksum
                            ReChecksum += (byte)PayloadLen;
                            ReChecksum += CurPacketId;
                            ReChecksum += (byte)ConnectionId;
                            ReChecksum += (byte)HeaderId;
                            ReChecksum += (byte)FeatureId;

                            if (ReChecksum != HeaderChecksum ||
                                PayloadLen >= MAX_PACKET_SIZE ||
                                PayloadLen < 0)
                            {
                                Disconnect();
                                return;
                            }

                            if (PayloadLen > Buffer.Length)
                            {
                                ResizeBuffer(PayloadLen);
                            }

                            TotalReceived    = HEADER_SIZE;
                            ReadableDataLen -= HEADER_SIZE;
                            ReadOffset      += HEADER_SIZE;
                            ReceiveState     = ReceiveType.Payload;
                        }
                    }
                    else if (ReceiveState == ReceiveType.Payload)
                    {
                        Process = ReadableDataLen >= PayloadLen;
                        if (ReadableDataLen >= PayloadLen)
                        {
                            byte[] DecryptedBuffer  = null;
                            int    DecryptedBuffLen = 0;

                            messageHandler.DecryptMessage(this, Buffer, ReadOffset, PayloadLen, ref DecryptedBuffer, ref DecryptedBuffLen);

                            if (DecryptedBuffer == null)
                            {
                                //failed to decrypt data
                                Disconnect();
                                return;
                            }

                            TotalReceived += PayloadLen;

                            using (PayloadReader pr = new PayloadReader(DecryptedBuffer))
                            {
                                OperationalSocket OpSocket = null;
                                if (ConnectionId > 0)
                                {
                                    lock (OperationalSockets)
                                    {
                                        if (!OperationalSockets.TryGetValue(ConnectionId, out OpSocket))
                                        {
                                            //strange...
                                            Disconnect();
                                            return;
                                        }
                                    }
                                }

                                Type type = Headers.GetHeaderType(HeaderId);

                                if (type != null)
                                {
                                    Header header = Header.DeSerialize(type, pr);

                                    if (header == null)
                                    {
                                        Disconnect();
                                        return;
                                    }

                                    uint     MessageId = pr.ReadUInteger();
                                    IMessage message   = OpSocket != null?OpSocket.MessageHandler.DeSerialize(pr, MessageId) : messageHandler.DeSerialize(pr, MessageId);

                                    if (message != null)
                                    {
                                        message.RawSize = TotalReceived;
                                        message.Header  = header;

                                        if (!HandShakeCompleted)
                                        {
                                            if (message.GetType() == typeof(MsgHandshake))
                                            {
                                                //process the handshake messages straight away
                                                message.ProcessPayload(Client, null);
                                            }
                                        }
                                        else
                                        {
                                            ProcessMessage(new SystemPacket(header, message, ConnectionId, OpSocket));
                                        }
                                    }
                                }
                                else
                                {
                                    Disconnect();
                                    return;
                                }
                            }
                            TotalReceived = 0;

                            PacketsIn++;
                            ReadOffset      += PayloadLen;
                            ReadableDataLen -= PayloadLen;
                            ReceiveState     = ReceiveType.Header;
                        }
                    }
                }

                int len = ReceiveState == ReceiveType.Header ? HEADER_SIZE : PayloadLen;
                if (ReadOffset + len >= this.Buffer.Length)
                {
                    //no more room for this data size, at the end of the buffer ?

                    //copy the buffer to the beginning
                    Array.Copy(this.Buffer, ReadOffset, this.Buffer, 0, ReadableDataLen);

                    WriteOffset = ReadableDataLen;
                    ReadOffset  = 0;
                }
                else
                {
                    //payload fits in the buffer from the current offset
                    //use BytesTransferred to write at the end of the payload
                    //so that the data is not split
                    WriteOffset += BytesTransferred;
                }

                if (Buffer.Length - WriteOffset > 0)
                {
                    Handle.BeginReceive(this.Buffer, WriteOffset, Buffer.Length - WriteOffset, SocketFlags.None, AynsReceive, null);
                }
                else
                {
                    //Shoudln't be even possible... very strange
                    Disconnect();
                }
            }
            catch (Exception ex)
            {
                //unexpected error, client might have disconnected itself, or else report this error
                SysLogger.Log(ex.Message, SysLogType.Error);
                Disconnect();
                return;
            }
        }