TCP send window underflow

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

TCP send window underflow

Alexander Bluhm
Hi,

FreeBSD has a fix for TCP send window underflow.  markus@ has seen
that this bug is also triggered in our code.

https://svnweb.freebsd.org/base/head/sys/netinet/tcp_input.c?r1=296935&r2=298408

    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.

Note that FreeBSD has an additional cast in "if (tp->snd_wnd >=
(u_long) acked)".  This is not necessary as the compiler will do
this conversion anyway.  markus@ did put an additional check in his
fix "if (tp->snd_wnd > acked && acked >= 0)", but this is also not
necessary.  The integer variable acked is always positive due to
the check "if (SEQ_LEQ(th->th_ack, tp->snd_una))" some lines above.

ok?

bluhm

Index: netinet/tcp_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.361
diff -u -p -r1.361 tcp_input.c
--- netinet/tcp_input.c 12 Jul 2019 19:43:51 -0000 1.361
+++ netinet/tcp_input.c 10 Nov 2019 22:00:29 -0000
@@ -1712,12 +1712,18 @@ trimthenstep6:
  }
  ND6_HINT(tp);
  if (acked > so->so_snd.sb_cc) {
- tp->snd_wnd -= so->so_snd.sb_cc;
+ if (tp->snd_wnd > so->so_snd.sb_cc)
+ tp->snd_wnd -= so->so_snd.sb_cc;
+ else
+ tp->snd_wnd = 0;
  sbdrop(so, &so->so_snd, (int)so->so_snd.sb_cc);
  ourfinisacked = 1;
  } else {
  sbdrop(so, &so->so_snd, acked);
- tp->snd_wnd -= acked;
+ if (tp->snd_wnd > acked)
+ tp->snd_wnd -= acked;
+ else
+ tp->snd_wnd = 0;
  ourfinisacked = 0;
  }

Reply | Threaded
Open this post in threaded view
|

Re: TCP send window underflow

Alexandr Nedvedicky
Hello,

the change looks OK to me.

thanks and
regards
sashan