Esempio n. 1
0
        private void HandleNotifyPacket(Connection connection, Packet packet)
        {
            if (packet.Data.Length < NotifyPacketHeaderSize)
            {
                return;
            }

            var offset = 1;
            var packetSequenceNumber = ByteUtils.ReadULong(packet.Data, offset, _config.SequenceNumberBytes);

            offset += _config.SequenceNumberBytes;
            var remoteRecvSequence = ByteUtils.ReadULong(packet.Data, offset, _config.SequenceNumberBytes);

            offset += _config.SequenceNumberBytes;
            var remoteRecvMask = ByteUtils.ReadULong(packet.Data, offset, sizeof(ulong));

            var sequenceDistance = connection.SendSequencer.Distance(packetSequenceNumber, connection.LastReceivedSequence);

            // Sequence so out of bounds we can't save, just disconnect
            if (Math.Abs(sequenceDistance) > _config.SendWindowSize)
            {
                DisconnectConnection(connection, DisconnectReason.SequenceOutOfBounds);
                return;
            }

            // Sequence is old, so duplicate or re-ordered packet
            if (sequenceDistance <= 0)
            {
                return;
            }

            // Update recv sequence for ou local connection object
            connection.LastReceivedSequence = packetSequenceNumber;

            if (sequenceDistance >= ACK_MASK_BITS)
            {
                connection.ReceiveMask = 1; // 0000 0000 0000 0000 0000 0000 0000 0001
            }
            else
            {
                connection.ReceiveMask = (connection.ReceiveMask << (int)sequenceDistance) | 1;
            }

            AckPackets(connection, remoteRecvSequence, remoteRecvMask);

            // Only a ack packet
            if (packet.Data.Length == NotifyPacketHeaderSize)
            {
                return;
            }

            var trimedPacket = packet.Slice(NotifyPacketHeaderSize);

            OnNotityPacketReceived?.Invoke(connection, trimedPacket);
        }