/// <summary>
        /// This method is used to receive data from anyone
        /// The main function of this method is establishing udp-hole connections
        /// </summary>
        private void UdpAsyncSocketCallback(object o, SocketAsyncEventArgs e)
        {
            if (e.LastOperation == SocketAsyncOperation.ReceiveFrom)
            {
                try
                {
                    if (e.BytesTransferred >= 21)
                    {
                        PayloadReader pr       = new PayloadReader(e.Buffer);
                        decimal       ClientId = pr.ReadDecimal();

                        lock (Clients)
                        {
                            if (Clients.ContainsKey(ClientId))
                            {
                                SSPClient client = Clients[ClientId];
                                client.AsyncSocketCallback(o, e);
                            }
                        }
                    }
                }
                catch { }

                if (!UdpServer.ReceiveFromAsync(udpAsyncSocket))
                {
                    UdpAsyncSocketCallback(null, udpAsyncSocket);
                }
            }
        }
        internal unsafe void AsyncSocketCallback(object o, SocketAsyncEventArgs e)
        {
            if (e.LastOperation == SocketAsyncOperation.ReceiveFrom)
            {
                try
                {
                    if (e.BytesTransferred >= 21)
                    {
                        if (!Connected)
                        {
                            return; //TCP Client is disconnected so don't process UDP packets
                        }
                        //before we process the packet, does the IP/LocalPort match ?
                        if (UdpHandshaked && BitConverter.ToUInt32(this.UdpEndPoint.Address.GetAddressBytes(), 0) !=
                            BitConverter.ToUInt32(((IPEndPoint)e.RemoteEndPoint).Address.GetAddressBytes(), 0))
                        {
                            //simply skip and don't disconnect TCP
                            //I'll add later a option to the server to disconnect or not just for safety reasons ;)
                            return;
                        }

                        //decrypt traffic here
                        PayloadReader pr       = new PayloadReader(e.Buffer);
                        decimal       clientId = pr.ReadDecimal();

                        //extra check
                        if (this.ClientId != clientId)
                        {
                            return;
                        }

                        UdpPAcketId packetId  = (UdpPAcketId)pr.ReadByte();
                        uint        MessageId = pr.ReadUInteger();

                        IMessage message = null;
                        try
                        {
                            message = Connection.messageHandler.HandleUdpMessage(pr, MessageId);

                            if (message != null)
                            {
                                message.RawSize = e.BytesTransferred;
                            }
                        }
                        catch (Exception ex)
                        {
                            return;
                        }


                        //process packet
                        if (UdpHandshaked)
                        {
                            switch (packetId)
                            {
                            case UdpPAcketId.Payload:
                            {
                                //onReceiveUdpMessage(message);
                                break;
                            }
                            }
                        }
                        else
                        {
                            MsgUdpHandshake HandshakeMsg = message as MsgUdpHandshake;
                            if (HandshakeMsg != null)
                            {
                                fixed(byte *ptr = HandshakeMsg.HandshakeCode, ptr2 = this.UdpHandshakeCode)
                                {
                                    if (NativeMethods.memcmp(ptr, ptr2, (uint)this.UdpHandshakeCode.Length) == 0)
                                    {
                                        this.UdpEndPoint = e.RemoteEndPoint as IPEndPoint;
                                        Connection.SendPayload(new MsgUdpValidation(new byte[] { 0x8F, 0xFF, 0x46, 0x4F, 0x37 }), PacketId.Unknown);
                                        UdpHandshaked       = true;
                                        UdpSyncObject.Value = true;
                                        UdpSyncObject.Pulse();
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    onException(ex, ErrorType.Core);
                }

                if (PeerSide == SecureSocketProtocol2.PeerSide.Client)
                {
                    if (!UdpHandle.ReceiveFromAsync(UdpAsyncReceiveEvent))
                    {
                        AsyncSocketCallback(null, UdpAsyncReceiveEvent);
                    }
                }
            }
            else
            {
            }
        }
Пример #3
0
        public IMessage DeCacheMessage(IMessage message, PayloadReader pr, ref bool isCached, ref IMessage CachedMessage, MessageHandler msgHandler)
        {
            lock (Messages)
            {
                uint Id = msgHandler.GetMessageId(message.GetType());
                isCached = pr.ReadBool();

                if (!Messages.TryGetValue(Id, out CachedMessage) && !isCached)
                {
                    CachedMessage = (IMessage)Activator.CreateInstance(message.GetType());
                    Messages.Add(Id, (IMessage)Activator.CreateInstance(message.GetType()));

                    FieldInfo[] _fields       = message.GetType().GetFields();
                    FieldInfo[] _cachedFields = CachedMessage.GetType().GetFields();

                    for (int i = 0; i < _fields.Length; i++)
                    {
                        //de-serialize objects
                        int oldPos = pr.Offset;
                        _fields[i].SetValue(message, pr.ReadObject());
                        pr.Offset = oldPos;
                        _fields[i].SetValue(Messages[Id], pr.ReadObject());
                    }
                    return(message);
                }

                FieldInfo[] fields      = message.GetType().GetFields();
                FieldInfo[] cacheFields = CachedMessage.GetType().GetFields();

                for (int i = 0; i < fields.Length; i++)
                {
                    MessageCacheType CacheType = (MessageCacheType)pr.ReadByte();
                    object           NewValue  = null;

                    switch (CacheType)
                    {
                    case MessageCacheType.Bool:
                    {
                        NewValue = pr.ReadBool();
                        break;
                    }

                    case MessageCacheType.Byte:
                    {
                        NewValue = pr.ReadByte();
                        break;
                    }

                    case MessageCacheType.ByteArray:
                    {
                        uint size = pr.ReadUInteger();
                        NewValue = pr.ReadBytes((int)size);
                        break;
                    }

                    case MessageCacheType.Decimal:
                    {
                        NewValue = pr.ReadDecimal();
                        break;
                    }

                    case MessageCacheType.Double:
                    {
                        NewValue = pr.ReadDouble();
                        break;
                    }

                    case MessageCacheType.Float:
                    {
                        NewValue = pr.ReadFloat();
                        break;
                    }

                    case MessageCacheType.Long:
                    {
                        NewValue = pr.ReadLong();
                        break;
                    }

                    case MessageCacheType.NULL:
                    {
                        NewValue = null;
                        break;
                    }

                    case MessageCacheType.OtherObject:
                    {
                        NewValue = pr.ReadObject();
                        break;
                    }

                    case MessageCacheType.Short:
                    {
                        NewValue = pr.ReadShort();
                        break;
                    }

                    case MessageCacheType.String:
                    {
                        NewValue = pr.ReadString();
                        break;
                    }

                    case MessageCacheType.Integer:
                    {
                        NewValue = pr.ReadInteger();
                        break;
                    }

                    case MessageCacheType.UInteger:
                    {
                        NewValue = pr.ReadUInteger();
                        break;
                    }

                    case MessageCacheType.ULong:
                    {
                        NewValue = pr.ReadULong();
                        break;
                    }

                    case MessageCacheType.UShort:
                    {
                        NewValue = pr.ReadUShort();
                        break;
                    }

                    case MessageCacheType.NotUpdated:
                    {
                        NewValue = cacheFields[i].GetValue(CachedMessage);
                        break;
                    }
                    }
                    fields[i].SetValue(message, NewValue);
                }
            }
            return(message);
        }