Ejemplo n.º 1
0
        /// <summary>
        /// Decrypt a packet's data
        /// </summary>
        public static int DecryptPacketData(NetcodePacketHeader header, ulong protocolID, byte[] packetData, int packetDataLen, byte[] key, byte[] outBuffer)
        {
            byte[] additionalData = BufferPool.GetBuffer(Defines.NETCODE_VERSION_INFO_BYTES + 8 + 1);
            using (var writer = ByteArrayReaderWriter.Get(additionalData))
            {
                writer.WriteASCII(Defines.NETCODE_VERSION_INFO_STR);
                writer.Write(protocolID);
                writer.Write(header.ReadSequenceByte);
            }

            byte[] nonce = BufferPool.GetBuffer(12);
            using (var writer = ByteArrayReaderWriter.Get(nonce))
            {
                writer.Write((UInt32)0);
                writer.Write(header.SequenceNumber);
            }

            int ret;

            try
            {
                ret = CryptoUtils.Decrypt(packetData, 0, packetDataLen, additionalData, key, nonce, outBuffer);
            }
            catch (Exception e)
            {
                BufferPool.ReturnBuffer(additionalData);
                BufferPool.ReturnBuffer(nonce);
                throw e;
            }

            BufferPool.ReturnBuffer(additionalData);
            BufferPool.ReturnBuffer(nonce);

            return(ret);
        }
Ejemplo n.º 2
0
        // process a received datagram
        private void processDatagram(byte[] payload, int size, EndPoint sender)
        {
            using (var reader = ByteArrayReaderWriter.Get(payload))
            {
                NetcodePacketHeader packetHeader = new NetcodePacketHeader();
                packetHeader.Read(reader);

                if (packetHeader.PacketType == NetcodePacketType.ConnectionRequest)
                {
                    processConnectionRequest(reader, size, sender);
                }
                else
                {
                    switch (packetHeader.PacketType)
                    {
                    case NetcodePacketType.ChallengeResponse:
                        processConnectionResponse(reader, packetHeader, size, sender);
                        break;

                    case NetcodePacketType.ConnectionKeepAlive:
                        processConnectionKeepAlive(reader, packetHeader, size, sender);
                        break;

                    case NetcodePacketType.ConnectionPayload:
                        processConnectionPayload(reader, packetHeader, size, sender);
                        break;

                    case NetcodePacketType.ConnectionDisconnect:
                        processConnectionDisconnect(reader, packetHeader, size, sender);
                        break;
                    }
                }
            }
        }
Ejemplo n.º 3
0
        internal sealed override void Deserialize(byte[] buffer)
        {
            using (var packetWriter = ByteArrayReaderWriter.Get(buffer))
            {
                Action = packetWriter.ReadByte();

                var haveSendTime = packetWriter.ReadByte();
                var havePayload  = packetWriter.ReadByte();

                if (havePayload == 0x1)
                {
                    _payloadLen = packetWriter.ReadUInt16();
                }

                SendType = (GProtocolSendType)packetWriter.ReadByte();
                Hash     = (long)packetWriter.ReadUInt64();

                if (havePayload == 0x1)
                {
                    Payload = packetWriter.ReadBytes(_payloadLen);
                }
                if (haveSendTime == 0x1)
                {
                    ClientSendTime = packetWriter.ReadInt64();
                }
            }
        }
