コード例 #1
0
        public void WriteHeader(byte[] payload, int offset, int length, NetworkPayloadWriter pw)
        {
            pw.WriteThreeByteInteger(PacketSize);
            pw.WriteBool(isCompressed);
            pw.WriteBool(isCached);
            pw.WriteByte((byte)PacketID);
            pw.WriteUInteger(MessageId);
            pw.WriteULong(PluginId);
            pw.WriteBool(isPluginPacket);
            pw.WriteUShort(CurPacketId);

            if (connection.Client.Certificate != null && connection.Client.Handshaked)
            {
                Hash = HashPayload(payload, offset, length, connection.Client.Certificate.Checksum);
            }
            else
            {
                //No certificate yet, always hash with SHA512
                Hash = HashPayload(payload, offset, length, Connection.HandshakeChecksum);
            }

            pw.WriteUInteger(Hash);
            pw.WriteUInteger(ChannelId);
            pw.WriteUInteger(PeerId);

            //trash data
            byte[] tempJumk = new byte[connection.Client.HeaderJunkCount];
            new Random().NextBytes(tempJumk);
            pw.WriteBytes(tempJumk);
        }
コード例 #2
0
        public unsafe void QueuePacket(IMessage message, PacketId packetId, IPlugin plugin, Channel channel)
        {
            lock (AddQueueLock)
            {
                if (sizeCounter > MaxPacketQueueSize)
                {
                    while (packetQueue.Count > 0)
                    {
                        SendQueue();
                    }
                }

                NetworkPayloadWriter temp = message.WritePacket(message, conn);
                message.RawSize = temp.Length - conn.HEADER_SIZE;
                byte[] packet = temp.GetPayload();

                lock (packetQueue)
                {
                    packetQueue.Enqueue(new PacketQueueInfo(packet, packetId, plugin, channel, conn.messageHandler.GetMessageId(message.GetType())));
                    sizeCounter += packet.Length;
                }

                if (!threadRunning)
                {
                    threadRunning = true;
                    ThreadPool.QueueUserWorkItem((object obj) => WorkerThread());
                }
                arSizeUpdate.Set();
            }
        }
コード例 #3
0
        public byte[] ToByteArray(Connection connection)
        {
            NetworkPayloadWriter pw = new NetworkPayloadWriter(connection);

            WriteHeader(null, 0, 0, pw);
            return(pw.GetPayload());
        }
コード例 #4
0
        internal unsafe void SendPayload(IMessage message, PacketId packetId, IPlugin plugin = null, Channel channel = null)
        {
            NetworkPayloadWriter temp = message.WritePacket(message, this);

            message.RawSize = temp.Length - HEADER_SIZE;
            SendPayload(temp, messageHandler.GetMessageId(message.GetType()), packetId, plugin, channel);
        }
