Index: kern/uipc_sockbuf.c =================================================================== --- kern/uipc_sockbuf.c (revision 211227) +++ kern/uipc_sockbuf.c (working copy) @@ -68,6 +68,22 @@ static void sbdrop_internal(struct sockbuf *sb, int len); static void sbflush_internal(struct sockbuf *sb); +#ifdef INVARIANTS +static int +sb_cc_check(struct sockbuf *sb) +{ + struct mbuf *n = sb->sb_mb; + int slen = 0; + + while (n) { + slen = m_length(n, &n); + n = n->m_nextpkt; + } + + return (slen == sb->sb_cc ? 1 : 0); +} +#endif + /* * Socantsendmore indicates that no more data will be sent on the socket; it * would normally be applied to a socket when the user informs the system @@ -528,6 +544,9 @@ SBLASTMBUFCHK(sb); + KASSERT(sb_cc_check(sb), + ("%s: sb_cc != total mbuf length - before", __func__)); + /* Remove all packet headers and mbuf tags to get a pure data chain. */ m_demote(m, 1); @@ -535,6 +554,9 @@ sb->sb_lastrecord = sb->sb_mb; SBLASTRECORDCHK(sb); + + KASSERT(sb_cc_check(sb), + ("%s: sb_cc != total mbuf length - after", __func__)); } /* @@ -811,6 +833,9 @@ sbflush_internal(struct sockbuf *sb) { + KASSERT(sb_cc_check(sb), + ("%s: sb_cc != total mbuf length", __func__)); + while (sb->sb_mbcnt) { /* * Don't call sbdrop(sb, 0) if the leading mbuf is non-empty: @@ -851,10 +876,22 @@ struct mbuf *m; struct mbuf *next; - next = (m = sb->sb_mb) ? m->m_nextpkt : 0; + KASSERT(len <= sb->sb_cc, + ("%s: len > sb->sb_cc", __func__)); + KASSERT(sb->sb_cc >= sb->sb_sndptroff, + ("%s: sb_sndptroff > sb_cc", __func__)); + KASSERT(sb_cc_check(sb), + ("%s: sb_cc != total mbuf length - enter", __func__)); + + if (len > sb->sb_sndptroff) { + sb->sb_sndptroff = 0; + sb->sb_sndptr = NULL; + } + + next = (m = sb->sb_mb) ? m->m_nextpkt : NULL; while (len > 0) { - if (m == 0) { - if (next == 0) + if (m == NULL) { + if (next == NULL) panic("sbdrop"); m = next; next = m->m_nextpkt; @@ -874,7 +911,7 @@ sbfree(sb, m); m = m_free(m); } - while (m && m->m_len == 0) { + while (m != NULL && m->m_len == 0) { sbfree(sb, m); m = m_free(m); } @@ -891,9 +928,13 @@ if (m == NULL) { sb->sb_mbtail = NULL; sb->sb_lastrecord = NULL; + sb->sb_sndptr = NULL; } else if (m->m_nextpkt == NULL) { sb->sb_lastrecord = m; } + + KASSERT(sb_cc_check(sb), + ("%s: sb_cc != total mbuf length - exit", __func__)); } /* @@ -922,13 +963,15 @@ * avoid traversal of the entire socket buffer for larger offsets. */ struct mbuf * -sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff) +sbsndptr(struct sockbuf *sb, int off, int len, int *moff) { struct mbuf *m, *ret; KASSERT(sb->sb_mb != NULL, ("%s: sb_mb is NULL", __func__)); KASSERT(off + len <= sb->sb_cc, ("%s: beyond sb", __func__)); KASSERT(sb->sb_sndptroff <= sb->sb_cc, ("%s: sndptroff broken", __func__)); + KASSERT(sb_cc_check(sb), + ("%s: sb_cc != total mbuf length", __func__)); /* * Is off below stored offset? Happens on retransmits. Index: sys/sockbuf.h =================================================================== --- sys/sockbuf.h (revision 211227) +++ sys/sockbuf.h (working copy) @@ -152,7 +152,7 @@ int sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so, struct thread *td); struct mbuf * - sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff); + sbsndptr(struct sockbuf *sb, int off, int len, int *moff); void sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb); int sbwait(struct sockbuf *sb); int sblock(struct sockbuf *sb, int flags); Index: netinet/tcp_output.c =================================================================== --- netinet/tcp_output.c (revision 211227) +++ netinet/tcp_output.c (working copy) @@ -153,7 +153,7 @@ int idle, sendalot; int sack_rxmit, sack_bytes_rxmt; struct sackhole *p; - int tso = 0; + int tso; struct tcpopt to; #if 0 int maxburst = TCP_MAXBURST; @@ -211,6 +211,7 @@ SEQ_LT(tp->snd_nxt, tp->snd_max)) tcp_sack_adjust(tp); sendalot = 0; + tso = 0; off = tp->snd_nxt - tp->snd_una; sendwin = min(tp->snd_wnd, tp->snd_cwnd); sendwin = min(sendwin, tp->snd_bwnd); @@ -490,9 +491,9 @@ } else { len = tp->t_maxseg; sendalot = 1; - tso = 0; } } + if (sack_rxmit) { if (SEQ_LT(p->rxmit + len, tp->snd_una + so->so_snd.sb_cc)) flags &= ~TH_FIN; @@ -766,7 +794,7 @@ */ if (len) { struct mbuf *mb; - u_int moff; + int moff; if ((tp->t_flags & TF_FORCEDATA) && len == 1) TCPSTAT_INC(tcps_sndprobe);