Ejemplo n.º 4
0
        // Decrypt a private connect token
        public static int DecryptPrivateConnectToken(byte[] encryptedConnectToken, ulong protocolID, ulong expireTimestamp, ulong sequence, byte[] key, byte[] outBuffer)
        {
            int len = encryptedConnectToken.Length;

            byte[] additionalData = BufferPool.GetBuffer(Defines.NETCODE_VERSION_INFO_BYTES + 8 + 8);
            using (var writer = ByteArrayReaderWriter.Get(additionalData))
            {
                writer.WriteASCII(Defines.NETCODE_VERSION_INFO_STR);
                writer.Write(protocolID);
                writer.Write(expireTimestamp);
            }

            byte[] nonce = BufferPool.GetBuffer(12);
            using (var writer = ByteArrayReaderWriter.Get(nonce))
            {
                writer.Write((UInt32)0);
                writer.Write(sequence);
            }

            var ret = CryptoUtils.Decrypt(encryptedConnectToken, 0, len, additionalData, key, nonce, outBuffer);

            BufferPool.ReturnBuffer(additionalData);
            BufferPool.ReturnBuffer(nonce);

            return(ret);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Encrypt a challenge token
        /// </summary>
        public static int EncryptChallengeToken(ulong sequenceNum, byte[] packetData, byte[] key, byte[] outBuffer)
        {
            byte[] additionalData = BufferPool.GetBuffer(0);

            byte[] nonce = BufferPool.GetBuffer(12);
            using (var writer = ByteArrayReaderWriter.Get(nonce))
            {
                writer.Write((UInt32)0);
                writer.Write(sequenceNum);
            }

            int ret;

            try
            {
                ret = AEAD_Chacha20_Poly1305.Encrypt(packetData, 0, 300 - Defines.MAC_SIZE, additionalData, nonce, key, outBuffer);
            }
            catch (Exception e)
            {
                BufferPool.ReturnBuffer(additionalData);
                BufferPool.ReturnBuffer(nonce);
                throw e;
            }

            BufferPool.ReturnBuffer(additionalData);
            BufferPool.ReturnBuffer(nonce);

            return(ret);
        }
Ejemplo n.º 6
0
        // encrypts a packet and sends it to the endpoint
        private void sendPacketToClient(NetcodePacketHeader packetHeader, byte[] packetData, int packetDataLen, EndPoint endpoint, byte[] key)
        {
            // assign a sequence number to this packet
            packetHeader.SequenceNumber = this.nextSequenceNumber++;

            // encrypt packet data
            byte[] encryptedPacketBuffer = BufferPool.GetBuffer(2048);
            int    encryptedBytes        = PacketIO.EncryptPacketData(packetHeader, protocolID, packetData, packetDataLen, key, encryptedPacketBuffer);

            int packetLen = 0;

            // write packet to byte array
            var packetBuffer = BufferPool.GetBuffer(2048);

            using (var packetWriter = ByteArrayReaderWriter.Get(packetBuffer))
            {
                packetHeader.Write(packetWriter);
                packetWriter.WriteBuffer(encryptedPacketBuffer, encryptedBytes);

                packetLen = (int)packetWriter.WritePosition;
            }

            // send packet
            listenSocket.SendTo(packetBuffer, packetLen, SocketFlags.None, endpoint);

            BufferPool.ReturnBuffer(packetBuffer);
            BufferPool.ReturnBuffer(encryptedPacketBuffer);
        }
Ejemplo n.º 7
0
        public bool Read(ByteArrayReaderWriter stream, int length, byte[] key, ulong protocolID)
        {
            if (length != 8 + Defines.MAC_SIZE)
            {
                return(false);
            }

            byte[] tempBuffer = BufferPool.GetBuffer(length);
            try
            {
                PacketIO.ReadPacketData(Header, stream, length, protocolID, key, tempBuffer);
            }
            catch
            {
                BufferPool.ReturnBuffer(tempBuffer);
                return(false);
            }

            using (var dataReader = ByteArrayReaderWriter.Get(tempBuffer))
            {
                ClientIndex = dataReader.ReadUInt32();
                MaxSlots    = dataReader.ReadUInt32();
            }

            return(true);
        }
 protected void processPacket(ushort seq, byte[] packetData, int packetLen)
 {
     using (ByteArrayReaderWriter byteArrayReaderWriter = ByteArrayReaderWriter.Get(packetData))
     {
         while (byteArrayReaderWriter.ReadPosition < packetLen)
         {
             ushort num  = byteArrayReaderWriter.ReadUInt16();
             ushort num2 = readVariableLengthUShort(byteArrayReaderWriter);
             if (num2 != 0)
             {
                 if (!receiveBuffer.Exists(num))
                 {
                     BufferedPacket bufferedPacket = receiveBuffer.Insert(num);
                     bufferedPacket.buffer.SetSize(num2);
                     byteArrayReaderWriter.ReadBytesIntoBuffer(bufferedPacket.buffer.InternalBuffer, num2);
                 }
                 else
                 {
                     byteArrayReaderWriter.SeekRead(byteArrayReaderWriter.ReadPosition + (int)num2);
                 }
                 while (receiveBuffer.Exists(nextReceive))
                 {
                     BufferedPacket bufferedPacket2 = receiveBuffer.Find(nextReceive);
                     ReceiveCallback(ChannelID, bufferedPacket2.buffer.InternalBuffer, bufferedPacket2.buffer.Length);
                     receiveBuffer.Remove(nextReceive);
                     nextReceive++;
                 }
             }
         }
     }
 }
Ejemplo n.º 9
0
        private void sendPacket(NetcodePacketHeader packetHeader, byte[] packetData, int packetDataLen, byte[] key)
        {
            // assign a sequence number to this packet
            packetHeader.SequenceNumber = this.nextPacketSequence++;

            // encrypt packet data
            byte[] encryptedPacketBuffer = BufferPool.GetBuffer(2048);
            int    encryptedBytes        = PacketIO.EncryptPacketData(packetHeader, connectToken.ProtocolID, packetData, packetDataLen, key, encryptedPacketBuffer);

            int packetLen = 0;

            // write packet to byte array
            var packetBuffer = BufferPool.GetBuffer(2048);

            using (var packetWriter = ByteArrayReaderWriter.Get(packetBuffer))
            {
                packetHeader.Write(packetWriter);
                packetWriter.WriteBuffer(encryptedPacketBuffer, encryptedBytes);

                packetLen = (int)packetWriter.WritePosition;
            }

            // send packet
            try {
                socket.SendTo(packetBuffer, packetLen, currentServerEndpoint);
            }
            catch { }

            BufferPool.ReturnBuffer(packetBuffer);
            BufferPool.ReturnBuffer(encryptedPacketBuffer);
        }
Ejemplo n.º 10
0
        public bool Read(ByteArrayReaderWriter stream, int length, byte[] key, ulong protocolID)
        {
            byte[] packetBuffer = BufferPool.GetBuffer(8 + 300 + Defines.MAC_SIZE);
            int    packetLen    = 0;

            try
            {
                packetLen = PacketIO.ReadPacketData(Header, stream, length, protocolID, key, packetBuffer);
            }
            catch (System.Exception e)
            {
                BufferPool.ReturnBuffer(packetBuffer);
                return(false);
            }

            if (packetLen != 308)
            {
                BufferPool.ReturnBuffer(packetBuffer);
                return(false);
            }

            ChallengeTokenBytes = BufferPool.GetBuffer(300);
            using (var reader = ByteArrayReaderWriter.Get(packetBuffer))
            {
                ChallengeTokenSequence = reader.ReadUInt64();
                reader.ReadBytesIntoBuffer(ChallengeTokenBytes, 300);
            }

            BufferPool.ReturnBuffer(packetBuffer);
            return(true);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Decrypt a challenge token
        /// </summary>
        public static int DecryptChallengeToken(ulong sequenceNum, byte[] packetData, byte[] key, byte[] outBuffer)
        {
            byte[] additionalData = BufferPool.GetBuffer(0);

            byte[] nonce = BufferPool.GetBuffer(12);
            using (var writer = ByteArrayReaderWriter.Get(nonce))
            {
                writer.Write((UInt32)0);
                writer.Write(sequenceNum);
            }

            int ret;

            try
            {
                ret = CryptoUtils.Decrypt(packetData, 0, 300, additionalData, key, nonce, outBuffer);
            }
            catch (Exception e)
            {
                BufferPool.ReturnBuffer(additionalData);
                BufferPool.ReturnBuffer(nonce);
                throw e;
            }

            BufferPool.ReturnBuffer(additionalData);
            BufferPool.ReturnBuffer(nonce);

            return(ret);
        }
Ejemplo n.º 12
0
        public void Connect(byte[] connectToken, bool autoTick)
        {
            if (state != ClientState.Disconnected)
            {
                throw new InvalidOperationException();
            }

            keepAliveTimer = 0.0;

            connectServers.Clear();
            replayProtection.Reset();

            if (connectToken.Length != Defines.NETCODE_CONNECT_TOKEN_PUBLIC_BYTES)
            {
                changeState(ClientState.InvalidConnectToken);
                return;
            }

            NetcodePublicConnectToken tokenData = new NetcodePublicConnectToken();

            using (var reader = ByteArrayReaderWriter.Get(connectToken))
            {
                if (!tokenData.Read(reader))
                {
                    changeState(ClientState.InvalidConnectToken);
                    return;
                }
            }

            if (tokenData.CreateTimestamp >= tokenData.ExpireTimestamp)
            {
                changeState(ClientState.InvalidConnectToken);
                return;
            }

            clientToServerKey = tokenData.ClientToServerKey;
            serverToClientKey = tokenData.ServerToClientKey;

            foreach (var server in tokenData.ConnectServers)
            {
                connectServers.Enqueue(server.Endpoint);
            }

            this.connectToken = tokenData;
            this.state        = ClientState.SendingConnectionRequest;

            // bind socket, spin up threads, and start trying to connect
            isRunning = true;

            currentServerEndpoint = connectServers.Dequeue();
            createSocket(currentServerEndpoint);

            if (autoTick)
            {
                this.time = DateTime.Now.GetTotalSeconds();
                ThreadPool.QueueUserWorkItem(clientTick);
            }
        }
Ejemplo n.º 13
0
 internal static Tuple <string, byte[]> GetObserver(byte[] buffer)
 {
     using (var packetReader = ByteArrayReaderWriter.Get(buffer))
     {
         var len     = packetReader.ReadByte();
         var ownerId = GetStringFromBuffer(packetReader.ReadBytes(len), true);
         var payload = packetReader.ReadBytes(buffer.Length - len);
         return(Tuple.Create(ownerId, payload));
     }
 }
Ejemplo n.º 14
0
        // sends a connection challenge packet to the endpoint
        private void sendConnectionChallenge(NetcodePrivateConnectToken connectToken, EndPoint endpoint)
        {
            log("Sending connection challenge", NetcodeLogLevel.Debug);

            var challengeToken = new NetcodeChallengeToken();

            challengeToken.ClientID = connectToken.ClientID;
            challengeToken.UserData = connectToken.UserData;

            ulong challengeSequence = nextChallengeSequenceNumber++;

            byte[] tokenBytes = BufferPool.GetBuffer(300);
            using (var tokenWriter = ByteArrayReaderWriter.Get(tokenBytes))
                challengeToken.Write(tokenWriter);

            byte[] encryptedToken = BufferPool.GetBuffer(300);
            int    encryptedTokenBytes;

            try
            {
                encryptedTokenBytes = PacketIO.EncryptChallengeToken(challengeSequence, tokenBytes, challengeKey, encryptedToken);
            }
            catch
            {
                BufferPool.ReturnBuffer(tokenBytes);
                BufferPool.ReturnBuffer(encryptedToken);
                return;
            }

            var challengePacket = new NetcodeConnectionChallengeResponsePacket();

            challengePacket.ChallengeTokenSequence = challengeSequence;
            challengePacket.ChallengeTokenBytes    = encryptedToken;

            var cryptIdx = encryptionManager.FindEncryptionMapping(endpoint, time);

            if (cryptIdx == -1)
            {
                return;
            }

            var cryptKey = encryptionManager.GetSendKey(cryptIdx);

            serializePacket(new NetcodePacketHeader()
            {
                PacketType = NetcodePacketType.ConnectionChallenge
            }, (writer) =>
            {
                challengePacket.Write(writer);
            }, endpoint, cryptKey);

            BufferPool.ReturnBuffer(tokenBytes);
            BufferPool.ReturnBuffer(encryptedToken);
        }
Ejemplo n.º 15
0
        private static void startClient()
        {
            // get token
            var webRequest = WebRequest.Create("http://127.0.0.1:8080/token");

            webRequest.Credentials = CredentialCache.DefaultCredentials;
            HttpWebResponse response;

            try
            {
                response = (HttpWebResponse)webRequest.GetResponse();
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to get token: " + e.Message);
                Console.ReadLine();
                return;
            }

            if (response.StatusCode != HttpStatusCode.OK)
            {
                Console.WriteLine("Failed to get token: " + response.StatusDescription);
                Console.ReadLine();
                return;
            }

            Stream       dataStream = response.GetResponseStream();
            StreamReader reader     = new StreamReader(dataStream);

            string responseStr = reader.ReadToEnd();

            reader.Close();
            dataStream.Close();
            response.Close();

            byte[] connectToken = System.Convert.FromBase64String(responseStr);

            testPacket = new byte[256];
            using (var testPacketWriter = ByteArrayReaderWriter.Get(testPacket))
            {
                testPacketWriter.Write((uint)0xAABBCCDD);
            }

            client = new Client();

            client.OnStateChanged    += Client_OnStateChanged;
            client.OnMessageReceived += Client_OnMessageReceived;

            Console.WriteLine("Connecting...");
            client.Connect(connectToken);

            Console.ReadLine();
            client.Disconnect();
        }
Ejemplo n.º 16
0
        public bool Read(byte[] token, byte[] key, ulong protocolID, ulong expiration, ulong sequence)
        {
            byte[] tokenBuffer = BufferPool.GetBuffer(Defines.NETCODE_CONNECT_TOKEN_PRIVATE_BYTES);
            int    tokenLen    = 0;

            try
            {
                tokenLen = PacketIO.DecryptPrivateConnectToken(token, protocolID, expiration, sequence, key, tokenBuffer);
            }
            catch
            {
                BufferPool.ReturnBuffer(tokenBuffer);
                return(false);
            }

            try
            {
                using (var reader = ByteArrayReaderWriter.Get(tokenBuffer))
                {
                    this.ClientID       = reader.ReadUInt64();
                    this.TimeoutSeconds = (int)reader.ReadUInt32();
                    uint numServerAddresses = reader.ReadUInt32();

                    if (numServerAddresses == 0 || numServerAddresses > Defines.MAX_SERVER_ADDRESSES)
                    {
                        BufferPool.ReturnBuffer(tokenBuffer);
                        return(false);
                    }

                    this.ConnectServers = new ConnectTokenServerEntry[numServerAddresses];
                    for (int i = 0; i < numServerAddresses; i++)
                    {
                        this.ConnectServers[i] = new ConnectTokenServerEntry();
                        this.ConnectServers[i].ReadData(reader);
                    }

                    ClientToServerKey = new byte[32];
                    ServerToClientKey = new byte[32];
                    UserData          = new byte[256];

                    reader.ReadBytesIntoBuffer(ClientToServerKey, 32);
                    reader.ReadBytesIntoBuffer(ServerToClientKey, 32);
                    reader.ReadBytesIntoBuffer(UserData, 256);
                }
            }
            catch
            {
                BufferPool.ReturnBuffer(tokenBuffer);
                return(false);
            }

            return(true);
        }
Ejemplo n.º 17
0
        private void serializePacket(NetcodePacketHeader packetHeader, Action <ByteArrayReaderWriter> write, byte[] key)
        {
            byte[] tempPacket = BufferPool.GetBuffer(2048);
            int    writeLen   = 0;

            using (var writer = ByteArrayReaderWriter.Get(tempPacket))
            {
                write(writer);
                writeLen = (int)writer.WritePosition;
            }

            sendPacket(packetHeader, tempPacket, writeLen, key);
            BufferPool.ReturnBuffer(tempPacket);
        }
Ejemplo n.º 18
0
        internal override byte[] Serialize(string key, bool isCommand)
        {
            byte  havePayload = 0x0, haveSendTime = 0x0;
            short prefixLen = 4 * sizeof(byte) + sizeof(ulong);


            if (Payload != null)
            {
                havePayload = 0x1;
                _payloadLen = Payload.Length;
                prefixLen  += sizeof(ushort);
            }

            if (ClientSendTime != 0L)
            {
                haveSendTime = 0x1;
                prefixLen   += sizeof(long);
            }

            var packetBuffer = BufferPool.GetBuffer(BufferSize(prefixLen));

            using (var packetWriter = ByteArrayReaderWriter.Get(packetBuffer))
            {
                // header Segment
                packetWriter.Write((byte)Action);
                packetWriter.Write(haveSendTime);
                packetWriter.Write(havePayload);

                if (havePayload == 0x1)
                {
                    packetWriter.Write((ushort)_payloadLen);
                }

                // data Segment
                packetWriter.Write((byte)SendType);
                packetWriter.Write((ulong)Hash);

                if (havePayload == 0x1)
                {
                    packetWriter.Write(Payload);
                }
                if (haveSendTime == 0x1)
                {
                    packetWriter.Write(ClientSendTime);
                }
            }

            return(packetBuffer);
        }
Ejemplo n.º 19
0
        internal static Queue <byte[]> GetQueueData(byte[] buffer)
        {
            var data = new Queue <byte[]>();

            using (var packetReader = ByteArrayReaderWriter.Get(buffer))
            {
                var count = packetReader.ReadByte();
                for (var i = 0; i < count; i++)
                {
                    data.Enqueue(packetReader.ReadBytes(packetReader.ReadUInt16()));
                }
            }

            return(data);
        }
Ejemplo n.º 20
0
        private static string[] GetStringsFromBuffer(byte[] bytes)
        {
            var data = new List <string>();

            using (var packetReader = ByteArrayReaderWriter.Get(bytes))
            {
                var count = packetReader.ReadUInt16();
                for (var i = 0; i < count; i++)
                {
                    data.Add(GetStringFromBuffer(packetReader.ReadBytes(packetReader.ReadUInt16()), true));
                }
            }

            return(data.ToArray());
        }
Ejemplo n.º 21
0
        private void sendConnectionRequest(EndPoint server)
        {
            byte[] packetBuffer = BufferPool.GetBuffer(1 + 13 + 8 + 8 + 8 + Defines.NETCODE_CONNECT_TOKEN_PRIVATE_BYTES);
            using (var stream = ByteArrayReaderWriter.Get(packetBuffer))
            {
                stream.Write((byte)0);
                stream.WriteASCII(Defines.NETCODE_VERSION_INFO_STR);
                stream.Write(connectToken.ProtocolID);
                stream.Write(connectToken.ExpireTimestamp);
                stream.Write(connectToken.ConnectTokenSequence);
                stream.Write(connectToken.PrivateConnectTokenBytes);
            }

            socket.SendTo(packetBuffer, server);
            BufferPool.ReturnBuffer(packetBuffer);
        }
        internal void Deserialize(byte[] buff)
        {
            using (var packetWriter = ByteArrayReaderWriter.Get(buff))
            {
                var haveSender   = packetWriter.ReadByte();
                var haveReceiver = packetWriter.ReadByte();
                var havePayload  = packetWriter.ReadByte();
                var haveExtra    = packetWriter.ReadByte();


                if (haveSender == 0x1)
                {
                    _senderLen = packetWriter.ReadByte();
                }
                if (haveReceiver == 0x1)
                {
                    _receiverLen = packetWriter.ReadByte();
                }
                if (havePayload == 0x1)
                {
                    _payloadLen = packetWriter.ReadUInt16();
                }
                if (haveExtra == 0x1)
                {
                    _extraLen = packetWriter.ReadUInt16();
                }


                if (haveSender == 0x1)
                {
                    SenderId = ConvertToString(packetWriter.ReadBytes(_senderLen));
                }
                if (haveReceiver == 0x1)
                {
                    ReceiverId = ConvertToString(packetWriter.ReadBytes(_receiverLen));
                }
                if (havePayload == 0x1)
                {
                    Payload = packetWriter.ReadBytes(_payloadLen);
                }
                if (haveExtra == 0x1)
                {
                    ExtraData = packetWriter.ReadBytes(_extraLen);
                }
            }
        }
Ejemplo n.º 23
0
        internal static List <SnapShotData> GetSnapShotsFromBuffer(byte[] buffer)
        {
            var data = new List <SnapShotData>();

            using (var packetReader = ByteArrayReaderWriter.Get(buffer))
            {
                var count = packetReader.ReadUInt16();
                for (var i = 0; i < count; i++)
                {
                    var type    = (SnapShotType)packetReader.ReadByte();
                    var ownerId = packetReader.ReadBytes(packetReader.ReadByte());
                    var payload = packetReader.ReadBytes(packetReader.ReadUInt16());
                    data.Add(new SnapShotData(type, GetStringFromBuffer(ownerId, true), payload));
                }
            }

            return(data);
        }
Ejemplo n.º 24
0
        internal static byte[] GetSendQueueBuffer(Queue <byte[]> queue)
        {
            var bufferSize   = GetSendQueueBufferSize(queue);
            var packetBuffer = BufferPool.GetBuffer(bufferSize);

            using (var packetWriter = ByteArrayReaderWriter.Get(packetBuffer))
            {
                packetWriter.Write((byte)queue.Count);
                while (queue.Count > 0)
                {
                    var item = queue.Dequeue();
                    packetWriter.Write((ushort)item.Length);
                    packetWriter.Write(item);
                }
            }

            return(packetBuffer);
        }
        public override void SendMessage(byte[] buffer, int bufferPosition, int bufferLength)
        {
            int sendBufferSize = 0;

            for (ushort seq = oldestUnacked; PacketIO.SequenceLessThan(seq, this.sequence); seq++)
            {
                if (sendBuffer.Exists(seq))
                {
                    sendBufferSize++;
                }
            }

            if (sendBufferSize == sendBuffer.Size)
            {
                ByteBuffer tempBuff = ObjPool <ByteBuffer> .Get();

                tempBuff.SetSize(bufferLength);
                tempBuff.BufferCopy(buffer, bufferPosition, 0, bufferLength);
                messageQueue.Enqueue(tempBuff);

                return;
            }

            ushort sequence = this.sequence++;
            var    packet   = sendBuffer.Insert(sequence);

            packet.time = -1.0;

            // ensure size for header
            int varLength = getVariableLengthBytes((ushort)bufferLength);

            packet.buffer.SetSize(2 + varLength + bufferLength);

            using (var writer = ByteArrayReaderWriter.Get(packet.buffer.InternalBuffer)) {
                writer.Write(sequence);

                writeVariableLengthUShort((ushort)bufferLength, writer);
                writer.WriteBuffer(buffer, bufferPosition, bufferLength);
            }

            // signal that packet is ready to be sent
            packet.writeLock = false;
        }
Ejemplo n.º 26
0
        // process incoming packets and turn them into messages
        protected void processPacket(ushort seq, byte[] packetData, int packetLen)
        {
            using (var reader = ByteArrayReaderWriter.Get(packetData))
            {
                while (reader.ReadPosition < packetLen)
                {
                    // get message bytes and send to receive callback
                    ushort messageID     = reader.ReadUInt16();
                    ushort messageLength = readVariableLengthUShort(reader);

                    if (messageLength == 0)
                    {
                        continue;
                    }

                    if (!receiveBuffer.Exists(messageID))
                    {
                        var receivedMessage = receiveBuffer.Insert(messageID);

                        receivedMessage.buffer.SetSize(messageLength);
                        reader.ReadBytesIntoBuffer(receivedMessage.buffer.InternalBuffer, messageLength);
                    }
                    else
                    {
                        reader.SeekRead(reader.ReadPosition + messageLength);
                    }

                    // keep returning the next message we're expecting as long as it's available
                    while (receiveBuffer.Exists(nextReceive))
                    {
                        var msg = receiveBuffer.Find(nextReceive);

                        ReceiveCallback(msg.buffer.InternalBuffer, msg.buffer.Length);

                        receiveBuffer.Remove(nextReceive);
                        nextReceive++;
                    }
                }
            }
        }
Ejemplo n.º 27
0
        private void processDatagram(Datagram datagram)
        {
            if (!MiscUtils.AddressEqual(datagram.sender, currentServerEndpoint))
            {
                return;
            }

            using (var reader = ByteArrayReaderWriter.Get(datagram.payload))
            {
                NetcodePacketHeader packetHeader = new NetcodePacketHeader();
                packetHeader.Read(reader);

                int length = datagram.payloadSize - (int)reader.ReadPosition;

                switch (packetHeader.PacketType)
                {
                case NetcodePacketType.ConnectionChallenge:
                    processChallengePacket(packetHeader, length, reader);
                    break;

                case NetcodePacketType.ConnectionDenied:
                    processConnectionDenied(packetHeader, length, reader);
                    break;

                case NetcodePacketType.ConnectionKeepAlive:
                    processConnectionKeepAlive(packetHeader, length, reader);
                    break;

                case NetcodePacketType.ConnectionPayload:
                    processConnectionPayload(packetHeader, length, reader);
                    break;

                case NetcodePacketType.ConnectionDisconnect:
                    processConnectionDisconnect(packetHeader, length, reader);
                    break;
                }
            }
        }
Ejemplo n.º 28
0
        public bool Read(byte[] token, ulong sequenceNum, byte[] key)
        {
            byte[] tokenBuffer = BufferPool.GetBuffer(300);
            int    tokenLen    = 0;

            try
            {
                tokenLen = PacketIO.DecryptChallengeToken(sequenceNum, token, key, tokenBuffer);
            }
            catch
            {
                BufferPool.ReturnBuffer(tokenBuffer);
                return(false);
            }

            using (var reader = ByteArrayReaderWriter.Get(tokenBuffer))
            {
                ClientID = reader.ReadUInt64();
                UserData = reader.ReadBytes(256);
            }

            return(true);
        }
        public override void SendMessage(byte[] buffer, int bufferLength)
        {
            int    num  = 0;
            ushort num2 = oldestUnacked;

            while (PacketIO.SequenceLessThan(num2, sequence))
            {
                if (sendBuffer.Exists(num2))
                {
                    num++;
                }
                num2 = (ushort)(num2 + 1);
            }
            if (num == sendBuffer.Size)
            {
                ByteBuffer byteBuffer = ObjPool <ByteBuffer> .Get();

                byteBuffer.SetSize(bufferLength);
                byteBuffer.BufferCopy(buffer, 0, 0, bufferLength);
                messageQueue.Enqueue(byteBuffer);
            }
            else
            {
                ushort         val            = sequence++;
                BufferedPacket bufferedPacket = sendBuffer.Insert(val);
                bufferedPacket.time = -1.0;
                int variableLengthBytes = getVariableLengthBytes((ushort)bufferLength);
                bufferedPacket.buffer.SetSize(bufferLength + 2 + variableLengthBytes);
                using (ByteArrayReaderWriter byteArrayReaderWriter = ByteArrayReaderWriter.Get(bufferedPacket.buffer.InternalBuffer))
                {
                    byteArrayReaderWriter.Write(val);
                    writeVariableLengthUShort((ushort)bufferLength, byteArrayReaderWriter);
                    byteArrayReaderWriter.WriteBuffer(buffer, bufferLength);
                }
                bufferedPacket.writeLock = false;
            }
        }
        public ushort SendPacket(byte[] packetData, int position, int length, byte channelID)
        {
            if (length > config.MaxPacketSize)
            {
                throw new ArgumentOutOfRangeException("Packet is too large to send, max packet size is " + config.MaxPacketSize + " bytes");
            }

            if (length < 1)
            {
                throw new ArgumentOutOfRangeException("Packet is too small; minimum packet size is 1 byte.");
            }

            var  compressedBuffer = LZ4Codec.Wrap(packetData, position, length);
            bool compressed       = false;
            int  bytesSaved       = length - compressedBuffer.Length;

            if (bytesSaved > 0)
            {
                packetData = compressedBuffer;
                position   = 0;
                length     = compressedBuffer.Length;
                compressed = true;
            }

            ushort sequence = this.sequence++;
            ushort ack;
            uint   ackBits;

            lock (receivedPackets)
                receivedPackets.GenerateAckBits(out ack, out ackBits);

            SentPacketData sentPacketData = sentPackets.Insert(sequence);

            sentPacketData.time        = this.time;
            sentPacketData.packetBytes = (uint)(config.PacketHeaderSize + length);
            sentPacketData.acked       = false;

            if (length <= config.FragmentThreshold)
            {
                // regular packet

                byte[] transmitData         = BufferPool.GetBuffer(2048);
                int    headerBytes          = PacketIO.WritePacketHeader(transmitData, channelID, sequence, ack, ackBits, compressed);
                int    transmitBufferLength = length + headerBytes;

                Buffer.BlockCopy(packetData, position, transmitData, headerBytes, length);

                config.TransmitPacketCallback(transmitData, transmitBufferLength);

                BufferPool.ReturnBuffer(transmitData);
            }
            else
            {
                // fragmented packet

                byte[] packetHeader = BufferPool.GetBuffer(Defines.MAX_PACKET_HEADER_BYTES);

                int packetHeaderBytes = 0;

                try {
                    packetHeaderBytes = PacketIO.WritePacketHeader(packetHeader, channelID, sequence, ack, ackBits, compressed);
                }
                catch {
                    throw;
                }

                int numFragments = (length / config.FragmentSize) + ((length % config.FragmentSize) != 0 ? 1 : 0);
                //int fragmentBufferSize = Defines.FRAGMENT_HEADER_BYTES + Defines.MAX_PACKET_HEADER_BYTES + config.FragmentSize;

                byte[] fragmentPacketData = BufferPool.GetBuffer(2048);
                int    qpos = 0;

                byte prefixByte = 1;
                prefixByte |= (byte)((channelID & 0x03) << 6);

                for (int fragmentID = 0; fragmentID < numFragments; fragmentID++)
                {
                    using (var writer = ByteArrayReaderWriter.Get(fragmentPacketData)) {
                        writer.Write(prefixByte);
                        writer.Write(channelID);
                        writer.Write(sequence);
                        writer.Write((byte)fragmentID);
                        writer.Write((byte)(numFragments - 1));
                        writer.Write(compressed ? (byte)1 : (byte)0);

                        if (fragmentID == 0)
                        {
                            writer.WriteBuffer(packetHeader, 0, packetHeaderBytes);
                        }

                        int bytesToCopy = config.FragmentSize;
                        if (qpos + bytesToCopy > length)
                        {
                            bytesToCopy = length - qpos;
                        }

                        for (int i = 0; i < bytesToCopy; i++)
                        {
                            writer.Write(packetData[position + qpos++]);
                        }

                        int fragmentPacketBytes = (int)writer.WritePosition;
                        config.TransmitPacketCallback(fragmentPacketData, fragmentPacketBytes);
                    }
                }

                BufferPool.ReturnBuffer(packetHeader);
                BufferPool.ReturnBuffer(fragmentPacketData);
            }

            return(sequence);
        }