Пример #1
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;
            }
        }
Пример #2
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;
            }
        }