--- tcp_output.c.~1.205.~ 2018-04-18 06:10:31.000000000 +0300 +++ tcp_output.c 2018-04-18 15:16:20.213923329 +0300 @@ -988,16 +988,27 @@ * taking into account that we are limited by * TCP_MAXWIN << tp->rcv_scale. */ - long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) - - (tp->rcv_adv - tp->rcv_nxt); + long recwin = min(win, (long)TCP_MAXWIN << tp->rcv_scale); + long oldwin, adv; /* - * If the new window size ends up being the same as the old - * size when it is scaled, then don't force a window update. + * rcv_nxt may overtake rcv_adv when we accept a + * zero-window probe. */ - if ((tp->rcv_adv - tp->rcv_nxt) >> tp->rcv_scale == - (adv + tp->rcv_adv - tp->rcv_nxt) >> tp->rcv_scale) + if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) + oldwin = tp->rcv_adv - tp->rcv_nxt; + else + oldwin = 0; + + /* + * If the new window size ends up being the same as or + * less than the old size when it is scaled, then + * don't force a window update. + */ + if (recwin >> tp->rcv_scale <= oldwin >> tp->rcv_scale) goto dontupdate; + + adv = recwin - oldwin; if (adv >= (long) (2 * rxsegsize)) goto send; if (2 * adv >= (long) so->so_rcv.sb_hiwat)