Recycle() private method

private Recycle ( NetPacket packet ) : void
packet NetPacket
return void
Example #1
0
        //ProcessAck in packet
        public void ProcessAck(NetPacket packet)
        {
            ushort ackWindowStart = packet.Sequence;

            //check relevance
            if (NetUtils.RelativeSequenceNumber(ackWindowStart, _localWindowStart) <= -_windowSize)
            {
                _peer.DebugWrite("[PA]Old acks");
                return;
            }

            byte[] acksData = packet.RawData;
            _peer.DebugWrite("[PA]AcksStart: {0}", ackWindowStart);
            int startByte = NetConstants.SequencedHeaderSize;

            _pendingPacketsAccess.WaitOne();
            for (int i = 0; i < _windowSize; i++)
            {
                int ackSequence = (ackWindowStart + i) % NetConstants.MaxSequence;
                if (NetUtils.RelativeSequenceNumber(ackSequence, _localWindowStart) < 0)
                {
                    continue;
                }

                int currentByte = startByte + i / BitsInByte;
                int currentBit  = i % BitsInByte;
                if ((acksData[currentByte] & (1 << currentBit)) == 0)
                {
                    continue;
                }

                if (ackSequence == _localWindowStart)
                {
                    _localWindowStart = (_localWindowStart + 1) % NetConstants.MaxSequence;
                }

                int storeIdx = ackSequence % _windowSize;

                if (_pendingPackets[storeIdx].NotEmpty)
                {
                    NetPacket removed = _pendingPackets[storeIdx].GetAndClear();
                    _peer.Recycle(removed);

                    _peer.DebugWrite("[PA]Removing reliableInOrder ack: {0} - true", ackSequence);
                }
                else
                {
                    _peer.DebugWrite("[PA]Removing reliableInOrder ack: {0} - false", ackSequence);
                }
            }
            _pendingPacketsAccess.Set();
        }
 public bool Clear(NetPeer peer)
 {
     if (_packet != null)
     {
         peer.Recycle(_packet);
         _packet = null;
         return(true);
     }
     return(false);
 }
Example #3
0
            public void Abort()
            {
                stopwatch.Stop();

                for (int i = 0; i < packets.Length; ++i)
                {
                    if (packets[i] != null)
                    {
                        peer.Recycle(packets[i]);
                    }
                }
            }
Example #4
0
 public void SendNextPackets()
 {
     lock (_outgoingPackets)
     {
         while (_outgoingPackets.Count > 0)
         {
             NetPacket packet = _outgoingPackets.Dequeue();
             _localSequence  = (_localSequence + 1) % NetConstants.MaxSequence;
             packet.Sequence = (ushort)_localSequence;
             _peer.SendRawData(packet);
             _peer.Recycle(packet);
         }
     }
 }
Example #5
0
        internal bool SendNextPacket()
        {
            NetPacket packet;

            lock (_outgoingPackets) {
                if (_outgoingPackets.Count == 0)
                {
                    return(false);
                }
                packet = _outgoingPackets.Dequeue();
            }
            _peer.SendRawData(packet);
            _peer.Recycle(packet);
            return(true);
        }
        public bool SendNextPackets()
        {
            NetPacket packet;

            lock (_outgoingPackets)
            {
                while (_outgoingPackets.Count > 0)
                {
                    packet = _outgoingPackets.Dequeue();
                    _peer.SendRawData(packet);
                    _peer.Recycle(packet);
                }
            }
            return(true);
        }
Example #7
0
        public bool SendNextPacket()
        {
            NetPacket packet;

            lock (_outgoingPackets)
            {
                if (_outgoingPackets.Count == 0)
                {
                    return(false);
                }
                packet = _outgoingPackets.Dequeue();
            }
            _localSequence  = (_localSequence + 1) % NetConstants.MaxSequence;
            packet.Sequence = (ushort)_localSequence;
            _peer.SendRawData(packet);
            _peer.Recycle(packet);
            return(true);
        }
