diff options
author | wollman <wollman@FreeBSD.org> | 1998-05-15 20:11:40 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1998-05-15 20:11:40 +0000 |
commit | bbc4497adab2d7702eab9a609897b2e5f672289e (patch) | |
tree | 10594c024ae545493609ccaa7de3d90faf27616a /sys/kern/uipc_socket.c | |
parent | be2e5ffcfc349cb4483b536bd57048eca466e0c9 (diff) | |
download | FreeBSD-src-bbc4497adab2d7702eab9a609897b2e5f672289e.zip FreeBSD-src-bbc4497adab2d7702eab9a609897b2e5f672289e.tar.gz |
Convert socket structures to be type-stable and add a version number.
Define a parameter which indicates the maximum number of sockets in a
system, and use this to size the zone allocators used for sockets and
for certain PCBs.
Convert PF_LOCAL PCB structures to be type-stable and add a version number.
Define an external format for infomation about socket structures and use
it in several places.
Define a mechanism to get all PF_LOCAL and PF_INET PCB lists through
sysctl(3) without blocking network interrupts for an unreasonable
length of time. This probably still has some bugs and/or race
conditions, but it seems to work well enough on my machines.
It is now possible for `netstat' to get almost all of its information
via the sysctl(3) interface rather than reading kmem (changes to follow).
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r-- | sys/kern/uipc_socket.c | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 58e309a..2ca79fc 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94 - * $Id: uipc_socket.c,v 1.38 1998/03/01 19:39:17 guido Exp $ + * $Id: uipc_socket.c,v 1.39 1998/03/28 10:33:08 bde Exp $ */ #include <sys/param.h> @@ -50,10 +50,13 @@ #include <sys/signalvar.h> #include <sys/sysctl.h> #include <sys/uio.h> +#include <vm/vm_zone.h> #include <machine/limits.h> -MALLOC_DEFINE(M_SOCKET, "socket", "socket structure"); +struct vm_zone *socket_zone; +so_gen_t so_gencnt; /* generation count for sockets */ + MALLOC_DEFINE(M_SONAME, "soname", "socket name"); MALLOC_DEFINE(M_PCB, "pcb", "protocol control block"); @@ -68,7 +71,30 @@ SYSCTL_INT(_kern_ipc, KIPC_SOMAXCONN, somaxconn, CTLFLAG_RW, &somaxconn, * implement the semantics of socket operations by * switching out to the protocol specific routines. */ -/*ARGSUSED*/ + +/* + * Get a socket structure from our zone, and initialize it. + * We don't implement `waitok' yet (see comments in uipc_domain.c). + * Note that it would probably be better to allocate socket + * and PCB at the same time, but I'm not convinced that all + * the protocols can be easily modified to do this. + */ +struct socket * +soalloc(waitok) + int waitok; +{ + struct socket *so; + + so = zalloci(socket_zone); + if (so) { + /* XXX race condition for reentrant kernel */ + bzero(so, sizeof *so); + so->so_gencnt = ++so_gencnt; + so->so_zone = socket_zone; + } + return so; +} + int socreate(dom, aso, type, proto, p) int dom; @@ -89,12 +115,15 @@ socreate(dom, aso, type, proto, p) return (EPROTONOSUPPORT); if (prp->pr_type != type) return (EPROTOTYPE); - MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_WAIT); - bzero((caddr_t)so, sizeof(*so)); + so = soalloc(p != 0); + if (so == 0) + return (ENOBUFS); + TAILQ_INIT(&so->so_incomp); TAILQ_INIT(&so->so_comp); so->so_type = type; - so->so_uid = p->p_ucred->cr_uid;; + if (p != 0) + so->so_uid = p->p_ucred->cr_uid; so->so_proto = prp; error = (*prp->pr_usrreqs->pru_attach)(so, proto, p); if (error) { @@ -120,14 +149,23 @@ sobind(so, nam, p) return (error); } +void +sodealloc(so) + struct socket *so; +{ + so->so_gencnt = ++so_gencnt; + zfreei(so->so_zone, so); +} + int solisten(so, backlog, p) register struct socket *so; int backlog; struct proc *p; { - int s = splnet(), error; + int s, error; + s = splnet(); error = (*so->so_proto->pr_usrreqs->pru_listen)(so, p); if (error) { splx(s); @@ -165,7 +203,7 @@ sofree(so) } sbrelease(&so->so_snd); sorflush(so); - FREE(so, M_SOCKET); + sodealloc(so); } /* |