diff options
author | rwatson <rwatson@FreeBSD.org> | 2006-04-01 16:20:54 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2006-04-01 16:20:54 +0000 |
commit | a7c2bca553bef1485f864043c190482cc9c6fdd4 (patch) | |
tree | 60c6d1ae13c348075601004daade9dd8338f72a3 /sys/netinet/ip_divert.c | |
parent | 71cc03392bbc78f93765e5550fc35f98c373df04 (diff) | |
download | FreeBSD-src-a7c2bca553bef1485f864043c190482cc9c6fdd4.zip FreeBSD-src-a7c2bca553bef1485f864043c190482cc9c6fdd4.tar.gz |
Update in_pcb-derived basic socket types following changes to
pru_abort(), pru_detach(), and in_pcbdetach():
- Universally support and enforce the invariant that so_pcb is
never NULL, converting dozens of unnecessary NULL checks into
assertions, and eliminating dozens of unnecessary error handling
cases in protocol code.
- In some cases, eliminate unnecessary pcbinfo locking, as it is no
longer required to ensure so_pcb != NULL. For example, in protocol
shutdown methods, and in raw IP send.
- Abort and detach protocol switch methods no longer return failures,
nor attempt to free sockets, as the socket layer does this.
- Invoke in_pcbfree() after in_pcbdetach() in order to free the
detached in_pcb structure for a socket.
MFC after: 3 months
Diffstat (limited to 'sys/netinet/ip_divert.c')
-rw-r--r-- | sys/netinet/ip_divert.c | 49 |
1 files changed, 15 insertions, 34 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index bb31630..89aa4e4 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -394,21 +394,14 @@ div_attach(struct socket *so, int proto, struct thread *td) struct inpcb *inp; int error; - INP_INFO_WLOCK(&divcbinfo); inp = sotoinpcb(so); - if (inp != 0) { - INP_INFO_WUNLOCK(&divcbinfo); - return EINVAL; - } - if (td && (error = suser(td)) != 0) { - INP_INFO_WUNLOCK(&divcbinfo); + KASSERT(inp == NULL, ("div_attach: inp != NULL")); + if (td && (error = suser(td)) != 0) return error; - } error = soreserve(so, div_sendspace, div_recvspace); - if (error) { - INP_INFO_WUNLOCK(&divcbinfo); + if (error) return error; - } + INP_INFO_WLOCK(&divcbinfo); error = in_pcballoc(so, &divcbinfo, "divinp"); if (error) { INP_INFO_WUNLOCK(&divcbinfo); @@ -429,14 +422,12 @@ div_detach(struct socket *so) { struct inpcb *inp; - INP_INFO_WLOCK(&divcbinfo); inp = sotoinpcb(so); - if (inp == 0) { - INP_INFO_WUNLOCK(&divcbinfo); - return; - } + KASSERT(inp != NULL, ("div_detach: inp == NULL")); + INP_INFO_WLOCK(&divcbinfo); INP_LOCK(inp); in_pcbdetach(inp); + in_pcbfree(inp); INP_INFO_WUNLOCK(&divcbinfo); } @@ -446,12 +437,8 @@ div_bind(struct socket *so, struct sockaddr *nam, struct thread *td) struct inpcb *inp; int error; - INP_INFO_WLOCK(&divcbinfo); inp = sotoinpcb(so); - if (inp == 0) { - INP_INFO_WUNLOCK(&divcbinfo); - return EINVAL; - } + KASSERT(inp == NULL, ("div_bind: inp == NULL")); /* in_pcbbind assumes that nam is a sockaddr_in * and in_pcbbind requires a valid address. Since divert * sockets don't we need to make sure the address is @@ -460,13 +447,12 @@ div_bind(struct socket *so, struct sockaddr *nam, struct thread *td) * and should probably have its own family. */ if (nam->sa_family != AF_INET) - error = EAFNOSUPPORT; - else { - ((struct sockaddr_in *)nam)->sin_addr.s_addr = INADDR_ANY; - INP_LOCK(inp); - error = in_pcbbind(inp, nam, td->td_ucred); - INP_UNLOCK(inp); - } + return EAFNOSUPPORT; + ((struct sockaddr_in *)nam)->sin_addr.s_addr = INADDR_ANY; + INP_INFO_WLOCK(&divcbinfo); + INP_LOCK(inp); + error = in_pcbbind(inp, nam, td->td_ucred); + INP_UNLOCK(inp); INP_INFO_WUNLOCK(&divcbinfo); return error; } @@ -476,14 +462,9 @@ div_shutdown(struct socket *so) { struct inpcb *inp; - INP_INFO_RLOCK(&divcbinfo); inp = sotoinpcb(so); - if (inp == 0) { - INP_INFO_RUNLOCK(&divcbinfo); - return EINVAL; - } + KASSERT(inp != NULL, ("div_shutdown: inp == NULL")); INP_LOCK(inp); - INP_INFO_RUNLOCK(&divcbinfo); socantsendmore(so); INP_UNLOCK(inp); return 0; |