Example #8
0
        public bool SendNextPacket()
        {
            if (_outgoingPackets.Count == 0)
            {
                return(false);
            }

            _localSequence++;
            NetPacket packet;

            lock (_outgoingPackets)
            {
                packet = _outgoingPackets.Dequeue();
            }
            packet.Sequence = _localSequence;
            _peer.SendRawData(packet.RawData);
            _peer.Recycle(packet);
            return(true);
        }
Example #9
0
        //ProcessAck in packet
        public void ProcessAck(NetPacket packet)
        {
            if (packet.Size != _outgoingAcks.Size)
            {
                NetUtils.DebugWrite("[PA]Invalid acks packet size");
                return;
            }

            ushort ackWindowStart = packet.Sequence;

            if (ackWindowStart > NetConstants.MaxSequence)
            {
                NetUtils.DebugWrite("[PA]Bad window start");
                return;
            }

            //check relevance
            if (NetUtils.RelativeSequenceNumber(ackWindowStart, _localWindowStart) <= -_windowSize)
            {
                NetUtils.DebugWrite("[PA]Old acks");
                return;
            }

            byte[] acksData = packet.RawData;
            Monitor.Enter(_pendingPackets);
            PendingPacket pendingPacket = _headPendingPacket;
            PendingPacket prevPacket    = null;

            while (pendingPacket != null)
            {
                int seq = pendingPacket.Packet.Sequence;
                int rel = NetUtils.RelativeSequenceNumber(seq, ackWindowStart);
                if (rel < 0 || rel >= _windowSize)
                {
                    prevPacket    = pendingPacket;
                    pendingPacket = pendingPacket.Next;
                    continue;
                }

                int idx         = seq % _windowSize;
                int currentByte = NetConstants.SequencedHeaderSize + idx / BitsInByte;
                int currentBit  = idx % BitsInByte;
                if ((acksData[currentByte] & (1 << currentBit)) == 0)
                {
#if STATS_ENABLED || DEBUG
                    _peer.Statistics.PacketLoss++;
#endif
                    //Skip false ack
                    prevPacket    = pendingPacket;
                    pendingPacket = pendingPacket.Next;
                    continue;
                }

                if (seq == _localWindowStart)
                {
                    //Move window
                    _localWindowStart = (_localWindowStart + _ackedPackets) % NetConstants.MaxSequence;
                    _ackedPackets     = 1;
                }
                else
                {
                    _ackedPackets++;
                }
                if (_headPendingPacket == pendingPacket)
                {
                    _headPendingPacket = _headPendingPacket.Next;
                }

                var packetToClear = pendingPacket;

                //move forward
                pendingPacket = pendingPacket.Next;
                if (prevPacket != null)
                {
                    prevPacket.Next = pendingPacket;
                }

                //clear acked packet
                _peer.Recycle(packetToClear.Packet);
                packetToClear.Clear();

                NetUtils.DebugWrite("[PA]Removing reliableInOrder ack: {0} - true", seq);
            }
            Monitor.Exit(_pendingPackets);
        }
