summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/sys_socket.c50
-rw-r--r--sys/kern/uipc_domain.c7
-rw-r--r--sys/kern/uipc_proto.c11
-rw-r--r--sys/kern/uipc_sockbuf.c13
-rw-r--r--sys/kern/uipc_socket.c83
-rw-r--r--sys/kern/uipc_socket2.c13
-rw-r--r--sys/kern/uipc_syscalls.c22
-rw-r--r--sys/kern/uipc_usrreq.c517
8 files changed, 411 insertions, 305 deletions
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index c3e6615..0c3b495 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)sys_socket.c 8.1 (Berkeley) 6/10/93
- * $Id: sys_socket.c,v 1.11 1997/03/23 03:36:25 bde Exp $
+ * $Id: sys_socket.c,v 1.12 1997/03/24 11:52:26 bde Exp $
*/
#include <sys/param.h>
@@ -68,9 +68,8 @@ soo_read(fp, uio, cred)
struct uio *uio;
struct ucred *cred;
{
-
- return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0,
- uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0));
+ struct socket *so = (struct socket *)fp->f_data;
+ return so->so_proto->pr_usrreqs->pru_soreceive(so, 0, uio, 0, 0, 0);
}
/* ARGSUSED */
@@ -80,9 +79,8 @@ soo_write(fp, uio, cred)
struct uio *uio;
struct ucred *cred;
{
-
- return (sosend((struct socket *)fp->f_data, (struct mbuf *)0,
- uio, (struct mbuf *)0, (struct mbuf *)0, 0));
+ struct socket *so = (struct socket *)fp->f_data;
+ return so->so_proto->pr_usrreqs->pru_sosend(so, 0, uio, 0, 0, 0);
}
int
@@ -140,7 +138,7 @@ soo_ioctl(fp, cmd, data, p)
return (ifioctl(so, cmd, data, p));
if (IOCGROUP(cmd) == 'r')
return (rtioctl(cmd, data, p));
- return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, 0));
+ return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, 0, p));
}
int
@@ -149,40 +147,8 @@ soo_select(fp, which, p)
int which;
struct proc *p;
{
- register struct socket *so = (struct socket *)fp->f_data;
- register int s = splnet();
-
- switch (which) {
-
- case FREAD:
- if (soreadable(so)) {
- splx(s);
- return (1);
- }
- selrecord(p, &so->so_rcv.sb_sel);
- so->so_rcv.sb_flags |= SB_SEL;
- break;
-
- case FWRITE:
- if (sowriteable(so)) {
- splx(s);
- return (1);
- }
- selrecord(p, &so->so_snd.sb_sel);
- so->so_snd.sb_flags |= SB_SEL;
- break;
-
- case 0:
- if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) {
- splx(s);
- return (1);
- }
- selrecord(p, &so->so_rcv.sb_sel);
- so->so_rcv.sb_flags |= SB_SEL;
- break;
- }
- splx(s);
- return (0);
+ struct socket *so = (struct socket *)fp->f_data;
+ return so->so_proto->pr_usrreqs->pru_soselect(so, which, p);
}
int
diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
index a2c3477..c2ec35f 100644
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93
- * $Id$
+ * $Id: uipc_domain.c,v 1.16 1997/02/22 09:39:27 peter Exp $
*/
#include <sys/param.h>
@@ -108,6 +108,11 @@ domaininit(dummy)
/* See comments in uipc_socket2.c. */
if (pr->pr_usrreqs == 0 && pr->pr_ousrreq)
pr->pr_usrreqs = &pru_oldstyle;
+#else
+ if (pr->pr_usrreqs == 0)
+ panic("domaininit: %ssw[%d] has no usrreqs!",
+ dp->dom_name,
+ (int)(pr - dp->dom_protosw));
#endif
if (pr->pr_init)
(*pr->pr_init)();
diff --git a/sys/kern/uipc_proto.c b/sys/kern/uipc_proto.c
index 664373c..bcd918c 100644
--- a/sys/kern/uipc_proto.c
+++ b/sys/kern/uipc_proto.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_proto.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_proto.c,v 1.10 1997/02/24 20:30:55 wollman Exp $
+ * $Id: uipc_proto.c,v 1.11 1997/04/14 18:23:48 phk Exp $
*/
#include <sys/param.h>
@@ -53,18 +53,21 @@
static struct protosw localsw[] = {
{ SOCK_STREAM, &localdomain, 0, PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS,
0, 0, 0, 0,
- uipc_usrreq,
+ 0,
0, 0, 0, 0,
+ &uipc_usrreqs
},
{ SOCK_DGRAM, &localdomain, 0, PR_ATOMIC|PR_ADDR|PR_RIGHTS,
0, 0, 0, 0,
- uipc_usrreq,
+ 0,
0, 0, 0, 0,
+ &uipc_usrreqs
},
{ 0, 0, 0, 0,
0, 0, raw_ctlinput, 0,
- raw_usrreq,
+ 0,
raw_init, 0, 0, 0,
+ &raw_usrreqs
}
};
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 4bddd1a..f31cc98 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.22 1997/02/24 20:30:57 wollman Exp $
+ * $Id: uipc_socket2.c,v 1.23 1997/03/31 12:29:59 davidg Exp $
*/
#include <sys/param.h>
@@ -220,7 +220,7 @@ sonewconn1(head, connstatus)
so->so_pgid = head->so_pgid;
(void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
- if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0)) {
+ if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0, curproc)) { /*XXX*/
(void) free((caddr_t)so, M_SOCKET);
return ((struct socket *)0);
}
@@ -975,7 +975,14 @@ pru_connect2_notsupp(struct socket *so1, struct socket *so2)
}
int
-pru_listen_notsupp(struct socket *so)
+pru_control_notsupp(struct socket *so, int cmd, caddr_t data,
+ struct ifnet *ifp, struct proc *p)
+{
+ return EOPNOTSUPP;
+}
+
+int
+pru_listen_notsupp(struct socket *so, struct proc *p)
{
return EOPNOTSUPP;
}
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 9f70207..095f764 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
- * $Id: uipc_socket.c,v 1.24 1997/02/24 20:30:56 wollman Exp $
+ * $Id: uipc_socket.c,v 1.25 1997/03/23 03:36:31 bde Exp $
*/
#include <sys/param.h>
@@ -78,7 +78,7 @@ socreate(dom, aso, type, proto, p)
prp = pffindproto(dom, proto, type);
else
prp = pffindtype(dom, type);
- if (prp == 0 || prp->pr_usrreqs == 0)
+ if (prp == 0 || prp->pr_usrreqs->pru_attach == 0)
return (EPROTONOSUPPORT);
if (prp->pr_type != type)
return (EPROTOTYPE);
@@ -87,10 +87,8 @@ socreate(dom, aso, type, proto, p)
TAILQ_INIT(&so->so_incomp);
TAILQ_INIT(&so->so_comp);
so->so_type = type;
- if (p->p_ucred->cr_uid == 0)
- so->so_state = SS_PRIV;
so->so_proto = prp;
- error = (*prp->pr_usrreqs->pru_attach)(so, proto);
+ error = (*prp->pr_usrreqs->pru_attach)(so, proto, p);
if (error) {
so->so_state |= SS_NOFDREF;
sofree(so);
@@ -101,26 +99,28 @@ socreate(dom, aso, type, proto, p)
}
int
-sobind(so, nam)
+sobind(so, nam, p)
struct socket *so;
struct mbuf *nam;
+ struct proc *p;
{
int s = splnet();
int error;
- error = (*so->so_proto->pr_usrreqs->pru_bind)(so, nam);
+ error = (*so->so_proto->pr_usrreqs->pru_bind)(so, nam, p);
splx(s);
return (error);
}
int
-solisten(so, backlog)
+solisten(so, backlog, p)
register struct socket *so;
int backlog;
+ struct proc *p;
{
int s = splnet(), error;
- error = (*so->so_proto->pr_usrreqs->pru_listen)(so);
+ error = (*so->so_proto->pr_usrreqs->pru_listen)(so, p);
if (error) {
splx(s);
return (error);
@@ -247,9 +247,10 @@ soaccept(so, nam)
}
int
-soconnect(so, nam)
+soconnect(so, nam, p)
register struct socket *so;
struct mbuf *nam;
+ struct proc *p;
{
int s;
int error;
@@ -268,7 +269,7 @@ soconnect(so, nam)
(error = sodisconnect(so))))
error = EISCONN;
else
- error = (*so->so_proto->pr_usrreqs->pru_connect)(so, nam);
+ error = (*so->so_proto->pr_usrreqs->pru_connect)(so, nam, p);
splx(s);
return (error);
}
@@ -471,7 +472,7 @@ nopages:
(so->so_proto->pr_flags & PR_IMPLOPCL) &&
(resid <= 0)) ?
PRUS_EOF : 0,
- top, addr, control);
+ top, addr, control, p);
splx(s);
if (dontroute)
so->so_options &= ~SO_DONTROUTE;
@@ -847,10 +848,11 @@ sorflush(so)
}
int
-sosetopt(so, level, optname, m0)
+sosetopt(so, level, optname, m0, p)
register struct socket *so;
int level, optname;
struct mbuf *m0;
+ struct proc *p;
{
int error = 0;
register struct mbuf *m = m0;
@@ -858,7 +860,7 @@ sosetopt(so, level, optname, m0)
if (level != SOL_SOCKET) {
if (so->so_proto && so->so_proto->pr_ctloutput)
return ((*so->so_proto->pr_ctloutput)
- (PRCO_SETOPT, so, level, optname, &m0));
+ (PRCO_SETOPT, so, level, optname, &m0, p));
error = ENOPROTOOPT;
} else {
switch (optname) {
@@ -948,18 +950,13 @@ sosetopt(so, level, optname, m0)
break;
}
- case SO_PRIVSTATE:
- /* we don't care what the parameter is... */
- so->so_state &= ~SS_PRIV;
- break;
-
default:
error = ENOPROTOOPT;
break;
}
if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
(void) ((*so->so_proto->pr_ctloutput)
- (PRCO_SETOPT, so, level, optname, &m0));
+ (PRCO_SETOPT, so, level, optname, &m0, p));
m = NULL; /* freed by protocol */
}
}
@@ -970,17 +967,18 @@ bad:
}
int
-sogetopt(so, level, optname, mp)
+sogetopt(so, level, optname, mp, p)
register struct socket *so;
int level, optname;
struct mbuf **mp;
+ struct proc *p;
{
register struct mbuf *m;
if (level != SOL_SOCKET) {
if (so->so_proto && so->so_proto->pr_ctloutput) {
return ((*so->so_proto->pr_ctloutput)
- (PRCO_GETOPT, so, level, optname, mp));
+ (PRCO_GETOPT, so, level, optname, mp, p));
} else
return (ENOPROTOOPT);
} else {
@@ -1008,10 +1006,6 @@ sogetopt(so, level, optname, mp)
*mtod(m, int *) = so->so_options & optname;
break;
- case SO_PRIVSTATE:
- *mtod(m, int *) = so->so_state & SS_PRIV;
- break;
-
case SO_TYPE:
*mtod(m, int *) = so->so_type;
break;
@@ -1071,3 +1065,40 @@ sohasoutofband(so)
psignal(p, SIGURG);
selwakeup(&so->so_rcv.sb_sel);
}
+
+int
+soselect(struct socket *so, int which, struct proc *p)
+{
+ int s = splnet();
+ switch (which) {
+
+ case FREAD:
+ if (soreadable(so)) {
+ splx(s);
+ return (1);
+ }
+ selrecord(p, &so->so_rcv.sb_sel);
+ so->so_rcv.sb_flags |= SB_SEL;
+ break;
+
+ case FWRITE:
+ if (sowriteable(so)) {
+ splx(s);
+ return (1);
+ }
+ selrecord(p, &so->so_snd.sb_sel);
+ so->so_snd.sb_flags |= SB_SEL;
+ break;
+
+ case 0:
+ if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) {
+ splx(s);
+ return (1);
+ }
+ selrecord(p, &so->so_rcv.sb_sel);
+ so->so_rcv.sb_flags |= SB_SEL;
+ break;
+ }
+ splx(s);
+ return (0);
+}
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index 4bddd1a..f31cc98 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.22 1997/02/24 20:30:57 wollman Exp $
+ * $Id: uipc_socket2.c,v 1.23 1997/03/31 12:29:59 davidg Exp $
*/
#include <sys/param.h>
@@ -220,7 +220,7 @@ sonewconn1(head, connstatus)
so->so_pgid = head->so_pgid;
(void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
- if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0)) {
+ if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0, curproc)) { /*XXX*/
(void) free((caddr_t)so, M_SOCKET);
return ((struct socket *)0);
}
@@ -975,7 +975,14 @@ pru_connect2_notsupp(struct socket *so1, struct socket *so2)
}
int
-pru_listen_notsupp(struct socket *so)
+pru_control_notsupp(struct socket *so, int cmd, caddr_t data,
+ struct ifnet *ifp, struct proc *p)
+{
+ return EOPNOTSUPP;
+}
+
+int
+pru_listen_notsupp(struct socket *so, struct proc *p)
{
return EOPNOTSUPP;
}
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 09156f0..fb8f428 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
- * $Id: uipc_syscalls.c,v 1.24 1997/03/31 12:30:01 davidg Exp $
+ * $Id: uipc_syscalls.c,v 1.25 1997/04/09 16:53:40 bde Exp $
*/
#include "opt_ktrace.h"
@@ -130,7 +130,7 @@ bind(p, uap, retval)
error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME);
if (error)
return (error);
- error = sobind((struct socket *)fp->f_data, nam);
+ error = sobind((struct socket *)fp->f_data, nam, p);
m_freem(nam);
return (error);
}
@@ -151,7 +151,7 @@ listen(p, uap, retval)
error = getsock(p->p_fd, uap->s, &fp);
if (error)
return (error);
- return (solisten((struct socket *)fp->f_data, uap->backlog));
+ return (solisten((struct socket *)fp->f_data, uap->backlog, p));
}
static int
@@ -312,7 +312,7 @@ connect(p, uap, retval)
error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME);
if (error)
return (error);
- error = soconnect(so, nam);
+ error = soconnect(so, nam, p);
if (error)
goto bad;
if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
@@ -420,6 +420,7 @@ sendit(p, s, mp, flags, retsize)
register int i;
struct mbuf *to, *control;
int len, error;
+ struct socket *so;
#ifdef KTRACE
struct iovec *ktriov = NULL;
#endif
@@ -485,8 +486,9 @@ sendit(p, s, mp, flags, retsize)
}
#endif
len = auio.uio_resid;
- error = sosend((struct socket *)fp->f_data, to, &auio,
- (struct mbuf *)0, control, flags);
+ so = (struct socket *)fp->f_data;
+ error = so->so_proto->pr_usrreqs->pru_sosend(so, to, &auio, 0, control,
+ flags);
if (error) {
if (auio.uio_resid != len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
@@ -659,6 +661,7 @@ recvit(p, s, mp, namelenp, retsize)
int len, error;
struct mbuf *m, *from = 0, *control = 0;
caddr_t ctlbuf;
+ struct socket *so;
#ifdef KTRACE
struct iovec *ktriov = NULL;
#endif
@@ -687,7 +690,8 @@ recvit(p, s, mp, namelenp, retsize)
}
#endif
len = auio.uio_resid;
- error = soreceive((struct socket *)fp->f_data, &from, &auio,
+ so = (struct socket *)fp->f_data;
+ error = so->so_proto->pr_usrreqs->pru_soreceive(so, &from, &auio,
(struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0,
&mp->msg_flags);
if (error) {
@@ -1012,7 +1016,7 @@ setsockopt(p, uap, retval)
m->m_len = uap->valsize;
}
return (sosetopt((struct socket *)fp->f_data, uap->level,
- uap->name, m));
+ uap->name, m, p));
}
/* ARGSUSED */
@@ -1043,7 +1047,7 @@ getsockopt(p, uap, retval)
} else
valsize = 0;
if ((error = sogetopt((struct socket *)fp->f_data, uap->level,
- uap->name, &m)) == 0 && uap->val && valsize && m != NULL) {
+ uap->name, &m, p)) == 0 && uap->val && valsize && m != NULL) {
op = 0;
while (m && !error && op < valsize) {
i = min(m->m_len, (valsize - op));
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 0a47414..2734778d 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* From: @(#)uipc_usrreq.c 8.3 (Berkeley) 1/4/94
- * $Id: uipc_usrreq.c,v 1.21 1997/03/21 16:12:32 wpaul Exp $
+ * $Id: uipc_usrreq.c,v 1.22 1997/03/23 03:36:33 bde Exp $
*/
#include <sys/param.h>
@@ -78,270 +78,353 @@ static void unp_mark __P((struct file *));
static void unp_discard __P((struct file *));
static int unp_internalize __P((struct mbuf *, struct proc *));
+static int
+uipc_abort(struct socket *so)
+{
+ struct unpcb *unp = sotounpcb(so);
-/*ARGSUSED*/
-int
-uipc_usrreq(so, req, m, nam, control)
- struct socket *so;
- int req;
- struct mbuf *m, *nam, *control;
+ if (unp == 0)
+ return EINVAL;
+ unp_drop(unp, ECONNABORTED);
+ return 0;
+}
+
+static int
+uipc_accept(struct socket *so, struct mbuf *nam)
{
struct unpcb *unp = sotounpcb(so);
- register struct socket *so2;
- register int error = 0;
- struct proc *p = curproc; /* XXX */
- if (req == PRU_CONTROL)
- return (EOPNOTSUPP);
- if (req != PRU_SEND && control && control->m_len) {
- error = EOPNOTSUPP;
- goto release;
- }
- if (unp == 0 && req != PRU_ATTACH) {
- error = EINVAL;
- goto release;
+ if (unp == 0)
+ return EINVAL;
+
+ /*
+ * Pass back name of connected socket,
+ * if it was bound and we are still connected
+ * (our peer may have closed already!).
+ */
+ if (unp->unp_conn && unp->unp_conn->unp_addr) {
+ nam->m_len = unp->unp_conn->unp_addr->m_len;
+ bcopy(mtod(unp->unp_conn->unp_addr, caddr_t),
+ mtod(nam, caddr_t), (unsigned)nam->m_len);
+ } else {
+ nam->m_len = sizeof(sun_noname);
+ *(mtod(nam, struct sockaddr *)) = sun_noname;
}
- switch (req) {
+ return 0;
+}
- case PRU_ATTACH:
- if (unp) {
- error = EISCONN;
- break;
- }
- error = unp_attach(so);
- break;
+static int
+uipc_attach(struct socket *so, int proto, struct proc *p)
+{
+ struct unpcb *unp = sotounpcb(so);
- case PRU_DETACH:
- unp_detach(unp);
- break;
+ if (unp != 0)
+ return EISCONN;
+ return unp_attach(so);
+}
- case PRU_BIND:
- error = unp_bind(unp, nam, p);
- break;
+static int
+uipc_bind(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+ struct unpcb *unp = sotounpcb(so);
- case PRU_LISTEN:
- if (unp->unp_vnode == 0)
- error = EINVAL;
- break;
+ if (unp == 0)
+ return EINVAL;
- case PRU_CONNECT:
- error = unp_connect(so, nam, p);
- break;
+ return unp_bind(unp, nam, p);
+}
- case PRU_CONNECT2:
- error = unp_connect2(so, (struct socket *)nam);
- break;
+static int
+uipc_connect(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+ struct unpcb *unp = sotounpcb(so);
- case PRU_DISCONNECT:
- unp_disconnect(unp);
- break;
+ if (unp == 0)
+ return EINVAL;
+ return unp_connect(so, nam, curproc);
+}
- case PRU_ACCEPT:
- /*
- * Pass back name of connected socket,
- * if it was bound and we are still connected
- * (our peer may have closed already!).
- */
- if (unp->unp_conn && unp->unp_conn->unp_addr) {
- nam->m_len = unp->unp_conn->unp_addr->m_len;
- bcopy(mtod(unp->unp_conn->unp_addr, caddr_t),
- mtod(nam, caddr_t), (unsigned)nam->m_len);
- } else {
- nam->m_len = sizeof(sun_noname);
- *(mtod(nam, struct sockaddr *)) = sun_noname;
- }
- break;
+static int
+uipc_connect2(struct socket *so1, struct socket *so2)
+{
+ struct unpcb *unp = sotounpcb(so1);
- case PRU_SHUTDOWN:
- socantsendmore(so);
- unp_shutdown(unp);
- break;
+ if (unp == 0)
+ return EINVAL;
- case PRU_RCVD:
- switch (so->so_type) {
+ return unp_connect2(so1, so2);
+}
- case SOCK_DGRAM:
- panic("uipc 1");
- /*NOTREACHED*/
+/* control is EOPNOTSUPP */
- case SOCK_STREAM:
+static int
+uipc_detach(struct socket *so)
+{
+ struct unpcb *unp = sotounpcb(so);
+
+ if (unp == 0)
+ return EINVAL;
+
+ unp_detach(unp);
+ return 0;
+}
+
+static int
+uipc_disconnect(struct socket *so)
+{
+ struct unpcb *unp = sotounpcb(so);
+
+ if (unp == 0)
+ return EINVAL;
+ unp_disconnect(unp);
+ return 0;
+}
+
+static int
+uipc_listen(struct socket *so, struct proc *p)
+{
+ struct unpcb *unp = sotounpcb(so);
+
+ if (unp == 0 || unp->unp_vnode == 0)
+ return EINVAL;
+ return 0;
+}
+
+static int
+uipc_peeraddr(struct socket *so, struct mbuf *nam)
+{
+ struct unpcb *unp = sotounpcb(so);
+
+ if (unp == 0)
+ return EINVAL;
+ if (unp->unp_conn && unp->unp_conn->unp_addr) {
+ nam->m_len = unp->unp_conn->unp_addr->m_len;
+ bcopy(mtod(unp->unp_conn->unp_addr, caddr_t),
+ mtod(nam, caddr_t), (unsigned)nam->m_len);
+ } else
+ nam->m_len = 0;
+ return 0;
+}
+
+static int
+uipc_rcvd(struct socket *so, int flags)
+{
+ struct unpcb *unp = sotounpcb(so);
+ struct socket *so2;
+
+ if (unp == 0)
+ return EINVAL;
+ switch (so->so_type) {
+ case SOCK_DGRAM:
+ panic("uipc_rcvd DGRAM?");
+ /*NOTREACHED*/
+
+ case SOCK_STREAM:
#define rcv (&so->so_rcv)
#define snd (&so2->so_snd)
- if (unp->unp_conn == 0)
- break;
- so2 = unp->unp_conn->unp_socket;
- /*
- * Adjust backpressure on sender
- * and wakeup any waiting to write.
- */
- snd->sb_mbmax += unp->unp_mbcnt - rcv->sb_mbcnt;
- unp->unp_mbcnt = rcv->sb_mbcnt;
- snd->sb_hiwat += unp->unp_cc - rcv->sb_cc;
- unp->unp_cc = rcv->sb_cc;
- sowwakeup(so2);
+ if (unp->unp_conn == 0)
+ break;
+ so2 = unp->unp_conn->unp_socket;
+ /*
+ * Adjust backpressure on sender
+ * and wakeup any waiting to write.
+ */
+ snd->sb_mbmax += unp->unp_mbcnt - rcv->sb_mbcnt;
+ unp->unp_mbcnt = rcv->sb_mbcnt;
+ snd->sb_hiwat += unp->unp_cc - rcv->sb_cc;
+ unp->unp_cc = rcv->sb_cc;
+ sowwakeup(so2);
#undef snd
#undef rcv
- break;
-
- default:
- panic("uipc 2");
- }
break;
- case PRU_SEND:
- case PRU_SEND_EOF:
- if (control && (error = unp_internalize(control, p)))
- break;
- switch (so->so_type) {
+ default:
+ panic("uipc_rcvd unknown socktype");
+ }
+ return 0;
+}
- case SOCK_DGRAM: {
- struct sockaddr *from;
+/* pru_rcvoob is EOPNOTSUPP */
- if (nam) {
- if (unp->unp_conn) {
- error = EISCONN;
- break;
- }
- error = unp_connect(so, nam, p);
- if (error)
- break;
- } else {
- if (unp->unp_conn == 0) {
- error = ENOTCONN;
- break;
- }
- }
- so2 = unp->unp_conn->unp_socket;
- if (unp->unp_addr)
- from = mtod(unp->unp_addr, struct sockaddr *);
- else
- from = &sun_noname;
- if (sbappendaddr(&so2->so_rcv, from, m, control)) {
- sorwakeup(so2);
- m = 0;
- control = 0;
- } else
- error = ENOBUFS;
- if (nam)
- unp_disconnect(unp);
- break;
- }
+static int
+uipc_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control, struct proc *p)
+{
+ int error = 0;
+ struct unpcb *unp = sotounpcb(so);
+ struct socket *so2;
- case SOCK_STREAM:
-#define rcv (&so2->so_rcv)
-#define snd (&so->so_snd)
- /* Connect if not connected yet. */
- /*
- * Note: A better implementation would complain
- * if not equal to the peer's address.
- */
- if ((so->so_state & SS_ISCONNECTED) == 0) {
- if (nam) {
- error = unp_connect(so, nam, p);
- if (error)
- break; /* XXX */
- } else {
- error = ENOTCONN;
- break;
- }
- }
+ if (unp == 0) {
+ error = EINVAL;
+ goto release;
+ }
+ if (flags & PRUS_OOB) {
+ error = EOPNOTSUPP;
+ goto release;
+ }
+
+ if (control && (error = unp_internalize(control, p)))
+ goto release;
- if (so->so_state & SS_CANTSENDMORE) {
- error = EPIPE;
+ switch (so->so_type) {
+ case SOCK_DGRAM:
+ {
+ struct sockaddr *from;
+
+ if (nam) {
+ if (unp->unp_conn) {
+ error = EISCONN;
break;
}
- if (unp->unp_conn == 0)
- panic("uipc 3");
- so2 = unp->unp_conn->unp_socket;
- /*
- * Send to paired receive port, and then reduce
- * send buffer hiwater marks to maintain backpressure.
- * Wake up readers.
- */
- if (control) {
- if (sbappendcontrol(rcv, m, control))
- control = 0;
- } else
- sbappend(rcv, m);
- snd->sb_mbmax -=
- rcv->sb_mbcnt - unp->unp_conn->unp_mbcnt;
- unp->unp_conn->unp_mbcnt = rcv->sb_mbcnt;
- snd->sb_hiwat -= rcv->sb_cc - unp->unp_conn->unp_cc;
- unp->unp_conn->unp_cc = rcv->sb_cc;
+ error = unp_connect(so, nam, p);
+ if (error)
+ break;
+ } else {
+ if (unp->unp_conn == 0) {
+ error = ENOTCONN;
+ break;
+ }
+ }
+ so2 = unp->unp_conn->unp_socket;
+ if (unp->unp_addr)
+ from = mtod(unp->unp_addr, struct sockaddr *);
+ else
+ from = &sun_noname;
+ if (sbappendaddr(&so2->so_rcv, from, m, control)) {
sorwakeup(so2);
m = 0;
-#undef snd
-#undef rcv
- break;
+ control = 0;
+ } else
+ error = ENOBUFS;
+ if (nam)
+ unp_disconnect(unp);
+ break;
+ }
- default:
- panic("uipc 4");
- }
+ case SOCK_STREAM:
+#define rcv (&so2->so_rcv)
+#define snd (&so->so_snd)
+ /* Connect if not connected yet. */
/*
- * SEND_EOF is equivalent to a SEND followed by
- * a SHUTDOWN.
+ * Note: A better implementation would complain
+ * if not equal to the peer's address.
*/
- if (req == PRU_SEND_EOF) {
- socantsendmore(so);
- unp_shutdown(unp);
+ if ((so->so_state & SS_ISCONNECTED) == 0) {
+ if (nam) {
+ error = unp_connect(so, nam, p);
+ if (error)
+ break; /* XXX */
+ } else {
+ error = ENOTCONN;
+ break;
+ }
}
- break;
- case PRU_ABORT:
- unp_drop(unp, ECONNABORTED);
- break;
-
- case PRU_SENSE:
- ((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat;
- if (so->so_type == SOCK_STREAM && unp->unp_conn != 0) {
- so2 = unp->unp_conn->unp_socket;
- ((struct stat *) m)->st_blksize += so2->so_rcv.sb_cc;
+ if (so->so_state & SS_CANTSENDMORE) {
+ error = EPIPE;
+ break;
}
- ((struct stat *) m)->st_dev = NODEV;
- if (unp->unp_ino == 0)
- unp->unp_ino = unp_ino++;
- ((struct stat *) m)->st_ino = unp->unp_ino;
- return (0);
-
- case PRU_RCVOOB:
- return (EOPNOTSUPP);
-
- case PRU_SENDOOB:
- error = EOPNOTSUPP;
- break;
-
- case PRU_SOCKADDR:
- if (unp->unp_addr) {
- nam->m_len = unp->unp_addr->m_len;
- bcopy(mtod(unp->unp_addr, caddr_t),
- mtod(nam, caddr_t), (unsigned)nam->m_len);
- } else
- nam->m_len = 0;
- break;
-
- case PRU_PEERADDR:
- if (unp->unp_conn && unp->unp_conn->unp_addr) {
- nam->m_len = unp->unp_conn->unp_addr->m_len;
- bcopy(mtod(unp->unp_conn->unp_addr, caddr_t),
- mtod(nam, caddr_t), (unsigned)nam->m_len);
+ if (unp->unp_conn == 0)
+ panic("uipc_send connected but no connection?");
+ so2 = unp->unp_conn->unp_socket;
+ /*
+ * Send to paired receive port, and then reduce
+ * send buffer hiwater marks to maintain backpressure.
+ * Wake up readers.
+ */
+ if (control) {
+ if (sbappendcontrol(rcv, m, control))
+ control = 0;
} else
- nam->m_len = 0;
- break;
-
- case PRU_SLOWTIMO:
+ sbappend(rcv, m);
+ snd->sb_mbmax -=
+ rcv->sb_mbcnt - unp->unp_conn->unp_mbcnt;
+ unp->unp_conn->unp_mbcnt = rcv->sb_mbcnt;
+ snd->sb_hiwat -= rcv->sb_cc - unp->unp_conn->unp_cc;
+ unp->unp_conn->unp_cc = rcv->sb_cc;
+ sorwakeup(so2);
+ m = 0;
+#undef snd
+#undef rcv
break;
default:
- panic("piusrreq");
+ panic("uipc_send unknown socktype");
+ }
+
+ /*
+ * SEND_EOF is equivalent to a SEND followed by
+ * a SHUTDOWN.
+ */
+ if (flags & PRUS_EOF) {
+ socantsendmore(so);
+ unp_shutdown(unp);
}
+
release:
if (control)
m_freem(control);
if (m)
m_freem(m);
- return (error);
+ return error;
+}
+
+static int
+uipc_sense(struct socket *so, struct stat *sb)
+{
+ struct unpcb *unp = sotounpcb(so);
+ struct socket *so2;
+
+ if (unp == 0)
+ return EINVAL;
+ sb->st_blksize = so->so_snd.sb_hiwat;
+ if (so->so_type == SOCK_STREAM && unp->unp_conn != 0) {
+ so2 = unp->unp_conn->unp_socket;
+ sb->st_blksize += so2->so_rcv.sb_cc;
+ }
+ sb->st_dev = NODEV;
+ if (unp->unp_ino == 0)
+ unp->unp_ino = unp_ino++;
+ sb->st_ino = unp->unp_ino;
+ return (0);
+}
+
+static int
+uipc_shutdown(struct socket *so)
+{
+ struct unpcb *unp = sotounpcb(so);
+
+ if (unp == 0)
+ return EINVAL;
+ socantsendmore(so);
+ unp_shutdown(unp);
+ return 0;
+}
+
+static int
+uipc_sockaddr(struct socket *so, struct mbuf *nam)
+{
+ struct unpcb *unp = sotounpcb(so);
+
+ if (unp == 0)
+ return EINVAL;
+ if (unp->unp_addr) {
+ nam->m_len = unp->unp_addr->m_len;
+ bcopy(mtod(unp->unp_addr, caddr_t),
+ mtod(nam, caddr_t), (unsigned)nam->m_len);
+ } else
+ nam->m_len = 0;
+ return 0;
}
+struct pr_usrreqs uipc_usrreqs = {
+ uipc_abort, uipc_accept, uipc_attach, uipc_bind, uipc_connect,
+ uipc_connect2, pru_control_notsupp, uipc_detach, uipc_disconnect,
+ uipc_listen, uipc_peeraddr, uipc_rcvd, pru_rcvoob_notsupp,
+ uipc_send, uipc_sense, uipc_shutdown, uipc_sockaddr,
+ sosend, soreceive, soselect
+};
+
/*
* Both send and receive buffers are allocated PIPSIZ bytes of buffering
* for stream sockets, although the total for sender and receiver is
@@ -472,7 +555,7 @@ unp_bind(unp, nam, p)
}
VATTR_NULL(&vattr);
vattr.va_type = VSOCK;
- vattr.va_mode = ACCESSPERMS;
+ vattr.va_mode = (ACCESSPERMS & ~p->p_fd->fd_cmask);
VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
if (error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr))
return (error);
OpenPOWER on IntegriCloud