//ProcessAck in packet public void ProcessAck(NetPacket packet) { ushort ackWindowStart = packet.Sequence; if (ackWindowStart >= NetConstants.MaxSequence) { NetUtils.DebugWrite("[PA]Bad window start"); return; } byte[] acksData = packet.RawData; NetUtils.DebugWrite("[PA]AcksStart: {0}", ackWindowStart); //Monitor.Enter(_pendingPackets); for (int i = 0; i < packet.GetDataSize(); ++i) { byte acksByte = acksData[i]; for (int idx = 0; idx < 8; ++idx) { if ((acksByte & (1 << idx)) == 0) { // Packet not ack, will be resent automaticaly as needed continue; } // packet acknowledged = true int seqAck = NetUtils.IncrementSequenceNumber(ackWindowStart, i * 8 + idx); PendingPacket pendingPacket = _tailPendingPacket; PendingPacket prevPacket = null; while (pendingPacket != _headPendingPacket) { // Looking for the packet to acknowledge if (pendingPacket.Packet == null || pendingPacket.Packet.Sequence != seqAck) { prevPacket = pendingPacket; pendingPacket = pendingPacket.Next; continue; } //clear acked packet pendingPacket.Packet.DontRecycleNow = false; pendingPacket.Packet.Recycle(); pendingPacket.Clear(); // Packet found, remove it from the list while (_tailPendingPacket.Packet == null && _tailPendingPacket != _headPendingPacket) { _tailPendingPacket = _tailPendingPacket.Next; } NetUtils.DebugWrite("[PA]Removing reliableInOrder ack: {0} - true", seqAck); break; } } } packet.Recycle(); //Monitor.Exit(_pendingPackets); }
//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); }