diff options
author | dg <dg@FreeBSD.org> | 1995-04-10 08:52:45 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1995-04-10 08:52:45 +0000 |
commit | 01191f6af457073796bd244ad734dfce0d3cda8e (patch) | |
tree | 81a803c6b995f161cb6f9e878faaa6c803fca26c /sys/netinet/in_pcb.c | |
parent | 22728a4eac36b0827a82cb67e0fbb652c00ae0e5 (diff) | |
download | FreeBSD-src-01191f6af457073796bd244ad734dfce0d3cda8e.zip FreeBSD-src-01191f6af457073796bd244ad734dfce0d3cda8e.tar.gz |
Added splnet protections for PCB list manipulations and traversals.
Diffstat (limited to 'sys/netinet/in_pcb.c')
-rw-r--r-- | sys/netinet/in_pcb.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index ed48027..3a4c552 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)in_pcb.c 8.2 (Berkeley) 1/4/94 - * $Id: in_pcb.c,v 1.8 1995/03/16 18:14:51 bde Exp $ + * $Id: in_pcb.c,v 1.9 1995/04/09 01:29:18 davidg Exp $ */ #include <sys/param.h> @@ -65,6 +65,7 @@ in_pcballoc(so, pcbinfo) struct inpcbinfo *pcbinfo; { register struct inpcb *inp; + int s; MALLOC(inp, struct inpcb *, sizeof(*inp), M_PCB, M_NOWAIT); if (inp == NULL) @@ -72,8 +73,10 @@ in_pcballoc(so, pcbinfo) bzero((caddr_t)inp, sizeof(*inp)); inp->inp_pcbinfo = pcbinfo; inp->inp_socket = so; + s = splnet(); LIST_INSERT_HEAD(pcbinfo->listhead, inp, inp_list); in_pcbinshash(inp); + splx(s); so->so_pcb = (caddr_t)inp; return (0); } @@ -335,6 +338,7 @@ in_pcbdetach(inp) struct inpcb *inp; { struct socket *so = inp->inp_socket; + int s; so->so_pcb = 0; sofree(so); @@ -343,8 +347,10 @@ in_pcbdetach(inp) if (inp->inp_route.ro_rt) rtfree(inp->inp_route.ro_rt); ip_freemoptions(inp->inp_moptions); + s = splnet(); LIST_REMOVE(inp, inp_hash); LIST_REMOVE(inp, inp_list); + splx(s); FREE(inp, M_PCB); } @@ -403,7 +409,7 @@ in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify) register struct inpcb *inp, *oinp; struct in_addr faddr; u_short fport = fport_arg, lport = lport_arg; - int errno; + int errno, s; if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET) return; @@ -426,6 +432,7 @@ in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify) notify = in_rtchange; } errno = inetctlerrmap[cmd]; + s = splnet(); for (inp = head->lh_first; inp != NULL;) { if (inp->inp_faddr.s_addr != faddr.s_addr || inp->inp_socket == 0 || @@ -440,6 +447,7 @@ in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify) if (notify) (*notify)(oinp, errno); } + splx(s); } /* @@ -505,6 +513,9 @@ in_pcblookup(head, faddr, fport_arg, laddr, lport_arg, flags) register struct inpcb *inp, *match = NULL; int matchwild = 3, wildcard; u_short fport = fport_arg, lport = lport_arg; + int s; + + s = splnet(); for (inp = head->lh_first; inp != NULL; inp = inp->inp_list.le_next) { if (inp->inp_lport != lport) @@ -539,6 +550,7 @@ in_pcblookup(head, faddr, fport_arg, laddr, lport_arg, flags) } } } + splx(s); return (match); } @@ -554,7 +566,9 @@ in_pcblookuphash(pcbinfo, faddr, fport_arg, laddr, lport_arg) struct inpcbhead *head; register struct inpcb *inp; u_short fport = fport_arg, lport = lport_arg; + int s; + s = splnet(); /* * First look for an exact match. */ @@ -574,8 +588,10 @@ in_pcblookuphash(pcbinfo, faddr, fport_arg, laddr, lport_arg) LIST_REMOVE(inp, inp_hash); LIST_INSERT_HEAD(head, inp, inp_hash); } + splx(s); return (inp); } + splx(s); /* * Didn't find an exact match, so try again looking for a matching @@ -585,6 +601,9 @@ in_pcblookuphash(pcbinfo, faddr, fport_arg, laddr, lport_arg) lport_arg, INPLOOKUP_WILDCARD)); } +/* + * Insert PCB into hash chain. Must be called at splnet. + */ void in_pcbinshash(inp) struct inpcb *inp; @@ -602,11 +621,14 @@ in_pcbrehash(inp) struct inpcb *inp; { struct inpcbhead *head; + int s; + s = splnet(); LIST_REMOVE(inp, inp_hash); head = &inp->inp_pcbinfo->hashbase[(inp->inp_faddr.s_addr + inp->inp_lport + inp->inp_fport) % inp->inp_pcbinfo->hashsize]; LIST_INSERT_HEAD(head, inp, inp_hash); + splx(s); } |