diff options
author | tanimura <tanimura@FreeBSD.org> | 2002-05-20 05:41:09 +0000 |
---|---|---|
committer | tanimura <tanimura@FreeBSD.org> | 2002-05-20 05:41:09 +0000 |
commit | 92d8381dd544a8237b3fd68c4e7fce9bd0903fb2 (patch) | |
tree | 2465ddbcecac65f96c5c6d5cef1a4fe3f1ac03f8 /sys/netns/idp_usrreq.c | |
parent | 969293170b27461145f69a538d5abd15fea34ba1 (diff) | |
download | FreeBSD-src-92d8381dd544a8237b3fd68c4e7fce9bd0903fb2.zip FreeBSD-src-92d8381dd544a8237b3fd68c4e7fce9bd0903fb2.tar.gz |
Lock down a socket, milestone 1.
o Add a mutex (sb_mtx) to struct sockbuf. This protects the data in a
socket buffer. The mutex in the receive buffer also protects the data
in struct socket.
o Determine the lock strategy for each members in struct socket.
o Lock down the following members:
- so_count
- so_options
- so_linger
- so_state
o Remove *_locked() socket APIs. Make the following socket APIs
touching the members above now require a locked socket:
- sodisconnect()
- soisconnected()
- soisconnecting()
- soisdisconnected()
- soisdisconnecting()
- sofree()
- soref()
- sorele()
- sorwakeup()
- sotryfree()
- sowakeup()
- sowwakeup()
Reviewed by: alfred
Diffstat (limited to 'sys/netns/idp_usrreq.c')
-rw-r--r-- | sys/netns/idp_usrreq.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/sys/netns/idp_usrreq.c b/sys/netns/idp_usrreq.c index 5203961..6ca054d 100644 --- a/sys/netns/idp_usrreq.c +++ b/sys/netns/idp_usrreq.c @@ -97,7 +97,9 @@ idp_input(m, nsp) if (sbappendaddr(&nsp->nsp_socket->so_rcv, (struct sockaddr *)&idp_ns, m, (struct mbuf *)0) == 0) goto bad; + SOCK_LOCK(nsp->nsp_socket); sorwakeup(nsp->nsp_socket); + SOCK_UNLOCK(nsp->nsp_socket); return; bad: m_freem(m); @@ -109,7 +111,9 @@ idp_abort(nsp) struct socket *so = nsp->nsp_socket; ns_pcbdisconnect(nsp); + SOCK_LOCK(so); soisdisconnected(so); + SOCK_UNLOCK(so); } /* * Drop connection, reporting @@ -133,7 +137,9 @@ idp_drop(nsp, errno) }*/ so->so_error = errno; ns_pcbdisconnect(nsp); + SOCK_LOCK(so); soisdisconnected(so); + SOCK_UNLOCK(so); } int noIdpRoute; @@ -148,6 +154,7 @@ idp_output(nsp, m0) register struct route *ro; struct mbuf *mprev; extern int idpcksum; + int soopts; /* * Calculate data length. @@ -211,9 +218,14 @@ idp_output(nsp, m0) * Output datagram. */ so = nsp->nsp_socket; - if (so->so_options & SO_DONTROUTE) + SOCK_LOCK(so); + if (so->so_options & SO_DONTROUTE) { + soopts = so->so_options & SO_BROADCAST; + SO_UNLOCK(so); return (ns_output(m, (struct route *)0, - (so->so_options & SO_BROADCAST) | NS_ROUTETOIF)); + soopts | NS_ROUTETOIF)); + } + SO_UNLOCK(so); /* * Use cached route for previous datagram if * possible. If the previous net was the same @@ -257,7 +269,10 @@ idp_output(nsp, m0) nsp->nsp_lastdst = idp->idp_dna; #endif /* ancient_history */ if (noIdpRoute) ro = 0; - return (ns_output(m, ro, so->so_options & SO_BROADCAST)); + SOCK_LOCK(so); + soopts = so->so_options & SO_BROADCAST; + SOCK_UNLOCK(so); + return (ns_output(m, ro, soopts)); } /* ARGSUSED */ idp_ctloutput(req, so, level, name, value) @@ -427,8 +442,11 @@ idp_usrreq(so, req, m, nam, control) break; } error = ns_pcbconnect(nsp, nam); - if (error == 0) + if (error == 0) { + SOCK_LOCK(so); soisconnected(so); + SOCK_UNLOCK(so); + } break; case PRU_CONNECT2: @@ -445,7 +463,9 @@ idp_usrreq(so, req, m, nam, control) break; } ns_pcbdisconnect(nsp); + SOCK_LOCK(so); soisdisconnected(so); + SOCK_UNLOCK(so); break; case PRU_SHUTDOWN: @@ -491,8 +511,11 @@ idp_usrreq(so, req, m, nam, control) case PRU_ABORT: ns_pcbdetach(nsp); + SOCK_LOCK(so); sotryfree(so); + SOCK_LOCK(so); soisdisconnected(so); /* XXX huh, called after sofree()? */ + SOCK_UNLOCK(so); break; case PRU_SOCKADDR: @@ -546,10 +569,13 @@ idp_raw_usrreq(so, req, m, nam, control) case PRU_ATTACH: + SOCK_LOCK(so); if (!(so->so_state & SS_PRIV) || (nsp != NULL)) { + SOCK_UNLOCK(so); error = EINVAL; break; } + SOCK_UNLOCK(so); error = ns_pcballoc(so, &nsrawpcb); if (error) break; |