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

ReliabilityLayer.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 #ifndef __RELIABILITY_LAYER_H
00019 #define __RELIABILITY_LAYER_H
00020 
00021 #include "RakMemoryOverride.h"
00022 #include "MTUSize.h"
00023 #include "DS_LinkedList.h"
00024 #include "DS_List.h"
00025 #include "SocketLayer.h"
00026 #include "PacketPriority.h"
00027 #include "DS_Queue.h"
00028 #include "BitStream.h"
00029 #include "InternalPacket.h"
00030 #include "DataBlockEncryptor.h"
00031 #include "RakNetStatistics.h"
00032 #include "SHA1.h"
00033 #include "DS_OrderedList.h"
00034 #include "DS_RangeList.h"
00035 #include "DS_BPlusTree.h"
00036 #include "DS_MemoryPool.h"
00037 #include "CCRakNetUDT.h"
00038 #include "DS_Multilist.h"
00039 #include "RakNetDefines.h"
00040 #include "DS_Heap.h"
00041 
00042 class PluginInterface2;
00043 class RakNetRandom;
00044 typedef uint64_t reliabilityHeapWeightType;
00045 
00047 #define NUMBER_OF_ORDERED_STREAMS 32 // 2^5
00048 
00049 #define RESEND_TREE_ORDER 32
00050 
00051 #include "BitStream.h"
00052 
00053 // int SplitPacketIndexComp( SplitPacketIndexType const &key, InternalPacket* const &data );
00054 struct SplitPacketChannel//<SplitPacketChannel>
00055 {
00056         CCTimeType lastUpdateTime;
00057 
00058         // This is here for progress notifications, since progress notifications return the first packet data, if available
00059         InternalPacket *firstPacket;
00060 
00061         // DataStructures::OrderedList<SplitPacketIndexType, InternalPacket*, SplitPacketIndexComp> splitPacketList;
00062         DataStructures::List<InternalPacket*> splitPacketList;
00063 };
00064 int RAK_DLL_EXPORT SplitPacketChannelComp( SplitPacketIdType const &key, SplitPacketChannel* const &data );
00065 
00066 // Helper class
00067 struct BPSTracker
00068 {
00069         BPSTracker();
00070         ~BPSTracker();
00071         void Reset(const char *file, unsigned int line);
00072         void Push1(CCTimeType time, uint64_t value1);
00073 //      void Push2(RakNetTimeUS time, uint64_t value1, uint64_t value2);
00074         uint64_t GetBPS1(CCTimeType time);
00075         uint64_t GetBPS1Threadsafe(CCTimeType time);
00076 //      uint64_t GetBPS2(RakNetTimeUS time);
00077 //      void GetBPS1And2(RakNetTimeUS time, uint64_t &out1, uint64_t &out2);
00078         uint64_t GetTotal1(void) const;
00079 //      uint64_t GetTotal2(void) const;
00080 
00081         struct TimeAndValue2
00082         {
00083                 TimeAndValue2();
00084                 ~TimeAndValue2();
00085                 TimeAndValue2(CCTimeType t, uint64_t v1);
00086         //      TimeAndValue2(RakNetTimeUS t, uint64_t v1, uint64_t v2);
00087         //      uint64_t value1, value2;
00088                 uint64_t value1;
00089                 CCTimeType time;
00090         };
00091 
00092         uint64_t total1, lastSec1;
00093 //      uint64_t total2, lastSec2;
00094         DataStructures::Queue<TimeAndValue2> dataQueue;
00095         void ClearExpired1(CCTimeType time);
00096 //      void ClearExpired2(RakNetTimeUS time);
00097 };
00098 
00100 class ReliabilityLayer//<ReliabilityLayer>
00101 {
00102 public:
00103 
00104         // Constructor
00105         ReliabilityLayer();
00106 
00107         // Destructor
00108         ~ReliabilityLayer();
00109 
00111         void Reset( bool resetVariables, int MTUSize );
00112 
00115         void SetEncryptionKey( const unsigned char *key );
00116 
00120         void SetTimeoutTime( RakNetTimeMS time );
00121 
00124         RakNetTimeMS GetTimeoutTime(void);
00125 
00135         bool HandleSocketReceiveFromConnectedPlayer(
00136                 const char *buffer, unsigned int length, SystemAddress systemAddress, DataStructures::List<PluginInterface2*> &messageHandlerList, int MTUSize,
00137                 SOCKET s, RakNetRandom *rnr, unsigned short remotePortRakNetWasStartedOn_PS3, CCTimeType timeRead);
00138 
00142         BitSize_t Receive( unsigned char**data );
00143 
00155         bool Send( char *data, BitSize_t numberOfBitsToSend, PacketPriority priority, PacketReliability reliability, unsigned char orderingChannel, bool makeDataCopy, int MTUSize, CCTimeType currentTime, uint32_t receipt );
00156 
00164         void Update( SOCKET s, SystemAddress systemAddress, int MTUSize, CCTimeType time,
00165                 unsigned bitsPerSecondLimit,
00166                 DataStructures::List<PluginInterface2*> &messageHandlerList,
00167                 RakNetRandom *rnr, unsigned short remotePortRakNetWasStartedOn_PS3);
00168         
00169 
00172         bool IsCheater( void ) const;
00173 
00176         bool IsDeadConnection( void ) const;
00177 
00179         void KillConnection(void);
00180 
00183         RakNetStatistics * const GetStatistics( RakNetStatistics *rns );
00184 
00186         bool IsOutgoingDataWaiting(void);
00187         bool AreAcksWaiting(void);
00188 
00189         // Set outgoing lag and packet loss properties
00190         void ApplyNetworkSimulator( double _maxSendBPS, RakNetTime _minExtraPing, RakNetTime _extraPingVariance );
00191 
00194         bool IsNetworkSimulatorActive( void );
00195 
00196         void SetSplitMessageProgressInterval(int interval);
00197         void SetUnreliableTimeout(RakNetTimeMS timeoutMS);
00199         bool AckTimeout(RakNetTimeMS curTime);
00200         CCTimeType GetNextSendTime(void) const;
00201         CCTimeType GetTimeBetweenPackets(void) const;
00202         CCTimeType GetAckPing(void) const;
00203         RakNetTimeMS GetTimeLastDatagramArrived(void) const {return timeLastDatagramArrived;}
00204 
00205         // If true, will update time between packets quickly based on ping calculations
00206         //void SetDoFastThroughputReactions(bool fast);
00207 
00208         // Encoded as numMessages[unsigned int], message1BitLength[unsigned int], message1Data (aligned), ...
00209         //void GetUndeliveredMessages(RakNet::BitStream *messages, int MTUSize);
00210 
00211 private:
00216         void SendBitStream( SOCKET s, SystemAddress systemAddress, RakNet::BitStream *bitStream, RakNetRandom *rnr, unsigned short remotePortRakNetWasStartedOn_PS3, CCTimeType currentTime);
00217 
00220         BitSize_t WriteToBitStreamFromInternalPacket( RakNet::BitStream *bitStream, const InternalPacket *const internalPacket, CCTimeType curTime );
00221 
00222 
00224         InternalPacket* CreateInternalPacketFromBitStream( RakNet::BitStream *bitStream, CCTimeType time );
00225 
00227         unsigned RemovePacketFromResendListAndDeleteOlderReliableSequenced( const MessageNumberType messageNumber, CCTimeType time, DataStructures::List<PluginInterface2*> &messageHandlerList, SystemAddress systemAddress );
00228 
00230         void SendAcknowledgementPacket( const DatagramSequenceNumberType messageNumber, CCTimeType time);
00231 
00233         bool IsSendThrottled( int MTUSize );
00234 
00236         void UpdateWindowFromPacketloss( CCTimeType time );
00237 
00239         void UpdateWindowFromAck( CCTimeType time );
00240 
00242         BitSize_t GetMaxMessageHeaderLengthBits( void );
00243         BitSize_t GetMessageHeaderLengthBits( const InternalPacket *const internalPacket );
00244 
00246         void GetSHA1( unsigned char * const buffer, unsigned int nbytes, char code[ SHA1_LENGTH ] );
00247 
00249         bool CheckSHA1( char code[ SHA1_LENGTH ], unsigned char * const buffer, unsigned int nbytes );
00250 
00252         void DeleteSequencedPacketsInList( unsigned char orderingChannel, DataStructures::List<InternalPacket*>&theList, int splitPacketId = -1 );
00253 
00255         void DeleteSequencedPacketsInList( unsigned char orderingChannel, DataStructures::Queue<InternalPacket*>&theList );
00256 
00258         bool IsOlderOrderedPacket( OrderingIndexType newPacketOrderingIndex, OrderingIndexType waitingForPacketOrderingIndex );
00259 
00261         void SplitPacket( InternalPacket *internalPacket );
00262 
00264         void InsertIntoSplitPacketList( InternalPacket * internalPacket, CCTimeType time );
00265 
00267         InternalPacket * BuildPacketFromSplitPacketList( SplitPacketIdType splitPacketId, CCTimeType time,
00268                 SOCKET s, SystemAddress systemAddress, RakNetRandom *rnr, unsigned short remotePortRakNetWasStartedOn_PS3);
00269         InternalPacket * BuildPacketFromSplitPacketList( SplitPacketChannel *splitPacketChannel, CCTimeType time );
00270 
00272         //void DeleteOldUnreliableSplitPackets( CCTimeType time );
00273 
00276         InternalPacket * CreateInternalPacketCopy( InternalPacket *original, int dataByteOffset, int dataByteLength, CCTimeType time );
00277 
00279         DataStructures::LinkedList<InternalPacket*> *GetOrderingListAtOrderingStream( unsigned char orderingChannel );
00280 
00282         void AddToOrderingList( InternalPacket * internalPacket );
00283 
00285         void InsertPacketIntoResendList( InternalPacket *internalPacket, CCTimeType time, bool firstResend, bool modifyUnacknowledgedBytes );
00286 
00288         void FreeMemory( bool freeAllImmediately );
00289 
00291         void FreeThreadedMemory( void );
00292 
00294         void FreeThreadSafeMemory( void );
00295 
00296         // Initialize the variables
00297         void InitializeVariables( int MTUSize );
00298 
00300         bool IsExpiredTime(unsigned int input, CCTimeType currentTime) const;
00301 
00302         // Make it so we don't do resends within a minimum threshold of time
00303         void UpdateNextActionTime(void);
00304 
00305 
00307         //unsigned int IsReceivedPacketHole(unsigned int input, RakNetTime currentTime) const;
00308 
00310         //unsigned int MakeReceivedPacketHole(unsigned int input) const;
00311 
00313         unsigned int GetResendListDataSize(void) const;
00314 
00316         void UpdateThreadedMemory(void);
00317 
00318         void CalculateHistogramAckSize(void);
00319 
00320         // Used ONLY for RELIABLE_ORDERED
00321         // RELIABLE_SEQUENCED just returns the newest one
00322         DataStructures::List<DataStructures::LinkedList<InternalPacket*>*> orderingList;
00323         DataStructures::Queue<InternalPacket*> outputQueue;
00324         int splitMessageProgressInterval;
00325         CCTimeType unreliableTimeout;
00326 
00327         struct MessageNumberNode
00328         {
00329                 DatagramSequenceNumberType messageNumber;
00330                 MessageNumberNode *next;
00331         };
00332         struct DatagramHistoryNode
00333         {
00334                 DatagramHistoryNode() {}
00335                 DatagramHistoryNode(MessageNumberNode *_head) :
00336                 head(_head) {}
00337                 MessageNumberNode *head;
00338         };
00339         // Queue length is programmatically restricted to DATAGRAM_MESSAGE_ID_ARRAY_LENGTH
00340         // This is essentially an O(1) lookup to get a DatagramHistoryNode given an index
00341         DataStructures::Queue<DatagramHistoryNode> datagramHistory;
00342         DataStructures::MemoryPool<MessageNumberNode> datagramHistoryMessagePool;
00343 
00344 
00345         void RemoveFromDatagramHistory(DatagramSequenceNumberType index);
00346         MessageNumberNode* GetMessageNumberNodeByDatagramIndex(DatagramSequenceNumberType index);
00347         void AddFirstToDatagramHistory(DatagramSequenceNumberType datagramNumber);
00348         MessageNumberNode* AddFirstToDatagramHistory(DatagramSequenceNumberType datagramNumber, DatagramSequenceNumberType messageNumber);
00349         MessageNumberNode* AddSubsequentToDatagramHistory(MessageNumberNode *messageNumberNode, DatagramSequenceNumberType messageNumber);
00350         DatagramSequenceNumberType datagramHistoryPopCount;
00351         
00352         DataStructures::MemoryPool<InternalPacket> internalPacketPool;
00353         // DataStructures::BPlusTree<DatagramSequenceNumberType, InternalPacket*, RESEND_TREE_ORDER> resendTree;
00354         InternalPacket *resendBuffer[RESEND_BUFFER_ARRAY_LENGTH];
00355         InternalPacket *resendLinkedListHead;
00356         InternalPacket *unreliableLinkedListHead;
00357         void RemoveFromUnreliableLinkedList(InternalPacket *internalPacket);
00358         void AddToUnreliableLinkedList(InternalPacket *internalPacket);
00359 //      unsigned int numPacketsOnResendBuffer;
00360         //unsigned int blockWindowIncreaseUntilTime;
00361         //      DataStructures::RangeList<DatagramSequenceNumberType> acknowlegements;
00362         // Resend list is a tree of packets we need to resend
00363 
00364         // Set to the current time when the resend queue is no longer empty
00365         // Set to zero when it becomes empty
00366         // Set to the current time if it is not zero, and we get incoming data
00367         // If the current time - timeResendQueueNonEmpty is greater than a threshold, we are disconnected
00368 //      CCTimeType timeResendQueueNonEmpty;
00369         RakNetTimeMS timeLastDatagramArrived;
00370 
00371 
00372         // If we backoff due to packetloss, don't remeasure until all waiting resends have gone out or else we overcount
00373 //      bool packetlossThisSample;
00374 //      int backoffThisSample;
00375 //      unsigned packetlossThisSampleResendCount;
00376 //      CCTimeType lastPacketlossTime;
00377 
00378         //DataStructures::Queue<InternalPacket*> sendPacketSet[ NUMBER_OF_PRIORITIES ];
00379         DataStructures::Heap<reliabilityHeapWeightType, InternalPacket*, false> outgoingPacketBuffer;
00380         reliabilityHeapWeightType outgoingPacketBufferNextWeights[NUMBER_OF_PRIORITIES];
00381         void InitHeapWeights(void);
00382         reliabilityHeapWeightType GetNextWeight(int priorityLevel);
00383 //      unsigned int messageInSendBuffer[NUMBER_OF_PRIORITIES];
00384 //      double bytesInSendBuffer[NUMBER_OF_PRIORITIES];
00385 
00386 
00387     DataStructures::OrderedList<SplitPacketIdType, SplitPacketChannel*, SplitPacketChannelComp> splitPacketChannelList;
00388 
00389         MessageNumberType sendReliableMessageNumberIndex;
00390         MessageNumberType internalOrderIndex;
00391         //unsigned int windowSize;
00392         RakNet::BitStream updateBitStream;
00393         OrderingIndexType waitingForOrderedPacketWriteIndex[ NUMBER_OF_ORDERED_STREAMS ], waitingForSequencedPacketWriteIndex[ NUMBER_OF_ORDERED_STREAMS ];
00394         
00395         // STUFF TO NOT MUTEX HERE (called from non-conflicting threads, or value is not important)
00396         OrderingIndexType waitingForOrderedPacketReadIndex[ NUMBER_OF_ORDERED_STREAMS ], waitingForSequencedPacketReadIndex[ NUMBER_OF_ORDERED_STREAMS ];
00397         bool deadConnection, cheater;
00398         // unsigned int lastPacketSendTime,retransmittedFrames, sentPackets, sentFrames, receivedPacketsCount, bytesSent, bytesReceived,lastPacketReceivedTime;
00399         SplitPacketIdType splitPacketId;
00400         RakNetTimeMS timeoutTime; // How long to wait in MS before timing someone out
00401         //int MAX_AVERAGE_PACKETS_PER_SECOND; // Name says it all
00402 //      int RECEIVED_PACKET_LOG_LENGTH, requestedReceivedPacketLogLength; // How big the receivedPackets array is
00403 //      unsigned int *receivedPackets;
00404         RakNetStatistics statistics;
00405 
00406 //      CCTimeType histogramStart;
00407 //      unsigned histogramBitsSent;
00408 
00409 
00418         // DataStructures::Queue<CCTimeType> hasReceivedPacketQueue;
00419         DataStructures::Queue<bool> hasReceivedPacketQueue;
00420         DatagramSequenceNumberType receivedPacketsBaseIndex;
00421         bool resetReceivedPackets;
00422 
00423         CCTimeType lastUpdateTime;
00424         CCTimeType timeBetweenPackets, nextSendTime, ackPing;
00425 //      CCTimeType ackPingSamples[ACK_PING_SAMPLES_SIZE]; // Must be range of unsigned char to wrap ackPingIndex properly
00426         CCTimeType ackPingSum;
00427         unsigned char ackPingIndex;
00428         //CCTimeType nextLowestPingReset;
00429         RemoteSystemTimeType remoteSystemTime;
00430 //      bool continuousSend;
00431 //      CCTimeType lastTimeBetweenPacketsIncrease,lastTimeBetweenPacketsDecrease;
00432         // Limit changes in throughput to once per ping - otherwise even if lag starts we don't know about it
00433         // In the meantime the connection is flooded and overrun.
00434         CCTimeType nextAllowedThroughputSample;
00435         bool bandwidthExceededStatistic;
00436 
00437         // If Update::maxBitsPerSecond > 0, then throughputCapCountdown is used as a timer to prevent sends for some amount of time after each send, depending on
00438         // the amount of data sent
00439         long long throughputCapCountdown;
00440 
00441         DataBlockEncryptor encryptor;
00442         unsigned receivePacketCount;
00443 
00445         bool freeThreadedMemoryOnNextUpdate;
00446 
00447         //long double timeBetweenPacketsIncreaseMultiplier, timeBetweenPacketsDecreaseMultiplier;
00448 
00449 #ifdef _DEBUG
00450         struct DataAndTime//<InternalPacket>
00451         {
00452                 SOCKET s;
00453                 char data[ MAXIMUM_MTU_SIZE ];
00454                 unsigned int length;
00455                 RakNetTimeMS sendTime;
00456         //      SystemAddress systemAddress;
00457                 unsigned short remotePortRakNetWasStartedOn_PS3;
00458         };
00459         DataStructures::Queue<DataAndTime*> delayList;
00460 
00461         // Internet simulator
00462         double packetloss;
00463         RakNetTimeMS minExtraPing, extraPingVariance;
00464 #endif
00465 
00466         CCTimeType elapsedTimeSinceLastUpdate;
00467 
00468         CCTimeType nextAckTimeToSend;
00469 
00470         RakNet::CCRakNetUDT congestionManager;
00471         uint32_t unacknowledgedBytes;
00472         
00473         bool ResendBufferOverflow(void) const;
00474         void ValidateResendList(void) const;
00475         void ResetPacketsAndDatagrams(void);
00476         void PushPacket(CCTimeType time, InternalPacket *internalPacket, bool isReliable);
00477         void PushDatagram(void);
00478         bool TagMostRecentPushAsSecondOfPacketPair(void);
00479         void ClearPacketsAndDatagrams(bool releaseToInternalPacketPoolIfNeedsAck);
00480         void MoveToListHead(InternalPacket *internalPacket);
00481         void RemoveFromList(InternalPacket *internalPacket, bool modifyUnacknowledgedBytes);
00482         void AddToListTail(InternalPacket *internalPacket, bool modifyUnacknowledgedBytes);
00483         void PopListHead(bool modifyUnacknowledgedBytes);
00484         bool IsResendQueueEmpty(void) const;
00485         void SortSplitPacketList(DataStructures::List<InternalPacket*> &data, unsigned int leftEdge, unsigned int rightEdge) const;
00486         void SendACKs(SOCKET s, SystemAddress systemAddress, CCTimeType time, RakNetRandom *rnr, unsigned short remotePortRakNetWasStartedOn_PS3);
00487 
00488         DataStructures::List<InternalPacket*> packetsToSendThisUpdate;
00489         DataStructures::List<bool> packetsToDeallocThisUpdate;
00490         // boundary is in packetsToSendThisUpdate, inclusive
00491         DataStructures::List<unsigned int> packetsToSendThisUpdateDatagramBoundaries;
00492         DataStructures::List<bool> datagramsToSendThisUpdateIsPair;
00493         DataStructures::List<unsigned int> datagramSizesInBytes;
00494         BitSize_t datagramSizeSoFar;
00495         BitSize_t allDatagramSizesSoFar;
00496         double totalUserDataBytesAcked;
00497         CCTimeType timeOfLastContinualSend;
00498         CCTimeType timeToNextUnreliableCull;
00499 
00500         // This doesn't need to be a member, but I do it to avoid reallocations
00501         DataStructures::RangeList<DatagramSequenceNumberType> incomingAcks;
00502 
00503         // Every 16 datagrams, we make sure the 17th datagram goes out the same update tick, and is the same size as the 16th
00504         int countdownToNextPacketPair;
00505         InternalPacket* AllocateFromInternalPacketPool(void);
00506         void ReleaseToInternalPacketPool(InternalPacket *ip);
00507 
00508         DataStructures::RangeList<DatagramSequenceNumberType> acknowlegements;
00509         DataStructures::RangeList<DatagramSequenceNumberType> NAKs;
00510         bool remoteSystemNeedsBAndAS;
00511 
00512         unsigned int GetMaxDatagramSizeExcludingMessageHeaderBytes(void);
00513         BitSize_t GetMaxDatagramSizeExcludingMessageHeaderBits(void);
00514 
00515         // ourOffset refers to a section within externallyAllocatedPtr. Do not deallocate externallyAllocatedPtr until all references are lost
00516         void AllocInternalPacketData(InternalPacket *internalPacket, InternalPacketRefCountedData **refCounter, unsigned char *externallyAllocatedPtr, unsigned char *ourOffset);
00517         // Set the data pointer to externallyAllocatedPtr, do not allocate
00518         void AllocInternalPacketData(InternalPacket *internalPacket, unsigned char *externallyAllocatedPtr);
00519         // Allocate new
00520         void AllocInternalPacketData(InternalPacket *internalPacket, unsigned int numBytes, const char *file, unsigned int line);
00521         void FreeInternalPacketData(InternalPacket *internalPacket, const char *file, unsigned int line);
00522         DataStructures::MemoryPool<InternalPacketRefCountedData> refCountedDataPool;
00523 
00524         BPSTracker bpsMetrics[RNS_PER_SECOND_METRICS_COUNT];
00525 };
00526 
00527 #endif

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