📄 cc.h
字号:
/*****************************************************************************DISCLAIMER: The algorithms implemented using UDT/CCC in this file may bemodified. These modifications may NOT necessarily reflect the view ofthe algorithms' original authors.Written by: Yunhong Gu <ygu@cs.uic.edu>, last updated on Mar 02, 2005.*****************************************************************************/#ifndef WIN32 #include <sys/time.h> #include <time.h>#endif#include <cmath>#include <vector>#include <algorithm>#include <window.h>#include <ccc.h>#include <udt.h>using namespace std;/*****************************************************************************TCP congestion controlReference: M. Allman, V. Paxson, W. Stevens (consultant), TCP Congestion Control, RFC 2581, April 1999.Note:This base TCP control class can be used to derive new TCP variants, includingthose implemented in this file: HighSpeed, Scalable, BiC, Vegas, and FAST.*****************************************************************************/class CTCP: public CCC{public: void init() { m_bSlowStart = true; m_issthresh = 83333; m_dPktSndPeriod = 0.0; m_dCWndSize = 2.0; setACKInterval(2); setRTO(1000000); } virtual void onACK(const int& ack) { if (ack == m_iLastACK) { if (3 == ++ m_iDupACKCount) DupACKAction(); else if (m_iDupACKCount > 3) m_dCWndSize += 1.0; else ACKAction(); } else { if (m_iDupACKCount >= 3) m_dCWndSize = m_issthresh; m_iLastACK = ack; m_iDupACKCount = 1; ACKAction(); } } virtual void onTimeout() { m_issthresh = getPerfInfo()->pktFlightSize / 2; if (m_issthresh < 2) m_issthresh = 2; m_bSlowStart = true; m_dCWndSize = 2.0; }protected: virtual void ACKAction() { if (m_bSlowStart) { m_dCWndSize += 1.0; if (m_dCWndSize >= m_issthresh) m_bSlowStart = false; } else m_dCWndSize += 1.0/m_dCWndSize; } virtual void DupACKAction() { m_bSlowStart = false; m_issthresh = getPerfInfo()->pktFlightSize / 2; if (m_issthresh < 2) m_issthresh = 2; m_dCWndSize = m_issthresh + 3; }protected: int m_issthresh; bool m_bSlowStart; int m_iDupACKCount; int m_iLastACK;};/*****************************************************************************Scalable TCP congestion controlReference:Tom Kelly, Scalable TCP: Improving Performance in Highspeed Wide Area Networks, Computer Communication Review, Vol. 33 No. 2 - April 2003*****************************************************************************/class CScalableTCP: public CTCP{protected: virtual void ACKAction() { if (m_dCWndSize <= 38.0) CTCP::ACKAction(); else { if (m_bSlowStart) m_dCWndSize += 1.0; else m_dCWndSize += 0.01; } if (m_dCWndSize > m_iMaxCWndSize) m_dCWndSize = m_iMaxCWndSize; } virtual void DupACKAction() { if (m_dCWndSize <= 38.0) m_dCWndSize *= 0.5; else m_dCWndSize *= 0.875; if (m_dCWndSize < m_iMinCWndSize) m_dCWndSize = m_iMinCWndSize; }private: static const int m_iMinCWndSize = 16; static const int m_iMaxCWndSize = 100000; static const int m_iCWndThresh = 38;};/*****************************************************************************HighSpeed TCP congestion controlReference:Sally Floyd, HighSpeed TCP for Large Congestion Windows, RFC 3649, Experimental, December 2003*****************************************************************************/class CHSTCP: public CTCP{public: virtual void ACKAction() { m_dCWndSize += a(m_dCWndSize)/m_dCWndSize; } virtual void DupACKAction() { m_dCWndSize -= m_dCWndSize*b(m_dCWndSize); }private: double a(double w) { return (w * w * 2.0 * b(w)) / ((2.0 - b(w)) * pow(w, 1.2) * 12.8); } double b(double w) { return (0.1 - 0.5) * (log(w) - log(38.)) / (log(83000.) - log(38.)) + 0.5; }private: static const int m_iHighWnd = 83000; static const int m_iLowWnd = 38;};/*****************************************************************************BiC TCP congestion controlReference:Lisong Xu, Khaled Harfoush, and Injong Rhee, "Binary Increase Congestion Control for Fast Long-Distance Networks", INFOCOM 2004.*****************************************************************************/class CBiCTCP: public CTCP{public: CBiCTCP() { m_dMaxWin = m_iDefaultMaxWin; m_dMinWin = m_dCWndSize; m_dTargetWin = (m_dMaxWin + m_dMinWin) / 2; m_dSSCWnd = 1.0; m_dSSTargetWin = m_dCWndSize + 1.0; }protected: virtual void ACKAction() { if (m_dCWndSize < m_iLowWindow) { m_dCWndSize += 1/m_dCWndSize; return; } if (!m_bSlowStart) { if (m_dTargetWin - m_dCWndSize < m_iSMax) m_dCWndSize += (m_dTargetWin - m_dCWndSize)/m_dCWndSize; else m_dCWndSize += m_iSMax/m_dCWndSize; if (m_dMaxWin > m_dCWndSize) { m_dMinWin = m_dCWndSize; m_dTargetWin = (m_dMaxWin + m_dMinWin) / 2; } else { m_bSlowStart = true; m_dSSCWnd = 1.0; m_dSSTargetWin = m_dCWndSize + 1.0; m_dMaxWin = m_iDefaultMaxWin; } } else { m_dCWndSize += m_dSSCWnd/m_dCWndSize; if(m_dCWndSize >= m_dSSTargetWin) { m_dSSCWnd *= 2; m_dSSTargetWin = m_dCWndSize + m_dSSCWnd; } if(m_dSSCWnd >= m_iSMax) m_bSlowStart = false; } } virtual void DupACKAction() { if (m_dCWndSize <= m_iLowWindow) m_dCWndSize *= 0.5; else { m_dPreMax = m_dMaxWin; m_dMaxWin = m_dCWndSize; m_dCWndSize *= 0.875; m_dMinWin = m_dCWndSize; if (m_dPreMax > m_dMaxWin) { m_dMaxWin = (m_dMaxWin + m_dMinWin) / 2; m_dTargetWin = (m_dMaxWin + m_dMinWin) / 2; } } }private: static const int m_iLowWindow = 38; static const int m_iSMax = 32; static const int m_iSMin = 1; static const int m_iDefaultMaxWin = 1 << 29; double m_dMaxWin; double m_dMinWin; double m_dPreMax; double m_dTargetWin; double m_dSSCWnd; double m_dSSTargetWin;};/*****************************************************************************TCP Westwoodreference:http://www.cs.ucla.edu/NRL/hpi/tcpw/*****************************************************************************/class CWestwood: public CTCP{public: CWestwood(): m_dBWE(1), m_dLastBWE(1), m_dBWESample(1), m_dLastBWESample(1) { gettimeofday(&m_LastACKTime, 0); } virtual void onACK(const int& ack) { timeval currtime; gettimeofday(&currtime, 0); m_dBWESample = double(ack - m_iLastACK) / double((currtime.tv_sec - m_LastACKTime.tv_sec) * 1000.0 + (currtime.tv_usec - m_LastACKTime.tv_usec) / 1000.0); m_dBWE = 19.0/21.0 * m_dLastBWE + 1.0/21.0 * (m_dBWESample + m_dLastBWESample); m_LastACKTime = currtime; m_dLastBWE = m_dBWE; m_dLastBWESample = m_dBWESample; if (ack == m_iLastACK) { if (3 == ++ m_iDupACKCount) { m_bSlowStart = false; m_issthresh = int(ceil(getPerfInfo()->msRTT * m_dBWE)); if (m_issthresh < 2) m_issthresh = 2; m_dCWndSize = m_issthresh + 3; } else if (m_iDupACKCount > 3) m_dCWndSize += 1.0; else ACKAction(); } else { if (m_iDupACKCount >= 3) m_dCWndSize = m_issthresh; m_iLastACK = ack; m_iDupACKCount = 1; ACKAction(); } } virtual void onTimeout() { m_issthresh = int(ceil(getPerfInfo()->msRTT * m_dBWE)); if (m_issthresh < 2) m_issthresh = 2; m_bSlowStart = true; m_dCWndSize = 2.0; }private: double m_dBWE, m_dLastBWE; double m_dBWESample, m_dLastBWESample; timeval m_LastACKTime;};/*****************************************************************************TCP VegasReference:L. Brakmo, S. O'Malley, and L. Peterson. TCP Vegas: New techniques for congestion detection and avoidance. In Proceedings of the SIGCOMM '94 Symposium (Aug. 1994) pages 24-35. Note:This class can be used to derive new delay based approaches, e.g., FAST.*****************************************************************************/class CVegas: public CTCP{public: CVegas() { m_iSSRound = 1; m_iRTT = 1000000; m_iBaseRTT = 1000000; gettimeofday(&m_LastCCTime, 0); m_iPktSent = 0; m_pAckWindow = new CACKWindow(100000); } ~CVegas() { delete m_pAckWindow; } virtual void onACK(const int& seq) { double expected, actual, diff; //kbps int rtt = m_pAckWindow->acknowledge(seq, const_cast<int&>(seq)); if (rtt > 0) m_iRTT = (m_iRTT * 15 + rtt) >> 4; timeval currtime; gettimeofday(&currtime, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -