Hi,

I have seen some stalling TCP connections while doing unidirectional
throughput tests.  The sending machine is doing zero window probes,
but is not sending more data although the other machine announced
that it has space again.

I guess this commit in tcp_input.c triggered it:
----------------------------
revision 1.362
date: 2019/11/11 21:17:21;  author: bluhm;  state: Exp;  lines: +9 -3;  
commitid: wXndkYTLO9jvCPdW;
Prevent underflows in tp->snd_wnd if the remote side ACKs more than
tp->snd_wnd.  This can happen, for example, when the remote side
responds to a window probe by ACKing the one byte it contains.
from FreeBSD; via markus@; OK sashan@ tobhe@
----------------------------

There we fixed an integer underflow.  So we no longer have uint32
max in the send window, but 0.  I see this in my test case.  Now
we need the machanism that writes the correct send window size.

There is a commit in FreeBSD from 2002:
https://github.com/freebsd/freebsd-src/commit/1645d0903ef7162f5c4516373f0c9df0501ac893

The header prediction code did not update snd_wl2.  If there is a
sequence number wrap, the send window update is not reached.

Although I did not obverve it, there seems to be the same problem
for snd_wl1 and rcv_up.  For rcv_up I copied the comparison with
rcv_nxt from urgent processing to keep future urgent data.

ok?

bluhm

Index: netinet/tcp_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.368
diff -u -p -r1.368 tcp_input.c
--- netinet/tcp_input.c 16 Apr 2021 12:08:25 -0000      1.368
+++ netinet/tcp_input.c 5 Aug 2021 21:51:50 -0000
@@ -966,6 +966,8 @@ findpcb:
                                        tp->t_pmtud_mss_acked = acked;
 
                                tp->snd_una = th->th_ack;
+                               /* Pull snd_wl2 up to prevent seq wrap. */
+                               tp->snd_wl2 = th->th_ack;
                                /*
                                 * We want snd_last to track snd_una so
                                 * as to avoid sequence wraparound problems
@@ -1015,6 +1017,10 @@ findpcb:
                                tcp_clean_sackreport(tp);
                        tcpstat_inc(tcps_preddat);
                        tp->rcv_nxt += tlen;
+                       /* Pull snd_wl1 and rcv_up up to prevent seq wrap. */
+                       tp->snd_wl1 = th->th_seq;
+                       if (SEQ_GT(tp->rcv_nxt, tp->rcv_up))
+                               tp->rcv_up = tp->rcv_nxt;
                        tcpstat_pkt(tcps_rcvpack, tcps_rcvbyte, tlen);
                        ND6_HINT(tp);
 

Reply via email to