/* * 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); } }