• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

ReliabilityLayer.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include "ReliabilityLayer.h"
00009 #include "GetTime.h"
00010 #include "SocketLayer.h"
00011 #include "PluginInterface2.h"
00012 #include "RakAssert.h"
00013 #include "Rand.h"
00014 #include "MessageIdentifiers.h"
00015 #include <math.h>
00016 
00017 // Can't figure out which library has this function on the PS3
00018 double Ceil(double d) {if (((double)((int)d))==d) return d; return (int) (d+1.0);}
00019 
00020 #if defined(new)
00021 #pragma push_macro("new")
00022 #undef new
00023 #define RELIABILITY_LAYER_NEW_UNDEF_ALLOCATING_QUEUE
00024 #endif
00025 
00026 
00027 //#define _DEBUG_LOGGER
00028 
00029 #if CC_TIME_TYPE_BYTES==4
00030 static const CCTimeType MAX_TIME_BETWEEN_PACKETS= 350; // 350 milliseconds
00031 static const CCTimeType HISTOGRAM_RESTART_CYCLE=10000; // Every 10 seconds reset the histogram
00032 #else
00033 static const CCTimeType MAX_TIME_BETWEEN_PACKETS= 350000; // 350 milliseconds
00034 //static const CCTimeType HISTOGRAM_RESTART_CYCLE=10000000; // Every 10 seconds reset the histogram
00035 #endif
00036 static const int DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE=512;
00037 static const CCTimeType STARTING_TIME_BETWEEN_PACKETS=MAX_TIME_BETWEEN_PACKETS;
00038 //static const long double TIME_BETWEEN_PACKETS_INCREASE_MULTIPLIER_DEFAULT=.02;
00039 //static const long double TIME_BETWEEN_PACKETS_DECREASE_MULTIPLIER_DEFAULT=1.0 / 9.0;
00040 
00041 typedef uint32_t BitstreamLengthEncoding;
00042 
00043 #ifdef _MSC_VER
00044 #pragma warning( push )
00045 #endif
00046 
00047 
00048 BPSTracker::TimeAndValue2::TimeAndValue2() {}
00049 BPSTracker::TimeAndValue2::~TimeAndValue2() {}
00050 BPSTracker::TimeAndValue2::TimeAndValue2(RakNetTimeUS t, uint64_t v1) : time(t), value1(v1) {}
00051 //BPSTracker::TimeAndValue2::TimeAndValue2(RakNetTimeUS t, uint64_t v1, uint64_t v2) : time(t), value1(v1), value2(v2) {}
00052 BPSTracker::BPSTracker() {Reset(__FILE__,__LINE__);}
00053 BPSTracker::~BPSTracker() {}
00054 //void BPSTracker::Reset(const char *file, unsigned int line) {total1=total2=lastSec1=lastSec2=0; dataQueue.Clear(file,line);}
00055 void BPSTracker::Reset(const char *file, unsigned int line) {total1=lastSec1=0; dataQueue.Clear(file,line);}
00056 void BPSTracker::Push1(RakNetTimeUS time, uint64_t value1) {
00057         ClearExpired1(time);
00058         dataQueue.Push(TimeAndValue2(time,value1),__FILE__,__LINE__); total1+=value1; lastSec1+=value1;
00059 }
00060 //void BPSTracker::Push2(RakNetTimeUS time, uint64_t value1, uint64_t value2) {dataQueue.Push(TimeAndValue2(time,value1,value2),__FILE__,__LINE__); total1+=value1; lastSec1+=value1;  total2+=value2; lastSec2+=value2;}
00061 uint64_t BPSTracker::GetBPS1(RakNetTimeUS time) {ClearExpired1(time); return lastSec1;}
00062 uint64_t BPSTracker::GetBPS1Threadsafe(RakNetTimeUS time) {(void) time; return lastSec1;}
00063 //uint64_t BPSTracker::GetBPS2(RakNetTimeUS time) {ClearExpired2(time); return lastSec2;}
00064 //void BPSTracker::GetBPS1And2(RakNetTimeUS time, uint64_t &out1, uint64_t &out2) {ClearExpired2(time); out1=lastSec1; out2=lastSec2;}
00065 uint64_t BPSTracker::GetTotal1(void) const {return total1;}
00066 //uint64_t BPSTracker::GetTotal2(void) const {return total2;}
00067 
00068 // void BPSTracker::ClearExpired2(RakNetTimeUS time) {
00069 //      RakNetTimeUS threshold=time;
00070 //      if (threshold < 1000000)
00071 //              return;
00072 //      threshold-=1000000;
00073 //      while (dataQueue.IsEmpty()==false && dataQueue.Peek().time < threshold)
00074 //      {
00075 //              lastSec1-=dataQueue.Peek().value1;
00076 //              lastSec2-=dataQueue.Peek().value2;
00077 //              dataQueue.Pop();
00078 //      }
00079 // }
00080 void BPSTracker::ClearExpired1(RakNetTimeUS time)
00081 {
00082         while (dataQueue.IsEmpty()==false &&
00083 #if CC_TIME_TYPE_BYTES==8
00084                 dataQueue.Peek().time+1000000 < time
00085 #else
00086                 dataQueue.Peek().time+1000 < time
00087 #endif
00088                 )
00089         {
00090                 lastSec1-=dataQueue.Peek().value1;
00091                 dataQueue.Pop();
00092         }
00093 }
00094 
00095 struct DatagramHeaderFormat
00096 {
00097         // Time must be first, see SendToThread.cpp
00098         CCTimeType sourceSystemTime;
00099         DatagramSequenceNumberType datagramNumber;
00100         // Use floats to save bandwidth
00101         //      float B; // Link capacity
00102         float AS; // Data arrival rate
00103         bool isACK;
00104         bool isNAK;
00105         bool isPacketPair;
00106         bool hasBAndAS;
00107         bool isContinuousSend;
00108         bool needsBAndAs;
00109         bool isValid; // To differentiate between what I serialized, and offline data
00110 
00111         static BitSize_t GetDataHeaderBitLength()
00112         {
00113                 return BYTES_TO_BITS(GetDataHeaderByteLength());
00114         }
00115 
00116         static unsigned int GetDataHeaderByteLength()
00117         {
00118                 //return 2 + 3 + sizeof(RakNetTimeMS) + sizeof(float)*2;
00119                 return 2 + 3 + sizeof(RakNetTimeMS) + sizeof(float)*1;
00120         }
00121 
00122         void Serialize(RakNet::BitStream *b)
00123         {
00124                 // Not endian safe
00125                 //              RakAssert(GetDataHeaderByteLength()==sizeof(DatagramHeaderFormat));
00126                 //              b->WriteAlignedBytes((const unsigned char*) this, sizeof(DatagramHeaderFormat));
00127                 //              return;
00128 
00129                 b->Write(true); // IsValid
00130                 if (isACK)
00131                 {
00132                         b->Write(true);
00133                         b->Write(hasBAndAS);
00134                         b->AlignWriteToByteBoundary();
00135                         RakNetTimeMS timeMSLow=(RakNetTimeMS) sourceSystemTime&0xFFFFFFFF; b->Write(timeMSLow);
00136                         if (hasBAndAS)
00137                         {
00138                                 //              b->Write(B);
00139                                 b->Write(AS);
00140                         }
00141                 }
00142                 else if (isNAK)
00143                 {
00144                         b->Write(false);
00145                         b->Write(true);
00146                 }
00147                 else
00148                 {
00149                         b->Write(false);
00150                         b->Write(false);
00151                         b->Write(isPacketPair);
00152                         b->Write(isContinuousSend);
00153                         b->Write(needsBAndAs);
00154                         b->AlignWriteToByteBoundary();
00155                         RakNetTimeMS timeMSLow=(RakNetTimeMS) sourceSystemTime&0xFFFFFFFF; b->Write(timeMSLow);
00156                         b->Write(datagramNumber);
00157                 }
00158         }
00159         void Deserialize(RakNet::BitStream *b)
00160         {
00161                 // Not endian safe
00162                 //              b->ReadAlignedBytes((unsigned char*) this, sizeof(DatagramHeaderFormat));
00163                 //              return;
00164 
00165                 b->Read(isValid);
00166                 b->Read(isACK);
00167                 if (isACK)
00168                 {
00169                         isNAK=false;
00170                         isPacketPair=false;
00171                         b->Read(hasBAndAS);
00172                         b->AlignReadToByteBoundary();
00173                         RakNetTimeMS timeMS; b->Read(timeMS); sourceSystemTime=(CCTimeType) timeMS;
00174                         if (hasBAndAS)
00175                         {
00176                                 //                      b->Read(B);
00177                                 b->Read(AS);
00178                         }
00179                 }
00180                 else
00181                 {
00182                         b->Read(isNAK);
00183                         if (isNAK)
00184                         {
00185                                 isPacketPair=false;
00186                         }
00187                         else
00188                         {
00189                                 b->Read(isPacketPair);
00190                                 b->Read(isContinuousSend);
00191                                 b->Read(needsBAndAs);
00192                                 b->AlignReadToByteBoundary();
00193                                 RakNetTimeMS timeMS; b->Read(timeMS); sourceSystemTime=(CCTimeType) timeMS;
00194                                 b->Read(datagramNumber);
00195                         }
00196                 }
00197         }
00198 };
00199 
00200 #pragma warning(disable:4702)   // unreachable code
00201 
00202 #ifdef _WIN32
00203 //#define _DEBUG_LOGGER
00204 #ifdef _DEBUG_LOGGER
00205 #include "WindowsIncludes.h"
00206 #endif
00207 #endif
00208 
00209 //#define DEBUG_SPLIT_PACKET_PROBLEMS
00210 #if defined (DEBUG_SPLIT_PACKET_PROBLEMS)
00211 static int waitFlag=-1;
00212 #endif
00213 
00214 using namespace RakNet;
00215 
00216 int SplitPacketChannelComp( SplitPacketIdType const &key, SplitPacketChannel* const &data )
00217 {
00218         if (key < data->splitPacketList[0]->splitPacketId)
00219                 return -1;
00220         if (key == data->splitPacketList[0]->splitPacketId)
00221                 return 0;
00222         return 1;
00223 }
00224 
00225 
00226 // DEFINE_MULTILIST_PTR_TO_MEMBER_COMPARISONS( InternalPacket, SplitPacketIndexType, splitPacketIndex )
00227 
00228 bool operator<( const DataStructures::MLKeyRef<SplitPacketIndexType> &inputKey, const InternalPacket *cls )
00229 {
00230         return inputKey.Get() < cls->splitPacketIndex;
00231 }
00232 bool operator>( const DataStructures::MLKeyRef<SplitPacketIndexType> &inputKey, const InternalPacket *cls )
00233 {
00234         return inputKey.Get() > cls->splitPacketIndex;
00235 }
00236 bool operator==( const DataStructures::MLKeyRef<SplitPacketIndexType> &inputKey, const InternalPacket *cls )
00237 {
00238         return inputKey.Get() == cls->splitPacketIndex;
00239 }
00241 bool operator<( const DataStructures::MLKeyRef<InternalPacket *> &inputKey, const InternalPacket *cls )
00242 {
00243         return inputKey.Get()->splitPacketIndex < cls->splitPacketIndex;
00244 }
00245 bool operator>( const DataStructures::MLKeyRef<InternalPacket *> &inputKey, const InternalPacket *cls )
00246 {
00247         return inputKey.Get()->splitPacketIndex > cls->splitPacketIndex;
00248 }
00249 bool operator==( const DataStructures::MLKeyRef<InternalPacket *> &inputKey, const InternalPacket *cls )
00250 {
00251         return inputKey.Get()->splitPacketIndex == cls->splitPacketIndex;
00252 }
00253 /*
00254 int SplitPacketIndexComp( SplitPacketIndexType const &key, InternalPacket* const &data )
00255 {
00256 if (key < data->splitPacketIndex)
00257 return -1;
00258 if (key == data->splitPacketIndex)
00259 return 0;
00260 return 1;
00261 }
00262 */
00263 
00264 //-------------------------------------------------------------------------------------------------------
00265 // Constructor
00266 //-------------------------------------------------------------------------------------------------------
00267 // Add 21 to the default MTU so if we encrypt it can hold potentially 21 more bytes of extra data + padding.
00268 ReliabilityLayer::ReliabilityLayer() :
00269 updateBitStream( MAXIMUM_MTU_SIZE + 21 )   // preallocate the update bitstream so we can avoid a lot of reallocs at runtime
00270 {
00271         freeThreadedMemoryOnNextUpdate = false;
00272 
00273 
00274 #ifdef _DEBUG
00275         // Wait longer to disconnect in debug so I don't get disconnected while tracing
00276         timeoutTime=30000;
00277 #else
00278         timeoutTime=10000;
00279 #endif
00280 
00281 #ifdef _DEBUG
00282         minExtraPing=extraPingVariance=0;
00283         packetloss=(double) minExtraPing;       
00284 #endif
00285 
00286         InitializeVariables(MAXIMUM_MTU_SIZE);
00287 
00288         datagramHistoryMessagePool.SetPageSize(sizeof(MessageNumberNode)*128);
00289         internalPacketPool.SetPageSize(sizeof(InternalPacket)*128);
00290         refCountedDataPool.SetPageSize(sizeof(InternalPacket)*32);
00291 }
00292 
00293 //-------------------------------------------------------------------------------------------------------
00294 // Destructor
00295 //-------------------------------------------------------------------------------------------------------
00296 ReliabilityLayer::~ReliabilityLayer()
00297 {
00298         FreeMemory( true ); // Free all memory immediately
00299 }
00300 //-------------------------------------------------------------------------------------------------------
00301 // Resets the layer for reuse
00302 //-------------------------------------------------------------------------------------------------------
00303 void ReliabilityLayer::Reset( bool resetVariables, int MTUSize )
00304 {
00305         FreeMemory( true ); // true because making a memory reset pending in the update cycle causes resets after reconnects.  Instead, just call Reset from a single thread
00306         if (resetVariables)
00307         {
00308                 InitializeVariables(MTUSize);
00309 
00310                 if ( encryptor.IsKeySet() )
00311                         congestionManager.Init(RakNet::GetTimeUS(), MTUSize - UDP_HEADER_SIZE);
00312                 else
00313                         congestionManager.Init(RakNet::GetTimeUS(), MTUSize - UDP_HEADER_SIZE);
00314         }
00315 }
00316 
00317 //-------------------------------------------------------------------------------------------------------
00318 // Sets up encryption
00319 //-------------------------------------------------------------------------------------------------------
00320 void ReliabilityLayer::SetEncryptionKey( const unsigned char* key )
00321 {
00322         if ( key )
00323                 encryptor.SetKey( key );
00324         else
00325                 encryptor.UnsetKey();
00326 }
00327 
00328 //-------------------------------------------------------------------------------------------------------
00329 // Set the time, in MS, to use before considering ourselves disconnected after not being able to deliver a reliable packet
00330 //-------------------------------------------------------------------------------------------------------
00331 void ReliabilityLayer::SetTimeoutTime( RakNetTimeMS time )
00332 {
00333         timeoutTime=time;
00334 }
00335 
00336 //-------------------------------------------------------------------------------------------------------
00337 // Returns the value passed to SetTimeoutTime. or the default if it was never called
00338 //-------------------------------------------------------------------------------------------------------
00339 RakNetTimeMS ReliabilityLayer::GetTimeoutTime(void)
00340 {
00341         return timeoutTime;
00342 }
00343 
00344 //-------------------------------------------------------------------------------------------------------
00345 // Initialize the variables
00346 //-------------------------------------------------------------------------------------------------------
00347 void ReliabilityLayer::InitializeVariables( int MTUSize )
00348 {
00349         (void) MTUSize;
00350 
00351         memset( waitingForOrderedPacketReadIndex, 0, NUMBER_OF_ORDERED_STREAMS * sizeof(OrderingIndexType));
00352         memset( waitingForSequencedPacketReadIndex, 0, NUMBER_OF_ORDERED_STREAMS * sizeof(OrderingIndexType) );
00353         memset( waitingForOrderedPacketWriteIndex, 0, NUMBER_OF_ORDERED_STREAMS * sizeof(OrderingIndexType) );
00354         memset( waitingForSequencedPacketWriteIndex, 0, NUMBER_OF_ORDERED_STREAMS * sizeof(OrderingIndexType) );
00355         memset( &statistics, 0, sizeof( statistics ) );
00356         statistics.connectionStartTime = RakNet::GetTimeUS();
00357         splitPacketId = 0;
00358         elapsedTimeSinceLastUpdate=0;
00359         throughputCapCountdown=0;
00360         sendReliableMessageNumberIndex = 0;
00361         internalOrderIndex=0;
00362         timeToNextUnreliableCull=0;
00363         unreliableLinkedListHead=0;
00364         lastUpdateTime= RakNet::GetTimeNS();
00365         bandwidthExceededStatistic=false;
00366         remoteSystemTime=0;
00367         unreliableTimeout=0;
00368 
00369         // Disable packet pairs
00370         countdownToNextPacketPair=15;
00371 
00372         nextAllowedThroughputSample=0;
00373         deadConnection = cheater = false;
00374         timeOfLastContinualSend=0;
00375 
00376         // timeResendQueueNonEmpty = 0;
00377         timeLastDatagramArrived=RakNet::GetTimeMS();
00378         //      packetlossThisSample=false;
00379         //      backoffThisSample=0;
00380         //      packetlossThisSampleResendCount=0;
00381         //      lastPacketlossTime=0;
00382         statistics.messagesInResendBuffer=0;
00383         statistics.bytesInResendBuffer=0;
00384 
00385         receivedPacketsBaseIndex=0;
00386         resetReceivedPackets=true;
00387         receivePacketCount=0; 
00388 
00389         //      SetPing( 1000 );
00390 
00391         timeBetweenPackets=STARTING_TIME_BETWEEN_PACKETS;
00392 
00393         ackPingIndex=0;
00394         ackPingSum=(CCTimeType)0;
00395 
00396         nextSendTime=lastUpdateTime;
00397         //nextLowestPingReset=(CCTimeType)0;
00398         //      continuousSend=false;
00399 
00400         //      histogramStart=(CCTimeType)0;
00401         //      histogramBitsSent=0;
00402         unacknowledgedBytes=0;
00403         resendLinkedListHead=0;
00404         totalUserDataBytesAcked=0;
00405 
00406         datagramHistoryPopCount=0;
00407 
00408         InitHeapWeights();
00409         for (int i=0; i < NUMBER_OF_PRIORITIES; i++)
00410         {
00411                 statistics.messageInSendBuffer[i]=0;
00412                 statistics.bytesInSendBuffer[i]=0.0;
00413         }
00414 
00415         for (int i=0; i < RNS_PER_SECOND_METRICS_COUNT; i++)
00416         {
00417                 bpsMetrics[i].Reset(__FILE__,__LINE__);
00418         }
00419 }
00420 
00421 //-------------------------------------------------------------------------------------------------------
00422 // Frees all allocated memory
00423 //-------------------------------------------------------------------------------------------------------
00424 void ReliabilityLayer::FreeMemory( bool freeAllImmediately )
00425 {
00426         if ( freeAllImmediately )
00427         {
00428                 FreeThreadedMemory();
00429                 FreeThreadSafeMemory();
00430         }
00431         else
00432         {
00433                 FreeThreadSafeMemory();
00434                 freeThreadedMemoryOnNextUpdate = true;
00435         }
00436 }
00437 
00438 void ReliabilityLayer::FreeThreadedMemory( void )
00439 {
00440 }
00441 
00442 void ReliabilityLayer::FreeThreadSafeMemory( void )
00443 {
00444         unsigned i,j;
00445         InternalPacket *internalPacket;
00446 
00447         ClearPacketsAndDatagrams(false);
00448 
00449         for (i=0; i < splitPacketChannelList.Size(); i++)
00450         {
00451                 for (j=0; j < splitPacketChannelList[i]->splitPacketList.Size(); j++)
00452                 {
00453                         FreeInternalPacketData(splitPacketChannelList[i]->splitPacketList[j], __FILE__, __LINE__ );
00454                         ReleaseToInternalPacketPool( splitPacketChannelList[i]->splitPacketList[j] );
00455                 }
00456                 RakNet::OP_DELETE(splitPacketChannelList[i], __FILE__, __LINE__);
00457         }
00458         splitPacketChannelList.Clear(false, __FILE__, __LINE__);
00459 
00460         while ( outputQueue.Size() > 0 )
00461         {
00462                 internalPacket = outputQueue.Pop();
00463                 FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
00464                 ReleaseToInternalPacketPool( internalPacket );
00465         }
00466 
00467         outputQueue.ClearAndForceAllocation( 32, __FILE__,__LINE__ );
00468 
00469         for ( i = 0; i < orderingList.Size(); i++ )
00470         {
00471                 if ( orderingList[ i ] )
00472                 {
00473                         DataStructures::LinkedList<InternalPacket*>* theList = orderingList[ i ];
00474 
00475                         if ( theList )
00476                         {
00477                                 while ( theList->Size() )
00478                                 {
00479                                         internalPacket = orderingList[ i ]->Pop();
00480                                         FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
00481                                         ReleaseToInternalPacketPool( internalPacket );
00482                                 }
00483 
00484                                 RakNet::OP_DELETE(theList, __FILE__, __LINE__);
00485                         }
00486                 }
00487         }
00488 
00489         orderingList.Clear(false, __FILE__, __LINE__);
00490 
00491         //resendList.ForEachData(DeleteInternalPacket);
00492         //      resendTree.Clear(__FILE__, __LINE__);
00493         memset(resendBuffer, 0, sizeof(resendBuffer));
00494         statistics.messagesInResendBuffer=0;
00495         statistics.bytesInResendBuffer=0;
00496 
00497         if (resendLinkedListHead)
00498         {
00499                 InternalPacket *prev;
00500                 InternalPacket *iter = resendLinkedListHead;
00501                 while (1)
00502                 {
00503                         if (iter->data)
00504                                 FreeInternalPacketData(iter, __FILE__, __LINE__ );
00505                         prev=iter;
00506                         iter=iter->resendNext;
00507                         if (iter==resendLinkedListHead)
00508                         {
00509                                 ReleaseToInternalPacketPool(prev);
00510                                 break;
00511                         }
00512                         ReleaseToInternalPacketPool(prev);
00513                 }
00514                 resendLinkedListHead=0;
00515         }
00516         unacknowledgedBytes=0;
00517 
00518         //      acknowlegements.Clear(__FILE__, __LINE__);
00519 
00520         for ( j=0 ; j < outgoingPacketBuffer.Size(); j++ )
00521         {
00522                 if ( outgoingPacketBuffer[ j ]->data)
00523                         FreeInternalPacketData( outgoingPacketBuffer[ j ], __FILE__, __LINE__ );
00524                 ReleaseToInternalPacketPool( outgoingPacketBuffer[ j ] );
00525         }
00526 
00527         outgoingPacketBuffer.Clear(true, __FILE__,__LINE__);
00528 
00529 
00530 #ifdef _DEBUG
00531         for (unsigned i = 0; i < delayList.Size(); i++ )
00532                 RakNet::OP_DELETE(delayList[ i ], __FILE__, __LINE__);
00533         delayList.Clear(__FILE__, __LINE__);
00534 #endif
00535 
00536         packetsToSendThisUpdate.Clear(false, __FILE__, __LINE__);
00537         packetsToSendThisUpdate.Preallocate(512, __FILE__, __LINE__);
00538         packetsToDeallocThisUpdate.Clear(false, __FILE__, __LINE__);
00539         packetsToDeallocThisUpdate.Preallocate(512, __FILE__, __LINE__);
00540         packetsToSendThisUpdateDatagramBoundaries.Clear(false, __FILE__, __LINE__);
00541         packetsToSendThisUpdateDatagramBoundaries.Preallocate(128, __FILE__, __LINE__);
00542         datagramSizesInBytes.Clear(false, __FILE__, __LINE__);
00543         datagramSizesInBytes.Preallocate(128, __FILE__, __LINE__);
00544 
00545         internalPacketPool.Clear(__FILE__, __LINE__);
00546 
00547         refCountedDataPool.Clear(__FILE__,__LINE__);
00548 
00549         /*
00550         DataStructures::Page<DatagramSequenceNumberType, DatagramMessageIDList*, RESEND_TREE_ORDER> *cur = datagramMessageIDTree.GetListHead();
00551         while (cur)
00552         {
00553         int treeIndex;
00554         for (treeIndex=0; treeIndex < cur->size; treeIndex++)
00555         ReleaseToDatagramMessageIDPool(cur->data[treeIndex]);
00556         cur=cur->resendNext;
00557         }
00558         datagramMessageIDTree.Clear(__FILE__, __LINE__);
00559         datagramMessageIDPool.Clear(__FILE__, __LINE__);
00560         */
00561 
00562         while (datagramHistory.Size())
00563         {
00564                 RemoveFromDatagramHistory(datagramHistoryPopCount);
00565                 datagramHistory.Pop();
00566                 datagramHistoryPopCount++;
00567         }
00568         datagramHistoryMessagePool.Clear(__FILE__,__LINE__);
00569         datagramHistoryPopCount=0;
00570 
00571         acknowlegements.Clear();
00572         NAKs.Clear();
00573 
00574         unreliableLinkedListHead=0;
00575 }
00576 
00577 //-------------------------------------------------------------------------------------------------------
00578 // Packets are read directly from the socket layer and skip the reliability
00579 //layer  because unconnected players do not use the reliability layer
00580 // This function takes packet data after a player has been confirmed as
00581 //connected.  The game should not use that data directly
00582 // because some data is used internally, such as packet acknowledgment and
00583 //split packets
00584 //-------------------------------------------------------------------------------------------------------
00585 bool ReliabilityLayer::HandleSocketReceiveFromConnectedPlayer(
00586         const char *buffer, unsigned int length, SystemAddress systemAddress, DataStructures::List<PluginInterface2*> &messageHandlerList, int MTUSize,
00587         SOCKET s, RakNetRandom *rnr, unsigned short remotePortRakNetWasStartedOn_PS3, CCTimeType timeRead)
00588 {
00589 #ifdef _DEBUG
00590         RakAssert( !( buffer == 0 ) );
00591 #endif
00592 
00593 #if CC_TIME_TYPE_BYTES==4
00594         timeRead/=1000;
00595 #endif
00596 
00597         bpsMetrics[(int) ACTUAL_BYTES_RECEIVED].Push1(timeRead,length);
00598 
00599         (void) MTUSize;
00600 
00601         if ( length <= 2 || buffer == 0 )   // Length of 1 is a connection request resend that we just ignore
00602         {
00603                 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00604                         messageHandlerList[messageHandlerIndex]->OnReliabilityLayerPacketError("length <= 2 || buffer == 0", BYTES_TO_BITS(length), systemAddress);
00605                 return true;
00606         }
00607 
00608         timeLastDatagramArrived=RakNet::GetTimeMS();
00609 
00610         //      CCTimeType time;
00611         bool indexFound;
00612         int count, size;
00613         DatagramSequenceNumberType holeCount;
00614         unsigned i;
00615         //      bool hasAcks=false;
00616 
00617         UpdateThreadedMemory();
00618 
00619         // decode this whole chunk if the decoder is defined.
00620         if ( encryptor.IsKeySet() )
00621         {
00622                 if ( encryptor.Decrypt( ( unsigned char* ) buffer, length, ( unsigned char* ) buffer, &length ) == false )
00623                 {
00624                         for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00625                                 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerPacketError("Decryption failed", BYTES_TO_BITS(length), systemAddress);
00626 
00627                         return false;
00628                 }
00629         }
00630         RakNet::BitStream socketData( (unsigned char*) buffer, length, false ); // Convert the incoming data to a bitstream for easy parsing
00631         //      time = RakNet::GetTimeNS();
00632 
00633         // Set to the current time if it is not zero, and we get incoming data
00634         //      if (timeResendQueueNonEmpty!=0)
00635         //              timeResendQueueNonEmpty=timeRead;
00636 
00637         DatagramHeaderFormat dhf;
00638         dhf.Deserialize(&socketData);
00639         if (dhf.isValid==false)
00640         {
00641                 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00642                         messageHandlerList[messageHandlerIndex]->OnReliabilityLayerPacketError("dhf.isValid==false", BYTES_TO_BITS(length), systemAddress);
00643 
00644                 return true;
00645         }
00646         if (dhf.isACK)
00647         {
00648                 DatagramSequenceNumberType datagramNumber;
00649                 // datagramNumber=dhf.datagramNumber;
00650                 RakNetTimeMS timeMSLow=(RakNetTimeMS) timeRead&0xFFFFFFFF;
00651                 CCTimeType rtt = timeMSLow-dhf.sourceSystemTime;
00652 #if CC_TIME_TYPE_BYTES==4
00653                 if (rtt > 10000)
00654 #else
00655                 if (rtt > 10000000)
00656 #endif
00657                 {
00658                         // Sanity check. This could happen due to type overflow, especially since I only send the low 4 bytes to reduce bandwidth
00659                         rtt=(CCTimeType) congestionManager.GetRTT();
00660                 }
00661                 //      RakAssert(rtt < 500000);
00662                 //      printf("%i ", (RakNetTimeMS)(rtt/1000));
00663                 ackPing=rtt;
00664 #ifdef _DEBUG
00665                 if (dhf.hasBAndAS==false)
00666                 {
00667                         //                      dhf.B=0;
00668                         dhf.AS=0;
00669                 }
00670 #endif
00671                 //              congestionManager.OnAck(timeRead, rtt, dhf.hasBAndAS, dhf.B, dhf.AS, totalUserDataBytesAcked );
00672 
00673 
00674                 incomingAcks.Clear();
00675                 if (incomingAcks.Deserialize(&socketData)==false)
00676                 {
00677                         for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00678                                 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerPacketError("incomingAcks.Deserialize failed", BYTES_TO_BITS(length), systemAddress);
00679 
00680                         return false;
00681                 }
00682                 for (i=0; i<incomingAcks.ranges.Size();i++)
00683                 {
00684                         if (incomingAcks.ranges[i].minIndex>incomingAcks.ranges[i].maxIndex)
00685                         {
00686                                 RakAssert(incomingAcks.ranges[i].minIndex<=incomingAcks.ranges[i].maxIndex);
00687 
00688                                 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00689                                         messageHandlerList[messageHandlerIndex]->OnReliabilityLayerPacketError("incomingAcks minIndex > maxIndex", BYTES_TO_BITS(length), systemAddress);
00690                                 return false;
00691                         }
00692                         for (datagramNumber=incomingAcks.ranges[i].minIndex; datagramNumber >= incomingAcks.ranges[i].minIndex && datagramNumber <= incomingAcks.ranges[i].maxIndex; datagramNumber++)
00693                         {
00694                                 congestionManager.OnAck(timeRead, rtt, dhf.hasBAndAS, 0, dhf.AS, totalUserDataBytesAcked, bandwidthExceededStatistic, datagramNumber );
00695 
00696                                 MessageNumberNode *messageNumberNode = GetMessageNumberNodeByDatagramIndex(datagramNumber);
00697                                 while (messageNumberNode)
00698                                 {
00699                                         RemovePacketFromResendListAndDeleteOlderReliableSequenced( messageNumberNode->messageNumber, timeRead, messageHandlerList, systemAddress );
00700                                         messageNumberNode=messageNumberNode->next;
00701                                 }
00702                                 if (messageNumberNode)
00703                                         RemoveFromDatagramHistory(datagramNumber);
00704                         }
00705                 }
00706         }
00707         else if (dhf.isNAK)
00708         {
00709                 DatagramSequenceNumberType messageNumber;
00710                 DataStructures::RangeList<DatagramSequenceNumberType> incomingNAKs;
00711                 if (incomingNAKs.Deserialize(&socketData)==false)
00712                 {
00713                         for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00714                                 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerPacketError("incomingNAKs.Deserialize failed", BYTES_TO_BITS(length), systemAddress);                        
00715 
00716                         return false;
00717                 }
00718                 for (i=0; i<incomingNAKs.ranges.Size();i++)
00719                 {
00720                         if (incomingNAKs.ranges[i].minIndex>incomingNAKs.ranges[i].maxIndex)
00721                         {
00722                                 RakAssert(incomingNAKs.ranges[i].minIndex<=incomingNAKs.ranges[i].maxIndex);
00723 
00724                                 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00725                                         messageHandlerList[messageHandlerIndex]->OnReliabilityLayerPacketError("incomingNAKs minIndex>maxIndex", BYTES_TO_BITS(length), systemAddress);                 
00726 
00727                                 return false;
00728                         }
00729                         // Sanity check
00730                         RakAssert(incomingNAKs.ranges[i].maxIndex.val-incomingNAKs.ranges[i].minIndex.val<1000);
00731                         for (messageNumber=incomingNAKs.ranges[i].minIndex; messageNumber >= incomingNAKs.ranges[i].minIndex && messageNumber <= incomingNAKs.ranges[i].maxIndex; messageNumber++)
00732                         {
00733                                 congestionManager.OnNAK(timeRead, messageNumber);
00734 
00735                                 // REMOVEME
00736                                 //                              printf("%p NAK %i\n", this, dhf.datagramNumber.val);
00737 
00738                                 MessageNumberNode *messageNumberNode = GetMessageNumberNodeByDatagramIndex(messageNumber);
00739                                 while (messageNumberNode)
00740                                 {
00741                                         // Update timers so resends occur immediately
00742                                         InternalPacket *internalPacket = resendBuffer[messageNumberNode->messageNumber & (uint32_t) RESEND_BUFFER_ARRAY_MASK];
00743                                         if (internalPacket)
00744                                         {
00745                                                 if (internalPacket->nextActionTime!=0)
00746                                                 {
00747                                                         internalPacket->nextActionTime=timeRead;
00748                                                 }
00749                                         }                               
00750 
00751                                         messageNumberNode=messageNumberNode->next;
00752                                 }
00753                         }
00754                 }
00755         }
00756         else
00757         {
00758                 uint32_t skippedMessageCount;
00759                 if (!congestionManager.OnGotPacket(dhf.datagramNumber, dhf.isContinuousSend, timeRead, length, &skippedMessageCount))
00760                 {
00761                         for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00762                                 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerPacketError("congestionManager.OnGotPacket failed", BYTES_TO_BITS(length), systemAddress);                   
00763 
00764                         return true;
00765                 }
00766                 if (dhf.isPacketPair)
00767                         congestionManager.OnGotPacketPair(dhf.datagramNumber, length, timeRead);
00768 
00769                 DatagramHeaderFormat dhfNAK;
00770                 dhfNAK.isNAK=true;
00771                 uint32_t skippedMessageOffset;
00772                 for (skippedMessageOffset=skippedMessageCount; skippedMessageOffset > 0; skippedMessageOffset--)
00773                 {
00774                         NAKs.Insert(dhf.datagramNumber-skippedMessageOffset);
00775                 }
00776                 remoteSystemNeedsBAndAS=dhf.needsBAndAs;
00777 
00778                 // REMOVEME
00779                 //              printf("%p Send ack %i\n", this, dhf.datagramNumber.val);
00780 
00781                 // Ack dhf.datagramNumber
00782                 // Ack even unreliable messages for congestion control, just don't resend them on no ack
00783                 SendAcknowledgementPacket( dhf.datagramNumber, dhf.sourceSystemTime);
00784 
00785                 InternalPacket* internalPacket = CreateInternalPacketFromBitStream( &socketData, timeRead );
00786                 if (internalPacket==0)
00787                 {
00788                         for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00789                                 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerPacketError("CreateInternalPacketFromBitStream failed", BYTES_TO_BITS(length), systemAddress);                       
00790 
00791                         return true;
00792                 }
00793 
00794                 while ( internalPacket )
00795                 {
00796                         for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00797                         {
00798 #if CC_TIME_TYPE_BYTES==4
00799                                 messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, receivePacketCount, systemAddress, timeRead, false);
00800 #else
00801                                 messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, receivePacketCount, systemAddress, (RakNetTime)(timeRead/(CCTimeType)1000), false);
00802 #endif
00803                         }
00804 
00805                         {
00806 
00807                                 // resetReceivedPackets is set from a non-threadsafe function.
00808                                 // We do the actual reset in this function so the data is not modified by multiple threads
00809                                 if (resetReceivedPackets)
00810                                 {
00811                                         hasReceivedPacketQueue.ClearAndForceAllocation(DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE, __FILE__,__LINE__);
00812                                         receivedPacketsBaseIndex=0;
00813                                         resetReceivedPackets=false;
00814                                 }
00815 
00816                                 // 8/12/09 was previously not checking if the message was reliable. However, on packetloss this would mean you'd eventually exceed the
00817                                 // hole count because unreliable messages were never resent, and you'd stop getting messages
00818                                 if (internalPacket->reliability == RELIABLE || internalPacket->reliability == RELIABLE_SEQUENCED || internalPacket->reliability == RELIABLE_ORDERED )
00819                                 {
00820                                         // If the following conditional is true then this either a duplicate packet
00821                                         // or an older out of order packet
00822                                         // The subtraction unsigned overflow is intentional
00823                                         holeCount = (DatagramSequenceNumberType)(internalPacket->reliableMessageNumber-receivedPacketsBaseIndex);
00824                                         const DatagramSequenceNumberType typeRange = (DatagramSequenceNumberType)(const uint32_t)-1;
00825 
00826                                         if (holeCount==(DatagramSequenceNumberType) 0)
00827                                         {
00828                                                 // Got what we were expecting
00829                                                 if (hasReceivedPacketQueue.Size())
00830                                                         hasReceivedPacketQueue.Pop();
00831                                                 ++receivedPacketsBaseIndex;
00832                                         }
00833                                         else if (holeCount > typeRange/(DatagramSequenceNumberType) 2)
00834                                         {
00835                                                 // Duplicate packet
00836                                                 FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
00837                                                 ReleaseToInternalPacketPool( internalPacket );
00838 
00839                                                 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
00840 
00841                                                 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
00842                                         }
00843                                         else if ((unsigned int) holeCount<hasReceivedPacketQueue.Size())
00844                                         {
00845 
00846                                                 // Got a higher count out of order packet that was missing in the sequence or we already got
00847                                                 if (hasReceivedPacketQueue[holeCount]!=false) // non-zero means this is a hole
00848                                                 {
00849                                                         // Fill in the hole
00850                                                         hasReceivedPacketQueue[holeCount]=false; // We got the packet at holeCount
00851                                                 }
00852                                                 else
00853                                                 {
00854                                                         // Duplicate packet
00855                                                         FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
00856                                                         ReleaseToInternalPacketPool( internalPacket );
00857 
00858                                                         bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
00859 
00860                                                         goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
00861                                                 }
00862                                         }
00863                                         else // holeCount>=receivedPackets.Size()
00864                                         {
00865                                                 if (holeCount > (DatagramSequenceNumberType) 1000000)
00866                                                 {
00867                                                         RakAssert("Hole count too high. See ReliabilityLayer.h" && 0);
00868 
00869                                                         for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00870                                                                 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerPacketError("holeCount > 1000000", BYTES_TO_BITS(length), systemAddress);                    
00871 
00872                                                         // Would crash due to out of memory!
00873                                                         FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
00874                                                         ReleaseToInternalPacketPool( internalPacket );
00875 
00876                                                         bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
00877 
00878                                                         goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
00879                                                 }
00880 
00881 
00882                                                 // Fix - sending on a higher priority gives us a very very high received packets base index if we formerly had pre-split a lot of messages and
00883                                                 // used that as the message number.  Because of this, a lot of time is spent in this linear loop and the timeout time expires because not
00884                                                 // all of the message is sent in time.
00885                                                 // Fixed by late assigning message IDs on the sender
00886 
00887                                                 // Add 0 times to the queue until (reliableMessageNumber - baseIndex) < queue size.
00888                                                 while ((unsigned int)(holeCount) > hasReceivedPacketQueue.Size())
00889                                                         hasReceivedPacketQueue.Push(true, __FILE__, __LINE__ ); // time+(CCTimeType)60 * (CCTimeType)1000 * (CCTimeType)1000); // Didn't get this packet - set the time to give up waiting
00890                                                 hasReceivedPacketQueue.Push(false, __FILE__, __LINE__ ); // Got the packet
00891 #ifdef _DEBUG
00892                                                 // If this assert hits then DatagramSequenceNumberType has overflowed
00893                                                 RakAssert(hasReceivedPacketQueue.Size() < (unsigned int)((DatagramSequenceNumberType)(const uint32_t)(-1)));
00894 #endif
00895                                         }
00896 
00897                                         while ( hasReceivedPacketQueue.Size()>0 && hasReceivedPacketQueue.Peek()==false )
00898                                         {
00899                                                 hasReceivedPacketQueue.Pop();
00900                                                 ++receivedPacketsBaseIndex;
00901                                         }
00902                                 }
00903 
00904                                 // If the allocated buffer is > DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE and it is 3x greater than the number of elements actually being used
00905                                 if (hasReceivedPacketQueue.AllocationSize() > (unsigned int) DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE && hasReceivedPacketQueue.AllocationSize() > hasReceivedPacketQueue.Size() * 3)
00906                                         hasReceivedPacketQueue.Compress(__FILE__,__LINE__);
00907 
00908                                 if ( internalPacket->reliability == RELIABLE_SEQUENCED || internalPacket->reliability == UNRELIABLE_SEQUENCED )
00909                                 {
00910 #ifdef _DEBUG
00911                                         RakAssert( internalPacket->orderingChannel < NUMBER_OF_ORDERED_STREAMS );
00912 #endif
00913 
00914                                         if ( internalPacket->orderingChannel >= NUMBER_OF_ORDERED_STREAMS )
00915                                         {
00916 
00917                                                 FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
00918                                                 ReleaseToInternalPacketPool( internalPacket );
00919 
00920                                                 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
00921                                                         messageHandlerList[messageHandlerIndex]->OnReliabilityLayerPacketError("internalPacket->orderingChannel >= NUMBER_OF_ORDERED_STREAMS", BYTES_TO_BITS(length), systemAddress);                   
00922 
00923                                                 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
00924 
00925                                                 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
00926                                         }
00927 
00928                                         if ( IsOlderOrderedPacket( internalPacket->orderingIndex, waitingForSequencedPacketReadIndex[ internalPacket->orderingChannel ] ) == false )
00929                                         {
00930                                                 // Is this a split packet?
00931                                                 if ( internalPacket->splitPacketCount > 0 )
00932                                                 {
00933                                                         // Generate the split
00934                                                         // Verify some parameters to make sure we don't get junk data
00935 
00936 
00937                                                         // Check for a rebuilt packet
00938                                                         InsertIntoSplitPacketList( internalPacket, timeRead );
00939                                                         bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_PROCESSED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
00940 
00941                                                         // Sequenced
00942                                                         internalPacket = BuildPacketFromSplitPacketList( internalPacket->splitPacketId, timeRead,
00943                                                                 s, systemAddress, rnr, remotePortRakNetWasStartedOn_PS3);
00944 
00945                                                         if ( internalPacket )
00946                                                         {
00947                                                                 // Update our index to the newest packet
00948                                                                 waitingForSequencedPacketReadIndex[ internalPacket->orderingChannel ] = internalPacket->orderingIndex + (OrderingIndexType)1;
00949 
00950                                                                 // If there is a rebuilt packet, add it to the output queue
00951                                                                 outputQueue.Push( internalPacket, __FILE__, __LINE__  );
00952                                                                 internalPacket = 0;
00953                                                         }
00954 
00955                                                         // else don't have all the parts yet
00956                                                 }
00957                                                 else
00958                                                 {
00959                                                         // Update our index to the newest packet
00960                                                         waitingForSequencedPacketReadIndex[ internalPacket->orderingChannel ] = internalPacket->orderingIndex + (OrderingIndexType)1;
00961 
00962                                                         // Not a split packet. Add the packet to the output queue
00963                                                         bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_PROCESSED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
00964                                                         outputQueue.Push( internalPacket, __FILE__, __LINE__  );
00965                                                         internalPacket = 0;
00966                                                 }
00967                                         }
00968                                         else
00969                                         {
00970                                                 // Older sequenced packet. Discard it
00971                                                 FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
00972                                                 ReleaseToInternalPacketPool( internalPacket );
00973 
00974                                                 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
00975 
00976                                         }
00977 
00978                                         goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
00979                                 }
00980 
00981                                 // Is this an unsequenced split packet?
00982                                 if ( internalPacket->splitPacketCount > 0 )
00983                                 {
00984                                         // An unsequenced split packet.  May be ordered though.
00985 
00986                                         // Check for a rebuilt packet
00987                                         if ( internalPacket->reliability != RELIABLE_ORDERED )
00988                                                 internalPacket->orderingChannel = 255; // Use 255 to designate not sequenced and not ordered
00989 
00990                                         InsertIntoSplitPacketList( internalPacket, timeRead );
00991 
00992                                         internalPacket = BuildPacketFromSplitPacketList( internalPacket->splitPacketId, timeRead,
00993                                                 s, systemAddress, rnr, remotePortRakNetWasStartedOn_PS3);
00994 
00995                                         if ( internalPacket == 0 )
00996                                         {
00997 
00998                                                 // Don't have all the parts yet
00999                                                 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
01000                                         }
01001 
01002                                         // else continue down to handle RELIABLE_ORDERED
01003 
01004                                 }
01005 
01006                                 if ( internalPacket->reliability == RELIABLE_ORDERED )
01007                                 {
01008 #ifdef _DEBUG
01009                                         RakAssert( internalPacket->orderingChannel < NUMBER_OF_ORDERED_STREAMS );
01010 #endif
01011 
01012                                         if ( internalPacket->orderingChannel >= NUMBER_OF_ORDERED_STREAMS )
01013                                         {
01014                                                 // Invalid packet
01015                                                 FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
01016                                                 ReleaseToInternalPacketPool( internalPacket );
01017 
01018                                                 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
01019 
01020                                                 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
01021                                         }
01022 
01023                                         bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_PROCESSED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
01024 
01025                                         if ( waitingForOrderedPacketReadIndex[ internalPacket->orderingChannel ] == internalPacket->orderingIndex )
01026                                         {
01027                                                 // Get the list to hold ordered packets for this stream
01028                                                 DataStructures::LinkedList<InternalPacket*> *orderingListAtOrderingStream;
01029                                                 unsigned char orderingChannelCopy = internalPacket->orderingChannel;
01030 
01031                                                 // Push the packet for the user to read
01032                                                 outputQueue.Push( internalPacket, __FILE__, __LINE__  );
01033                                                 internalPacket = 0; // Don't reference this any longer since other threads access it
01034 
01035                                                 // Wait for the resendNext ordered packet in sequence
01036                                                 waitingForOrderedPacketReadIndex[ orderingChannelCopy ] ++; // This wraps
01037 
01038                                                 orderingListAtOrderingStream = GetOrderingListAtOrderingStream( orderingChannelCopy );
01039 
01040                                                 if ( orderingListAtOrderingStream != 0)
01041                                                 {
01042                                                         while ( orderingListAtOrderingStream->Size() > 0 )
01043                                                         {
01044                                                                 // Cycle through the list until nothing is found
01045                                                                 orderingListAtOrderingStream->Beginning();
01046                                                                 indexFound=false;
01047                                                                 size=orderingListAtOrderingStream->Size();
01048                                                                 count=0;
01049 
01050                                                                 while (count++ < size)
01051                                                                 {
01052                                                                         if ( orderingListAtOrderingStream->Peek()->orderingIndex == waitingForOrderedPacketReadIndex[ orderingChannelCopy ] )
01053                                                                         {
01054                                                                                 outputQueue.Push( orderingListAtOrderingStream->Pop(), __FILE__, __LINE__  );
01055                                                                                 waitingForOrderedPacketReadIndex[ orderingChannelCopy ]++;
01056                                                                                 indexFound=true;
01057                                                                         }
01058                                                                         else
01059                                                                                 (*orderingListAtOrderingStream)++;
01060                                                                 }
01061 
01062                                                                 if (indexFound==false)
01063                                                                         break;
01064                                                         }
01065                                                 }
01066                                                 internalPacket = 0;
01067                                         }
01068                                         else
01069                                         {
01070                                                 // This is a newer ordered packet than we are waiting for. Store it for future use
01071                                                 AddToOrderingList( internalPacket );
01072                                         }
01073 
01074 
01075                                         goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
01076                                 }
01077 
01078                                 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_PROCESSED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
01079 
01080                                 // Nothing special about this packet.  Add it to the output queue
01081                                 outputQueue.Push( internalPacket, __FILE__, __LINE__  );
01082 
01083                                 internalPacket = 0;
01084                         }
01085 
01086                         // Used for a goto to jump to the resendNext packet immediately
01087 
01088 CONTINUE_SOCKET_DATA_PARSE_LOOP:
01089                         // Parse the bitstream to create an internal packet
01090                         internalPacket = CreateInternalPacketFromBitStream( &socketData, timeRead );
01091                 }
01092 
01093         }
01094 
01095 
01096         receivePacketCount++;
01097 
01098         return true;
01099 }
01100 
01101 //-------------------------------------------------------------------------------------------------------
01102 // This gets an end-user packet already parsed out. Returns number of BITS put into the buffer
01103 //-------------------------------------------------------------------------------------------------------
01104 BitSize_t ReliabilityLayer::Receive( unsigned char **data )
01105 {
01106         // Wait until the clear occurs
01107         if (freeThreadedMemoryOnNextUpdate)
01108                 return 0;
01109 
01110         InternalPacket * internalPacket;
01111 
01112         if ( outputQueue.Size() > 0 )
01113         {
01114                 //  #ifdef _DEBUG
01115                 //  RakAssert(bitStream->GetNumberOfBitsUsed()==0);
01116                 //  #endif
01117                 internalPacket = outputQueue.Pop();
01118 
01119                 BitSize_t bitLength;
01120                 *data = internalPacket->data;
01121                 bitLength = internalPacket->dataBitLength;
01122                 ReleaseToInternalPacketPool( internalPacket );
01123                 return bitLength;
01124         }
01125 
01126         else
01127         {
01128                 return 0;
01129         }
01130 
01131 }
01132 
01133 //-------------------------------------------------------------------------------------------------------
01134 // Puts data on the send queue
01135 // bitStream contains the data to send
01136 // priority is what priority to send the data at
01137 // reliability is what reliability to use
01138 // ordering channel is from 0 to 255 and specifies what stream to use
01139 //-------------------------------------------------------------------------------------------------------
01140 bool ReliabilityLayer::Send( char *data, BitSize_t numberOfBitsToSend, PacketPriority priority, PacketReliability reliability, unsigned char orderingChannel, bool makeDataCopy, int MTUSize, CCTimeType currentTime, uint32_t receipt )
01141 {
01142 #ifdef _DEBUG
01143         RakAssert( !( reliability >= NUMBER_OF_RELIABILITIES || reliability < 0 ) );
01144         RakAssert( !( priority > NUMBER_OF_PRIORITIES || priority < 0 ) );
01145         RakAssert( !( orderingChannel >= NUMBER_OF_ORDERED_STREAMS ) );
01146         RakAssert( numberOfBitsToSend > 0 );
01147 #endif
01148 
01149 #if CC_TIME_TYPE_BYTES==4
01150         currentTime/=1000;
01151 #endif
01152 
01153         (void) MTUSize;
01154 
01155         //      int a = BITS_TO_BYTES(numberOfBitsToSend);
01156 
01157         // Fix any bad parameters
01158         if ( reliability > RELIABLE_ORDERED_WITH_ACK_RECEIPT || reliability < 0 )
01159                 reliability = RELIABLE;
01160 
01161         if ( priority > NUMBER_OF_PRIORITIES || priority < 0 )
01162                 priority = HIGH_PRIORITY;
01163 
01164         if ( orderingChannel >= NUMBER_OF_ORDERED_STREAMS )
01165                 orderingChannel = 0;
01166 
01167         unsigned int numberOfBytesToSend=(unsigned int) BITS_TO_BYTES(numberOfBitsToSend);
01168         if ( numberOfBitsToSend == 0 )
01169         {
01170                 return false;
01171         }
01172         InternalPacket * internalPacket = AllocateFromInternalPacketPool();
01173         if (internalPacket==0)
01174         {
01175                 notifyOutOfMemory(__FILE__, __LINE__);
01176                 return false; // Out of memory
01177         }
01178 
01179         bpsMetrics[(int) USER_MESSAGE_BYTES_PUSHED].Push1(currentTime,numberOfBytesToSend);
01180 
01181         internalPacket->creationTime = currentTime;
01182 
01183         if ( makeDataCopy )
01184         {
01185                 AllocInternalPacketData(internalPacket, numberOfBytesToSend, __FILE__, __LINE__ );
01186                 //internalPacket->data = (unsigned char*) rakMalloc_Ex( numberOfBytesToSend, __FILE__, __LINE__ );
01187                 memcpy( internalPacket->data, data, numberOfBytesToSend );
01188         }
01189         else
01190         {
01191                 // Allocated the data elsewhere, delete it in here
01192                 //internalPacket->data = ( unsigned char* ) data;
01193                 AllocInternalPacketData(internalPacket, (unsigned char*) data );
01194         }
01195 
01196         internalPacket->dataBitLength = numberOfBitsToSend;
01197         internalPacket->messageInternalOrder = internalOrderIndex++;
01198         internalPacket->priority = priority;
01199         internalPacket->reliability = reliability;
01200         internalPacket->sendReceiptSerial=receipt;
01201 
01202         // Calculate if I need to split the packet
01203         //      int headerLength = BITS_TO_BYTES( GetMessageHeaderLengthBits( internalPacket, true ) );
01204 
01205         unsigned int maxDataSizeBytes = GetMaxDatagramSizeExcludingMessageHeaderBytes() - BITS_TO_BYTES(GetMaxMessageHeaderLengthBits());
01206 
01207         bool splitPacket = numberOfBytesToSend > maxDataSizeBytes;
01208 
01209         // If a split packet, we might have to upgrade the reliability
01210         if ( splitPacket )
01211         {
01212                 // Split packets cannot be unreliable, in case that one part doesn't arrive and the whole cannot be reassembled.
01213                 // One part could not arrive either due to packetloss or due to unreliable discard
01214                 if (internalPacket->reliability==UNRELIABLE)
01215                         internalPacket->reliability=RELIABLE;
01216                 else if (internalPacket->reliability==UNRELIABLE_WITH_ACK_RECEIPT)
01217                         internalPacket->reliability=RELIABLE_WITH_ACK_RECEIPT;
01218                 else if (internalPacket->reliability==UNRELIABLE_SEQUENCED)
01219                         internalPacket->reliability=RELIABLE_SEQUENCED;
01220 //              else if (internalPacket->reliability==UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT)
01221 //                      internalPacket->reliability=RELIABLE_SEQUENCED_WITH_ACK_RECEIPT;
01222         }
01223 
01224         //      ++sendMessageNumberIndex;
01225 
01226         if ( internalPacket->reliability == RELIABLE_SEQUENCED ||
01227                 internalPacket->reliability == UNRELIABLE_SEQUENCED
01228 //              ||
01229 //              internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
01230 //              internalPacket->reliability == UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
01231                 )
01232         {
01233                 // Assign the sequence stream and index
01234                 internalPacket->orderingChannel = orderingChannel;
01235                 internalPacket->orderingIndex = waitingForSequencedPacketWriteIndex[ orderingChannel ] ++;
01236 
01237                 // This packet supersedes all other sequenced packets on the same ordering channel
01238                 // Delete all packets in all send lists that are sequenced and on the same ordering channel
01239                 // UPDATE:
01240                 // Disabled.  We don't have enough info to consistently do this.  Sometimes newer data does supercede
01241                 // older data such as with constantly declining health, but not in all cases.
01242                 // For example, with sequenced unreliable sound packets just because you send a newer one doesn't mean you
01243                 // don't need the older ones because the odds are they will still arrive in order
01244                 /*
01245                 for (int i=0; i < NUMBER_OF_PRIORITIES; i++)
01246                 {
01247                 DeleteSequencedPacketsInList(orderingChannel, sendQueue[i]);
01248                 }
01249                 */
01250         }
01251         else if ( internalPacket->reliability == RELIABLE_ORDERED || internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT )
01252         {
01253                 // Assign the ordering channel and index
01254                 internalPacket->orderingChannel = orderingChannel;
01255                 internalPacket->orderingIndex = waitingForOrderedPacketWriteIndex[ orderingChannel ] ++;
01256         }
01257 
01258 
01259 
01260         if ( splitPacket )   // If it uses a secure header it will be generated here
01261         {
01262                 // Must split the packet.  This will also generate the SHA1 if it is required. It also adds it to the send list.
01263                 //InternalPacket packetCopy;
01264                 //memcpy(&packetCopy, internalPacket, sizeof(InternalPacket));
01265                 //sendPacketSet[priority].CancelWriteLock(internalPacket);
01266                 //SplitPacket( &packetCopy, MTUSize );
01267                 SplitPacket( internalPacket );
01268                 //RakNet::OP_DELETE_ARRAY(packetCopy.data, __FILE__, __LINE__);
01269                 return true;
01270         }
01271 
01272         RakAssert(internalPacket->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
01273         AddToUnreliableLinkedList(internalPacket);
01274 
01275         RakAssert(internalPacket->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
01276         RakAssert(internalPacket->messageNumberAssigned==false);
01277         outgoingPacketBuffer.Push( GetNextWeight(internalPacket->priority), internalPacket, __FILE__, __LINE__  );
01278         RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
01279         statistics.messageInSendBuffer[(int)internalPacket->priority]++;
01280         statistics.bytesInSendBuffer[(int)internalPacket->priority]+=(double) BITS_TO_BYTES(internalPacket->dataBitLength);
01281 
01282         //      sendPacketSet[priority].WriteUnlock();
01283         return true;
01284 }
01285 //-------------------------------------------------------------------------------------------------------
01286 // Run this once per game cycle.  Handles internal lists and actually does the send
01287 //-------------------------------------------------------------------------------------------------------
01288 void ReliabilityLayer::Update( SOCKET s, SystemAddress systemAddress, int MTUSize, CCTimeType time,
01289                                                           unsigned bitsPerSecondLimit,
01290                                                           DataStructures::List<PluginInterface2*> &messageHandlerList,
01291                                                           RakNetRandom *rnr, unsigned short remotePortRakNetWasStartedOn_PS3)
01292 
01293 {
01294         (void) bitsPerSecondLimit;
01295         (void) MTUSize;
01296 
01297         RakNetTimeMS timeMs;
01298 #if CC_TIME_TYPE_BYTES==4
01299         time/=1000;
01300         timeMs=time;
01301 #else
01302         timeMs=time/1000;
01303 #endif
01304 
01305         //      int i;
01306 
01307 #ifdef _DEBUG
01308         while (delayList.Size())
01309         {
01310                 if (delayList.Peek()->sendTime <= timeMs)
01311                 {
01312                         DataAndTime *dat = delayList.Pop();
01313                         SocketLayer::Instance()->SendTo( dat->s, dat->data, dat->length, systemAddress.binaryAddress, systemAddress.port, dat->remotePortRakNetWasStartedOn_PS3 );
01314                         RakNet::OP_DELETE(dat,__FILE__,__LINE__);
01315                 }
01316                 break;
01317         }
01318 #endif
01319 
01320         // This line is necessary because the timer isn't accurate
01321         if (time <= lastUpdateTime)
01322         {
01323                 // Always set the last time in case of overflow
01324                 lastUpdateTime=time;
01325                 return;
01326         }
01327 
01328         CCTimeType timeSinceLastTick = time - lastUpdateTime;
01329         lastUpdateTime=time;
01330 #if CC_TIME_TYPE_BYTES==4
01331         if (timeSinceLastTick>100)
01332                 timeSinceLastTick=100;
01333 #else
01334         if (timeSinceLastTick>100000)
01335                 timeSinceLastTick=100000;
01336 #endif
01337 
01338         if (unreliableTimeout>0)
01339         {
01340                 if (timeSinceLastTick>=timeToNextUnreliableCull)
01341                 {
01342                         if (unreliableLinkedListHead)
01343                         {
01344                                 // Cull out all unreliable messages that have exceeded the timeout
01345                                 InternalPacket *cur = unreliableLinkedListHead;
01346                                 InternalPacket *end = unreliableLinkedListHead->unreliablePrev;
01347                                 while (1)
01348                                 {
01349                                         if (time > cur->creationTime+(CCTimeType)unreliableTimeout)
01350                                         {
01351                                                 // Flag invalid, and clear the memory. Still needs to be removed from the sendPacketSet later
01352                                                 // This fixes a problem where a remote system disconnects, but we don't know it yet, and memory consumption increases to a huge value
01353                                                 FreeInternalPacketData(cur, __FILE__, __LINE__ );
01354                                                 cur->data=0;
01355                                                 InternalPacket *next = cur->unreliableNext;
01356                                                 RemoveFromUnreliableLinkedList(cur);
01357 
01358                                                 if (cur==end)
01359                                                         break;
01360 
01361                                                 cur=next;
01362                                         }
01363                                         else
01364                                         {
01365                                                 //                                              if (cur==end)
01366                                                 //                                                      break;
01367                                                 // 
01368                                                 //                                              cur=cur->unreliableNext;
01369 
01370                                                 // They should be inserted in-order, so no need to iterate past the first failure
01371                                                 break;
01372                                         }
01373                                 }
01374                         }
01375 
01376                         timeToNextUnreliableCull=unreliableTimeout/(CCTimeType)2;
01377                 }
01378                 else
01379                 {
01380                         timeToNextUnreliableCull-=timeSinceLastTick;
01381                 }
01382         }
01383 
01384 
01385         // Due to thread vagarities and the way I store the time to avoid slow calls to RakNet::GetTime
01386         // time may be less than lastAck
01387 #if CC_TIME_TYPE_BYTES==4
01388         if ( statistics.messagesInResendBuffer!=0 && AckTimeout(time) )
01389 #else
01390         if ( statistics.messagesInResendBuffer!=0 && AckTimeout(time/1000) )
01391 #endif
01392         {
01393                 // SHOW - dead connection
01394                 // We've waited a very long time for a reliable packet to get an ack and it never has
01395                 deadConnection = true;
01396                 return;
01397         }
01398 
01399         if (congestionManager.ShouldSendACKs(time,timeSinceLastTick))
01400         {
01401                 SendACKs(s, systemAddress, time, rnr, remotePortRakNetWasStartedOn_PS3);
01402         }
01403 
01404         if (NAKs.Size()>0)
01405         {
01406                 updateBitStream.Reset();
01407                 DatagramHeaderFormat dhfNAK;
01408                 dhfNAK.isNAK=true;
01409                 dhfNAK.isACK=false;
01410                 dhfNAK.isPacketPair=false;
01411                 dhfNAK.Serialize(&updateBitStream);
01412                 NAKs.Serialize(&updateBitStream, GetMaxDatagramSizeExcludingMessageHeaderBits(), true);
01413                 SendBitStream( s, systemAddress, &updateBitStream, rnr, remotePortRakNetWasStartedOn_PS3, time );
01414         }
01415 
01416         DatagramHeaderFormat dhf;
01417         dhf.needsBAndAs=congestionManager.GetIsInSlowStart();
01418         dhf.isContinuousSend=bandwidthExceededStatistic;
01419         //      bandwidthExceededStatistic=sendPacketSet[0].IsEmpty()==false ||
01420         //              sendPacketSet[1].IsEmpty()==false ||
01421         //              sendPacketSet[2].IsEmpty()==false ||
01422         //              sendPacketSet[3].IsEmpty()==false;
01423         bandwidthExceededStatistic=outgoingPacketBuffer.Size()>0;
01424 
01425         const bool hasDataToSendOrResend = IsResendQueueEmpty()==false || bandwidthExceededStatistic;
01426         RakAssert(NUMBER_OF_PRIORITIES==4);
01427         congestionManager.Update(time, hasDataToSendOrResend);
01428 
01429         uint64_t actualBPS = bpsMetrics[(int) ACTUAL_BYTES_SENT].GetBPS1(time);
01430         statistics.BPSLimitByOutgoingBandwidthLimit = BITS_TO_BYTES(bitsPerSecondLimit);
01431         statistics.BPSLimitByCongestionControl = congestionManager.GetBytesPerSecondLimitByCongestionControl();
01432         if (statistics.BPSLimitByOutgoingBandwidthLimit > 0 && statistics.BPSLimitByOutgoingBandwidthLimit < actualBPS)
01433         {
01434                 statistics.BPSLimitByOutgoingBandwidthLimit=true;
01435                 return;
01436         }
01437         else
01438         {
01439                 statistics.BPSLimitByOutgoingBandwidthLimit=false;
01440         }
01441 
01442         if (hasDataToSendOrResend==true)
01443         {
01444                 InternalPacket *internalPacket;
01445                 //              bool forceSend=false;
01446                 bool pushedAnything;
01447                 BitSize_t nextPacketBitLength;
01448                 dhf.isACK=false;
01449                 dhf.isNAK=false;
01450                 dhf.hasBAndAS=false;
01451                 ResetPacketsAndDatagrams();
01452 
01453                 int transmissionBandwidth = congestionManager.GetTransmissionBandwidth(time, timeSinceLastTick, unacknowledgedBytes,dhf.isContinuousSend);
01454                 int retransmissionBandwidth = congestionManager.GetRetransmissionBandwidth(time, timeSinceLastTick, unacknowledgedBytes,dhf.isContinuousSend);
01455                 if (retransmissionBandwidth>0 || transmissionBandwidth>0)
01456                 {
01457                         statistics.isLimitedByCongestionControl=false;
01458 
01459                         allDatagramSizesSoFar=0;
01460 
01461                         // Keep filling datagrams until we exceed retransmission bandwidth
01462                         while ((int)BITS_TO_BYTES(allDatagramSizesSoFar)<retransmissionBandwidth)
01463                         {
01464                                 pushedAnything=false;
01465 
01466                                 // Fill one datagram, then break
01467                                 while ( IsResendQueueEmpty()==false )
01468                                 {
01469                                         internalPacket = resendLinkedListHead;
01470                                         RakAssert(internalPacket->messageNumberAssigned==true);
01471 
01472                                         if ( internalPacket->nextActionTime < time )
01473                                         {
01474                                                 // If this is unreliable, then it was just in this list for a receipt. Don't actually resend, and remove from the list
01475                                                 if (internalPacket->reliability==UNRELIABLE_WITH_ACK_RECEIPT
01476                                                 //      || internalPacket->reliability==UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
01477                                                         )
01478                                                 {
01479                                                         PopListHead(false);
01480 
01481                                                         InternalPacket *ackReceipt = AllocateFromInternalPacketPool();
01482                                                         AllocInternalPacketData(ackReceipt, 5,  __FILE__, __LINE__ );
01483                                                         ackReceipt->dataBitLength=BYTES_TO_BITS(5);
01484                                                         ackReceipt->data[0]=(MessageID)ID_SND_RECEIPT_LOSS;
01485                                                         ackReceipt->allocationScheme=InternalPacket::NORMAL;
01486                                                         memcpy(ackReceipt->data+sizeof(MessageID), &internalPacket->sendReceiptSerial, sizeof(internalPacket->sendReceiptSerial));
01487                                                         outputQueue.Push(ackReceipt, __FILE__, __LINE__ );
01488 
01489                                                         statistics.messagesInResendBuffer--;
01490                                                         statistics.bytesInResendBuffer-=BITS_TO_BYTES(internalPacket->dataBitLength);
01491 
01492                                                         ReleaseToInternalPacketPool( internalPacket );
01493 
01494                                                         resendBuffer[internalPacket->reliableMessageNumber & (uint32_t) RESEND_BUFFER_ARRAY_MASK] = 0;
01495                                                         
01496 
01497                                                         continue;
01498                                                 }
01499 
01500                                                 nextPacketBitLength = internalPacket->headerLength + internalPacket->dataBitLength;
01501                                                 if ( datagramSizeSoFar + nextPacketBitLength > GetMaxDatagramSizeExcludingMessageHeaderBits() )
01502                                                 {
01503                                                         // Gathers all PushPackets()
01504                                                         PushDatagram();
01505                                                         break;
01506                                                 }
01507 
01508                                                 PopListHead(false);
01509 
01510                                                 CC_DEBUG_PRINTF_2("Rs %i ", internalPacket->reliableMessageNumber.val);
01511 
01512                                                 bpsMetrics[(int) USER_MESSAGE_BYTES_RESENT].Push1(time,BITS_TO_BYTES(internalPacket->dataBitLength));
01513                                                 PushPacket(time,internalPacket,true); // Affects GetNewTransmissionBandwidth()
01514                                                 internalPacket->timesSent++;
01515                                                 internalPacket->nextActionTime = congestionManager.GetRTOForRetransmission()+time;
01516 #if CC_TIME_TYPE_BYTES==4
01517                                                 if (internalPacket->nextActionTime-time > 10000)
01518 #else
01519                                                 if (internalPacket->nextActionTime-time > 10000000)
01520 #endif
01521                                                 {
01522                                                         //                                                      int a=5;
01523                                                         RakAssert(0);
01524                                                 }
01525 
01526                                                 congestionManager.OnResend(time);
01527 
01528                                                 pushedAnything=true;
01529 
01530                                                 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
01531                                                 {
01532 #if CC_TIME_TYPE_BYTES==4
01533                                                         messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, internalPacket->reliableMessageNumber, systemAddress, time, true);
01534 #else
01535                                                         messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, internalPacket->reliableMessageNumber, systemAddress, (RakNetTime)(time/(CCTimeType)1000), true);
01536 #endif
01537                                                 }
01538 
01539                                                 // Put the packet back into the resend list at the correct spot
01540                                                 // Don't make a copy since I'm reinserting an allocated struct
01541                                                 InsertPacketIntoResendList( internalPacket, time, false, false );
01542 
01543                                                 // Removeme
01544                                                 //                                              printf("Resend:%i ", internalPacket->reliableMessageNumber);
01545                                         }
01546                                         else
01547                                         {
01548                                                 // Filled one datagram.
01549                                                 // If the 2nd and it's time to send a datagram pair, will be marked as a pair
01550                                                 PushDatagram();
01551                                                 break;
01552                                         }
01553                                 }
01554 
01555                                 if (pushedAnything==false)
01556                                         break;
01557                         }
01558                 }
01559                 else
01560                 {
01561                         statistics.isLimitedByCongestionControl=true;
01562                 }
01563 
01564 //              CCTimeType timeSinceLastContinualSend;
01565 //              if (timeOfLastContinualSend!=0)
01566 //                      timeSinceLastContinualSend=time-timeOfLastContinualSend;
01567 //              else
01568 //                      timeSinceLastContinualSend=0;
01569 
01570 
01571                 //RakAssert(bufferOverflow==false); // If asserts, buffer is too small. We are using a slot that wasn't acked yet
01572                 if ((int)BITS_TO_BYTES(allDatagramSizesSoFar)<transmissionBandwidth)
01573                 {
01574                         //      printf("S+ ");
01575                         allDatagramSizesSoFar=0;
01576 
01577                         // Keep filling datagrams until we exceed retransmission bandwidth
01578                         while (
01579                                 ResendBufferOverflow()==false &&
01580                                 ((int)BITS_TO_BYTES(allDatagramSizesSoFar)<transmissionBandwidth ||
01581                                 // This condition means if we want to send a datagram pair, and only have one datagram buffered, exceed bandwidth to add another
01582                                 (countdownToNextPacketPair==0 &&
01583                                 datagramsToSendThisUpdateIsPair.Size()==1))
01584                                 )
01585                         {
01586                                 // Fill with packets until MTU is reached
01587                                 //      for ( i = 0; i < NUMBER_OF_PRIORITIES; i++ )
01588                                 //      {
01589                                 pushedAnything=false;
01590 
01591 
01592                                 while (outgoingPacketBuffer.Size())
01593                                         //while ( sendPacketSet[ i ].Size() )
01594                                 {
01595                                         internalPacket=outgoingPacketBuffer.Peek();
01596                                         RakAssert(internalPacket->messageNumberAssigned==false);
01597                                         RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
01598 
01599                                         // internalPacket = sendPacketSet[ i ].Peek();
01600                                         if (internalPacket->data==0)
01601                                         {
01602                                                 //sendPacketSet[ i ].Pop();
01603                                                 outgoingPacketBuffer.Pop(0);
01604                                                 RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
01605                                                 statistics.messageInSendBuffer[(int)internalPacket->priority]--;
01606                                                 statistics.bytesInSendBuffer[(int)internalPacket->priority]-=(double) BITS_TO_BYTES(internalPacket->dataBitLength);
01607                                                 ReleaseToInternalPacketPool( internalPacket );
01608                                                 continue;
01609                                         }
01610 
01611                                         internalPacket->headerLength=GetMessageHeaderLengthBits(internalPacket);
01612                                         nextPacketBitLength = internalPacket->headerLength + internalPacket->dataBitLength;
01613                                         if ( datagramSizeSoFar + nextPacketBitLength > GetMaxDatagramSizeExcludingMessageHeaderBits() )
01614                                         {
01615                                                 // Hit MTU. May still push packets if smaller ones exist at a lower priority
01616                                                 RakAssert(internalPacket->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
01617                                                 break;
01618                                         }
01619 
01620                                         bool isReliable;
01621                                         if ( internalPacket->reliability == RELIABLE ||
01622                                                 internalPacket->reliability == RELIABLE_SEQUENCED ||
01623                                                 internalPacket->reliability == RELIABLE_ORDERED ||
01624                                                 internalPacket->reliability == RELIABLE_WITH_ACK_RECEIPT  ||
01625 //                                              internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT  ||
01626                                                 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
01627                                                 )
01628                                                 isReliable = true;
01629                                         else
01630                                                 isReliable = false;
01631 
01632                                         //sendPacketSet[ i ].Pop();
01633                                         outgoingPacketBuffer.Pop(0);
01634                                         RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
01635                                         RakAssert(internalPacket->messageNumberAssigned==false);
01636                                         statistics.messageInSendBuffer[(int)internalPacket->priority]--;
01637                                         statistics.bytesInSendBuffer[(int)internalPacket->priority]-=(double) BITS_TO_BYTES(internalPacket->dataBitLength);
01638                                         if (isReliable
01639                                                 /*
01640                                                 I thought about this and agree that UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT and RELIABLE_SEQUENCED_WITH_ACK_RECEIPT is not useful unless you also know if the message was discarded.
01641 
01642                                                 The problem is that internally, message numbers are only assigned to reliable messages, because message numbers are only used to discard duplicate message receipt and only reliable messages get sent more than once. However, without message numbers getting assigned and transmitted, there is no way to tell the sender about which messages were discarded. In fact, in looking this over I realized that UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT introduced a bug, because the remote system assumes all message numbers are used (no holes). With that send type, on packetloss, a permanent hole would have been created which eventually would cause the system to discard all further packets.
01643 
01644                                                 So I have two options. Either do not support ack receipts when sending sequenced, or write complex and major new systems. UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT would need to send the message ID number on a special channel which allows for non-delivery. And both of them would need to have a special range list to indicate which message numbers were not delivered, so when acks are sent that can be indicated as well. A further problem is that the ack itself can be lost - it is possible that the message can arrive but be discarded, yet the ack is lost. On resend, the resent message would be ignored as duplicate, and you'd never get the discard message either (unless I made a special buffer for that case too). 
01645 */
01646 //                                              ||
01647                                                 // If needs an ack receipt, keep the internal packet around in the list
01648 //                                              internalPacket->reliability == UNRELIABLE_WITH_ACK_RECEIPT ||
01649 //                                              internalPacket->reliability == UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
01650                                                 )
01651                                         {
01652                                                 internalPacket->messageNumberAssigned=true;
01653                                                 internalPacket->reliableMessageNumber=sendReliableMessageNumberIndex;
01654                                                 internalPacket->nextActionTime = congestionManager.GetRTOForRetransmission()+time;
01655 #if CC_TIME_TYPE_BYTES==4
01656                                                 const CCTimeType threshhold = 10000;
01657 #else
01658                                                 const CCTimeType threshhold = 10000000;
01659 #endif
01660                                                 if (internalPacket->nextActionTime-time > threshhold)
01661                                                 {
01662                                                         //                                                              int a=5;
01663                                                         RakAssert(time-internalPacket->nextActionTime < threshhold);
01664                                                 }
01665                                                 //resendTree.Insert( internalPacket->reliableMessageNumber, internalPacket);
01666                                                 if (resendBuffer[internalPacket->reliableMessageNumber & (uint32_t) RESEND_BUFFER_ARRAY_MASK]!=0)
01667                                                 {
01668                                                         //                                                              bool overflow = ResendBufferOverflow();
01669                                                         RakAssert(0);
01670                                                 }
01671                                                 resendBuffer[internalPacket->reliableMessageNumber & (uint32_t) RESEND_BUFFER_ARRAY_MASK] = internalPacket;
01672                                                 statistics.messagesInResendBuffer++;
01673                                                 statistics.bytesInResendBuffer+=BITS_TO_BYTES(internalPacket->dataBitLength);
01674 
01675                                                 //              printf("pre:%i ", unacknowledgedBytes);
01676 
01677                                                 InsertPacketIntoResendList( internalPacket, time, true, isReliable);
01678 
01679 
01680                                                 //              printf("post:%i ", unacknowledgedBytes);
01681                                                 sendReliableMessageNumberIndex++;
01682                                         }
01683                                         internalPacket->timesSent=1;
01684                                         // If isReliable is false, the packet and its contents will be added to a list to be freed in ClearPacketsAndDatagrams
01685                                         // However, the internalPacket structure will remain allocated and be in the resendBuffer list if it requires a receipt
01686                                         bpsMetrics[(int) USER_MESSAGE_BYTES_SENT].Push1(time,BITS_TO_BYTES(internalPacket->dataBitLength));
01687                                         PushPacket(time,internalPacket, isReliable);
01688 
01689                                         for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
01690                                         {
01691 #if CC_TIME_TYPE_BYTES==4
01692                                                 messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, internalPacket->reliableMessageNumber, systemAddress, time, true);
01693 #else
01694                                                 messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, internalPacket->reliableMessageNumber, systemAddress, (RakNetTime)(time/(CCTimeType)1000), true);
01695 #endif
01696                                         }
01697                                         pushedAnything=true;
01698 
01699                                         if (ResendBufferOverflow())
01700                                                 break;
01701                                 }
01702                                 //      if (ResendBufferOverflow())
01703                                 //              break;
01704                                 //      }z
01705 
01706                                 // No datagrams pushed?
01707                                 if (datagramSizeSoFar==0)
01708                                         break;
01709 
01710                                 // Filled one datagram.
01711                                 // If the 2nd and it's time to send a datagram pair, will be marked as a pair
01712                                 PushDatagram();
01713                         }
01714                 }
01715                 else
01716                 {
01717                         //      printf("S- ");
01718 
01719                 }
01720 
01721 
01722 
01723                 for (unsigned int datagramIndex=0; datagramIndex < packetsToSendThisUpdateDatagramBoundaries.Size(); datagramIndex++)
01724                 {
01725                         if (datagramIndex>0)
01726                                 dhf.isContinuousSend=true;
01727                         MessageNumberNode* messageNumberNode = 0;
01728                         dhf.datagramNumber=congestionManager.GetNextDatagramSequenceNumber();
01729                         dhf.isPacketPair=datagramsToSendThisUpdateIsPair[datagramIndex];
01730 
01731                         bool isSecondOfPacketPair=dhf.isPacketPair && datagramIndex>0 &&  datagramsToSendThisUpdateIsPair[datagramIndex-1];
01732                         unsigned int msgIndex, msgTerm;
01733                         if (datagramIndex==0)
01734                         {
01735                                 msgIndex=0;
01736                                 msgTerm=packetsToSendThisUpdateDatagramBoundaries[0];
01737                         }
01738                         else
01739                         {
01740                                 msgIndex=packetsToSendThisUpdateDatagramBoundaries[datagramIndex-1];
01741                                 msgTerm=packetsToSendThisUpdateDatagramBoundaries[datagramIndex];
01742                         }
01743 
01744                         // More accurate time to reset here
01745                         dhf.sourceSystemTime=RakNet::GetTimeUS();
01746                         updateBitStream.Reset();
01747                         dhf.Serialize(&updateBitStream);
01748                         CC_DEBUG_PRINTF_2("S%i ",dhf.datagramNumber.val);
01749 
01750                         while (msgIndex < msgTerm)
01751                         {
01752                                 // If reliable or needs receipt
01753                                 if ( packetsToSendThisUpdate[msgIndex]->reliability != UNRELIABLE &&
01754                                         packetsToSendThisUpdate[msgIndex]->reliability != UNRELIABLE_SEQUENCED
01755                                         )
01756                                 {
01757                                         if (messageNumberNode==0)
01758                                         {
01759                                                 messageNumberNode = AddFirstToDatagramHistory(dhf.datagramNumber, packetsToSendThisUpdate[msgIndex]->reliableMessageNumber);
01760                                         }
01761                                         else
01762                                         {
01763                                                 messageNumberNode = AddSubsequentToDatagramHistory(messageNumberNode, packetsToSendThisUpdate[msgIndex]->reliableMessageNumber);
01764                                         }
01765                                 }
01766 
01767                                 RakAssert(updateBitStream.GetNumberOfBytesUsed()<=MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
01768                                 WriteToBitStreamFromInternalPacket( &updateBitStream, packetsToSendThisUpdate[msgIndex], time );
01769                                 RakAssert(updateBitStream.GetNumberOfBytesUsed()<=MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
01770                                 msgIndex++;
01771                         }
01772 
01773                         if (isSecondOfPacketPair)
01774                         {
01775                                 // Pad to size of first datagram
01776                                 RakAssert(updateBitStream.GetNumberOfBytesUsed()<=MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
01777                                 updateBitStream.PadWithZeroToByteLength(datagramSizesInBytes[datagramIndex-1]);
01778                                 RakAssert(updateBitStream.GetNumberOfBytesUsed()<=MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
01779                         }
01780 
01781                         if (messageNumberNode==0)
01782                         {
01783                                 // REMOVEME
01784                                 //                              printf("%p AddFirstToDatagramHistory (no reliable) %i\n", this, dhf.datagramNumber.val);
01785                                 AddFirstToDatagramHistory(dhf.datagramNumber);
01786                         }
01787 
01788                         // Store what message ids were sent with this datagram
01789                         //      datagramMessageIDTree.Insert(dhf.datagramNumber,idList);
01790 
01791                         congestionManager.OnSendBytes(time,UDP_HEADER_SIZE+DatagramHeaderFormat::GetDataHeaderByteLength());
01792 
01793                         SendBitStream( s, systemAddress, &updateBitStream, rnr, remotePortRakNetWasStartedOn_PS3, time );
01794 
01795                         bandwidthExceededStatistic=outgoingPacketBuffer.Size()>0;
01796                         //                      bandwidthExceededStatistic=sendPacketSet[0].IsEmpty()==false ||
01797                         //                              sendPacketSet[1].IsEmpty()==false ||
01798                         //                              sendPacketSet[2].IsEmpty()==false ||
01799                         //                              sendPacketSet[3].IsEmpty()==false;
01800 
01801 
01802 
01803                         if (bandwidthExceededStatistic==true)
01804                                 timeOfLastContinualSend=time;
01805                         else
01806                                 timeOfLastContinualSend=0;
01807                 }
01808 
01809                 ClearPacketsAndDatagrams(true);
01810 
01811                 // Any data waiting to send after attempting to send, then bandwidth is exceeded
01812                 bandwidthExceededStatistic=outgoingPacketBuffer.Size()>0;
01813                 //              bandwidthExceededStatistic=sendPacketSet[0].IsEmpty()==false ||
01814                 //                      sendPacketSet[1].IsEmpty()==false ||
01815                 //                      sendPacketSet[2].IsEmpty()==false ||
01816                 //                      sendPacketSet[3].IsEmpty()==false;
01817         }
01818 
01819 
01820         // Keep on top of deleting old unreliable split packets so they don't clog the list.
01821         //DeleteOldUnreliableSplitPackets( time );
01822 }
01823 
01824 //-------------------------------------------------------------------------------------------------------
01825 // Writes a bitstream to the socket
01826 //-------------------------------------------------------------------------------------------------------
01827 void ReliabilityLayer::SendBitStream( SOCKET s, SystemAddress systemAddress, RakNet::BitStream *bitStream, RakNetRandom *rnr, unsigned short remotePortRakNetWasStartedOn_PS3, CCTimeType currentTime)
01828 {
01829         (void) systemAddress;
01830 
01831         unsigned int length;
01832 
01833 
01834         if ( encryptor.IsKeySet() )
01835         {
01836                 length = (unsigned int) bitStream->GetNumberOfBytesUsed();
01837 
01838                 encryptor.Encrypt( ( unsigned char* ) bitStream->GetData(), length, ( unsigned char* ) bitStream->GetData(), &length, rnr );
01839 
01840                 RakAssert( ( length % 16 ) == 0 );
01841         }
01842         else
01843         {
01844                 length = (unsigned int) bitStream->GetNumberOfBytesUsed();
01845         }
01846 
01847 #ifdef _DEBUG
01848         if (packetloss > 0.0)
01849         {
01850                 if (frandomMT() < packetloss)
01851                         return;
01852         }
01853 
01854         if (minExtraPing > 0 || extraPingVariance > 0)
01855         {
01856                 RakNetTimeMS delay = minExtraPing;
01857                 if (extraPingVariance>0)
01858                         delay += (randomMT() % extraPingVariance);
01859                 if (delay > 0)
01860                 {
01861                         DataAndTime *dat = RakNet::OP_NEW<DataAndTime>(__FILE__,__LINE__);
01862                         memcpy(dat->data, ( char* ) bitStream->GetData(), length );
01863                         dat->s=s;
01864                         dat->length=length;
01865                         dat->sendTime = RakNet::GetTimeMS() + delay;
01866                         dat->remotePortRakNetWasStartedOn_PS3=remotePortRakNetWasStartedOn_PS3;
01867                         for (unsigned int i=0; i < delayList.Size(); i++)
01868                         {
01869                                 if (dat->sendTime < delayList[i]->sendTime)
01870                                 {
01871                                         delayList.PushAtHead(dat, i, __FILE__, __LINE__);
01872                                         dat=0;
01873                                         break;
01874                                 }
01875                         }
01876                         if (dat!=0)
01877                                 delayList.Push(dat,__FILE__,__LINE__);
01878                         return;
01879                 }
01880         }
01881 #endif
01882 
01883         // Test packetloss
01884 //      if (frandomMT()<.1)
01885 //              return;
01886 
01887         //      printf("%i/%i\n", length,congestionManager.GetMTU());
01888 
01889         bpsMetrics[(int) ACTUAL_BYTES_SENT].Push1(currentTime,length);
01890 
01891         RakAssert(length <= congestionManager.GetMTU());
01892         SocketLayer::Instance()->SendTo( s, ( char* ) bitStream->GetData(), length, systemAddress.binaryAddress, systemAddress.port, remotePortRakNetWasStartedOn_PS3 );
01893 }
01894 
01895 //-------------------------------------------------------------------------------------------------------
01896 // Are we waiting for any data to be sent out or be processed by the player?
01897 //-------------------------------------------------------------------------------------------------------
01898 bool ReliabilityLayer::IsOutgoingDataWaiting(void)
01899 {
01900         if (outgoingPacketBuffer.Size()>0)
01901                 return true;
01902 
01903         //      unsigned i;
01904         //      for ( i = 0; i < NUMBER_OF_PRIORITIES; i++ )
01905         //      {
01906         //              if (sendPacketSet[ i ].Size() > 0)
01907         //                      return true;
01908         //      }
01909 
01910         return 
01911                 //acknowlegements.Size() > 0 ||
01912                 //resendTree.IsEmpty()==false;// || outputQueue.Size() > 0 || orderingList.Size() > 0 || splitPacketChannelList.Size() > 0;
01913                 statistics.messagesInResendBuffer!=0;
01914 }
01915 bool ReliabilityLayer::AreAcksWaiting(void)
01916 {
01917         return acknowlegements.Size() > 0;
01918 }
01919 
01920 //-------------------------------------------------------------------------------------------------------
01921 void ReliabilityLayer::ApplyNetworkSimulator( double _packetloss, RakNetTime _minExtraPing, RakNetTime _extraPingVariance )
01922 {
01923 #ifdef _DEBUG
01924         packetloss=_packetloss;
01925         minExtraPing=_minExtraPing;
01926         extraPingVariance=_extraPingVariance;
01927         //      if (ping < (unsigned int)(minExtraPing+extraPingVariance)*2)
01928         //              ping=(minExtraPing+extraPingVariance)*2;
01929 #endif
01930 }
01931 //-------------------------------------------------------------------------------------------------------
01932 void ReliabilityLayer::SetSplitMessageProgressInterval(int interval)
01933 {
01934         splitMessageProgressInterval=interval;
01935 }
01936 //-------------------------------------------------------------------------------------------------------
01937 void ReliabilityLayer::SetUnreliableTimeout(RakNetTimeMS timeoutMS)
01938 {
01939 #if CC_TIME_TYPE_BYTES==4
01940         unreliableTimeout=timeoutMS;
01941 #else
01942         unreliableTimeout=(CCTimeType)timeoutMS*(CCTimeType)1000;
01943 #endif
01944 }
01945 
01946 //-------------------------------------------------------------------------------------------------------
01947 // This will return true if we should not send at this time
01948 //-------------------------------------------------------------------------------------------------------
01949 bool ReliabilityLayer::IsSendThrottled( int MTUSize )
01950 {
01951         (void) MTUSize;
01952 
01953         return false;
01954         //      return resendList.Size() > windowSize;
01955 
01956         // Disabling this, because it can get stuck here forever
01957         /*
01958         unsigned packetsWaiting;
01959         unsigned resendListDataSize=0;
01960         unsigned i;
01961         for (i=0; i < resendList.Size(); i++)
01962         {
01963         if (resendList[i])
01964         resendListDataSize+=resendList[i]->dataBitLength;
01965         }
01966         packetsWaiting = 1 + ((BITS_TO_BYTES(resendListDataSize)) / (MTUSize - UDP_HEADER_SIZE - 10)); // 10 to roughly estimate the raknet header
01967 
01968         return packetsWaiting >= windowSize;
01969         */
01970 }
01971 
01972 //-------------------------------------------------------------------------------------------------------
01973 // We lost a packet
01974 //-------------------------------------------------------------------------------------------------------
01975 void ReliabilityLayer::UpdateWindowFromPacketloss( CCTimeType time )
01976 {
01977         (void) time;
01978 }
01979 
01980 //-------------------------------------------------------------------------------------------------------
01981 // Increase the window size
01982 //-------------------------------------------------------------------------------------------------------
01983 void ReliabilityLayer::UpdateWindowFromAck( CCTimeType time )
01984 {
01985         (void) time;
01986 }
01987 
01988 //-------------------------------------------------------------------------------------------------------
01989 // Does what the function name says
01990 //-------------------------------------------------------------------------------------------------------
01991 unsigned ReliabilityLayer::RemovePacketFromResendListAndDeleteOlderReliableSequenced( const MessageNumberType messageNumber, CCTimeType time, DataStructures::List<PluginInterface2*> &messageHandlerList, SystemAddress systemAddress )
01992 {
01993         (void) time;
01994         (void) messageNumber;
01995         InternalPacket * internalPacket;
01996         //InternalPacket *temp;
01997 //      PacketReliability reliability; // What type of reliability algorithm to use with this packet
01998 //      unsigned char orderingChannel; // What ordering channel this packet is on, if the reliability type uses ordering channels
01999         OrderingIndexType orderingIndex; // The ID used as identification for ordering channels
02000         //      unsigned j;
02001 
02002         for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
02003         {
02004 #if CC_TIME_TYPE_BYTES==4
02005                 messageHandlerList[messageHandlerIndex]->OnAck(messageNumber, systemAddress, time);
02006 #else
02007                 messageHandlerList[messageHandlerIndex]->OnAck(messageNumber, systemAddress, (RakNetTime)(time/(CCTimeType)1000));
02008 #endif
02009         }
02010 
02011         //      bool deleted;
02012         //      deleted=resendTree.Delete(messageNumber, internalPacket);
02013         internalPacket = resendBuffer[messageNumber & RESEND_BUFFER_ARRAY_MASK];
02014         if (internalPacket)
02015         {
02016                 ValidateResendList();
02017                 resendBuffer[messageNumber & RESEND_BUFFER_ARRAY_MASK]=0;
02018                 CC_DEBUG_PRINTF_2("AckRcv %i ", messageNumber);
02019 
02020                 statistics.messagesInResendBuffer--;
02021                 statistics.bytesInResendBuffer-=BITS_TO_BYTES(internalPacket->dataBitLength);
02022 
02023                 orderingIndex = internalPacket->orderingIndex;
02024                 totalUserDataBytesAcked+=(double) BITS_TO_BYTES(internalPacket->headerLength+internalPacket->dataBitLength);
02025 
02026                 // Return receipt if asked for
02027                 if (internalPacket->reliability>=UNRELIABLE_WITH_ACK_RECEIPT && 
02028                         (internalPacket->splitPacketCount==0 || internalPacket->splitPacketIndex+1==internalPacket->splitPacketCount)
02029                         )
02030                 {
02031                         InternalPacket *ackReceipt = AllocateFromInternalPacketPool();
02032                         AllocInternalPacketData(ackReceipt, 5,  __FILE__, __LINE__ );
02033                         ackReceipt->dataBitLength=BYTES_TO_BITS(5);
02034                         ackReceipt->data[0]=(MessageID)ID_SND_RECEIPT_ACKED;
02035                         ackReceipt->allocationScheme=InternalPacket::NORMAL;
02036                         memcpy(ackReceipt->data+sizeof(MessageID), &internalPacket->sendReceiptSerial, sizeof(internalPacket->sendReceiptSerial));
02037                         outputQueue.Push(ackReceipt, __FILE__, __LINE__ );
02038                 }
02039 
02040                 bool isReliable;
02041                 if ( internalPacket->reliability == RELIABLE ||
02042                         internalPacket->reliability == RELIABLE_SEQUENCED ||
02043                         internalPacket->reliability == RELIABLE_ORDERED ||
02044                         internalPacket->reliability == RELIABLE_WITH_ACK_RECEIPT  ||
02045 //                      internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT  ||
02046                         internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
02047                         )
02048                         isReliable = true;
02049                 else
02050                         isReliable = false;
02051 
02052                 RemoveFromList(internalPacket, isReliable);
02053                 FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
02054                 ReleaseToInternalPacketPool( internalPacket );
02055 
02056 
02057                 return 0;
02058         }
02059         else
02060         {
02061 
02062         }
02063 
02064         return (unsigned)-1;
02065 }
02066 
02067 //-------------------------------------------------------------------------------------------------------
02068 // Acknowledge receipt of the packet with the specified messageNumber
02069 //-------------------------------------------------------------------------------------------------------
02070 void ReliabilityLayer::SendAcknowledgementPacket( const DatagramSequenceNumberType messageNumber, CCTimeType time )
02071 {
02072 
02073         nextAckTimeToSend=time;
02074         acknowlegements.Insert(messageNumber);
02075 
02076         //printf("ACK_DG:%i ", messageNumber.val);
02077 
02078         CC_DEBUG_PRINTF_2("AckPush %i ", messageNumber);
02079 
02080 }
02081 
02082 //-------------------------------------------------------------------------------------------------------
02083 // Parse an internalPacket and figure out how many header bits would be
02084 // written.  Returns that number
02085 //-------------------------------------------------------------------------------------------------------
02086 BitSize_t ReliabilityLayer::GetMaxMessageHeaderLengthBits( void )
02087 {
02088         InternalPacket ip;
02089         ip.reliability=RELIABLE_ORDERED;
02090         ip.splitPacketCount=1;
02091         return GetMessageHeaderLengthBits(&ip);
02092 }
02093 //-------------------------------------------------------------------------------------------------------
02094 BitSize_t ReliabilityLayer::GetMessageHeaderLengthBits( const InternalPacket *const internalPacket )
02095 {       
02096         BitSize_t bitLength;
02097 
02098         //      bitStream->AlignWriteToByteBoundary(); // Potentially unaligned
02099         //      tempChar=(unsigned char)internalPacket->reliability; bitStream->WriteBits( (const unsigned char *)&tempChar, 3, true ); // 3 bits to write reliability.
02100         //      bool hasSplitPacket = internalPacket->splitPacketCount>0; bitStream->Write(hasSplitPacket); // Write 1 bit to indicate if splitPacketCount>0
02101         bitLength = 8*1;
02102 
02103         //      bitStream->AlignWriteToByteBoundary();
02104         //      RakAssert(internalPacket->dataBitLength < 65535);
02105         //      unsigned short s; s = (unsigned short) internalPacket->dataBitLength; bitStream->WriteAlignedVar16((const char*)& s);
02106         bitLength += 8*2;
02107 
02108         if ( internalPacket->reliability == RELIABLE ||
02109                 internalPacket->reliability == RELIABLE_SEQUENCED ||
02110                 internalPacket->reliability == RELIABLE_ORDERED ||
02111                 internalPacket->reliability == RELIABLE_WITH_ACK_RECEIPT ||
02112 //              internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
02113                 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
02114                 )
02115                 bitLength += 8*3; // bitStream->Write(internalPacket->reliableMessageNumber); // Message sequence number
02116         // bitStream->AlignWriteToByteBoundary(); // Potentially nothing else to write
02117         if ( internalPacket->reliability == UNRELIABLE_SEQUENCED ||
02118                 internalPacket->reliability == RELIABLE_SEQUENCED ||
02119                 internalPacket->reliability == RELIABLE_ORDERED ||
02120 //              internalPacket->reliability == UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
02121 //              internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
02122                 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
02123                 )
02124         {
02125                 bitLength += 8*3; // bitStream->Write(internalPacket->orderingIndex); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED.
02126                 bitLength += 8*1; // tempChar=internalPacket->orderingChannel; bitStream->WriteAlignedVar8((const char*)& tempChar); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED. 5 bits needed, write one byte
02127         }
02128         if (internalPacket->splitPacketCount>0)
02129         {
02130                 bitLength += 8*4; // bitStream->WriteAlignedVar32((const char*)& internalPacket->splitPacketCount); RakAssert(sizeof(SplitPacketIndexType)==4); // Only needed if splitPacketCount>0. 4 bytes
02131                 bitLength += 8*sizeof(SplitPacketIdType); // bitStream->WriteAlignedVar16((const char*)& internalPacket->splitPacketId); RakAssert(sizeof(SplitPacketIdType)==2); // Only needed if splitPacketCount>0.
02132                 bitLength += 8*4; // bitStream->WriteAlignedVar32((const char*)& internalPacket->splitPacketIndex); // Only needed if splitPacketCount>0. 4 bytes
02133         }
02134 
02135         return bitLength;
02136 }
02137 
02138 //-------------------------------------------------------------------------------------------------------
02139 // Parse an internalPacket and create a bitstream to represent this data
02140 //-------------------------------------------------------------------------------------------------------
02141 BitSize_t ReliabilityLayer::WriteToBitStreamFromInternalPacket( RakNet::BitStream *bitStream, const InternalPacket *const internalPacket, CCTimeType curTime )
02142 {
02143         (void) curTime;
02144 
02145         BitSize_t start = bitStream->GetNumberOfBitsUsed();
02146         unsigned char tempChar;
02147 
02148         // (Incoming data may be all zeros due to padding)
02149         bitStream->AlignWriteToByteBoundary(); // Potentially unaligned
02150         if (internalPacket->reliability==UNRELIABLE_WITH_ACK_RECEIPT)
02151                 tempChar=UNRELIABLE;
02152         else if (internalPacket->reliability==RELIABLE_WITH_ACK_RECEIPT)
02153                 tempChar=RELIABLE_WITH_ACK_RECEIPT;
02154         else if (internalPacket->reliability==RELIABLE_ORDERED_WITH_ACK_RECEIPT)
02155                 tempChar=RELIABLE_ORDERED;
02156         else
02157                 tempChar=(unsigned char)internalPacket->reliability; 
02158         bitStream->WriteBits( (const unsigned char *)&tempChar, 3, true ); // 3 bits to write reliability.
02159 
02160         bool hasSplitPacket = internalPacket->splitPacketCount>0; bitStream->Write(hasSplitPacket); // Write 1 bit to indicate if splitPacketCount>0
02161         bitStream->AlignWriteToByteBoundary();
02162         RakAssert(internalPacket->dataBitLength < 65535);
02163         unsigned short s; s = (unsigned short) internalPacket->dataBitLength; bitStream->WriteAlignedVar16((const char*)& s);
02164         if ( internalPacket->reliability == RELIABLE ||
02165                 internalPacket->reliability == RELIABLE_SEQUENCED ||
02166                 internalPacket->reliability == RELIABLE_ORDERED ||
02167                 internalPacket->reliability == RELIABLE_WITH_ACK_RECEIPT ||
02168 //              internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
02169                 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
02170                 )
02171                 bitStream->Write(internalPacket->reliableMessageNumber); // Message sequence number
02172         bitStream->AlignWriteToByteBoundary(); // Potentially nothing else to write
02173         if ( internalPacket->reliability == UNRELIABLE_SEQUENCED ||
02174                 internalPacket->reliability == RELIABLE_SEQUENCED ||
02175                 internalPacket->reliability == RELIABLE_ORDERED ||
02176         //      internalPacket->reliability == UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
02177         //      internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
02178                 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
02179                 )
02180         {
02181                 bitStream->Write(internalPacket->orderingIndex); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED.
02182                 tempChar=internalPacket->orderingChannel; bitStream->WriteAlignedVar8((const char*)& tempChar); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED. 5 bits needed, write one byte
02183         }
02184         if (internalPacket->splitPacketCount>0)
02185         {
02186                 bitStream->WriteAlignedVar32((const char*)& internalPacket->splitPacketCount); RakAssert(sizeof(SplitPacketIndexType)==4); // Only needed if splitPacketCount>0. 4 bytes
02187                 bitStream->WriteAlignedVar16((const char*)& internalPacket->splitPacketId); RakAssert(sizeof(SplitPacketIdType)==2); // Only needed if splitPacketCount>0.
02188                 bitStream->WriteAlignedVar32((const char*)& internalPacket->splitPacketIndex); // Only needed if splitPacketCount>0. 4 bytes
02189         }
02190 
02191         // Write the actual data.
02192         bitStream->WriteAlignedBytes( ( unsigned char* ) internalPacket->data, BITS_TO_BYTES( internalPacket->dataBitLength ) );
02193 
02194         return bitStream->GetNumberOfBitsUsed() - start;
02195 }
02196 
02197 //-------------------------------------------------------------------------------------------------------
02198 // Parse a bitstream and create an internal packet to represent this data
02199 //-------------------------------------------------------------------------------------------------------
02200 InternalPacket* ReliabilityLayer::CreateInternalPacketFromBitStream( RakNet::BitStream *bitStream, CCTimeType time )
02201 {
02202         bool bitStreamSucceeded;
02203         InternalPacket* internalPacket;
02204         unsigned char tempChar;
02205         bool hasSplitPacket;
02206         bool readSuccess;
02207 
02208         if ( bitStream->GetNumberOfUnreadBits() < (int) sizeof( internalPacket->reliableMessageNumber ) * 8 )
02209                 return 0; // leftover bits
02210 
02211         internalPacket = AllocateFromInternalPacketPool();
02212         if (internalPacket==0)
02213         {
02214                 // Out of memory
02215                 RakAssert(0);
02216                 return 0;
02217         }
02218         internalPacket->creationTime = time;
02219 
02220         // (Incoming data may be all zeros due to padding)
02221         bitStream->AlignReadToByteBoundary(); // Potentially unaligned
02222         bitStream->ReadBits( ( unsigned char* ) ( &( tempChar ) ), 3 );
02223         internalPacket->reliability = ( const PacketReliability ) tempChar;
02224         readSuccess=bitStream->Read(hasSplitPacket); // Read 1 bit to indicate if splitPacketCount>0
02225         bitStream->AlignReadToByteBoundary();
02226         unsigned short s; bitStream->ReadAlignedVar16((char*)&s); internalPacket->dataBitLength=s; // Length of message (2 bytes)
02227         if ( internalPacket->reliability == RELIABLE ||
02228                 internalPacket->reliability == RELIABLE_SEQUENCED ||
02229                 internalPacket->reliability == RELIABLE_ORDERED
02230                 // I don't write ACK_RECEIPT to the remote system
02231 //              ||
02232 //              internalPacket->reliability == RELIABLE_WITH_ACK_RECEIPT ||
02233 //              internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
02234 //              internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
02235                 )
02236                 bitStream->Read(internalPacket->reliableMessageNumber); // Message sequence number
02237         else
02238                 internalPacket->reliableMessageNumber=(MessageNumberType)(const uint32_t)-1;
02239         bitStream->AlignReadToByteBoundary(); // Potentially nothing else to Read
02240         if ( internalPacket->reliability == UNRELIABLE_SEQUENCED ||
02241                 internalPacket->reliability == RELIABLE_SEQUENCED ||
02242                 internalPacket->reliability == RELIABLE_ORDERED
02243                 // I don't write ACK_RECEIPT to the remote system
02244 //              ||
02245 //              internalPacket->reliability == UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
02246 //              internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
02247 //              internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
02248                 )
02249         {
02250                 bitStream->Read(internalPacket->orderingIndex); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED. 4 bytes.
02251                 readSuccess=bitStream->ReadAlignedVar8((char*)& internalPacket->orderingChannel); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED. 5 bits needed, Read one byte
02252         }
02253         else
02254                 internalPacket->orderingChannel=0;
02255         if (hasSplitPacket)
02256         {
02257                 bitStream->ReadAlignedVar32((char*)& internalPacket->splitPacketCount); // Only needed if splitPacketCount>0. 4 bytes
02258                 bitStream->ReadAlignedVar16((char*)& internalPacket->splitPacketId); // Only needed if splitPacketCount>0.
02259                 readSuccess=bitStream->ReadAlignedVar32((char*)& internalPacket->splitPacketIndex); // Only needed if splitPacketCount>0. 4 bytes
02260                 RakAssert(readSuccess);
02261         }
02262         else
02263         {
02264                 internalPacket->splitPacketCount=0;
02265         }
02266 
02267         if (readSuccess==false ||
02268                 internalPacket->dataBitLength==0 ||
02269                 internalPacket->reliability>=NUMBER_OF_RELIABILITIES ||
02270                 internalPacket->orderingChannel>=32 || 
02271                 (hasSplitPacket && (internalPacket->splitPacketIndex >= internalPacket->splitPacketCount)))
02272         {
02273                 // If this assert hits, encoding is garbage
02274                 RakAssert(internalPacket->dataBitLength==0);
02275                 ReleaseToInternalPacketPool( internalPacket );
02276                 return 0;
02277         }
02278 
02279         // Allocate memory to hold our data
02280         AllocInternalPacketData(internalPacket, BITS_TO_BYTES( internalPacket->dataBitLength ),  __FILE__, __LINE__ );
02281         RakAssert(BITS_TO_BYTES( internalPacket->dataBitLength )<MAXIMUM_MTU_SIZE);
02282 
02283         if (internalPacket->data == 0)
02284         {
02285                 RakAssert("Out of memory in ReliabilityLayer::CreateInternalPacketFromBitStream" && 0);
02286                 notifyOutOfMemory(__FILE__, __LINE__);
02287                 ReleaseToInternalPacketPool( internalPacket );
02288                 return 0;
02289         }
02290 
02291         // Set the last byte to 0 so if ReadBits does not read a multiple of 8 the last bits are 0'ed out
02292         internalPacket->data[ BITS_TO_BYTES( internalPacket->dataBitLength ) - 1 ] = 0;
02293 
02294         // Read the data the packet holds
02295         bitStreamSucceeded = bitStream->ReadAlignedBytes( ( unsigned char* ) internalPacket->data, BITS_TO_BYTES( internalPacket->dataBitLength ) );
02296 
02297         if ( bitStreamSucceeded == false )
02298         {
02299                 // If this hits, most likely the variable buff is too small in RunUpdateCycle in RakPeer.cpp
02300                 RakAssert("Couldn't read all the data"  && 0);
02301 
02302                 FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
02303                 ReleaseToInternalPacketPool( internalPacket );
02304                 return 0;
02305         }
02306 
02307         return internalPacket;
02308 }
02309 
02310 
02311 //-------------------------------------------------------------------------------------------------------
02312 // Get the SHA1 code
02313 //-------------------------------------------------------------------------------------------------------
02314 void ReliabilityLayer::GetSHA1( unsigned char * const buffer, unsigned int
02315                                                            nbytes, char code[ SHA1_LENGTH ] )
02316 {
02317         CSHA1 sha1;
02318 
02319         sha1.Reset();
02320         sha1.Update( ( unsigned char* ) buffer, nbytes );
02321         sha1.Final();
02322         memcpy( code, sha1.GetHash(), SHA1_LENGTH );
02323 }
02324 
02325 //-------------------------------------------------------------------------------------------------------
02326 // Check the SHA1 code
02327 //-------------------------------------------------------------------------------------------------------
02328 bool ReliabilityLayer::CheckSHA1( char code[ SHA1_LENGTH ], unsigned char *
02329                                                                  const buffer, unsigned int nbytes )
02330 {
02331         char code2[ SHA1_LENGTH ];
02332         GetSHA1( buffer, nbytes, code2 );
02333 
02334         for ( int i = 0; i < SHA1_LENGTH; i++ )
02335                 if ( code[ i ] != code2[ i ] )
02336                         return false;
02337 
02338         return true;
02339 }
02340 
02341 //-------------------------------------------------------------------------------------------------------
02342 // Search the specified list for sequenced packets on the specified ordering
02343 // stream, optionally skipping those with splitPacketId, and delete them
02344 //-------------------------------------------------------------------------------------------------------
02345 void ReliabilityLayer::DeleteSequencedPacketsInList( unsigned char orderingChannel, DataStructures::List<InternalPacket*>&theList, int splitPacketId )
02346 {
02347         unsigned i = 0;
02348 
02349         while ( i < theList.Size() )
02350         {
02351                 if ( ( 
02352                         theList[ i ]->reliability == RELIABLE_SEQUENCED ||
02353                         theList[ i ]->reliability == UNRELIABLE_SEQUENCED 
02354 //                      ||
02355 //                      theList[ i ]->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
02356 //                      theList[ i ]->reliability == UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
02357                         ) &&
02358                         theList[ i ]->orderingChannel == orderingChannel && ( splitPacketId == -1 || theList[ i ]->splitPacketId != (unsigned int) splitPacketId ) )
02359                 {
02360                         InternalPacket * internalPacket = theList[ i ];
02361                         theList.RemoveAtIndex( i );
02362                         FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
02363                         ReleaseToInternalPacketPool( internalPacket );
02364                 }
02365 
02366                 else
02367                         i++;
02368         }
02369 }
02370 
02371 //-------------------------------------------------------------------------------------------------------
02372 // Search the specified list for sequenced packets with a value less than orderingIndex and delete them
02373 // Note - I added functionality so you can use the Queue as a list (in this case for searching) but it is less efficient to do so than a regular list
02374 //-------------------------------------------------------------------------------------------------------
02375 void ReliabilityLayer::DeleteSequencedPacketsInList( unsigned char orderingChannel, DataStructures::Queue<InternalPacket*>&theList )
02376 {
02377         InternalPacket * internalPacket;
02378         int listSize = theList.Size();
02379         int i = 0;
02380 
02381         while ( i < listSize )
02382         {
02383                 if ( (
02384                         theList[ i ]->reliability == RELIABLE_SEQUENCED ||
02385                         theList[ i ]->reliability == UNRELIABLE_SEQUENCED
02386 //                      ||
02387 //                      theList[ i ]->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
02388 //                      theList[ i ]->reliability == UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
02389                         ) && theList[ i ]->orderingChannel == orderingChannel )
02390                 {
02391                         internalPacket = theList[ i ];
02392                         theList.RemoveAtIndex( i );
02393                         FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
02394                         ReleaseToInternalPacketPool( internalPacket );
02395                         listSize--;
02396                 }
02397 
02398                 else
02399                         i++;
02400         }
02401 }
02402 
02403 //-------------------------------------------------------------------------------------------------------
02404 // Returns true if newPacketOrderingIndex is older than the waitingForPacketOrderingIndex
02405 //-------------------------------------------------------------------------------------------------------
02406 bool ReliabilityLayer::IsOlderOrderedPacket( OrderingIndexType newPacketOrderingIndex, OrderingIndexType waitingForPacketOrderingIndex )
02407 {
02408         OrderingIndexType maxRange = (OrderingIndexType) (const uint32_t)-1;
02409 
02410         if ( waitingForPacketOrderingIndex > maxRange/(OrderingIndexType)2 )
02411         {
02412                 if ( newPacketOrderingIndex >= waitingForPacketOrderingIndex - maxRange/(OrderingIndexType)2+(OrderingIndexType)1 && newPacketOrderingIndex < waitingForPacketOrderingIndex )
02413                 {
02414                         return true;
02415                 }
02416         }
02417 
02418         else
02419                 if ( newPacketOrderingIndex >= ( OrderingIndexType ) ( waitingForPacketOrderingIndex - (( OrderingIndexType ) maxRange/(OrderingIndexType)2+(OrderingIndexType)1) ) ||
02420                         newPacketOrderingIndex < waitingForPacketOrderingIndex )
02421                 {
02422                         return true;
02423                 }
02424 
02425                 // Old packet
02426                 return false;
02427 }
02428 
02429 //-------------------------------------------------------------------------------------------------------
02430 // Split the passed packet into chunks under MTU_SIZEbytes (including headers) and save those new chunks
02431 // Optimized version
02432 //-------------------------------------------------------------------------------------------------------
02433 void ReliabilityLayer::SplitPacket( InternalPacket *internalPacket )
02434 {
02435         // Doing all sizes in bytes in this function so I don't write partial bytes with split packets
02436         internalPacket->splitPacketCount = 1; // This causes GetMessageHeaderLengthBits to account for the split packet header
02437         unsigned int headerLength = (unsigned int) BITS_TO_BYTES( GetMessageHeaderLengthBits( internalPacket ) );
02438         unsigned int dataByteLength = (unsigned int) BITS_TO_BYTES( internalPacket->dataBitLength );
02439         int maximumSendBlockBytes, byteOffset, bytesToSend;
02440         SplitPacketIndexType splitPacketIndex;
02441         int i;
02442         InternalPacket **internalPacketArray;
02443 
02444         maximumSendBlockBytes = GetMaxDatagramSizeExcludingMessageHeaderBytes() - BITS_TO_BYTES(GetMaxMessageHeaderLengthBits());
02445 
02446         // Calculate how many packets we need to create
02447         internalPacket->splitPacketCount = ( ( dataByteLength - 1 ) / ( maximumSendBlockBytes ) + 1 );
02448 
02449         // Optimization
02450         // internalPacketArray = RakNet::OP_NEW<InternalPacket*>(internalPacket->splitPacketCount, __FILE__, __LINE__ );
02451         bool usedAlloca=false;
02452 #if !defined(_XBOX) && !defined(_X360)
02453         if (sizeof( InternalPacket* ) * internalPacket->splitPacketCount < MAX_ALLOCA_STACK_ALLOCATION)
02454         {
02455                 internalPacketArray = ( InternalPacket** ) alloca( sizeof( InternalPacket* ) * internalPacket->splitPacketCount );
02456                 usedAlloca=true;
02457         }
02458         else
02459 #endif
02460                 internalPacketArray = (InternalPacket**) rakMalloc_Ex( sizeof(InternalPacket*) * internalPacket->splitPacketCount, __FILE__, __LINE__ );
02461 
02462         for ( i = 0; i < ( int ) internalPacket->splitPacketCount; i++ )
02463         {
02464                 internalPacketArray[ i ] = AllocateFromInternalPacketPool();
02465 
02466                 //internalPacketArray[ i ] = (InternalPacket*) alloca( sizeof( InternalPacket ) );
02467                 //              internalPacketArray[ i ] = sendPacketSet[internalPacket->priority].WriteLock();
02468                 *internalPacketArray[ i ]=*internalPacket;
02469                 internalPacketArray[ i ]->messageNumberAssigned=false;
02470 
02471                 if (i!=0)
02472                         internalPacket->messageInternalOrder = internalOrderIndex++;
02473         }
02474 
02475         // This identifies which packet this is in the set
02476         splitPacketIndex = 0;
02477 
02478         InternalPacketRefCountedData *refCounter=0;
02479 
02480         // Do a loop to send out all the packets
02481         do
02482         {
02483                 byteOffset = splitPacketIndex * maximumSendBlockBytes;
02484                 bytesToSend = dataByteLength - byteOffset;
02485 
02486                 if ( bytesToSend > maximumSendBlockBytes )
02487                         bytesToSend = maximumSendBlockBytes;
02488 
02489                 // Copy over our chunk of data
02490 
02491                 AllocInternalPacketData(internalPacketArray[ splitPacketIndex ], &refCounter, internalPacket->data, internalPacket->data + byteOffset);
02492                 //              internalPacketArray[ splitPacketIndex ]->data = (unsigned char*) rakMalloc_Ex( bytesToSend, __FILE__, __LINE__ );
02493                 //              memcpy( internalPacketArray[ splitPacketIndex ]->data, internalPacket->data + byteOffset, bytesToSend );
02494 
02495                 if ( bytesToSend != maximumSendBlockBytes )
02496                         internalPacketArray[ splitPacketIndex ]->dataBitLength = internalPacket->dataBitLength - splitPacketIndex * ( maximumSendBlockBytes << 3 );
02497                 else
02498                         internalPacketArray[ splitPacketIndex ]->dataBitLength = bytesToSend << 3;
02499 
02500                 internalPacketArray[ splitPacketIndex ]->splitPacketIndex = splitPacketIndex;
02501                 internalPacketArray[ splitPacketIndex ]->splitPacketId = splitPacketId;
02502                 internalPacketArray[ splitPacketIndex ]->splitPacketCount = internalPacket->splitPacketCount;
02503                 RakAssert(internalPacketArray[ splitPacketIndex ]->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
02504         } while ( ++splitPacketIndex < internalPacket->splitPacketCount );
02505 
02506         splitPacketId++; // It's ok if this wraps to 0
02507 
02508         //      InternalPacket *workingPacket;
02509 
02510         // Tell the heap we are going to push a list of elements where each element in the list follows the heap order
02511         RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
02512         outgoingPacketBuffer.StartSeries();
02513 
02514         // Copy all the new packets into the split packet list
02515         for ( i = 0; i < ( int ) internalPacket->splitPacketCount; i++ )
02516         {
02517                 internalPacketArray[ i ]->headerLength=headerLength;
02518                 RakAssert(internalPacketArray[ i ]->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
02519                 AddToUnreliableLinkedList(internalPacketArray[ i ]);
02520                 //              sendPacketSet[ internalPacket->priority ].Push( internalPacketArray[ i ], __FILE__, __LINE__  );
02521                 RakAssert(internalPacketArray[ i ]->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
02522                 RakAssert(internalPacketArray[ i ]->messageNumberAssigned==false);
02523                 outgoingPacketBuffer.PushSeries(GetNextWeight(internalPacketArray[ i ]->priority), internalPacketArray[ i ], __FILE__, __LINE__);
02524                 RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
02525                 statistics.messageInSendBuffer[(int)internalPacketArray[ i ]->priority]++;
02526                 statistics.bytesInSendBuffer[(int)(int)internalPacketArray[ i ]->priority]+=(double) BITS_TO_BYTES(internalPacketArray[ i ]->dataBitLength);
02527                 //              workingPacket=sendPacketSet[internalPacket->priority].WriteLock();
02528                 //              memcpy(workingPacket, internalPacketArray[ i ], sizeof(InternalPacket));
02529                 //              sendPacketSet[internalPacket->priority].WriteUnlock();
02530         }
02531 
02532         // Do not delete, original is referenced by all split packets to avoid numerous allocations. See AllocInternalPacketData above
02533         //      FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
02534         ReleaseToInternalPacketPool( internalPacket );
02535 
02536         if (usedAlloca==false)
02537                 rakFree_Ex(internalPacketArray, __FILE__, __LINE__ );
02538 }
02539 
02540 //-------------------------------------------------------------------------------------------------------
02541 // Insert a packet into the split packet list
02542 //-------------------------------------------------------------------------------------------------------
02543 void ReliabilityLayer::InsertIntoSplitPacketList( InternalPacket * internalPacket, CCTimeType time )
02544 {
02545         bool objectExists;
02546         unsigned index;
02547         index=splitPacketChannelList.GetIndexFromKey(internalPacket->splitPacketId, &objectExists);
02548         if (objectExists==false)
02549         {
02550                 SplitPacketChannel *newChannel = RakNet::OP_NEW<SplitPacketChannel>( __FILE__, __LINE__ );
02551                 //SplitPacketChannel *newChannel = RakNet::OP_NEW<SplitPacketChannel>(1, __FILE__, __LINE__ );
02552                 newChannel->firstPacket=0;
02553                 index=splitPacketChannelList.Insert(internalPacket->splitPacketId, newChannel, true, __FILE__,__LINE__);
02554                 // Preallocate to the final size, to avoid runtime copies
02555                 newChannel->splitPacketList.Preallocate(internalPacket->splitPacketCount, __FILE__,__LINE__);
02556         }
02557         splitPacketChannelList[index]->splitPacketList.Insert(internalPacket, __FILE__, __LINE__ );
02558         splitPacketChannelList[index]->lastUpdateTime=time;
02559 
02560         if (internalPacket->splitPacketIndex==0)
02561                 splitPacketChannelList[index]->firstPacket=internalPacket;
02562 
02563         if (splitMessageProgressInterval &&
02564                 splitPacketChannelList[index]->firstPacket &&
02565                 splitPacketChannelList[index]->splitPacketList.Size()!=splitPacketChannelList[index]->firstPacket->splitPacketCount &&
02566                 (splitPacketChannelList[index]->splitPacketList.Size()%splitMessageProgressInterval)==0)
02567         {
02568                 // Return ID_DOWNLOAD_PROGRESS
02569                 // Write splitPacketIndex (SplitPacketIndexType)
02570                 // Write splitPacketCount (SplitPacketIndexType)
02571                 // Write byteLength (4)
02572                 // Write data, splitPacketChannelList[index]->splitPacketList[0]->data
02573                 InternalPacket *progressIndicator = AllocateFromInternalPacketPool();
02574                 unsigned int length = sizeof(MessageID) + sizeof(unsigned int)*2 + sizeof(unsigned int) + (unsigned int) BITS_TO_BYTES(splitPacketChannelList[index]->firstPacket->dataBitLength);
02575                 AllocInternalPacketData(progressIndicator, length,  __FILE__, __LINE__ );
02576                 progressIndicator->dataBitLength=BYTES_TO_BITS(length);
02577                 progressIndicator->data[0]=(MessageID)ID_DOWNLOAD_PROGRESS;
02578                 progressIndicator->allocationScheme=InternalPacket::NORMAL;
02579                 unsigned int temp;
02580                 temp=splitPacketChannelList[index]->splitPacketList.Size();
02581                 memcpy(progressIndicator->data+sizeof(MessageID), &temp, sizeof(unsigned int));
02582                 temp=(unsigned int)internalPacket->splitPacketCount;
02583                 memcpy(progressIndicator->data+sizeof(MessageID)+sizeof(unsigned int)*1, &temp, sizeof(unsigned int));
02584                 temp=(unsigned int) BITS_TO_BYTES(splitPacketChannelList[index]->firstPacket->dataBitLength);
02585                 memcpy(progressIndicator->data+sizeof(MessageID)+sizeof(unsigned int)*2, &temp, sizeof(unsigned int));
02586 
02587                 memcpy(progressIndicator->data+sizeof(MessageID)+sizeof(unsigned int)*3, splitPacketChannelList[index]->firstPacket->data, (size_t) BITS_TO_BYTES(splitPacketChannelList[index]->firstPacket->dataBitLength));
02588                 outputQueue.Push(progressIndicator, __FILE__, __LINE__ );
02589         }
02590 }
02591 
02592 //-------------------------------------------------------------------------------------------------------
02593 // Take all split chunks with the specified splitPacketId and try to
02594 //reconstruct a packet.  If we can, allocate and return it.  Otherwise return 0
02595 // Optimized version
02596 //-------------------------------------------------------------------------------------------------------
02597 InternalPacket * ReliabilityLayer::BuildPacketFromSplitPacketList( SplitPacketChannel *splitPacketChannel, CCTimeType time )
02598 {
02599         unsigned int j;
02600         InternalPacket * internalPacket, *splitPacket;
02601         int splitPacketPartLength;
02602 
02603         // Reconstruct
02604         internalPacket = CreateInternalPacketCopy( splitPacketChannel->splitPacketList[0], 0, 0, time );
02605         internalPacket->dataBitLength=0;
02606         for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++)
02607                 internalPacket->dataBitLength+=splitPacketChannel->splitPacketList[j]->dataBitLength;
02608         splitPacketPartLength=BITS_TO_BYTES(splitPacketChannel->firstPacket->dataBitLength);
02609 
02610         internalPacket->data = (unsigned char*) rakMalloc_Ex( (size_t) BITS_TO_BYTES( internalPacket->dataBitLength ), __FILE__, __LINE__ );
02611 
02612         for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++)
02613         {
02614                 splitPacket=splitPacketChannel->splitPacketList[j];
02615                 memcpy(internalPacket->data+splitPacket->splitPacketIndex*splitPacketPartLength, splitPacket->data, (size_t) BITS_TO_BYTES(splitPacketChannel->splitPacketList[j]->dataBitLength));
02616         }
02617 
02618         for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++)
02619         {
02620                 FreeInternalPacketData(splitPacketChannel->splitPacketList[j], __FILE__, __LINE__ );
02621                 ReleaseToInternalPacketPool(splitPacketChannel->splitPacketList[j]);
02622         }
02623         RakNet::OP_DELETE(splitPacketChannel, __FILE__, __LINE__);
02624 
02625         return internalPacket;
02626 }
02627 //-------------------------------------------------------------------------------------------------------
02628 InternalPacket * ReliabilityLayer::BuildPacketFromSplitPacketList( SplitPacketIdType splitPacketId, CCTimeType time,
02629                                                                                                                                   SOCKET s, SystemAddress systemAddress, RakNetRandom *rnr, unsigned short remotePortRakNetWasStartedOn_PS3)
02630 {
02631         unsigned int i;
02632         bool objectExists;
02633         SplitPacketChannel *splitPacketChannel;
02634         InternalPacket * internalPacket;
02635 
02636         i=splitPacketChannelList.GetIndexFromKey(splitPacketId, &objectExists);
02637         splitPacketChannel=splitPacketChannelList[i];
02638         if (splitPacketChannel->splitPacketList.Size()==splitPacketChannel->splitPacketList[0]->splitPacketCount)
02639         {
02640                 // Ack immediately, because for large files this can take a long time
02641                 SendACKs(s, systemAddress, time, rnr, remotePortRakNetWasStartedOn_PS3);
02642                 internalPacket=BuildPacketFromSplitPacketList(splitPacketChannel,time);
02643                 splitPacketChannelList.RemoveAtIndex(i);
02644                 return internalPacket;
02645         }
02646         else
02647         {
02648                 return 0;
02649         }
02650 }
02651 /*
02652 //-------------------------------------------------------------------------------------------------------
02653 // Delete any unreliable split packets that have long since expired
02654 void ReliabilityLayer::DeleteOldUnreliableSplitPackets( CCTimeType time )
02655 {
02656 unsigned i,j;
02657 i=0;
02658 while (i < splitPacketChannelList.Size())
02659 {
02660 #if CC_TIME_TYPE_BYTES==4
02661 if (time > splitPacketChannelList[i]->lastUpdateTime + timeoutTime &&
02662 #else
02663 if (time > splitPacketChannelList[i]->lastUpdateTime + (CCTimeType)timeoutTime*(CCTimeType)1000 &&
02664 #endif
02665 (splitPacketChannelList[i]->splitPacketList[0]->reliability==UNRELIABLE || splitPacketChannelList[i]->splitPacketList[0]->reliability==UNRELIABLE_SEQUENCED))
02666 {
02667 for (j=0; j < splitPacketChannelList[i]->splitPacketList.Size(); j++)
02668 {
02669 RakNet::OP_DELETE_ARRAY(splitPacketChannelList[i]->splitPacketList[j]->data, __FILE__, __LINE__);
02670 ReleaseToInternalPacketPool(splitPacketChannelList[i]->splitPacketList[j]);
02671 }
02672 RakNet::OP_DELETE(splitPacketChannelList[i], __FILE__, __LINE__);
02673 splitPacketChannelList.RemoveAtIndex(i);
02674 }
02675 else
02676 i++;
02677 }
02678 }
02679 */
02680 
02681 //-------------------------------------------------------------------------------------------------------
02682 // Creates a copy of the specified internal packet with data copied from the original starting at dataByteOffset for dataByteLength bytes.
02683 // Does not copy any split data parameters as that information is always generated does not have any reason to be copied
02684 //-------------------------------------------------------------------------------------------------------
02685 InternalPacket * ReliabilityLayer::CreateInternalPacketCopy( InternalPacket *original, int dataByteOffset, int dataByteLength, CCTimeType time )
02686 {
02687         InternalPacket * copy = AllocateFromInternalPacketPool();
02688 #ifdef _DEBUG
02689         // Remove accessing undefined memory error
02690         memset( copy, 255, sizeof( InternalPacket ) );
02691 #endif
02692         // Copy over our chunk of data
02693 
02694         if ( dataByteLength > 0 )
02695         {
02696                 AllocInternalPacketData(copy, BITS_TO_BYTES(dataByteLength ),  __FILE__, __LINE__ );
02697                 memcpy( copy->data, original->data + dataByteOffset, dataByteLength );
02698         }
02699         else
02700                 copy->data = 0;
02701 
02702         copy->dataBitLength = dataByteLength << 3;
02703         copy->creationTime = time;
02704         copy->nextActionTime = 0;
02705         copy->orderingIndex = original->orderingIndex;
02706         copy->orderingChannel = original->orderingChannel;
02707         copy->reliableMessageNumber = original->reliableMessageNumber;
02708         copy->priority = original->priority;
02709         copy->reliability = original->reliability;
02710 
02711 
02712         return copy;
02713 }
02714 
02715 //-------------------------------------------------------------------------------------------------------
02716 // Get the specified ordering list
02717 //-------------------------------------------------------------------------------------------------------
02718 DataStructures::LinkedList<InternalPacket*> *ReliabilityLayer::GetOrderingListAtOrderingStream( unsigned char orderingChannel )
02719 {
02720         if ( orderingChannel >= orderingList.Size() )
02721                 return 0;
02722 
02723         return orderingList[ orderingChannel ];
02724 }
02725 
02726 //-------------------------------------------------------------------------------------------------------
02727 // Add the internal packet to the ordering list in order based on order index
02728 //-------------------------------------------------------------------------------------------------------
02729 void ReliabilityLayer::AddToOrderingList( InternalPacket * internalPacket )
02730 {
02731 #ifdef _DEBUG
02732         RakAssert( internalPacket->orderingChannel < NUMBER_OF_ORDERED_STREAMS );
02733 #endif
02734 
02735         if ( internalPacket->orderingChannel >= NUMBER_OF_ORDERED_STREAMS )
02736         {
02737                 return;
02738         }
02739 
02740         DataStructures::LinkedList<InternalPacket*> *theList;
02741 
02742         if ( internalPacket->orderingChannel >= orderingList.Size() || orderingList[ internalPacket->orderingChannel ] == 0 )
02743         {
02744                 // Need a linked list in this index
02745                 orderingList.Replace( RakNet::OP_NEW<DataStructures::LinkedList<InternalPacket*> >(__FILE__,__LINE__) , 0, internalPacket->orderingChannel, __FILE__,__LINE__ );
02746                 theList=orderingList[ internalPacket->orderingChannel ];
02747         }
02748         else
02749         {
02750                 // Have a linked list in this index
02751                 if ( orderingList[ internalPacket->orderingChannel ]->Size() == 0 )
02752                 {
02753                         theList=orderingList[ internalPacket->orderingChannel ];
02754                 }
02755                 else
02756                 {
02757                         theList = GetOrderingListAtOrderingStream( internalPacket->orderingChannel );
02758                 }
02759         }
02760 
02761         theList->End();
02762         theList->Add(internalPacket);
02763 }
02764 
02765 //-------------------------------------------------------------------------------------------------------
02766 // Inserts a packet into the resend list in order
02767 //-------------------------------------------------------------------------------------------------------
02768 void ReliabilityLayer::InsertPacketIntoResendList( InternalPacket *internalPacket, CCTimeType time, bool firstResend, bool modifyUnacknowledgedBytes )
02769 {
02770         (void) firstResend;
02771         (void) time;
02772         (void) internalPacket;
02773 
02774         AddToListTail(internalPacket, modifyUnacknowledgedBytes);
02775         RakAssert(internalPacket->nextActionTime!=0);
02776 
02777 }
02778 
02779 //-------------------------------------------------------------------------------------------------------
02780 // If Read returns -1 and this returns true then a modified packet was detected
02781 //-------------------------------------------------------------------------------------------------------
02782 bool ReliabilityLayer::IsCheater( void ) const
02783 {
02784         return cheater;
02785 }
02786 
02787 //-------------------------------------------------------------------------------------------------------
02788 //  Were you ever unable to deliver a packet despite retries?
02789 //-------------------------------------------------------------------------------------------------------
02790 bool ReliabilityLayer::IsDeadConnection( void ) const
02791 {
02792         return deadConnection;
02793 }
02794 
02795 //-------------------------------------------------------------------------------------------------------
02796 //  Causes IsDeadConnection to return true
02797 //-------------------------------------------------------------------------------------------------------
02798 void ReliabilityLayer::KillConnection( void )
02799 {
02800         deadConnection=true;
02801 }
02802 
02803 
02804 //-------------------------------------------------------------------------------------------------------
02805 // Statistics
02806 //-------------------------------------------------------------------------------------------------------
02807 RakNetStatistics * const ReliabilityLayer::GetStatistics( RakNetStatistics *rns )
02808 {
02809         unsigned i;
02810         RakNetTimeUS time = RakNet::GetTimeUS();
02811         uint64_t uint64Denominator;
02812         double doubleDenominator;
02813 
02814         for (i=0; i < RNS_PER_SECOND_METRICS_COUNT; i++)
02815         {
02816                 statistics.valueOverLastSecond[i]=bpsMetrics[i].GetBPS1Threadsafe(time);
02817                 statistics.runningTotal[i]=bpsMetrics[i].GetTotal1();
02818         }
02819 
02820         memcpy(rns, &statistics, sizeof(statistics));
02821 
02822         if (rns->valueOverLastSecond[USER_MESSAGE_BYTES_SENT]+rns->valueOverLastSecond[USER_MESSAGE_BYTES_RESENT]>0)
02823                 rns->packetlossLastSecond=(float)((double) rns->valueOverLastSecond[USER_MESSAGE_BYTES_RESENT]/((double) rns->valueOverLastSecond[USER_MESSAGE_BYTES_SENT]+(double) rns->valueOverLastSecond[USER_MESSAGE_BYTES_RESENT]));
02824         else
02825                 rns->packetlossLastSecond=0.0f;
02826 
02827         rns->packetlossTotal=0.0f;
02828         uint64Denominator=(rns->runningTotal[USER_MESSAGE_BYTES_SENT]+rns->runningTotal[USER_MESSAGE_BYTES_RESENT]);
02829         if (uint64Denominator!=0&&rns->runningTotal[USER_MESSAGE_BYTES_SENT]/uint64Denominator>0)
02830         {
02831                 doubleDenominator=((double) rns->runningTotal[USER_MESSAGE_BYTES_SENT]+(double) rns->runningTotal[USER_MESSAGE_BYTES_RESENT]);
02832                 if(doubleDenominator!=0)
02833                 {
02834                         rns->packetlossTotal=(float)((double) rns->runningTotal[USER_MESSAGE_BYTES_RESENT]/doubleDenominator);
02835                 }
02836         }
02837 
02838         return rns;
02839 }
02840 
02841 //-------------------------------------------------------------------------------------------------------
02842 // Returns the number of packets in the resend queue, not counting holes
02843 //-------------------------------------------------------------------------------------------------------
02844 unsigned int ReliabilityLayer::GetResendListDataSize(void) const
02845 {
02846         // Not accurate but thread-safe.  The commented version might crash if the queue is cleared while we loop through it
02847         // return resendTree.Size();
02848         return statistics.messagesInResendBuffer;
02849 }
02850 
02851 //-------------------------------------------------------------------------------------------------------
02852 // Process threaded commands
02853 //-------------------------------------------------------------------------------------------------------
02854 void ReliabilityLayer::UpdateThreadedMemory(void)
02855 {
02856         if ( freeThreadedMemoryOnNextUpdate )
02857         {
02858                 freeThreadedMemoryOnNextUpdate = false;
02859                 FreeThreadedMemory();
02860         }
02861 }
02862 //-------------------------------------------------------------------------------------------------------
02863 bool ReliabilityLayer::AckTimeout(RakNetTimeMS curTime)
02864 {
02865         return curTime-timeLastDatagramArrived>timeoutTime;
02866         // 
02867         // #if CC_TIME_TYPE_BYTES==4
02868         //      return curTime > timeResendQueueNonEmpty && timeResendQueueNonEmpty && curTime - timeResendQueueNonEmpty > timeoutTime;
02869         // #else
02870         //      return curTime > timeResendQueueNonEmpty/(RakNetTimeUS)1000 && timeResendQueueNonEmpty && curTime - timeResendQueueNonEmpty/(RakNetTimeUS)1000 > timeoutTime;
02871         // #endif
02872 }
02873 //-------------------------------------------------------------------------------------------------------
02874 CCTimeType ReliabilityLayer::GetNextSendTime(void) const
02875 {
02876         return nextSendTime;
02877 }
02878 //-------------------------------------------------------------------------------------------------------
02879 CCTimeType ReliabilityLayer::GetTimeBetweenPackets(void) const
02880 {
02881         return timeBetweenPackets;
02882 }
02883 //-------------------------------------------------------------------------------------------------------
02884 CCTimeType ReliabilityLayer::GetAckPing(void) const
02885 {
02886         return ackPing;
02887 }
02888 //-------------------------------------------------------------------------------------------------------
02889 void ReliabilityLayer::ResetPacketsAndDatagrams(void)
02890 {
02891         packetsToSendThisUpdate.Clear(true, __FILE__, __LINE__);
02892         packetsToDeallocThisUpdate.Clear(true, __FILE__, __LINE__);
02893         packetsToSendThisUpdateDatagramBoundaries.Clear(true, __FILE__, __LINE__);
02894         datagramsToSendThisUpdateIsPair.Clear(true, __FILE__, __LINE__);
02895         datagramSizesInBytes.Clear(true, __FILE__, __LINE__);
02896         datagramSizeSoFar=0;
02897 }
02898 //-------------------------------------------------------------------------------------------------------
02899 void ReliabilityLayer::PushPacket(CCTimeType time, InternalPacket *internalPacket, bool isReliable)
02900 {
02901         BitSize_t bitsForThisPacket=BYTES_TO_BITS(BITS_TO_BYTES(internalPacket->dataBitLength)+BITS_TO_BYTES(internalPacket->headerLength));
02902         datagramSizeSoFar+=bitsForThisPacket;
02903         RakAssert(BITS_TO_BYTES(datagramSizeSoFar)<MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
02904         allDatagramSizesSoFar+=bitsForThisPacket;
02905         packetsToSendThisUpdate.Push(internalPacket, __FILE__, __LINE__ );
02906         packetsToDeallocThisUpdate.Push(isReliable==false, __FILE__, __LINE__ );
02907         RakAssert(internalPacket->headerLength==GetMessageHeaderLengthBits(internalPacket));
02908 // This code tells me how much time elapses between when you send, and when the message actually goes out
02909 //      if (internalPacket->data[0]==0)
02910 //      {
02911 //              RakNetTime t;
02912 //              RakNet::BitStream bs(internalPacket->data+1,sizeof(t),false);
02913 //              bs.Read(t);
02914 //              RakNetTime curTime=RakNet::GetTime();
02915 //              RakNetTime diff = curTime-t;
02916 //      }
02917 
02918         congestionManager.OnSendBytes(time, BITS_TO_BYTES(internalPacket->dataBitLength)+BITS_TO_BYTES(internalPacket->headerLength));
02919 }
02920 //-------------------------------------------------------------------------------------------------------
02921 void ReliabilityLayer::PushDatagram(void)
02922 {
02923         if (datagramSizeSoFar>0)
02924         {
02925                 packetsToSendThisUpdateDatagramBoundaries.Push(packetsToSendThisUpdate.Size(), __FILE__, __LINE__ );
02926                 datagramsToSendThisUpdateIsPair.Push(false, __FILE__, __LINE__ );
02927                 RakAssert(BITS_TO_BYTES(datagramSizeSoFar)<MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
02928                 datagramSizesInBytes.Push(BITS_TO_BYTES(datagramSizeSoFar), __FILE__, __LINE__ );
02929                 datagramSizeSoFar=0;
02930 
02931                 // Disable packet pairs
02932                 /*
02933                 if (countdownToNextPacketPair==0)
02934                 {
02935                 if (TagMostRecentPushAsSecondOfPacketPair())
02936                 countdownToNextPacketPair=15;
02937                 }
02938                 else
02939                 countdownToNextPacketPair--;
02940                 */
02941         }
02942 }
02943 //-------------------------------------------------------------------------------------------------------
02944 bool ReliabilityLayer::TagMostRecentPushAsSecondOfPacketPair(void)
02945 {
02946         if (datagramsToSendThisUpdateIsPair.Size()>=2)
02947         {
02948                 datagramsToSendThisUpdateIsPair[datagramsToSendThisUpdateIsPair.Size()-2]=true;
02949                 datagramsToSendThisUpdateIsPair[datagramsToSendThisUpdateIsPair.Size()-1]=true;
02950                 return true;
02951         }
02952         return false;
02953 }
02954 //-------------------------------------------------------------------------------------------------------
02955 void ReliabilityLayer::ClearPacketsAndDatagrams(bool keepInternalPacketIfNeedsAck)
02956 {
02957         unsigned int i;
02958         for (i=0; i < packetsToDeallocThisUpdate.Size(); i++)
02959         {
02960                 // packetsToDeallocThisUpdate holds a boolean indicating if packetsToSendThisUpdate at this index should be freed
02961                 if (packetsToDeallocThisUpdate[i])
02962                 {
02963                         RemoveFromUnreliableLinkedList(packetsToSendThisUpdate[i]);
02964                         FreeInternalPacketData(packetsToSendThisUpdate[i], __FILE__, __LINE__ );
02965                         if (keepInternalPacketIfNeedsAck==false || packetsToSendThisUpdate[i]->reliability<UNRELIABLE_WITH_ACK_RECEIPT)
02966                                 ReleaseToInternalPacketPool( packetsToSendThisUpdate[i] );
02967                 }
02968         }
02969         packetsToDeallocThisUpdate.Clear(true, __FILE__, __LINE__);
02970 }
02971 //-------------------------------------------------------------------------------------------------------
02972 void ReliabilityLayer::MoveToListHead(InternalPacket *internalPacket)
02973 {
02974         if ( internalPacket == resendLinkedListHead )
02975                 return;
02976         if (resendLinkedListHead==0)
02977         {
02978                 internalPacket->resendNext=internalPacket;
02979                 internalPacket->resendPrev=internalPacket;
02980                 resendLinkedListHead=internalPacket;
02981                 return;
02982         }
02983         internalPacket->resendPrev->resendNext = internalPacket->resendNext;
02984         internalPacket->resendNext->resendPrev = internalPacket->resendPrev;
02985         internalPacket->resendNext=resendLinkedListHead;
02986         internalPacket->resendPrev=resendLinkedListHead->resendPrev;
02987         internalPacket->resendPrev->resendNext=internalPacket;
02988         resendLinkedListHead->resendPrev=internalPacket;
02989         resendLinkedListHead=internalPacket;
02990         RakAssert(internalPacket->headerLength+internalPacket->dataBitLength>0);
02991 
02992         ValidateResendList();
02993 }
02994 //-------------------------------------------------------------------------------------------------------
02995 void ReliabilityLayer::RemoveFromList(InternalPacket *internalPacket, bool modifyUnacknowledgedBytes)
02996 {
02997         InternalPacket *newPosition;
02998         internalPacket->resendPrev->resendNext = internalPacket->resendNext;
02999         internalPacket->resendNext->resendPrev = internalPacket->resendPrev;
03000         newPosition = internalPacket->resendNext;
03001         if ( internalPacket == resendLinkedListHead )
03002                 resendLinkedListHead = newPosition;
03003         if (resendLinkedListHead==internalPacket)
03004                 resendLinkedListHead=0;
03005 
03006         if (modifyUnacknowledgedBytes)
03007         {
03008                 RakAssert(unacknowledgedBytes>=BITS_TO_BYTES(internalPacket->headerLength+internalPacket->dataBitLength));
03009                 unacknowledgedBytes-=BITS_TO_BYTES(internalPacket->headerLength+internalPacket->dataBitLength);
03010                 // printf("-unacknowledgedBytes:%i ", unacknowledgedBytes);
03011 
03012 
03013                 ValidateResendList();
03014         }
03015 }
03016 //-------------------------------------------------------------------------------------------------------
03017 void ReliabilityLayer::AddToListTail(InternalPacket *internalPacket, bool modifyUnacknowledgedBytes)
03018 {
03019         if (modifyUnacknowledgedBytes)
03020         {
03021                 unacknowledgedBytes+=BITS_TO_BYTES(internalPacket->headerLength+internalPacket->dataBitLength);
03022                 // printf("+unacknowledgedBytes:%i ", unacknowledgedBytes);
03023         }
03024 
03025         if (resendLinkedListHead==0)
03026         {
03027                 internalPacket->resendNext=internalPacket;
03028                 internalPacket->resendPrev=internalPacket;
03029                 resendLinkedListHead=internalPacket;
03030                 return;
03031         }
03032         internalPacket->resendNext=resendLinkedListHead;
03033         internalPacket->resendPrev=resendLinkedListHead->resendPrev;
03034         internalPacket->resendPrev->resendNext=internalPacket;
03035         resendLinkedListHead->resendPrev=internalPacket;
03036 
03037         ValidateResendList();
03038 
03039 }
03040 //-------------------------------------------------------------------------------------------------------
03041 void ReliabilityLayer::PopListHead(bool modifyUnacknowledgedBytes)
03042 {
03043         RakAssert(resendLinkedListHead!=0);
03044         RemoveFromList(resendLinkedListHead, modifyUnacknowledgedBytes);
03045 }
03046 //-------------------------------------------------------------------------------------------------------
03047 bool ReliabilityLayer::IsResendQueueEmpty(void) const
03048 {
03049         return resendLinkedListHead==0;
03050 }
03051 //-------------------------------------------------------------------------------------------------------
03052 void ReliabilityLayer::SendACKs(SOCKET s, SystemAddress systemAddress, CCTimeType time, RakNetRandom *rnr, unsigned short remotePortRakNetWasStartedOn_PS3)
03053 {
03054         BitSize_t maxDatagramPayload = GetMaxDatagramSizeExcludingMessageHeaderBits();
03055 
03056         while (acknowlegements.Size()>0)
03057         {
03058                 // Send acks
03059                 updateBitStream.Reset();
03060                 DatagramHeaderFormat dhf;
03061                 dhf.isACK=true;
03062                 dhf.isNAK=false;
03063                 dhf.isPacketPair=false;
03064                 dhf.sourceSystemTime=time;
03065                 double B;
03066                 double AS;
03067                 bool hasBAndAS;
03068                 if (remoteSystemNeedsBAndAS)
03069                 {
03070                         congestionManager.OnSendAckGetBAndAS(time, &hasBAndAS,&B,&AS);
03071                         dhf.AS=(float)AS;
03072                         dhf.hasBAndAS=hasBAndAS;
03073                 }
03074                 else
03075                         dhf.hasBAndAS=false;            
03076                 dhf.sourceSystemTime=nextAckTimeToSend;
03077                 //              dhf.B=(float)B;
03078                 updateBitStream.Reset();
03079                 dhf.Serialize(&updateBitStream);
03080                 CC_DEBUG_PRINTF_1("AckSnd ");
03081                 acknowlegements.Serialize(&updateBitStream, maxDatagramPayload, true);
03082                 SendBitStream( s, systemAddress, &updateBitStream, rnr, remotePortRakNetWasStartedOn_PS3, time );
03083                 congestionManager.OnSendAck(time,updateBitStream.GetNumberOfBytesUsed());
03084 
03085                 // I think this is causing a bug where if the estimated bandwidth is very low for the recipient, only acks ever get sent
03086                 //      congestionManager.OnSendBytes(time,UDP_HEADER_SIZE+updateBitStream.GetNumberOfBytesUsed());
03087         }
03088 
03089 
03090 }
03091 /*
03092 //-------------------------------------------------------------------------------------------------------
03093 ReliabilityLayer::DatagramMessageIDList* ReliabilityLayer::AllocateFromDatagramMessageIDPool(void)
03094 {
03095 DatagramMessageIDList*s;
03096 s=datagramMessageIDPool.Allocate( __FILE__, __LINE__ );
03097 // Call new operator, memoryPool doesn't do this
03098 s = new ((void*)s) DatagramMessageIDList;
03099 return s;
03100 }
03101 //-------------------------------------------------------------------------------------------------------
03102 void ReliabilityLayer::ReleaseToDatagramMessageIDPool(DatagramMessageIDList* d)
03103 {
03104 d->~DatagramMessageIDList();
03105 datagramMessageIDPool.Release(d);
03106 }
03107 */
03108 //-------------------------------------------------------------------------------------------------------
03109 InternalPacket* ReliabilityLayer::AllocateFromInternalPacketPool(void)
03110 {
03111         InternalPacket *ip = internalPacketPool.Allocate( __FILE__, __LINE__ );
03112         ip->reliableMessageNumber = (MessageNumberType) (const uint32_t)-1;
03113         ip->messageNumberAssigned=false;
03114         ip->nextActionTime = 0;
03115         ip->splitPacketCount = 0;
03116         ip->allocationScheme=InternalPacket::NORMAL;
03117         ip->data=0;
03118         return ip;
03119 }
03120 //-------------------------------------------------------------------------------------------------------
03121 void ReliabilityLayer::ReleaseToInternalPacketPool(InternalPacket *ip)
03122 {
03123         internalPacketPool.Release(ip, __FILE__,__LINE__);
03124 }
03125 //-------------------------------------------------------------------------------------------------------
03126 void ReliabilityLayer::RemoveFromUnreliableLinkedList(InternalPacket *internalPacket)
03127 {
03128         if (internalPacket->reliability==UNRELIABLE ||
03129                 internalPacket->reliability==UNRELIABLE_SEQUENCED ||
03130                 internalPacket->reliability==UNRELIABLE_WITH_ACK_RECEIPT
03131 //              ||
03132 //              internalPacket->reliability==UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
03133                 )
03134         {
03135                 InternalPacket *newPosition;
03136                 internalPacket->unreliablePrev->unreliableNext = internalPacket->unreliableNext;
03137                 internalPacket->unreliableNext->unreliablePrev = internalPacket->unreliablePrev;
03138                 newPosition = internalPacket->unreliableNext;
03139                 if ( internalPacket == unreliableLinkedListHead )
03140                         unreliableLinkedListHead = newPosition;
03141                 if (unreliableLinkedListHead==internalPacket)
03142                         unreliableLinkedListHead=0;
03143         }
03144 }
03145 //-------------------------------------------------------------------------------------------------------
03146 void ReliabilityLayer::AddToUnreliableLinkedList(InternalPacket *internalPacket)
03147 {
03148         if (internalPacket->reliability==UNRELIABLE ||
03149                 internalPacket->reliability==UNRELIABLE_SEQUENCED ||
03150                 internalPacket->reliability==UNRELIABLE_WITH_ACK_RECEIPT
03151 //              ||
03152 //              internalPacket->reliability==UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
03153                 )
03154         {
03155                 if (unreliableLinkedListHead==0)
03156                 {
03157                         internalPacket->unreliableNext=internalPacket;
03158                         internalPacket->unreliablePrev=internalPacket;
03159                         unreliableLinkedListHead=internalPacket;
03160                         return;
03161                 }
03162                 internalPacket->unreliableNext=unreliableLinkedListHead;
03163                 internalPacket->unreliablePrev=unreliableLinkedListHead->unreliablePrev;
03164                 internalPacket->unreliablePrev->unreliableNext=internalPacket;
03165                 unreliableLinkedListHead->unreliablePrev=internalPacket;
03166         }
03167 }
03168 //-------------------------------------------------------------------------------------------------------
03169 void ReliabilityLayer::ValidateResendList(void) const
03170 {
03171         /*
03172         unsigned int count1=0, count2=0;
03173         for (unsigned int i=0; i < RESEND_BUFFER_ARRAY_LENGTH; i++)
03174         if (resendBuffer[i])
03175         count1++;
03176 
03177         if (resendLinkedListHead)
03178         {
03179         InternalPacket *internalPacket = resendLinkedListHead;
03180         do 
03181         {
03182         count2++;
03183         internalPacket=internalPacket->resendNext;
03184         } while (internalPacket!=resendLinkedListHead);
03185         }
03186         RakAssert(count1==count2);
03187         RakAssert(count2<=RESEND_BUFFER_ARRAY_LENGTH);
03188         */
03189 }
03190 //-------------------------------------------------------------------------------------------------------
03191 bool ReliabilityLayer::ResendBufferOverflow(void) const
03192 {
03193         int index1 = sendReliableMessageNumberIndex & (uint32_t) RESEND_BUFFER_ARRAY_MASK;
03194         //      int index2 = (sendReliableMessageNumberIndex+(uint32_t)1) & (uint32_t) RESEND_BUFFER_ARRAY_MASK;
03195         RakAssert(index1<RESEND_BUFFER_ARRAY_LENGTH);
03196         return resendBuffer[index1]!=0; // || resendBuffer[index2]!=0;
03197 
03198 }
03199 //-------------------------------------------------------------------------------------------------------
03200 ReliabilityLayer::MessageNumberNode* ReliabilityLayer::GetMessageNumberNodeByDatagramIndex(DatagramSequenceNumberType index)
03201 {
03202         if (datagramHistory.IsEmpty())
03203                 return 0;
03204 
03205         if (CCRakNetUDT::LessThan(index, datagramHistoryPopCount))
03206                 return 0;
03207 
03208         DatagramSequenceNumberType offsetIntoList = index - datagramHistoryPopCount;
03209         if (offsetIntoList >= datagramHistory.Size())
03210                 return 0;
03211         return datagramHistory[offsetIntoList].head;
03212 }
03213 //-------------------------------------------------------------------------------------------------------
03214 void ReliabilityLayer::RemoveFromDatagramHistory(DatagramSequenceNumberType index)
03215 {
03216         DatagramSequenceNumberType offsetIntoList = index - datagramHistoryPopCount;
03217         MessageNumberNode *mnm = datagramHistory[offsetIntoList].head;
03218         MessageNumberNode *next;
03219         while (mnm)
03220         {
03221                 next=mnm->next;
03222                 datagramHistoryMessagePool.Release(mnm, __FILE__,__LINE__);
03223                 mnm=next;
03224         }
03225         datagramHistory[offsetIntoList].head=0;
03226 }
03227 //-------------------------------------------------------------------------------------------------------
03228 void ReliabilityLayer::AddFirstToDatagramHistory(DatagramSequenceNumberType datagramNumber)
03229 {
03230         (void) datagramNumber;
03231         if (datagramHistory.Size()>DATAGRAM_MESSAGE_ID_ARRAY_LENGTH)
03232         {
03233                 RemoveFromDatagramHistory(datagramHistoryPopCount);
03234                 datagramHistory.Pop();
03235                 datagramHistoryPopCount++;
03236         }
03237 
03238         datagramHistory.Push(DatagramHistoryNode(0), __FILE__,__LINE__);
03239 }
03240 //-------------------------------------------------------------------------------------------------------
03241 ReliabilityLayer::MessageNumberNode* ReliabilityLayer::AddFirstToDatagramHistory(DatagramSequenceNumberType datagramNumber, DatagramSequenceNumberType messageNumber)
03242 {
03243         (void) datagramNumber;
03244 //      RakAssert(datagramHistoryPopCount+(unsigned int) datagramHistory.Size()==datagramNumber);
03245         if (datagramHistory.Size()>DATAGRAM_MESSAGE_ID_ARRAY_LENGTH)
03246         {
03247                 RemoveFromDatagramHistory(datagramHistoryPopCount);
03248                 datagramHistory.Pop();
03249                 datagramHistoryPopCount++;
03250         }
03251 
03252         MessageNumberNode *mnm = datagramHistoryMessagePool.Allocate(__FILE__,__LINE__);
03253         mnm->next=0;
03254         mnm->messageNumber=messageNumber;
03255         datagramHistory.Push(DatagramHistoryNode(mnm), __FILE__,__LINE__);
03256         return mnm;
03257 }
03258 //-------------------------------------------------------------------------------------------------------
03259 ReliabilityLayer::MessageNumberNode* ReliabilityLayer::AddSubsequentToDatagramHistory(MessageNumberNode *messageNumberNode, DatagramSequenceNumberType messageNumber)
03260 {
03261         messageNumberNode->next=datagramHistoryMessagePool.Allocate(__FILE__,__LINE__);
03262         messageNumberNode->next->messageNumber=messageNumber;
03263         messageNumberNode->next->next=0;
03264         return messageNumberNode->next;         
03265 }
03266 //-------------------------------------------------------------------------------------------------------
03267 void ReliabilityLayer::AllocInternalPacketData(InternalPacket *internalPacket, InternalPacketRefCountedData **refCounter, unsigned char *externallyAllocatedPtr, unsigned char *ourOffset)
03268 {
03269         internalPacket->allocationScheme=InternalPacket::REF_COUNTED;
03270         internalPacket->data=ourOffset;
03271         if (*refCounter==0)
03272         {
03273                 *refCounter = refCountedDataPool.Allocate(__FILE__,__LINE__);
03274                 // *refCounter = RakNet::OP_NEW<InternalPacketRefCountedData>(__FILE__,__LINE__);
03275                 (*refCounter)->refCount=1;
03276                 (*refCounter)->sharedDataBlock=externallyAllocatedPtr;
03277         }
03278         else
03279                 (*refCounter)->refCount++;
03280         internalPacket->refCountedData=(*refCounter);
03281 }
03282 //-------------------------------------------------------------------------------------------------------
03283 void ReliabilityLayer::AllocInternalPacketData(InternalPacket *internalPacket, unsigned char *externallyAllocatedPtr)
03284 {
03285         internalPacket->allocationScheme=InternalPacket::NORMAL;
03286         internalPacket->data=externallyAllocatedPtr;
03287 }
03288 //-------------------------------------------------------------------------------------------------------
03289 void ReliabilityLayer::AllocInternalPacketData(InternalPacket *internalPacket, unsigned int numBytes, const char *file, unsigned int line)
03290 {
03291         internalPacket->allocationScheme=InternalPacket::NORMAL;
03292         internalPacket->data=(unsigned char*) rakMalloc_Ex(numBytes,file,line);
03293 }
03294 //-------------------------------------------------------------------------------------------------------
03295 void ReliabilityLayer::FreeInternalPacketData(InternalPacket *internalPacket, const char *file, unsigned int line)
03296 {
03297         if (internalPacket==0)
03298                 return;
03299 
03300         if (internalPacket->allocationScheme==InternalPacket::REF_COUNTED)
03301         {
03302                 if (internalPacket->refCountedData==0)
03303                         return;
03304 
03305                 internalPacket->refCountedData->refCount--;
03306                 if (internalPacket->refCountedData->refCount==0)
03307                 {
03308                         rakFree_Ex(internalPacket->refCountedData->sharedDataBlock, file, line );
03309                         internalPacket->refCountedData->sharedDataBlock=0;
03310                         // RakNet::OP_DELETE(internalPacket->refCountedData,file, line);
03311                         refCountedDataPool.Release(internalPacket->refCountedData,file, line);
03312                         internalPacket->refCountedData=0;
03313                 }
03314         }
03315         else
03316         {
03317                 if (internalPacket->data==0)
03318                         return;
03319 
03320                 rakFree_Ex(internalPacket->data, file, line );
03321                 internalPacket->data=0;
03322         }
03323 }
03324 //-------------------------------------------------------------------------------------------------------
03325 unsigned int ReliabilityLayer::GetMaxDatagramSizeExcludingMessageHeaderBytes(void)
03326 {
03327         // When using encryption, the data may be padded by up to 15 bytes in order to be a multiple of 16.
03328         // I don't know how many exactly, it depends on the datagram header serialization
03329         if (encryptor.IsKeySet())
03330                 return congestionManager.GetMTU() - DatagramHeaderFormat::GetDataHeaderByteLength() - 15;
03331         else
03332                 return congestionManager.GetMTU() - DatagramHeaderFormat::GetDataHeaderByteLength();
03333 }
03334 //-------------------------------------------------------------------------------------------------------
03335 BitSize_t ReliabilityLayer::GetMaxDatagramSizeExcludingMessageHeaderBits(void)
03336 {
03337         return BYTES_TO_BITS(GetMaxDatagramSizeExcludingMessageHeaderBytes());
03338 }
03339 //-------------------------------------------------------------------------------------------------------
03340 void ReliabilityLayer::InitHeapWeights(void)
03341 {
03342         for (int priorityLevel=0; priorityLevel < NUMBER_OF_PRIORITIES; priorityLevel++)
03343         {
03344                 outgoingPacketBufferNextWeights[priorityLevel]=(1<<priorityLevel)*priorityLevel+priorityLevel;
03345         }
03346 }
03347 //-------------------------------------------------------------------------------------------------------
03348 reliabilityHeapWeightType ReliabilityLayer::GetNextWeight(int priorityLevel)
03349 {
03350         uint64_t next = outgoingPacketBufferNextWeights[priorityLevel];
03351         if (outgoingPacketBuffer.Size()>0)
03352         {
03353                 uint64_t min = outgoingPacketBuffer.PeekWeight()+(1<<priorityLevel)*priorityLevel+priorityLevel;
03354                 if (next<min)
03355                 {
03356                         next=min + (min%NUMBER_OF_PRIORITIES);
03357                 }
03358         }
03359         else
03360         {
03361                 InitHeapWeights();
03362         }
03363         outgoingPacketBufferNextWeights[priorityLevel]=next+(1<<priorityLevel)*(priorityLevel+1)+priorityLevel;
03364         return next;
03365 }
03366 
03367 //-------------------------------------------------------------------------------------------------------
03368 #if defined(RELIABILITY_LAYER_NEW_UNDEF_ALLOCATING_QUEUE)
03369 #pragma pop_macro("new")
03370 #undef RELIABILITY_LAYER_NEW_UNDEF_ALLOCATING_QUEUE
03371 #endif
03372 
03373 
03374 #ifdef _MSC_VER
03375 #pragma warning( pop )
03376 #endif

Generated on Thu Sep 30 2010 01:27:27 for RakNet by  doxygen 1.7.1