Chance protocol switch method pru_detach() so that it returns void
rather than an error. Detaches do not "fail", they other occur or the protocol flags SS_PROTOREF to take ownership of the socket. soclose() no longer looks at so_pcb to see if it's NULL, relying entirely on the protocol to decide whether it's time to free the socket or not using SS_PROTOREF. so_pcb is now entirely owned and managed by the protocol code. Likewise, no longer test so_pcb in other socket functions, such as soreceive(), which have no business digging into protocol internals. Protocol detach routines no longer try to free the socket on detach, this is performed in the socket code if the protocol permits it. In rts_detach(), no longer test for rp != NULL in detach, and likewise in other protocols that don't permit a NULL so_pcb, reduce the incidence of testing for it during detach. netinet and netinet6 are not fully updated to this change, which will be in an upcoming commit. In their current state they may leak memory or panic. MFC after: 3 months
This commit is contained in:
parent
f7f45ac8e2
commit
bc725eafc7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=157370
@ -1335,10 +1335,10 @@ pru_control_notsupp(struct socket *so, u_long cmd, caddr_t data,
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
pru_detach_notsupp(struct socket *so)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -387,13 +387,18 @@ solisten_proto(so, backlog)
|
||||
/*
|
||||
* Attempt to free a socket. This should really be sotryfree().
|
||||
*
|
||||
* We free the socket if the protocol is no longer interested in the socket,
|
||||
* there's no file descriptor reference, and the refcount is 0. While the
|
||||
* calling macro sotryfree() tests the refcount, sofree() has to test it
|
||||
* again as it's possible to race with an accept()ing thread if the socket is
|
||||
* in an listen queue of a listen socket, as being in the listen queue
|
||||
* doesn't elevate the reference count. sofree() acquires the accept mutex
|
||||
* early for this test in order to avoid that race.
|
||||
* sofree() will succeed if:
|
||||
*
|
||||
* - There are no outstanding file descriptor references or related consumers
|
||||
* (so_count == 0).
|
||||
*
|
||||
* - The socket has been closed by user space, if ever open (SS_NOFDREF).
|
||||
*
|
||||
* - The protocol does not have an outstanding strong reference on the socket
|
||||
* (SS_PROTOREF).
|
||||
*
|
||||
* Otherwise, it will quietly abort so that a future call to sofree(), when
|
||||
* conditions are right, can succeed.
|
||||
*/
|
||||
void
|
||||
sofree(so)
|
||||
@ -404,8 +409,8 @@ sofree(so)
|
||||
ACCEPT_LOCK_ASSERT();
|
||||
SOCK_LOCK_ASSERT(so);
|
||||
|
||||
if (so->so_pcb != NULL || (so->so_state & SS_NOFDREF) == 0 ||
|
||||
so->so_count != 0 || (so->so_state & SS_PROTOREF)) {
|
||||
if ((so->so_state & SS_NOFDREF) == 0 || so->so_count != 0 ||
|
||||
(so->so_state & SS_PROTOREF)) {
|
||||
SOCK_UNLOCK(so);
|
||||
ACCEPT_UNLOCK();
|
||||
return;
|
||||
@ -447,6 +452,7 @@ sofree(so)
|
||||
so->so_qstate & SQ_COMP, so->so_qstate & SQ_INCOMP));
|
||||
SOCK_UNLOCK(so);
|
||||
ACCEPT_UNLOCK();
|
||||
|
||||
SOCKBUF_LOCK(&so->so_snd);
|
||||
so->so_snd.sb_flags |= SB_NOINTR;
|
||||
(void)sblock(&so->so_snd, M_WAITOK);
|
||||
@ -507,8 +513,6 @@ soclose(so)
|
||||
}
|
||||
ACCEPT_UNLOCK();
|
||||
}
|
||||
if (so->so_pcb == NULL)
|
||||
goto discard;
|
||||
if (so->so_state & SS_ISCONNECTED) {
|
||||
if ((so->so_state & SS_ISDISCONNECTING) == 0) {
|
||||
error = sodisconnect(so);
|
||||
@ -527,13 +531,9 @@ soclose(so)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drop:
|
||||
if (so->so_pcb != NULL) {
|
||||
int error2 = (*so->so_proto->pr_usrreqs->pru_detach)(so);
|
||||
if (error == 0)
|
||||
error = error2;
|
||||
}
|
||||
discard:
|
||||
(*so->so_proto->pr_usrreqs->pru_detach)(so);
|
||||
ACCEPT_LOCK();
|
||||
SOCK_LOCK(so);
|
||||
KASSERT((so->so_state & SS_NOFDREF) == 0, ("soclose: NOFDREF"));
|
||||
@ -1602,7 +1602,7 @@ soreceive(so, psa, uio, mp0, controlp, flagsp)
|
||||
* Notify the protocol that some data has been
|
||||
* drained before blocking.
|
||||
*/
|
||||
if (pr->pr_flags & PR_WANTRCVD && so->so_pcb != NULL) {
|
||||
if (pr->pr_flags & PR_WANTRCVD) {
|
||||
SOCKBUF_UNLOCK(&so->so_rcv);
|
||||
(*pr->pr_usrreqs->pru_rcvd)(so, flags);
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
@ -1646,7 +1646,7 @@ soreceive(so, psa, uio, mp0, controlp, flagsp)
|
||||
* ACK will be generated on return to TCP.
|
||||
*/
|
||||
if (!(flags & MSG_SOCALLBCK) &&
|
||||
(pr->pr_flags & PR_WANTRCVD) && so->so_pcb) {
|
||||
(pr->pr_flags & PR_WANTRCVD)) {
|
||||
SOCKBUF_UNLOCK(&so->so_rcv);
|
||||
(*pr->pr_usrreqs->pru_rcvd)(so, flags);
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
|
@ -1335,10 +1335,10 @@ pru_control_notsupp(struct socket *so, u_long cmd, caddr_t data,
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
pru_detach_notsupp(struct socket *so)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -228,7 +228,7 @@ uipc_connect2(struct socket *so1, struct socket *so2)
|
||||
|
||||
/* control is EOPNOTSUPP */
|
||||
|
||||
static int
|
||||
static void
|
||||
uipc_detach(struct socket *so)
|
||||
{
|
||||
struct unpcb *unp;
|
||||
@ -238,7 +238,6 @@ uipc_detach(struct socket *so)
|
||||
UNP_LOCK();
|
||||
unp_detach(unp);
|
||||
UNP_UNLOCK_ASSERT();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -98,10 +98,9 @@ raw_detach(rp)
|
||||
{
|
||||
struct socket *so = rp->rcb_socket;
|
||||
|
||||
ACCEPT_LOCK();
|
||||
SOCK_LOCK(so);
|
||||
so->so_pcb = 0;
|
||||
sotryfree(so);
|
||||
KASSERT(so->so_pcb == rp, ("raw_detach: so_pcb != rp"));
|
||||
|
||||
so->so_pcb = NULL;
|
||||
mtx_lock(&rawcb_mtx);
|
||||
LIST_REMOVE(rp, list);
|
||||
mtx_unlock(&rawcb_mtx);
|
||||
|
@ -178,16 +178,15 @@ raw_uconnect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
/* pru_connect2 is EOPNOTSUPP */
|
||||
/* pru_control is EOPNOTSUPP */
|
||||
|
||||
static int
|
||||
static void
|
||||
raw_udetach(struct socket *so)
|
||||
{
|
||||
struct rawcb *rp = sotorawcb(so);
|
||||
|
||||
if (rp == 0)
|
||||
return EINVAL;
|
||||
return;
|
||||
|
||||
raw_detach(rp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -152,8 +152,8 @@ rts_attach(struct socket *so, int proto, struct thread *td)
|
||||
struct rawcb *rp;
|
||||
int s, error;
|
||||
|
||||
if (sotorawcb(so) != NULL)
|
||||
return EISCONN; /* XXX panic? */
|
||||
KASSERT(so->so_pcb == NULL, ("rts_attach: so_pcb != NULL"));
|
||||
|
||||
/* XXX */
|
||||
MALLOC(rp, struct rawcb *, sizeof *rp, M_PCB, M_WAITOK | M_ZERO);
|
||||
if (rp == NULL)
|
||||
@ -214,32 +214,28 @@ rts_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
/* pru_connect2 is EOPNOTSUPP */
|
||||
/* pru_control is EOPNOTSUPP */
|
||||
|
||||
static int
|
||||
static void
|
||||
rts_detach(struct socket *so)
|
||||
{
|
||||
struct rawcb *rp = sotorawcb(so);
|
||||
int s, error;
|
||||
|
||||
s = splnet();
|
||||
if (rp != NULL) {
|
||||
RTSOCK_LOCK();
|
||||
switch(rp->rcb_proto.sp_protocol) {
|
||||
case AF_INET:
|
||||
route_cb.ip_count--;
|
||||
break;
|
||||
case AF_INET6:
|
||||
route_cb.ip6_count--;
|
||||
break;
|
||||
case AF_IPX:
|
||||
route_cb.ipx_count--;
|
||||
break;
|
||||
}
|
||||
route_cb.any_count--;
|
||||
RTSOCK_UNLOCK();
|
||||
KASSERT(rp != NULL, ("rts_detach: rp == NULL"));
|
||||
|
||||
RTSOCK_LOCK();
|
||||
switch(rp->rcb_proto.sp_protocol) {
|
||||
case AF_INET:
|
||||
route_cb.ip_count--;
|
||||
break;
|
||||
case AF_INET6:
|
||||
route_cb.ip6_count--;
|
||||
break;
|
||||
case AF_IPX:
|
||||
route_cb.ipx_count--;
|
||||
break;
|
||||
}
|
||||
error = raw_usrreqs.pru_detach(so);
|
||||
splx(s);
|
||||
return error;
|
||||
route_cb.any_count--;
|
||||
RTSOCK_UNLOCK();
|
||||
raw_usrreqs.pru_detach(so);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -72,7 +72,7 @@ ddp_attach(struct socket *so, int proto, struct thread *td)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
ddp_detach(struct socket *so)
|
||||
{
|
||||
struct ddpcb *ddp;
|
||||
@ -84,7 +84,6 @@ ddp_detach(struct socket *so)
|
||||
DDP_LOCK(ddp);
|
||||
at_pcbdetach(so, ddp);
|
||||
DDP_LIST_XUNLOCK();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -66,7 +66,7 @@ u_long atm_aal5_recvspace = 64 * 1024; /* XXX */
|
||||
* Local functions
|
||||
*/
|
||||
static int atm_aal5_attach(struct socket *, int, struct thread *td);
|
||||
static int atm_aal5_detach(struct socket *);
|
||||
static void atm_aal5_detach(struct socket *);
|
||||
static int atm_aal5_bind(struct socket *, struct sockaddr *,
|
||||
struct thread *td);
|
||||
static int atm_aal5_listen(struct socket *, int backlog,
|
||||
@ -290,15 +290,15 @@ atm_aal5_attach(so, proto, td)
|
||||
* errno error processing request - reason indicated
|
||||
*
|
||||
*/
|
||||
static int
|
||||
static void
|
||||
atm_aal5_detach(so)
|
||||
struct socket *so;
|
||||
{
|
||||
ATM_INTRO("detach");
|
||||
ATM_INTRO_NOERR("detach");
|
||||
|
||||
err = atm_sock_detach(so);
|
||||
atm_sock_detach(so);
|
||||
|
||||
ATM_OUTRO();
|
||||
ATM_OUTRO_NOERR();
|
||||
}
|
||||
|
||||
|
||||
|
@ -146,12 +146,8 @@ atm_sock_attach(so, send, recv)
|
||||
* Arguments:
|
||||
* so pointer to socket
|
||||
*
|
||||
* Returns:
|
||||
* 0 detach successful
|
||||
* errno detach failed - reason indicated
|
||||
*
|
||||
*/
|
||||
int
|
||||
void
|
||||
atm_sock_detach(so)
|
||||
struct socket *so;
|
||||
{
|
||||
@ -160,8 +156,7 @@ atm_sock_detach(so)
|
||||
/*
|
||||
* Make sure we're still attached
|
||||
*/
|
||||
if (atp == NULL)
|
||||
return (ENOTCONN);
|
||||
KASSERT(atp != NULL, ("atm_sock_detach: atp == NULL"));
|
||||
|
||||
/*
|
||||
* Terminate any (possibly pending) connection
|
||||
@ -170,17 +165,9 @@ atm_sock_detach(so)
|
||||
(void) atm_sock_disconnect(so);
|
||||
}
|
||||
|
||||
/*
|
||||
* Break links and free control blocks
|
||||
*/
|
||||
ACCEPT_LOCK();
|
||||
SOCK_LOCK(so);
|
||||
so->so_pcb = NULL;
|
||||
sotryfree(so);
|
||||
|
||||
uma_zfree(atm_pcb_zone, atp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,7 +70,7 @@ struct pr_usrreqs atm_dgram_usrreqs = {
|
||||
.pru_attach = atm_dgram_attach,
|
||||
.pru_bind = atm_proto_notsupp2,
|
||||
.pru_control = atm_dgram_control,
|
||||
.pru_detach = atm_proto_notsupp1,
|
||||
.pru_detach = atm_proto_notsupp5,
|
||||
.pru_disconnect = atm_proto_notsupp1,
|
||||
.pru_peeraddr = atm_proto_notsupp3,
|
||||
.pru_send = atm_proto_notsupp4,
|
||||
|
@ -151,7 +151,7 @@ int atm_create_stack(Atm_connvc *, struct stack_list *,
|
||||
/* atm_socket.c */
|
||||
void atm_sock_init(void);
|
||||
int atm_sock_attach(struct socket *, u_long, u_long);
|
||||
int atm_sock_detach(struct socket *);
|
||||
void atm_sock_detach(struct socket *);
|
||||
int atm_sock_bind(struct socket *, struct sockaddr *);
|
||||
int atm_sock_listen(struct socket *, Atm_endpoint *, int);
|
||||
int atm_sock_connect(struct socket *, struct sockaddr *,
|
||||
|
@ -75,7 +75,7 @@ int ng_btsocket_hci_raw_connect (struct socket *, struct sockaddr *,
|
||||
int ng_btsocket_hci_raw_control (struct socket *, u_long, caddr_t,
|
||||
struct ifnet *, struct thread *);
|
||||
int ng_btsocket_hci_raw_ctloutput (struct socket *, struct sockopt *);
|
||||
int ng_btsocket_hci_raw_detach (struct socket *);
|
||||
void ng_btsocket_hci_raw_detach (struct socket *);
|
||||
int ng_btsocket_hci_raw_disconnect (struct socket *);
|
||||
int ng_btsocket_hci_raw_peeraddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_hci_raw_send (struct socket *, int, struct mbuf *,
|
||||
|
@ -100,7 +100,7 @@ int ng_btsocket_l2cap_raw_connect (struct socket *, struct sockaddr *,
|
||||
struct thread *);
|
||||
int ng_btsocket_l2cap_raw_control (struct socket *, u_long, caddr_t,
|
||||
struct ifnet *, struct thread *);
|
||||
int ng_btsocket_l2cap_raw_detach (struct socket *);
|
||||
void ng_btsocket_l2cap_raw_detach (struct socket *);
|
||||
int ng_btsocket_l2cap_raw_disconnect (struct socket *);
|
||||
int ng_btsocket_l2cap_raw_peeraddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_l2cap_raw_send (struct socket *, int, struct mbuf *,
|
||||
@ -193,7 +193,7 @@ int ng_btsocket_l2cap_connect (struct socket *, struct sockaddr *,
|
||||
int ng_btsocket_l2cap_control (struct socket *, u_long, caddr_t,
|
||||
struct ifnet *, struct thread *);
|
||||
int ng_btsocket_l2cap_ctloutput (struct socket *, struct sockopt *);
|
||||
int ng_btsocket_l2cap_detach (struct socket *);
|
||||
void ng_btsocket_l2cap_detach (struct socket *);
|
||||
int ng_btsocket_l2cap_disconnect (struct socket *);
|
||||
int ng_btsocket_l2cap_listen (struct socket *, int, struct thread *);
|
||||
int ng_btsocket_l2cap_peeraddr (struct socket *, struct sockaddr **);
|
||||
|
@ -324,7 +324,7 @@ int ng_btsocket_rfcomm_connect (struct socket *, struct sockaddr *,
|
||||
int ng_btsocket_rfcomm_control (struct socket *, u_long, caddr_t,
|
||||
struct ifnet *, struct thread *);
|
||||
int ng_btsocket_rfcomm_ctloutput (struct socket *, struct sockopt *);
|
||||
int ng_btsocket_rfcomm_detach (struct socket *);
|
||||
void ng_btsocket_rfcomm_detach (struct socket *);
|
||||
int ng_btsocket_rfcomm_disconnect (struct socket *);
|
||||
int ng_btsocket_rfcomm_listen (struct socket *, int, struct thread *);
|
||||
int ng_btsocket_rfcomm_peeraddr (struct socket *, struct sockaddr **);
|
||||
|
@ -1399,15 +1399,15 @@ ng_btsocket_hci_raw_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
* Detach raw HCI socket
|
||||
*/
|
||||
|
||||
int
|
||||
void
|
||||
ng_btsocket_hci_raw_detach(struct socket *so)
|
||||
{
|
||||
ng_btsocket_hci_raw_pcb_p pcb = so2hci_raw_pcb(so);
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
KASSERT(pcb != NULL, ("ng_btsocket_hci_raw_detach: pcb == NULL"));
|
||||
|
||||
if (ng_btsocket_hci_raw_node == NULL)
|
||||
return (EINVAL);
|
||||
return;
|
||||
|
||||
mtx_lock(&ng_btsocket_hci_raw_sockets_mtx);
|
||||
mtx_lock(&pcb->pcb_mtx);
|
||||
@ -1422,12 +1422,7 @@ ng_btsocket_hci_raw_detach(struct socket *so)
|
||||
bzero(pcb, sizeof(*pcb));
|
||||
FREE(pcb, M_NETGRAPH_BTSOCKET_HCI_RAW);
|
||||
|
||||
ACCEPT_LOCK();
|
||||
SOCK_LOCK(so);
|
||||
so->so_pcb = NULL;
|
||||
sotryfree(so);
|
||||
|
||||
return (0);
|
||||
} /* ng_btsocket_hci_raw_detach */
|
||||
|
||||
/*
|
||||
|
@ -2316,15 +2316,15 @@ ng_btsocket_l2cap_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
* Detach and destroy socket
|
||||
*/
|
||||
|
||||
int
|
||||
void
|
||||
ng_btsocket_l2cap_detach(struct socket *so)
|
||||
{
|
||||
ng_btsocket_l2cap_pcb_p pcb = so2l2cap_pcb(so);
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
KASSERT(pcb != NULL, ("ng_btsocket_l2cap_detach: pcb == NULL"));
|
||||
|
||||
if (ng_btsocket_l2cap_node == NULL)
|
||||
return (EINVAL);
|
||||
return;
|
||||
|
||||
mtx_lock(&ng_btsocket_l2cap_sockets_mtx);
|
||||
mtx_lock(&pcb->pcb_mtx);
|
||||
@ -2350,12 +2350,7 @@ ng_btsocket_l2cap_detach(struct socket *so)
|
||||
FREE(pcb, M_NETGRAPH_BTSOCKET_L2CAP);
|
||||
|
||||
soisdisconnected(so);
|
||||
ACCEPT_LOCK();
|
||||
SOCK_LOCK(so);
|
||||
so->so_pcb = NULL;
|
||||
sotryfree(so);
|
||||
|
||||
return (0);
|
||||
} /* ng_btsocket_l2cap_detach */
|
||||
|
||||
/*
|
||||
|
@ -1094,15 +1094,14 @@ ng_btsocket_l2cap_raw_control(struct socket *so, u_long cmd, caddr_t data,
|
||||
* Detach and destroy socket
|
||||
*/
|
||||
|
||||
int
|
||||
void
|
||||
ng_btsocket_l2cap_raw_detach(struct socket *so)
|
||||
{
|
||||
ng_btsocket_l2cap_raw_pcb_p pcb = so2l2cap_raw_pcb(so);
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
KASSERT(pcb != NULL, ("nt_btsocket_l2cap_raw_detach: pcb == NULL"));
|
||||
if (ng_btsocket_l2cap_raw_node == NULL)
|
||||
return (EINVAL);
|
||||
return;
|
||||
|
||||
mtx_lock(&ng_btsocket_l2cap_raw_sockets_mtx);
|
||||
mtx_lock(&pcb->pcb_mtx);
|
||||
@ -1117,12 +1116,7 @@ ng_btsocket_l2cap_raw_detach(struct socket *so)
|
||||
bzero(pcb, sizeof(*pcb));
|
||||
FREE(pcb, M_NETGRAPH_BTSOCKET_L2CAP_RAW);
|
||||
|
||||
ACCEPT_LOCK();
|
||||
SOCK_LOCK(so);
|
||||
so->so_pcb = NULL;
|
||||
sotryfree(so);
|
||||
|
||||
return (0);
|
||||
} /* ng_btsocket_l2cap_raw_detach */
|
||||
|
||||
/*
|
||||
|
@ -674,13 +674,12 @@ ng_btsocket_rfcomm_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
* Detach and destroy socket
|
||||
*/
|
||||
|
||||
int
|
||||
void
|
||||
ng_btsocket_rfcomm_detach(struct socket *so)
|
||||
{
|
||||
ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so);
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
KASSERT(pcb != NULL, ("ng_btsocket_rfcomm_detach: pcb == NULL"));
|
||||
|
||||
mtx_lock(&pcb->pcb_mtx);
|
||||
|
||||
@ -726,12 +725,7 @@ ng_btsocket_rfcomm_detach(struct socket *so)
|
||||
FREE(pcb, M_NETGRAPH_BTSOCKET_RFCOMM);
|
||||
|
||||
soisdisconnected(so);
|
||||
ACCEPT_LOCK();
|
||||
SOCK_LOCK(so);
|
||||
so->so_pcb = NULL;
|
||||
sotryfree(so);
|
||||
|
||||
return (0);
|
||||
} /* ng_btsocket_rfcomm_detach */
|
||||
|
||||
/*
|
||||
|
@ -185,15 +185,13 @@ ngc_attach(struct socket *so, int proto, struct thread *td)
|
||||
return (ng_attach_cntl(so));
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
ngc_detach(struct socket *so)
|
||||
{
|
||||
struct ngpcb *const pcbp = sotongpcb(so);
|
||||
|
||||
if (pcbp == NULL)
|
||||
return (EINVAL);
|
||||
KASSERT(pcbp != NULL, ("ngc_detach: pcbp == NULL"));
|
||||
ng_detach_common(pcbp, NG_CONTROL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -395,15 +393,13 @@ ngd_attach(struct socket *so, int proto, struct thread *td)
|
||||
return (ng_attach_data(so));
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
ngd_detach(struct socket *so)
|
||||
{
|
||||
struct ngpcb *const pcbp = sotongpcb(so);
|
||||
|
||||
if (pcbp == NULL)
|
||||
return (EINVAL);
|
||||
KASSERT(pcbp == NULL, ("ngd_detach: pcbp == NULL"));
|
||||
ng_detach_common(pcbp, NG_DATA);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -424,7 +424,7 @@ div_attach(struct socket *so, int proto, struct thread *td)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
div_detach(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
@ -433,12 +433,11 @@ div_detach(struct socket *so)
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&divcbinfo);
|
||||
return EINVAL;
|
||||
return;
|
||||
}
|
||||
INP_LOCK(inp);
|
||||
in_pcbdetach(inp);
|
||||
INP_INFO_WUNLOCK(&divcbinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -635,7 +635,7 @@ rip_pcbdetach(struct socket *so, struct inpcb *inp)
|
||||
in_pcbdetach(inp);
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
rip_detach(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
@ -645,12 +645,11 @@ rip_detach(struct socket *so)
|
||||
if (inp == 0) {
|
||||
/* XXX counter, printf */
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
return EINVAL;
|
||||
return;
|
||||
}
|
||||
INP_LOCK(inp);
|
||||
rip_pcbdetach(so, inp);
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -148,10 +148,9 @@ tcp_usr_attach(struct socket *so, int proto, struct thread *td)
|
||||
* which may finish later; embryonic TCB's can just
|
||||
* be discarded here.
|
||||
*/
|
||||
static int
|
||||
static void
|
||||
tcp_usr_detach(struct socket *so)
|
||||
{
|
||||
int error = 0;
|
||||
struct inpcb *inp;
|
||||
struct tcpcb *tp;
|
||||
TCPDEBUG0;
|
||||
@ -160,7 +159,7 @@ tcp_usr_detach(struct socket *so)
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == NULL) {
|
||||
INP_INFO_WUNLOCK(&tcbinfo);
|
||||
return error;
|
||||
return;
|
||||
}
|
||||
INP_LOCK(inp);
|
||||
tp = intotcpcb(inp);
|
||||
@ -171,7 +170,6 @@ tcp_usr_detach(struct socket *so)
|
||||
if (tp)
|
||||
INP_UNLOCK(inp);
|
||||
INP_INFO_WUNLOCK(&tcbinfo);
|
||||
return error;
|
||||
}
|
||||
|
||||
#define INI_NOLOCK 0
|
||||
|
@ -125,7 +125,7 @@ SYSCTL_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RW,
|
||||
static void udp_append(struct inpcb *last, struct ip *ip, struct mbuf *n,
|
||||
int off, struct sockaddr_in *udp_in);
|
||||
|
||||
static int udp_detach(struct socket *so);
|
||||
static void udp_detach(struct socket *so);
|
||||
static int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *,
|
||||
struct mbuf *, struct thread *);
|
||||
|
||||
@ -1027,7 +1027,7 @@ udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
udp_detach(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
@ -1036,12 +1036,10 @@ udp_detach(struct socket *so)
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return EINVAL;
|
||||
}
|
||||
INP_LOCK(inp);
|
||||
in_pcbdetach(inp);
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -591,7 +591,7 @@ rip6_attach(struct socket *so, int proto, struct thread *td)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
rip6_detach(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
@ -612,7 +612,6 @@ rip6_detach(struct socket *so)
|
||||
INP_LOCK(inp);
|
||||
in6_pcbdetach(inp);
|
||||
INP_INFO_WUNLOCK(&ripcbinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -117,7 +117,7 @@
|
||||
*/
|
||||
|
||||
extern struct protosw inetsw[];
|
||||
static int udp6_detach __P((struct socket *so));
|
||||
static void udp6_detach __P((struct socket *so));
|
||||
|
||||
int
|
||||
udp6_input(mp, offp, proto)
|
||||
@ -665,7 +665,7 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
udp6_detach(struct socket *so)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
@ -675,14 +675,13 @@ udp6_detach(struct socket *so)
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0) {
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return EINVAL;
|
||||
return;
|
||||
}
|
||||
INP_LOCK(inp);
|
||||
s = splnet();
|
||||
in6_pcbdetach(inp);
|
||||
splx(s);
|
||||
INP_INFO_WUNLOCK(&udbinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -456,24 +456,20 @@ key_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
* key_detach()
|
||||
* derived from net/rtsock.c:rts_detach()
|
||||
*/
|
||||
static int
|
||||
static void
|
||||
key_detach(struct socket *so)
|
||||
{
|
||||
struct keycb *kp = (struct keycb *)sotorawcb(so);
|
||||
int s, error;
|
||||
|
||||
s = splnet();
|
||||
if (kp != 0) {
|
||||
if (kp->kp_raw.rcb_proto.sp_protocol
|
||||
== PF_KEY) /* XXX: AF_KEY */
|
||||
key_cb.key_count--;
|
||||
key_cb.any_count--;
|
||||
KASSERT(kp != NULL, ("key_detach: kp == NULL"));
|
||||
if (kp->kp_raw.rcb_proto.sp_protocol
|
||||
== PF_KEY) /* XXX: AF_KEY */
|
||||
key_cb.key_count--;
|
||||
key_cb.any_count--;
|
||||
|
||||
key_freereg(so);
|
||||
}
|
||||
error = raw_usrreqs.pru_detach(so);
|
||||
splx(s);
|
||||
return error;
|
||||
key_freereg(so);
|
||||
raw_usrreqs.pru_detach(so);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -80,7 +80,7 @@ static int ipx_attach(struct socket *so, int proto, struct thread *td);
|
||||
static int ipx_bind(struct socket *so, struct sockaddr *nam, struct thread *td);
|
||||
static int ipx_connect(struct socket *so, struct sockaddr *nam,
|
||||
struct thread *td);
|
||||
static int ipx_detach(struct socket *so);
|
||||
static void ipx_detach(struct socket *so);
|
||||
static int ipx_disconnect(struct socket *so);
|
||||
static int ipx_send(struct socket *so, int flags, struct mbuf *m,
|
||||
struct sockaddr *addr, struct mbuf *control,
|
||||
@ -505,7 +505,7 @@ ipx_connect(so, nam, td)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
ipx_detach(so)
|
||||
struct socket *so;
|
||||
{
|
||||
@ -517,7 +517,6 @@ ipx_detach(so)
|
||||
ipx_pcbdetach(ipxp);
|
||||
ipx_pcbfree(ipxp);
|
||||
IPX_LIST_UNLOCK();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -103,7 +103,7 @@ static int spx_attach(struct socket *so, int proto, struct thread *td);
|
||||
static int spx_bind(struct socket *so, struct sockaddr *nam, struct thread *td);
|
||||
static int spx_connect(struct socket *so, struct sockaddr *nam,
|
||||
struct thread *td);
|
||||
static int spx_detach(struct socket *so);
|
||||
static void spx_detach(struct socket *so);
|
||||
static void spx_pcbdetach(struct ipxpcb *ipxp);
|
||||
static int spx_usr_disconnect(struct socket *so);
|
||||
static int spx_listen(struct socket *so, int backlog, struct thread *td);
|
||||
@ -1512,7 +1512,7 @@ spx_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
spx_detach(struct socket *so)
|
||||
{
|
||||
struct ipxpcb *ipxp;
|
||||
@ -1534,7 +1534,6 @@ spx_detach(struct socket *so)
|
||||
ipx_pcbdetach(ipxp);
|
||||
ipx_pcbfree(ipxp);
|
||||
IPX_LIST_UNLOCK();
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -366,24 +366,17 @@ key_connect(struct socket *so, struct sockaddr *nam, struct thread *p)
|
||||
* key_detach()
|
||||
* derived from net/rtsock.c:rts_detach()
|
||||
*/
|
||||
static int
|
||||
static void
|
||||
key_detach(struct socket *so)
|
||||
{
|
||||
struct keycb *kp = (struct keycb *)sotorawcb(so);
|
||||
int s, error;
|
||||
|
||||
s = splnet();
|
||||
if (kp != 0) {
|
||||
if (kp->kp_raw.rcb_proto.sp_protocol
|
||||
== PF_KEY) /* XXX: AF_KEY */
|
||||
key_cb.key_count--;
|
||||
key_cb.any_count--;
|
||||
|
||||
key_freereg(so);
|
||||
}
|
||||
error = raw_usrreqs.pru_detach(so);
|
||||
splx(s);
|
||||
return error;
|
||||
KASSERT(kp != NULL, ("key_detach: kp == NULL"));
|
||||
if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */
|
||||
key_cb.key_count--;
|
||||
key_cb.any_count--;
|
||||
key_freereg(so);
|
||||
raw_usrreqs.pru_detach(so);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -74,7 +74,7 @@ struct mtx natm_mtx;
|
||||
* user requests
|
||||
*/
|
||||
static int natm_usr_attach(struct socket *, int, d_thread_t *);
|
||||
static int natm_usr_detach(struct socket *);
|
||||
static void natm_usr_detach(struct socket *);
|
||||
static int natm_usr_connect(struct socket *, struct sockaddr *, d_thread_t *);
|
||||
static int natm_usr_disconnect(struct socket *);
|
||||
static int natm_usr_shutdown(struct socket *);
|
||||
@ -111,7 +111,7 @@ natm_usr_attach(struct socket *so, int proto, d_thread_t *p)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
natm_usr_detach(struct socket *so)
|
||||
{
|
||||
struct natmpcb *npcb;
|
||||
@ -122,7 +122,6 @@ natm_usr_detach(struct socket *so)
|
||||
npcb_free(npcb, NPCB_DESTROY); /* drain */
|
||||
so->so_pcb = NULL;
|
||||
NATM_UNLOCK();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -206,7 +206,7 @@ struct pr_usrreqs {
|
||||
int (*pru_connect2)(struct socket *so1, struct socket *so2);
|
||||
int (*pru_control)(struct socket *so, u_long cmd, caddr_t data,
|
||||
struct ifnet *ifp, struct thread *td);
|
||||
int (*pru_detach)(struct socket *so);
|
||||
void (*pru_detach)(struct socket *so);
|
||||
int (*pru_disconnect)(struct socket *so);
|
||||
int (*pru_listen)(struct socket *so, int backlog,
|
||||
struct thread *td);
|
||||
@ -256,7 +256,7 @@ int pru_connect_notsupp(struct socket *so, struct sockaddr *nam,
|
||||
int pru_connect2_notsupp(struct socket *so1, struct socket *so2);
|
||||
int pru_control_notsupp(struct socket *so, u_long cmd, caddr_t data,
|
||||
struct ifnet *ifp, struct thread *td);
|
||||
int pru_detach_notsupp(struct socket *so);
|
||||
void pru_detach_notsupp(struct socket *so);
|
||||
int pru_disconnect_notsupp(struct socket *so);
|
||||
int pru_listen_notsupp(struct socket *so, int backlog, struct thread *td);
|
||||
int pru_peeraddr_notsupp(struct socket *so, struct sockaddr **nam);
|
||||
|
Loading…
Reference in New Issue
Block a user