[ENet-discuss] Why not drop it when reliableSequenceNumber < channel -> incomingReliableSequenceNumber?
Lee Salzman
lsalzman at gmail.com
Thu Jun 14 15:33:47 PDT 2012
By the time it gets there, reliableSequenceNumber < channel -> incomingReliableSequenceNumber indicates a roll-over in the sequence number space, not an old packet. So, essentially, the sequence number rolled over and became small again, but that represents still a 'higher' sequence number in the overall scheme.
The actual dropping happens earlier in the code here:
if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
{
reliableSequenceNumber = command -> header.reliableSequenceNumber;
reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
goto freePacket;
}
The reason the above code works, if the packet was old or if it is actually a roll-over, its reliable window gets bumped into the space of rolled-over windows. If a roll-over happened, the current window of the channel would be near the top of the sequence number space, and the reliable window of the packet would be near the bottom, so bumping it should not put it outside of the current window + a margin of reliable windows that are "guaranteed" to be empty (or rather free of old packets, by virtue of it taking a rather long time for the sequence number to wrap, and verifying all packets within that bubble have been acknowledged) at the end of the sequence number space for the purpose of disambiguating this case, as new packets will never advance beyond this bubble of free sequence number space. If it was, however, just an old packet, reliable window and current window would be close enough to each other that bumping it puts it outside of that range of free windows instead,
thus hitting the free packet goto there.
This is totally code you should not try to understand while sober, it is harder to understand that way, I think. Or at least make sure you are in a sufficiently abnormal state of consciousness to understand wrapping sequence number spaces...
On 06/15/2012 05:54 AM, kaka chen wrote:
> Hi All:
>
> I am reading the source code of enet-1.3.4, but have some questions now. Can someone explain when enet_peer_queue_incoming_
> commands() process reliable command, if the reliableSequenceNumber < channel -> incomingReliableSequenceNumber, it will be added at the end of the channel -> incomingReliableCommands? Then how it worked? Why not drop it? Thanks!
>
> 790 case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
> 791 if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
> 792 goto freePacket;
> 793
> 794 for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
> 795 currentCommand != enet_list_end (& channel -> incomingReliableCommands);
> 796 currentCommand = enet_list_previous (currentCommand))
> 797 {
> 798 incomingCommand = (ENetIncomingCommand *) currentCommand;
> 799
> 800 if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
> 801 {
> 802 if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
> 803 continue;
> 804 }
> 805 else
> 806 if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
> 807 break;
> 808
> 809 if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber)
> 810 {
> 811 if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
> 812 break;
> 813
> 814 goto freePacket;
> 815 }
> 816 }
> 817 break;
>
> Kaka Chen
>
>
> _______________________________________________
> ENet-discuss mailing list
> ENet-discuss at cubik.org
> http://lists.cubik.org/mailman/listinfo/enet-discuss
More information about the ENet-discuss
mailing list