tcp: fix sack retransmit beyond snd_nxt
Type: fix
Ensure that sack retransmit logic does not try to inadvertently send new
data.
Change-Id: Idfda19643577d9c1b58e2af8d8283cabfbaf98e6
Signed-off-by: Florin Coras <fcoras@cisco.com>
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c
index e3228c0..0047f3c 100644
--- a/src/vnet/tcp/tcp_output.c
+++ b/src/vnet/tcp/tcp_output.c
@@ -1392,6 +1392,8 @@
max_deq_bytes = clib_min (available_bytes, max_deq_bytes);
start = tc->snd_una + offset;
+ ASSERT (seq_leq (start + max_deq_bytes, tc->snd_nxt));
+
n_bytes = tcp_prepare_segment (wrk, tc, offset, max_deq_bytes, b);
if (!n_bytes)
return 0;
@@ -1521,7 +1523,8 @@
/* Send the first unacked segment. If we're short on buffers, return
* as soon as possible */
- n_bytes = tcp_prepare_retransmit_segment (wrk, tc, 0, tc->snd_mss, &b);
+ n_bytes = clib_min (tc->snd_mss, tc->snd_nxt - tc->snd_una);
+ n_bytes = tcp_prepare_retransmit_segment (wrk, tc, 0, n_bytes, &b);
if (!n_bytes)
{
tcp_timer_update (tc, TCP_TIMER_RETRANSMIT, 1);
@@ -1922,7 +1925,7 @@
while (snd_space > 0 && n_segs < burst_size)
{
- hole = scoreboard_next_rxt_hole (sb, hole, max_deq, &can_rescue,
+ hole = scoreboard_next_rxt_hole (sb, hole, max_deq != 0, &can_rescue,
&snd_limited);
if (!hole)
{
@@ -1990,6 +1993,8 @@
tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
sb->high_rxt += n_written;
+ ASSERT (seq_leq (sb->high_rxt, tc->snd_nxt));
+
snd_space -= n_written;
n_segs += 1;
}