diff options
author | Florin Coras <fcoras@cisco.com> | 2020-07-06 08:06:54 -0700 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2020-07-07 14:56:02 +0000 |
commit | c78d47b1417706b278dd15098a47d380596442ce (patch) | |
tree | 1ace71eedca2c3da383ce514a20bcea74dd0031d /src | |
parent | 4834a66b7b3ef73e486c40ea9d8e36cc2e09c473 (diff) |
tcp: round down rcv wnd even if avoiding retraction
Type: improvement
Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I7fb3a4a2ffc4c5f42aa043e3a317b52d7767fb81
Diffstat (limited to 'src')
-rw-r--r-- | src/vnet/tcp/tcp_output.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c index 3b1bbacbbe6..46c5661f7c1 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -121,33 +121,29 @@ tcp_update_rcv_wnd (tcp_connection_t * tc) */ available_space = transport_max_rx_enqueue (&tc->connection); - /* Make sure we have a multiple of 1 << rcv_wscale. We round down to - * avoid advertising a window larger than what can be buffered */ - available_space = round_down_pow2 (available_space, 1 << tc->rcv_wscale); - - if (PREDICT_FALSE (available_space < tc->rcv_opts.mss)) - { - tc->rcv_wnd = 0; - return; - } - /* * Use the above and what we know about what we've previously advertised * to compute the new window */ observed_wnd = (i32) tc->rcv_wnd - (tc->rcv_nxt - tc->rcv_las); - /* Bad. Thou shalt not shrink */ + /* Check if we are about to retract the window. Do the comparison before + * rounding to avoid errors. Per RFC7323 sec. 2.4 we could remove this */ if (PREDICT_FALSE ((i32) available_space < observed_wnd)) { - wnd = round_pow2 (clib_max (observed_wnd, 0), 1 << tc->rcv_wscale); + wnd = round_down_pow2 (clib_max (observed_wnd, 0), 1 << tc->rcv_wscale); TCP_EVT (TCP_EVT_RCV_WND_SHRUNK, tc, observed_wnd, available_space); } else { - wnd = available_space; + /* Make sure we have a multiple of 1 << rcv_wscale. We round down to + * avoid advertising a window larger than what can be buffered */ + wnd = round_down_pow2 (available_space, 1 << tc->rcv_wscale); } + if (PREDICT_FALSE (wnd < tc->rcv_opts.mss)) + wnd = 0; + tc->rcv_wnd = clib_min (wnd, TCP_WND_MAX << tc->rcv_wscale); } |