Skip to content
This repository has been archived by the owner on Jan 13, 2022. It is now read-only.

Packet Corruption on 64bit #50

Open
garrynewman opened this issue Mar 4, 2015 · 25 comments
Open

Packet Corruption on 64bit #50

garrynewman opened this issue Mar 4, 2015 · 25 comments

Comments

@garrynewman
Copy link

I've been having issues where packets are apparently corrupted. This seems to only affect about 1 in 50 people, who it seems to happen to quite regularly. I've added CRCs to both datagrams and packet content, the CRC on the datagrams always pass. The CRC on the packet content itself fails very occasionally.

This apparently happens when packet size > MTU. Could there be an issue when sending lots of data to 100+ connected clients where the client would reconstruct packets wrong?

@garrynewman
Copy link
Author

I did some logging and found that the issue is only apparent when the packets are split, and when the first fragment isn't received first.

It seems to be that split packets aren't being reconstructed in the correct order, but in the order in which the packets are received. I've changed the BuildPacketFromSplitPacketList function to construct the packets in order splitPacketIndex - will report whether this fixes it.

@larku
Copy link

larku commented Mar 5, 2015

Hi @garrynewman,

If you could contribute a patch/pull request that would be great - I'm using RakNet in an application that will often have packets > MTU so I'm very interested in any fixes here.

Regards.

@larku
Copy link

larku commented Apr 18, 2015

Hey @garrynewman

Did you have any success with your fixes?

Note, the latest source already appears to use splitPacketIndex when reconstructing the packets:

memcpy(internalPacket->data+splitPacket->splitPacketIndex*splitPacketPartLength, splitPacket->data, (size_t) BITS_TO_BYTES(splitPacketChannel->splitPacketList[j]->dataBitLength));

Regards.

@garrynewman
Copy link
Author

Yeah my fix did fix it for me. Here's what I changed in BuildPacketFromSplitPacketList:

    for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++)
    {
        splitPacket=splitPacketChannel->splitPacketList[j];
        memcpy(internalPacket->data + BITS_TO_BYTES(offset), splitPacket->data, (size_t)BITS_TO_BYTES(splitPacketChannel->splitPacketList[j]->dataBitLength));
        offset += splitPacketChannel->splitPacketList[j]->dataBitLength;
    }

to

    BitSize_t offset = 0;
    for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++)
    {
//
// GARRY - RETRIEVE SPLIT PACKETS IN THE PROPER ORDER
//
        splitPacket = NULL;

        for ( int a = 0; a < splitPacketChannel->splitPacketList.Size(); a++ )
        {
            if ( splitPacketChannel->splitPacketList[a]->splitPacketIndex != j )
                continue;

            splitPacket = splitPacketChannel->splitPacketList[a];
            break;
        }

        if ( splitPacket == NULL ) 
        splitPacket = splitPacketChannel->splitPacketList[j];

        memcpy( internalPacket->data + BITS_TO_BYTES( offset ), splitPacket->data, (size_t)BITS_TO_BYTES( splitPacket->dataBitLength ) );
        offset += splitPacket->dataBitLength;
//
// END GARRY
//
    }

@Cleroth
Copy link

Cleroth commented Apr 18, 2015

Having a serious issue like this and no replies from the developers doesn't exactly make RakNet look very good.

@vrripoll
Copy link

it, is the code of previous version, it think all split packet have the same size, it store the size into splitPacketPartLength=BITS_TO_BYTES(splitPacketChannel->firstPacket->dataBitLength);

and fill the memory with
memcpy(internalPacket->data+splitPacket->splitPacketIndex*splitPacketPartLength, splitPacket->data, (size_t) BITS_TO_BYTES(splitPacketChannel->splitPacketList[j]->dataBitLength));

and use splitPacketIndex to put the split pack in this position.

but i am not sure this code it is ok and all split packet have the same size.

