Index: sys/netinet/tcp_output.c =================================================================== --- sys/netinet/tcp_output.c +++ sys/netinet/tcp_output.c @@ -185,7 +185,8 @@ tcp_output(struct tcpcb *tp) { struct socket *so = tp->t_inpcb->inp_socket; - long len, recwin, sendwin; + long len; + uint32_t recwin, sendwin; int off, flags, error = 0; /* Keep compiler happy */ struct mbuf *m; struct ip *ip = NULL; @@ -566,7 +567,8 @@ flags &= ~TH_FIN; } - recwin = sbspace(&so->so_rcv); + recwin = lmin(lmax(sbspace(&so->so_rcv), 0), + (long)TCP_MAXWIN << tp->rcv_scale); /* * Sender silly window avoidance. We transmit under the following @@ -643,10 +645,10 @@ * taking into account that we are limited by * TCP_MAXWIN << tp->rcv_scale. */ - long adv; + int32_t adv; int oldwin; - adv = min(recwin, (long)TCP_MAXWIN << tp->rcv_scale); + adv = recwin; if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) { oldwin = (tp->rcv_adv - tp->rcv_nxt); adv -= oldwin; @@ -660,9 +662,9 @@ if (oldwin >> tp->rcv_scale == (adv + oldwin) >> tp->rcv_scale) goto dontupdate; - if (adv >= (long)(2 * tp->t_maxseg) && - (adv >= (long)(so->so_rcv.sb_hiwat / 4) || - recwin <= (long)(so->so_rcv.sb_hiwat / 8) || + if (adv >= (int32_t)(2 * tp->t_maxseg) && + (adv >= (int32_t)(so->so_rcv.sb_hiwat / 4) || + recwin <= (so->so_rcv.sb_hiwat / 8) || so->so_rcv.sb_hiwat <= 8 * tp->t_maxseg)) goto send; } @@ -1198,14 +1200,12 @@ * Calculate receive window. Don't shrink window, * but avoid silly window syndrome. */ - if (recwin < (long)(so->so_rcv.sb_hiwat / 4) && - recwin < (long)tp->t_maxseg) + if (recwin < (so->so_rcv.sb_hiwat / 4) && + recwin < tp->t_maxseg) recwin = 0; if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt) && - recwin < (long)(tp->rcv_adv - tp->rcv_nxt)) - recwin = (long)(tp->rcv_adv - tp->rcv_nxt); - if (recwin > (long)TCP_MAXWIN << tp->rcv_scale) - recwin = (long)TCP_MAXWIN << tp->rcv_scale; + recwin < (tp->rcv_adv - tp->rcv_nxt)) + recwin = (tp->rcv_adv - tp->rcv_nxt); /* * According to RFC1323 the window field in a SYN (i.e., a @@ -1596,7 +1596,7 @@ * then remember the size of the advertised window. * Any pending ACK has now been sent. */ - if (recwin >= 0 && SEQ_GT(tp->rcv_nxt + recwin, tp->rcv_adv)) + if (SEQ_GT(tp->rcv_nxt + recwin, tp->rcv_adv)) tp->rcv_adv = tp->rcv_nxt + recwin; tp->last_ack_sent = tp->rcv_nxt; tp->t_flags &= ~(TF_ACKNOW | TF_DELACK);