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
This commit is contained in:
parent
4c7c478d0f
commit
14ba8add01
@ -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;
|
||||
|
@ -578,32 +578,18 @@ rip_attach(struct socket *so, int proto, struct thread *td)
|
||||
struct inpcb *inp;
|
||||
int error;
|
||||
|
||||
/* XXX why not lower? */
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp) {
|
||||
/* XXX counter, printf */
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
if (jailed(td->td_ucred) && !jail_allow_raw_sockets) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
KASSERT(inp == NULL, ("rip_attach: inp != NULL"));
|
||||
if (jailed(td->td_ucred) && !jail_allow_raw_sockets)
|
||||
return (EPERM);
|
||||
}
|
||||
if ((error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
if ((error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL)) != 0)
|
||||
return error;
|
||||
}
|
||||
if (proto >= IPPROTO_MAX || proto < 0) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
if (proto >= IPPROTO_MAX || proto < 0)
|
||||
return EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
error = soreserve(so, rip_sendspace, rip_recvspace);
|
||||
if (error) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
error = in_pcballoc(so, &ripcbinfo, "rawinp");
|
||||
if (error) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
@ -633,6 +619,7 @@ rip_pcbdetach(struct socket *so, struct inpcb *inp)
|
||||
if (so == ip_rsvpd)
|
||||
ip_rsvp_done();
|
||||
in_pcbdetach(inp);
|
||||
in_pcbfree(inp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -640,13 +627,9 @@ rip_detach(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
/* XXX counter, printf */
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
return;
|
||||
}
|
||||
KASSERT(inp != NULL, ("rip_detach: inp == NULL"));
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
INP_LOCK(inp);
|
||||
rip_pcbdetach(so, inp);
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
@ -657,18 +640,12 @@ rip_abort(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
return; /* ??? possible? panic instead? */
|
||||
}
|
||||
KASSERT(inp != NULL, ("rip_abort: inp == NULL"));
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
INP_LOCK(inp);
|
||||
soisdisconnected(so);
|
||||
if (so->so_state & SS_NOFDREF)
|
||||
rip_pcbdetach(so, inp);
|
||||
else
|
||||
INP_UNLOCK(inp);
|
||||
rip_pcbdetach(so, inp);
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
}
|
||||
|
||||
@ -678,7 +655,7 @@ rip_disconnect(struct socket *so)
|
||||
if ((so->so_state & SS_ISCONNECTED) == 0)
|
||||
return ENOTCONN;
|
||||
rip_abort(so);
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -704,12 +681,9 @@ rip_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
ifa_ifwithaddr((struct sockaddr *)addr) == 0))
|
||||
return EADDRNOTAVAIL;
|
||||
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp != NULL, ("rip_bind: inp == NULL"));
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
INP_LOCK(inp);
|
||||
inp->inp_laddr = addr->sin_addr;
|
||||
INP_UNLOCK(inp);
|
||||
@ -730,12 +704,9 @@ rip_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
if (addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK)
|
||||
return EAFNOSUPPORT;
|
||||
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp != NULL, ("rip_connect: inp == NULL"));
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
INP_LOCK(inp);
|
||||
inp->inp_faddr = addr->sin_addr;
|
||||
soisconnected(so);
|
||||
@ -749,14 +720,9 @@ rip_shutdown(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
|
||||
INP_INFO_RLOCK(&ripcbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_RUNLOCK(&ripcbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp != NULL, ("rip_shutdown: inp == NULL"));
|
||||
INP_LOCK(inp);
|
||||
INP_INFO_RUNLOCK(&ripcbinfo);
|
||||
socantsendmore(so);
|
||||
INP_UNLOCK(inp);
|
||||
return 0;
|
||||
@ -768,28 +734,26 @@ rip_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
|
||||
{
|
||||
struct inpcb *inp;
|
||||
u_long dst;
|
||||
int ret;
|
||||
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
KASSERT(inp != NULL, ("rip_send: inp == NULL"));
|
||||
/*
|
||||
* Note: 'dst' reads below are unlocked.
|
||||
*/
|
||||
if (so->so_state & SS_ISCONNECTED) {
|
||||
if (nam) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
m_freem(m);
|
||||
return EISCONN;
|
||||
}
|
||||
dst = inp->inp_faddr.s_addr;
|
||||
dst = inp->inp_faddr.s_addr; /* Unlocked read. */
|
||||
} else {
|
||||
if (nam == NULL) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
m_freem(m);
|
||||
return ENOTCONN;
|
||||
}
|
||||
dst = ((struct sockaddr_in *)nam)->sin_addr.s_addr;
|
||||
}
|
||||
ret = rip_output(m, so, dst);
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
return ret;
|
||||
return rip_output(m, so, dst);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -934,15 +934,13 @@ udp_abort(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return; /* ??? possible? panic instead? */
|
||||
}
|
||||
KASSERT(inp != NULL, ("udp_abort: inp == NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
INP_LOCK(inp);
|
||||
soisdisconnected(so);
|
||||
in_pcbdetach(inp);
|
||||
in_pcbfree(inp);
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
}
|
||||
|
||||
@ -952,12 +950,9 @@ udp_attach(struct socket *so, int proto, struct thread *td)
|
||||
struct inpcb *inp;
|
||||
int error;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp != 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp == NULL, ("udp_attach: inp != NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
error = soreserve(so, udp_sendspace, udp_recvspace);
|
||||
if (error) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
@ -984,12 +979,9 @@ udp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
struct inpcb *inp;
|
||||
int error;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp != NULL, ("udp_bind: inp == NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
INP_LOCK(inp);
|
||||
error = in_pcbbind(inp, nam, td->td_ucred);
|
||||
INP_UNLOCK(inp);
|
||||
@ -1004,12 +996,9 @@ udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
int error;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp != NULL, ("udp_connect: inp == NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
INP_LOCK(inp);
|
||||
if (inp->inp_faddr.s_addr != INADDR_ANY) {
|
||||
INP_UNLOCK(inp);
|
||||
@ -1032,13 +1021,12 @@ udp_detach(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
}
|
||||
KASSERT(inp != NULL, ("udp_detach: inp == NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
INP_LOCK(inp);
|
||||
in_pcbdetach(inp);
|
||||
in_pcbfree(inp);
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
}
|
||||
|
||||
@ -1047,12 +1035,9 @@ udp_disconnect(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp != NULL, ("udp_disconnect: inp == NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
INP_LOCK(inp);
|
||||
if (inp->inp_faddr.s_addr == INADDR_ANY) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
@ -1075,6 +1060,7 @@ udp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
struct inpcb *inp;
|
||||
|
||||
inp = sotoinpcb(so);
|
||||
KASSERT(inp != NULL, ("udp_send: inp == NULL"));
|
||||
return udp_output(inp, m, addr, control, td);
|
||||
}
|
||||
|
||||
@ -1083,14 +1069,9 @@ udp_shutdown(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
|
||||
INP_INFO_RLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_RUNLOCK(&udbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp != NULL, ("udp_shutdown: inp == NULL"));
|
||||
INP_LOCK(inp);
|
||||
INP_INFO_RUNLOCK(&udbinfo);
|
||||
socantsendmore(so);
|
||||
INP_UNLOCK(inp);
|
||||
return 0;
|
||||
|
@ -549,27 +549,18 @@ rip6_attach(struct socket *so, int proto, struct thread *td)
|
||||
struct icmp6_filter *filter;
|
||||
int error, s;
|
||||
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
panic("rip6_attach");
|
||||
}
|
||||
if (td && (error = suser(td)) != 0) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
KASSERT(inp == NULL, ("rip6_attach: inp != NULL"));
|
||||
if (td && (error = suser(td)) != 0)
|
||||
return error;
|
||||
}
|
||||
error = soreserve(so, rip_sendspace, rip_recvspace);
|
||||
if (error) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
MALLOC(filter, struct icmp6_filter *,
|
||||
sizeof(struct icmp6_filter), M_PCB, M_NOWAIT);
|
||||
if (filter == NULL) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
if (filter == NULL)
|
||||
return ENOMEM;
|
||||
}
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
s = splnet();
|
||||
error = in_pcballoc(so, &ripcbinfo, "raw6inp");
|
||||
splx(s);
|
||||
@ -596,12 +587,8 @@ rip6_detach(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
panic("rip6_detach");
|
||||
}
|
||||
KASSERT(inp != NULL, ("rip6_detach: inp == NULL"));
|
||||
/* xxx: RSVP */
|
||||
if (so == ip6_mrouter)
|
||||
ip6_mrouter_done();
|
||||
@ -609,8 +596,10 @@ rip6_detach(struct socket *so)
|
||||
FREE(inp->in6p_icmp6filt, M_PCB);
|
||||
inp->in6p_icmp6filt = NULL;
|
||||
}
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
INP_LOCK(inp);
|
||||
in6_pcbdetach(inp);
|
||||
in6_pcbfree(inp);
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
}
|
||||
|
||||
@ -630,7 +619,7 @@ rip6_disconnect(struct socket *so)
|
||||
return ENOTCONN;
|
||||
inp->in6p_faddr = in6addr_any;
|
||||
rip6_abort(so);
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -641,6 +630,7 @@ rip6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
struct ifaddr *ia = NULL;
|
||||
int error = 0;
|
||||
|
||||
KASSERT(inp != NULL, ("rip6_bind: inp == NULL"));
|
||||
if (nam->sa_len != sizeof(*addr))
|
||||
return EINVAL;
|
||||
if (TAILQ_EMPTY(&ifnet) || addr->sin6_family != AF_INET6)
|
||||
@ -674,6 +664,7 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
struct ifnet *ifp = NULL;
|
||||
int error = 0, scope_ambiguous = 0;
|
||||
|
||||
KASSERT(inp != NULL, ("rip6_connect: inp == NULL"));
|
||||
if (nam->sa_len != sizeof(*addr))
|
||||
return EINVAL;
|
||||
if (TAILQ_EMPTY(&ifnet))
|
||||
@ -726,10 +717,9 @@ rip6_shutdown(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
|
||||
INP_INFO_RLOCK(&ripcbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
KASSERT(inp != NULL, ("rip6_shutdown: inp == NULL"));
|
||||
INP_LOCK(inp);
|
||||
INP_INFO_RUNLOCK(&ripcbinfo);
|
||||
socantsendmore(so);
|
||||
INP_UNLOCK(inp);
|
||||
return 0;
|
||||
@ -744,6 +734,7 @@ rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
|
||||
struct sockaddr_in6 *dst;
|
||||
int ret;
|
||||
|
||||
KASSERT(inp != NULL, ("rip6_send: inp == NULL"));
|
||||
INP_INFO_WLOCK(&ripcbinfo);
|
||||
/* always copy sockaddr to avoid overwrites */
|
||||
/* Unlocked read. */
|
||||
|
@ -501,20 +501,15 @@ static void
|
||||
udp6_abort(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
int s;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return; /* ??? possible? panic instead? */
|
||||
}
|
||||
soisdisconnected(so);
|
||||
s = splnet();
|
||||
KASSERT(inp != NULL, ("udp6_abort: inp == NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
INP_LOCK(inp);
|
||||
soisdisconnected(so);
|
||||
in6_pcbdetach(inp);
|
||||
in6_pcbfree(inp);
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -523,21 +518,15 @@ udp6_attach(struct socket *so, int proto, struct thread *td)
|
||||
struct inpcb *inp;
|
||||
int s, error;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp != 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
KASSERT(inp == NULL, ("udp6_attach: inp == NULL"));
|
||||
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
|
||||
error = soreserve(so, udp_sendspace, udp_recvspace);
|
||||
if (error) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
s = splnet();
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
error = in_pcballoc(so, &udbinfo, "udp6inp");
|
||||
splx(s);
|
||||
if (error) {
|
||||
@ -569,12 +558,9 @@ udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
struct inpcb *inp;
|
||||
int s, error;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp != NULL, ("udp6_bind: inp == NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
INP_LOCK(inp);
|
||||
|
||||
inp->inp_vflag &= ~INP_IPV4;
|
||||
@ -614,14 +600,10 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
struct inpcb *inp;
|
||||
int s, error;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp != NULL, ("udp6_connect: inp == NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
INP_LOCK(inp);
|
||||
|
||||
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
|
||||
struct sockaddr_in6 *sin6_p;
|
||||
|
||||
@ -669,18 +651,13 @@ static void
|
||||
udp6_detach(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
int s;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return;
|
||||
}
|
||||
KASSERT(inp != NULL, ("udp6_detach: inp == NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
INP_LOCK(inp);
|
||||
s = splnet();
|
||||
in6_pcbdetach(inp);
|
||||
splx(s);
|
||||
in6_pcbfree(inp);
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
}
|
||||
|
||||
@ -690,12 +667,9 @@ udp6_disconnect(struct socket *so)
|
||||
struct inpcb *inp;
|
||||
int error, s;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp != NULL, ("udp6_disconnect: inp == NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
INP_LOCK(inp);
|
||||
|
||||
#ifdef INET
|
||||
@ -732,13 +706,9 @@ udp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
struct inpcb *inp;
|
||||
int error = 0;
|
||||
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
m_freem(m);
|
||||
return EINVAL;
|
||||
}
|
||||
KASSERT(inp != NULL, ("udp6_send: inp == NULL"));
|
||||
INP_INFO_WLOCK(&udbinfo);
|
||||
INP_LOCK(inp);
|
||||
|
||||
if (addr) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user