----------- CODE -----------------------------
'''
InternalPacket * ReliabilityLayer::BuildPacketFromSplitPacketList( SplitPacketChannel *splitPacketChannel, CCTimeType time )
{
#if PREALLOCATE_LARGE_MESSAGES==1
InternalPacket *returnedPacket=splitPacketChannel->returnedPacket;
RakNet::OP_DELETE(splitPacketChannel, FILE, LINE);
(void) time;
return returnedPacket;
#else
unsigned int j;
InternalPacket * internalPacket, *splitPacket;
int splitPacketPartLength;
internalPacket = CreateInternalPacketCopy( splitPacketChannel->splitPacketList[0], 0, 0, time );
internalPacket->dataBitLength=0;
for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++)
internalPacket->dataBitLength+=splitPacketChannel->splitPacketList[j]->dataBitLength;
splitPacketPartLength=BITS_TO_BYTES(splitPacketChannel->firstPacket->dataBitLength);

internalPacket->data = (unsigned char*) rakMalloc_Ex( (size_t) BITS_TO_BYTES( internalPacket->dataBitLength ), _FILE_AND_LINE_ );
internalPacket->allocationScheme=InternalPacket::NORMAL;

for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++)
{
    splitPacket=splitPacketChannel->splitPacketList[j];
    memcpy(internalPacket->data+splitPacket->splitPacketIndex*splitPacketPartLength, splitPacket->data, (size_t) BITS_TO_BYTES(splitPacketChannel->splitPacketList[j]->dataBitLength));
}

for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++)
{
    FreeInternalPacketData(splitPacketChannel->splitPacketList[j], _FILE_AND_LINE_ );
    ReleaseToInternalPacketPool(splitPacketChannel->splitPacketList[j]);
}
RakNet::OP_DELETE(splitPacketChannel, __FILE__, __LINE__);

return internalPacket;

#endif
}
'''

@Cleroth
Copy link

Cleroth commented Jun 10, 2015

I might want to wrape that code with ```

@vrripoll
Copy link

sorry i only speak a little english

@Cleroth
Copy link

Cleroth commented Jun 10, 2015

Put ``` at the start and end of your code.

@Cleroth
Copy link

Cleroth commented Jun 10, 2015

That's almost right. You have to include new lines before and after it. So like

'''
Code
Code
'''

@vrripoll
Copy link

sorry i try it,y put ''' but it is not ok

@Cleroth
Copy link

Cleroth commented Jun 10, 2015

It's ```, I just put ''' as an example so it didn't show as code. You still have to put a new line before your last one.

@vrripoll
Copy link

in the code of GARRY i dont understan how this part of the code it is possible

if ( splitPacket == NULL )
splitPacket = splitPacketChannel->splitPacketList[j];

how ist si posible not found splitPacket by splitPacketIndex

@Cleroth
Copy link

Cleroth commented Jun 10, 2015

Packet editing? Packet corruption? Dunno.

@vrripoll
Copy link

i think if it not found splitPacket , it is a error and this mesage must be discard.
if use splitPacket = splitPacketChannel->splitPacketList[j]; it must be copying data in a Incorrect position

@Mellnik
Copy link

Mellnik commented Jul 16, 2015

Can this be fixed and officially be committed on the repo? Ever since Oculus bought it there are no big updates...

@Cleroth
Copy link

Cleroth commented Jul 16, 2015

RakNet has been abandoned, as is shown on the website.

@biller23
Copy link

Maybe Oculus, the new owner of RakNet, is too busy with VR to care about this project for now...

@Mellnik
Copy link

Mellnik commented Jul 16, 2015

Fine, Oculus shall then assign someone repo admin rights so he can process pull requests.

@Cleroth
Copy link

Cleroth commented Jul 16, 2015

I'm not really sure why they bought something to leave it die. It certainly at least needs someone to process pull requests, so we can include fixes like Garry's.

@Brybry
Copy link

Brybry commented Jul 25, 2015

Maybe someone with the know-how will start a community fork

Thanks for the fix @garrynewman! I was beating my head against this bug for hours :(
As noted by larku, it seems e97c4bb introduced this bug.

@larku
Copy link

larku commented Jul 27, 2015

I've got a fork ( https://github.com/larku/RakNet ) that includes most of the pending pull requests from the official if that's of use to you. I'm also happy to accept pull requests into this fork.

@Cleroth
Copy link

Cleroth commented Jul 27, 2015

Seems the problem described in this ticket is still present in your fork.

@larku
Copy link

larku commented Jul 27, 2015

Hey @Cleroth, that fork includes:

larku@c15dd90

Which should address this.

@Cleroth
Copy link

Cleroth commented Jul 27, 2015

Oh... so it was fixed long ago in a different way...
Thanks. I might actually give RakNet a try now.

@Mellnik Mellnik mentioned this issue Oct 26, 2015
rhard pushed a commit to rhard/RakNet that referenced this issue Aug 20, 2021
…r-gitignore

Added gitignore for top-level 'build' directory since this is fairly …
rhard pushed a commit to rhard/RakNet that referenced this issue Aug 20, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants