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 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; } 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") + 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") + + 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"); } 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; diff --git a/Source/DS_WeightedGraph.h b/Source/DS_WeightedGraph.h index f40fce3e4..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.Size(); 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.Size(); col++) + while (!outputQueue.Empty()) path.Insert(outputQueue.Pop(), _FILE_AND_LINE_); return true; } diff --git a/Source/NatPunchthroughClient.cpp b/Source/NatPunchthroughClient.cpp index 82bb07027..6c0438f92 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) { @@ -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) 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++) 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; } diff --git a/Source/RakPeer.cpp b/Source/RakPeer.cpp index 09718ded0..0365a0196 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); @@ -1685,28 +1678,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(); } // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -2559,7 +2565,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; } @@ -3778,6 +3784,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); @@ -4495,31 +4502,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) @@ -5459,7 +5473,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 @@ -5497,7 +5511,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_); } @@ -5688,6 +5702,8 @@ bool RakPeer::RunUpdateCycle(BitStream &updateBitStream ) bufferedCommands.Deallocate(bcs, _FILE_AND_LINE_); } + HandleConnectionCancelQueue(); + if (requestedConnectionQueue.IsEmpty()==false) { if (timeNS==0) @@ -5868,7 +5884,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/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); 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 ) { diff --git a/Source/ReliabilityLayer.cpp b/Source/ReliabilityLayer.cpp index dbeb17b94..0c1e78da7 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) @@ -634,7 +640,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 +1090,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 +1138,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 +1233,7 @@ bool ReliabilityLayer::HandleSocketReceiveFromConnectedPlayer( InsertIntoSplitPacketList( internalPacket, timeRead ); internalPacket = BuildPacketFromSplitPacketList( internalPacket->splitPacketId, timeRead, - s, systemAddress, rnr, updateBitStream); + s, systemAddress, updateBitStream); if ( internalPacket == 0 ) { @@ -1687,7 +1693,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 +1814,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 +1826,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 +2215,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 || @@ -2241,13 +2246,13 @@ void ReliabilityLayer::Update( RakNetSocket2 *s, SystemAddress &systemAddress, i //DeleteOldUnreliableSplitPackets( time ); } + //------------------------------------------------------------------------------------------------------- // 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; @@ -3055,7 +3060,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 +3143,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 +3158,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 +3172,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,36 +3204,38 @@ 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, + RakNetSocket2 *s, SystemAddress &systemAddress, BitStream &updateBitStream) { unsigned int i; @@ -3238,11 +3250,11 @@ 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 - SendACKs(s, systemAddress, time, rnr, updateBitStream); + SendACKs(s, systemAddress, time, updateBitStream); internalPacket=BuildPacketFromSplitPacketList(splitPacketChannel,time); splitPacketChannelList.RemoveAtIndex(i); return internalPacket; @@ -3613,7 +3625,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(); @@ -3647,7 +3659,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..d5fd10819 100644 --- a/Source/ReliabilityLayer.h +++ b/Source/ReliabilityLayer.h @@ -57,15 +57,88 @@ namespace RakNet { /// Forward declarations 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; @@ -147,7 +220,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 +250,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 +296,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 +348,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 +613,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; diff --git a/Source/ReplicaManager3.cpp b/Source/ReplicaManager3.cpp index ba79c498a..b041765ea 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) @@ -1185,6 +1185,7 @@ PluginReceiveResult ReplicaManager3::OnConstruction(Packet *packet, unsigned cha } } } + bsIn.AlignReadToByteBoundary(); for (index=0; index < constructionObjectListSize; index++) { 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 )