summaryrefslogtreecommitdiffstats
path: root/src/vnet/tcp/tcp_input.c
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2020-01-04 00:53:04 +0000
committerDave Wallace <dwallacelf@gmail.com>2020-08-12 14:37:52 +0000
commit20ebef4714ebbc7d533a0c9c03bb39f8a1014365 (patch)
treee55dc906dfd6ab91c81c560755e07ac972bad604 /src/vnet/tcp/tcp_input.c
parentc2130c0102aeb658501ac43e36fde3c815a5aea2 (diff)
tcp: fix duplicate sack whith reneging
Type: fix Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I6f7fb91e059996ff702eb9c36e3abaed237fe221 (cherry picked from commit 067f8f963d64b1cbc70f2b78ebd2c6d3791e7d22)
Diffstat (limited to 'src/vnet/tcp/tcp_input.c')
-rwxr-xr-xsrc/vnet/tcp/tcp_input.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c
index e33a03271cd..92144f32504 100755
--- a/src/vnet/tcp/tcp_input.c
+++ b/src/vnet/tcp/tcp_input.c
@@ -1119,7 +1119,11 @@ tcp_rcv_sacks (tcp_connection_t * tc, u32 ack)
hole = pool_elt_at_index (sb->holes, sb->head);
if (PREDICT_FALSE (sb->is_reneging))
- sb->last_bytes_delivered += hole->start - tc->snd_una;
+ {
+ sb->last_bytes_delivered += clib_min (hole->start - tc->snd_una,
+ ack - tc->snd_una);
+ sb->is_reneging = seq_lt (ack, hole->start);
+ }
while (hole && blk_index < vec_len (rcv_sacks))
{
@@ -1202,7 +1206,7 @@ tcp_rcv_sacks (tcp_connection_t * tc, u32 ack)
|| sb->is_reneging || sb->holes[sb->head].start == ack);
ASSERT (sb->last_lost_bytes <= sb->lost_bytes);
ASSERT ((ack - tc->snd_una) + sb->last_sacked_bytes
- - sb->last_bytes_delivered >= sb->rxt_sacked);
+ - sb->last_bytes_delivered >= sb->rxt_sacked || sb->is_reneging);
ASSERT ((ack - tc->snd_una) >= tc->sack_sb.last_bytes_delivered
|| (tc->flags & TCP_CONN_FINSNT));
@@ -1532,14 +1536,13 @@ tcp_cc_handle_event (tcp_connection_t * tc, tcp_rate_sample_t * rs,
}
static void
-tcp_handle_old_ack (tcp_connection_t * tc, vlib_buffer_t * b,
- tcp_rate_sample_t * rs)
+tcp_handle_old_ack (tcp_connection_t * tc, tcp_rate_sample_t * rs)
{
if (!tcp_in_cong_recovery (tc))
return;
if (tcp_opts_sack_permitted (&tc->rcv_opts))
- tcp_rcv_sacks (tc, vnet_buffer (b)->tcp.ack_number);
+ tcp_rcv_sacks (tc, tc->snd_una);
tc->bytes_acked = 0;
@@ -1618,7 +1621,7 @@ tcp_rcv_ack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc, vlib_buffer_t * b,
if (seq_lt (vnet_buffer (b)->tcp.ack_number, tc->snd_una - tc->rcv_wnd))
return -1;
- tcp_handle_old_ack (tc, b, &rs);
+ tcp_handle_old_ack (tc, &rs);
/* Don't drop yet */
return 0;