public override void onACK(int ack) { long B = 0; double inc = 0; // Note: 1/24/2012 // The minimum increase parameter is increased from "1.0 / m_iMSS" to 0.01 // because the original was too small and caused sending rate to stay at low level // for long time. const double min_inc = 0.01; ulong currtime = Timer.getTime(); if (currtime - m_LastRCTime < (ulong)m_iRCInterval) { return; } m_LastRCTime = currtime; if (m_bSlowStart) { m_dCWndSize += SequenceNumber.seqlen(m_iLastAck, ack); m_iLastAck = ack; if (m_dCWndSize > m_dMaxCWndSize) { m_bSlowStart = false; if (m_iRcvRate > 0) { m_dPktSndPeriod = 1000000.0 / m_iRcvRate; } else { m_dPktSndPeriod = (m_iRTT + m_iRCInterval) / m_dCWndSize; } } } else { m_dCWndSize = m_iRcvRate / 1000000.0 * (m_iRTT + m_iRCInterval) + 16; } // During Slow Start, no rate increase if (m_bSlowStart) { return; } if (m_bLoss) { m_bLoss = false; return; } B = (long)(m_iBandwidth - 1000000.0 / m_dPktSndPeriod); if ((m_dPktSndPeriod > m_dLastDecPeriod) && ((m_iBandwidth / 9) < B)) { B = m_iBandwidth / 9; } if (B <= 0) { inc = min_inc; } else { // inc = max(10 ^ ceil(log10( B * MSS * 8 ) * Beta / MSS, 1/MSS) // Beta = 1.5 * 10^(-6) inc = Math.Pow(10.0, Math.Ceiling(Math.Log10(B * m_iMSS * 8.0))) * 0.0000015 / m_iMSS; if (inc < min_inc) { inc = min_inc; } } m_dPktSndPeriod = (m_dPktSndPeriod * m_iRCInterval) / (m_dPktSndPeriod * inc + m_iRCInterval); }