Example #10
0
        protected override void ReceiveFromSocket(byte[] reusableBuffer, int count, NetEndPoint remoteEndPoint)
        {
            //Parse packet
            //Peer null when P2P connection packets
            NetPacket packet = _peer == null ? new NetPacket() : _peer.GetPacketFromPool(init: false);

            if (!packet.FromBytes(reusableBuffer, count))
            {
                if (_peer != null)
                {
                    _peer.Recycle(packet);
                }
                return;
            }

            //Check P2P mode
            if (PeerToPeerMode && packet.Property == PacketProperty.ConnectRequest)
            {
                NetUtils.DebugWrite(ConsoleColor.Cyan, "[NC] Received peer connect request");

                string peerKey = Encoding.UTF8.GetString(packet.RawData, 9, packet.RawData.Length - 9);
                if (peerKey != _connectKey)
                {
                    NetUtils.DebugWrite(ConsoleColor.Cyan, "[NC] Peer connect reject. Invalid key: " + peerKey);
                    return;
                }

                NetUtils.DebugWrite(ConsoleColor.Cyan, "[NC] Peer connect accepting");

                //Make initial packet and put id from received packet
                var connectPacket = NetPacket.CreateRawPacket(PacketProperty.ConnectAccept, 8);
                Buffer.BlockCopy(packet.RawData, 1, connectPacket, 1, 8);

                //Check our peer and create
                if (_peer == null)
                {
                    //Create connect id for proper connection
                    Connect(remoteEndPoint);
                }

                //Send raw
                _peer.SendRawData(connectPacket);

                //clean incoming packet
                _peer.Recycle(packet);

                //We connected
                ProcessConnectAccept();

                return;
            }

            //Check peer
            if (_peer == null)
            {
                return;
            }

            //Check endpoint
            if (!_peer.EndPoint.Equals(remoteEndPoint))
            {
                NetUtils.DebugWriteForce(ConsoleColor.DarkCyan, "[NC] Bad EndPoint " + remoteEndPoint);
                return;
            }

            if (packet.Property == PacketProperty.Disconnect)
            {
                NetUtils.DebugWrite(ConsoleColor.Cyan, "[NC] Received disconnection");
                CloseConnection(true);
                var disconnectEvent = CreateEvent(NetEventType.Disconnect);
                disconnectEvent.AdditionalInfo = "Received disconnection from server";
                EnqueueEvent(disconnectEvent);
                return;
            }

            if (packet.Property == PacketProperty.ConnectAccept)
            {
                if (_connected)
                {
                    return;
                }

                //check connection id
                if (BitConverter.ToUInt64(packet.RawData, 1) != _connectId)
                {
                    return;
                }

                //connection things
                ProcessConnectAccept();
                return;
            }

            //Process income packet
            _peer.ProcessPacket(packet);
        }
        //ProcessAck in packet
        public void ProcessAck(NetPacket packet)
        {
            int validPacketSize = (_windowSize - 1) / BitsInByte + 1 + NetConstants.SequencedHeaderSize;

            if (packet.Size != validPacketSize)
            {
                NetUtils.DebugWrite("[PA]Invalid acks packet size");
                return;
            }

            ushort ackWindowStart = packet.Sequence;

            if (ackWindowStart > NetConstants.MaxSequence)
            {
                NetUtils.DebugWrite("[PA]Bad window start");
                return;
            }

            //check relevance
            if (NetUtils.RelativeSequenceNumber(ackWindowStart, _localWindowStart) <= -_windowSize)
            {
                NetUtils.DebugWrite("[PA]Old acks");
                return;
            }

            byte[] acksData = packet.RawData;
            NetUtils.DebugWrite("[PA]AcksStart: {0}", ackWindowStart);
            int startByte = NetConstants.SequencedHeaderSize;

            Monitor.Enter(_pendingPackets);
            for (int i = 0; i < _windowSize; i++)
            {
                int ackSequence = (ackWindowStart + i) % NetConstants.MaxSequence;
                if (NetUtils.RelativeSequenceNumber(ackSequence, _localWindowStart) < 0)
                {
                    //NetUtils.DebugWrite(ConsoleColor.Cyan, "[PA] SKIP OLD: " + ackSequence);
                    //Skip old ack
                    continue;
                }

                int currentByte = startByte + i / BitsInByte;
                int currentBit  = i % BitsInByte;

                if ((acksData[currentByte] & (1 << currentBit)) == 0)
                {
#if STATS_ENABLED || DEBUG
                    if (_pendingPackets[ackSequence % _windowSize].TimeStamp.HasValue)
                    {
                        _peer.Statistics.PacketLoss++;
                    }
#endif
                    //NetUtils.DebugWrite(ConsoleColor.Cyan, "[PA] SKIP FALSE: " + ackSequence);
                    //Skip false ack
                    continue;
                }

                if (ackSequence == _localWindowStart)
                {
                    //Move window
                    _localWindowStart = (_localWindowStart + 1) % NetConstants.MaxSequence;
                }

                PendingPacket pendingPacket = _pendingPackets[ackSequence % _windowSize];
                if (pendingPacket.Packet != null)
                {
                    if (pendingPacket == _headPendingPacket)
                    {
                        _headPendingPacket = _headPendingPacket.Prev;
                    }
                    _peer.Recycle(pendingPacket.Packet);
                    pendingPacket.Clear();
                    NetUtils.DebugWrite("[PA]Removing reliableInOrder ack: {0} - true", ackSequence);
                }
                else
                {
                    NetUtils.DebugWrite("[PA]Removing reliableInOrder ack: {0} - false", ackSequence);
                }
            }
            Monitor.Exit(_pendingPackets);
        }
