summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/tcp_reass.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index 14f0e93..d7efe1d 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -214,16 +214,29 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
mq = nq;
}
- /* Insert the new segment queue entry into place. */
+ /*
+ * Insert the new segment queue entry into place. Try to collapse
+ * mbuf chains if segments are adjacent.
+ */
if (mp) {
- m->m_nextpkt = mp->m_nextpkt;
- mp->m_nextpkt = m;
+ if (M_TCPHDR(mp)->th_seq + mp->m_pkthdr.len == th->th_seq)
+ m_catpkt(mp, m);
+ else {
+ m->m_nextpkt = mp->m_nextpkt;
+ mp->m_nextpkt = m;
+ m->m_pkthdr.pkt_tcphdr = th;
+ }
} else {
- m->m_nextpkt = tp->t_segq;
- tp->t_segq = m ;
+ mq = tp->t_segq;
+ tp->t_segq = m;
+ if (mq && th->th_seq + *tlenp == M_TCPHDR(mq)->th_seq) {
+ m->m_nextpkt = mq->m_nextpkt;
+ m_catpkt(m, mq);
+ } else
+ m->m_nextpkt = mq;
+ m->m_pkthdr.pkt_tcphdr = th;
}
- m->m_pkthdr.pkt_tcphdr = th;
- tp->t_segqlen += m->m_pkthdr.len;
+ tp->t_segqlen += *tlenp;
present:
/*
OpenPOWER on IntegriCloud