summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1999-12-28 23:18:33 +0000
committermsmith <msmith@FreeBSD.org>1999-12-28 23:18:33 +0000
commitfe241c25718fbd3870d62981ab0828287a76a1bb (patch)
treee76c0ae529a42abb1344a4ca93eee77c4a6ee3e0 /sys/netinet
parentf9f846550e250ee609ee8c0582f13ae2520680af (diff)
downloadFreeBSD-src-fe241c25718fbd3870d62981ab0828287a76a1bb.zip
FreeBSD-src-fe241c25718fbd3870d62981ab0828287a76a1bb.tar.gz
Make tcp_drain() actually do something. When invoked (usually as a
desperation measure in low-memory situations), walk the tcpbs and flush the reassembly queues. This behaviour is currently controlled by the debug.do_tcpdrain sysctl (defaults to on). Submitted by: Bosko Milekic <bmilekic@dsuper.net> Reviewed by: wollman
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/tcp_subr.c29
-rw-r--r--sys/netinet/tcp_timewait.c29
2 files changed, 58 insertions, 0 deletions
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index fd3e435..c2cf691 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -100,6 +100,10 @@ static int tcp_tcbhashsize = 0;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RD,
&tcp_tcbhashsize, 0, "Size of TCP control-block hashtable");
+static int do_tcpdrain = 1;
+SYSCTL_INT(_debug, OID_AUTO, do_tcpdrain, CTLFLAG_RW, &do_tcpdrain, 0,
+ "Enable non Net3 compliant tcp_drain");
+
SYSCTL_INT(_net_inet_tcp, OID_AUTO, pcbcount, CTLFLAG_RD,
&tcbinfo.ipi_count, 0, "Number of active PCBs");
@@ -503,7 +507,32 @@ tcp_close(tp)
void
tcp_drain()
{
+ if (do_tcpdrain)
+ {
+ struct inpcb *inpb;
+ struct tcpcb *tcpb;
+ struct mbuf *m, *mq;
+
+ /*
+ * Walk the tcpbs, if existing, and flush the reassembly queue,
+ * if there is one...
+ * XXX: The "Net/3" implementation doesn't imply that the TCP
+ * reassembly queue should be flushed, but in a situation
+ * where we're really low on mbufs, this is potentially
+ * usefull.
+ */
+ for (inpb = tcbinfo.listhead->lh_first; inpb;
+ inpb = inpb->inp_list.le_next) {
+ if ((tcpb = intotcpcb(inpb))) {
+ for (mq = tcpb->t_segq; mq; mq = m) {
+ m = mq->m_nextpkt;
+ tcpb->t_segq = m;
+ m_freem(mq);
+ }
+ }
+ }
+ }
}
/*
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index fd3e435..c2cf691 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -100,6 +100,10 @@ static int tcp_tcbhashsize = 0;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RD,
&tcp_tcbhashsize, 0, "Size of TCP control-block hashtable");
+static int do_tcpdrain = 1;
+SYSCTL_INT(_debug, OID_AUTO, do_tcpdrain, CTLFLAG_RW, &do_tcpdrain, 0,
+ "Enable non Net3 compliant tcp_drain");
+
SYSCTL_INT(_net_inet_tcp, OID_AUTO, pcbcount, CTLFLAG_RD,
&tcbinfo.ipi_count, 0, "Number of active PCBs");
@@ -503,7 +507,32 @@ tcp_close(tp)
void
tcp_drain()
{
+ if (do_tcpdrain)
+ {
+ struct inpcb *inpb;
+ struct tcpcb *tcpb;
+ struct mbuf *m, *mq;
+
+ /*
+ * Walk the tcpbs, if existing, and flush the reassembly queue,
+ * if there is one...
+ * XXX: The "Net/3" implementation doesn't imply that the TCP
+ * reassembly queue should be flushed, but in a situation
+ * where we're really low on mbufs, this is potentially
+ * usefull.
+ */
+ for (inpb = tcbinfo.listhead->lh_first; inpb;
+ inpb = inpb->inp_list.le_next) {
+ if ((tcpb = intotcpcb(inpb))) {
+ for (mq = tcpb->t_segq; mq; mq = m) {
+ m = mq->m_nextpkt;
+ tcpb->t_segq = m;
+ m_freem(mq);
+ }
+ }
+ }
+ }
}
/*
OpenPOWER on IntegriCloud