From 8204abe58b3f2477dcd002adb4aa6c26bae39057 Mon Sep 17 00:00:00 2001 From: jarikomppa Date: Tue, 8 Jul 2014 10:10:15 +0300 Subject: [PATCH 01/25] Fix possible buffer overrun (these arrays may be accessed at (1..512) below) --- Source/PacketizedTCP.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/PacketizedTCP.cpp b/Source/PacketizedTCP.cpp index e84dcd2b5..75e135743 100644 --- a/Source/PacketizedTCP.cpp +++ b/Source/PacketizedTCP.cpp @@ -87,8 +87,8 @@ bool PacketizedTCP::SendList( const char **data, const unsigned int *lengths, co #endif - unsigned int lengthsArray[512]; - const char *dataArray[512]; + unsigned int lengthsArray[513]; + const char *dataArray[513]; dataArray[0]=(char*) &dataLength; lengthsArray[0]=sizeof(dataLength); for (int i=0; i < 512 && i < numParameters; i++) From ad7507c5d7fda65890702c69a6e01fabeafa59f7 Mon Sep 17 00:00:00 2001 From: jarikomppa Date: Tue, 8 Jul 2014 10:15:21 +0300 Subject: [PATCH 02/25] sizeof() usage mistake reported by cppcheck --- Source/RakNetSocket2_Berkley_NativeClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/RakNetSocket2_Berkley_NativeClient.cpp b/Source/RakNetSocket2_Berkley_NativeClient.cpp index 58106c549..11e254993 100644 --- a/Source/RakNetSocket2_Berkley_NativeClient.cpp +++ b/Source/RakNetSocket2_Berkley_NativeClient.cpp @@ -33,7 +33,7 @@ void DomainNameToIP_Berkley_IPV4And6( const char *domainName, char ip[65] ) hints.ai_socktype = SOCK_DGRAM; if ((status = getaddrinfo(domainName, NULL, &hints, &res)) != 0) { - memset(ip, 0, sizeof(ip)); + memset(ip, 0, 65); // sizeof(ip) returns pointer size, not array size return; } From 87523e0950d827216d8a8e36ac3116a9ab0cc8dc Mon Sep 17 00:00:00 2001 From: "Peter Hille (png!das-system)" Date: Tue, 8 Jul 2014 23:14:44 +0200 Subject: [PATCH 03/25] Fix 3 memory leaks in AutoPatcher/ApplyPatch.cpp This commit fixes three memory leaks in the AutoPatcher code: ApplyPatch.cpp:288: patch = new char[patchSize]; ApplyPatch.cpp:289: old = new char[oldSize]; ApplyPatch.cpp:191: _new = new char[*newSize+1]; These buffers aren't deleted when returning from int TestPatchInMemory(int argc, char*argv[]) at line 300 of the original sources, so (patchSize + oldSize + newSize + 1) bytes of memory are leaked. --- DependentExtensions/Autopatcher/ApplyPatch.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DependentExtensions/Autopatcher/ApplyPatch.cpp b/DependentExtensions/Autopatcher/ApplyPatch.cpp index 53dc4efbb..da19ff5bb 100644 --- a/DependentExtensions/Autopatcher/ApplyPatch.cpp +++ b/DependentExtensions/Autopatcher/ApplyPatch.cpp @@ -297,6 +297,10 @@ int TestPatchInMemory(int argc,char *argv[]) fclose(newFile); fclose(oldFile); + delete[] patch; + delete[] old; + delete[] _new; + return res; } From 3898a7d7d9b6826d12a3cb348e9fde7651bae46a Mon Sep 17 00:00:00 2001 From: TheComet Date: Fri, 5 Sep 2014 20:18:09 +0200 Subject: [PATCH 04/25] Fixed proper installation destination --- Lib/DLL/CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/DLL/CMakeLists.txt b/Lib/DLL/CMakeLists.txt index 771fdc6b8..77da8ff83 100644 --- a/Lib/DLL/CMakeLists.txt +++ b/Lib/DLL/CMakeLists.txt @@ -13,9 +13,9 @@ IF(WIN32 AND NOT UNIX) SET( CMAKE_CXX_FLAGS "/D WIN32 /D _RAKNET_DLL /D _CRT_NONSTDC_NO_DEPRECATE /D _CRT_SECURE_NO_DEPRECATE /GS- /GR- ") ENDIF(WIN32 AND NOT UNIX) -IF(WIN32 AND NOT UNIX) - target_link_libraries (RakNetDLL ${RAKNET_LIBRARY_LIBS}) -ELSE(WIN32 AND NOT UNIX) - target_link_libraries (RakNetDLL ${RAKNET_LIBRARY_LIBS}) - INSTALL(TARGETS RakNetDLL DESTINATION ${RakNet_SOURCE_DIR}/Lib/DLL) -ENDIF(WIN32 AND NOT UNIX) +target_link_libraries (RakNetDLL ${RAKNET_LIBRARY_LIBS}) + +# install lib and header files to CMAKE_INSTALL_PREFIX +install(TARGETS RakNetDLL DESTINATION "lib") +install(FILES ${ALL_HEADER_SRCS} DESTINATION "include/RakNet") + From 62158854391e67494bca4bb0c431a8f394b8ea6b Mon Sep 17 00:00:00 2001 From: TheComet Date: Fri, 5 Sep 2014 20:20:19 +0200 Subject: [PATCH 05/25] Fixed proper installation destination for static lib --- Lib/LibStatic/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/LibStatic/CMakeLists.txt b/Lib/LibStatic/CMakeLists.txt index c116ee5f0..e7e1efd09 100644 --- a/Lib/LibStatic/CMakeLists.txt +++ b/Lib/LibStatic/CMakeLists.txt @@ -27,8 +27,10 @@ IF(WIN32 AND NOT UNIX) ELSE(WIN32 AND NOT UNIX) target_link_libraries (RakNetLibStatic ${RAKNET_LIBRARY_LIBS}) - INSTALL(TARGETS RakNetLibStatic DESTINATION ${RakNet_SOURCE_DIR}/Lib/RakNetLibStatic) - INSTALL(FILES ${ALL_HEADER_SRCS} DESTINATION ${RakNet_SOURCE_DIR}/include/raknet) ENDIF(WIN32 AND NOT UNIX) +INSTALL(TARGETS RakNetLibStatic DESTINATION "lib") +INSTALL(FILES ${ALL_HEADER_SRCS} DESTINATION "include/RakNet") + + From 71cadf64fc21db41e6e4e89a80d8644339a4e4eb Mon Sep 17 00:00:00 2001 From: TheComet Date: Sun, 7 Sep 2014 05:39:28 +0200 Subject: [PATCH 06/25] Fixed an issue where a pointer was being compared to a bool --- Source/ReplicaManager3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ReplicaManager3.cpp b/Source/ReplicaManager3.cpp index ba79c498a..dee569c81 100644 --- a/Source/ReplicaManager3.cpp +++ b/Source/ReplicaManager3.cpp @@ -138,7 +138,7 @@ void ReplicaManager3::AutoCreateConnectionList( { for (unsigned int index=0; index < participantListIn.Size(); index++) { - if (GetConnectionByGUID(participantListIn[index], worldId)==false) + if (GetConnectionByGUID(participantListIn[index], worldId)==NULL) { Connection_RM3 *connection = AllocConnection(rakPeerInterface->GetSystemAddressFromGuid(participantListIn[index]), participantListIn[index]); if (connection) From 48f4a064c5db9f194664d565075682cf4dda19d5 Mon Sep 17 00:00:00 2001 From: David Staessens Date: Fri, 12 Sep 2014 12:11:37 +0200 Subject: [PATCH 07/25] Fixed GetTimeoutTime function in RakPeer.cpp not working. --- Source/RakPeer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/RakPeer.cpp b/Source/RakPeer.cpp index 09718ded0..1277b2b22 100644 --- a/Source/RakPeer.cpp +++ b/Source/RakPeer.cpp @@ -2559,7 +2559,7 @@ RakNet::TimeMS RakPeer::GetTimeoutTime( const SystemAddress target ) RemoteSystemStruct * remoteSystem = GetRemoteSystemFromSystemAddress( target, false, true ); if ( remoteSystem != 0 ) - remoteSystem->reliabilityLayer.GetTimeoutTime(); + return remoteSystem->reliabilityLayer.GetTimeoutTime(); } return defaultTimeoutTime; } From e9d73217cf34b7a680f58c8668104f72ca8c1354 Mon Sep 17 00:00:00 2001 From: David Staessens Date: Tue, 16 Sep 2014 10:43:27 +0200 Subject: [PATCH 08/25] Fixed RakNet GUID generation. A mistake in the generation of the random 64bit RakNet GUID causes only about half of the bits to be set on the Windows platform. On other platforms 'gettimeofday' is used to generate the GUID, which can lead to collisions. Also using the 4 last bits of a short sleep duration as a source of randomness isn't sufficiently random so the granularity has been increased a bit. --- Source/RakPeer.cpp | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/Source/RakPeer.cpp b/Source/RakPeer.cpp index 09718ded0..9250afd01 100644 --- a/Source/RakPeer.cpp +++ b/Source/RakPeer.cpp @@ -4495,31 +4495,38 @@ uint64_t RakPeerInterface::Get64BitUniqueRandomNumber(void) + uint64_t g; #if defined(_WIN32) - uint64_t g=RakNet::GetTimeUS(); + g = RakNet::GetTimeUS(); +#else + struct timeval tv; + gettimeofday(&tv, NULL); + g = tv.tv_usec + tv.tv_sec * 1000000; +#endif RakNet::TimeUS lastTime, thisTime; int j; // Sleep a small random time, then use the last 4 bits as a source of randomness - for (j=0; j < 8; j++) + for (j=0; j < 4; j++) { - lastTime = RakNet::GetTimeUS(); - RakSleep(1); - RakSleep(0); - thisTime = RakNet::GetTimeUS(); - RakNet::TimeUS diff = thisTime-lastTime; - unsigned int diff4Bits = (unsigned int) (diff & 15); - diff4Bits <<= 32-4; - diff4Bits >>= j*4; - ((char*)&g)[j] ^= diff4Bits; + unsigned char diffByte = 0; + for (int i=0; i < 4; i++) + { + lastTime = RakNet::GetTimeUS(); + RakSleep(1); + RakSleep(0); + thisTime = RakNet::GetTimeUS(); + RakNet::TimeUS diff = thisTime-lastTime; + diffByte ^= (unsigned char) ((diff & 15) << (i * 2)); + if (i == 3) + { + diffByte ^= (unsigned char) ((diff & 15) >> 2); + } + } + + ((char*)&g)[4 + j] ^= diffByte; } return g; - -#else - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_usec + tv.tv_sec * 1000000; -#endif } // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void RakPeer::GenerateGUID(void) From d2f33bc4a94c9447d046ef7f6cd321632cadfa1d Mon Sep 17 00:00:00 2001 From: David Staessens Date: Tue, 16 Sep 2014 10:57:11 +0200 Subject: [PATCH 09/25] Removed an unused instance of RakNetRandom. --- Source/RakPeer.cpp | 11 ++--------- Source/ReliabilityLayer.cpp | 26 ++++++++++++-------------- Source/ReliabilityLayer.h | 11 +++++------ 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/Source/RakPeer.cpp b/Source/RakPeer.cpp index 09718ded0..352ec45bd 100644 --- a/Source/RakPeer.cpp +++ b/Source/RakPeer.cpp @@ -114,8 +114,6 @@ static const int mtuSizes[NUM_MTU_SIZES]={MAXIMUM_MTU_SIZE, 1200, 576}; using namespace RakNet; -static RakNetRandom rnr; - /* struct RakPeerAndIndex { @@ -400,11 +398,6 @@ StartupResult RakPeer::Startup( unsigned int maxConnections, SocketDescriptor *s FillIPList(); - if (myGuid==UNASSIGNED_RAKNET_GUID) - { - rnr.SeedMT( GenerateSeedFromGuid() ); - } - //RakPeerAndIndex rpai[32]; //RakAssert(socketDescriptorCount<32); @@ -5459,7 +5452,7 @@ void ProcessNetworkPacket( SystemAddress systemAddress, const char *data, const { remoteSystem->reliabilityLayer.HandleSocketReceiveFromConnectedPlayer( data, length, systemAddress, rakPeer->pluginListNTS, remoteSystem->MTUSize, - rakNetSocket, &rnr, timeRead, updateBitStream); + rakNetSocket, timeRead, updateBitStream); } } else @@ -5868,7 +5861,7 @@ bool RakPeer::RunUpdateCycle(BitStream &updateBitStream ) } } - remoteSystem->reliabilityLayer.Update( remoteSystem->rakNetSocket, systemAddress, remoteSystem->MTUSize, timeNS, maxOutgoingBPS, pluginListNTS, &rnr, updateBitStream ); // systemAddress only used for the internet simulator test + remoteSystem->reliabilityLayer.Update( remoteSystem->rakNetSocket, systemAddress, remoteSystem->MTUSize, timeNS, maxOutgoingBPS, pluginListNTS, updateBitStream ); // systemAddress only used for the internet simulator test // Check for failure conditions if ( remoteSystem->reliabilityLayer.IsDeadConnection() || diff --git a/Source/ReliabilityLayer.cpp b/Source/ReliabilityLayer.cpp index a9f17d1fa..19e82b1a0 100644 --- a/Source/ReliabilityLayer.cpp +++ b/Source/ReliabilityLayer.cpp @@ -634,7 +634,7 @@ void ReliabilityLayer::FreeThreadSafeMemory( void ) //------------------------------------------------------------------------------------------------------- bool ReliabilityLayer::HandleSocketReceiveFromConnectedPlayer( const char *buffer, unsigned int length, SystemAddress &systemAddress, DataStructures::List &messageHandlerList, int MTUSize, - RakNetSocket2 *s, RakNetRandom *rnr, CCTimeType timeRead, + RakNetSocket2 *s, CCTimeType timeRead, BitStream &updateBitStream) { #ifdef _DEBUG @@ -1084,7 +1084,7 @@ bool ReliabilityLayer::HandleSocketReceiveFromConnectedPlayer( // Sequenced internalPacket = BuildPacketFromSplitPacketList( internalPacket->splitPacketId, timeRead, - s, systemAddress, rnr, remotePortRakNetWasStartedOn_PS3, extraSocketOptions); + s, systemAddress, remotePortRakNetWasStartedOn_PS3, extraSocketOptions); if ( internalPacket ) { @@ -1132,7 +1132,7 @@ bool ReliabilityLayer::HandleSocketReceiveFromConnectedPlayer( InsertIntoSplitPacketList( internalPacket, timeRead ); internalPacket = BuildPacketFromSplitPacketList( internalPacket->splitPacketId, timeRead, - s, systemAddress, rnr, remotePortRakNetWasStartedOn_PS3, extraSocketOptions); + s, systemAddress, remotePortRakNetWasStartedOn_PS3, extraSocketOptions); if ( internalPacket == 0 ) { @@ -1227,7 +1227,7 @@ bool ReliabilityLayer::HandleSocketReceiveFromConnectedPlayer( InsertIntoSplitPacketList( internalPacket, timeRead ); internalPacket = BuildPacketFromSplitPacketList( internalPacket->splitPacketId, timeRead, - s, systemAddress, rnr, updateBitStream); + s, systemAddress, updateBitStream); if ( internalPacket == 0 ) { @@ -1687,7 +1687,6 @@ bool ReliabilityLayer::Send( char *data, BitSize_t numberOfBitsToSend, PacketPri void ReliabilityLayer::Update( RakNetSocket2 *s, SystemAddress &systemAddress, int MTUSize, CCTimeType time, unsigned bitsPerSecondLimit, DataStructures::List &messageHandlerList, - RakNetRandom *rnr, BitStream &updateBitStream) { @@ -1809,7 +1808,7 @@ void ReliabilityLayer::Update( RakNetSocket2 *s, SystemAddress &systemAddress, i if (congestionManager.ShouldSendACKs(time,timeSinceLastTick)) { - SendACKs(s, systemAddress, time, rnr, updateBitStream); + SendACKs(s, systemAddress, time, updateBitStream); } if (NAKs.Size()>0) @@ -1821,7 +1820,7 @@ void ReliabilityLayer::Update( RakNetSocket2 *s, SystemAddress &systemAddress, i dhfNAK.isPacketPair=false; dhfNAK.Serialize(&updateBitStream); NAKs.Serialize(&updateBitStream, GetMaxDatagramSizeExcludingMessageHeaderBits(), true); - SendBitStream( s, systemAddress, &updateBitStream, rnr, time ); + SendBitStream( s, systemAddress, &updateBitStream, time ); } DatagramHeaderFormat dhf; @@ -2210,7 +2209,7 @@ void ReliabilityLayer::Update( RakNetSocket2 *s, SystemAddress &systemAddress, i congestionManager.OnSendBytes(time,UDP_HEADER_SIZE+DatagramHeaderFormat::GetDataHeaderByteLength()); - SendBitStream( s, systemAddress, &updateBitStream, rnr, time ); + SendBitStream( s, systemAddress, &updateBitStream, time ); bandwidthExceededStatistic=outgoingPacketBuffer.Size()>0; // bandwidthExceededStatistic=sendPacketSet[0].IsEmpty()==false || @@ -2244,10 +2243,9 @@ void ReliabilityLayer::Update( RakNetSocket2 *s, SystemAddress &systemAddress, i //------------------------------------------------------------------------------------------------------- // Writes a bitstream to the socket //------------------------------------------------------------------------------------------------------- -void ReliabilityLayer::SendBitStream( RakNetSocket2 *s, SystemAddress &systemAddress, RakNet::BitStream *bitStream, RakNetRandom *rnr, CCTimeType currentTime) +void ReliabilityLayer::SendBitStream( RakNetSocket2 *s, SystemAddress &systemAddress, RakNet::BitStream *bitStream, CCTimeType currentTime) { (void) systemAddress; - (void) rnr; unsigned int length; @@ -3221,7 +3219,7 @@ InternalPacket * ReliabilityLayer::BuildPacketFromSplitPacketList( SplitPacketCh } //------------------------------------------------------------------------------------------------------- InternalPacket * ReliabilityLayer::BuildPacketFromSplitPacketList( SplitPacketIdType splitPacketId, CCTimeType time, - RakNetSocket2 *s, SystemAddress &systemAddress, RakNetRandom *rnr, + RakNetSocket2 *s, SystemAddress &systemAddress, BitStream &updateBitStream) { unsigned int i; @@ -3240,7 +3238,7 @@ InternalPacket * ReliabilityLayer::BuildPacketFromSplitPacketList( SplitPacketId #endif { // Ack immediately, because for large files this can take a long time - SendACKs(s, systemAddress, time, rnr, updateBitStream); + SendACKs(s, systemAddress, time, updateBitStream); internalPacket=BuildPacketFromSplitPacketList(splitPacketChannel,time); splitPacketChannelList.RemoveAtIndex(i); return internalPacket; @@ -3611,7 +3609,7 @@ bool ReliabilityLayer::IsResendQueueEmpty(void) const return resendLinkedListHead==0; } //------------------------------------------------------------------------------------------------------- -void ReliabilityLayer::SendACKs(RakNetSocket2 *s, SystemAddress &systemAddress, CCTimeType time, RakNetRandom *rnr, BitStream &updateBitStream) +void ReliabilityLayer::SendACKs(RakNetSocket2 *s, SystemAddress &systemAddress, CCTimeType time, BitStream &updateBitStream) { BitSize_t maxDatagramPayload = GetMaxDatagramSizeExcludingMessageHeaderBits(); @@ -3645,7 +3643,7 @@ void ReliabilityLayer::SendACKs(RakNetSocket2 *s, SystemAddress &systemAddress, dhf.Serialize(&updateBitStream); CC_DEBUG_PRINTF_1("AckSnd "); acknowlegements.Serialize(&updateBitStream, maxDatagramPayload, true); - SendBitStream( s, systemAddress, &updateBitStream, rnr, time ); + SendBitStream( s, systemAddress, &updateBitStream, time ); congestionManager.OnSendAck(time,updateBitStream.GetNumberOfBytesUsed()); // I think this is causing a bug where if the estimated bandwidth is very low for the recipient, only acks ever get sent diff --git a/Source/ReliabilityLayer.h b/Source/ReliabilityLayer.h index 14fbd8ff0..b3372bc2c 100644 --- a/Source/ReliabilityLayer.h +++ b/Source/ReliabilityLayer.h @@ -57,7 +57,6 @@ namespace RakNet { /// Forward declarations class PluginInterface2; -class RakNetRandom; typedef uint64_t reliabilityHeapWeightType; // int SplitPacketIndexComp( SplitPacketIndexType const &key, InternalPacket* const &data ); @@ -147,7 +146,7 @@ class ReliabilityLayer// /// \retval false Modified packet bool HandleSocketReceiveFromConnectedPlayer( const char *buffer, unsigned int length, SystemAddress &systemAddress, DataStructures::List &messageHandlerList, int MTUSize, - RakNetSocket2 *s, RakNetRandom *rnr, CCTimeType timeRead, BitStream &updateBitStream); + RakNetSocket2 *s, CCTimeType timeRead, BitStream &updateBitStream); /// This allocates bytes and writes a user-level message to those bytes. /// \param[out] data The message @@ -177,7 +176,7 @@ class ReliabilityLayer// void Update( RakNetSocket2 *s, SystemAddress &systemAddress, int MTUSize, CCTimeType time, unsigned bitsPerSecondLimit, DataStructures::List &messageHandlerList, - RakNetRandom *rnr, BitStream &updateBitStream); + BitStream &updateBitStream); /// Were you ever unable to deliver a packet despite retries? /// \return true means the connection has been lost. Otherwise not. @@ -223,7 +222,7 @@ class ReliabilityLayer// /// \param[in] s The socket used for sending data /// \param[in] systemAddress The address and port to send to /// \param[in] bitStream The data to send. - void SendBitStream( RakNetSocket2 *s, SystemAddress &systemAddress, RakNet::BitStream *bitStream, RakNetRandom *rnr, CCTimeType currentTime); + void SendBitStream( RakNetSocket2 *s, SystemAddress &systemAddress, RakNet::BitStream *bitStream, CCTimeType currentTime); ///Parse an internalPacket and create a bitstream to represent this data /// \return Returns number of bits used @@ -275,7 +274,7 @@ class ReliabilityLayer// /// Take all split chunks with the specified splitPacketId and try to reconstruct a packet. If we can, allocate and return it. Otherwise return 0 InternalPacket * BuildPacketFromSplitPacketList( SplitPacketIdType splitPacketId, CCTimeType time, - RakNetSocket2 *s, SystemAddress &systemAddress, RakNetRandom *rnr, BitStream &updateBitStream); + RakNetSocket2 *s, SystemAddress &systemAddress, BitStream &updateBitStream); InternalPacket * BuildPacketFromSplitPacketList( SplitPacketChannel *splitPacketChannel, CCTimeType time ); /// Delete any unreliable split packets that have long since expired @@ -540,7 +539,7 @@ class ReliabilityLayer// void PopListHead(bool modifyUnacknowledgedBytes); bool IsResendQueueEmpty(void) const; void SortSplitPacketList(DataStructures::List &data, unsigned int leftEdge, unsigned int rightEdge) const; - void SendACKs(RakNetSocket2 *s, SystemAddress &systemAddress, CCTimeType time, RakNetRandom *rnr, BitStream &updateBitStream); + void SendACKs(RakNetSocket2 *s, SystemAddress &systemAddress, CCTimeType time, BitStream &updateBitStream); DataStructures::List packetsToSendThisUpdate; DataStructures::List packetsToDeallocThisUpdate; From edbc1c9a6c0ec9bde5c61f7da6cffcd8d5b4169e Mon Sep 17 00:00:00 2001 From: David Staessens Date: Tue, 16 Sep 2014 11:44:56 +0200 Subject: [PATCH 10/25] Fixed threading issue in CancelConnectionAttempt. A mutex is locked when getting entries in requestedConnectionQueue, but these entries are then manipulated outside of the locked area. When calling CancelConnectionAttempt these entries can be removed while still being manipulated causing all kinds of corruptions and crashes. This is now fixed by queuing the canceling of connection attempts. --- Source/RakPeer.cpp | 45 ++++++++++++++++++++++++++++++--------------- Source/RakPeer.h | 3 +++ 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/Source/RakPeer.cpp b/Source/RakPeer.cpp index 09718ded0..ae5212c84 100644 --- a/Source/RakPeer.cpp +++ b/Source/RakPeer.cpp @@ -1685,28 +1685,41 @@ void RakPeer::CloseConnection( const AddressOrGUID target, bool sendDisconnectio // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void RakPeer::CancelConnectionAttempt( const SystemAddress target ) { - unsigned int i; + requestedConnectionCancelQueueMutex.Lock(); + requestedConnectionCancelQueue.Push(target, _FILE_AND_LINE_ ); + requestedConnectionCancelQueueMutex.Unlock(); +} - // Cancel pending connection attempt, if there is one - i=0; - requestedConnectionQueueMutex.Lock(); - while (i < requestedConnectionQueue.Size()) +void RakPeer::HandleConnectionCancelQueue( ) +{ + requestedConnectionCancelQueueMutex.Lock(); + while (requestedConnectionCancelQueue.Size() > 0) { - if (requestedConnectionQueue[i]->systemAddress==target) + unsigned int i; + + // Cancel pending connection attempt, if there is one + i=0; + requestedConnectionQueueMutex.Lock(); + while (i < requestedConnectionQueue.Size()) { + if (requestedConnectionQueue[i]->systemAddress==requestedConnectionCancelQueue[0]) + { #if LIBCAT_SECURITY==1 - CAT_AUDIT_PRINTF("AUDIT: Deleting requestedConnectionQueue %i client_handshake %x\n", i, requestedConnectionQueue[ i ]->client_handshake); - RakNet::OP_DELETE(requestedConnectionQueue[i]->client_handshake, _FILE_AND_LINE_ ); + CAT_AUDIT_PRINTF("AUDIT: Deleting requestedConnectionQueue %i client_handshake %x\n", i, requestedConnectionQueue[ i ]->client_handshake); + RakNet::OP_DELETE(requestedConnectionQueue[i]->client_handshake, _FILE_AND_LINE_ ); #endif - RakNet::OP_DELETE(requestedConnectionQueue[i], _FILE_AND_LINE_ ); - requestedConnectionQueue.RemoveAtIndex(i); - break; + RakNet::OP_DELETE(requestedConnectionQueue[i], _FILE_AND_LINE_ ); + requestedConnectionQueue.RemoveAtIndex(i); + break; + } + else + i++; } - else - i++; - } - requestedConnectionQueueMutex.Unlock(); + requestedConnectionQueueMutex.Unlock(); + requestedConnectionCancelQueue.RemoveAtIndex(0); + } + requestedConnectionCancelQueueMutex.Unlock(); } // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -5688,6 +5701,8 @@ bool RakPeer::RunUpdateCycle(BitStream &updateBitStream ) bufferedCommands.Deallocate(bcs, _FILE_AND_LINE_); } + HandleConnectionCancelQueue(); + if (requestedConnectionQueue.IsEmpty()==false) { if (timeNS==0) diff --git a/Source/RakPeer.h b/Source/RakPeer.h index 40ab131fe..c99d0ec9d 100644 --- a/Source/RakPeer.h +++ b/Source/RakPeer.h @@ -713,6 +713,7 @@ class RAK_DLL_EXPORT RakPeer : public RakPeerInterface, public RNS2EventHandler // Two versions needed because some buggy compilers strip the last parameter if unused, and crashes ConnectionAttemptResult SendConnectionRequest( const char* host, unsigned short remotePort, const char *passwordData, int passwordDataLength, PublicKey *publicKey, unsigned connectionSocketIndex, unsigned int extraData, unsigned sendConnectionAttemptCount, unsigned timeBetweenSendConnectionAttemptsMS, RakNet::TimeMS timeoutTime, RakNetSocket2* socket ); ConnectionAttemptResult SendConnectionRequest( const char* host, unsigned short remotePort, const char *passwordData, int passwordDataLength, PublicKey *publicKey, unsigned connectionSocketIndex, unsigned int extraData, unsigned sendConnectionAttemptCount, unsigned timeBetweenSendConnectionAttemptsMS, RakNet::TimeMS timeoutTime ); + void HandleConnectionCancelQueue( ); ///Get the reliability layer associated with a systemAddress. /// \param[in] systemAddress The player identifier /// \return 0 if none @@ -864,7 +865,9 @@ class RAK_DLL_EXPORT RakPeer : public RakPeerInterface, public RNS2EventHandler DataStructures::List pluginListTS, pluginListNTS; DataStructures::Queue requestedConnectionQueue; + DataStructures::Queue requestedConnectionCancelQueue; SimpleMutex requestedConnectionQueueMutex; + SimpleMutex requestedConnectionCancelQueueMutex; // void RunMutexedUpdateCycle(void); From 1519b5ba9e1e44619085eb8995da8e2102b803ed Mon Sep 17 00:00:00 2001 From: David Staessens Date: Wed, 17 Sep 2014 11:28:01 +0200 Subject: [PATCH 11/25] Fix for NatPunchthroughDebugInterface on non-Windows platforms --- Source/NatPunchthroughClient.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/NatPunchthroughClient.cpp b/Source/NatPunchthroughClient.cpp index 82bb07027..4c1491461 100644 --- a/Source/NatPunchthroughClient.cpp +++ b/Source/NatPunchthroughClient.cpp @@ -855,9 +855,17 @@ void NatPunchthroughClient::SendOutOfBand(SystemAddress sa, MessageID oobId) RakNet::Time serverTime = RakNet::GetTime() + clockDifferential; if (oobId==ID_NAT_ESTABLISH_UNIDIRECTIONAL) +#if defined(_WIN32) natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("%I64d: %s: OOB ID_NAT_ESTABLISH_UNIDIRECTIONAL to guid %s, system address %s.\n", serverTime, TestModeToString(sp.testMode), guidString, ipAddressString)); +#else + natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("%lld: %s: OOB ID_NAT_ESTABLISH_UNIDIRECTIONAL to guid %s, system address %s.\n", serverTime, TestModeToString(sp.testMode), guidString, ipAddressString)); +#endif else +#if defined(_WIN32) natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("%I64d: %s: OOB ID_NAT_ESTABLISH_BIDIRECTIONAL to guid %s, system address %s.\n", serverTime, TestModeToString(sp.testMode), guidString, ipAddressString)); +#else + natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("%lld: %s: OOB ID_NAT_ESTABLISH_BIDIRECTIONAL to guid %s, system address %s.\n", serverTime, TestModeToString(sp.testMode), guidString, ipAddressString)); +#endif } } void NatPunchthroughClient::OnNewConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, bool isIncoming) From b1649413a4c1d4f2c453cc764549c233644d2ab2 Mon Sep 17 00:00:00 2001 From: Hunter Mayer Date: Mon, 13 Oct 2014 22:55:24 -0700 Subject: [PATCH 12/25] Removes deprecation build warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changing the return type form char* to const char* removes a build warnings: “NatPunchthroughClient.cpp:800:11: Conversion from string literal to 'char *' is deprecated” Only tested on Mac Xcode 5.1.1 and a gcc compile running on Android (targeting 2.3 API level 10) --- Source/NatPunchthroughClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/NatPunchthroughClient.cpp b/Source/NatPunchthroughClient.cpp index 82bb07027..4a8b11f38 100644 --- a/Source/NatPunchthroughClient.cpp +++ b/Source/NatPunchthroughClient.cpp @@ -792,7 +792,7 @@ void NatPunchthroughClient::SendTTL(const SystemAddress &sa) rakPeerInterface->SendTTL(ipAddressString,sa.GetPort(), 2); } -char *TestModeToString(NatPunchthroughClient::SendPing::TestMode tm) +const char *TestModeToString(NatPunchthroughClient::SendPing::TestMode tm) { switch (tm) { From 1fa2bc5b44e9390929553de247481825d77292a6 Mon Sep 17 00:00:00 2001 From: Jason Gauci Date: Tue, 6 Jan 2015 00:51:41 -0800 Subject: [PATCH 13/25] Bug handling timestamps with different endian-ness --- Source/RakPeer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/RakPeer.cpp b/Source/RakPeer.cpp index 09718ded0..d5562d130 100644 --- a/Source/RakPeer.cpp +++ b/Source/RakPeer.cpp @@ -3778,6 +3778,7 @@ void RakPeer::ShiftIncomingTimestamp( unsigned char *data, const SystemAddress & #endif RakNet::BitStream timeBS( data, sizeof(RakNet::Time), false); + timeBS.EndianSwapBytes(0,sizeof(RakNet::Time)); RakNet::Time encodedTimestamp; timeBS.Read(encodedTimestamp); From 4fcb6f83298c1a4ae25d9545ba898ee038c84632 Mon Sep 17 00:00:00 2001 From: SirTobi Date: Thu, 5 Mar 2015 22:00:20 +0100 Subject: [PATCH 14/25] Fixed #28 (CMake doesn't compile samples by default) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0814bb8e0..f17a5013d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,6 @@ add_subdirectory(Lib) set(RAKNET_COMMON_LIBS RakNetLibStatic) -if( RAKNET_GENERATE_SAMPLES ) +if( RAKNET_ENABLE_SAMPLES ) add_subdirectory(Samples) endif() \ No newline at end of file From e832bf82c2088879dd05b85c62457842ddb82940 Mon Sep 17 00:00:00 2001 From: Echelon9 Date: Thu, 10 Jul 2014 23:51:10 +1000 Subject: [PATCH 15/25] Fix Issue #13 - It is possible i < X.size() should be used instead of X.size() --- Source/DS_WeightedGraph.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/DS_WeightedGraph.h b/Source/DS_WeightedGraph.h index f40fce3e4..03753675f 100644 --- a/Source/DS_WeightedGraph.h +++ b/Source/DS_WeightedGraph.h @@ -280,7 +280,7 @@ namespace DataStructures if (row==0) { path.Insert(startNode, _FILE_AND_LINE_); - for (col=0; outputQueue.Size(); col++) + for (col=0; col Date: Mon, 14 Jul 2014 17:30:35 +1000 Subject: [PATCH 16/25] Revert e00548f141 --- Source/DS_WeightedGraph.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/DS_WeightedGraph.h b/Source/DS_WeightedGraph.h index 03753675f..f40fce3e4 100644 --- a/Source/DS_WeightedGraph.h +++ b/Source/DS_WeightedGraph.h @@ -280,7 +280,7 @@ namespace DataStructures if (row==0) { path.Insert(startNode, _FILE_AND_LINE_); - for (col=0; col Date: Mon, 14 Jul 2014 17:37:05 +1000 Subject: [PATCH 17/25] Revised approach to fix Issue #13 --- Source/DS_WeightedGraph.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/DS_WeightedGraph.h b/Source/DS_WeightedGraph.h index f40fce3e4..852346139 100644 --- a/Source/DS_WeightedGraph.h +++ b/Source/DS_WeightedGraph.h @@ -280,7 +280,7 @@ namespace DataStructures if (row==0) { path.Insert(startNode, _FILE_AND_LINE_); - for (col=0; outputQueue.Size(); col++) + for (col=0; !outputQueue.Empty(); col++) path.Insert(outputQueue.Pop(), _FILE_AND_LINE_); return true; } @@ -296,7 +296,7 @@ namespace DataStructures } path.Insert(startNode, _FILE_AND_LINE_); - for (col=0; outputQueue.Size(); col++) + for (col=0; !outputQueue.Empty(); col++) path.Insert(outputQueue.Pop(), _FILE_AND_LINE_); return true; } From 82b69722811093183919925bd28d64489447d53d Mon Sep 17 00:00:00 2001 From: Echelon9 Date: Sat, 7 Mar 2015 01:42:48 +1100 Subject: [PATCH 18/25] Refactor outputQueue approach --- Source/DS_WeightedGraph.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/DS_WeightedGraph.h b/Source/DS_WeightedGraph.h index 852346139..1f1373b0a 100644 --- a/Source/DS_WeightedGraph.h +++ b/Source/DS_WeightedGraph.h @@ -280,7 +280,7 @@ namespace DataStructures if (row==0) { path.Insert(startNode, _FILE_AND_LINE_); - for (col=0; !outputQueue.Empty(); col++) + while (!outputQueue.Empty()) path.Insert(outputQueue.Pop(), _FILE_AND_LINE_); return true; } @@ -296,7 +296,7 @@ namespace DataStructures } path.Insert(startNode, _FILE_AND_LINE_); - for (col=0; !outputQueue.Empty(); col++) + while (!outputQueue.Empty()) path.Insert(outputQueue.Pop(), _FILE_AND_LINE_); return true; } From 4000141cf5687a16859af2d5ac4aa502b9db9ec3 Mon Sep 17 00:00:00 2001 From: Echelon9 Date: Thu, 10 Jul 2014 21:56:43 +1000 Subject: [PATCH 19/25] Resolve Issue #8 - Incorrect/duplicated test conditional --- Samples/CrossConnectionTest/CrossConnectionTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Samples/CrossConnectionTest/CrossConnectionTest.cpp b/Samples/CrossConnectionTest/CrossConnectionTest.cpp index c765e6c5c..6d997f5b6 100644 --- a/Samples/CrossConnectionTest/CrossConnectionTest.cpp +++ b/Samples/CrossConnectionTest/CrossConnectionTest.cpp @@ -99,7 +99,7 @@ int main() { printf("Test failed, ID_NEW_INCOMING_CONNECTION is true for both instances\n"); } - else if (gotConnectionRequestAccepted[0]==0 && gotConnectionRequestAccepted[1]==0) + else if (gotNewIncomingConnection[0]==0 && gotNewIncomingConnection[1]==0) { printf("Test failed, ID_NEW_INCOMING_CONNECTION is false for both instances\n"); } From 62c71c467fa19459c63fafb8f592361e6fe5661a Mon Sep 17 00:00:00 2001 From: SirTobi Date: Fri, 6 Mar 2015 22:35:18 +0100 Subject: [PATCH 20/25] fixed #52 --- Source/BitStream.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/BitStream.h b/Source/BitStream.h index ccb2e5d0c..70011197e 100644 --- a/Source/BitStream.h +++ b/Source/BitStream.h @@ -2022,7 +2022,7 @@ namespace RakNet } template - BitStream& operator<<(BitStream& out, templateType& c) + BitStream& operator<<(BitStream& out, const templateType& c) { out.Write(c); return out; From 11b1b8a25354e0f6e35dd818c55da86b06841d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AB=98=E7=BE=A4=E5=87=AF?= Date: Sun, 3 May 2015 20:46:53 +0800 Subject: [PATCH 21/25] Fix: RakString::Assign error when the _vsnprintf() length is larger than 512 in Linux. Just a typo error, i think. --- Source/RakString.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/RakString.cpp b/Source/RakString.cpp index 5d8583ecd..d44ffa12a 100644 --- a/Source/RakString.cpp +++ b/Source/RakString.cpp @@ -1377,7 +1377,7 @@ void RakString::Assign(const char *str, va_list ap) if (_vsnprintf(stackBuff, 512, str, ap)!=-1 #ifndef _WIN32 // Here Windows will return -1 if the string is too long; Linux just truncates the string. - && strlen(str) <511 + && strlen(stackBuff) <511 #endif ) { From cfbff96f2b2a779844572995c920c1a17a9046b5 Mon Sep 17 00:00:00 2001 From: Tim Ullrich Date: Fri, 8 May 2015 13:24:41 -0500 Subject: [PATCH 22/25] Add missing read alignment in ReplicaManager3::OnConstruction --- Source/ReplicaManager3.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/ReplicaManager3.cpp b/Source/ReplicaManager3.cpp index ba79c498a..a1d22ffcb 100644 --- a/Source/ReplicaManager3.cpp +++ b/Source/ReplicaManager3.cpp @@ -1185,6 +1185,7 @@ PluginReceiveResult ReplicaManager3::OnConstruction(Packet *packet, unsigned cha } } } + bsIn.AlignReadToByteBoundary(); for (index=0; index < constructionObjectListSize; index++) { From c15dd90afb7268f531312bc4b149206f219452b0 Mon Sep 17 00:00:00 2001 From: Joerg Boehnel Date: Thu, 19 Feb 2015 16:02:40 +0100 Subject: [PATCH 23/25] Fixed sorting on splitted packages... --- Source/ReliabilityLayer.cpp | 56 +++++++++++++++++---------- Source/ReliabilityLayer.h | 76 ++++++++++++++++++++++++++++++++++++- 2 files changed, 110 insertions(+), 22 deletions(-) diff --git a/Source/ReliabilityLayer.cpp b/Source/ReliabilityLayer.cpp index dbeb17b94..c3cc29f67 100644 --- a/Source/ReliabilityLayer.cpp +++ b/Source/ReliabilityLayer.cpp @@ -252,9 +252,9 @@ int RakNet::SplitPacketChannelComp( SplitPacketIdType const &key, SplitPacketCha if (key == data->returnedPacket->splitPacketId) return 0; #else - if (key < data->splitPacketList[0]->splitPacketId) + if (key < data->splitPacketList.PacketId()) return -1; - if (key == data->splitPacketList[0]->splitPacketId) + if (key == data->splitPacketList.PacketId()) return 0; #endif return 1; @@ -298,6 +298,8 @@ return 0; return 1; } + + //------------------------------------------------------------------------------------------------------- // Constructor //------------------------------------------------------------------------------------------------------- @@ -474,10 +476,14 @@ void ReliabilityLayer::FreeThreadSafeMemory( void ) for (i=0; i < splitPacketChannelList.Size(); i++) { - for (j=0; j < splitPacketChannelList[i]->splitPacketList.Size(); j++) + for (j=0; j < splitPacketChannelList[i]->splitPacketList.AllocSize(); j++) { - FreeInternalPacketData(splitPacketChannelList[i]->splitPacketList[j], _FILE_AND_LINE_ ); - ReleaseToInternalPacketPool( splitPacketChannelList[i]->splitPacketList[j] ); + internalPacket = splitPacketChannelList[i]->splitPacketList.Get(j); + if (internalPacket != NULL) + { + FreeInternalPacketData(splitPacketChannelList[i]->splitPacketList.Get(j), _FILE_AND_LINE_); + ReleaseToInternalPacketPool(splitPacketChannelList[i]->splitPacketList.Get(j)); + } } #if PREALLOCATE_LARGE_MESSAGES==1 if (splitPacketChannelList[i]->returnedPacket) @@ -2241,6 +2247,7 @@ void ReliabilityLayer::Update( RakNetSocket2 *s, SystemAddress &systemAddress, i //DeleteOldUnreliableSplitPackets( time ); } + //------------------------------------------------------------------------------------------------------- // Writes a bitstream to the socket //------------------------------------------------------------------------------------------------------- @@ -3055,7 +3062,7 @@ void ReliabilityLayer::InsertIntoSplitPacketList( InternalPacket * internalPacke newChannel->firstPacket=0; index=splitPacketChannelList.Insert(internalPacket->splitPacketId, newChannel, true, __FILE__,__LINE__); // Preallocate to the final size, to avoid runtime copies - newChannel->splitPacketList.Preallocate(internalPacket->splitPacketCount, __FILE__,__LINE__); + newChannel->splitPacketList.Preallocate(internalPacket, __FILE__,__LINE__); #endif } @@ -3138,7 +3145,12 @@ void ReliabilityLayer::InsertIntoSplitPacketList( InternalPacket * internalPacke } #else // Insert the packet into the SplitPacketChannel - splitPacketChannelList[index]->splitPacketList.Insert(internalPacket, __FILE__, __LINE__ ); + if (!splitPacketChannelList[index]->splitPacketList.Add(internalPacket, __FILE__, __LINE__ )) + { + FreeInternalPacketData(internalPacket, _FILE_AND_LINE_); + ReleaseToInternalPacketPool(internalPacket); + return; + } splitPacketChannelList[index]->lastUpdateTime=time; // If the index is 0, then this is the first packet. Record this so it can be returned to the user with download progress @@ -3148,8 +3160,8 @@ void ReliabilityLayer::InsertIntoSplitPacketList( InternalPacket * internalPacke // Return download progress if we have the first packet, the list is not complete, and there are enough packets to justify it if (splitMessageProgressInterval && splitPacketChannelList[index]->firstPacket && - splitPacketChannelList[index]->splitPacketList.Size()!=splitPacketChannelList[index]->firstPacket->splitPacketCount && - (splitPacketChannelList[index]->splitPacketList.Size()%splitMessageProgressInterval)==0) + splitPacketChannelList[index]->splitPacketList.AddedPacketsCount()!=splitPacketChannelList[index]->firstPacket->splitPacketCount && + (splitPacketChannelList[index]->splitPacketList.AddedPacketsCount()%splitMessageProgressInterval)==0) { // Return ID_DOWNLOAD_PROGRESS // Write splitPacketIndex (SplitPacketIndexType) @@ -3162,7 +3174,7 @@ void ReliabilityLayer::InsertIntoSplitPacketList( InternalPacket * internalPacke progressIndicator->dataBitLength=BYTES_TO_BITS(length); progressIndicator->data[0]=(MessageID)ID_DOWNLOAD_PROGRESS; unsigned int temp; - temp=splitPacketChannelList[index]->splitPacketList.Size(); + temp=splitPacketChannelList[index]->splitPacketList.AddedPacketsCount(); memcpy(progressIndicator->data+sizeof(MessageID), &temp, sizeof(unsigned int)); temp=(unsigned int)internalPacket->splitPacketCount; memcpy(progressIndicator->data+sizeof(MessageID)+sizeof(unsigned int)*1, &temp, sizeof(unsigned int)); @@ -3194,33 +3206,35 @@ InternalPacket * ReliabilityLayer::BuildPacketFromSplitPacketList( SplitPacketCh // int splitPacketPartLength; // Reconstruct - internalPacket = CreateInternalPacketCopy( splitPacketChannel->splitPacketList[0], 0, 0, time ); + internalPacket = CreateInternalPacketCopy( splitPacketChannel->splitPacketList.Get(0), 0, 0, time ); internalPacket->dataBitLength=0; - for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++) - internalPacket->dataBitLength+=splitPacketChannel->splitPacketList[j]->dataBitLength; + for (j=0; j < splitPacketChannel->splitPacketList.AllocSize(); j++) + internalPacket->dataBitLength+=splitPacketChannel->splitPacketList.Get(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; BitSize_t offset = 0; - for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++) + for (j=0; j < splitPacketChannel->splitPacketList.AllocSize(); 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; + splitPacket = splitPacketChannel->splitPacketList.Get(j); + memcpy(internalPacket->data + BITS_TO_BYTES(offset), splitPacket->data, (size_t)BITS_TO_BYTES(splitPacket->dataBitLength)); + offset += splitPacket->dataBitLength; } - for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++) + for (j=0; j < splitPacketChannel->splitPacketList.AllocSize(); j++) { - FreeInternalPacketData(splitPacketChannel->splitPacketList[j], _FILE_AND_LINE_ ); - ReleaseToInternalPacketPool(splitPacketChannel->splitPacketList[j]); + FreeInternalPacketData(splitPacketChannel->splitPacketList.Get(j), _FILE_AND_LINE_ ); + ReleaseToInternalPacketPool(splitPacketChannel->splitPacketList.Get(j)); } RakNet::OP_DELETE(splitPacketChannel, __FILE__, __LINE__); return internalPacket; #endif } + + //------------------------------------------------------------------------------------------------------- InternalPacket * ReliabilityLayer::BuildPacketFromSplitPacketList( SplitPacketIdType splitPacketId, CCTimeType time, RakNetSocket2 *s, SystemAddress &systemAddress, RakNetRandom *rnr, @@ -3238,7 +3252,7 @@ InternalPacket * ReliabilityLayer::BuildPacketFromSplitPacketList( SplitPacketId #if PREALLOCATE_LARGE_MESSAGES==1 if (splitPacketChannel->splitPacketsArrived==splitPacketChannel->returnedPacket->splitPacketCount) #else - if (splitPacketChannel->splitPacketList.Size()==splitPacketChannel->splitPacketList[0]->splitPacketCount) + if (splitPacketChannel->splitPacketList.AllocSize() == splitPacketChannel->splitPacketList.AddedPacketsCount()) #endif { // Ack immediately, because for large files this can take a long time diff --git a/Source/ReliabilityLayer.h b/Source/ReliabilityLayer.h index 14fbd8ff0..20b169016 100644 --- a/Source/ReliabilityLayer.h +++ b/Source/ReliabilityLayer.h @@ -60,12 +60,86 @@ class PluginInterface2; class RakNetRandom; typedef uint64_t reliabilityHeapWeightType; + + +class SortedSplittedPackets +{ +private: + InternalPacket ** data; + unsigned int allocation_size; + unsigned int addedPacketsCount; + SplitPacketIdType packetId; + +public: + SortedSplittedPackets() + { + data = NULL; + allocation_size = 0; + addedPacketsCount = 0; + } + ~SortedSplittedPackets() + { + if (allocation_size > 0) + { + RakNet::OP_DELETE_ARRAY(data, _FILE_AND_LINE_); + } + } + + void Preallocate(InternalPacket * internalPacket, const char *file, unsigned int line) + { + RakAssert(data == NULL); + allocation_size = internalPacket->splitPacketCount; + data = RakNet::OP_NEW_ARRAY(allocation_size, file, line); + packetId = internalPacket->splitPacketId; + + for (int i = 0; i < allocation_size; ++i) + { + data[i] = NULL; + } + } + bool Add(InternalPacket * internalPacket, const char *file, unsigned int line) + { + RakAssert(data != NULL); + RakAssert(internalPacket->splitPacketIndex < allocation_size); + RakAssert(packetId == internalPacket->splitPacketId); + RakAssert(data[internalPacket->splitPacketIndex] == NULL); + if (data[internalPacket->splitPacketIndex] == NULL) + { + data[internalPacket->splitPacketIndex] = internalPacket; + ++addedPacketsCount; + return true; + } + return false; + } + + unsigned int AllocSize() + { + return allocation_size; + } + unsigned int AddedPacketsCount() + { + return addedPacketsCount; + } + InternalPacket * Get(unsigned int index) + { + RakAssert(data != NULL); + RakAssert(index < allocation_size); + return data[index]; + } + SplitPacketIdType PacketId() + { + RakAssert(data != NULL); + return packetId; + } +}; + + // int SplitPacketIndexComp( SplitPacketIndexType const &key, InternalPacket* const &data ); struct SplitPacketChannel// { CCTimeType lastUpdateTime; - DataStructures::List splitPacketList; + SortedSplittedPackets splitPacketList; #if PREALLOCATE_LARGE_MESSAGES==1 InternalPacket *returnedPacket; From 5c719c392b34794c5e45cc35f0b7e1b2d6164ec7 Mon Sep 17 00:00:00 2001 From: GBearUK Date: Mon, 22 Jun 2015 07:50:18 +0100 Subject: [PATCH 24/25] Fix for GetIndexFromKey failing on forwardingRequestList The ordered list wasn't ordered! --- Source/UDPProxyCoordinator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/UDPProxyCoordinator.cpp b/Source/UDPProxyCoordinator.cpp index 7f4578d49..7deec4885 100644 --- a/Source/UDPProxyCoordinator.cpp +++ b/Source/UDPProxyCoordinator.cpp @@ -44,7 +44,7 @@ int UDPProxyCoordinator::ForwardingRequestComp( const SenderAndTargetAddress &ke if (key.senderClientAddress < data->sata.senderClientAddress ) return -1; if (key.senderClientAddress > data->sata.senderClientAddress ) - return -1; + return 1; if (key.targetClientAddress < data->sata.targetClientAddress ) return -1; if (key.targetClientAddress > data->sata.targetClientAddress ) From 66ea65dd435fe3dfff15a88619e80d3376ac7af7 Mon Sep 17 00:00:00 2001 From: vandeer Date: Fri, 18 Sep 2015 14:19:36 +0500 Subject: [PATCH 25/25] fix RakMemoryOverride --- Source/RakPeer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/RakPeer.cpp b/Source/RakPeer.cpp index 09718ded0..f1f5a4d95 100644 --- a/Source/RakPeer.cpp +++ b/Source/RakPeer.cpp @@ -5497,7 +5497,7 @@ void RakPeer::DerefAllSockets(void) unsigned int i; for (i=0; i < socketList.Size(); i++) { - delete socketList[i]; + RakNet::OP_DELETE(socketList[i], _FILE_AND_LINE_); } socketList.Clear(false, _FILE_AND_LINE_); }