Example #1
0
        /*
         * o  When cwnd is less than or equal to ssthresh, an SCTP endpoint MUST
         * use the slow-start algorithm to increase cwnd only if the current
         * congestion window is being fully utilized, an incoming SACK
         * advances the Cumulative TSN Ack Point, and the data sender is not
         * in Fast Recovery.  Only when these three conditions are met can
         * the cwnd be increased; otherwise, the cwnd MUST not be increased.
         * If these conditions are met, then cwnd MUST be increased by, at
         * most, the lesser of 1) the total size of the previously
         * outstanding DATA chunk(s) acknowledged, and 2) the destination's
         * path MTU.  This upper bound protects against the ACK-Splitting
         * attack outlined in [SAVAGE99].
         */
        protected void adjustCwind(bool didAdvance, int inFlightBytes, int totalAcked)
        {
            bool fullyUtilized = ((inFlightBytes - _cwnd) < DataChunk.GetCapacity());             // could we fit one more in?

            if (_cwnd <= _ssthresh)
            {
                // slow start
                Logger.Debug("slow start");

                if (didAdvance && fullyUtilized && !_fastRecovery)
                {
                    int incCwinBy = Math.Min(_transpMTU, totalAcked);
                    _cwnd += incCwinBy;
                    Logger.Debug("cwnd now " + _cwnd);
                }
                else
                {
                    Logger.Debug("cwnd static at " + _cwnd + " (didAdvance fullyUtilized  _fastRecovery inFlightBytes totalAcked)  " + didAdvance + " " + fullyUtilized + " " + _fastRecovery + " " + inFlightBytes + " " + totalAcked);
                }
            }
            else
            {
                /*
                 * 7.2.2.  Congestion Avoidance
                 *
                 * When cwnd is greater than ssthresh, cwnd should be incremented by
                 * 1*MTU per RTT if the sender has cwnd or more bytes of data
                 * outstanding for the corresponding transport address.
                 *
                 * In practice, an implementation can achieve this goal in the following
                 * way:
                 *
                 * o  partial_bytes_acked is initialized to 0.
                 *
                 * o  Whenever cwnd is greater than ssthresh, upon each SACK arrival
                 * that advances the Cumulative TSN Ack Point, increase
                 * partial_bytes_acked by the total number of bytes of all new chunks
                 * acknowledged in that SACK including chunks acknowledged by the new
                 * Cumulative TSN Ack and by Gap Ack Blocks.
                 *
                 * o  When partial_bytes_acked is equal to or greater than cwnd and
                 * before the arrival of the SACK the sender had cwnd or more bytes
                 * of data outstanding (i.e., before arrival of the SACK, flightsize
                 * was greater than or equal to cwnd), increase cwnd by MTU, and
                 * reset partial_bytes_acked to (partial_bytes_acked - cwnd).
                 *
                 * o  Same as in the slow start, when the sender does not transmit DATA
                 * on a given transport address, the cwnd of the transport address
                 * should be adjusted to max(cwnd / 2, 4*MTU) per RTO.
                 *
                 *
                 *
                 *
                 *
                 * Stewart                     Standards Track                    [Page 97]
                 * 
                 * RFC 4960          Stream Control Transmission Protocol    September 2007
                 *
                 *
                 * o  When all of the data transmitted by the sender has been
                 * acknowledged by the receiver, partial_bytes_acked is initialized
                 * to 0.
                 *
                 */
                if (didAdvance)
                {
                    _partial_bytes_acked += totalAcked;
                    if ((_partial_bytes_acked >= _cwnd) && fullyUtilized)
                    {
                        _cwnd += _transpMTU;
                        _partial_bytes_acked -= _cwnd;
                    }
                }
            }
            lock (_congestion) {
                Monitor.PulseAll(_congestion);
            }
        }