void AckHandles(UdpHeader header, bool updateRtt) { while (!sendWindow.Empty) { UdpHandle handle = sendWindow.Peek(); int seqDistance = UdpMath.SeqDistance(handle.ObjSequence, header.AckSequence, UdpHeader.SEQ_PADD); if (seqDistance > 0) { break; } if (handle.IsObject) { if (seqDistance <= -UdpSocket.AckRedundancy) { // track stats stats.PacketLost(); socket.Statistics.PacketLost(); // handle lost ObjectLost(handle.Object); } else { if ((header.AckHistory & (1UL << -seqDistance)) != 0UL) { // track stats stats.PacketDelivered(); socket.Statistics.PacketDelivered(); // handle delivered objects ObjectDelivered(handle.Object); } else { // track stats stats.PacketLost(); socket.Statistics.PacketLost(); // handle ObjectLost(handle.Object); } } } if (seqDistance == 0 && header.AckTime > 0) { UpdatePing(recvTime, handle.SendTime, header.AckTime); } sendWindow.Dequeue(); } }
bool ParseHeader(UdpStream stream) { // we should always start at ptr 0 UdpAssert.Assert(stream.Ptr == 0); UdpHeader header = new UdpHeader(); header.Unpack(stream, socket); // after unpacking the header, the pointer should be at the header size UdpAssert.Assert(stream.Ptr == UdpSocket.HeaderBitSize); int seqDistance = UdpMath.SeqDistance(header.ObjSequence, recvSequence, UdpHeader.SEQ_PADD); // we have to be within window size if (seqDistance > socket.Config.PacketWindow || seqDistance < -socket.Config.PacketWindow) { ConnectionError(UdpConnectionError.SequenceOutOfBounds); return(false); } // this is an old packet if (seqDistance <= 0) { return(false); } // update receive history if (seqDistance >= UdpSocket.AckRedundancy) { recvHistory = 1UL; } else { recvHistory = (recvHistory << seqDistance) | 1UL; } // update our receive stats recvSequence = header.ObjSequence; recvSinceLastSend += 1; // ack sent objects AckHandles(header, true); return(true); }
bool ParseHeader(ref UdpBitStream buffer) { UdpHeader header = new UdpHeader(); header.Unpack(new UdpBitStream(buffer.Data, buffer.Length, 0), socket); // Assign bit size if (socket.Config.WritePacketBitSize) { buffer.Length = header.BitSize; } int seqDistance = UdpMath.SeqDistance(header.ObjSequence, recvSequence, UdpHeader.SEQ_PADD); // we have to be within window size if (seqDistance > socket.Config.PacketWindow || seqDistance < -socket.Config.PacketWindow) { ConnectionError(UdpConnectionError.SequenceOutOfBounds); return(false); } // this is an old packet if (seqDistance <= 0) { return(false); } // update receive history if (seqDistance >= socket.Config.AckRedundancy) { recvHistory = 1UL; } else { recvHistory = (recvHistory << seqDistance) | 1UL; } // update our receive stats recvSequence = header.ObjSequence; recvSinceLastSend += 1; // ack sent objects AckHandles(header, true); return(true); }
void AckHandles(UdpHeader header, bool updateRtt) { while (!sendWindow.Empty) { UdpHandle handle = sendWindow.Peek(); int seqDistance = UdpMath.SeqDistance(handle.ObjSequence, header.AckSequence, UdpHeader.SEQ_PADD); if (seqDistance > 0) { break; } if (handle.IsObject) { if (seqDistance <= -socket.Config.AckRedundancy) { ObjectLost(handle.Object); } if ((header.AckHistory & (1UL << -seqDistance)) != 0UL) { ObjectDelivered(handle.Object); } else { ObjectLost(handle.Object); } } if (seqDistance == 0 && header.AckTime > 0) { UpdatePing(recvTime, handle.SendTime, header.AckTime); } sendWindow.Dequeue(); } }