diff options
author | rwatson <rwatson@FreeBSD.org> | 2008-05-29 08:27:14 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2008-05-29 08:27:14 +0000 |
commit | 68f17e9b6872a274fd98ed5d52f202e5157b39df (patch) | |
tree | 22388d704d4fc56644136213a5896ab417d441cb /sys/netinet6/udp6_usrreq.c | |
parent | c0f6b35a3a61d7db3bbff88e6509740819efee75 (diff) | |
download | FreeBSD-src-68f17e9b6872a274fd98ed5d52f202e5157b39df.zip FreeBSD-src-68f17e9b6872a274fd98ed5d52f202e5157b39df.tar.gz |
Employ read locks on UDP inpcbs, rather than write locks, when
monitoring UDP connections using sysctls. In some cases, add
previously missing locking of inpcbs, as inp_socket is followed,
which also allows us to drop global locks more quickly.
MFC after: 1 week
Diffstat (limited to 'sys/netinet6/udp6_usrreq.c')
-rw-r--r-- | sys/netinet6/udp6_usrreq.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 161c274..a3cf3e1 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -449,20 +449,21 @@ udp6_getcred(SYSCTL_HANDLER_ARGS) inp = in6_pcblookup_hash(&udbinfo, &addrs[1].sin6_addr, addrs[1].sin6_port, &addrs[0].sin6_addr, addrs[0].sin6_port, 1, NULL); - if (inp == NULL) { + if (inp != NULL) { + INP_RLOCK(inp); + INP_INFO_RUNLOCK(&udbinfo); + if (inp->inp_socket == NULL) + error = ENOENT; + if (error == 0) + error = cr_canseesocket(req->td->td_ucred, + inp->inp_socket); + if (error == 0) + cru2x(inp->inp_socket->so_cred, &xuc); + INP_RUNLOCK(inp); + } else { INP_INFO_RUNLOCK(&udbinfo); - return (ENOENT); - } - INP_RLOCK(inp); - if (inp->inp_socket == NULL) { error = ENOENT; - goto out; } - error = cr_canseesocket(req->td->td_ucred, inp->inp_socket); - if (error) - goto out; - cru2x(inp->inp_socket->so_cred, &xuc); -out: INP_RUNLOCK(inp); INP_INFO_RUNLOCK(&udbinfo); if (error == 0) |