This avoids socket.so_pcb use-after-check race against protocol thread.
There is no performance impact on the mostly used sockets:
- IPv4/IPv6 TCP implemented pru_savefaddr, so their pru_accept will not
be called at all
- UNIX domain socket uses sync msgport, so no protocol thread dispatching
sofree(msg.base.nm_so);
}
-/*
- * WARNING! Synchronous call from user context
- */
int
-so_pru_accept_direct(struct socket *so, struct sockaddr **nam)
+so_pru_accept(struct socket *so, struct sockaddr **nam)
{
struct netmsg_pru_accept msg;
- netisr_fn_t func = so->so_proto->pr_usrreqs->pru_accept;
- netmsg_init(&msg.base, so, &netisr_adone_rport, 0, func);
- msg.base.lmsg.ms_flags &= ~(MSGF_REPLY | MSGF_DONE);
- msg.base.lmsg.ms_flags |= MSGF_SYNC;
+ netmsg_init(&msg.base, so, &curthread->td_msgport,
+ 0, so->so_proto->pr_usrreqs->pru_accept);
msg.nm_nam = nam;
- func((netmsg_t)&msg);
- KKASSERT(msg.base.lmsg.ms_flags & MSGF_DONE);
- return(msg.base.lmsg.ms_error);
+
+ return lwkt_domsg(so->so_port, &msg.base.lmsg, 0);
}
int
int error;
soaccept_generic(so);
- error = so_pru_accept_direct(so, nam);
+ error = so_pru_accept(so, nam);
return (error);
}
* These are netmsg'd requests almost universally in the context of the
* appropriate protocol thread. Exceptions:
*
- * pru_accept() - called synchronously from user context
- *
* pru_sosend() - called synchronously from user context, typically
* runs generic kernel code and then messages via
* pru_send().
*/
struct pr_usrreqs {
void (*pru_abort) (netmsg_t msg);
- void (*pru_accept) (netmsg_t msg); /* synchronous call */
+ void (*pru_accept) (netmsg_t msg);
void (*pru_attach) (netmsg_t msg);
void (*pru_bind) (netmsg_t msg);
void (*pru_connect) (netmsg_t msg);
void so_pru_abort (struct socket *so);
void so_pru_aborta (struct socket *so);
void so_pru_abort_oncpu (struct socket *so);
-int so_pru_accept_direct(struct socket *so, struct sockaddr **nam);
+int so_pru_accept (struct socket *so, struct sockaddr **nam);
int so_pru_attach (struct socket *so, int proto, struct pru_attach_info *ai);
int so_pru_attach_direct(struct socket *so, int proto,
struct pru_attach_info *ai);