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); }
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(); } }
public byte[] ToByteArray(Connection connection) { NetworkPayloadWriter pw = new NetworkPayloadWriter(connection); WriteHeader(null, 0, 0, pw); return(pw.GetPayload()); }
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); }
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; } } } } }
/// <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 { } } }
internal unsafe void SendPayload(NetworkPayloadWriter npw, uint MessageId, PacketId packetId, IPlugin plugin = null, Channel channel = null) { SendPayload(npw, MessageId, packetId, true, plugin, channel); }