Re: [PATCH net v2] net: Update window_clamp if SOCK_RCVBUF is set

From: Mao Wenan
Date: Mon Nov 09 2020 - 11:26:47 EST




在 2020/11/9 下午10:01, Eric Dumazet 写道:
On Mon, Nov 9, 2020 at 12:41 PM Eric Dumazet <edumazet@xxxxxxxxxx> wrote:

Packetdrill test would be :

// Force syncookies
`sysctl -q net.ipv4.tcp_syncookies=2`

0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [2048], 4) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0

+0 < S 0:0(0) win 32792 <mss 1000,sackOK,TS val 100 ecr 0,nop,wscale 7>
+0 > S. 0:0(0) ack 1 <mss 1460,sackOK,TS val 4000 ecr 100,nop,wscale 0>
+.1 < . 1:1(0) ack 1 win 1024 <nop,nop,TS val 200 ecr 4000>
+0 accept(3, ..., ...) = 4
+0 %{ assert tcpi_snd_wscale == 0, tcpi_snd_wscale }%


Also, please add to your next submission an appropriate Fixes: tag :

Fixes: e88c64f0a425 ("tcp: allow effective reduction of TCP's
rcv-buffer via setsockopt")

OK, thanks, I can reproduce wscale=0 with your packetdrill, and I will send v3 with the fixes tag.


On Mon, Nov 9, 2020 at 12:02 PM Eric Dumazet <edumazet@xxxxxxxxxx> wrote:

On Mon, Nov 9, 2020 at 11:12 AM Mao Wenan <wenan.mao@xxxxxxxxxxxxxxxxx> wrote:



在 2020/11/9 下午5:56, Eric Dumazet 写道:
On Mon, Nov 9, 2020 at 10:33 AM Mao Wenan <wenan.mao@xxxxxxxxxxxxxxxxx> wrote:

When net.ipv4.tcp_syncookies=1 and syn flood is happened,
cookie_v4_check or cookie_v6_check tries to redo what
tcp_v4_send_synack or tcp_v6_send_synack did,
rsk_window_clamp will be changed if SOCK_RCVBUF is set,
which will make rcv_wscale is different, the client
still operates with initial window scale and can overshot
granted window, the client use the initial scale but local
server use new scale to advertise window value, and session
work abnormally.

What is not working exactly ?

Sending a 'big wscale' should not really matter, unless perhaps there
is a buggy stack at the remote end ?
1)in tcp_v4_send_synack, if SO_RCVBUF is set and
tcp_full_space(sk)=65535, pass req->rsk_window_clamp=65535 to
tcp_select_initial_window, rcv_wscale will be zero, and send to client,
the client consider wscale is 0;
2)when ack is back from client, if there is no this patch,
req->rsk_window_clamp is 0, and pass to tcp_select_initial_window,
wscale will be 7, this new rcv_wscale is no way to advertise to client.
3)if server send rcv_wind to client with window=63, it consider the real
window is 63*2^7=8064, but client consider the server window is only
63*2^0=63, it can't send big packet to server, and the send-q of client
is full.


I see, please change your patches so that tcp_full_space() is used _once_

listener sk_rcvbuf can change under us.

I really have no idea how window can be set to 63, so please send us
the packetdrill test once you have it.