Shadowrun: Awakened 29 September 2011 - Build 871
CCRakNetUDT.h
Go to the documentation of this file.
00001 #include "RakNetDefines.h"
00002 
00003 #if USE_SLIDING_WINDOW_CONGESTION_CONTROL!=1
00004 
00005 #ifndef __CONGESTION_CONTROL_UDT_H
00006 #define __CONGESTION_CONTROL_UDT_H
00007 
00008 #include "NativeTypes.h"
00009 #include "RakNetTime.h"
00010 #include "RakNetTypes.h"
00011 #include "DS_Queue.h"
00012 
00014 #define CC_TIME_TYPE_BYTES 8
00015 
00016 namespace RakNet
00017 {
00018 
00019 
00020 typedef uint64_t CCTimeType;
00021 
00022 
00023 
00024 
00025 typedef uint24_t DatagramSequenceNumberType;
00026 typedef double BytesPerMicrosecond;
00027 typedef double BytesPerSecond;
00028 typedef double MicrosecondsPerByte;
00029 
00031 #define CC_RAKNET_UDT_PACKET_HISTORY_LENGTH 64
00032 #define RTT_HISTORY_LENGTH 64
00033 
00035 #define UDP_HEADER_SIZE 28
00036 
00037 #define CC_DEBUG_PRINTF_1(x)
00038 #define CC_DEBUG_PRINTF_2(x,y)
00039 #define CC_DEBUG_PRINTF_3(x,y,z)
00040 #define CC_DEBUG_PRINTF_4(x,y,z,a)
00041 #define CC_DEBUG_PRINTF_5(x,y,z,a,b)
00042 //#define CC_DEBUG_PRINTF_1(x) printf(x)
00043 //#define CC_DEBUG_PRINTF_2(x,y) printf(x,y)
00044 //#define CC_DEBUG_PRINTF_3(x,y,z) printf(x,y,z)
00045 //#define CC_DEBUG_PRINTF_4(x,y,z,a) printf(x,y,z,a)
00046 //#define CC_DEBUG_PRINTF_5(x,y,z,a,b) printf(x,y,z,a,b)
00047 
00076 class CCRakNetUDT
00077 {
00078     public:
00079     
00080     CCRakNetUDT();
00081     ~CCRakNetUDT();
00082 
00084     void Init(CCTimeType curTime, uint32_t maxDatagramPayload);
00085 
00087     void Update(CCTimeType curTime, bool hasDataToSendOrResend);
00088 
00089     int GetRetransmissionBandwidth(CCTimeType curTime, CCTimeType timeSinceLastTick, uint32_t unacknowledgedBytes, bool isContinuousSend);
00090     int GetTransmissionBandwidth(CCTimeType curTime, CCTimeType timeSinceLastTick, uint32_t unacknowledgedBytes, bool isContinuousSend);
00091 
00096     bool ShouldSendACKs(CCTimeType curTime, CCTimeType estimatedTimeToNextTick);
00097 
00100     DatagramSequenceNumberType GetAndIncrementNextDatagramSequenceNumber(void);
00101     DatagramSequenceNumberType GetNextDatagramSequenceNumber(void);
00102 
00108     void OnSendBytes(CCTimeType curTime, uint32_t numBytes);
00109 
00111     void OnGotPacketPair(DatagramSequenceNumberType datagramSequenceNumber, uint32_t sizeInBytes, CCTimeType curTime);
00112 
00116     bool OnGotPacket(DatagramSequenceNumberType datagramSequenceNumber, bool isContinuousSend, CCTimeType curTime, uint32_t sizeInBytes, uint32_t *skippedMessageCount);
00117 
00120     void OnResend(CCTimeType curTime);
00121     void OnNAK(CCTimeType curTime, DatagramSequenceNumberType nakSequenceNumber);
00122 
00127     void OnAck(CCTimeType curTime, CCTimeType rtt, bool hasBAndAS, BytesPerMicrosecond _B, BytesPerMicrosecond _AS, double totalUserDataBytesAcked, bool isContinuousSend, DatagramSequenceNumberType sequenceNumber );
00128     void OnDuplicateAck( CCTimeType curTime, DatagramSequenceNumberType sequenceNumber ) {}
00129     
00132     void OnSendAckGetBAndAS(CCTimeType curTime, bool *hasBAndAS, BytesPerMicrosecond *_B, BytesPerMicrosecond *_AS);
00133 
00138     void OnSendAck(CCTimeType curTime, uint32_t numBytes);
00139 
00142     void OnSendNACK(CCTimeType curTime, uint32_t numBytes);
00143     
00150     CCTimeType GetRTOForRetransmission(void) const;
00151 
00154     void SetMTU(uint32_t bytes);
00155 
00157     uint32_t GetMTU(void) const;
00158 
00160     BytesPerMicrosecond GetLocalSendRate(void) const {return 1.0 / SND;}
00161     BytesPerMicrosecond GetLocalReceiveRate(CCTimeType currentTime) const;
00162     BytesPerMicrosecond GetRemoveReceiveRate(void) const {return AS;}
00163     //BytesPerMicrosecond GetEstimatedBandwidth(void) const {return B;}
00164     BytesPerMicrosecond GetEstimatedBandwidth(void) const {return GetLinkCapacityBytesPerSecond()*1000000.0;}
00165     double GetLinkCapacityBytesPerSecond(void) const {return estimatedLinkCapacityBytesPerSecond;};
00166 
00168     double GetRTT(void) const;
00169 
00170     bool GetIsInSlowStart(void) const {return isInSlowStart;}
00171     uint32_t GetCWNDLimit(void) const {return (uint32_t) (CWND*MAXIMUM_MTU_INCLUDING_UDP_HEADER);}
00172 
00173 
00175     static bool GreaterThan(DatagramSequenceNumberType a, DatagramSequenceNumberType b);
00177     static bool LessThan(DatagramSequenceNumberType a, DatagramSequenceNumberType b);
00178 //  void SetTimeBetweenSendsLimit(unsigned int bitsPerSecond);
00179     uint64_t GetBytesPerSecondLimitByCongestionControl(void) const;
00180 
00181     protected:
00182     // --------------------------- PROTECTED VARIABLES ---------------------------
00188     MicrosecondsPerByte SND;
00189     
00195     double CWND;
00196     
00200     CCTimeType nextSYNUpdate;
00201         
00202         
00205     int packetPairRecieptHistoryWriteIndex;
00206 
00209     //BytesPerMicrosecond B;
00210     
00216     double RTT;
00217     
00222     // double RTTVar;   
00224     double minRTT, maxRTT;
00225         
00232     BytesPerMicrosecond packetArrivalHistory[CC_RAKNET_UDT_PACKET_HISTORY_LENGTH];
00233     BytesPerMicrosecond packetArrivalHistoryContinuousGaps[CC_RAKNET_UDT_PACKET_HISTORY_LENGTH];
00234     unsigned char packetArrivalHistoryContinuousGapsIndex;
00235     uint64_t continuousBytesReceived;
00236     CCTimeType continuousBytesReceivedStartTime;
00237     unsigned int packetArrivalHistoryWriteCount;
00238 
00241     int packetArrivalHistoryWriteIndex;
00242 
00244     CCTimeType lastPacketArrivalTime;
00245 
00248     BytesPerMicrosecond AS;
00249 
00252     CCTimeType lastTransmitOfBAndAS;
00253     
00258     bool isInSlowStart;
00259     
00262     uint32_t NAKCount;
00263     
00267     uint32_t AvgNAKNum;
00268     
00270     uint32_t DecCount;
00271 
00273     uint32_t DecInterval;
00274 
00276     DatagramSequenceNumberType nextDatagramSequenceNumber;
00277 
00280     CCTimeType lastPacketPairPacketArrivalTime;
00281 
00286     DatagramSequenceNumberType lastPacketPairSequenceNumber;
00287 
00290     CCTimeType lastUpdateWindowSizeAndAck;
00291 
00295     double ExpCount;
00296 
00299     uint64_t totalUserDataBytesSent;
00300     
00303     CCTimeType oldestUnsentAck;
00304     
00305     // Maximum amount of bytes that the user can send, e.g. the size of one full datagram
00306     uint32_t MAXIMUM_MTU_INCLUDING_UDP_HEADER;
00307     
00308     // Max window size
00309     double CWND_MAX_THRESHOLD;
00310     
00313     DatagramSequenceNumberType expectedNextSequenceNumber;
00314 
00315     // How many times have we sent B and AS? Used to force it to send at least CC_RAKNET_UDT_PACKET_HISTORY_LENGTH times
00316     // Otherwise, the default values in the array generate inaccuracy
00317     uint32_t sendBAndASCount;
00318 
00321     BytesPerMicrosecond mostRecentPacketArrivalHistory;
00322 
00323     bool hasWrittenToPacketPairReceiptHistory;
00324 
00325 //  uint32_t rttHistory[RTT_HISTORY_LENGTH];
00326 //  uint32_t rttHistoryIndex;
00327 //  uint32_t rttHistoryWriteCount;
00328 //  uint32_t rttSum, rttLow;
00329 //  CCTimeType lastSndUpdateTime;
00330     double estimatedLinkCapacityBytesPerSecond;
00331 
00332     // --------------------------- PROTECTED METHODS ---------------------------
00334     void SetNextSYNUpdate(CCTimeType currentTime);
00335     
00337     BytesPerMicrosecond ReceiverCalculateDataArrivalRate(CCTimeType curTime) const;
00339     BytesPerMicrosecond ReceiverCalculateDataArrivalRateMedian(void) const;
00340 
00342     static BytesPerMicrosecond CalculateListMedianRecursive(const BytesPerMicrosecond inputList[CC_RAKNET_UDT_PACKET_HISTORY_LENGTH], int inputListLength, int lessThanSum, int greaterThanSum);
00343 //  static uint32_t CalculateListMedianRecursive(const uint32_t inputList[RTT_HISTORY_LENGTH], int inputListLength, int lessThanSum, int greaterThanSum);
00344         
00347     CCTimeType GetSenderRTOForACK(void) const;
00348 
00350     void EndSlowStart(void);
00351 
00353     inline double BytesPerMicrosecondToPacketsPerMillisecond(BytesPerMicrosecond in);
00354 
00356     //void UpdateRTT(CCTimeType rtt);
00357 
00359     void UpdateWindowSizeAndAckOnAckPreSlowStart(double totalUserDataBytesAcked);
00360 
00362     void UpdateWindowSizeAndAckOnAckPerSyn(CCTimeType curTime, CCTimeType rtt, bool isContinuousSend, DatagramSequenceNumberType sequenceNumber);
00363 
00364 
00366     void ResetOnDataArrivalHalveSNDOnNoDataTime(CCTimeType curTime);
00367     
00368     // Init array
00369     void InitPacketArrivalHistory(void);
00370 
00371     // Printf
00372     void PrintLowBandwidthWarning(void);
00373 
00374     // Bug: SND can sometimes get super high - have seen 11693
00375     void CapMinSnd(const char *file, int line);
00376 
00377     void DecreaseTimeBetweenSends(void);
00378     void IncreaseTimeBetweenSends(void);
00379 
00380     int bytesCanSendThisTick;
00381 
00382     CCTimeType lastRttOnIncreaseSendRate;
00383     CCTimeType lastRtt;
00384 
00385     DatagramSequenceNumberType nextCongestionControlBlock;
00386     bool hadPacketlossThisBlock;
00387     DataStructures::Queue<CCTimeType> pingsLastInterval;
00388 };
00389 
00390 }
00391 
00392 #endif
00393 
00394 #endif

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net