Esempio n. 1
0
int
so_pru_attach_fast(struct socket *so, int proto, struct pru_attach_info *ai)
{
	struct netmsg_pru_attach *msg;
	int error;

	error = so->so_proto->pr_usrreqs->pru_preattach(so, proto, ai);
	if (error)
		return error;

	msg = kmalloc(sizeof(*msg), M_LWKTMSG, M_WAITOK | M_NULLOK);
	if (msg == NULL) {
		/*
		 * Fail to allocate message; fallback to
		 * synchronized pru_attach.
		 */
		return so_pru_attach(so, proto, NULL /* postattach */);
	}

	netmsg_init(&msg->base, so, &netisr_afree_rport, 0,
	    so->so_proto->pr_usrreqs->pru_attach);
	msg->nm_proto = proto;
	msg->nm_ai = NULL; /* postattach */
	lwkt_sendmsg(so->so_port, &msg->base.lmsg);

	return 0;
}
Esempio n. 2
0
int
socreate(int dom, struct socket **aso, int type,
	int proto, struct thread *td)
{
	struct proc *p = td->td_proc;
	struct protosw *prp;
	struct socket *so;
	struct pru_attach_info ai;
	int error;

	if (proto)
		prp = pffindproto(dom, proto, type);
	else
		prp = pffindtype(dom, type);

	if (prp == 0 || prp->pr_usrreqs->pru_attach == 0)
		return (EPROTONOSUPPORT);

	if (p->p_ucred->cr_prison && jail_socket_unixiproute_only &&
	    prp->pr_domain->dom_family != PF_LOCAL &&
	    prp->pr_domain->dom_family != PF_INET &&
	    prp->pr_domain->dom_family != PF_INET6 &&
	    prp->pr_domain->dom_family != PF_ROUTE) {
		return (EPROTONOSUPPORT);
	}

	if (prp->pr_type != type)
		return (EPROTOTYPE);
	so = soalloc(p != 0);
	if (so == NULL)
		return (ENOBUFS);

	/*
	 * Callers of socreate() presumably will connect up a descriptor
	 * and call soclose() if they cannot.  This represents our so_refs
	 * (which should be 1) from soalloc().
	 */
	soclrstate(so, SS_NOFDREF);

	/*
	 * Set a default port for protocol processing.  No action will occur
	 * on the socket on this port until an inpcb is attached to it and
	 * is able to match incoming packets, or until the socket becomes
	 * available to userland.
	 *
	 * We normally default the socket to the protocol thread on cpu 0.
	 * If PR_SYNC_PORT is set (unix domain sockets) there is no protocol
	 * thread and all pr_*()/pru_*() calls are executed synchronously.
	 */
	if (prp->pr_flags & PR_SYNC_PORT)
		so->so_port = &netisr_sync_port;
	else
		so->so_port = cpu_portfn(0);

	TAILQ_INIT(&so->so_incomp);
	TAILQ_INIT(&so->so_comp);
	so->so_type = type;
	so->so_cred = crhold(p->p_ucred);
	so->so_proto = prp;
	ai.sb_rlimit = &p->p_rlimit[RLIMIT_SBSIZE];
	ai.p_ucred = p->p_ucred;
	ai.fd_rdir = p->p_fd->fd_rdir;

	/*
	 * Auto-sizing of socket buffers is managed by the protocols and
	 * the appropriate flags must be set in the pru_attach function.
	 */
	error = so_pru_attach(so, proto, &ai);
	if (error) {
		sosetstate(so, SS_NOFDREF);
		sofree(so);	/* from soalloc */
		return error;
	}

	/*
	 * NOTE: Returns referenced socket.
	 */
	*aso = so;
	return (0);
}