diff options
author | Florin Coras <fcoras@cisco.com> | 2019-11-15 17:56:48 -0800 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2019-12-06 03:55:48 +0000 |
commit | 3eba7f1575a17b77924bf5be67b03b0227d04b78 (patch) | |
tree | e79d16153de8cfe63a6a96fa79cbd152c4cf5a84 | |
parent | 61e3ade8436e77730150568ad3a48058c4f49d97 (diff) |
tcp: fix tail rescue with sacks
Type: fix
Change-Id: Iad73f47cef3d29c4b0b7d1f58f2f2b14ba4b1d38
Signed-off-by: Florin Coras <fcoras@cisco.com>
-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 f63ffa64022..05db72770f5 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -1924,8 +1924,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, @@ -1948,16 +1950,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; |