summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_timewait.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/tcp_timewait.c')
-rw-r--r--sys/netinet/tcp_timewait.c117
1 files changed, 92 insertions, 25 deletions
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 7820b63..43139ca 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95
- * $Id: tcp_subr.c,v 1.43 1998/03/24 18:06:28 wollman Exp $
+ * $Id: tcp_subr.c,v 1.44 1998/03/28 10:18:24 bde Exp $
*/
#include "opt_compat.h"
@@ -85,6 +85,9 @@ static int tcp_do_rfc1644 = 1;
SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1644, rfc1644,
CTLFLAG_RW, &tcp_do_rfc1644 , 0, "");
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, pcbcount, CTLFLAG_RD, &tcbinfo.ipi_count,
+ 0, "Number of active PCBs");
+
static void tcp_cleartaocache __P((void));
static void tcp_notify __P((struct inpcb *, int));
@@ -130,22 +133,7 @@ tcp_init()
tcbinfo.hashbase = hashinit(TCBHASHSIZE, M_PCB, &tcbinfo.hashmask);
tcbinfo.porthashbase = hashinit(TCBHASHSIZE, M_PCB,
&tcbinfo.porthashmask);
- /* For the moment, we just worry about putting inpcbs here. */
- /*
- * Rationale for a maximum of `nmbclusters':
- * 1) It's a convenient value, sized by config, based on
- * parameters already known to be tweakable as needed
- * for network-intensive systems.
- * 2) Under the Old World Order, when pcbs were stored in
- * mbufs, it was of course impossible to have more
- * pcbs than mbufs.
- * 3) The zone allocator doesn't allocate physical memory
- * for this many pcbs; it just sizes the virtual
- * address space appropriately. Thus, even for very large
- * values of nmbclusters, we don't actually take up much
- * memory unless required.
- */
- tcbinfo.ipi_zone = zinit("tcpcb", sizeof(struct inp_tp), nmbclusters,
+ tcbinfo.ipi_zone = zinit("tcpcb", sizeof(struct inp_tp), maxsockets,
ZONE_INTERRUPT, 0);
if (max_protohdr < sizeof(struct tcpiphdr))
max_protohdr = sizeof(struct tcpiphdr);
@@ -421,14 +409,10 @@ tcp_close(tp)
* way to calculate the pipesize, it will have to do.
*/
i = tp->snd_ssthresh;
-#if 1
if (rt->rt_rmx.rmx_sendpipe != 0)
dosavessthresh = (i < rt->rt_rmx.rmx_sendpipe / 2);
else
dosavessthresh = (i < so->so_snd.sb_hiwat / 2);
-#else
- dosavessthresh = (i < rt->rt_rmx.rmx_sendpipe / 2);
-#endif
if (((rt->rt_rmx.rmx_locks & RTV_SSTHRESH) == 0 &&
i != 0 && rt->rt_rmx.rmx_ssthresh != 0)
|| dosavessthresh) {
@@ -505,6 +489,93 @@ tcp_notify(inp, error)
sowwakeup(so);
}
+static int
+tcp_pcblist SYSCTL_HANDLER_ARGS
+{
+ int error, i, n, s;
+ struct inpcb *inp, **inp_list;
+ inp_gen_t gencnt;
+ struct xinpgen xig;
+
+ /*
+ * The process of preparing the TCB list is too time-consuming and
+ * resource-intensive to repeat twice on every request.
+ */
+ if (req->oldptr == 0) {
+ n = tcbinfo.ipi_count;
+ req->oldidx = 2 * (sizeof xig)
+ + (n + n/8) * sizeof(struct xtcpcb);
+ return 0;
+ }
+
+ if (req->newptr != 0)
+ return EPERM;
+
+ /*
+ * OK, now we're committed to doing something.
+ */
+ s = splnet();
+ gencnt = tcbinfo.ipi_gencnt;
+ n = tcbinfo.ipi_count;
+ splx(s);
+
+ xig.xig_len = sizeof xig;
+ xig.xig_count = n;
+ xig.xig_gen = gencnt;
+ xig.xig_sogen = so_gencnt;
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ if (error)
+ return error;
+
+ inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
+ if (inp_list == 0)
+ return ENOMEM;
+
+ s = splnet();
+ for (inp = tcbinfo.listhead->lh_first, i = 0; inp && i < n;
+ inp = inp->inp_list.le_next) {
+ if (inp->inp_gencnt <= gencnt)
+ inp_list[i++] = inp;
+ }
+ splx(s);
+ n = i;
+
+ error = 0;
+ for (i = 0; i < n; i++) {
+ inp = inp_list[i];
+ if (inp->inp_gencnt <= gencnt) {
+ struct xtcpcb xt;
+ xt.xt_len = sizeof xt;
+ /* XXX should avoid extra copy */
+ bcopy(inp, &xt.xt_inp, sizeof *inp);
+ bcopy(inp->inp_ppcb, &xt.xt_tp, sizeof xt.xt_tp);
+ if (inp->inp_socket)
+ sotoxsocket(inp->inp_socket, &xt.xt_socket);
+ error = SYSCTL_OUT(req, &xt, sizeof xt);
+ }
+ }
+ if (!error) {
+ /*
+ * Give the user an updated idea of our state.
+ * If the generation differs from what we told
+ * her before, she knows that something happened
+ * while we were processing this request, and it
+ * might be necessary to retry.
+ */
+ s = splnet();
+ xig.xig_gen = tcbinfo.ipi_gencnt;
+ xig.xig_sogen = so_gencnt;
+ xig.xig_count = tcbinfo.ipi_count;
+ splx(s);
+ error = SYSCTL_OUT(req, &xig, sizeof xig);
+ }
+ free(inp_list, M_TEMP);
+ return error;
+}
+
+SYSCTL_PROC(_net_inet_tcp, TCPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0,
+ tcp_pcblist, "S,xtcpcb", "List of active TCP connections");
+
void
tcp_ctlinput(cmd, sa, vip)
int cmd;
@@ -517,10 +588,8 @@ tcp_ctlinput(cmd, sa, vip)
if (cmd == PRC_QUENCH)
notify = tcp_quench;
-#if 1
else if (cmd == PRC_MSGSIZE)
notify = tcp_mtudisc;
-#endif
else if (!PRC_IS_REDIRECT(cmd) &&
((unsigned)cmd > PRC_NCMDS || inetctlerrmap[cmd] == 0))
return;
@@ -548,7 +617,6 @@ tcp_quench(inp, errno)
tp->snd_cwnd = tp->t_maxseg;
}
-#if 1
/*
* When `need fragmentation' ICMP is received, update our idea of the MSS
* based on the new value in the route. Also nudge TCP to send something,
@@ -623,7 +691,6 @@ tcp_mtudisc(inp, errno)
tcp_output(tp);
}
}
-#endif
/*
* Look-up the routing entry to the peer of this inpcb. If no route
OpenPOWER on IntegriCloud