diff options
author | Florin Coras <fcoras@cisco.com> | 2019-11-15 17:56:48 -0800 |
---|---|---|
committer | Andrew Yourtchenko <ayourtch@gmail.com> | 2020-08-12 07:43:14 +0000 |
commit | 9e51b52bb96288fe6003a248ae67165be026a40b (patch) | |
tree | 9cd1b3c74e7a69b1d7bdc9f1876c74bd7b5f63fc /src/vnet/tcp | |
parent | 25b58c6d21db0d0ffaebff4effb4aa4a9e41745e (diff) |
tcp: fix tail rescue with sacks
Type: fix
Change-Id: Iad73f47cef3d29c4b0b7d1f58f2f2b14ba4b1d38
Signed-off-by: Florin Coras <fcoras@cisco.com>
(cherry picked from commit 3eba7f1575a17b77924bf5be67b03b0227d04b78)
Diffstat (limited to 'src/vnet/tcp')
-rw-r--r-- | src/vnet/tcp/tcp_output.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c index 1dc629d45c6..60e0927af85 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -1937,8 +1937,10 @@ tcp_retransmit_sack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc, u32 n_segs_new; int av_wnd; + /* Make sure we don't exceed available window and leave space + * for one more packet, to avoid zero window acks */ av_wnd = (int) tc->snd_wnd - (tc->snd_nxt - tc->snd_una); - av_wnd = clib_max (av_wnd, 0); + av_wnd = clib_max (av_wnd - tc->snd_mss, 0); snd_space = clib_min (snd_space, av_wnd); snd_space = clib_min (max_deq, snd_space); burst_size = clib_min (burst_size - n_segs, @@ -1961,16 +1963,16 @@ tcp_retransmit_sack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc, * unSACKed sequence number SHOULD be returned, and RescueRxt set to * RecoveryPoint. HighRxt MUST NOT be updated. */ - max_bytes = clib_min (tc->snd_mss, - tc->snd_congestion - tc->snd_una); + hole = scoreboard_last_hole (sb); + max_bytes = clib_min (tc->snd_mss, hole->end - hole->start); max_bytes = clib_min (max_bytes, snd_space); - offset = tc->snd_congestion - tc->snd_una - max_bytes; - sb->rescue_rxt = tc->snd_congestion; + offset = hole->end - tc->snd_una - max_bytes; n_written = tcp_prepare_retransmit_segment (wrk, tc, offset, max_bytes, &b); if (!n_written) goto done; + sb->rescue_rxt = tc->snd_congestion; bi = vlib_get_buffer_index (vm, b); tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4); n_segs += 1; |