}
else
{
- /* Round up to 1 if needed */
- tc->cwnd += clib_max ((tc->snd_mss * tc->snd_mss) / tc->cwnd, 1);
+ /* tc->cwnd += clib_max ((tc->snd_mss * tc->snd_mss) / tc->cwnd, 1); */
+ tc->cwnd_acc_bytes += tc->bytes_acked;
+ if (tc->cwnd_acc_bytes >= tc->cwnd)
+ {
+ u32 inc = tc->cwnd_acc_bytes / tc->cwnd;
+ tc->cwnd_acc_bytes -= inc * tc->cwnd;
+ tc->cwnd += inc * tc->snd_mss;
+ }
+ tc->cwnd = clib_min (tc->cwnd,
+ transport_tx_fifo_size (&tc->connection));
}
}
* window deflation" attempts to ensure that, when fast recovery
* eventually ends, approximately ssthresh amount of data will be
* outstanding in the network.*/
- tc->cwnd = (tc->cwnd > tc->bytes_acked) ?
- tc->cwnd - tc->bytes_acked : 0;
+ tc->cwnd = (tc->cwnd > tc->bytes_acked + tc->snd_mss) ?
+ tc->cwnd - tc->bytes_acked : tc->snd_mss;
if (tc->bytes_acked > tc->snd_mss)
tc->cwnd += tc->snd_mss;
}