Index: tcp_input.c =================================================================== --- tcp_input.c (revision 228534) +++ tcp_input.c (working copy) @@ -1778,9 +1778,15 @@ sorwakeup_locked(so); if (DELAY_ACK(tp)) { tp->t_flags |= TF_DELACK; + /* XXX: Debug */ + if (SEQ_LT(tp->rcv_adv, tp->rcv_nxt)) + printf("tcp_input: rcv_nxt beyond window due to delayed ACK\n"); } else { tp->t_flags |= TF_ACKNOW; tcp_output(tp); + /* XXX: Debug */ + KASSERT(SEQ_GEQ(tp->rcv_adv, tp->rcv_nxt), + ("tcp_input: negative window after ACK")); } goto check_delack; } @@ -1795,9 +1801,6 @@ win = sbspace(&so->so_rcv); if (win < 0) win = 0; - KASSERT(SEQ_GEQ(tp->rcv_adv, tp->rcv_nxt), - ("tcp_input negative window: tp %p rcv_nxt %u rcv_adv %u", tp, - tp->rcv_nxt, tp->rcv_adv)); tp->rcv_wnd = imax(win, (int)(tp->rcv_adv - tp->rcv_nxt)); /* Reset receive buffer auto scaling when not in bulk receive mode. */ @@ -2906,8 +2909,21 @@ /* * Return any desired output. */ - if (needoutput || (tp->t_flags & TF_ACKNOW)) + if (needoutput || (tp->t_flags & TF_ACKNOW)) { + uint64_t last = tp->t_sent; (void) tcp_output(tp); + /* XXX: Debug */ + if (tp->t_sent == last) { + if (SEQ_LT(tp->rcv_adv, tp->rcv_nxt)) + printf("tcp_input: rcv_nxt beyond window due to delayed ACK\n"); + } else + KASSERT(SEQ_GEQ(tp->rcv_adv, tp->rcv_nxt), + ("tcp_input: negative window after ACK")); + } else { + /* XXX: Debug */ + if (SEQ_LT(tp->rcv_adv, tp->rcv_nxt)) + printf("tcp_input: rcv_nxt beyond window due to delayed ACK\n"); + } check_delack: KASSERT(ti_locked == TI_UNLOCKED, ("%s: check_delack ti_locked %d", Index: tcp_var.h =================================================================== --- tcp_var.h (revision 228534) +++ tcp_var.h (working copy) @@ -205,7 +205,8 @@ uint32_t t_ispare[12]; /* 4 keep timers, 5 UTO, 3 TBD */ void *t_pspare2[4]; /* 4 TBD */ - uint64_t _pad[6]; /* 6 TBD (1-2 CC/RTT?) */ + uint64_t _pad[5]; /* 6 TBD (1-2 CC/RTT?) */ + uint64_t t_sent; }; /* Index: tcp_output.c =================================================================== --- tcp_output.c (revision 228534) +++ tcp_output.c (working copy) @@ -1309,6 +1309,7 @@ } } TCPSTAT_INC(tcps_sndtotal); + tp->t_sent++; /* * Data sent (as far as we can tell). Index: tcp_timewait.c =================================================================== --- tcp_timewait.c (revision 228534) +++ tcp_timewait.c (working copy) @@ -242,10 +242,10 @@ /* * Recover last window size sent. */ - KASSERT(SEQ_GEQ(tp->rcv_adv, tp->rcv_nxt), - ("tcp_twstart negative window: tp %p rcv_nxt %u rcv_adv %u", tp, - tp->rcv_nxt, tp->rcv_adv)); - tw->last_win = (tp->rcv_adv - tp->rcv_nxt) >> tp->rcv_scale; + if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) + tw->last_win = (tp->rcv_adv - tp->rcv_nxt) >> tp->rcv_scale; + else + tw->last_win = 0; /* * Set t_recent if timestamps are used on the connection.