Example #12
0
        private void DataReceived(byte[] reusableBuffer, int count, NetEndPoint remoteEndPoint)
        {
#if STATS_ENABLED
            PacketsReceived++;
            BytesReceived += (uint)count;
#endif

            //Try get packet property
            PacketProperty property;
            if (!NetPacket.GetPacketProperty(reusableBuffer, out property))
            {
                return;
            }

            //Check unconnected
            switch (property)
            {
            case PacketProperty.DiscoveryRequest:
                if (DiscoveryEnabled)
                {
                    var netEvent = CreateEvent(NetEventType.DiscoveryRequest);
                    netEvent.RemoteEndPoint = remoteEndPoint;
                    netEvent.DataReader.SetSource(NetPacket.GetUnconnectedData(reusableBuffer, count));
                    EnqueueEvent(netEvent);
                }
                return;

            case PacketProperty.DiscoveryResponse:
            {
                var netEvent = CreateEvent(NetEventType.DiscoveryResponse);
                netEvent.RemoteEndPoint = remoteEndPoint;
                netEvent.DataReader.SetSource(NetPacket.GetUnconnectedData(reusableBuffer, count));
                EnqueueEvent(netEvent);
            }
                return;

            case PacketProperty.UnconnectedMessage:
                if (UnconnectedMessagesEnabled)
                {
                    var netEvent = CreateEvent(NetEventType.ReceiveUnconnected);
                    netEvent.RemoteEndPoint = remoteEndPoint;
                    netEvent.DataReader.SetSource(NetPacket.GetUnconnectedData(reusableBuffer, count));
                    EnqueueEvent(netEvent);
                }
                return;

            case PacketProperty.NatIntroduction:
            case PacketProperty.NatIntroductionRequest:
            case PacketProperty.NatPunchMessage:
            {
                if (NatPunchEnabled)
                {
                    NatPunchModule.ProcessMessage(remoteEndPoint, property, NetPacket.GetUnconnectedData(reusableBuffer, count));
                }
                return;
            }
            }

            //Check normal packets
            NetPacket packet;
            NetPeer   netPeer;

            //Check peers
            Monitor.Enter(_peers);
            int peersCount = _peers.Count;

            if (_peers.TryGetValue(remoteEndPoint, out netPeer))
            {
                Monitor.Exit(_peers);
                packet = netPeer.GetPacketFromPool(init: false);

                //Bad packet check
                if (!packet.FromBytes(reusableBuffer, 0, count))
                {
                    netPeer.Recycle(packet);
                    return;
                }

                //Send
                if (packet.Property == PacketProperty.Disconnect)
                {
                    if (BitConverter.ToInt64(packet.RawData, 1) != netPeer.ConnectId)
                    {
                        //Old or incorrect disconnect
                        netPeer.Recycle(packet);
                        return;
                    }

                    var netEvent = CreateEvent(NetEventType.Disconnect);
                    netEvent.Peer = netPeer;
                    netEvent.DataReader.SetSource(packet.RawData, 5, packet.RawData.Length - 5);
                    netEvent.DisconnectReason = DisconnectReason.RemoteConnectionClose;
                    EnqueueEvent(netEvent);
                    lock (_peersToRemove)
                    {
                        _peersToRemove.Enqueue(netPeer.EndPoint);
                    }
                    //do not recycle because no sense)
                }
                else if (packet.Property == PacketProperty.ConnectAccept)
                {
                    if (netPeer.ProcessConnectAccept(packet))
                    {
                        var connectEvent = CreateEvent(NetEventType.Connect);
                        connectEvent.Peer = netPeer;
                        EnqueueEvent(connectEvent);
                    }
                    netPeer.Recycle(packet);
                }
                else
                {
                    netPeer.ProcessPacket(packet);
                }
                return;
            }

            try
            {
                //Else add new peer
                packet = new NetPacket();
                if (!packet.FromBytes(reusableBuffer, 0, count))
                {
                    //Bad packet
                    return;
                }

                if (peersCount < _maxConnections && packet.Property == PacketProperty.ConnectRequest)
                {
                    int protoId = BitConverter.ToInt32(packet.RawData, 1);
                    if (protoId != NetConstants.ProtocolId)
                    {
                        NetUtils.DebugWrite(ConsoleColor.Cyan,
                                            "[NS] Peer connect reject. Invalid protocol ID: " + protoId);
                        return;
                    }

                    string peerKey = Encoding.UTF8.GetString(packet.RawData, 13, packet.RawData.Length - 13);
                    if (peerKey != _connectKey)
                    {
                        NetUtils.DebugWrite(ConsoleColor.Cyan, "[NS] Peer connect reject. Invalid key: " + peerKey);
                        return;
                    }

                    //Getting new id for peer
                    long connectionId = BitConverter.ToInt64(packet.RawData, 5);
                    //response with id
                    NetUtils.DebugWrite(ConsoleColor.Cyan, "[NS] Received peer connect request Id: {0}, EP: {1}",
                                        netPeer.ConnectId, remoteEndPoint);
                    netPeer = new NetPeer(this, remoteEndPoint, connectionId);

                    //clean incoming packet
                    netPeer.Recycle(packet);

                    _peers.Add(remoteEndPoint, netPeer);

                    var netEvent = CreateEvent(NetEventType.Connect);
                    netEvent.Peer = netPeer;
                    EnqueueEvent(netEvent);
                }
            }
            finally
            {
                Monitor.Exit(_peers);
            }
        }