コード例 #5
0
        private unsafe void networkStreamCallback(Network.NetworkStream stream)
        {
            lock (stream)
            {
                bool DataAvailable = true;
                while (DataAvailable)
                {
                    switch (this.stream.ReceiveState)
                    {
                    case ReceiveType.Header:
                    {
                        if (stream.CanRead(HEADER_SIZE))
                        {
                            byte[] headerData = new byte[HEADER_SIZE];
                            if (stream.Read(ref headerData, 0, headerData.Length) > 0)
                            {
                                //wopEncryption.Decrypt(header, 0, HEADER_SIZE);
                                stream.NetworkPayload.Header = new PacketHeader(headerData, 0, this);

                                if (!DPI.Inspect(stream.NetworkPayload.Header))
                                {
                                    Client.Disconnect(DisconnectReason.DeepPacketInspectionDisconnection);
                                    return;
                                }
                                this.stream.ReceiveState = ReceiveType.Payload;
                            }
                        }
                        else
                        {
                            DataAvailable = false;
                        }
                        break;
                    }

                    case ReceiveType.Payload:
                    {
                        if (stream.CanRead(stream.NetworkPayload.Header.PacketSize))
                        {
                            int          receivedSize = stream.NetworkPayload.Header.PacketSize;
                            uint         packetSize   = (uint)stream.NetworkPayload.Header.PacketSize;
                            byte[]       payload      = stream.Buffer;
                            uint         offset       = (uint)stream.Position;
                            PacketHeader header       = stream.NetworkPayload.Header;
                            IPlugin      plugin       = null;
                            uint         GenHash      = 0;

                            if (stream.NetworkPayload.Header.PacketID == PacketId.PluginPacket)
                            {
                                plugin = pluginSystem.GetPlugin(stream.NetworkPayload.Header.PluginId);

                                if (plugin == null)
                                {
                                    throw new Exception("Plugin not found");
                                }
                            }

                            if (Client.Certificate != null)
                            {
                                GenHash = stream.NetworkPayload.Header.HashPayload(payload, (int)offset, (int)packetSize, Client.Certificate.Checksum);

                                if (stream.NetworkPayload.Header.Hash != GenHash)
                                {
                                    Client.Disconnect(DisconnectReason.DataModificationDetected);
                                    return;
                                }
                            }

                            //peer code
                            if (stream.NetworkPayload.Header.PeerId != 0 && stream.NetworkPayload.Header.PacketID == PacketId.RootSocket_Payload)
                            {
                                if (stream.NetworkPayload.Header.PeerId == Client.VirtualIpInt && !Client.ServerSided)
                                {
                                    //we arrived at the target peer !
                                    IPeerMessage PeerMsg = null;
                                    try
                                    {
                                        PeerMsg = (IPeerMessage)messageHandler.HandleMessage(new PayloadReader(payload)
                                            {
                                                Offset = (int)offset
                                            }, stream.NetworkPayload.Header.MessageId);

                                        if (PeerMsg != null)
                                        {
                                            PeerMsg.RawSize             = stream.NetworkPayload.Header.PacketSize;
                                            PeerMsg.DecompressedRawSize = payload.Length;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Client.onException(ex, ErrorType.Core);
                                        return;
                                    }

                                    lock (Client.PeerConnections)
                                    {
                                        RootPeer peer = null;
                                        if (Client.PeerConnections.TryGetValue(PeerMsg.ConnectionId, out peer))
                                        {
                                            /*try
                                             * {
                                             *  if (!peer.DPI.Inspect(stream.NetworkPayload.Header, PeerMsg))
                                             *  {
                                             *      Client.Disconnect(DisconnectReason.DeepPacketInspectionDisconnection);
                                             *      return;
                                             *  }
                                             * }
                                             * catch { }*/

                                            PeerMsg.Peer = peer;
                                            RootSocketQueue.Enqueue(PeerMsg);
                                        }
                                    }
                                }
                                else if (Client.ServerSided)
                                {
                                    SSPClient TargetClient = null;

                                    lock (Client.PeerConnections)
                                    {
                                        for (int i = 0; i < Client.PeerConnections.Count; i++)
                                        {
                                            RootPeer rootPeer = Client.PeerConnections.Values[i];
                                            if (rootPeer.FromClient != null && rootPeer.FromClient.VirtualIpInt == stream.NetworkPayload.Header.PeerId)
                                            {
                                                TargetClient = rootPeer.FromClient;
                                                break;
                                            }
                                            if (rootPeer.ToClient != null && rootPeer.ToClient.VirtualIpInt == stream.NetworkPayload.Header.PeerId)
                                            {
                                                TargetClient = rootPeer.ToClient;
                                                break;
                                            }
                                        }
                                    }

                                    if (TargetClient != null)
                                    {
                                        //no protection is being applied to the payload
                                        //the protection should already have been applied
                                        //when the client sended this data to the server
                                        NetworkPayloadWriter pw = new NetworkPayloadWriter(this);
                                        pw.WriteBytes(payload, (int)offset, receivedSize);
                                        TargetClient.Connection.SendPayload(pw, stream.NetworkPayload.Header.MessageId,
                                                                            PacketId.RootSocket_Payload, false, null, null,
                                                                            stream.NetworkPayload.Header.PeerId);
                                    }
                                }
                                else
                                {
                                    //strange...
                                }

                                this.stream.ReceiveState = ReceiveType.Header;
                                stream.Position         += receivedSize;
                                payload = null;
                                break;
                            }

                            //decrypt, decompress, de-cache the data we received
                            if (plugin != null && plugin.UseOwnProtection)
                            {
                                payload = plugin.protection.RemoveProtection(payload, ref offset, ref packetSize, ref stream.NetworkPayload.Header);
                            }
                            else
                            {
                                payload = protection.RemoveProtection(payload, ref offset, ref packetSize, ref stream.NetworkPayload.Header);
                            }

                            /*
                             * if (stream.NetworkPayload.isCached)
                             * {
                             *  payload = ReceiveCache.DeCache(payload, offset, packetSize);
                             *  offset = 0;
                             *  packetSize = payload.Length;
                             * }*/

                            IMessage message = null;
                            try
                            {
                                message = messageHandler.HandleMessage(new PayloadReader(payload)
                                    {
                                        Offset = (int)offset
                                    }, stream.NetworkPayload.Header.MessageId);

                                if (message != null)
                                {
                                    message.RawSize             = stream.NetworkPayload.Header.PacketSize;
                                    message.DecompressedRawSize = payload.Length;
                                }
                            }
                            catch (Exception ex)
                            {
                                Client.onException(ex, ErrorType.Core);
                                return;
                            }

                            if (!Client.DPI.Inspect(null, message))
                            {
                                Client.Disconnect(DisconnectReason.DeepPacketInspectionDisconnection);
                                return;
                            }

                            /*if(ProcessSpeed == ReceivePerformance.Unsafe)
                             * {
                             *  if(!MovedPayload && plugin != null && (plugin.UseOwnSystem))
                             *  {
                             *      //payload is not moved from memory and plugin is using his own system
                             *      //We'll just copy the memory...
                             *      payload = new byte[packetSize];
                             *      fixed (byte* dataPtr = payload, streamPtr = stream.Buffer)
                             *      {
                             *          NativeMethods.memcpy(dataPtr, streamPtr, (uint)packetSize);
                             *      }
                             *  }
                             * }*/

                            switch (stream.NetworkPayload.Header.PacketID)
                            {
                            case PacketId.PacketQueue:
                            {
                                PacketTaskQueue.Enqueue(message);
                                break;
                            }

                            case PacketId.ChannelPayload:
                            {
                                ChannelPayloadQueue.Enqueue(new ChannelRecvInfo(message, stream.NetworkPayload.Header.ChannelId));
                                break;
                            }

                            case PacketId.CloseChannel:
                            {
                                CloseChannelQueue.Enqueue(message);
                                break;
                            }

                            case PacketId.Disconnected:
                            {
                                DisconnectedQueue.Enqueue(message);
                                break;
                            }

                            case PacketId.OpenChannel:
                            {
                                OpenChannelQueue.Enqueue(message);
                                break;
                            }

                            case PacketId.OpenChannelResponse:
                            case PacketId.LiteCodeResponse:
                            case PacketId.KeepAlive:
                            {
                                ResponseQueue.Enqueue(message);
                                break;
                            }

                            case PacketId.Payload:
                            {
                                PayloadQueue.Enqueue(message);
                                break;
                            }

                            case PacketId.PluginPacket:
                            {
                                PluginDataQueue.Enqueue(new PluginRecvInfo(plugin, message, payload));
                                break;
                            }

                            case PacketId.StreamMessages:
                            {
                                StreamQueue.Enqueue(message);
                                break;
                            }

                            case PacketId.LiteCode:
                            {
                                LiteCodeQueue.Enqueue(message);
                                break;
                            }

                            case PacketId.LiteCode_Delegates:
                            {
                                LiteCodeDelegateQueue.Enqueue(message);
                                break;
                            }

                            case PacketId.RequestMessages:
                            {
                                RequestQueue.Enqueue(message);
                                break;
                            }
                            }

                            this.stream.ReceiveState = ReceiveType.Header;
                            stream.Position         += receivedSize;
                            payload = null;
                        }
                        else
                        {
                            DataAvailable = false;
                        }
                        break;
                    }
                    }
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Send the data to the target connection
        /// </summary>
        /// <param name="npw"></param>
        /// <param name="MessageId"></param>
        /// <param name="packetId"></param>
        /// <param name="ApplyProtection">Only set this to false when it's being redirected to a Peer when encryption is still applied</param>
        /// <param name="plugin"></param>
        /// <param name="channel"></param>
        internal unsafe void SendPayload(NetworkPayloadWriter npw, uint MessageId, PacketId packetId,
                                         bool ApplyProtection, IPlugin plugin = null, Channel channel = null, uint VirtualIp = 0)
        {
            lock (ClientSendLock)
            {
                while (Client.State == ConnectionState.Reconnecting)
                {
                    Thread.Sleep(100); //wait till we are re connected
                }
                if (Client.State != ConnectionState.Open)
                {
                    return;
                }

                PacketHeader header        = new PacketHeader(this);
                uint         offset        = (uint)HEADER_SIZE;
                uint         PayloadLength = (uint)npw.PayloadSize;
                byte[]       payload       = npw.GetBuffer();

                if (ApplyProtection)
                {
                    //apply the encryption(s), compression(s) and cache

                    /*if(plugin != null)
                     *  plugin.protection.ApplyProtection(npw.GetBuffer(), offset, ref length, ref header);
                     * else*/
                    payload = protection.ApplyProtection(payload, ref offset, ref PayloadLength, ref header);
                }

                header.PacketSize = (int)PayloadLength;
                header.PacketID   = packetId;
                header.ChannelId  = channel != null ? channel.ConnectionId : 0;
                header.PeerId     = VirtualIp;

                if (packetId == PacketId.PluginPacket)
                {
                    header.isPluginPacket = true;
                    if (plugin != null)
                    {
                        header.PluginId = plugin.PluginId;
                    }
                }

                header.CurPacketId = CurPacketId;
                CurPacketId++;
                header.MessageId     = MessageId;
                npw.vStream.Position = 0;
                header.WriteHeader(payload, (int)offset, (int)PayloadLength, npw);

                //let's not re-write to NPW when nothing has modified
                if (protection.LayerCount > 0 && ApplyProtection)
                {
                    npw.WriteBytes(payload, (int)offset, (int)PayloadLength);
                }

                //encrypt the header

                /*wopEncryption.Encrypt(temp, 0, HEADER_SIZE);
                 * if (this.EncryptionType == EncryptionType.Wop)
                 * {
                 *  wopEncryption.Encrypt(temp, HEADER_SIZE, npw.Length);
                 * }
                 * else if (this.EncryptionType == EncryptionType.UnsafeXor)
                 * {
                 *  unsafeXorEncryption.Encrypt(ref temp, HEADER_SIZE, npw.Length);
                 * }*/

                try
                {
                    this.Handle.Send(npw.GetBuffer(), (int)PayloadLength + HEADER_SIZE, SocketFlags.None);
                    BytesOut += (ulong)(PayloadLength + HEADER_SIZE);
                }
                catch { }
            }
        }
コード例 #7
0
 internal unsafe void SendPayload(NetworkPayloadWriter npw, uint MessageId, PacketId packetId, IPlugin plugin = null, Channel channel = null)
 {
     SendPayload(npw, MessageId, packetId, true, plugin, channel);
 }