Example #13
0
        //ProcessAck in packet
        public void ProcessAck(NetPacket packet)
        {
            int validPacketSize = (_windowSize - 1) / BitsInByte + 1 + NetConstants.SequencedHeaderSize;

            if (packet.RawData.Length != validPacketSize)
            {
                _peer.DebugWriteForce("[PA]Invalid acks packet size");
                return;
            }

            ushort ackWindowStart = packet.Sequence;

            if (ackWindowStart > NetConstants.MaxSequence)
            {
                _peer.DebugWrite("[PA]Bad window start");
                return;
            }

            //check relevance
            if (NetUtils.RelativeSequenceNumber(ackWindowStart, _localWindowStart) <= -_windowSize)
            {
                _peer.DebugWrite("[PA]Old acks");
                return;
            }

            byte[] acksData = packet.RawData;
            _peer.DebugWrite("[PA]AcksStart: {0}", ackWindowStart);
            int startByte = NetConstants.SequencedHeaderSize;

            Monitor.Enter(_pendingPacketsAccess);
            for (int i = 0; i < _windowSize; i++)
            {
                int ackSequence = (ackWindowStart + i) % NetConstants.MaxSequence;
                if (NetUtils.RelativeSequenceNumber(ackSequence, _localWindowStart) < 0)
                {
                    //Skip old ack
                    continue;
                }

                int currentByte = startByte + i / BitsInByte;
                int currentBit  = i % BitsInByte;

                if ((acksData[currentByte] & (1 << currentBit)) == 0)
                {
                    //Skip false ack
                    continue;
                }

                if (ackSequence == _localWindowStart)
                {
                    //Move window
                    _localWindowStart = (_localWindowStart + 1) % NetConstants.MaxSequence;
                }

                int storeIdx = ackSequence % _windowSize;
                if (_pendingPackets[storeIdx].NotEmpty)
                {
                    NetPacket removed = _pendingPackets[storeIdx].GetAndClear();
                    _peer.Recycle(removed);

                    _peer.DebugWrite("[PA]Removing reliableInOrder ack: {0} - true", ackSequence);
                }
                else
                {
                    _peer.DebugWrite("[PA]Removing reliableInOrder ack: {0} - false", ackSequence);
                }
            }
            Monitor.Exit(_pendingPacketsAccess);
        }